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 ifnet *); 187 static void bwn_update_promisc(struct ifnet *); 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 < sizeof(bwn_devs) / sizeof(bwn_devs[0]); 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 /* XXX not right but it's not used anywhere important */ 1036 ic->ic_phytype = IEEE80211_T_OFDM; 1037 ic->ic_opmode = IEEE80211_M_STA; 1038 ic->ic_caps = 1039 IEEE80211_C_STA /* station mode supported */ 1040 | IEEE80211_C_MONITOR /* monitor mode */ 1041 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1042 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1043 | IEEE80211_C_SHSLOT /* short slot time supported */ 1044 | IEEE80211_C_WME /* WME/WMM supported */ 1045 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1046 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1047 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1048 ; 1049 1050 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1051 1052 /* call MI attach routine. */ 1053 ieee80211_ifattach(ic, 1054 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1055 siba_sprom_get_mac_80211a(sc->sc_dev) : 1056 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1057 1058 ic->ic_headroom = sizeof(struct bwn_txhdr); 1059 1060 /* override default methods */ 1061 ic->ic_raw_xmit = bwn_raw_xmit; 1062 ic->ic_updateslot = bwn_updateslot; 1063 ic->ic_update_promisc = bwn_update_promisc; 1064 ic->ic_wme.wme_update = bwn_wme_update; 1065 1066 ic->ic_scan_start = bwn_scan_start; 1067 ic->ic_scan_end = bwn_scan_end; 1068 ic->ic_set_channel = bwn_set_channel; 1069 1070 ic->ic_vap_create = bwn_vap_create; 1071 ic->ic_vap_delete = bwn_vap_delete; 1072 1073 ieee80211_radiotap_attach(ic, 1074 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1075 BWN_TX_RADIOTAP_PRESENT, 1076 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1077 BWN_RX_RADIOTAP_PRESENT); 1078 1079 bwn_sysctl_node(sc); 1080 1081 if (bootverbose) 1082 ieee80211_announce(ic); 1083 return (0); 1084 } 1085 1086 static void 1087 bwn_phy_detach(struct bwn_mac *mac) 1088 { 1089 1090 if (mac->mac_phy.detach != NULL) 1091 mac->mac_phy.detach(mac); 1092 } 1093 1094 static int 1095 bwn_detach(device_t dev) 1096 { 1097 struct bwn_softc *sc = device_get_softc(dev); 1098 struct bwn_mac *mac = sc->sc_curmac; 1099 struct ifnet *ifp = sc->sc_ifp; 1100 struct ieee80211com *ic = ifp->if_l2com; 1101 1102 wlan_serialize_enter(); 1103 1104 sc->sc_flags |= BWN_FLAG_INVALID; 1105 1106 if (device_is_attached(sc->sc_dev)) { 1107 bwn_stop(sc, 1); 1108 bwn_dma_free(mac); 1109 callout_stop_sync(&sc->sc_led_blink_ch); 1110 callout_stop_sync(&sc->sc_rfswitch_ch); 1111 callout_stop_sync(&sc->sc_task_ch); 1112 callout_stop_sync(&sc->sc_watchdog_ch); 1113 bwn_phy_detach(mac); 1114 if (ifp != NULL) { 1115 wlan_serialize_exit(); 1116 ieee80211_draintask(ic, &mac->mac_hwreset); 1117 ieee80211_draintask(ic, &mac->mac_txpower); 1118 wlan_serialize_enter(); 1119 ieee80211_ifdetach(ic); 1120 if_free(ifp); 1121 } 1122 } 1123 wlan_serialize_exit(); 1124 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1125 taskqueue_free(sc->sc_tq); 1126 wlan_serialize_enter(); 1127 1128 if (sc->bwn_intr) 1129 bus_teardown_intr(dev, sc->bwn_irq, sc->bwn_intr); 1130 if (sc->bwn_irq != NULL) 1131 bus_release_resource(dev, SYS_RES_IRQ, sc->bwn_irq_rid, 1132 sc->bwn_irq); 1133 1134 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI) 1135 pci_release_msi(dev); 1136 1137 if (sc->sc_sysctl_tree) { 1138 sysctl_ctx_free(&sc->sc_sysctl_ctx); 1139 sc->sc_sysctl_tree = NULL; 1140 } 1141 1142 wlan_serialize_exit(); 1143 return (0); 1144 } 1145 1146 static int 1147 bwn_attach_pre(struct bwn_softc *sc) 1148 { 1149 struct ifnet *ifp; 1150 int error = 0; 1151 1152 TAILQ_INIT(&sc->sc_maclist); 1153 callout_init(&sc->sc_rfswitch_ch); 1154 callout_init(&sc->sc_task_ch); 1155 callout_init(&sc->sc_watchdog_ch); 1156 1157 sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK, 1158 taskqueue_thread_enqueue, &sc->sc_tq); 1159 taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1, 1160 "%s taskq", device_get_nameunit(sc->sc_dev)); 1161 1162 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1163 if (ifp == NULL) { 1164 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1165 error = ENOSPC; 1166 goto fail; 1167 } 1168 1169 /* set these up early for if_printf use */ 1170 if_initname(ifp, device_get_name(sc->sc_dev), 1171 device_get_unit(sc->sc_dev)); 1172 1173 /* prepare sysctl tree for use in sub modules */ 1174 sysctl_ctx_init(&sc->sc_sysctl_ctx); 1175 sc->sc_sysctl_tree = SYSCTL_ADD_NODE(&sc->sc_sysctl_ctx, 1176 SYSCTL_STATIC_CHILDREN(_hw), 1177 OID_AUTO, 1178 device_get_nameunit(sc->sc_dev), 1179 CTLFLAG_RD, 0, ""); 1180 1181 ifp->if_softc = sc; 1182 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1183 ifp->if_init = bwn_init; 1184 ifp->if_ioctl = bwn_ioctl; 1185 ifp->if_start = bwn_start; 1186 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); 1187 1188 return (0); 1189 1190 fail: 1191 return (error); 1192 } 1193 1194 static void 1195 bwn_sprom_bugfixes(device_t dev) 1196 { 1197 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1198 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1199 (siba_get_pci_device(dev) == _device) && \ 1200 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1201 (siba_get_pci_subdevice(dev) == _subdevice)) 1202 1203 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1204 siba_get_pci_subdevice(dev) == 0x4e && 1205 siba_get_pci_revid(dev) > 0x40) 1206 siba_sprom_set_bf_lo(dev, 1207 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1208 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1209 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1210 siba_sprom_set_bf_lo(dev, 1211 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1212 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1213 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1214 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1215 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1216 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1217 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1218 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1219 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1220 siba_sprom_set_bf_lo(dev, 1221 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1222 } 1223 #undef BWN_ISDEV 1224 } 1225 1226 static int 1227 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, 1228 struct ucred *cr __unused) 1229 { 1230 #define IS_RUNNING(ifp) \ 1231 ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING)) 1232 struct bwn_softc *sc = ifp->if_softc; 1233 struct ieee80211com *ic = ifp->if_l2com; 1234 struct ifreq *ifr = (struct ifreq *)data; 1235 int error = 0; 1236 1237 switch (cmd) { 1238 case SIOCSIFFLAGS: 1239 if (IS_RUNNING(ifp)) { 1240 bwn_update_promisc(ifp); 1241 } else if (ifp->if_flags & IFF_UP) { 1242 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1243 bwn_init(sc); 1244 } 1245 } else 1246 bwn_stop(sc, 1); 1247 break; 1248 case SIOCGIFMEDIA: 1249 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1250 break; 1251 case SIOCGIFADDR: 1252 error = ether_ioctl(ifp, cmd, data); 1253 break; 1254 default: 1255 error = EINVAL; 1256 break; 1257 } 1258 return (error); 1259 } 1260 1261 static void 1262 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) 1263 { 1264 wlan_assert_serialized(); 1265 bwn_start_locked(ifp); 1266 } 1267 1268 static void 1269 bwn_start_locked(struct ifnet *ifp) 1270 { 1271 struct bwn_softc *sc = ifp->if_softc; 1272 struct bwn_mac *mac = sc->sc_curmac; 1273 struct ieee80211_frame *wh; 1274 struct ieee80211_node *ni; 1275 struct ieee80211_key *k; 1276 struct mbuf *m; 1277 1278 wlan_assert_serialized(); 1279 1280 if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL || 1281 mac->mac_status < BWN_MAC_STATUS_STARTED) 1282 return; 1283 1284 for (;;) { 1285 m = ifq_dequeue(&ifp->if_snd); /* XXX: LOCK */ 1286 if (m == NULL) 1287 break; 1288 1289 if (bwn_tx_isfull(sc, m)) 1290 break; 1291 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1292 if (ni == NULL) { 1293 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1294 m_freem(m); 1295 ifp->if_oerrors++; 1296 continue; 1297 } 1298 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1299 wh = mtod(m, struct ieee80211_frame *); 1300 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1301 k = ieee80211_crypto_encap(ni, m); 1302 if (k == NULL) { 1303 ieee80211_free_node(ni); 1304 m_freem(m); 1305 ifp->if_oerrors++; 1306 continue; 1307 } 1308 } 1309 wh = NULL; /* Catch any invalid use */ 1310 1311 if (bwn_tx_start(sc, ni, m) != 0) { 1312 if (ni != NULL) 1313 ieee80211_free_node(ni); 1314 ifp->if_oerrors++; 1315 continue; 1316 } 1317 1318 sc->sc_watchdog_timer = 5; 1319 } 1320 } 1321 1322 static int 1323 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1324 { 1325 struct bwn_dma_ring *dr; 1326 struct bwn_mac *mac = sc->sc_curmac; 1327 struct bwn_pio_txqueue *tq; 1328 struct ifnet *ifp = sc->sc_ifp; 1329 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1330 1331 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1332 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1333 if (dr->dr_stop == 1 || 1334 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1335 dr->dr_stop = 1; 1336 goto full; 1337 } 1338 } else { 1339 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1340 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1341 pktlen > (tq->tq_size - tq->tq_used)) { 1342 tq->tq_stop = 1; 1343 goto full; 1344 } 1345 } 1346 return (0); 1347 full: 1348 ifq_prepend(&ifp->if_snd, m); 1349 ifq_set_oactive(&ifp->if_snd); 1350 return (1); 1351 } 1352 1353 static int 1354 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1355 { 1356 struct bwn_mac *mac = sc->sc_curmac; 1357 int error; 1358 1359 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1360 m_freem(m); 1361 return (ENXIO); 1362 } 1363 1364 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1365 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1366 if (error) { 1367 m_freem(m); 1368 return (error); 1369 } 1370 return (0); 1371 } 1372 1373 static int 1374 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1375 { 1376 struct bwn_pio_txpkt *tp; 1377 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1378 struct bwn_softc *sc = mac->mac_sc; 1379 struct bwn_txhdr txhdr; 1380 struct mbuf *m_new; 1381 uint32_t ctl32; 1382 int error; 1383 uint16_t ctl16; 1384 1385 /* XXX TODO send packets after DTIM */ 1386 1387 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1388 tp = TAILQ_FIRST(&tq->tq_pktlist); 1389 tp->tp_ni = ni; 1390 tp->tp_m = m; 1391 1392 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1393 if (error) { 1394 device_printf(sc->sc_dev, "tx fail\n"); 1395 return (error); 1396 } 1397 1398 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1399 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1400 tq->tq_free--; 1401 1402 if (siba_get_revid(sc->sc_dev) >= 8) { 1403 /* 1404 * XXX please removes m_defrag(9) 1405 */ 1406 m_new = m_defrag(m, M_INTWAIT); 1407 if (m_new == NULL) { 1408 device_printf(sc->sc_dev, 1409 "%s: can't defrag TX buffer\n", 1410 __func__); 1411 return (ENOBUFS); 1412 } 1413 if (m_new->m_next != NULL) 1414 device_printf(sc->sc_dev, 1415 "TODO: fragmented packets for PIO\n"); 1416 tp->tp_m = m_new; 1417 1418 /* send HEADER */ 1419 ctl32 = bwn_pio_write_multi_4(mac, tq, 1420 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1421 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1422 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1423 /* send BODY */ 1424 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1425 mtod(m_new, const void *), m_new->m_pkthdr.len); 1426 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1427 ctl32 | BWN_PIO8_TXCTL_EOF); 1428 } else { 1429 ctl16 = bwn_pio_write_multi_2(mac, tq, 1430 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1431 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1432 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1433 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1434 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1435 ctl16 | BWN_PIO_TXCTL_EOF); 1436 } 1437 1438 return (0); 1439 } 1440 1441 static struct bwn_pio_txqueue * 1442 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1443 { 1444 1445 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1446 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1447 1448 switch (prio) { 1449 case 0: 1450 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1451 case 1: 1452 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1453 case 2: 1454 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1455 case 3: 1456 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1457 } 1458 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1459 return (NULL); 1460 } 1461 1462 static int 1463 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1464 { 1465 #define BWN_GET_TXHDRCACHE(slot) \ 1466 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)]) 1467 struct bwn_dma *dma = &mac->mac_method.dma; 1468 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1469 struct bwn_dmadesc_generic *desc; 1470 struct bwn_dmadesc_meta *mt; 1471 struct bwn_softc *sc = mac->mac_sc; 1472 struct ifnet *ifp = sc->sc_ifp; 1473 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1474 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1475 1476 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1477 1478 /* XXX send after DTIM */ 1479 1480 slot = bwn_dma_getslot(dr); 1481 dr->getdesc(dr, slot, &desc, &mt); 1482 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1483 ("%s:%d: fail", __func__, __LINE__)); 1484 1485 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1486 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1487 BWN_DMA_COOKIE(dr, slot)); 1488 if (error) 1489 goto fail; 1490 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1491 BUS_DMASYNC_PREWRITE); 1492 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1493 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1494 BUS_DMASYNC_PREWRITE); 1495 1496 slot = bwn_dma_getslot(dr); 1497 dr->getdesc(dr, slot, &desc, &mt); 1498 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1499 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1500 mt->mt_m = m; 1501 mt->mt_ni = ni; 1502 1503 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1504 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1505 if (error && error != EFBIG) { 1506 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1507 __func__, error); 1508 goto fail; 1509 } 1510 if (error) { /* error == EFBIG */ 1511 struct mbuf *m_new; 1512 1513 m_new = m_defrag(m, M_INTWAIT); 1514 if (m_new == NULL) { 1515 if_printf(ifp, "%s: can't defrag TX buffer\n", 1516 __func__); 1517 error = ENOBUFS; 1518 goto fail; 1519 } else { 1520 m = m_new; 1521 } 1522 1523 mt->mt_m = m; 1524 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1525 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1526 if (error) { 1527 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1528 __func__, error); 1529 goto fail; 1530 } 1531 } 1532 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1533 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1534 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1535 BUS_DMASYNC_PREWRITE); 1536 1537 /* XXX send after DTIM */ 1538 1539 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1540 return (0); 1541 fail: 1542 dr->dr_curslot = backup[0]; 1543 dr->dr_usedslot = backup[1]; 1544 return (error); 1545 #undef BWN_GET_TXHDRCACHE 1546 } 1547 1548 static void 1549 bwn_watchdog(void *arg) 1550 { 1551 struct bwn_softc *sc = arg; 1552 struct ifnet *ifp = sc->sc_ifp; 1553 1554 wlan_serialize_enter(); 1555 1556 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1557 if_printf(ifp, "device timeout\n"); 1558 ifp->if_oerrors++; 1559 } 1560 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 1561 wlan_serialize_exit(); 1562 } 1563 1564 static int 1565 bwn_attach_core(struct bwn_mac *mac) 1566 { 1567 struct bwn_softc *sc = mac->mac_sc; 1568 int error, have_bg = 0, have_a = 0; 1569 uint32_t high; 1570 1571 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1572 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1573 1574 siba_powerup(sc->sc_dev, 0); 1575 1576 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1577 bwn_reset_core(mac, 1578 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1579 error = bwn_phy_getinfo(mac, high); 1580 if (error) 1581 goto fail; 1582 1583 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1584 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1585 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1586 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1587 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1588 have_a = have_bg = 0; 1589 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1590 have_a = 1; 1591 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1592 mac->mac_phy.type == BWN_PHYTYPE_N || 1593 mac->mac_phy.type == BWN_PHYTYPE_LP) 1594 have_bg = 1; 1595 else 1596 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1597 mac->mac_phy.type)); 1598 } 1599 /* XXX turns off PHY A because it's not supported */ 1600 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1601 mac->mac_phy.type != BWN_PHYTYPE_N) { 1602 have_a = 0; 1603 have_bg = 1; 1604 } 1605 1606 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1607 mac->mac_phy.attach = bwn_phy_g_attach; 1608 mac->mac_phy.detach = bwn_phy_g_detach; 1609 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1610 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1611 mac->mac_phy.init = bwn_phy_g_init; 1612 mac->mac_phy.exit = bwn_phy_g_exit; 1613 mac->mac_phy.phy_read = bwn_phy_g_read; 1614 mac->mac_phy.phy_write = bwn_phy_g_write; 1615 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1616 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1617 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1618 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1619 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1620 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1621 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1622 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1623 mac->mac_phy.set_im = bwn_phy_g_im; 1624 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1625 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1626 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1627 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1628 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1629 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1630 mac->mac_phy.init = bwn_phy_lp_init; 1631 mac->mac_phy.phy_read = bwn_phy_lp_read; 1632 mac->mac_phy.phy_write = bwn_phy_lp_write; 1633 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1634 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1635 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1636 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1637 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1638 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1639 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1640 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1641 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1642 } else { 1643 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1644 mac->mac_phy.type); 1645 error = ENXIO; 1646 goto fail; 1647 } 1648 1649 mac->mac_phy.gmode = have_bg; 1650 if (mac->mac_phy.attach != NULL) { 1651 error = mac->mac_phy.attach(mac); 1652 if (error) { 1653 device_printf(sc->sc_dev, "failed\n"); 1654 goto fail; 1655 } 1656 } 1657 1658 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1659 1660 error = bwn_chiptest(mac); 1661 if (error) 1662 goto fail; 1663 error = bwn_setup_channels(mac, have_bg, have_a); 1664 if (error) { 1665 device_printf(sc->sc_dev, "failed to setup channels\n"); 1666 goto fail; 1667 } 1668 1669 if (sc->sc_curmac == NULL) 1670 sc->sc_curmac = mac; 1671 1672 wlan_assert_serialized(); 1673 wlan_serialize_exit(); 1674 error = bwn_dma_attach(mac); 1675 wlan_serialize_enter(); 1676 if (error != 0) { 1677 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1678 goto fail; 1679 } 1680 1681 mac->mac_phy.switch_analog(mac, 0); 1682 1683 siba_dev_down(sc->sc_dev, 0); 1684 fail: 1685 siba_powerdown(sc->sc_dev); 1686 return (error); 1687 } 1688 1689 static void 1690 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1691 { 1692 struct bwn_softc *sc = mac->mac_sc; 1693 uint32_t low, ctl; 1694 1695 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1696 1697 siba_dev_up(sc->sc_dev, flags); 1698 DELAY(2000); 1699 1700 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1701 ~BWN_TGSLOW_PHYRESET; 1702 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1703 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1704 DELAY(1000); 1705 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1706 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1707 DELAY(1000); 1708 1709 if (mac->mac_phy.switch_analog != NULL) 1710 mac->mac_phy.switch_analog(mac, 1); 1711 1712 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1713 if (flags & BWN_TGSLOW_SUPPORT_G) 1714 ctl |= BWN_MACCTL_GMODE; 1715 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1716 } 1717 1718 static int 1719 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1720 { 1721 struct bwn_phy *phy = &mac->mac_phy; 1722 struct bwn_softc *sc = mac->mac_sc; 1723 uint32_t tmp; 1724 1725 /* PHY */ 1726 tmp = BWN_READ_2(mac, BWN_PHYVER); 1727 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1728 phy->rf_on = 1; 1729 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1730 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1731 phy->rev = (tmp & BWN_PHYVER_VERSION); 1732 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1733 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1734 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1735 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1736 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1737 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1738 goto unsupphy; 1739 1740 /* RADIO */ 1741 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1742 if (siba_get_chiprev(sc->sc_dev) == 0) 1743 tmp = 0x3205017f; 1744 else if (siba_get_chiprev(sc->sc_dev) == 1) 1745 tmp = 0x4205017f; 1746 else 1747 tmp = 0x5205017f; 1748 } else { 1749 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1750 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1751 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1752 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1753 } 1754 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1755 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1756 phy->rf_manuf = (tmp & 0x00000fff); 1757 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1758 goto unsupradio; 1759 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1760 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1761 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1762 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1763 (phy->type == BWN_PHYTYPE_N && 1764 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1765 (phy->type == BWN_PHYTYPE_LP && 1766 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1767 goto unsupradio; 1768 1769 return (0); 1770 unsupphy: 1771 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1772 "analog %#x)\n", 1773 phy->type, phy->rev, phy->analog); 1774 return (ENXIO); 1775 unsupradio: 1776 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1777 "rev %#x)\n", 1778 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1779 return (ENXIO); 1780 } 1781 1782 static int 1783 bwn_chiptest(struct bwn_mac *mac) 1784 { 1785 #define TESTVAL0 0x55aaaa55 1786 #define TESTVAL1 0xaa5555aa 1787 struct bwn_softc *sc = mac->mac_sc; 1788 uint32_t v, backup; 1789 1790 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1791 1792 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1793 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1794 goto error; 1795 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1796 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1797 goto error; 1798 1799 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1800 1801 if ((siba_get_revid(sc->sc_dev) >= 3) && 1802 (siba_get_revid(sc->sc_dev) <= 10)) { 1803 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1804 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1805 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1806 goto error; 1807 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1808 goto error; 1809 } 1810 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1811 1812 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1813 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1814 goto error; 1815 1816 return (0); 1817 error: 1818 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1819 return (ENODEV); 1820 } 1821 1822 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1823 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1824 1825 static int 1826 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1827 { 1828 struct bwn_softc *sc = mac->mac_sc; 1829 struct ifnet *ifp = sc->sc_ifp; 1830 struct ieee80211com *ic = ifp->if_l2com; 1831 1832 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1833 ic->ic_nchans = 0; 1834 1835 if (have_bg) 1836 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1837 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1838 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1839 if (have_a) 1840 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1841 &ic->ic_nchans, &bwn_chantable_n, 1842 IEEE80211_CHAN_HTA); 1843 } else { 1844 if (have_a) 1845 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1846 &ic->ic_nchans, &bwn_chantable_a, 1847 IEEE80211_CHAN_A); 1848 } 1849 1850 mac->mac_phy.supports_2ghz = have_bg; 1851 mac->mac_phy.supports_5ghz = have_a; 1852 1853 return (ic->ic_nchans == 0 ? ENXIO : 0); 1854 } 1855 1856 static uint32_t 1857 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1858 { 1859 uint32_t ret; 1860 1861 if (way == BWN_SHARED) { 1862 KASSERT((offset & 0x0001) == 0, 1863 ("%s:%d warn", __func__, __LINE__)); 1864 if (offset & 0x0003) { 1865 bwn_shm_ctlword(mac, way, offset >> 2); 1866 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1867 ret <<= 16; 1868 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1869 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1870 goto out; 1871 } 1872 offset >>= 2; 1873 } 1874 bwn_shm_ctlword(mac, way, offset); 1875 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1876 out: 1877 return (ret); 1878 } 1879 1880 static uint16_t 1881 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1882 { 1883 uint16_t ret; 1884 1885 if (way == BWN_SHARED) { 1886 KASSERT((offset & 0x0001) == 0, 1887 ("%s:%d warn", __func__, __LINE__)); 1888 if (offset & 0x0003) { 1889 bwn_shm_ctlword(mac, way, offset >> 2); 1890 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1891 goto out; 1892 } 1893 offset >>= 2; 1894 } 1895 bwn_shm_ctlword(mac, way, offset); 1896 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1897 out: 1898 1899 return (ret); 1900 } 1901 1902 static void 1903 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1904 uint16_t offset) 1905 { 1906 uint32_t control; 1907 1908 control = way; 1909 control <<= 16; 1910 control |= offset; 1911 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1912 } 1913 1914 static void 1915 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1916 uint32_t value) 1917 { 1918 if (way == BWN_SHARED) { 1919 KASSERT((offset & 0x0001) == 0, 1920 ("%s:%d warn", __func__, __LINE__)); 1921 if (offset & 0x0003) { 1922 bwn_shm_ctlword(mac, way, offset >> 2); 1923 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1924 (value >> 16) & 0xffff); 1925 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1926 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1927 return; 1928 } 1929 offset >>= 2; 1930 } 1931 bwn_shm_ctlword(mac, way, offset); 1932 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1933 } 1934 1935 static void 1936 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1937 uint16_t value) 1938 { 1939 if (way == BWN_SHARED) { 1940 KASSERT((offset & 0x0001) == 0, 1941 ("%s:%d warn", __func__, __LINE__)); 1942 if (offset & 0x0003) { 1943 bwn_shm_ctlword(mac, way, offset >> 2); 1944 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1945 return; 1946 } 1947 offset >>= 2; 1948 } 1949 bwn_shm_ctlword(mac, way, offset); 1950 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1951 } 1952 1953 static void 1954 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1955 int txpow) 1956 { 1957 1958 c->ic_freq = freq; 1959 c->ic_flags = flags; 1960 c->ic_ieee = ieee; 1961 c->ic_minpower = 0; 1962 c->ic_maxpower = 2 * txpow; 1963 c->ic_maxregpower = txpow; 1964 } 1965 1966 static void 1967 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 1968 const struct bwn_channelinfo *ci, int flags) 1969 { 1970 struct ieee80211_channel *c; 1971 int i; 1972 1973 c = &chans[*nchans]; 1974 1975 for (i = 0; i < ci->nchannels; i++) { 1976 const struct bwn_channel *hc; 1977 1978 hc = &ci->channels[i]; 1979 if (*nchans >= maxchans) 1980 break; 1981 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 1982 c++, (*nchans)++; 1983 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 1984 /* g channel have a separate b-only entry */ 1985 if (*nchans >= maxchans) 1986 break; 1987 c[0] = c[-1]; 1988 c[-1].ic_flags = IEEE80211_CHAN_B; 1989 c++, (*nchans)++; 1990 } 1991 if (flags == IEEE80211_CHAN_HTG) { 1992 /* HT g channel have a separate g-only entry */ 1993 if (*nchans >= maxchans) 1994 break; 1995 c[-1].ic_flags = IEEE80211_CHAN_G; 1996 c[0] = c[-1]; 1997 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1998 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1999 c++, (*nchans)++; 2000 } 2001 if (flags == IEEE80211_CHAN_HTA) { 2002 /* HT a channel have a separate a-only entry */ 2003 if (*nchans >= maxchans) 2004 break; 2005 c[-1].ic_flags = IEEE80211_CHAN_A; 2006 c[0] = c[-1]; 2007 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2008 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2009 c++, (*nchans)++; 2010 } 2011 } 2012 } 2013 2014 static int 2015 bwn_phy_g_attach(struct bwn_mac *mac) 2016 { 2017 struct bwn_softc *sc = mac->mac_sc; 2018 struct bwn_phy *phy = &mac->mac_phy; 2019 struct bwn_phy_g *pg = &phy->phy_g; 2020 unsigned int i; 2021 int16_t pab0, pab1, pab2; 2022 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2023 int8_t bg; 2024 2025 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2026 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2027 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2028 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2029 2030 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2031 device_printf(sc->sc_dev, "not supported anymore\n"); 2032 2033 pg->pg_flags = 0; 2034 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2035 pab2 == -1) { 2036 pg->pg_idletssi = 52; 2037 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2038 return (0); 2039 } 2040 2041 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2042 pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO); 2043 for (i = 0; i < 64; i++) { 2044 int32_t m1, m2, f, q, delta; 2045 int8_t j = 0; 2046 2047 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2048 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2049 f = 256; 2050 2051 do { 2052 if (j > 15) { 2053 device_printf(sc->sc_dev, 2054 "failed to generate tssi2dBm\n"); 2055 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2056 return (ENOMEM); 2057 } 2058 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2059 f, 2048); 2060 delta = abs(q - f); 2061 f = q; 2062 j++; 2063 } while (delta >= 2); 2064 2065 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2066 128); 2067 } 2068 2069 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2070 return (0); 2071 } 2072 2073 static void 2074 bwn_phy_g_detach(struct bwn_mac *mac) 2075 { 2076 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2077 2078 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2079 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2080 pg->pg_tssi2dbm = NULL; 2081 } 2082 pg->pg_flags = 0; 2083 } 2084 2085 static void 2086 bwn_phy_g_init_pre(struct bwn_mac *mac) 2087 { 2088 struct bwn_phy *phy = &mac->mac_phy; 2089 struct bwn_phy_g *pg = &phy->phy_g; 2090 void *tssi2dbm; 2091 int idletssi; 2092 unsigned int i; 2093 2094 tssi2dbm = pg->pg_tssi2dbm; 2095 idletssi = pg->pg_idletssi; 2096 2097 memset(pg, 0, sizeof(*pg)); 2098 2099 pg->pg_tssi2dbm = tssi2dbm; 2100 pg->pg_idletssi = idletssi; 2101 2102 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2103 2104 for (i = 0; i < N(pg->pg_nrssi); i++) 2105 pg->pg_nrssi[i] = -1000; 2106 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2107 pg->pg_nrssi_lt[i] = i; 2108 pg->pg_lofcal = 0xffff; 2109 pg->pg_initval = 0xffff; 2110 pg->pg_immode = BWN_IMMODE_NONE; 2111 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2112 pg->pg_avgtssi = 0xff; 2113 2114 pg->pg_loctl.tx_bias = 0xff; 2115 TAILQ_INIT(&pg->pg_loctl.calib_list); 2116 } 2117 2118 static int 2119 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2120 { 2121 struct bwn_phy *phy = &mac->mac_phy; 2122 struct bwn_phy_g *pg = &phy->phy_g; 2123 struct bwn_softc *sc = mac->mac_sc; 2124 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2125 static const struct bwn_rfatt rfatt0[] = { 2126 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2127 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2128 { 3, 1 }, { 4, 1 } 2129 }; 2130 static const struct bwn_rfatt rfatt1[] = { 2131 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2132 { 14, 1 } 2133 }; 2134 static const struct bwn_rfatt rfatt2[] = { 2135 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2136 { 9, 1 } 2137 }; 2138 static const struct bwn_bbatt bbatt_0[] = { 2139 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2140 }; 2141 2142 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2143 2144 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2145 pg->pg_bbatt.att = 0; 2146 else 2147 pg->pg_bbatt.att = 2; 2148 2149 /* prepare Radio Attenuation */ 2150 pg->pg_rfatt.padmix = 0; 2151 2152 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2153 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2154 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2155 pg->pg_rfatt.att = 2; 2156 goto done; 2157 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2158 pg->pg_rfatt.att = 3; 2159 goto done; 2160 } 2161 } 2162 2163 if (phy->type == BWN_PHYTYPE_A) { 2164 pg->pg_rfatt.att = 0x60; 2165 goto done; 2166 } 2167 2168 switch (phy->rf_ver) { 2169 case 0x2050: 2170 switch (phy->rf_rev) { 2171 case 0: 2172 pg->pg_rfatt.att = 5; 2173 goto done; 2174 case 1: 2175 if (phy->type == BWN_PHYTYPE_G) { 2176 if (siba_get_pci_subvendor(sc->sc_dev) == 2177 SIBA_BOARDVENDOR_BCM && 2178 siba_get_pci_subdevice(sc->sc_dev) == 2179 SIBA_BOARD_BCM4309G && 2180 siba_get_pci_revid(sc->sc_dev) >= 30) 2181 pg->pg_rfatt.att = 3; 2182 else if (siba_get_pci_subvendor(sc->sc_dev) == 2183 SIBA_BOARDVENDOR_BCM && 2184 siba_get_pci_subdevice(sc->sc_dev) == 2185 SIBA_BOARD_BU4306) 2186 pg->pg_rfatt.att = 3; 2187 else 2188 pg->pg_rfatt.att = 1; 2189 } else { 2190 if (siba_get_pci_subvendor(sc->sc_dev) == 2191 SIBA_BOARDVENDOR_BCM && 2192 siba_get_pci_subdevice(sc->sc_dev) == 2193 SIBA_BOARD_BCM4309G && 2194 siba_get_pci_revid(sc->sc_dev) >= 30) 2195 pg->pg_rfatt.att = 7; 2196 else 2197 pg->pg_rfatt.att = 6; 2198 } 2199 goto done; 2200 case 2: 2201 if (phy->type == BWN_PHYTYPE_G) { 2202 if (siba_get_pci_subvendor(sc->sc_dev) == 2203 SIBA_BOARDVENDOR_BCM && 2204 siba_get_pci_subdevice(sc->sc_dev) == 2205 SIBA_BOARD_BCM4309G && 2206 siba_get_pci_revid(sc->sc_dev) >= 30) 2207 pg->pg_rfatt.att = 3; 2208 else if (siba_get_pci_subvendor(sc->sc_dev) == 2209 SIBA_BOARDVENDOR_BCM && 2210 siba_get_pci_subdevice(sc->sc_dev) == 2211 SIBA_BOARD_BU4306) 2212 pg->pg_rfatt.att = 5; 2213 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2214 pg->pg_rfatt.att = 4; 2215 else 2216 pg->pg_rfatt.att = 3; 2217 } else 2218 pg->pg_rfatt.att = 6; 2219 goto done; 2220 case 3: 2221 pg->pg_rfatt.att = 5; 2222 goto done; 2223 case 4: 2224 case 5: 2225 pg->pg_rfatt.att = 1; 2226 goto done; 2227 case 6: 2228 case 7: 2229 pg->pg_rfatt.att = 5; 2230 goto done; 2231 case 8: 2232 pg->pg_rfatt.att = 0xa; 2233 pg->pg_rfatt.padmix = 1; 2234 goto done; 2235 case 9: 2236 default: 2237 pg->pg_rfatt.att = 5; 2238 goto done; 2239 } 2240 break; 2241 case 0x2053: 2242 switch (phy->rf_rev) { 2243 case 1: 2244 pg->pg_rfatt.att = 6; 2245 goto done; 2246 } 2247 break; 2248 } 2249 pg->pg_rfatt.att = 5; 2250 done: 2251 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2252 2253 if (!bwn_has_hwpctl(mac)) { 2254 lo->rfatt.array = rfatt0; 2255 lo->rfatt.len = N(rfatt0); 2256 lo->rfatt.min = 0; 2257 lo->rfatt.max = 9; 2258 goto genbbatt; 2259 } 2260 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2261 lo->rfatt.array = rfatt1; 2262 lo->rfatt.len = N(rfatt1); 2263 lo->rfatt.min = 0; 2264 lo->rfatt.max = 14; 2265 goto genbbatt; 2266 } 2267 lo->rfatt.array = rfatt2; 2268 lo->rfatt.len = N(rfatt2); 2269 lo->rfatt.min = 0; 2270 lo->rfatt.max = 9; 2271 genbbatt: 2272 lo->bbatt.array = bbatt_0; 2273 lo->bbatt.len = N(bbatt_0); 2274 lo->bbatt.min = 0; 2275 lo->bbatt.max = 8; 2276 2277 BWN_READ_4(mac, BWN_MACCTL); 2278 if (phy->rev == 1) { 2279 phy->gmode = 0; 2280 bwn_reset_core(mac, 0); 2281 bwn_phy_g_init_sub(mac); 2282 phy->gmode = 1; 2283 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2284 } 2285 return (0); 2286 } 2287 2288 static uint16_t 2289 bwn_phy_g_txctl(struct bwn_mac *mac) 2290 { 2291 struct bwn_phy *phy = &mac->mac_phy; 2292 2293 if (phy->rf_ver != 0x2050) 2294 return (0); 2295 if (phy->rf_rev == 1) 2296 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2297 if (phy->rf_rev < 6) 2298 return (BWN_TXCTL_PA2DB); 2299 if (phy->rf_rev == 8) 2300 return (BWN_TXCTL_TXMIX); 2301 return (0); 2302 } 2303 2304 static int 2305 bwn_phy_g_init(struct bwn_mac *mac) 2306 { 2307 2308 bwn_phy_g_init_sub(mac); 2309 return (0); 2310 } 2311 2312 static void 2313 bwn_phy_g_exit(struct bwn_mac *mac) 2314 { 2315 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2316 struct bwn_lo_calib *cal, *tmp; 2317 2318 if (lo == NULL) 2319 return; 2320 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2321 TAILQ_REMOVE(&lo->calib_list, cal, list); 2322 kfree(cal, M_DEVBUF); 2323 } 2324 } 2325 2326 static uint16_t 2327 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2328 { 2329 2330 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2331 return (BWN_READ_2(mac, BWN_PHYDATA)); 2332 } 2333 2334 static void 2335 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2336 { 2337 2338 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2339 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2340 } 2341 2342 static uint16_t 2343 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2344 { 2345 2346 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2347 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2348 return (BWN_READ_2(mac, BWN_RFDATALO)); 2349 } 2350 2351 static void 2352 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2353 { 2354 2355 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2356 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2357 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2358 } 2359 2360 static int 2361 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2362 { 2363 2364 return (mac->mac_phy.rev >= 6); 2365 } 2366 2367 static void 2368 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2369 { 2370 struct bwn_phy *phy = &mac->mac_phy; 2371 struct bwn_phy_g *pg = &phy->phy_g; 2372 unsigned int channel; 2373 uint16_t rfover, rfoverval; 2374 2375 if (on) { 2376 if (phy->rf_on) 2377 return; 2378 2379 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2380 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2381 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2382 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2383 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2384 pg->pg_radioctx_over); 2385 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2386 pg->pg_radioctx_overval); 2387 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2388 } 2389 channel = phy->chan; 2390 bwn_phy_g_switch_chan(mac, 6, 1); 2391 bwn_phy_g_switch_chan(mac, channel, 0); 2392 return; 2393 } 2394 2395 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2396 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2397 pg->pg_radioctx_over = rfover; 2398 pg->pg_radioctx_overval = rfoverval; 2399 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2400 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2401 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2402 } 2403 2404 static int 2405 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2406 { 2407 2408 if ((newchan < 1) || (newchan > 14)) 2409 return (EINVAL); 2410 bwn_phy_g_switch_chan(mac, newchan, 0); 2411 2412 return (0); 2413 } 2414 2415 static uint32_t 2416 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2417 { 2418 2419 return (1); 2420 } 2421 2422 static void 2423 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2424 { 2425 struct bwn_phy *phy = &mac->mac_phy; 2426 uint64_t hf; 2427 int autodiv = 0; 2428 uint16_t tmp; 2429 2430 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2431 autodiv = 1; 2432 2433 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2434 bwn_hf_write(mac, hf); 2435 2436 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2437 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2438 ((autodiv ? BWN_ANTAUTO1 : antenna) 2439 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2440 2441 if (autodiv) { 2442 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2443 if (antenna == BWN_ANTAUTO1) 2444 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2445 else 2446 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2447 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2448 } 2449 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2450 if (autodiv) 2451 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2452 else 2453 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2454 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2455 if (phy->rev >= 2) { 2456 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2457 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2458 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2459 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2460 0x15); 2461 if (phy->rev == 2) 2462 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2463 else 2464 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2465 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2466 8); 2467 } 2468 if (phy->rev >= 6) 2469 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2470 2471 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2472 bwn_hf_write(mac, hf); 2473 } 2474 2475 static int 2476 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2477 { 2478 struct bwn_phy *phy = &mac->mac_phy; 2479 struct bwn_phy_g *pg = &phy->phy_g; 2480 2481 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2482 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2483 2484 if (phy->rev == 0 || !phy->gmode) 2485 return (ENODEV); 2486 2487 pg->pg_aci_wlan_automatic = 0; 2488 return (0); 2489 } 2490 2491 static int 2492 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2493 { 2494 struct bwn_phy *phy = &mac->mac_phy; 2495 struct bwn_phy_g *pg = &phy->phy_g; 2496 struct bwn_softc *sc = mac->mac_sc; 2497 unsigned int tssi; 2498 int cck, ofdm; 2499 int power; 2500 int rfatt, bbatt; 2501 unsigned int max; 2502 2503 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2504 2505 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2506 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2507 if (cck < 0 && ofdm < 0) { 2508 if (ignore_tssi == 0) 2509 return (BWN_TXPWR_RES_DONE); 2510 cck = 0; 2511 ofdm = 0; 2512 } 2513 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2514 if (pg->pg_avgtssi != 0xff) 2515 tssi = (tssi + pg->pg_avgtssi) / 2; 2516 pg->pg_avgtssi = tssi; 2517 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2518 2519 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2520 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2521 max -= 3; 2522 if (max >= 120) { 2523 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2524 max = 80; 2525 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2526 } 2527 2528 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2529 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2530 tssi, 0x00), 0x3f)]); 2531 if (power == 0) 2532 return (BWN_TXPWR_RES_DONE); 2533 2534 rfatt = -((power + 7) / 8); 2535 bbatt = (-(power / 2)) - (4 * rfatt); 2536 if ((rfatt == 0) && (bbatt == 0)) 2537 return (BWN_TXPWR_RES_DONE); 2538 pg->pg_bbatt_delta = bbatt; 2539 pg->pg_rfatt_delta = rfatt; 2540 return (BWN_TXPWR_RES_NEED_ADJUST); 2541 } 2542 2543 static void 2544 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2545 { 2546 struct bwn_phy *phy = &mac->mac_phy; 2547 struct bwn_phy_g *pg = &phy->phy_g; 2548 struct bwn_softc *sc = mac->mac_sc; 2549 int rfatt, bbatt; 2550 uint8_t txctl; 2551 2552 bwn_mac_suspend(mac); 2553 2554 bbatt = pg->pg_bbatt.att; 2555 bbatt += pg->pg_bbatt_delta; 2556 rfatt = pg->pg_rfatt.att; 2557 rfatt += pg->pg_rfatt_delta; 2558 2559 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2560 txctl = pg->pg_txctl; 2561 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2562 if (rfatt <= 1) { 2563 if (txctl == 0) { 2564 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2565 rfatt += 2; 2566 bbatt += 2; 2567 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2568 BWN_BFL_PACTRL) { 2569 bbatt += 4 * (rfatt - 2); 2570 rfatt = 2; 2571 } 2572 } else if (rfatt > 4 && txctl) { 2573 txctl = 0; 2574 if (bbatt < 3) { 2575 rfatt -= 3; 2576 bbatt += 2; 2577 } else { 2578 rfatt -= 2; 2579 bbatt -= 2; 2580 } 2581 } 2582 } 2583 pg->pg_txctl = txctl; 2584 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2585 pg->pg_rfatt.att = rfatt; 2586 pg->pg_bbatt.att = bbatt; 2587 2588 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2589 2590 bwn_phy_lock(mac); 2591 bwn_rf_lock(mac); 2592 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2593 pg->pg_txctl); 2594 bwn_rf_unlock(mac); 2595 bwn_phy_unlock(mac); 2596 2597 bwn_mac_enable(mac); 2598 } 2599 2600 static void 2601 bwn_phy_g_task_15s(struct bwn_mac *mac) 2602 { 2603 struct bwn_phy *phy = &mac->mac_phy; 2604 struct bwn_phy_g *pg = &phy->phy_g; 2605 struct bwn_softc *sc = mac->mac_sc; 2606 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2607 unsigned long expire, now; 2608 struct bwn_lo_calib *cal, *tmp; 2609 uint8_t expired = 0; 2610 2611 bwn_mac_suspend(mac); 2612 2613 if (lo == NULL) 2614 goto fail; 2615 2616 BWN_GETTIME(now); 2617 if (bwn_has_hwpctl(mac)) { 2618 expire = now - BWN_LO_PWRVEC_EXPIRE; 2619 if (time_before(lo->pwr_vec_read_time, expire)) { 2620 bwn_lo_get_powervector(mac); 2621 bwn_phy_g_dc_lookup_init(mac, 0); 2622 } 2623 goto fail; 2624 } 2625 2626 expire = now - BWN_LO_CALIB_EXPIRE; 2627 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2628 if (!time_before(cal->calib_time, expire)) 2629 continue; 2630 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2631 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2632 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2633 expired = 1; 2634 } 2635 2636 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2637 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2638 cal->ctl.i, cal->ctl.q); 2639 2640 TAILQ_REMOVE(&lo->calib_list, cal, list); 2641 kfree(cal, M_DEVBUF); 2642 } 2643 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2644 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2645 &pg->pg_rfatt); 2646 if (cal == NULL) { /* XXX ivadasz: can't happen */ 2647 device_printf(sc->sc_dev, 2648 "failed to recalibrate LO\n"); 2649 goto fail; 2650 } 2651 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2652 bwn_lo_write(mac, &cal->ctl); 2653 } 2654 2655 fail: 2656 bwn_mac_enable(mac); 2657 } 2658 2659 static void 2660 bwn_phy_g_task_60s(struct bwn_mac *mac) 2661 { 2662 struct bwn_phy *phy = &mac->mac_phy; 2663 struct bwn_softc *sc = mac->mac_sc; 2664 uint8_t old = phy->chan; 2665 2666 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2667 return; 2668 2669 bwn_mac_suspend(mac); 2670 bwn_nrssi_slope_11g(mac); 2671 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2672 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2673 bwn_switch_channel(mac, old); 2674 } 2675 bwn_mac_enable(mac); 2676 } 2677 2678 static void 2679 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2680 { 2681 2682 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2683 } 2684 2685 static int 2686 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2687 const struct ieee80211_bpf_params *params) 2688 { 2689 struct ieee80211com *ic = ni->ni_ic; 2690 struct ifnet *ifp = ic->ic_ifp; 2691 struct bwn_softc *sc = ifp->if_softc; 2692 struct bwn_mac *mac = sc->sc_curmac; 2693 2694 if ((ifp->if_flags & IFF_RUNNING) == 0 || 2695 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2696 ieee80211_free_node(ni); 2697 m_freem(m); 2698 return (ENETDOWN); 2699 } 2700 2701 if (bwn_tx_isfull(sc, m)) { 2702 ieee80211_free_node(ni); 2703 m_freem(m); 2704 ifp->if_oerrors++; 2705 return (ENOBUFS); 2706 } 2707 2708 if (bwn_tx_start(sc, ni, m) != 0) { 2709 if (ni != NULL) 2710 ieee80211_free_node(ni); 2711 ifp->if_oerrors++; 2712 } 2713 sc->sc_watchdog_timer = 5; 2714 return (0); 2715 } 2716 2717 /* 2718 * Callback from the 802.11 layer to update the slot time 2719 * based on the current setting. We use it to notify the 2720 * firmware of ERP changes and the f/w takes care of things 2721 * like slot time and preamble. 2722 */ 2723 static void 2724 bwn_updateslot(struct ifnet *ifp) 2725 { 2726 struct bwn_softc *sc = ifp->if_softc; 2727 struct ieee80211com *ic = ifp->if_l2com; 2728 struct bwn_mac *mac; 2729 2730 if (ifp->if_flags & IFF_RUNNING) { 2731 mac = (struct bwn_mac *)sc->sc_curmac; 2732 bwn_set_slot_time(mac, 2733 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2734 } 2735 } 2736 2737 /* 2738 * Callback from the 802.11 layer after a promiscuous mode change. 2739 * Note this interface does not check the operating mode as this 2740 * is an internal callback and we are expected to honor the current 2741 * state (e.g. this is used for setting the interface in promiscuous 2742 * mode when operating in hostap mode to do ACS). 2743 */ 2744 static void 2745 bwn_update_promisc(struct ifnet *ifp) 2746 { 2747 struct bwn_softc *sc = ifp->if_softc; 2748 struct bwn_mac *mac = sc->sc_curmac; 2749 2750 mac = sc->sc_curmac; 2751 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2752 if (ifp->if_flags & IFF_PROMISC) 2753 sc->sc_filters |= BWN_MACCTL_PROMISC; 2754 else 2755 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2756 bwn_set_opmode(mac); 2757 } 2758 } 2759 2760 /* 2761 * Callback from the 802.11 layer to update WME parameters. 2762 */ 2763 static int 2764 bwn_wme_update(struct ieee80211com *ic) 2765 { 2766 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2767 struct bwn_mac *mac = sc->sc_curmac; 2768 struct wmeParams *wmep; 2769 int i; 2770 2771 mac = sc->sc_curmac; 2772 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2773 bwn_mac_suspend(mac); 2774 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2775 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2776 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2777 } 2778 bwn_mac_enable(mac); 2779 } 2780 return (0); 2781 } 2782 2783 static void 2784 bwn_scan_start(struct ieee80211com *ic) 2785 { 2786 struct ifnet *ifp = ic->ic_ifp; 2787 struct bwn_softc *sc = ifp->if_softc; 2788 struct bwn_mac *mac; 2789 2790 mac = sc->sc_curmac; 2791 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2792 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2793 bwn_set_opmode(mac); 2794 /* disable CFP update during scan */ 2795 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2796 } 2797 } 2798 2799 static void 2800 bwn_scan_end(struct ieee80211com *ic) 2801 { 2802 struct ifnet *ifp = ic->ic_ifp; 2803 struct bwn_softc *sc = ifp->if_softc; 2804 struct bwn_mac *mac; 2805 2806 mac = sc->sc_curmac; 2807 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2808 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2809 bwn_set_opmode(mac); 2810 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2811 } 2812 } 2813 2814 static void 2815 bwn_set_channel(struct ieee80211com *ic) 2816 { 2817 struct ifnet *ifp = ic->ic_ifp; 2818 struct bwn_softc *sc = ifp->if_softc; 2819 struct bwn_mac *mac = sc->sc_curmac; 2820 struct bwn_phy *phy = &mac->mac_phy; 2821 int chan, error; 2822 2823 error = bwn_switch_band(sc, ic->ic_curchan); 2824 if (error) 2825 goto fail; 2826 bwn_mac_suspend(mac); 2827 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2828 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2829 if (chan != phy->chan) 2830 bwn_switch_channel(mac, chan); 2831 2832 /* TX power level */ 2833 if (ic->ic_curchan->ic_maxpower != 0 && 2834 ic->ic_curchan->ic_maxpower != phy->txpower) { 2835 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2836 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2837 BWN_TXPWR_IGNORE_TSSI); 2838 } 2839 2840 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2841 if (phy->set_antenna) 2842 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2843 2844 if (sc->sc_rf_enabled != phy->rf_on) { 2845 if (sc->sc_rf_enabled) { 2846 bwn_rf_turnon(mac); 2847 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2848 device_printf(sc->sc_dev, 2849 "please turn on the RF switch\n"); 2850 } else 2851 bwn_rf_turnoff(mac); 2852 } 2853 2854 bwn_mac_enable(mac); 2855 2856 fail: 2857 /* 2858 * Setup radio tap channel freq and flags 2859 */ 2860 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2861 htole16(ic->ic_curchan->ic_freq); 2862 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2863 htole16(ic->ic_curchan->ic_flags & 0xffff); 2864 } 2865 2866 static struct ieee80211vap * 2867 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2868 enum ieee80211_opmode opmode, int flags, 2869 const uint8_t bssid[IEEE80211_ADDR_LEN], 2870 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2871 { 2872 struct ifnet *ifp = ic->ic_ifp; 2873 struct bwn_softc *sc = ifp->if_softc; 2874 struct ieee80211vap *vap; 2875 struct bwn_vap *bvp; 2876 uint8_t mac[IEEE80211_ADDR_LEN]; 2877 2878 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 2879 return NULL; 2880 2881 IEEE80211_ADDR_COPY(mac, mac0); 2882 switch (opmode) { 2883 case IEEE80211_M_HOSTAP: 2884 case IEEE80211_M_MBSS: 2885 case IEEE80211_M_STA: 2886 case IEEE80211_M_WDS: 2887 case IEEE80211_M_MONITOR: 2888 case IEEE80211_M_IBSS: 2889 case IEEE80211_M_AHDEMO: 2890 break; 2891 default: 2892 return (NULL); 2893 } 2894 2895 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2896 2897 bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap), 2898 M_80211_VAP, M_INTWAIT | M_ZERO); 2899 vap = &bvp->bv_vap; 2900 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2901 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2902 /* override with driver methods */ 2903 bvp->bv_newstate = vap->iv_newstate; 2904 vap->iv_newstate = bwn_newstate; 2905 2906 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2907 vap->iv_max_aid = BWN_STAID_MAX; 2908 2909 ieee80211_ratectl_init(vap); 2910 2911 /* complete setup */ 2912 ieee80211_vap_attach(vap, ieee80211_media_change, 2913 ieee80211_media_status); 2914 ic->ic_opmode = opmode; 2915 return (vap); 2916 } 2917 2918 static void 2919 bwn_vap_delete(struct ieee80211vap *vap) 2920 { 2921 struct bwn_vap *bvp = BWN_VAP(vap); 2922 2923 ieee80211_ratectl_deinit(vap); 2924 ieee80211_vap_detach(vap); 2925 kfree(bvp, M_80211_VAP); 2926 } 2927 2928 static void 2929 bwn_init(void *arg) 2930 { 2931 struct bwn_softc *sc = arg; 2932 struct ifnet *ifp = sc->sc_ifp; 2933 struct ieee80211com *ic = ifp->if_l2com; 2934 int error = 0; 2935 2936 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 2937 __func__, ifp->if_flags); 2938 2939 wlan_assert_serialized(); 2940 error = bwn_init_locked(sc); 2941 2942 if (error == 0) 2943 ieee80211_start_all(ic); /* start all vap's */ 2944 } 2945 2946 static int 2947 bwn_init_locked(struct bwn_softc *sc) 2948 { 2949 struct bwn_mac *mac; 2950 struct ifnet *ifp = sc->sc_ifp; 2951 int error; 2952 2953 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2954 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2955 sc->sc_filters = 0; 2956 bwn_wme_clear(sc); 2957 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2958 sc->sc_rf_enabled = 1; 2959 2960 mac = sc->sc_curmac; 2961 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2962 error = bwn_core_init(mac); 2963 if (error != 0) 2964 return (error); 2965 } 2966 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2967 bwn_core_start(mac); 2968 2969 bwn_set_opmode(mac); 2970 bwn_set_pretbtt(mac); 2971 bwn_spu_setdelay(mac, 0); 2972 bwn_set_macaddr(mac); 2973 2974 ifp->if_flags |= IFF_RUNNING; 2975 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2976 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2977 2978 return (0); 2979 } 2980 2981 static void 2982 bwn_stop(struct bwn_softc *sc, int statechg) 2983 { 2984 2985 wlan_assert_serialized(); 2986 bwn_stop_locked(sc, statechg); 2987 } 2988 2989 static void 2990 bwn_stop_locked(struct bwn_softc *sc, int statechg) 2991 { 2992 struct bwn_mac *mac = sc->sc_curmac; 2993 struct ifnet *ifp = sc->sc_ifp; 2994 2995 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2996 /* XXX FIXME opmode not based on VAP */ 2997 bwn_set_opmode(mac); 2998 bwn_set_macaddr(mac); 2999 } 3000 3001 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3002 bwn_core_stop(mac); 3003 3004 callout_stop(&sc->sc_led_blink_ch); 3005 sc->sc_led_blinking = 0; 3006 3007 bwn_core_exit(mac); 3008 sc->sc_rf_enabled = 0; 3009 3010 ifp->if_flags &= ~IFF_RUNNING; 3011 ifq_clr_oactive(&ifp->if_snd); 3012 } 3013 3014 static void 3015 bwn_wme_clear(struct bwn_softc *sc) 3016 { 3017 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3018 struct wmeParams *p; 3019 unsigned int i; 3020 3021 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3022 ("%s:%d: fail", __func__, __LINE__)); 3023 3024 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3025 p = &(sc->sc_wmeParams[i]); 3026 3027 switch (bwn_wme_shm_offsets[i]) { 3028 case BWN_WME_VOICE: 3029 p->wmep_txopLimit = 0; 3030 p->wmep_aifsn = 2; 3031 /* XXX FIXME: log2(cwmin) */ 3032 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3033 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3034 break; 3035 case BWN_WME_VIDEO: 3036 p->wmep_txopLimit = 0; 3037 p->wmep_aifsn = 2; 3038 /* XXX FIXME: log2(cwmin) */ 3039 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3040 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3041 break; 3042 case BWN_WME_BESTEFFORT: 3043 p->wmep_txopLimit = 0; 3044 p->wmep_aifsn = 3; 3045 /* XXX FIXME: log2(cwmin) */ 3046 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3047 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3048 break; 3049 case BWN_WME_BACKGROUND: 3050 p->wmep_txopLimit = 0; 3051 p->wmep_aifsn = 7; 3052 /* XXX FIXME: log2(cwmin) */ 3053 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3054 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3055 break; 3056 default: 3057 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3058 } 3059 } 3060 } 3061 3062 static int 3063 bwn_core_init(struct bwn_mac *mac) 3064 { 3065 struct bwn_softc *sc = mac->mac_sc; 3066 uint64_t hf; 3067 int error; 3068 3069 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3070 ("%s:%d: fail", __func__, __LINE__)); 3071 3072 siba_powerup(sc->sc_dev, 0); 3073 if (!siba_dev_isup(sc->sc_dev)) 3074 bwn_reset_core(mac, 3075 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3076 3077 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3078 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3079 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3080 BWN_GETTIME(mac->mac_phy.nexttime); 3081 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3082 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3083 mac->mac_stats.link_noise = -95; 3084 mac->mac_reason_intr = 0; 3085 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3086 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3087 #ifdef BWN_DEBUG 3088 if (sc->sc_debug & BWN_DEBUG_XMIT) 3089 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3090 #endif 3091 mac->mac_suspended = 1; 3092 mac->mac_task_state = 0; 3093 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3094 3095 mac->mac_phy.init_pre(mac); 3096 3097 siba_pcicore_intr(sc->sc_dev); 3098 3099 siba_fix_imcfglobug(sc->sc_dev); 3100 bwn_bt_disable(mac); 3101 if (mac->mac_phy.prepare_hw) { 3102 error = mac->mac_phy.prepare_hw(mac); 3103 if (error) 3104 goto fail0; 3105 } 3106 error = bwn_chip_init(mac); 3107 if (error) 3108 goto fail0; 3109 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3110 siba_get_revid(sc->sc_dev)); 3111 hf = bwn_hf_read(mac); 3112 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3113 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3114 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3115 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3116 if (mac->mac_phy.rev == 1) 3117 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3118 } 3119 if (mac->mac_phy.rf_ver == 0x2050) { 3120 if (mac->mac_phy.rf_rev < 6) 3121 hf |= BWN_HF_FORCE_VCO_RECALC; 3122 if (mac->mac_phy.rf_rev == 6) 3123 hf |= BWN_HF_4318_TSSI; 3124 } 3125 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3126 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3127 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3128 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3129 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3130 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3131 bwn_hf_write(mac, hf); 3132 3133 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3134 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3135 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3136 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3137 3138 bwn_rate_init(mac); 3139 bwn_set_phytxctl(mac); 3140 3141 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3142 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3143 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3144 3145 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3146 bwn_pio_init(mac); 3147 else 3148 bwn_dma_init(mac); 3149 bwn_wme_init(mac); 3150 bwn_spu_setdelay(mac, 1); 3151 bwn_bt_enable(mac); 3152 3153 siba_powerup(sc->sc_dev, 3154 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3155 bwn_set_macaddr(mac); 3156 bwn_crypt_init(mac); 3157 3158 /* XXX LED initializatin */ 3159 3160 mac->mac_status = BWN_MAC_STATUS_INITED; 3161 3162 return (error); 3163 3164 fail0: 3165 siba_powerdown(sc->sc_dev); 3166 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3167 ("%s:%d: fail", __func__, __LINE__)); 3168 return (error); 3169 } 3170 3171 static void 3172 bwn_core_start(struct bwn_mac *mac) 3173 { 3174 struct bwn_softc *sc = mac->mac_sc; 3175 uint32_t tmp; 3176 3177 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3178 ("%s:%d: fail", __func__, __LINE__)); 3179 3180 if (siba_get_revid(sc->sc_dev) < 5) 3181 return; 3182 3183 while (1) { 3184 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3185 if (!(tmp & 0x00000001)) 3186 break; 3187 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3188 } 3189 3190 bwn_mac_enable(mac); 3191 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3192 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3193 3194 mac->mac_status = BWN_MAC_STATUS_STARTED; 3195 } 3196 3197 static void 3198 bwn_core_exit(struct bwn_mac *mac) 3199 { 3200 struct bwn_softc *sc = mac->mac_sc; 3201 uint32_t macctl; 3202 3203 wlan_assert_serialized(); 3204 3205 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3206 ("%s:%d: fail", __func__, __LINE__)); 3207 3208 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3209 return; 3210 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3211 3212 macctl = BWN_READ_4(mac, BWN_MACCTL); 3213 macctl &= ~BWN_MACCTL_MCODE_RUN; 3214 macctl |= BWN_MACCTL_MCODE_JMP0; 3215 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3216 3217 bwn_dma_stop(mac); 3218 bwn_pio_stop(mac); 3219 bwn_chip_exit(mac); 3220 mac->mac_phy.switch_analog(mac, 0); 3221 siba_dev_down(sc->sc_dev, 0); 3222 siba_powerdown(sc->sc_dev); 3223 } 3224 3225 static void 3226 bwn_bt_disable(struct bwn_mac *mac) 3227 { 3228 struct bwn_softc *sc = mac->mac_sc; 3229 3230 (void)sc; 3231 /* XXX do nothing yet */ 3232 } 3233 3234 static int 3235 bwn_chip_init(struct bwn_mac *mac) 3236 { 3237 struct bwn_softc *sc = mac->mac_sc; 3238 struct bwn_phy *phy = &mac->mac_phy; 3239 uint32_t macctl; 3240 int error; 3241 3242 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3243 if (phy->gmode) 3244 macctl |= BWN_MACCTL_GMODE; 3245 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3246 3247 error = bwn_fw_fillinfo(mac); 3248 if (error) 3249 return (error); 3250 error = bwn_fw_loaducode(mac); 3251 if (error) 3252 return (error); 3253 3254 error = bwn_gpio_init(mac); 3255 if (error) 3256 return (error); 3257 3258 error = bwn_fw_loadinitvals(mac); 3259 if (error) { 3260 siba_gpio_set(sc->sc_dev, 0); 3261 return (error); 3262 } 3263 phy->switch_analog(mac, 1); 3264 error = bwn_phy_init(mac); 3265 if (error) { 3266 siba_gpio_set(sc->sc_dev, 0); 3267 return (error); 3268 } 3269 if (phy->set_im) 3270 phy->set_im(mac, BWN_IMMODE_NONE); 3271 if (phy->set_antenna) 3272 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3273 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3274 3275 if (phy->type == BWN_PHYTYPE_B) 3276 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3277 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3278 if (siba_get_revid(sc->sc_dev) < 5) 3279 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3280 3281 BWN_WRITE_4(mac, BWN_MACCTL, 3282 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3283 BWN_WRITE_4(mac, BWN_MACCTL, 3284 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3285 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3286 3287 bwn_set_opmode(mac); 3288 if (siba_get_revid(sc->sc_dev) < 3) { 3289 BWN_WRITE_2(mac, 0x060e, 0x0000); 3290 BWN_WRITE_2(mac, 0x0610, 0x8000); 3291 BWN_WRITE_2(mac, 0x0604, 0x0000); 3292 BWN_WRITE_2(mac, 0x0606, 0x0200); 3293 } else { 3294 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3295 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3296 } 3297 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3298 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00); 3299 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3300 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3301 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3302 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3303 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3304 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3305 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3306 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3307 return (error); 3308 } 3309 3310 /* read hostflags */ 3311 static uint64_t 3312 bwn_hf_read(struct bwn_mac *mac) 3313 { 3314 uint64_t ret; 3315 3316 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3317 ret <<= 16; 3318 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3319 ret <<= 16; 3320 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3321 return (ret); 3322 } 3323 3324 static void 3325 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3326 { 3327 3328 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3329 (value & 0x00000000ffffull)); 3330 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3331 (value & 0x0000ffff0000ull) >> 16); 3332 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3333 (value & 0xffff00000000ULL) >> 32); 3334 } 3335 3336 static void 3337 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3338 { 3339 3340 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3341 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3342 } 3343 3344 static void 3345 bwn_rate_init(struct bwn_mac *mac) 3346 { 3347 3348 switch (mac->mac_phy.type) { 3349 case BWN_PHYTYPE_A: 3350 case BWN_PHYTYPE_G: 3351 case BWN_PHYTYPE_LP: 3352 case BWN_PHYTYPE_N: 3353 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3354 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3355 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3356 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3357 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3358 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3359 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3360 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3361 break; 3362 /* FALLTHROUGH */ 3363 case BWN_PHYTYPE_B: 3364 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3365 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3366 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3367 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3368 break; 3369 default: 3370 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3371 } 3372 } 3373 3374 static void 3375 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3376 { 3377 uint16_t offset; 3378 3379 if (ofdm) { 3380 offset = 0x480; 3381 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3382 } else { 3383 offset = 0x4c0; 3384 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3385 } 3386 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3387 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3388 } 3389 3390 static uint8_t 3391 bwn_plcp_getcck(const uint8_t bitrate) 3392 { 3393 3394 switch (bitrate) { 3395 case BWN_CCK_RATE_1MB: 3396 return (0x0a); 3397 case BWN_CCK_RATE_2MB: 3398 return (0x14); 3399 case BWN_CCK_RATE_5MB: 3400 return (0x37); 3401 case BWN_CCK_RATE_11MB: 3402 return (0x6e); 3403 } 3404 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3405 return (0); 3406 } 3407 3408 static uint8_t 3409 bwn_plcp_getofdm(const uint8_t bitrate) 3410 { 3411 3412 switch (bitrate) { 3413 case BWN_OFDM_RATE_6MB: 3414 return (0xb); 3415 case BWN_OFDM_RATE_9MB: 3416 return (0xf); 3417 case BWN_OFDM_RATE_12MB: 3418 return (0xa); 3419 case BWN_OFDM_RATE_18MB: 3420 return (0xe); 3421 case BWN_OFDM_RATE_24MB: 3422 return (0x9); 3423 case BWN_OFDM_RATE_36MB: 3424 return (0xd); 3425 case BWN_OFDM_RATE_48MB: 3426 return (0x8); 3427 case BWN_OFDM_RATE_54MB: 3428 return (0xc); 3429 } 3430 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3431 return (0); 3432 } 3433 3434 static void 3435 bwn_set_phytxctl(struct bwn_mac *mac) 3436 { 3437 uint16_t ctl; 3438 3439 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3440 BWN_TX_PHY_TXPWR); 3441 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3442 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3443 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3444 } 3445 3446 static void 3447 bwn_pio_init(struct bwn_mac *mac) 3448 { 3449 struct bwn_pio *pio = &mac->mac_method.pio; 3450 3451 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3452 & ~BWN_MACCTL_BIGENDIAN); 3453 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3454 3455 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3456 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3457 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3458 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3459 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3460 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3461 } 3462 3463 static void 3464 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3465 int index) 3466 { 3467 struct bwn_pio_txpkt *tp; 3468 struct bwn_softc *sc = mac->mac_sc; 3469 unsigned int i; 3470 3471 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3472 tq->tq_index = index; 3473 3474 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3475 if (siba_get_revid(sc->sc_dev) >= 8) 3476 tq->tq_size = 1920; 3477 else { 3478 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3479 tq->tq_size -= 80; 3480 } 3481 3482 TAILQ_INIT(&tq->tq_pktlist); 3483 for (i = 0; i < N(tq->tq_pkts); i++) { 3484 tp = &(tq->tq_pkts[i]); 3485 tp->tp_index = i; 3486 tp->tp_queue = tq; 3487 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3488 } 3489 } 3490 3491 static uint16_t 3492 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3493 { 3494 struct bwn_softc *sc = mac->mac_sc; 3495 static const uint16_t bases[] = { 3496 BWN_PIO_BASE0, 3497 BWN_PIO_BASE1, 3498 BWN_PIO_BASE2, 3499 BWN_PIO_BASE3, 3500 BWN_PIO_BASE4, 3501 BWN_PIO_BASE5, 3502 BWN_PIO_BASE6, 3503 BWN_PIO_BASE7, 3504 }; 3505 static const uint16_t bases_rev11[] = { 3506 BWN_PIO11_BASE0, 3507 BWN_PIO11_BASE1, 3508 BWN_PIO11_BASE2, 3509 BWN_PIO11_BASE3, 3510 BWN_PIO11_BASE4, 3511 BWN_PIO11_BASE5, 3512 }; 3513 3514 if (siba_get_revid(sc->sc_dev) >= 11) { 3515 if (index >= N(bases_rev11)) 3516 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3517 return (bases_rev11[index]); 3518 } 3519 if (index >= N(bases)) 3520 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3521 return (bases[index]); 3522 } 3523 3524 static void 3525 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3526 int index) 3527 { 3528 struct bwn_softc *sc = mac->mac_sc; 3529 3530 prq->prq_mac = mac; 3531 prq->prq_rev = siba_get_revid(sc->sc_dev); 3532 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3533 bwn_dma_rxdirectfifo(mac, index, 1); 3534 } 3535 3536 static void 3537 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3538 { 3539 if (tq == NULL) 3540 return; 3541 bwn_pio_cancel_tx_packets(tq); 3542 } 3543 3544 static void 3545 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3546 { 3547 3548 bwn_destroy_pioqueue_tx(pio); 3549 } 3550 3551 static uint16_t 3552 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3553 uint16_t offset) 3554 { 3555 3556 return (BWN_READ_2(mac, tq->tq_base + offset)); 3557 } 3558 3559 static void 3560 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3561 { 3562 uint32_t ctl; 3563 int type; 3564 uint16_t base; 3565 3566 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3567 base = bwn_dma_base(type, idx); 3568 if (type == BWN_DMA_64BIT) { 3569 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3570 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3571 if (enable) 3572 ctl |= BWN_DMA64_RXDIRECTFIFO; 3573 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3574 } else { 3575 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3576 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3577 if (enable) 3578 ctl |= BWN_DMA32_RXDIRECTFIFO; 3579 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3580 } 3581 } 3582 3583 static uint64_t 3584 bwn_dma_mask(struct bwn_mac *mac) 3585 { 3586 uint32_t tmp; 3587 uint16_t base; 3588 3589 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3590 if (tmp & SIBA_TGSHIGH_DMA64) 3591 return (BWN_DMA_BIT_MASK(64)); 3592 base = bwn_dma_base(0, 0); 3593 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3594 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3595 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3596 return (BWN_DMA_BIT_MASK(32)); 3597 3598 return (BWN_DMA_BIT_MASK(30)); 3599 } 3600 3601 static int 3602 bwn_dma_mask2type(uint64_t dmamask) 3603 { 3604 3605 if (dmamask == BWN_DMA_BIT_MASK(30)) 3606 return (BWN_DMA_30BIT); 3607 if (dmamask == BWN_DMA_BIT_MASK(32)) 3608 return (BWN_DMA_32BIT); 3609 if (dmamask == BWN_DMA_BIT_MASK(64)) 3610 return (BWN_DMA_64BIT); 3611 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3612 return (BWN_DMA_30BIT); 3613 } 3614 3615 static void 3616 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3617 { 3618 struct bwn_pio_txpkt *tp; 3619 unsigned int i; 3620 3621 for (i = 0; i < N(tq->tq_pkts); i++) { 3622 tp = &(tq->tq_pkts[i]); 3623 if (tp->tp_m) { 3624 m_freem(tp->tp_m); 3625 tp->tp_m = NULL; 3626 } 3627 } 3628 } 3629 3630 static uint16_t 3631 bwn_dma_base(int type, int controller_idx) 3632 { 3633 static const uint16_t map64[] = { 3634 BWN_DMA64_BASE0, 3635 BWN_DMA64_BASE1, 3636 BWN_DMA64_BASE2, 3637 BWN_DMA64_BASE3, 3638 BWN_DMA64_BASE4, 3639 BWN_DMA64_BASE5, 3640 }; 3641 static const uint16_t map32[] = { 3642 BWN_DMA32_BASE0, 3643 BWN_DMA32_BASE1, 3644 BWN_DMA32_BASE2, 3645 BWN_DMA32_BASE3, 3646 BWN_DMA32_BASE4, 3647 BWN_DMA32_BASE5, 3648 }; 3649 3650 if (type == BWN_DMA_64BIT) { 3651 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3652 ("%s:%d: fail", __func__, __LINE__)); 3653 return (map64[controller_idx]); 3654 } 3655 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3656 ("%s:%d: fail", __func__, __LINE__)); 3657 return (map32[controller_idx]); 3658 } 3659 3660 static void 3661 bwn_dma_init(struct bwn_mac *mac) 3662 { 3663 struct bwn_dma *dma = &mac->mac_method.dma; 3664 3665 /* setup TX DMA channels. */ 3666 bwn_dma_setup(dma->wme[WME_AC_BK]); 3667 bwn_dma_setup(dma->wme[WME_AC_BE]); 3668 bwn_dma_setup(dma->wme[WME_AC_VI]); 3669 bwn_dma_setup(dma->wme[WME_AC_VO]); 3670 bwn_dma_setup(dma->mcast); 3671 /* setup RX DMA channel. */ 3672 bwn_dma_setup(dma->rx); 3673 } 3674 3675 static struct bwn_dma_ring * 3676 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3677 int for_tx, int type) 3678 { 3679 struct bwn_dma *dma = &mac->mac_method.dma; 3680 struct bwn_dma_ring *dr; 3681 struct bwn_dmadesc_generic *desc; 3682 struct bwn_dmadesc_meta *mt; 3683 struct bwn_softc *sc = mac->mac_sc; 3684 int error, i; 3685 3686 dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO); 3687 dr->dr_numslots = BWN_RXRING_SLOTS; 3688 if (for_tx) 3689 dr->dr_numslots = BWN_TXRING_SLOTS; 3690 3691 dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3692 M_DEVBUF, M_INTWAIT | M_ZERO); 3693 3694 dr->dr_type = type; 3695 dr->dr_mac = mac; 3696 dr->dr_base = bwn_dma_base(type, controller_index); 3697 dr->dr_index = controller_index; 3698 if (type == BWN_DMA_64BIT) { 3699 dr->getdesc = bwn_dma_64_getdesc; 3700 dr->setdesc = bwn_dma_64_setdesc; 3701 dr->start_transfer = bwn_dma_64_start_transfer; 3702 dr->suspend = bwn_dma_64_suspend; 3703 dr->resume = bwn_dma_64_resume; 3704 dr->get_curslot = bwn_dma_64_get_curslot; 3705 dr->set_curslot = bwn_dma_64_set_curslot; 3706 } else { 3707 dr->getdesc = bwn_dma_32_getdesc; 3708 dr->setdesc = bwn_dma_32_setdesc; 3709 dr->start_transfer = bwn_dma_32_start_transfer; 3710 dr->suspend = bwn_dma_32_suspend; 3711 dr->resume = bwn_dma_32_resume; 3712 dr->get_curslot = bwn_dma_32_get_curslot; 3713 dr->set_curslot = bwn_dma_32_set_curslot; 3714 } 3715 if (for_tx) { 3716 dr->dr_tx = 1; 3717 dr->dr_curslot = -1; 3718 } else { 3719 if (dr->dr_index == 0) { 3720 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3721 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3722 } else 3723 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3724 } 3725 3726 error = bwn_dma_allocringmemory(dr); 3727 if (error) 3728 goto fail1; 3729 3730 if (for_tx) { 3731 /* 3732 * Assumption: BWN_TXRING_SLOTS can be divided by 3733 * BWN_TX_SLOTS_PER_FRAME 3734 */ 3735 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3736 ("%s:%d: fail", __func__, __LINE__)); 3737 3738 /* 3739 * Create TX ring DMA stuffs 3740 */ 3741 dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag, 3742 4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3743 BWN_MAX_HDRSIZE(mac), 3744 BUS_DMA_WAITOK | BUS_DMA_ZERO, 3745 &dr->dr_txring_dtag, &dr->dr_txring_dmap, 3746 &dr->dr_txring_paddr); 3747 if (dr->dr_txhdr_cache == NULL) { 3748 device_printf(sc->sc_dev, 3749 "can't create TX ring DMA memory\n"); 3750 goto fail1; 3751 } 3752 3753 for (i = 0; i < dr->dr_numslots; i += 2) { 3754 dr->getdesc(dr, i, &desc, &mt); 3755 3756 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3757 mt->mt_m = NULL; 3758 mt->mt_ni = NULL; 3759 mt->mt_islast = 0; 3760 mt->mt_dmap = dr->dr_txring_dmap; 3761 mt->mt_paddr = dr->dr_txring_paddr + 3762 (i / BWN_TX_SLOTS_PER_FRAME) * 3763 BWN_MAX_HDRSIZE(mac); 3764 3765 dr->getdesc(dr, i + 1, &desc, &mt); 3766 3767 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3768 mt->mt_m = NULL; 3769 mt->mt_ni = NULL; 3770 mt->mt_islast = 1; 3771 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3772 &mt->mt_dmap); 3773 if (error) { 3774 device_printf(sc->sc_dev, 3775 "can't create RX buf DMA map\n"); 3776 goto fail2; 3777 } 3778 } 3779 } else { 3780 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3781 &dr->dr_spare_dmap); 3782 if (error) { 3783 device_printf(sc->sc_dev, 3784 "can't create RX buf DMA map\n"); 3785 goto out; /* XXX wrong! */ 3786 } 3787 3788 for (i = 0; i < dr->dr_numslots; i++) { 3789 dr->getdesc(dr, i, &desc, &mt); 3790 3791 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3792 &mt->mt_dmap); 3793 if (error) { 3794 device_printf(sc->sc_dev, 3795 "can't create RX buf DMA map\n"); 3796 goto out; /* XXX wrong! */ 3797 } 3798 error = bwn_dma_newbuf(dr, desc, mt, 1); 3799 if (error) { 3800 device_printf(sc->sc_dev, 3801 "failed to allocate RX buf\n"); 3802 goto out; /* XXX wrong! */ 3803 } 3804 } 3805 3806 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3807 BUS_DMASYNC_PREWRITE); 3808 3809 dr->dr_usedslot = dr->dr_numslots; 3810 } 3811 3812 out: 3813 return (dr); 3814 3815 fail2: 3816 /* XXX free up dma allocations */ 3817 fail1: 3818 kfree(dr->dr_meta, M_DEVBUF); 3819 kfree(dr, M_DEVBUF); 3820 return (NULL); 3821 } 3822 3823 static void 3824 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3825 { 3826 3827 if (dr == NULL) 3828 return; 3829 3830 bwn_dma_free_descbufs(*dr); 3831 bwn_dma_free_ringmemory(*dr); 3832 3833 if ((*dr)->dr_meta != NULL) 3834 kfree((*dr)->dr_meta, M_DEVBUF); 3835 kfree(*dr, M_DEVBUF); 3836 3837 *dr = NULL; 3838 } 3839 3840 static void 3841 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3842 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3843 { 3844 struct bwn_dmadesc32 *desc; 3845 3846 *meta = &(dr->dr_meta[slot]); 3847 desc = dr->dr_ring_descbase; 3848 desc = &(desc[slot]); 3849 3850 *gdesc = (struct bwn_dmadesc_generic *)desc; 3851 } 3852 3853 static void 3854 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3855 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3856 int start, int end, int irq) 3857 { 3858 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3859 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3860 uint32_t addr, addrext, ctl; 3861 int slot; 3862 3863 slot = (int)(&(desc->dma.dma32) - descbase); 3864 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3865 ("%s:%d: fail", __func__, __LINE__)); 3866 3867 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3868 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3869 addr |= siba_dma_translation(sc->sc_dev); 3870 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3871 if (slot == dr->dr_numslots - 1) 3872 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3873 if (start) 3874 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3875 if (end) 3876 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3877 if (irq) 3878 ctl |= BWN_DMA32_DCTL_IRQ; 3879 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3880 & BWN_DMA32_DCTL_ADDREXT_MASK; 3881 3882 desc->dma.dma32.control = htole32(ctl); 3883 desc->dma.dma32.address = htole32(addr); 3884 } 3885 3886 static void 3887 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3888 { 3889 3890 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3891 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3892 } 3893 3894 static void 3895 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3896 { 3897 3898 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3899 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3900 } 3901 3902 static void 3903 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3904 { 3905 3906 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3907 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3908 } 3909 3910 static int 3911 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3912 { 3913 uint32_t val; 3914 3915 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3916 val &= BWN_DMA32_RXDPTR; 3917 3918 return (val / sizeof(struct bwn_dmadesc32)); 3919 } 3920 3921 static void 3922 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3923 { 3924 3925 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3926 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3927 } 3928 3929 static void 3930 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3931 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3932 { 3933 struct bwn_dmadesc64 *desc; 3934 3935 *meta = &(dr->dr_meta[slot]); 3936 desc = dr->dr_ring_descbase; 3937 desc = &(desc[slot]); 3938 3939 *gdesc = (struct bwn_dmadesc_generic *)desc; 3940 } 3941 3942 static void 3943 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3944 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3945 int start, int end, int irq) 3946 { 3947 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3948 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3949 int slot; 3950 uint32_t ctl0 = 0, ctl1 = 0; 3951 uint32_t addrlo, addrhi; 3952 uint32_t addrext; 3953 3954 slot = (int)(&(desc->dma.dma64) - descbase); 3955 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3956 ("%s:%d: fail", __func__, __LINE__)); 3957 3958 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3959 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3960 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3961 30; 3962 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3963 if (slot == dr->dr_numslots - 1) 3964 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3965 if (start) 3966 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3967 if (end) 3968 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3969 if (irq) 3970 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3971 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3972 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3973 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3974 3975 desc->dma.dma64.control0 = htole32(ctl0); 3976 desc->dma.dma64.control1 = htole32(ctl1); 3977 desc->dma.dma64.address_low = htole32(addrlo); 3978 desc->dma.dma64.address_high = htole32(addrhi); 3979 } 3980 3981 static void 3982 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3983 { 3984 3985 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3986 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3987 } 3988 3989 static void 3990 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3991 { 3992 3993 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3994 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3995 } 3996 3997 static void 3998 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3999 { 4000 4001 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4002 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4003 } 4004 4005 static int 4006 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4007 { 4008 uint32_t val; 4009 4010 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4011 val &= BWN_DMA64_RXSTATDPTR; 4012 4013 return (val / sizeof(struct bwn_dmadesc64)); 4014 } 4015 4016 static void 4017 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4018 { 4019 4020 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4021 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4022 } 4023 4024 static int 4025 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4026 { 4027 struct bwn_mac *mac = dr->dr_mac; 4028 struct bwn_dma *dma = &mac->mac_method.dma; 4029 struct bwn_softc *sc = mac->mac_sc; 4030 int error; 4031 4032 error = bus_dma_tag_create(dma->parent_dtag, 4033 BWN_ALIGN, 0, 4034 BUS_SPACE_MAXADDR, 4035 BUS_SPACE_MAXADDR, 4036 NULL, NULL, 4037 BWN_DMA_RINGMEMSIZE, 4038 1, 4039 BUS_SPACE_MAXSIZE_32BIT, 4040 0, 4041 &dr->dr_ring_dtag); 4042 if (error) { 4043 device_printf(sc->sc_dev, 4044 "can't create TX ring DMA tag: TODO frees\n"); 4045 return (-1); 4046 } 4047 4048 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4049 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4050 &dr->dr_ring_dmap); 4051 if (error) { 4052 device_printf(sc->sc_dev, 4053 "can't allocate DMA mem: TODO frees\n"); 4054 return (-1); 4055 } 4056 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4057 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4058 bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0); 4059 if (error) { 4060 device_printf(sc->sc_dev, 4061 "can't load DMA mem: TODO free\n"); 4062 return (-1); 4063 } 4064 4065 return (0); 4066 } 4067 4068 static void 4069 bwn_dma_setup(struct bwn_dma_ring *dr) 4070 { 4071 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4072 uint64_t ring64; 4073 uint32_t addrext, ring32, value; 4074 uint32_t trans = siba_dma_translation(sc->sc_dev); 4075 4076 if (dr->dr_tx) { 4077 dr->dr_curslot = -1; 4078 4079 if (dr->dr_type == BWN_DMA_64BIT) { 4080 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4081 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4082 >> 30; 4083 value = BWN_DMA64_TXENABLE; 4084 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4085 & BWN_DMA64_TXADDREXT_MASK; 4086 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4087 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4088 (ring64 & 0xffffffff)); 4089 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4090 ((ring64 >> 32) & 4091 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4092 } else { 4093 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4094 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4095 value = BWN_DMA32_TXENABLE; 4096 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4097 & BWN_DMA32_TXADDREXT_MASK; 4098 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4099 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4100 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4101 } 4102 return; 4103 } 4104 4105 /* 4106 * set for RX 4107 */ 4108 dr->dr_usedslot = dr->dr_numslots; 4109 4110 if (dr->dr_type == BWN_DMA_64BIT) { 4111 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4112 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4113 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4114 value |= BWN_DMA64_RXENABLE; 4115 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4116 & BWN_DMA64_RXADDREXT_MASK; 4117 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4118 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4119 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4120 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4121 | (trans << 1)); 4122 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4123 sizeof(struct bwn_dmadesc64)); 4124 } else { 4125 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4126 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4127 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4128 value |= BWN_DMA32_RXENABLE; 4129 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4130 & BWN_DMA32_RXADDREXT_MASK; 4131 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4132 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4133 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4134 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4135 sizeof(struct bwn_dmadesc32)); 4136 } 4137 } 4138 4139 static void 4140 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4141 { 4142 4143 if (dr->dr_tx) { 4144 bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap); 4145 if (dr->dr_txhdr_cache != NULL) 4146 bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache, 4147 dr->dr_txring_dmap); 4148 bus_dma_tag_destroy(dr->dr_txring_dtag); 4149 } 4150 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4151 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4152 dr->dr_ring_dmap); 4153 bus_dma_tag_destroy(dr->dr_ring_dtag); 4154 } 4155 4156 static void 4157 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4158 { 4159 4160 if (dr->dr_tx) { 4161 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4162 if (dr->dr_type == BWN_DMA_64BIT) { 4163 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4164 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4165 } else 4166 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4167 } else { 4168 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4169 if (dr->dr_type == BWN_DMA_64BIT) { 4170 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4171 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4172 } else 4173 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4174 } 4175 } 4176 4177 static void 4178 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4179 { 4180 struct bwn_dmadesc_generic *desc; 4181 struct bwn_dmadesc_meta *meta; 4182 struct bwn_mac *mac = dr->dr_mac; 4183 struct bwn_dma *dma = &mac->mac_method.dma; 4184 struct bwn_softc *sc = mac->mac_sc; 4185 int i; 4186 4187 if (!dr->dr_usedslot) 4188 return; 4189 for (i = 0; i < dr->dr_numslots; i++) { 4190 dr->getdesc(dr, i, &desc, &meta); 4191 4192 if (meta->mt_m == NULL) { 4193 if (!dr->dr_tx) 4194 device_printf(sc->sc_dev, "%s: not TX?\n", 4195 __func__); 4196 continue; 4197 } 4198 if (dr->dr_tx) { 4199 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 4200 /* Nothing */ 4201 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 4202 bus_dmamap_unload(dma->txbuf_dtag, 4203 meta->mt_dmap); 4204 } 4205 } else 4206 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4207 bwn_dma_free_descbuf(dr, meta); 4208 } 4209 } 4210 4211 static int 4212 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4213 int type) 4214 { 4215 struct bwn_softc *sc = mac->mac_sc; 4216 uint32_t value; 4217 int i; 4218 uint16_t offset; 4219 4220 for (i = 0; i < 10; i++) { 4221 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4222 BWN_DMA32_TXSTATUS; 4223 value = BWN_READ_4(mac, base + offset); 4224 if (type == BWN_DMA_64BIT) { 4225 value &= BWN_DMA64_TXSTAT; 4226 if (value == BWN_DMA64_TXSTAT_DISABLED || 4227 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4228 value == BWN_DMA64_TXSTAT_STOPPED) 4229 break; 4230 } else { 4231 value &= BWN_DMA32_TXSTATE; 4232 if (value == BWN_DMA32_TXSTAT_DISABLED || 4233 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4234 value == BWN_DMA32_TXSTAT_STOPPED) 4235 break; 4236 } 4237 DELAY(1000); 4238 } 4239 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4240 BWN_WRITE_4(mac, base + offset, 0); 4241 for (i = 0; i < 10; i++) { 4242 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4243 BWN_DMA32_TXSTATUS; 4244 value = BWN_READ_4(mac, base + offset); 4245 if (type == BWN_DMA_64BIT) { 4246 value &= BWN_DMA64_TXSTAT; 4247 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4248 i = -1; 4249 break; 4250 } 4251 } else { 4252 value &= BWN_DMA32_TXSTATE; 4253 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4254 i = -1; 4255 break; 4256 } 4257 } 4258 DELAY(1000); 4259 } 4260 if (i != -1) { 4261 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4262 return (ENODEV); 4263 } 4264 DELAY(1000); 4265 4266 return (0); 4267 } 4268 4269 static int 4270 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4271 int type) 4272 { 4273 struct bwn_softc *sc = mac->mac_sc; 4274 uint32_t value; 4275 int i; 4276 uint16_t offset; 4277 4278 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4279 BWN_WRITE_4(mac, base + offset, 0); 4280 for (i = 0; i < 10; i++) { 4281 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4282 BWN_DMA32_RXSTATUS; 4283 value = BWN_READ_4(mac, base + offset); 4284 if (type == BWN_DMA_64BIT) { 4285 value &= BWN_DMA64_RXSTAT; 4286 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4287 i = -1; 4288 break; 4289 } 4290 } else { 4291 value &= BWN_DMA32_RXSTATE; 4292 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4293 i = -1; 4294 break; 4295 } 4296 } 4297 DELAY(1000); 4298 } 4299 if (i != -1) { 4300 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4301 return (ENODEV); 4302 } 4303 4304 return (0); 4305 } 4306 4307 static void 4308 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4309 struct bwn_dmadesc_meta *meta) 4310 { 4311 4312 if (meta->mt_m != NULL) { 4313 m_freem(meta->mt_m); 4314 meta->mt_m = NULL; 4315 } 4316 if (meta->mt_ni != NULL) { 4317 ieee80211_free_node(meta->mt_ni); 4318 meta->mt_ni = NULL; 4319 } 4320 } 4321 4322 static void 4323 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4324 { 4325 struct bwn_rxhdr4 *rxhdr; 4326 unsigned char *frame; 4327 4328 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4329 rxhdr->frame_len = 0; 4330 4331 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4332 sizeof(struct bwn_plcp6) + 2, 4333 ("%s:%d: fail", __func__, __LINE__)); 4334 frame = mtod(m, char *) + dr->dr_frameoffset; 4335 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4336 } 4337 4338 static uint8_t 4339 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4340 { 4341 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4342 4343 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4344 == 0xff); 4345 } 4346 4347 static void 4348 bwn_wme_init(struct bwn_mac *mac) 4349 { 4350 4351 bwn_wme_load(mac); 4352 4353 /* enable WME support. */ 4354 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4355 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4356 BWN_IFSCTL_USE_EDCF); 4357 } 4358 4359 static void 4360 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4361 { 4362 struct bwn_softc *sc = mac->mac_sc; 4363 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4364 uint16_t delay; /* microsec */ 4365 4366 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4367 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4368 delay = 500; 4369 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4370 delay = max(delay, (uint16_t)2400); 4371 4372 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4373 } 4374 4375 static void 4376 bwn_bt_enable(struct bwn_mac *mac) 4377 { 4378 struct bwn_softc *sc = mac->mac_sc; 4379 uint64_t hf; 4380 4381 if (bwn_bluetooth == 0) 4382 return; 4383 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4384 return; 4385 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4386 return; 4387 4388 hf = bwn_hf_read(mac); 4389 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4390 hf |= BWN_HF_BT_COEXISTALT; 4391 else 4392 hf |= BWN_HF_BT_COEXIST; 4393 bwn_hf_write(mac, hf); 4394 } 4395 4396 static void 4397 bwn_set_macaddr(struct bwn_mac *mac) 4398 { 4399 4400 bwn_mac_write_bssid(mac); 4401 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4402 } 4403 4404 static void 4405 bwn_clear_keys(struct bwn_mac *mac) 4406 { 4407 int i; 4408 4409 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4410 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4411 ("%s:%d: fail", __func__, __LINE__)); 4412 4413 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4414 NULL, BWN_SEC_KEYSIZE, NULL); 4415 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4416 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4417 NULL, BWN_SEC_KEYSIZE, NULL); 4418 } 4419 mac->mac_key[i].keyconf = NULL; 4420 } 4421 } 4422 4423 static void 4424 bwn_crypt_init(struct bwn_mac *mac) 4425 { 4426 struct bwn_softc *sc = mac->mac_sc; 4427 4428 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4429 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4430 ("%s:%d: fail", __func__, __LINE__)); 4431 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4432 mac->mac_ktp *= 2; 4433 if (siba_get_revid(sc->sc_dev) >= 5) 4434 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4435 bwn_clear_keys(mac); 4436 } 4437 4438 static void 4439 bwn_chip_exit(struct bwn_mac *mac) 4440 { 4441 struct bwn_softc *sc = mac->mac_sc; 4442 4443 bwn_phy_exit(mac); 4444 siba_gpio_set(sc->sc_dev, 0); 4445 } 4446 4447 static int 4448 bwn_fw_fillinfo(struct bwn_mac *mac) 4449 { 4450 int error; 4451 4452 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4453 if (error == 0) 4454 return (0); 4455 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4456 if (error == 0) 4457 return (0); 4458 return (error); 4459 } 4460 4461 static int 4462 bwn_gpio_init(struct bwn_mac *mac) 4463 { 4464 struct bwn_softc *sc = mac->mac_sc; 4465 uint32_t mask = 0x1f, set = 0xf, value; 4466 4467 BWN_WRITE_4(mac, BWN_MACCTL, 4468 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4469 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4470 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4471 4472 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4473 mask |= 0x0060; 4474 set |= 0x0060; 4475 } 4476 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4477 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4478 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4479 mask |= 0x0200; 4480 set |= 0x0200; 4481 } 4482 if (siba_get_revid(sc->sc_dev) >= 2) 4483 mask |= 0x0010; 4484 4485 value = siba_gpio_get(sc->sc_dev); 4486 if (value == -1) 4487 return (0); 4488 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4489 4490 return (0); 4491 } 4492 4493 static int 4494 bwn_fw_loadinitvals(struct bwn_mac *mac) 4495 { 4496 #define GETFWOFFSET(fwp, offset) \ 4497 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4498 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4499 const struct bwn_fwhdr *hdr; 4500 struct bwn_fw *fw = &mac->mac_fw; 4501 int error; 4502 4503 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4504 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4505 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4506 if (error) 4507 return (error); 4508 if (fw->initvals_band.fw) { 4509 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4510 error = bwn_fwinitvals_write(mac, 4511 GETFWOFFSET(fw->initvals_band, hdr_len), 4512 be32toh(hdr->size), 4513 fw->initvals_band.fw->datasize - hdr_len); 4514 } 4515 return (error); 4516 #undef GETFWOFFSET 4517 } 4518 4519 static int 4520 bwn_phy_init(struct bwn_mac *mac) 4521 { 4522 struct bwn_softc *sc = mac->mac_sc; 4523 int error; 4524 4525 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4526 mac->mac_phy.rf_onoff(mac, 1); 4527 error = mac->mac_phy.init(mac); 4528 if (error) { 4529 device_printf(sc->sc_dev, "PHY init failed\n"); 4530 goto fail0; 4531 } 4532 error = bwn_switch_channel(mac, 4533 mac->mac_phy.get_default_chan(mac)); 4534 if (error) { 4535 device_printf(sc->sc_dev, 4536 "failed to switch default channel\n"); 4537 goto fail1; 4538 } 4539 return (0); 4540 fail1: 4541 if (mac->mac_phy.exit) 4542 mac->mac_phy.exit(mac); 4543 fail0: 4544 mac->mac_phy.rf_onoff(mac, 0); 4545 4546 return (error); 4547 } 4548 4549 static void 4550 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4551 { 4552 uint16_t ant; 4553 uint16_t tmp; 4554 4555 ant = bwn_ant2phy(antenna); 4556 4557 /* For ACK/CTS */ 4558 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4559 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4560 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4561 /* For Probe Resposes */ 4562 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4563 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4564 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4565 } 4566 4567 static void 4568 bwn_set_opmode(struct bwn_mac *mac) 4569 { 4570 struct bwn_softc *sc = mac->mac_sc; 4571 struct ifnet *ifp = sc->sc_ifp; 4572 struct ieee80211com *ic = ifp->if_l2com; 4573 uint32_t ctl; 4574 uint16_t cfp_pretbtt; 4575 4576 ctl = BWN_READ_4(mac, BWN_MACCTL); 4577 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4578 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4579 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4580 ctl |= BWN_MACCTL_STA; 4581 4582 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4583 ic->ic_opmode == IEEE80211_M_MBSS) 4584 ctl |= BWN_MACCTL_HOSTAP; 4585 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4586 ctl &= ~BWN_MACCTL_STA; 4587 ctl |= sc->sc_filters; 4588 4589 if (siba_get_revid(sc->sc_dev) <= 4) 4590 ctl |= BWN_MACCTL_PROMISC; 4591 4592 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4593 4594 cfp_pretbtt = 2; 4595 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4596 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4597 siba_get_chiprev(sc->sc_dev) == 3) 4598 cfp_pretbtt = 100; 4599 else 4600 cfp_pretbtt = 50; 4601 } 4602 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4603 } 4604 4605 static int 4606 bwn_dma_gettype(struct bwn_mac *mac) 4607 { 4608 uint32_t tmp; 4609 uint16_t base; 4610 4611 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4612 if (tmp & SIBA_TGSHIGH_DMA64) 4613 return (BWN_DMA_64BIT); 4614 base = bwn_dma_base(0, 0); 4615 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4616 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4617 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4618 return (BWN_DMA_32BIT); 4619 4620 return (BWN_DMA_30BIT); 4621 } 4622 4623 static void 4624 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4625 { 4626 if (!error) { 4627 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4628 *((bus_addr_t *)arg) = seg->ds_addr; 4629 } 4630 } 4631 4632 static void 4633 bwn_phy_g_init_sub(struct bwn_mac *mac) 4634 { 4635 struct bwn_phy *phy = &mac->mac_phy; 4636 struct bwn_phy_g *pg = &phy->phy_g; 4637 struct bwn_softc *sc = mac->mac_sc; 4638 uint16_t i, tmp; 4639 4640 if (phy->rev == 1) 4641 bwn_phy_init_b5(mac); 4642 else 4643 bwn_phy_init_b6(mac); 4644 4645 if (phy->rev >= 2 || phy->gmode) 4646 bwn_phy_init_a(mac); 4647 4648 if (phy->rev >= 2) { 4649 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4650 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4651 } 4652 if (phy->rev == 2) { 4653 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4654 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4655 } 4656 if (phy->rev > 5) { 4657 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4658 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4659 } 4660 if (phy->gmode || phy->rev >= 2) { 4661 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4662 tmp &= BWN_PHYVER_VERSION; 4663 if (tmp == 3 || tmp == 5) { 4664 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4665 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4666 } 4667 if (tmp == 5) { 4668 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4669 0x1f00); 4670 } 4671 } 4672 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4673 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4674 if (phy->rf_rev == 8) { 4675 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4676 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4677 } 4678 if (BWN_HAS_LOOPBACK(phy)) 4679 bwn_loopback_calcgain(mac); 4680 4681 if (phy->rf_rev != 8) { 4682 if (pg->pg_initval == 0xffff) 4683 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4684 else 4685 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4686 } 4687 bwn_lo_g_init(mac); 4688 if (BWN_HAS_TXMAG(phy)) { 4689 BWN_RF_WRITE(mac, 0x52, 4690 (BWN_RF_READ(mac, 0x52) & 0xff00) 4691 | pg->pg_loctl.tx_bias | 4692 pg->pg_loctl.tx_magn); 4693 } else { 4694 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4695 } 4696 if (phy->rev >= 6) { 4697 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4698 (pg->pg_loctl.tx_bias << 12)); 4699 } 4700 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4701 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4702 else 4703 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4704 if (phy->rev < 2) 4705 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4706 else 4707 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4708 if (phy->gmode || phy->rev >= 2) { 4709 bwn_lo_g_adjust(mac); 4710 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4711 } 4712 4713 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4714 for (i = 0; i < 64; i++) { 4715 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4716 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4717 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4718 -32), 31)); 4719 } 4720 bwn_nrssi_threshold(mac); 4721 } else if (phy->gmode || phy->rev >= 2) { 4722 if (pg->pg_nrssi[0] == -1000) { 4723 KASSERT(pg->pg_nrssi[1] == -1000, 4724 ("%s:%d: fail", __func__, __LINE__)); 4725 bwn_nrssi_slope_11g(mac); 4726 } else 4727 bwn_nrssi_threshold(mac); 4728 } 4729 if (phy->rf_rev == 8) 4730 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4731 bwn_phy_hwpctl_init(mac); 4732 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4733 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4734 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4735 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4736 } 4737 } 4738 4739 static uint8_t 4740 bwn_has_hwpctl(struct bwn_mac *mac) 4741 { 4742 4743 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4744 return (0); 4745 return (mac->mac_phy.use_hwpctl(mac)); 4746 } 4747 4748 static void 4749 bwn_phy_init_b5(struct bwn_mac *mac) 4750 { 4751 struct bwn_phy *phy = &mac->mac_phy; 4752 struct bwn_phy_g *pg = &phy->phy_g; 4753 struct bwn_softc *sc = mac->mac_sc; 4754 uint16_t offset, value; 4755 uint8_t old_channel; 4756 4757 if (phy->analog == 1) 4758 BWN_RF_SET(mac, 0x007a, 0x0050); 4759 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4760 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4761 value = 0x2120; 4762 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4763 BWN_PHY_WRITE(mac, offset, value); 4764 value += 0x202; 4765 } 4766 } 4767 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4768 if (phy->rf_ver == 0x2050) 4769 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4770 4771 if (phy->gmode || phy->rev >= 2) { 4772 if (phy->rf_ver == 0x2050) { 4773 BWN_RF_SET(mac, 0x007a, 0x0020); 4774 BWN_RF_SET(mac, 0x0051, 0x0004); 4775 } 4776 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4777 4778 BWN_PHY_SET(mac, 0x0802, 0x0100); 4779 BWN_PHY_SET(mac, 0x042b, 0x2000); 4780 4781 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4782 4783 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4784 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4785 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4786 } 4787 4788 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4789 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4790 4791 if (phy->analog == 1) { 4792 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4793 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4794 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4795 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4796 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4797 } else 4798 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4799 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4800 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4801 4802 if (phy->analog == 1) 4803 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4804 else 4805 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4806 4807 if (phy->analog == 0) 4808 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4809 4810 old_channel = phy->chan; 4811 bwn_phy_g_switch_chan(mac, 7, 0); 4812 4813 if (phy->rf_ver != 0x2050) { 4814 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4815 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4816 } 4817 4818 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4819 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4820 4821 if (phy->rf_ver == 0x2050) { 4822 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4823 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4824 } 4825 4826 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4827 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4828 BWN_RF_SET(mac, 0x007a, 0x0007); 4829 4830 bwn_phy_g_switch_chan(mac, old_channel, 0); 4831 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4832 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4833 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4834 4835 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4836 pg->pg_txctl); 4837 4838 if (phy->rf_ver == 0x2050) 4839 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4840 4841 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4842 } 4843 4844 static void 4845 bwn_loopback_calcgain(struct bwn_mac *mac) 4846 { 4847 struct bwn_phy *phy = &mac->mac_phy; 4848 struct bwn_phy_g *pg = &phy->phy_g; 4849 struct bwn_softc *sc = mac->mac_sc; 4850 uint16_t backup_phy[16] = { 0 }; 4851 uint16_t backup_radio[3]; 4852 uint16_t backup_bband; 4853 uint16_t i, j, loop_i_max; 4854 uint16_t trsw_rx; 4855 uint16_t loop1_outer_done, loop1_inner_done; 4856 4857 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4858 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4859 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4860 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4861 if (phy->rev != 1) { 4862 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4863 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4864 } 4865 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4866 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4867 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4868 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4869 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4870 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4871 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4872 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4873 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4874 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4875 backup_bband = pg->pg_bbatt.att; 4876 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4877 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4878 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4879 4880 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4881 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4882 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4883 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4884 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4885 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4886 if (phy->rev != 1) { 4887 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4888 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4889 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4890 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4891 } 4892 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4893 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4894 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4895 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4896 4897 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4898 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4899 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4900 4901 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4902 if (phy->rev != 1) { 4903 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4904 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4905 } 4906 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4907 4908 if (phy->rf_rev == 8) 4909 BWN_RF_WRITE(mac, 0x43, 0x000f); 4910 else { 4911 BWN_RF_WRITE(mac, 0x52, 0); 4912 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4913 } 4914 bwn_phy_g_set_bbatt(mac, 11); 4915 4916 if (phy->rev >= 3) 4917 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4918 else 4919 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4920 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4921 4922 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 4923 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 4924 4925 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 4926 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 4927 4928 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 4929 if (phy->rev >= 7) { 4930 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 4931 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 4932 } 4933 } 4934 BWN_RF_MASK(mac, 0x7a, 0x00f7); 4935 4936 j = 0; 4937 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 4938 for (i = 0; i < loop_i_max; i++) { 4939 for (j = 0; j < 16; j++) { 4940 BWN_RF_WRITE(mac, 0x43, i); 4941 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 4942 (j << 8)); 4943 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4944 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4945 DELAY(20); 4946 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4947 goto done0; 4948 } 4949 } 4950 done0: 4951 loop1_outer_done = i; 4952 loop1_inner_done = j; 4953 if (j >= 8) { 4954 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 4955 trsw_rx = 0x1b; 4956 for (j = j - 8; j < 16; j++) { 4957 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 4958 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4959 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4960 DELAY(20); 4961 trsw_rx -= 3; 4962 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4963 goto done1; 4964 } 4965 } else 4966 trsw_rx = 0x18; 4967 done1: 4968 4969 if (phy->rev != 1) { 4970 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 4971 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 4972 } 4973 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 4974 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 4975 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 4976 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 4977 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 4978 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 4979 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 4981 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 4982 4983 bwn_phy_g_set_bbatt(mac, backup_bband); 4984 4985 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 4986 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 4987 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 4988 4989 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 4990 DELAY(10); 4991 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 4992 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 4993 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 4994 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 4995 4996 pg->pg_max_lb_gain = 4997 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 4998 pg->pg_trsw_rx_gain = trsw_rx * 2; 4999 } 5000 5001 static uint16_t 5002 bwn_rf_init_bcm2050(struct bwn_mac *mac) 5003 { 5004 struct bwn_phy *phy = &mac->mac_phy; 5005 uint32_t tmp1 = 0, tmp2 = 0; 5006 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5007 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5008 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5009 static const uint8_t rcc_table[] = { 5010 0x02, 0x03, 0x01, 0x0f, 5011 0x06, 0x07, 0x05, 0x0f, 5012 0x0a, 0x0b, 0x09, 0x0f, 5013 0x0e, 0x0f, 0x0d, 0x0f, 5014 }; 5015 5016 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5017 rfoverval = rfover = cck3 = 0; 5018 radio0 = BWN_RF_READ(mac, 0x43); 5019 radio1 = BWN_RF_READ(mac, 0x51); 5020 radio2 = BWN_RF_READ(mac, 0x52); 5021 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5022 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5023 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5024 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5025 5026 if (phy->type == BWN_PHYTYPE_B) { 5027 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5028 reg0 = BWN_READ_2(mac, 0x3ec); 5029 5030 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5031 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5032 } else if (phy->gmode || phy->rev >= 2) { 5033 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5034 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5035 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5036 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5037 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5038 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5039 5040 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5041 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5042 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5043 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5044 if (BWN_HAS_LOOPBACK(phy)) { 5045 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5046 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5047 if (phy->rev >= 3) 5048 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5049 else 5050 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5051 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5052 } 5053 5054 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5055 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5056 BWN_LPD(0, 1, 1))); 5057 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5058 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5059 } 5060 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5061 5062 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5063 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5064 reg1 = BWN_READ_2(mac, 0x3e6); 5065 reg2 = BWN_READ_2(mac, 0x3f4); 5066 5067 if (phy->analog == 0) 5068 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5069 else { 5070 if (phy->analog >= 2) 5071 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5072 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5073 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5074 } 5075 5076 reg = BWN_RF_READ(mac, 0x60); 5077 index = (reg & 0x001e) >> 1; 5078 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5079 5080 if (phy->type == BWN_PHYTYPE_B) 5081 BWN_RF_WRITE(mac, 0x78, 0x26); 5082 if (phy->gmode || phy->rev >= 2) { 5083 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5084 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5085 BWN_LPD(0, 1, 1))); 5086 } 5087 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5088 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5089 if (phy->gmode || phy->rev >= 2) { 5090 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5091 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5092 BWN_LPD(0, 0, 1))); 5093 } 5094 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5095 BWN_RF_SET(mac, 0x51, 0x0004); 5096 if (phy->rf_rev == 8) 5097 BWN_RF_WRITE(mac, 0x43, 0x1f); 5098 else { 5099 BWN_RF_WRITE(mac, 0x52, 0); 5100 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5101 } 5102 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5103 5104 for (i = 0; i < 16; i++) { 5105 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5106 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5107 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5108 if (phy->gmode || phy->rev >= 2) { 5109 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5110 bwn_rf_2050_rfoverval(mac, 5111 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5112 } 5113 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5114 DELAY(10); 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, 0xefb0); 5121 DELAY(10); 5122 if (phy->gmode || phy->rev >= 2) { 5123 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5124 bwn_rf_2050_rfoverval(mac, 5125 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5126 } 5127 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5128 DELAY(20); 5129 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5130 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5131 if (phy->gmode || phy->rev >= 2) { 5132 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5133 bwn_rf_2050_rfoverval(mac, 5134 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5135 } 5136 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5137 } 5138 DELAY(10); 5139 5140 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5141 tmp1++; 5142 tmp1 >>= 9; 5143 5144 for (i = 0; i < 16; i++) { 5145 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5146 BWN_RF_WRITE(mac, 0x78, radio78); 5147 DELAY(10); 5148 for (j = 0; j < 16; j++) { 5149 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5150 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5151 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5152 if (phy->gmode || phy->rev >= 2) { 5153 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5154 bwn_rf_2050_rfoverval(mac, 5155 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5156 } 5157 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5158 DELAY(10); 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, 0xefb0); 5165 DELAY(10); 5166 if (phy->gmode || phy->rev >= 2) { 5167 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5168 bwn_rf_2050_rfoverval(mac, 5169 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5170 } 5171 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5172 DELAY(10); 5173 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5174 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5175 if (phy->gmode || phy->rev >= 2) { 5176 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5177 bwn_rf_2050_rfoverval(mac, 5178 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5179 } 5180 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5181 } 5182 tmp2++; 5183 tmp2 >>= 8; 5184 if (tmp1 < tmp2) 5185 break; 5186 } 5187 5188 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5189 BWN_RF_WRITE(mac, 0x51, radio1); 5190 BWN_RF_WRITE(mac, 0x52, radio2); 5191 BWN_RF_WRITE(mac, 0x43, radio0); 5192 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5193 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5194 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5195 BWN_WRITE_2(mac, 0x3e6, reg1); 5196 if (phy->analog != 0) 5197 BWN_WRITE_2(mac, 0x3f4, reg2); 5198 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5199 bwn_spu_workaround(mac, phy->chan); 5200 if (phy->type == BWN_PHYTYPE_B) { 5201 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5202 BWN_WRITE_2(mac, 0x3ec, reg0); 5203 } else if (phy->gmode) { 5204 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5205 BWN_READ_2(mac, BWN_PHY_RADIO) 5206 & 0x7fff); 5207 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5208 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5209 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5210 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5211 analogoverval); 5212 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5213 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5214 if (BWN_HAS_LOOPBACK(phy)) { 5215 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5216 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5217 } 5218 } 5219 5220 return ((i > 15) ? radio78 : rcc); 5221 } 5222 5223 static void 5224 bwn_phy_init_b6(struct bwn_mac *mac) 5225 { 5226 struct bwn_phy *phy = &mac->mac_phy; 5227 struct bwn_phy_g *pg = &phy->phy_g; 5228 struct bwn_softc *sc = mac->mac_sc; 5229 uint16_t offset, val; 5230 uint8_t old_channel; 5231 5232 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5233 ("%s:%d: fail", __func__, __LINE__)); 5234 5235 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5236 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5237 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5238 BWN_RF_WRITE(mac, 0x51, 0x37); 5239 BWN_RF_WRITE(mac, 0x52, 0x70); 5240 BWN_RF_WRITE(mac, 0x53, 0xb3); 5241 BWN_RF_WRITE(mac, 0x54, 0x9b); 5242 BWN_RF_WRITE(mac, 0x5a, 0x88); 5243 BWN_RF_WRITE(mac, 0x5b, 0x88); 5244 BWN_RF_WRITE(mac, 0x5d, 0x88); 5245 BWN_RF_WRITE(mac, 0x5e, 0x88); 5246 BWN_RF_WRITE(mac, 0x7d, 0x88); 5247 bwn_hf_write(mac, 5248 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5249 } 5250 if (phy->rf_rev == 8) { 5251 BWN_RF_WRITE(mac, 0x51, 0); 5252 BWN_RF_WRITE(mac, 0x52, 0x40); 5253 BWN_RF_WRITE(mac, 0x53, 0xb7); 5254 BWN_RF_WRITE(mac, 0x54, 0x98); 5255 BWN_RF_WRITE(mac, 0x5a, 0x88); 5256 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5257 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5258 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5259 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5260 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5261 } else { 5262 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5263 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5264 } 5265 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5266 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5267 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5268 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5269 } 5270 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5271 BWN_PHY_WRITE(mac, offset, val); 5272 val -= 0x0202; 5273 } 5274 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5275 BWN_PHY_WRITE(mac, offset, val); 5276 val -= 0x0202; 5277 } 5278 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5279 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5280 val += 0x0202; 5281 } 5282 if (phy->type == BWN_PHYTYPE_G) { 5283 BWN_RF_SET(mac, 0x007a, 0x0020); 5284 BWN_RF_SET(mac, 0x0051, 0x0004); 5285 BWN_PHY_SET(mac, 0x0802, 0x0100); 5286 BWN_PHY_SET(mac, 0x042b, 0x2000); 5287 BWN_PHY_WRITE(mac, 0x5b, 0); 5288 BWN_PHY_WRITE(mac, 0x5c, 0); 5289 } 5290 5291 old_channel = phy->chan; 5292 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5293 5294 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5295 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5296 DELAY(40); 5297 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5298 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5299 BWN_RF_WRITE(mac, 0x50, 0x20); 5300 } 5301 if (phy->rf_rev <= 2) { 5302 BWN_RF_WRITE(mac, 0x7c, 0x20); 5303 BWN_RF_WRITE(mac, 0x5a, 0x70); 5304 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5305 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5306 } 5307 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5308 5309 bwn_phy_g_switch_chan(mac, old_channel, 0); 5310 5311 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5312 if (phy->rf_rev >= 6) 5313 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5314 else 5315 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5316 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5317 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5318 pg->pg_txctl); 5319 if (phy->rf_rev <= 5) 5320 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5321 if (phy->rf_rev <= 2) 5322 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5323 5324 if (phy->analog == 4) { 5325 BWN_WRITE_2(mac, 0x3e4, 9); 5326 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5327 } else 5328 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5329 if (phy->type == BWN_PHYTYPE_B) 5330 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5331 else if (phy->type == BWN_PHYTYPE_G) 5332 BWN_WRITE_2(mac, 0x03e6, 0x0); 5333 } 5334 5335 static void 5336 bwn_phy_init_a(struct bwn_mac *mac) 5337 { 5338 struct bwn_phy *phy = &mac->mac_phy; 5339 struct bwn_softc *sc = mac->mac_sc; 5340 5341 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5342 ("%s:%d: fail", __func__, __LINE__)); 5343 5344 if (phy->rev >= 6) { 5345 if (phy->type == BWN_PHYTYPE_A) 5346 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5347 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5348 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5349 else 5350 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5351 } 5352 5353 bwn_wa_init(mac); 5354 5355 if (phy->type == BWN_PHYTYPE_G && 5356 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5357 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5358 } 5359 5360 static void 5361 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5362 { 5363 int i; 5364 5365 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5366 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5367 } 5368 5369 static void 5370 bwn_wa_agc(struct bwn_mac *mac) 5371 { 5372 struct bwn_phy *phy = &mac->mac_phy; 5373 5374 if (phy->rev == 1) { 5375 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5376 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5377 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5378 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5379 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5380 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5381 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5382 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5383 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5384 } else { 5385 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5386 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5387 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5388 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5389 } 5390 5391 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5392 0x5700); 5393 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5394 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5395 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5396 BWN_RF_SET(mac, 0x7a, 0x0008); 5397 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5398 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5399 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5400 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5401 if (phy->rev == 1) 5402 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5403 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5404 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5405 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5406 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5407 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5408 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5409 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5410 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5411 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5412 if (phy->rev == 1) { 5413 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5414 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5415 } else { 5416 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5417 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5418 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5419 if (phy->rev >= 6) { 5420 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5421 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5422 (uint16_t)~0xf000, 0x3000); 5423 } 5424 } 5425 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5426 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5427 if (phy->rev == 1) { 5428 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5429 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5430 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5431 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5432 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5433 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5434 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5435 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5436 } else { 5437 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5438 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5439 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5440 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5441 } 5442 if (phy->rev >= 6) { 5443 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5444 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5445 } 5446 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5447 } 5448 5449 static void 5450 bwn_wa_grev1(struct bwn_mac *mac) 5451 { 5452 struct bwn_phy *phy = &mac->mac_phy; 5453 int i; 5454 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5455 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5456 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5457 5458 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5459 5460 /* init CRSTHRES and ANTDWELL */ 5461 if (phy->rev == 1) { 5462 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5463 } else if (phy->rev == 2) { 5464 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5465 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5466 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5467 } else { 5468 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5469 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5470 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5471 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5472 } 5473 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5474 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5475 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5476 5477 /* XXX support PHY-A??? */ 5478 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5479 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5480 bwn_tab_finefreqg[i]); 5481 5482 /* XXX support PHY-A??? */ 5483 if (phy->rev == 1) 5484 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5485 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5486 bwn_tab_noise_g1[i]); 5487 else 5488 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5489 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5490 bwn_tab_noise_g2[i]); 5491 5492 5493 for (i = 0; i < N(bwn_tab_rotor); i++) 5494 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5495 bwn_tab_rotor[i]); 5496 5497 /* XXX support PHY-A??? */ 5498 if (phy->rev >= 6) { 5499 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5500 BWN_PHY_ENCORE_EN) 5501 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5502 else 5503 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5504 } else 5505 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5506 5507 for (i = 0; i < N(bwn_tab_retard); i++) 5508 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5509 bwn_tab_retard[i]); 5510 5511 if (phy->rev == 1) { 5512 for (i = 0; i < 16; i++) 5513 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5514 i, 0x0020); 5515 } else { 5516 for (i = 0; i < 32; i++) 5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5518 } 5519 5520 bwn_wa_agc(mac); 5521 } 5522 5523 static void 5524 bwn_wa_grev26789(struct bwn_mac *mac) 5525 { 5526 struct bwn_phy *phy = &mac->mac_phy; 5527 int i; 5528 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5529 uint16_t ofdmrev; 5530 5531 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5532 5533 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5534 5535 /* init CRSTHRES and ANTDWELL */ 5536 if (phy->rev == 1) 5537 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5538 else if (phy->rev == 2) { 5539 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5540 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5541 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5542 } else { 5543 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5544 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5545 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5546 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5547 } 5548 5549 for (i = 0; i < 64; i++) 5550 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5551 5552 /* XXX support PHY-A??? */ 5553 if (phy->rev == 1) 5554 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5555 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5556 bwn_tab_noise_g1[i]); 5557 else 5558 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5559 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5560 bwn_tab_noise_g2[i]); 5561 5562 /* XXX support PHY-A??? */ 5563 if (phy->rev >= 6) { 5564 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5565 BWN_PHY_ENCORE_EN) 5566 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5567 else 5568 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5569 } else 5570 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5571 5572 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5573 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5574 bwn_tab_sigmasqr2[i]); 5575 5576 if (phy->rev == 1) { 5577 for (i = 0; i < 16; i++) 5578 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5579 0x0020); 5580 } else { 5581 for (i = 0; i < 32; i++) 5582 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5583 } 5584 5585 bwn_wa_agc(mac); 5586 5587 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5588 if (ofdmrev > 2) { 5589 if (phy->type == BWN_PHYTYPE_A) 5590 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5591 else 5592 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5593 } else { 5594 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5595 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5596 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5597 } 5598 5599 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5600 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5601 } 5602 5603 static void 5604 bwn_wa_init(struct bwn_mac *mac) 5605 { 5606 struct bwn_phy *phy = &mac->mac_phy; 5607 struct bwn_softc *sc = mac->mac_sc; 5608 5609 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5610 5611 switch (phy->rev) { 5612 case 1: 5613 bwn_wa_grev1(mac); 5614 break; 5615 case 2: 5616 case 6: 5617 case 7: 5618 case 8: 5619 case 9: 5620 bwn_wa_grev26789(mac); 5621 break; 5622 default: 5623 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5624 } 5625 5626 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5627 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5628 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5629 if (phy->rev < 2) { 5630 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5631 0x0002); 5632 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5633 0x0001); 5634 } else { 5635 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5637 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5638 BWN_BFL_EXTLNA) && 5639 (phy->rev >= 7)) { 5640 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5641 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5642 0x0020, 0x0001); 5643 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5644 0x0021, 0x0001); 5645 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5646 0x0022, 0x0001); 5647 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5648 0x0023, 0x0000); 5649 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5650 0x0000, 0x0000); 5651 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5652 0x0003, 0x0002); 5653 } 5654 } 5655 } 5656 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5657 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5658 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5659 } 5660 5661 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5662 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5663 } 5664 5665 static void 5666 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5667 uint16_t value) 5668 { 5669 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5670 uint16_t addr; 5671 5672 addr = table + offset; 5673 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5674 (addr - 1 != pg->pg_ofdmtab_addr)) { 5675 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5676 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5677 } 5678 pg->pg_ofdmtab_addr = addr; 5679 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5680 } 5681 5682 static void 5683 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5684 uint32_t value) 5685 { 5686 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5687 uint16_t addr; 5688 5689 addr = table + offset; 5690 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5691 (addr - 1 != pg->pg_ofdmtab_addr)) { 5692 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5693 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5694 } 5695 pg->pg_ofdmtab_addr = addr; 5696 5697 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5698 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5699 } 5700 5701 static void 5702 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5703 uint16_t value) 5704 { 5705 5706 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5707 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5708 } 5709 5710 static void 5711 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5712 { 5713 struct bwn_phy *phy = &mac->mac_phy; 5714 struct bwn_softc *sc = mac->mac_sc; 5715 unsigned int i, max_loop; 5716 uint16_t value; 5717 uint32_t buffer[5] = { 5718 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5719 }; 5720 5721 if (ofdm) { 5722 max_loop = 0x1e; 5723 buffer[0] = 0x000201cc; 5724 } else { 5725 max_loop = 0xfa; 5726 buffer[0] = 0x000b846e; 5727 } 5728 5729 for (i = 0; i < 5; i++) 5730 bwn_ram_write(mac, i * 4, buffer[i]); 5731 5732 BWN_WRITE_2(mac, 0x0568, 0x0000); 5733 BWN_WRITE_2(mac, 0x07c0, 5734 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5735 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5736 BWN_WRITE_2(mac, 0x050c, value); 5737 if (phy->type == BWN_PHYTYPE_LP) 5738 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5739 BWN_WRITE_2(mac, 0x0508, 0x0000); 5740 BWN_WRITE_2(mac, 0x050a, 0x0000); 5741 BWN_WRITE_2(mac, 0x054c, 0x0000); 5742 BWN_WRITE_2(mac, 0x056a, 0x0014); 5743 BWN_WRITE_2(mac, 0x0568, 0x0826); 5744 BWN_WRITE_2(mac, 0x0500, 0x0000); 5745 if (phy->type == BWN_PHYTYPE_LP) 5746 BWN_WRITE_2(mac, 0x0502, 0x0050); 5747 else 5748 BWN_WRITE_2(mac, 0x0502, 0x0030); 5749 5750 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5751 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5752 for (i = 0x00; i < max_loop; i++) { 5753 value = BWN_READ_2(mac, 0x050e); 5754 if (value & 0x0080) 5755 break; 5756 DELAY(10); 5757 } 5758 for (i = 0x00; i < 0x0a; i++) { 5759 value = BWN_READ_2(mac, 0x050e); 5760 if (value & 0x0400) 5761 break; 5762 DELAY(10); 5763 } 5764 for (i = 0x00; i < 0x19; i++) { 5765 value = BWN_READ_2(mac, 0x0690); 5766 if (!(value & 0x0100)) 5767 break; 5768 DELAY(10); 5769 } 5770 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5771 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5772 } 5773 5774 static void 5775 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5776 { 5777 uint32_t macctl; 5778 5779 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5780 5781 macctl = BWN_READ_4(mac, BWN_MACCTL); 5782 if (macctl & BWN_MACCTL_BIGENDIAN) 5783 kprintf("TODO: need swap\n"); 5784 5785 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5786 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5787 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5788 } 5789 5790 static void 5791 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5792 { 5793 uint16_t value; 5794 5795 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5796 ("%s:%d: fail", __func__, __LINE__)); 5797 5798 value = (uint8_t) (ctl->q); 5799 value |= ((uint8_t) (ctl->i)) << 8; 5800 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5801 } 5802 5803 static uint16_t 5804 bwn_lo_calcfeed(struct bwn_mac *mac, 5805 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5806 { 5807 struct bwn_phy *phy = &mac->mac_phy; 5808 struct bwn_softc *sc = mac->mac_sc; 5809 uint16_t rfover; 5810 uint16_t feedthrough; 5811 5812 if (phy->gmode) { 5813 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5814 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5815 5816 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5817 ("%s:%d: fail", __func__, __LINE__)); 5818 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5819 ("%s:%d: fail", __func__, __LINE__)); 5820 5821 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5822 5823 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5824 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5825 phy->rev > 6) 5826 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5827 5828 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5829 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5830 DELAY(10); 5831 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5832 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5833 DELAY(10); 5834 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5835 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5836 DELAY(10); 5837 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5838 } else { 5839 pga |= BWN_PHY_PGACTL_UNKNOWN; 5840 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5841 DELAY(10); 5842 pga |= BWN_PHY_PGACTL_LOWBANDW; 5843 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5844 DELAY(10); 5845 pga |= BWN_PHY_PGACTL_LPF; 5846 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5847 } 5848 DELAY(21); 5849 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5850 5851 return (feedthrough); 5852 } 5853 5854 static uint16_t 5855 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5856 uint16_t *value, uint16_t *pad_mix_gain) 5857 { 5858 struct bwn_phy *phy = &mac->mac_phy; 5859 uint16_t reg, v, padmix; 5860 5861 if (phy->type == BWN_PHYTYPE_B) { 5862 v = 0x30; 5863 if (phy->rf_rev <= 5) { 5864 reg = 0x43; 5865 padmix = 0; 5866 } else { 5867 reg = 0x52; 5868 padmix = 5; 5869 } 5870 } else { 5871 if (phy->rev >= 2 && phy->rf_rev == 8) { 5872 reg = 0x43; 5873 v = 0x10; 5874 padmix = 2; 5875 } else { 5876 reg = 0x52; 5877 v = 0x30; 5878 padmix = 5; 5879 } 5880 } 5881 if (value) 5882 *value = v; 5883 if (pad_mix_gain) 5884 *pad_mix_gain = padmix; 5885 5886 return (reg); 5887 } 5888 5889 static void 5890 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5891 { 5892 struct bwn_phy *phy = &mac->mac_phy; 5893 struct bwn_phy_g *pg = &phy->phy_g; 5894 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5895 uint16_t reg, mask; 5896 uint16_t trsw_rx, pga; 5897 uint16_t rf_pctl_reg; 5898 5899 static const uint8_t tx_bias_values[] = { 5900 0x09, 0x08, 0x0a, 0x01, 0x00, 5901 0x02, 0x05, 0x04, 0x06, 5902 }; 5903 static const uint8_t tx_magn_values[] = { 5904 0x70, 0x40, 5905 }; 5906 5907 if (!BWN_HAS_LOOPBACK(phy)) { 5908 rf_pctl_reg = 6; 5909 trsw_rx = 2; 5910 pga = 0; 5911 } else { 5912 int lb_gain; 5913 5914 trsw_rx = 0; 5915 lb_gain = pg->pg_max_lb_gain / 2; 5916 if (lb_gain > 10) { 5917 rf_pctl_reg = 0; 5918 pga = abs(10 - lb_gain) / 6; 5919 pga = MIN(MAX(pga, 0), 15); 5920 } else { 5921 int cmp_val; 5922 int tmp; 5923 5924 pga = 0; 5925 cmp_val = 0x24; 5926 if ((phy->rev >= 2) && 5927 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 5928 cmp_val = 0x3c; 5929 tmp = lb_gain; 5930 if ((10 - lb_gain) < cmp_val) 5931 tmp = (10 - lb_gain); 5932 if (tmp < 0) 5933 tmp += 6; 5934 else 5935 tmp += 3; 5936 cmp_val /= 4; 5937 tmp /= 4; 5938 if (tmp >= cmp_val) 5939 rf_pctl_reg = cmp_val; 5940 else 5941 rf_pctl_reg = tmp; 5942 } 5943 } 5944 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 5945 bwn_phy_g_set_bbatt(mac, 2); 5946 5947 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 5948 mask = ~mask; 5949 BWN_RF_MASK(mac, reg, mask); 5950 5951 if (BWN_HAS_TXMAG(phy)) { 5952 int i, j; 5953 int feedthrough; 5954 int min_feedth = 0xffff; 5955 uint8_t tx_magn, tx_bias; 5956 5957 for (i = 0; i < N(tx_magn_values); i++) { 5958 tx_magn = tx_magn_values[i]; 5959 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 5960 for (j = 0; j < N(tx_bias_values); j++) { 5961 tx_bias = tx_bias_values[j]; 5962 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 5963 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 5964 trsw_rx); 5965 if (feedthrough < min_feedth) { 5966 lo->tx_bias = tx_bias; 5967 lo->tx_magn = tx_magn; 5968 min_feedth = feedthrough; 5969 } 5970 if (lo->tx_bias == 0) 5971 break; 5972 } 5973 BWN_RF_WRITE(mac, 0x52, 5974 (BWN_RF_READ(mac, 0x52) 5975 & 0xff00) | lo->tx_bias | lo-> 5976 tx_magn); 5977 } 5978 } else { 5979 lo->tx_magn = 0; 5980 lo->tx_bias = 0; 5981 BWN_RF_MASK(mac, 0x52, 0xfff0); 5982 } 5983 5984 BWN_GETTIME(lo->txctl_measured_time); 5985 } 5986 5987 static void 5988 bwn_lo_get_powervector(struct bwn_mac *mac) 5989 { 5990 struct bwn_phy *phy = &mac->mac_phy; 5991 struct bwn_phy_g *pg = &phy->phy_g; 5992 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5993 int i; 5994 uint64_t tmp; 5995 uint64_t power_vector = 0; 5996 5997 for (i = 0; i < 8; i += 2) { 5998 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 5999 power_vector |= (tmp << (i * 8)); 6000 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6001 } 6002 if (power_vector) 6003 lo->power_vector = power_vector; 6004 6005 BWN_GETTIME(lo->pwr_vec_read_time); 6006 } 6007 6008 static void 6009 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6010 int use_trsw_rx) 6011 { 6012 struct bwn_phy *phy = &mac->mac_phy; 6013 struct bwn_phy_g *pg = &phy->phy_g; 6014 uint16_t tmp; 6015 6016 if (max_rx_gain < 0) 6017 max_rx_gain = 0; 6018 6019 if (BWN_HAS_LOOPBACK(phy)) { 6020 int trsw_rx = 0; 6021 int trsw_rx_gain; 6022 6023 if (use_trsw_rx) { 6024 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6025 if (max_rx_gain >= trsw_rx_gain) { 6026 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6027 trsw_rx = 0x20; 6028 } 6029 } else 6030 trsw_rx_gain = max_rx_gain; 6031 if (trsw_rx_gain < 9) { 6032 pg->pg_lna_lod_gain = 0; 6033 } else { 6034 pg->pg_lna_lod_gain = 1; 6035 trsw_rx_gain -= 8; 6036 } 6037 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6038 pg->pg_pga_gain = trsw_rx_gain / 3; 6039 if (pg->pg_pga_gain >= 5) { 6040 pg->pg_pga_gain -= 5; 6041 pg->pg_lna_gain = 2; 6042 } else 6043 pg->pg_lna_gain = 0; 6044 } else { 6045 pg->pg_lna_gain = 0; 6046 pg->pg_trsw_rx_gain = 0x20; 6047 if (max_rx_gain >= 0x14) { 6048 pg->pg_lna_lod_gain = 1; 6049 pg->pg_pga_gain = 2; 6050 } else if (max_rx_gain >= 0x12) { 6051 pg->pg_lna_lod_gain = 1; 6052 pg->pg_pga_gain = 1; 6053 } else if (max_rx_gain >= 0xf) { 6054 pg->pg_lna_lod_gain = 1; 6055 pg->pg_pga_gain = 0; 6056 } else { 6057 pg->pg_lna_lod_gain = 0; 6058 pg->pg_pga_gain = 0; 6059 } 6060 } 6061 6062 tmp = BWN_RF_READ(mac, 0x7a); 6063 if (pg->pg_lna_lod_gain == 0) 6064 tmp &= ~0x0008; 6065 else 6066 tmp |= 0x0008; 6067 BWN_RF_WRITE(mac, 0x7a, tmp); 6068 } 6069 6070 static void 6071 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6072 { 6073 struct bwn_phy *phy = &mac->mac_phy; 6074 struct bwn_phy_g *pg = &phy->phy_g; 6075 struct bwn_softc *sc = mac->mac_sc; 6076 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6077 struct timespec ts; 6078 uint16_t tmp; 6079 6080 if (bwn_has_hwpctl(mac)) { 6081 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6082 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6083 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6084 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6085 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6086 6087 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6088 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6089 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6090 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6091 } 6092 if (phy->type == BWN_PHYTYPE_B && 6093 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6094 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6095 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6096 } 6097 if (phy->rev >= 2) { 6098 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6099 sav->phy_analogoverval = 6100 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6101 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6102 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6103 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6104 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6105 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6106 6107 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6108 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6109 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6110 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6111 if (phy->type == BWN_PHYTYPE_G) { 6112 if ((phy->rev >= 7) && 6113 (siba_sprom_get_bf_lo(sc->sc_dev) & 6114 BWN_BFL_EXTLNA)) { 6115 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6116 } else { 6117 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6118 } 6119 } else { 6120 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6121 } 6122 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6123 } 6124 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6125 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6126 sav->rf0 = BWN_RF_READ(mac, 0x43); 6127 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6128 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6129 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6130 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6131 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6132 6133 if (!BWN_HAS_TXMAG(phy)) { 6134 sav->rf2 = BWN_RF_READ(mac, 0x52); 6135 sav->rf2 &= 0x00f0; 6136 } 6137 if (phy->type == BWN_PHYTYPE_B) { 6138 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6139 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6140 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6141 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6142 } else { 6143 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6144 | 0x8000); 6145 } 6146 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6147 & 0xf000); 6148 6149 tmp = 6150 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6151 BWN_PHY_WRITE(mac, tmp, 0x007f); 6152 6153 tmp = sav->phy_syncctl; 6154 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6155 tmp = sav->rf1; 6156 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6157 6158 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6159 if (phy->type == BWN_PHYTYPE_G || 6160 (phy->type == BWN_PHYTYPE_B && 6161 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6162 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6163 } else 6164 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6165 if (phy->rev >= 2) 6166 bwn_dummy_transmission(mac, 0, 1); 6167 bwn_phy_g_switch_chan(mac, 6, 0); 6168 BWN_RF_READ(mac, 0x51); 6169 if (phy->type == BWN_PHYTYPE_G) 6170 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6171 6172 nanouptime(&ts); 6173 if (time_before(lo->txctl_measured_time, 6174 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6175 bwn_lo_measure_txctl_values(mac); 6176 6177 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6178 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6179 else { 6180 if (phy->type == BWN_PHYTYPE_B) 6181 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6182 else 6183 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6184 } 6185 } 6186 6187 static void 6188 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6189 { 6190 struct bwn_phy *phy = &mac->mac_phy; 6191 struct bwn_phy_g *pg = &phy->phy_g; 6192 uint16_t tmp; 6193 6194 if (phy->rev >= 2) { 6195 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6196 tmp = (pg->pg_pga_gain << 8); 6197 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6198 DELAY(5); 6199 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6200 DELAY(2); 6201 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6202 } else { 6203 tmp = (pg->pg_pga_gain | 0xefa0); 6204 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6205 } 6206 if (phy->type == BWN_PHYTYPE_G) { 6207 if (phy->rev >= 3) 6208 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6209 else 6210 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6211 if (phy->rev >= 2) 6212 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6213 else 6214 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6215 } 6216 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6217 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6218 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6219 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6220 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6221 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6222 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6223 if (!BWN_HAS_TXMAG(phy)) { 6224 tmp = sav->rf2; 6225 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6226 } 6227 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6228 if (phy->type == BWN_PHYTYPE_B && 6229 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6231 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6232 } 6233 if (phy->rev >= 2) { 6234 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6235 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6236 sav->phy_analogoverval); 6237 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6238 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6239 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6240 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6241 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6242 } 6243 if (bwn_has_hwpctl(mac)) { 6244 tmp = (sav->phy_lomask & 0xbfff); 6245 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6246 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6247 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6248 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6249 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6250 } 6251 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6252 } 6253 6254 static int 6255 bwn_lo_probe_loctl(struct bwn_mac *mac, 6256 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6257 { 6258 struct bwn_phy *phy = &mac->mac_phy; 6259 struct bwn_phy_g *pg = &phy->phy_g; 6260 struct bwn_loctl orig, test; 6261 struct bwn_loctl prev = { -100, -100 }; 6262 static const struct bwn_loctl modifiers[] = { 6263 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6264 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6265 }; 6266 int begin, end, lower = 0, i; 6267 uint16_t feedth; 6268 6269 if (d->curstate == 0) { 6270 begin = 1; 6271 end = 8; 6272 } else if (d->curstate % 2 == 0) { 6273 begin = d->curstate - 1; 6274 end = d->curstate + 1; 6275 } else { 6276 begin = d->curstate - 2; 6277 end = d->curstate + 2; 6278 } 6279 if (begin < 1) 6280 begin += 8; 6281 if (end > 8) 6282 end -= 8; 6283 6284 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6285 i = begin; 6286 d->curstate = i; 6287 while (1) { 6288 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6289 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6290 test.i += modifiers[i - 1].i * d->multipler; 6291 test.q += modifiers[i - 1].q * d->multipler; 6292 if ((test.i != prev.i || test.q != prev.q) && 6293 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6294 bwn_lo_write(mac, &test); 6295 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6296 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6297 if (feedth < d->feedth) { 6298 memcpy(probe, &test, 6299 sizeof(struct bwn_loctl)); 6300 lower = 1; 6301 d->feedth = feedth; 6302 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6303 break; 6304 } 6305 } 6306 memcpy(&prev, &test, sizeof(prev)); 6307 if (i == end) 6308 break; 6309 if (i == 8) 6310 i = 1; 6311 else 6312 i++; 6313 d->curstate = i; 6314 } 6315 6316 return (lower); 6317 } 6318 6319 static void 6320 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6321 { 6322 struct bwn_phy *phy = &mac->mac_phy; 6323 struct bwn_phy_g *pg = &phy->phy_g; 6324 struct bwn_lo_g_sm d; 6325 struct bwn_loctl probe; 6326 int lower, repeat, cnt = 0; 6327 uint16_t feedth; 6328 6329 d.nmeasure = 0; 6330 d.multipler = 1; 6331 if (BWN_HAS_LOOPBACK(phy)) 6332 d.multipler = 3; 6333 6334 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6335 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6336 6337 do { 6338 bwn_lo_write(mac, &d.loctl); 6339 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6340 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6341 if (feedth < 0x258) { 6342 if (feedth >= 0x12c) 6343 *rxgain += 6; 6344 else 6345 *rxgain += 3; 6346 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6347 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6348 } 6349 d.feedth = feedth; 6350 d.curstate = 0; 6351 do { 6352 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6353 ("%s:%d: fail", __func__, __LINE__)); 6354 memcpy(&probe, &d.loctl, 6355 sizeof(struct bwn_loctl)); 6356 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6357 if (!lower) 6358 break; 6359 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6360 break; 6361 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6362 d.nmeasure++; 6363 } while (d.nmeasure < 24); 6364 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6365 6366 if (BWN_HAS_LOOPBACK(phy)) { 6367 if (d.feedth > 0x1194) 6368 *rxgain -= 6; 6369 else if (d.feedth < 0x5dc) 6370 *rxgain += 3; 6371 if (cnt == 0) { 6372 if (d.feedth <= 0x5dc) { 6373 d.multipler = 1; 6374 cnt++; 6375 } else 6376 d.multipler = 2; 6377 } else if (cnt == 2) 6378 d.multipler = 1; 6379 } 6380 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6381 } while (++cnt < repeat); 6382 } 6383 6384 static struct bwn_lo_calib * 6385 bwn_lo_calibset(struct bwn_mac *mac, 6386 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6387 { 6388 struct bwn_phy *phy = &mac->mac_phy; 6389 struct bwn_phy_g *pg = &phy->phy_g; 6390 struct bwn_loctl loctl = { 0, 0 }; 6391 struct bwn_lo_calib *cal; 6392 struct bwn_lo_g_value sval = { 0 }; 6393 int rxgain; 6394 uint16_t pad, reg, value; 6395 6396 sval.old_channel = phy->chan; 6397 bwn_mac_suspend(mac); 6398 bwn_lo_save(mac, &sval); 6399 6400 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6401 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6402 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6403 6404 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6405 if (rfatt->padmix) 6406 rxgain -= pad; 6407 if (BWN_HAS_LOOPBACK(phy)) 6408 rxgain += pg->pg_max_lb_gain; 6409 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6410 bwn_phy_g_set_bbatt(mac, bbatt->att); 6411 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6412 6413 bwn_lo_restore(mac, &sval); 6414 bwn_mac_enable(mac); 6415 6416 cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO); 6417 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6418 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6419 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6420 6421 BWN_GETTIME(cal->calib_time); 6422 6423 return (cal); 6424 } 6425 6426 static struct bwn_lo_calib * 6427 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6428 const struct bwn_rfatt *rfatt) 6429 { 6430 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6431 struct bwn_lo_calib *c; 6432 6433 TAILQ_FOREACH(c, &lo->calib_list, list) { 6434 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6435 continue; 6436 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6437 continue; 6438 return (c); 6439 } 6440 6441 c = bwn_lo_calibset(mac, bbatt, rfatt); 6442 if (c == NULL) /* XXX ivadasz: can't happen */ 6443 return (NULL); 6444 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6445 6446 return (c); 6447 } 6448 6449 static void 6450 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6451 { 6452 struct bwn_phy *phy = &mac->mac_phy; 6453 struct bwn_phy_g *pg = &phy->phy_g; 6454 struct bwn_softc *sc = mac->mac_sc; 6455 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6456 const struct bwn_rfatt *rfatt; 6457 const struct bwn_bbatt *bbatt; 6458 uint64_t pvector; 6459 int i; 6460 int rf_offset, bb_offset; 6461 uint8_t changed = 0; 6462 6463 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6464 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6465 ("%s:%d: fail", __func__, __LINE__)); 6466 6467 pvector = lo->power_vector; 6468 if (!update && !pvector) 6469 return; 6470 6471 bwn_mac_suspend(mac); 6472 6473 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6474 struct bwn_lo_calib *cal; 6475 int idx; 6476 uint16_t val; 6477 6478 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6479 continue; 6480 bb_offset = i / lo->rfatt.len; 6481 rf_offset = i % lo->rfatt.len; 6482 bbatt = &(lo->bbatt.array[bb_offset]); 6483 rfatt = &(lo->rfatt.array[rf_offset]); 6484 6485 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6486 if (cal == NULL) { /* XXX ivadasz: can't happen */ 6487 device_printf(sc->sc_dev, "LO: Could not " 6488 "calibrate DC table entry\n"); 6489 continue; 6490 } 6491 val = (uint8_t)(cal->ctl.q); 6492 val |= ((uint8_t)(cal->ctl.i)) << 4; 6493 kfree(cal, M_DEVBUF); 6494 6495 idx = i / 2; 6496 if (i % 2) 6497 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6498 | ((val & 0x00ff) << 8); 6499 else 6500 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6501 | (val & 0x00ff); 6502 changed = 1; 6503 } 6504 if (changed) { 6505 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6506 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6507 } 6508 bwn_mac_enable(mac); 6509 } 6510 6511 static void 6512 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6513 { 6514 6515 if (!rf->padmix) 6516 return; 6517 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6518 rf->att = 4; 6519 } 6520 6521 static void 6522 bwn_lo_g_adjust(struct bwn_mac *mac) 6523 { 6524 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6525 struct bwn_lo_calib *cal; 6526 struct bwn_rfatt rf; 6527 6528 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6529 bwn_lo_fixup_rfatt(&rf); 6530 6531 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6532 if (cal == NULL) /* XXX ivadasz: can't happen */ 6533 return; 6534 bwn_lo_write(mac, &cal->ctl); 6535 } 6536 6537 static void 6538 bwn_lo_g_init(struct bwn_mac *mac) 6539 { 6540 6541 if (!bwn_has_hwpctl(mac)) 6542 return; 6543 6544 bwn_lo_get_powervector(mac); 6545 bwn_phy_g_dc_lookup_init(mac, 1); 6546 } 6547 6548 static void 6549 bwn_mac_suspend(struct bwn_mac *mac) 6550 { 6551 struct bwn_softc *sc = mac->mac_sc; 6552 int i; 6553 uint32_t tmp; 6554 6555 KASSERT(mac->mac_suspended >= 0, 6556 ("%s:%d: fail", __func__, __LINE__)); 6557 6558 if (mac->mac_suspended == 0) { 6559 bwn_psctl(mac, BWN_PS_AWAKE); 6560 BWN_WRITE_4(mac, BWN_MACCTL, 6561 BWN_READ_4(mac, BWN_MACCTL) 6562 & ~BWN_MACCTL_ON); 6563 BWN_READ_4(mac, BWN_MACCTL); 6564 for (i = 35; i; i--) { 6565 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6566 if (tmp & BWN_INTR_MAC_SUSPENDED) 6567 goto out; 6568 DELAY(10); 6569 } 6570 for (i = 40; i; i--) { 6571 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6572 if (tmp & BWN_INTR_MAC_SUSPENDED) 6573 goto out; 6574 DELAY(1000); 6575 } 6576 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6577 } 6578 out: 6579 mac->mac_suspended++; 6580 } 6581 6582 static void 6583 bwn_mac_enable(struct bwn_mac *mac) 6584 { 6585 struct bwn_softc *sc = mac->mac_sc; 6586 uint16_t state; 6587 6588 state = bwn_shm_read_2(mac, BWN_SHARED, 6589 BWN_SHARED_UCODESTAT); 6590 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6591 state != BWN_SHARED_UCODESTAT_SLEEP) 6592 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6593 6594 mac->mac_suspended--; 6595 KASSERT(mac->mac_suspended >= 0, 6596 ("%s:%d: fail", __func__, __LINE__)); 6597 if (mac->mac_suspended == 0) { 6598 BWN_WRITE_4(mac, BWN_MACCTL, 6599 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6600 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6601 BWN_READ_4(mac, BWN_MACCTL); 6602 BWN_READ_4(mac, BWN_INTR_REASON); 6603 bwn_psctl(mac, 0); 6604 } 6605 } 6606 6607 static void 6608 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6609 { 6610 struct bwn_softc *sc = mac->mac_sc; 6611 int i; 6612 uint16_t ucstat; 6613 6614 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6615 ("%s:%d: fail", __func__, __LINE__)); 6616 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6617 ("%s:%d: fail", __func__, __LINE__)); 6618 6619 /* XXX forcibly awake and hwps-off */ 6620 6621 BWN_WRITE_4(mac, BWN_MACCTL, 6622 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6623 ~BWN_MACCTL_HWPS); 6624 BWN_READ_4(mac, BWN_MACCTL); 6625 if (siba_get_revid(sc->sc_dev) >= 5) { 6626 for (i = 0; i < 100; i++) { 6627 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6628 BWN_SHARED_UCODESTAT); 6629 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6630 break; 6631 DELAY(10); 6632 } 6633 } 6634 } 6635 6636 static int16_t 6637 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6638 { 6639 6640 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6641 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6642 } 6643 6644 static void 6645 bwn_nrssi_threshold(struct bwn_mac *mac) 6646 { 6647 struct bwn_phy *phy = &mac->mac_phy; 6648 struct bwn_phy_g *pg = &phy->phy_g; 6649 struct bwn_softc *sc = mac->mac_sc; 6650 int32_t a, b; 6651 int16_t tmp16; 6652 uint16_t tmpu16; 6653 6654 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6655 6656 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6657 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6658 a = 0x13; 6659 b = 0x12; 6660 } else { 6661 a = 0xe; 6662 b = 0x11; 6663 } 6664 6665 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6666 a += (pg->pg_nrssi[0] << 6); 6667 a += (a < 32) ? 31 : 32; 6668 a = a >> 6; 6669 a = MIN(MAX(a, -31), 31); 6670 6671 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6672 b += (pg->pg_nrssi[0] << 6); 6673 if (b < 32) 6674 b += 31; 6675 else 6676 b += 32; 6677 b = b >> 6; 6678 b = MIN(MAX(b, -31), 31); 6679 6680 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6681 tmpu16 |= ((uint32_t)b & 0x0000003f); 6682 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6683 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6684 return; 6685 } 6686 6687 tmp16 = bwn_nrssi_read(mac, 0x20); 6688 if (tmp16 >= 0x20) 6689 tmp16 -= 0x40; 6690 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6691 } 6692 6693 static void 6694 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6695 { 6696 #define SAVE_RF_MAX 3 6697 #define SAVE_PHY_COMM_MAX 4 6698 #define SAVE_PHY3_MAX 8 6699 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6700 { 0x7a, 0x52, 0x43 }; 6701 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6702 { 0x15, 0x5a, 0x59, 0x58 }; 6703 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6704 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6705 0x0801, 0x0060, 0x0014, 0x0478 6706 }; 6707 struct bwn_phy *phy = &mac->mac_phy; 6708 struct bwn_phy_g *pg = &phy->phy_g; 6709 int32_t i, tmp32, phy3_idx = 0; 6710 uint16_t delta, tmp; 6711 uint16_t save_rf[SAVE_RF_MAX]; 6712 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6713 uint16_t save_phy3[SAVE_PHY3_MAX]; 6714 uint16_t ant_div, phy0, chan_ex; 6715 int16_t nrssi0, nrssi1; 6716 6717 KASSERT(phy->type == BWN_PHYTYPE_G, 6718 ("%s:%d: fail", __func__, __LINE__)); 6719 6720 if (phy->rf_rev >= 9) 6721 return; 6722 if (phy->rf_rev == 8) 6723 bwn_nrssi_offset(mac); 6724 6725 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6726 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6727 6728 /* 6729 * Save RF/PHY registers for later restoration 6730 */ 6731 ant_div = BWN_READ_2(mac, 0x03e2); 6732 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6733 for (i = 0; i < SAVE_RF_MAX; ++i) 6734 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6735 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6736 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6737 6738 phy0 = BWN_READ_2(mac, BWN_PHY0); 6739 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6740 if (phy->rev >= 3) { 6741 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6742 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6743 BWN_PHY_WRITE(mac, 0x002e, 0); 6744 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6745 switch (phy->rev) { 6746 case 4: 6747 case 6: 6748 case 7: 6749 BWN_PHY_SET(mac, 0x0478, 0x0100); 6750 BWN_PHY_SET(mac, 0x0801, 0x0040); 6751 break; 6752 case 3: 6753 case 5: 6754 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6755 break; 6756 } 6757 BWN_PHY_SET(mac, 0x0060, 0x0040); 6758 BWN_PHY_SET(mac, 0x0014, 0x0200); 6759 } 6760 /* 6761 * Calculate nrssi0 6762 */ 6763 BWN_RF_SET(mac, 0x007a, 0x0070); 6764 bwn_set_all_gains(mac, 0, 8, 0); 6765 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6766 if (phy->rev >= 2) { 6767 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6768 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6769 } 6770 BWN_RF_SET(mac, 0x007a, 0x0080); 6771 DELAY(20); 6772 6773 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6774 if (nrssi0 >= 0x0020) 6775 nrssi0 -= 0x0040; 6776 6777 /* 6778 * Calculate nrssi1 6779 */ 6780 BWN_RF_MASK(mac, 0x007a, 0x007f); 6781 if (phy->rev >= 2) 6782 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6783 6784 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6785 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6786 BWN_RF_SET(mac, 0x007a, 0x000f); 6787 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6788 if (phy->rev >= 2) { 6789 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6790 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6791 } 6792 6793 bwn_set_all_gains(mac, 3, 0, 1); 6794 if (phy->rf_rev == 8) { 6795 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6796 } else { 6797 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6798 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6799 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6800 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6801 } 6802 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6803 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6804 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6805 DELAY(20); 6806 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6807 6808 /* 6809 * Install calculated narrow RSSI values 6810 */ 6811 if (nrssi1 >= 0x0020) 6812 nrssi1 -= 0x0040; 6813 if (nrssi0 == nrssi1) 6814 pg->pg_nrssi_slope = 0x00010000; 6815 else 6816 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6817 if (nrssi0 >= -4) { 6818 pg->pg_nrssi[0] = nrssi1; 6819 pg->pg_nrssi[1] = nrssi0; 6820 } 6821 6822 /* 6823 * Restore saved RF/PHY registers 6824 */ 6825 if (phy->rev >= 3) { 6826 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6827 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6828 save_phy3[phy3_idx]); 6829 } 6830 } 6831 if (phy->rev >= 2) { 6832 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6833 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6834 } 6835 6836 for (i = 0; i < SAVE_RF_MAX; ++i) 6837 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6838 6839 BWN_WRITE_2(mac, 0x03e2, ant_div); 6840 BWN_WRITE_2(mac, 0x03e6, phy0); 6841 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6842 6843 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6844 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6845 6846 bwn_spu_workaround(mac, phy->chan); 6847 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6848 bwn_set_original_gains(mac); 6849 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6850 if (phy->rev >= 3) { 6851 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6852 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6853 save_phy3[phy3_idx]); 6854 } 6855 } 6856 6857 delta = 0x1f - pg->pg_nrssi[0]; 6858 for (i = 0; i < 64; i++) { 6859 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6860 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6861 pg->pg_nrssi_lt[i] = tmp32; 6862 } 6863 6864 bwn_nrssi_threshold(mac); 6865 #undef SAVE_RF_MAX 6866 #undef SAVE_PHY_COMM_MAX 6867 #undef SAVE_PHY3_MAX 6868 } 6869 6870 static void 6871 bwn_nrssi_offset(struct bwn_mac *mac) 6872 { 6873 #define SAVE_RF_MAX 2 6874 #define SAVE_PHY_COMM_MAX 10 6875 #define SAVE_PHY6_MAX 8 6876 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6877 { 0x7a, 0x43 }; 6878 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6879 0x0001, 0x0811, 0x0812, 0x0814, 6880 0x0815, 0x005a, 0x0059, 0x0058, 6881 0x000a, 0x0003 6882 }; 6883 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6884 0x002e, 0x002f, 0x080f, 0x0810, 6885 0x0801, 0x0060, 0x0014, 0x0478 6886 }; 6887 struct bwn_phy *phy = &mac->mac_phy; 6888 int i, phy6_idx = 0; 6889 uint16_t save_rf[SAVE_RF_MAX]; 6890 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6891 uint16_t save_phy6[SAVE_PHY6_MAX]; 6892 int16_t nrssi; 6893 uint16_t saved = 0xffff; 6894 6895 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6896 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6897 for (i = 0; i < SAVE_RF_MAX; ++i) 6898 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6899 6900 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6901 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6902 BWN_PHY_SET(mac, 0x0811, 0x000c); 6903 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6904 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6905 if (phy->rev >= 6) { 6906 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6907 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6908 6909 BWN_PHY_WRITE(mac, 0x002e, 0); 6910 BWN_PHY_WRITE(mac, 0x002f, 0); 6911 BWN_PHY_WRITE(mac, 0x080f, 0); 6912 BWN_PHY_WRITE(mac, 0x0810, 0); 6913 BWN_PHY_SET(mac, 0x0478, 0x0100); 6914 BWN_PHY_SET(mac, 0x0801, 0x0040); 6915 BWN_PHY_SET(mac, 0x0060, 0x0040); 6916 BWN_PHY_SET(mac, 0x0014, 0x0200); 6917 } 6918 BWN_RF_SET(mac, 0x007a, 0x0070); 6919 BWN_RF_SET(mac, 0x007a, 0x0080); 6920 DELAY(30); 6921 6922 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6923 if (nrssi >= 0x20) 6924 nrssi -= 0x40; 6925 if (nrssi == 31) { 6926 for (i = 7; i >= 4; i--) { 6927 BWN_RF_WRITE(mac, 0x007b, i); 6928 DELAY(20); 6929 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 6930 0x003f); 6931 if (nrssi >= 0x20) 6932 nrssi -= 0x40; 6933 if (nrssi < 31 && saved == 0xffff) 6934 saved = i; 6935 } 6936 if (saved == 0xffff) 6937 saved = 4; 6938 } else { 6939 BWN_RF_MASK(mac, 0x007a, 0x007f); 6940 if (phy->rev != 1) { 6941 BWN_PHY_SET(mac, 0x0814, 0x0001); 6942 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 6943 } 6944 BWN_PHY_SET(mac, 0x0811, 0x000c); 6945 BWN_PHY_SET(mac, 0x0812, 0x000c); 6946 BWN_PHY_SET(mac, 0x0811, 0x0030); 6947 BWN_PHY_SET(mac, 0x0812, 0x0030); 6948 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6949 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6950 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6951 if (phy->rev == 0) 6952 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 6953 else 6954 BWN_PHY_SET(mac, 0x000a, 0x2000); 6955 if (phy->rev != 1) { 6956 BWN_PHY_SET(mac, 0x0814, 0x0004); 6957 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 6958 } 6959 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6960 BWN_RF_SET(mac, 0x007a, 0x000f); 6961 bwn_set_all_gains(mac, 3, 0, 1); 6962 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 6963 DELAY(30); 6964 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6965 if (nrssi >= 0x20) 6966 nrssi -= 0x40; 6967 if (nrssi == -32) { 6968 for (i = 0; i < 4; i++) { 6969 BWN_RF_WRITE(mac, 0x007b, i); 6970 DELAY(20); 6971 nrssi = (int16_t)((BWN_PHY_READ(mac, 6972 0x047f) >> 8) & 0x003f); 6973 if (nrssi >= 0x20) 6974 nrssi -= 0x40; 6975 if (nrssi > -31 && saved == 0xffff) 6976 saved = i; 6977 } 6978 if (saved == 0xffff) 6979 saved = 3; 6980 } else 6981 saved = 0; 6982 } 6983 BWN_RF_WRITE(mac, 0x007b, saved); 6984 6985 /* 6986 * Restore saved RF/PHY registers 6987 */ 6988 if (phy->rev >= 6) { 6989 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 6990 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6991 save_phy6[phy6_idx]); 6992 } 6993 } 6994 if (phy->rev != 1) { 6995 for (i = 3; i < 5; i++) 6996 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 6997 save_phy_comm[i]); 6998 } 6999 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7000 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7001 7002 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7003 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7004 7005 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7006 BWN_PHY_SET(mac, 0x0429, 0x8000); 7007 bwn_set_original_gains(mac); 7008 if (phy->rev >= 6) { 7009 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7010 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7011 save_phy6[phy6_idx]); 7012 } 7013 } 7014 7015 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7016 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7017 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7018 } 7019 7020 static void 7021 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7022 int16_t third) 7023 { 7024 struct bwn_phy *phy = &mac->mac_phy; 7025 uint16_t i; 7026 uint16_t start = 0x08, end = 0x18; 7027 uint16_t tmp; 7028 uint16_t table; 7029 7030 if (phy->rev <= 1) { 7031 start = 0x10; 7032 end = 0x20; 7033 } 7034 7035 table = BWN_OFDMTAB_GAINX; 7036 if (phy->rev <= 1) 7037 table = BWN_OFDMTAB_GAINX_R1; 7038 for (i = 0; i < 4; i++) 7039 bwn_ofdmtab_write_2(mac, table, i, first); 7040 7041 for (i = start; i < end; i++) 7042 bwn_ofdmtab_write_2(mac, table, i, second); 7043 7044 if (third != -1) { 7045 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7046 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7047 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7048 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7049 } 7050 bwn_dummy_transmission(mac, 0, 1); 7051 } 7052 7053 static void 7054 bwn_set_original_gains(struct bwn_mac *mac) 7055 { 7056 struct bwn_phy *phy = &mac->mac_phy; 7057 uint16_t i, tmp; 7058 uint16_t table; 7059 uint16_t start = 0x0008, end = 0x0018; 7060 7061 if (phy->rev <= 1) { 7062 start = 0x0010; 7063 end = 0x0020; 7064 } 7065 7066 table = BWN_OFDMTAB_GAINX; 7067 if (phy->rev <= 1) 7068 table = BWN_OFDMTAB_GAINX_R1; 7069 for (i = 0; i < 4; i++) { 7070 tmp = (i & 0xfffc); 7071 tmp |= (i & 0x0001) << 1; 7072 tmp |= (i & 0x0002) >> 1; 7073 7074 bwn_ofdmtab_write_2(mac, table, i, tmp); 7075 } 7076 7077 for (i = start; i < end; i++) 7078 bwn_ofdmtab_write_2(mac, table, i, i - start); 7079 7080 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7081 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7082 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7083 bwn_dummy_transmission(mac, 0, 1); 7084 } 7085 7086 static void 7087 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7088 { 7089 struct bwn_phy *phy = &mac->mac_phy; 7090 struct bwn_phy_g *pg = &phy->phy_g; 7091 struct bwn_rfatt old_rfatt, rfatt; 7092 struct bwn_bbatt old_bbatt, bbatt; 7093 struct bwn_softc *sc = mac->mac_sc; 7094 uint8_t old_txctl = 0; 7095 7096 KASSERT(phy->type == BWN_PHYTYPE_G, 7097 ("%s:%d: fail", __func__, __LINE__)); 7098 7099 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7100 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7101 return; 7102 7103 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7104 7105 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7106 7107 if (!phy->gmode) 7108 return; 7109 bwn_hwpctl_early_init(mac); 7110 if (pg->pg_curtssi == 0) { 7111 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7112 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7113 } else { 7114 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7115 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7116 old_txctl = pg->pg_txctl; 7117 7118 bbatt.att = 11; 7119 if (phy->rf_rev == 8) { 7120 rfatt.att = 15; 7121 rfatt.padmix = 1; 7122 } else { 7123 rfatt.att = 9; 7124 rfatt.padmix = 0; 7125 } 7126 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7127 } 7128 bwn_dummy_transmission(mac, 0, 1); 7129 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7130 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7131 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7132 else 7133 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7134 &old_rfatt, old_txctl); 7135 } 7136 bwn_hwpctl_init_gphy(mac); 7137 7138 /* clear TSSI */ 7139 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7140 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7141 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7142 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7143 } 7144 7145 static void 7146 bwn_hwpctl_early_init(struct bwn_mac *mac) 7147 { 7148 struct bwn_phy *phy = &mac->mac_phy; 7149 7150 if (!bwn_has_hwpctl(mac)) { 7151 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7152 return; 7153 } 7154 7155 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7156 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7157 BWN_PHY_SET(mac, 0x047c, 0x0002); 7158 BWN_PHY_SET(mac, 0x047a, 0xf000); 7159 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7160 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7161 BWN_PHY_SET(mac, 0x005d, 0x8000); 7162 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7163 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7164 BWN_PHY_SET(mac, 0x0036, 0x0400); 7165 } else { 7166 BWN_PHY_SET(mac, 0x0036, 0x0200); 7167 BWN_PHY_SET(mac, 0x0036, 0x0400); 7168 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7169 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7170 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7171 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7172 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7173 } 7174 } 7175 7176 static void 7177 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7178 { 7179 struct bwn_phy *phy = &mac->mac_phy; 7180 struct bwn_phy_g *pg = &phy->phy_g; 7181 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7182 int i; 7183 uint16_t nr_written = 0, tmp, value; 7184 uint8_t rf, bb; 7185 7186 if (!bwn_has_hwpctl(mac)) { 7187 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7188 return; 7189 } 7190 7191 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7192 (pg->pg_idletssi - pg->pg_curtssi)); 7193 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7194 (pg->pg_idletssi - pg->pg_curtssi)); 7195 7196 for (i = 0; i < 32; i++) 7197 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7198 for (i = 32; i < 64; i++) 7199 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7200 for (i = 0; i < 64; i += 2) { 7201 value = (uint16_t) pg->pg_tssi2dbm[i]; 7202 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7203 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7204 } 7205 7206 for (rf = 0; rf < lo->rfatt.len; rf++) { 7207 for (bb = 0; bb < lo->bbatt.len; bb++) { 7208 if (nr_written >= 0x40) 7209 return; 7210 tmp = lo->bbatt.array[bb].att; 7211 tmp <<= 8; 7212 if (phy->rf_rev == 8) 7213 tmp |= 0x50; 7214 else 7215 tmp |= 0x40; 7216 tmp |= lo->rfatt.array[rf].att; 7217 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7218 nr_written++; 7219 } 7220 } 7221 7222 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7223 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7224 7225 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7226 BWN_PHY_SET(mac, 0x0478, 0x0800); 7227 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7228 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7229 7230 bwn_phy_g_dc_lookup_init(mac, 1); 7231 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7232 } 7233 7234 static void 7235 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7236 { 7237 struct bwn_softc *sc = mac->mac_sc; 7238 7239 if (spu != 0) 7240 bwn_spu_workaround(mac, channel); 7241 7242 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7243 7244 if (channel == 14) { 7245 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7246 bwn_hf_write(mac, 7247 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7248 else 7249 bwn_hf_write(mac, 7250 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7251 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7252 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7253 return; 7254 } 7255 7256 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7257 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7258 } 7259 7260 static uint16_t 7261 bwn_phy_g_chan2freq(uint8_t channel) 7262 { 7263 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7264 7265 KASSERT(channel >= 1 && channel <= 14, 7266 ("%s:%d: fail", __func__, __LINE__)); 7267 7268 return (bwn_phy_g_rf_channels[channel - 1]); 7269 } 7270 7271 static void 7272 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7273 const struct bwn_rfatt *rfatt, uint8_t txctl) 7274 { 7275 struct bwn_phy *phy = &mac->mac_phy; 7276 struct bwn_phy_g *pg = &phy->phy_g; 7277 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7278 uint16_t bb, rf; 7279 uint16_t tx_bias, tx_magn; 7280 7281 bb = bbatt->att; 7282 rf = rfatt->att; 7283 tx_bias = lo->tx_bias; 7284 tx_magn = lo->tx_magn; 7285 if (tx_bias == 0xff) 7286 tx_bias = 0; 7287 7288 pg->pg_txctl = txctl; 7289 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7290 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7291 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7292 bwn_phy_g_set_bbatt(mac, bb); 7293 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7294 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7295 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7296 else { 7297 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7298 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7299 } 7300 if (BWN_HAS_TXMAG(phy)) 7301 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7302 else 7303 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7304 bwn_lo_g_adjust(mac); 7305 } 7306 7307 static void 7308 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7309 uint16_t bbatt) 7310 { 7311 struct bwn_phy *phy = &mac->mac_phy; 7312 7313 if (phy->analog == 0) { 7314 BWN_WRITE_2(mac, BWN_PHY0, 7315 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7316 return; 7317 } 7318 if (phy->analog > 1) { 7319 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7320 return; 7321 } 7322 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7323 } 7324 7325 static uint16_t 7326 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7327 { 7328 struct bwn_phy *phy = &mac->mac_phy; 7329 struct bwn_phy_g *pg = &phy->phy_g; 7330 struct bwn_softc *sc = mac->mac_sc; 7331 int max_lb_gain; 7332 uint16_t extlna; 7333 uint16_t i; 7334 7335 if (phy->gmode == 0) 7336 return (0); 7337 7338 if (BWN_HAS_LOOPBACK(phy)) { 7339 max_lb_gain = pg->pg_max_lb_gain; 7340 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7341 if (max_lb_gain >= 0x46) { 7342 extlna = 0x3000; 7343 max_lb_gain -= 0x46; 7344 } else if (max_lb_gain >= 0x3a) { 7345 extlna = 0x1000; 7346 max_lb_gain -= 0x3a; 7347 } else if (max_lb_gain >= 0x2e) { 7348 extlna = 0x2000; 7349 max_lb_gain -= 0x2e; 7350 } else { 7351 extlna = 0; 7352 max_lb_gain -= 0x10; 7353 } 7354 7355 for (i = 0; i < 16; i++) { 7356 max_lb_gain -= (i * 6); 7357 if (max_lb_gain < 6) 7358 break; 7359 } 7360 7361 if ((phy->rev < 7) || 7362 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7363 if (reg == BWN_PHY_RFOVER) { 7364 return (0x1b3); 7365 } else if (reg == BWN_PHY_RFOVERVAL) { 7366 extlna |= (i << 8); 7367 switch (lpd) { 7368 case BWN_LPD(0, 1, 1): 7369 return (0x0f92); 7370 case BWN_LPD(0, 0, 1): 7371 case BWN_LPD(1, 0, 1): 7372 return (0x0092 | extlna); 7373 case BWN_LPD(1, 0, 0): 7374 return (0x0093 | extlna); 7375 } 7376 KASSERT(0 == 1, 7377 ("%s:%d: fail", __func__, __LINE__)); 7378 } 7379 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7380 } else { 7381 if (reg == BWN_PHY_RFOVER) 7382 return (0x9b3); 7383 if (reg == BWN_PHY_RFOVERVAL) { 7384 if (extlna) 7385 extlna |= 0x8000; 7386 extlna |= (i << 8); 7387 switch (lpd) { 7388 case BWN_LPD(0, 1, 1): 7389 return (0x8f92); 7390 case BWN_LPD(0, 0, 1): 7391 return (0x8092 | extlna); 7392 case BWN_LPD(1, 0, 1): 7393 return (0x2092 | extlna); 7394 case BWN_LPD(1, 0, 0): 7395 return (0x2093 | extlna); 7396 } 7397 KASSERT(0 == 1, 7398 ("%s:%d: fail", __func__, __LINE__)); 7399 } 7400 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7401 } 7402 return (0); 7403 } 7404 7405 if ((phy->rev < 7) || 7406 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7407 if (reg == BWN_PHY_RFOVER) { 7408 return (0x1b3); 7409 } else if (reg == BWN_PHY_RFOVERVAL) { 7410 switch (lpd) { 7411 case BWN_LPD(0, 1, 1): 7412 return (0x0fb2); 7413 case BWN_LPD(0, 0, 1): 7414 return (0x00b2); 7415 case BWN_LPD(1, 0, 1): 7416 return (0x30b2); 7417 case BWN_LPD(1, 0, 0): 7418 return (0x30b3); 7419 } 7420 KASSERT(0 == 1, 7421 ("%s:%d: fail", __func__, __LINE__)); 7422 } 7423 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7424 } else { 7425 if (reg == BWN_PHY_RFOVER) { 7426 return (0x9b3); 7427 } else if (reg == BWN_PHY_RFOVERVAL) { 7428 switch (lpd) { 7429 case BWN_LPD(0, 1, 1): 7430 return (0x8fb2); 7431 case BWN_LPD(0, 0, 1): 7432 return (0x80b2); 7433 case BWN_LPD(1, 0, 1): 7434 return (0x20b2); 7435 case BWN_LPD(1, 0, 0): 7436 return (0x20b3); 7437 } 7438 KASSERT(0 == 1, 7439 ("%s:%d: fail", __func__, __LINE__)); 7440 } 7441 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7442 } 7443 return (0); 7444 } 7445 7446 static void 7447 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7448 { 7449 7450 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7451 return; 7452 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7453 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7454 DELAY(1000); 7455 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7456 } 7457 7458 static int 7459 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7460 { 7461 struct bwn_softc *sc = mac->mac_sc; 7462 struct bwn_fw *fw = &mac->mac_fw; 7463 const uint8_t rev = siba_get_revid(sc->sc_dev); 7464 const char *filename; 7465 uint32_t high; 7466 int error; 7467 7468 /* microcode */ 7469 if (rev >= 5 && rev <= 10) 7470 filename = "ucode5"; 7471 else if (rev >= 11 && rev <= 12) 7472 filename = "ucode11"; 7473 else if (rev == 13) 7474 filename = "ucode13"; 7475 else if (rev == 14) 7476 filename = "ucode14"; 7477 else if (rev >= 15) 7478 filename = "ucode15"; 7479 else { 7480 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7481 bwn_release_firmware(mac); 7482 return (EOPNOTSUPP); 7483 } 7484 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7485 if (error) { 7486 bwn_release_firmware(mac); 7487 return (error); 7488 } 7489 7490 /* PCM */ 7491 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7492 if (rev >= 5 && rev <= 10) { 7493 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7494 if (error == ENOENT) 7495 fw->no_pcmfile = 1; 7496 else if (error) { 7497 bwn_release_firmware(mac); 7498 return (error); 7499 } 7500 } else if (rev < 11) { 7501 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7502 return (EOPNOTSUPP); 7503 } 7504 7505 /* initvals */ 7506 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7507 switch (mac->mac_phy.type) { 7508 case BWN_PHYTYPE_A: 7509 if (rev < 5 || rev > 10) 7510 goto fail1; 7511 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7512 filename = "a0g1initvals5"; 7513 else 7514 filename = "a0g0initvals5"; 7515 break; 7516 case BWN_PHYTYPE_G: 7517 if (rev >= 5 && rev <= 10) 7518 filename = "b0g0initvals5"; 7519 else if (rev >= 13) 7520 filename = "b0g0initvals13"; 7521 else 7522 goto fail1; 7523 break; 7524 case BWN_PHYTYPE_LP: 7525 if (rev == 13) 7526 filename = "lp0initvals13"; 7527 else if (rev == 14) 7528 filename = "lp0initvals14"; 7529 else if (rev >= 15) 7530 filename = "lp0initvals15"; 7531 else 7532 goto fail1; 7533 break; 7534 case BWN_PHYTYPE_N: 7535 if (rev >= 11 && rev <= 12) 7536 filename = "n0initvals11"; 7537 else 7538 goto fail1; 7539 break; 7540 default: 7541 goto fail1; 7542 } 7543 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7544 if (error) { 7545 bwn_release_firmware(mac); 7546 return (error); 7547 } 7548 7549 /* bandswitch initvals */ 7550 switch (mac->mac_phy.type) { 7551 case BWN_PHYTYPE_A: 7552 if (rev >= 5 && rev <= 10) { 7553 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7554 filename = "a0g1bsinitvals5"; 7555 else 7556 filename = "a0g0bsinitvals5"; 7557 } else if (rev >= 11) 7558 filename = NULL; 7559 else 7560 goto fail1; 7561 break; 7562 case BWN_PHYTYPE_G: 7563 if (rev >= 5 && rev <= 10) 7564 filename = "b0g0bsinitvals5"; 7565 else if (rev >= 11) 7566 filename = NULL; 7567 else 7568 goto fail1; 7569 break; 7570 case BWN_PHYTYPE_LP: 7571 if (rev == 13) 7572 filename = "lp0bsinitvals13"; 7573 else if (rev == 14) 7574 filename = "lp0bsinitvals14"; 7575 else if (rev >= 15) 7576 filename = "lp0bsinitvals15"; 7577 else 7578 goto fail1; 7579 break; 7580 case BWN_PHYTYPE_N: 7581 if (rev >= 11 && rev <= 12) 7582 filename = "n0bsinitvals11"; 7583 else 7584 goto fail1; 7585 break; 7586 default: 7587 goto fail1; 7588 } 7589 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7590 if (error) { 7591 bwn_release_firmware(mac); 7592 return (error); 7593 } 7594 return (0); 7595 fail1: 7596 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7597 bwn_release_firmware(mac); 7598 return (EOPNOTSUPP); 7599 } 7600 7601 static int 7602 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7603 const char *name, struct bwn_fwfile *bfw) 7604 { 7605 const struct bwn_fwhdr *hdr; 7606 struct bwn_softc *sc = mac->mac_sc; 7607 const struct firmware *fw; 7608 char namebuf[64]; 7609 7610 if (name == NULL) { 7611 bwn_do_release_fw(bfw); 7612 return (0); 7613 } 7614 if (bfw->filename != NULL) { 7615 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7616 return (0); 7617 bwn_do_release_fw(bfw); 7618 } 7619 7620 ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7621 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7622 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7623 wlan_assert_serialized(); 7624 wlan_serialize_exit(); 7625 fw = firmware_get(namebuf); 7626 wlan_serialize_enter(); 7627 if (fw == NULL) { 7628 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7629 namebuf); 7630 return (ENOENT); 7631 } 7632 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7633 goto fail; 7634 hdr = (const struct bwn_fwhdr *)(fw->data); 7635 switch (hdr->type) { 7636 case BWN_FWTYPE_UCODE: 7637 case BWN_FWTYPE_PCM: 7638 if (be32toh(hdr->size) != 7639 (fw->datasize - sizeof(struct bwn_fwhdr))) 7640 goto fail; 7641 /* FALLTHROUGH */ 7642 case BWN_FWTYPE_IV: 7643 if (hdr->ver != 1) 7644 goto fail; 7645 break; 7646 default: 7647 goto fail; 7648 } 7649 bfw->filename = name; 7650 bfw->fw = fw; 7651 bfw->type = type; 7652 return (0); 7653 fail: 7654 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7655 if (fw != NULL) 7656 firmware_put(fw, FIRMWARE_UNLOAD); 7657 return (EPROTO); 7658 } 7659 7660 static void 7661 bwn_release_firmware(struct bwn_mac *mac) 7662 { 7663 7664 bwn_do_release_fw(&mac->mac_fw.ucode); 7665 bwn_do_release_fw(&mac->mac_fw.pcm); 7666 bwn_do_release_fw(&mac->mac_fw.initvals); 7667 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7668 } 7669 7670 static void 7671 bwn_do_release_fw(struct bwn_fwfile *bfw) 7672 { 7673 7674 if (bfw->fw != NULL) 7675 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7676 bfw->fw = NULL; 7677 bfw->filename = NULL; 7678 } 7679 7680 static int 7681 bwn_fw_loaducode(struct bwn_mac *mac) 7682 { 7683 #define GETFWOFFSET(fwp, offset) \ 7684 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7685 #define GETFWSIZE(fwp, offset) \ 7686 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7687 struct bwn_softc *sc = mac->mac_sc; 7688 const uint32_t *data; 7689 unsigned int i; 7690 uint32_t ctl; 7691 uint16_t date, fwcaps, time; 7692 int error = 0; 7693 7694 ctl = BWN_READ_4(mac, BWN_MACCTL); 7695 ctl |= BWN_MACCTL_MCODE_JMP0; 7696 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7697 __LINE__)); 7698 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7699 for (i = 0; i < 64; i++) 7700 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7701 for (i = 0; i < 4096; i += 2) 7702 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7703 7704 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7705 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7706 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7707 i++) { 7708 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7709 DELAY(10); 7710 } 7711 7712 if (mac->mac_fw.pcm.fw) { 7713 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7714 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7715 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7716 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7717 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7718 sizeof(struct bwn_fwhdr)); i++) { 7719 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7720 DELAY(10); 7721 } 7722 } 7723 7724 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7725 BWN_WRITE_4(mac, BWN_MACCTL, 7726 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7727 BWN_MACCTL_MCODE_RUN); 7728 7729 for (i = 0; i < 21; i++) { 7730 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7731 break; 7732 if (i >= 20) { 7733 device_printf(sc->sc_dev, "ucode timeout\n"); 7734 error = ENXIO; 7735 goto error; 7736 } 7737 DELAY(50000); 7738 } 7739 BWN_READ_4(mac, BWN_INTR_REASON); 7740 7741 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7742 if (mac->mac_fw.rev <= 0x128) { 7743 device_printf(sc->sc_dev, "the firmware is too old\n"); 7744 error = EOPNOTSUPP; 7745 goto error; 7746 } 7747 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7748 BWN_SHARED_UCODE_PATCH); 7749 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7750 mac->mac_fw.opensource = (date == 0xffff); 7751 if (bwn_wme != 0) 7752 mac->mac_flags |= BWN_MAC_FLAG_WME; 7753 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7754 7755 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7756 if (mac->mac_fw.opensource == 0) { 7757 device_printf(sc->sc_dev, 7758 "firmware version (rev %u patch %u date %#x time %#x)\n", 7759 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7760 if (mac->mac_fw.no_pcmfile) 7761 device_printf(sc->sc_dev, 7762 "no HW crypto acceleration due to pcm5\n"); 7763 } else { 7764 mac->mac_fw.patch = time; 7765 fwcaps = bwn_fwcaps_read(mac); 7766 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7767 device_printf(sc->sc_dev, 7768 "disabling HW crypto acceleration\n"); 7769 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7770 } 7771 if (!(fwcaps & BWN_FWCAPS_WME)) { 7772 device_printf(sc->sc_dev, "disabling WME support\n"); 7773 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7774 } 7775 } 7776 7777 if (BWN_ISOLDFMT(mac)) 7778 device_printf(sc->sc_dev, "using old firmware image\n"); 7779 7780 return (0); 7781 7782 error: 7783 BWN_WRITE_4(mac, BWN_MACCTL, 7784 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7785 BWN_MACCTL_MCODE_JMP0); 7786 7787 return (error); 7788 #undef GETFWSIZE 7789 #undef GETFWOFFSET 7790 } 7791 7792 /* OpenFirmware only */ 7793 static uint16_t 7794 bwn_fwcaps_read(struct bwn_mac *mac) 7795 { 7796 7797 KASSERT(mac->mac_fw.opensource == 1, 7798 ("%s:%d: fail", __func__, __LINE__)); 7799 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7800 } 7801 7802 static int 7803 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7804 size_t count, size_t array_size) 7805 { 7806 #define GET_NEXTIV16(iv) \ 7807 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7808 sizeof(uint16_t) + sizeof(uint16_t))) 7809 #define GET_NEXTIV32(iv) \ 7810 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7811 sizeof(uint16_t) + sizeof(uint32_t))) 7812 struct bwn_softc *sc = mac->mac_sc; 7813 const struct bwn_fwinitvals *iv; 7814 uint16_t offset; 7815 size_t i; 7816 uint8_t bit32; 7817 7818 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7819 ("%s:%d: fail", __func__, __LINE__)); 7820 iv = ivals; 7821 for (i = 0; i < count; i++) { 7822 if (array_size < sizeof(iv->offset_size)) 7823 goto fail; 7824 array_size -= sizeof(iv->offset_size); 7825 offset = be16toh(iv->offset_size); 7826 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7827 offset &= BWN_FWINITVALS_OFFSET_MASK; 7828 if (offset >= 0x1000) 7829 goto fail; 7830 if (bit32) { 7831 if (array_size < sizeof(iv->data.d32)) 7832 goto fail; 7833 array_size -= sizeof(iv->data.d32); 7834 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7835 iv = GET_NEXTIV32(iv); 7836 } else { 7837 7838 if (array_size < sizeof(iv->data.d16)) 7839 goto fail; 7840 array_size -= sizeof(iv->data.d16); 7841 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7842 7843 iv = GET_NEXTIV16(iv); 7844 } 7845 } 7846 if (array_size != 0) 7847 goto fail; 7848 return (0); 7849 fail: 7850 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7851 return (EPROTO); 7852 #undef GET_NEXTIV16 7853 #undef GET_NEXTIV32 7854 } 7855 7856 static int 7857 bwn_switch_channel(struct bwn_mac *mac, int chan) 7858 { 7859 struct bwn_phy *phy = &(mac->mac_phy); 7860 struct bwn_softc *sc = mac->mac_sc; 7861 struct ifnet *ifp = sc->sc_ifp; 7862 struct ieee80211com *ic = ifp->if_l2com; 7863 uint16_t channelcookie, savedcookie; 7864 int error; 7865 7866 if (chan == 0xffff) 7867 chan = phy->get_default_chan(mac); 7868 7869 channelcookie = chan; 7870 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7871 channelcookie |= 0x100; 7872 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7873 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7874 error = phy->switch_channel(mac, chan); 7875 if (error) 7876 goto fail; 7877 7878 mac->mac_phy.chan = chan; 7879 DELAY(8000); 7880 return (0); 7881 fail: 7882 device_printf(sc->sc_dev, "failed to switch channel\n"); 7883 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7884 return (error); 7885 } 7886 7887 static uint16_t 7888 bwn_ant2phy(int antenna) 7889 { 7890 7891 switch (antenna) { 7892 case BWN_ANT0: 7893 return (BWN_TX_PHY_ANT0); 7894 case BWN_ANT1: 7895 return (BWN_TX_PHY_ANT1); 7896 case BWN_ANT2: 7897 return (BWN_TX_PHY_ANT2); 7898 case BWN_ANT3: 7899 return (BWN_TX_PHY_ANT3); 7900 case BWN_ANTAUTO: 7901 return (BWN_TX_PHY_ANT01AUTO); 7902 } 7903 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7904 return (0); 7905 } 7906 7907 static void 7908 bwn_wme_load(struct bwn_mac *mac) 7909 { 7910 struct bwn_softc *sc = mac->mac_sc; 7911 int i; 7912 7913 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7914 ("%s:%d: fail", __func__, __LINE__)); 7915 7916 bwn_mac_suspend(mac); 7917 for (i = 0; i < N(sc->sc_wmeParams); i++) 7918 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 7919 bwn_wme_shm_offsets[i]); 7920 bwn_mac_enable(mac); 7921 } 7922 7923 static void 7924 bwn_wme_loadparams(struct bwn_mac *mac, 7925 const struct wmeParams *p, uint16_t shm_offset) 7926 { 7927 #define SM(_v, _f) (((_v) << _f##_S) & _f) 7928 struct bwn_softc *sc = mac->mac_sc; 7929 uint16_t params[BWN_NR_WMEPARAMS]; 7930 int slot, tmp; 7931 unsigned int i; 7932 7933 slot = BWN_READ_2(mac, BWN_RNG) & 7934 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7935 7936 memset(¶ms, 0, sizeof(params)); 7937 7938 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 7939 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 7940 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 7941 7942 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 7943 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7944 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 7945 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7946 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 7947 params[BWN_WMEPARAM_BSLOTS] = slot; 7948 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 7949 7950 for (i = 0; i < N(params); i++) { 7951 if (i == BWN_WMEPARAM_STATUS) { 7952 tmp = bwn_shm_read_2(mac, BWN_SHARED, 7953 shm_offset + (i * 2)); 7954 tmp |= 0x100; 7955 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7956 tmp); 7957 } else { 7958 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7959 params[i]); 7960 } 7961 } 7962 } 7963 7964 static void 7965 bwn_mac_write_bssid(struct bwn_mac *mac) 7966 { 7967 struct bwn_softc *sc = mac->mac_sc; 7968 uint32_t tmp; 7969 int i; 7970 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 7971 7972 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 7973 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 7974 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 7975 IEEE80211_ADDR_LEN); 7976 7977 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 7978 tmp = (uint32_t) (mac_bssid[i + 0]); 7979 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 7980 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 7981 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 7982 bwn_ram_write(mac, 0x20 + i, tmp); 7983 } 7984 } 7985 7986 static void 7987 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 7988 const uint8_t *macaddr) 7989 { 7990 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 7991 uint16_t data; 7992 7993 if (mac == NULL) 7994 macaddr = zero; 7995 7996 offset |= 0x0020; 7997 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 7998 7999 data = macaddr[0]; 8000 data |= macaddr[1] << 8; 8001 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8002 data = macaddr[2]; 8003 data |= macaddr[3] << 8; 8004 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8005 data = macaddr[4]; 8006 data |= macaddr[5] << 8; 8007 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8008 } 8009 8010 static void 8011 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8012 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8013 { 8014 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8015 uint8_t per_sta_keys_start = 8; 8016 8017 if (BWN_SEC_NEWAPI(mac)) 8018 per_sta_keys_start = 4; 8019 8020 KASSERT(index < mac->mac_max_nr_keys, 8021 ("%s:%d: fail", __func__, __LINE__)); 8022 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8023 ("%s:%d: fail", __func__, __LINE__)); 8024 8025 if (index >= per_sta_keys_start) 8026 bwn_key_macwrite(mac, index, NULL); 8027 if (key) 8028 memcpy(buf, key, key_len); 8029 bwn_key_write(mac, index, algorithm, buf); 8030 if (index >= per_sta_keys_start) 8031 bwn_key_macwrite(mac, index, mac_addr); 8032 8033 mac->mac_key[index].algorithm = algorithm; 8034 } 8035 8036 static void 8037 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8038 { 8039 struct bwn_softc *sc = mac->mac_sc; 8040 uint32_t addrtmp[2] = { 0, 0 }; 8041 uint8_t start = 8; 8042 8043 if (BWN_SEC_NEWAPI(mac)) 8044 start = 4; 8045 8046 KASSERT(index >= start, 8047 ("%s:%d: fail", __func__, __LINE__)); 8048 index -= start; 8049 8050 if (addr) { 8051 addrtmp[0] = addr[0]; 8052 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8053 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8054 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8055 addrtmp[1] = addr[4]; 8056 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8057 } 8058 8059 if (siba_get_revid(sc->sc_dev) >= 5) { 8060 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8061 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8062 } else { 8063 if (index >= 8) { 8064 bwn_shm_write_4(mac, BWN_SHARED, 8065 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8066 bwn_shm_write_2(mac, BWN_SHARED, 8067 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8068 } 8069 } 8070 } 8071 8072 static void 8073 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8074 const uint8_t *key) 8075 { 8076 unsigned int i; 8077 uint32_t offset; 8078 uint16_t kidx, value; 8079 8080 kidx = BWN_SEC_KEY2FW(mac, index); 8081 bwn_shm_write_2(mac, BWN_SHARED, 8082 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8083 8084 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8085 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8086 value = key[i]; 8087 value |= (uint16_t)(key[i + 1]) << 8; 8088 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8089 } 8090 } 8091 8092 static void 8093 bwn_phy_exit(struct bwn_mac *mac) 8094 { 8095 8096 mac->mac_phy.rf_onoff(mac, 0); 8097 if (mac->mac_phy.exit != NULL) 8098 mac->mac_phy.exit(mac); 8099 } 8100 8101 static void 8102 bwn_dma_free(struct bwn_mac *mac) 8103 { 8104 struct bwn_dma *dma; 8105 8106 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8107 return; 8108 dma = &mac->mac_method.dma; 8109 8110 bwn_dma_ringfree(&dma->rx); 8111 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8112 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8113 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8114 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8115 bwn_dma_ringfree(&dma->mcast); 8116 } 8117 8118 static void 8119 bwn_core_stop(struct bwn_mac *mac) 8120 { 8121 struct bwn_softc *sc = mac->mac_sc; 8122 8123 wlan_assert_serialized(); 8124 8125 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8126 return; 8127 8128 callout_stop(&sc->sc_rfswitch_ch); 8129 callout_stop(&sc->sc_task_ch); 8130 callout_stop(&sc->sc_watchdog_ch); 8131 sc->sc_watchdog_timer = 0; 8132 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8133 BWN_READ_4(mac, BWN_INTR_MASK); 8134 bwn_mac_suspend(mac); 8135 8136 mac->mac_status = BWN_MAC_STATUS_INITED; 8137 } 8138 8139 static int 8140 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8141 { 8142 struct bwn_mac *up_dev = NULL; 8143 struct bwn_mac *down_dev; 8144 struct bwn_mac *mac; 8145 int err, status; 8146 uint8_t gmode; 8147 8148 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8149 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8150 mac->mac_phy.supports_2ghz) { 8151 up_dev = mac; 8152 gmode = 1; 8153 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8154 mac->mac_phy.supports_5ghz) { 8155 up_dev = mac; 8156 gmode = 0; 8157 } else { 8158 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8159 return (EINVAL); 8160 } 8161 if (up_dev != NULL) 8162 break; 8163 } 8164 if (up_dev == NULL) { 8165 device_printf(sc->sc_dev, "Could not find a device\n"); 8166 return (ENODEV); 8167 } 8168 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8169 return (0); 8170 8171 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8172 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8173 8174 down_dev = sc->sc_curmac; 8175 status = down_dev->mac_status; 8176 if (status >= BWN_MAC_STATUS_STARTED) 8177 bwn_core_stop(down_dev); 8178 if (status >= BWN_MAC_STATUS_INITED) 8179 bwn_core_exit(down_dev); 8180 8181 if (down_dev != up_dev) 8182 bwn_phy_reset(down_dev); 8183 8184 up_dev->mac_phy.gmode = gmode; 8185 if (status >= BWN_MAC_STATUS_INITED) { 8186 err = bwn_core_init(up_dev); 8187 if (err) { 8188 device_printf(sc->sc_dev, 8189 "fatal: failed to initialize for %s-GHz\n", 8190 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8191 goto fail; 8192 } 8193 } 8194 if (status >= BWN_MAC_STATUS_STARTED) 8195 bwn_core_start(up_dev); 8196 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8197 sc->sc_curmac = up_dev; 8198 8199 return (0); 8200 fail: 8201 sc->sc_curmac = NULL; 8202 return (err); 8203 } 8204 8205 static void 8206 bwn_rf_turnon(struct bwn_mac *mac) 8207 { 8208 8209 bwn_mac_suspend(mac); 8210 mac->mac_phy.rf_onoff(mac, 1); 8211 mac->mac_phy.rf_on = 1; 8212 bwn_mac_enable(mac); 8213 } 8214 8215 static void 8216 bwn_rf_turnoff(struct bwn_mac *mac) 8217 { 8218 8219 bwn_mac_suspend(mac); 8220 mac->mac_phy.rf_onoff(mac, 0); 8221 mac->mac_phy.rf_on = 0; 8222 bwn_mac_enable(mac); 8223 } 8224 8225 static void 8226 bwn_phy_reset(struct bwn_mac *mac) 8227 { 8228 struct bwn_softc *sc = mac->mac_sc; 8229 8230 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8231 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8232 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8233 DELAY(1000); 8234 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8235 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8236 BWN_TGSLOW_PHYRESET); 8237 DELAY(1000); 8238 } 8239 8240 static int 8241 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8242 { 8243 struct bwn_vap *bvp = BWN_VAP(vap); 8244 struct ieee80211com *ic= vap->iv_ic; 8245 struct ifnet *ifp = ic->ic_ifp; 8246 enum ieee80211_state ostate = vap->iv_state; 8247 struct bwn_softc *sc = ifp->if_softc; 8248 struct bwn_mac *mac = sc->sc_curmac; 8249 int error; 8250 8251 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8252 ieee80211_state_name[vap->iv_state], 8253 ieee80211_state_name[nstate]); 8254 8255 error = bvp->bv_newstate(vap, nstate, arg); 8256 if (error != 0) 8257 return (error); 8258 8259 bwn_led_newstate(mac, nstate); 8260 8261 /* 8262 * Clear the BSSID when we stop a STA 8263 */ 8264 if (vap->iv_opmode == IEEE80211_M_STA) { 8265 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8266 /* 8267 * Clear out the BSSID. If we reassociate to 8268 * the same AP, this will reinialize things 8269 * correctly... 8270 */ 8271 if (ic->ic_opmode == IEEE80211_M_STA && 8272 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8273 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8274 bwn_set_macaddr(mac); 8275 } 8276 } 8277 } 8278 8279 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8280 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8281 /* XXX nothing to do? */ 8282 } else if (nstate == IEEE80211_S_RUN) { 8283 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8284 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8285 bwn_set_opmode(mac); 8286 bwn_set_pretbtt(mac); 8287 bwn_spu_setdelay(mac, 0); 8288 bwn_set_macaddr(mac); 8289 } 8290 8291 return (error); 8292 } 8293 8294 static void 8295 bwn_set_pretbtt(struct bwn_mac *mac) 8296 { 8297 struct bwn_softc *sc = mac->mac_sc; 8298 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8299 uint16_t pretbtt; 8300 8301 if (ic->ic_opmode == IEEE80211_M_IBSS) 8302 pretbtt = 2; 8303 else 8304 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8305 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8306 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8307 } 8308 8309 static void 8310 bwn_intr(void *arg) 8311 { 8312 struct bwn_mac *mac = arg; 8313 struct bwn_softc *sc = mac->mac_sc; 8314 uint32_t reason; 8315 8316 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8317 (sc->sc_flags & BWN_FLAG_INVALID)) 8318 return; 8319 8320 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8321 if (reason == 0xffffffff) /* shared IRQ */ 8322 return; 8323 reason &= mac->mac_intr_mask; 8324 if (reason == 0) 8325 return; 8326 8327 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00; 8328 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8329 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8330 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8331 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8332 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8333 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8334 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8335 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8336 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8337 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8338 8339 /* Disable interrupts. */ 8340 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8341 8342 mac->mac_reason_intr = reason; 8343 8344 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8345 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8346 8347 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask); 8348 return; 8349 } 8350 8351 static void 8352 bwn_intrtask(void *arg, int npending) 8353 { 8354 struct bwn_mac *mac = arg; 8355 struct bwn_softc *sc = mac->mac_sc; 8356 struct ifnet *ifp = sc->sc_ifp; 8357 uint32_t merged = 0; 8358 int i, tx = 0, rx = 0; 8359 8360 wlan_serialize_enter(); 8361 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8362 (sc->sc_flags & BWN_FLAG_INVALID)) { 8363 wlan_serialize_exit(); 8364 return; 8365 } 8366 8367 for (i = 0; i < N(mac->mac_reason); i++) 8368 merged |= mac->mac_reason[i]; 8369 8370 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8371 device_printf(sc->sc_dev, "MAC trans error\n"); 8372 8373 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8374 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8375 mac->mac_phy.txerrors--; 8376 if (mac->mac_phy.txerrors == 0) { 8377 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8378 bwn_restart(mac, "PHY TX errors"); 8379 } 8380 } 8381 8382 if (merged & BWN_DMAINTR_FATALMASK) { 8383 device_printf(sc->sc_dev, 8384 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8385 mac->mac_reason[0], mac->mac_reason[1], 8386 mac->mac_reason[2], mac->mac_reason[3], 8387 mac->mac_reason[4], mac->mac_reason[5]); 8388 bwn_restart(mac, "DMA error"); 8389 wlan_serialize_exit(); 8390 return; 8391 } 8392 8393 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8394 bwn_intr_ucode_debug(mac); 8395 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8396 bwn_intr_tbtt_indication(mac); 8397 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8398 bwn_intr_atim_end(mac); 8399 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8400 bwn_intr_beacon(mac); 8401 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8402 bwn_intr_pmq(mac); 8403 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8404 bwn_intr_noise(mac); 8405 8406 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8407 if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) { 8408 device_printf(sc->sc_dev, "RX descriptor overflow\n"); 8409 bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx); 8410 } 8411 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8412 bwn_dma_rx(mac->mac_method.dma.rx); 8413 rx = 1; 8414 } 8415 } else 8416 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8417 8418 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8419 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8420 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8421 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8422 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8423 8424 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8425 bwn_intr_txeof(mac); 8426 tx = 1; 8427 } 8428 8429 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8430 8431 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8432 int evt = BWN_LED_EVENT_NONE; 8433 8434 if (tx && rx) { 8435 if (sc->sc_rx_rate > sc->sc_tx_rate) 8436 evt = BWN_LED_EVENT_RX; 8437 else 8438 evt = BWN_LED_EVENT_TX; 8439 } else if (tx) { 8440 evt = BWN_LED_EVENT_TX; 8441 } else if (rx) { 8442 evt = BWN_LED_EVENT_RX; 8443 } else if (rx == 0) { 8444 evt = BWN_LED_EVENT_POLL; 8445 } 8446 8447 if (evt != BWN_LED_EVENT_NONE) 8448 bwn_led_event(mac, evt); 8449 } 8450 8451 if (!ifq_is_oactive(&ifp->if_snd)) { 8452 if (!ifq_is_empty(&ifp->if_snd)) 8453 bwn_start_locked(ifp); 8454 } 8455 8456 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8457 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8458 8459 wlan_serialize_exit(); 8460 } 8461 8462 static void 8463 bwn_restart(struct bwn_mac *mac, const char *msg) 8464 { 8465 struct bwn_softc *sc = mac->mac_sc; 8466 struct ifnet *ifp = sc->sc_ifp; 8467 struct ieee80211com *ic = ifp->if_l2com; 8468 8469 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8470 return; 8471 8472 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8473 ieee80211_runtask(ic, &mac->mac_hwreset); 8474 } 8475 8476 static void 8477 bwn_intr_ucode_debug(struct bwn_mac *mac) 8478 { 8479 struct bwn_softc *sc = mac->mac_sc; 8480 uint16_t reason; 8481 8482 if (mac->mac_fw.opensource == 0) 8483 return; 8484 8485 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8486 switch (reason) { 8487 case BWN_DEBUGINTR_PANIC: 8488 bwn_handle_fwpanic(mac); 8489 break; 8490 case BWN_DEBUGINTR_DUMP_SHM: 8491 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8492 break; 8493 case BWN_DEBUGINTR_DUMP_REGS: 8494 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8495 break; 8496 case BWN_DEBUGINTR_MARKER: 8497 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8498 break; 8499 default: 8500 device_printf(sc->sc_dev, 8501 "ucode debug unknown reason: %#x\n", reason); 8502 } 8503 8504 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8505 BWN_DEBUGINTR_ACK); 8506 } 8507 8508 static void 8509 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8510 { 8511 struct bwn_softc *sc = mac->mac_sc; 8512 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8513 8514 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8515 bwn_psctl(mac, 0); 8516 if (ic->ic_opmode == IEEE80211_M_IBSS) 8517 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8518 } 8519 8520 static void 8521 bwn_intr_atim_end(struct bwn_mac *mac) 8522 { 8523 8524 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8525 BWN_WRITE_4(mac, BWN_MACCMD, 8526 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8527 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8528 } 8529 } 8530 8531 static void 8532 bwn_intr_beacon(struct bwn_mac *mac) 8533 { 8534 struct bwn_softc *sc = mac->mac_sc; 8535 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8536 uint32_t cmd, beacon0, beacon1; 8537 8538 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8539 ic->ic_opmode == IEEE80211_M_MBSS) 8540 return; 8541 8542 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8543 8544 cmd = BWN_READ_4(mac, BWN_MACCMD); 8545 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8546 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8547 8548 if (beacon0 && beacon1) { 8549 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8550 mac->mac_intr_mask |= BWN_INTR_BEACON; 8551 return; 8552 } 8553 8554 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8555 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8556 bwn_load_beacon0(mac); 8557 bwn_load_beacon1(mac); 8558 cmd = BWN_READ_4(mac, BWN_MACCMD); 8559 cmd |= BWN_MACCMD_BEACON0_VALID; 8560 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8561 } else { 8562 if (!beacon0) { 8563 bwn_load_beacon0(mac); 8564 cmd = BWN_READ_4(mac, BWN_MACCMD); 8565 cmd |= BWN_MACCMD_BEACON0_VALID; 8566 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8567 } else if (!beacon1) { 8568 bwn_load_beacon1(mac); 8569 cmd = BWN_READ_4(mac, BWN_MACCMD); 8570 cmd |= BWN_MACCMD_BEACON1_VALID; 8571 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8572 } 8573 } 8574 } 8575 8576 static void 8577 bwn_intr_pmq(struct bwn_mac *mac) 8578 { 8579 uint32_t tmp; 8580 8581 while (1) { 8582 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8583 if (!(tmp & 0x00000008)) 8584 break; 8585 } 8586 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8587 } 8588 8589 static void 8590 bwn_intr_noise(struct bwn_mac *mac) 8591 { 8592 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8593 uint16_t tmp; 8594 uint8_t noise[4]; 8595 uint8_t i, j; 8596 int32_t average; 8597 8598 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8599 return; 8600 8601 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8602 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8603 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8604 noise[3] == 0x7f) 8605 goto new; 8606 8607 KASSERT(mac->mac_noise.noi_nsamples < 8, 8608 ("%s:%d: fail", __func__, __LINE__)); 8609 i = mac->mac_noise.noi_nsamples; 8610 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8611 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8612 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8613 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8614 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8615 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8616 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8617 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8618 mac->mac_noise.noi_nsamples++; 8619 if (mac->mac_noise.noi_nsamples == 8) { 8620 average = 0; 8621 for (i = 0; i < 8; i++) { 8622 for (j = 0; j < 4; j++) 8623 average += mac->mac_noise.noi_samples[i][j]; 8624 } 8625 average = (((average / 32) * 125) + 64) / 128; 8626 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8627 if (tmp >= 8) 8628 average += 2; 8629 else 8630 average -= 25; 8631 average -= (tmp == 8) ? 72 : 48; 8632 8633 mac->mac_stats.link_noise = average; 8634 mac->mac_noise.noi_running = 0; 8635 return; 8636 } 8637 new: 8638 bwn_noise_gensample(mac); 8639 } 8640 8641 static int 8642 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8643 { 8644 struct bwn_mac *mac = prq->prq_mac; 8645 struct bwn_softc *sc = mac->mac_sc; 8646 unsigned int i; 8647 8648 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8649 return (0); 8650 8651 for (i = 0; i < 5000; i++) { 8652 if (bwn_pio_rxeof(prq) == 0) 8653 break; 8654 } 8655 if (i >= 5000) 8656 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8657 return ((i > 0) ? 1 : 0); 8658 } 8659 8660 static void 8661 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr) 8662 { 8663 int curslot, prevslot; 8664 8665 curslot = dr->get_curslot(dr); 8666 if (curslot == 0) 8667 prevslot = dr->dr_numslots - 1; 8668 else 8669 prevslot = curslot - 1; 8670 dr->set_curslot(dr, prevslot); 8671 } 8672 8673 static void 8674 bwn_dma_rx(struct bwn_dma_ring *dr) 8675 { 8676 int slot, curslot; 8677 8678 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8679 curslot = dr->get_curslot(dr); 8680 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8681 ("%s:%d: fail", __func__, __LINE__)); 8682 8683 slot = dr->dr_curslot; 8684 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8685 bwn_dma_rxeof(dr, &slot); 8686 8687 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8688 BUS_DMASYNC_PREWRITE); 8689 8690 dr->set_curslot(dr, slot); 8691 dr->dr_curslot = slot; 8692 } 8693 8694 static void 8695 bwn_intr_txeof(struct bwn_mac *mac) 8696 { 8697 struct bwn_txstatus stat; 8698 uint32_t stat0, stat1; 8699 uint16_t tmp; 8700 8701 while (1) { 8702 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8703 if (!(stat0 & 0x00000001)) 8704 break; 8705 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8706 8707 stat.cookie = (stat0 >> 16); 8708 stat.seq = (stat1 & 0x0000ffff); 8709 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8710 tmp = (stat0 & 0x0000ffff); 8711 stat.framecnt = ((tmp & 0xf000) >> 12); 8712 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8713 stat.sreason = ((tmp & 0x001c) >> 2); 8714 stat.pm = (tmp & 0x0080) ? 1 : 0; 8715 stat.im = (tmp & 0x0040) ? 1 : 0; 8716 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8717 stat.ack = (tmp & 0x0002) ? 1 : 0; 8718 8719 bwn_handle_txeof(mac, &stat); 8720 } 8721 } 8722 8723 static void 8724 bwn_hwreset(void *arg, int npending) 8725 { 8726 struct bwn_mac *mac = arg; 8727 struct bwn_softc *sc = mac->mac_sc; 8728 int error = 0; 8729 int prev_status; 8730 8731 wlan_serialize_enter(); 8732 8733 prev_status = mac->mac_status; 8734 if (prev_status >= BWN_MAC_STATUS_STARTED) 8735 bwn_core_stop(mac); 8736 if (prev_status >= BWN_MAC_STATUS_INITED) 8737 bwn_core_exit(mac); 8738 8739 if (prev_status >= BWN_MAC_STATUS_INITED) { 8740 error = bwn_core_init(mac); 8741 if (error) 8742 goto out; 8743 } 8744 if (prev_status >= BWN_MAC_STATUS_STARTED) 8745 bwn_core_start(mac); 8746 out: 8747 if (error) { 8748 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8749 sc->sc_curmac = NULL; 8750 } 8751 wlan_serialize_exit(); 8752 } 8753 8754 static void 8755 bwn_handle_fwpanic(struct bwn_mac *mac) 8756 { 8757 struct bwn_softc *sc = mac->mac_sc; 8758 uint16_t reason; 8759 8760 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8761 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8762 8763 if (reason == BWN_FWPANIC_RESTART) 8764 bwn_restart(mac, "ucode panic"); 8765 } 8766 8767 static void 8768 bwn_load_beacon0(struct bwn_mac *mac) 8769 { 8770 8771 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8772 } 8773 8774 static void 8775 bwn_load_beacon1(struct bwn_mac *mac) 8776 { 8777 8778 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8779 } 8780 8781 static uint32_t 8782 bwn_jssi_read(struct bwn_mac *mac) 8783 { 8784 uint32_t val = 0; 8785 8786 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8787 val <<= 16; 8788 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8789 8790 return (val); 8791 } 8792 8793 static void 8794 bwn_noise_gensample(struct bwn_mac *mac) 8795 { 8796 uint32_t jssi = 0x7f7f7f7f; 8797 8798 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8799 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8800 BWN_WRITE_4(mac, BWN_MACCMD, 8801 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8802 } 8803 8804 static int 8805 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8806 { 8807 return (dr->dr_numslots - dr->dr_usedslot); 8808 } 8809 8810 static int 8811 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8812 { 8813 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8814 ("%s:%d: fail", __func__, __LINE__)); 8815 if (slot == dr->dr_numslots - 1) 8816 return (0); 8817 return (slot + 1); 8818 } 8819 8820 static void 8821 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8822 { 8823 struct bwn_mac *mac = dr->dr_mac; 8824 struct bwn_softc *sc = mac->mac_sc; 8825 struct bwn_dma *dma = &mac->mac_method.dma; 8826 struct bwn_dmadesc_generic *desc; 8827 struct bwn_dmadesc_meta *meta; 8828 struct bwn_rxhdr4 *rxhdr; 8829 struct ifnet *ifp = sc->sc_ifp; 8830 struct mbuf *m; 8831 uint32_t macstat; 8832 int32_t tmp; 8833 int cnt = 0; 8834 uint16_t len; 8835 8836 dr->getdesc(dr, *slot, &desc, &meta); 8837 8838 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8839 m = meta->mt_m; 8840 8841 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8842 ifp->if_ierrors++; 8843 return; 8844 } 8845 8846 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8847 len = le16toh(rxhdr->frame_len); 8848 if (len <= 0) { 8849 ifp->if_ierrors++; 8850 return; 8851 } 8852 if (bwn_dma_check_redzone(dr, m)) { 8853 device_printf(sc->sc_dev, "redzone error.\n"); 8854 bwn_dma_set_redzone(dr, m); 8855 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8856 BUS_DMASYNC_PREWRITE); 8857 return; 8858 } 8859 if (len > dr->dr_rx_bufsize) { 8860 tmp = len; 8861 while (1) { 8862 dr->getdesc(dr, *slot, &desc, &meta); 8863 bwn_dma_set_redzone(dr, meta->mt_m); 8864 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8865 BUS_DMASYNC_PREWRITE); 8866 *slot = bwn_dma_nextslot(dr, *slot); 8867 cnt++; 8868 tmp -= dr->dr_rx_bufsize; 8869 if (tmp <= 0) 8870 break; 8871 } 8872 device_printf(sc->sc_dev, "too small buffer " 8873 "(len %u buffer %u dropped %d)\n", 8874 len, dr->dr_rx_bufsize, cnt); 8875 return; 8876 } 8877 macstat = le32toh(rxhdr->mac_status); 8878 if (macstat & BWN_RX_MAC_FCSERR) { 8879 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8880 device_printf(sc->sc_dev, "RX drop\n"); 8881 return; 8882 } 8883 } 8884 8885 m->m_pkthdr.rcvif = ifp; 8886 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8887 m_adj(m, dr->dr_frameoffset); 8888 8889 bwn_rxeof(dr->dr_mac, m, rxhdr); 8890 } 8891 8892 static void 8893 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8894 { 8895 struct bwn_dma_ring *dr; 8896 struct bwn_dmadesc_generic *desc; 8897 struct bwn_dmadesc_meta *meta; 8898 struct bwn_pio_txqueue *tq; 8899 struct bwn_pio_txpkt *tp = NULL; 8900 struct bwn_softc *sc = mac->mac_sc; 8901 struct bwn_stats *stats = &mac->mac_stats; 8902 struct ieee80211_node *ni; 8903 struct ieee80211vap *vap; 8904 int retrycnt = 0, slot; 8905 8906 if (status->im) 8907 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8908 if (status->ampdu) 8909 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8910 if (status->rtscnt) { 8911 if (status->rtscnt == 0xf) 8912 stats->rtsfail++; 8913 else 8914 stats->rts++; 8915 } 8916 8917 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8918 if (status->ack) { 8919 dr = bwn_dma_parse_cookie(mac, status, 8920 status->cookie, &slot); 8921 if (dr == NULL) { 8922 device_printf(sc->sc_dev, 8923 "failed to parse cookie\n"); 8924 return; 8925 } 8926 while (1) { 8927 dr->getdesc(dr, slot, &desc, &meta); 8928 if (meta->mt_islast) { 8929 ni = meta->mt_ni; 8930 vap = ni->ni_vap; 8931 ieee80211_ratectl_tx_complete(vap, ni, 8932 status->ack ? 8933 IEEE80211_RATECTL_TX_SUCCESS : 8934 IEEE80211_RATECTL_TX_FAILURE, 8935 &retrycnt, 0); 8936 break; 8937 } 8938 slot = bwn_dma_nextslot(dr, slot); 8939 } 8940 } 8941 bwn_dma_handle_txeof(mac, status); 8942 } else { 8943 if (status->ack) { 8944 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 8945 if (tq == NULL) { 8946 device_printf(sc->sc_dev, 8947 "failed to parse cookie\n"); 8948 return; 8949 } 8950 ni = tp->tp_ni; 8951 vap = ni->ni_vap; 8952 ieee80211_ratectl_tx_complete(vap, ni, 8953 status->ack ? 8954 IEEE80211_RATECTL_TX_SUCCESS : 8955 IEEE80211_RATECTL_TX_FAILURE, 8956 &retrycnt, 0); 8957 } 8958 bwn_pio_handle_txeof(mac, status); 8959 } 8960 8961 bwn_phy_txpower_check(mac, 0); 8962 } 8963 8964 static uint8_t 8965 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 8966 { 8967 struct bwn_mac *mac = prq->prq_mac; 8968 struct bwn_softc *sc = mac->mac_sc; 8969 struct bwn_rxhdr4 rxhdr; 8970 struct ifnet *ifp = sc->sc_ifp; 8971 struct mbuf *m; 8972 uint32_t ctl32, macstat, v32; 8973 unsigned int i, padding; 8974 uint16_t ctl16, len, totlen, v16; 8975 unsigned char *mp; 8976 char *data; 8977 8978 memset(&rxhdr, 0, sizeof(rxhdr)); 8979 8980 if (prq->prq_rev >= 8) { 8981 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8982 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 8983 return (0); 8984 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 8985 BWN_PIO8_RXCTL_FRAMEREADY); 8986 for (i = 0; i < 10; i++) { 8987 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8988 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 8989 goto ready; 8990 DELAY(10); 8991 } 8992 } else { 8993 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8994 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 8995 return (0); 8996 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 8997 BWN_PIO_RXCTL_FRAMEREADY); 8998 for (i = 0; i < 10; i++) { 8999 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9000 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9001 goto ready; 9002 DELAY(10); 9003 } 9004 } 9005 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9006 return (1); 9007 ready: 9008 if (prq->prq_rev >= 8) 9009 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9010 prq->prq_base + BWN_PIO8_RXDATA); 9011 else 9012 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9013 prq->prq_base + BWN_PIO_RXDATA); 9014 len = le16toh(rxhdr.frame_len); 9015 if (len > 0x700) { 9016 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9017 goto error; 9018 } 9019 if (len == 0) { 9020 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9021 goto error; 9022 } 9023 9024 macstat = le32toh(rxhdr.mac_status); 9025 if (macstat & BWN_RX_MAC_FCSERR) { 9026 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9027 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9028 goto error; 9029 } 9030 } 9031 9032 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9033 totlen = len + padding; 9034 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9035 m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR); 9036 if (m == NULL) { 9037 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9038 goto error; 9039 } 9040 mp = mtod(m, unsigned char *); 9041 if (prq->prq_rev >= 8) { 9042 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9043 prq->prq_base + BWN_PIO8_RXDATA); 9044 if (totlen & 3) { 9045 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9046 data = &(mp[totlen - 1]); 9047 switch (totlen & 3) { 9048 case 3: 9049 *data = (v32 >> 16); 9050 data--; 9051 case 2: 9052 *data = (v32 >> 8); 9053 data--; 9054 case 1: 9055 *data = v32; 9056 } 9057 } 9058 } else { 9059 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9060 prq->prq_base + BWN_PIO_RXDATA); 9061 if (totlen & 1) { 9062 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9063 mp[totlen - 1] = v16; 9064 } 9065 } 9066 9067 m->m_pkthdr.rcvif = ifp; 9068 m->m_len = m->m_pkthdr.len = totlen; 9069 9070 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9071 9072 return (1); 9073 error: 9074 if (prq->prq_rev >= 8) 9075 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9076 BWN_PIO8_RXCTL_DATAREADY); 9077 else 9078 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9079 return (1); 9080 } 9081 9082 static int 9083 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9084 struct bwn_dmadesc_meta *meta, int init) 9085 { 9086 struct bwn_mac *mac = dr->dr_mac; 9087 struct bwn_dma *dma = &mac->mac_method.dma; 9088 struct bwn_rxhdr4 *hdr; 9089 bus_dmamap_t map; 9090 bus_addr_t paddr; 9091 struct mbuf *m; 9092 int error; 9093 9094 m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR); 9095 if (m == NULL) { 9096 error = ENOBUFS; 9097 9098 /* 9099 * If the NIC is up and running, we need to: 9100 * - Clear RX buffer's header. 9101 * - Restore RX descriptor settings. 9102 */ 9103 if (init) 9104 return (error); 9105 else 9106 goto back; 9107 } 9108 m->m_len = m->m_pkthdr.len = MCLBYTES; 9109 9110 bwn_dma_set_redzone(dr, m); 9111 9112 /* 9113 * Try to load RX buf into temporary DMA map 9114 */ 9115 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9116 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9117 if (error) { 9118 m_freem(m); 9119 9120 /* 9121 * See the comment above 9122 */ 9123 if (init) 9124 return (error); 9125 else 9126 goto back; 9127 } 9128 9129 if (!init) 9130 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9131 meta->mt_m = m; 9132 meta->mt_paddr = paddr; 9133 9134 /* 9135 * Swap RX buf's DMA map with the loaded temporary one 9136 */ 9137 map = meta->mt_dmap; 9138 meta->mt_dmap = dr->dr_spare_dmap; 9139 dr->dr_spare_dmap = map; 9140 9141 back: 9142 /* 9143 * Clear RX buf header 9144 */ 9145 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9146 bzero(hdr, sizeof(*hdr)); 9147 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9148 BUS_DMASYNC_PREWRITE); 9149 9150 /* 9151 * Setup RX buf descriptor 9152 */ 9153 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9154 sizeof(*hdr), 0, 0, 0); 9155 return (error); 9156 } 9157 9158 static void 9159 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9160 bus_size_t mapsz __unused, int error) 9161 { 9162 9163 if (!error) { 9164 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9165 *((bus_addr_t *)arg) = seg->ds_addr; 9166 } 9167 } 9168 9169 static int 9170 bwn_hwrate2ieeerate(int rate) 9171 { 9172 9173 switch (rate) { 9174 case BWN_CCK_RATE_1MB: 9175 return (2); 9176 case BWN_CCK_RATE_2MB: 9177 return (4); 9178 case BWN_CCK_RATE_5MB: 9179 return (11); 9180 case BWN_CCK_RATE_11MB: 9181 return (22); 9182 case BWN_OFDM_RATE_6MB: 9183 return (12); 9184 case BWN_OFDM_RATE_9MB: 9185 return (18); 9186 case BWN_OFDM_RATE_12MB: 9187 return (24); 9188 case BWN_OFDM_RATE_18MB: 9189 return (36); 9190 case BWN_OFDM_RATE_24MB: 9191 return (48); 9192 case BWN_OFDM_RATE_36MB: 9193 return (72); 9194 case BWN_OFDM_RATE_48MB: 9195 return (96); 9196 case BWN_OFDM_RATE_54MB: 9197 return (108); 9198 default: 9199 kprintf("Ooops\n"); 9200 return (0); 9201 } 9202 } 9203 9204 static void 9205 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9206 { 9207 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9208 struct bwn_plcp6 *plcp; 9209 struct bwn_softc *sc = mac->mac_sc; 9210 struct ieee80211_frame_min *wh; 9211 struct ieee80211_node *ni; 9212 struct ifnet *ifp = sc->sc_ifp; 9213 struct ieee80211com *ic = ifp->if_l2com; 9214 uint32_t macstat; 9215 int padding, rate, rssi = 0, noise = 0, type; 9216 uint16_t phytype, phystat0, phystat3, chanstat; 9217 unsigned char *mp = mtod(m, unsigned char *); 9218 static int rx_mac_dec_rpt = 0; 9219 9220 phystat0 = le16toh(rxhdr->phy_status0); 9221 phystat3 = le16toh(rxhdr->phy_status3); 9222 macstat = le32toh(rxhdr->mac_status); 9223 chanstat = le16toh(rxhdr->channel); 9224 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9225 9226 if (macstat & BWN_RX_MAC_FCSERR) 9227 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9228 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9229 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9230 if (macstat & BWN_RX_MAC_DECERR) 9231 goto drop; 9232 9233 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9234 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9235 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9236 m->m_pkthdr.len); 9237 goto drop; 9238 } 9239 plcp = (struct bwn_plcp6 *)(mp + padding); 9240 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9241 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9242 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9243 m->m_pkthdr.len); 9244 goto drop; 9245 } 9246 wh = mtod(m, struct ieee80211_frame_min *); 9247 9248 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9249 device_printf(sc->sc_dev, 9250 "RX decryption attempted (old %d keyidx %#x)\n", 9251 BWN_ISOLDFMT(mac), 9252 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9253 9254 /* XXX calculating RSSI & noise & antenna */ 9255 9256 if (phystat0 & BWN_RX_PHYST0_OFDM) 9257 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9258 phytype == BWN_PHYTYPE_A); 9259 else 9260 rate = bwn_plcp_get_cckrate(mac, plcp); 9261 if (rate == -1) { 9262 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9263 goto drop; 9264 } 9265 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9266 9267 /* RX radio tap */ 9268 if (ieee80211_radiotap_active(ic)) 9269 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9270 m_adj(m, -IEEE80211_CRC_LEN); 9271 9272 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9273 noise = mac->mac_stats.link_noise; 9274 9275 ifp->if_ipackets++; 9276 9277 ni = ieee80211_find_rxnode(ic, wh); 9278 if (ni != NULL) { 9279 type = ieee80211_input(ni, m, rssi, noise); 9280 ieee80211_free_node(ni); 9281 } else 9282 type = ieee80211_input_all(ic, m, rssi, noise); 9283 9284 return; 9285 drop: 9286 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9287 } 9288 9289 static void 9290 bwn_dma_handle_txeof(struct bwn_mac *mac, 9291 const struct bwn_txstatus *status) 9292 { 9293 struct bwn_dma *dma = &mac->mac_method.dma; 9294 struct bwn_dma_ring *dr; 9295 struct bwn_dmadesc_generic *desc; 9296 struct bwn_dmadesc_meta *meta; 9297 struct bwn_softc *sc = mac->mac_sc; 9298 struct ieee80211_node *ni; 9299 struct ifnet *ifp = sc->sc_ifp; 9300 struct mbuf *m; 9301 int slot; 9302 9303 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9304 if (dr == NULL) { 9305 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9306 return; 9307 } 9308 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9309 9310 while (1) { 9311 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9312 ("%s:%d: fail", __func__, __LINE__)); 9313 dr->getdesc(dr, slot, &desc, &meta); 9314 9315 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 9316 bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap, 9317 BUS_DMASYNC_POSTWRITE); 9318 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 9319 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9320 } 9321 9322 if (meta->mt_islast) { 9323 KASSERT(meta->mt_m != NULL, 9324 ("%s:%d: fail", __func__, __LINE__)); 9325 9326 ni = meta->mt_ni; 9327 m = meta->mt_m; 9328 if (ni != NULL) { 9329 /* 9330 * Do any tx complete callback. Note this must 9331 * be done before releasing the node reference. 9332 */ 9333 if (m->m_flags & M_TXCB) 9334 ieee80211_process_callback(ni, m, 0); 9335 ieee80211_free_node(ni); 9336 meta->mt_ni = NULL; 9337 } 9338 m_freem(m); 9339 meta->mt_m = NULL; 9340 } else { 9341 KASSERT(meta->mt_m == NULL, 9342 ("%s:%d: fail", __func__, __LINE__)); 9343 } 9344 9345 dr->dr_usedslot--; 9346 if (meta->mt_islast) { 9347 ifp->if_opackets++; 9348 break; 9349 } 9350 slot = bwn_dma_nextslot(dr, slot); 9351 } 9352 sc->sc_watchdog_timer = 0; 9353 if (dr->dr_stop) { 9354 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9355 ("%s:%d: fail", __func__, __LINE__)); 9356 ifq_clr_oactive(&ifp->if_snd); 9357 dr->dr_stop = 0; 9358 } 9359 } 9360 9361 static void 9362 bwn_pio_handle_txeof(struct bwn_mac *mac, 9363 const struct bwn_txstatus *status) 9364 { 9365 struct bwn_pio_txqueue *tq; 9366 struct bwn_pio_txpkt *tp = NULL; 9367 struct bwn_softc *sc = mac->mac_sc; 9368 struct ifnet *ifp = sc->sc_ifp; 9369 9370 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9371 if (tq == NULL) 9372 return; 9373 9374 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9375 tq->tq_free++; 9376 9377 if (tp->tp_ni != NULL) { 9378 /* 9379 * Do any tx complete callback. Note this must 9380 * be done before releasing the node reference. 9381 */ 9382 if (tp->tp_m->m_flags & M_TXCB) 9383 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9384 ieee80211_free_node(tp->tp_ni); 9385 tp->tp_ni = NULL; 9386 } 9387 m_freem(tp->tp_m); 9388 tp->tp_m = NULL; 9389 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9390 9391 ifp->if_opackets++; 9392 9393 sc->sc_watchdog_timer = 0; 9394 if (tq->tq_stop) { 9395 ifq_clr_oactive(&ifp->if_snd); 9396 tq->tq_stop = 0; 9397 } 9398 } 9399 9400 static void 9401 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9402 { 9403 struct bwn_softc *sc = mac->mac_sc; 9404 struct bwn_phy *phy = &mac->mac_phy; 9405 struct ifnet *ifp = sc->sc_ifp; 9406 struct ieee80211com *ic = ifp->if_l2com; 9407 unsigned long now; 9408 int result; 9409 9410 BWN_GETTIME(now); 9411 9412 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9413 return; 9414 phy->nexttime = now + 2 * 1000; 9415 9416 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9417 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9418 return; 9419 9420 if (phy->recalc_txpwr != NULL) { 9421 result = phy->recalc_txpwr(mac, 9422 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9423 if (result == BWN_TXPWR_RES_DONE) 9424 return; 9425 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9426 ("%s: fail", __func__)); 9427 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9428 9429 ieee80211_runtask(ic, &mac->mac_txpower); 9430 } 9431 } 9432 9433 static uint16_t 9434 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9435 { 9436 9437 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9438 } 9439 9440 static uint32_t 9441 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9442 { 9443 9444 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9445 } 9446 9447 static void 9448 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9449 { 9450 9451 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9452 } 9453 9454 static void 9455 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9456 { 9457 9458 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9459 } 9460 9461 static int 9462 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9463 { 9464 9465 switch (rate) { 9466 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9467 case 12: 9468 return (BWN_OFDM_RATE_6MB); 9469 case 18: 9470 return (BWN_OFDM_RATE_9MB); 9471 case 24: 9472 return (BWN_OFDM_RATE_12MB); 9473 case 36: 9474 return (BWN_OFDM_RATE_18MB); 9475 case 48: 9476 return (BWN_OFDM_RATE_24MB); 9477 case 72: 9478 return (BWN_OFDM_RATE_36MB); 9479 case 96: 9480 return (BWN_OFDM_RATE_48MB); 9481 case 108: 9482 return (BWN_OFDM_RATE_54MB); 9483 /* CCK rates (NB: not IEEE std, device-specific) */ 9484 case 2: 9485 return (BWN_CCK_RATE_1MB); 9486 case 4: 9487 return (BWN_CCK_RATE_2MB); 9488 case 11: 9489 return (BWN_CCK_RATE_5MB); 9490 case 22: 9491 return (BWN_CCK_RATE_11MB); 9492 } 9493 9494 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9495 return (BWN_CCK_RATE_1MB); 9496 } 9497 9498 static int 9499 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9500 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9501 { 9502 const struct bwn_phy *phy = &mac->mac_phy; 9503 struct bwn_softc *sc = mac->mac_sc; 9504 struct ieee80211_frame *wh; 9505 struct ieee80211_frame *protwh; 9506 struct ieee80211_frame_cts *cts; 9507 struct ieee80211_frame_rts *rts; 9508 const struct ieee80211_txparam *tp; 9509 struct ieee80211vap *vap = ni->ni_vap; 9510 struct ifnet *ifp = sc->sc_ifp; 9511 struct ieee80211com *ic = ifp->if_l2com; 9512 struct mbuf *mprot; 9513 unsigned int len; 9514 uint32_t macctl = 0; 9515 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9516 uint16_t phyctl = 0; 9517 uint8_t rate, rate_fb; 9518 9519 wh = mtod(m, struct ieee80211_frame *); 9520 memset(txhdr, 0, sizeof(*txhdr)); 9521 9522 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9523 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9524 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9525 9526 /* 9527 * Find TX rate 9528 */ 9529 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9530 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9531 rate = rate_fb = tp->mgmtrate; 9532 else if (ismcast) 9533 rate = rate_fb = tp->mcastrate; 9534 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9535 rate = rate_fb = tp->ucastrate; 9536 else { 9537 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9538 rate = ni->ni_txrate; 9539 9540 if (rix > 0) 9541 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9542 IEEE80211_RATE_VAL; 9543 else 9544 rate_fb = rate; 9545 } 9546 9547 sc->sc_tx_rate = rate; 9548 9549 rate = bwn_ieeerate2hwrate(sc, rate); 9550 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9551 9552 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9553 bwn_plcp_getcck(rate); 9554 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9555 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9556 9557 if ((rate_fb == rate) || 9558 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9559 (*(u_int16_t *)wh->i_dur == htole16(0))) 9560 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9561 else 9562 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9563 m->m_pkthdr.len, rate, isshort); 9564 9565 /* XXX TX encryption */ 9566 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9567 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9568 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9569 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9570 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9571 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9572 9573 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9574 BWN_TX_EFT_FB_CCK; 9575 txhdr->chan = phy->chan; 9576 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9577 BWN_TX_PHY_ENC_CCK; 9578 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9579 rate == BWN_CCK_RATE_11MB)) 9580 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9581 9582 /* XXX TX antenna selection */ 9583 9584 switch (bwn_antenna_sanitize(mac, 0)) { 9585 case 0: 9586 phyctl |= BWN_TX_PHY_ANT01AUTO; 9587 break; 9588 case 1: 9589 phyctl |= BWN_TX_PHY_ANT0; 9590 break; 9591 case 2: 9592 phyctl |= BWN_TX_PHY_ANT1; 9593 break; 9594 case 3: 9595 phyctl |= BWN_TX_PHY_ANT2; 9596 break; 9597 case 4: 9598 phyctl |= BWN_TX_PHY_ANT3; 9599 break; 9600 default: 9601 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9602 } 9603 9604 if (!ismcast) 9605 macctl |= BWN_TX_MAC_ACK; 9606 9607 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9608 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9609 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9610 macctl |= BWN_TX_MAC_LONGFRAME; 9611 9612 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9613 /* XXX RTS rate is always 1MB??? */ 9614 rts_rate = BWN_CCK_RATE_1MB; 9615 rts_rate_fb = bwn_get_fbrate(rts_rate); 9616 9617 protdur = ieee80211_compute_duration(ic->ic_rt, 9618 m->m_pkthdr.len, rate, isshort) + 9619 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9620 9621 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9622 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9623 (txhdr->body.old.rts_frame) : 9624 (txhdr->body.new.rts_frame)); 9625 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9626 protdur); 9627 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9628 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9629 mprot->m_pkthdr.len); 9630 m_freem(mprot); 9631 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9632 len = sizeof(struct ieee80211_frame_cts); 9633 } else { 9634 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9635 (txhdr->body.old.rts_frame) : 9636 (txhdr->body.new.rts_frame)); 9637 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9638 isshort); 9639 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9640 wh->i_addr2, protdur); 9641 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9642 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9643 mprot->m_pkthdr.len); 9644 m_freem(mprot); 9645 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9646 len = sizeof(struct ieee80211_frame_rts); 9647 } 9648 len += IEEE80211_CRC_LEN; 9649 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9650 &txhdr->body.old.rts_plcp : 9651 &txhdr->body.new.rts_plcp), len, rts_rate); 9652 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9653 rts_rate_fb); 9654 9655 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9656 (&txhdr->body.old.rts_frame) : 9657 (&txhdr->body.new.rts_frame)); 9658 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9659 9660 if (BWN_ISOFDMRATE(rts_rate)) { 9661 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9662 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9663 } else { 9664 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9665 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9666 } 9667 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9668 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9669 } 9670 9671 if (BWN_ISOLDFMT(mac)) 9672 txhdr->body.old.cookie = htole16(cookie); 9673 else 9674 txhdr->body.new.cookie = htole16(cookie); 9675 9676 txhdr->macctl = htole32(macctl); 9677 txhdr->phyctl = htole16(phyctl); 9678 9679 /* 9680 * TX radio tap 9681 */ 9682 if (ieee80211_radiotap_active_vap(vap)) { 9683 sc->sc_tx_th.wt_flags = 0; 9684 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9685 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9686 if (isshort && 9687 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9688 rate == BWN_CCK_RATE_11MB)) 9689 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9690 sc->sc_tx_th.wt_rate = rate; 9691 9692 ieee80211_radiotap_tx(vap, m); 9693 } 9694 9695 return (0); 9696 } 9697 9698 static void 9699 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9700 const uint8_t rate) 9701 { 9702 uint32_t d, plen; 9703 uint8_t *raw = plcp->o.raw; 9704 9705 if (BWN_ISOFDMRATE(rate)) { 9706 d = bwn_plcp_getofdm(rate); 9707 KASSERT(!(octets & 0xf000), 9708 ("%s:%d: fail", __func__, __LINE__)); 9709 d |= (octets << 5); 9710 plcp->o.data = htole32(d); 9711 } else { 9712 plen = octets * 16 / rate; 9713 if ((octets * 16 % rate) > 0) { 9714 plen++; 9715 if ((rate == BWN_CCK_RATE_11MB) 9716 && ((octets * 8 % 11) < 4)) { 9717 raw[1] = 0x84; 9718 } else 9719 raw[1] = 0x04; 9720 } else 9721 raw[1] = 0x04; 9722 plcp->o.data |= htole32(plen << 16); 9723 raw[0] = bwn_plcp_getcck(rate); 9724 } 9725 } 9726 9727 static uint8_t 9728 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9729 { 9730 struct bwn_softc *sc = mac->mac_sc; 9731 uint8_t mask; 9732 9733 if (n == 0) 9734 return (0); 9735 if (mac->mac_phy.gmode) 9736 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9737 else 9738 mask = siba_sprom_get_ant_a(sc->sc_dev); 9739 if (!(mask & (1 << (n - 1)))) 9740 return (0); 9741 return (n); 9742 } 9743 9744 static uint8_t 9745 bwn_get_fbrate(uint8_t bitrate) 9746 { 9747 switch (bitrate) { 9748 case BWN_CCK_RATE_1MB: 9749 return (BWN_CCK_RATE_1MB); 9750 case BWN_CCK_RATE_2MB: 9751 return (BWN_CCK_RATE_1MB); 9752 case BWN_CCK_RATE_5MB: 9753 return (BWN_CCK_RATE_2MB); 9754 case BWN_CCK_RATE_11MB: 9755 return (BWN_CCK_RATE_5MB); 9756 case BWN_OFDM_RATE_6MB: 9757 return (BWN_CCK_RATE_5MB); 9758 case BWN_OFDM_RATE_9MB: 9759 return (BWN_OFDM_RATE_6MB); 9760 case BWN_OFDM_RATE_12MB: 9761 return (BWN_OFDM_RATE_9MB); 9762 case BWN_OFDM_RATE_18MB: 9763 return (BWN_OFDM_RATE_12MB); 9764 case BWN_OFDM_RATE_24MB: 9765 return (BWN_OFDM_RATE_18MB); 9766 case BWN_OFDM_RATE_36MB: 9767 return (BWN_OFDM_RATE_24MB); 9768 case BWN_OFDM_RATE_48MB: 9769 return (BWN_OFDM_RATE_36MB); 9770 case BWN_OFDM_RATE_54MB: 9771 return (BWN_OFDM_RATE_48MB); 9772 } 9773 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9774 return (0); 9775 } 9776 9777 static uint32_t 9778 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9779 uint32_t ctl, const void *_data, int len) 9780 { 9781 struct bwn_softc *sc = mac->mac_sc; 9782 uint32_t value = 0; 9783 const uint8_t *data = _data; 9784 9785 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9786 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9787 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9788 9789 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9790 tq->tq_base + BWN_PIO8_TXDATA); 9791 if (len & 3) { 9792 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9793 BWN_PIO8_TXCTL_24_31); 9794 data = &(data[len - 1]); 9795 switch (len & 3) { 9796 case 3: 9797 ctl |= BWN_PIO8_TXCTL_16_23; 9798 value |= (uint32_t)(*data) << 16; 9799 data--; 9800 case 2: 9801 ctl |= BWN_PIO8_TXCTL_8_15; 9802 value |= (uint32_t)(*data) << 8; 9803 data--; 9804 case 1: 9805 value |= (uint32_t)(*data); 9806 } 9807 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9808 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9809 } 9810 9811 return (ctl); 9812 } 9813 9814 static void 9815 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9816 uint16_t offset, uint32_t value) 9817 { 9818 9819 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9820 } 9821 9822 static uint16_t 9823 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9824 uint16_t ctl, const void *_data, int len) 9825 { 9826 struct bwn_softc *sc = mac->mac_sc; 9827 const uint8_t *data = _data; 9828 9829 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9830 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9831 9832 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9833 tq->tq_base + BWN_PIO_TXDATA); 9834 if (len & 1) { 9835 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9836 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9837 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9838 } 9839 9840 return (ctl); 9841 } 9842 9843 static uint16_t 9844 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9845 uint16_t ctl, struct mbuf *m0) 9846 { 9847 int i, j = 0; 9848 uint16_t data = 0; 9849 const uint8_t *buf; 9850 struct mbuf *m = m0; 9851 9852 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9853 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9854 9855 for (; m != NULL; m = m->m_next) { 9856 buf = mtod(m, const uint8_t *); 9857 for (i = 0; i < m->m_len; i++) { 9858 if (!((j++) % 2)) 9859 data |= buf[i]; 9860 else { 9861 data |= (buf[i] << 8); 9862 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9863 data = 0; 9864 } 9865 } 9866 } 9867 if (m0->m_pkthdr.len % 2) { 9868 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9869 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9870 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9871 } 9872 9873 return (ctl); 9874 } 9875 9876 static void 9877 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9878 { 9879 9880 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9881 return; 9882 BWN_WRITE_2(mac, 0x684, 510 + time); 9883 9884 /* 9885 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a 9886 * a severe performance penalty (especially when sending). 9887 */ 9888 #if 0 9889 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9890 #endif 9891 } 9892 9893 static struct bwn_dma_ring * 9894 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9895 { 9896 9897 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9898 return (mac->mac_method.dma.wme[WME_AC_BE]); 9899 9900 switch (prio) { 9901 case 3: 9902 return (mac->mac_method.dma.wme[WME_AC_VO]); 9903 case 2: 9904 return (mac->mac_method.dma.wme[WME_AC_VI]); 9905 case 0: 9906 return (mac->mac_method.dma.wme[WME_AC_BE]); 9907 case 1: 9908 return (mac->mac_method.dma.wme[WME_AC_BK]); 9909 } 9910 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9911 return (NULL); 9912 } 9913 9914 static int 9915 bwn_dma_getslot(struct bwn_dma_ring *dr) 9916 { 9917 int slot; 9918 9919 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9920 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 9921 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 9922 9923 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 9924 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 9925 dr->dr_curslot = slot; 9926 dr->dr_usedslot++; 9927 9928 return (slot); 9929 } 9930 9931 static int 9932 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 9933 { 9934 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 9935 unsigned int a, b, c, d; 9936 unsigned int avg; 9937 uint32_t tmp; 9938 9939 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 9940 a = tmp & 0xff; 9941 b = (tmp >> 8) & 0xff; 9942 c = (tmp >> 16) & 0xff; 9943 d = (tmp >> 24) & 0xff; 9944 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 9945 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 9946 return (ENOENT); 9947 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 9948 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 9949 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 9950 9951 if (ofdm) { 9952 a = (a + 32) & 0x3f; 9953 b = (b + 32) & 0x3f; 9954 c = (c + 32) & 0x3f; 9955 d = (d + 32) & 0x3f; 9956 } 9957 9958 avg = (a + b + c + d + 2) / 4; 9959 if (ofdm) { 9960 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 9961 & BWN_HF_4DB_CCK_POWERBOOST) 9962 avg = (avg >= 13) ? (avg - 13) : 0; 9963 } 9964 return (avg); 9965 } 9966 9967 static void 9968 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 9969 { 9970 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 9971 int rfatt = *rfattp; 9972 int bbatt = *bbattp; 9973 9974 while (1) { 9975 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 9976 break; 9977 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 9978 break; 9979 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 9980 break; 9981 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 9982 break; 9983 if (bbatt > lo->bbatt.max) { 9984 bbatt -= 4; 9985 rfatt += 1; 9986 continue; 9987 } 9988 if (bbatt < lo->bbatt.min) { 9989 bbatt += 4; 9990 rfatt -= 1; 9991 continue; 9992 } 9993 if (rfatt > lo->rfatt.max) { 9994 rfatt -= 1; 9995 bbatt += 4; 9996 continue; 9997 } 9998 if (rfatt < lo->rfatt.min) { 9999 rfatt += 1; 10000 bbatt -= 4; 10001 continue; 10002 } 10003 break; 10004 } 10005 10006 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10007 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10008 } 10009 10010 static void 10011 bwn_phy_lock(struct bwn_mac *mac) 10012 { 10013 struct bwn_softc *sc = mac->mac_sc; 10014 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10015 10016 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10017 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10018 10019 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10020 bwn_psctl(mac, BWN_PS_AWAKE); 10021 } 10022 10023 static void 10024 bwn_phy_unlock(struct bwn_mac *mac) 10025 { 10026 struct bwn_softc *sc = mac->mac_sc; 10027 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10028 10029 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10030 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10031 10032 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10033 bwn_psctl(mac, 0); 10034 } 10035 10036 static void 10037 bwn_rf_lock(struct bwn_mac *mac) 10038 { 10039 10040 BWN_WRITE_4(mac, BWN_MACCTL, 10041 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10042 BWN_READ_4(mac, BWN_MACCTL); 10043 DELAY(10); 10044 } 10045 10046 static void 10047 bwn_rf_unlock(struct bwn_mac *mac) 10048 { 10049 10050 BWN_READ_2(mac, BWN_PHYVER); 10051 BWN_WRITE_4(mac, BWN_MACCTL, 10052 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10053 } 10054 10055 static struct bwn_pio_txqueue * 10056 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10057 struct bwn_pio_txpkt **pack) 10058 { 10059 struct bwn_pio *pio = &mac->mac_method.pio; 10060 struct bwn_pio_txqueue *tq = NULL; 10061 unsigned int index; 10062 10063 switch (cookie & 0xf000) { 10064 case 0x1000: 10065 tq = &pio->wme[WME_AC_BK]; 10066 break; 10067 case 0x2000: 10068 tq = &pio->wme[WME_AC_BE]; 10069 break; 10070 case 0x3000: 10071 tq = &pio->wme[WME_AC_VI]; 10072 break; 10073 case 0x4000: 10074 tq = &pio->wme[WME_AC_VO]; 10075 break; 10076 case 0x5000: 10077 tq = &pio->mcast; 10078 break; 10079 } 10080 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10081 if (tq == NULL) 10082 return (NULL); 10083 index = (cookie & 0x0fff); 10084 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10085 if (index >= N(tq->tq_pkts)) 10086 return (NULL); 10087 *pack = &tq->tq_pkts[index]; 10088 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10089 return (tq); 10090 } 10091 10092 static void 10093 bwn_txpwr(void *arg, int npending) 10094 { 10095 struct bwn_mac *mac = arg; 10096 10097 wlan_serialize_enter(); 10098 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10099 mac->mac_phy.set_txpwr != NULL) 10100 mac->mac_phy.set_txpwr(mac); 10101 wlan_serialize_exit(); 10102 } 10103 10104 static void 10105 bwn_task_15s(struct bwn_mac *mac) 10106 { 10107 uint16_t reg; 10108 10109 if (mac->mac_fw.opensource) { 10110 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10111 if (reg) { 10112 bwn_restart(mac, "fw watchdog"); 10113 return; 10114 } 10115 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10116 } 10117 if (mac->mac_phy.task_15s) 10118 mac->mac_phy.task_15s(mac); 10119 10120 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10121 } 10122 10123 static void 10124 bwn_task_30s(struct bwn_mac *mac) 10125 { 10126 10127 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10128 return; 10129 mac->mac_noise.noi_running = 1; 10130 mac->mac_noise.noi_nsamples = 0; 10131 10132 bwn_noise_gensample(mac); 10133 } 10134 10135 static void 10136 bwn_task_60s(struct bwn_mac *mac) 10137 { 10138 10139 if (mac->mac_phy.task_60s) 10140 mac->mac_phy.task_60s(mac); 10141 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10142 } 10143 10144 static void 10145 bwn_tasks(void *arg) 10146 { 10147 struct bwn_mac *mac = arg; 10148 struct bwn_softc *sc = mac->mac_sc; 10149 10150 wlan_serialize_enter(); 10151 10152 if (mac->mac_status != BWN_MAC_STATUS_STARTED) { 10153 wlan_serialize_exit(); 10154 return; 10155 } 10156 10157 if (mac->mac_task_state % 4 == 0) 10158 bwn_task_60s(mac); 10159 if (mac->mac_task_state % 2 == 0) 10160 bwn_task_30s(mac); 10161 bwn_task_15s(mac); 10162 10163 mac->mac_task_state++; 10164 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10165 wlan_serialize_exit(); 10166 } 10167 10168 static int 10169 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10170 { 10171 struct bwn_softc *sc = mac->mac_sc; 10172 10173 KASSERT(a == 0, ("not support APHY\n")); 10174 10175 switch (plcp->o.raw[0] & 0xf) { 10176 case 0xb: 10177 return (BWN_OFDM_RATE_6MB); 10178 case 0xf: 10179 return (BWN_OFDM_RATE_9MB); 10180 case 0xa: 10181 return (BWN_OFDM_RATE_12MB); 10182 case 0xe: 10183 return (BWN_OFDM_RATE_18MB); 10184 case 0x9: 10185 return (BWN_OFDM_RATE_24MB); 10186 case 0xd: 10187 return (BWN_OFDM_RATE_36MB); 10188 case 0x8: 10189 return (BWN_OFDM_RATE_48MB); 10190 case 0xc: 10191 return (BWN_OFDM_RATE_54MB); 10192 } 10193 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10194 plcp->o.raw[0] & 0xf); 10195 return (-1); 10196 } 10197 10198 static int 10199 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10200 { 10201 struct bwn_softc *sc = mac->mac_sc; 10202 10203 switch (plcp->o.raw[0]) { 10204 case 0x0a: 10205 return (BWN_CCK_RATE_1MB); 10206 case 0x14: 10207 return (BWN_CCK_RATE_2MB); 10208 case 0x37: 10209 return (BWN_CCK_RATE_5MB); 10210 case 0x6e: 10211 return (BWN_CCK_RATE_11MB); 10212 } 10213 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10214 return (-1); 10215 } 10216 10217 static void 10218 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10219 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10220 int rssi, int noise) 10221 { 10222 struct bwn_softc *sc = mac->mac_sc; 10223 const struct ieee80211_frame_min *wh; 10224 uint64_t tsf; 10225 uint16_t low_mactime_now; 10226 10227 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10228 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10229 10230 wh = mtod(m, const struct ieee80211_frame_min *); 10231 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10232 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10233 10234 bwn_tsf_read(mac, &tsf); 10235 low_mactime_now = tsf; 10236 tsf = tsf & ~0xffffULL; 10237 tsf += le16toh(rxhdr->mac_time); 10238 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10239 tsf -= 0x10000; 10240 10241 sc->sc_rx_th.wr_tsf = tsf; 10242 sc->sc_rx_th.wr_rate = rate; 10243 sc->sc_rx_th.wr_antsignal = rssi; 10244 sc->sc_rx_th.wr_antnoise = noise; 10245 } 10246 10247 static void 10248 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10249 { 10250 uint32_t low, high; 10251 10252 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10253 ("%s:%d: fail", __func__, __LINE__)); 10254 10255 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10256 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10257 *tsf = high; 10258 *tsf <<= 32; 10259 *tsf |= low; 10260 } 10261 10262 static int 10263 bwn_dma_attach(struct bwn_mac *mac) 10264 { 10265 struct bwn_dma *dma = &mac->mac_method.dma; 10266 struct bwn_softc *sc = mac->mac_sc; 10267 bus_addr_t lowaddr = 0; 10268 int error; 10269 10270 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10271 return (0); 10272 10273 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10274 10275 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10276 10277 dma->dmatype = bwn_dma_gettype(mac); 10278 if (dma->dmatype == BWN_DMA_30BIT) 10279 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10280 else if (dma->dmatype == BWN_DMA_32BIT) 10281 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10282 else 10283 lowaddr = BUS_SPACE_MAXADDR; 10284 10285 /* 10286 * Create top level DMA tag 10287 */ 10288 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10289 BWN_ALIGN, 0, /* alignment, bounds */ 10290 lowaddr, /* lowaddr */ 10291 BUS_SPACE_MAXADDR, /* highaddr */ 10292 NULL, NULL, /* filter, filterarg */ 10293 MAXBSIZE, /* maxsize */ 10294 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10295 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10296 0, /* flags */ 10297 &dma->parent_dtag); 10298 if (error) { 10299 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10300 return (error); 10301 } 10302 10303 /* 10304 * Create TX/RX mbuf DMA tag 10305 */ 10306 error = bus_dma_tag_create(dma->parent_dtag, 10307 4, 10308 0, 10309 BUS_SPACE_MAXADDR, 10310 BUS_SPACE_MAXADDR, 10311 NULL, NULL, 10312 MCLBYTES, 10313 1, 10314 BUS_SPACE_MAXSIZE_32BIT, 10315 0, 10316 &dma->rxbuf_dtag); 10317 if (error) { 10318 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10319 goto fail0; 10320 } 10321 error = bus_dma_tag_create(dma->parent_dtag, 10322 4, 10323 0, 10324 BUS_SPACE_MAXADDR, 10325 BUS_SPACE_MAXADDR, 10326 NULL, NULL, 10327 MCLBYTES, 10328 1, 10329 BUS_SPACE_MAXSIZE_32BIT, 10330 0, 10331 &dma->txbuf_dtag); 10332 if (error) { 10333 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10334 goto fail1; 10335 } 10336 10337 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10338 if (dma->wme[WME_AC_BK] == NULL) 10339 goto fail2; 10340 10341 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10342 if (dma->wme[WME_AC_BE] == NULL) 10343 goto fail3; 10344 10345 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10346 if (dma->wme[WME_AC_VI] == NULL) 10347 goto fail4; 10348 10349 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10350 if (dma->wme[WME_AC_VO] == NULL) 10351 goto fail5; 10352 10353 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10354 if (dma->mcast == NULL) 10355 goto fail6; 10356 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10357 if (dma->rx == NULL) 10358 goto fail7; 10359 10360 return (error); 10361 10362 fail7: bwn_dma_ringfree(&dma->mcast); 10363 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10364 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10365 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10366 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10367 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10368 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10369 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10370 return (error); 10371 } 10372 10373 static struct bwn_dma_ring * 10374 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10375 uint16_t cookie, int *slot) 10376 { 10377 struct bwn_dma *dma = &mac->mac_method.dma; 10378 struct bwn_dma_ring *dr; 10379 struct bwn_softc *sc = mac->mac_sc; 10380 10381 switch (cookie & 0xf000) { 10382 case 0x1000: 10383 dr = dma->wme[WME_AC_BK]; 10384 break; 10385 case 0x2000: 10386 dr = dma->wme[WME_AC_BE]; 10387 break; 10388 case 0x3000: 10389 dr = dma->wme[WME_AC_VI]; 10390 break; 10391 case 0x4000: 10392 dr = dma->wme[WME_AC_VO]; 10393 break; 10394 case 0x5000: 10395 dr = dma->mcast; 10396 break; 10397 default: 10398 dr = NULL; 10399 KASSERT(0 == 1, 10400 ("invalid cookie value %d", cookie & 0xf000)); 10401 } 10402 *slot = (cookie & 0x0fff); 10403 if (*slot < 0 || *slot >= dr->dr_numslots) { 10404 /* 10405 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10406 * that it occurs events which have same H/W sequence numbers. 10407 * When it's occurred just prints a WARNING msgs and ignores. 10408 */ 10409 KASSERT(status->seq == dma->lastseq, 10410 ("%s:%d: fail", __func__, __LINE__)); 10411 device_printf(sc->sc_dev, 10412 "out of slot ranges (0 < %d < %d)\n", *slot, 10413 dr->dr_numslots); 10414 return (NULL); 10415 } 10416 dma->lastseq = status->seq; 10417 return (dr); 10418 } 10419 10420 static void 10421 bwn_dma_stop(struct bwn_mac *mac) 10422 { 10423 struct bwn_dma *dma; 10424 10425 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10426 return; 10427 dma = &mac->mac_method.dma; 10428 10429 bwn_dma_ringstop(&dma->rx); 10430 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10431 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10432 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10433 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10434 bwn_dma_ringstop(&dma->mcast); 10435 } 10436 10437 static void 10438 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10439 { 10440 10441 if (dr == NULL) 10442 return; 10443 10444 bwn_dma_cleanup(*dr); 10445 } 10446 10447 static void 10448 bwn_pio_stop(struct bwn_mac *mac) 10449 { 10450 struct bwn_pio *pio; 10451 10452 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10453 return; 10454 pio = &mac->mac_method.pio; 10455 10456 bwn_destroy_queue_tx(&pio->mcast); 10457 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10458 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10459 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10460 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10461 } 10462 10463 static void 10464 bwn_led_attach(struct bwn_mac *mac) 10465 { 10466 struct bwn_softc *sc = mac->mac_sc; 10467 const uint8_t *led_act = NULL; 10468 uint16_t val[BWN_LED_MAX]; 10469 int i; 10470 10471 sc->sc_led_idle = (2350 * hz) / 1000; 10472 sc->sc_led_blink = 1; 10473 10474 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10475 if (siba_get_pci_subvendor(sc->sc_dev) == 10476 bwn_vendor_led_act[i].vid) { 10477 led_act = bwn_vendor_led_act[i].led_act; 10478 break; 10479 } 10480 } 10481 if (led_act == NULL) 10482 led_act = bwn_default_led_act; 10483 10484 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10485 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10486 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10487 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10488 10489 for (i = 0; i < BWN_LED_MAX; ++i) { 10490 struct bwn_led *led = &sc->sc_leds[i]; 10491 10492 if (val[i] == 0xff) { 10493 led->led_act = led_act[i]; 10494 } else { 10495 if (val[i] & BWN_LED_ACT_LOW) 10496 led->led_flags |= BWN_LED_F_ACTLOW; 10497 led->led_act = val[i] & BWN_LED_ACT_MASK; 10498 } 10499 led->led_mask = (1 << i); 10500 10501 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10502 led->led_act == BWN_LED_ACT_BLINK_POLL || 10503 led->led_act == BWN_LED_ACT_BLINK) { 10504 led->led_flags |= BWN_LED_F_BLINK; 10505 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10506 led->led_flags |= BWN_LED_F_POLLABLE; 10507 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10508 led->led_flags |= BWN_LED_F_SLOW; 10509 10510 if (sc->sc_blink_led == NULL) { 10511 sc->sc_blink_led = led; 10512 if (led->led_flags & BWN_LED_F_SLOW) 10513 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10514 } 10515 } 10516 10517 DPRINTF(sc, BWN_DEBUG_LED, 10518 "%dth led, act %d, lowact %d\n", i, 10519 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10520 } 10521 callout_init(&sc->sc_led_blink_ch); 10522 } 10523 10524 static __inline uint16_t 10525 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10526 { 10527 10528 if (led->led_flags & BWN_LED_F_ACTLOW) 10529 on = !on; 10530 if (on) 10531 val |= led->led_mask; 10532 else 10533 val &= ~led->led_mask; 10534 return val; 10535 } 10536 10537 static void 10538 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10539 { 10540 struct bwn_softc *sc = mac->mac_sc; 10541 struct ifnet *ifp = sc->sc_ifp; 10542 struct ieee80211com *ic = ifp->if_l2com; 10543 uint16_t val; 10544 int i; 10545 10546 if (nstate == IEEE80211_S_INIT) { 10547 callout_stop(&sc->sc_led_blink_ch); 10548 sc->sc_led_blinking = 0; 10549 } 10550 10551 if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0) 10552 return; 10553 10554 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10555 for (i = 0; i < BWN_LED_MAX; ++i) { 10556 struct bwn_led *led = &sc->sc_leds[i]; 10557 int on; 10558 10559 if (led->led_act == BWN_LED_ACT_UNKN || 10560 led->led_act == BWN_LED_ACT_NULL) 10561 continue; 10562 10563 if ((led->led_flags & BWN_LED_F_BLINK) && 10564 nstate != IEEE80211_S_INIT) 10565 continue; 10566 10567 switch (led->led_act) { 10568 case BWN_LED_ACT_ON: /* Always on */ 10569 on = 1; 10570 break; 10571 case BWN_LED_ACT_OFF: /* Always off */ 10572 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10573 on = 0; 10574 break; 10575 default: 10576 on = 1; 10577 switch (nstate) { 10578 case IEEE80211_S_INIT: 10579 on = 0; 10580 break; 10581 case IEEE80211_S_RUN: 10582 if (led->led_act == BWN_LED_ACT_11G && 10583 ic->ic_curmode != IEEE80211_MODE_11G) 10584 on = 0; 10585 break; 10586 default: 10587 if (led->led_act == BWN_LED_ACT_ASSOC) 10588 on = 0; 10589 break; 10590 } 10591 break; 10592 } 10593 10594 val = bwn_led_onoff(led, val, on); 10595 } 10596 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10597 } 10598 10599 static void 10600 bwn_led_event(struct bwn_mac *mac, int event) 10601 { 10602 struct bwn_softc *sc = mac->mac_sc; 10603 struct bwn_led *led = sc->sc_blink_led; 10604 int rate; 10605 10606 if (event == BWN_LED_EVENT_POLL) { 10607 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10608 return; 10609 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10610 return; 10611 } 10612 10613 sc->sc_led_ticks = ticks; 10614 if (sc->sc_led_blinking) 10615 return; 10616 10617 switch (event) { 10618 case BWN_LED_EVENT_RX: 10619 rate = sc->sc_rx_rate; 10620 break; 10621 case BWN_LED_EVENT_TX: 10622 rate = sc->sc_tx_rate; 10623 break; 10624 case BWN_LED_EVENT_POLL: 10625 rate = 0; 10626 break; 10627 default: 10628 panic("unknown LED event %d\n", event); 10629 break; 10630 } 10631 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10632 bwn_led_duration[rate].off_dur); 10633 } 10634 10635 static void 10636 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10637 { 10638 struct bwn_softc *sc = mac->mac_sc; 10639 struct bwn_led *led = sc->sc_blink_led; 10640 uint16_t val; 10641 10642 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10643 val = bwn_led_onoff(led, val, 1); 10644 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10645 10646 if (led->led_flags & BWN_LED_F_SLOW) { 10647 BWN_LED_SLOWDOWN(on_dur); 10648 BWN_LED_SLOWDOWN(off_dur); 10649 } 10650 10651 sc->sc_led_blinking = 1; 10652 sc->sc_led_blink_offdur = off_dur; 10653 10654 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10655 } 10656 10657 static void 10658 bwn_led_blink_next(void *arg) 10659 { 10660 struct bwn_mac *mac = arg; 10661 struct bwn_softc *sc = mac->mac_sc; 10662 uint16_t val; 10663 10664 wlan_serialize_enter(); 10665 10666 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10667 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10668 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10669 10670 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10671 bwn_led_blink_end, mac); 10672 wlan_serialize_exit(); 10673 } 10674 10675 static void 10676 bwn_led_blink_end(void *arg) 10677 { 10678 struct bwn_mac *mac = arg; 10679 struct bwn_softc *sc = mac->mac_sc; 10680 10681 sc->sc_led_blinking = 0; 10682 } 10683 10684 static int 10685 bwn_suspend(device_t dev) 10686 { 10687 struct bwn_softc *sc = device_get_softc(dev); 10688 10689 wlan_serialize_enter(); 10690 bwn_stop(sc, 1); 10691 wlan_serialize_exit(); 10692 10693 return (0); 10694 } 10695 10696 static int 10697 bwn_resume(device_t dev) 10698 { 10699 struct bwn_softc *sc = device_get_softc(dev); 10700 struct ifnet *ifp = sc->sc_ifp; 10701 10702 wlan_serialize_enter(); 10703 if (ifp->if_flags & IFF_UP) 10704 bwn_init(sc); 10705 wlan_serialize_exit(); 10706 return (0); 10707 } 10708 10709 static void 10710 bwn_rfswitch(void *arg) 10711 { 10712 struct bwn_softc *sc = arg; 10713 struct bwn_mac *mac = sc->sc_curmac; 10714 int cur = 0, prev = 0; 10715 10716 wlan_serialize_enter(); 10717 10718 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10719 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10720 10721 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10722 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10723 & BWN_RF_HWENABLED_HI_MASK)) 10724 cur = 1; 10725 } else { 10726 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10727 & BWN_RF_HWENABLED_LO_MASK) 10728 cur = 1; 10729 } 10730 10731 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10732 prev = 1; 10733 10734 if (cur != prev) { 10735 if (cur) 10736 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10737 else 10738 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10739 10740 device_printf(sc->sc_dev, 10741 "status of RF switch is changed to %s\n", 10742 cur ? "ON" : "OFF"); 10743 if (cur != mac->mac_phy.rf_on) { 10744 if (cur) 10745 bwn_rf_turnon(mac); 10746 else 10747 bwn_rf_turnoff(mac); 10748 } 10749 } 10750 10751 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 10752 wlan_serialize_exit(); 10753 } 10754 10755 static void 10756 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10757 { 10758 struct bwn_phy *phy = &mac->mac_phy; 10759 struct bwn_phy_lp *plp = &phy->phy_lp; 10760 10761 plp->plp_antenna = BWN_ANT_DEFAULT; 10762 } 10763 10764 static int 10765 bwn_phy_lp_init(struct bwn_mac *mac) 10766 { 10767 static const struct bwn_stxtable tables[] = { 10768 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10769 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10770 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10771 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10772 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10773 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10774 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10775 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10776 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10777 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10778 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10779 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10780 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10781 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10782 { 2, 11, 0x40, 0, 0x0f } 10783 }; 10784 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10785 struct bwn_softc *sc = mac->mac_sc; 10786 const struct bwn_stxtable *st; 10787 struct ifnet *ifp = sc->sc_ifp; 10788 struct ieee80211com *ic = ifp->if_l2com; 10789 int i, error; 10790 uint16_t tmp; 10791 10792 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10793 bwn_phy_lp_bbinit(mac); 10794 10795 /* initialize RF */ 10796 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10797 DELAY(1); 10798 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10799 DELAY(1); 10800 10801 if (mac->mac_phy.rf_ver == 0x2062) 10802 bwn_phy_lp_b2062_init(mac); 10803 else { 10804 bwn_phy_lp_b2063_init(mac); 10805 10806 /* synchronize stx table. */ 10807 for (i = 0; i < N(tables); i++) { 10808 st = &tables[i]; 10809 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10810 tmp >>= st->st_rfshift; 10811 tmp <<= st->st_physhift; 10812 BWN_PHY_SETMASK(mac, 10813 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10814 ~(st->st_mask << st->st_physhift), tmp); 10815 } 10816 10817 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10818 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10819 } 10820 10821 /* calibrate RC */ 10822 if (mac->mac_phy.rev >= 2) 10823 bwn_phy_lp_rxcal_r2(mac); 10824 else if (!plp->plp_rccap) { 10825 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10826 bwn_phy_lp_rccal_r12(mac); 10827 } else 10828 bwn_phy_lp_set_rccap(mac); 10829 10830 error = bwn_phy_lp_switch_channel(mac, 7); 10831 if (error) 10832 device_printf(sc->sc_dev, 10833 "failed to change channel 7 (%d)\n", error); 10834 bwn_phy_lp_txpctl_init(mac); 10835 bwn_phy_lp_calib(mac); 10836 return (0); 10837 } 10838 10839 static uint16_t 10840 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10841 { 10842 10843 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10844 return (BWN_READ_2(mac, BWN_PHYDATA)); 10845 } 10846 10847 static void 10848 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10849 { 10850 10851 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10852 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10853 } 10854 10855 static void 10856 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10857 uint16_t set) 10858 { 10859 10860 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10861 BWN_WRITE_2(mac, BWN_PHYDATA, 10862 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10863 } 10864 10865 static uint16_t 10866 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10867 { 10868 10869 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10870 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10871 reg |= 0x100; 10872 if (mac->mac_phy.rev >= 2) 10873 reg |= 0x200; 10874 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10875 return BWN_READ_2(mac, BWN_RFDATALO); 10876 } 10877 10878 static void 10879 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10880 { 10881 10882 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10883 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10884 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10885 } 10886 10887 static void 10888 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10889 { 10890 10891 if (on) { 10892 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10893 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10894 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10895 return; 10896 } 10897 10898 if (mac->mac_phy.rev >= 2) { 10899 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10900 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10901 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10902 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10903 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10904 return; 10905 } 10906 10907 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10908 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10909 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10910 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10911 } 10912 10913 static int 10914 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10915 { 10916 struct bwn_phy *phy = &mac->mac_phy; 10917 struct bwn_phy_lp *plp = &phy->phy_lp; 10918 int error; 10919 10920 if (phy->rf_ver == 0x2063) { 10921 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 10922 if (error) 10923 return (error); 10924 } else { 10925 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 10926 if (error) 10927 return (error); 10928 bwn_phy_lp_set_anafilter(mac, chan); 10929 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 10930 } 10931 10932 plp->plp_chan = chan; 10933 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 10934 return (0); 10935 } 10936 10937 static uint32_t 10938 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 10939 { 10940 struct bwn_softc *sc = mac->mac_sc; 10941 struct ifnet *ifp = sc->sc_ifp; 10942 struct ieee80211com *ic = ifp->if_l2com; 10943 10944 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 10945 } 10946 10947 static void 10948 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 10949 { 10950 struct bwn_phy *phy = &mac->mac_phy; 10951 struct bwn_phy_lp *plp = &phy->phy_lp; 10952 10953 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 10954 return; 10955 10956 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 10957 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 10958 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 10959 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 10960 plp->plp_antenna = antenna; 10961 } 10962 10963 static void 10964 bwn_phy_lp_task_60s(struct bwn_mac *mac) 10965 { 10966 10967 bwn_phy_lp_calib(mac); 10968 } 10969 10970 static void 10971 bwn_phy_lp_readsprom(struct bwn_mac *mac) 10972 { 10973 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10974 struct bwn_softc *sc = mac->mac_sc; 10975 struct ifnet *ifp = sc->sc_ifp; 10976 struct ieee80211com *ic = ifp->if_l2com; 10977 10978 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 10979 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 10980 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 10981 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 10982 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 10983 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 10984 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 10985 return; 10986 } 10987 10988 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 10989 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 10990 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 10991 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 10992 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 10993 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 10994 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 10995 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 10996 } 10997 10998 static void 10999 bwn_phy_lp_bbinit(struct bwn_mac *mac) 11000 { 11001 11002 bwn_phy_lp_tblinit(mac); 11003 if (mac->mac_phy.rev >= 2) 11004 bwn_phy_lp_bbinit_r2(mac); 11005 else 11006 bwn_phy_lp_bbinit_r01(mac); 11007 } 11008 11009 static void 11010 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11011 { 11012 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11013 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11014 struct bwn_softc *sc = mac->mac_sc; 11015 struct ifnet *ifp = sc->sc_ifp; 11016 struct ieee80211com *ic = ifp->if_l2com; 11017 11018 bwn_phy_lp_set_txgain(mac, 11019 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11020 bwn_phy_lp_set_bbmult(mac, 150); 11021 } 11022 11023 static void 11024 bwn_phy_lp_calib(struct bwn_mac *mac) 11025 { 11026 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11027 struct bwn_softc *sc = mac->mac_sc; 11028 struct ifnet *ifp = sc->sc_ifp; 11029 struct ieee80211com *ic = ifp->if_l2com; 11030 const struct bwn_rxcompco *rc = NULL; 11031 struct bwn_txgain ogain; 11032 int i, omode, oafeovr, orf, obbmult; 11033 uint8_t mode, fc = 0; 11034 11035 if (plp->plp_chanfullcal != plp->plp_chan) { 11036 plp->plp_chanfullcal = plp->plp_chan; 11037 fc = 1; 11038 } 11039 11040 bwn_mac_suspend(mac); 11041 11042 /* BlueTooth Coexistance Override */ 11043 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11044 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11045 11046 if (mac->mac_phy.rev >= 2) 11047 bwn_phy_lp_digflt_save(mac); 11048 bwn_phy_lp_get_txpctlmode(mac); 11049 mode = plp->plp_txpctlmode; 11050 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11051 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11052 bwn_phy_lp_bugfix(mac); 11053 if (mac->mac_phy.rev >= 2 && fc == 1) { 11054 bwn_phy_lp_get_txpctlmode(mac); 11055 omode = plp->plp_txpctlmode; 11056 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11057 if (oafeovr) 11058 ogain = bwn_phy_lp_get_txgain(mac); 11059 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11060 obbmult = bwn_phy_lp_get_bbmult(mac); 11061 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11062 if (oafeovr) 11063 bwn_phy_lp_set_txgain(mac, &ogain); 11064 bwn_phy_lp_set_bbmult(mac, obbmult); 11065 bwn_phy_lp_set_txpctlmode(mac, omode); 11066 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11067 } 11068 bwn_phy_lp_set_txpctlmode(mac, mode); 11069 if (mac->mac_phy.rev >= 2) 11070 bwn_phy_lp_digflt_restore(mac); 11071 11072 /* do RX IQ Calculation; assumes that noise is true. */ 11073 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11074 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11075 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11076 rc = &bwn_rxcompco_5354[i]; 11077 } 11078 } else if (mac->mac_phy.rev >= 2) 11079 rc = &bwn_rxcompco_r2; 11080 else { 11081 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11082 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11083 rc = &bwn_rxcompco_r12[i]; 11084 } 11085 } 11086 if (rc == NULL) 11087 goto fail; 11088 11089 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11090 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11091 11092 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11093 11094 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11095 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11096 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11097 } else { 11098 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11099 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11100 } 11101 11102 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11103 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11104 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11105 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11106 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11107 bwn_phy_lp_set_deaf(mac, 0); 11108 /* XXX no checking return value? */ 11109 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11110 bwn_phy_lp_clear_deaf(mac, 0); 11111 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11112 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11113 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11114 11115 /* disable RX GAIN override. */ 11116 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11117 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11118 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11119 if (mac->mac_phy.rev >= 2) { 11120 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11121 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11122 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11123 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11124 } 11125 } else { 11126 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11127 } 11128 11129 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11130 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11131 fail: 11132 bwn_mac_enable(mac); 11133 } 11134 11135 static void 11136 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11137 { 11138 11139 if (on) { 11140 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11141 return; 11142 } 11143 11144 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11145 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11146 } 11147 11148 static int 11149 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11150 { 11151 static const struct bwn_b206x_chan *bc = NULL; 11152 struct bwn_softc *sc = mac->mac_sc; 11153 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11154 tmp[6]; 11155 uint16_t old, scale, tmp16; 11156 int i, div; 11157 11158 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11159 if (bwn_b2063_chantable[i].bc_chan == chan) { 11160 bc = &bwn_b2063_chantable[i]; 11161 break; 11162 } 11163 } 11164 if (bc == NULL) 11165 return (EINVAL); 11166 11167 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11168 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11169 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11170 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11171 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11172 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11173 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11174 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11175 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11176 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11177 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11178 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11179 11180 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11181 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11182 11183 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11184 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11185 freqref = freqxtal * 3; 11186 div = (freqxtal <= 26000000 ? 1 : 2); 11187 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11188 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11189 999999) / 1000000) + 1; 11190 11191 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11192 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11193 0xfff8, timeout >> 2); 11194 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11195 0xff9f,timeout << 5); 11196 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11197 11198 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11199 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11200 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11201 11202 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11203 (timeoutref + 1)) - 1; 11204 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11205 0xf0, count >> 8); 11206 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11207 11208 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11209 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11210 while (tmp[1] >= freqref) { 11211 tmp[0]++; 11212 tmp[1] -= freqref; 11213 } 11214 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11215 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11216 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11217 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11218 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11219 11220 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11221 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11222 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11223 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11224 11225 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11226 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11227 11228 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11229 scale = 1; 11230 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11231 } else { 11232 scale = 0; 11233 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11234 } 11235 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11236 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11237 11238 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11239 (scale + 1); 11240 if (tmp[5] > 150) 11241 tmp[5] = 0; 11242 11243 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11244 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11245 11246 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11247 if (freqxtal > 26000000) 11248 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11249 else 11250 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11251 11252 if (val[0] == 45) 11253 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11254 else 11255 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11256 11257 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11258 DELAY(1); 11259 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11260 11261 /* VCO Calibration */ 11262 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11263 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11264 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11265 DELAY(1); 11266 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11267 DELAY(1); 11268 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11269 DELAY(1); 11270 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11271 DELAY(300); 11272 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11273 11274 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11275 return (0); 11276 } 11277 11278 static int 11279 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11280 { 11281 struct bwn_softc *sc = mac->mac_sc; 11282 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11283 const struct bwn_b206x_chan *bc = NULL; 11284 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11285 uint32_t tmp[9]; 11286 int i; 11287 11288 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11289 if (bwn_b2062_chantable[i].bc_chan == chan) { 11290 bc = &bwn_b2062_chantable[i]; 11291 break; 11292 } 11293 } 11294 11295 if (bc == NULL) 11296 return (EINVAL); 11297 11298 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11299 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11300 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11301 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11302 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11303 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11304 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11305 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11306 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11307 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11308 11309 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11310 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11311 bwn_phy_lp_b2062_reset_pllbias(mac); 11312 tmp[0] = freqxtal / 1000; 11313 tmp[1] = plp->plp_div * 1000; 11314 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11315 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11316 tmp[2] *= 2; 11317 tmp[3] = 48 * tmp[0]; 11318 tmp[5] = tmp[2] / tmp[3]; 11319 tmp[6] = tmp[2] % tmp[3]; 11320 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11321 tmp[4] = tmp[6] * 0x100; 11322 tmp[5] = tmp[4] / tmp[3]; 11323 tmp[6] = tmp[4] % tmp[3]; 11324 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11325 tmp[4] = tmp[6] * 0x100; 11326 tmp[5] = tmp[4] / tmp[3]; 11327 tmp[6] = tmp[4] % tmp[3]; 11328 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11329 tmp[4] = tmp[6] * 0x100; 11330 tmp[5] = tmp[4] / tmp[3]; 11331 tmp[6] = tmp[4] % tmp[3]; 11332 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11333 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11334 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11335 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11336 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11337 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11338 11339 bwn_phy_lp_b2062_vco_calib(mac); 11340 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11341 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11342 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11343 bwn_phy_lp_b2062_reset_pllbias(mac); 11344 bwn_phy_lp_b2062_vco_calib(mac); 11345 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11346 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11347 return (EIO); 11348 } 11349 } 11350 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11351 return (0); 11352 } 11353 11354 static void 11355 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11356 { 11357 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11358 uint16_t tmp = (channel == 14); 11359 11360 if (mac->mac_phy.rev < 2) { 11361 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11362 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11363 bwn_phy_lp_set_rccap(mac); 11364 return; 11365 } 11366 11367 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11368 } 11369 11370 static void 11371 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11372 { 11373 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11374 struct bwn_softc *sc = mac->mac_sc; 11375 struct ifnet *ifp = sc->sc_ifp; 11376 struct ieee80211com *ic = ifp->if_l2com; 11377 uint16_t iso, tmp[3]; 11378 11379 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11380 11381 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11382 iso = plp->plp_txisoband_m; 11383 else if (freq <= 5320) 11384 iso = plp->plp_txisoband_l; 11385 else if (freq <= 5700) 11386 iso = plp->plp_txisoband_m; 11387 else 11388 iso = plp->plp_txisoband_h; 11389 11390 tmp[0] = ((iso - 26) / 12) << 12; 11391 tmp[1] = tmp[0] + 0x1000; 11392 tmp[2] = tmp[0] + 0x2000; 11393 11394 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11395 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11396 } 11397 11398 static void 11399 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11400 { 11401 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11402 int i; 11403 static const uint16_t addr[] = { 11404 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11405 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11406 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11407 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11408 BWN_PHY_OFDM(0xcf), 11409 }; 11410 static const uint16_t val[] = { 11411 0xde5e, 0xe832, 0xe331, 0x4d26, 11412 0x0026, 0x1420, 0x0020, 0xfe08, 11413 0x0008, 11414 }; 11415 11416 for (i = 0; i < N(addr); i++) { 11417 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11418 BWN_PHY_WRITE(mac, addr[i], val[i]); 11419 } 11420 } 11421 11422 static void 11423 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11424 { 11425 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11426 struct bwn_softc *sc = mac->mac_sc; 11427 uint16_t ctl; 11428 11429 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11430 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11431 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11432 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11433 break; 11434 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11435 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11436 break; 11437 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11438 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11439 break; 11440 default: 11441 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11442 device_printf(sc->sc_dev, "unknown command mode\n"); 11443 break; 11444 } 11445 } 11446 11447 static void 11448 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11449 { 11450 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11451 uint16_t ctl; 11452 uint8_t old; 11453 11454 bwn_phy_lp_get_txpctlmode(mac); 11455 old = plp->plp_txpctlmode; 11456 if (old == mode) 11457 return; 11458 plp->plp_txpctlmode = mode; 11459 11460 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11461 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11462 plp->plp_tssiidx); 11463 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11464 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11465 11466 /* disable TX GAIN override */ 11467 if (mac->mac_phy.rev < 2) 11468 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11469 else { 11470 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11471 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11472 } 11473 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11474 11475 plp->plp_txpwridx = -1; 11476 } 11477 if (mac->mac_phy.rev >= 2) { 11478 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11479 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11480 else 11481 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11482 } 11483 11484 /* writes TX Power Control mode */ 11485 switch (plp->plp_txpctlmode) { 11486 case BWN_PHYLP_TXPCTL_OFF: 11487 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11488 break; 11489 case BWN_PHYLP_TXPCTL_ON_HW: 11490 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11491 break; 11492 case BWN_PHYLP_TXPCTL_ON_SW: 11493 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11494 break; 11495 default: 11496 ctl = 0; 11497 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11498 } 11499 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11500 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11501 } 11502 11503 static void 11504 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11505 { 11506 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11507 const unsigned int size = 256; 11508 struct bwn_txgain tg; 11509 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11510 uint16_t tssinpt, tssiidx, value[2]; 11511 uint8_t mode; 11512 int8_t txpwridx; 11513 11514 tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF, 11515 M_INTWAIT | M_ZERO); 11516 11517 bwn_phy_lp_get_txpctlmode(mac); 11518 mode = plp->plp_txpctlmode; 11519 txpwridx = plp->plp_txpwridx; 11520 tssinpt = plp->plp_tssinpt; 11521 tssiidx = plp->plp_tssiidx; 11522 11523 bwn_tab_read_multi(mac, 11524 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11525 BWN_TAB_4(7, 0x140), size, tabs); 11526 11527 bwn_phy_lp_tblinit(mac); 11528 bwn_phy_lp_bbinit(mac); 11529 bwn_phy_lp_txpctl_init(mac); 11530 bwn_phy_lp_rf_onoff(mac, 1); 11531 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11532 11533 bwn_tab_write_multi(mac, 11534 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11535 BWN_TAB_4(7, 0x140), size, tabs); 11536 11537 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11538 plp->plp_tssinpt = tssinpt; 11539 plp->plp_tssiidx = tssiidx; 11540 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11541 if (txpwridx != -1) { 11542 /* set TX power by index */ 11543 plp->plp_txpwridx = txpwridx; 11544 bwn_phy_lp_get_txpctlmode(mac); 11545 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11546 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11547 if (mac->mac_phy.rev >= 2) { 11548 rxcomp = bwn_tab_read(mac, 11549 BWN_TAB_4(7, txpwridx + 320)); 11550 txgain = bwn_tab_read(mac, 11551 BWN_TAB_4(7, txpwridx + 192)); 11552 tg.tg_pad = (txgain >> 16) & 0xff; 11553 tg.tg_gm = txgain & 0xff; 11554 tg.tg_pga = (txgain >> 8) & 0xff; 11555 tg.tg_dac = (rxcomp >> 28) & 0xff; 11556 bwn_phy_lp_set_txgain(mac, &tg); 11557 } else { 11558 rxcomp = bwn_tab_read(mac, 11559 BWN_TAB_4(10, txpwridx + 320)); 11560 txgain = bwn_tab_read(mac, 11561 BWN_TAB_4(10, txpwridx + 192)); 11562 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11563 0xf800, (txgain >> 4) & 0x7fff); 11564 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11565 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11566 } 11567 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11568 11569 /* set TX IQCC */ 11570 value[0] = (rxcomp >> 10) & 0x3ff; 11571 value[1] = rxcomp & 0x3ff; 11572 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11573 11574 coeff = bwn_tab_read(mac, 11575 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11576 BWN_TAB_4(10, txpwridx + 448)); 11577 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11578 if (mac->mac_phy.rev >= 2) { 11579 rfpwr = bwn_tab_read(mac, 11580 BWN_TAB_4(7, txpwridx + 576)); 11581 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11582 rfpwr & 0xffff); 11583 } 11584 bwn_phy_lp_set_txgain_override(mac); 11585 } 11586 if (plp->plp_rccap) 11587 bwn_phy_lp_set_rccap(mac); 11588 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11589 bwn_phy_lp_set_txpctlmode(mac, mode); 11590 kfree(tabs, M_DEVBUF); 11591 } 11592 11593 static void 11594 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11595 { 11596 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11597 int i; 11598 static const uint16_t addr[] = { 11599 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11600 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11601 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11602 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11603 BWN_PHY_OFDM(0xcf), 11604 }; 11605 11606 for (i = 0; i < N(addr); i++) 11607 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11608 } 11609 11610 static void 11611 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11612 { 11613 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11614 11615 if (mac->mac_phy.rev < 2) { 11616 bwn_phy_lp_tblinit_r01(mac); 11617 bwn_phy_lp_tblinit_txgain(mac); 11618 bwn_phy_lp_set_gaintbl(mac, freq); 11619 return; 11620 } 11621 11622 bwn_phy_lp_tblinit_r2(mac); 11623 bwn_phy_lp_tblinit_txgain(mac); 11624 } 11625 11626 struct bwn_wpair { 11627 uint16_t reg; 11628 uint16_t value; 11629 }; 11630 11631 struct bwn_smpair { 11632 uint16_t offset; 11633 uint16_t mask; 11634 uint16_t set; 11635 }; 11636 11637 static void 11638 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11639 { 11640 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11641 struct bwn_softc *sc = mac->mac_sc; 11642 struct ifnet *ifp = sc->sc_ifp; 11643 struct ieee80211com *ic = ifp->if_l2com; 11644 static const struct bwn_wpair v1[] = { 11645 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11646 { BWN_PHY_AFE_CTL, 0x8800 }, 11647 { BWN_PHY_AFE_CTL_OVR, 0 }, 11648 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11649 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11650 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11651 { BWN_PHY_OFDM(0xf9), 0 }, 11652 { BWN_PHY_TR_LOOKUP_1, 0 } 11653 }; 11654 static const struct bwn_smpair v2[] = { 11655 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11656 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11657 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11658 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11659 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11660 }; 11661 static const struct bwn_smpair v3[] = { 11662 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11663 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11664 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11665 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11666 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11667 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11668 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11669 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11670 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11671 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11672 11673 }; 11674 int i; 11675 11676 for (i = 0; i < N(v1); i++) 11677 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11678 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11679 for (i = 0; i < N(v2); i++) 11680 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11681 11682 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11683 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11684 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11685 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11686 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11687 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11688 } else { 11689 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11690 } 11691 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11692 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11693 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11694 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11695 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11696 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11697 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11698 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11699 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11700 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11701 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11702 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11703 (siba_get_chiprev(sc->sc_dev) == 0)) { 11704 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11705 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11706 } else { 11707 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11708 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11709 } 11710 for (i = 0; i < N(v3); i++) 11711 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11712 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11713 (siba_get_chiprev(sc->sc_dev) == 0)) { 11714 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11715 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11716 } 11717 11718 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11719 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11720 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11721 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11722 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11723 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11724 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11725 } else 11726 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11727 11728 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11729 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11730 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11731 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11732 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11733 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11734 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11735 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11736 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11737 11738 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11739 (siba_get_chiprev(sc->sc_dev) == 0)) { 11740 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11741 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11742 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11743 } 11744 11745 bwn_phy_lp_digflt_save(mac); 11746 } 11747 11748 static void 11749 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11750 { 11751 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11752 struct bwn_softc *sc = mac->mac_sc; 11753 struct ifnet *ifp = sc->sc_ifp; 11754 struct ieee80211com *ic = ifp->if_l2com; 11755 static const struct bwn_smpair v1[] = { 11756 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11757 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11758 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11759 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11760 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11761 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11762 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11763 }; 11764 static const struct bwn_smpair v2[] = { 11765 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11766 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11767 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11768 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11769 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11770 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11771 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11772 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11773 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11774 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11775 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11776 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11777 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11778 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11779 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11780 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11781 }; 11782 static const struct bwn_smpair v3[] = { 11783 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11784 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11785 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11786 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11787 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11788 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11789 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11790 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11791 }; 11792 static const struct bwn_smpair v4[] = { 11793 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11794 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11795 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11796 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11797 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11798 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11799 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11800 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11801 }; 11802 static const struct bwn_smpair v5[] = { 11803 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11804 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11805 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11806 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11807 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11808 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11809 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11810 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11811 }; 11812 int i; 11813 uint16_t tmp, tmp2; 11814 11815 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11816 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11817 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11818 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11819 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11820 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11821 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11822 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11823 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11824 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11825 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11826 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11827 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11828 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11829 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11830 for (i = 0; i < N(v1); i++) 11831 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11832 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11833 0xff00, plp->plp_rxpwroffset); 11834 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11835 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11836 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11837 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11838 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11839 if (mac->mac_phy.rev == 0) 11840 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11841 0xffcf, 0x0010); 11842 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11843 } else { 11844 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11845 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11846 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11847 } 11848 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11849 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11850 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11851 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11852 else 11853 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11854 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11855 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11856 0xfff9, (plp->plp_bxarch << 1)); 11857 if (mac->mac_phy.rev == 1 && 11858 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11859 for (i = 0; i < N(v2); i++) 11860 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11861 v2[i].set); 11862 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11863 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11864 ((mac->mac_phy.rev == 0) && 11865 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11866 for (i = 0; i < N(v3); i++) 11867 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11868 v3[i].set); 11869 } else if (mac->mac_phy.rev == 1 || 11870 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11871 for (i = 0; i < N(v4); i++) 11872 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11873 v4[i].set); 11874 } else { 11875 for (i = 0; i < N(v5); i++) 11876 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11877 v5[i].set); 11878 } 11879 if (mac->mac_phy.rev == 1 && 11880 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11881 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11882 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11883 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11884 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11885 } 11886 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11887 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11888 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11889 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11890 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11891 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11892 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11893 } 11894 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11895 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11896 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11897 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11898 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11899 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11900 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11901 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11902 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11903 } else { 11904 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11905 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11906 } 11907 if (mac->mac_phy.rev == 1) { 11908 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11909 tmp2 = (tmp & 0x03e0) >> 5; 11910 tmp2 |= tmp2 << 5; 11911 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11912 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 11913 tmp2 = (tmp & 0x1f00) >> 8; 11914 tmp2 |= tmp2 << 5; 11915 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 11916 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 11917 tmp2 = tmp & 0x00ff; 11918 tmp2 |= tmp << 8; 11919 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 11920 } 11921 } 11922 11923 struct bwn_b2062_freq { 11924 uint16_t freq; 11925 uint8_t value[6]; 11926 }; 11927 11928 static void 11929 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 11930 { 11931 #define CALC_CTL7(freq, div) \ 11932 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 11933 #define CALC_CTL18(freq, div) \ 11934 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 11935 #define CALC_CTL19(freq, div) \ 11936 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 11937 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11938 struct bwn_softc *sc = mac->mac_sc; 11939 struct ifnet *ifp = sc->sc_ifp; 11940 struct ieee80211com *ic = ifp->if_l2com; 11941 static const struct bwn_b2062_freq freqdata_tab[] = { 11942 { 12000, { 6, 6, 6, 6, 10, 6 } }, 11943 { 13000, { 4, 4, 4, 4, 11, 7 } }, 11944 { 14400, { 3, 3, 3, 3, 12, 7 } }, 11945 { 16200, { 3, 3, 3, 3, 13, 8 } }, 11946 { 18000, { 2, 2, 2, 2, 14, 8 } }, 11947 { 19200, { 1, 1, 1, 1, 14, 9 } } 11948 }; 11949 static const struct bwn_wpair v1[] = { 11950 { BWN_B2062_N_TXCTL3, 0 }, 11951 { BWN_B2062_N_TXCTL4, 0 }, 11952 { BWN_B2062_N_TXCTL5, 0 }, 11953 { BWN_B2062_N_TXCTL6, 0 }, 11954 { BWN_B2062_N_PDNCTL0, 0x40 }, 11955 { BWN_B2062_N_PDNCTL0, 0 }, 11956 { BWN_B2062_N_CALIB_TS, 0x10 }, 11957 { BWN_B2062_N_CALIB_TS, 0 } 11958 }; 11959 const struct bwn_b2062_freq *f = NULL; 11960 uint32_t xtalfreq, ref; 11961 unsigned int i; 11962 11963 bwn_phy_lp_b2062_tblinit(mac); 11964 11965 for (i = 0; i < N(v1); i++) 11966 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 11967 if (mac->mac_phy.rev > 0) 11968 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 11969 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 11970 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11971 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 11972 else 11973 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 11974 11975 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 11976 ("%s:%d: fail", __func__, __LINE__)); 11977 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11978 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 11979 11980 if (xtalfreq <= 30000000) { 11981 plp->plp_div = 1; 11982 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 11983 } else { 11984 plp->plp_div = 2; 11985 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 11986 } 11987 11988 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 11989 CALC_CTL7(xtalfreq, plp->plp_div)); 11990 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 11991 CALC_CTL18(xtalfreq, plp->plp_div)); 11992 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 11993 CALC_CTL19(xtalfreq, plp->plp_div)); 11994 11995 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 11996 ref &= 0xffff; 11997 for (i = 0; i < N(freqdata_tab); i++) { 11998 if (ref < freqdata_tab[i].freq) { 11999 f = &freqdata_tab[i]; 12000 break; 12001 } 12002 } 12003 if (f == NULL) 12004 f = &freqdata_tab[N(freqdata_tab) - 1]; 12005 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12006 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12007 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12008 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12009 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12010 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12011 #undef CALC_CTL7 12012 #undef CALC_CTL18 12013 #undef CALC_CTL19 12014 } 12015 12016 static void 12017 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12018 { 12019 12020 bwn_phy_lp_b2063_tblinit(mac); 12021 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12022 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12023 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12024 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12025 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12026 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12027 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12028 if (mac->mac_phy.rev == 2) { 12029 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12030 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12031 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12032 } else { 12033 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12034 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12035 } 12036 } 12037 12038 static void 12039 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12040 { 12041 struct bwn_softc *sc = mac->mac_sc; 12042 static const struct bwn_wpair v1[] = { 12043 { BWN_B2063_RX_BB_SP8, 0x0 }, 12044 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12045 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12046 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12047 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12048 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12049 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12050 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12051 }; 12052 static const struct bwn_wpair v2[] = { 12053 { BWN_B2063_TX_BB_SP3, 0x0 }, 12054 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12055 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12056 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12057 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12058 }; 12059 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12060 int i; 12061 uint8_t tmp; 12062 12063 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12064 12065 for (i = 0; i < 2; i++) 12066 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12067 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12068 for (i = 2; i < N(v1); i++) 12069 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12070 for (i = 0; i < 10000; i++) { 12071 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12072 break; 12073 DELAY(1000); 12074 } 12075 12076 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12077 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12078 12079 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12080 12081 for (i = 0; i < N(v2); i++) 12082 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12083 if (freqxtal == 24000000) { 12084 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12085 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12086 } else { 12087 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12088 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12089 } 12090 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12091 for (i = 0; i < 10000; i++) { 12092 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12093 break; 12094 DELAY(1000); 12095 } 12096 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12097 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12098 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12099 } 12100 12101 static void 12102 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12103 { 12104 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12105 struct bwn_softc *sc = mac->mac_sc; 12106 struct bwn_phy_lp_iq_est ie; 12107 struct bwn_txgain tx_gains; 12108 static const uint32_t pwrtbl[21] = { 12109 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12110 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12111 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12112 0x0004c, 0x0002c, 0x0001a, 12113 }; 12114 uint32_t npwr, ipwr, sqpwr, tmp; 12115 int loopback, i, j, sum, error; 12116 uint16_t save[7]; 12117 uint8_t txo, bbmult, txpctlmode; 12118 12119 error = bwn_phy_lp_switch_channel(mac, 7); 12120 if (error) 12121 device_printf(sc->sc_dev, 12122 "failed to change channel to 7 (%d)\n", error); 12123 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12124 bbmult = bwn_phy_lp_get_bbmult(mac); 12125 if (txo) 12126 tx_gains = bwn_phy_lp_get_txgain(mac); 12127 12128 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12129 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12130 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12131 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12132 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12133 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12134 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12135 12136 bwn_phy_lp_get_txpctlmode(mac); 12137 txpctlmode = plp->plp_txpctlmode; 12138 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12139 12140 /* disable CRS */ 12141 bwn_phy_lp_set_deaf(mac, 1); 12142 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12143 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12144 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12145 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12146 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12147 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12148 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12149 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12150 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12151 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12152 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12153 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12154 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12155 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12156 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12157 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12158 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12159 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12160 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12161 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12162 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12163 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12164 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12165 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12166 12167 loopback = bwn_phy_lp_loopback(mac); 12168 if (loopback == -1) 12169 goto done; 12170 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12171 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12172 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12173 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12174 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12175 12176 tmp = 0; 12177 memset(&ie, 0, sizeof(ie)); 12178 for (i = 128; i <= 159; i++) { 12179 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12180 sum = 0; 12181 for (j = 5; j <= 25; j++) { 12182 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12183 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12184 goto done; 12185 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12186 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12187 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12188 12); 12189 sum += ((ipwr - npwr) * (ipwr - npwr)); 12190 if ((i == 128) || (sum < tmp)) { 12191 plp->plp_rccap = i; 12192 tmp = sum; 12193 } 12194 } 12195 } 12196 bwn_phy_lp_ddfs_turnoff(mac); 12197 done: 12198 /* restore CRS */ 12199 bwn_phy_lp_clear_deaf(mac, 1); 12200 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12201 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12202 12203 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12204 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12205 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12206 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12207 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12208 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12209 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12210 12211 bwn_phy_lp_set_bbmult(mac, bbmult); 12212 if (txo) 12213 bwn_phy_lp_set_txgain(mac, &tx_gains); 12214 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12215 if (plp->plp_rccap) 12216 bwn_phy_lp_set_rccap(mac); 12217 } 12218 12219 static void 12220 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12221 { 12222 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12223 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12224 12225 if (mac->mac_phy.rev == 1) 12226 rc_cap = MIN(rc_cap + 5, 15); 12227 12228 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12229 MAX(plp->plp_rccap - 4, 0x80)); 12230 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12231 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12232 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12233 } 12234 12235 static uint32_t 12236 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12237 { 12238 uint32_t i, q, r; 12239 12240 if (div == 0) 12241 return (0); 12242 12243 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12244 q <<= 1; 12245 if (r << 1 >= div) { 12246 q++; 12247 r = (r << 1) - div; 12248 } 12249 } 12250 if (r << 1 >= div) 12251 q++; 12252 return (q); 12253 } 12254 12255 static void 12256 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12257 { 12258 struct bwn_softc *sc = mac->mac_sc; 12259 12260 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12261 DELAY(20); 12262 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12263 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12264 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12265 } else { 12266 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12267 } 12268 DELAY(5); 12269 } 12270 12271 static void 12272 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12273 { 12274 12275 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12276 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12277 DELAY(200); 12278 } 12279 12280 static void 12281 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12282 { 12283 #define FLAG_A 0x01 12284 #define FLAG_G 0x02 12285 struct bwn_softc *sc = mac->mac_sc; 12286 struct ifnet *ifp = sc->sc_ifp; 12287 struct ieee80211com *ic = ifp->if_l2com; 12288 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12289 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12290 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12291 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12292 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12293 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12294 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12295 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12296 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12297 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12298 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12299 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12300 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12301 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12302 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12303 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12304 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12305 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12306 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12307 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12308 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12309 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12310 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12311 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12312 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12313 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12314 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12315 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12316 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12317 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12318 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12319 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12320 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12321 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12322 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12323 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12324 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12325 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12326 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12327 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12328 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12329 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12330 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12331 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12332 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12333 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12334 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12335 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12336 }; 12337 const struct bwn_b206x_rfinit_entry *br; 12338 unsigned int i; 12339 12340 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12341 br = &bwn_b2062_init_tab[i]; 12342 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12343 if (br->br_flags & FLAG_G) 12344 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12345 } else { 12346 if (br->br_flags & FLAG_A) 12347 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12348 } 12349 } 12350 #undef FLAG_A 12351 #undef FLAG_B 12352 } 12353 12354 static void 12355 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12356 { 12357 #define FLAG_A 0x01 12358 #define FLAG_G 0x02 12359 struct bwn_softc *sc = mac->mac_sc; 12360 struct ifnet *ifp = sc->sc_ifp; 12361 struct ieee80211com *ic = ifp->if_l2com; 12362 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12363 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12364 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12365 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12366 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12367 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12368 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12369 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12370 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12371 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12372 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12373 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12374 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12375 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12376 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12377 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12378 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12379 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12380 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12381 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12382 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12383 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12384 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12385 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12386 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12387 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12388 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12389 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12390 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12391 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12392 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12393 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12394 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12395 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12396 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12397 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12398 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12399 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12400 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12401 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12402 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12403 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12404 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12405 }; 12406 const struct bwn_b206x_rfinit_entry *br; 12407 unsigned int i; 12408 12409 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12410 br = &bwn_b2063_init_tab[i]; 12411 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12412 if (br->br_flags & FLAG_G) 12413 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12414 } else { 12415 if (br->br_flags & FLAG_A) 12416 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12417 } 12418 } 12419 #undef FLAG_A 12420 #undef FLAG_B 12421 } 12422 12423 static void 12424 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12425 int count, void *_data) 12426 { 12427 unsigned int i; 12428 uint32_t offset, type; 12429 uint8_t *data = _data; 12430 12431 type = BWN_TAB_GETTYPE(typenoffset); 12432 offset = BWN_TAB_GETOFFSET(typenoffset); 12433 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12434 12435 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12436 12437 for (i = 0; i < count; i++) { 12438 switch (type) { 12439 case BWN_TAB_8BIT: 12440 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12441 data++; 12442 break; 12443 case BWN_TAB_16BIT: 12444 *((uint16_t *)data) = BWN_PHY_READ(mac, 12445 BWN_PHY_TABLEDATALO); 12446 data += 2; 12447 break; 12448 case BWN_TAB_32BIT: 12449 *((uint32_t *)data) = BWN_PHY_READ(mac, 12450 BWN_PHY_TABLEDATAHI); 12451 *((uint32_t *)data) <<= 16; 12452 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12453 BWN_PHY_TABLEDATALO); 12454 data += 4; 12455 break; 12456 default: 12457 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12458 } 12459 } 12460 } 12461 12462 static void 12463 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12464 int count, const void *_data) 12465 { 12466 uint32_t offset, type, value; 12467 const uint8_t *data = _data; 12468 unsigned int i; 12469 12470 type = BWN_TAB_GETTYPE(typenoffset); 12471 offset = BWN_TAB_GETOFFSET(typenoffset); 12472 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12473 12474 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12475 12476 for (i = 0; i < count; i++) { 12477 switch (type) { 12478 case BWN_TAB_8BIT: 12479 value = *data; 12480 data++; 12481 KASSERT(!(value & ~0xff), 12482 ("%s:%d: fail", __func__, __LINE__)); 12483 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12484 break; 12485 case BWN_TAB_16BIT: 12486 value = *((const uint16_t *)data); 12487 data += 2; 12488 KASSERT(!(value & ~0xffff), 12489 ("%s:%d: fail", __func__, __LINE__)); 12490 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12491 break; 12492 case BWN_TAB_32BIT: 12493 value = *((const uint32_t *)data); 12494 data += 4; 12495 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12496 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12497 break; 12498 default: 12499 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12500 } 12501 } 12502 } 12503 12504 static struct bwn_txgain 12505 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12506 { 12507 struct bwn_txgain tg; 12508 uint16_t tmp; 12509 12510 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12511 if (mac->mac_phy.rev < 2) { 12512 tmp = BWN_PHY_READ(mac, 12513 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12514 tg.tg_gm = tmp & 0x0007; 12515 tg.tg_pga = (tmp & 0x0078) >> 3; 12516 tg.tg_pad = (tmp & 0x780) >> 7; 12517 return (tg); 12518 } 12519 12520 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12521 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12522 tg.tg_gm = tmp & 0xff; 12523 tg.tg_pga = (tmp >> 8) & 0xff; 12524 return (tg); 12525 } 12526 12527 static uint8_t 12528 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12529 { 12530 12531 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12532 } 12533 12534 static void 12535 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12536 { 12537 uint16_t pa; 12538 12539 if (mac->mac_phy.rev < 2) { 12540 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12541 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12542 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12543 bwn_phy_lp_set_txgain_override(mac); 12544 return; 12545 } 12546 12547 pa = bwn_phy_lp_get_pa_gain(mac); 12548 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12549 (tg->tg_pga << 8) | tg->tg_gm); 12550 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12551 tg->tg_pad | (pa << 6)); 12552 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12553 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12554 tg->tg_pad | (pa << 8)); 12555 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12556 bwn_phy_lp_set_txgain_override(mac); 12557 } 12558 12559 static void 12560 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12561 { 12562 12563 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12564 } 12565 12566 static void 12567 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12568 { 12569 uint16_t trsw = (tx << 1) | rx; 12570 12571 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12572 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12573 } 12574 12575 static void 12576 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12577 { 12578 struct bwn_softc *sc = mac->mac_sc; 12579 struct ifnet *ifp = sc->sc_ifp; 12580 struct ieee80211com *ic = ifp->if_l2com; 12581 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12582 12583 if (mac->mac_phy.rev < 2) { 12584 trsw = gain & 0x1; 12585 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12586 ext_lna = (gain & 2) >> 1; 12587 12588 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12589 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12590 0xfbff, ext_lna << 10); 12591 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12592 0xf7ff, ext_lna << 11); 12593 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12594 } else { 12595 low_gain = gain & 0xffff; 12596 high_gain = (gain >> 16) & 0xf; 12597 ext_lna = (gain >> 21) & 0x1; 12598 trsw = ~(gain >> 20) & 0x1; 12599 12600 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12601 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12602 0xfdff, ext_lna << 9); 12603 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12604 0xfbff, ext_lna << 10); 12605 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12606 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12607 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12608 tmp = (gain >> 2) & 0x3; 12609 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12610 0xe7ff, tmp<<11); 12611 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12612 tmp << 3); 12613 } 12614 } 12615 12616 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12617 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12618 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12619 if (mac->mac_phy.rev >= 2) { 12620 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12621 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12622 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12623 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12624 } 12625 return; 12626 } 12627 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12628 } 12629 12630 static void 12631 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12632 { 12633 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12634 12635 if (user) 12636 plp->plp_crsusr_off = 1; 12637 else 12638 plp->plp_crssys_off = 1; 12639 12640 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12641 } 12642 12643 static void 12644 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12645 { 12646 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12647 struct bwn_softc *sc = mac->mac_sc; 12648 struct ifnet *ifp = sc->sc_ifp; 12649 struct ieee80211com *ic = ifp->if_l2com; 12650 12651 if (user) 12652 plp->plp_crsusr_off = 0; 12653 else 12654 plp->plp_crssys_off = 0; 12655 12656 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12657 return; 12658 12659 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12660 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12661 else 12662 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12663 } 12664 12665 static unsigned int 12666 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12667 { 12668 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12669 static uint8_t sqrt_table[256] = { 12670 10, 14, 17, 20, 22, 24, 26, 28, 12671 30, 31, 33, 34, 36, 37, 38, 40, 12672 41, 42, 43, 44, 45, 46, 47, 48, 12673 50, 50, 51, 52, 53, 54, 55, 56, 12674 57, 58, 59, 60, 60, 61, 62, 63, 12675 64, 64, 65, 66, 67, 67, 68, 69, 12676 70, 70, 71, 72, 72, 73, 74, 74, 12677 75, 76, 76, 77, 78, 78, 79, 80, 12678 80, 81, 81, 82, 83, 83, 84, 84, 12679 85, 86, 86, 87, 87, 88, 88, 89, 12680 90, 90, 91, 91, 92, 92, 93, 93, 12681 94, 94, 95, 95, 96, 96, 97, 97, 12682 98, 98, 99, 100, 100, 100, 101, 101, 12683 102, 102, 103, 103, 104, 104, 105, 105, 12684 106, 106, 107, 107, 108, 108, 109, 109, 12685 110, 110, 110, 111, 111, 112, 112, 113, 12686 113, 114, 114, 114, 115, 115, 116, 116, 12687 117, 117, 117, 118, 118, 119, 119, 120, 12688 120, 120, 121, 121, 122, 122, 122, 123, 12689 123, 124, 124, 124, 125, 125, 126, 126, 12690 126, 127, 127, 128, 128, 128, 129, 129, 12691 130, 130, 130, 131, 131, 131, 132, 132, 12692 133, 133, 133, 134, 134, 134, 135, 135, 12693 136, 136, 136, 137, 137, 137, 138, 138, 12694 138, 139, 139, 140, 140, 140, 141, 141, 12695 141, 142, 142, 142, 143, 143, 143, 144, 12696 144, 144, 145, 145, 145, 146, 146, 146, 12697 147, 147, 147, 148, 148, 148, 149, 149, 12698 150, 150, 150, 150, 151, 151, 151, 152, 12699 152, 152, 153, 153, 153, 154, 154, 154, 12700 155, 155, 155, 156, 156, 156, 157, 157, 12701 157, 158, 158, 158, 159, 159, 159, 160 12702 }; 12703 12704 if (x == 0) 12705 return (0); 12706 if (x >= 256) { 12707 unsigned int tmp; 12708 12709 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12710 /* do nothing */ ; 12711 return (tmp); 12712 } 12713 return (sqrt_table[x - 1] / 10); 12714 } 12715 12716 static int 12717 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12718 { 12719 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12720 int _t; \ 12721 _t = _x - 20; \ 12722 if (_t >= 0) { \ 12723 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12724 } else { \ 12725 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12726 } \ 12727 } while (0) 12728 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12729 int _t; \ 12730 _t = _x - 11; \ 12731 if (_t >= 0) \ 12732 _v = (_y << (31 - _x)) / (_z >> _t); \ 12733 else \ 12734 _v = (_y << (31 - _x)) / (_z << -_t); \ 12735 } while (0) 12736 struct bwn_phy_lp_iq_est ie; 12737 uint16_t v0, v1; 12738 int tmp[2], ret; 12739 12740 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12741 v0 = v1 >> 8; 12742 v1 |= 0xff; 12743 12744 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12745 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12746 12747 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12748 if (ret == 0) 12749 goto done; 12750 12751 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12752 ret = 0; 12753 goto done; 12754 } 12755 12756 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12757 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12758 12759 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12760 v0 = tmp[0] >> 3; 12761 v1 = tmp[1] >> 4; 12762 done: 12763 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12764 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12765 return ret; 12766 #undef CALC_COEFF 12767 #undef CALC_COEFF2 12768 } 12769 12770 static void 12771 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12772 { 12773 static const uint16_t noisescale[] = { 12774 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12775 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12776 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12777 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12778 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12779 }; 12780 static const uint16_t crsgainnft[] = { 12781 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12782 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12783 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12784 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12785 0x013d, 12786 }; 12787 static const uint16_t filterctl[] = { 12788 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12789 0xff53, 0x0127, 12790 }; 12791 static const uint32_t psctl[] = { 12792 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12793 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12794 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12795 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12796 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12797 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12798 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12799 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12800 }; 12801 static const uint16_t ofdmcckgain_r0[] = { 12802 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12803 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12804 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12805 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12806 0x755d, 12807 }; 12808 static const uint16_t ofdmcckgain_r1[] = { 12809 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12810 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12811 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12812 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12813 0x755d, 12814 }; 12815 static const uint16_t gaindelta[] = { 12816 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12817 0x0000, 12818 }; 12819 static const uint32_t txpwrctl[] = { 12820 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12821 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12822 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12823 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12824 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12825 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12826 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12827 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12828 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12829 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12830 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12831 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12832 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000, 12843 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12844 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12845 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12846 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12847 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12848 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12849 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12850 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12851 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12852 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12853 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12854 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12855 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12856 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12857 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12858 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12859 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12860 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12861 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12862 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12863 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12864 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12865 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12866 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12867 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12868 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12869 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12870 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12871 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12872 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12873 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12874 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12875 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12876 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12877 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12878 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12879 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12880 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12881 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12882 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12883 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 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, 0x04200000, 0x04000000, 12894 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12895 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12896 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12897 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12898 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12899 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12900 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12901 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12902 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12903 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12904 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12905 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12906 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12907 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12908 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12909 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12910 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12911 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12912 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 12913 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 12914 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 12915 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 12916 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 12917 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 12918 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 12919 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 12920 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 12921 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 12922 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 12923 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 12924 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 12925 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 12926 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 12927 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 12928 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 12929 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 12930 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 12931 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 12932 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 12933 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 12934 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 12935 0x00000702, 12936 }; 12937 12938 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 12939 12940 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 12941 bwn_tab_sigsq_tbl); 12942 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 12943 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 12944 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 12945 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 12946 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 12947 bwn_tab_pllfrac_tbl); 12948 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 12949 bwn_tabl_iqlocal_tbl); 12950 if (mac->mac_phy.rev == 0) { 12951 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 12952 ofdmcckgain_r0); 12953 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 12954 ofdmcckgain_r0); 12955 } else { 12956 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 12957 ofdmcckgain_r1); 12958 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 12959 ofdmcckgain_r1); 12960 } 12961 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 12962 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 12963 } 12964 12965 static void 12966 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 12967 { 12968 struct bwn_softc *sc = mac->mac_sc; 12969 int i; 12970 static const uint16_t noisescale[] = { 12971 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12972 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12973 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12974 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12975 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12976 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12977 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 12978 }; 12979 static const uint32_t filterctl[] = { 12980 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 12981 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 12982 }; 12983 static const uint32_t psctl[] = { 12984 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 12985 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 12986 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 12987 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 12988 }; 12989 static const uint32_t gainidx[] = { 12990 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12991 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12992 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12993 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 12994 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 12995 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 12996 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 12997 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 12998 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 12999 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13000 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13001 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13002 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13003 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13004 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13005 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13006 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13007 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13008 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13009 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13010 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13011 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13012 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13013 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13014 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13015 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13016 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13017 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13018 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13019 0x0000001a, 0x64ca55ad, 0x0000001a 13020 }; 13021 static const uint16_t auxgainidx[] = { 13022 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13023 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13024 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13025 0x0004, 0x0016 13026 }; 13027 static const uint16_t swctl[] = { 13028 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13029 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13030 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13031 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13032 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13033 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13034 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13035 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13036 }; 13037 static const uint8_t hf[] = { 13038 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13039 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13040 }; 13041 static const uint32_t gainval[] = { 13042 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13043 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13044 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13045 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13046 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13047 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13048 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13049 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13050 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13051 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13052 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13053 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13054 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13055 0x000000f1, 0x00000000, 0x00000000 13056 }; 13057 static const uint16_t gain[] = { 13058 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13059 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13060 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13061 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13062 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13063 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13064 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13065 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13066 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13067 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13068 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13069 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13070 }; 13071 static const uint32_t papdeps[] = { 13072 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13073 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13074 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13075 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13076 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13077 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13078 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13079 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13080 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13081 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13082 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13083 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13084 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13085 }; 13086 static const uint32_t papdmult[] = { 13087 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13088 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13089 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13090 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13091 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13092 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13093 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13094 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13095 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13096 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13097 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13098 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13099 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13100 }; 13101 static const uint32_t gainidx_a0[] = { 13102 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13103 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13104 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13105 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13106 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13107 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13108 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13109 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13110 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13111 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13112 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13113 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13114 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13115 }; 13116 static const uint16_t auxgainidx_a0[] = { 13117 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13118 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13119 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13120 0x0002, 0x0014 13121 }; 13122 static const uint32_t gainval_a0[] = { 13123 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13124 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13125 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13126 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13127 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13128 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13129 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13130 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13131 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13132 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13133 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13134 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13135 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13136 0x000000f7, 0x00000000, 0x00000000 13137 }; 13138 static const uint16_t gain_a0[] = { 13139 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13140 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13141 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13142 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13143 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13144 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13145 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13146 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13147 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13148 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13149 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13150 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13151 }; 13152 13153 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13154 13155 for (i = 0; i < 704; i++) 13156 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13157 13158 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13159 bwn_tab_sigsq_tbl); 13160 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13161 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13162 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13163 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13164 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13165 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13166 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13167 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13168 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13169 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13170 bwn_tab_pllfrac_tbl); 13171 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13172 bwn_tabl_iqlocal_tbl); 13173 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13174 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13175 13176 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13177 (siba_get_chiprev(sc->sc_dev) == 0)) { 13178 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13179 gainidx_a0); 13180 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13181 auxgainidx_a0); 13182 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13183 gainval_a0); 13184 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13185 } 13186 } 13187 13188 static void 13189 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13190 { 13191 struct bwn_softc *sc = mac->mac_sc; 13192 struct ifnet *ifp = sc->sc_ifp; 13193 struct ieee80211com *ic = ifp->if_l2com; 13194 static struct bwn_txgain_entry txgain_r2[] = { 13195 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13196 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13197 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13198 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13199 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13200 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13201 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13202 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13203 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13204 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13205 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13206 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13207 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13208 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13209 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13210 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13211 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13212 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13213 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13214 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13215 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13216 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13217 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13218 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13219 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13220 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13221 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13222 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13223 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13224 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13225 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13226 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13227 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13228 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13229 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13230 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13231 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13232 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13233 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13234 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13235 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13236 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13237 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13238 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13239 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13240 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13241 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13242 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13243 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13244 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13245 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13246 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13247 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13248 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13249 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13250 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13251 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13252 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13253 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13254 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13255 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13256 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13257 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13258 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13259 }; 13260 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13261 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13262 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13263 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13264 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13265 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13266 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13267 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13268 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13269 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13270 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13271 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13272 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13273 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13274 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13275 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13276 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13277 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13278 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13279 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13280 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13281 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13282 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13283 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13284 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13285 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13286 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13287 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13288 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13289 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13290 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13291 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13292 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13293 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13294 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13295 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13296 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13297 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13298 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13299 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13300 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13301 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13302 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13303 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13304 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13305 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13306 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13307 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13308 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13309 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13310 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13311 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13312 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13313 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13314 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13315 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13316 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13317 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13318 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13319 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13320 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13321 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13322 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13323 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13324 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13325 }; 13326 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13327 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13328 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13329 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13330 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13331 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13332 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13333 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13334 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13335 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13336 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13337 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13338 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13339 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13340 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13341 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13342 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13343 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13344 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13345 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13346 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13347 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13348 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13349 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13350 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13351 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13352 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13353 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13354 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13355 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13356 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13357 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13358 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13359 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13360 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13361 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13362 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13363 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13364 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13365 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13366 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13367 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13368 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13369 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13370 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13371 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13372 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13373 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13374 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13375 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13376 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13377 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13378 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13379 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13380 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13381 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13382 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13383 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13384 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13385 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13386 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13387 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13388 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13389 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13390 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13391 }; 13392 static struct bwn_txgain_entry txgain_r0[] = { 13393 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13394 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13395 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13396 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13397 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13398 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13399 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13400 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13401 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13402 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13403 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13404 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13405 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13406 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13407 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13408 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13409 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13410 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13411 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13412 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13413 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13414 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13415 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13416 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13417 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13418 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13419 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13420 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13421 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13422 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13423 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13424 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13425 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13426 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13427 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13428 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13429 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13430 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13431 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13432 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13433 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13434 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13435 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13436 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13437 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13438 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13439 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13440 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13441 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13442 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13443 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13444 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13445 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13446 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13447 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13448 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13449 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13450 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13451 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13452 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13453 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13454 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13455 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13456 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13457 }; 13458 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13459 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13460 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13461 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13462 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13463 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13464 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13465 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13466 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13467 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13468 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13469 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13470 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13471 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13472 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13473 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13474 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13475 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13476 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13477 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13478 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13479 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13480 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13481 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13482 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13483 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13484 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13485 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13486 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13487 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13488 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13489 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13490 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13491 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13492 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13493 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13494 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13495 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13496 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13497 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13498 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13499 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13500 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13501 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13502 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13503 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13504 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13505 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13506 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13507 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13508 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13509 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13510 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13511 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13512 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13513 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13514 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13515 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13516 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13517 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13518 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13519 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13520 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13521 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13522 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13523 }; 13524 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13525 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13526 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13527 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13528 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13529 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13530 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13531 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13532 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13533 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13534 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13535 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13536 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13537 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13538 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13539 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13540 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13541 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13542 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13543 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13544 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13545 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13546 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13547 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13548 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13549 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13550 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13551 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13552 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13553 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13554 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13555 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13556 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13557 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13558 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13559 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13560 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13561 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13562 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13563 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13564 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13565 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13566 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13567 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13568 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13569 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13570 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13571 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13572 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13573 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13574 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13575 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13576 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13577 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13578 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13579 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13580 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13581 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13582 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13583 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13584 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13585 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13586 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13587 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13588 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13589 }; 13590 static struct bwn_txgain_entry txgain_r1[] = { 13591 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13592 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13593 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13594 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13595 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13596 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13597 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13598 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13599 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13600 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13601 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13602 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13603 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13604 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13605 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13606 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13607 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13608 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13609 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13610 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13611 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13612 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13613 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13614 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13615 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13616 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13617 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13618 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13619 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13620 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13621 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13622 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13623 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13624 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13625 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13626 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13627 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13628 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13629 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13630 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13631 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13632 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13633 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13634 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13635 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13636 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13637 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13638 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13639 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13640 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13641 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13642 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13643 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13644 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13645 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13646 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13647 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13648 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13649 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13650 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13651 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13652 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13653 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13654 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13655 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13656 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13657 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13658 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13659 { 7, 11, 6, 0, 71 } 13660 }; 13661 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13662 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13663 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13664 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13665 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13666 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13667 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13668 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13669 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13670 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13671 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13672 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13673 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13674 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13675 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13676 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13677 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13678 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13679 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13680 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13681 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13682 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13683 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13684 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13685 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13686 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13687 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13688 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13689 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13690 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13691 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13692 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13693 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13694 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13695 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13696 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13697 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13698 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13699 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13700 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13701 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13702 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13703 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13704 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13705 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13706 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13707 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13708 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13709 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13710 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13711 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13712 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13713 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13714 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13715 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13716 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13717 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13718 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13719 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13720 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13721 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13722 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13723 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13724 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13725 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13726 }; 13727 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13728 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13729 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13730 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13731 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13732 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13733 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13734 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13735 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13736 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13737 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13738 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13739 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13740 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13741 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13742 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13743 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13744 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13745 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13746 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13747 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13748 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13749 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13750 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13751 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13752 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13753 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13754 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13755 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13756 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13757 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13758 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13759 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13760 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13761 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13762 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13763 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13764 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13765 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13766 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13767 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13768 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13769 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13770 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13771 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13772 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13773 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13774 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13775 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13776 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13777 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13778 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13779 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13780 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13781 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13782 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13783 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13784 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13785 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13786 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13787 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13788 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13789 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13790 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13791 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13792 }; 13793 13794 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13795 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13796 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13797 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13798 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13799 txgain_2ghz_r2); 13800 else 13801 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13802 txgain_5ghz_r2); 13803 return; 13804 } 13805 13806 if (mac->mac_phy.rev == 0) { 13807 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13808 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13809 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13810 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13811 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13812 txgain_2ghz_r0); 13813 else 13814 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13815 txgain_5ghz_r0); 13816 return; 13817 } 13818 13819 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13820 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13821 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13822 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13823 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13824 else 13825 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13826 } 13827 13828 static void 13829 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13830 { 13831 uint32_t offset, type; 13832 13833 type = BWN_TAB_GETTYPE(typeoffset); 13834 offset = BWN_TAB_GETOFFSET(typeoffset); 13835 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13836 13837 switch (type) { 13838 case BWN_TAB_8BIT: 13839 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13840 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13841 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13842 break; 13843 case BWN_TAB_16BIT: 13844 KASSERT(!(value & ~0xffff), 13845 ("%s:%d: fail", __func__, __LINE__)); 13846 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13847 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13848 break; 13849 case BWN_TAB_32BIT: 13850 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13851 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13852 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13853 break; 13854 default: 13855 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13856 } 13857 } 13858 13859 static int 13860 bwn_phy_lp_loopback(struct bwn_mac *mac) 13861 { 13862 struct bwn_phy_lp_iq_est ie; 13863 int i, index = -1; 13864 uint32_t tmp; 13865 13866 memset(&ie, 0, sizeof(ie)); 13867 13868 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13869 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13870 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13871 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13872 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13873 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13874 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13875 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13876 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13877 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13878 for (i = 0; i < 32; i++) { 13879 bwn_phy_lp_set_rxgain_idx(mac, i); 13880 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13881 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13882 continue; 13883 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13884 if ((tmp > 4000) && (tmp < 10000)) { 13885 index = i; 13886 break; 13887 } 13888 } 13889 bwn_phy_lp_ddfs_turnoff(mac); 13890 return (index); 13891 } 13892 13893 static void 13894 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13895 { 13896 13897 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13898 } 13899 13900 static void 13901 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13902 int incr1, int incr2, int scale_idx) 13903 { 13904 13905 bwn_phy_lp_ddfs_turnoff(mac); 13906 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13907 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13908 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13909 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13910 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13911 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13912 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 13913 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 13914 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 13915 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 13916 } 13917 13918 static uint8_t 13919 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 13920 struct bwn_phy_lp_iq_est *ie) 13921 { 13922 int i; 13923 13924 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 13925 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 13926 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 13927 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 13928 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 13929 13930 for (i = 0; i < 500; i++) { 13931 if (!(BWN_PHY_READ(mac, 13932 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 13933 break; 13934 DELAY(1000); 13935 } 13936 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 13937 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13938 return 0; 13939 } 13940 13941 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 13942 ie->ie_iqprod <<= 16; 13943 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 13944 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 13945 ie->ie_ipwr <<= 16; 13946 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 13947 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 13948 ie->ie_qpwr <<= 16; 13949 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 13950 13951 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13952 return 1; 13953 } 13954 13955 static uint32_t 13956 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 13957 { 13958 uint32_t offset, type, value; 13959 13960 type = BWN_TAB_GETTYPE(typeoffset); 13961 offset = BWN_TAB_GETOFFSET(typeoffset); 13962 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13963 13964 switch (type) { 13965 case BWN_TAB_8BIT: 13966 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13967 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 13968 break; 13969 case BWN_TAB_16BIT: 13970 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13971 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13972 break; 13973 case BWN_TAB_32BIT: 13974 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13975 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 13976 value <<= 16; 13977 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13978 break; 13979 default: 13980 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13981 value = 0; 13982 } 13983 13984 return (value); 13985 } 13986 13987 static void 13988 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 13989 { 13990 13991 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 13992 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 13993 } 13994 13995 static void 13996 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 13997 { 13998 uint16_t ctl; 13999 14000 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14001 ctl |= dac << 7; 14002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14003 } 14004 14005 static void 14006 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14007 { 14008 14009 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14010 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14011 } 14012 14013 static void 14014 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14015 { 14016 14017 if (mac->mac_phy.rev < 2) 14018 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14019 else { 14020 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14021 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14022 } 14023 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14024 } 14025 14026 static uint16_t 14027 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14028 { 14029 14030 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14031 } 14032 14033 static uint8_t 14034 bwn_nbits(int32_t val) 14035 { 14036 uint32_t tmp; 14037 uint8_t nbits = 0; 14038 14039 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14040 nbits++; 14041 return (nbits); 14042 } 14043 14044 static void 14045 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14046 struct bwn_txgain_entry *table) 14047 { 14048 int i; 14049 14050 for (i = offset; i < count; i++) 14051 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14052 } 14053 14054 static void 14055 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14056 struct bwn_txgain_entry data) 14057 { 14058 14059 if (mac->mac_phy.rev >= 2) 14060 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14061 else 14062 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14063 } 14064 14065 static void 14066 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14067 struct bwn_txgain_entry te) 14068 { 14069 struct bwn_softc *sc = mac->mac_sc; 14070 struct ifnet *ifp = sc->sc_ifp; 14071 struct ieee80211com *ic = ifp->if_l2com; 14072 uint32_t tmp; 14073 14074 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14075 14076 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14077 if (mac->mac_phy.rev >= 3) { 14078 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14079 (0x10 << 24) : (0x70 << 24)); 14080 } else { 14081 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14082 (0x14 << 24) : (0x7f << 24)); 14083 } 14084 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14085 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14086 te.te_bbmult << 20 | te.te_dac << 28); 14087 } 14088 14089 static void 14090 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14091 struct bwn_txgain_entry te) 14092 { 14093 14094 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14095 14096 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14097 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14098 te.te_dac); 14099 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14100 } 14101 14102 static void 14103 bwn_sysctl_node(struct bwn_softc *sc) 14104 { 14105 struct bwn_mac *mac; 14106 struct bwn_stats *stats; 14107 struct sysctl_ctx_list *ctx; 14108 struct sysctl_oid *tree; 14109 14110 /* XXX assume that count of MAC is only 1. */ 14111 14112 if ((mac = sc->sc_curmac) == NULL) 14113 return; 14114 stats = &mac->mac_stats; 14115 14116 ctx = &sc->sc_sysctl_ctx; 14117 tree = sc->sc_sysctl_tree; 14118 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14119 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14120 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14121 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14122 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14123 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14124 14125 #ifdef BWN_DEBUG 14126 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14127 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14128 #endif 14129 } 14130 14131 static device_method_t bwn_methods[] = { 14132 /* Device interface */ 14133 DEVMETHOD(device_probe, bwn_probe), 14134 DEVMETHOD(device_attach, bwn_attach), 14135 DEVMETHOD(device_detach, bwn_detach), 14136 DEVMETHOD(device_suspend, bwn_suspend), 14137 DEVMETHOD(device_resume, bwn_resume), 14138 DEVMETHOD_END 14139 }; 14140 static driver_t bwn_driver = { 14141 "bwn", 14142 bwn_methods, 14143 sizeof(struct bwn_softc) 14144 }; 14145 static devclass_t bwn_devclass; 14146 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14147 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14148 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14149 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14150 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14151