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 260444 2014-01-08 08:06:56Z kevlo $"); 32 33 /* 34 * The Broadcom Wireless LAN controller driver. 35 */ 36 37 #include <opt_wlan.h> 38 #include <opt_bwn.h> 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/module.h> 43 #include <sys/kernel.h> 44 #include <sys/endian.h> 45 #include <sys/errno.h> 46 #include <sys/firmware.h> 47 #include <sys/bus_resource.h> 48 #include <sys/bus.h> 49 #include <sys/rman.h> 50 #include <sys/socket.h> 51 #include <sys/sockio.h> 52 53 #include <net/ethernet.h> 54 #include <net/if.h> 55 #include <net/if_var.h> 56 #include <net/if_arp.h> 57 #include <net/if_dl.h> 58 #include <net/if_llc.h> 59 #include <net/if_media.h> 60 #include <net/if_types.h> 61 #include <net/ifq_var.h> 62 63 #include <bus/pci/pcivar.h> 64 #include <bus/pci/pcireg.h> 65 #include <dev/netif/bwn/siba/siba_ids.h> 66 #include <dev/netif/bwn/siba/sibareg.h> 67 #include <dev/netif/bwn/siba/sibavar.h> 68 69 #include <netproto/802_11/ieee80211_var.h> 70 #include <netproto/802_11/ieee80211_radiotap.h> 71 #include <netproto/802_11/ieee80211_regdomain.h> 72 #include <netproto/802_11/ieee80211_phy.h> 73 #include <netproto/802_11/ieee80211_ratectl.h> 74 75 #include "if_bwnreg.h" 76 #include "if_bwnvar.h" 77 78 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, 79 "Broadcom driver parameters"); 80 81 /* 82 * Tunable & sysctl variables. 83 */ 84 85 #ifdef BWN_DEBUG 86 static int bwn_debug = 0; 87 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0, 88 "Broadcom debugging printfs"); 89 TUNABLE_INT("hw.bwn.debug", &bwn_debug); 90 enum { 91 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 92 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 93 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 94 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 95 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 96 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 97 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 98 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 99 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 100 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 101 BWN_DEBUG_NODE = 0x00000400, /* node management */ 102 BWN_DEBUG_LED = 0x00000800, /* led management */ 103 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 104 BWN_DEBUG_LO = 0x00002000, /* LO */ 105 BWN_DEBUG_FW = 0x00004000, /* firmware */ 106 BWN_DEBUG_WME = 0x00008000, /* WME */ 107 BWN_DEBUG_RF = 0x00010000, /* RF */ 108 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 109 BWN_DEBUG_ANY = 0xffffffff 110 }; 111 #define DPRINTF(sc, m, fmt, ...) do { \ 112 if (sc->sc_debug & (m)) \ 113 kprintf(fmt, __VA_ARGS__); \ 114 } while (0) 115 #else 116 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 117 #endif 118 119 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 120 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 121 "uses Bad Frames Preemption"); 122 static int bwn_bluetooth = 1; 123 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 124 "turns on Bluetooth Coexistence"); 125 static int bwn_hwpctl = 0; 126 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 127 "uses H/W power control"); 128 static int bwn_msi_enable = 1; 129 TUNABLE_INT("hw.bwn.msi.enable", &bwn_msi_enable); 130 static int bwn_usedma = 1; 131 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 132 "uses DMA"); 133 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 134 static int bwn_wme = 1; 135 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 136 "uses WME support"); 137 138 static int bwn_attach_pre(struct bwn_softc *); 139 static int bwn_attach_post(struct bwn_softc *); 140 static void bwn_sprom_bugfixes(device_t); 141 static void bwn_init(void *); 142 static int bwn_init_locked(struct bwn_softc *); 143 static int bwn_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *); 144 static void bwn_start(struct ifnet *, struct ifaltq_subque *); 145 static int bwn_attach_core(struct bwn_mac *); 146 static void bwn_reset_core(struct bwn_mac *, uint32_t); 147 static int bwn_phy_getinfo(struct bwn_mac *, int); 148 static int bwn_chiptest(struct bwn_mac *); 149 static int bwn_setup_channels(struct bwn_mac *, int, int); 150 static int bwn_phy_g_attach(struct bwn_mac *); 151 static void bwn_phy_g_detach(struct bwn_mac *); 152 static void bwn_phy_g_init_pre(struct bwn_mac *); 153 static int bwn_phy_g_prepare_hw(struct bwn_mac *); 154 static int bwn_phy_g_init(struct bwn_mac *); 155 static void bwn_phy_g_exit(struct bwn_mac *); 156 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 157 static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 158 uint16_t); 159 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 160 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 161 uint16_t); 162 static int bwn_phy_g_hwpctl(struct bwn_mac *); 163 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 164 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 165 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 166 static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 167 static int bwn_phy_g_im(struct bwn_mac *, int); 168 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 169 static void bwn_phy_g_set_txpwr(struct bwn_mac *); 170 static void bwn_phy_g_task_15s(struct bwn_mac *); 171 static void bwn_phy_g_task_60s(struct bwn_mac *); 172 static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 173 static void bwn_phy_switch_analog(struct bwn_mac *, int); 174 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 175 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 176 uint16_t); 177 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 178 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 179 uint32_t); 180 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 181 uint16_t); 182 static void bwn_addchannels(struct ieee80211_channel [], int, int *, 183 const struct bwn_channelinfo *, int); 184 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 185 const struct ieee80211_bpf_params *); 186 static void bwn_updateslot(struct ieee80211com *); 187 static void bwn_update_promisc(struct ieee80211com *); 188 static void bwn_wme_init(struct bwn_mac *); 189 static int bwn_wme_update(struct ieee80211com *); 190 static void bwn_wme_clear(struct bwn_softc *); 191 static void bwn_wme_load(struct bwn_mac *); 192 static void bwn_wme_loadparams(struct bwn_mac *, 193 const struct wmeParams *, uint16_t); 194 static void bwn_scan_start(struct ieee80211com *); 195 static void bwn_scan_end(struct ieee80211com *); 196 static void bwn_set_channel(struct ieee80211com *); 197 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 198 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 199 const uint8_t [IEEE80211_ADDR_LEN], 200 const uint8_t [IEEE80211_ADDR_LEN]); 201 static void bwn_vap_delete(struct ieee80211vap *); 202 static void bwn_stop(struct bwn_softc *, int); 203 static void bwn_stop_locked(struct bwn_softc *, int); 204 static int bwn_core_init(struct bwn_mac *); 205 static void bwn_core_start(struct bwn_mac *); 206 static void bwn_core_exit(struct bwn_mac *); 207 static void bwn_bt_disable(struct bwn_mac *); 208 static int bwn_chip_init(struct bwn_mac *); 209 static uint64_t bwn_hf_read(struct bwn_mac *); 210 static void bwn_hf_write(struct bwn_mac *, uint64_t); 211 static void bwn_set_txretry(struct bwn_mac *, int, int); 212 static void bwn_rate_init(struct bwn_mac *); 213 static void bwn_set_phytxctl(struct bwn_mac *); 214 static void bwn_spu_setdelay(struct bwn_mac *, int); 215 static void bwn_bt_enable(struct bwn_mac *); 216 static void bwn_set_macaddr(struct bwn_mac *); 217 static void bwn_crypt_init(struct bwn_mac *); 218 static void bwn_chip_exit(struct bwn_mac *); 219 static int bwn_fw_fillinfo(struct bwn_mac *); 220 static int bwn_fw_loaducode(struct bwn_mac *); 221 static int bwn_gpio_init(struct bwn_mac *); 222 static int bwn_fw_loadinitvals(struct bwn_mac *); 223 static int bwn_phy_init(struct bwn_mac *); 224 static void bwn_set_txantenna(struct bwn_mac *, int); 225 static void bwn_set_opmode(struct bwn_mac *); 226 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 227 static uint8_t bwn_plcp_getcck(const uint8_t); 228 static uint8_t bwn_plcp_getofdm(const uint8_t); 229 static void bwn_pio_init(struct bwn_mac *); 230 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 231 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 232 int); 233 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 234 struct bwn_pio_rxqueue *, int); 235 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 236 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 237 uint16_t); 238 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 239 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 240 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 241 static void bwn_pio_handle_txeof(struct bwn_mac *, 242 const struct bwn_txstatus *); 243 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 244 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 245 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 246 uint16_t); 247 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 248 uint32_t); 249 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 250 struct mbuf *); 251 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 252 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 253 struct bwn_pio_txqueue *, uint32_t, const void *, int); 254 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 255 uint16_t, uint32_t); 256 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 257 struct bwn_pio_txqueue *, uint16_t, const void *, int); 258 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 259 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 260 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 261 uint16_t, struct bwn_pio_txpkt **); 262 static void bwn_dma_init(struct bwn_mac *); 263 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 264 static int bwn_dma_mask2type(uint64_t); 265 static uint64_t bwn_dma_mask(struct bwn_mac *); 266 static uint16_t bwn_dma_base(int, int); 267 static void bwn_dma_ringfree(struct bwn_dma_ring **); 268 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 269 int, struct bwn_dmadesc_generic **, 270 struct bwn_dmadesc_meta **); 271 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 272 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 273 int, int); 274 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 275 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 276 static void bwn_dma_32_resume(struct bwn_dma_ring *); 277 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 278 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 279 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 280 int, struct bwn_dmadesc_generic **, 281 struct bwn_dmadesc_meta **); 282 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 283 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 284 int, int); 285 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 286 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 287 static void bwn_dma_64_resume(struct bwn_dma_ring *); 288 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 289 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 290 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 291 static void bwn_dma_setup(struct bwn_dma_ring *); 292 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 293 static void bwn_dma_cleanup(struct bwn_dma_ring *); 294 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 295 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 296 static void bwn_dma_rx_handle_overflow(struct bwn_dma_ring *); 297 static void bwn_dma_rx(struct bwn_dma_ring *); 298 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 299 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 300 struct bwn_dmadesc_meta *); 301 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 302 static int bwn_dma_gettype(struct bwn_mac *); 303 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 304 static int bwn_dma_freeslot(struct bwn_dma_ring *); 305 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 306 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 307 static int bwn_dma_newbuf(struct bwn_dma_ring *, 308 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 309 int); 310 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 311 bus_size_t, int); 312 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 313 static void bwn_dma_handle_txeof(struct bwn_mac *, 314 const struct bwn_txstatus *); 315 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 316 struct mbuf *); 317 static int bwn_dma_getslot(struct bwn_dma_ring *); 318 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 319 uint8_t); 320 static int bwn_dma_attach(struct bwn_mac *); 321 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 322 int, int, int); 323 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 324 const struct bwn_txstatus *, uint16_t, int *); 325 static void bwn_dma_free(struct bwn_mac *); 326 static void bwn_phy_g_init_sub(struct bwn_mac *); 327 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 328 static void bwn_phy_init_b5(struct bwn_mac *); 329 static void bwn_phy_init_b6(struct bwn_mac *); 330 static void bwn_phy_init_a(struct bwn_mac *); 331 static void bwn_loopback_calcgain(struct bwn_mac *); 332 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 333 static void bwn_lo_g_init(struct bwn_mac *); 334 static void bwn_lo_g_adjust(struct bwn_mac *); 335 static void bwn_lo_get_powervector(struct bwn_mac *); 336 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 337 const struct bwn_bbatt *, const struct bwn_rfatt *); 338 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 339 static void bwn_phy_hwpctl_init(struct bwn_mac *); 340 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 341 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 342 const struct bwn_bbatt *, const struct bwn_rfatt *, 343 uint8_t); 344 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 345 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 346 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 347 static void bwn_wa_init(struct bwn_mac *); 348 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 349 uint16_t); 350 static void bwn_dummy_transmission(struct bwn_mac *, int, int); 351 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 352 uint32_t); 353 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 354 uint16_t); 355 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 356 static void bwn_mac_suspend(struct bwn_mac *); 357 static void bwn_mac_enable(struct bwn_mac *); 358 static void bwn_psctl(struct bwn_mac *, uint32_t); 359 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 360 static void bwn_nrssi_offset(struct bwn_mac *); 361 static void bwn_nrssi_threshold(struct bwn_mac *); 362 static void bwn_nrssi_slope_11g(struct bwn_mac *); 363 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 364 int16_t); 365 static void bwn_set_original_gains(struct bwn_mac *); 366 static void bwn_hwpctl_early_init(struct bwn_mac *); 367 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 368 static uint16_t bwn_phy_g_chan2freq(uint8_t); 369 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 370 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 371 const char *, struct bwn_fwfile *); 372 static void bwn_release_firmware(struct bwn_mac *); 373 static void bwn_do_release_fw(struct bwn_fwfile *); 374 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 375 static int bwn_fwinitvals_write(struct bwn_mac *, 376 const struct bwn_fwinitvals *, size_t, size_t); 377 static int bwn_switch_channel(struct bwn_mac *, int); 378 static uint16_t bwn_ant2phy(int); 379 static void bwn_mac_write_bssid(struct bwn_mac *); 380 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 381 const uint8_t *); 382 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 383 const uint8_t *, size_t, const uint8_t *); 384 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 385 const uint8_t *); 386 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 387 const uint8_t *); 388 static void bwn_phy_exit(struct bwn_mac *); 389 static void bwn_core_stop(struct bwn_mac *); 390 static int bwn_switch_band(struct bwn_softc *, 391 struct ieee80211_channel *); 392 static void bwn_phy_reset(struct bwn_mac *); 393 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 394 static void bwn_set_pretbtt(struct bwn_mac *); 395 static void bwn_intr(void *); 396 static void bwn_intrtask(void *, int); 397 static void bwn_restart(struct bwn_mac *, const char *); 398 static void bwn_intr_ucode_debug(struct bwn_mac *); 399 static void bwn_intr_tbtt_indication(struct bwn_mac *); 400 static void bwn_intr_atim_end(struct bwn_mac *); 401 static void bwn_intr_beacon(struct bwn_mac *); 402 static void bwn_intr_pmq(struct bwn_mac *); 403 static void bwn_intr_noise(struct bwn_mac *); 404 static void bwn_intr_txeof(struct bwn_mac *); 405 static void bwn_hwreset(void *, int); 406 static void bwn_handle_fwpanic(struct bwn_mac *); 407 static void bwn_load_beacon0(struct bwn_mac *); 408 static void bwn_load_beacon1(struct bwn_mac *); 409 static uint32_t bwn_jssi_read(struct bwn_mac *); 410 static void bwn_noise_gensample(struct bwn_mac *); 411 static void bwn_handle_txeof(struct bwn_mac *, 412 const struct bwn_txstatus *); 413 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 414 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 415 static void bwn_start_locked(struct ifnet *); 416 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 417 struct mbuf *); 418 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 419 static int bwn_set_txhdr(struct bwn_mac *, 420 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 421 uint16_t); 422 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 423 const uint8_t); 424 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 425 static uint8_t bwn_get_fbrate(uint8_t); 426 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 427 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 428 static void bwn_phy_lock(struct bwn_mac *); 429 static void bwn_phy_unlock(struct bwn_mac *); 430 static void bwn_rf_lock(struct bwn_mac *); 431 static void bwn_rf_unlock(struct bwn_mac *); 432 static void bwn_txpwr(void *, int); 433 static void bwn_tasks(void *); 434 static void bwn_task_15s(struct bwn_mac *); 435 static void bwn_task_30s(struct bwn_mac *); 436 static void bwn_task_60s(struct bwn_mac *); 437 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 438 uint8_t); 439 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 440 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 441 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 442 int, int); 443 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 444 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 445 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 446 static void bwn_watchdog(void *); 447 static void bwn_dma_stop(struct bwn_mac *); 448 static void bwn_pio_stop(struct bwn_mac *); 449 static void bwn_dma_ringstop(struct bwn_dma_ring **); 450 static void bwn_led_attach(struct bwn_mac *); 451 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 452 static void bwn_led_event(struct bwn_mac *, int); 453 static void bwn_led_blink_start(struct bwn_mac *, int, int); 454 static void bwn_led_blink_next(void *); 455 static void bwn_led_blink_end(void *); 456 static void bwn_rfswitch(void *); 457 static void bwn_rf_turnon(struct bwn_mac *); 458 static void bwn_rf_turnoff(struct bwn_mac *); 459 static void bwn_phy_lp_init_pre(struct bwn_mac *); 460 static int bwn_phy_lp_init(struct bwn_mac *); 461 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 462 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 463 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 464 uint16_t); 465 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 466 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 467 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 468 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 469 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 470 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 471 static void bwn_phy_lp_task_60s(struct bwn_mac *); 472 static void bwn_phy_lp_readsprom(struct bwn_mac *); 473 static void bwn_phy_lp_bbinit(struct bwn_mac *); 474 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 475 static void bwn_phy_lp_calib(struct bwn_mac *); 476 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 477 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 478 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 479 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 480 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 481 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 482 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 483 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 484 static void bwn_phy_lp_bugfix(struct bwn_mac *); 485 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 486 static void bwn_phy_lp_tblinit(struct bwn_mac *); 487 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 488 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 489 static void bwn_phy_lp_b2062_init(struct bwn_mac *); 490 static void bwn_phy_lp_b2063_init(struct bwn_mac *); 491 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 492 static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 493 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 494 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 495 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 496 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 497 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 498 const void *); 499 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 500 static struct bwn_txgain 501 bwn_phy_lp_get_txgain(struct bwn_mac *); 502 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 503 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 504 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 505 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 506 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 507 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 508 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 509 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 510 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 511 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 512 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 513 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 514 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 515 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 516 static int bwn_phy_lp_loopback(struct bwn_mac *); 517 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 518 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 519 int); 520 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 521 struct bwn_phy_lp_iq_est *); 522 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 523 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 524 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 525 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 526 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 527 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 528 static uint8_t bwn_nbits(int32_t); 529 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 530 struct bwn_txgain_entry *); 531 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 532 struct bwn_txgain_entry); 533 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 534 struct bwn_txgain_entry); 535 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 536 struct bwn_txgain_entry); 537 static void bwn_sysctl_node(struct bwn_softc *); 538 539 static const struct bwn_channelinfo bwn_chantable_bg = { 540 .channels = { 541 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 542 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 543 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 544 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 545 { 2472, 13, 30 }, { 2484, 14, 30 } }, 546 .nchannels = 14 547 }; 548 549 static const struct bwn_channelinfo bwn_chantable_a = { 550 .channels = { 551 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 552 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 553 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 554 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 555 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 556 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 557 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 558 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 559 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 560 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 561 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 562 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 563 { 6080, 216, 30 } }, 564 .nchannels = 37 565 }; 566 567 static const struct bwn_channelinfo bwn_chantable_n = { 568 .channels = { 569 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 570 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 571 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 572 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 573 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 574 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 575 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 576 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 577 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 578 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 579 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 580 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 581 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 582 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 583 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 584 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 585 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 586 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 587 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 588 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 589 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 590 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 591 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 592 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 593 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 594 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 595 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 596 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 597 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 598 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 599 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 600 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 601 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 602 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 603 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 604 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 605 { 6130, 226, 30 }, { 6140, 228, 30 } }, 606 .nchannels = 110 607 }; 608 609 static const uint8_t bwn_b2063_chantable_data[33][12] = { 610 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 611 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 612 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 613 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 614 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 615 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 616 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 617 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 618 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 619 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 620 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 621 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 622 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 623 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 624 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 625 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 626 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 627 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 628 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 629 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 630 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 631 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 632 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 633 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 634 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 635 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 636 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 637 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 638 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 639 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 640 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 641 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 642 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 643 }; 644 645 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 646 { 1, 2412, bwn_b2063_chantable_data[0] }, 647 { 2, 2417, bwn_b2063_chantable_data[0] }, 648 { 3, 2422, bwn_b2063_chantable_data[0] }, 649 { 4, 2427, bwn_b2063_chantable_data[1] }, 650 { 5, 2432, bwn_b2063_chantable_data[1] }, 651 { 6, 2437, bwn_b2063_chantable_data[1] }, 652 { 7, 2442, bwn_b2063_chantable_data[1] }, 653 { 8, 2447, bwn_b2063_chantable_data[1] }, 654 { 9, 2452, bwn_b2063_chantable_data[2] }, 655 { 10, 2457, bwn_b2063_chantable_data[2] }, 656 { 11, 2462, bwn_b2063_chantable_data[3] }, 657 { 12, 2467, bwn_b2063_chantable_data[3] }, 658 { 13, 2472, bwn_b2063_chantable_data[3] }, 659 { 14, 2484, bwn_b2063_chantable_data[4] }, 660 { 34, 5170, bwn_b2063_chantable_data[5] }, 661 { 36, 5180, bwn_b2063_chantable_data[6] }, 662 { 38, 5190, bwn_b2063_chantable_data[7] }, 663 { 40, 5200, bwn_b2063_chantable_data[8] }, 664 { 42, 5210, bwn_b2063_chantable_data[9] }, 665 { 44, 5220, bwn_b2063_chantable_data[10] }, 666 { 46, 5230, bwn_b2063_chantable_data[11] }, 667 { 48, 5240, bwn_b2063_chantable_data[12] }, 668 { 52, 5260, bwn_b2063_chantable_data[13] }, 669 { 56, 5280, bwn_b2063_chantable_data[14] }, 670 { 60, 5300, bwn_b2063_chantable_data[14] }, 671 { 64, 5320, bwn_b2063_chantable_data[15] }, 672 { 100, 5500, bwn_b2063_chantable_data[16] }, 673 { 104, 5520, bwn_b2063_chantable_data[17] }, 674 { 108, 5540, bwn_b2063_chantable_data[18] }, 675 { 112, 5560, bwn_b2063_chantable_data[19] }, 676 { 116, 5580, bwn_b2063_chantable_data[20] }, 677 { 120, 5600, bwn_b2063_chantable_data[21] }, 678 { 124, 5620, bwn_b2063_chantable_data[21] }, 679 { 128, 5640, bwn_b2063_chantable_data[22] }, 680 { 132, 5660, bwn_b2063_chantable_data[22] }, 681 { 136, 5680, bwn_b2063_chantable_data[22] }, 682 { 140, 5700, bwn_b2063_chantable_data[23] }, 683 { 149, 5745, bwn_b2063_chantable_data[23] }, 684 { 153, 5765, bwn_b2063_chantable_data[23] }, 685 { 157, 5785, bwn_b2063_chantable_data[23] }, 686 { 161, 5805, bwn_b2063_chantable_data[23] }, 687 { 165, 5825, bwn_b2063_chantable_data[23] }, 688 { 184, 4920, bwn_b2063_chantable_data[24] }, 689 { 188, 4940, bwn_b2063_chantable_data[25] }, 690 { 192, 4960, bwn_b2063_chantable_data[26] }, 691 { 196, 4980, bwn_b2063_chantable_data[27] }, 692 { 200, 5000, bwn_b2063_chantable_data[28] }, 693 { 204, 5020, bwn_b2063_chantable_data[29] }, 694 { 208, 5040, bwn_b2063_chantable_data[30] }, 695 { 212, 5060, bwn_b2063_chantable_data[31] }, 696 { 216, 5080, bwn_b2063_chantable_data[32] } 697 }; 698 699 static const uint8_t bwn_b2062_chantable_data[22][12] = { 700 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 701 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 702 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 703 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 704 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 705 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 706 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 707 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 708 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 713 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 714 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 715 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 716 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 717 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 718 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 719 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 720 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 721 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 722 }; 723 724 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 725 { 1, 2412, bwn_b2062_chantable_data[0] }, 726 { 2, 2417, bwn_b2062_chantable_data[0] }, 727 { 3, 2422, bwn_b2062_chantable_data[0] }, 728 { 4, 2427, bwn_b2062_chantable_data[0] }, 729 { 5, 2432, bwn_b2062_chantable_data[0] }, 730 { 6, 2437, bwn_b2062_chantable_data[0] }, 731 { 7, 2442, bwn_b2062_chantable_data[0] }, 732 { 8, 2447, bwn_b2062_chantable_data[0] }, 733 { 9, 2452, bwn_b2062_chantable_data[0] }, 734 { 10, 2457, bwn_b2062_chantable_data[0] }, 735 { 11, 2462, bwn_b2062_chantable_data[0] }, 736 { 12, 2467, bwn_b2062_chantable_data[0] }, 737 { 13, 2472, bwn_b2062_chantable_data[0] }, 738 { 14, 2484, bwn_b2062_chantable_data[0] }, 739 { 34, 5170, bwn_b2062_chantable_data[1] }, 740 { 38, 5190, bwn_b2062_chantable_data[2] }, 741 { 42, 5210, bwn_b2062_chantable_data[2] }, 742 { 46, 5230, bwn_b2062_chantable_data[3] }, 743 { 36, 5180, bwn_b2062_chantable_data[4] }, 744 { 40, 5200, bwn_b2062_chantable_data[5] }, 745 { 44, 5220, bwn_b2062_chantable_data[6] }, 746 { 48, 5240, bwn_b2062_chantable_data[3] }, 747 { 52, 5260, bwn_b2062_chantable_data[3] }, 748 { 56, 5280, bwn_b2062_chantable_data[3] }, 749 { 60, 5300, bwn_b2062_chantable_data[7] }, 750 { 64, 5320, bwn_b2062_chantable_data[8] }, 751 { 100, 5500, bwn_b2062_chantable_data[9] }, 752 { 104, 5520, bwn_b2062_chantable_data[10] }, 753 { 108, 5540, bwn_b2062_chantable_data[10] }, 754 { 112, 5560, bwn_b2062_chantable_data[10] }, 755 { 116, 5580, bwn_b2062_chantable_data[11] }, 756 { 120, 5600, bwn_b2062_chantable_data[12] }, 757 { 124, 5620, bwn_b2062_chantable_data[12] }, 758 { 128, 5640, bwn_b2062_chantable_data[12] }, 759 { 132, 5660, bwn_b2062_chantable_data[12] }, 760 { 136, 5680, bwn_b2062_chantable_data[12] }, 761 { 140, 5700, bwn_b2062_chantable_data[12] }, 762 { 149, 5745, bwn_b2062_chantable_data[12] }, 763 { 153, 5765, bwn_b2062_chantable_data[12] }, 764 { 157, 5785, bwn_b2062_chantable_data[12] }, 765 { 161, 5805, bwn_b2062_chantable_data[12] }, 766 { 165, 5825, bwn_b2062_chantable_data[12] }, 767 { 184, 4920, bwn_b2062_chantable_data[13] }, 768 { 188, 4940, bwn_b2062_chantable_data[14] }, 769 { 192, 4960, bwn_b2062_chantable_data[15] }, 770 { 196, 4980, bwn_b2062_chantable_data[16] }, 771 { 200, 5000, bwn_b2062_chantable_data[17] }, 772 { 204, 5020, bwn_b2062_chantable_data[18] }, 773 { 208, 5040, bwn_b2062_chantable_data[19] }, 774 { 212, 5060, bwn_b2062_chantable_data[20] }, 775 { 216, 5080, bwn_b2062_chantable_data[21] } 776 }; 777 778 /* for LP PHY */ 779 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 780 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 781 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 782 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 783 { 13, -66, 13 }, { 14, -66, 13 }, 784 }; 785 786 /* for LP PHY */ 787 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 788 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 789 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 790 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 791 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 792 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 793 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 794 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 795 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 796 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 797 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 798 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 799 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 800 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 801 }; 802 803 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 804 805 static const uint8_t bwn_tab_sigsq_tbl[] = { 806 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 807 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 808 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 809 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 810 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 811 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 812 }; 813 814 static const uint8_t bwn_tab_pllfrac_tbl[] = { 815 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 816 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 817 }; 818 819 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 820 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 821 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 822 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 823 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 824 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 825 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 826 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 827 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 831 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 832 }; 833 834 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 835 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 836 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 837 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 838 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 839 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 840 841 #define VENDOR_LED_ACT(vendor) \ 842 { \ 843 .vid = PCI_VENDOR_##vendor, \ 844 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 845 } 846 847 static const struct { 848 uint16_t vid; 849 uint8_t led_act[BWN_LED_MAX]; 850 } bwn_vendor_led_act[] = { 851 VENDOR_LED_ACT(COMPAQ), 852 VENDOR_LED_ACT(ASUSTEK) 853 }; 854 855 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 856 { BWN_VENDOR_LED_ACT_DEFAULT }; 857 858 #undef VENDOR_LED_ACT 859 860 static const struct { 861 int on_dur; 862 int off_dur; 863 } bwn_led_duration[109] = { 864 [0] = { 400, 100 }, 865 [2] = { 150, 75 }, 866 [4] = { 90, 45 }, 867 [11] = { 66, 34 }, 868 [12] = { 53, 26 }, 869 [18] = { 42, 21 }, 870 [22] = { 35, 17 }, 871 [24] = { 32, 16 }, 872 [36] = { 21, 10 }, 873 [48] = { 16, 8 }, 874 [72] = { 11, 5 }, 875 [96] = { 9, 4 }, 876 [108] = { 7, 3 } 877 }; 878 879 static const uint16_t bwn_wme_shm_offsets[] = { 880 [0] = BWN_WME_BESTEFFORT, 881 [1] = BWN_WME_BACKGROUND, 882 [2] = BWN_WME_VOICE, 883 [3] = BWN_WME_VIDEO, 884 }; 885 886 static const struct siba_devid bwn_devs[] = { 887 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 888 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 889 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 890 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 891 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 892 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 893 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 894 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 895 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 896 }; 897 898 static int 899 bwn_probe(device_t dev) 900 { 901 int i; 902 903 wlan_serialize_enter(); 904 905 for (i = 0; i < NELEM(bwn_devs); i++) { 906 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 907 siba_get_device(dev) == bwn_devs[i].sd_device && 908 siba_get_revid(dev) == bwn_devs[i].sd_rev) { 909 wlan_serialize_exit(); 910 return (BUS_PROBE_DEFAULT); 911 } 912 } 913 wlan_serialize_exit(); 914 return (ENXIO); 915 } 916 917 static int 918 bwn_attach(device_t dev) 919 { 920 struct bwn_mac *mac; 921 struct bwn_softc *sc = device_get_softc(dev); 922 int error; 923 u_int irq_flags; 924 925 wlan_serialize_enter(); 926 927 sc->sc_dev = dev; 928 #ifdef BWN_DEBUG 929 sc->sc_debug = bwn_debug; 930 #endif 931 932 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 933 error = bwn_attach_pre(sc); 934 if (error != 0) { 935 wlan_serialize_exit(); 936 return (error); 937 } 938 bwn_sprom_bugfixes(dev); 939 sc->sc_flags |= BWN_FLAG_ATTACHED; 940 } 941 942 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 943 if (siba_get_pci_device(dev) != 0x4313 && 944 siba_get_pci_device(dev) != 0x431a && 945 siba_get_pci_device(dev) != 0x4321) { 946 device_printf(sc->sc_dev, 947 "skip 802.11 cores\n"); 948 wlan_serialize_exit(); 949 return (ENODEV); 950 } 951 } 952 953 mac = (struct bwn_mac *)kmalloc(sizeof(*mac), M_DEVBUF, 954 M_INTWAIT | M_ZERO); 955 mac->mac_sc = sc; 956 mac->mac_status = BWN_MAC_STATUS_UNINIT; 957 if (bwn_bfp != 0) 958 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 959 960 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 961 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 962 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 963 964 error = bwn_attach_core(mac); 965 if (error) 966 goto fail0; 967 bwn_led_attach(mac); 968 969 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 970 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 971 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 972 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 973 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 974 mac->mac_phy.rf_rev); 975 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 976 device_printf(sc->sc_dev, "DMA (%d bits)\n", 977 mac->mac_method.dma.dmatype); 978 else 979 device_printf(sc->sc_dev, "PIO\n"); 980 981 /* Allocate IRQ resource. */ 982 sc->bwn_irq_rid = 0; 983 sc->bwn_irq_type = pci_alloc_1intr(sc->sc_dev, bwn_msi_enable, 984 &sc->bwn_irq_rid, &irq_flags); 985 if ((sc->bwn_irq = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ, 986 &sc->bwn_irq_rid, irq_flags)) == NULL) { 987 device_printf(sc->sc_dev, "Cannot allocate interrupt\n"); 988 error = EINVAL; 989 goto fail1; 990 } 991 if ((error = bus_setup_intr(sc->sc_dev, sc->bwn_irq, INTR_MPSAFE, 992 bwn_intr, mac, &sc->bwn_intr, &wlan_global_serializer)) != 0) { 993 device_printf(sc->sc_dev, "Cannot set up interrupt\n"); 994 goto fail1; 995 } 996 997 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 998 999 /* 1000 * calls attach-post routine 1001 */ 1002 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1003 bwn_attach_post(sc); 1004 1005 wlan_serialize_exit(); 1006 return (0); 1007 fail1: 1008 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI) 1009 pci_release_msi(dev); 1010 fail0: 1011 kfree(mac, M_DEVBUF); 1012 wlan_serialize_exit(); 1013 return (error); 1014 } 1015 1016 static int 1017 bwn_is_valid_ether_addr(uint8_t *addr) 1018 { 1019 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1020 1021 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1022 return (FALSE); 1023 1024 return (TRUE); 1025 } 1026 1027 static int 1028 bwn_attach_post(struct bwn_softc *sc) 1029 { 1030 struct ieee80211com *ic; 1031 struct ifnet *ifp = sc->sc_ifp; 1032 1033 ic = ifp->if_l2com; 1034 ic->ic_ifp = ifp; 1035 ic->ic_softc = sc; 1036 ic->ic_name = device_get_nameunit(sc->sc_dev); 1037 /* XXX not right but it's not used anywhere important */ 1038 ic->ic_phytype = IEEE80211_T_OFDM; 1039 ic->ic_opmode = IEEE80211_M_STA; 1040 ic->ic_caps = 1041 IEEE80211_C_STA /* station mode supported */ 1042 | IEEE80211_C_MONITOR /* monitor mode */ 1043 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1044 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1045 | IEEE80211_C_SHSLOT /* short slot time supported */ 1046 | IEEE80211_C_WME /* WME/WMM supported */ 1047 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1048 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1049 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1050 ; 1051 1052 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1053 1054 /* call MI attach routine. */ 1055 ieee80211_ifattach(ic, 1056 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1057 siba_sprom_get_mac_80211a(sc->sc_dev) : 1058 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1059 1060 ic->ic_headroom = sizeof(struct bwn_txhdr); 1061 1062 /* override default methods */ 1063 ic->ic_raw_xmit = bwn_raw_xmit; 1064 ic->ic_updateslot = bwn_updateslot; 1065 ic->ic_update_promisc = bwn_update_promisc; 1066 ic->ic_wme.wme_update = bwn_wme_update; 1067 1068 ic->ic_scan_start = bwn_scan_start; 1069 ic->ic_scan_end = bwn_scan_end; 1070 ic->ic_set_channel = bwn_set_channel; 1071 1072 ic->ic_vap_create = bwn_vap_create; 1073 ic->ic_vap_delete = bwn_vap_delete; 1074 1075 ieee80211_radiotap_attach(ic, 1076 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1077 BWN_TX_RADIOTAP_PRESENT, 1078 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1079 BWN_RX_RADIOTAP_PRESENT); 1080 1081 bwn_sysctl_node(sc); 1082 1083 if (bootverbose) 1084 ieee80211_announce(ic); 1085 return (0); 1086 } 1087 1088 static void 1089 bwn_phy_detach(struct bwn_mac *mac) 1090 { 1091 1092 if (mac->mac_phy.detach != NULL) 1093 mac->mac_phy.detach(mac); 1094 } 1095 1096 static int 1097 bwn_detach(device_t dev) 1098 { 1099 struct bwn_softc *sc = device_get_softc(dev); 1100 struct bwn_mac *mac = sc->sc_curmac; 1101 struct ifnet *ifp = sc->sc_ifp; 1102 struct ieee80211com *ic = ifp->if_l2com; 1103 1104 wlan_serialize_enter(); 1105 1106 sc->sc_flags |= BWN_FLAG_INVALID; 1107 1108 if (device_is_attached(sc->sc_dev)) { 1109 bwn_stop(sc, 1); 1110 bwn_dma_free(mac); 1111 callout_stop_sync(&sc->sc_led_blink_ch); 1112 callout_stop_sync(&sc->sc_rfswitch_ch); 1113 callout_stop_sync(&sc->sc_task_ch); 1114 callout_stop_sync(&sc->sc_watchdog_ch); 1115 bwn_phy_detach(mac); 1116 if (ifp != NULL) { 1117 wlan_serialize_exit(); 1118 ieee80211_draintask(ic, &mac->mac_hwreset); 1119 ieee80211_draintask(ic, &mac->mac_txpower); 1120 wlan_serialize_enter(); 1121 ieee80211_ifdetach(ic); 1122 if_free(ifp); 1123 } 1124 } 1125 wlan_serialize_exit(); 1126 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1127 taskqueue_free(sc->sc_tq); 1128 wlan_serialize_enter(); 1129 1130 if (sc->bwn_intr) 1131 bus_teardown_intr(dev, sc->bwn_irq, sc->bwn_intr); 1132 if (sc->bwn_irq != NULL) 1133 bus_release_resource(dev, SYS_RES_IRQ, sc->bwn_irq_rid, 1134 sc->bwn_irq); 1135 1136 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI) 1137 pci_release_msi(dev); 1138 1139 wlan_serialize_exit(); 1140 return (0); 1141 } 1142 1143 static int 1144 bwn_attach_pre(struct bwn_softc *sc) 1145 { 1146 struct ifnet *ifp; 1147 int error = 0; 1148 1149 TAILQ_INIT(&sc->sc_maclist); 1150 callout_init(&sc->sc_rfswitch_ch); 1151 callout_init(&sc->sc_task_ch); 1152 callout_init(&sc->sc_watchdog_ch); 1153 1154 sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK, 1155 taskqueue_thread_enqueue, &sc->sc_tq); 1156 taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1, 1157 "%s taskq", device_get_nameunit(sc->sc_dev)); 1158 1159 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1160 if (ifp == NULL) { 1161 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1162 error = ENOSPC; 1163 goto fail; 1164 } 1165 1166 /* set these up early for if_printf use */ 1167 if_initname(ifp, device_get_name(sc->sc_dev), 1168 device_get_unit(sc->sc_dev)); 1169 1170 ifp->if_softc = sc; 1171 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1172 ifp->if_init = bwn_init; 1173 ifp->if_ioctl = bwn_ioctl; 1174 ifp->if_start = bwn_start; 1175 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); 1176 1177 return (0); 1178 1179 fail: 1180 return (error); 1181 } 1182 1183 static void 1184 bwn_sprom_bugfixes(device_t dev) 1185 { 1186 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1187 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1188 (siba_get_pci_device(dev) == _device) && \ 1189 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1190 (siba_get_pci_subdevice(dev) == _subdevice)) 1191 1192 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1193 siba_get_pci_subdevice(dev) == 0x4e && 1194 siba_get_pci_revid(dev) > 0x40) 1195 siba_sprom_set_bf_lo(dev, 1196 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1197 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1198 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1199 siba_sprom_set_bf_lo(dev, 1200 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1201 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1202 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1203 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1204 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1205 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1206 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1207 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1208 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1209 siba_sprom_set_bf_lo(dev, 1210 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1211 } 1212 #undef BWN_ISDEV 1213 } 1214 1215 static int 1216 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, 1217 struct ucred *cr __unused) 1218 { 1219 #define IS_RUNNING(ifp) \ 1220 ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING)) 1221 struct bwn_softc *sc = ifp->if_softc; 1222 struct ieee80211com *ic = ifp->if_l2com; 1223 struct ifreq *ifr = (struct ifreq *)data; 1224 int error = 0; 1225 1226 switch (cmd) { 1227 case SIOCSIFFLAGS: 1228 if (IS_RUNNING(ifp)) { 1229 bwn_update_promisc(ic); 1230 } else if (ifp->if_flags & IFF_UP) { 1231 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1232 bwn_init(sc); 1233 } 1234 } else 1235 bwn_stop(sc, 1); 1236 break; 1237 case SIOCGIFMEDIA: 1238 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1239 break; 1240 case SIOCGIFADDR: 1241 error = ether_ioctl(ifp, cmd, data); 1242 break; 1243 default: 1244 error = EINVAL; 1245 break; 1246 } 1247 return (error); 1248 } 1249 1250 static void 1251 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) 1252 { 1253 wlan_assert_serialized(); 1254 bwn_start_locked(ifp); 1255 } 1256 1257 static void 1258 bwn_start_locked(struct ifnet *ifp) 1259 { 1260 struct bwn_softc *sc = ifp->if_softc; 1261 struct bwn_mac *mac = sc->sc_curmac; 1262 struct ieee80211_frame *wh; 1263 struct ieee80211_node *ni; 1264 struct ieee80211_key *k; 1265 struct mbuf *m; 1266 1267 wlan_assert_serialized(); 1268 1269 if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL || 1270 mac->mac_status < BWN_MAC_STATUS_STARTED) 1271 return; 1272 1273 for (;;) { 1274 m = ifq_dequeue(&ifp->if_snd); /* XXX: LOCK */ 1275 if (m == NULL) 1276 break; 1277 1278 if (bwn_tx_isfull(sc, m)) 1279 break; 1280 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1281 if (ni == NULL) { 1282 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1283 m_freem(m); 1284 ifp->if_oerrors++; 1285 continue; 1286 } 1287 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1288 wh = mtod(m, struct ieee80211_frame *); 1289 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1290 k = ieee80211_crypto_encap(ni, m); 1291 if (k == NULL) { 1292 ieee80211_free_node(ni); 1293 m_freem(m); 1294 ifp->if_oerrors++; 1295 continue; 1296 } 1297 } 1298 wh = NULL; /* Catch any invalid use */ 1299 1300 if (bwn_tx_start(sc, ni, m) != 0) { 1301 if (ni != NULL) 1302 ieee80211_free_node(ni); 1303 ifp->if_oerrors++; 1304 continue; 1305 } 1306 1307 sc->sc_watchdog_timer = 5; 1308 } 1309 } 1310 1311 static int 1312 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1313 { 1314 struct bwn_dma_ring *dr; 1315 struct bwn_mac *mac = sc->sc_curmac; 1316 struct bwn_pio_txqueue *tq; 1317 struct ifnet *ifp = sc->sc_ifp; 1318 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1319 1320 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1321 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1322 if (dr->dr_stop == 1 || 1323 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1324 dr->dr_stop = 1; 1325 goto full; 1326 } 1327 } else { 1328 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1329 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1330 pktlen > (tq->tq_size - tq->tq_used)) { 1331 tq->tq_stop = 1; 1332 goto full; 1333 } 1334 } 1335 return (0); 1336 full: 1337 ifq_prepend(&ifp->if_snd, m); 1338 ifq_set_oactive(&ifp->if_snd); 1339 return (1); 1340 } 1341 1342 static int 1343 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1344 { 1345 struct bwn_mac *mac = sc->sc_curmac; 1346 int error; 1347 1348 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1349 m_freem(m); 1350 return (ENXIO); 1351 } 1352 1353 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1354 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1355 if (error) { 1356 m_freem(m); 1357 return (error); 1358 } 1359 return (0); 1360 } 1361 1362 static int 1363 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1364 { 1365 struct bwn_pio_txpkt *tp; 1366 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1367 struct bwn_softc *sc = mac->mac_sc; 1368 struct bwn_txhdr txhdr; 1369 struct mbuf *m_new; 1370 uint32_t ctl32; 1371 int error; 1372 uint16_t ctl16; 1373 1374 /* XXX TODO send packets after DTIM */ 1375 1376 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1377 tp = TAILQ_FIRST(&tq->tq_pktlist); 1378 tp->tp_ni = ni; 1379 tp->tp_m = m; 1380 1381 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1382 if (error) { 1383 device_printf(sc->sc_dev, "tx fail\n"); 1384 return (error); 1385 } 1386 1387 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1388 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1389 tq->tq_free--; 1390 1391 if (siba_get_revid(sc->sc_dev) >= 8) { 1392 /* 1393 * XXX please removes m_defrag(9) 1394 */ 1395 m_new = m_defrag(m, M_NOWAIT); 1396 if (m_new == NULL) { 1397 device_printf(sc->sc_dev, 1398 "%s: can't defrag TX buffer\n", 1399 __func__); 1400 return (ENOBUFS); 1401 } 1402 if (m_new->m_next != NULL) 1403 device_printf(sc->sc_dev, 1404 "TODO: fragmented packets for PIO\n"); 1405 tp->tp_m = m_new; 1406 1407 /* send HEADER */ 1408 ctl32 = bwn_pio_write_multi_4(mac, tq, 1409 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1410 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1411 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1412 /* send BODY */ 1413 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1414 mtod(m_new, const void *), m_new->m_pkthdr.len); 1415 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1416 ctl32 | BWN_PIO8_TXCTL_EOF); 1417 } else { 1418 ctl16 = bwn_pio_write_multi_2(mac, tq, 1419 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1420 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1421 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1422 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1423 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1424 ctl16 | BWN_PIO_TXCTL_EOF); 1425 } 1426 1427 return (0); 1428 } 1429 1430 static struct bwn_pio_txqueue * 1431 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1432 { 1433 1434 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1435 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1436 1437 switch (prio) { 1438 case 0: 1439 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1440 case 1: 1441 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1442 case 2: 1443 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1444 case 3: 1445 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1446 } 1447 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1448 return (NULL); 1449 } 1450 1451 static int 1452 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1453 { 1454 #define BWN_GET_TXHDRCACHE(slot) \ 1455 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)]) 1456 struct bwn_dma *dma = &mac->mac_method.dma; 1457 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1458 struct bwn_dmadesc_generic *desc; 1459 struct bwn_dmadesc_meta *mt; 1460 struct bwn_softc *sc = mac->mac_sc; 1461 struct ifnet *ifp = sc->sc_ifp; 1462 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1463 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1464 1465 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1466 1467 /* XXX send after DTIM */ 1468 1469 slot = bwn_dma_getslot(dr); 1470 dr->getdesc(dr, slot, &desc, &mt); 1471 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1472 ("%s:%d: fail", __func__, __LINE__)); 1473 1474 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1475 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1476 BWN_DMA_COOKIE(dr, slot)); 1477 if (error) 1478 goto fail; 1479 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1480 BUS_DMASYNC_PREWRITE); 1481 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1482 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1483 BUS_DMASYNC_PREWRITE); 1484 1485 slot = bwn_dma_getslot(dr); 1486 dr->getdesc(dr, slot, &desc, &mt); 1487 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1488 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1489 mt->mt_m = m; 1490 mt->mt_ni = ni; 1491 1492 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1493 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1494 if (error && error != EFBIG) { 1495 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1496 __func__, error); 1497 goto fail; 1498 } 1499 if (error) { /* error == EFBIG */ 1500 struct mbuf *m_new; 1501 1502 m_new = m_defrag(m, M_NOWAIT); 1503 if (m_new == NULL) { 1504 if_printf(ifp, "%s: can't defrag TX buffer\n", 1505 __func__); 1506 error = ENOBUFS; 1507 goto fail; 1508 } else { 1509 m = m_new; 1510 } 1511 1512 mt->mt_m = m; 1513 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1514 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1515 if (error) { 1516 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1517 __func__, error); 1518 goto fail; 1519 } 1520 } 1521 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1522 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1523 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1524 BUS_DMASYNC_PREWRITE); 1525 1526 /* XXX send after DTIM */ 1527 1528 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1529 return (0); 1530 fail: 1531 dr->dr_curslot = backup[0]; 1532 dr->dr_usedslot = backup[1]; 1533 return (error); 1534 #undef BWN_GET_TXHDRCACHE 1535 } 1536 1537 static void 1538 bwn_watchdog(void *arg) 1539 { 1540 struct bwn_softc *sc = arg; 1541 struct ifnet *ifp = sc->sc_ifp; 1542 1543 wlan_serialize_enter(); 1544 1545 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1546 if_printf(ifp, "device timeout\n"); 1547 ifp->if_oerrors++; 1548 } 1549 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 1550 wlan_serialize_exit(); 1551 } 1552 1553 static int 1554 bwn_attach_core(struct bwn_mac *mac) 1555 { 1556 struct bwn_softc *sc = mac->mac_sc; 1557 int error, have_bg = 0, have_a = 0; 1558 uint32_t high; 1559 1560 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1561 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1562 1563 siba_powerup(sc->sc_dev, 0); 1564 1565 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1566 bwn_reset_core(mac, 1567 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1568 error = bwn_phy_getinfo(mac, high); 1569 if (error) 1570 goto fail; 1571 1572 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1573 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1574 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1575 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1576 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1577 have_a = have_bg = 0; 1578 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1579 have_a = 1; 1580 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1581 mac->mac_phy.type == BWN_PHYTYPE_N || 1582 mac->mac_phy.type == BWN_PHYTYPE_LP) 1583 have_bg = 1; 1584 else 1585 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1586 mac->mac_phy.type)); 1587 } 1588 /* XXX turns off PHY A because it's not supported */ 1589 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1590 mac->mac_phy.type != BWN_PHYTYPE_N) { 1591 have_a = 0; 1592 have_bg = 1; 1593 } 1594 1595 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1596 mac->mac_phy.attach = bwn_phy_g_attach; 1597 mac->mac_phy.detach = bwn_phy_g_detach; 1598 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1599 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1600 mac->mac_phy.init = bwn_phy_g_init; 1601 mac->mac_phy.exit = bwn_phy_g_exit; 1602 mac->mac_phy.phy_read = bwn_phy_g_read; 1603 mac->mac_phy.phy_write = bwn_phy_g_write; 1604 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1605 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1606 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1607 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1608 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1609 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1610 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1611 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1612 mac->mac_phy.set_im = bwn_phy_g_im; 1613 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1614 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1615 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1616 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1617 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1618 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1619 mac->mac_phy.init = bwn_phy_lp_init; 1620 mac->mac_phy.phy_read = bwn_phy_lp_read; 1621 mac->mac_phy.phy_write = bwn_phy_lp_write; 1622 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1623 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1624 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1625 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1626 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1627 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1628 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1629 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1630 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1631 } else { 1632 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1633 mac->mac_phy.type); 1634 error = ENXIO; 1635 goto fail; 1636 } 1637 1638 mac->mac_phy.gmode = have_bg; 1639 if (mac->mac_phy.attach != NULL) { 1640 error = mac->mac_phy.attach(mac); 1641 if (error) { 1642 device_printf(sc->sc_dev, "failed\n"); 1643 goto fail; 1644 } 1645 } 1646 1647 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1648 1649 error = bwn_chiptest(mac); 1650 if (error) 1651 goto fail; 1652 error = bwn_setup_channels(mac, have_bg, have_a); 1653 if (error) { 1654 device_printf(sc->sc_dev, "failed to setup channels\n"); 1655 goto fail; 1656 } 1657 1658 if (sc->sc_curmac == NULL) 1659 sc->sc_curmac = mac; 1660 1661 wlan_assert_serialized(); 1662 wlan_serialize_exit(); 1663 error = bwn_dma_attach(mac); 1664 wlan_serialize_enter(); 1665 if (error != 0) { 1666 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1667 goto fail; 1668 } 1669 1670 mac->mac_phy.switch_analog(mac, 0); 1671 1672 siba_dev_down(sc->sc_dev, 0); 1673 fail: 1674 siba_powerdown(sc->sc_dev); 1675 return (error); 1676 } 1677 1678 static void 1679 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1680 { 1681 struct bwn_softc *sc = mac->mac_sc; 1682 uint32_t low, ctl; 1683 1684 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1685 1686 siba_dev_up(sc->sc_dev, flags); 1687 DELAY(2000); 1688 1689 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1690 ~BWN_TGSLOW_PHYRESET; 1691 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1692 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1693 DELAY(1000); 1694 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1695 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1696 DELAY(1000); 1697 1698 if (mac->mac_phy.switch_analog != NULL) 1699 mac->mac_phy.switch_analog(mac, 1); 1700 1701 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1702 if (flags & BWN_TGSLOW_SUPPORT_G) 1703 ctl |= BWN_MACCTL_GMODE; 1704 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1705 } 1706 1707 static int 1708 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1709 { 1710 struct bwn_phy *phy = &mac->mac_phy; 1711 struct bwn_softc *sc = mac->mac_sc; 1712 uint32_t tmp; 1713 1714 /* PHY */ 1715 tmp = BWN_READ_2(mac, BWN_PHYVER); 1716 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1717 phy->rf_on = 1; 1718 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1719 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1720 phy->rev = (tmp & BWN_PHYVER_VERSION); 1721 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1722 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1723 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1724 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1725 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1726 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1727 goto unsupphy; 1728 1729 /* RADIO */ 1730 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1731 if (siba_get_chiprev(sc->sc_dev) == 0) 1732 tmp = 0x3205017f; 1733 else if (siba_get_chiprev(sc->sc_dev) == 1) 1734 tmp = 0x4205017f; 1735 else 1736 tmp = 0x5205017f; 1737 } else { 1738 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1739 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1740 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1741 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1742 } 1743 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1744 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1745 phy->rf_manuf = (tmp & 0x00000fff); 1746 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1747 goto unsupradio; 1748 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1749 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1750 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1751 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1752 (phy->type == BWN_PHYTYPE_N && 1753 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1754 (phy->type == BWN_PHYTYPE_LP && 1755 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1756 goto unsupradio; 1757 1758 return (0); 1759 unsupphy: 1760 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1761 "analog %#x)\n", 1762 phy->type, phy->rev, phy->analog); 1763 return (ENXIO); 1764 unsupradio: 1765 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1766 "rev %#x)\n", 1767 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1768 return (ENXIO); 1769 } 1770 1771 static int 1772 bwn_chiptest(struct bwn_mac *mac) 1773 { 1774 #define TESTVAL0 0x55aaaa55 1775 #define TESTVAL1 0xaa5555aa 1776 struct bwn_softc *sc = mac->mac_sc; 1777 uint32_t v, backup; 1778 1779 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1780 1781 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1782 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1783 goto error; 1784 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1785 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1786 goto error; 1787 1788 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1789 1790 if ((siba_get_revid(sc->sc_dev) >= 3) && 1791 (siba_get_revid(sc->sc_dev) <= 10)) { 1792 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1793 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1794 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1795 goto error; 1796 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1797 goto error; 1798 } 1799 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1800 1801 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1802 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1803 goto error; 1804 1805 return (0); 1806 error: 1807 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1808 return (ENODEV); 1809 } 1810 1811 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1812 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1813 1814 static int 1815 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1816 { 1817 struct bwn_softc *sc = mac->mac_sc; 1818 struct ifnet *ifp = sc->sc_ifp; 1819 struct ieee80211com *ic = ifp->if_l2com; 1820 1821 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1822 ic->ic_nchans = 0; 1823 1824 if (have_bg) 1825 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1826 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1827 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1828 if (have_a) 1829 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1830 &ic->ic_nchans, &bwn_chantable_n, 1831 IEEE80211_CHAN_HTA); 1832 } else { 1833 if (have_a) 1834 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1835 &ic->ic_nchans, &bwn_chantable_a, 1836 IEEE80211_CHAN_A); 1837 } 1838 1839 mac->mac_phy.supports_2ghz = have_bg; 1840 mac->mac_phy.supports_5ghz = have_a; 1841 1842 return (ic->ic_nchans == 0 ? ENXIO : 0); 1843 } 1844 1845 static uint32_t 1846 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1847 { 1848 uint32_t ret; 1849 1850 if (way == BWN_SHARED) { 1851 KASSERT((offset & 0x0001) == 0, 1852 ("%s:%d warn", __func__, __LINE__)); 1853 if (offset & 0x0003) { 1854 bwn_shm_ctlword(mac, way, offset >> 2); 1855 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1856 ret <<= 16; 1857 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1858 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1859 goto out; 1860 } 1861 offset >>= 2; 1862 } 1863 bwn_shm_ctlword(mac, way, offset); 1864 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1865 out: 1866 return (ret); 1867 } 1868 1869 static uint16_t 1870 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1871 { 1872 uint16_t ret; 1873 1874 if (way == BWN_SHARED) { 1875 KASSERT((offset & 0x0001) == 0, 1876 ("%s:%d warn", __func__, __LINE__)); 1877 if (offset & 0x0003) { 1878 bwn_shm_ctlword(mac, way, offset >> 2); 1879 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1880 goto out; 1881 } 1882 offset >>= 2; 1883 } 1884 bwn_shm_ctlword(mac, way, offset); 1885 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1886 out: 1887 1888 return (ret); 1889 } 1890 1891 static void 1892 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1893 uint16_t offset) 1894 { 1895 uint32_t control; 1896 1897 control = way; 1898 control <<= 16; 1899 control |= offset; 1900 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1901 } 1902 1903 static void 1904 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1905 uint32_t value) 1906 { 1907 if (way == BWN_SHARED) { 1908 KASSERT((offset & 0x0001) == 0, 1909 ("%s:%d warn", __func__, __LINE__)); 1910 if (offset & 0x0003) { 1911 bwn_shm_ctlword(mac, way, offset >> 2); 1912 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1913 (value >> 16) & 0xffff); 1914 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1915 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1916 return; 1917 } 1918 offset >>= 2; 1919 } 1920 bwn_shm_ctlword(mac, way, offset); 1921 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1922 } 1923 1924 static void 1925 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1926 uint16_t value) 1927 { 1928 if (way == BWN_SHARED) { 1929 KASSERT((offset & 0x0001) == 0, 1930 ("%s:%d warn", __func__, __LINE__)); 1931 if (offset & 0x0003) { 1932 bwn_shm_ctlword(mac, way, offset >> 2); 1933 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1934 return; 1935 } 1936 offset >>= 2; 1937 } 1938 bwn_shm_ctlword(mac, way, offset); 1939 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1940 } 1941 1942 static void 1943 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1944 int txpow) 1945 { 1946 1947 c->ic_freq = freq; 1948 c->ic_flags = flags; 1949 c->ic_ieee = ieee; 1950 c->ic_minpower = 0; 1951 c->ic_maxpower = 2 * txpow; 1952 c->ic_maxregpower = txpow; 1953 } 1954 1955 static void 1956 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 1957 const struct bwn_channelinfo *ci, int flags) 1958 { 1959 struct ieee80211_channel *c; 1960 int i; 1961 1962 c = &chans[*nchans]; 1963 1964 for (i = 0; i < ci->nchannels; i++) { 1965 const struct bwn_channel *hc; 1966 1967 hc = &ci->channels[i]; 1968 if (*nchans >= maxchans) 1969 break; 1970 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 1971 c++, (*nchans)++; 1972 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 1973 /* g channel have a separate b-only entry */ 1974 if (*nchans >= maxchans) 1975 break; 1976 c[0] = c[-1]; 1977 c[-1].ic_flags = IEEE80211_CHAN_B; 1978 c++, (*nchans)++; 1979 } 1980 if (flags == IEEE80211_CHAN_HTG) { 1981 /* HT g channel have a separate g-only entry */ 1982 if (*nchans >= maxchans) 1983 break; 1984 c[-1].ic_flags = IEEE80211_CHAN_G; 1985 c[0] = c[-1]; 1986 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1987 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1988 c++, (*nchans)++; 1989 } 1990 if (flags == IEEE80211_CHAN_HTA) { 1991 /* HT a channel have a separate a-only entry */ 1992 if (*nchans >= maxchans) 1993 break; 1994 c[-1].ic_flags = IEEE80211_CHAN_A; 1995 c[0] = c[-1]; 1996 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1997 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1998 c++, (*nchans)++; 1999 } 2000 } 2001 } 2002 2003 static int 2004 bwn_phy_g_attach(struct bwn_mac *mac) 2005 { 2006 struct bwn_softc *sc = mac->mac_sc; 2007 struct bwn_phy *phy = &mac->mac_phy; 2008 struct bwn_phy_g *pg = &phy->phy_g; 2009 unsigned int i; 2010 int16_t pab0, pab1, pab2; 2011 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2012 int8_t bg; 2013 2014 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2015 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2016 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2017 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2018 2019 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2020 device_printf(sc->sc_dev, "not supported anymore\n"); 2021 2022 pg->pg_flags = 0; 2023 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2024 pab2 == -1) { 2025 pg->pg_idletssi = 52; 2026 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2027 return (0); 2028 } 2029 2030 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2031 pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO); 2032 for (i = 0; i < 64; i++) { 2033 int32_t m1, m2, f, q, delta; 2034 int8_t j = 0; 2035 2036 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2037 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2038 f = 256; 2039 2040 do { 2041 if (j > 15) { 2042 device_printf(sc->sc_dev, 2043 "failed to generate tssi2dBm\n"); 2044 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2045 return (ENOMEM); 2046 } 2047 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2048 f, 2048); 2049 delta = abs(q - f); 2050 f = q; 2051 j++; 2052 } while (delta >= 2); 2053 2054 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2055 128); 2056 } 2057 2058 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2059 return (0); 2060 } 2061 2062 static void 2063 bwn_phy_g_detach(struct bwn_mac *mac) 2064 { 2065 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2066 2067 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2068 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2069 pg->pg_tssi2dbm = NULL; 2070 } 2071 pg->pg_flags = 0; 2072 } 2073 2074 static void 2075 bwn_phy_g_init_pre(struct bwn_mac *mac) 2076 { 2077 struct bwn_phy *phy = &mac->mac_phy; 2078 struct bwn_phy_g *pg = &phy->phy_g; 2079 void *tssi2dbm; 2080 int idletssi; 2081 unsigned int i; 2082 2083 tssi2dbm = pg->pg_tssi2dbm; 2084 idletssi = pg->pg_idletssi; 2085 2086 memset(pg, 0, sizeof(*pg)); 2087 2088 pg->pg_tssi2dbm = tssi2dbm; 2089 pg->pg_idletssi = idletssi; 2090 2091 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2092 2093 for (i = 0; i < N(pg->pg_nrssi); i++) 2094 pg->pg_nrssi[i] = -1000; 2095 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2096 pg->pg_nrssi_lt[i] = i; 2097 pg->pg_lofcal = 0xffff; 2098 pg->pg_initval = 0xffff; 2099 pg->pg_immode = BWN_IMMODE_NONE; 2100 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2101 pg->pg_avgtssi = 0xff; 2102 2103 pg->pg_loctl.tx_bias = 0xff; 2104 TAILQ_INIT(&pg->pg_loctl.calib_list); 2105 } 2106 2107 static int 2108 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2109 { 2110 struct bwn_phy *phy = &mac->mac_phy; 2111 struct bwn_phy_g *pg = &phy->phy_g; 2112 struct bwn_softc *sc = mac->mac_sc; 2113 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2114 static const struct bwn_rfatt rfatt0[] = { 2115 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2116 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2117 { 3, 1 }, { 4, 1 } 2118 }; 2119 static const struct bwn_rfatt rfatt1[] = { 2120 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2121 { 14, 1 } 2122 }; 2123 static const struct bwn_rfatt rfatt2[] = { 2124 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2125 { 9, 1 } 2126 }; 2127 static const struct bwn_bbatt bbatt_0[] = { 2128 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2129 }; 2130 2131 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2132 2133 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2134 pg->pg_bbatt.att = 0; 2135 else 2136 pg->pg_bbatt.att = 2; 2137 2138 /* prepare Radio Attenuation */ 2139 pg->pg_rfatt.padmix = 0; 2140 2141 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2142 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2143 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2144 pg->pg_rfatt.att = 2; 2145 goto done; 2146 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2147 pg->pg_rfatt.att = 3; 2148 goto done; 2149 } 2150 } 2151 2152 if (phy->type == BWN_PHYTYPE_A) { 2153 pg->pg_rfatt.att = 0x60; 2154 goto done; 2155 } 2156 2157 switch (phy->rf_ver) { 2158 case 0x2050: 2159 switch (phy->rf_rev) { 2160 case 0: 2161 pg->pg_rfatt.att = 5; 2162 goto done; 2163 case 1: 2164 if (phy->type == BWN_PHYTYPE_G) { 2165 if (siba_get_pci_subvendor(sc->sc_dev) == 2166 SIBA_BOARDVENDOR_BCM && 2167 siba_get_pci_subdevice(sc->sc_dev) == 2168 SIBA_BOARD_BCM4309G && 2169 siba_get_pci_revid(sc->sc_dev) >= 30) 2170 pg->pg_rfatt.att = 3; 2171 else if (siba_get_pci_subvendor(sc->sc_dev) == 2172 SIBA_BOARDVENDOR_BCM && 2173 siba_get_pci_subdevice(sc->sc_dev) == 2174 SIBA_BOARD_BU4306) 2175 pg->pg_rfatt.att = 3; 2176 else 2177 pg->pg_rfatt.att = 1; 2178 } else { 2179 if (siba_get_pci_subvendor(sc->sc_dev) == 2180 SIBA_BOARDVENDOR_BCM && 2181 siba_get_pci_subdevice(sc->sc_dev) == 2182 SIBA_BOARD_BCM4309G && 2183 siba_get_pci_revid(sc->sc_dev) >= 30) 2184 pg->pg_rfatt.att = 7; 2185 else 2186 pg->pg_rfatt.att = 6; 2187 } 2188 goto done; 2189 case 2: 2190 if (phy->type == BWN_PHYTYPE_G) { 2191 if (siba_get_pci_subvendor(sc->sc_dev) == 2192 SIBA_BOARDVENDOR_BCM && 2193 siba_get_pci_subdevice(sc->sc_dev) == 2194 SIBA_BOARD_BCM4309G && 2195 siba_get_pci_revid(sc->sc_dev) >= 30) 2196 pg->pg_rfatt.att = 3; 2197 else if (siba_get_pci_subvendor(sc->sc_dev) == 2198 SIBA_BOARDVENDOR_BCM && 2199 siba_get_pci_subdevice(sc->sc_dev) == 2200 SIBA_BOARD_BU4306) 2201 pg->pg_rfatt.att = 5; 2202 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2203 pg->pg_rfatt.att = 4; 2204 else 2205 pg->pg_rfatt.att = 3; 2206 } else 2207 pg->pg_rfatt.att = 6; 2208 goto done; 2209 case 3: 2210 pg->pg_rfatt.att = 5; 2211 goto done; 2212 case 4: 2213 case 5: 2214 pg->pg_rfatt.att = 1; 2215 goto done; 2216 case 6: 2217 case 7: 2218 pg->pg_rfatt.att = 5; 2219 goto done; 2220 case 8: 2221 pg->pg_rfatt.att = 0xa; 2222 pg->pg_rfatt.padmix = 1; 2223 goto done; 2224 case 9: 2225 default: 2226 pg->pg_rfatt.att = 5; 2227 goto done; 2228 } 2229 break; 2230 case 0x2053: 2231 switch (phy->rf_rev) { 2232 case 1: 2233 pg->pg_rfatt.att = 6; 2234 goto done; 2235 } 2236 break; 2237 } 2238 pg->pg_rfatt.att = 5; 2239 done: 2240 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2241 2242 if (!bwn_has_hwpctl(mac)) { 2243 lo->rfatt.array = rfatt0; 2244 lo->rfatt.len = N(rfatt0); 2245 lo->rfatt.min = 0; 2246 lo->rfatt.max = 9; 2247 goto genbbatt; 2248 } 2249 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2250 lo->rfatt.array = rfatt1; 2251 lo->rfatt.len = N(rfatt1); 2252 lo->rfatt.min = 0; 2253 lo->rfatt.max = 14; 2254 goto genbbatt; 2255 } 2256 lo->rfatt.array = rfatt2; 2257 lo->rfatt.len = N(rfatt2); 2258 lo->rfatt.min = 0; 2259 lo->rfatt.max = 9; 2260 genbbatt: 2261 lo->bbatt.array = bbatt_0; 2262 lo->bbatt.len = N(bbatt_0); 2263 lo->bbatt.min = 0; 2264 lo->bbatt.max = 8; 2265 2266 BWN_READ_4(mac, BWN_MACCTL); 2267 if (phy->rev == 1) { 2268 phy->gmode = 0; 2269 bwn_reset_core(mac, 0); 2270 bwn_phy_g_init_sub(mac); 2271 phy->gmode = 1; 2272 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2273 } 2274 return (0); 2275 } 2276 2277 static uint16_t 2278 bwn_phy_g_txctl(struct bwn_mac *mac) 2279 { 2280 struct bwn_phy *phy = &mac->mac_phy; 2281 2282 if (phy->rf_ver != 0x2050) 2283 return (0); 2284 if (phy->rf_rev == 1) 2285 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2286 if (phy->rf_rev < 6) 2287 return (BWN_TXCTL_PA2DB); 2288 if (phy->rf_rev == 8) 2289 return (BWN_TXCTL_TXMIX); 2290 return (0); 2291 } 2292 2293 static int 2294 bwn_phy_g_init(struct bwn_mac *mac) 2295 { 2296 2297 bwn_phy_g_init_sub(mac); 2298 return (0); 2299 } 2300 2301 static void 2302 bwn_phy_g_exit(struct bwn_mac *mac) 2303 { 2304 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2305 struct bwn_lo_calib *cal, *tmp; 2306 2307 if (lo == NULL) 2308 return; 2309 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2310 TAILQ_REMOVE(&lo->calib_list, cal, list); 2311 kfree(cal, M_DEVBUF); 2312 } 2313 } 2314 2315 static uint16_t 2316 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2317 { 2318 2319 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2320 return (BWN_READ_2(mac, BWN_PHYDATA)); 2321 } 2322 2323 static void 2324 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2325 { 2326 2327 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2328 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2329 } 2330 2331 static uint16_t 2332 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2333 { 2334 2335 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2336 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2337 return (BWN_READ_2(mac, BWN_RFDATALO)); 2338 } 2339 2340 static void 2341 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2342 { 2343 2344 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2345 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2346 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2347 } 2348 2349 static int 2350 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2351 { 2352 2353 return (mac->mac_phy.rev >= 6); 2354 } 2355 2356 static void 2357 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2358 { 2359 struct bwn_phy *phy = &mac->mac_phy; 2360 struct bwn_phy_g *pg = &phy->phy_g; 2361 unsigned int channel; 2362 uint16_t rfover, rfoverval; 2363 2364 if (on) { 2365 if (phy->rf_on) 2366 return; 2367 2368 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2369 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2370 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2371 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2372 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2373 pg->pg_radioctx_over); 2374 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2375 pg->pg_radioctx_overval); 2376 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2377 } 2378 channel = phy->chan; 2379 bwn_phy_g_switch_chan(mac, 6, 1); 2380 bwn_phy_g_switch_chan(mac, channel, 0); 2381 return; 2382 } 2383 2384 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2385 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2386 pg->pg_radioctx_over = rfover; 2387 pg->pg_radioctx_overval = rfoverval; 2388 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2389 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2390 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2391 } 2392 2393 static int 2394 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2395 { 2396 2397 if ((newchan < 1) || (newchan > 14)) 2398 return (EINVAL); 2399 bwn_phy_g_switch_chan(mac, newchan, 0); 2400 2401 return (0); 2402 } 2403 2404 static uint32_t 2405 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2406 { 2407 2408 return (1); 2409 } 2410 2411 static void 2412 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2413 { 2414 struct bwn_phy *phy = &mac->mac_phy; 2415 uint64_t hf; 2416 int autodiv = 0; 2417 uint16_t tmp; 2418 2419 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2420 autodiv = 1; 2421 2422 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2423 bwn_hf_write(mac, hf); 2424 2425 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2426 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2427 ((autodiv ? BWN_ANTAUTO1 : antenna) 2428 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2429 2430 if (autodiv) { 2431 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2432 if (antenna == BWN_ANTAUTO1) 2433 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2434 else 2435 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2436 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2437 } 2438 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2439 if (autodiv) 2440 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2441 else 2442 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2443 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2444 if (phy->rev >= 2) { 2445 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2446 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2447 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2448 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2449 0x15); 2450 if (phy->rev == 2) 2451 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2452 else 2453 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2454 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2455 8); 2456 } 2457 if (phy->rev >= 6) 2458 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2459 2460 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2461 bwn_hf_write(mac, hf); 2462 } 2463 2464 static int 2465 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2466 { 2467 struct bwn_phy *phy = &mac->mac_phy; 2468 struct bwn_phy_g *pg = &phy->phy_g; 2469 2470 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2471 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2472 2473 if (phy->rev == 0 || !phy->gmode) 2474 return (ENODEV); 2475 2476 pg->pg_aci_wlan_automatic = 0; 2477 return (0); 2478 } 2479 2480 static int 2481 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2482 { 2483 struct bwn_phy *phy = &mac->mac_phy; 2484 struct bwn_phy_g *pg = &phy->phy_g; 2485 struct bwn_softc *sc = mac->mac_sc; 2486 unsigned int tssi; 2487 int cck, ofdm; 2488 int power; 2489 int rfatt, bbatt; 2490 unsigned int max; 2491 2492 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2493 2494 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2495 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2496 if (cck < 0 && ofdm < 0) { 2497 if (ignore_tssi == 0) 2498 return (BWN_TXPWR_RES_DONE); 2499 cck = 0; 2500 ofdm = 0; 2501 } 2502 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2503 if (pg->pg_avgtssi != 0xff) 2504 tssi = (tssi + pg->pg_avgtssi) / 2; 2505 pg->pg_avgtssi = tssi; 2506 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2507 2508 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2509 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2510 max -= 3; 2511 if (max >= 120) { 2512 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2513 max = 80; 2514 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2515 } 2516 2517 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2518 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2519 tssi, 0x00), 0x3f)]); 2520 if (power == 0) 2521 return (BWN_TXPWR_RES_DONE); 2522 2523 rfatt = -((power + 7) / 8); 2524 bbatt = (-(power / 2)) - (4 * rfatt); 2525 if ((rfatt == 0) && (bbatt == 0)) 2526 return (BWN_TXPWR_RES_DONE); 2527 pg->pg_bbatt_delta = bbatt; 2528 pg->pg_rfatt_delta = rfatt; 2529 return (BWN_TXPWR_RES_NEED_ADJUST); 2530 } 2531 2532 static void 2533 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2534 { 2535 struct bwn_phy *phy = &mac->mac_phy; 2536 struct bwn_phy_g *pg = &phy->phy_g; 2537 struct bwn_softc *sc = mac->mac_sc; 2538 int rfatt, bbatt; 2539 uint8_t txctl; 2540 2541 bwn_mac_suspend(mac); 2542 2543 bbatt = pg->pg_bbatt.att; 2544 bbatt += pg->pg_bbatt_delta; 2545 rfatt = pg->pg_rfatt.att; 2546 rfatt += pg->pg_rfatt_delta; 2547 2548 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2549 txctl = pg->pg_txctl; 2550 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2551 if (rfatt <= 1) { 2552 if (txctl == 0) { 2553 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2554 rfatt += 2; 2555 bbatt += 2; 2556 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2557 BWN_BFL_PACTRL) { 2558 bbatt += 4 * (rfatt - 2); 2559 rfatt = 2; 2560 } 2561 } else if (rfatt > 4 && txctl) { 2562 txctl = 0; 2563 if (bbatt < 3) { 2564 rfatt -= 3; 2565 bbatt += 2; 2566 } else { 2567 rfatt -= 2; 2568 bbatt -= 2; 2569 } 2570 } 2571 } 2572 pg->pg_txctl = txctl; 2573 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2574 pg->pg_rfatt.att = rfatt; 2575 pg->pg_bbatt.att = bbatt; 2576 2577 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2578 2579 bwn_phy_lock(mac); 2580 bwn_rf_lock(mac); 2581 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2582 pg->pg_txctl); 2583 bwn_rf_unlock(mac); 2584 bwn_phy_unlock(mac); 2585 2586 bwn_mac_enable(mac); 2587 } 2588 2589 static void 2590 bwn_phy_g_task_15s(struct bwn_mac *mac) 2591 { 2592 struct bwn_phy *phy = &mac->mac_phy; 2593 struct bwn_phy_g *pg = &phy->phy_g; 2594 struct bwn_softc *sc = mac->mac_sc; 2595 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2596 unsigned long expire, now; 2597 struct bwn_lo_calib *cal, *tmp; 2598 uint8_t expired = 0; 2599 2600 bwn_mac_suspend(mac); 2601 2602 if (lo == NULL) 2603 goto fail; 2604 2605 BWN_GETTIME(now); 2606 if (bwn_has_hwpctl(mac)) { 2607 expire = now - BWN_LO_PWRVEC_EXPIRE; 2608 if (time_before(lo->pwr_vec_read_time, expire)) { 2609 bwn_lo_get_powervector(mac); 2610 bwn_phy_g_dc_lookup_init(mac, 0); 2611 } 2612 goto fail; 2613 } 2614 2615 expire = now - BWN_LO_CALIB_EXPIRE; 2616 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2617 if (!time_before(cal->calib_time, expire)) 2618 continue; 2619 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2620 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2621 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2622 expired = 1; 2623 } 2624 2625 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2626 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2627 cal->ctl.i, cal->ctl.q); 2628 2629 TAILQ_REMOVE(&lo->calib_list, cal, list); 2630 kfree(cal, M_DEVBUF); 2631 } 2632 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2633 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2634 &pg->pg_rfatt); 2635 if (cal == NULL) { /* XXX ivadasz: can't happen */ 2636 device_printf(sc->sc_dev, 2637 "failed to recalibrate LO\n"); 2638 goto fail; 2639 } 2640 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2641 bwn_lo_write(mac, &cal->ctl); 2642 } 2643 2644 fail: 2645 bwn_mac_enable(mac); 2646 } 2647 2648 static void 2649 bwn_phy_g_task_60s(struct bwn_mac *mac) 2650 { 2651 struct bwn_phy *phy = &mac->mac_phy; 2652 struct bwn_softc *sc = mac->mac_sc; 2653 uint8_t old = phy->chan; 2654 2655 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2656 return; 2657 2658 bwn_mac_suspend(mac); 2659 bwn_nrssi_slope_11g(mac); 2660 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2661 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2662 bwn_switch_channel(mac, old); 2663 } 2664 bwn_mac_enable(mac); 2665 } 2666 2667 static void 2668 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2669 { 2670 2671 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2672 } 2673 2674 static int 2675 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2676 const struct ieee80211_bpf_params *params) 2677 { 2678 struct ieee80211com *ic = ni->ni_ic; 2679 struct ifnet *ifp = ic->ic_ifp; 2680 struct bwn_softc *sc = ic->ic_softc; 2681 struct bwn_mac *mac = sc->sc_curmac; 2682 2683 if ((ifp->if_flags & IFF_RUNNING) == 0 || 2684 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2685 ieee80211_free_node(ni); 2686 m_freem(m); 2687 return (ENETDOWN); 2688 } 2689 2690 if (bwn_tx_isfull(sc, m)) { 2691 ieee80211_free_node(ni); 2692 m_freem(m); 2693 ifp->if_oerrors++; 2694 return (ENOBUFS); 2695 } 2696 2697 if (bwn_tx_start(sc, ni, m) != 0) { 2698 if (ni != NULL) 2699 ieee80211_free_node(ni); 2700 ifp->if_oerrors++; 2701 } 2702 sc->sc_watchdog_timer = 5; 2703 return (0); 2704 } 2705 2706 /* 2707 * Callback from the 802.11 layer to update the slot time 2708 * based on the current setting. We use it to notify the 2709 * firmware of ERP changes and the f/w takes care of things 2710 * like slot time and preamble. 2711 */ 2712 static void 2713 bwn_updateslot(struct ieee80211com *ic) 2714 { 2715 struct bwn_softc *sc = ic->ic_softc; 2716 struct bwn_mac *mac; 2717 2718 if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) { 2719 mac = (struct bwn_mac *)sc->sc_curmac; 2720 bwn_set_slot_time(mac, 2721 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2722 } 2723 } 2724 2725 /* 2726 * Callback from the 802.11 layer after a promiscuous mode change. 2727 * Note this interface does not check the operating mode as this 2728 * is an internal callback and we are expected to honor the current 2729 * state (e.g. this is used for setting the interface in promiscuous 2730 * mode when operating in hostap mode to do ACS). 2731 */ 2732 static void 2733 bwn_update_promisc(struct ieee80211com *ic) 2734 { 2735 struct bwn_softc *sc = ic->ic_softc; 2736 struct bwn_mac *mac = sc->sc_curmac; 2737 2738 mac = sc->sc_curmac; 2739 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2740 if (ic->ic_ifp->if_flags & IFF_PROMISC) 2741 sc->sc_filters |= BWN_MACCTL_PROMISC; 2742 else 2743 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2744 bwn_set_opmode(mac); 2745 } 2746 } 2747 2748 /* 2749 * Callback from the 802.11 layer to update WME parameters. 2750 */ 2751 static int 2752 bwn_wme_update(struct ieee80211com *ic) 2753 { 2754 struct bwn_softc *sc = ic->ic_softc; 2755 struct bwn_mac *mac = sc->sc_curmac; 2756 struct wmeParams *wmep; 2757 int i; 2758 2759 mac = sc->sc_curmac; 2760 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2761 bwn_mac_suspend(mac); 2762 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2763 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2764 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2765 } 2766 bwn_mac_enable(mac); 2767 } 2768 return (0); 2769 } 2770 2771 static void 2772 bwn_scan_start(struct ieee80211com *ic) 2773 { 2774 struct bwn_softc *sc = ic->ic_softc; 2775 struct bwn_mac *mac; 2776 2777 mac = sc->sc_curmac; 2778 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2779 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2780 bwn_set_opmode(mac); 2781 /* disable CFP update during scan */ 2782 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2783 } 2784 } 2785 2786 static void 2787 bwn_scan_end(struct ieee80211com *ic) 2788 { 2789 struct bwn_softc *sc = ic->ic_softc; 2790 struct bwn_mac *mac; 2791 2792 mac = sc->sc_curmac; 2793 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2794 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2795 bwn_set_opmode(mac); 2796 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2797 } 2798 } 2799 2800 static void 2801 bwn_set_channel(struct ieee80211com *ic) 2802 { 2803 struct bwn_softc *sc = ic->ic_softc; 2804 struct bwn_mac *mac = sc->sc_curmac; 2805 struct bwn_phy *phy = &mac->mac_phy; 2806 int chan, error; 2807 2808 error = bwn_switch_band(sc, ic->ic_curchan); 2809 if (error) 2810 goto fail; 2811 bwn_mac_suspend(mac); 2812 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2813 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2814 if (chan != phy->chan) 2815 bwn_switch_channel(mac, chan); 2816 2817 /* TX power level */ 2818 if (ic->ic_curchan->ic_maxpower != 0 && 2819 ic->ic_curchan->ic_maxpower != phy->txpower) { 2820 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2821 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2822 BWN_TXPWR_IGNORE_TSSI); 2823 } 2824 2825 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2826 if (phy->set_antenna) 2827 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2828 2829 if (sc->sc_rf_enabled != phy->rf_on) { 2830 if (sc->sc_rf_enabled) { 2831 bwn_rf_turnon(mac); 2832 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2833 device_printf(sc->sc_dev, 2834 "please turn on the RF switch\n"); 2835 } else 2836 bwn_rf_turnoff(mac); 2837 } 2838 2839 bwn_mac_enable(mac); 2840 2841 fail: 2842 /* 2843 * Setup radio tap channel freq and flags 2844 */ 2845 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2846 htole16(ic->ic_curchan->ic_freq); 2847 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2848 htole16(ic->ic_curchan->ic_flags & 0xffff); 2849 } 2850 2851 static struct ieee80211vap * 2852 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2853 enum ieee80211_opmode opmode, int flags, 2854 const uint8_t bssid[IEEE80211_ADDR_LEN], 2855 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2856 { 2857 struct bwn_softc *sc = ic->ic_softc; 2858 struct ieee80211vap *vap; 2859 struct bwn_vap *bvp; 2860 uint8_t mac[IEEE80211_ADDR_LEN]; 2861 2862 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 2863 return NULL; 2864 2865 IEEE80211_ADDR_COPY(mac, mac0); 2866 switch (opmode) { 2867 case IEEE80211_M_HOSTAP: 2868 case IEEE80211_M_MBSS: 2869 case IEEE80211_M_STA: 2870 case IEEE80211_M_WDS: 2871 case IEEE80211_M_MONITOR: 2872 case IEEE80211_M_IBSS: 2873 case IEEE80211_M_AHDEMO: 2874 break; 2875 default: 2876 return (NULL); 2877 } 2878 2879 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2880 2881 bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap), 2882 M_80211_VAP, M_INTWAIT | M_ZERO); 2883 vap = &bvp->bv_vap; 2884 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2885 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2886 /* override with driver methods */ 2887 bvp->bv_newstate = vap->iv_newstate; 2888 vap->iv_newstate = bwn_newstate; 2889 2890 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2891 vap->iv_max_aid = BWN_STAID_MAX; 2892 2893 ieee80211_ratectl_init(vap); 2894 2895 /* complete setup */ 2896 ieee80211_vap_attach(vap, ieee80211_media_change, 2897 ieee80211_media_status); 2898 ic->ic_opmode = opmode; 2899 return (vap); 2900 } 2901 2902 static void 2903 bwn_vap_delete(struct ieee80211vap *vap) 2904 { 2905 struct bwn_vap *bvp = BWN_VAP(vap); 2906 2907 ieee80211_ratectl_deinit(vap); 2908 ieee80211_vap_detach(vap); 2909 kfree(bvp, M_80211_VAP); 2910 } 2911 2912 static void 2913 bwn_init(void *arg) 2914 { 2915 struct bwn_softc *sc = arg; 2916 struct ifnet *ifp = sc->sc_ifp; 2917 struct ieee80211com *ic = ifp->if_l2com; 2918 int error = 0; 2919 2920 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 2921 __func__, ifp->if_flags); 2922 2923 wlan_assert_serialized(); 2924 error = bwn_init_locked(sc); 2925 2926 if (error == 0) 2927 ieee80211_start_all(ic); /* start all vap's */ 2928 } 2929 2930 static int 2931 bwn_init_locked(struct bwn_softc *sc) 2932 { 2933 struct bwn_mac *mac; 2934 struct ifnet *ifp = sc->sc_ifp; 2935 int error; 2936 2937 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2938 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2939 sc->sc_filters = 0; 2940 bwn_wme_clear(sc); 2941 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2942 sc->sc_rf_enabled = 1; 2943 2944 mac = sc->sc_curmac; 2945 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2946 error = bwn_core_init(mac); 2947 if (error != 0) 2948 return (error); 2949 } 2950 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2951 bwn_core_start(mac); 2952 2953 bwn_set_opmode(mac); 2954 bwn_set_pretbtt(mac); 2955 bwn_spu_setdelay(mac, 0); 2956 bwn_set_macaddr(mac); 2957 2958 ifp->if_flags |= IFF_RUNNING; 2959 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2960 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2961 2962 return (0); 2963 } 2964 2965 static void 2966 bwn_stop(struct bwn_softc *sc, int statechg) 2967 { 2968 2969 wlan_assert_serialized(); 2970 bwn_stop_locked(sc, statechg); 2971 } 2972 2973 static void 2974 bwn_stop_locked(struct bwn_softc *sc, int statechg) 2975 { 2976 struct bwn_mac *mac = sc->sc_curmac; 2977 struct ifnet *ifp = sc->sc_ifp; 2978 2979 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2980 /* XXX FIXME opmode not based on VAP */ 2981 bwn_set_opmode(mac); 2982 bwn_set_macaddr(mac); 2983 } 2984 2985 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 2986 bwn_core_stop(mac); 2987 2988 callout_stop(&sc->sc_led_blink_ch); 2989 sc->sc_led_blinking = 0; 2990 2991 bwn_core_exit(mac); 2992 sc->sc_rf_enabled = 0; 2993 2994 ifp->if_flags &= ~IFF_RUNNING; 2995 ifq_clr_oactive(&ifp->if_snd); 2996 } 2997 2998 static void 2999 bwn_wme_clear(struct bwn_softc *sc) 3000 { 3001 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3002 struct wmeParams *p; 3003 unsigned int i; 3004 3005 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3006 ("%s:%d: fail", __func__, __LINE__)); 3007 3008 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3009 p = &(sc->sc_wmeParams[i]); 3010 3011 switch (bwn_wme_shm_offsets[i]) { 3012 case BWN_WME_VOICE: 3013 p->wmep_txopLimit = 0; 3014 p->wmep_aifsn = 2; 3015 /* XXX FIXME: log2(cwmin) */ 3016 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3017 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3018 break; 3019 case BWN_WME_VIDEO: 3020 p->wmep_txopLimit = 0; 3021 p->wmep_aifsn = 2; 3022 /* XXX FIXME: log2(cwmin) */ 3023 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3024 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3025 break; 3026 case BWN_WME_BESTEFFORT: 3027 p->wmep_txopLimit = 0; 3028 p->wmep_aifsn = 3; 3029 /* XXX FIXME: log2(cwmin) */ 3030 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3031 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3032 break; 3033 case BWN_WME_BACKGROUND: 3034 p->wmep_txopLimit = 0; 3035 p->wmep_aifsn = 7; 3036 /* XXX FIXME: log2(cwmin) */ 3037 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3038 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3039 break; 3040 default: 3041 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3042 } 3043 } 3044 } 3045 3046 static int 3047 bwn_core_init(struct bwn_mac *mac) 3048 { 3049 struct bwn_softc *sc = mac->mac_sc; 3050 uint64_t hf; 3051 int error; 3052 3053 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3054 ("%s:%d: fail", __func__, __LINE__)); 3055 3056 siba_powerup(sc->sc_dev, 0); 3057 if (!siba_dev_isup(sc->sc_dev)) 3058 bwn_reset_core(mac, 3059 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3060 3061 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3062 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3063 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3064 BWN_GETTIME(mac->mac_phy.nexttime); 3065 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3066 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3067 mac->mac_stats.link_noise = -95; 3068 mac->mac_reason_intr = 0; 3069 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3070 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3071 #ifdef BWN_DEBUG 3072 if (sc->sc_debug & BWN_DEBUG_XMIT) 3073 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3074 #endif 3075 mac->mac_suspended = 1; 3076 mac->mac_task_state = 0; 3077 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3078 3079 mac->mac_phy.init_pre(mac); 3080 3081 siba_pcicore_intr(sc->sc_dev); 3082 3083 siba_fix_imcfglobug(sc->sc_dev); 3084 bwn_bt_disable(mac); 3085 if (mac->mac_phy.prepare_hw) { 3086 error = mac->mac_phy.prepare_hw(mac); 3087 if (error) 3088 goto fail0; 3089 } 3090 error = bwn_chip_init(mac); 3091 if (error) 3092 goto fail0; 3093 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3094 siba_get_revid(sc->sc_dev)); 3095 hf = bwn_hf_read(mac); 3096 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3097 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3098 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3099 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3100 if (mac->mac_phy.rev == 1) 3101 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3102 } 3103 if (mac->mac_phy.rf_ver == 0x2050) { 3104 if (mac->mac_phy.rf_rev < 6) 3105 hf |= BWN_HF_FORCE_VCO_RECALC; 3106 if (mac->mac_phy.rf_rev == 6) 3107 hf |= BWN_HF_4318_TSSI; 3108 } 3109 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3110 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3111 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3112 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3113 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3114 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3115 bwn_hf_write(mac, hf); 3116 3117 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3118 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3119 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3120 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3121 3122 bwn_rate_init(mac); 3123 bwn_set_phytxctl(mac); 3124 3125 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3126 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3127 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3128 3129 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3130 bwn_pio_init(mac); 3131 else 3132 bwn_dma_init(mac); 3133 bwn_wme_init(mac); 3134 bwn_spu_setdelay(mac, 1); 3135 bwn_bt_enable(mac); 3136 3137 siba_powerup(sc->sc_dev, 3138 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3139 bwn_set_macaddr(mac); 3140 bwn_crypt_init(mac); 3141 3142 /* XXX LED initializatin */ 3143 3144 mac->mac_status = BWN_MAC_STATUS_INITED; 3145 3146 return (error); 3147 3148 fail0: 3149 siba_powerdown(sc->sc_dev); 3150 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3151 ("%s:%d: fail", __func__, __LINE__)); 3152 return (error); 3153 } 3154 3155 static void 3156 bwn_core_start(struct bwn_mac *mac) 3157 { 3158 struct bwn_softc *sc = mac->mac_sc; 3159 uint32_t tmp; 3160 3161 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3162 ("%s:%d: fail", __func__, __LINE__)); 3163 3164 if (siba_get_revid(sc->sc_dev) < 5) 3165 return; 3166 3167 while (1) { 3168 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3169 if (!(tmp & 0x00000001)) 3170 break; 3171 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3172 } 3173 3174 bwn_mac_enable(mac); 3175 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3176 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3177 3178 mac->mac_status = BWN_MAC_STATUS_STARTED; 3179 } 3180 3181 static void 3182 bwn_core_exit(struct bwn_mac *mac) 3183 { 3184 struct bwn_softc *sc = mac->mac_sc; 3185 uint32_t macctl; 3186 3187 wlan_assert_serialized(); 3188 3189 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3190 ("%s:%d: fail", __func__, __LINE__)); 3191 3192 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3193 return; 3194 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3195 3196 macctl = BWN_READ_4(mac, BWN_MACCTL); 3197 macctl &= ~BWN_MACCTL_MCODE_RUN; 3198 macctl |= BWN_MACCTL_MCODE_JMP0; 3199 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3200 3201 bwn_dma_stop(mac); 3202 bwn_pio_stop(mac); 3203 bwn_chip_exit(mac); 3204 mac->mac_phy.switch_analog(mac, 0); 3205 siba_dev_down(sc->sc_dev, 0); 3206 siba_powerdown(sc->sc_dev); 3207 } 3208 3209 static void 3210 bwn_bt_disable(struct bwn_mac *mac) 3211 { 3212 struct bwn_softc *sc = mac->mac_sc; 3213 3214 (void)sc; 3215 /* XXX do nothing yet */ 3216 } 3217 3218 static int 3219 bwn_chip_init(struct bwn_mac *mac) 3220 { 3221 struct bwn_softc *sc = mac->mac_sc; 3222 struct bwn_phy *phy = &mac->mac_phy; 3223 uint32_t macctl; 3224 int error; 3225 3226 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3227 if (phy->gmode) 3228 macctl |= BWN_MACCTL_GMODE; 3229 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3230 3231 error = bwn_fw_fillinfo(mac); 3232 if (error) 3233 return (error); 3234 error = bwn_fw_loaducode(mac); 3235 if (error) 3236 return (error); 3237 3238 error = bwn_gpio_init(mac); 3239 if (error) 3240 return (error); 3241 3242 error = bwn_fw_loadinitvals(mac); 3243 if (error) { 3244 siba_gpio_set(sc->sc_dev, 0); 3245 return (error); 3246 } 3247 phy->switch_analog(mac, 1); 3248 error = bwn_phy_init(mac); 3249 if (error) { 3250 siba_gpio_set(sc->sc_dev, 0); 3251 return (error); 3252 } 3253 if (phy->set_im) 3254 phy->set_im(mac, BWN_IMMODE_NONE); 3255 if (phy->set_antenna) 3256 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3257 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3258 3259 if (phy->type == BWN_PHYTYPE_B) 3260 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3261 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3262 if (siba_get_revid(sc->sc_dev) < 5) 3263 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3264 3265 BWN_WRITE_4(mac, BWN_MACCTL, 3266 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3267 BWN_WRITE_4(mac, BWN_MACCTL, 3268 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3269 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3270 3271 bwn_set_opmode(mac); 3272 if (siba_get_revid(sc->sc_dev) < 3) { 3273 BWN_WRITE_2(mac, 0x060e, 0x0000); 3274 BWN_WRITE_2(mac, 0x0610, 0x8000); 3275 BWN_WRITE_2(mac, 0x0604, 0x0000); 3276 BWN_WRITE_2(mac, 0x0606, 0x0200); 3277 } else { 3278 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3279 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3280 } 3281 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3282 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00); 3283 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3284 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3285 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3286 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3287 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3288 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3289 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3290 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3291 return (error); 3292 } 3293 3294 /* read hostflags */ 3295 static uint64_t 3296 bwn_hf_read(struct bwn_mac *mac) 3297 { 3298 uint64_t ret; 3299 3300 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3301 ret <<= 16; 3302 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3303 ret <<= 16; 3304 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3305 return (ret); 3306 } 3307 3308 static void 3309 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3310 { 3311 3312 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3313 (value & 0x00000000ffffull)); 3314 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3315 (value & 0x0000ffff0000ull) >> 16); 3316 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3317 (value & 0xffff00000000ULL) >> 32); 3318 } 3319 3320 static void 3321 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3322 { 3323 3324 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3325 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3326 } 3327 3328 static void 3329 bwn_rate_init(struct bwn_mac *mac) 3330 { 3331 3332 switch (mac->mac_phy.type) { 3333 case BWN_PHYTYPE_A: 3334 case BWN_PHYTYPE_G: 3335 case BWN_PHYTYPE_LP: 3336 case BWN_PHYTYPE_N: 3337 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3338 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3339 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3340 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3341 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3342 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3343 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3344 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3345 break; 3346 /* FALLTHROUGH */ 3347 case BWN_PHYTYPE_B: 3348 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3349 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3350 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3351 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3352 break; 3353 default: 3354 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3355 } 3356 } 3357 3358 static void 3359 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3360 { 3361 uint16_t offset; 3362 3363 if (ofdm) { 3364 offset = 0x480; 3365 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3366 } else { 3367 offset = 0x4c0; 3368 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3369 } 3370 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3371 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3372 } 3373 3374 static uint8_t 3375 bwn_plcp_getcck(const uint8_t bitrate) 3376 { 3377 3378 switch (bitrate) { 3379 case BWN_CCK_RATE_1MB: 3380 return (0x0a); 3381 case BWN_CCK_RATE_2MB: 3382 return (0x14); 3383 case BWN_CCK_RATE_5MB: 3384 return (0x37); 3385 case BWN_CCK_RATE_11MB: 3386 return (0x6e); 3387 } 3388 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3389 return (0); 3390 } 3391 3392 static uint8_t 3393 bwn_plcp_getofdm(const uint8_t bitrate) 3394 { 3395 3396 switch (bitrate) { 3397 case BWN_OFDM_RATE_6MB: 3398 return (0xb); 3399 case BWN_OFDM_RATE_9MB: 3400 return (0xf); 3401 case BWN_OFDM_RATE_12MB: 3402 return (0xa); 3403 case BWN_OFDM_RATE_18MB: 3404 return (0xe); 3405 case BWN_OFDM_RATE_24MB: 3406 return (0x9); 3407 case BWN_OFDM_RATE_36MB: 3408 return (0xd); 3409 case BWN_OFDM_RATE_48MB: 3410 return (0x8); 3411 case BWN_OFDM_RATE_54MB: 3412 return (0xc); 3413 } 3414 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3415 return (0); 3416 } 3417 3418 static void 3419 bwn_set_phytxctl(struct bwn_mac *mac) 3420 { 3421 uint16_t ctl; 3422 3423 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3424 BWN_TX_PHY_TXPWR); 3425 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3426 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3427 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3428 } 3429 3430 static void 3431 bwn_pio_init(struct bwn_mac *mac) 3432 { 3433 struct bwn_pio *pio = &mac->mac_method.pio; 3434 3435 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3436 & ~BWN_MACCTL_BIGENDIAN); 3437 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3438 3439 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3440 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3441 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3442 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3443 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3444 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3445 } 3446 3447 static void 3448 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3449 int index) 3450 { 3451 struct bwn_pio_txpkt *tp; 3452 struct bwn_softc *sc = mac->mac_sc; 3453 unsigned int i; 3454 3455 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3456 tq->tq_index = index; 3457 3458 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3459 if (siba_get_revid(sc->sc_dev) >= 8) 3460 tq->tq_size = 1920; 3461 else { 3462 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3463 tq->tq_size -= 80; 3464 } 3465 3466 TAILQ_INIT(&tq->tq_pktlist); 3467 for (i = 0; i < N(tq->tq_pkts); i++) { 3468 tp = &(tq->tq_pkts[i]); 3469 tp->tp_index = i; 3470 tp->tp_queue = tq; 3471 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3472 } 3473 } 3474 3475 static uint16_t 3476 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3477 { 3478 struct bwn_softc *sc = mac->mac_sc; 3479 static const uint16_t bases[] = { 3480 BWN_PIO_BASE0, 3481 BWN_PIO_BASE1, 3482 BWN_PIO_BASE2, 3483 BWN_PIO_BASE3, 3484 BWN_PIO_BASE4, 3485 BWN_PIO_BASE5, 3486 BWN_PIO_BASE6, 3487 BWN_PIO_BASE7, 3488 }; 3489 static const uint16_t bases_rev11[] = { 3490 BWN_PIO11_BASE0, 3491 BWN_PIO11_BASE1, 3492 BWN_PIO11_BASE2, 3493 BWN_PIO11_BASE3, 3494 BWN_PIO11_BASE4, 3495 BWN_PIO11_BASE5, 3496 }; 3497 3498 if (siba_get_revid(sc->sc_dev) >= 11) { 3499 if (index >= N(bases_rev11)) 3500 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3501 return (bases_rev11[index]); 3502 } 3503 if (index >= N(bases)) 3504 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3505 return (bases[index]); 3506 } 3507 3508 static void 3509 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3510 int index) 3511 { 3512 struct bwn_softc *sc = mac->mac_sc; 3513 3514 prq->prq_mac = mac; 3515 prq->prq_rev = siba_get_revid(sc->sc_dev); 3516 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3517 bwn_dma_rxdirectfifo(mac, index, 1); 3518 } 3519 3520 static void 3521 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3522 { 3523 if (tq == NULL) 3524 return; 3525 bwn_pio_cancel_tx_packets(tq); 3526 } 3527 3528 static void 3529 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3530 { 3531 3532 bwn_destroy_pioqueue_tx(pio); 3533 } 3534 3535 static uint16_t 3536 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3537 uint16_t offset) 3538 { 3539 3540 return (BWN_READ_2(mac, tq->tq_base + offset)); 3541 } 3542 3543 static void 3544 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3545 { 3546 uint32_t ctl; 3547 int type; 3548 uint16_t base; 3549 3550 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3551 base = bwn_dma_base(type, idx); 3552 if (type == BWN_DMA_64BIT) { 3553 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3554 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3555 if (enable) 3556 ctl |= BWN_DMA64_RXDIRECTFIFO; 3557 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3558 } else { 3559 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3560 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3561 if (enable) 3562 ctl |= BWN_DMA32_RXDIRECTFIFO; 3563 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3564 } 3565 } 3566 3567 static uint64_t 3568 bwn_dma_mask(struct bwn_mac *mac) 3569 { 3570 uint32_t tmp; 3571 uint16_t base; 3572 3573 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3574 if (tmp & SIBA_TGSHIGH_DMA64) 3575 return (BWN_DMA_BIT_MASK(64)); 3576 base = bwn_dma_base(0, 0); 3577 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3578 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3579 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3580 return (BWN_DMA_BIT_MASK(32)); 3581 3582 return (BWN_DMA_BIT_MASK(30)); 3583 } 3584 3585 static int 3586 bwn_dma_mask2type(uint64_t dmamask) 3587 { 3588 3589 if (dmamask == BWN_DMA_BIT_MASK(30)) 3590 return (BWN_DMA_30BIT); 3591 if (dmamask == BWN_DMA_BIT_MASK(32)) 3592 return (BWN_DMA_32BIT); 3593 if (dmamask == BWN_DMA_BIT_MASK(64)) 3594 return (BWN_DMA_64BIT); 3595 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3596 return (BWN_DMA_30BIT); 3597 } 3598 3599 static void 3600 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3601 { 3602 struct bwn_pio_txpkt *tp; 3603 unsigned int i; 3604 3605 for (i = 0; i < N(tq->tq_pkts); i++) { 3606 tp = &(tq->tq_pkts[i]); 3607 if (tp->tp_m) { 3608 m_freem(tp->tp_m); 3609 tp->tp_m = NULL; 3610 } 3611 } 3612 } 3613 3614 static uint16_t 3615 bwn_dma_base(int type, int controller_idx) 3616 { 3617 static const uint16_t map64[] = { 3618 BWN_DMA64_BASE0, 3619 BWN_DMA64_BASE1, 3620 BWN_DMA64_BASE2, 3621 BWN_DMA64_BASE3, 3622 BWN_DMA64_BASE4, 3623 BWN_DMA64_BASE5, 3624 }; 3625 static const uint16_t map32[] = { 3626 BWN_DMA32_BASE0, 3627 BWN_DMA32_BASE1, 3628 BWN_DMA32_BASE2, 3629 BWN_DMA32_BASE3, 3630 BWN_DMA32_BASE4, 3631 BWN_DMA32_BASE5, 3632 }; 3633 3634 if (type == BWN_DMA_64BIT) { 3635 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3636 ("%s:%d: fail", __func__, __LINE__)); 3637 return (map64[controller_idx]); 3638 } 3639 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3640 ("%s:%d: fail", __func__, __LINE__)); 3641 return (map32[controller_idx]); 3642 } 3643 3644 static void 3645 bwn_dma_init(struct bwn_mac *mac) 3646 { 3647 struct bwn_dma *dma = &mac->mac_method.dma; 3648 3649 /* setup TX DMA channels. */ 3650 bwn_dma_setup(dma->wme[WME_AC_BK]); 3651 bwn_dma_setup(dma->wme[WME_AC_BE]); 3652 bwn_dma_setup(dma->wme[WME_AC_VI]); 3653 bwn_dma_setup(dma->wme[WME_AC_VO]); 3654 bwn_dma_setup(dma->mcast); 3655 /* setup RX DMA channel. */ 3656 bwn_dma_setup(dma->rx); 3657 } 3658 3659 static struct bwn_dma_ring * 3660 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3661 int for_tx, int type) 3662 { 3663 struct bwn_dma *dma = &mac->mac_method.dma; 3664 struct bwn_dma_ring *dr; 3665 struct bwn_dmadesc_generic *desc; 3666 struct bwn_dmadesc_meta *mt; 3667 struct bwn_softc *sc = mac->mac_sc; 3668 int error, i; 3669 3670 dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO); 3671 dr->dr_numslots = BWN_RXRING_SLOTS; 3672 if (for_tx) 3673 dr->dr_numslots = BWN_TXRING_SLOTS; 3674 3675 dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3676 M_DEVBUF, M_INTWAIT | M_ZERO); 3677 3678 dr->dr_type = type; 3679 dr->dr_mac = mac; 3680 dr->dr_base = bwn_dma_base(type, controller_index); 3681 dr->dr_index = controller_index; 3682 if (type == BWN_DMA_64BIT) { 3683 dr->getdesc = bwn_dma_64_getdesc; 3684 dr->setdesc = bwn_dma_64_setdesc; 3685 dr->start_transfer = bwn_dma_64_start_transfer; 3686 dr->suspend = bwn_dma_64_suspend; 3687 dr->resume = bwn_dma_64_resume; 3688 dr->get_curslot = bwn_dma_64_get_curslot; 3689 dr->set_curslot = bwn_dma_64_set_curslot; 3690 } else { 3691 dr->getdesc = bwn_dma_32_getdesc; 3692 dr->setdesc = bwn_dma_32_setdesc; 3693 dr->start_transfer = bwn_dma_32_start_transfer; 3694 dr->suspend = bwn_dma_32_suspend; 3695 dr->resume = bwn_dma_32_resume; 3696 dr->get_curslot = bwn_dma_32_get_curslot; 3697 dr->set_curslot = bwn_dma_32_set_curslot; 3698 } 3699 if (for_tx) { 3700 dr->dr_tx = 1; 3701 dr->dr_curslot = -1; 3702 } else { 3703 if (dr->dr_index == 0) { 3704 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3705 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3706 } else 3707 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3708 } 3709 3710 error = bwn_dma_allocringmemory(dr); 3711 if (error) 3712 goto fail1; 3713 3714 if (for_tx) { 3715 /* 3716 * Assumption: BWN_TXRING_SLOTS can be divided by 3717 * BWN_TX_SLOTS_PER_FRAME 3718 */ 3719 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3720 ("%s:%d: fail", __func__, __LINE__)); 3721 3722 /* 3723 * Create TX ring DMA stuffs 3724 */ 3725 dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag, 3726 4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3727 BWN_MAX_HDRSIZE(mac), 3728 BUS_DMA_WAITOK | BUS_DMA_ZERO, 3729 &dr->dr_txring_dtag, &dr->dr_txring_dmap, 3730 &dr->dr_txring_paddr); 3731 if (dr->dr_txhdr_cache == NULL) { 3732 device_printf(sc->sc_dev, 3733 "can't create TX ring DMA memory\n"); 3734 goto fail1; 3735 } 3736 3737 for (i = 0; i < dr->dr_numslots; i += 2) { 3738 dr->getdesc(dr, i, &desc, &mt); 3739 3740 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3741 mt->mt_m = NULL; 3742 mt->mt_ni = NULL; 3743 mt->mt_islast = 0; 3744 mt->mt_dmap = dr->dr_txring_dmap; 3745 mt->mt_paddr = dr->dr_txring_paddr + 3746 (i / BWN_TX_SLOTS_PER_FRAME) * 3747 BWN_MAX_HDRSIZE(mac); 3748 3749 dr->getdesc(dr, i + 1, &desc, &mt); 3750 3751 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3752 mt->mt_m = NULL; 3753 mt->mt_ni = NULL; 3754 mt->mt_islast = 1; 3755 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3756 &mt->mt_dmap); 3757 if (error) { 3758 device_printf(sc->sc_dev, 3759 "can't create RX buf DMA map\n"); 3760 goto fail2; 3761 } 3762 } 3763 } else { 3764 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3765 &dr->dr_spare_dmap); 3766 if (error) { 3767 device_printf(sc->sc_dev, 3768 "can't create RX buf DMA map\n"); 3769 goto out; /* XXX wrong! */ 3770 } 3771 3772 for (i = 0; i < dr->dr_numslots; i++) { 3773 dr->getdesc(dr, i, &desc, &mt); 3774 3775 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3776 &mt->mt_dmap); 3777 if (error) { 3778 device_printf(sc->sc_dev, 3779 "can't create RX buf DMA map\n"); 3780 goto out; /* XXX wrong! */ 3781 } 3782 error = bwn_dma_newbuf(dr, desc, mt, 1); 3783 if (error) { 3784 device_printf(sc->sc_dev, 3785 "failed to allocate RX buf\n"); 3786 goto out; /* XXX wrong! */ 3787 } 3788 } 3789 3790 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3791 BUS_DMASYNC_PREWRITE); 3792 3793 dr->dr_usedslot = dr->dr_numslots; 3794 } 3795 3796 out: 3797 return (dr); 3798 3799 fail2: 3800 /* XXX free up dma allocations */ 3801 fail1: 3802 kfree(dr->dr_meta, M_DEVBUF); 3803 kfree(dr, M_DEVBUF); 3804 return (NULL); 3805 } 3806 3807 static void 3808 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3809 { 3810 3811 if (dr == NULL) 3812 return; 3813 3814 bwn_dma_free_descbufs(*dr); 3815 bwn_dma_free_ringmemory(*dr); 3816 3817 if ((*dr)->dr_meta != NULL) 3818 kfree((*dr)->dr_meta, M_DEVBUF); 3819 kfree(*dr, M_DEVBUF); 3820 3821 *dr = NULL; 3822 } 3823 3824 static void 3825 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3826 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3827 { 3828 struct bwn_dmadesc32 *desc; 3829 3830 *meta = &(dr->dr_meta[slot]); 3831 desc = dr->dr_ring_descbase; 3832 desc = &(desc[slot]); 3833 3834 *gdesc = (struct bwn_dmadesc_generic *)desc; 3835 } 3836 3837 static void 3838 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3839 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3840 int start, int end, int irq) 3841 { 3842 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3843 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3844 uint32_t addr, addrext, ctl; 3845 int slot; 3846 3847 slot = (int)(&(desc->dma.dma32) - descbase); 3848 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3849 ("%s:%d: fail", __func__, __LINE__)); 3850 3851 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3852 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3853 addr |= siba_dma_translation(sc->sc_dev); 3854 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3855 if (slot == dr->dr_numslots - 1) 3856 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3857 if (start) 3858 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3859 if (end) 3860 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3861 if (irq) 3862 ctl |= BWN_DMA32_DCTL_IRQ; 3863 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3864 & BWN_DMA32_DCTL_ADDREXT_MASK; 3865 3866 desc->dma.dma32.control = htole32(ctl); 3867 desc->dma.dma32.address = htole32(addr); 3868 } 3869 3870 static void 3871 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3872 { 3873 3874 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3875 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3876 } 3877 3878 static void 3879 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3880 { 3881 3882 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3883 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3884 } 3885 3886 static void 3887 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3888 { 3889 3890 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3891 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3892 } 3893 3894 static int 3895 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3896 { 3897 uint32_t val; 3898 3899 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3900 val &= BWN_DMA32_RXDPTR; 3901 3902 return (val / sizeof(struct bwn_dmadesc32)); 3903 } 3904 3905 static void 3906 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3907 { 3908 3909 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3910 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3911 } 3912 3913 static void 3914 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3915 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3916 { 3917 struct bwn_dmadesc64 *desc; 3918 3919 *meta = &(dr->dr_meta[slot]); 3920 desc = dr->dr_ring_descbase; 3921 desc = &(desc[slot]); 3922 3923 *gdesc = (struct bwn_dmadesc_generic *)desc; 3924 } 3925 3926 static void 3927 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3928 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3929 int start, int end, int irq) 3930 { 3931 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3932 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3933 int slot; 3934 uint32_t ctl0 = 0, ctl1 = 0; 3935 uint32_t addrlo, addrhi; 3936 uint32_t addrext; 3937 3938 slot = (int)(&(desc->dma.dma64) - descbase); 3939 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3940 ("%s:%d: fail", __func__, __LINE__)); 3941 3942 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3943 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3944 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3945 30; 3946 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3947 if (slot == dr->dr_numslots - 1) 3948 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3949 if (start) 3950 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3951 if (end) 3952 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3953 if (irq) 3954 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3955 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3956 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3957 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3958 3959 desc->dma.dma64.control0 = htole32(ctl0); 3960 desc->dma.dma64.control1 = htole32(ctl1); 3961 desc->dma.dma64.address_low = htole32(addrlo); 3962 desc->dma.dma64.address_high = htole32(addrhi); 3963 } 3964 3965 static void 3966 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3967 { 3968 3969 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3970 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3971 } 3972 3973 static void 3974 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3975 { 3976 3977 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3978 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3979 } 3980 3981 static void 3982 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3983 { 3984 3985 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3986 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 3987 } 3988 3989 static int 3990 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 3991 { 3992 uint32_t val; 3993 3994 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 3995 val &= BWN_DMA64_RXSTATDPTR; 3996 3997 return (val / sizeof(struct bwn_dmadesc64)); 3998 } 3999 4000 static void 4001 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4002 { 4003 4004 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4005 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4006 } 4007 4008 static int 4009 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4010 { 4011 struct bwn_mac *mac = dr->dr_mac; 4012 struct bwn_dma *dma = &mac->mac_method.dma; 4013 struct bwn_softc *sc = mac->mac_sc; 4014 int error; 4015 4016 error = bus_dma_tag_create(dma->parent_dtag, 4017 BWN_ALIGN, 0, 4018 BUS_SPACE_MAXADDR, 4019 BUS_SPACE_MAXADDR, 4020 NULL, NULL, 4021 BWN_DMA_RINGMEMSIZE, 4022 1, 4023 BUS_SPACE_MAXSIZE_32BIT, 4024 0, 4025 &dr->dr_ring_dtag); 4026 if (error) { 4027 device_printf(sc->sc_dev, 4028 "can't create TX ring DMA tag: TODO frees\n"); 4029 return (-1); 4030 } 4031 4032 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4033 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4034 &dr->dr_ring_dmap); 4035 if (error) { 4036 device_printf(sc->sc_dev, 4037 "can't allocate DMA mem: TODO frees\n"); 4038 return (-1); 4039 } 4040 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4041 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4042 bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0); 4043 if (error) { 4044 device_printf(sc->sc_dev, 4045 "can't load DMA mem: TODO free\n"); 4046 return (-1); 4047 } 4048 4049 return (0); 4050 } 4051 4052 static void 4053 bwn_dma_setup(struct bwn_dma_ring *dr) 4054 { 4055 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4056 uint64_t ring64; 4057 uint32_t addrext, ring32, value; 4058 uint32_t trans = siba_dma_translation(sc->sc_dev); 4059 4060 if (dr->dr_tx) { 4061 dr->dr_curslot = -1; 4062 4063 if (dr->dr_type == BWN_DMA_64BIT) { 4064 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4065 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4066 >> 30; 4067 value = BWN_DMA64_TXENABLE; 4068 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4069 & BWN_DMA64_TXADDREXT_MASK; 4070 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4071 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4072 (ring64 & 0xffffffff)); 4073 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4074 ((ring64 >> 32) & 4075 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4076 } else { 4077 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4078 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4079 value = BWN_DMA32_TXENABLE; 4080 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4081 & BWN_DMA32_TXADDREXT_MASK; 4082 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4083 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4084 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4085 } 4086 return; 4087 } 4088 4089 /* 4090 * set for RX 4091 */ 4092 dr->dr_usedslot = dr->dr_numslots; 4093 4094 if (dr->dr_type == BWN_DMA_64BIT) { 4095 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4096 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4097 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4098 value |= BWN_DMA64_RXENABLE; 4099 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4100 & BWN_DMA64_RXADDREXT_MASK; 4101 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4102 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4103 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4104 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4105 | (trans << 1)); 4106 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4107 sizeof(struct bwn_dmadesc64)); 4108 } else { 4109 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4110 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4111 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4112 value |= BWN_DMA32_RXENABLE; 4113 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4114 & BWN_DMA32_RXADDREXT_MASK; 4115 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4116 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4117 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4118 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4119 sizeof(struct bwn_dmadesc32)); 4120 } 4121 } 4122 4123 static void 4124 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4125 { 4126 4127 if (dr->dr_tx) { 4128 bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap); 4129 if (dr->dr_txhdr_cache != NULL) 4130 bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache, 4131 dr->dr_txring_dmap); 4132 bus_dma_tag_destroy(dr->dr_txring_dtag); 4133 } 4134 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4135 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4136 dr->dr_ring_dmap); 4137 bus_dma_tag_destroy(dr->dr_ring_dtag); 4138 } 4139 4140 static void 4141 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4142 { 4143 4144 if (dr->dr_tx) { 4145 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4146 if (dr->dr_type == BWN_DMA_64BIT) { 4147 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4148 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4149 } else 4150 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4151 } else { 4152 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4153 if (dr->dr_type == BWN_DMA_64BIT) { 4154 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4155 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4156 } else 4157 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4158 } 4159 } 4160 4161 static void 4162 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4163 { 4164 struct bwn_dmadesc_generic *desc; 4165 struct bwn_dmadesc_meta *meta; 4166 struct bwn_mac *mac = dr->dr_mac; 4167 struct bwn_dma *dma = &mac->mac_method.dma; 4168 struct bwn_softc *sc = mac->mac_sc; 4169 int i; 4170 4171 if (!dr->dr_usedslot) 4172 return; 4173 for (i = 0; i < dr->dr_numslots; i++) { 4174 dr->getdesc(dr, i, &desc, &meta); 4175 4176 if (meta->mt_m == NULL) { 4177 if (!dr->dr_tx) 4178 device_printf(sc->sc_dev, "%s: not TX?\n", 4179 __func__); 4180 continue; 4181 } 4182 if (dr->dr_tx) { 4183 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 4184 /* Nothing */ 4185 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 4186 bus_dmamap_unload(dma->txbuf_dtag, 4187 meta->mt_dmap); 4188 } 4189 } else 4190 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4191 bwn_dma_free_descbuf(dr, meta); 4192 } 4193 } 4194 4195 static int 4196 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4197 int type) 4198 { 4199 struct bwn_softc *sc = mac->mac_sc; 4200 uint32_t value; 4201 int i; 4202 uint16_t offset; 4203 4204 for (i = 0; i < 10; i++) { 4205 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4206 BWN_DMA32_TXSTATUS; 4207 value = BWN_READ_4(mac, base + offset); 4208 if (type == BWN_DMA_64BIT) { 4209 value &= BWN_DMA64_TXSTAT; 4210 if (value == BWN_DMA64_TXSTAT_DISABLED || 4211 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4212 value == BWN_DMA64_TXSTAT_STOPPED) 4213 break; 4214 } else { 4215 value &= BWN_DMA32_TXSTATE; 4216 if (value == BWN_DMA32_TXSTAT_DISABLED || 4217 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4218 value == BWN_DMA32_TXSTAT_STOPPED) 4219 break; 4220 } 4221 DELAY(1000); 4222 } 4223 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4224 BWN_WRITE_4(mac, base + offset, 0); 4225 for (i = 0; i < 10; i++) { 4226 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4227 BWN_DMA32_TXSTATUS; 4228 value = BWN_READ_4(mac, base + offset); 4229 if (type == BWN_DMA_64BIT) { 4230 value &= BWN_DMA64_TXSTAT; 4231 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4232 i = -1; 4233 break; 4234 } 4235 } else { 4236 value &= BWN_DMA32_TXSTATE; 4237 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4238 i = -1; 4239 break; 4240 } 4241 } 4242 DELAY(1000); 4243 } 4244 if (i != -1) { 4245 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4246 return (ENODEV); 4247 } 4248 DELAY(1000); 4249 4250 return (0); 4251 } 4252 4253 static int 4254 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4255 int type) 4256 { 4257 struct bwn_softc *sc = mac->mac_sc; 4258 uint32_t value; 4259 int i; 4260 uint16_t offset; 4261 4262 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4263 BWN_WRITE_4(mac, base + offset, 0); 4264 for (i = 0; i < 10; i++) { 4265 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4266 BWN_DMA32_RXSTATUS; 4267 value = BWN_READ_4(mac, base + offset); 4268 if (type == BWN_DMA_64BIT) { 4269 value &= BWN_DMA64_RXSTAT; 4270 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4271 i = -1; 4272 break; 4273 } 4274 } else { 4275 value &= BWN_DMA32_RXSTATE; 4276 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4277 i = -1; 4278 break; 4279 } 4280 } 4281 DELAY(1000); 4282 } 4283 if (i != -1) { 4284 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4285 return (ENODEV); 4286 } 4287 4288 return (0); 4289 } 4290 4291 static void 4292 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4293 struct bwn_dmadesc_meta *meta) 4294 { 4295 4296 if (meta->mt_m != NULL) { 4297 m_freem(meta->mt_m); 4298 meta->mt_m = NULL; 4299 } 4300 if (meta->mt_ni != NULL) { 4301 ieee80211_free_node(meta->mt_ni); 4302 meta->mt_ni = NULL; 4303 } 4304 } 4305 4306 static void 4307 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4308 { 4309 struct bwn_rxhdr4 *rxhdr; 4310 unsigned char *frame; 4311 4312 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4313 rxhdr->frame_len = 0; 4314 4315 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4316 sizeof(struct bwn_plcp6) + 2, 4317 ("%s:%d: fail", __func__, __LINE__)); 4318 frame = mtod(m, char *) + dr->dr_frameoffset; 4319 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4320 } 4321 4322 static uint8_t 4323 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4324 { 4325 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4326 4327 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4328 == 0xff); 4329 } 4330 4331 static void 4332 bwn_wme_init(struct bwn_mac *mac) 4333 { 4334 4335 bwn_wme_load(mac); 4336 4337 /* enable WME support. */ 4338 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4339 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4340 BWN_IFSCTL_USE_EDCF); 4341 } 4342 4343 static void 4344 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4345 { 4346 struct bwn_softc *sc = mac->mac_sc; 4347 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4348 uint16_t delay; /* microsec */ 4349 4350 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4351 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4352 delay = 500; 4353 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4354 delay = max(delay, (uint16_t)2400); 4355 4356 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4357 } 4358 4359 static void 4360 bwn_bt_enable(struct bwn_mac *mac) 4361 { 4362 struct bwn_softc *sc = mac->mac_sc; 4363 uint64_t hf; 4364 4365 if (bwn_bluetooth == 0) 4366 return; 4367 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4368 return; 4369 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4370 return; 4371 4372 hf = bwn_hf_read(mac); 4373 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4374 hf |= BWN_HF_BT_COEXISTALT; 4375 else 4376 hf |= BWN_HF_BT_COEXIST; 4377 bwn_hf_write(mac, hf); 4378 } 4379 4380 static void 4381 bwn_set_macaddr(struct bwn_mac *mac) 4382 { 4383 4384 bwn_mac_write_bssid(mac); 4385 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4386 } 4387 4388 static void 4389 bwn_clear_keys(struct bwn_mac *mac) 4390 { 4391 int i; 4392 4393 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4394 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4395 ("%s:%d: fail", __func__, __LINE__)); 4396 4397 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4398 NULL, BWN_SEC_KEYSIZE, NULL); 4399 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4400 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4401 NULL, BWN_SEC_KEYSIZE, NULL); 4402 } 4403 mac->mac_key[i].keyconf = NULL; 4404 } 4405 } 4406 4407 static void 4408 bwn_crypt_init(struct bwn_mac *mac) 4409 { 4410 struct bwn_softc *sc = mac->mac_sc; 4411 4412 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4413 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4414 ("%s:%d: fail", __func__, __LINE__)); 4415 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4416 mac->mac_ktp *= 2; 4417 if (siba_get_revid(sc->sc_dev) >= 5) 4418 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4419 bwn_clear_keys(mac); 4420 } 4421 4422 static void 4423 bwn_chip_exit(struct bwn_mac *mac) 4424 { 4425 struct bwn_softc *sc = mac->mac_sc; 4426 4427 bwn_phy_exit(mac); 4428 siba_gpio_set(sc->sc_dev, 0); 4429 } 4430 4431 static int 4432 bwn_fw_fillinfo(struct bwn_mac *mac) 4433 { 4434 int error; 4435 4436 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4437 if (error == 0) 4438 return (0); 4439 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4440 if (error == 0) 4441 return (0); 4442 return (error); 4443 } 4444 4445 static int 4446 bwn_gpio_init(struct bwn_mac *mac) 4447 { 4448 struct bwn_softc *sc = mac->mac_sc; 4449 uint32_t mask = 0x1f, set = 0xf, value; 4450 4451 BWN_WRITE_4(mac, BWN_MACCTL, 4452 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4453 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4454 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4455 4456 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4457 mask |= 0x0060; 4458 set |= 0x0060; 4459 } 4460 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4461 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4462 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4463 mask |= 0x0200; 4464 set |= 0x0200; 4465 } 4466 if (siba_get_revid(sc->sc_dev) >= 2) 4467 mask |= 0x0010; 4468 4469 value = siba_gpio_get(sc->sc_dev); 4470 if (value == -1) 4471 return (0); 4472 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4473 4474 return (0); 4475 } 4476 4477 static int 4478 bwn_fw_loadinitvals(struct bwn_mac *mac) 4479 { 4480 #define GETFWOFFSET(fwp, offset) \ 4481 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4482 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4483 const struct bwn_fwhdr *hdr; 4484 struct bwn_fw *fw = &mac->mac_fw; 4485 int error; 4486 4487 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4488 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4489 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4490 if (error) 4491 return (error); 4492 if (fw->initvals_band.fw) { 4493 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4494 error = bwn_fwinitvals_write(mac, 4495 GETFWOFFSET(fw->initvals_band, hdr_len), 4496 be32toh(hdr->size), 4497 fw->initvals_band.fw->datasize - hdr_len); 4498 } 4499 return (error); 4500 #undef GETFWOFFSET 4501 } 4502 4503 static int 4504 bwn_phy_init(struct bwn_mac *mac) 4505 { 4506 struct bwn_softc *sc = mac->mac_sc; 4507 int error; 4508 4509 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4510 mac->mac_phy.rf_onoff(mac, 1); 4511 error = mac->mac_phy.init(mac); 4512 if (error) { 4513 device_printf(sc->sc_dev, "PHY init failed\n"); 4514 goto fail0; 4515 } 4516 error = bwn_switch_channel(mac, 4517 mac->mac_phy.get_default_chan(mac)); 4518 if (error) { 4519 device_printf(sc->sc_dev, 4520 "failed to switch default channel\n"); 4521 goto fail1; 4522 } 4523 return (0); 4524 fail1: 4525 if (mac->mac_phy.exit) 4526 mac->mac_phy.exit(mac); 4527 fail0: 4528 mac->mac_phy.rf_onoff(mac, 0); 4529 4530 return (error); 4531 } 4532 4533 static void 4534 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4535 { 4536 uint16_t ant; 4537 uint16_t tmp; 4538 4539 ant = bwn_ant2phy(antenna); 4540 4541 /* For ACK/CTS */ 4542 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4543 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4544 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4545 /* For Probe Resposes */ 4546 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4547 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4548 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4549 } 4550 4551 static void 4552 bwn_set_opmode(struct bwn_mac *mac) 4553 { 4554 struct bwn_softc *sc = mac->mac_sc; 4555 struct ifnet *ifp = sc->sc_ifp; 4556 struct ieee80211com *ic = ifp->if_l2com; 4557 uint32_t ctl; 4558 uint16_t cfp_pretbtt; 4559 4560 ctl = BWN_READ_4(mac, BWN_MACCTL); 4561 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4562 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4563 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4564 ctl |= BWN_MACCTL_STA; 4565 4566 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4567 ic->ic_opmode == IEEE80211_M_MBSS) 4568 ctl |= BWN_MACCTL_HOSTAP; 4569 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4570 ctl &= ~BWN_MACCTL_STA; 4571 ctl |= sc->sc_filters; 4572 4573 if (siba_get_revid(sc->sc_dev) <= 4) 4574 ctl |= BWN_MACCTL_PROMISC; 4575 4576 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4577 4578 cfp_pretbtt = 2; 4579 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4580 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4581 siba_get_chiprev(sc->sc_dev) == 3) 4582 cfp_pretbtt = 100; 4583 else 4584 cfp_pretbtt = 50; 4585 } 4586 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4587 } 4588 4589 static int 4590 bwn_dma_gettype(struct bwn_mac *mac) 4591 { 4592 uint32_t tmp; 4593 uint16_t base; 4594 4595 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4596 if (tmp & SIBA_TGSHIGH_DMA64) 4597 return (BWN_DMA_64BIT); 4598 base = bwn_dma_base(0, 0); 4599 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4600 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4601 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4602 return (BWN_DMA_32BIT); 4603 4604 return (BWN_DMA_30BIT); 4605 } 4606 4607 static void 4608 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4609 { 4610 if (!error) { 4611 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4612 *((bus_addr_t *)arg) = seg->ds_addr; 4613 } 4614 } 4615 4616 static void 4617 bwn_phy_g_init_sub(struct bwn_mac *mac) 4618 { 4619 struct bwn_phy *phy = &mac->mac_phy; 4620 struct bwn_phy_g *pg = &phy->phy_g; 4621 struct bwn_softc *sc = mac->mac_sc; 4622 uint16_t i, tmp; 4623 4624 if (phy->rev == 1) 4625 bwn_phy_init_b5(mac); 4626 else 4627 bwn_phy_init_b6(mac); 4628 4629 if (phy->rev >= 2 || phy->gmode) 4630 bwn_phy_init_a(mac); 4631 4632 if (phy->rev >= 2) { 4633 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4634 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4635 } 4636 if (phy->rev == 2) { 4637 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4638 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4639 } 4640 if (phy->rev > 5) { 4641 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4642 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4643 } 4644 if (phy->gmode || phy->rev >= 2) { 4645 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4646 tmp &= BWN_PHYVER_VERSION; 4647 if (tmp == 3 || tmp == 5) { 4648 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4649 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4650 } 4651 if (tmp == 5) { 4652 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4653 0x1f00); 4654 } 4655 } 4656 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4657 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4658 if (phy->rf_rev == 8) { 4659 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4660 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4661 } 4662 if (BWN_HAS_LOOPBACK(phy)) 4663 bwn_loopback_calcgain(mac); 4664 4665 if (phy->rf_rev != 8) { 4666 if (pg->pg_initval == 0xffff) 4667 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4668 else 4669 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4670 } 4671 bwn_lo_g_init(mac); 4672 if (BWN_HAS_TXMAG(phy)) { 4673 BWN_RF_WRITE(mac, 0x52, 4674 (BWN_RF_READ(mac, 0x52) & 0xff00) 4675 | pg->pg_loctl.tx_bias | 4676 pg->pg_loctl.tx_magn); 4677 } else { 4678 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4679 } 4680 if (phy->rev >= 6) { 4681 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4682 (pg->pg_loctl.tx_bias << 12)); 4683 } 4684 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4685 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4686 else 4687 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4688 if (phy->rev < 2) 4689 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4690 else 4691 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4692 if (phy->gmode || phy->rev >= 2) { 4693 bwn_lo_g_adjust(mac); 4694 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4695 } 4696 4697 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4698 for (i = 0; i < 64; i++) { 4699 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4700 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4701 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4702 -32), 31)); 4703 } 4704 bwn_nrssi_threshold(mac); 4705 } else if (phy->gmode || phy->rev >= 2) { 4706 if (pg->pg_nrssi[0] == -1000) { 4707 KASSERT(pg->pg_nrssi[1] == -1000, 4708 ("%s:%d: fail", __func__, __LINE__)); 4709 bwn_nrssi_slope_11g(mac); 4710 } else 4711 bwn_nrssi_threshold(mac); 4712 } 4713 if (phy->rf_rev == 8) 4714 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4715 bwn_phy_hwpctl_init(mac); 4716 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4717 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4718 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4719 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4720 } 4721 } 4722 4723 static uint8_t 4724 bwn_has_hwpctl(struct bwn_mac *mac) 4725 { 4726 4727 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4728 return (0); 4729 return (mac->mac_phy.use_hwpctl(mac)); 4730 } 4731 4732 static void 4733 bwn_phy_init_b5(struct bwn_mac *mac) 4734 { 4735 struct bwn_phy *phy = &mac->mac_phy; 4736 struct bwn_phy_g *pg = &phy->phy_g; 4737 struct bwn_softc *sc = mac->mac_sc; 4738 uint16_t offset, value; 4739 uint8_t old_channel; 4740 4741 if (phy->analog == 1) 4742 BWN_RF_SET(mac, 0x007a, 0x0050); 4743 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4744 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4745 value = 0x2120; 4746 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4747 BWN_PHY_WRITE(mac, offset, value); 4748 value += 0x202; 4749 } 4750 } 4751 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4752 if (phy->rf_ver == 0x2050) 4753 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4754 4755 if (phy->gmode || phy->rev >= 2) { 4756 if (phy->rf_ver == 0x2050) { 4757 BWN_RF_SET(mac, 0x007a, 0x0020); 4758 BWN_RF_SET(mac, 0x0051, 0x0004); 4759 } 4760 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4761 4762 BWN_PHY_SET(mac, 0x0802, 0x0100); 4763 BWN_PHY_SET(mac, 0x042b, 0x2000); 4764 4765 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4766 4767 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4768 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4769 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4770 } 4771 4772 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4773 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4774 4775 if (phy->analog == 1) { 4776 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4777 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4778 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4779 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4780 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4781 } else 4782 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4783 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4784 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4785 4786 if (phy->analog == 1) 4787 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4788 else 4789 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4790 4791 if (phy->analog == 0) 4792 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4793 4794 old_channel = phy->chan; 4795 bwn_phy_g_switch_chan(mac, 7, 0); 4796 4797 if (phy->rf_ver != 0x2050) { 4798 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4799 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4800 } 4801 4802 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4803 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4804 4805 if (phy->rf_ver == 0x2050) { 4806 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4807 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4808 } 4809 4810 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4811 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4812 BWN_RF_SET(mac, 0x007a, 0x0007); 4813 4814 bwn_phy_g_switch_chan(mac, old_channel, 0); 4815 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4816 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4817 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4818 4819 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4820 pg->pg_txctl); 4821 4822 if (phy->rf_ver == 0x2050) 4823 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4824 4825 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4826 } 4827 4828 static void 4829 bwn_loopback_calcgain(struct bwn_mac *mac) 4830 { 4831 struct bwn_phy *phy = &mac->mac_phy; 4832 struct bwn_phy_g *pg = &phy->phy_g; 4833 struct bwn_softc *sc = mac->mac_sc; 4834 uint16_t backup_phy[16] = { 0 }; 4835 uint16_t backup_radio[3]; 4836 uint16_t backup_bband; 4837 uint16_t i, j, loop_i_max; 4838 uint16_t trsw_rx; 4839 uint16_t loop1_outer_done, loop1_inner_done; 4840 4841 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4842 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4843 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4844 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4845 if (phy->rev != 1) { 4846 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4847 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4848 } 4849 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4850 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4851 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4852 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4853 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4854 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4855 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4856 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4857 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4858 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4859 backup_bband = pg->pg_bbatt.att; 4860 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4861 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4862 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4863 4864 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4865 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4866 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4867 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4868 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4869 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4870 if (phy->rev != 1) { 4871 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4872 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4873 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4874 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4875 } 4876 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4877 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4878 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4879 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4880 4881 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4882 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4883 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4884 4885 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4886 if (phy->rev != 1) { 4887 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4888 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4889 } 4890 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4891 4892 if (phy->rf_rev == 8) 4893 BWN_RF_WRITE(mac, 0x43, 0x000f); 4894 else { 4895 BWN_RF_WRITE(mac, 0x52, 0); 4896 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4897 } 4898 bwn_phy_g_set_bbatt(mac, 11); 4899 4900 if (phy->rev >= 3) 4901 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4902 else 4903 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4904 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4905 4906 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 4907 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 4908 4909 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 4910 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 4911 4912 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 4913 if (phy->rev >= 7) { 4914 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 4915 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 4916 } 4917 } 4918 BWN_RF_MASK(mac, 0x7a, 0x00f7); 4919 4920 j = 0; 4921 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 4922 for (i = 0; i < loop_i_max; i++) { 4923 for (j = 0; j < 16; j++) { 4924 BWN_RF_WRITE(mac, 0x43, i); 4925 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 4926 (j << 8)); 4927 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4928 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4929 DELAY(20); 4930 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4931 goto done0; 4932 } 4933 } 4934 done0: 4935 loop1_outer_done = i; 4936 loop1_inner_done = j; 4937 if (j >= 8) { 4938 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 4939 trsw_rx = 0x1b; 4940 for (j = j - 8; j < 16; j++) { 4941 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 4942 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4943 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4944 DELAY(20); 4945 trsw_rx -= 3; 4946 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4947 goto done1; 4948 } 4949 } else 4950 trsw_rx = 0x18; 4951 done1: 4952 4953 if (phy->rev != 1) { 4954 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 4955 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 4956 } 4957 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 4958 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 4959 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 4960 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 4961 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 4962 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 4963 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 4964 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 4965 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 4966 4967 bwn_phy_g_set_bbatt(mac, backup_bband); 4968 4969 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 4970 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 4971 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 4972 4973 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 4974 DELAY(10); 4975 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 4976 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 4977 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 4978 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 4979 4980 pg->pg_max_lb_gain = 4981 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 4982 pg->pg_trsw_rx_gain = trsw_rx * 2; 4983 } 4984 4985 static uint16_t 4986 bwn_rf_init_bcm2050(struct bwn_mac *mac) 4987 { 4988 struct bwn_phy *phy = &mac->mac_phy; 4989 uint32_t tmp1 = 0, tmp2 = 0; 4990 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 4991 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 4992 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 4993 static const uint8_t rcc_table[] = { 4994 0x02, 0x03, 0x01, 0x0f, 4995 0x06, 0x07, 0x05, 0x0f, 4996 0x0a, 0x0b, 0x09, 0x0f, 4997 0x0e, 0x0f, 0x0d, 0x0f, 4998 }; 4999 5000 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5001 rfoverval = rfover = cck3 = 0; 5002 radio0 = BWN_RF_READ(mac, 0x43); 5003 radio1 = BWN_RF_READ(mac, 0x51); 5004 radio2 = BWN_RF_READ(mac, 0x52); 5005 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5006 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5007 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5008 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5009 5010 if (phy->type == BWN_PHYTYPE_B) { 5011 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5012 reg0 = BWN_READ_2(mac, 0x3ec); 5013 5014 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5015 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5016 } else if (phy->gmode || phy->rev >= 2) { 5017 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5018 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5019 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5020 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5021 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5022 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5023 5024 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5025 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5026 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5027 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5028 if (BWN_HAS_LOOPBACK(phy)) { 5029 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5030 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5031 if (phy->rev >= 3) 5032 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5033 else 5034 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5035 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5036 } 5037 5038 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5039 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5040 BWN_LPD(0, 1, 1))); 5041 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5042 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5043 } 5044 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5045 5046 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5047 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5048 reg1 = BWN_READ_2(mac, 0x3e6); 5049 reg2 = BWN_READ_2(mac, 0x3f4); 5050 5051 if (phy->analog == 0) 5052 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5053 else { 5054 if (phy->analog >= 2) 5055 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5056 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5057 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5058 } 5059 5060 reg = BWN_RF_READ(mac, 0x60); 5061 index = (reg & 0x001e) >> 1; 5062 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5063 5064 if (phy->type == BWN_PHYTYPE_B) 5065 BWN_RF_WRITE(mac, 0x78, 0x26); 5066 if (phy->gmode || phy->rev >= 2) { 5067 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5068 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5069 BWN_LPD(0, 1, 1))); 5070 } 5071 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5072 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5073 if (phy->gmode || phy->rev >= 2) { 5074 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5075 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5076 BWN_LPD(0, 0, 1))); 5077 } 5078 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5079 BWN_RF_SET(mac, 0x51, 0x0004); 5080 if (phy->rf_rev == 8) 5081 BWN_RF_WRITE(mac, 0x43, 0x1f); 5082 else { 5083 BWN_RF_WRITE(mac, 0x52, 0); 5084 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5085 } 5086 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5087 5088 for (i = 0; i < 16; i++) { 5089 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5090 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5091 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5092 if (phy->gmode || phy->rev >= 2) { 5093 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5094 bwn_rf_2050_rfoverval(mac, 5095 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5096 } 5097 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5098 DELAY(10); 5099 if (phy->gmode || phy->rev >= 2) { 5100 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5101 bwn_rf_2050_rfoverval(mac, 5102 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5103 } 5104 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5105 DELAY(10); 5106 if (phy->gmode || phy->rev >= 2) { 5107 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5108 bwn_rf_2050_rfoverval(mac, 5109 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5110 } 5111 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5112 DELAY(20); 5113 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5114 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5115 if (phy->gmode || phy->rev >= 2) { 5116 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5117 bwn_rf_2050_rfoverval(mac, 5118 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5119 } 5120 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5121 } 5122 DELAY(10); 5123 5124 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5125 tmp1++; 5126 tmp1 >>= 9; 5127 5128 for (i = 0; i < 16; i++) { 5129 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5130 BWN_RF_WRITE(mac, 0x78, radio78); 5131 DELAY(10); 5132 for (j = 0; j < 16; j++) { 5133 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5134 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5135 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5136 if (phy->gmode || phy->rev >= 2) { 5137 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5138 bwn_rf_2050_rfoverval(mac, 5139 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5140 } 5141 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5142 DELAY(10); 5143 if (phy->gmode || phy->rev >= 2) { 5144 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5145 bwn_rf_2050_rfoverval(mac, 5146 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5147 } 5148 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5149 DELAY(10); 5150 if (phy->gmode || phy->rev >= 2) { 5151 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5152 bwn_rf_2050_rfoverval(mac, 5153 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5154 } 5155 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5156 DELAY(10); 5157 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5158 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5159 if (phy->gmode || phy->rev >= 2) { 5160 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5161 bwn_rf_2050_rfoverval(mac, 5162 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5163 } 5164 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5165 } 5166 tmp2++; 5167 tmp2 >>= 8; 5168 if (tmp1 < tmp2) 5169 break; 5170 } 5171 5172 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5173 BWN_RF_WRITE(mac, 0x51, radio1); 5174 BWN_RF_WRITE(mac, 0x52, radio2); 5175 BWN_RF_WRITE(mac, 0x43, radio0); 5176 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5177 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5179 BWN_WRITE_2(mac, 0x3e6, reg1); 5180 if (phy->analog != 0) 5181 BWN_WRITE_2(mac, 0x3f4, reg2); 5182 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5183 bwn_spu_workaround(mac, phy->chan); 5184 if (phy->type == BWN_PHYTYPE_B) { 5185 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5186 BWN_WRITE_2(mac, 0x3ec, reg0); 5187 } else if (phy->gmode) { 5188 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5189 BWN_READ_2(mac, BWN_PHY_RADIO) 5190 & 0x7fff); 5191 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5192 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5193 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5194 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5195 analogoverval); 5196 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5197 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5198 if (BWN_HAS_LOOPBACK(phy)) { 5199 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5200 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5201 } 5202 } 5203 5204 return ((i > 15) ? radio78 : rcc); 5205 } 5206 5207 static void 5208 bwn_phy_init_b6(struct bwn_mac *mac) 5209 { 5210 struct bwn_phy *phy = &mac->mac_phy; 5211 struct bwn_phy_g *pg = &phy->phy_g; 5212 struct bwn_softc *sc = mac->mac_sc; 5213 uint16_t offset, val; 5214 uint8_t old_channel; 5215 5216 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5217 ("%s:%d: fail", __func__, __LINE__)); 5218 5219 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5220 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5221 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5222 BWN_RF_WRITE(mac, 0x51, 0x37); 5223 BWN_RF_WRITE(mac, 0x52, 0x70); 5224 BWN_RF_WRITE(mac, 0x53, 0xb3); 5225 BWN_RF_WRITE(mac, 0x54, 0x9b); 5226 BWN_RF_WRITE(mac, 0x5a, 0x88); 5227 BWN_RF_WRITE(mac, 0x5b, 0x88); 5228 BWN_RF_WRITE(mac, 0x5d, 0x88); 5229 BWN_RF_WRITE(mac, 0x5e, 0x88); 5230 BWN_RF_WRITE(mac, 0x7d, 0x88); 5231 bwn_hf_write(mac, 5232 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5233 } 5234 if (phy->rf_rev == 8) { 5235 BWN_RF_WRITE(mac, 0x51, 0); 5236 BWN_RF_WRITE(mac, 0x52, 0x40); 5237 BWN_RF_WRITE(mac, 0x53, 0xb7); 5238 BWN_RF_WRITE(mac, 0x54, 0x98); 5239 BWN_RF_WRITE(mac, 0x5a, 0x88); 5240 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5241 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5242 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5243 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5244 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5245 } else { 5246 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5247 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5248 } 5249 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5250 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5251 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5252 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5253 } 5254 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5255 BWN_PHY_WRITE(mac, offset, val); 5256 val -= 0x0202; 5257 } 5258 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5259 BWN_PHY_WRITE(mac, offset, val); 5260 val -= 0x0202; 5261 } 5262 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5263 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5264 val += 0x0202; 5265 } 5266 if (phy->type == BWN_PHYTYPE_G) { 5267 BWN_RF_SET(mac, 0x007a, 0x0020); 5268 BWN_RF_SET(mac, 0x0051, 0x0004); 5269 BWN_PHY_SET(mac, 0x0802, 0x0100); 5270 BWN_PHY_SET(mac, 0x042b, 0x2000); 5271 BWN_PHY_WRITE(mac, 0x5b, 0); 5272 BWN_PHY_WRITE(mac, 0x5c, 0); 5273 } 5274 5275 old_channel = phy->chan; 5276 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5277 5278 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5279 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5280 DELAY(40); 5281 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5282 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5283 BWN_RF_WRITE(mac, 0x50, 0x20); 5284 } 5285 if (phy->rf_rev <= 2) { 5286 BWN_RF_WRITE(mac, 0x7c, 0x20); 5287 BWN_RF_WRITE(mac, 0x5a, 0x70); 5288 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5289 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5290 } 5291 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5292 5293 bwn_phy_g_switch_chan(mac, old_channel, 0); 5294 5295 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5296 if (phy->rf_rev >= 6) 5297 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5298 else 5299 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5300 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5301 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5302 pg->pg_txctl); 5303 if (phy->rf_rev <= 5) 5304 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5305 if (phy->rf_rev <= 2) 5306 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5307 5308 if (phy->analog == 4) { 5309 BWN_WRITE_2(mac, 0x3e4, 9); 5310 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5311 } else 5312 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5313 if (phy->type == BWN_PHYTYPE_B) 5314 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5315 else if (phy->type == BWN_PHYTYPE_G) 5316 BWN_WRITE_2(mac, 0x03e6, 0x0); 5317 } 5318 5319 static void 5320 bwn_phy_init_a(struct bwn_mac *mac) 5321 { 5322 struct bwn_phy *phy = &mac->mac_phy; 5323 struct bwn_softc *sc = mac->mac_sc; 5324 5325 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5326 ("%s:%d: fail", __func__, __LINE__)); 5327 5328 if (phy->rev >= 6) { 5329 if (phy->type == BWN_PHYTYPE_A) 5330 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5331 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5332 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5333 else 5334 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5335 } 5336 5337 bwn_wa_init(mac); 5338 5339 if (phy->type == BWN_PHYTYPE_G && 5340 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5341 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5342 } 5343 5344 static void 5345 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5346 { 5347 int i; 5348 5349 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5350 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5351 } 5352 5353 static void 5354 bwn_wa_agc(struct bwn_mac *mac) 5355 { 5356 struct bwn_phy *phy = &mac->mac_phy; 5357 5358 if (phy->rev == 1) { 5359 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5360 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5361 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5362 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5363 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5364 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5365 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5366 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5367 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5368 } else { 5369 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5370 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5371 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5372 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5373 } 5374 5375 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5376 0x5700); 5377 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5378 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5379 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5380 BWN_RF_SET(mac, 0x7a, 0x0008); 5381 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5382 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5383 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5384 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5385 if (phy->rev == 1) 5386 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5387 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5388 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5389 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5390 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5391 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5392 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5393 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5394 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5395 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5396 if (phy->rev == 1) { 5397 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5398 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5399 } else { 5400 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5401 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5402 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5403 if (phy->rev >= 6) { 5404 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5405 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5406 (uint16_t)~0xf000, 0x3000); 5407 } 5408 } 5409 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5410 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5411 if (phy->rev == 1) { 5412 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5413 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5414 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5415 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5416 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5417 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5418 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5419 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5420 } else { 5421 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5422 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5423 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5424 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5425 } 5426 if (phy->rev >= 6) { 5427 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5428 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5429 } 5430 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5431 } 5432 5433 static void 5434 bwn_wa_grev1(struct bwn_mac *mac) 5435 { 5436 struct bwn_phy *phy = &mac->mac_phy; 5437 int i; 5438 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5439 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5440 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5441 5442 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5443 5444 /* init CRSTHRES and ANTDWELL */ 5445 if (phy->rev == 1) { 5446 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5447 } else if (phy->rev == 2) { 5448 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5449 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5450 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5451 } else { 5452 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5453 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5454 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5455 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5456 } 5457 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5458 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5459 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5460 5461 /* XXX support PHY-A??? */ 5462 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5464 bwn_tab_finefreqg[i]); 5465 5466 /* XXX support PHY-A??? */ 5467 if (phy->rev == 1) 5468 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5470 bwn_tab_noise_g1[i]); 5471 else 5472 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5473 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5474 bwn_tab_noise_g2[i]); 5475 5476 5477 for (i = 0; i < N(bwn_tab_rotor); i++) 5478 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5479 bwn_tab_rotor[i]); 5480 5481 /* XXX support PHY-A??? */ 5482 if (phy->rev >= 6) { 5483 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5484 BWN_PHY_ENCORE_EN) 5485 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5486 else 5487 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5488 } else 5489 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5490 5491 for (i = 0; i < N(bwn_tab_retard); i++) 5492 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5493 bwn_tab_retard[i]); 5494 5495 if (phy->rev == 1) { 5496 for (i = 0; i < 16; i++) 5497 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5498 i, 0x0020); 5499 } else { 5500 for (i = 0; i < 32; i++) 5501 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5502 } 5503 5504 bwn_wa_agc(mac); 5505 } 5506 5507 static void 5508 bwn_wa_grev26789(struct bwn_mac *mac) 5509 { 5510 struct bwn_phy *phy = &mac->mac_phy; 5511 int i; 5512 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5513 uint16_t ofdmrev; 5514 5515 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5516 5517 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5518 5519 /* init CRSTHRES and ANTDWELL */ 5520 if (phy->rev == 1) 5521 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5522 else if (phy->rev == 2) { 5523 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5524 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5525 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5526 } else { 5527 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5528 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5529 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5530 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5531 } 5532 5533 for (i = 0; i < 64; i++) 5534 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5535 5536 /* XXX support PHY-A??? */ 5537 if (phy->rev == 1) 5538 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5539 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5540 bwn_tab_noise_g1[i]); 5541 else 5542 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5543 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5544 bwn_tab_noise_g2[i]); 5545 5546 /* XXX support PHY-A??? */ 5547 if (phy->rev >= 6) { 5548 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5549 BWN_PHY_ENCORE_EN) 5550 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5551 else 5552 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5553 } else 5554 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5555 5556 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5557 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5558 bwn_tab_sigmasqr2[i]); 5559 5560 if (phy->rev == 1) { 5561 for (i = 0; i < 16; i++) 5562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5563 0x0020); 5564 } else { 5565 for (i = 0; i < 32; i++) 5566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5567 } 5568 5569 bwn_wa_agc(mac); 5570 5571 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5572 if (ofdmrev > 2) { 5573 if (phy->type == BWN_PHYTYPE_A) 5574 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5575 else 5576 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5577 } else { 5578 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5579 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5580 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5581 } 5582 5583 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5584 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5585 } 5586 5587 static void 5588 bwn_wa_init(struct bwn_mac *mac) 5589 { 5590 struct bwn_phy *phy = &mac->mac_phy; 5591 struct bwn_softc *sc = mac->mac_sc; 5592 5593 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5594 5595 switch (phy->rev) { 5596 case 1: 5597 bwn_wa_grev1(mac); 5598 break; 5599 case 2: 5600 case 6: 5601 case 7: 5602 case 8: 5603 case 9: 5604 bwn_wa_grev26789(mac); 5605 break; 5606 default: 5607 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5608 } 5609 5610 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5611 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5612 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5613 if (phy->rev < 2) { 5614 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5615 0x0002); 5616 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5617 0x0001); 5618 } else { 5619 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5620 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5621 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5622 BWN_BFL_EXTLNA) && 5623 (phy->rev >= 7)) { 5624 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5625 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5626 0x0020, 0x0001); 5627 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5628 0x0021, 0x0001); 5629 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5630 0x0022, 0x0001); 5631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5632 0x0023, 0x0000); 5633 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5634 0x0000, 0x0000); 5635 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5636 0x0003, 0x0002); 5637 } 5638 } 5639 } 5640 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5641 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5642 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5643 } 5644 5645 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5646 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5647 } 5648 5649 static void 5650 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5651 uint16_t value) 5652 { 5653 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5654 uint16_t addr; 5655 5656 addr = table + offset; 5657 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5658 (addr - 1 != pg->pg_ofdmtab_addr)) { 5659 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5660 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5661 } 5662 pg->pg_ofdmtab_addr = addr; 5663 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5664 } 5665 5666 static void 5667 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5668 uint32_t value) 5669 { 5670 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5671 uint16_t addr; 5672 5673 addr = table + offset; 5674 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5675 (addr - 1 != pg->pg_ofdmtab_addr)) { 5676 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5677 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5678 } 5679 pg->pg_ofdmtab_addr = addr; 5680 5681 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5682 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5683 } 5684 5685 static void 5686 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5687 uint16_t value) 5688 { 5689 5690 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5691 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5692 } 5693 5694 static void 5695 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5696 { 5697 struct bwn_phy *phy = &mac->mac_phy; 5698 struct bwn_softc *sc = mac->mac_sc; 5699 unsigned int i, max_loop; 5700 uint16_t value; 5701 uint32_t buffer[5] = { 5702 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5703 }; 5704 5705 if (ofdm) { 5706 max_loop = 0x1e; 5707 buffer[0] = 0x000201cc; 5708 } else { 5709 max_loop = 0xfa; 5710 buffer[0] = 0x000b846e; 5711 } 5712 5713 for (i = 0; i < 5; i++) 5714 bwn_ram_write(mac, i * 4, buffer[i]); 5715 5716 BWN_WRITE_2(mac, 0x0568, 0x0000); 5717 BWN_WRITE_2(mac, 0x07c0, 5718 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5719 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5720 BWN_WRITE_2(mac, 0x050c, value); 5721 if (phy->type == BWN_PHYTYPE_LP) 5722 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5723 BWN_WRITE_2(mac, 0x0508, 0x0000); 5724 BWN_WRITE_2(mac, 0x050a, 0x0000); 5725 BWN_WRITE_2(mac, 0x054c, 0x0000); 5726 BWN_WRITE_2(mac, 0x056a, 0x0014); 5727 BWN_WRITE_2(mac, 0x0568, 0x0826); 5728 BWN_WRITE_2(mac, 0x0500, 0x0000); 5729 if (phy->type == BWN_PHYTYPE_LP) 5730 BWN_WRITE_2(mac, 0x0502, 0x0050); 5731 else 5732 BWN_WRITE_2(mac, 0x0502, 0x0030); 5733 5734 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5735 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5736 for (i = 0x00; i < max_loop; i++) { 5737 value = BWN_READ_2(mac, 0x050e); 5738 if (value & 0x0080) 5739 break; 5740 DELAY(10); 5741 } 5742 for (i = 0x00; i < 0x0a; i++) { 5743 value = BWN_READ_2(mac, 0x050e); 5744 if (value & 0x0400) 5745 break; 5746 DELAY(10); 5747 } 5748 for (i = 0x00; i < 0x19; i++) { 5749 value = BWN_READ_2(mac, 0x0690); 5750 if (!(value & 0x0100)) 5751 break; 5752 DELAY(10); 5753 } 5754 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5755 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5756 } 5757 5758 static void 5759 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5760 { 5761 uint32_t macctl; 5762 5763 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5764 5765 macctl = BWN_READ_4(mac, BWN_MACCTL); 5766 if (macctl & BWN_MACCTL_BIGENDIAN) 5767 kprintf("TODO: need swap\n"); 5768 5769 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5770 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5771 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5772 } 5773 5774 static void 5775 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5776 { 5777 uint16_t value; 5778 5779 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5780 ("%s:%d: fail", __func__, __LINE__)); 5781 5782 value = (uint8_t) (ctl->q); 5783 value |= ((uint8_t) (ctl->i)) << 8; 5784 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5785 } 5786 5787 static uint16_t 5788 bwn_lo_calcfeed(struct bwn_mac *mac, 5789 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5790 { 5791 struct bwn_phy *phy = &mac->mac_phy; 5792 struct bwn_softc *sc = mac->mac_sc; 5793 uint16_t rfover; 5794 uint16_t feedthrough; 5795 5796 if (phy->gmode) { 5797 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5798 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5799 5800 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5801 ("%s:%d: fail", __func__, __LINE__)); 5802 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5803 ("%s:%d: fail", __func__, __LINE__)); 5804 5805 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5806 5807 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5808 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5809 phy->rev > 6) 5810 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5811 5812 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5813 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5814 DELAY(10); 5815 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5816 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5817 DELAY(10); 5818 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5819 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5820 DELAY(10); 5821 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5822 } else { 5823 pga |= BWN_PHY_PGACTL_UNKNOWN; 5824 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5825 DELAY(10); 5826 pga |= BWN_PHY_PGACTL_LOWBANDW; 5827 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5828 DELAY(10); 5829 pga |= BWN_PHY_PGACTL_LPF; 5830 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5831 } 5832 DELAY(21); 5833 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5834 5835 return (feedthrough); 5836 } 5837 5838 static uint16_t 5839 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5840 uint16_t *value, uint16_t *pad_mix_gain) 5841 { 5842 struct bwn_phy *phy = &mac->mac_phy; 5843 uint16_t reg, v, padmix; 5844 5845 if (phy->type == BWN_PHYTYPE_B) { 5846 v = 0x30; 5847 if (phy->rf_rev <= 5) { 5848 reg = 0x43; 5849 padmix = 0; 5850 } else { 5851 reg = 0x52; 5852 padmix = 5; 5853 } 5854 } else { 5855 if (phy->rev >= 2 && phy->rf_rev == 8) { 5856 reg = 0x43; 5857 v = 0x10; 5858 padmix = 2; 5859 } else { 5860 reg = 0x52; 5861 v = 0x30; 5862 padmix = 5; 5863 } 5864 } 5865 if (value) 5866 *value = v; 5867 if (pad_mix_gain) 5868 *pad_mix_gain = padmix; 5869 5870 return (reg); 5871 } 5872 5873 static void 5874 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5875 { 5876 struct bwn_phy *phy = &mac->mac_phy; 5877 struct bwn_phy_g *pg = &phy->phy_g; 5878 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5879 uint16_t reg, mask; 5880 uint16_t trsw_rx, pga; 5881 uint16_t rf_pctl_reg; 5882 5883 static const uint8_t tx_bias_values[] = { 5884 0x09, 0x08, 0x0a, 0x01, 0x00, 5885 0x02, 0x05, 0x04, 0x06, 5886 }; 5887 static const uint8_t tx_magn_values[] = { 5888 0x70, 0x40, 5889 }; 5890 5891 if (!BWN_HAS_LOOPBACK(phy)) { 5892 rf_pctl_reg = 6; 5893 trsw_rx = 2; 5894 pga = 0; 5895 } else { 5896 int lb_gain; 5897 5898 trsw_rx = 0; 5899 lb_gain = pg->pg_max_lb_gain / 2; 5900 if (lb_gain > 10) { 5901 rf_pctl_reg = 0; 5902 pga = abs(10 - lb_gain) / 6; 5903 pga = MIN(MAX(pga, 0), 15); 5904 } else { 5905 int cmp_val; 5906 int tmp; 5907 5908 pga = 0; 5909 cmp_val = 0x24; 5910 if ((phy->rev >= 2) && 5911 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 5912 cmp_val = 0x3c; 5913 tmp = lb_gain; 5914 if ((10 - lb_gain) < cmp_val) 5915 tmp = (10 - lb_gain); 5916 if (tmp < 0) 5917 tmp += 6; 5918 else 5919 tmp += 3; 5920 cmp_val /= 4; 5921 tmp /= 4; 5922 if (tmp >= cmp_val) 5923 rf_pctl_reg = cmp_val; 5924 else 5925 rf_pctl_reg = tmp; 5926 } 5927 } 5928 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 5929 bwn_phy_g_set_bbatt(mac, 2); 5930 5931 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 5932 mask = ~mask; 5933 BWN_RF_MASK(mac, reg, mask); 5934 5935 if (BWN_HAS_TXMAG(phy)) { 5936 int i, j; 5937 int feedthrough; 5938 int min_feedth = 0xffff; 5939 uint8_t tx_magn, tx_bias; 5940 5941 for (i = 0; i < N(tx_magn_values); i++) { 5942 tx_magn = tx_magn_values[i]; 5943 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 5944 for (j = 0; j < N(tx_bias_values); j++) { 5945 tx_bias = tx_bias_values[j]; 5946 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 5947 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 5948 trsw_rx); 5949 if (feedthrough < min_feedth) { 5950 lo->tx_bias = tx_bias; 5951 lo->tx_magn = tx_magn; 5952 min_feedth = feedthrough; 5953 } 5954 if (lo->tx_bias == 0) 5955 break; 5956 } 5957 BWN_RF_WRITE(mac, 0x52, 5958 (BWN_RF_READ(mac, 0x52) 5959 & 0xff00) | lo->tx_bias | lo-> 5960 tx_magn); 5961 } 5962 } else { 5963 lo->tx_magn = 0; 5964 lo->tx_bias = 0; 5965 BWN_RF_MASK(mac, 0x52, 0xfff0); 5966 } 5967 5968 BWN_GETTIME(lo->txctl_measured_time); 5969 } 5970 5971 static void 5972 bwn_lo_get_powervector(struct bwn_mac *mac) 5973 { 5974 struct bwn_phy *phy = &mac->mac_phy; 5975 struct bwn_phy_g *pg = &phy->phy_g; 5976 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5977 int i; 5978 uint64_t tmp; 5979 uint64_t power_vector = 0; 5980 5981 for (i = 0; i < 8; i += 2) { 5982 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 5983 power_vector |= (tmp << (i * 8)); 5984 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 5985 } 5986 if (power_vector) 5987 lo->power_vector = power_vector; 5988 5989 BWN_GETTIME(lo->pwr_vec_read_time); 5990 } 5991 5992 static void 5993 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 5994 int use_trsw_rx) 5995 { 5996 struct bwn_phy *phy = &mac->mac_phy; 5997 struct bwn_phy_g *pg = &phy->phy_g; 5998 uint16_t tmp; 5999 6000 if (max_rx_gain < 0) 6001 max_rx_gain = 0; 6002 6003 if (BWN_HAS_LOOPBACK(phy)) { 6004 int trsw_rx = 0; 6005 int trsw_rx_gain; 6006 6007 if (use_trsw_rx) { 6008 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6009 if (max_rx_gain >= trsw_rx_gain) { 6010 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6011 trsw_rx = 0x20; 6012 } 6013 } else 6014 trsw_rx_gain = max_rx_gain; 6015 if (trsw_rx_gain < 9) { 6016 pg->pg_lna_lod_gain = 0; 6017 } else { 6018 pg->pg_lna_lod_gain = 1; 6019 trsw_rx_gain -= 8; 6020 } 6021 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6022 pg->pg_pga_gain = trsw_rx_gain / 3; 6023 if (pg->pg_pga_gain >= 5) { 6024 pg->pg_pga_gain -= 5; 6025 pg->pg_lna_gain = 2; 6026 } else 6027 pg->pg_lna_gain = 0; 6028 } else { 6029 pg->pg_lna_gain = 0; 6030 pg->pg_trsw_rx_gain = 0x20; 6031 if (max_rx_gain >= 0x14) { 6032 pg->pg_lna_lod_gain = 1; 6033 pg->pg_pga_gain = 2; 6034 } else if (max_rx_gain >= 0x12) { 6035 pg->pg_lna_lod_gain = 1; 6036 pg->pg_pga_gain = 1; 6037 } else if (max_rx_gain >= 0xf) { 6038 pg->pg_lna_lod_gain = 1; 6039 pg->pg_pga_gain = 0; 6040 } else { 6041 pg->pg_lna_lod_gain = 0; 6042 pg->pg_pga_gain = 0; 6043 } 6044 } 6045 6046 tmp = BWN_RF_READ(mac, 0x7a); 6047 if (pg->pg_lna_lod_gain == 0) 6048 tmp &= ~0x0008; 6049 else 6050 tmp |= 0x0008; 6051 BWN_RF_WRITE(mac, 0x7a, tmp); 6052 } 6053 6054 static void 6055 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6056 { 6057 struct bwn_phy *phy = &mac->mac_phy; 6058 struct bwn_phy_g *pg = &phy->phy_g; 6059 struct bwn_softc *sc = mac->mac_sc; 6060 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6061 struct timespec ts; 6062 uint16_t tmp; 6063 6064 if (bwn_has_hwpctl(mac)) { 6065 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6066 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6067 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6068 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6069 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6070 6071 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6072 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6073 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6074 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6075 } 6076 if (phy->type == BWN_PHYTYPE_B && 6077 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6078 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6079 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6080 } 6081 if (phy->rev >= 2) { 6082 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6083 sav->phy_analogoverval = 6084 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6085 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6086 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6087 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6088 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6089 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6090 6091 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6092 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6093 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6094 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6095 if (phy->type == BWN_PHYTYPE_G) { 6096 if ((phy->rev >= 7) && 6097 (siba_sprom_get_bf_lo(sc->sc_dev) & 6098 BWN_BFL_EXTLNA)) { 6099 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6100 } else { 6101 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6102 } 6103 } else { 6104 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6105 } 6106 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6107 } 6108 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6109 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6110 sav->rf0 = BWN_RF_READ(mac, 0x43); 6111 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6112 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6113 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6114 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6115 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6116 6117 if (!BWN_HAS_TXMAG(phy)) { 6118 sav->rf2 = BWN_RF_READ(mac, 0x52); 6119 sav->rf2 &= 0x00f0; 6120 } 6121 if (phy->type == BWN_PHYTYPE_B) { 6122 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6123 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6124 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6125 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6126 } else { 6127 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6128 | 0x8000); 6129 } 6130 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6131 & 0xf000); 6132 6133 tmp = 6134 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6135 BWN_PHY_WRITE(mac, tmp, 0x007f); 6136 6137 tmp = sav->phy_syncctl; 6138 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6139 tmp = sav->rf1; 6140 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6141 6142 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6143 if (phy->type == BWN_PHYTYPE_G || 6144 (phy->type == BWN_PHYTYPE_B && 6145 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6146 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6147 } else 6148 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6149 if (phy->rev >= 2) 6150 bwn_dummy_transmission(mac, 0, 1); 6151 bwn_phy_g_switch_chan(mac, 6, 0); 6152 BWN_RF_READ(mac, 0x51); 6153 if (phy->type == BWN_PHYTYPE_G) 6154 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6155 6156 nanouptime(&ts); 6157 if (time_before(lo->txctl_measured_time, 6158 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6159 bwn_lo_measure_txctl_values(mac); 6160 6161 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6162 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6163 else { 6164 if (phy->type == BWN_PHYTYPE_B) 6165 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6166 else 6167 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6168 } 6169 } 6170 6171 static void 6172 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6173 { 6174 struct bwn_phy *phy = &mac->mac_phy; 6175 struct bwn_phy_g *pg = &phy->phy_g; 6176 uint16_t tmp; 6177 6178 if (phy->rev >= 2) { 6179 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6180 tmp = (pg->pg_pga_gain << 8); 6181 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6182 DELAY(5); 6183 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6184 DELAY(2); 6185 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6186 } else { 6187 tmp = (pg->pg_pga_gain | 0xefa0); 6188 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6189 } 6190 if (phy->type == BWN_PHYTYPE_G) { 6191 if (phy->rev >= 3) 6192 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6193 else 6194 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6195 if (phy->rev >= 2) 6196 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6197 else 6198 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6199 } 6200 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6201 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6202 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6203 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6204 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6205 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6206 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6207 if (!BWN_HAS_TXMAG(phy)) { 6208 tmp = sav->rf2; 6209 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6210 } 6211 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6212 if (phy->type == BWN_PHYTYPE_B && 6213 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6214 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6215 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6216 } 6217 if (phy->rev >= 2) { 6218 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6219 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6220 sav->phy_analogoverval); 6221 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6222 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6223 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6224 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6225 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6226 } 6227 if (bwn_has_hwpctl(mac)) { 6228 tmp = (sav->phy_lomask & 0xbfff); 6229 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6230 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6231 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6233 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6234 } 6235 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6236 } 6237 6238 static int 6239 bwn_lo_probe_loctl(struct bwn_mac *mac, 6240 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6241 { 6242 struct bwn_phy *phy = &mac->mac_phy; 6243 struct bwn_phy_g *pg = &phy->phy_g; 6244 struct bwn_loctl orig, test; 6245 struct bwn_loctl prev = { -100, -100 }; 6246 static const struct bwn_loctl modifiers[] = { 6247 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6248 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6249 }; 6250 int begin, end, lower = 0, i; 6251 uint16_t feedth; 6252 6253 if (d->curstate == 0) { 6254 begin = 1; 6255 end = 8; 6256 } else if (d->curstate % 2 == 0) { 6257 begin = d->curstate - 1; 6258 end = d->curstate + 1; 6259 } else { 6260 begin = d->curstate - 2; 6261 end = d->curstate + 2; 6262 } 6263 if (begin < 1) 6264 begin += 8; 6265 if (end > 8) 6266 end -= 8; 6267 6268 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6269 i = begin; 6270 d->curstate = i; 6271 while (1) { 6272 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6273 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6274 test.i += modifiers[i - 1].i * d->multipler; 6275 test.q += modifiers[i - 1].q * d->multipler; 6276 if ((test.i != prev.i || test.q != prev.q) && 6277 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6278 bwn_lo_write(mac, &test); 6279 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6280 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6281 if (feedth < d->feedth) { 6282 memcpy(probe, &test, 6283 sizeof(struct bwn_loctl)); 6284 lower = 1; 6285 d->feedth = feedth; 6286 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6287 break; 6288 } 6289 } 6290 memcpy(&prev, &test, sizeof(prev)); 6291 if (i == end) 6292 break; 6293 if (i == 8) 6294 i = 1; 6295 else 6296 i++; 6297 d->curstate = i; 6298 } 6299 6300 return (lower); 6301 } 6302 6303 static void 6304 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6305 { 6306 struct bwn_phy *phy = &mac->mac_phy; 6307 struct bwn_phy_g *pg = &phy->phy_g; 6308 struct bwn_lo_g_sm d; 6309 struct bwn_loctl probe; 6310 int lower, repeat, cnt = 0; 6311 uint16_t feedth; 6312 6313 d.nmeasure = 0; 6314 d.multipler = 1; 6315 if (BWN_HAS_LOOPBACK(phy)) 6316 d.multipler = 3; 6317 6318 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6319 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6320 6321 do { 6322 bwn_lo_write(mac, &d.loctl); 6323 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6324 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6325 if (feedth < 0x258) { 6326 if (feedth >= 0x12c) 6327 *rxgain += 6; 6328 else 6329 *rxgain += 3; 6330 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6331 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6332 } 6333 d.feedth = feedth; 6334 d.curstate = 0; 6335 do { 6336 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6337 ("%s:%d: fail", __func__, __LINE__)); 6338 memcpy(&probe, &d.loctl, 6339 sizeof(struct bwn_loctl)); 6340 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6341 if (!lower) 6342 break; 6343 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6344 break; 6345 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6346 d.nmeasure++; 6347 } while (d.nmeasure < 24); 6348 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6349 6350 if (BWN_HAS_LOOPBACK(phy)) { 6351 if (d.feedth > 0x1194) 6352 *rxgain -= 6; 6353 else if (d.feedth < 0x5dc) 6354 *rxgain += 3; 6355 if (cnt == 0) { 6356 if (d.feedth <= 0x5dc) { 6357 d.multipler = 1; 6358 cnt++; 6359 } else 6360 d.multipler = 2; 6361 } else if (cnt == 2) 6362 d.multipler = 1; 6363 } 6364 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6365 } while (++cnt < repeat); 6366 } 6367 6368 static struct bwn_lo_calib * 6369 bwn_lo_calibset(struct bwn_mac *mac, 6370 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6371 { 6372 struct bwn_phy *phy = &mac->mac_phy; 6373 struct bwn_phy_g *pg = &phy->phy_g; 6374 struct bwn_loctl loctl = { 0, 0 }; 6375 struct bwn_lo_calib *cal; 6376 struct bwn_lo_g_value sval = { 0 }; 6377 int rxgain; 6378 uint16_t pad, reg, value; 6379 6380 sval.old_channel = phy->chan; 6381 bwn_mac_suspend(mac); 6382 bwn_lo_save(mac, &sval); 6383 6384 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6385 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6386 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6387 6388 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6389 if (rfatt->padmix) 6390 rxgain -= pad; 6391 if (BWN_HAS_LOOPBACK(phy)) 6392 rxgain += pg->pg_max_lb_gain; 6393 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6394 bwn_phy_g_set_bbatt(mac, bbatt->att); 6395 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6396 6397 bwn_lo_restore(mac, &sval); 6398 bwn_mac_enable(mac); 6399 6400 cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO); 6401 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6402 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6403 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6404 6405 BWN_GETTIME(cal->calib_time); 6406 6407 return (cal); 6408 } 6409 6410 static struct bwn_lo_calib * 6411 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6412 const struct bwn_rfatt *rfatt) 6413 { 6414 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6415 struct bwn_lo_calib *c; 6416 6417 TAILQ_FOREACH(c, &lo->calib_list, list) { 6418 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6419 continue; 6420 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6421 continue; 6422 return (c); 6423 } 6424 6425 c = bwn_lo_calibset(mac, bbatt, rfatt); 6426 if (c == NULL) /* XXX ivadasz: can't happen */ 6427 return (NULL); 6428 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6429 6430 return (c); 6431 } 6432 6433 static void 6434 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6435 { 6436 struct bwn_phy *phy = &mac->mac_phy; 6437 struct bwn_phy_g *pg = &phy->phy_g; 6438 struct bwn_softc *sc = mac->mac_sc; 6439 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6440 const struct bwn_rfatt *rfatt; 6441 const struct bwn_bbatt *bbatt; 6442 uint64_t pvector; 6443 int i; 6444 int rf_offset, bb_offset; 6445 uint8_t changed = 0; 6446 6447 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6448 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6449 ("%s:%d: fail", __func__, __LINE__)); 6450 6451 pvector = lo->power_vector; 6452 if (!update && !pvector) 6453 return; 6454 6455 bwn_mac_suspend(mac); 6456 6457 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6458 struct bwn_lo_calib *cal; 6459 int idx; 6460 uint16_t val; 6461 6462 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6463 continue; 6464 bb_offset = i / lo->rfatt.len; 6465 rf_offset = i % lo->rfatt.len; 6466 bbatt = &(lo->bbatt.array[bb_offset]); 6467 rfatt = &(lo->rfatt.array[rf_offset]); 6468 6469 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6470 if (cal == NULL) { /* XXX ivadasz: can't happen */ 6471 device_printf(sc->sc_dev, "LO: Could not " 6472 "calibrate DC table entry\n"); 6473 continue; 6474 } 6475 val = (uint8_t)(cal->ctl.q); 6476 val |= ((uint8_t)(cal->ctl.i)) << 4; 6477 kfree(cal, M_DEVBUF); 6478 6479 idx = i / 2; 6480 if (i % 2) 6481 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6482 | ((val & 0x00ff) << 8); 6483 else 6484 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6485 | (val & 0x00ff); 6486 changed = 1; 6487 } 6488 if (changed) { 6489 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6490 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6491 } 6492 bwn_mac_enable(mac); 6493 } 6494 6495 static void 6496 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6497 { 6498 6499 if (!rf->padmix) 6500 return; 6501 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6502 rf->att = 4; 6503 } 6504 6505 static void 6506 bwn_lo_g_adjust(struct bwn_mac *mac) 6507 { 6508 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6509 struct bwn_lo_calib *cal; 6510 struct bwn_rfatt rf; 6511 6512 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6513 bwn_lo_fixup_rfatt(&rf); 6514 6515 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6516 if (cal == NULL) /* XXX ivadasz: can't happen */ 6517 return; 6518 bwn_lo_write(mac, &cal->ctl); 6519 } 6520 6521 static void 6522 bwn_lo_g_init(struct bwn_mac *mac) 6523 { 6524 6525 if (!bwn_has_hwpctl(mac)) 6526 return; 6527 6528 bwn_lo_get_powervector(mac); 6529 bwn_phy_g_dc_lookup_init(mac, 1); 6530 } 6531 6532 static void 6533 bwn_mac_suspend(struct bwn_mac *mac) 6534 { 6535 struct bwn_softc *sc = mac->mac_sc; 6536 int i; 6537 uint32_t tmp; 6538 6539 KASSERT(mac->mac_suspended >= 0, 6540 ("%s:%d: fail", __func__, __LINE__)); 6541 6542 if (mac->mac_suspended == 0) { 6543 bwn_psctl(mac, BWN_PS_AWAKE); 6544 BWN_WRITE_4(mac, BWN_MACCTL, 6545 BWN_READ_4(mac, BWN_MACCTL) 6546 & ~BWN_MACCTL_ON); 6547 BWN_READ_4(mac, BWN_MACCTL); 6548 for (i = 35; i; i--) { 6549 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6550 if (tmp & BWN_INTR_MAC_SUSPENDED) 6551 goto out; 6552 DELAY(10); 6553 } 6554 for (i = 40; i; i--) { 6555 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6556 if (tmp & BWN_INTR_MAC_SUSPENDED) 6557 goto out; 6558 DELAY(1000); 6559 } 6560 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6561 } 6562 out: 6563 mac->mac_suspended++; 6564 } 6565 6566 static void 6567 bwn_mac_enable(struct bwn_mac *mac) 6568 { 6569 struct bwn_softc *sc = mac->mac_sc; 6570 uint16_t state; 6571 6572 state = bwn_shm_read_2(mac, BWN_SHARED, 6573 BWN_SHARED_UCODESTAT); 6574 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6575 state != BWN_SHARED_UCODESTAT_SLEEP) 6576 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6577 6578 mac->mac_suspended--; 6579 KASSERT(mac->mac_suspended >= 0, 6580 ("%s:%d: fail", __func__, __LINE__)); 6581 if (mac->mac_suspended == 0) { 6582 BWN_WRITE_4(mac, BWN_MACCTL, 6583 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6584 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6585 BWN_READ_4(mac, BWN_MACCTL); 6586 BWN_READ_4(mac, BWN_INTR_REASON); 6587 bwn_psctl(mac, 0); 6588 } 6589 } 6590 6591 static void 6592 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6593 { 6594 struct bwn_softc *sc = mac->mac_sc; 6595 int i; 6596 uint16_t ucstat; 6597 6598 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6599 ("%s:%d: fail", __func__, __LINE__)); 6600 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6601 ("%s:%d: fail", __func__, __LINE__)); 6602 6603 /* XXX forcibly awake and hwps-off */ 6604 6605 BWN_WRITE_4(mac, BWN_MACCTL, 6606 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6607 ~BWN_MACCTL_HWPS); 6608 BWN_READ_4(mac, BWN_MACCTL); 6609 if (siba_get_revid(sc->sc_dev) >= 5) { 6610 for (i = 0; i < 100; i++) { 6611 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6612 BWN_SHARED_UCODESTAT); 6613 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6614 break; 6615 DELAY(10); 6616 } 6617 } 6618 } 6619 6620 static int16_t 6621 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6622 { 6623 6624 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6625 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6626 } 6627 6628 static void 6629 bwn_nrssi_threshold(struct bwn_mac *mac) 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 int32_t a, b; 6635 int16_t tmp16; 6636 uint16_t tmpu16; 6637 6638 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6639 6640 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6641 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6642 a = 0x13; 6643 b = 0x12; 6644 } else { 6645 a = 0xe; 6646 b = 0x11; 6647 } 6648 6649 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6650 a += (pg->pg_nrssi[0] << 6); 6651 a += (a < 32) ? 31 : 32; 6652 a = a >> 6; 6653 a = MIN(MAX(a, -31), 31); 6654 6655 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6656 b += (pg->pg_nrssi[0] << 6); 6657 if (b < 32) 6658 b += 31; 6659 else 6660 b += 32; 6661 b = b >> 6; 6662 b = MIN(MAX(b, -31), 31); 6663 6664 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6665 tmpu16 |= ((uint32_t)b & 0x0000003f); 6666 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6667 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6668 return; 6669 } 6670 6671 tmp16 = bwn_nrssi_read(mac, 0x20); 6672 if (tmp16 >= 0x20) 6673 tmp16 -= 0x40; 6674 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6675 } 6676 6677 static void 6678 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6679 { 6680 #define SAVE_RF_MAX 3 6681 #define SAVE_PHY_COMM_MAX 4 6682 #define SAVE_PHY3_MAX 8 6683 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6684 { 0x7a, 0x52, 0x43 }; 6685 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6686 { 0x15, 0x5a, 0x59, 0x58 }; 6687 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6688 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6689 0x0801, 0x0060, 0x0014, 0x0478 6690 }; 6691 struct bwn_phy *phy = &mac->mac_phy; 6692 struct bwn_phy_g *pg = &phy->phy_g; 6693 int32_t i, tmp32, phy3_idx = 0; 6694 uint16_t delta, tmp; 6695 uint16_t save_rf[SAVE_RF_MAX]; 6696 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6697 uint16_t save_phy3[SAVE_PHY3_MAX]; 6698 uint16_t ant_div, phy0, chan_ex; 6699 int16_t nrssi0, nrssi1; 6700 6701 KASSERT(phy->type == BWN_PHYTYPE_G, 6702 ("%s:%d: fail", __func__, __LINE__)); 6703 6704 if (phy->rf_rev >= 9) 6705 return; 6706 if (phy->rf_rev == 8) 6707 bwn_nrssi_offset(mac); 6708 6709 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6710 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6711 6712 /* 6713 * Save RF/PHY registers for later restoration 6714 */ 6715 ant_div = BWN_READ_2(mac, 0x03e2); 6716 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6717 for (i = 0; i < SAVE_RF_MAX; ++i) 6718 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6719 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6720 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6721 6722 phy0 = BWN_READ_2(mac, BWN_PHY0); 6723 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6724 if (phy->rev >= 3) { 6725 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6726 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6727 BWN_PHY_WRITE(mac, 0x002e, 0); 6728 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6729 switch (phy->rev) { 6730 case 4: 6731 case 6: 6732 case 7: 6733 BWN_PHY_SET(mac, 0x0478, 0x0100); 6734 BWN_PHY_SET(mac, 0x0801, 0x0040); 6735 break; 6736 case 3: 6737 case 5: 6738 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6739 break; 6740 } 6741 BWN_PHY_SET(mac, 0x0060, 0x0040); 6742 BWN_PHY_SET(mac, 0x0014, 0x0200); 6743 } 6744 /* 6745 * Calculate nrssi0 6746 */ 6747 BWN_RF_SET(mac, 0x007a, 0x0070); 6748 bwn_set_all_gains(mac, 0, 8, 0); 6749 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6750 if (phy->rev >= 2) { 6751 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6752 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6753 } 6754 BWN_RF_SET(mac, 0x007a, 0x0080); 6755 DELAY(20); 6756 6757 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6758 if (nrssi0 >= 0x0020) 6759 nrssi0 -= 0x0040; 6760 6761 /* 6762 * Calculate nrssi1 6763 */ 6764 BWN_RF_MASK(mac, 0x007a, 0x007f); 6765 if (phy->rev >= 2) 6766 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6767 6768 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6769 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6770 BWN_RF_SET(mac, 0x007a, 0x000f); 6771 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6772 if (phy->rev >= 2) { 6773 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6774 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6775 } 6776 6777 bwn_set_all_gains(mac, 3, 0, 1); 6778 if (phy->rf_rev == 8) { 6779 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6780 } else { 6781 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6782 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6783 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6784 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6785 } 6786 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6787 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6788 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6789 DELAY(20); 6790 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6791 6792 /* 6793 * Install calculated narrow RSSI values 6794 */ 6795 if (nrssi1 >= 0x0020) 6796 nrssi1 -= 0x0040; 6797 if (nrssi0 == nrssi1) 6798 pg->pg_nrssi_slope = 0x00010000; 6799 else 6800 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6801 if (nrssi0 >= -4) { 6802 pg->pg_nrssi[0] = nrssi1; 6803 pg->pg_nrssi[1] = nrssi0; 6804 } 6805 6806 /* 6807 * Restore saved RF/PHY registers 6808 */ 6809 if (phy->rev >= 3) { 6810 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6811 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6812 save_phy3[phy3_idx]); 6813 } 6814 } 6815 if (phy->rev >= 2) { 6816 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6817 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6818 } 6819 6820 for (i = 0; i < SAVE_RF_MAX; ++i) 6821 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6822 6823 BWN_WRITE_2(mac, 0x03e2, ant_div); 6824 BWN_WRITE_2(mac, 0x03e6, phy0); 6825 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6826 6827 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6828 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6829 6830 bwn_spu_workaround(mac, phy->chan); 6831 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6832 bwn_set_original_gains(mac); 6833 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6834 if (phy->rev >= 3) { 6835 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6836 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6837 save_phy3[phy3_idx]); 6838 } 6839 } 6840 6841 delta = 0x1f - pg->pg_nrssi[0]; 6842 for (i = 0; i < 64; i++) { 6843 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6844 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6845 pg->pg_nrssi_lt[i] = tmp32; 6846 } 6847 6848 bwn_nrssi_threshold(mac); 6849 #undef SAVE_RF_MAX 6850 #undef SAVE_PHY_COMM_MAX 6851 #undef SAVE_PHY3_MAX 6852 } 6853 6854 static void 6855 bwn_nrssi_offset(struct bwn_mac *mac) 6856 { 6857 #define SAVE_RF_MAX 2 6858 #define SAVE_PHY_COMM_MAX 10 6859 #define SAVE_PHY6_MAX 8 6860 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6861 { 0x7a, 0x43 }; 6862 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6863 0x0001, 0x0811, 0x0812, 0x0814, 6864 0x0815, 0x005a, 0x0059, 0x0058, 6865 0x000a, 0x0003 6866 }; 6867 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6868 0x002e, 0x002f, 0x080f, 0x0810, 6869 0x0801, 0x0060, 0x0014, 0x0478 6870 }; 6871 struct bwn_phy *phy = &mac->mac_phy; 6872 int i, phy6_idx = 0; 6873 uint16_t save_rf[SAVE_RF_MAX]; 6874 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6875 uint16_t save_phy6[SAVE_PHY6_MAX]; 6876 int16_t nrssi; 6877 uint16_t saved = 0xffff; 6878 6879 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6880 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6881 for (i = 0; i < SAVE_RF_MAX; ++i) 6882 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6883 6884 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6885 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6886 BWN_PHY_SET(mac, 0x0811, 0x000c); 6887 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6888 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6889 if (phy->rev >= 6) { 6890 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6891 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6892 6893 BWN_PHY_WRITE(mac, 0x002e, 0); 6894 BWN_PHY_WRITE(mac, 0x002f, 0); 6895 BWN_PHY_WRITE(mac, 0x080f, 0); 6896 BWN_PHY_WRITE(mac, 0x0810, 0); 6897 BWN_PHY_SET(mac, 0x0478, 0x0100); 6898 BWN_PHY_SET(mac, 0x0801, 0x0040); 6899 BWN_PHY_SET(mac, 0x0060, 0x0040); 6900 BWN_PHY_SET(mac, 0x0014, 0x0200); 6901 } 6902 BWN_RF_SET(mac, 0x007a, 0x0070); 6903 BWN_RF_SET(mac, 0x007a, 0x0080); 6904 DELAY(30); 6905 6906 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6907 if (nrssi >= 0x20) 6908 nrssi -= 0x40; 6909 if (nrssi == 31) { 6910 for (i = 7; i >= 4; i--) { 6911 BWN_RF_WRITE(mac, 0x007b, i); 6912 DELAY(20); 6913 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 6914 0x003f); 6915 if (nrssi >= 0x20) 6916 nrssi -= 0x40; 6917 if (nrssi < 31 && saved == 0xffff) 6918 saved = i; 6919 } 6920 if (saved == 0xffff) 6921 saved = 4; 6922 } else { 6923 BWN_RF_MASK(mac, 0x007a, 0x007f); 6924 if (phy->rev != 1) { 6925 BWN_PHY_SET(mac, 0x0814, 0x0001); 6926 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 6927 } 6928 BWN_PHY_SET(mac, 0x0811, 0x000c); 6929 BWN_PHY_SET(mac, 0x0812, 0x000c); 6930 BWN_PHY_SET(mac, 0x0811, 0x0030); 6931 BWN_PHY_SET(mac, 0x0812, 0x0030); 6932 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6933 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6934 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6935 if (phy->rev == 0) 6936 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 6937 else 6938 BWN_PHY_SET(mac, 0x000a, 0x2000); 6939 if (phy->rev != 1) { 6940 BWN_PHY_SET(mac, 0x0814, 0x0004); 6941 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 6942 } 6943 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6944 BWN_RF_SET(mac, 0x007a, 0x000f); 6945 bwn_set_all_gains(mac, 3, 0, 1); 6946 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 6947 DELAY(30); 6948 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6949 if (nrssi >= 0x20) 6950 nrssi -= 0x40; 6951 if (nrssi == -32) { 6952 for (i = 0; i < 4; i++) { 6953 BWN_RF_WRITE(mac, 0x007b, i); 6954 DELAY(20); 6955 nrssi = (int16_t)((BWN_PHY_READ(mac, 6956 0x047f) >> 8) & 0x003f); 6957 if (nrssi >= 0x20) 6958 nrssi -= 0x40; 6959 if (nrssi > -31 && saved == 0xffff) 6960 saved = i; 6961 } 6962 if (saved == 0xffff) 6963 saved = 3; 6964 } else 6965 saved = 0; 6966 } 6967 BWN_RF_WRITE(mac, 0x007b, saved); 6968 6969 /* 6970 * Restore saved RF/PHY registers 6971 */ 6972 if (phy->rev >= 6) { 6973 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 6974 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6975 save_phy6[phy6_idx]); 6976 } 6977 } 6978 if (phy->rev != 1) { 6979 for (i = 3; i < 5; i++) 6980 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 6981 save_phy_comm[i]); 6982 } 6983 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 6984 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6985 6986 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 6987 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6988 6989 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 6990 BWN_PHY_SET(mac, 0x0429, 0x8000); 6991 bwn_set_original_gains(mac); 6992 if (phy->rev >= 6) { 6993 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 6994 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6995 save_phy6[phy6_idx]); 6996 } 6997 } 6998 6999 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7000 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7001 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7002 } 7003 7004 static void 7005 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7006 int16_t third) 7007 { 7008 struct bwn_phy *phy = &mac->mac_phy; 7009 uint16_t i; 7010 uint16_t start = 0x08, end = 0x18; 7011 uint16_t tmp; 7012 uint16_t table; 7013 7014 if (phy->rev <= 1) { 7015 start = 0x10; 7016 end = 0x20; 7017 } 7018 7019 table = BWN_OFDMTAB_GAINX; 7020 if (phy->rev <= 1) 7021 table = BWN_OFDMTAB_GAINX_R1; 7022 for (i = 0; i < 4; i++) 7023 bwn_ofdmtab_write_2(mac, table, i, first); 7024 7025 for (i = start; i < end; i++) 7026 bwn_ofdmtab_write_2(mac, table, i, second); 7027 7028 if (third != -1) { 7029 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7030 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7031 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7032 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7033 } 7034 bwn_dummy_transmission(mac, 0, 1); 7035 } 7036 7037 static void 7038 bwn_set_original_gains(struct bwn_mac *mac) 7039 { 7040 struct bwn_phy *phy = &mac->mac_phy; 7041 uint16_t i, tmp; 7042 uint16_t table; 7043 uint16_t start = 0x0008, end = 0x0018; 7044 7045 if (phy->rev <= 1) { 7046 start = 0x0010; 7047 end = 0x0020; 7048 } 7049 7050 table = BWN_OFDMTAB_GAINX; 7051 if (phy->rev <= 1) 7052 table = BWN_OFDMTAB_GAINX_R1; 7053 for (i = 0; i < 4; i++) { 7054 tmp = (i & 0xfffc); 7055 tmp |= (i & 0x0001) << 1; 7056 tmp |= (i & 0x0002) >> 1; 7057 7058 bwn_ofdmtab_write_2(mac, table, i, tmp); 7059 } 7060 7061 for (i = start; i < end; i++) 7062 bwn_ofdmtab_write_2(mac, table, i, i - start); 7063 7064 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7065 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7066 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7067 bwn_dummy_transmission(mac, 0, 1); 7068 } 7069 7070 static void 7071 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7072 { 7073 struct bwn_phy *phy = &mac->mac_phy; 7074 struct bwn_phy_g *pg = &phy->phy_g; 7075 struct bwn_rfatt old_rfatt, rfatt; 7076 struct bwn_bbatt old_bbatt, bbatt; 7077 struct bwn_softc *sc = mac->mac_sc; 7078 uint8_t old_txctl = 0; 7079 7080 KASSERT(phy->type == BWN_PHYTYPE_G, 7081 ("%s:%d: fail", __func__, __LINE__)); 7082 7083 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7084 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7085 return; 7086 7087 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7088 7089 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7090 7091 if (!phy->gmode) 7092 return; 7093 bwn_hwpctl_early_init(mac); 7094 if (pg->pg_curtssi == 0) { 7095 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7096 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7097 } else { 7098 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7099 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7100 old_txctl = pg->pg_txctl; 7101 7102 bbatt.att = 11; 7103 if (phy->rf_rev == 8) { 7104 rfatt.att = 15; 7105 rfatt.padmix = 1; 7106 } else { 7107 rfatt.att = 9; 7108 rfatt.padmix = 0; 7109 } 7110 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7111 } 7112 bwn_dummy_transmission(mac, 0, 1); 7113 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7114 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7115 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7116 else 7117 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7118 &old_rfatt, old_txctl); 7119 } 7120 bwn_hwpctl_init_gphy(mac); 7121 7122 /* clear TSSI */ 7123 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7124 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7125 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7126 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7127 } 7128 7129 static void 7130 bwn_hwpctl_early_init(struct bwn_mac *mac) 7131 { 7132 struct bwn_phy *phy = &mac->mac_phy; 7133 7134 if (!bwn_has_hwpctl(mac)) { 7135 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7136 return; 7137 } 7138 7139 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7140 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7141 BWN_PHY_SET(mac, 0x047c, 0x0002); 7142 BWN_PHY_SET(mac, 0x047a, 0xf000); 7143 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7144 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7145 BWN_PHY_SET(mac, 0x005d, 0x8000); 7146 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7147 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7148 BWN_PHY_SET(mac, 0x0036, 0x0400); 7149 } else { 7150 BWN_PHY_SET(mac, 0x0036, 0x0200); 7151 BWN_PHY_SET(mac, 0x0036, 0x0400); 7152 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7153 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7154 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7155 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7156 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7157 } 7158 } 7159 7160 static void 7161 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7162 { 7163 struct bwn_phy *phy = &mac->mac_phy; 7164 struct bwn_phy_g *pg = &phy->phy_g; 7165 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7166 int i; 7167 uint16_t nr_written = 0, tmp, value; 7168 uint8_t rf, bb; 7169 7170 if (!bwn_has_hwpctl(mac)) { 7171 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7172 return; 7173 } 7174 7175 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7176 (pg->pg_idletssi - pg->pg_curtssi)); 7177 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7178 (pg->pg_idletssi - pg->pg_curtssi)); 7179 7180 for (i = 0; i < 32; i++) 7181 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7182 for (i = 32; i < 64; i++) 7183 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7184 for (i = 0; i < 64; i += 2) { 7185 value = (uint16_t) pg->pg_tssi2dbm[i]; 7186 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7187 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7188 } 7189 7190 for (rf = 0; rf < lo->rfatt.len; rf++) { 7191 for (bb = 0; bb < lo->bbatt.len; bb++) { 7192 if (nr_written >= 0x40) 7193 return; 7194 tmp = lo->bbatt.array[bb].att; 7195 tmp <<= 8; 7196 if (phy->rf_rev == 8) 7197 tmp |= 0x50; 7198 else 7199 tmp |= 0x40; 7200 tmp |= lo->rfatt.array[rf].att; 7201 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7202 nr_written++; 7203 } 7204 } 7205 7206 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7207 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7208 7209 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7210 BWN_PHY_SET(mac, 0x0478, 0x0800); 7211 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7212 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7213 7214 bwn_phy_g_dc_lookup_init(mac, 1); 7215 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7216 } 7217 7218 static void 7219 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7220 { 7221 struct bwn_softc *sc = mac->mac_sc; 7222 7223 if (spu != 0) 7224 bwn_spu_workaround(mac, channel); 7225 7226 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7227 7228 if (channel == 14) { 7229 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7230 bwn_hf_write(mac, 7231 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7232 else 7233 bwn_hf_write(mac, 7234 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7235 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7236 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7237 return; 7238 } 7239 7240 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7241 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7242 } 7243 7244 static uint16_t 7245 bwn_phy_g_chan2freq(uint8_t channel) 7246 { 7247 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7248 7249 KASSERT(channel >= 1 && channel <= 14, 7250 ("%s:%d: fail", __func__, __LINE__)); 7251 7252 return (bwn_phy_g_rf_channels[channel - 1]); 7253 } 7254 7255 static void 7256 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7257 const struct bwn_rfatt *rfatt, uint8_t txctl) 7258 { 7259 struct bwn_phy *phy = &mac->mac_phy; 7260 struct bwn_phy_g *pg = &phy->phy_g; 7261 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7262 uint16_t bb, rf; 7263 uint16_t tx_bias, tx_magn; 7264 7265 bb = bbatt->att; 7266 rf = rfatt->att; 7267 tx_bias = lo->tx_bias; 7268 tx_magn = lo->tx_magn; 7269 if (tx_bias == 0xff) 7270 tx_bias = 0; 7271 7272 pg->pg_txctl = txctl; 7273 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7274 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7275 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7276 bwn_phy_g_set_bbatt(mac, bb); 7277 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7278 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7279 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7280 else { 7281 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7282 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7283 } 7284 if (BWN_HAS_TXMAG(phy)) 7285 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7286 else 7287 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7288 bwn_lo_g_adjust(mac); 7289 } 7290 7291 static void 7292 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7293 uint16_t bbatt) 7294 { 7295 struct bwn_phy *phy = &mac->mac_phy; 7296 7297 if (phy->analog == 0) { 7298 BWN_WRITE_2(mac, BWN_PHY0, 7299 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7300 return; 7301 } 7302 if (phy->analog > 1) { 7303 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7304 return; 7305 } 7306 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7307 } 7308 7309 static uint16_t 7310 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7311 { 7312 struct bwn_phy *phy = &mac->mac_phy; 7313 struct bwn_phy_g *pg = &phy->phy_g; 7314 struct bwn_softc *sc = mac->mac_sc; 7315 int max_lb_gain; 7316 uint16_t extlna; 7317 uint16_t i; 7318 7319 if (phy->gmode == 0) 7320 return (0); 7321 7322 if (BWN_HAS_LOOPBACK(phy)) { 7323 max_lb_gain = pg->pg_max_lb_gain; 7324 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7325 if (max_lb_gain >= 0x46) { 7326 extlna = 0x3000; 7327 max_lb_gain -= 0x46; 7328 } else if (max_lb_gain >= 0x3a) { 7329 extlna = 0x1000; 7330 max_lb_gain -= 0x3a; 7331 } else if (max_lb_gain >= 0x2e) { 7332 extlna = 0x2000; 7333 max_lb_gain -= 0x2e; 7334 } else { 7335 extlna = 0; 7336 max_lb_gain -= 0x10; 7337 } 7338 7339 for (i = 0; i < 16; i++) { 7340 max_lb_gain -= (i * 6); 7341 if (max_lb_gain < 6) 7342 break; 7343 } 7344 7345 if ((phy->rev < 7) || 7346 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7347 if (reg == BWN_PHY_RFOVER) { 7348 return (0x1b3); 7349 } else if (reg == BWN_PHY_RFOVERVAL) { 7350 extlna |= (i << 8); 7351 switch (lpd) { 7352 case BWN_LPD(0, 1, 1): 7353 return (0x0f92); 7354 case BWN_LPD(0, 0, 1): 7355 case BWN_LPD(1, 0, 1): 7356 return (0x0092 | extlna); 7357 case BWN_LPD(1, 0, 0): 7358 return (0x0093 | extlna); 7359 } 7360 KASSERT(0 == 1, 7361 ("%s:%d: fail", __func__, __LINE__)); 7362 } 7363 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7364 } else { 7365 if (reg == BWN_PHY_RFOVER) 7366 return (0x9b3); 7367 if (reg == BWN_PHY_RFOVERVAL) { 7368 if (extlna) 7369 extlna |= 0x8000; 7370 extlna |= (i << 8); 7371 switch (lpd) { 7372 case BWN_LPD(0, 1, 1): 7373 return (0x8f92); 7374 case BWN_LPD(0, 0, 1): 7375 return (0x8092 | extlna); 7376 case BWN_LPD(1, 0, 1): 7377 return (0x2092 | extlna); 7378 case BWN_LPD(1, 0, 0): 7379 return (0x2093 | extlna); 7380 } 7381 KASSERT(0 == 1, 7382 ("%s:%d: fail", __func__, __LINE__)); 7383 } 7384 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7385 } 7386 return (0); 7387 } 7388 7389 if ((phy->rev < 7) || 7390 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7391 if (reg == BWN_PHY_RFOVER) { 7392 return (0x1b3); 7393 } else if (reg == BWN_PHY_RFOVERVAL) { 7394 switch (lpd) { 7395 case BWN_LPD(0, 1, 1): 7396 return (0x0fb2); 7397 case BWN_LPD(0, 0, 1): 7398 return (0x00b2); 7399 case BWN_LPD(1, 0, 1): 7400 return (0x30b2); 7401 case BWN_LPD(1, 0, 0): 7402 return (0x30b3); 7403 } 7404 KASSERT(0 == 1, 7405 ("%s:%d: fail", __func__, __LINE__)); 7406 } 7407 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7408 } else { 7409 if (reg == BWN_PHY_RFOVER) { 7410 return (0x9b3); 7411 } else if (reg == BWN_PHY_RFOVERVAL) { 7412 switch (lpd) { 7413 case BWN_LPD(0, 1, 1): 7414 return (0x8fb2); 7415 case BWN_LPD(0, 0, 1): 7416 return (0x80b2); 7417 case BWN_LPD(1, 0, 1): 7418 return (0x20b2); 7419 case BWN_LPD(1, 0, 0): 7420 return (0x20b3); 7421 } 7422 KASSERT(0 == 1, 7423 ("%s:%d: fail", __func__, __LINE__)); 7424 } 7425 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7426 } 7427 return (0); 7428 } 7429 7430 static void 7431 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7432 { 7433 7434 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7435 return; 7436 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7437 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7438 DELAY(1000); 7439 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7440 } 7441 7442 static int 7443 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7444 { 7445 struct bwn_softc *sc = mac->mac_sc; 7446 struct bwn_fw *fw = &mac->mac_fw; 7447 const uint8_t rev = siba_get_revid(sc->sc_dev); 7448 const char *filename; 7449 uint32_t high; 7450 int error; 7451 7452 /* microcode */ 7453 if (rev >= 5 && rev <= 10) 7454 filename = "ucode5"; 7455 else if (rev >= 11 && rev <= 12) 7456 filename = "ucode11"; 7457 else if (rev == 13) 7458 filename = "ucode13"; 7459 else if (rev == 14) 7460 filename = "ucode14"; 7461 else if (rev >= 15) 7462 filename = "ucode15"; 7463 else { 7464 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7465 bwn_release_firmware(mac); 7466 return (EOPNOTSUPP); 7467 } 7468 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7469 if (error) { 7470 bwn_release_firmware(mac); 7471 return (error); 7472 } 7473 7474 /* PCM */ 7475 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7476 if (rev >= 5 && rev <= 10) { 7477 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7478 if (error == ENOENT) 7479 fw->no_pcmfile = 1; 7480 else if (error) { 7481 bwn_release_firmware(mac); 7482 return (error); 7483 } 7484 } else if (rev < 11) { 7485 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7486 return (EOPNOTSUPP); 7487 } 7488 7489 /* initvals */ 7490 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7491 switch (mac->mac_phy.type) { 7492 case BWN_PHYTYPE_A: 7493 if (rev < 5 || rev > 10) 7494 goto fail1; 7495 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7496 filename = "a0g1initvals5"; 7497 else 7498 filename = "a0g0initvals5"; 7499 break; 7500 case BWN_PHYTYPE_G: 7501 if (rev >= 5 && rev <= 10) 7502 filename = "b0g0initvals5"; 7503 else if (rev >= 13) 7504 filename = "b0g0initvals13"; 7505 else 7506 goto fail1; 7507 break; 7508 case BWN_PHYTYPE_LP: 7509 if (rev == 13) 7510 filename = "lp0initvals13"; 7511 else if (rev == 14) 7512 filename = "lp0initvals14"; 7513 else if (rev >= 15) 7514 filename = "lp0initvals15"; 7515 else 7516 goto fail1; 7517 break; 7518 case BWN_PHYTYPE_N: 7519 if (rev >= 11 && rev <= 12) 7520 filename = "n0initvals11"; 7521 else 7522 goto fail1; 7523 break; 7524 default: 7525 goto fail1; 7526 } 7527 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7528 if (error) { 7529 bwn_release_firmware(mac); 7530 return (error); 7531 } 7532 7533 /* bandswitch initvals */ 7534 switch (mac->mac_phy.type) { 7535 case BWN_PHYTYPE_A: 7536 if (rev >= 5 && rev <= 10) { 7537 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7538 filename = "a0g1bsinitvals5"; 7539 else 7540 filename = "a0g0bsinitvals5"; 7541 } else if (rev >= 11) 7542 filename = NULL; 7543 else 7544 goto fail1; 7545 break; 7546 case BWN_PHYTYPE_G: 7547 if (rev >= 5 && rev <= 10) 7548 filename = "b0g0bsinitvals5"; 7549 else if (rev >= 11) 7550 filename = NULL; 7551 else 7552 goto fail1; 7553 break; 7554 case BWN_PHYTYPE_LP: 7555 if (rev == 13) 7556 filename = "lp0bsinitvals13"; 7557 else if (rev == 14) 7558 filename = "lp0bsinitvals14"; 7559 else if (rev >= 15) 7560 filename = "lp0bsinitvals15"; 7561 else 7562 goto fail1; 7563 break; 7564 case BWN_PHYTYPE_N: 7565 if (rev >= 11 && rev <= 12) 7566 filename = "n0bsinitvals11"; 7567 else 7568 goto fail1; 7569 break; 7570 default: 7571 goto fail1; 7572 } 7573 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7574 if (error) { 7575 bwn_release_firmware(mac); 7576 return (error); 7577 } 7578 return (0); 7579 fail1: 7580 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7581 bwn_release_firmware(mac); 7582 return (EOPNOTSUPP); 7583 } 7584 7585 static int 7586 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7587 const char *name, struct bwn_fwfile *bfw) 7588 { 7589 const struct bwn_fwhdr *hdr; 7590 struct bwn_softc *sc = mac->mac_sc; 7591 const struct firmware *fw; 7592 char namebuf[64]; 7593 7594 if (name == NULL) { 7595 bwn_do_release_fw(bfw); 7596 return (0); 7597 } 7598 if (bfw->filename != NULL) { 7599 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7600 return (0); 7601 bwn_do_release_fw(bfw); 7602 } 7603 7604 ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7605 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7606 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7607 wlan_assert_serialized(); 7608 wlan_serialize_exit(); 7609 fw = firmware_get(namebuf); 7610 wlan_serialize_enter(); 7611 if (fw == NULL) { 7612 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7613 namebuf); 7614 return (ENOENT); 7615 } 7616 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7617 goto fail; 7618 hdr = (const struct bwn_fwhdr *)(fw->data); 7619 switch (hdr->type) { 7620 case BWN_FWTYPE_UCODE: 7621 case BWN_FWTYPE_PCM: 7622 if (be32toh(hdr->size) != 7623 (fw->datasize - sizeof(struct bwn_fwhdr))) 7624 goto fail; 7625 /* FALLTHROUGH */ 7626 case BWN_FWTYPE_IV: 7627 if (hdr->ver != 1) 7628 goto fail; 7629 break; 7630 default: 7631 goto fail; 7632 } 7633 bfw->filename = name; 7634 bfw->fw = fw; 7635 bfw->type = type; 7636 return (0); 7637 fail: 7638 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7639 if (fw != NULL) 7640 firmware_put(fw, FIRMWARE_UNLOAD); 7641 return (EPROTO); 7642 } 7643 7644 static void 7645 bwn_release_firmware(struct bwn_mac *mac) 7646 { 7647 7648 bwn_do_release_fw(&mac->mac_fw.ucode); 7649 bwn_do_release_fw(&mac->mac_fw.pcm); 7650 bwn_do_release_fw(&mac->mac_fw.initvals); 7651 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7652 } 7653 7654 static void 7655 bwn_do_release_fw(struct bwn_fwfile *bfw) 7656 { 7657 7658 if (bfw->fw != NULL) 7659 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7660 bfw->fw = NULL; 7661 bfw->filename = NULL; 7662 } 7663 7664 static int 7665 bwn_fw_loaducode(struct bwn_mac *mac) 7666 { 7667 #define GETFWOFFSET(fwp, offset) \ 7668 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7669 #define GETFWSIZE(fwp, offset) \ 7670 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7671 struct bwn_softc *sc = mac->mac_sc; 7672 const uint32_t *data; 7673 unsigned int i; 7674 uint32_t ctl; 7675 uint16_t date, fwcaps, time; 7676 int error = 0; 7677 7678 ctl = BWN_READ_4(mac, BWN_MACCTL); 7679 ctl |= BWN_MACCTL_MCODE_JMP0; 7680 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7681 __LINE__)); 7682 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7683 for (i = 0; i < 64; i++) 7684 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7685 for (i = 0; i < 4096; i += 2) 7686 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7687 7688 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7689 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7690 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7691 i++) { 7692 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7693 DELAY(10); 7694 } 7695 7696 if (mac->mac_fw.pcm.fw) { 7697 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7698 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7699 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7700 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7701 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7702 sizeof(struct bwn_fwhdr)); i++) { 7703 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7704 DELAY(10); 7705 } 7706 } 7707 7708 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7709 BWN_WRITE_4(mac, BWN_MACCTL, 7710 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7711 BWN_MACCTL_MCODE_RUN); 7712 7713 for (i = 0; i < 21; i++) { 7714 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7715 break; 7716 if (i >= 20) { 7717 device_printf(sc->sc_dev, "ucode timeout\n"); 7718 error = ENXIO; 7719 goto error; 7720 } 7721 DELAY(50000); 7722 } 7723 BWN_READ_4(mac, BWN_INTR_REASON); 7724 7725 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7726 if (mac->mac_fw.rev <= 0x128) { 7727 device_printf(sc->sc_dev, "the firmware is too old\n"); 7728 error = EOPNOTSUPP; 7729 goto error; 7730 } 7731 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7732 BWN_SHARED_UCODE_PATCH); 7733 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7734 mac->mac_fw.opensource = (date == 0xffff); 7735 if (bwn_wme != 0) 7736 mac->mac_flags |= BWN_MAC_FLAG_WME; 7737 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7738 7739 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7740 if (mac->mac_fw.opensource == 0) { 7741 device_printf(sc->sc_dev, 7742 "firmware version (rev %u patch %u date %#x time %#x)\n", 7743 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7744 if (mac->mac_fw.no_pcmfile) 7745 device_printf(sc->sc_dev, 7746 "no HW crypto acceleration due to pcm5\n"); 7747 } else { 7748 mac->mac_fw.patch = time; 7749 fwcaps = bwn_fwcaps_read(mac); 7750 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7751 device_printf(sc->sc_dev, 7752 "disabling HW crypto acceleration\n"); 7753 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7754 } 7755 if (!(fwcaps & BWN_FWCAPS_WME)) { 7756 device_printf(sc->sc_dev, "disabling WME support\n"); 7757 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7758 } 7759 } 7760 7761 if (BWN_ISOLDFMT(mac)) 7762 device_printf(sc->sc_dev, "using old firmware image\n"); 7763 7764 return (0); 7765 7766 error: 7767 BWN_WRITE_4(mac, BWN_MACCTL, 7768 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7769 BWN_MACCTL_MCODE_JMP0); 7770 7771 return (error); 7772 #undef GETFWSIZE 7773 #undef GETFWOFFSET 7774 } 7775 7776 /* OpenFirmware only */ 7777 static uint16_t 7778 bwn_fwcaps_read(struct bwn_mac *mac) 7779 { 7780 7781 KASSERT(mac->mac_fw.opensource == 1, 7782 ("%s:%d: fail", __func__, __LINE__)); 7783 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7784 } 7785 7786 static int 7787 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7788 size_t count, size_t array_size) 7789 { 7790 #define GET_NEXTIV16(iv) \ 7791 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7792 sizeof(uint16_t) + sizeof(uint16_t))) 7793 #define GET_NEXTIV32(iv) \ 7794 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7795 sizeof(uint16_t) + sizeof(uint32_t))) 7796 struct bwn_softc *sc = mac->mac_sc; 7797 const struct bwn_fwinitvals *iv; 7798 uint16_t offset; 7799 size_t i; 7800 uint8_t bit32; 7801 7802 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7803 ("%s:%d: fail", __func__, __LINE__)); 7804 iv = ivals; 7805 for (i = 0; i < count; i++) { 7806 if (array_size < sizeof(iv->offset_size)) 7807 goto fail; 7808 array_size -= sizeof(iv->offset_size); 7809 offset = be16toh(iv->offset_size); 7810 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7811 offset &= BWN_FWINITVALS_OFFSET_MASK; 7812 if (offset >= 0x1000) 7813 goto fail; 7814 if (bit32) { 7815 if (array_size < sizeof(iv->data.d32)) 7816 goto fail; 7817 array_size -= sizeof(iv->data.d32); 7818 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7819 iv = GET_NEXTIV32(iv); 7820 } else { 7821 7822 if (array_size < sizeof(iv->data.d16)) 7823 goto fail; 7824 array_size -= sizeof(iv->data.d16); 7825 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7826 7827 iv = GET_NEXTIV16(iv); 7828 } 7829 } 7830 if (array_size != 0) 7831 goto fail; 7832 return (0); 7833 fail: 7834 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7835 return (EPROTO); 7836 #undef GET_NEXTIV16 7837 #undef GET_NEXTIV32 7838 } 7839 7840 static int 7841 bwn_switch_channel(struct bwn_mac *mac, int chan) 7842 { 7843 struct bwn_phy *phy = &(mac->mac_phy); 7844 struct bwn_softc *sc = mac->mac_sc; 7845 struct ifnet *ifp = sc->sc_ifp; 7846 struct ieee80211com *ic = ifp->if_l2com; 7847 uint16_t channelcookie, savedcookie; 7848 int error; 7849 7850 if (chan == 0xffff) 7851 chan = phy->get_default_chan(mac); 7852 7853 channelcookie = chan; 7854 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7855 channelcookie |= 0x100; 7856 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7857 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7858 error = phy->switch_channel(mac, chan); 7859 if (error) 7860 goto fail; 7861 7862 mac->mac_phy.chan = chan; 7863 DELAY(8000); 7864 return (0); 7865 fail: 7866 device_printf(sc->sc_dev, "failed to switch channel\n"); 7867 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7868 return (error); 7869 } 7870 7871 static uint16_t 7872 bwn_ant2phy(int antenna) 7873 { 7874 7875 switch (antenna) { 7876 case BWN_ANT0: 7877 return (BWN_TX_PHY_ANT0); 7878 case BWN_ANT1: 7879 return (BWN_TX_PHY_ANT1); 7880 case BWN_ANT2: 7881 return (BWN_TX_PHY_ANT2); 7882 case BWN_ANT3: 7883 return (BWN_TX_PHY_ANT3); 7884 case BWN_ANTAUTO: 7885 return (BWN_TX_PHY_ANT01AUTO); 7886 } 7887 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7888 return (0); 7889 } 7890 7891 static void 7892 bwn_wme_load(struct bwn_mac *mac) 7893 { 7894 struct bwn_softc *sc = mac->mac_sc; 7895 int i; 7896 7897 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7898 ("%s:%d: fail", __func__, __LINE__)); 7899 7900 bwn_mac_suspend(mac); 7901 for (i = 0; i < N(sc->sc_wmeParams); i++) 7902 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 7903 bwn_wme_shm_offsets[i]); 7904 bwn_mac_enable(mac); 7905 } 7906 7907 static void 7908 bwn_wme_loadparams(struct bwn_mac *mac, 7909 const struct wmeParams *p, uint16_t shm_offset) 7910 { 7911 #define SM(_v, _f) (((_v) << _f##_S) & _f) 7912 struct bwn_softc *sc = mac->mac_sc; 7913 uint16_t params[BWN_NR_WMEPARAMS]; 7914 int slot, tmp; 7915 unsigned int i; 7916 7917 slot = BWN_READ_2(mac, BWN_RNG) & 7918 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7919 7920 memset(¶ms, 0, sizeof(params)); 7921 7922 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 7923 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 7924 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 7925 7926 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 7927 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7928 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 7929 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7930 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 7931 params[BWN_WMEPARAM_BSLOTS] = slot; 7932 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 7933 7934 for (i = 0; i < N(params); i++) { 7935 if (i == BWN_WMEPARAM_STATUS) { 7936 tmp = bwn_shm_read_2(mac, BWN_SHARED, 7937 shm_offset + (i * 2)); 7938 tmp |= 0x100; 7939 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7940 tmp); 7941 } else { 7942 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7943 params[i]); 7944 } 7945 } 7946 } 7947 7948 static void 7949 bwn_mac_write_bssid(struct bwn_mac *mac) 7950 { 7951 struct bwn_softc *sc = mac->mac_sc; 7952 uint32_t tmp; 7953 int i; 7954 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 7955 7956 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 7957 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 7958 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 7959 IEEE80211_ADDR_LEN); 7960 7961 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 7962 tmp = (uint32_t) (mac_bssid[i + 0]); 7963 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 7964 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 7965 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 7966 bwn_ram_write(mac, 0x20 + i, tmp); 7967 } 7968 } 7969 7970 static void 7971 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 7972 const uint8_t *macaddr) 7973 { 7974 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 7975 uint16_t data; 7976 7977 if (mac == NULL) 7978 macaddr = zero; 7979 7980 offset |= 0x0020; 7981 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 7982 7983 data = macaddr[0]; 7984 data |= macaddr[1] << 8; 7985 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7986 data = macaddr[2]; 7987 data |= macaddr[3] << 8; 7988 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7989 data = macaddr[4]; 7990 data |= macaddr[5] << 8; 7991 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7992 } 7993 7994 static void 7995 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 7996 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 7997 { 7998 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 7999 uint8_t per_sta_keys_start = 8; 8000 8001 if (BWN_SEC_NEWAPI(mac)) 8002 per_sta_keys_start = 4; 8003 8004 KASSERT(index < mac->mac_max_nr_keys, 8005 ("%s:%d: fail", __func__, __LINE__)); 8006 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8007 ("%s:%d: fail", __func__, __LINE__)); 8008 8009 if (index >= per_sta_keys_start) 8010 bwn_key_macwrite(mac, index, NULL); 8011 if (key) 8012 memcpy(buf, key, key_len); 8013 bwn_key_write(mac, index, algorithm, buf); 8014 if (index >= per_sta_keys_start) 8015 bwn_key_macwrite(mac, index, mac_addr); 8016 8017 mac->mac_key[index].algorithm = algorithm; 8018 } 8019 8020 static void 8021 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8022 { 8023 struct bwn_softc *sc = mac->mac_sc; 8024 uint32_t addrtmp[2] = { 0, 0 }; 8025 uint8_t start = 8; 8026 8027 if (BWN_SEC_NEWAPI(mac)) 8028 start = 4; 8029 8030 KASSERT(index >= start, 8031 ("%s:%d: fail", __func__, __LINE__)); 8032 index -= start; 8033 8034 if (addr) { 8035 addrtmp[0] = addr[0]; 8036 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8037 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8038 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8039 addrtmp[1] = addr[4]; 8040 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8041 } 8042 8043 if (siba_get_revid(sc->sc_dev) >= 5) { 8044 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8045 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8046 } else { 8047 if (index >= 8) { 8048 bwn_shm_write_4(mac, BWN_SHARED, 8049 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8050 bwn_shm_write_2(mac, BWN_SHARED, 8051 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8052 } 8053 } 8054 } 8055 8056 static void 8057 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8058 const uint8_t *key) 8059 { 8060 unsigned int i; 8061 uint32_t offset; 8062 uint16_t kidx, value; 8063 8064 kidx = BWN_SEC_KEY2FW(mac, index); 8065 bwn_shm_write_2(mac, BWN_SHARED, 8066 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8067 8068 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8069 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8070 value = key[i]; 8071 value |= (uint16_t)(key[i + 1]) << 8; 8072 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8073 } 8074 } 8075 8076 static void 8077 bwn_phy_exit(struct bwn_mac *mac) 8078 { 8079 8080 mac->mac_phy.rf_onoff(mac, 0); 8081 if (mac->mac_phy.exit != NULL) 8082 mac->mac_phy.exit(mac); 8083 } 8084 8085 static void 8086 bwn_dma_free(struct bwn_mac *mac) 8087 { 8088 struct bwn_dma *dma; 8089 8090 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8091 return; 8092 dma = &mac->mac_method.dma; 8093 8094 bwn_dma_ringfree(&dma->rx); 8095 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8096 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8097 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8098 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8099 bwn_dma_ringfree(&dma->mcast); 8100 } 8101 8102 static void 8103 bwn_core_stop(struct bwn_mac *mac) 8104 { 8105 struct bwn_softc *sc = mac->mac_sc; 8106 8107 wlan_assert_serialized(); 8108 8109 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8110 return; 8111 8112 callout_stop(&sc->sc_rfswitch_ch); 8113 callout_stop(&sc->sc_task_ch); 8114 callout_stop(&sc->sc_watchdog_ch); 8115 sc->sc_watchdog_timer = 0; 8116 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8117 BWN_READ_4(mac, BWN_INTR_MASK); 8118 bwn_mac_suspend(mac); 8119 8120 mac->mac_status = BWN_MAC_STATUS_INITED; 8121 } 8122 8123 static int 8124 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8125 { 8126 struct bwn_mac *up_dev = NULL; 8127 struct bwn_mac *down_dev; 8128 struct bwn_mac *mac; 8129 int err, status; 8130 uint8_t gmode; 8131 8132 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8133 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8134 mac->mac_phy.supports_2ghz) { 8135 up_dev = mac; 8136 gmode = 1; 8137 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8138 mac->mac_phy.supports_5ghz) { 8139 up_dev = mac; 8140 gmode = 0; 8141 } else { 8142 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8143 return (EINVAL); 8144 } 8145 if (up_dev != NULL) 8146 break; 8147 } 8148 if (up_dev == NULL) { 8149 device_printf(sc->sc_dev, "Could not find a device\n"); 8150 return (ENODEV); 8151 } 8152 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8153 return (0); 8154 8155 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8156 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8157 8158 down_dev = sc->sc_curmac; 8159 status = down_dev->mac_status; 8160 if (status >= BWN_MAC_STATUS_STARTED) 8161 bwn_core_stop(down_dev); 8162 if (status >= BWN_MAC_STATUS_INITED) 8163 bwn_core_exit(down_dev); 8164 8165 if (down_dev != up_dev) 8166 bwn_phy_reset(down_dev); 8167 8168 up_dev->mac_phy.gmode = gmode; 8169 if (status >= BWN_MAC_STATUS_INITED) { 8170 err = bwn_core_init(up_dev); 8171 if (err) { 8172 device_printf(sc->sc_dev, 8173 "fatal: failed to initialize for %s-GHz\n", 8174 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8175 goto fail; 8176 } 8177 } 8178 if (status >= BWN_MAC_STATUS_STARTED) 8179 bwn_core_start(up_dev); 8180 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8181 sc->sc_curmac = up_dev; 8182 8183 return (0); 8184 fail: 8185 sc->sc_curmac = NULL; 8186 return (err); 8187 } 8188 8189 static void 8190 bwn_rf_turnon(struct bwn_mac *mac) 8191 { 8192 8193 bwn_mac_suspend(mac); 8194 mac->mac_phy.rf_onoff(mac, 1); 8195 mac->mac_phy.rf_on = 1; 8196 bwn_mac_enable(mac); 8197 } 8198 8199 static void 8200 bwn_rf_turnoff(struct bwn_mac *mac) 8201 { 8202 8203 bwn_mac_suspend(mac); 8204 mac->mac_phy.rf_onoff(mac, 0); 8205 mac->mac_phy.rf_on = 0; 8206 bwn_mac_enable(mac); 8207 } 8208 8209 static void 8210 bwn_phy_reset(struct bwn_mac *mac) 8211 { 8212 struct bwn_softc *sc = mac->mac_sc; 8213 8214 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8215 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8216 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8217 DELAY(1000); 8218 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8219 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8220 BWN_TGSLOW_PHYRESET); 8221 DELAY(1000); 8222 } 8223 8224 static int 8225 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8226 { 8227 struct bwn_vap *bvp = BWN_VAP(vap); 8228 struct ieee80211com *ic= vap->iv_ic; 8229 struct ifnet *ifp = ic->ic_ifp; 8230 enum ieee80211_state ostate = vap->iv_state; 8231 struct bwn_softc *sc = ic->ic_softc; 8232 struct bwn_mac *mac = sc->sc_curmac; 8233 int error; 8234 8235 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8236 ieee80211_state_name[vap->iv_state], 8237 ieee80211_state_name[nstate]); 8238 8239 error = bvp->bv_newstate(vap, nstate, arg); 8240 if (error != 0) 8241 return (error); 8242 8243 bwn_led_newstate(mac, nstate); 8244 8245 /* 8246 * Clear the BSSID when we stop a STA 8247 */ 8248 if (vap->iv_opmode == IEEE80211_M_STA) { 8249 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8250 /* 8251 * Clear out the BSSID. If we reassociate to 8252 * the same AP, this will reinialize things 8253 * correctly... 8254 */ 8255 if (ic->ic_opmode == IEEE80211_M_STA && 8256 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8257 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8258 bwn_set_macaddr(mac); 8259 } 8260 } 8261 } 8262 8263 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8264 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8265 /* XXX nothing to do? */ 8266 } else if (nstate == IEEE80211_S_RUN) { 8267 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8268 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8269 bwn_set_opmode(mac); 8270 bwn_set_pretbtt(mac); 8271 bwn_spu_setdelay(mac, 0); 8272 bwn_set_macaddr(mac); 8273 } 8274 8275 return (error); 8276 } 8277 8278 static void 8279 bwn_set_pretbtt(struct bwn_mac *mac) 8280 { 8281 struct bwn_softc *sc = mac->mac_sc; 8282 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8283 uint16_t pretbtt; 8284 8285 if (ic->ic_opmode == IEEE80211_M_IBSS) 8286 pretbtt = 2; 8287 else 8288 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8289 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8290 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8291 } 8292 8293 static void 8294 bwn_intr(void *arg) 8295 { 8296 struct bwn_mac *mac = arg; 8297 struct bwn_softc *sc = mac->mac_sc; 8298 uint32_t reason; 8299 8300 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8301 (sc->sc_flags & BWN_FLAG_INVALID)) 8302 return; 8303 8304 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8305 if (reason == 0xffffffff) /* shared IRQ */ 8306 return; 8307 reason &= mac->mac_intr_mask; 8308 if (reason == 0) 8309 return; 8310 8311 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00; 8312 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8313 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8314 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8315 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8316 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8317 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8318 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8319 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8320 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8321 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8322 8323 /* Disable interrupts. */ 8324 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8325 8326 mac->mac_reason_intr = reason; 8327 8328 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8329 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8330 8331 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask); 8332 return; 8333 } 8334 8335 static void 8336 bwn_intrtask(void *arg, int npending) 8337 { 8338 struct bwn_mac *mac = arg; 8339 struct bwn_softc *sc = mac->mac_sc; 8340 struct ifnet *ifp = sc->sc_ifp; 8341 uint32_t merged = 0; 8342 int i, tx = 0, rx = 0; 8343 8344 wlan_serialize_enter(); 8345 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8346 (sc->sc_flags & BWN_FLAG_INVALID)) { 8347 wlan_serialize_exit(); 8348 return; 8349 } 8350 8351 for (i = 0; i < N(mac->mac_reason); i++) 8352 merged |= mac->mac_reason[i]; 8353 8354 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8355 device_printf(sc->sc_dev, "MAC trans error\n"); 8356 8357 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8358 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8359 mac->mac_phy.txerrors--; 8360 if (mac->mac_phy.txerrors == 0) { 8361 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8362 bwn_restart(mac, "PHY TX errors"); 8363 } 8364 } 8365 8366 if (merged & BWN_DMAINTR_FATALMASK) { 8367 device_printf(sc->sc_dev, 8368 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8369 mac->mac_reason[0], mac->mac_reason[1], 8370 mac->mac_reason[2], mac->mac_reason[3], 8371 mac->mac_reason[4], mac->mac_reason[5]); 8372 bwn_restart(mac, "DMA error"); 8373 wlan_serialize_exit(); 8374 return; 8375 } 8376 8377 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8378 bwn_intr_ucode_debug(mac); 8379 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8380 bwn_intr_tbtt_indication(mac); 8381 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8382 bwn_intr_atim_end(mac); 8383 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8384 bwn_intr_beacon(mac); 8385 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8386 bwn_intr_pmq(mac); 8387 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8388 bwn_intr_noise(mac); 8389 8390 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8391 if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) { 8392 device_printf(sc->sc_dev, "RX descriptor overflow\n"); 8393 bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx); 8394 } 8395 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8396 bwn_dma_rx(mac->mac_method.dma.rx); 8397 rx = 1; 8398 } 8399 } else 8400 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8401 8402 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8403 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8404 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8405 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8406 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8407 8408 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8409 bwn_intr_txeof(mac); 8410 tx = 1; 8411 } 8412 8413 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8414 8415 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8416 int evt = BWN_LED_EVENT_NONE; 8417 8418 if (tx && rx) { 8419 if (sc->sc_rx_rate > sc->sc_tx_rate) 8420 evt = BWN_LED_EVENT_RX; 8421 else 8422 evt = BWN_LED_EVENT_TX; 8423 } else if (tx) { 8424 evt = BWN_LED_EVENT_TX; 8425 } else if (rx) { 8426 evt = BWN_LED_EVENT_RX; 8427 } else if (rx == 0) { 8428 evt = BWN_LED_EVENT_POLL; 8429 } 8430 8431 if (evt != BWN_LED_EVENT_NONE) 8432 bwn_led_event(mac, evt); 8433 } 8434 8435 if (!ifq_is_oactive(&ifp->if_snd)) { 8436 if (!ifq_is_empty(&ifp->if_snd)) 8437 bwn_start_locked(ifp); 8438 } 8439 8440 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8441 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8442 8443 wlan_serialize_exit(); 8444 } 8445 8446 static void 8447 bwn_restart(struct bwn_mac *mac, const char *msg) 8448 { 8449 struct bwn_softc *sc = mac->mac_sc; 8450 struct ifnet *ifp = sc->sc_ifp; 8451 struct ieee80211com *ic = ifp->if_l2com; 8452 8453 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8454 return; 8455 8456 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8457 ieee80211_runtask(ic, &mac->mac_hwreset); 8458 } 8459 8460 static void 8461 bwn_intr_ucode_debug(struct bwn_mac *mac) 8462 { 8463 struct bwn_softc *sc = mac->mac_sc; 8464 uint16_t reason; 8465 8466 if (mac->mac_fw.opensource == 0) 8467 return; 8468 8469 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8470 switch (reason) { 8471 case BWN_DEBUGINTR_PANIC: 8472 bwn_handle_fwpanic(mac); 8473 break; 8474 case BWN_DEBUGINTR_DUMP_SHM: 8475 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8476 break; 8477 case BWN_DEBUGINTR_DUMP_REGS: 8478 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8479 break; 8480 case BWN_DEBUGINTR_MARKER: 8481 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8482 break; 8483 default: 8484 device_printf(sc->sc_dev, 8485 "ucode debug unknown reason: %#x\n", reason); 8486 } 8487 8488 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8489 BWN_DEBUGINTR_ACK); 8490 } 8491 8492 static void 8493 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8494 { 8495 struct bwn_softc *sc = mac->mac_sc; 8496 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8497 8498 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8499 bwn_psctl(mac, 0); 8500 if (ic->ic_opmode == IEEE80211_M_IBSS) 8501 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8502 } 8503 8504 static void 8505 bwn_intr_atim_end(struct bwn_mac *mac) 8506 { 8507 8508 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8509 BWN_WRITE_4(mac, BWN_MACCMD, 8510 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8511 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8512 } 8513 } 8514 8515 static void 8516 bwn_intr_beacon(struct bwn_mac *mac) 8517 { 8518 struct bwn_softc *sc = mac->mac_sc; 8519 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8520 uint32_t cmd, beacon0, beacon1; 8521 8522 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8523 ic->ic_opmode == IEEE80211_M_MBSS) 8524 return; 8525 8526 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8527 8528 cmd = BWN_READ_4(mac, BWN_MACCMD); 8529 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8530 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8531 8532 if (beacon0 && beacon1) { 8533 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8534 mac->mac_intr_mask |= BWN_INTR_BEACON; 8535 return; 8536 } 8537 8538 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8539 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8540 bwn_load_beacon0(mac); 8541 bwn_load_beacon1(mac); 8542 cmd = BWN_READ_4(mac, BWN_MACCMD); 8543 cmd |= BWN_MACCMD_BEACON0_VALID; 8544 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8545 } else { 8546 if (!beacon0) { 8547 bwn_load_beacon0(mac); 8548 cmd = BWN_READ_4(mac, BWN_MACCMD); 8549 cmd |= BWN_MACCMD_BEACON0_VALID; 8550 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8551 } else if (!beacon1) { 8552 bwn_load_beacon1(mac); 8553 cmd = BWN_READ_4(mac, BWN_MACCMD); 8554 cmd |= BWN_MACCMD_BEACON1_VALID; 8555 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8556 } 8557 } 8558 } 8559 8560 static void 8561 bwn_intr_pmq(struct bwn_mac *mac) 8562 { 8563 uint32_t tmp; 8564 8565 while (1) { 8566 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8567 if (!(tmp & 0x00000008)) 8568 break; 8569 } 8570 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8571 } 8572 8573 static void 8574 bwn_intr_noise(struct bwn_mac *mac) 8575 { 8576 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8577 uint16_t tmp; 8578 uint8_t noise[4]; 8579 uint8_t i, j; 8580 int32_t average; 8581 8582 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8583 return; 8584 8585 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8586 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8587 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8588 noise[3] == 0x7f) 8589 goto new; 8590 8591 KASSERT(mac->mac_noise.noi_nsamples < 8, 8592 ("%s:%d: fail", __func__, __LINE__)); 8593 i = mac->mac_noise.noi_nsamples; 8594 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8595 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8596 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8597 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8598 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8599 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8600 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8601 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8602 mac->mac_noise.noi_nsamples++; 8603 if (mac->mac_noise.noi_nsamples == 8) { 8604 average = 0; 8605 for (i = 0; i < 8; i++) { 8606 for (j = 0; j < 4; j++) 8607 average += mac->mac_noise.noi_samples[i][j]; 8608 } 8609 average = (((average / 32) * 125) + 64) / 128; 8610 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8611 if (tmp >= 8) 8612 average += 2; 8613 else 8614 average -= 25; 8615 average -= (tmp == 8) ? 72 : 48; 8616 8617 mac->mac_stats.link_noise = average; 8618 mac->mac_noise.noi_running = 0; 8619 return; 8620 } 8621 new: 8622 bwn_noise_gensample(mac); 8623 } 8624 8625 static int 8626 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8627 { 8628 struct bwn_mac *mac = prq->prq_mac; 8629 struct bwn_softc *sc = mac->mac_sc; 8630 unsigned int i; 8631 8632 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8633 return (0); 8634 8635 for (i = 0; i < 5000; i++) { 8636 if (bwn_pio_rxeof(prq) == 0) 8637 break; 8638 } 8639 if (i >= 5000) 8640 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8641 return ((i > 0) ? 1 : 0); 8642 } 8643 8644 static void 8645 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr) 8646 { 8647 int curslot, prevslot; 8648 8649 curslot = dr->get_curslot(dr); 8650 if (curslot == 0) 8651 prevslot = dr->dr_numslots - 1; 8652 else 8653 prevslot = curslot - 1; 8654 dr->set_curslot(dr, prevslot); 8655 } 8656 8657 static void 8658 bwn_dma_rx(struct bwn_dma_ring *dr) 8659 { 8660 int slot, curslot; 8661 8662 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8663 curslot = dr->get_curslot(dr); 8664 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8665 ("%s:%d: fail", __func__, __LINE__)); 8666 8667 slot = dr->dr_curslot; 8668 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8669 bwn_dma_rxeof(dr, &slot); 8670 8671 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8672 BUS_DMASYNC_PREWRITE); 8673 8674 dr->set_curslot(dr, slot); 8675 dr->dr_curslot = slot; 8676 } 8677 8678 static void 8679 bwn_intr_txeof(struct bwn_mac *mac) 8680 { 8681 struct bwn_txstatus stat; 8682 uint32_t stat0, stat1; 8683 uint16_t tmp; 8684 8685 while (1) { 8686 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8687 if (!(stat0 & 0x00000001)) 8688 break; 8689 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8690 8691 stat.cookie = (stat0 >> 16); 8692 stat.seq = (stat1 & 0x0000ffff); 8693 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8694 tmp = (stat0 & 0x0000ffff); 8695 stat.framecnt = ((tmp & 0xf000) >> 12); 8696 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8697 stat.sreason = ((tmp & 0x001c) >> 2); 8698 stat.pm = (tmp & 0x0080) ? 1 : 0; 8699 stat.im = (tmp & 0x0040) ? 1 : 0; 8700 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8701 stat.ack = (tmp & 0x0002) ? 1 : 0; 8702 8703 bwn_handle_txeof(mac, &stat); 8704 } 8705 } 8706 8707 static void 8708 bwn_hwreset(void *arg, int npending) 8709 { 8710 struct bwn_mac *mac = arg; 8711 struct bwn_softc *sc = mac->mac_sc; 8712 int error = 0; 8713 int prev_status; 8714 8715 wlan_serialize_enter(); 8716 8717 prev_status = mac->mac_status; 8718 if (prev_status >= BWN_MAC_STATUS_STARTED) 8719 bwn_core_stop(mac); 8720 if (prev_status >= BWN_MAC_STATUS_INITED) 8721 bwn_core_exit(mac); 8722 8723 if (prev_status >= BWN_MAC_STATUS_INITED) { 8724 error = bwn_core_init(mac); 8725 if (error) 8726 goto out; 8727 } 8728 if (prev_status >= BWN_MAC_STATUS_STARTED) 8729 bwn_core_start(mac); 8730 out: 8731 if (error) { 8732 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8733 sc->sc_curmac = NULL; 8734 } 8735 wlan_serialize_exit(); 8736 } 8737 8738 static void 8739 bwn_handle_fwpanic(struct bwn_mac *mac) 8740 { 8741 struct bwn_softc *sc = mac->mac_sc; 8742 uint16_t reason; 8743 8744 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8745 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8746 8747 if (reason == BWN_FWPANIC_RESTART) 8748 bwn_restart(mac, "ucode panic"); 8749 } 8750 8751 static void 8752 bwn_load_beacon0(struct bwn_mac *mac) 8753 { 8754 8755 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8756 } 8757 8758 static void 8759 bwn_load_beacon1(struct bwn_mac *mac) 8760 { 8761 8762 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8763 } 8764 8765 static uint32_t 8766 bwn_jssi_read(struct bwn_mac *mac) 8767 { 8768 uint32_t val = 0; 8769 8770 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8771 val <<= 16; 8772 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8773 8774 return (val); 8775 } 8776 8777 static void 8778 bwn_noise_gensample(struct bwn_mac *mac) 8779 { 8780 uint32_t jssi = 0x7f7f7f7f; 8781 8782 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8783 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8784 BWN_WRITE_4(mac, BWN_MACCMD, 8785 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8786 } 8787 8788 static int 8789 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8790 { 8791 return (dr->dr_numslots - dr->dr_usedslot); 8792 } 8793 8794 static int 8795 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8796 { 8797 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8798 ("%s:%d: fail", __func__, __LINE__)); 8799 if (slot == dr->dr_numslots - 1) 8800 return (0); 8801 return (slot + 1); 8802 } 8803 8804 static void 8805 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8806 { 8807 struct bwn_mac *mac = dr->dr_mac; 8808 struct bwn_softc *sc = mac->mac_sc; 8809 struct bwn_dma *dma = &mac->mac_method.dma; 8810 struct bwn_dmadesc_generic *desc; 8811 struct bwn_dmadesc_meta *meta; 8812 struct bwn_rxhdr4 *rxhdr; 8813 struct ifnet *ifp = sc->sc_ifp; 8814 struct mbuf *m; 8815 uint32_t macstat; 8816 int32_t tmp; 8817 int cnt = 0; 8818 uint16_t len; 8819 8820 dr->getdesc(dr, *slot, &desc, &meta); 8821 8822 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8823 m = meta->mt_m; 8824 8825 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8826 ifp->if_ierrors++; 8827 return; 8828 } 8829 8830 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8831 len = le16toh(rxhdr->frame_len); 8832 if (len <= 0) { 8833 ifp->if_ierrors++; 8834 return; 8835 } 8836 if (bwn_dma_check_redzone(dr, m)) { 8837 device_printf(sc->sc_dev, "redzone error.\n"); 8838 bwn_dma_set_redzone(dr, m); 8839 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8840 BUS_DMASYNC_PREWRITE); 8841 return; 8842 } 8843 if (len > dr->dr_rx_bufsize) { 8844 tmp = len; 8845 while (1) { 8846 dr->getdesc(dr, *slot, &desc, &meta); 8847 bwn_dma_set_redzone(dr, meta->mt_m); 8848 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8849 BUS_DMASYNC_PREWRITE); 8850 *slot = bwn_dma_nextslot(dr, *slot); 8851 cnt++; 8852 tmp -= dr->dr_rx_bufsize; 8853 if (tmp <= 0) 8854 break; 8855 } 8856 device_printf(sc->sc_dev, "too small buffer " 8857 "(len %u buffer %u dropped %d)\n", 8858 len, dr->dr_rx_bufsize, cnt); 8859 return; 8860 } 8861 macstat = le32toh(rxhdr->mac_status); 8862 if (macstat & BWN_RX_MAC_FCSERR) { 8863 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8864 device_printf(sc->sc_dev, "RX drop\n"); 8865 return; 8866 } 8867 } 8868 8869 m->m_pkthdr.rcvif = ifp; 8870 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8871 m_adj(m, dr->dr_frameoffset); 8872 8873 bwn_rxeof(dr->dr_mac, m, rxhdr); 8874 } 8875 8876 static void 8877 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8878 { 8879 struct bwn_dma_ring *dr; 8880 struct bwn_dmadesc_generic *desc; 8881 struct bwn_dmadesc_meta *meta; 8882 struct bwn_pio_txqueue *tq; 8883 struct bwn_pio_txpkt *tp = NULL; 8884 struct bwn_softc *sc = mac->mac_sc; 8885 struct bwn_stats *stats = &mac->mac_stats; 8886 struct ieee80211_node *ni; 8887 struct ieee80211vap *vap; 8888 int retrycnt = 0, slot; 8889 8890 if (status->im) 8891 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8892 if (status->ampdu) 8893 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8894 if (status->rtscnt) { 8895 if (status->rtscnt == 0xf) 8896 stats->rtsfail++; 8897 else 8898 stats->rts++; 8899 } 8900 8901 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8902 if (status->ack) { 8903 dr = bwn_dma_parse_cookie(mac, status, 8904 status->cookie, &slot); 8905 if (dr == NULL) { 8906 device_printf(sc->sc_dev, 8907 "failed to parse cookie\n"); 8908 return; 8909 } 8910 while (1) { 8911 dr->getdesc(dr, slot, &desc, &meta); 8912 if (meta->mt_islast) { 8913 ni = meta->mt_ni; 8914 vap = ni->ni_vap; 8915 ieee80211_ratectl_tx_complete(vap, ni, 8916 status->ack ? 8917 IEEE80211_RATECTL_TX_SUCCESS : 8918 IEEE80211_RATECTL_TX_FAILURE, 8919 &retrycnt, 0); 8920 break; 8921 } 8922 slot = bwn_dma_nextslot(dr, slot); 8923 } 8924 } 8925 bwn_dma_handle_txeof(mac, status); 8926 } else { 8927 if (status->ack) { 8928 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 8929 if (tq == NULL) { 8930 device_printf(sc->sc_dev, 8931 "failed to parse cookie\n"); 8932 return; 8933 } 8934 ni = tp->tp_ni; 8935 vap = ni->ni_vap; 8936 ieee80211_ratectl_tx_complete(vap, ni, 8937 status->ack ? 8938 IEEE80211_RATECTL_TX_SUCCESS : 8939 IEEE80211_RATECTL_TX_FAILURE, 8940 &retrycnt, 0); 8941 } 8942 bwn_pio_handle_txeof(mac, status); 8943 } 8944 8945 bwn_phy_txpower_check(mac, 0); 8946 } 8947 8948 static uint8_t 8949 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 8950 { 8951 struct bwn_mac *mac = prq->prq_mac; 8952 struct bwn_softc *sc = mac->mac_sc; 8953 struct bwn_rxhdr4 rxhdr; 8954 struct ifnet *ifp = sc->sc_ifp; 8955 struct mbuf *m; 8956 uint32_t ctl32, macstat, v32; 8957 unsigned int i, padding; 8958 uint16_t ctl16, len, totlen, v16; 8959 unsigned char *mp; 8960 char *data; 8961 8962 memset(&rxhdr, 0, sizeof(rxhdr)); 8963 8964 if (prq->prq_rev >= 8) { 8965 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8966 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 8967 return (0); 8968 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 8969 BWN_PIO8_RXCTL_FRAMEREADY); 8970 for (i = 0; i < 10; i++) { 8971 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8972 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 8973 goto ready; 8974 DELAY(10); 8975 } 8976 } else { 8977 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8978 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 8979 return (0); 8980 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 8981 BWN_PIO_RXCTL_FRAMEREADY); 8982 for (i = 0; i < 10; i++) { 8983 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8984 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 8985 goto ready; 8986 DELAY(10); 8987 } 8988 } 8989 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 8990 return (1); 8991 ready: 8992 if (prq->prq_rev >= 8) 8993 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8994 prq->prq_base + BWN_PIO8_RXDATA); 8995 else 8996 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8997 prq->prq_base + BWN_PIO_RXDATA); 8998 len = le16toh(rxhdr.frame_len); 8999 if (len > 0x700) { 9000 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9001 goto error; 9002 } 9003 if (len == 0) { 9004 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9005 goto error; 9006 } 9007 9008 macstat = le32toh(rxhdr.mac_status); 9009 if (macstat & BWN_RX_MAC_FCSERR) { 9010 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9011 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9012 goto error; 9013 } 9014 } 9015 9016 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9017 totlen = len + padding; 9018 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9019 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9020 if (m == NULL) { 9021 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9022 goto error; 9023 } 9024 mp = mtod(m, unsigned char *); 9025 if (prq->prq_rev >= 8) { 9026 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9027 prq->prq_base + BWN_PIO8_RXDATA); 9028 if (totlen & 3) { 9029 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9030 data = &(mp[totlen - 1]); 9031 switch (totlen & 3) { 9032 case 3: 9033 *data = (v32 >> 16); 9034 data--; 9035 case 2: 9036 *data = (v32 >> 8); 9037 data--; 9038 case 1: 9039 *data = v32; 9040 } 9041 } 9042 } else { 9043 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9044 prq->prq_base + BWN_PIO_RXDATA); 9045 if (totlen & 1) { 9046 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9047 mp[totlen - 1] = v16; 9048 } 9049 } 9050 9051 m->m_pkthdr.rcvif = ifp; 9052 m->m_len = m->m_pkthdr.len = totlen; 9053 9054 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9055 9056 return (1); 9057 error: 9058 if (prq->prq_rev >= 8) 9059 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9060 BWN_PIO8_RXCTL_DATAREADY); 9061 else 9062 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9063 return (1); 9064 } 9065 9066 static int 9067 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9068 struct bwn_dmadesc_meta *meta, int init) 9069 { 9070 struct bwn_mac *mac = dr->dr_mac; 9071 struct bwn_dma *dma = &mac->mac_method.dma; 9072 struct bwn_rxhdr4 *hdr; 9073 bus_dmamap_t map; 9074 bus_addr_t paddr; 9075 struct mbuf *m; 9076 int error; 9077 9078 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9079 if (m == NULL) { 9080 error = ENOBUFS; 9081 9082 /* 9083 * If the NIC is up and running, we need to: 9084 * - Clear RX buffer's header. 9085 * - Restore RX descriptor settings. 9086 */ 9087 if (init) 9088 return (error); 9089 else 9090 goto back; 9091 } 9092 m->m_len = m->m_pkthdr.len = MCLBYTES; 9093 9094 bwn_dma_set_redzone(dr, m); 9095 9096 /* 9097 * Try to load RX buf into temporary DMA map 9098 */ 9099 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9100 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9101 if (error) { 9102 m_freem(m); 9103 9104 /* 9105 * See the comment above 9106 */ 9107 if (init) 9108 return (error); 9109 else 9110 goto back; 9111 } 9112 9113 if (!init) 9114 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9115 meta->mt_m = m; 9116 meta->mt_paddr = paddr; 9117 9118 /* 9119 * Swap RX buf's DMA map with the loaded temporary one 9120 */ 9121 map = meta->mt_dmap; 9122 meta->mt_dmap = dr->dr_spare_dmap; 9123 dr->dr_spare_dmap = map; 9124 9125 back: 9126 /* 9127 * Clear RX buf header 9128 */ 9129 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9130 bzero(hdr, sizeof(*hdr)); 9131 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9132 BUS_DMASYNC_PREWRITE); 9133 9134 /* 9135 * Setup RX buf descriptor 9136 */ 9137 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9138 sizeof(*hdr), 0, 0, 0); 9139 return (error); 9140 } 9141 9142 static void 9143 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9144 bus_size_t mapsz __unused, int error) 9145 { 9146 9147 if (!error) { 9148 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9149 *((bus_addr_t *)arg) = seg->ds_addr; 9150 } 9151 } 9152 9153 static int 9154 bwn_hwrate2ieeerate(int rate) 9155 { 9156 9157 switch (rate) { 9158 case BWN_CCK_RATE_1MB: 9159 return (2); 9160 case BWN_CCK_RATE_2MB: 9161 return (4); 9162 case BWN_CCK_RATE_5MB: 9163 return (11); 9164 case BWN_CCK_RATE_11MB: 9165 return (22); 9166 case BWN_OFDM_RATE_6MB: 9167 return (12); 9168 case BWN_OFDM_RATE_9MB: 9169 return (18); 9170 case BWN_OFDM_RATE_12MB: 9171 return (24); 9172 case BWN_OFDM_RATE_18MB: 9173 return (36); 9174 case BWN_OFDM_RATE_24MB: 9175 return (48); 9176 case BWN_OFDM_RATE_36MB: 9177 return (72); 9178 case BWN_OFDM_RATE_48MB: 9179 return (96); 9180 case BWN_OFDM_RATE_54MB: 9181 return (108); 9182 default: 9183 kprintf("Ooops\n"); 9184 return (0); 9185 } 9186 } 9187 9188 static void 9189 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9190 { 9191 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9192 struct bwn_plcp6 *plcp; 9193 struct bwn_softc *sc = mac->mac_sc; 9194 struct ieee80211_frame_min *wh; 9195 struct ieee80211_node *ni; 9196 struct ifnet *ifp = sc->sc_ifp; 9197 struct ieee80211com *ic = ifp->if_l2com; 9198 uint32_t macstat; 9199 int padding, rate, rssi = 0, noise = 0, type; 9200 uint16_t phytype, phystat0, phystat3, chanstat; 9201 unsigned char *mp = mtod(m, unsigned char *); 9202 static int rx_mac_dec_rpt = 0; 9203 9204 phystat0 = le16toh(rxhdr->phy_status0); 9205 phystat3 = le16toh(rxhdr->phy_status3); 9206 macstat = le32toh(rxhdr->mac_status); 9207 chanstat = le16toh(rxhdr->channel); 9208 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9209 9210 if (macstat & BWN_RX_MAC_FCSERR) 9211 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9212 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9213 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9214 if (macstat & BWN_RX_MAC_DECERR) 9215 goto drop; 9216 9217 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9218 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9219 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9220 m->m_pkthdr.len); 9221 goto drop; 9222 } 9223 plcp = (struct bwn_plcp6 *)(mp + padding); 9224 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9225 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9226 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9227 m->m_pkthdr.len); 9228 goto drop; 9229 } 9230 wh = mtod(m, struct ieee80211_frame_min *); 9231 9232 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9233 device_printf(sc->sc_dev, 9234 "RX decryption attempted (old %d keyidx %#x)\n", 9235 BWN_ISOLDFMT(mac), 9236 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9237 9238 /* XXX calculating RSSI & noise & antenna */ 9239 9240 if (phystat0 & BWN_RX_PHYST0_OFDM) 9241 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9242 phytype == BWN_PHYTYPE_A); 9243 else 9244 rate = bwn_plcp_get_cckrate(mac, plcp); 9245 if (rate == -1) { 9246 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9247 goto drop; 9248 } 9249 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9250 9251 /* RX radio tap */ 9252 if (ieee80211_radiotap_active(ic)) 9253 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9254 m_adj(m, -IEEE80211_CRC_LEN); 9255 9256 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9257 noise = mac->mac_stats.link_noise; 9258 9259 ifp->if_ipackets++; 9260 9261 ni = ieee80211_find_rxnode(ic, wh); 9262 if (ni != NULL) { 9263 type = ieee80211_input(ni, m, rssi, noise); 9264 ieee80211_free_node(ni); 9265 } else 9266 type = ieee80211_input_all(ic, m, rssi, noise); 9267 9268 return; 9269 drop: 9270 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9271 } 9272 9273 static void 9274 bwn_dma_handle_txeof(struct bwn_mac *mac, 9275 const struct bwn_txstatus *status) 9276 { 9277 struct bwn_dma *dma = &mac->mac_method.dma; 9278 struct bwn_dma_ring *dr; 9279 struct bwn_dmadesc_generic *desc; 9280 struct bwn_dmadesc_meta *meta; 9281 struct bwn_softc *sc = mac->mac_sc; 9282 struct ieee80211_node *ni; 9283 struct ifnet *ifp = sc->sc_ifp; 9284 struct mbuf *m; 9285 int slot; 9286 9287 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9288 if (dr == NULL) { 9289 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9290 return; 9291 } 9292 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9293 9294 while (1) { 9295 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9296 ("%s:%d: fail", __func__, __LINE__)); 9297 dr->getdesc(dr, slot, &desc, &meta); 9298 9299 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 9300 bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap, 9301 BUS_DMASYNC_POSTWRITE); 9302 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 9303 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9304 } 9305 9306 if (meta->mt_islast) { 9307 KASSERT(meta->mt_m != NULL, 9308 ("%s:%d: fail", __func__, __LINE__)); 9309 9310 ni = meta->mt_ni; 9311 m = meta->mt_m; 9312 if (ni != NULL) { 9313 /* 9314 * Do any tx complete callback. Note this must 9315 * be done before releasing the node reference. 9316 */ 9317 if (m->m_flags & M_TXCB) 9318 ieee80211_process_callback(ni, m, 0); 9319 ieee80211_free_node(ni); 9320 meta->mt_ni = NULL; 9321 } 9322 m_freem(m); 9323 meta->mt_m = NULL; 9324 } else { 9325 KASSERT(meta->mt_m == NULL, 9326 ("%s:%d: fail", __func__, __LINE__)); 9327 } 9328 9329 dr->dr_usedslot--; 9330 if (meta->mt_islast) { 9331 ifp->if_opackets++; 9332 break; 9333 } 9334 slot = bwn_dma_nextslot(dr, slot); 9335 } 9336 sc->sc_watchdog_timer = 0; 9337 if (dr->dr_stop) { 9338 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9339 ("%s:%d: fail", __func__, __LINE__)); 9340 ifq_clr_oactive(&ifp->if_snd); 9341 dr->dr_stop = 0; 9342 } 9343 } 9344 9345 static void 9346 bwn_pio_handle_txeof(struct bwn_mac *mac, 9347 const struct bwn_txstatus *status) 9348 { 9349 struct bwn_pio_txqueue *tq; 9350 struct bwn_pio_txpkt *tp = NULL; 9351 struct bwn_softc *sc = mac->mac_sc; 9352 struct ifnet *ifp = sc->sc_ifp; 9353 9354 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9355 if (tq == NULL) 9356 return; 9357 9358 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9359 tq->tq_free++; 9360 9361 if (tp->tp_ni != NULL) { 9362 /* 9363 * Do any tx complete callback. Note this must 9364 * be done before releasing the node reference. 9365 */ 9366 if (tp->tp_m->m_flags & M_TXCB) 9367 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9368 ieee80211_free_node(tp->tp_ni); 9369 tp->tp_ni = NULL; 9370 } 9371 m_freem(tp->tp_m); 9372 tp->tp_m = NULL; 9373 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9374 9375 ifp->if_opackets++; 9376 9377 sc->sc_watchdog_timer = 0; 9378 if (tq->tq_stop) { 9379 ifq_clr_oactive(&ifp->if_snd); 9380 tq->tq_stop = 0; 9381 } 9382 } 9383 9384 static void 9385 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9386 { 9387 struct bwn_softc *sc = mac->mac_sc; 9388 struct bwn_phy *phy = &mac->mac_phy; 9389 struct ifnet *ifp = sc->sc_ifp; 9390 struct ieee80211com *ic = ifp->if_l2com; 9391 unsigned long now; 9392 int result; 9393 9394 BWN_GETTIME(now); 9395 9396 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9397 return; 9398 phy->nexttime = now + 2 * 1000; 9399 9400 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9401 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9402 return; 9403 9404 if (phy->recalc_txpwr != NULL) { 9405 result = phy->recalc_txpwr(mac, 9406 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9407 if (result == BWN_TXPWR_RES_DONE) 9408 return; 9409 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9410 ("%s: fail", __func__)); 9411 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9412 9413 ieee80211_runtask(ic, &mac->mac_txpower); 9414 } 9415 } 9416 9417 static uint16_t 9418 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9419 { 9420 9421 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9422 } 9423 9424 static uint32_t 9425 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9426 { 9427 9428 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9429 } 9430 9431 static void 9432 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9433 { 9434 9435 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9436 } 9437 9438 static void 9439 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9440 { 9441 9442 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9443 } 9444 9445 static int 9446 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9447 { 9448 9449 switch (rate) { 9450 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9451 case 12: 9452 return (BWN_OFDM_RATE_6MB); 9453 case 18: 9454 return (BWN_OFDM_RATE_9MB); 9455 case 24: 9456 return (BWN_OFDM_RATE_12MB); 9457 case 36: 9458 return (BWN_OFDM_RATE_18MB); 9459 case 48: 9460 return (BWN_OFDM_RATE_24MB); 9461 case 72: 9462 return (BWN_OFDM_RATE_36MB); 9463 case 96: 9464 return (BWN_OFDM_RATE_48MB); 9465 case 108: 9466 return (BWN_OFDM_RATE_54MB); 9467 /* CCK rates (NB: not IEEE std, device-specific) */ 9468 case 2: 9469 return (BWN_CCK_RATE_1MB); 9470 case 4: 9471 return (BWN_CCK_RATE_2MB); 9472 case 11: 9473 return (BWN_CCK_RATE_5MB); 9474 case 22: 9475 return (BWN_CCK_RATE_11MB); 9476 } 9477 9478 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9479 return (BWN_CCK_RATE_1MB); 9480 } 9481 9482 static int 9483 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9484 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9485 { 9486 const struct bwn_phy *phy = &mac->mac_phy; 9487 struct bwn_softc *sc = mac->mac_sc; 9488 struct ieee80211_frame *wh; 9489 struct ieee80211_frame *protwh; 9490 struct ieee80211_frame_cts *cts; 9491 struct ieee80211_frame_rts *rts; 9492 const struct ieee80211_txparam *tp; 9493 struct ieee80211vap *vap = ni->ni_vap; 9494 struct ifnet *ifp = sc->sc_ifp; 9495 struct ieee80211com *ic = ifp->if_l2com; 9496 struct mbuf *mprot; 9497 unsigned int len; 9498 uint32_t macctl = 0; 9499 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9500 uint16_t phyctl = 0; 9501 uint8_t rate, rate_fb; 9502 9503 wh = mtod(m, struct ieee80211_frame *); 9504 memset(txhdr, 0, sizeof(*txhdr)); 9505 9506 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9507 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9508 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9509 9510 /* 9511 * Find TX rate 9512 */ 9513 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9514 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9515 rate = rate_fb = tp->mgmtrate; 9516 else if (ismcast) 9517 rate = rate_fb = tp->mcastrate; 9518 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9519 rate = rate_fb = tp->ucastrate; 9520 else { 9521 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9522 rate = ni->ni_txrate; 9523 9524 if (rix > 0) 9525 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9526 IEEE80211_RATE_VAL; 9527 else 9528 rate_fb = rate; 9529 } 9530 9531 sc->sc_tx_rate = rate; 9532 9533 rate = bwn_ieeerate2hwrate(sc, rate); 9534 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9535 9536 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9537 bwn_plcp_getcck(rate); 9538 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9539 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9540 9541 if ((rate_fb == rate) || 9542 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9543 (*(u_int16_t *)wh->i_dur == htole16(0))) 9544 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9545 else 9546 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9547 m->m_pkthdr.len, rate, isshort); 9548 9549 /* XXX TX encryption */ 9550 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9551 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9552 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9553 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9554 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9555 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9556 9557 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9558 BWN_TX_EFT_FB_CCK; 9559 txhdr->chan = phy->chan; 9560 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9561 BWN_TX_PHY_ENC_CCK; 9562 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9563 rate == BWN_CCK_RATE_11MB)) 9564 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9565 9566 /* XXX TX antenna selection */ 9567 9568 switch (bwn_antenna_sanitize(mac, 0)) { 9569 case 0: 9570 phyctl |= BWN_TX_PHY_ANT01AUTO; 9571 break; 9572 case 1: 9573 phyctl |= BWN_TX_PHY_ANT0; 9574 break; 9575 case 2: 9576 phyctl |= BWN_TX_PHY_ANT1; 9577 break; 9578 case 3: 9579 phyctl |= BWN_TX_PHY_ANT2; 9580 break; 9581 case 4: 9582 phyctl |= BWN_TX_PHY_ANT3; 9583 break; 9584 default: 9585 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9586 } 9587 9588 if (!ismcast) 9589 macctl |= BWN_TX_MAC_ACK; 9590 9591 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9592 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9593 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9594 macctl |= BWN_TX_MAC_LONGFRAME; 9595 9596 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9597 /* XXX RTS rate is always 1MB??? */ 9598 rts_rate = BWN_CCK_RATE_1MB; 9599 rts_rate_fb = bwn_get_fbrate(rts_rate); 9600 9601 protdur = ieee80211_compute_duration(ic->ic_rt, 9602 m->m_pkthdr.len, rate, isshort) + 9603 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9604 9605 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9606 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9607 (txhdr->body.old.rts_frame) : 9608 (txhdr->body.new.rts_frame)); 9609 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9610 protdur); 9611 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9612 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9613 mprot->m_pkthdr.len); 9614 m_freem(mprot); 9615 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9616 len = sizeof(struct ieee80211_frame_cts); 9617 } else { 9618 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9619 (txhdr->body.old.rts_frame) : 9620 (txhdr->body.new.rts_frame)); 9621 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9622 isshort); 9623 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9624 wh->i_addr2, protdur); 9625 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9626 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9627 mprot->m_pkthdr.len); 9628 m_freem(mprot); 9629 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9630 len = sizeof(struct ieee80211_frame_rts); 9631 } 9632 len += IEEE80211_CRC_LEN; 9633 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9634 &txhdr->body.old.rts_plcp : 9635 &txhdr->body.new.rts_plcp), len, rts_rate); 9636 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9637 rts_rate_fb); 9638 9639 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9640 (&txhdr->body.old.rts_frame) : 9641 (&txhdr->body.new.rts_frame)); 9642 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9643 9644 if (BWN_ISOFDMRATE(rts_rate)) { 9645 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9646 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9647 } else { 9648 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9649 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9650 } 9651 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9652 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9653 } 9654 9655 if (BWN_ISOLDFMT(mac)) 9656 txhdr->body.old.cookie = htole16(cookie); 9657 else 9658 txhdr->body.new.cookie = htole16(cookie); 9659 9660 txhdr->macctl = htole32(macctl); 9661 txhdr->phyctl = htole16(phyctl); 9662 9663 /* 9664 * TX radio tap 9665 */ 9666 if (ieee80211_radiotap_active_vap(vap)) { 9667 sc->sc_tx_th.wt_flags = 0; 9668 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9669 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9670 if (isshort && 9671 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9672 rate == BWN_CCK_RATE_11MB)) 9673 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9674 sc->sc_tx_th.wt_rate = rate; 9675 9676 ieee80211_radiotap_tx(vap, m); 9677 } 9678 9679 return (0); 9680 } 9681 9682 static void 9683 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9684 const uint8_t rate) 9685 { 9686 uint32_t d, plen; 9687 uint8_t *raw = plcp->o.raw; 9688 9689 if (BWN_ISOFDMRATE(rate)) { 9690 d = bwn_plcp_getofdm(rate); 9691 KASSERT(!(octets & 0xf000), 9692 ("%s:%d: fail", __func__, __LINE__)); 9693 d |= (octets << 5); 9694 plcp->o.data = htole32(d); 9695 } else { 9696 plen = octets * 16 / rate; 9697 if ((octets * 16 % rate) > 0) { 9698 plen++; 9699 if ((rate == BWN_CCK_RATE_11MB) 9700 && ((octets * 8 % 11) < 4)) { 9701 raw[1] = 0x84; 9702 } else 9703 raw[1] = 0x04; 9704 } else 9705 raw[1] = 0x04; 9706 plcp->o.data |= htole32(plen << 16); 9707 raw[0] = bwn_plcp_getcck(rate); 9708 } 9709 } 9710 9711 static uint8_t 9712 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9713 { 9714 struct bwn_softc *sc = mac->mac_sc; 9715 uint8_t mask; 9716 9717 if (n == 0) 9718 return (0); 9719 if (mac->mac_phy.gmode) 9720 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9721 else 9722 mask = siba_sprom_get_ant_a(sc->sc_dev); 9723 if (!(mask & (1 << (n - 1)))) 9724 return (0); 9725 return (n); 9726 } 9727 9728 static uint8_t 9729 bwn_get_fbrate(uint8_t bitrate) 9730 { 9731 switch (bitrate) { 9732 case BWN_CCK_RATE_1MB: 9733 return (BWN_CCK_RATE_1MB); 9734 case BWN_CCK_RATE_2MB: 9735 return (BWN_CCK_RATE_1MB); 9736 case BWN_CCK_RATE_5MB: 9737 return (BWN_CCK_RATE_2MB); 9738 case BWN_CCK_RATE_11MB: 9739 return (BWN_CCK_RATE_5MB); 9740 case BWN_OFDM_RATE_6MB: 9741 return (BWN_CCK_RATE_5MB); 9742 case BWN_OFDM_RATE_9MB: 9743 return (BWN_OFDM_RATE_6MB); 9744 case BWN_OFDM_RATE_12MB: 9745 return (BWN_OFDM_RATE_9MB); 9746 case BWN_OFDM_RATE_18MB: 9747 return (BWN_OFDM_RATE_12MB); 9748 case BWN_OFDM_RATE_24MB: 9749 return (BWN_OFDM_RATE_18MB); 9750 case BWN_OFDM_RATE_36MB: 9751 return (BWN_OFDM_RATE_24MB); 9752 case BWN_OFDM_RATE_48MB: 9753 return (BWN_OFDM_RATE_36MB); 9754 case BWN_OFDM_RATE_54MB: 9755 return (BWN_OFDM_RATE_48MB); 9756 } 9757 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9758 return (0); 9759 } 9760 9761 static uint32_t 9762 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9763 uint32_t ctl, const void *_data, int len) 9764 { 9765 struct bwn_softc *sc = mac->mac_sc; 9766 uint32_t value = 0; 9767 const uint8_t *data = _data; 9768 9769 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9770 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9771 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9772 9773 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9774 tq->tq_base + BWN_PIO8_TXDATA); 9775 if (len & 3) { 9776 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9777 BWN_PIO8_TXCTL_24_31); 9778 data = &(data[len - 1]); 9779 switch (len & 3) { 9780 case 3: 9781 ctl |= BWN_PIO8_TXCTL_16_23; 9782 value |= (uint32_t)(*data) << 16; 9783 data--; 9784 case 2: 9785 ctl |= BWN_PIO8_TXCTL_8_15; 9786 value |= (uint32_t)(*data) << 8; 9787 data--; 9788 case 1: 9789 value |= (uint32_t)(*data); 9790 } 9791 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9792 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9793 } 9794 9795 return (ctl); 9796 } 9797 9798 static void 9799 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9800 uint16_t offset, uint32_t value) 9801 { 9802 9803 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9804 } 9805 9806 static uint16_t 9807 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9808 uint16_t ctl, const void *_data, int len) 9809 { 9810 struct bwn_softc *sc = mac->mac_sc; 9811 const uint8_t *data = _data; 9812 9813 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9814 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9815 9816 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9817 tq->tq_base + BWN_PIO_TXDATA); 9818 if (len & 1) { 9819 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9820 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9821 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9822 } 9823 9824 return (ctl); 9825 } 9826 9827 static uint16_t 9828 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9829 uint16_t ctl, struct mbuf *m0) 9830 { 9831 int i, j = 0; 9832 uint16_t data = 0; 9833 const uint8_t *buf; 9834 struct mbuf *m = m0; 9835 9836 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9837 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9838 9839 for (; m != NULL; m = m->m_next) { 9840 buf = mtod(m, const uint8_t *); 9841 for (i = 0; i < m->m_len; i++) { 9842 if (!((j++) % 2)) 9843 data |= buf[i]; 9844 else { 9845 data |= (buf[i] << 8); 9846 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9847 data = 0; 9848 } 9849 } 9850 } 9851 if (m0->m_pkthdr.len % 2) { 9852 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9853 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9854 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9855 } 9856 9857 return (ctl); 9858 } 9859 9860 static void 9861 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9862 { 9863 9864 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9865 return; 9866 BWN_WRITE_2(mac, 0x684, 510 + time); 9867 9868 /* 9869 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a 9870 * a severe performance penalty (especially when sending). 9871 */ 9872 #if 0 9873 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9874 #endif 9875 } 9876 9877 static struct bwn_dma_ring * 9878 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9879 { 9880 9881 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9882 return (mac->mac_method.dma.wme[WME_AC_BE]); 9883 9884 switch (prio) { 9885 case 3: 9886 return (mac->mac_method.dma.wme[WME_AC_VO]); 9887 case 2: 9888 return (mac->mac_method.dma.wme[WME_AC_VI]); 9889 case 0: 9890 return (mac->mac_method.dma.wme[WME_AC_BE]); 9891 case 1: 9892 return (mac->mac_method.dma.wme[WME_AC_BK]); 9893 } 9894 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9895 return (NULL); 9896 } 9897 9898 static int 9899 bwn_dma_getslot(struct bwn_dma_ring *dr) 9900 { 9901 int slot; 9902 9903 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9904 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 9905 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 9906 9907 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 9908 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 9909 dr->dr_curslot = slot; 9910 dr->dr_usedslot++; 9911 9912 return (slot); 9913 } 9914 9915 static int 9916 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 9917 { 9918 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 9919 unsigned int a, b, c, d; 9920 unsigned int avg; 9921 uint32_t tmp; 9922 9923 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 9924 a = tmp & 0xff; 9925 b = (tmp >> 8) & 0xff; 9926 c = (tmp >> 16) & 0xff; 9927 d = (tmp >> 24) & 0xff; 9928 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 9929 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 9930 return (ENOENT); 9931 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 9932 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 9933 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 9934 9935 if (ofdm) { 9936 a = (a + 32) & 0x3f; 9937 b = (b + 32) & 0x3f; 9938 c = (c + 32) & 0x3f; 9939 d = (d + 32) & 0x3f; 9940 } 9941 9942 avg = (a + b + c + d + 2) / 4; 9943 if (ofdm) { 9944 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 9945 & BWN_HF_4DB_CCK_POWERBOOST) 9946 avg = (avg >= 13) ? (avg - 13) : 0; 9947 } 9948 return (avg); 9949 } 9950 9951 static void 9952 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 9953 { 9954 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 9955 int rfatt = *rfattp; 9956 int bbatt = *bbattp; 9957 9958 while (1) { 9959 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 9960 break; 9961 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 9962 break; 9963 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 9964 break; 9965 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 9966 break; 9967 if (bbatt > lo->bbatt.max) { 9968 bbatt -= 4; 9969 rfatt += 1; 9970 continue; 9971 } 9972 if (bbatt < lo->bbatt.min) { 9973 bbatt += 4; 9974 rfatt -= 1; 9975 continue; 9976 } 9977 if (rfatt > lo->rfatt.max) { 9978 rfatt -= 1; 9979 bbatt += 4; 9980 continue; 9981 } 9982 if (rfatt < lo->rfatt.min) { 9983 rfatt += 1; 9984 bbatt -= 4; 9985 continue; 9986 } 9987 break; 9988 } 9989 9990 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 9991 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 9992 } 9993 9994 static void 9995 bwn_phy_lock(struct bwn_mac *mac) 9996 { 9997 struct bwn_softc *sc = mac->mac_sc; 9998 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 9999 10000 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10001 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10002 10003 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10004 bwn_psctl(mac, BWN_PS_AWAKE); 10005 } 10006 10007 static void 10008 bwn_phy_unlock(struct bwn_mac *mac) 10009 { 10010 struct bwn_softc *sc = mac->mac_sc; 10011 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10012 10013 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10014 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10015 10016 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10017 bwn_psctl(mac, 0); 10018 } 10019 10020 static void 10021 bwn_rf_lock(struct bwn_mac *mac) 10022 { 10023 10024 BWN_WRITE_4(mac, BWN_MACCTL, 10025 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10026 BWN_READ_4(mac, BWN_MACCTL); 10027 DELAY(10); 10028 } 10029 10030 static void 10031 bwn_rf_unlock(struct bwn_mac *mac) 10032 { 10033 10034 BWN_READ_2(mac, BWN_PHYVER); 10035 BWN_WRITE_4(mac, BWN_MACCTL, 10036 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10037 } 10038 10039 static struct bwn_pio_txqueue * 10040 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10041 struct bwn_pio_txpkt **pack) 10042 { 10043 struct bwn_pio *pio = &mac->mac_method.pio; 10044 struct bwn_pio_txqueue *tq = NULL; 10045 unsigned int index; 10046 10047 switch (cookie & 0xf000) { 10048 case 0x1000: 10049 tq = &pio->wme[WME_AC_BK]; 10050 break; 10051 case 0x2000: 10052 tq = &pio->wme[WME_AC_BE]; 10053 break; 10054 case 0x3000: 10055 tq = &pio->wme[WME_AC_VI]; 10056 break; 10057 case 0x4000: 10058 tq = &pio->wme[WME_AC_VO]; 10059 break; 10060 case 0x5000: 10061 tq = &pio->mcast; 10062 break; 10063 } 10064 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10065 if (tq == NULL) 10066 return (NULL); 10067 index = (cookie & 0x0fff); 10068 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10069 if (index >= N(tq->tq_pkts)) 10070 return (NULL); 10071 *pack = &tq->tq_pkts[index]; 10072 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10073 return (tq); 10074 } 10075 10076 static void 10077 bwn_txpwr(void *arg, int npending) 10078 { 10079 struct bwn_mac *mac = arg; 10080 10081 wlan_serialize_enter(); 10082 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10083 mac->mac_phy.set_txpwr != NULL) 10084 mac->mac_phy.set_txpwr(mac); 10085 wlan_serialize_exit(); 10086 } 10087 10088 static void 10089 bwn_task_15s(struct bwn_mac *mac) 10090 { 10091 uint16_t reg; 10092 10093 if (mac->mac_fw.opensource) { 10094 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10095 if (reg) { 10096 bwn_restart(mac, "fw watchdog"); 10097 return; 10098 } 10099 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10100 } 10101 if (mac->mac_phy.task_15s) 10102 mac->mac_phy.task_15s(mac); 10103 10104 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10105 } 10106 10107 static void 10108 bwn_task_30s(struct bwn_mac *mac) 10109 { 10110 10111 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10112 return; 10113 mac->mac_noise.noi_running = 1; 10114 mac->mac_noise.noi_nsamples = 0; 10115 10116 bwn_noise_gensample(mac); 10117 } 10118 10119 static void 10120 bwn_task_60s(struct bwn_mac *mac) 10121 { 10122 10123 if (mac->mac_phy.task_60s) 10124 mac->mac_phy.task_60s(mac); 10125 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10126 } 10127 10128 static void 10129 bwn_tasks(void *arg) 10130 { 10131 struct bwn_mac *mac = arg; 10132 struct bwn_softc *sc = mac->mac_sc; 10133 10134 wlan_serialize_enter(); 10135 10136 if (mac->mac_status != BWN_MAC_STATUS_STARTED) { 10137 wlan_serialize_exit(); 10138 return; 10139 } 10140 10141 if (mac->mac_task_state % 4 == 0) 10142 bwn_task_60s(mac); 10143 if (mac->mac_task_state % 2 == 0) 10144 bwn_task_30s(mac); 10145 bwn_task_15s(mac); 10146 10147 mac->mac_task_state++; 10148 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10149 wlan_serialize_exit(); 10150 } 10151 10152 static int 10153 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10154 { 10155 struct bwn_softc *sc = mac->mac_sc; 10156 10157 KASSERT(a == 0, ("not support APHY\n")); 10158 10159 switch (plcp->o.raw[0] & 0xf) { 10160 case 0xb: 10161 return (BWN_OFDM_RATE_6MB); 10162 case 0xf: 10163 return (BWN_OFDM_RATE_9MB); 10164 case 0xa: 10165 return (BWN_OFDM_RATE_12MB); 10166 case 0xe: 10167 return (BWN_OFDM_RATE_18MB); 10168 case 0x9: 10169 return (BWN_OFDM_RATE_24MB); 10170 case 0xd: 10171 return (BWN_OFDM_RATE_36MB); 10172 case 0x8: 10173 return (BWN_OFDM_RATE_48MB); 10174 case 0xc: 10175 return (BWN_OFDM_RATE_54MB); 10176 } 10177 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10178 plcp->o.raw[0] & 0xf); 10179 return (-1); 10180 } 10181 10182 static int 10183 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10184 { 10185 struct bwn_softc *sc = mac->mac_sc; 10186 10187 switch (plcp->o.raw[0]) { 10188 case 0x0a: 10189 return (BWN_CCK_RATE_1MB); 10190 case 0x14: 10191 return (BWN_CCK_RATE_2MB); 10192 case 0x37: 10193 return (BWN_CCK_RATE_5MB); 10194 case 0x6e: 10195 return (BWN_CCK_RATE_11MB); 10196 } 10197 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10198 return (-1); 10199 } 10200 10201 static void 10202 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10203 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10204 int rssi, int noise) 10205 { 10206 struct bwn_softc *sc = mac->mac_sc; 10207 const struct ieee80211_frame_min *wh; 10208 uint64_t tsf; 10209 uint16_t low_mactime_now; 10210 10211 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10212 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10213 10214 wh = mtod(m, const struct ieee80211_frame_min *); 10215 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10216 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10217 10218 bwn_tsf_read(mac, &tsf); 10219 low_mactime_now = tsf; 10220 tsf = tsf & ~0xffffULL; 10221 tsf += le16toh(rxhdr->mac_time); 10222 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10223 tsf -= 0x10000; 10224 10225 sc->sc_rx_th.wr_tsf = tsf; 10226 sc->sc_rx_th.wr_rate = rate; 10227 sc->sc_rx_th.wr_antsignal = rssi; 10228 sc->sc_rx_th.wr_antnoise = noise; 10229 } 10230 10231 static void 10232 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10233 { 10234 uint32_t low, high; 10235 10236 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10237 ("%s:%d: fail", __func__, __LINE__)); 10238 10239 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10240 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10241 *tsf = high; 10242 *tsf <<= 32; 10243 *tsf |= low; 10244 } 10245 10246 static int 10247 bwn_dma_attach(struct bwn_mac *mac) 10248 { 10249 struct bwn_dma *dma = &mac->mac_method.dma; 10250 struct bwn_softc *sc = mac->mac_sc; 10251 bus_addr_t lowaddr = 0; 10252 int error; 10253 10254 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10255 return (0); 10256 10257 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10258 10259 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10260 10261 dma->dmatype = bwn_dma_gettype(mac); 10262 if (dma->dmatype == BWN_DMA_30BIT) 10263 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10264 else if (dma->dmatype == BWN_DMA_32BIT) 10265 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10266 else 10267 lowaddr = BUS_SPACE_MAXADDR; 10268 10269 /* 10270 * Create top level DMA tag 10271 */ 10272 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10273 BWN_ALIGN, 0, /* alignment, bounds */ 10274 lowaddr, /* lowaddr */ 10275 BUS_SPACE_MAXADDR, /* highaddr */ 10276 NULL, NULL, /* filter, filterarg */ 10277 MAXBSIZE, /* maxsize */ 10278 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10279 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10280 0, /* flags */ 10281 &dma->parent_dtag); 10282 if (error) { 10283 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10284 return (error); 10285 } 10286 10287 /* 10288 * Create TX/RX mbuf DMA tag 10289 */ 10290 error = bus_dma_tag_create(dma->parent_dtag, 10291 4, 10292 0, 10293 BUS_SPACE_MAXADDR, 10294 BUS_SPACE_MAXADDR, 10295 NULL, NULL, 10296 MCLBYTES, 10297 1, 10298 BUS_SPACE_MAXSIZE_32BIT, 10299 0, 10300 &dma->rxbuf_dtag); 10301 if (error) { 10302 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10303 goto fail0; 10304 } 10305 error = bus_dma_tag_create(dma->parent_dtag, 10306 4, 10307 0, 10308 BUS_SPACE_MAXADDR, 10309 BUS_SPACE_MAXADDR, 10310 NULL, NULL, 10311 MCLBYTES, 10312 1, 10313 BUS_SPACE_MAXSIZE_32BIT, 10314 0, 10315 &dma->txbuf_dtag); 10316 if (error) { 10317 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10318 goto fail1; 10319 } 10320 10321 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10322 if (dma->wme[WME_AC_BK] == NULL) 10323 goto fail2; 10324 10325 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10326 if (dma->wme[WME_AC_BE] == NULL) 10327 goto fail3; 10328 10329 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10330 if (dma->wme[WME_AC_VI] == NULL) 10331 goto fail4; 10332 10333 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10334 if (dma->wme[WME_AC_VO] == NULL) 10335 goto fail5; 10336 10337 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10338 if (dma->mcast == NULL) 10339 goto fail6; 10340 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10341 if (dma->rx == NULL) 10342 goto fail7; 10343 10344 return (error); 10345 10346 fail7: bwn_dma_ringfree(&dma->mcast); 10347 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10348 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10349 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10350 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10351 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10352 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10353 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10354 return (error); 10355 } 10356 10357 static struct bwn_dma_ring * 10358 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10359 uint16_t cookie, int *slot) 10360 { 10361 struct bwn_dma *dma = &mac->mac_method.dma; 10362 struct bwn_dma_ring *dr; 10363 struct bwn_softc *sc = mac->mac_sc; 10364 10365 switch (cookie & 0xf000) { 10366 case 0x1000: 10367 dr = dma->wme[WME_AC_BK]; 10368 break; 10369 case 0x2000: 10370 dr = dma->wme[WME_AC_BE]; 10371 break; 10372 case 0x3000: 10373 dr = dma->wme[WME_AC_VI]; 10374 break; 10375 case 0x4000: 10376 dr = dma->wme[WME_AC_VO]; 10377 break; 10378 case 0x5000: 10379 dr = dma->mcast; 10380 break; 10381 default: 10382 dr = NULL; 10383 KASSERT(0 == 1, 10384 ("invalid cookie value %d", cookie & 0xf000)); 10385 } 10386 *slot = (cookie & 0x0fff); 10387 if (*slot < 0 || *slot >= dr->dr_numslots) { 10388 /* 10389 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10390 * that it occurs events which have same H/W sequence numbers. 10391 * When it's occurred just prints a WARNING msgs and ignores. 10392 */ 10393 KASSERT(status->seq == dma->lastseq, 10394 ("%s:%d: fail", __func__, __LINE__)); 10395 device_printf(sc->sc_dev, 10396 "out of slot ranges (0 < %d < %d)\n", *slot, 10397 dr->dr_numslots); 10398 return (NULL); 10399 } 10400 dma->lastseq = status->seq; 10401 return (dr); 10402 } 10403 10404 static void 10405 bwn_dma_stop(struct bwn_mac *mac) 10406 { 10407 struct bwn_dma *dma; 10408 10409 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10410 return; 10411 dma = &mac->mac_method.dma; 10412 10413 bwn_dma_ringstop(&dma->rx); 10414 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10415 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10416 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10417 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10418 bwn_dma_ringstop(&dma->mcast); 10419 } 10420 10421 static void 10422 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10423 { 10424 10425 if (dr == NULL) 10426 return; 10427 10428 bwn_dma_cleanup(*dr); 10429 } 10430 10431 static void 10432 bwn_pio_stop(struct bwn_mac *mac) 10433 { 10434 struct bwn_pio *pio; 10435 10436 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10437 return; 10438 pio = &mac->mac_method.pio; 10439 10440 bwn_destroy_queue_tx(&pio->mcast); 10441 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10442 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10443 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10444 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10445 } 10446 10447 static void 10448 bwn_led_attach(struct bwn_mac *mac) 10449 { 10450 struct bwn_softc *sc = mac->mac_sc; 10451 const uint8_t *led_act = NULL; 10452 uint16_t val[BWN_LED_MAX]; 10453 int i; 10454 10455 sc->sc_led_idle = (2350 * hz) / 1000; 10456 sc->sc_led_blink = 1; 10457 10458 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10459 if (siba_get_pci_subvendor(sc->sc_dev) == 10460 bwn_vendor_led_act[i].vid) { 10461 led_act = bwn_vendor_led_act[i].led_act; 10462 break; 10463 } 10464 } 10465 if (led_act == NULL) 10466 led_act = bwn_default_led_act; 10467 10468 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10469 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10470 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10471 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10472 10473 for (i = 0; i < BWN_LED_MAX; ++i) { 10474 struct bwn_led *led = &sc->sc_leds[i]; 10475 10476 if (val[i] == 0xff) { 10477 led->led_act = led_act[i]; 10478 } else { 10479 if (val[i] & BWN_LED_ACT_LOW) 10480 led->led_flags |= BWN_LED_F_ACTLOW; 10481 led->led_act = val[i] & BWN_LED_ACT_MASK; 10482 } 10483 led->led_mask = (1 << i); 10484 10485 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10486 led->led_act == BWN_LED_ACT_BLINK_POLL || 10487 led->led_act == BWN_LED_ACT_BLINK) { 10488 led->led_flags |= BWN_LED_F_BLINK; 10489 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10490 led->led_flags |= BWN_LED_F_POLLABLE; 10491 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10492 led->led_flags |= BWN_LED_F_SLOW; 10493 10494 if (sc->sc_blink_led == NULL) { 10495 sc->sc_blink_led = led; 10496 if (led->led_flags & BWN_LED_F_SLOW) 10497 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10498 } 10499 } 10500 10501 DPRINTF(sc, BWN_DEBUG_LED, 10502 "%dth led, act %d, lowact %d\n", i, 10503 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10504 } 10505 callout_init(&sc->sc_led_blink_ch); 10506 } 10507 10508 static __inline uint16_t 10509 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10510 { 10511 10512 if (led->led_flags & BWN_LED_F_ACTLOW) 10513 on = !on; 10514 if (on) 10515 val |= led->led_mask; 10516 else 10517 val &= ~led->led_mask; 10518 return val; 10519 } 10520 10521 static void 10522 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10523 { 10524 struct bwn_softc *sc = mac->mac_sc; 10525 struct ifnet *ifp = sc->sc_ifp; 10526 struct ieee80211com *ic = ifp->if_l2com; 10527 uint16_t val; 10528 int i; 10529 10530 if (nstate == IEEE80211_S_INIT) { 10531 callout_stop(&sc->sc_led_blink_ch); 10532 sc->sc_led_blinking = 0; 10533 } 10534 10535 if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0) 10536 return; 10537 10538 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10539 for (i = 0; i < BWN_LED_MAX; ++i) { 10540 struct bwn_led *led = &sc->sc_leds[i]; 10541 int on; 10542 10543 if (led->led_act == BWN_LED_ACT_UNKN || 10544 led->led_act == BWN_LED_ACT_NULL) 10545 continue; 10546 10547 if ((led->led_flags & BWN_LED_F_BLINK) && 10548 nstate != IEEE80211_S_INIT) 10549 continue; 10550 10551 switch (led->led_act) { 10552 case BWN_LED_ACT_ON: /* Always on */ 10553 on = 1; 10554 break; 10555 case BWN_LED_ACT_OFF: /* Always off */ 10556 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10557 on = 0; 10558 break; 10559 default: 10560 on = 1; 10561 switch (nstate) { 10562 case IEEE80211_S_INIT: 10563 on = 0; 10564 break; 10565 case IEEE80211_S_RUN: 10566 if (led->led_act == BWN_LED_ACT_11G && 10567 ic->ic_curmode != IEEE80211_MODE_11G) 10568 on = 0; 10569 break; 10570 default: 10571 if (led->led_act == BWN_LED_ACT_ASSOC) 10572 on = 0; 10573 break; 10574 } 10575 break; 10576 } 10577 10578 val = bwn_led_onoff(led, val, on); 10579 } 10580 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10581 } 10582 10583 static void 10584 bwn_led_event(struct bwn_mac *mac, int event) 10585 { 10586 struct bwn_softc *sc = mac->mac_sc; 10587 struct bwn_led *led = sc->sc_blink_led; 10588 int rate; 10589 10590 if (event == BWN_LED_EVENT_POLL) { 10591 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10592 return; 10593 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10594 return; 10595 } 10596 10597 sc->sc_led_ticks = ticks; 10598 if (sc->sc_led_blinking) 10599 return; 10600 10601 switch (event) { 10602 case BWN_LED_EVENT_RX: 10603 rate = sc->sc_rx_rate; 10604 break; 10605 case BWN_LED_EVENT_TX: 10606 rate = sc->sc_tx_rate; 10607 break; 10608 case BWN_LED_EVENT_POLL: 10609 rate = 0; 10610 break; 10611 default: 10612 panic("unknown LED event %d\n", event); 10613 break; 10614 } 10615 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10616 bwn_led_duration[rate].off_dur); 10617 } 10618 10619 static void 10620 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10621 { 10622 struct bwn_softc *sc = mac->mac_sc; 10623 struct bwn_led *led = sc->sc_blink_led; 10624 uint16_t val; 10625 10626 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10627 val = bwn_led_onoff(led, val, 1); 10628 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10629 10630 if (led->led_flags & BWN_LED_F_SLOW) { 10631 BWN_LED_SLOWDOWN(on_dur); 10632 BWN_LED_SLOWDOWN(off_dur); 10633 } 10634 10635 sc->sc_led_blinking = 1; 10636 sc->sc_led_blink_offdur = off_dur; 10637 10638 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10639 } 10640 10641 static void 10642 bwn_led_blink_next(void *arg) 10643 { 10644 struct bwn_mac *mac = arg; 10645 struct bwn_softc *sc = mac->mac_sc; 10646 uint16_t val; 10647 10648 wlan_serialize_enter(); 10649 10650 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10651 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10652 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10653 10654 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10655 bwn_led_blink_end, mac); 10656 wlan_serialize_exit(); 10657 } 10658 10659 static void 10660 bwn_led_blink_end(void *arg) 10661 { 10662 struct bwn_mac *mac = arg; 10663 struct bwn_softc *sc = mac->mac_sc; 10664 10665 sc->sc_led_blinking = 0; 10666 } 10667 10668 static int 10669 bwn_suspend(device_t dev) 10670 { 10671 struct bwn_softc *sc = device_get_softc(dev); 10672 10673 wlan_serialize_enter(); 10674 bwn_stop(sc, 1); 10675 wlan_serialize_exit(); 10676 10677 return (0); 10678 } 10679 10680 static int 10681 bwn_resume(device_t dev) 10682 { 10683 struct bwn_softc *sc = device_get_softc(dev); 10684 struct ifnet *ifp = sc->sc_ifp; 10685 10686 wlan_serialize_enter(); 10687 if (ifp->if_flags & IFF_UP) 10688 bwn_init(sc); 10689 wlan_serialize_exit(); 10690 return (0); 10691 } 10692 10693 static void 10694 bwn_rfswitch(void *arg) 10695 { 10696 struct bwn_softc *sc = arg; 10697 struct bwn_mac *mac = sc->sc_curmac; 10698 int cur = 0, prev = 0; 10699 10700 wlan_serialize_enter(); 10701 10702 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10703 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10704 10705 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10706 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10707 & BWN_RF_HWENABLED_HI_MASK)) 10708 cur = 1; 10709 } else { 10710 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10711 & BWN_RF_HWENABLED_LO_MASK) 10712 cur = 1; 10713 } 10714 10715 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10716 prev = 1; 10717 10718 if (cur != prev) { 10719 if (cur) 10720 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10721 else 10722 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10723 10724 device_printf(sc->sc_dev, 10725 "status of RF switch is changed to %s\n", 10726 cur ? "ON" : "OFF"); 10727 if (cur != mac->mac_phy.rf_on) { 10728 if (cur) 10729 bwn_rf_turnon(mac); 10730 else 10731 bwn_rf_turnoff(mac); 10732 } 10733 } 10734 10735 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 10736 wlan_serialize_exit(); 10737 } 10738 10739 static void 10740 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10741 { 10742 struct bwn_phy *phy = &mac->mac_phy; 10743 struct bwn_phy_lp *plp = &phy->phy_lp; 10744 10745 plp->plp_antenna = BWN_ANT_DEFAULT; 10746 } 10747 10748 static int 10749 bwn_phy_lp_init(struct bwn_mac *mac) 10750 { 10751 static const struct bwn_stxtable tables[] = { 10752 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10753 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10754 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10755 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10756 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10757 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10758 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10759 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10760 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10761 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10762 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10763 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10764 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10765 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10766 { 2, 11, 0x40, 0, 0x0f } 10767 }; 10768 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10769 struct bwn_softc *sc = mac->mac_sc; 10770 const struct bwn_stxtable *st; 10771 struct ifnet *ifp = sc->sc_ifp; 10772 struct ieee80211com *ic = ifp->if_l2com; 10773 int i, error; 10774 uint16_t tmp; 10775 10776 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10777 bwn_phy_lp_bbinit(mac); 10778 10779 /* initialize RF */ 10780 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10781 DELAY(1); 10782 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10783 DELAY(1); 10784 10785 if (mac->mac_phy.rf_ver == 0x2062) 10786 bwn_phy_lp_b2062_init(mac); 10787 else { 10788 bwn_phy_lp_b2063_init(mac); 10789 10790 /* synchronize stx table. */ 10791 for (i = 0; i < N(tables); i++) { 10792 st = &tables[i]; 10793 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10794 tmp >>= st->st_rfshift; 10795 tmp <<= st->st_physhift; 10796 BWN_PHY_SETMASK(mac, 10797 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10798 ~(st->st_mask << st->st_physhift), tmp); 10799 } 10800 10801 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10802 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10803 } 10804 10805 /* calibrate RC */ 10806 if (mac->mac_phy.rev >= 2) 10807 bwn_phy_lp_rxcal_r2(mac); 10808 else if (!plp->plp_rccap) { 10809 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10810 bwn_phy_lp_rccal_r12(mac); 10811 } else 10812 bwn_phy_lp_set_rccap(mac); 10813 10814 error = bwn_phy_lp_switch_channel(mac, 7); 10815 if (error) 10816 device_printf(sc->sc_dev, 10817 "failed to change channel 7 (%d)\n", error); 10818 bwn_phy_lp_txpctl_init(mac); 10819 bwn_phy_lp_calib(mac); 10820 return (0); 10821 } 10822 10823 static uint16_t 10824 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10825 { 10826 10827 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10828 return (BWN_READ_2(mac, BWN_PHYDATA)); 10829 } 10830 10831 static void 10832 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10833 { 10834 10835 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10836 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10837 } 10838 10839 static void 10840 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10841 uint16_t set) 10842 { 10843 10844 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10845 BWN_WRITE_2(mac, BWN_PHYDATA, 10846 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10847 } 10848 10849 static uint16_t 10850 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10851 { 10852 10853 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10854 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10855 reg |= 0x100; 10856 if (mac->mac_phy.rev >= 2) 10857 reg |= 0x200; 10858 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10859 return BWN_READ_2(mac, BWN_RFDATALO); 10860 } 10861 10862 static void 10863 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10864 { 10865 10866 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10867 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10868 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10869 } 10870 10871 static void 10872 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10873 { 10874 10875 if (on) { 10876 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10877 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10878 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10879 return; 10880 } 10881 10882 if (mac->mac_phy.rev >= 2) { 10883 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10884 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10885 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10886 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10887 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10888 return; 10889 } 10890 10891 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10892 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10893 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10894 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10895 } 10896 10897 static int 10898 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10899 { 10900 struct bwn_phy *phy = &mac->mac_phy; 10901 struct bwn_phy_lp *plp = &phy->phy_lp; 10902 int error; 10903 10904 if (phy->rf_ver == 0x2063) { 10905 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 10906 if (error) 10907 return (error); 10908 } else { 10909 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 10910 if (error) 10911 return (error); 10912 bwn_phy_lp_set_anafilter(mac, chan); 10913 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 10914 } 10915 10916 plp->plp_chan = chan; 10917 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 10918 return (0); 10919 } 10920 10921 static uint32_t 10922 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 10923 { 10924 struct bwn_softc *sc = mac->mac_sc; 10925 struct ifnet *ifp = sc->sc_ifp; 10926 struct ieee80211com *ic = ifp->if_l2com; 10927 10928 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 10929 } 10930 10931 static void 10932 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 10933 { 10934 struct bwn_phy *phy = &mac->mac_phy; 10935 struct bwn_phy_lp *plp = &phy->phy_lp; 10936 10937 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 10938 return; 10939 10940 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 10941 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 10942 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 10943 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 10944 plp->plp_antenna = antenna; 10945 } 10946 10947 static void 10948 bwn_phy_lp_task_60s(struct bwn_mac *mac) 10949 { 10950 10951 bwn_phy_lp_calib(mac); 10952 } 10953 10954 static void 10955 bwn_phy_lp_readsprom(struct bwn_mac *mac) 10956 { 10957 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10958 struct bwn_softc *sc = mac->mac_sc; 10959 struct ifnet *ifp = sc->sc_ifp; 10960 struct ieee80211com *ic = ifp->if_l2com; 10961 10962 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 10963 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 10964 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 10965 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 10966 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 10967 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 10968 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 10969 return; 10970 } 10971 10972 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 10973 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 10974 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 10975 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 10976 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 10977 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 10978 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 10979 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 10980 } 10981 10982 static void 10983 bwn_phy_lp_bbinit(struct bwn_mac *mac) 10984 { 10985 10986 bwn_phy_lp_tblinit(mac); 10987 if (mac->mac_phy.rev >= 2) 10988 bwn_phy_lp_bbinit_r2(mac); 10989 else 10990 bwn_phy_lp_bbinit_r01(mac); 10991 } 10992 10993 static void 10994 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 10995 { 10996 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 10997 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 10998 struct bwn_softc *sc = mac->mac_sc; 10999 struct ifnet *ifp = sc->sc_ifp; 11000 struct ieee80211com *ic = ifp->if_l2com; 11001 11002 bwn_phy_lp_set_txgain(mac, 11003 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11004 bwn_phy_lp_set_bbmult(mac, 150); 11005 } 11006 11007 static void 11008 bwn_phy_lp_calib(struct bwn_mac *mac) 11009 { 11010 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11011 struct bwn_softc *sc = mac->mac_sc; 11012 struct ifnet *ifp = sc->sc_ifp; 11013 struct ieee80211com *ic = ifp->if_l2com; 11014 const struct bwn_rxcompco *rc = NULL; 11015 struct bwn_txgain ogain; 11016 int i, omode, oafeovr, orf, obbmult; 11017 uint8_t mode, fc = 0; 11018 11019 if (plp->plp_chanfullcal != plp->plp_chan) { 11020 plp->plp_chanfullcal = plp->plp_chan; 11021 fc = 1; 11022 } 11023 11024 bwn_mac_suspend(mac); 11025 11026 /* BlueTooth Coexistance Override */ 11027 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11028 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11029 11030 if (mac->mac_phy.rev >= 2) 11031 bwn_phy_lp_digflt_save(mac); 11032 bwn_phy_lp_get_txpctlmode(mac); 11033 mode = plp->plp_txpctlmode; 11034 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11035 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11036 bwn_phy_lp_bugfix(mac); 11037 if (mac->mac_phy.rev >= 2 && fc == 1) { 11038 bwn_phy_lp_get_txpctlmode(mac); 11039 omode = plp->plp_txpctlmode; 11040 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11041 if (oafeovr) 11042 ogain = bwn_phy_lp_get_txgain(mac); 11043 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11044 obbmult = bwn_phy_lp_get_bbmult(mac); 11045 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11046 if (oafeovr) 11047 bwn_phy_lp_set_txgain(mac, &ogain); 11048 bwn_phy_lp_set_bbmult(mac, obbmult); 11049 bwn_phy_lp_set_txpctlmode(mac, omode); 11050 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11051 } 11052 bwn_phy_lp_set_txpctlmode(mac, mode); 11053 if (mac->mac_phy.rev >= 2) 11054 bwn_phy_lp_digflt_restore(mac); 11055 11056 /* do RX IQ Calculation; assumes that noise is true. */ 11057 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11058 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11059 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11060 rc = &bwn_rxcompco_5354[i]; 11061 } 11062 } else if (mac->mac_phy.rev >= 2) 11063 rc = &bwn_rxcompco_r2; 11064 else { 11065 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11066 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11067 rc = &bwn_rxcompco_r12[i]; 11068 } 11069 } 11070 if (rc == NULL) 11071 goto fail; 11072 11073 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11074 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11075 11076 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11077 11078 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11079 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11080 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11081 } else { 11082 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11083 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11084 } 11085 11086 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11087 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11088 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11089 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11090 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11091 bwn_phy_lp_set_deaf(mac, 0); 11092 /* XXX no checking return value? */ 11093 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11094 bwn_phy_lp_clear_deaf(mac, 0); 11095 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11096 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11097 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11098 11099 /* disable RX GAIN override. */ 11100 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11101 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11102 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11103 if (mac->mac_phy.rev >= 2) { 11104 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11105 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11106 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11107 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11108 } 11109 } else { 11110 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11111 } 11112 11113 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11114 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11115 fail: 11116 bwn_mac_enable(mac); 11117 } 11118 11119 static void 11120 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11121 { 11122 11123 if (on) { 11124 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11125 return; 11126 } 11127 11128 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11129 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11130 } 11131 11132 static int 11133 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11134 { 11135 static const struct bwn_b206x_chan *bc = NULL; 11136 struct bwn_softc *sc = mac->mac_sc; 11137 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11138 tmp[6]; 11139 uint16_t old, scale, tmp16; 11140 int i, div; 11141 11142 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11143 if (bwn_b2063_chantable[i].bc_chan == chan) { 11144 bc = &bwn_b2063_chantable[i]; 11145 break; 11146 } 11147 } 11148 if (bc == NULL) 11149 return (EINVAL); 11150 11151 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11152 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11153 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11154 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11155 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11156 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11157 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11158 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11159 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11160 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11161 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11162 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11163 11164 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11165 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11166 11167 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11168 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11169 freqref = freqxtal * 3; 11170 div = (freqxtal <= 26000000 ? 1 : 2); 11171 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11172 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11173 999999) / 1000000) + 1; 11174 11175 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11176 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11177 0xfff8, timeout >> 2); 11178 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11179 0xff9f,timeout << 5); 11180 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11181 11182 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11183 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11184 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11185 11186 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11187 (timeoutref + 1)) - 1; 11188 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11189 0xf0, count >> 8); 11190 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11191 11192 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11193 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11194 while (tmp[1] >= freqref) { 11195 tmp[0]++; 11196 tmp[1] -= freqref; 11197 } 11198 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11199 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11200 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11201 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11202 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11203 11204 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11205 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11206 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11207 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11208 11209 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11210 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11211 11212 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11213 scale = 1; 11214 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11215 } else { 11216 scale = 0; 11217 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11218 } 11219 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11220 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11221 11222 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11223 (scale + 1); 11224 if (tmp[5] > 150) 11225 tmp[5] = 0; 11226 11227 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11228 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11229 11230 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11231 if (freqxtal > 26000000) 11232 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11233 else 11234 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11235 11236 if (val[0] == 45) 11237 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11238 else 11239 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11240 11241 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11242 DELAY(1); 11243 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11244 11245 /* VCO Calibration */ 11246 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11247 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11248 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11249 DELAY(1); 11250 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11251 DELAY(1); 11252 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11253 DELAY(1); 11254 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11255 DELAY(300); 11256 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11257 11258 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11259 return (0); 11260 } 11261 11262 static int 11263 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11264 { 11265 struct bwn_softc *sc = mac->mac_sc; 11266 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11267 const struct bwn_b206x_chan *bc = NULL; 11268 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11269 uint32_t tmp[9]; 11270 int i; 11271 11272 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11273 if (bwn_b2062_chantable[i].bc_chan == chan) { 11274 bc = &bwn_b2062_chantable[i]; 11275 break; 11276 } 11277 } 11278 11279 if (bc == NULL) 11280 return (EINVAL); 11281 11282 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11283 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11284 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11285 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11286 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11287 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11288 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11289 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11290 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11291 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11292 11293 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11294 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11295 bwn_phy_lp_b2062_reset_pllbias(mac); 11296 tmp[0] = freqxtal / 1000; 11297 tmp[1] = plp->plp_div * 1000; 11298 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11299 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11300 tmp[2] *= 2; 11301 tmp[3] = 48 * tmp[0]; 11302 tmp[5] = tmp[2] / tmp[3]; 11303 tmp[6] = tmp[2] % tmp[3]; 11304 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11305 tmp[4] = tmp[6] * 0x100; 11306 tmp[5] = tmp[4] / tmp[3]; 11307 tmp[6] = tmp[4] % tmp[3]; 11308 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11309 tmp[4] = tmp[6] * 0x100; 11310 tmp[5] = tmp[4] / tmp[3]; 11311 tmp[6] = tmp[4] % tmp[3]; 11312 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11313 tmp[4] = tmp[6] * 0x100; 11314 tmp[5] = tmp[4] / tmp[3]; 11315 tmp[6] = tmp[4] % tmp[3]; 11316 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11317 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11318 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11319 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11320 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11321 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11322 11323 bwn_phy_lp_b2062_vco_calib(mac); 11324 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11325 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11326 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11327 bwn_phy_lp_b2062_reset_pllbias(mac); 11328 bwn_phy_lp_b2062_vco_calib(mac); 11329 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11330 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11331 return (EIO); 11332 } 11333 } 11334 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11335 return (0); 11336 } 11337 11338 static void 11339 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11340 { 11341 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11342 uint16_t tmp = (channel == 14); 11343 11344 if (mac->mac_phy.rev < 2) { 11345 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11346 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11347 bwn_phy_lp_set_rccap(mac); 11348 return; 11349 } 11350 11351 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11352 } 11353 11354 static void 11355 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11356 { 11357 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11358 struct bwn_softc *sc = mac->mac_sc; 11359 struct ifnet *ifp = sc->sc_ifp; 11360 struct ieee80211com *ic = ifp->if_l2com; 11361 uint16_t iso, tmp[3]; 11362 11363 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11364 11365 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11366 iso = plp->plp_txisoband_m; 11367 else if (freq <= 5320) 11368 iso = plp->plp_txisoband_l; 11369 else if (freq <= 5700) 11370 iso = plp->plp_txisoband_m; 11371 else 11372 iso = plp->plp_txisoband_h; 11373 11374 tmp[0] = ((iso - 26) / 12) << 12; 11375 tmp[1] = tmp[0] + 0x1000; 11376 tmp[2] = tmp[0] + 0x2000; 11377 11378 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11379 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11380 } 11381 11382 static void 11383 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11384 { 11385 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11386 int i; 11387 static const uint16_t addr[] = { 11388 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11389 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11390 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11391 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11392 BWN_PHY_OFDM(0xcf), 11393 }; 11394 static const uint16_t val[] = { 11395 0xde5e, 0xe832, 0xe331, 0x4d26, 11396 0x0026, 0x1420, 0x0020, 0xfe08, 11397 0x0008, 11398 }; 11399 11400 for (i = 0; i < N(addr); i++) { 11401 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11402 BWN_PHY_WRITE(mac, addr[i], val[i]); 11403 } 11404 } 11405 11406 static void 11407 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11408 { 11409 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11410 struct bwn_softc *sc = mac->mac_sc; 11411 uint16_t ctl; 11412 11413 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11414 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11415 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11416 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11417 break; 11418 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11419 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11420 break; 11421 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11422 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11423 break; 11424 default: 11425 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11426 device_printf(sc->sc_dev, "unknown command mode\n"); 11427 break; 11428 } 11429 } 11430 11431 static void 11432 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11433 { 11434 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11435 uint16_t ctl; 11436 uint8_t old; 11437 11438 bwn_phy_lp_get_txpctlmode(mac); 11439 old = plp->plp_txpctlmode; 11440 if (old == mode) 11441 return; 11442 plp->plp_txpctlmode = mode; 11443 11444 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11445 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11446 plp->plp_tssiidx); 11447 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11448 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11449 11450 /* disable TX GAIN override */ 11451 if (mac->mac_phy.rev < 2) 11452 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11453 else { 11454 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11455 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11456 } 11457 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11458 11459 plp->plp_txpwridx = -1; 11460 } 11461 if (mac->mac_phy.rev >= 2) { 11462 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11463 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11464 else 11465 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11466 } 11467 11468 /* writes TX Power Control mode */ 11469 switch (plp->plp_txpctlmode) { 11470 case BWN_PHYLP_TXPCTL_OFF: 11471 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11472 break; 11473 case BWN_PHYLP_TXPCTL_ON_HW: 11474 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11475 break; 11476 case BWN_PHYLP_TXPCTL_ON_SW: 11477 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11478 break; 11479 default: 11480 ctl = 0; 11481 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11482 } 11483 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11484 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11485 } 11486 11487 static void 11488 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11489 { 11490 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11491 const unsigned int size = 256; 11492 struct bwn_txgain tg; 11493 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11494 uint16_t tssinpt, tssiidx, value[2]; 11495 uint8_t mode; 11496 int8_t txpwridx; 11497 11498 tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF, 11499 M_INTWAIT | M_ZERO); 11500 11501 bwn_phy_lp_get_txpctlmode(mac); 11502 mode = plp->plp_txpctlmode; 11503 txpwridx = plp->plp_txpwridx; 11504 tssinpt = plp->plp_tssinpt; 11505 tssiidx = plp->plp_tssiidx; 11506 11507 bwn_tab_read_multi(mac, 11508 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11509 BWN_TAB_4(7, 0x140), size, tabs); 11510 11511 bwn_phy_lp_tblinit(mac); 11512 bwn_phy_lp_bbinit(mac); 11513 bwn_phy_lp_txpctl_init(mac); 11514 bwn_phy_lp_rf_onoff(mac, 1); 11515 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11516 11517 bwn_tab_write_multi(mac, 11518 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11519 BWN_TAB_4(7, 0x140), size, tabs); 11520 11521 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11522 plp->plp_tssinpt = tssinpt; 11523 plp->plp_tssiidx = tssiidx; 11524 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11525 if (txpwridx != -1) { 11526 /* set TX power by index */ 11527 plp->plp_txpwridx = txpwridx; 11528 bwn_phy_lp_get_txpctlmode(mac); 11529 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11530 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11531 if (mac->mac_phy.rev >= 2) { 11532 rxcomp = bwn_tab_read(mac, 11533 BWN_TAB_4(7, txpwridx + 320)); 11534 txgain = bwn_tab_read(mac, 11535 BWN_TAB_4(7, txpwridx + 192)); 11536 tg.tg_pad = (txgain >> 16) & 0xff; 11537 tg.tg_gm = txgain & 0xff; 11538 tg.tg_pga = (txgain >> 8) & 0xff; 11539 tg.tg_dac = (rxcomp >> 28) & 0xff; 11540 bwn_phy_lp_set_txgain(mac, &tg); 11541 } else { 11542 rxcomp = bwn_tab_read(mac, 11543 BWN_TAB_4(10, txpwridx + 320)); 11544 txgain = bwn_tab_read(mac, 11545 BWN_TAB_4(10, txpwridx + 192)); 11546 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11547 0xf800, (txgain >> 4) & 0x7fff); 11548 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11549 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11550 } 11551 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11552 11553 /* set TX IQCC */ 11554 value[0] = (rxcomp >> 10) & 0x3ff; 11555 value[1] = rxcomp & 0x3ff; 11556 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11557 11558 coeff = bwn_tab_read(mac, 11559 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11560 BWN_TAB_4(10, txpwridx + 448)); 11561 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11562 if (mac->mac_phy.rev >= 2) { 11563 rfpwr = bwn_tab_read(mac, 11564 BWN_TAB_4(7, txpwridx + 576)); 11565 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11566 rfpwr & 0xffff); 11567 } 11568 bwn_phy_lp_set_txgain_override(mac); 11569 } 11570 if (plp->plp_rccap) 11571 bwn_phy_lp_set_rccap(mac); 11572 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11573 bwn_phy_lp_set_txpctlmode(mac, mode); 11574 kfree(tabs, M_DEVBUF); 11575 } 11576 11577 static void 11578 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11579 { 11580 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11581 int i; 11582 static const uint16_t addr[] = { 11583 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11584 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11585 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11586 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11587 BWN_PHY_OFDM(0xcf), 11588 }; 11589 11590 for (i = 0; i < N(addr); i++) 11591 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11592 } 11593 11594 static void 11595 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11596 { 11597 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11598 11599 if (mac->mac_phy.rev < 2) { 11600 bwn_phy_lp_tblinit_r01(mac); 11601 bwn_phy_lp_tblinit_txgain(mac); 11602 bwn_phy_lp_set_gaintbl(mac, freq); 11603 return; 11604 } 11605 11606 bwn_phy_lp_tblinit_r2(mac); 11607 bwn_phy_lp_tblinit_txgain(mac); 11608 } 11609 11610 struct bwn_wpair { 11611 uint16_t reg; 11612 uint16_t value; 11613 }; 11614 11615 struct bwn_smpair { 11616 uint16_t offset; 11617 uint16_t mask; 11618 uint16_t set; 11619 }; 11620 11621 static void 11622 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11623 { 11624 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11625 struct bwn_softc *sc = mac->mac_sc; 11626 struct ifnet *ifp = sc->sc_ifp; 11627 struct ieee80211com *ic = ifp->if_l2com; 11628 static const struct bwn_wpair v1[] = { 11629 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11630 { BWN_PHY_AFE_CTL, 0x8800 }, 11631 { BWN_PHY_AFE_CTL_OVR, 0 }, 11632 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11633 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11634 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11635 { BWN_PHY_OFDM(0xf9), 0 }, 11636 { BWN_PHY_TR_LOOKUP_1, 0 } 11637 }; 11638 static const struct bwn_smpair v2[] = { 11639 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11640 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11641 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11642 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11643 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11644 }; 11645 static const struct bwn_smpair v3[] = { 11646 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11647 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11648 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11649 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11650 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11651 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11652 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11653 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11654 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11655 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11656 11657 }; 11658 int i; 11659 11660 for (i = 0; i < N(v1); i++) 11661 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11662 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11663 for (i = 0; i < N(v2); i++) 11664 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11665 11666 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11667 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11668 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11669 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11670 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11671 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11672 } else { 11673 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11674 } 11675 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11676 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11677 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11678 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11679 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11680 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11681 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11682 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11683 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11684 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11685 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11686 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11687 (siba_get_chiprev(sc->sc_dev) == 0)) { 11688 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11689 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11690 } else { 11691 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11692 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11693 } 11694 for (i = 0; i < N(v3); i++) 11695 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11696 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11697 (siba_get_chiprev(sc->sc_dev) == 0)) { 11698 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11699 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11700 } 11701 11702 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11703 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11704 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11705 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11706 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11707 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11708 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11709 } else 11710 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11711 11712 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11713 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11714 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11715 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11716 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11717 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11718 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11719 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11720 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11721 11722 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11723 (siba_get_chiprev(sc->sc_dev) == 0)) { 11724 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11725 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11726 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11727 } 11728 11729 bwn_phy_lp_digflt_save(mac); 11730 } 11731 11732 static void 11733 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11734 { 11735 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11736 struct bwn_softc *sc = mac->mac_sc; 11737 struct ifnet *ifp = sc->sc_ifp; 11738 struct ieee80211com *ic = ifp->if_l2com; 11739 static const struct bwn_smpair v1[] = { 11740 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11741 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11742 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11743 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11744 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11745 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11746 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11747 }; 11748 static const struct bwn_smpair v2[] = { 11749 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11750 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11751 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11752 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11753 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11754 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11755 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11756 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11757 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11758 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11759 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11760 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11761 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11762 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11763 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11764 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11765 }; 11766 static const struct bwn_smpair v3[] = { 11767 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11768 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11769 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11770 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11771 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11772 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11773 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11774 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11775 }; 11776 static const struct bwn_smpair v4[] = { 11777 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11778 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11779 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11780 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11781 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11782 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11783 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11784 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11785 }; 11786 static const struct bwn_smpair v5[] = { 11787 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11788 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11789 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11790 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11791 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11792 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11793 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11794 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11795 }; 11796 int i; 11797 uint16_t tmp, tmp2; 11798 11799 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11800 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11801 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11802 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11803 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11804 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11805 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11806 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11807 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11808 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11809 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11810 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11811 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11812 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11813 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11814 for (i = 0; i < N(v1); i++) 11815 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11816 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11817 0xff00, plp->plp_rxpwroffset); 11818 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11819 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11820 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11821 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11822 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11823 if (mac->mac_phy.rev == 0) 11824 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11825 0xffcf, 0x0010); 11826 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11827 } else { 11828 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11829 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11830 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11831 } 11832 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11833 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11834 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11835 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11836 else 11837 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11838 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11839 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11840 0xfff9, (plp->plp_bxarch << 1)); 11841 if (mac->mac_phy.rev == 1 && 11842 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11843 for (i = 0; i < N(v2); i++) 11844 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11845 v2[i].set); 11846 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11847 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11848 ((mac->mac_phy.rev == 0) && 11849 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11850 for (i = 0; i < N(v3); i++) 11851 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11852 v3[i].set); 11853 } else if (mac->mac_phy.rev == 1 || 11854 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11855 for (i = 0; i < N(v4); i++) 11856 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11857 v4[i].set); 11858 } else { 11859 for (i = 0; i < N(v5); i++) 11860 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11861 v5[i].set); 11862 } 11863 if (mac->mac_phy.rev == 1 && 11864 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11865 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11866 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11867 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11868 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11869 } 11870 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11871 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11872 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11873 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11874 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11875 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11876 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11877 } 11878 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11879 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11880 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11881 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11882 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11883 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11884 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11885 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11886 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11887 } else { 11888 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11889 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11890 } 11891 if (mac->mac_phy.rev == 1) { 11892 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11893 tmp2 = (tmp & 0x03e0) >> 5; 11894 tmp2 |= tmp2 << 5; 11895 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11896 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 11897 tmp2 = (tmp & 0x1f00) >> 8; 11898 tmp2 |= tmp2 << 5; 11899 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 11900 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 11901 tmp2 = tmp & 0x00ff; 11902 tmp2 |= tmp << 8; 11903 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 11904 } 11905 } 11906 11907 struct bwn_b2062_freq { 11908 uint16_t freq; 11909 uint8_t value[6]; 11910 }; 11911 11912 static void 11913 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 11914 { 11915 #define CALC_CTL7(freq, div) \ 11916 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 11917 #define CALC_CTL18(freq, div) \ 11918 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 11919 #define CALC_CTL19(freq, div) \ 11920 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 11921 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11922 struct bwn_softc *sc = mac->mac_sc; 11923 struct ifnet *ifp = sc->sc_ifp; 11924 struct ieee80211com *ic = ifp->if_l2com; 11925 static const struct bwn_b2062_freq freqdata_tab[] = { 11926 { 12000, { 6, 6, 6, 6, 10, 6 } }, 11927 { 13000, { 4, 4, 4, 4, 11, 7 } }, 11928 { 14400, { 3, 3, 3, 3, 12, 7 } }, 11929 { 16200, { 3, 3, 3, 3, 13, 8 } }, 11930 { 18000, { 2, 2, 2, 2, 14, 8 } }, 11931 { 19200, { 1, 1, 1, 1, 14, 9 } } 11932 }; 11933 static const struct bwn_wpair v1[] = { 11934 { BWN_B2062_N_TXCTL3, 0 }, 11935 { BWN_B2062_N_TXCTL4, 0 }, 11936 { BWN_B2062_N_TXCTL5, 0 }, 11937 { BWN_B2062_N_TXCTL6, 0 }, 11938 { BWN_B2062_N_PDNCTL0, 0x40 }, 11939 { BWN_B2062_N_PDNCTL0, 0 }, 11940 { BWN_B2062_N_CALIB_TS, 0x10 }, 11941 { BWN_B2062_N_CALIB_TS, 0 } 11942 }; 11943 const struct bwn_b2062_freq *f = NULL; 11944 uint32_t xtalfreq, ref; 11945 unsigned int i; 11946 11947 bwn_phy_lp_b2062_tblinit(mac); 11948 11949 for (i = 0; i < N(v1); i++) 11950 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 11951 if (mac->mac_phy.rev > 0) 11952 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 11953 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 11954 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11955 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 11956 else 11957 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 11958 11959 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 11960 ("%s:%d: fail", __func__, __LINE__)); 11961 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11962 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 11963 11964 if (xtalfreq <= 30000000) { 11965 plp->plp_div = 1; 11966 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 11967 } else { 11968 plp->plp_div = 2; 11969 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 11970 } 11971 11972 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 11973 CALC_CTL7(xtalfreq, plp->plp_div)); 11974 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 11975 CALC_CTL18(xtalfreq, plp->plp_div)); 11976 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 11977 CALC_CTL19(xtalfreq, plp->plp_div)); 11978 11979 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 11980 ref &= 0xffff; 11981 for (i = 0; i < N(freqdata_tab); i++) { 11982 if (ref < freqdata_tab[i].freq) { 11983 f = &freqdata_tab[i]; 11984 break; 11985 } 11986 } 11987 if (f == NULL) 11988 f = &freqdata_tab[N(freqdata_tab) - 1]; 11989 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 11990 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 11991 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 11992 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 11993 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 11994 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 11995 #undef CALC_CTL7 11996 #undef CALC_CTL18 11997 #undef CALC_CTL19 11998 } 11999 12000 static void 12001 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12002 { 12003 12004 bwn_phy_lp_b2063_tblinit(mac); 12005 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12006 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12007 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12008 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12009 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12010 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12011 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12012 if (mac->mac_phy.rev == 2) { 12013 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12014 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12015 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12016 } else { 12017 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12018 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12019 } 12020 } 12021 12022 static void 12023 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12024 { 12025 struct bwn_softc *sc = mac->mac_sc; 12026 static const struct bwn_wpair v1[] = { 12027 { BWN_B2063_RX_BB_SP8, 0x0 }, 12028 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12029 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12030 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12031 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12032 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12033 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12034 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12035 }; 12036 static const struct bwn_wpair v2[] = { 12037 { BWN_B2063_TX_BB_SP3, 0x0 }, 12038 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12039 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12040 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12041 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12042 }; 12043 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12044 int i; 12045 uint8_t tmp; 12046 12047 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12048 12049 for (i = 0; i < 2; i++) 12050 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12051 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12052 for (i = 2; i < N(v1); i++) 12053 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12054 for (i = 0; i < 10000; i++) { 12055 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12056 break; 12057 DELAY(1000); 12058 } 12059 12060 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12061 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12062 12063 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12064 12065 for (i = 0; i < N(v2); i++) 12066 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12067 if (freqxtal == 24000000) { 12068 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12069 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12070 } else { 12071 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12072 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12073 } 12074 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12075 for (i = 0; i < 10000; i++) { 12076 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12077 break; 12078 DELAY(1000); 12079 } 12080 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12081 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12082 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12083 } 12084 12085 static void 12086 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12087 { 12088 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12089 struct bwn_softc *sc = mac->mac_sc; 12090 struct bwn_phy_lp_iq_est ie; 12091 struct bwn_txgain tx_gains; 12092 static const uint32_t pwrtbl[21] = { 12093 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12094 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12095 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12096 0x0004c, 0x0002c, 0x0001a, 12097 }; 12098 uint32_t npwr, ipwr, sqpwr, tmp; 12099 int loopback, i, j, sum, error; 12100 uint16_t save[7]; 12101 uint8_t txo, bbmult, txpctlmode; 12102 12103 error = bwn_phy_lp_switch_channel(mac, 7); 12104 if (error) 12105 device_printf(sc->sc_dev, 12106 "failed to change channel to 7 (%d)\n", error); 12107 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12108 bbmult = bwn_phy_lp_get_bbmult(mac); 12109 if (txo) 12110 tx_gains = bwn_phy_lp_get_txgain(mac); 12111 12112 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12113 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12114 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12115 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12116 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12117 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12118 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12119 12120 bwn_phy_lp_get_txpctlmode(mac); 12121 txpctlmode = plp->plp_txpctlmode; 12122 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12123 12124 /* disable CRS */ 12125 bwn_phy_lp_set_deaf(mac, 1); 12126 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12127 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12128 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12129 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12130 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12131 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12132 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12133 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12134 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12135 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12136 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12137 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12138 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12139 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12140 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12141 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12142 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12143 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12144 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12145 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12146 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12147 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12148 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12149 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12150 12151 loopback = bwn_phy_lp_loopback(mac); 12152 if (loopback == -1) 12153 goto done; 12154 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12155 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12156 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12157 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12158 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12159 12160 tmp = 0; 12161 memset(&ie, 0, sizeof(ie)); 12162 for (i = 128; i <= 159; i++) { 12163 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12164 sum = 0; 12165 for (j = 5; j <= 25; j++) { 12166 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12167 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12168 goto done; 12169 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12170 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12171 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12172 12); 12173 sum += ((ipwr - npwr) * (ipwr - npwr)); 12174 if ((i == 128) || (sum < tmp)) { 12175 plp->plp_rccap = i; 12176 tmp = sum; 12177 } 12178 } 12179 } 12180 bwn_phy_lp_ddfs_turnoff(mac); 12181 done: 12182 /* restore CRS */ 12183 bwn_phy_lp_clear_deaf(mac, 1); 12184 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12185 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12186 12187 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12188 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12189 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12190 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12191 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12192 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12193 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12194 12195 bwn_phy_lp_set_bbmult(mac, bbmult); 12196 if (txo) 12197 bwn_phy_lp_set_txgain(mac, &tx_gains); 12198 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12199 if (plp->plp_rccap) 12200 bwn_phy_lp_set_rccap(mac); 12201 } 12202 12203 static void 12204 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12205 { 12206 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12207 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12208 12209 if (mac->mac_phy.rev == 1) 12210 rc_cap = MIN(rc_cap + 5, 15); 12211 12212 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12213 MAX(plp->plp_rccap - 4, 0x80)); 12214 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12215 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12216 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12217 } 12218 12219 static uint32_t 12220 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12221 { 12222 uint32_t i, q, r; 12223 12224 if (div == 0) 12225 return (0); 12226 12227 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12228 q <<= 1; 12229 if (r << 1 >= div) { 12230 q++; 12231 r = (r << 1) - div; 12232 } 12233 } 12234 if (r << 1 >= div) 12235 q++; 12236 return (q); 12237 } 12238 12239 static void 12240 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12241 { 12242 struct bwn_softc *sc = mac->mac_sc; 12243 12244 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12245 DELAY(20); 12246 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12247 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12248 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12249 } else { 12250 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12251 } 12252 DELAY(5); 12253 } 12254 12255 static void 12256 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12257 { 12258 12259 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12260 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12261 DELAY(200); 12262 } 12263 12264 static void 12265 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12266 { 12267 #define FLAG_A 0x01 12268 #define FLAG_G 0x02 12269 struct bwn_softc *sc = mac->mac_sc; 12270 struct ifnet *ifp = sc->sc_ifp; 12271 struct ieee80211com *ic = ifp->if_l2com; 12272 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12273 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12274 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12275 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12276 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12277 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12278 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12279 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12280 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12281 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12282 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12283 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12284 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12285 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12286 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12287 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12288 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12289 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12290 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12291 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12292 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12293 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12294 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12295 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12296 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12297 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12298 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12299 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12300 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12301 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12302 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12303 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12304 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12305 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12306 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12307 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12308 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12309 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12310 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12311 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12312 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12313 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12314 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12315 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12316 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12317 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12318 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12319 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12320 }; 12321 const struct bwn_b206x_rfinit_entry *br; 12322 unsigned int i; 12323 12324 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12325 br = &bwn_b2062_init_tab[i]; 12326 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12327 if (br->br_flags & FLAG_G) 12328 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12329 } else { 12330 if (br->br_flags & FLAG_A) 12331 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12332 } 12333 } 12334 #undef FLAG_A 12335 #undef FLAG_B 12336 } 12337 12338 static void 12339 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12340 { 12341 #define FLAG_A 0x01 12342 #define FLAG_G 0x02 12343 struct bwn_softc *sc = mac->mac_sc; 12344 struct ifnet *ifp = sc->sc_ifp; 12345 struct ieee80211com *ic = ifp->if_l2com; 12346 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12347 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12348 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12349 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12350 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12351 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12352 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12353 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12354 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12355 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12356 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12357 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12358 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12359 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12360 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12361 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12362 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12363 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12364 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12365 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12366 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12367 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12368 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12369 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12370 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12371 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12372 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12373 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12374 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12375 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12376 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12377 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12378 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12379 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12380 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12381 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12382 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12383 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12384 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12385 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12386 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12387 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12388 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12389 }; 12390 const struct bwn_b206x_rfinit_entry *br; 12391 unsigned int i; 12392 12393 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12394 br = &bwn_b2063_init_tab[i]; 12395 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12396 if (br->br_flags & FLAG_G) 12397 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12398 } else { 12399 if (br->br_flags & FLAG_A) 12400 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12401 } 12402 } 12403 #undef FLAG_A 12404 #undef FLAG_B 12405 } 12406 12407 static void 12408 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12409 int count, void *_data) 12410 { 12411 unsigned int i; 12412 uint32_t offset, type; 12413 uint8_t *data = _data; 12414 12415 type = BWN_TAB_GETTYPE(typenoffset); 12416 offset = BWN_TAB_GETOFFSET(typenoffset); 12417 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12418 12419 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12420 12421 for (i = 0; i < count; i++) { 12422 switch (type) { 12423 case BWN_TAB_8BIT: 12424 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12425 data++; 12426 break; 12427 case BWN_TAB_16BIT: 12428 *((uint16_t *)data) = BWN_PHY_READ(mac, 12429 BWN_PHY_TABLEDATALO); 12430 data += 2; 12431 break; 12432 case BWN_TAB_32BIT: 12433 *((uint32_t *)data) = BWN_PHY_READ(mac, 12434 BWN_PHY_TABLEDATAHI); 12435 *((uint32_t *)data) <<= 16; 12436 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12437 BWN_PHY_TABLEDATALO); 12438 data += 4; 12439 break; 12440 default: 12441 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12442 } 12443 } 12444 } 12445 12446 static void 12447 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12448 int count, const void *_data) 12449 { 12450 uint32_t offset, type, value; 12451 const uint8_t *data = _data; 12452 unsigned int i; 12453 12454 type = BWN_TAB_GETTYPE(typenoffset); 12455 offset = BWN_TAB_GETOFFSET(typenoffset); 12456 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12457 12458 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12459 12460 for (i = 0; i < count; i++) { 12461 switch (type) { 12462 case BWN_TAB_8BIT: 12463 value = *data; 12464 data++; 12465 KASSERT(!(value & ~0xff), 12466 ("%s:%d: fail", __func__, __LINE__)); 12467 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12468 break; 12469 case BWN_TAB_16BIT: 12470 value = *((const uint16_t *)data); 12471 data += 2; 12472 KASSERT(!(value & ~0xffff), 12473 ("%s:%d: fail", __func__, __LINE__)); 12474 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12475 break; 12476 case BWN_TAB_32BIT: 12477 value = *((const uint32_t *)data); 12478 data += 4; 12479 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12480 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12481 break; 12482 default: 12483 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12484 } 12485 } 12486 } 12487 12488 static struct bwn_txgain 12489 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12490 { 12491 struct bwn_txgain tg; 12492 uint16_t tmp; 12493 12494 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12495 if (mac->mac_phy.rev < 2) { 12496 tmp = BWN_PHY_READ(mac, 12497 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12498 tg.tg_gm = tmp & 0x0007; 12499 tg.tg_pga = (tmp & 0x0078) >> 3; 12500 tg.tg_pad = (tmp & 0x780) >> 7; 12501 return (tg); 12502 } 12503 12504 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12505 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12506 tg.tg_gm = tmp & 0xff; 12507 tg.tg_pga = (tmp >> 8) & 0xff; 12508 return (tg); 12509 } 12510 12511 static uint8_t 12512 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12513 { 12514 12515 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12516 } 12517 12518 static void 12519 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12520 { 12521 uint16_t pa; 12522 12523 if (mac->mac_phy.rev < 2) { 12524 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12525 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12526 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12527 bwn_phy_lp_set_txgain_override(mac); 12528 return; 12529 } 12530 12531 pa = bwn_phy_lp_get_pa_gain(mac); 12532 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12533 (tg->tg_pga << 8) | tg->tg_gm); 12534 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12535 tg->tg_pad | (pa << 6)); 12536 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12537 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12538 tg->tg_pad | (pa << 8)); 12539 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12540 bwn_phy_lp_set_txgain_override(mac); 12541 } 12542 12543 static void 12544 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12545 { 12546 12547 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12548 } 12549 12550 static void 12551 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12552 { 12553 uint16_t trsw = (tx << 1) | rx; 12554 12555 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12556 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12557 } 12558 12559 static void 12560 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12561 { 12562 struct bwn_softc *sc = mac->mac_sc; 12563 struct ifnet *ifp = sc->sc_ifp; 12564 struct ieee80211com *ic = ifp->if_l2com; 12565 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12566 12567 if (mac->mac_phy.rev < 2) { 12568 trsw = gain & 0x1; 12569 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12570 ext_lna = (gain & 2) >> 1; 12571 12572 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12573 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12574 0xfbff, ext_lna << 10); 12575 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12576 0xf7ff, ext_lna << 11); 12577 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12578 } else { 12579 low_gain = gain & 0xffff; 12580 high_gain = (gain >> 16) & 0xf; 12581 ext_lna = (gain >> 21) & 0x1; 12582 trsw = ~(gain >> 20) & 0x1; 12583 12584 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12585 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12586 0xfdff, ext_lna << 9); 12587 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12588 0xfbff, ext_lna << 10); 12589 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12590 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12591 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12592 tmp = (gain >> 2) & 0x3; 12593 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12594 0xe7ff, tmp<<11); 12595 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12596 tmp << 3); 12597 } 12598 } 12599 12600 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12601 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12602 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12603 if (mac->mac_phy.rev >= 2) { 12604 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12605 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12606 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12607 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12608 } 12609 return; 12610 } 12611 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12612 } 12613 12614 static void 12615 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12616 { 12617 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12618 12619 if (user) 12620 plp->plp_crsusr_off = 1; 12621 else 12622 plp->plp_crssys_off = 1; 12623 12624 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12625 } 12626 12627 static void 12628 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12629 { 12630 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12631 struct bwn_softc *sc = mac->mac_sc; 12632 struct ifnet *ifp = sc->sc_ifp; 12633 struct ieee80211com *ic = ifp->if_l2com; 12634 12635 if (user) 12636 plp->plp_crsusr_off = 0; 12637 else 12638 plp->plp_crssys_off = 0; 12639 12640 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12641 return; 12642 12643 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12644 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12645 else 12646 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12647 } 12648 12649 static unsigned int 12650 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12651 { 12652 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12653 static uint8_t sqrt_table[256] = { 12654 10, 14, 17, 20, 22, 24, 26, 28, 12655 30, 31, 33, 34, 36, 37, 38, 40, 12656 41, 42, 43, 44, 45, 46, 47, 48, 12657 50, 50, 51, 52, 53, 54, 55, 56, 12658 57, 58, 59, 60, 60, 61, 62, 63, 12659 64, 64, 65, 66, 67, 67, 68, 69, 12660 70, 70, 71, 72, 72, 73, 74, 74, 12661 75, 76, 76, 77, 78, 78, 79, 80, 12662 80, 81, 81, 82, 83, 83, 84, 84, 12663 85, 86, 86, 87, 87, 88, 88, 89, 12664 90, 90, 91, 91, 92, 92, 93, 93, 12665 94, 94, 95, 95, 96, 96, 97, 97, 12666 98, 98, 99, 100, 100, 100, 101, 101, 12667 102, 102, 103, 103, 104, 104, 105, 105, 12668 106, 106, 107, 107, 108, 108, 109, 109, 12669 110, 110, 110, 111, 111, 112, 112, 113, 12670 113, 114, 114, 114, 115, 115, 116, 116, 12671 117, 117, 117, 118, 118, 119, 119, 120, 12672 120, 120, 121, 121, 122, 122, 122, 123, 12673 123, 124, 124, 124, 125, 125, 126, 126, 12674 126, 127, 127, 128, 128, 128, 129, 129, 12675 130, 130, 130, 131, 131, 131, 132, 132, 12676 133, 133, 133, 134, 134, 134, 135, 135, 12677 136, 136, 136, 137, 137, 137, 138, 138, 12678 138, 139, 139, 140, 140, 140, 141, 141, 12679 141, 142, 142, 142, 143, 143, 143, 144, 12680 144, 144, 145, 145, 145, 146, 146, 146, 12681 147, 147, 147, 148, 148, 148, 149, 149, 12682 150, 150, 150, 150, 151, 151, 151, 152, 12683 152, 152, 153, 153, 153, 154, 154, 154, 12684 155, 155, 155, 156, 156, 156, 157, 157, 12685 157, 158, 158, 158, 159, 159, 159, 160 12686 }; 12687 12688 if (x == 0) 12689 return (0); 12690 if (x >= 256) { 12691 unsigned int tmp; 12692 12693 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12694 /* do nothing */ ; 12695 return (tmp); 12696 } 12697 return (sqrt_table[x - 1] / 10); 12698 } 12699 12700 static int 12701 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12702 { 12703 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12704 int _t; \ 12705 _t = _x - 20; \ 12706 if (_t >= 0) { \ 12707 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12708 } else { \ 12709 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12710 } \ 12711 } while (0) 12712 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12713 int _t; \ 12714 _t = _x - 11; \ 12715 if (_t >= 0) \ 12716 _v = (_y << (31 - _x)) / (_z >> _t); \ 12717 else \ 12718 _v = (_y << (31 - _x)) / (_z << -_t); \ 12719 } while (0) 12720 struct bwn_phy_lp_iq_est ie; 12721 uint16_t v0, v1; 12722 int tmp[2], ret; 12723 12724 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12725 v0 = v1 >> 8; 12726 v1 |= 0xff; 12727 12728 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12729 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12730 12731 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12732 if (ret == 0) 12733 goto done; 12734 12735 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12736 ret = 0; 12737 goto done; 12738 } 12739 12740 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12741 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12742 12743 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12744 v0 = tmp[0] >> 3; 12745 v1 = tmp[1] >> 4; 12746 done: 12747 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12748 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12749 return ret; 12750 #undef CALC_COEFF 12751 #undef CALC_COEFF2 12752 } 12753 12754 static void 12755 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12756 { 12757 static const uint16_t noisescale[] = { 12758 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12759 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12760 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12761 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12762 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12763 }; 12764 static const uint16_t crsgainnft[] = { 12765 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12766 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12767 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12768 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12769 0x013d, 12770 }; 12771 static const uint16_t filterctl[] = { 12772 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12773 0xff53, 0x0127, 12774 }; 12775 static const uint32_t psctl[] = { 12776 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12777 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12778 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12779 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12780 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12781 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12782 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12783 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12784 }; 12785 static const uint16_t ofdmcckgain_r0[] = { 12786 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12787 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12788 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12789 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12790 0x755d, 12791 }; 12792 static const uint16_t ofdmcckgain_r1[] = { 12793 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12794 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12795 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12796 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12797 0x755d, 12798 }; 12799 static const uint16_t gaindelta[] = { 12800 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12801 0x0000, 12802 }; 12803 static const uint32_t txpwrctl[] = { 12804 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12805 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12806 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12807 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12808 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12809 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12810 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12811 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12812 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12813 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12814 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12815 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12816 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12817 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12818 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12819 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12820 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12821 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12822 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12823 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12824 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12825 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12826 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12827 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12828 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12829 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12830 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12831 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12832 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12833 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12834 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12835 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12836 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12837 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12838 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12839 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12840 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12841 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12842 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12843 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12844 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12845 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12846 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12847 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12848 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12849 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12850 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12851 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12852 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12853 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12854 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12855 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12856 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12857 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12858 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12859 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12860 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12861 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12862 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12863 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12864 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12865 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12866 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12867 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12868 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12869 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12870 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12871 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12872 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12873 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12874 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12875 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12876 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12877 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12878 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12879 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12880 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12881 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12882 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12883 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12884 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12885 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12886 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12887 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12888 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12889 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12890 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12891 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12892 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12893 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12894 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12895 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12896 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 12897 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 12898 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 12899 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 12900 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 12901 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 12902 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 12903 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 12904 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 12905 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 12906 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 12907 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 12908 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 12909 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 12910 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 12911 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 12912 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 12913 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 12914 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 12915 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 12916 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 12917 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 12918 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 12919 0x00000702, 12920 }; 12921 12922 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 12923 12924 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 12925 bwn_tab_sigsq_tbl); 12926 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 12927 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 12928 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 12929 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 12930 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 12931 bwn_tab_pllfrac_tbl); 12932 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 12933 bwn_tabl_iqlocal_tbl); 12934 if (mac->mac_phy.rev == 0) { 12935 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 12936 ofdmcckgain_r0); 12937 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 12938 ofdmcckgain_r0); 12939 } else { 12940 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 12941 ofdmcckgain_r1); 12942 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 12943 ofdmcckgain_r1); 12944 } 12945 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 12946 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 12947 } 12948 12949 static void 12950 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 12951 { 12952 struct bwn_softc *sc = mac->mac_sc; 12953 int i; 12954 static const uint16_t noisescale[] = { 12955 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12956 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12957 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12958 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12959 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12960 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12961 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 12962 }; 12963 static const uint32_t filterctl[] = { 12964 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 12965 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 12966 }; 12967 static const uint32_t psctl[] = { 12968 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 12969 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 12970 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 12971 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 12972 }; 12973 static const uint32_t gainidx[] = { 12974 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12975 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12976 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12977 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 12978 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 12979 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 12980 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 12981 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 12982 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 12983 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 12984 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 12985 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 12986 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 12987 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 12988 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 12989 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12990 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12991 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12992 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 12993 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 12994 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 12995 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 12996 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 12997 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 12998 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 12999 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13000 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13001 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13002 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13003 0x0000001a, 0x64ca55ad, 0x0000001a 13004 }; 13005 static const uint16_t auxgainidx[] = { 13006 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13007 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13008 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13009 0x0004, 0x0016 13010 }; 13011 static const uint16_t swctl[] = { 13012 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13013 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13014 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13015 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13016 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13017 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13018 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13019 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13020 }; 13021 static const uint8_t hf[] = { 13022 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13023 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13024 }; 13025 static const uint32_t gainval[] = { 13026 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13027 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13028 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13029 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13030 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13031 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13032 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13033 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13034 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13035 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13036 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13037 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13038 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13039 0x000000f1, 0x00000000, 0x00000000 13040 }; 13041 static const uint16_t gain[] = { 13042 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13043 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13044 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13045 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13046 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13047 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13048 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13049 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13050 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13051 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13052 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13053 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13054 }; 13055 static const uint32_t papdeps[] = { 13056 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13057 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13058 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13059 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13060 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13061 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13062 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13063 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13064 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13065 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13066 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13067 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13068 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13069 }; 13070 static const uint32_t papdmult[] = { 13071 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13072 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13073 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13074 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13075 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13076 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13077 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13078 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13079 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13080 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13081 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13082 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13083 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13084 }; 13085 static const uint32_t gainidx_a0[] = { 13086 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13087 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13088 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13089 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13090 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13091 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13092 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13093 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13094 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13095 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13096 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13097 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13098 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13099 }; 13100 static const uint16_t auxgainidx_a0[] = { 13101 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13102 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13103 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13104 0x0002, 0x0014 13105 }; 13106 static const uint32_t gainval_a0[] = { 13107 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13108 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13109 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13110 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13111 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13112 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13113 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13114 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13115 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13116 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13117 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13118 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13119 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13120 0x000000f7, 0x00000000, 0x00000000 13121 }; 13122 static const uint16_t gain_a0[] = { 13123 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13124 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13125 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13126 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13127 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13128 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13129 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13130 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13131 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13132 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13133 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13134 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13135 }; 13136 13137 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13138 13139 for (i = 0; i < 704; i++) 13140 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13141 13142 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13143 bwn_tab_sigsq_tbl); 13144 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13145 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13146 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13147 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13148 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13149 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13150 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13151 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13152 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13153 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13154 bwn_tab_pllfrac_tbl); 13155 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13156 bwn_tabl_iqlocal_tbl); 13157 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13158 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13159 13160 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13161 (siba_get_chiprev(sc->sc_dev) == 0)) { 13162 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13163 gainidx_a0); 13164 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13165 auxgainidx_a0); 13166 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13167 gainval_a0); 13168 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13169 } 13170 } 13171 13172 static void 13173 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13174 { 13175 struct bwn_softc *sc = mac->mac_sc; 13176 struct ifnet *ifp = sc->sc_ifp; 13177 struct ieee80211com *ic = ifp->if_l2com; 13178 static struct bwn_txgain_entry txgain_r2[] = { 13179 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13180 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13181 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13182 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13183 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13184 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13185 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13186 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13187 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13188 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13189 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13190 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13191 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13192 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13193 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13194 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13195 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13196 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13197 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13198 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13199 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13200 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13201 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13202 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13203 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13204 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13205 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13206 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13207 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13208 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13209 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13210 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13211 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13212 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13213 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13214 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13215 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13216 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13217 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13218 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13219 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13220 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13221 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13222 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13223 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13224 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13225 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13226 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13227 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13228 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13229 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13230 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13231 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13232 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13233 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13234 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13235 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13236 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13237 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13238 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13239 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13240 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13241 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13242 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13243 }; 13244 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13245 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13246 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13247 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13248 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13249 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13250 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13251 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13252 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13253 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13254 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13255 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13256 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13257 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13258 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13259 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13260 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13261 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13262 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13263 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13264 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13265 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13266 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13267 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13268 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13269 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13270 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13271 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13272 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13273 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13274 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13275 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13276 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13277 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13278 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13279 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13280 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13281 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13282 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13283 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13284 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13285 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13286 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13287 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13288 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13289 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13290 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13291 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13292 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13293 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13294 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13295 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13296 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13297 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13298 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13299 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13300 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13301 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13302 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13303 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13304 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13305 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13306 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13307 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13308 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13309 }; 13310 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13311 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13312 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13313 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13314 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13315 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13316 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13317 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13318 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13319 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13320 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13321 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13322 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13323 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13324 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13325 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13326 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13327 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13328 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13329 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13330 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13331 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13332 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13333 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13334 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13335 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13336 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13337 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13338 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13339 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13340 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13341 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13342 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13343 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13344 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13345 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13346 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13347 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13348 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13349 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13350 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13351 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13352 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13353 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13354 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13355 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13356 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13357 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13358 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13359 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13360 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13361 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13362 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13363 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13364 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13365 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13366 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13367 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13368 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13369 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13370 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13371 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13372 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13373 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13374 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13375 }; 13376 static struct bwn_txgain_entry txgain_r0[] = { 13377 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13378 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13379 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13380 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13381 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13382 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13383 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13384 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13385 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13386 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13387 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13388 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13389 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13390 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13391 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13392 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13393 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13394 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13395 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13396 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13397 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13398 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13399 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13400 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13401 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13402 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13403 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13404 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13405 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13406 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13407 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13408 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13409 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13410 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13411 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13412 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13413 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13414 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13415 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13416 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13417 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13418 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13419 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13420 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13421 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13422 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13423 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13424 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13425 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13426 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13427 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13428 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13429 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13430 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13431 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13432 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13433 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13434 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13435 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13436 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13437 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13438 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13439 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13440 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13441 }; 13442 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13443 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13444 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13445 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13446 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13447 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13448 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13449 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13450 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13451 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13452 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13453 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13454 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13455 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13456 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13457 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13458 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13459 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13460 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13461 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13462 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13463 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13464 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13465 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13466 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13467 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13468 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13469 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13470 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13471 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13472 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13473 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13474 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13475 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13476 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13477 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13478 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13479 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13480 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13481 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13482 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13483 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13484 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13485 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13486 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13487 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13488 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13489 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13490 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13491 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13492 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13493 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13494 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13495 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13496 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13497 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13498 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13499 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13500 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13501 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13502 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13503 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13504 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13505 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13506 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13507 }; 13508 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13509 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13510 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13511 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13512 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13513 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13514 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13515 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13516 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13517 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13518 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13519 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13520 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13521 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13522 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13523 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13524 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13525 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13526 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13527 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13528 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13529 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13530 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13531 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13532 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13533 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13534 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13535 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13536 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13537 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13538 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13539 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13540 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13541 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13542 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13543 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13544 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13545 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13546 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13547 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13548 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13549 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13550 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13551 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13552 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13553 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13554 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13555 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13556 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13557 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13558 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13559 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13560 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13561 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13562 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13563 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13564 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13565 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13566 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13567 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13568 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13569 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13570 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13571 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13572 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13573 }; 13574 static struct bwn_txgain_entry txgain_r1[] = { 13575 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13576 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13577 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13578 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13579 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13580 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13581 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13582 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13583 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13584 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13585 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13586 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13587 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13588 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13589 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13590 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13591 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13592 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13593 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13594 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13595 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13596 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13597 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13598 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13599 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13600 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13601 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13602 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13603 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13604 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13605 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13606 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13607 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13608 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13609 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13610 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13611 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13612 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13613 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13614 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13615 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13616 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13617 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13618 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13619 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13620 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13621 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13622 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13623 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13624 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13625 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13626 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13627 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13628 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13629 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13630 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13631 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13632 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13633 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13634 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13635 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13636 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13637 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13638 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13639 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13640 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13641 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13642 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13643 { 7, 11, 6, 0, 71 } 13644 }; 13645 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13646 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13647 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13648 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13649 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13650 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13651 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13652 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13653 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13654 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13655 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13656 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13657 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13658 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13659 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13660 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13661 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13662 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13663 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13664 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13665 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13666 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13667 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13668 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13669 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13670 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13671 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13672 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13673 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13674 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13675 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13676 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13677 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13678 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13679 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13680 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13681 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13682 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13683 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13684 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13685 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13686 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13687 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13688 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13689 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13690 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13691 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13692 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13693 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13694 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13695 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13696 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13697 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13698 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13699 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13700 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13701 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13702 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13703 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13704 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13705 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13706 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13707 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13708 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13709 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13710 }; 13711 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13712 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13713 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13714 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13715 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13716 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13717 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13718 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13719 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13720 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13721 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13722 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13723 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13724 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13725 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13726 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13727 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13728 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13729 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13730 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13731 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13732 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13733 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13734 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13735 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13736 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13737 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13738 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13739 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13740 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13741 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13742 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13743 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13744 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13745 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13746 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13747 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13748 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13749 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13750 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13751 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13752 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13753 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13754 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13755 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13756 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13757 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13758 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13759 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13760 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13761 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13762 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13763 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13764 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13765 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13766 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13767 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13768 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13769 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13770 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13771 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13772 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13773 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13774 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13775 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13776 }; 13777 13778 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13779 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13780 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13781 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13782 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13783 txgain_2ghz_r2); 13784 else 13785 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13786 txgain_5ghz_r2); 13787 return; 13788 } 13789 13790 if (mac->mac_phy.rev == 0) { 13791 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13792 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13793 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13794 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13795 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13796 txgain_2ghz_r0); 13797 else 13798 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13799 txgain_5ghz_r0); 13800 return; 13801 } 13802 13803 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13804 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13805 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13806 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13807 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13808 else 13809 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13810 } 13811 13812 static void 13813 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13814 { 13815 uint32_t offset, type; 13816 13817 type = BWN_TAB_GETTYPE(typeoffset); 13818 offset = BWN_TAB_GETOFFSET(typeoffset); 13819 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13820 13821 switch (type) { 13822 case BWN_TAB_8BIT: 13823 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13824 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13825 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13826 break; 13827 case BWN_TAB_16BIT: 13828 KASSERT(!(value & ~0xffff), 13829 ("%s:%d: fail", __func__, __LINE__)); 13830 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13831 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13832 break; 13833 case BWN_TAB_32BIT: 13834 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13835 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13836 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13837 break; 13838 default: 13839 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13840 } 13841 } 13842 13843 static int 13844 bwn_phy_lp_loopback(struct bwn_mac *mac) 13845 { 13846 struct bwn_phy_lp_iq_est ie; 13847 int i, index = -1; 13848 uint32_t tmp; 13849 13850 memset(&ie, 0, sizeof(ie)); 13851 13852 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13853 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13854 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13855 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13856 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13857 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13858 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13859 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13860 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13861 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13862 for (i = 0; i < 32; i++) { 13863 bwn_phy_lp_set_rxgain_idx(mac, i); 13864 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13865 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13866 continue; 13867 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13868 if ((tmp > 4000) && (tmp < 10000)) { 13869 index = i; 13870 break; 13871 } 13872 } 13873 bwn_phy_lp_ddfs_turnoff(mac); 13874 return (index); 13875 } 13876 13877 static void 13878 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13879 { 13880 13881 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13882 } 13883 13884 static void 13885 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13886 int incr1, int incr2, int scale_idx) 13887 { 13888 13889 bwn_phy_lp_ddfs_turnoff(mac); 13890 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13891 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13892 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13893 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13894 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13895 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13896 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 13897 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 13898 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 13899 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 13900 } 13901 13902 static uint8_t 13903 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 13904 struct bwn_phy_lp_iq_est *ie) 13905 { 13906 int i; 13907 13908 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 13909 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 13910 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 13911 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 13912 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 13913 13914 for (i = 0; i < 500; i++) { 13915 if (!(BWN_PHY_READ(mac, 13916 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 13917 break; 13918 DELAY(1000); 13919 } 13920 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 13921 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13922 return 0; 13923 } 13924 13925 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 13926 ie->ie_iqprod <<= 16; 13927 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 13928 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 13929 ie->ie_ipwr <<= 16; 13930 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 13931 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 13932 ie->ie_qpwr <<= 16; 13933 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 13934 13935 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13936 return 1; 13937 } 13938 13939 static uint32_t 13940 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 13941 { 13942 uint32_t offset, type, value; 13943 13944 type = BWN_TAB_GETTYPE(typeoffset); 13945 offset = BWN_TAB_GETOFFSET(typeoffset); 13946 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13947 13948 switch (type) { 13949 case BWN_TAB_8BIT: 13950 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13951 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 13952 break; 13953 case BWN_TAB_16BIT: 13954 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13955 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13956 break; 13957 case BWN_TAB_32BIT: 13958 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13959 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 13960 value <<= 16; 13961 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13962 break; 13963 default: 13964 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13965 value = 0; 13966 } 13967 13968 return (value); 13969 } 13970 13971 static void 13972 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 13973 { 13974 13975 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 13976 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 13977 } 13978 13979 static void 13980 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 13981 { 13982 uint16_t ctl; 13983 13984 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 13985 ctl |= dac << 7; 13986 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 13987 } 13988 13989 static void 13990 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 13991 { 13992 13993 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 13994 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 13995 } 13996 13997 static void 13998 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 13999 { 14000 14001 if (mac->mac_phy.rev < 2) 14002 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14003 else { 14004 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14005 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14006 } 14007 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14008 } 14009 14010 static uint16_t 14011 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14012 { 14013 14014 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14015 } 14016 14017 static uint8_t 14018 bwn_nbits(int32_t val) 14019 { 14020 uint32_t tmp; 14021 uint8_t nbits = 0; 14022 14023 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14024 nbits++; 14025 return (nbits); 14026 } 14027 14028 static void 14029 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14030 struct bwn_txgain_entry *table) 14031 { 14032 int i; 14033 14034 for (i = offset; i < count; i++) 14035 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14036 } 14037 14038 static void 14039 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14040 struct bwn_txgain_entry data) 14041 { 14042 14043 if (mac->mac_phy.rev >= 2) 14044 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14045 else 14046 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14047 } 14048 14049 static void 14050 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14051 struct bwn_txgain_entry te) 14052 { 14053 struct bwn_softc *sc = mac->mac_sc; 14054 struct ifnet *ifp = sc->sc_ifp; 14055 struct ieee80211com *ic = ifp->if_l2com; 14056 uint32_t tmp; 14057 14058 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14059 14060 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14061 if (mac->mac_phy.rev >= 3) { 14062 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14063 (0x10 << 24) : (0x70 << 24)); 14064 } else { 14065 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14066 (0x14 << 24) : (0x7f << 24)); 14067 } 14068 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14069 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14070 te.te_bbmult << 20 | te.te_dac << 28); 14071 } 14072 14073 static void 14074 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14075 struct bwn_txgain_entry te) 14076 { 14077 14078 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14079 14080 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14081 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14082 te.te_dac); 14083 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14084 } 14085 14086 static void 14087 bwn_sysctl_node(struct bwn_softc *sc) 14088 { 14089 struct bwn_mac *mac; 14090 struct bwn_stats *stats; 14091 struct sysctl_ctx_list *ctx; 14092 struct sysctl_oid *tree; 14093 14094 /* XXX assume that count of MAC is only 1. */ 14095 14096 if ((mac = sc->sc_curmac) == NULL) 14097 return; 14098 stats = &mac->mac_stats; 14099 14100 ctx = device_get_sysctl_ctx(sc->sc_dev); 14101 tree = device_get_sysctl_tree(sc->sc_dev); 14102 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14103 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14104 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14105 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14106 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14107 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14108 14109 #ifdef BWN_DEBUG 14110 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14111 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14112 #endif 14113 } 14114 14115 static device_method_t bwn_methods[] = { 14116 /* Device interface */ 14117 DEVMETHOD(device_probe, bwn_probe), 14118 DEVMETHOD(device_attach, bwn_attach), 14119 DEVMETHOD(device_detach, bwn_detach), 14120 DEVMETHOD(device_suspend, bwn_suspend), 14121 DEVMETHOD(device_resume, bwn_resume), 14122 DEVMETHOD_END 14123 }; 14124 static driver_t bwn_driver = { 14125 "bwn", 14126 bwn_methods, 14127 sizeof(struct bwn_softc) 14128 }; 14129 static devclass_t bwn_devclass; 14130 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, NULL, NULL); 14131 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14132 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14133 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14134 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14135