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 < NELEM(bwn_devs); i++) { 906 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 907 siba_get_device(dev) == bwn_devs[i].sd_device && 908 siba_get_revid(dev) == bwn_devs[i].sd_rev) { 909 wlan_serialize_exit(); 910 return (BUS_PROBE_DEFAULT); 911 } 912 } 913 wlan_serialize_exit(); 914 return (ENXIO); 915 } 916 917 static int 918 bwn_attach(device_t dev) 919 { 920 struct bwn_mac *mac; 921 struct bwn_softc *sc = device_get_softc(dev); 922 int error; 923 u_int irq_flags; 924 925 wlan_serialize_enter(); 926 927 sc->sc_dev = dev; 928 #ifdef BWN_DEBUG 929 sc->sc_debug = bwn_debug; 930 #endif 931 932 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 933 error = bwn_attach_pre(sc); 934 if (error != 0) { 935 wlan_serialize_exit(); 936 return (error); 937 } 938 bwn_sprom_bugfixes(dev); 939 sc->sc_flags |= BWN_FLAG_ATTACHED; 940 } 941 942 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 943 if (siba_get_pci_device(dev) != 0x4313 && 944 siba_get_pci_device(dev) != 0x431a && 945 siba_get_pci_device(dev) != 0x4321) { 946 device_printf(sc->sc_dev, 947 "skip 802.11 cores\n"); 948 wlan_serialize_exit(); 949 return (ENODEV); 950 } 951 } 952 953 mac = (struct bwn_mac *)kmalloc(sizeof(*mac), M_DEVBUF, 954 M_INTWAIT | M_ZERO); 955 mac->mac_sc = sc; 956 mac->mac_status = BWN_MAC_STATUS_UNINIT; 957 if (bwn_bfp != 0) 958 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 959 960 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 961 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 962 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 963 964 error = bwn_attach_core(mac); 965 if (error) 966 goto fail0; 967 bwn_led_attach(mac); 968 969 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 970 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 971 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 972 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 973 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 974 mac->mac_phy.rf_rev); 975 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 976 device_printf(sc->sc_dev, "DMA (%d bits)\n", 977 mac->mac_method.dma.dmatype); 978 else 979 device_printf(sc->sc_dev, "PIO\n"); 980 981 /* Allocate IRQ resource. */ 982 sc->bwn_irq_rid = 0; 983 sc->bwn_irq_type = pci_alloc_1intr(sc->sc_dev, bwn_msi_enable, 984 &sc->bwn_irq_rid, &irq_flags); 985 if ((sc->bwn_irq = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ, 986 &sc->bwn_irq_rid, irq_flags)) == NULL) { 987 device_printf(sc->sc_dev, "Cannot allocate interrupt\n"); 988 error = EINVAL; 989 goto fail1; 990 } 991 if ((error = bus_setup_intr(sc->sc_dev, sc->bwn_irq, INTR_MPSAFE, 992 bwn_intr, mac, &sc->bwn_intr, &wlan_global_serializer)) != 0) { 993 device_printf(sc->sc_dev, "Cannot set up interrupt\n"); 994 goto fail1; 995 } 996 997 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 998 999 /* 1000 * calls attach-post routine 1001 */ 1002 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1003 bwn_attach_post(sc); 1004 1005 wlan_serialize_exit(); 1006 return (0); 1007 fail1: 1008 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI) 1009 pci_release_msi(dev); 1010 fail0: 1011 kfree(mac, M_DEVBUF); 1012 wlan_serialize_exit(); 1013 return (error); 1014 } 1015 1016 static int 1017 bwn_is_valid_ether_addr(uint8_t *addr) 1018 { 1019 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1020 1021 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1022 return (FALSE); 1023 1024 return (TRUE); 1025 } 1026 1027 static int 1028 bwn_attach_post(struct bwn_softc *sc) 1029 { 1030 struct ieee80211com *ic; 1031 struct ifnet *ifp = sc->sc_ifp; 1032 1033 ic = ifp->if_l2com; 1034 ic->ic_ifp = ifp; 1035 /* 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 wlan_serialize_exit(); 1138 return (0); 1139 } 1140 1141 static int 1142 bwn_attach_pre(struct bwn_softc *sc) 1143 { 1144 struct ifnet *ifp; 1145 int error = 0; 1146 1147 TAILQ_INIT(&sc->sc_maclist); 1148 callout_init(&sc->sc_rfswitch_ch); 1149 callout_init(&sc->sc_task_ch); 1150 callout_init(&sc->sc_watchdog_ch); 1151 1152 sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK, 1153 taskqueue_thread_enqueue, &sc->sc_tq); 1154 taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1, 1155 "%s taskq", device_get_nameunit(sc->sc_dev)); 1156 1157 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1158 if (ifp == NULL) { 1159 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1160 error = ENOSPC; 1161 goto fail; 1162 } 1163 1164 /* set these up early for if_printf use */ 1165 if_initname(ifp, device_get_name(sc->sc_dev), 1166 device_get_unit(sc->sc_dev)); 1167 1168 ifp->if_softc = sc; 1169 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1170 ifp->if_init = bwn_init; 1171 ifp->if_ioctl = bwn_ioctl; 1172 ifp->if_start = bwn_start; 1173 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); 1174 1175 return (0); 1176 1177 fail: 1178 return (error); 1179 } 1180 1181 static void 1182 bwn_sprom_bugfixes(device_t dev) 1183 { 1184 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1185 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1186 (siba_get_pci_device(dev) == _device) && \ 1187 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1188 (siba_get_pci_subdevice(dev) == _subdevice)) 1189 1190 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1191 siba_get_pci_subdevice(dev) == 0x4e && 1192 siba_get_pci_revid(dev) > 0x40) 1193 siba_sprom_set_bf_lo(dev, 1194 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1195 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1196 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1197 siba_sprom_set_bf_lo(dev, 1198 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1199 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1200 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1201 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1202 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1203 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1204 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1205 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1206 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1207 siba_sprom_set_bf_lo(dev, 1208 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1209 } 1210 #undef BWN_ISDEV 1211 } 1212 1213 static int 1214 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, 1215 struct ucred *cr __unused) 1216 { 1217 #define IS_RUNNING(ifp) \ 1218 ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING)) 1219 struct bwn_softc *sc = ifp->if_softc; 1220 struct ieee80211com *ic = ifp->if_l2com; 1221 struct ifreq *ifr = (struct ifreq *)data; 1222 int error = 0; 1223 1224 switch (cmd) { 1225 case SIOCSIFFLAGS: 1226 if (IS_RUNNING(ifp)) { 1227 bwn_update_promisc(ifp); 1228 } else if (ifp->if_flags & IFF_UP) { 1229 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1230 bwn_init(sc); 1231 } 1232 } else 1233 bwn_stop(sc, 1); 1234 break; 1235 case SIOCGIFMEDIA: 1236 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1237 break; 1238 case SIOCGIFADDR: 1239 error = ether_ioctl(ifp, cmd, data); 1240 break; 1241 default: 1242 error = EINVAL; 1243 break; 1244 } 1245 return (error); 1246 } 1247 1248 static void 1249 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) 1250 { 1251 wlan_assert_serialized(); 1252 bwn_start_locked(ifp); 1253 } 1254 1255 static void 1256 bwn_start_locked(struct ifnet *ifp) 1257 { 1258 struct bwn_softc *sc = ifp->if_softc; 1259 struct bwn_mac *mac = sc->sc_curmac; 1260 struct ieee80211_frame *wh; 1261 struct ieee80211_node *ni; 1262 struct ieee80211_key *k; 1263 struct mbuf *m; 1264 1265 wlan_assert_serialized(); 1266 1267 if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL || 1268 mac->mac_status < BWN_MAC_STATUS_STARTED) 1269 return; 1270 1271 for (;;) { 1272 m = ifq_dequeue(&ifp->if_snd); /* XXX: LOCK */ 1273 if (m == NULL) 1274 break; 1275 1276 if (bwn_tx_isfull(sc, m)) 1277 break; 1278 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1279 if (ni == NULL) { 1280 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1281 m_freem(m); 1282 ifp->if_oerrors++; 1283 continue; 1284 } 1285 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1286 wh = mtod(m, struct ieee80211_frame *); 1287 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1288 k = ieee80211_crypto_encap(ni, m); 1289 if (k == NULL) { 1290 ieee80211_free_node(ni); 1291 m_freem(m); 1292 ifp->if_oerrors++; 1293 continue; 1294 } 1295 } 1296 wh = NULL; /* Catch any invalid use */ 1297 1298 if (bwn_tx_start(sc, ni, m) != 0) { 1299 if (ni != NULL) 1300 ieee80211_free_node(ni); 1301 ifp->if_oerrors++; 1302 continue; 1303 } 1304 1305 sc->sc_watchdog_timer = 5; 1306 } 1307 } 1308 1309 static int 1310 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1311 { 1312 struct bwn_dma_ring *dr; 1313 struct bwn_mac *mac = sc->sc_curmac; 1314 struct bwn_pio_txqueue *tq; 1315 struct ifnet *ifp = sc->sc_ifp; 1316 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1317 1318 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1319 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1320 if (dr->dr_stop == 1 || 1321 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1322 dr->dr_stop = 1; 1323 goto full; 1324 } 1325 } else { 1326 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1327 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1328 pktlen > (tq->tq_size - tq->tq_used)) { 1329 tq->tq_stop = 1; 1330 goto full; 1331 } 1332 } 1333 return (0); 1334 full: 1335 ifq_prepend(&ifp->if_snd, m); 1336 ifq_set_oactive(&ifp->if_snd); 1337 return (1); 1338 } 1339 1340 static int 1341 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1342 { 1343 struct bwn_mac *mac = sc->sc_curmac; 1344 int error; 1345 1346 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1347 m_freem(m); 1348 return (ENXIO); 1349 } 1350 1351 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1352 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1353 if (error) { 1354 m_freem(m); 1355 return (error); 1356 } 1357 return (0); 1358 } 1359 1360 static int 1361 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1362 { 1363 struct bwn_pio_txpkt *tp; 1364 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1365 struct bwn_softc *sc = mac->mac_sc; 1366 struct bwn_txhdr txhdr; 1367 struct mbuf *m_new; 1368 uint32_t ctl32; 1369 int error; 1370 uint16_t ctl16; 1371 1372 /* XXX TODO send packets after DTIM */ 1373 1374 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1375 tp = TAILQ_FIRST(&tq->tq_pktlist); 1376 tp->tp_ni = ni; 1377 tp->tp_m = m; 1378 1379 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1380 if (error) { 1381 device_printf(sc->sc_dev, "tx fail\n"); 1382 return (error); 1383 } 1384 1385 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1386 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1387 tq->tq_free--; 1388 1389 if (siba_get_revid(sc->sc_dev) >= 8) { 1390 /* 1391 * XXX please removes m_defrag(9) 1392 */ 1393 m_new = m_defrag(m, M_NOWAIT); 1394 if (m_new == NULL) { 1395 device_printf(sc->sc_dev, 1396 "%s: can't defrag TX buffer\n", 1397 __func__); 1398 return (ENOBUFS); 1399 } 1400 if (m_new->m_next != NULL) 1401 device_printf(sc->sc_dev, 1402 "TODO: fragmented packets for PIO\n"); 1403 tp->tp_m = m_new; 1404 1405 /* send HEADER */ 1406 ctl32 = bwn_pio_write_multi_4(mac, tq, 1407 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1408 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1409 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1410 /* send BODY */ 1411 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1412 mtod(m_new, const void *), m_new->m_pkthdr.len); 1413 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1414 ctl32 | BWN_PIO8_TXCTL_EOF); 1415 } else { 1416 ctl16 = bwn_pio_write_multi_2(mac, tq, 1417 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1418 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1419 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1420 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1421 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1422 ctl16 | BWN_PIO_TXCTL_EOF); 1423 } 1424 1425 return (0); 1426 } 1427 1428 static struct bwn_pio_txqueue * 1429 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1430 { 1431 1432 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1433 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1434 1435 switch (prio) { 1436 case 0: 1437 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1438 case 1: 1439 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1440 case 2: 1441 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1442 case 3: 1443 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1444 } 1445 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1446 return (NULL); 1447 } 1448 1449 static int 1450 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1451 { 1452 #define BWN_GET_TXHDRCACHE(slot) \ 1453 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)]) 1454 struct bwn_dma *dma = &mac->mac_method.dma; 1455 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1456 struct bwn_dmadesc_generic *desc; 1457 struct bwn_dmadesc_meta *mt; 1458 struct bwn_softc *sc = mac->mac_sc; 1459 struct ifnet *ifp = sc->sc_ifp; 1460 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1461 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1462 1463 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1464 1465 /* XXX send after DTIM */ 1466 1467 slot = bwn_dma_getslot(dr); 1468 dr->getdesc(dr, slot, &desc, &mt); 1469 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1470 ("%s:%d: fail", __func__, __LINE__)); 1471 1472 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1473 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1474 BWN_DMA_COOKIE(dr, slot)); 1475 if (error) 1476 goto fail; 1477 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1478 BUS_DMASYNC_PREWRITE); 1479 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1480 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1481 BUS_DMASYNC_PREWRITE); 1482 1483 slot = bwn_dma_getslot(dr); 1484 dr->getdesc(dr, slot, &desc, &mt); 1485 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1486 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1487 mt->mt_m = m; 1488 mt->mt_ni = ni; 1489 1490 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1491 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1492 if (error && error != EFBIG) { 1493 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1494 __func__, error); 1495 goto fail; 1496 } 1497 if (error) { /* error == EFBIG */ 1498 struct mbuf *m_new; 1499 1500 m_new = m_defrag(m, M_NOWAIT); 1501 if (m_new == NULL) { 1502 if_printf(ifp, "%s: can't defrag TX buffer\n", 1503 __func__); 1504 error = ENOBUFS; 1505 goto fail; 1506 } else { 1507 m = m_new; 1508 } 1509 1510 mt->mt_m = m; 1511 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1512 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1513 if (error) { 1514 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1515 __func__, error); 1516 goto fail; 1517 } 1518 } 1519 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1520 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1521 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1522 BUS_DMASYNC_PREWRITE); 1523 1524 /* XXX send after DTIM */ 1525 1526 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1527 return (0); 1528 fail: 1529 dr->dr_curslot = backup[0]; 1530 dr->dr_usedslot = backup[1]; 1531 return (error); 1532 #undef BWN_GET_TXHDRCACHE 1533 } 1534 1535 static void 1536 bwn_watchdog(void *arg) 1537 { 1538 struct bwn_softc *sc = arg; 1539 struct ifnet *ifp = sc->sc_ifp; 1540 1541 wlan_serialize_enter(); 1542 1543 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1544 if_printf(ifp, "device timeout\n"); 1545 ifp->if_oerrors++; 1546 } 1547 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 1548 wlan_serialize_exit(); 1549 } 1550 1551 static int 1552 bwn_attach_core(struct bwn_mac *mac) 1553 { 1554 struct bwn_softc *sc = mac->mac_sc; 1555 int error, have_bg = 0, have_a = 0; 1556 uint32_t high; 1557 1558 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1559 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1560 1561 siba_powerup(sc->sc_dev, 0); 1562 1563 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1564 bwn_reset_core(mac, 1565 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1566 error = bwn_phy_getinfo(mac, high); 1567 if (error) 1568 goto fail; 1569 1570 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1571 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1572 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1573 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1574 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1575 have_a = have_bg = 0; 1576 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1577 have_a = 1; 1578 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1579 mac->mac_phy.type == BWN_PHYTYPE_N || 1580 mac->mac_phy.type == BWN_PHYTYPE_LP) 1581 have_bg = 1; 1582 else 1583 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1584 mac->mac_phy.type)); 1585 } 1586 /* XXX turns off PHY A because it's not supported */ 1587 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1588 mac->mac_phy.type != BWN_PHYTYPE_N) { 1589 have_a = 0; 1590 have_bg = 1; 1591 } 1592 1593 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1594 mac->mac_phy.attach = bwn_phy_g_attach; 1595 mac->mac_phy.detach = bwn_phy_g_detach; 1596 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1597 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1598 mac->mac_phy.init = bwn_phy_g_init; 1599 mac->mac_phy.exit = bwn_phy_g_exit; 1600 mac->mac_phy.phy_read = bwn_phy_g_read; 1601 mac->mac_phy.phy_write = bwn_phy_g_write; 1602 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1603 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1604 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1605 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1606 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1607 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1608 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1609 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1610 mac->mac_phy.set_im = bwn_phy_g_im; 1611 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1612 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1613 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1614 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1615 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1616 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1617 mac->mac_phy.init = bwn_phy_lp_init; 1618 mac->mac_phy.phy_read = bwn_phy_lp_read; 1619 mac->mac_phy.phy_write = bwn_phy_lp_write; 1620 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1621 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1622 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1623 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1624 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1625 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1626 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1627 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1628 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1629 } else { 1630 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1631 mac->mac_phy.type); 1632 error = ENXIO; 1633 goto fail; 1634 } 1635 1636 mac->mac_phy.gmode = have_bg; 1637 if (mac->mac_phy.attach != NULL) { 1638 error = mac->mac_phy.attach(mac); 1639 if (error) { 1640 device_printf(sc->sc_dev, "failed\n"); 1641 goto fail; 1642 } 1643 } 1644 1645 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1646 1647 error = bwn_chiptest(mac); 1648 if (error) 1649 goto fail; 1650 error = bwn_setup_channels(mac, have_bg, have_a); 1651 if (error) { 1652 device_printf(sc->sc_dev, "failed to setup channels\n"); 1653 goto fail; 1654 } 1655 1656 if (sc->sc_curmac == NULL) 1657 sc->sc_curmac = mac; 1658 1659 wlan_assert_serialized(); 1660 wlan_serialize_exit(); 1661 error = bwn_dma_attach(mac); 1662 wlan_serialize_enter(); 1663 if (error != 0) { 1664 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1665 goto fail; 1666 } 1667 1668 mac->mac_phy.switch_analog(mac, 0); 1669 1670 siba_dev_down(sc->sc_dev, 0); 1671 fail: 1672 siba_powerdown(sc->sc_dev); 1673 return (error); 1674 } 1675 1676 static void 1677 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1678 { 1679 struct bwn_softc *sc = mac->mac_sc; 1680 uint32_t low, ctl; 1681 1682 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1683 1684 siba_dev_up(sc->sc_dev, flags); 1685 DELAY(2000); 1686 1687 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1688 ~BWN_TGSLOW_PHYRESET; 1689 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1690 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1691 DELAY(1000); 1692 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1693 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1694 DELAY(1000); 1695 1696 if (mac->mac_phy.switch_analog != NULL) 1697 mac->mac_phy.switch_analog(mac, 1); 1698 1699 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1700 if (flags & BWN_TGSLOW_SUPPORT_G) 1701 ctl |= BWN_MACCTL_GMODE; 1702 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1703 } 1704 1705 static int 1706 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1707 { 1708 struct bwn_phy *phy = &mac->mac_phy; 1709 struct bwn_softc *sc = mac->mac_sc; 1710 uint32_t tmp; 1711 1712 /* PHY */ 1713 tmp = BWN_READ_2(mac, BWN_PHYVER); 1714 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1715 phy->rf_on = 1; 1716 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1717 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1718 phy->rev = (tmp & BWN_PHYVER_VERSION); 1719 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1720 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1721 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1722 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1723 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1724 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1725 goto unsupphy; 1726 1727 /* RADIO */ 1728 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1729 if (siba_get_chiprev(sc->sc_dev) == 0) 1730 tmp = 0x3205017f; 1731 else if (siba_get_chiprev(sc->sc_dev) == 1) 1732 tmp = 0x4205017f; 1733 else 1734 tmp = 0x5205017f; 1735 } else { 1736 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1737 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1738 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1739 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1740 } 1741 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1742 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1743 phy->rf_manuf = (tmp & 0x00000fff); 1744 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1745 goto unsupradio; 1746 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1747 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1748 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1749 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1750 (phy->type == BWN_PHYTYPE_N && 1751 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1752 (phy->type == BWN_PHYTYPE_LP && 1753 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1754 goto unsupradio; 1755 1756 return (0); 1757 unsupphy: 1758 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1759 "analog %#x)\n", 1760 phy->type, phy->rev, phy->analog); 1761 return (ENXIO); 1762 unsupradio: 1763 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1764 "rev %#x)\n", 1765 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1766 return (ENXIO); 1767 } 1768 1769 static int 1770 bwn_chiptest(struct bwn_mac *mac) 1771 { 1772 #define TESTVAL0 0x55aaaa55 1773 #define TESTVAL1 0xaa5555aa 1774 struct bwn_softc *sc = mac->mac_sc; 1775 uint32_t v, backup; 1776 1777 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1778 1779 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1780 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1781 goto error; 1782 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1783 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1784 goto error; 1785 1786 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1787 1788 if ((siba_get_revid(sc->sc_dev) >= 3) && 1789 (siba_get_revid(sc->sc_dev) <= 10)) { 1790 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1791 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1792 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1793 goto error; 1794 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1795 goto error; 1796 } 1797 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1798 1799 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1800 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1801 goto error; 1802 1803 return (0); 1804 error: 1805 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1806 return (ENODEV); 1807 } 1808 1809 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1810 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1811 1812 static int 1813 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1814 { 1815 struct bwn_softc *sc = mac->mac_sc; 1816 struct ifnet *ifp = sc->sc_ifp; 1817 struct ieee80211com *ic = ifp->if_l2com; 1818 1819 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1820 ic->ic_nchans = 0; 1821 1822 if (have_bg) 1823 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1824 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1825 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1826 if (have_a) 1827 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1828 &ic->ic_nchans, &bwn_chantable_n, 1829 IEEE80211_CHAN_HTA); 1830 } else { 1831 if (have_a) 1832 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1833 &ic->ic_nchans, &bwn_chantable_a, 1834 IEEE80211_CHAN_A); 1835 } 1836 1837 mac->mac_phy.supports_2ghz = have_bg; 1838 mac->mac_phy.supports_5ghz = have_a; 1839 1840 return (ic->ic_nchans == 0 ? ENXIO : 0); 1841 } 1842 1843 static uint32_t 1844 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1845 { 1846 uint32_t ret; 1847 1848 if (way == BWN_SHARED) { 1849 KASSERT((offset & 0x0001) == 0, 1850 ("%s:%d warn", __func__, __LINE__)); 1851 if (offset & 0x0003) { 1852 bwn_shm_ctlword(mac, way, offset >> 2); 1853 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1854 ret <<= 16; 1855 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1856 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1857 goto out; 1858 } 1859 offset >>= 2; 1860 } 1861 bwn_shm_ctlword(mac, way, offset); 1862 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1863 out: 1864 return (ret); 1865 } 1866 1867 static uint16_t 1868 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1869 { 1870 uint16_t ret; 1871 1872 if (way == BWN_SHARED) { 1873 KASSERT((offset & 0x0001) == 0, 1874 ("%s:%d warn", __func__, __LINE__)); 1875 if (offset & 0x0003) { 1876 bwn_shm_ctlword(mac, way, offset >> 2); 1877 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1878 goto out; 1879 } 1880 offset >>= 2; 1881 } 1882 bwn_shm_ctlword(mac, way, offset); 1883 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1884 out: 1885 1886 return (ret); 1887 } 1888 1889 static void 1890 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1891 uint16_t offset) 1892 { 1893 uint32_t control; 1894 1895 control = way; 1896 control <<= 16; 1897 control |= offset; 1898 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1899 } 1900 1901 static void 1902 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1903 uint32_t value) 1904 { 1905 if (way == BWN_SHARED) { 1906 KASSERT((offset & 0x0001) == 0, 1907 ("%s:%d warn", __func__, __LINE__)); 1908 if (offset & 0x0003) { 1909 bwn_shm_ctlword(mac, way, offset >> 2); 1910 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1911 (value >> 16) & 0xffff); 1912 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1913 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1914 return; 1915 } 1916 offset >>= 2; 1917 } 1918 bwn_shm_ctlword(mac, way, offset); 1919 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1920 } 1921 1922 static void 1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1924 uint16_t value) 1925 { 1926 if (way == BWN_SHARED) { 1927 KASSERT((offset & 0x0001) == 0, 1928 ("%s:%d warn", __func__, __LINE__)); 1929 if (offset & 0x0003) { 1930 bwn_shm_ctlword(mac, way, offset >> 2); 1931 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1932 return; 1933 } 1934 offset >>= 2; 1935 } 1936 bwn_shm_ctlword(mac, way, offset); 1937 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1938 } 1939 1940 static void 1941 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1942 int txpow) 1943 { 1944 1945 c->ic_freq = freq; 1946 c->ic_flags = flags; 1947 c->ic_ieee = ieee; 1948 c->ic_minpower = 0; 1949 c->ic_maxpower = 2 * txpow; 1950 c->ic_maxregpower = txpow; 1951 } 1952 1953 static void 1954 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 1955 const struct bwn_channelinfo *ci, int flags) 1956 { 1957 struct ieee80211_channel *c; 1958 int i; 1959 1960 c = &chans[*nchans]; 1961 1962 for (i = 0; i < ci->nchannels; i++) { 1963 const struct bwn_channel *hc; 1964 1965 hc = &ci->channels[i]; 1966 if (*nchans >= maxchans) 1967 break; 1968 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 1969 c++, (*nchans)++; 1970 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 1971 /* g channel have a separate b-only entry */ 1972 if (*nchans >= maxchans) 1973 break; 1974 c[0] = c[-1]; 1975 c[-1].ic_flags = IEEE80211_CHAN_B; 1976 c++, (*nchans)++; 1977 } 1978 if (flags == IEEE80211_CHAN_HTG) { 1979 /* HT g channel have a separate g-only entry */ 1980 if (*nchans >= maxchans) 1981 break; 1982 c[-1].ic_flags = IEEE80211_CHAN_G; 1983 c[0] = c[-1]; 1984 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1985 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1986 c++, (*nchans)++; 1987 } 1988 if (flags == IEEE80211_CHAN_HTA) { 1989 /* HT a channel have a separate a-only entry */ 1990 if (*nchans >= maxchans) 1991 break; 1992 c[-1].ic_flags = IEEE80211_CHAN_A; 1993 c[0] = c[-1]; 1994 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1995 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1996 c++, (*nchans)++; 1997 } 1998 } 1999 } 2000 2001 static int 2002 bwn_phy_g_attach(struct bwn_mac *mac) 2003 { 2004 struct bwn_softc *sc = mac->mac_sc; 2005 struct bwn_phy *phy = &mac->mac_phy; 2006 struct bwn_phy_g *pg = &phy->phy_g; 2007 unsigned int i; 2008 int16_t pab0, pab1, pab2; 2009 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2010 int8_t bg; 2011 2012 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2013 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2014 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2015 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2016 2017 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2018 device_printf(sc->sc_dev, "not supported anymore\n"); 2019 2020 pg->pg_flags = 0; 2021 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2022 pab2 == -1) { 2023 pg->pg_idletssi = 52; 2024 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2025 return (0); 2026 } 2027 2028 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2029 pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO); 2030 for (i = 0; i < 64; i++) { 2031 int32_t m1, m2, f, q, delta; 2032 int8_t j = 0; 2033 2034 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2035 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2036 f = 256; 2037 2038 do { 2039 if (j > 15) { 2040 device_printf(sc->sc_dev, 2041 "failed to generate tssi2dBm\n"); 2042 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2043 return (ENOMEM); 2044 } 2045 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2046 f, 2048); 2047 delta = abs(q - f); 2048 f = q; 2049 j++; 2050 } while (delta >= 2); 2051 2052 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2053 128); 2054 } 2055 2056 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2057 return (0); 2058 } 2059 2060 static void 2061 bwn_phy_g_detach(struct bwn_mac *mac) 2062 { 2063 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2064 2065 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2066 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2067 pg->pg_tssi2dbm = NULL; 2068 } 2069 pg->pg_flags = 0; 2070 } 2071 2072 static void 2073 bwn_phy_g_init_pre(struct bwn_mac *mac) 2074 { 2075 struct bwn_phy *phy = &mac->mac_phy; 2076 struct bwn_phy_g *pg = &phy->phy_g; 2077 void *tssi2dbm; 2078 int idletssi; 2079 unsigned int i; 2080 2081 tssi2dbm = pg->pg_tssi2dbm; 2082 idletssi = pg->pg_idletssi; 2083 2084 memset(pg, 0, sizeof(*pg)); 2085 2086 pg->pg_tssi2dbm = tssi2dbm; 2087 pg->pg_idletssi = idletssi; 2088 2089 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2090 2091 for (i = 0; i < N(pg->pg_nrssi); i++) 2092 pg->pg_nrssi[i] = -1000; 2093 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2094 pg->pg_nrssi_lt[i] = i; 2095 pg->pg_lofcal = 0xffff; 2096 pg->pg_initval = 0xffff; 2097 pg->pg_immode = BWN_IMMODE_NONE; 2098 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2099 pg->pg_avgtssi = 0xff; 2100 2101 pg->pg_loctl.tx_bias = 0xff; 2102 TAILQ_INIT(&pg->pg_loctl.calib_list); 2103 } 2104 2105 static int 2106 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2107 { 2108 struct bwn_phy *phy = &mac->mac_phy; 2109 struct bwn_phy_g *pg = &phy->phy_g; 2110 struct bwn_softc *sc = mac->mac_sc; 2111 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2112 static const struct bwn_rfatt rfatt0[] = { 2113 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2114 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2115 { 3, 1 }, { 4, 1 } 2116 }; 2117 static const struct bwn_rfatt rfatt1[] = { 2118 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2119 { 14, 1 } 2120 }; 2121 static const struct bwn_rfatt rfatt2[] = { 2122 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2123 { 9, 1 } 2124 }; 2125 static const struct bwn_bbatt bbatt_0[] = { 2126 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2127 }; 2128 2129 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2130 2131 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2132 pg->pg_bbatt.att = 0; 2133 else 2134 pg->pg_bbatt.att = 2; 2135 2136 /* prepare Radio Attenuation */ 2137 pg->pg_rfatt.padmix = 0; 2138 2139 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2140 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2141 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2142 pg->pg_rfatt.att = 2; 2143 goto done; 2144 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2145 pg->pg_rfatt.att = 3; 2146 goto done; 2147 } 2148 } 2149 2150 if (phy->type == BWN_PHYTYPE_A) { 2151 pg->pg_rfatt.att = 0x60; 2152 goto done; 2153 } 2154 2155 switch (phy->rf_ver) { 2156 case 0x2050: 2157 switch (phy->rf_rev) { 2158 case 0: 2159 pg->pg_rfatt.att = 5; 2160 goto done; 2161 case 1: 2162 if (phy->type == BWN_PHYTYPE_G) { 2163 if (siba_get_pci_subvendor(sc->sc_dev) == 2164 SIBA_BOARDVENDOR_BCM && 2165 siba_get_pci_subdevice(sc->sc_dev) == 2166 SIBA_BOARD_BCM4309G && 2167 siba_get_pci_revid(sc->sc_dev) >= 30) 2168 pg->pg_rfatt.att = 3; 2169 else if (siba_get_pci_subvendor(sc->sc_dev) == 2170 SIBA_BOARDVENDOR_BCM && 2171 siba_get_pci_subdevice(sc->sc_dev) == 2172 SIBA_BOARD_BU4306) 2173 pg->pg_rfatt.att = 3; 2174 else 2175 pg->pg_rfatt.att = 1; 2176 } else { 2177 if (siba_get_pci_subvendor(sc->sc_dev) == 2178 SIBA_BOARDVENDOR_BCM && 2179 siba_get_pci_subdevice(sc->sc_dev) == 2180 SIBA_BOARD_BCM4309G && 2181 siba_get_pci_revid(sc->sc_dev) >= 30) 2182 pg->pg_rfatt.att = 7; 2183 else 2184 pg->pg_rfatt.att = 6; 2185 } 2186 goto done; 2187 case 2: 2188 if (phy->type == BWN_PHYTYPE_G) { 2189 if (siba_get_pci_subvendor(sc->sc_dev) == 2190 SIBA_BOARDVENDOR_BCM && 2191 siba_get_pci_subdevice(sc->sc_dev) == 2192 SIBA_BOARD_BCM4309G && 2193 siba_get_pci_revid(sc->sc_dev) >= 30) 2194 pg->pg_rfatt.att = 3; 2195 else if (siba_get_pci_subvendor(sc->sc_dev) == 2196 SIBA_BOARDVENDOR_BCM && 2197 siba_get_pci_subdevice(sc->sc_dev) == 2198 SIBA_BOARD_BU4306) 2199 pg->pg_rfatt.att = 5; 2200 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2201 pg->pg_rfatt.att = 4; 2202 else 2203 pg->pg_rfatt.att = 3; 2204 } else 2205 pg->pg_rfatt.att = 6; 2206 goto done; 2207 case 3: 2208 pg->pg_rfatt.att = 5; 2209 goto done; 2210 case 4: 2211 case 5: 2212 pg->pg_rfatt.att = 1; 2213 goto done; 2214 case 6: 2215 case 7: 2216 pg->pg_rfatt.att = 5; 2217 goto done; 2218 case 8: 2219 pg->pg_rfatt.att = 0xa; 2220 pg->pg_rfatt.padmix = 1; 2221 goto done; 2222 case 9: 2223 default: 2224 pg->pg_rfatt.att = 5; 2225 goto done; 2226 } 2227 break; 2228 case 0x2053: 2229 switch (phy->rf_rev) { 2230 case 1: 2231 pg->pg_rfatt.att = 6; 2232 goto done; 2233 } 2234 break; 2235 } 2236 pg->pg_rfatt.att = 5; 2237 done: 2238 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2239 2240 if (!bwn_has_hwpctl(mac)) { 2241 lo->rfatt.array = rfatt0; 2242 lo->rfatt.len = N(rfatt0); 2243 lo->rfatt.min = 0; 2244 lo->rfatt.max = 9; 2245 goto genbbatt; 2246 } 2247 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2248 lo->rfatt.array = rfatt1; 2249 lo->rfatt.len = N(rfatt1); 2250 lo->rfatt.min = 0; 2251 lo->rfatt.max = 14; 2252 goto genbbatt; 2253 } 2254 lo->rfatt.array = rfatt2; 2255 lo->rfatt.len = N(rfatt2); 2256 lo->rfatt.min = 0; 2257 lo->rfatt.max = 9; 2258 genbbatt: 2259 lo->bbatt.array = bbatt_0; 2260 lo->bbatt.len = N(bbatt_0); 2261 lo->bbatt.min = 0; 2262 lo->bbatt.max = 8; 2263 2264 BWN_READ_4(mac, BWN_MACCTL); 2265 if (phy->rev == 1) { 2266 phy->gmode = 0; 2267 bwn_reset_core(mac, 0); 2268 bwn_phy_g_init_sub(mac); 2269 phy->gmode = 1; 2270 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2271 } 2272 return (0); 2273 } 2274 2275 static uint16_t 2276 bwn_phy_g_txctl(struct bwn_mac *mac) 2277 { 2278 struct bwn_phy *phy = &mac->mac_phy; 2279 2280 if (phy->rf_ver != 0x2050) 2281 return (0); 2282 if (phy->rf_rev == 1) 2283 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2284 if (phy->rf_rev < 6) 2285 return (BWN_TXCTL_PA2DB); 2286 if (phy->rf_rev == 8) 2287 return (BWN_TXCTL_TXMIX); 2288 return (0); 2289 } 2290 2291 static int 2292 bwn_phy_g_init(struct bwn_mac *mac) 2293 { 2294 2295 bwn_phy_g_init_sub(mac); 2296 return (0); 2297 } 2298 2299 static void 2300 bwn_phy_g_exit(struct bwn_mac *mac) 2301 { 2302 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2303 struct bwn_lo_calib *cal, *tmp; 2304 2305 if (lo == NULL) 2306 return; 2307 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2308 TAILQ_REMOVE(&lo->calib_list, cal, list); 2309 kfree(cal, M_DEVBUF); 2310 } 2311 } 2312 2313 static uint16_t 2314 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2315 { 2316 2317 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2318 return (BWN_READ_2(mac, BWN_PHYDATA)); 2319 } 2320 2321 static void 2322 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2323 { 2324 2325 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2326 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2327 } 2328 2329 static uint16_t 2330 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2331 { 2332 2333 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2334 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2335 return (BWN_READ_2(mac, BWN_RFDATALO)); 2336 } 2337 2338 static void 2339 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2340 { 2341 2342 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2343 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2344 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2345 } 2346 2347 static int 2348 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2349 { 2350 2351 return (mac->mac_phy.rev >= 6); 2352 } 2353 2354 static void 2355 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2356 { 2357 struct bwn_phy *phy = &mac->mac_phy; 2358 struct bwn_phy_g *pg = &phy->phy_g; 2359 unsigned int channel; 2360 uint16_t rfover, rfoverval; 2361 2362 if (on) { 2363 if (phy->rf_on) 2364 return; 2365 2366 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2367 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2368 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2369 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2370 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2371 pg->pg_radioctx_over); 2372 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2373 pg->pg_radioctx_overval); 2374 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2375 } 2376 channel = phy->chan; 2377 bwn_phy_g_switch_chan(mac, 6, 1); 2378 bwn_phy_g_switch_chan(mac, channel, 0); 2379 return; 2380 } 2381 2382 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2383 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2384 pg->pg_radioctx_over = rfover; 2385 pg->pg_radioctx_overval = rfoverval; 2386 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2387 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2388 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2389 } 2390 2391 static int 2392 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2393 { 2394 2395 if ((newchan < 1) || (newchan > 14)) 2396 return (EINVAL); 2397 bwn_phy_g_switch_chan(mac, newchan, 0); 2398 2399 return (0); 2400 } 2401 2402 static uint32_t 2403 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2404 { 2405 2406 return (1); 2407 } 2408 2409 static void 2410 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2411 { 2412 struct bwn_phy *phy = &mac->mac_phy; 2413 uint64_t hf; 2414 int autodiv = 0; 2415 uint16_t tmp; 2416 2417 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2418 autodiv = 1; 2419 2420 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2421 bwn_hf_write(mac, hf); 2422 2423 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2424 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2425 ((autodiv ? BWN_ANTAUTO1 : antenna) 2426 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2427 2428 if (autodiv) { 2429 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2430 if (antenna == BWN_ANTAUTO1) 2431 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2432 else 2433 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2434 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2435 } 2436 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2437 if (autodiv) 2438 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2439 else 2440 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2441 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2442 if (phy->rev >= 2) { 2443 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2444 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2445 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2446 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2447 0x15); 2448 if (phy->rev == 2) 2449 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2450 else 2451 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2452 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2453 8); 2454 } 2455 if (phy->rev >= 6) 2456 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2457 2458 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2459 bwn_hf_write(mac, hf); 2460 } 2461 2462 static int 2463 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2464 { 2465 struct bwn_phy *phy = &mac->mac_phy; 2466 struct bwn_phy_g *pg = &phy->phy_g; 2467 2468 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2469 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2470 2471 if (phy->rev == 0 || !phy->gmode) 2472 return (ENODEV); 2473 2474 pg->pg_aci_wlan_automatic = 0; 2475 return (0); 2476 } 2477 2478 static int 2479 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2480 { 2481 struct bwn_phy *phy = &mac->mac_phy; 2482 struct bwn_phy_g *pg = &phy->phy_g; 2483 struct bwn_softc *sc = mac->mac_sc; 2484 unsigned int tssi; 2485 int cck, ofdm; 2486 int power; 2487 int rfatt, bbatt; 2488 unsigned int max; 2489 2490 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2491 2492 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2493 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2494 if (cck < 0 && ofdm < 0) { 2495 if (ignore_tssi == 0) 2496 return (BWN_TXPWR_RES_DONE); 2497 cck = 0; 2498 ofdm = 0; 2499 } 2500 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2501 if (pg->pg_avgtssi != 0xff) 2502 tssi = (tssi + pg->pg_avgtssi) / 2; 2503 pg->pg_avgtssi = tssi; 2504 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2505 2506 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2507 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2508 max -= 3; 2509 if (max >= 120) { 2510 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2511 max = 80; 2512 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2513 } 2514 2515 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2516 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2517 tssi, 0x00), 0x3f)]); 2518 if (power == 0) 2519 return (BWN_TXPWR_RES_DONE); 2520 2521 rfatt = -((power + 7) / 8); 2522 bbatt = (-(power / 2)) - (4 * rfatt); 2523 if ((rfatt == 0) && (bbatt == 0)) 2524 return (BWN_TXPWR_RES_DONE); 2525 pg->pg_bbatt_delta = bbatt; 2526 pg->pg_rfatt_delta = rfatt; 2527 return (BWN_TXPWR_RES_NEED_ADJUST); 2528 } 2529 2530 static void 2531 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2532 { 2533 struct bwn_phy *phy = &mac->mac_phy; 2534 struct bwn_phy_g *pg = &phy->phy_g; 2535 struct bwn_softc *sc = mac->mac_sc; 2536 int rfatt, bbatt; 2537 uint8_t txctl; 2538 2539 bwn_mac_suspend(mac); 2540 2541 bbatt = pg->pg_bbatt.att; 2542 bbatt += pg->pg_bbatt_delta; 2543 rfatt = pg->pg_rfatt.att; 2544 rfatt += pg->pg_rfatt_delta; 2545 2546 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2547 txctl = pg->pg_txctl; 2548 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2549 if (rfatt <= 1) { 2550 if (txctl == 0) { 2551 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2552 rfatt += 2; 2553 bbatt += 2; 2554 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2555 BWN_BFL_PACTRL) { 2556 bbatt += 4 * (rfatt - 2); 2557 rfatt = 2; 2558 } 2559 } else if (rfatt > 4 && txctl) { 2560 txctl = 0; 2561 if (bbatt < 3) { 2562 rfatt -= 3; 2563 bbatt += 2; 2564 } else { 2565 rfatt -= 2; 2566 bbatt -= 2; 2567 } 2568 } 2569 } 2570 pg->pg_txctl = txctl; 2571 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2572 pg->pg_rfatt.att = rfatt; 2573 pg->pg_bbatt.att = bbatt; 2574 2575 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2576 2577 bwn_phy_lock(mac); 2578 bwn_rf_lock(mac); 2579 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2580 pg->pg_txctl); 2581 bwn_rf_unlock(mac); 2582 bwn_phy_unlock(mac); 2583 2584 bwn_mac_enable(mac); 2585 } 2586 2587 static void 2588 bwn_phy_g_task_15s(struct bwn_mac *mac) 2589 { 2590 struct bwn_phy *phy = &mac->mac_phy; 2591 struct bwn_phy_g *pg = &phy->phy_g; 2592 struct bwn_softc *sc = mac->mac_sc; 2593 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2594 unsigned long expire, now; 2595 struct bwn_lo_calib *cal, *tmp; 2596 uint8_t expired = 0; 2597 2598 bwn_mac_suspend(mac); 2599 2600 if (lo == NULL) 2601 goto fail; 2602 2603 BWN_GETTIME(now); 2604 if (bwn_has_hwpctl(mac)) { 2605 expire = now - BWN_LO_PWRVEC_EXPIRE; 2606 if (time_before(lo->pwr_vec_read_time, expire)) { 2607 bwn_lo_get_powervector(mac); 2608 bwn_phy_g_dc_lookup_init(mac, 0); 2609 } 2610 goto fail; 2611 } 2612 2613 expire = now - BWN_LO_CALIB_EXPIRE; 2614 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2615 if (!time_before(cal->calib_time, expire)) 2616 continue; 2617 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2618 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2619 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2620 expired = 1; 2621 } 2622 2623 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2624 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2625 cal->ctl.i, cal->ctl.q); 2626 2627 TAILQ_REMOVE(&lo->calib_list, cal, list); 2628 kfree(cal, M_DEVBUF); 2629 } 2630 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2631 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2632 &pg->pg_rfatt); 2633 if (cal == NULL) { /* XXX ivadasz: can't happen */ 2634 device_printf(sc->sc_dev, 2635 "failed to recalibrate LO\n"); 2636 goto fail; 2637 } 2638 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2639 bwn_lo_write(mac, &cal->ctl); 2640 } 2641 2642 fail: 2643 bwn_mac_enable(mac); 2644 } 2645 2646 static void 2647 bwn_phy_g_task_60s(struct bwn_mac *mac) 2648 { 2649 struct bwn_phy *phy = &mac->mac_phy; 2650 struct bwn_softc *sc = mac->mac_sc; 2651 uint8_t old = phy->chan; 2652 2653 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2654 return; 2655 2656 bwn_mac_suspend(mac); 2657 bwn_nrssi_slope_11g(mac); 2658 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2659 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2660 bwn_switch_channel(mac, old); 2661 } 2662 bwn_mac_enable(mac); 2663 } 2664 2665 static void 2666 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2667 { 2668 2669 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2670 } 2671 2672 static int 2673 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2674 const struct ieee80211_bpf_params *params) 2675 { 2676 struct ieee80211com *ic = ni->ni_ic; 2677 struct ifnet *ifp = ic->ic_ifp; 2678 struct bwn_softc *sc = ifp->if_softc; 2679 struct bwn_mac *mac = sc->sc_curmac; 2680 2681 if ((ifp->if_flags & IFF_RUNNING) == 0 || 2682 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2683 ieee80211_free_node(ni); 2684 m_freem(m); 2685 return (ENETDOWN); 2686 } 2687 2688 if (bwn_tx_isfull(sc, m)) { 2689 ieee80211_free_node(ni); 2690 m_freem(m); 2691 ifp->if_oerrors++; 2692 return (ENOBUFS); 2693 } 2694 2695 if (bwn_tx_start(sc, ni, m) != 0) { 2696 if (ni != NULL) 2697 ieee80211_free_node(ni); 2698 ifp->if_oerrors++; 2699 } 2700 sc->sc_watchdog_timer = 5; 2701 return (0); 2702 } 2703 2704 /* 2705 * Callback from the 802.11 layer to update the slot time 2706 * based on the current setting. We use it to notify the 2707 * firmware of ERP changes and the f/w takes care of things 2708 * like slot time and preamble. 2709 */ 2710 static void 2711 bwn_updateslot(struct ifnet *ifp) 2712 { 2713 struct bwn_softc *sc = ifp->if_softc; 2714 struct ieee80211com *ic = ifp->if_l2com; 2715 struct bwn_mac *mac; 2716 2717 if (ifp->if_flags & IFF_RUNNING) { 2718 mac = (struct bwn_mac *)sc->sc_curmac; 2719 bwn_set_slot_time(mac, 2720 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2721 } 2722 } 2723 2724 /* 2725 * Callback from the 802.11 layer after a promiscuous mode change. 2726 * Note this interface does not check the operating mode as this 2727 * is an internal callback and we are expected to honor the current 2728 * state (e.g. this is used for setting the interface in promiscuous 2729 * mode when operating in hostap mode to do ACS). 2730 */ 2731 static void 2732 bwn_update_promisc(struct ifnet *ifp) 2733 { 2734 struct bwn_softc *sc = ifp->if_softc; 2735 struct bwn_mac *mac = sc->sc_curmac; 2736 2737 mac = sc->sc_curmac; 2738 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2739 if (ifp->if_flags & IFF_PROMISC) 2740 sc->sc_filters |= BWN_MACCTL_PROMISC; 2741 else 2742 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2743 bwn_set_opmode(mac); 2744 } 2745 } 2746 2747 /* 2748 * Callback from the 802.11 layer to update WME parameters. 2749 */ 2750 static int 2751 bwn_wme_update(struct ieee80211com *ic) 2752 { 2753 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2754 struct bwn_mac *mac = sc->sc_curmac; 2755 struct wmeParams *wmep; 2756 int i; 2757 2758 mac = sc->sc_curmac; 2759 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2760 bwn_mac_suspend(mac); 2761 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2762 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2763 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2764 } 2765 bwn_mac_enable(mac); 2766 } 2767 return (0); 2768 } 2769 2770 static void 2771 bwn_scan_start(struct ieee80211com *ic) 2772 { 2773 struct ifnet *ifp = ic->ic_ifp; 2774 struct bwn_softc *sc = ifp->if_softc; 2775 struct bwn_mac *mac; 2776 2777 mac = sc->sc_curmac; 2778 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2779 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2780 bwn_set_opmode(mac); 2781 /* disable CFP update during scan */ 2782 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2783 } 2784 } 2785 2786 static void 2787 bwn_scan_end(struct ieee80211com *ic) 2788 { 2789 struct ifnet *ifp = ic->ic_ifp; 2790 struct bwn_softc *sc = ifp->if_softc; 2791 struct bwn_mac *mac; 2792 2793 mac = sc->sc_curmac; 2794 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2795 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2796 bwn_set_opmode(mac); 2797 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2798 } 2799 } 2800 2801 static void 2802 bwn_set_channel(struct ieee80211com *ic) 2803 { 2804 struct ifnet *ifp = ic->ic_ifp; 2805 struct bwn_softc *sc = ifp->if_softc; 2806 struct bwn_mac *mac = sc->sc_curmac; 2807 struct bwn_phy *phy = &mac->mac_phy; 2808 int chan, error; 2809 2810 error = bwn_switch_band(sc, ic->ic_curchan); 2811 if (error) 2812 goto fail; 2813 bwn_mac_suspend(mac); 2814 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2815 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2816 if (chan != phy->chan) 2817 bwn_switch_channel(mac, chan); 2818 2819 /* TX power level */ 2820 if (ic->ic_curchan->ic_maxpower != 0 && 2821 ic->ic_curchan->ic_maxpower != phy->txpower) { 2822 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2823 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2824 BWN_TXPWR_IGNORE_TSSI); 2825 } 2826 2827 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2828 if (phy->set_antenna) 2829 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2830 2831 if (sc->sc_rf_enabled != phy->rf_on) { 2832 if (sc->sc_rf_enabled) { 2833 bwn_rf_turnon(mac); 2834 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2835 device_printf(sc->sc_dev, 2836 "please turn on the RF switch\n"); 2837 } else 2838 bwn_rf_turnoff(mac); 2839 } 2840 2841 bwn_mac_enable(mac); 2842 2843 fail: 2844 /* 2845 * Setup radio tap channel freq and flags 2846 */ 2847 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2848 htole16(ic->ic_curchan->ic_freq); 2849 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2850 htole16(ic->ic_curchan->ic_flags & 0xffff); 2851 } 2852 2853 static struct ieee80211vap * 2854 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2855 enum ieee80211_opmode opmode, int flags, 2856 const uint8_t bssid[IEEE80211_ADDR_LEN], 2857 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2858 { 2859 struct ifnet *ifp = ic->ic_ifp; 2860 struct bwn_softc *sc = ifp->if_softc; 2861 struct ieee80211vap *vap; 2862 struct bwn_vap *bvp; 2863 uint8_t mac[IEEE80211_ADDR_LEN]; 2864 2865 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 2866 return NULL; 2867 2868 IEEE80211_ADDR_COPY(mac, mac0); 2869 switch (opmode) { 2870 case IEEE80211_M_HOSTAP: 2871 case IEEE80211_M_MBSS: 2872 case IEEE80211_M_STA: 2873 case IEEE80211_M_WDS: 2874 case IEEE80211_M_MONITOR: 2875 case IEEE80211_M_IBSS: 2876 case IEEE80211_M_AHDEMO: 2877 break; 2878 default: 2879 return (NULL); 2880 } 2881 2882 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2883 2884 bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap), 2885 M_80211_VAP, M_INTWAIT | M_ZERO); 2886 vap = &bvp->bv_vap; 2887 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2888 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2889 /* override with driver methods */ 2890 bvp->bv_newstate = vap->iv_newstate; 2891 vap->iv_newstate = bwn_newstate; 2892 2893 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2894 vap->iv_max_aid = BWN_STAID_MAX; 2895 2896 ieee80211_ratectl_init(vap); 2897 2898 /* complete setup */ 2899 ieee80211_vap_attach(vap, ieee80211_media_change, 2900 ieee80211_media_status); 2901 ic->ic_opmode = opmode; 2902 return (vap); 2903 } 2904 2905 static void 2906 bwn_vap_delete(struct ieee80211vap *vap) 2907 { 2908 struct bwn_vap *bvp = BWN_VAP(vap); 2909 2910 ieee80211_ratectl_deinit(vap); 2911 ieee80211_vap_detach(vap); 2912 kfree(bvp, M_80211_VAP); 2913 } 2914 2915 static void 2916 bwn_init(void *arg) 2917 { 2918 struct bwn_softc *sc = arg; 2919 struct ifnet *ifp = sc->sc_ifp; 2920 struct ieee80211com *ic = ifp->if_l2com; 2921 int error = 0; 2922 2923 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 2924 __func__, ifp->if_flags); 2925 2926 wlan_assert_serialized(); 2927 error = bwn_init_locked(sc); 2928 2929 if (error == 0) 2930 ieee80211_start_all(ic); /* start all vap's */ 2931 } 2932 2933 static int 2934 bwn_init_locked(struct bwn_softc *sc) 2935 { 2936 struct bwn_mac *mac; 2937 struct ifnet *ifp = sc->sc_ifp; 2938 int error; 2939 2940 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2941 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2942 sc->sc_filters = 0; 2943 bwn_wme_clear(sc); 2944 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2945 sc->sc_rf_enabled = 1; 2946 2947 mac = sc->sc_curmac; 2948 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2949 error = bwn_core_init(mac); 2950 if (error != 0) 2951 return (error); 2952 } 2953 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2954 bwn_core_start(mac); 2955 2956 bwn_set_opmode(mac); 2957 bwn_set_pretbtt(mac); 2958 bwn_spu_setdelay(mac, 0); 2959 bwn_set_macaddr(mac); 2960 2961 ifp->if_flags |= IFF_RUNNING; 2962 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2963 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2964 2965 return (0); 2966 } 2967 2968 static void 2969 bwn_stop(struct bwn_softc *sc, int statechg) 2970 { 2971 2972 wlan_assert_serialized(); 2973 bwn_stop_locked(sc, statechg); 2974 } 2975 2976 static void 2977 bwn_stop_locked(struct bwn_softc *sc, int statechg) 2978 { 2979 struct bwn_mac *mac = sc->sc_curmac; 2980 struct ifnet *ifp = sc->sc_ifp; 2981 2982 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2983 /* XXX FIXME opmode not based on VAP */ 2984 bwn_set_opmode(mac); 2985 bwn_set_macaddr(mac); 2986 } 2987 2988 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 2989 bwn_core_stop(mac); 2990 2991 callout_stop(&sc->sc_led_blink_ch); 2992 sc->sc_led_blinking = 0; 2993 2994 bwn_core_exit(mac); 2995 sc->sc_rf_enabled = 0; 2996 2997 ifp->if_flags &= ~IFF_RUNNING; 2998 ifq_clr_oactive(&ifp->if_snd); 2999 } 3000 3001 static void 3002 bwn_wme_clear(struct bwn_softc *sc) 3003 { 3004 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3005 struct wmeParams *p; 3006 unsigned int i; 3007 3008 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3009 ("%s:%d: fail", __func__, __LINE__)); 3010 3011 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3012 p = &(sc->sc_wmeParams[i]); 3013 3014 switch (bwn_wme_shm_offsets[i]) { 3015 case BWN_WME_VOICE: 3016 p->wmep_txopLimit = 0; 3017 p->wmep_aifsn = 2; 3018 /* XXX FIXME: log2(cwmin) */ 3019 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3020 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3021 break; 3022 case BWN_WME_VIDEO: 3023 p->wmep_txopLimit = 0; 3024 p->wmep_aifsn = 2; 3025 /* XXX FIXME: log2(cwmin) */ 3026 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3027 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3028 break; 3029 case BWN_WME_BESTEFFORT: 3030 p->wmep_txopLimit = 0; 3031 p->wmep_aifsn = 3; 3032 /* XXX FIXME: log2(cwmin) */ 3033 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3034 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3035 break; 3036 case BWN_WME_BACKGROUND: 3037 p->wmep_txopLimit = 0; 3038 p->wmep_aifsn = 7; 3039 /* XXX FIXME: log2(cwmin) */ 3040 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3041 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3042 break; 3043 default: 3044 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3045 } 3046 } 3047 } 3048 3049 static int 3050 bwn_core_init(struct bwn_mac *mac) 3051 { 3052 struct bwn_softc *sc = mac->mac_sc; 3053 uint64_t hf; 3054 int error; 3055 3056 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3057 ("%s:%d: fail", __func__, __LINE__)); 3058 3059 siba_powerup(sc->sc_dev, 0); 3060 if (!siba_dev_isup(sc->sc_dev)) 3061 bwn_reset_core(mac, 3062 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3063 3064 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3065 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3066 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3067 BWN_GETTIME(mac->mac_phy.nexttime); 3068 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3069 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3070 mac->mac_stats.link_noise = -95; 3071 mac->mac_reason_intr = 0; 3072 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3073 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3074 #ifdef BWN_DEBUG 3075 if (sc->sc_debug & BWN_DEBUG_XMIT) 3076 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3077 #endif 3078 mac->mac_suspended = 1; 3079 mac->mac_task_state = 0; 3080 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3081 3082 mac->mac_phy.init_pre(mac); 3083 3084 siba_pcicore_intr(sc->sc_dev); 3085 3086 siba_fix_imcfglobug(sc->sc_dev); 3087 bwn_bt_disable(mac); 3088 if (mac->mac_phy.prepare_hw) { 3089 error = mac->mac_phy.prepare_hw(mac); 3090 if (error) 3091 goto fail0; 3092 } 3093 error = bwn_chip_init(mac); 3094 if (error) 3095 goto fail0; 3096 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3097 siba_get_revid(sc->sc_dev)); 3098 hf = bwn_hf_read(mac); 3099 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3100 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3101 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3102 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3103 if (mac->mac_phy.rev == 1) 3104 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3105 } 3106 if (mac->mac_phy.rf_ver == 0x2050) { 3107 if (mac->mac_phy.rf_rev < 6) 3108 hf |= BWN_HF_FORCE_VCO_RECALC; 3109 if (mac->mac_phy.rf_rev == 6) 3110 hf |= BWN_HF_4318_TSSI; 3111 } 3112 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3113 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3114 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3115 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3116 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3117 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3118 bwn_hf_write(mac, hf); 3119 3120 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3121 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3122 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3123 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3124 3125 bwn_rate_init(mac); 3126 bwn_set_phytxctl(mac); 3127 3128 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3129 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3130 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3131 3132 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3133 bwn_pio_init(mac); 3134 else 3135 bwn_dma_init(mac); 3136 bwn_wme_init(mac); 3137 bwn_spu_setdelay(mac, 1); 3138 bwn_bt_enable(mac); 3139 3140 siba_powerup(sc->sc_dev, 3141 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3142 bwn_set_macaddr(mac); 3143 bwn_crypt_init(mac); 3144 3145 /* XXX LED initializatin */ 3146 3147 mac->mac_status = BWN_MAC_STATUS_INITED; 3148 3149 return (error); 3150 3151 fail0: 3152 siba_powerdown(sc->sc_dev); 3153 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3154 ("%s:%d: fail", __func__, __LINE__)); 3155 return (error); 3156 } 3157 3158 static void 3159 bwn_core_start(struct bwn_mac *mac) 3160 { 3161 struct bwn_softc *sc = mac->mac_sc; 3162 uint32_t tmp; 3163 3164 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3165 ("%s:%d: fail", __func__, __LINE__)); 3166 3167 if (siba_get_revid(sc->sc_dev) < 5) 3168 return; 3169 3170 while (1) { 3171 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3172 if (!(tmp & 0x00000001)) 3173 break; 3174 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3175 } 3176 3177 bwn_mac_enable(mac); 3178 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3179 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3180 3181 mac->mac_status = BWN_MAC_STATUS_STARTED; 3182 } 3183 3184 static void 3185 bwn_core_exit(struct bwn_mac *mac) 3186 { 3187 struct bwn_softc *sc = mac->mac_sc; 3188 uint32_t macctl; 3189 3190 wlan_assert_serialized(); 3191 3192 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3193 ("%s:%d: fail", __func__, __LINE__)); 3194 3195 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3196 return; 3197 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3198 3199 macctl = BWN_READ_4(mac, BWN_MACCTL); 3200 macctl &= ~BWN_MACCTL_MCODE_RUN; 3201 macctl |= BWN_MACCTL_MCODE_JMP0; 3202 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3203 3204 bwn_dma_stop(mac); 3205 bwn_pio_stop(mac); 3206 bwn_chip_exit(mac); 3207 mac->mac_phy.switch_analog(mac, 0); 3208 siba_dev_down(sc->sc_dev, 0); 3209 siba_powerdown(sc->sc_dev); 3210 } 3211 3212 static void 3213 bwn_bt_disable(struct bwn_mac *mac) 3214 { 3215 struct bwn_softc *sc = mac->mac_sc; 3216 3217 (void)sc; 3218 /* XXX do nothing yet */ 3219 } 3220 3221 static int 3222 bwn_chip_init(struct bwn_mac *mac) 3223 { 3224 struct bwn_softc *sc = mac->mac_sc; 3225 struct bwn_phy *phy = &mac->mac_phy; 3226 uint32_t macctl; 3227 int error; 3228 3229 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3230 if (phy->gmode) 3231 macctl |= BWN_MACCTL_GMODE; 3232 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3233 3234 error = bwn_fw_fillinfo(mac); 3235 if (error) 3236 return (error); 3237 error = bwn_fw_loaducode(mac); 3238 if (error) 3239 return (error); 3240 3241 error = bwn_gpio_init(mac); 3242 if (error) 3243 return (error); 3244 3245 error = bwn_fw_loadinitvals(mac); 3246 if (error) { 3247 siba_gpio_set(sc->sc_dev, 0); 3248 return (error); 3249 } 3250 phy->switch_analog(mac, 1); 3251 error = bwn_phy_init(mac); 3252 if (error) { 3253 siba_gpio_set(sc->sc_dev, 0); 3254 return (error); 3255 } 3256 if (phy->set_im) 3257 phy->set_im(mac, BWN_IMMODE_NONE); 3258 if (phy->set_antenna) 3259 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3260 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3261 3262 if (phy->type == BWN_PHYTYPE_B) 3263 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3264 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3265 if (siba_get_revid(sc->sc_dev) < 5) 3266 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3267 3268 BWN_WRITE_4(mac, BWN_MACCTL, 3269 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3270 BWN_WRITE_4(mac, BWN_MACCTL, 3271 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3272 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3273 3274 bwn_set_opmode(mac); 3275 if (siba_get_revid(sc->sc_dev) < 3) { 3276 BWN_WRITE_2(mac, 0x060e, 0x0000); 3277 BWN_WRITE_2(mac, 0x0610, 0x8000); 3278 BWN_WRITE_2(mac, 0x0604, 0x0000); 3279 BWN_WRITE_2(mac, 0x0606, 0x0200); 3280 } else { 3281 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3282 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3283 } 3284 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3285 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00); 3286 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3287 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3288 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3289 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3290 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3291 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3292 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3293 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3294 return (error); 3295 } 3296 3297 /* read hostflags */ 3298 static uint64_t 3299 bwn_hf_read(struct bwn_mac *mac) 3300 { 3301 uint64_t ret; 3302 3303 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3304 ret <<= 16; 3305 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3306 ret <<= 16; 3307 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3308 return (ret); 3309 } 3310 3311 static void 3312 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3313 { 3314 3315 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3316 (value & 0x00000000ffffull)); 3317 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3318 (value & 0x0000ffff0000ull) >> 16); 3319 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3320 (value & 0xffff00000000ULL) >> 32); 3321 } 3322 3323 static void 3324 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3325 { 3326 3327 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3328 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3329 } 3330 3331 static void 3332 bwn_rate_init(struct bwn_mac *mac) 3333 { 3334 3335 switch (mac->mac_phy.type) { 3336 case BWN_PHYTYPE_A: 3337 case BWN_PHYTYPE_G: 3338 case BWN_PHYTYPE_LP: 3339 case BWN_PHYTYPE_N: 3340 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3341 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3342 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3343 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3344 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3345 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3346 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3347 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3348 break; 3349 /* FALLTHROUGH */ 3350 case BWN_PHYTYPE_B: 3351 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3352 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3353 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3354 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3355 break; 3356 default: 3357 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3358 } 3359 } 3360 3361 static void 3362 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3363 { 3364 uint16_t offset; 3365 3366 if (ofdm) { 3367 offset = 0x480; 3368 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3369 } else { 3370 offset = 0x4c0; 3371 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3372 } 3373 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3374 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3375 } 3376 3377 static uint8_t 3378 bwn_plcp_getcck(const uint8_t bitrate) 3379 { 3380 3381 switch (bitrate) { 3382 case BWN_CCK_RATE_1MB: 3383 return (0x0a); 3384 case BWN_CCK_RATE_2MB: 3385 return (0x14); 3386 case BWN_CCK_RATE_5MB: 3387 return (0x37); 3388 case BWN_CCK_RATE_11MB: 3389 return (0x6e); 3390 } 3391 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3392 return (0); 3393 } 3394 3395 static uint8_t 3396 bwn_plcp_getofdm(const uint8_t bitrate) 3397 { 3398 3399 switch (bitrate) { 3400 case BWN_OFDM_RATE_6MB: 3401 return (0xb); 3402 case BWN_OFDM_RATE_9MB: 3403 return (0xf); 3404 case BWN_OFDM_RATE_12MB: 3405 return (0xa); 3406 case BWN_OFDM_RATE_18MB: 3407 return (0xe); 3408 case BWN_OFDM_RATE_24MB: 3409 return (0x9); 3410 case BWN_OFDM_RATE_36MB: 3411 return (0xd); 3412 case BWN_OFDM_RATE_48MB: 3413 return (0x8); 3414 case BWN_OFDM_RATE_54MB: 3415 return (0xc); 3416 } 3417 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3418 return (0); 3419 } 3420 3421 static void 3422 bwn_set_phytxctl(struct bwn_mac *mac) 3423 { 3424 uint16_t ctl; 3425 3426 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3427 BWN_TX_PHY_TXPWR); 3428 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3429 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3430 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3431 } 3432 3433 static void 3434 bwn_pio_init(struct bwn_mac *mac) 3435 { 3436 struct bwn_pio *pio = &mac->mac_method.pio; 3437 3438 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3439 & ~BWN_MACCTL_BIGENDIAN); 3440 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3441 3442 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3443 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3444 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3445 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3446 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3447 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3448 } 3449 3450 static void 3451 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3452 int index) 3453 { 3454 struct bwn_pio_txpkt *tp; 3455 struct bwn_softc *sc = mac->mac_sc; 3456 unsigned int i; 3457 3458 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3459 tq->tq_index = index; 3460 3461 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3462 if (siba_get_revid(sc->sc_dev) >= 8) 3463 tq->tq_size = 1920; 3464 else { 3465 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3466 tq->tq_size -= 80; 3467 } 3468 3469 TAILQ_INIT(&tq->tq_pktlist); 3470 for (i = 0; i < N(tq->tq_pkts); i++) { 3471 tp = &(tq->tq_pkts[i]); 3472 tp->tp_index = i; 3473 tp->tp_queue = tq; 3474 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3475 } 3476 } 3477 3478 static uint16_t 3479 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3480 { 3481 struct bwn_softc *sc = mac->mac_sc; 3482 static const uint16_t bases[] = { 3483 BWN_PIO_BASE0, 3484 BWN_PIO_BASE1, 3485 BWN_PIO_BASE2, 3486 BWN_PIO_BASE3, 3487 BWN_PIO_BASE4, 3488 BWN_PIO_BASE5, 3489 BWN_PIO_BASE6, 3490 BWN_PIO_BASE7, 3491 }; 3492 static const uint16_t bases_rev11[] = { 3493 BWN_PIO11_BASE0, 3494 BWN_PIO11_BASE1, 3495 BWN_PIO11_BASE2, 3496 BWN_PIO11_BASE3, 3497 BWN_PIO11_BASE4, 3498 BWN_PIO11_BASE5, 3499 }; 3500 3501 if (siba_get_revid(sc->sc_dev) >= 11) { 3502 if (index >= N(bases_rev11)) 3503 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3504 return (bases_rev11[index]); 3505 } 3506 if (index >= N(bases)) 3507 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3508 return (bases[index]); 3509 } 3510 3511 static void 3512 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3513 int index) 3514 { 3515 struct bwn_softc *sc = mac->mac_sc; 3516 3517 prq->prq_mac = mac; 3518 prq->prq_rev = siba_get_revid(sc->sc_dev); 3519 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3520 bwn_dma_rxdirectfifo(mac, index, 1); 3521 } 3522 3523 static void 3524 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3525 { 3526 if (tq == NULL) 3527 return; 3528 bwn_pio_cancel_tx_packets(tq); 3529 } 3530 3531 static void 3532 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3533 { 3534 3535 bwn_destroy_pioqueue_tx(pio); 3536 } 3537 3538 static uint16_t 3539 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3540 uint16_t offset) 3541 { 3542 3543 return (BWN_READ_2(mac, tq->tq_base + offset)); 3544 } 3545 3546 static void 3547 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3548 { 3549 uint32_t ctl; 3550 int type; 3551 uint16_t base; 3552 3553 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3554 base = bwn_dma_base(type, idx); 3555 if (type == BWN_DMA_64BIT) { 3556 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3557 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3558 if (enable) 3559 ctl |= BWN_DMA64_RXDIRECTFIFO; 3560 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3561 } else { 3562 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3563 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3564 if (enable) 3565 ctl |= BWN_DMA32_RXDIRECTFIFO; 3566 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3567 } 3568 } 3569 3570 static uint64_t 3571 bwn_dma_mask(struct bwn_mac *mac) 3572 { 3573 uint32_t tmp; 3574 uint16_t base; 3575 3576 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3577 if (tmp & SIBA_TGSHIGH_DMA64) 3578 return (BWN_DMA_BIT_MASK(64)); 3579 base = bwn_dma_base(0, 0); 3580 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3581 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3582 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3583 return (BWN_DMA_BIT_MASK(32)); 3584 3585 return (BWN_DMA_BIT_MASK(30)); 3586 } 3587 3588 static int 3589 bwn_dma_mask2type(uint64_t dmamask) 3590 { 3591 3592 if (dmamask == BWN_DMA_BIT_MASK(30)) 3593 return (BWN_DMA_30BIT); 3594 if (dmamask == BWN_DMA_BIT_MASK(32)) 3595 return (BWN_DMA_32BIT); 3596 if (dmamask == BWN_DMA_BIT_MASK(64)) 3597 return (BWN_DMA_64BIT); 3598 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3599 return (BWN_DMA_30BIT); 3600 } 3601 3602 static void 3603 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3604 { 3605 struct bwn_pio_txpkt *tp; 3606 unsigned int i; 3607 3608 for (i = 0; i < N(tq->tq_pkts); i++) { 3609 tp = &(tq->tq_pkts[i]); 3610 if (tp->tp_m) { 3611 m_freem(tp->tp_m); 3612 tp->tp_m = NULL; 3613 } 3614 } 3615 } 3616 3617 static uint16_t 3618 bwn_dma_base(int type, int controller_idx) 3619 { 3620 static const uint16_t map64[] = { 3621 BWN_DMA64_BASE0, 3622 BWN_DMA64_BASE1, 3623 BWN_DMA64_BASE2, 3624 BWN_DMA64_BASE3, 3625 BWN_DMA64_BASE4, 3626 BWN_DMA64_BASE5, 3627 }; 3628 static const uint16_t map32[] = { 3629 BWN_DMA32_BASE0, 3630 BWN_DMA32_BASE1, 3631 BWN_DMA32_BASE2, 3632 BWN_DMA32_BASE3, 3633 BWN_DMA32_BASE4, 3634 BWN_DMA32_BASE5, 3635 }; 3636 3637 if (type == BWN_DMA_64BIT) { 3638 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3639 ("%s:%d: fail", __func__, __LINE__)); 3640 return (map64[controller_idx]); 3641 } 3642 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3643 ("%s:%d: fail", __func__, __LINE__)); 3644 return (map32[controller_idx]); 3645 } 3646 3647 static void 3648 bwn_dma_init(struct bwn_mac *mac) 3649 { 3650 struct bwn_dma *dma = &mac->mac_method.dma; 3651 3652 /* setup TX DMA channels. */ 3653 bwn_dma_setup(dma->wme[WME_AC_BK]); 3654 bwn_dma_setup(dma->wme[WME_AC_BE]); 3655 bwn_dma_setup(dma->wme[WME_AC_VI]); 3656 bwn_dma_setup(dma->wme[WME_AC_VO]); 3657 bwn_dma_setup(dma->mcast); 3658 /* setup RX DMA channel. */ 3659 bwn_dma_setup(dma->rx); 3660 } 3661 3662 static struct bwn_dma_ring * 3663 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3664 int for_tx, int type) 3665 { 3666 struct bwn_dma *dma = &mac->mac_method.dma; 3667 struct bwn_dma_ring *dr; 3668 struct bwn_dmadesc_generic *desc; 3669 struct bwn_dmadesc_meta *mt; 3670 struct bwn_softc *sc = mac->mac_sc; 3671 int error, i; 3672 3673 dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO); 3674 dr->dr_numslots = BWN_RXRING_SLOTS; 3675 if (for_tx) 3676 dr->dr_numslots = BWN_TXRING_SLOTS; 3677 3678 dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3679 M_DEVBUF, M_INTWAIT | M_ZERO); 3680 3681 dr->dr_type = type; 3682 dr->dr_mac = mac; 3683 dr->dr_base = bwn_dma_base(type, controller_index); 3684 dr->dr_index = controller_index; 3685 if (type == BWN_DMA_64BIT) { 3686 dr->getdesc = bwn_dma_64_getdesc; 3687 dr->setdesc = bwn_dma_64_setdesc; 3688 dr->start_transfer = bwn_dma_64_start_transfer; 3689 dr->suspend = bwn_dma_64_suspend; 3690 dr->resume = bwn_dma_64_resume; 3691 dr->get_curslot = bwn_dma_64_get_curslot; 3692 dr->set_curslot = bwn_dma_64_set_curslot; 3693 } else { 3694 dr->getdesc = bwn_dma_32_getdesc; 3695 dr->setdesc = bwn_dma_32_setdesc; 3696 dr->start_transfer = bwn_dma_32_start_transfer; 3697 dr->suspend = bwn_dma_32_suspend; 3698 dr->resume = bwn_dma_32_resume; 3699 dr->get_curslot = bwn_dma_32_get_curslot; 3700 dr->set_curslot = bwn_dma_32_set_curslot; 3701 } 3702 if (for_tx) { 3703 dr->dr_tx = 1; 3704 dr->dr_curslot = -1; 3705 } else { 3706 if (dr->dr_index == 0) { 3707 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3708 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3709 } else 3710 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3711 } 3712 3713 error = bwn_dma_allocringmemory(dr); 3714 if (error) 3715 goto fail1; 3716 3717 if (for_tx) { 3718 /* 3719 * Assumption: BWN_TXRING_SLOTS can be divided by 3720 * BWN_TX_SLOTS_PER_FRAME 3721 */ 3722 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3723 ("%s:%d: fail", __func__, __LINE__)); 3724 3725 /* 3726 * Create TX ring DMA stuffs 3727 */ 3728 dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag, 3729 4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3730 BWN_MAX_HDRSIZE(mac), 3731 BUS_DMA_WAITOK | BUS_DMA_ZERO, 3732 &dr->dr_txring_dtag, &dr->dr_txring_dmap, 3733 &dr->dr_txring_paddr); 3734 if (dr->dr_txhdr_cache == NULL) { 3735 device_printf(sc->sc_dev, 3736 "can't create TX ring DMA memory\n"); 3737 goto fail1; 3738 } 3739 3740 for (i = 0; i < dr->dr_numslots; i += 2) { 3741 dr->getdesc(dr, i, &desc, &mt); 3742 3743 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3744 mt->mt_m = NULL; 3745 mt->mt_ni = NULL; 3746 mt->mt_islast = 0; 3747 mt->mt_dmap = dr->dr_txring_dmap; 3748 mt->mt_paddr = dr->dr_txring_paddr + 3749 (i / BWN_TX_SLOTS_PER_FRAME) * 3750 BWN_MAX_HDRSIZE(mac); 3751 3752 dr->getdesc(dr, i + 1, &desc, &mt); 3753 3754 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3755 mt->mt_m = NULL; 3756 mt->mt_ni = NULL; 3757 mt->mt_islast = 1; 3758 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3759 &mt->mt_dmap); 3760 if (error) { 3761 device_printf(sc->sc_dev, 3762 "can't create RX buf DMA map\n"); 3763 goto fail2; 3764 } 3765 } 3766 } else { 3767 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3768 &dr->dr_spare_dmap); 3769 if (error) { 3770 device_printf(sc->sc_dev, 3771 "can't create RX buf DMA map\n"); 3772 goto out; /* XXX wrong! */ 3773 } 3774 3775 for (i = 0; i < dr->dr_numslots; i++) { 3776 dr->getdesc(dr, i, &desc, &mt); 3777 3778 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3779 &mt->mt_dmap); 3780 if (error) { 3781 device_printf(sc->sc_dev, 3782 "can't create RX buf DMA map\n"); 3783 goto out; /* XXX wrong! */ 3784 } 3785 error = bwn_dma_newbuf(dr, desc, mt, 1); 3786 if (error) { 3787 device_printf(sc->sc_dev, 3788 "failed to allocate RX buf\n"); 3789 goto out; /* XXX wrong! */ 3790 } 3791 } 3792 3793 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3794 BUS_DMASYNC_PREWRITE); 3795 3796 dr->dr_usedslot = dr->dr_numslots; 3797 } 3798 3799 out: 3800 return (dr); 3801 3802 fail2: 3803 /* XXX free up dma allocations */ 3804 fail1: 3805 kfree(dr->dr_meta, M_DEVBUF); 3806 kfree(dr, M_DEVBUF); 3807 return (NULL); 3808 } 3809 3810 static void 3811 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3812 { 3813 3814 if (dr == NULL) 3815 return; 3816 3817 bwn_dma_free_descbufs(*dr); 3818 bwn_dma_free_ringmemory(*dr); 3819 3820 if ((*dr)->dr_meta != NULL) 3821 kfree((*dr)->dr_meta, M_DEVBUF); 3822 kfree(*dr, M_DEVBUF); 3823 3824 *dr = NULL; 3825 } 3826 3827 static void 3828 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3829 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3830 { 3831 struct bwn_dmadesc32 *desc; 3832 3833 *meta = &(dr->dr_meta[slot]); 3834 desc = dr->dr_ring_descbase; 3835 desc = &(desc[slot]); 3836 3837 *gdesc = (struct bwn_dmadesc_generic *)desc; 3838 } 3839 3840 static void 3841 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3842 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3843 int start, int end, int irq) 3844 { 3845 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3846 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3847 uint32_t addr, addrext, ctl; 3848 int slot; 3849 3850 slot = (int)(&(desc->dma.dma32) - descbase); 3851 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3852 ("%s:%d: fail", __func__, __LINE__)); 3853 3854 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3855 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3856 addr |= siba_dma_translation(sc->sc_dev); 3857 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3858 if (slot == dr->dr_numslots - 1) 3859 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3860 if (start) 3861 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3862 if (end) 3863 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3864 if (irq) 3865 ctl |= BWN_DMA32_DCTL_IRQ; 3866 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3867 & BWN_DMA32_DCTL_ADDREXT_MASK; 3868 3869 desc->dma.dma32.control = htole32(ctl); 3870 desc->dma.dma32.address = htole32(addr); 3871 } 3872 3873 static void 3874 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3875 { 3876 3877 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3878 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3879 } 3880 3881 static void 3882 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3883 { 3884 3885 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3886 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3887 } 3888 3889 static void 3890 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3891 { 3892 3893 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3894 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3895 } 3896 3897 static int 3898 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3899 { 3900 uint32_t val; 3901 3902 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3903 val &= BWN_DMA32_RXDPTR; 3904 3905 return (val / sizeof(struct bwn_dmadesc32)); 3906 } 3907 3908 static void 3909 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3910 { 3911 3912 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3913 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3914 } 3915 3916 static void 3917 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3918 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3919 { 3920 struct bwn_dmadesc64 *desc; 3921 3922 *meta = &(dr->dr_meta[slot]); 3923 desc = dr->dr_ring_descbase; 3924 desc = &(desc[slot]); 3925 3926 *gdesc = (struct bwn_dmadesc_generic *)desc; 3927 } 3928 3929 static void 3930 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3931 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3932 int start, int end, int irq) 3933 { 3934 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3935 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3936 int slot; 3937 uint32_t ctl0 = 0, ctl1 = 0; 3938 uint32_t addrlo, addrhi; 3939 uint32_t addrext; 3940 3941 slot = (int)(&(desc->dma.dma64) - descbase); 3942 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3943 ("%s:%d: fail", __func__, __LINE__)); 3944 3945 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3946 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3947 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3948 30; 3949 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3950 if (slot == dr->dr_numslots - 1) 3951 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3952 if (start) 3953 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3954 if (end) 3955 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3956 if (irq) 3957 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3958 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3959 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3960 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3961 3962 desc->dma.dma64.control0 = htole32(ctl0); 3963 desc->dma.dma64.control1 = htole32(ctl1); 3964 desc->dma.dma64.address_low = htole32(addrlo); 3965 desc->dma.dma64.address_high = htole32(addrhi); 3966 } 3967 3968 static void 3969 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3970 { 3971 3972 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3973 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3974 } 3975 3976 static void 3977 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3978 { 3979 3980 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3981 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3982 } 3983 3984 static void 3985 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3986 { 3987 3988 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3989 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 3990 } 3991 3992 static int 3993 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 3994 { 3995 uint32_t val; 3996 3997 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 3998 val &= BWN_DMA64_RXSTATDPTR; 3999 4000 return (val / sizeof(struct bwn_dmadesc64)); 4001 } 4002 4003 static void 4004 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4005 { 4006 4007 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4008 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4009 } 4010 4011 static int 4012 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4013 { 4014 struct bwn_mac *mac = dr->dr_mac; 4015 struct bwn_dma *dma = &mac->mac_method.dma; 4016 struct bwn_softc *sc = mac->mac_sc; 4017 int error; 4018 4019 error = bus_dma_tag_create(dma->parent_dtag, 4020 BWN_ALIGN, 0, 4021 BUS_SPACE_MAXADDR, 4022 BUS_SPACE_MAXADDR, 4023 NULL, NULL, 4024 BWN_DMA_RINGMEMSIZE, 4025 1, 4026 BUS_SPACE_MAXSIZE_32BIT, 4027 0, 4028 &dr->dr_ring_dtag); 4029 if (error) { 4030 device_printf(sc->sc_dev, 4031 "can't create TX ring DMA tag: TODO frees\n"); 4032 return (-1); 4033 } 4034 4035 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4036 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4037 &dr->dr_ring_dmap); 4038 if (error) { 4039 device_printf(sc->sc_dev, 4040 "can't allocate DMA mem: TODO frees\n"); 4041 return (-1); 4042 } 4043 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4044 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4045 bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0); 4046 if (error) { 4047 device_printf(sc->sc_dev, 4048 "can't load DMA mem: TODO free\n"); 4049 return (-1); 4050 } 4051 4052 return (0); 4053 } 4054 4055 static void 4056 bwn_dma_setup(struct bwn_dma_ring *dr) 4057 { 4058 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4059 uint64_t ring64; 4060 uint32_t addrext, ring32, value; 4061 uint32_t trans = siba_dma_translation(sc->sc_dev); 4062 4063 if (dr->dr_tx) { 4064 dr->dr_curslot = -1; 4065 4066 if (dr->dr_type == BWN_DMA_64BIT) { 4067 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4068 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4069 >> 30; 4070 value = BWN_DMA64_TXENABLE; 4071 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4072 & BWN_DMA64_TXADDREXT_MASK; 4073 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4074 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4075 (ring64 & 0xffffffff)); 4076 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4077 ((ring64 >> 32) & 4078 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4079 } else { 4080 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4081 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4082 value = BWN_DMA32_TXENABLE; 4083 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4084 & BWN_DMA32_TXADDREXT_MASK; 4085 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4086 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4087 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4088 } 4089 return; 4090 } 4091 4092 /* 4093 * set for RX 4094 */ 4095 dr->dr_usedslot = dr->dr_numslots; 4096 4097 if (dr->dr_type == BWN_DMA_64BIT) { 4098 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4099 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4100 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4101 value |= BWN_DMA64_RXENABLE; 4102 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4103 & BWN_DMA64_RXADDREXT_MASK; 4104 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4105 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4106 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4107 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4108 | (trans << 1)); 4109 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4110 sizeof(struct bwn_dmadesc64)); 4111 } else { 4112 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4113 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4114 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4115 value |= BWN_DMA32_RXENABLE; 4116 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4117 & BWN_DMA32_RXADDREXT_MASK; 4118 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4119 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4120 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4121 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4122 sizeof(struct bwn_dmadesc32)); 4123 } 4124 } 4125 4126 static void 4127 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4128 { 4129 4130 if (dr->dr_tx) { 4131 bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap); 4132 if (dr->dr_txhdr_cache != NULL) 4133 bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache, 4134 dr->dr_txring_dmap); 4135 bus_dma_tag_destroy(dr->dr_txring_dtag); 4136 } 4137 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4138 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4139 dr->dr_ring_dmap); 4140 bus_dma_tag_destroy(dr->dr_ring_dtag); 4141 } 4142 4143 static void 4144 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4145 { 4146 4147 if (dr->dr_tx) { 4148 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4149 if (dr->dr_type == BWN_DMA_64BIT) { 4150 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4151 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4152 } else 4153 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4154 } else { 4155 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4156 if (dr->dr_type == BWN_DMA_64BIT) { 4157 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4158 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4159 } else 4160 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4161 } 4162 } 4163 4164 static void 4165 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4166 { 4167 struct bwn_dmadesc_generic *desc; 4168 struct bwn_dmadesc_meta *meta; 4169 struct bwn_mac *mac = dr->dr_mac; 4170 struct bwn_dma *dma = &mac->mac_method.dma; 4171 struct bwn_softc *sc = mac->mac_sc; 4172 int i; 4173 4174 if (!dr->dr_usedslot) 4175 return; 4176 for (i = 0; i < dr->dr_numslots; i++) { 4177 dr->getdesc(dr, i, &desc, &meta); 4178 4179 if (meta->mt_m == NULL) { 4180 if (!dr->dr_tx) 4181 device_printf(sc->sc_dev, "%s: not TX?\n", 4182 __func__); 4183 continue; 4184 } 4185 if (dr->dr_tx) { 4186 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 4187 /* Nothing */ 4188 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 4189 bus_dmamap_unload(dma->txbuf_dtag, 4190 meta->mt_dmap); 4191 } 4192 } else 4193 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4194 bwn_dma_free_descbuf(dr, meta); 4195 } 4196 } 4197 4198 static int 4199 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4200 int type) 4201 { 4202 struct bwn_softc *sc = mac->mac_sc; 4203 uint32_t value; 4204 int i; 4205 uint16_t offset; 4206 4207 for (i = 0; i < 10; i++) { 4208 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4209 BWN_DMA32_TXSTATUS; 4210 value = BWN_READ_4(mac, base + offset); 4211 if (type == BWN_DMA_64BIT) { 4212 value &= BWN_DMA64_TXSTAT; 4213 if (value == BWN_DMA64_TXSTAT_DISABLED || 4214 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4215 value == BWN_DMA64_TXSTAT_STOPPED) 4216 break; 4217 } else { 4218 value &= BWN_DMA32_TXSTATE; 4219 if (value == BWN_DMA32_TXSTAT_DISABLED || 4220 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4221 value == BWN_DMA32_TXSTAT_STOPPED) 4222 break; 4223 } 4224 DELAY(1000); 4225 } 4226 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4227 BWN_WRITE_4(mac, base + offset, 0); 4228 for (i = 0; i < 10; i++) { 4229 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4230 BWN_DMA32_TXSTATUS; 4231 value = BWN_READ_4(mac, base + offset); 4232 if (type == BWN_DMA_64BIT) { 4233 value &= BWN_DMA64_TXSTAT; 4234 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4235 i = -1; 4236 break; 4237 } 4238 } else { 4239 value &= BWN_DMA32_TXSTATE; 4240 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4241 i = -1; 4242 break; 4243 } 4244 } 4245 DELAY(1000); 4246 } 4247 if (i != -1) { 4248 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4249 return (ENODEV); 4250 } 4251 DELAY(1000); 4252 4253 return (0); 4254 } 4255 4256 static int 4257 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4258 int type) 4259 { 4260 struct bwn_softc *sc = mac->mac_sc; 4261 uint32_t value; 4262 int i; 4263 uint16_t offset; 4264 4265 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4266 BWN_WRITE_4(mac, base + offset, 0); 4267 for (i = 0; i < 10; i++) { 4268 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4269 BWN_DMA32_RXSTATUS; 4270 value = BWN_READ_4(mac, base + offset); 4271 if (type == BWN_DMA_64BIT) { 4272 value &= BWN_DMA64_RXSTAT; 4273 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4274 i = -1; 4275 break; 4276 } 4277 } else { 4278 value &= BWN_DMA32_RXSTATE; 4279 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4280 i = -1; 4281 break; 4282 } 4283 } 4284 DELAY(1000); 4285 } 4286 if (i != -1) { 4287 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4288 return (ENODEV); 4289 } 4290 4291 return (0); 4292 } 4293 4294 static void 4295 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4296 struct bwn_dmadesc_meta *meta) 4297 { 4298 4299 if (meta->mt_m != NULL) { 4300 m_freem(meta->mt_m); 4301 meta->mt_m = NULL; 4302 } 4303 if (meta->mt_ni != NULL) { 4304 ieee80211_free_node(meta->mt_ni); 4305 meta->mt_ni = NULL; 4306 } 4307 } 4308 4309 static void 4310 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4311 { 4312 struct bwn_rxhdr4 *rxhdr; 4313 unsigned char *frame; 4314 4315 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4316 rxhdr->frame_len = 0; 4317 4318 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4319 sizeof(struct bwn_plcp6) + 2, 4320 ("%s:%d: fail", __func__, __LINE__)); 4321 frame = mtod(m, char *) + dr->dr_frameoffset; 4322 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4323 } 4324 4325 static uint8_t 4326 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4327 { 4328 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4329 4330 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4331 == 0xff); 4332 } 4333 4334 static void 4335 bwn_wme_init(struct bwn_mac *mac) 4336 { 4337 4338 bwn_wme_load(mac); 4339 4340 /* enable WME support. */ 4341 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4342 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4343 BWN_IFSCTL_USE_EDCF); 4344 } 4345 4346 static void 4347 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4348 { 4349 struct bwn_softc *sc = mac->mac_sc; 4350 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4351 uint16_t delay; /* microsec */ 4352 4353 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4354 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4355 delay = 500; 4356 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4357 delay = max(delay, (uint16_t)2400); 4358 4359 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4360 } 4361 4362 static void 4363 bwn_bt_enable(struct bwn_mac *mac) 4364 { 4365 struct bwn_softc *sc = mac->mac_sc; 4366 uint64_t hf; 4367 4368 if (bwn_bluetooth == 0) 4369 return; 4370 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4371 return; 4372 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4373 return; 4374 4375 hf = bwn_hf_read(mac); 4376 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4377 hf |= BWN_HF_BT_COEXISTALT; 4378 else 4379 hf |= BWN_HF_BT_COEXIST; 4380 bwn_hf_write(mac, hf); 4381 } 4382 4383 static void 4384 bwn_set_macaddr(struct bwn_mac *mac) 4385 { 4386 4387 bwn_mac_write_bssid(mac); 4388 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4389 } 4390 4391 static void 4392 bwn_clear_keys(struct bwn_mac *mac) 4393 { 4394 int i; 4395 4396 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4397 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4398 ("%s:%d: fail", __func__, __LINE__)); 4399 4400 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4401 NULL, BWN_SEC_KEYSIZE, NULL); 4402 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4403 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4404 NULL, BWN_SEC_KEYSIZE, NULL); 4405 } 4406 mac->mac_key[i].keyconf = NULL; 4407 } 4408 } 4409 4410 static void 4411 bwn_crypt_init(struct bwn_mac *mac) 4412 { 4413 struct bwn_softc *sc = mac->mac_sc; 4414 4415 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4416 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4417 ("%s:%d: fail", __func__, __LINE__)); 4418 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4419 mac->mac_ktp *= 2; 4420 if (siba_get_revid(sc->sc_dev) >= 5) 4421 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4422 bwn_clear_keys(mac); 4423 } 4424 4425 static void 4426 bwn_chip_exit(struct bwn_mac *mac) 4427 { 4428 struct bwn_softc *sc = mac->mac_sc; 4429 4430 bwn_phy_exit(mac); 4431 siba_gpio_set(sc->sc_dev, 0); 4432 } 4433 4434 static int 4435 bwn_fw_fillinfo(struct bwn_mac *mac) 4436 { 4437 int error; 4438 4439 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4440 if (error == 0) 4441 return (0); 4442 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4443 if (error == 0) 4444 return (0); 4445 return (error); 4446 } 4447 4448 static int 4449 bwn_gpio_init(struct bwn_mac *mac) 4450 { 4451 struct bwn_softc *sc = mac->mac_sc; 4452 uint32_t mask = 0x1f, set = 0xf, value; 4453 4454 BWN_WRITE_4(mac, BWN_MACCTL, 4455 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4456 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4457 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4458 4459 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4460 mask |= 0x0060; 4461 set |= 0x0060; 4462 } 4463 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4464 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4465 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4466 mask |= 0x0200; 4467 set |= 0x0200; 4468 } 4469 if (siba_get_revid(sc->sc_dev) >= 2) 4470 mask |= 0x0010; 4471 4472 value = siba_gpio_get(sc->sc_dev); 4473 if (value == -1) 4474 return (0); 4475 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4476 4477 return (0); 4478 } 4479 4480 static int 4481 bwn_fw_loadinitvals(struct bwn_mac *mac) 4482 { 4483 #define GETFWOFFSET(fwp, offset) \ 4484 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4485 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4486 const struct bwn_fwhdr *hdr; 4487 struct bwn_fw *fw = &mac->mac_fw; 4488 int error; 4489 4490 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4491 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4492 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4493 if (error) 4494 return (error); 4495 if (fw->initvals_band.fw) { 4496 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4497 error = bwn_fwinitvals_write(mac, 4498 GETFWOFFSET(fw->initvals_band, hdr_len), 4499 be32toh(hdr->size), 4500 fw->initvals_band.fw->datasize - hdr_len); 4501 } 4502 return (error); 4503 #undef GETFWOFFSET 4504 } 4505 4506 static int 4507 bwn_phy_init(struct bwn_mac *mac) 4508 { 4509 struct bwn_softc *sc = mac->mac_sc; 4510 int error; 4511 4512 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4513 mac->mac_phy.rf_onoff(mac, 1); 4514 error = mac->mac_phy.init(mac); 4515 if (error) { 4516 device_printf(sc->sc_dev, "PHY init failed\n"); 4517 goto fail0; 4518 } 4519 error = bwn_switch_channel(mac, 4520 mac->mac_phy.get_default_chan(mac)); 4521 if (error) { 4522 device_printf(sc->sc_dev, 4523 "failed to switch default channel\n"); 4524 goto fail1; 4525 } 4526 return (0); 4527 fail1: 4528 if (mac->mac_phy.exit) 4529 mac->mac_phy.exit(mac); 4530 fail0: 4531 mac->mac_phy.rf_onoff(mac, 0); 4532 4533 return (error); 4534 } 4535 4536 static void 4537 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4538 { 4539 uint16_t ant; 4540 uint16_t tmp; 4541 4542 ant = bwn_ant2phy(antenna); 4543 4544 /* For ACK/CTS */ 4545 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4546 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4547 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4548 /* For Probe Resposes */ 4549 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4550 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4551 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4552 } 4553 4554 static void 4555 bwn_set_opmode(struct bwn_mac *mac) 4556 { 4557 struct bwn_softc *sc = mac->mac_sc; 4558 struct ifnet *ifp = sc->sc_ifp; 4559 struct ieee80211com *ic = ifp->if_l2com; 4560 uint32_t ctl; 4561 uint16_t cfp_pretbtt; 4562 4563 ctl = BWN_READ_4(mac, BWN_MACCTL); 4564 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4565 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4566 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4567 ctl |= BWN_MACCTL_STA; 4568 4569 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4570 ic->ic_opmode == IEEE80211_M_MBSS) 4571 ctl |= BWN_MACCTL_HOSTAP; 4572 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4573 ctl &= ~BWN_MACCTL_STA; 4574 ctl |= sc->sc_filters; 4575 4576 if (siba_get_revid(sc->sc_dev) <= 4) 4577 ctl |= BWN_MACCTL_PROMISC; 4578 4579 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4580 4581 cfp_pretbtt = 2; 4582 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4583 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4584 siba_get_chiprev(sc->sc_dev) == 3) 4585 cfp_pretbtt = 100; 4586 else 4587 cfp_pretbtt = 50; 4588 } 4589 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4590 } 4591 4592 static int 4593 bwn_dma_gettype(struct bwn_mac *mac) 4594 { 4595 uint32_t tmp; 4596 uint16_t base; 4597 4598 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4599 if (tmp & SIBA_TGSHIGH_DMA64) 4600 return (BWN_DMA_64BIT); 4601 base = bwn_dma_base(0, 0); 4602 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4603 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4604 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4605 return (BWN_DMA_32BIT); 4606 4607 return (BWN_DMA_30BIT); 4608 } 4609 4610 static void 4611 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4612 { 4613 if (!error) { 4614 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4615 *((bus_addr_t *)arg) = seg->ds_addr; 4616 } 4617 } 4618 4619 static void 4620 bwn_phy_g_init_sub(struct bwn_mac *mac) 4621 { 4622 struct bwn_phy *phy = &mac->mac_phy; 4623 struct bwn_phy_g *pg = &phy->phy_g; 4624 struct bwn_softc *sc = mac->mac_sc; 4625 uint16_t i, tmp; 4626 4627 if (phy->rev == 1) 4628 bwn_phy_init_b5(mac); 4629 else 4630 bwn_phy_init_b6(mac); 4631 4632 if (phy->rev >= 2 || phy->gmode) 4633 bwn_phy_init_a(mac); 4634 4635 if (phy->rev >= 2) { 4636 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4637 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4638 } 4639 if (phy->rev == 2) { 4640 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4641 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4642 } 4643 if (phy->rev > 5) { 4644 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4645 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4646 } 4647 if (phy->gmode || phy->rev >= 2) { 4648 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4649 tmp &= BWN_PHYVER_VERSION; 4650 if (tmp == 3 || tmp == 5) { 4651 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4652 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4653 } 4654 if (tmp == 5) { 4655 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4656 0x1f00); 4657 } 4658 } 4659 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4660 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4661 if (phy->rf_rev == 8) { 4662 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4663 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4664 } 4665 if (BWN_HAS_LOOPBACK(phy)) 4666 bwn_loopback_calcgain(mac); 4667 4668 if (phy->rf_rev != 8) { 4669 if (pg->pg_initval == 0xffff) 4670 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4671 else 4672 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4673 } 4674 bwn_lo_g_init(mac); 4675 if (BWN_HAS_TXMAG(phy)) { 4676 BWN_RF_WRITE(mac, 0x52, 4677 (BWN_RF_READ(mac, 0x52) & 0xff00) 4678 | pg->pg_loctl.tx_bias | 4679 pg->pg_loctl.tx_magn); 4680 } else { 4681 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4682 } 4683 if (phy->rev >= 6) { 4684 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4685 (pg->pg_loctl.tx_bias << 12)); 4686 } 4687 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4688 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4689 else 4690 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4691 if (phy->rev < 2) 4692 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4693 else 4694 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4695 if (phy->gmode || phy->rev >= 2) { 4696 bwn_lo_g_adjust(mac); 4697 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4698 } 4699 4700 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4701 for (i = 0; i < 64; i++) { 4702 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4703 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4704 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4705 -32), 31)); 4706 } 4707 bwn_nrssi_threshold(mac); 4708 } else if (phy->gmode || phy->rev >= 2) { 4709 if (pg->pg_nrssi[0] == -1000) { 4710 KASSERT(pg->pg_nrssi[1] == -1000, 4711 ("%s:%d: fail", __func__, __LINE__)); 4712 bwn_nrssi_slope_11g(mac); 4713 } else 4714 bwn_nrssi_threshold(mac); 4715 } 4716 if (phy->rf_rev == 8) 4717 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4718 bwn_phy_hwpctl_init(mac); 4719 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4720 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4721 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4722 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4723 } 4724 } 4725 4726 static uint8_t 4727 bwn_has_hwpctl(struct bwn_mac *mac) 4728 { 4729 4730 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4731 return (0); 4732 return (mac->mac_phy.use_hwpctl(mac)); 4733 } 4734 4735 static void 4736 bwn_phy_init_b5(struct bwn_mac *mac) 4737 { 4738 struct bwn_phy *phy = &mac->mac_phy; 4739 struct bwn_phy_g *pg = &phy->phy_g; 4740 struct bwn_softc *sc = mac->mac_sc; 4741 uint16_t offset, value; 4742 uint8_t old_channel; 4743 4744 if (phy->analog == 1) 4745 BWN_RF_SET(mac, 0x007a, 0x0050); 4746 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4747 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4748 value = 0x2120; 4749 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4750 BWN_PHY_WRITE(mac, offset, value); 4751 value += 0x202; 4752 } 4753 } 4754 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4755 if (phy->rf_ver == 0x2050) 4756 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4757 4758 if (phy->gmode || phy->rev >= 2) { 4759 if (phy->rf_ver == 0x2050) { 4760 BWN_RF_SET(mac, 0x007a, 0x0020); 4761 BWN_RF_SET(mac, 0x0051, 0x0004); 4762 } 4763 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4764 4765 BWN_PHY_SET(mac, 0x0802, 0x0100); 4766 BWN_PHY_SET(mac, 0x042b, 0x2000); 4767 4768 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4769 4770 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4771 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4772 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4773 } 4774 4775 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4776 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4777 4778 if (phy->analog == 1) { 4779 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4780 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4781 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4782 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4783 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4784 } else 4785 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4786 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4787 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4788 4789 if (phy->analog == 1) 4790 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4791 else 4792 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4793 4794 if (phy->analog == 0) 4795 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4796 4797 old_channel = phy->chan; 4798 bwn_phy_g_switch_chan(mac, 7, 0); 4799 4800 if (phy->rf_ver != 0x2050) { 4801 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4802 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4803 } 4804 4805 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4806 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4807 4808 if (phy->rf_ver == 0x2050) { 4809 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4810 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4811 } 4812 4813 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4814 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4815 BWN_RF_SET(mac, 0x007a, 0x0007); 4816 4817 bwn_phy_g_switch_chan(mac, old_channel, 0); 4818 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4819 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4820 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4821 4822 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4823 pg->pg_txctl); 4824 4825 if (phy->rf_ver == 0x2050) 4826 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4827 4828 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4829 } 4830 4831 static void 4832 bwn_loopback_calcgain(struct bwn_mac *mac) 4833 { 4834 struct bwn_phy *phy = &mac->mac_phy; 4835 struct bwn_phy_g *pg = &phy->phy_g; 4836 struct bwn_softc *sc = mac->mac_sc; 4837 uint16_t backup_phy[16] = { 0 }; 4838 uint16_t backup_radio[3]; 4839 uint16_t backup_bband; 4840 uint16_t i, j, loop_i_max; 4841 uint16_t trsw_rx; 4842 uint16_t loop1_outer_done, loop1_inner_done; 4843 4844 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4845 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4846 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4847 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4848 if (phy->rev != 1) { 4849 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4850 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4851 } 4852 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4853 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4854 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4855 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4856 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4857 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4858 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4859 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4860 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4861 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4862 backup_bband = pg->pg_bbatt.att; 4863 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4864 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4865 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4866 4867 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4868 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4869 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4870 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4871 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4872 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4873 if (phy->rev != 1) { 4874 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4875 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4876 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4877 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4878 } 4879 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4880 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4881 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4882 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4883 4884 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4885 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4886 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4887 4888 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4889 if (phy->rev != 1) { 4890 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4891 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4892 } 4893 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4894 4895 if (phy->rf_rev == 8) 4896 BWN_RF_WRITE(mac, 0x43, 0x000f); 4897 else { 4898 BWN_RF_WRITE(mac, 0x52, 0); 4899 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4900 } 4901 bwn_phy_g_set_bbatt(mac, 11); 4902 4903 if (phy->rev >= 3) 4904 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4905 else 4906 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4907 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4908 4909 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 4910 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 4911 4912 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 4913 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 4914 4915 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 4916 if (phy->rev >= 7) { 4917 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 4918 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 4919 } 4920 } 4921 BWN_RF_MASK(mac, 0x7a, 0x00f7); 4922 4923 j = 0; 4924 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 4925 for (i = 0; i < loop_i_max; i++) { 4926 for (j = 0; j < 16; j++) { 4927 BWN_RF_WRITE(mac, 0x43, i); 4928 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 4929 (j << 8)); 4930 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4931 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4932 DELAY(20); 4933 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4934 goto done0; 4935 } 4936 } 4937 done0: 4938 loop1_outer_done = i; 4939 loop1_inner_done = j; 4940 if (j >= 8) { 4941 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 4942 trsw_rx = 0x1b; 4943 for (j = j - 8; j < 16; j++) { 4944 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 4945 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4946 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4947 DELAY(20); 4948 trsw_rx -= 3; 4949 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4950 goto done1; 4951 } 4952 } else 4953 trsw_rx = 0x18; 4954 done1: 4955 4956 if (phy->rev != 1) { 4957 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 4958 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 4959 } 4960 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 4961 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 4962 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 4963 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 4964 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 4965 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 4966 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 4967 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 4968 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 4969 4970 bwn_phy_g_set_bbatt(mac, backup_bband); 4971 4972 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 4973 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 4974 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 4975 4976 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 4977 DELAY(10); 4978 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 4979 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 4980 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 4981 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 4982 4983 pg->pg_max_lb_gain = 4984 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 4985 pg->pg_trsw_rx_gain = trsw_rx * 2; 4986 } 4987 4988 static uint16_t 4989 bwn_rf_init_bcm2050(struct bwn_mac *mac) 4990 { 4991 struct bwn_phy *phy = &mac->mac_phy; 4992 uint32_t tmp1 = 0, tmp2 = 0; 4993 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 4994 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 4995 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 4996 static const uint8_t rcc_table[] = { 4997 0x02, 0x03, 0x01, 0x0f, 4998 0x06, 0x07, 0x05, 0x0f, 4999 0x0a, 0x0b, 0x09, 0x0f, 5000 0x0e, 0x0f, 0x0d, 0x0f, 5001 }; 5002 5003 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5004 rfoverval = rfover = cck3 = 0; 5005 radio0 = BWN_RF_READ(mac, 0x43); 5006 radio1 = BWN_RF_READ(mac, 0x51); 5007 radio2 = BWN_RF_READ(mac, 0x52); 5008 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5009 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5010 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5011 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5012 5013 if (phy->type == BWN_PHYTYPE_B) { 5014 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5015 reg0 = BWN_READ_2(mac, 0x3ec); 5016 5017 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5018 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5019 } else if (phy->gmode || phy->rev >= 2) { 5020 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5021 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5022 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5023 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5024 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5025 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5026 5027 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5028 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5029 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5030 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5031 if (BWN_HAS_LOOPBACK(phy)) { 5032 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5033 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5034 if (phy->rev >= 3) 5035 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5036 else 5037 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5038 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5039 } 5040 5041 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5042 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5043 BWN_LPD(0, 1, 1))); 5044 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5045 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5046 } 5047 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5048 5049 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5050 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5051 reg1 = BWN_READ_2(mac, 0x3e6); 5052 reg2 = BWN_READ_2(mac, 0x3f4); 5053 5054 if (phy->analog == 0) 5055 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5056 else { 5057 if (phy->analog >= 2) 5058 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5059 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5060 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5061 } 5062 5063 reg = BWN_RF_READ(mac, 0x60); 5064 index = (reg & 0x001e) >> 1; 5065 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5066 5067 if (phy->type == BWN_PHYTYPE_B) 5068 BWN_RF_WRITE(mac, 0x78, 0x26); 5069 if (phy->gmode || phy->rev >= 2) { 5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5071 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5072 BWN_LPD(0, 1, 1))); 5073 } 5074 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5075 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5076 if (phy->gmode || phy->rev >= 2) { 5077 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5078 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5079 BWN_LPD(0, 0, 1))); 5080 } 5081 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5082 BWN_RF_SET(mac, 0x51, 0x0004); 5083 if (phy->rf_rev == 8) 5084 BWN_RF_WRITE(mac, 0x43, 0x1f); 5085 else { 5086 BWN_RF_WRITE(mac, 0x52, 0); 5087 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5088 } 5089 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5090 5091 for (i = 0; i < 16; i++) { 5092 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5093 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5094 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5095 if (phy->gmode || phy->rev >= 2) { 5096 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5097 bwn_rf_2050_rfoverval(mac, 5098 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5099 } 5100 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5101 DELAY(10); 5102 if (phy->gmode || phy->rev >= 2) { 5103 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5104 bwn_rf_2050_rfoverval(mac, 5105 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5106 } 5107 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5108 DELAY(10); 5109 if (phy->gmode || phy->rev >= 2) { 5110 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5111 bwn_rf_2050_rfoverval(mac, 5112 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5113 } 5114 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5115 DELAY(20); 5116 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5117 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5118 if (phy->gmode || phy->rev >= 2) { 5119 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5120 bwn_rf_2050_rfoverval(mac, 5121 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5122 } 5123 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5124 } 5125 DELAY(10); 5126 5127 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5128 tmp1++; 5129 tmp1 >>= 9; 5130 5131 for (i = 0; i < 16; i++) { 5132 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5133 BWN_RF_WRITE(mac, 0x78, radio78); 5134 DELAY(10); 5135 for (j = 0; j < 16; j++) { 5136 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5137 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5138 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5139 if (phy->gmode || phy->rev >= 2) { 5140 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5141 bwn_rf_2050_rfoverval(mac, 5142 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5143 } 5144 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5145 DELAY(10); 5146 if (phy->gmode || phy->rev >= 2) { 5147 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5148 bwn_rf_2050_rfoverval(mac, 5149 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5150 } 5151 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5152 DELAY(10); 5153 if (phy->gmode || phy->rev >= 2) { 5154 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5155 bwn_rf_2050_rfoverval(mac, 5156 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5157 } 5158 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5159 DELAY(10); 5160 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5161 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5162 if (phy->gmode || phy->rev >= 2) { 5163 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5164 bwn_rf_2050_rfoverval(mac, 5165 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5166 } 5167 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5168 } 5169 tmp2++; 5170 tmp2 >>= 8; 5171 if (tmp1 < tmp2) 5172 break; 5173 } 5174 5175 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5176 BWN_RF_WRITE(mac, 0x51, radio1); 5177 BWN_RF_WRITE(mac, 0x52, radio2); 5178 BWN_RF_WRITE(mac, 0x43, radio0); 5179 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5180 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5181 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5182 BWN_WRITE_2(mac, 0x3e6, reg1); 5183 if (phy->analog != 0) 5184 BWN_WRITE_2(mac, 0x3f4, reg2); 5185 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5186 bwn_spu_workaround(mac, phy->chan); 5187 if (phy->type == BWN_PHYTYPE_B) { 5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5189 BWN_WRITE_2(mac, 0x3ec, reg0); 5190 } else if (phy->gmode) { 5191 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5192 BWN_READ_2(mac, BWN_PHY_RADIO) 5193 & 0x7fff); 5194 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5195 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5196 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5197 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5198 analogoverval); 5199 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5200 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5201 if (BWN_HAS_LOOPBACK(phy)) { 5202 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5203 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5204 } 5205 } 5206 5207 return ((i > 15) ? radio78 : rcc); 5208 } 5209 5210 static void 5211 bwn_phy_init_b6(struct bwn_mac *mac) 5212 { 5213 struct bwn_phy *phy = &mac->mac_phy; 5214 struct bwn_phy_g *pg = &phy->phy_g; 5215 struct bwn_softc *sc = mac->mac_sc; 5216 uint16_t offset, val; 5217 uint8_t old_channel; 5218 5219 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5220 ("%s:%d: fail", __func__, __LINE__)); 5221 5222 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5223 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5224 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5225 BWN_RF_WRITE(mac, 0x51, 0x37); 5226 BWN_RF_WRITE(mac, 0x52, 0x70); 5227 BWN_RF_WRITE(mac, 0x53, 0xb3); 5228 BWN_RF_WRITE(mac, 0x54, 0x9b); 5229 BWN_RF_WRITE(mac, 0x5a, 0x88); 5230 BWN_RF_WRITE(mac, 0x5b, 0x88); 5231 BWN_RF_WRITE(mac, 0x5d, 0x88); 5232 BWN_RF_WRITE(mac, 0x5e, 0x88); 5233 BWN_RF_WRITE(mac, 0x7d, 0x88); 5234 bwn_hf_write(mac, 5235 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5236 } 5237 if (phy->rf_rev == 8) { 5238 BWN_RF_WRITE(mac, 0x51, 0); 5239 BWN_RF_WRITE(mac, 0x52, 0x40); 5240 BWN_RF_WRITE(mac, 0x53, 0xb7); 5241 BWN_RF_WRITE(mac, 0x54, 0x98); 5242 BWN_RF_WRITE(mac, 0x5a, 0x88); 5243 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5244 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5245 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5246 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5247 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5248 } else { 5249 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5250 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5251 } 5252 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5253 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5254 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5255 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5256 } 5257 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5258 BWN_PHY_WRITE(mac, offset, val); 5259 val -= 0x0202; 5260 } 5261 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5262 BWN_PHY_WRITE(mac, offset, val); 5263 val -= 0x0202; 5264 } 5265 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5266 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5267 val += 0x0202; 5268 } 5269 if (phy->type == BWN_PHYTYPE_G) { 5270 BWN_RF_SET(mac, 0x007a, 0x0020); 5271 BWN_RF_SET(mac, 0x0051, 0x0004); 5272 BWN_PHY_SET(mac, 0x0802, 0x0100); 5273 BWN_PHY_SET(mac, 0x042b, 0x2000); 5274 BWN_PHY_WRITE(mac, 0x5b, 0); 5275 BWN_PHY_WRITE(mac, 0x5c, 0); 5276 } 5277 5278 old_channel = phy->chan; 5279 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5280 5281 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5282 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5283 DELAY(40); 5284 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5285 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5286 BWN_RF_WRITE(mac, 0x50, 0x20); 5287 } 5288 if (phy->rf_rev <= 2) { 5289 BWN_RF_WRITE(mac, 0x7c, 0x20); 5290 BWN_RF_WRITE(mac, 0x5a, 0x70); 5291 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5292 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5293 } 5294 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5295 5296 bwn_phy_g_switch_chan(mac, old_channel, 0); 5297 5298 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5299 if (phy->rf_rev >= 6) 5300 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5301 else 5302 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5303 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5304 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5305 pg->pg_txctl); 5306 if (phy->rf_rev <= 5) 5307 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5308 if (phy->rf_rev <= 2) 5309 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5310 5311 if (phy->analog == 4) { 5312 BWN_WRITE_2(mac, 0x3e4, 9); 5313 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5314 } else 5315 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5316 if (phy->type == BWN_PHYTYPE_B) 5317 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5318 else if (phy->type == BWN_PHYTYPE_G) 5319 BWN_WRITE_2(mac, 0x03e6, 0x0); 5320 } 5321 5322 static void 5323 bwn_phy_init_a(struct bwn_mac *mac) 5324 { 5325 struct bwn_phy *phy = &mac->mac_phy; 5326 struct bwn_softc *sc = mac->mac_sc; 5327 5328 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5329 ("%s:%d: fail", __func__, __LINE__)); 5330 5331 if (phy->rev >= 6) { 5332 if (phy->type == BWN_PHYTYPE_A) 5333 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5334 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5335 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5336 else 5337 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5338 } 5339 5340 bwn_wa_init(mac); 5341 5342 if (phy->type == BWN_PHYTYPE_G && 5343 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5344 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5345 } 5346 5347 static void 5348 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5349 { 5350 int i; 5351 5352 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5353 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5354 } 5355 5356 static void 5357 bwn_wa_agc(struct bwn_mac *mac) 5358 { 5359 struct bwn_phy *phy = &mac->mac_phy; 5360 5361 if (phy->rev == 1) { 5362 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5363 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5364 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5365 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5366 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5367 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5368 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5369 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5370 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5371 } else { 5372 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5373 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5374 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5375 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5376 } 5377 5378 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5379 0x5700); 5380 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5381 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5382 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5383 BWN_RF_SET(mac, 0x7a, 0x0008); 5384 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5385 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5386 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5387 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5388 if (phy->rev == 1) 5389 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5390 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5391 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5392 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5393 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5394 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5395 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5396 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5397 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5398 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5399 if (phy->rev == 1) { 5400 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5401 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5402 } else { 5403 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5404 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5405 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5406 if (phy->rev >= 6) { 5407 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5408 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5409 (uint16_t)~0xf000, 0x3000); 5410 } 5411 } 5412 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5413 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5414 if (phy->rev == 1) { 5415 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5416 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5417 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5418 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5419 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5420 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5421 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5422 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5423 } else { 5424 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5425 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5426 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5427 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5428 } 5429 if (phy->rev >= 6) { 5430 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5431 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5432 } 5433 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5434 } 5435 5436 static void 5437 bwn_wa_grev1(struct bwn_mac *mac) 5438 { 5439 struct bwn_phy *phy = &mac->mac_phy; 5440 int i; 5441 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5442 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5443 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5444 5445 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5446 5447 /* init CRSTHRES and ANTDWELL */ 5448 if (phy->rev == 1) { 5449 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5450 } else if (phy->rev == 2) { 5451 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5452 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5453 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5454 } else { 5455 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5456 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5457 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5458 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5459 } 5460 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5461 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5462 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5463 5464 /* XXX support PHY-A??? */ 5465 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5467 bwn_tab_finefreqg[i]); 5468 5469 /* XXX support PHY-A??? */ 5470 if (phy->rev == 1) 5471 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5472 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5473 bwn_tab_noise_g1[i]); 5474 else 5475 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5476 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5477 bwn_tab_noise_g2[i]); 5478 5479 5480 for (i = 0; i < N(bwn_tab_rotor); i++) 5481 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5482 bwn_tab_rotor[i]); 5483 5484 /* XXX support PHY-A??? */ 5485 if (phy->rev >= 6) { 5486 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5487 BWN_PHY_ENCORE_EN) 5488 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5489 else 5490 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5491 } else 5492 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5493 5494 for (i = 0; i < N(bwn_tab_retard); i++) 5495 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5496 bwn_tab_retard[i]); 5497 5498 if (phy->rev == 1) { 5499 for (i = 0; i < 16; i++) 5500 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5501 i, 0x0020); 5502 } else { 5503 for (i = 0; i < 32; i++) 5504 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5505 } 5506 5507 bwn_wa_agc(mac); 5508 } 5509 5510 static void 5511 bwn_wa_grev26789(struct bwn_mac *mac) 5512 { 5513 struct bwn_phy *phy = &mac->mac_phy; 5514 int i; 5515 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5516 uint16_t ofdmrev; 5517 5518 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5519 5520 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5521 5522 /* init CRSTHRES and ANTDWELL */ 5523 if (phy->rev == 1) 5524 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5525 else if (phy->rev == 2) { 5526 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5527 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5528 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5529 } else { 5530 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5531 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5532 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5533 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5534 } 5535 5536 for (i = 0; i < 64; i++) 5537 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5538 5539 /* XXX support PHY-A??? */ 5540 if (phy->rev == 1) 5541 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5542 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5543 bwn_tab_noise_g1[i]); 5544 else 5545 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5546 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5547 bwn_tab_noise_g2[i]); 5548 5549 /* XXX support PHY-A??? */ 5550 if (phy->rev >= 6) { 5551 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5552 BWN_PHY_ENCORE_EN) 5553 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5554 else 5555 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5556 } else 5557 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5558 5559 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5560 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5561 bwn_tab_sigmasqr2[i]); 5562 5563 if (phy->rev == 1) { 5564 for (i = 0; i < 16; i++) 5565 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5566 0x0020); 5567 } else { 5568 for (i = 0; i < 32; i++) 5569 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5570 } 5571 5572 bwn_wa_agc(mac); 5573 5574 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5575 if (ofdmrev > 2) { 5576 if (phy->type == BWN_PHYTYPE_A) 5577 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5578 else 5579 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5580 } else { 5581 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5582 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5583 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5584 } 5585 5586 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5587 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5588 } 5589 5590 static void 5591 bwn_wa_init(struct bwn_mac *mac) 5592 { 5593 struct bwn_phy *phy = &mac->mac_phy; 5594 struct bwn_softc *sc = mac->mac_sc; 5595 5596 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5597 5598 switch (phy->rev) { 5599 case 1: 5600 bwn_wa_grev1(mac); 5601 break; 5602 case 2: 5603 case 6: 5604 case 7: 5605 case 8: 5606 case 9: 5607 bwn_wa_grev26789(mac); 5608 break; 5609 default: 5610 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5611 } 5612 5613 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5614 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5615 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5616 if (phy->rev < 2) { 5617 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5618 0x0002); 5619 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5620 0x0001); 5621 } else { 5622 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5623 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5624 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5625 BWN_BFL_EXTLNA) && 5626 (phy->rev >= 7)) { 5627 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5628 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5629 0x0020, 0x0001); 5630 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5631 0x0021, 0x0001); 5632 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5633 0x0022, 0x0001); 5634 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5635 0x0023, 0x0000); 5636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5637 0x0000, 0x0000); 5638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5639 0x0003, 0x0002); 5640 } 5641 } 5642 } 5643 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5644 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5645 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5646 } 5647 5648 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5649 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5650 } 5651 5652 static void 5653 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5654 uint16_t value) 5655 { 5656 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5657 uint16_t addr; 5658 5659 addr = table + offset; 5660 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5661 (addr - 1 != pg->pg_ofdmtab_addr)) { 5662 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5663 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5664 } 5665 pg->pg_ofdmtab_addr = addr; 5666 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5667 } 5668 5669 static void 5670 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5671 uint32_t value) 5672 { 5673 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5674 uint16_t addr; 5675 5676 addr = table + offset; 5677 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5678 (addr - 1 != pg->pg_ofdmtab_addr)) { 5679 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5680 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5681 } 5682 pg->pg_ofdmtab_addr = addr; 5683 5684 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5685 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5686 } 5687 5688 static void 5689 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5690 uint16_t value) 5691 { 5692 5693 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5694 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5695 } 5696 5697 static void 5698 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5699 { 5700 struct bwn_phy *phy = &mac->mac_phy; 5701 struct bwn_softc *sc = mac->mac_sc; 5702 unsigned int i, max_loop; 5703 uint16_t value; 5704 uint32_t buffer[5] = { 5705 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5706 }; 5707 5708 if (ofdm) { 5709 max_loop = 0x1e; 5710 buffer[0] = 0x000201cc; 5711 } else { 5712 max_loop = 0xfa; 5713 buffer[0] = 0x000b846e; 5714 } 5715 5716 for (i = 0; i < 5; i++) 5717 bwn_ram_write(mac, i * 4, buffer[i]); 5718 5719 BWN_WRITE_2(mac, 0x0568, 0x0000); 5720 BWN_WRITE_2(mac, 0x07c0, 5721 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5722 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5723 BWN_WRITE_2(mac, 0x050c, value); 5724 if (phy->type == BWN_PHYTYPE_LP) 5725 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5726 BWN_WRITE_2(mac, 0x0508, 0x0000); 5727 BWN_WRITE_2(mac, 0x050a, 0x0000); 5728 BWN_WRITE_2(mac, 0x054c, 0x0000); 5729 BWN_WRITE_2(mac, 0x056a, 0x0014); 5730 BWN_WRITE_2(mac, 0x0568, 0x0826); 5731 BWN_WRITE_2(mac, 0x0500, 0x0000); 5732 if (phy->type == BWN_PHYTYPE_LP) 5733 BWN_WRITE_2(mac, 0x0502, 0x0050); 5734 else 5735 BWN_WRITE_2(mac, 0x0502, 0x0030); 5736 5737 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5738 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5739 for (i = 0x00; i < max_loop; i++) { 5740 value = BWN_READ_2(mac, 0x050e); 5741 if (value & 0x0080) 5742 break; 5743 DELAY(10); 5744 } 5745 for (i = 0x00; i < 0x0a; i++) { 5746 value = BWN_READ_2(mac, 0x050e); 5747 if (value & 0x0400) 5748 break; 5749 DELAY(10); 5750 } 5751 for (i = 0x00; i < 0x19; i++) { 5752 value = BWN_READ_2(mac, 0x0690); 5753 if (!(value & 0x0100)) 5754 break; 5755 DELAY(10); 5756 } 5757 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5758 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5759 } 5760 5761 static void 5762 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5763 { 5764 uint32_t macctl; 5765 5766 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5767 5768 macctl = BWN_READ_4(mac, BWN_MACCTL); 5769 if (macctl & BWN_MACCTL_BIGENDIAN) 5770 kprintf("TODO: need swap\n"); 5771 5772 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5773 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5774 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5775 } 5776 5777 static void 5778 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5779 { 5780 uint16_t value; 5781 5782 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5783 ("%s:%d: fail", __func__, __LINE__)); 5784 5785 value = (uint8_t) (ctl->q); 5786 value |= ((uint8_t) (ctl->i)) << 8; 5787 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5788 } 5789 5790 static uint16_t 5791 bwn_lo_calcfeed(struct bwn_mac *mac, 5792 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5793 { 5794 struct bwn_phy *phy = &mac->mac_phy; 5795 struct bwn_softc *sc = mac->mac_sc; 5796 uint16_t rfover; 5797 uint16_t feedthrough; 5798 5799 if (phy->gmode) { 5800 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5801 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5802 5803 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5804 ("%s:%d: fail", __func__, __LINE__)); 5805 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5806 ("%s:%d: fail", __func__, __LINE__)); 5807 5808 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5809 5810 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5811 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5812 phy->rev > 6) 5813 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5814 5815 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5816 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5817 DELAY(10); 5818 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5819 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5820 DELAY(10); 5821 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5822 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5823 DELAY(10); 5824 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5825 } else { 5826 pga |= BWN_PHY_PGACTL_UNKNOWN; 5827 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5828 DELAY(10); 5829 pga |= BWN_PHY_PGACTL_LOWBANDW; 5830 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5831 DELAY(10); 5832 pga |= BWN_PHY_PGACTL_LPF; 5833 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5834 } 5835 DELAY(21); 5836 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5837 5838 return (feedthrough); 5839 } 5840 5841 static uint16_t 5842 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5843 uint16_t *value, uint16_t *pad_mix_gain) 5844 { 5845 struct bwn_phy *phy = &mac->mac_phy; 5846 uint16_t reg, v, padmix; 5847 5848 if (phy->type == BWN_PHYTYPE_B) { 5849 v = 0x30; 5850 if (phy->rf_rev <= 5) { 5851 reg = 0x43; 5852 padmix = 0; 5853 } else { 5854 reg = 0x52; 5855 padmix = 5; 5856 } 5857 } else { 5858 if (phy->rev >= 2 && phy->rf_rev == 8) { 5859 reg = 0x43; 5860 v = 0x10; 5861 padmix = 2; 5862 } else { 5863 reg = 0x52; 5864 v = 0x30; 5865 padmix = 5; 5866 } 5867 } 5868 if (value) 5869 *value = v; 5870 if (pad_mix_gain) 5871 *pad_mix_gain = padmix; 5872 5873 return (reg); 5874 } 5875 5876 static void 5877 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5878 { 5879 struct bwn_phy *phy = &mac->mac_phy; 5880 struct bwn_phy_g *pg = &phy->phy_g; 5881 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5882 uint16_t reg, mask; 5883 uint16_t trsw_rx, pga; 5884 uint16_t rf_pctl_reg; 5885 5886 static const uint8_t tx_bias_values[] = { 5887 0x09, 0x08, 0x0a, 0x01, 0x00, 5888 0x02, 0x05, 0x04, 0x06, 5889 }; 5890 static const uint8_t tx_magn_values[] = { 5891 0x70, 0x40, 5892 }; 5893 5894 if (!BWN_HAS_LOOPBACK(phy)) { 5895 rf_pctl_reg = 6; 5896 trsw_rx = 2; 5897 pga = 0; 5898 } else { 5899 int lb_gain; 5900 5901 trsw_rx = 0; 5902 lb_gain = pg->pg_max_lb_gain / 2; 5903 if (lb_gain > 10) { 5904 rf_pctl_reg = 0; 5905 pga = abs(10 - lb_gain) / 6; 5906 pga = MIN(MAX(pga, 0), 15); 5907 } else { 5908 int cmp_val; 5909 int tmp; 5910 5911 pga = 0; 5912 cmp_val = 0x24; 5913 if ((phy->rev >= 2) && 5914 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 5915 cmp_val = 0x3c; 5916 tmp = lb_gain; 5917 if ((10 - lb_gain) < cmp_val) 5918 tmp = (10 - lb_gain); 5919 if (tmp < 0) 5920 tmp += 6; 5921 else 5922 tmp += 3; 5923 cmp_val /= 4; 5924 tmp /= 4; 5925 if (tmp >= cmp_val) 5926 rf_pctl_reg = cmp_val; 5927 else 5928 rf_pctl_reg = tmp; 5929 } 5930 } 5931 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 5932 bwn_phy_g_set_bbatt(mac, 2); 5933 5934 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 5935 mask = ~mask; 5936 BWN_RF_MASK(mac, reg, mask); 5937 5938 if (BWN_HAS_TXMAG(phy)) { 5939 int i, j; 5940 int feedthrough; 5941 int min_feedth = 0xffff; 5942 uint8_t tx_magn, tx_bias; 5943 5944 for (i = 0; i < N(tx_magn_values); i++) { 5945 tx_magn = tx_magn_values[i]; 5946 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 5947 for (j = 0; j < N(tx_bias_values); j++) { 5948 tx_bias = tx_bias_values[j]; 5949 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 5950 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 5951 trsw_rx); 5952 if (feedthrough < min_feedth) { 5953 lo->tx_bias = tx_bias; 5954 lo->tx_magn = tx_magn; 5955 min_feedth = feedthrough; 5956 } 5957 if (lo->tx_bias == 0) 5958 break; 5959 } 5960 BWN_RF_WRITE(mac, 0x52, 5961 (BWN_RF_READ(mac, 0x52) 5962 & 0xff00) | lo->tx_bias | lo-> 5963 tx_magn); 5964 } 5965 } else { 5966 lo->tx_magn = 0; 5967 lo->tx_bias = 0; 5968 BWN_RF_MASK(mac, 0x52, 0xfff0); 5969 } 5970 5971 BWN_GETTIME(lo->txctl_measured_time); 5972 } 5973 5974 static void 5975 bwn_lo_get_powervector(struct bwn_mac *mac) 5976 { 5977 struct bwn_phy *phy = &mac->mac_phy; 5978 struct bwn_phy_g *pg = &phy->phy_g; 5979 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5980 int i; 5981 uint64_t tmp; 5982 uint64_t power_vector = 0; 5983 5984 for (i = 0; i < 8; i += 2) { 5985 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 5986 power_vector |= (tmp << (i * 8)); 5987 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 5988 } 5989 if (power_vector) 5990 lo->power_vector = power_vector; 5991 5992 BWN_GETTIME(lo->pwr_vec_read_time); 5993 } 5994 5995 static void 5996 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 5997 int use_trsw_rx) 5998 { 5999 struct bwn_phy *phy = &mac->mac_phy; 6000 struct bwn_phy_g *pg = &phy->phy_g; 6001 uint16_t tmp; 6002 6003 if (max_rx_gain < 0) 6004 max_rx_gain = 0; 6005 6006 if (BWN_HAS_LOOPBACK(phy)) { 6007 int trsw_rx = 0; 6008 int trsw_rx_gain; 6009 6010 if (use_trsw_rx) { 6011 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6012 if (max_rx_gain >= trsw_rx_gain) { 6013 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6014 trsw_rx = 0x20; 6015 } 6016 } else 6017 trsw_rx_gain = max_rx_gain; 6018 if (trsw_rx_gain < 9) { 6019 pg->pg_lna_lod_gain = 0; 6020 } else { 6021 pg->pg_lna_lod_gain = 1; 6022 trsw_rx_gain -= 8; 6023 } 6024 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6025 pg->pg_pga_gain = trsw_rx_gain / 3; 6026 if (pg->pg_pga_gain >= 5) { 6027 pg->pg_pga_gain -= 5; 6028 pg->pg_lna_gain = 2; 6029 } else 6030 pg->pg_lna_gain = 0; 6031 } else { 6032 pg->pg_lna_gain = 0; 6033 pg->pg_trsw_rx_gain = 0x20; 6034 if (max_rx_gain >= 0x14) { 6035 pg->pg_lna_lod_gain = 1; 6036 pg->pg_pga_gain = 2; 6037 } else if (max_rx_gain >= 0x12) { 6038 pg->pg_lna_lod_gain = 1; 6039 pg->pg_pga_gain = 1; 6040 } else if (max_rx_gain >= 0xf) { 6041 pg->pg_lna_lod_gain = 1; 6042 pg->pg_pga_gain = 0; 6043 } else { 6044 pg->pg_lna_lod_gain = 0; 6045 pg->pg_pga_gain = 0; 6046 } 6047 } 6048 6049 tmp = BWN_RF_READ(mac, 0x7a); 6050 if (pg->pg_lna_lod_gain == 0) 6051 tmp &= ~0x0008; 6052 else 6053 tmp |= 0x0008; 6054 BWN_RF_WRITE(mac, 0x7a, tmp); 6055 } 6056 6057 static void 6058 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6059 { 6060 struct bwn_phy *phy = &mac->mac_phy; 6061 struct bwn_phy_g *pg = &phy->phy_g; 6062 struct bwn_softc *sc = mac->mac_sc; 6063 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6064 struct timespec ts; 6065 uint16_t tmp; 6066 6067 if (bwn_has_hwpctl(mac)) { 6068 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6069 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6070 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6071 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6072 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6073 6074 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6075 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6076 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6077 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6078 } 6079 if (phy->type == BWN_PHYTYPE_B && 6080 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6081 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6082 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6083 } 6084 if (phy->rev >= 2) { 6085 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6086 sav->phy_analogoverval = 6087 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6088 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6089 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6090 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6091 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6092 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6093 6094 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6095 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6096 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6097 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6098 if (phy->type == BWN_PHYTYPE_G) { 6099 if ((phy->rev >= 7) && 6100 (siba_sprom_get_bf_lo(sc->sc_dev) & 6101 BWN_BFL_EXTLNA)) { 6102 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6103 } else { 6104 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6105 } 6106 } else { 6107 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6108 } 6109 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6110 } 6111 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6112 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6113 sav->rf0 = BWN_RF_READ(mac, 0x43); 6114 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6115 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6116 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6117 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6118 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6119 6120 if (!BWN_HAS_TXMAG(phy)) { 6121 sav->rf2 = BWN_RF_READ(mac, 0x52); 6122 sav->rf2 &= 0x00f0; 6123 } 6124 if (phy->type == BWN_PHYTYPE_B) { 6125 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6126 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6127 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6128 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6129 } else { 6130 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6131 | 0x8000); 6132 } 6133 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6134 & 0xf000); 6135 6136 tmp = 6137 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6138 BWN_PHY_WRITE(mac, tmp, 0x007f); 6139 6140 tmp = sav->phy_syncctl; 6141 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6142 tmp = sav->rf1; 6143 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6144 6145 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6146 if (phy->type == BWN_PHYTYPE_G || 6147 (phy->type == BWN_PHYTYPE_B && 6148 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6149 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6150 } else 6151 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6152 if (phy->rev >= 2) 6153 bwn_dummy_transmission(mac, 0, 1); 6154 bwn_phy_g_switch_chan(mac, 6, 0); 6155 BWN_RF_READ(mac, 0x51); 6156 if (phy->type == BWN_PHYTYPE_G) 6157 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6158 6159 nanouptime(&ts); 6160 if (time_before(lo->txctl_measured_time, 6161 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6162 bwn_lo_measure_txctl_values(mac); 6163 6164 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6165 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6166 else { 6167 if (phy->type == BWN_PHYTYPE_B) 6168 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6169 else 6170 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6171 } 6172 } 6173 6174 static void 6175 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6176 { 6177 struct bwn_phy *phy = &mac->mac_phy; 6178 struct bwn_phy_g *pg = &phy->phy_g; 6179 uint16_t tmp; 6180 6181 if (phy->rev >= 2) { 6182 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6183 tmp = (pg->pg_pga_gain << 8); 6184 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6185 DELAY(5); 6186 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6187 DELAY(2); 6188 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6189 } else { 6190 tmp = (pg->pg_pga_gain | 0xefa0); 6191 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6192 } 6193 if (phy->type == BWN_PHYTYPE_G) { 6194 if (phy->rev >= 3) 6195 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6196 else 6197 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6198 if (phy->rev >= 2) 6199 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6200 else 6201 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6202 } 6203 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6204 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6205 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6206 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6207 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6208 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6209 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6210 if (!BWN_HAS_TXMAG(phy)) { 6211 tmp = sav->rf2; 6212 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6213 } 6214 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6215 if (phy->type == BWN_PHYTYPE_B && 6216 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6217 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6218 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6219 } 6220 if (phy->rev >= 2) { 6221 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6222 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6223 sav->phy_analogoverval); 6224 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6225 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6226 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6227 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6228 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6229 } 6230 if (bwn_has_hwpctl(mac)) { 6231 tmp = (sav->phy_lomask & 0xbfff); 6232 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6233 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6234 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6235 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6236 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6237 } 6238 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6239 } 6240 6241 static int 6242 bwn_lo_probe_loctl(struct bwn_mac *mac, 6243 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6244 { 6245 struct bwn_phy *phy = &mac->mac_phy; 6246 struct bwn_phy_g *pg = &phy->phy_g; 6247 struct bwn_loctl orig, test; 6248 struct bwn_loctl prev = { -100, -100 }; 6249 static const struct bwn_loctl modifiers[] = { 6250 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6251 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6252 }; 6253 int begin, end, lower = 0, i; 6254 uint16_t feedth; 6255 6256 if (d->curstate == 0) { 6257 begin = 1; 6258 end = 8; 6259 } else if (d->curstate % 2 == 0) { 6260 begin = d->curstate - 1; 6261 end = d->curstate + 1; 6262 } else { 6263 begin = d->curstate - 2; 6264 end = d->curstate + 2; 6265 } 6266 if (begin < 1) 6267 begin += 8; 6268 if (end > 8) 6269 end -= 8; 6270 6271 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6272 i = begin; 6273 d->curstate = i; 6274 while (1) { 6275 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6276 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6277 test.i += modifiers[i - 1].i * d->multipler; 6278 test.q += modifiers[i - 1].q * d->multipler; 6279 if ((test.i != prev.i || test.q != prev.q) && 6280 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6281 bwn_lo_write(mac, &test); 6282 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6283 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6284 if (feedth < d->feedth) { 6285 memcpy(probe, &test, 6286 sizeof(struct bwn_loctl)); 6287 lower = 1; 6288 d->feedth = feedth; 6289 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6290 break; 6291 } 6292 } 6293 memcpy(&prev, &test, sizeof(prev)); 6294 if (i == end) 6295 break; 6296 if (i == 8) 6297 i = 1; 6298 else 6299 i++; 6300 d->curstate = i; 6301 } 6302 6303 return (lower); 6304 } 6305 6306 static void 6307 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6308 { 6309 struct bwn_phy *phy = &mac->mac_phy; 6310 struct bwn_phy_g *pg = &phy->phy_g; 6311 struct bwn_lo_g_sm d; 6312 struct bwn_loctl probe; 6313 int lower, repeat, cnt = 0; 6314 uint16_t feedth; 6315 6316 d.nmeasure = 0; 6317 d.multipler = 1; 6318 if (BWN_HAS_LOOPBACK(phy)) 6319 d.multipler = 3; 6320 6321 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6322 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6323 6324 do { 6325 bwn_lo_write(mac, &d.loctl); 6326 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6327 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6328 if (feedth < 0x258) { 6329 if (feedth >= 0x12c) 6330 *rxgain += 6; 6331 else 6332 *rxgain += 3; 6333 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6334 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6335 } 6336 d.feedth = feedth; 6337 d.curstate = 0; 6338 do { 6339 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6340 ("%s:%d: fail", __func__, __LINE__)); 6341 memcpy(&probe, &d.loctl, 6342 sizeof(struct bwn_loctl)); 6343 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6344 if (!lower) 6345 break; 6346 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6347 break; 6348 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6349 d.nmeasure++; 6350 } while (d.nmeasure < 24); 6351 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6352 6353 if (BWN_HAS_LOOPBACK(phy)) { 6354 if (d.feedth > 0x1194) 6355 *rxgain -= 6; 6356 else if (d.feedth < 0x5dc) 6357 *rxgain += 3; 6358 if (cnt == 0) { 6359 if (d.feedth <= 0x5dc) { 6360 d.multipler = 1; 6361 cnt++; 6362 } else 6363 d.multipler = 2; 6364 } else if (cnt == 2) 6365 d.multipler = 1; 6366 } 6367 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6368 } while (++cnt < repeat); 6369 } 6370 6371 static struct bwn_lo_calib * 6372 bwn_lo_calibset(struct bwn_mac *mac, 6373 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6374 { 6375 struct bwn_phy *phy = &mac->mac_phy; 6376 struct bwn_phy_g *pg = &phy->phy_g; 6377 struct bwn_loctl loctl = { 0, 0 }; 6378 struct bwn_lo_calib *cal; 6379 struct bwn_lo_g_value sval = { 0 }; 6380 int rxgain; 6381 uint16_t pad, reg, value; 6382 6383 sval.old_channel = phy->chan; 6384 bwn_mac_suspend(mac); 6385 bwn_lo_save(mac, &sval); 6386 6387 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6388 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6389 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6390 6391 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6392 if (rfatt->padmix) 6393 rxgain -= pad; 6394 if (BWN_HAS_LOOPBACK(phy)) 6395 rxgain += pg->pg_max_lb_gain; 6396 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6397 bwn_phy_g_set_bbatt(mac, bbatt->att); 6398 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6399 6400 bwn_lo_restore(mac, &sval); 6401 bwn_mac_enable(mac); 6402 6403 cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO); 6404 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6405 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6406 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6407 6408 BWN_GETTIME(cal->calib_time); 6409 6410 return (cal); 6411 } 6412 6413 static struct bwn_lo_calib * 6414 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6415 const struct bwn_rfatt *rfatt) 6416 { 6417 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6418 struct bwn_lo_calib *c; 6419 6420 TAILQ_FOREACH(c, &lo->calib_list, list) { 6421 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6422 continue; 6423 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6424 continue; 6425 return (c); 6426 } 6427 6428 c = bwn_lo_calibset(mac, bbatt, rfatt); 6429 if (c == NULL) /* XXX ivadasz: can't happen */ 6430 return (NULL); 6431 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6432 6433 return (c); 6434 } 6435 6436 static void 6437 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6438 { 6439 struct bwn_phy *phy = &mac->mac_phy; 6440 struct bwn_phy_g *pg = &phy->phy_g; 6441 struct bwn_softc *sc = mac->mac_sc; 6442 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6443 const struct bwn_rfatt *rfatt; 6444 const struct bwn_bbatt *bbatt; 6445 uint64_t pvector; 6446 int i; 6447 int rf_offset, bb_offset; 6448 uint8_t changed = 0; 6449 6450 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6451 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6452 ("%s:%d: fail", __func__, __LINE__)); 6453 6454 pvector = lo->power_vector; 6455 if (!update && !pvector) 6456 return; 6457 6458 bwn_mac_suspend(mac); 6459 6460 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6461 struct bwn_lo_calib *cal; 6462 int idx; 6463 uint16_t val; 6464 6465 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6466 continue; 6467 bb_offset = i / lo->rfatt.len; 6468 rf_offset = i % lo->rfatt.len; 6469 bbatt = &(lo->bbatt.array[bb_offset]); 6470 rfatt = &(lo->rfatt.array[rf_offset]); 6471 6472 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6473 if (cal == NULL) { /* XXX ivadasz: can't happen */ 6474 device_printf(sc->sc_dev, "LO: Could not " 6475 "calibrate DC table entry\n"); 6476 continue; 6477 } 6478 val = (uint8_t)(cal->ctl.q); 6479 val |= ((uint8_t)(cal->ctl.i)) << 4; 6480 kfree(cal, M_DEVBUF); 6481 6482 idx = i / 2; 6483 if (i % 2) 6484 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6485 | ((val & 0x00ff) << 8); 6486 else 6487 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6488 | (val & 0x00ff); 6489 changed = 1; 6490 } 6491 if (changed) { 6492 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6493 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6494 } 6495 bwn_mac_enable(mac); 6496 } 6497 6498 static void 6499 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6500 { 6501 6502 if (!rf->padmix) 6503 return; 6504 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6505 rf->att = 4; 6506 } 6507 6508 static void 6509 bwn_lo_g_adjust(struct bwn_mac *mac) 6510 { 6511 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6512 struct bwn_lo_calib *cal; 6513 struct bwn_rfatt rf; 6514 6515 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6516 bwn_lo_fixup_rfatt(&rf); 6517 6518 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6519 if (cal == NULL) /* XXX ivadasz: can't happen */ 6520 return; 6521 bwn_lo_write(mac, &cal->ctl); 6522 } 6523 6524 static void 6525 bwn_lo_g_init(struct bwn_mac *mac) 6526 { 6527 6528 if (!bwn_has_hwpctl(mac)) 6529 return; 6530 6531 bwn_lo_get_powervector(mac); 6532 bwn_phy_g_dc_lookup_init(mac, 1); 6533 } 6534 6535 static void 6536 bwn_mac_suspend(struct bwn_mac *mac) 6537 { 6538 struct bwn_softc *sc = mac->mac_sc; 6539 int i; 6540 uint32_t tmp; 6541 6542 KASSERT(mac->mac_suspended >= 0, 6543 ("%s:%d: fail", __func__, __LINE__)); 6544 6545 if (mac->mac_suspended == 0) { 6546 bwn_psctl(mac, BWN_PS_AWAKE); 6547 BWN_WRITE_4(mac, BWN_MACCTL, 6548 BWN_READ_4(mac, BWN_MACCTL) 6549 & ~BWN_MACCTL_ON); 6550 BWN_READ_4(mac, BWN_MACCTL); 6551 for (i = 35; i; i--) { 6552 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6553 if (tmp & BWN_INTR_MAC_SUSPENDED) 6554 goto out; 6555 DELAY(10); 6556 } 6557 for (i = 40; i; i--) { 6558 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6559 if (tmp & BWN_INTR_MAC_SUSPENDED) 6560 goto out; 6561 DELAY(1000); 6562 } 6563 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6564 } 6565 out: 6566 mac->mac_suspended++; 6567 } 6568 6569 static void 6570 bwn_mac_enable(struct bwn_mac *mac) 6571 { 6572 struct bwn_softc *sc = mac->mac_sc; 6573 uint16_t state; 6574 6575 state = bwn_shm_read_2(mac, BWN_SHARED, 6576 BWN_SHARED_UCODESTAT); 6577 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6578 state != BWN_SHARED_UCODESTAT_SLEEP) 6579 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6580 6581 mac->mac_suspended--; 6582 KASSERT(mac->mac_suspended >= 0, 6583 ("%s:%d: fail", __func__, __LINE__)); 6584 if (mac->mac_suspended == 0) { 6585 BWN_WRITE_4(mac, BWN_MACCTL, 6586 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6587 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6588 BWN_READ_4(mac, BWN_MACCTL); 6589 BWN_READ_4(mac, BWN_INTR_REASON); 6590 bwn_psctl(mac, 0); 6591 } 6592 } 6593 6594 static void 6595 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6596 { 6597 struct bwn_softc *sc = mac->mac_sc; 6598 int i; 6599 uint16_t ucstat; 6600 6601 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6602 ("%s:%d: fail", __func__, __LINE__)); 6603 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6604 ("%s:%d: fail", __func__, __LINE__)); 6605 6606 /* XXX forcibly awake and hwps-off */ 6607 6608 BWN_WRITE_4(mac, BWN_MACCTL, 6609 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6610 ~BWN_MACCTL_HWPS); 6611 BWN_READ_4(mac, BWN_MACCTL); 6612 if (siba_get_revid(sc->sc_dev) >= 5) { 6613 for (i = 0; i < 100; i++) { 6614 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6615 BWN_SHARED_UCODESTAT); 6616 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6617 break; 6618 DELAY(10); 6619 } 6620 } 6621 } 6622 6623 static int16_t 6624 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6625 { 6626 6627 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6628 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6629 } 6630 6631 static void 6632 bwn_nrssi_threshold(struct bwn_mac *mac) 6633 { 6634 struct bwn_phy *phy = &mac->mac_phy; 6635 struct bwn_phy_g *pg = &phy->phy_g; 6636 struct bwn_softc *sc = mac->mac_sc; 6637 int32_t a, b; 6638 int16_t tmp16; 6639 uint16_t tmpu16; 6640 6641 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6642 6643 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6644 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6645 a = 0x13; 6646 b = 0x12; 6647 } else { 6648 a = 0xe; 6649 b = 0x11; 6650 } 6651 6652 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6653 a += (pg->pg_nrssi[0] << 6); 6654 a += (a < 32) ? 31 : 32; 6655 a = a >> 6; 6656 a = MIN(MAX(a, -31), 31); 6657 6658 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6659 b += (pg->pg_nrssi[0] << 6); 6660 if (b < 32) 6661 b += 31; 6662 else 6663 b += 32; 6664 b = b >> 6; 6665 b = MIN(MAX(b, -31), 31); 6666 6667 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6668 tmpu16 |= ((uint32_t)b & 0x0000003f); 6669 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6670 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6671 return; 6672 } 6673 6674 tmp16 = bwn_nrssi_read(mac, 0x20); 6675 if (tmp16 >= 0x20) 6676 tmp16 -= 0x40; 6677 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6678 } 6679 6680 static void 6681 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6682 { 6683 #define SAVE_RF_MAX 3 6684 #define SAVE_PHY_COMM_MAX 4 6685 #define SAVE_PHY3_MAX 8 6686 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6687 { 0x7a, 0x52, 0x43 }; 6688 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6689 { 0x15, 0x5a, 0x59, 0x58 }; 6690 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6691 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6692 0x0801, 0x0060, 0x0014, 0x0478 6693 }; 6694 struct bwn_phy *phy = &mac->mac_phy; 6695 struct bwn_phy_g *pg = &phy->phy_g; 6696 int32_t i, tmp32, phy3_idx = 0; 6697 uint16_t delta, tmp; 6698 uint16_t save_rf[SAVE_RF_MAX]; 6699 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6700 uint16_t save_phy3[SAVE_PHY3_MAX]; 6701 uint16_t ant_div, phy0, chan_ex; 6702 int16_t nrssi0, nrssi1; 6703 6704 KASSERT(phy->type == BWN_PHYTYPE_G, 6705 ("%s:%d: fail", __func__, __LINE__)); 6706 6707 if (phy->rf_rev >= 9) 6708 return; 6709 if (phy->rf_rev == 8) 6710 bwn_nrssi_offset(mac); 6711 6712 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6713 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6714 6715 /* 6716 * Save RF/PHY registers for later restoration 6717 */ 6718 ant_div = BWN_READ_2(mac, 0x03e2); 6719 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6720 for (i = 0; i < SAVE_RF_MAX; ++i) 6721 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6722 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6723 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6724 6725 phy0 = BWN_READ_2(mac, BWN_PHY0); 6726 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6727 if (phy->rev >= 3) { 6728 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6729 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6730 BWN_PHY_WRITE(mac, 0x002e, 0); 6731 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6732 switch (phy->rev) { 6733 case 4: 6734 case 6: 6735 case 7: 6736 BWN_PHY_SET(mac, 0x0478, 0x0100); 6737 BWN_PHY_SET(mac, 0x0801, 0x0040); 6738 break; 6739 case 3: 6740 case 5: 6741 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6742 break; 6743 } 6744 BWN_PHY_SET(mac, 0x0060, 0x0040); 6745 BWN_PHY_SET(mac, 0x0014, 0x0200); 6746 } 6747 /* 6748 * Calculate nrssi0 6749 */ 6750 BWN_RF_SET(mac, 0x007a, 0x0070); 6751 bwn_set_all_gains(mac, 0, 8, 0); 6752 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6753 if (phy->rev >= 2) { 6754 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6755 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6756 } 6757 BWN_RF_SET(mac, 0x007a, 0x0080); 6758 DELAY(20); 6759 6760 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6761 if (nrssi0 >= 0x0020) 6762 nrssi0 -= 0x0040; 6763 6764 /* 6765 * Calculate nrssi1 6766 */ 6767 BWN_RF_MASK(mac, 0x007a, 0x007f); 6768 if (phy->rev >= 2) 6769 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6770 6771 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6772 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6773 BWN_RF_SET(mac, 0x007a, 0x000f); 6774 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6775 if (phy->rev >= 2) { 6776 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6777 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6778 } 6779 6780 bwn_set_all_gains(mac, 3, 0, 1); 6781 if (phy->rf_rev == 8) { 6782 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6783 } else { 6784 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6785 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6786 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6787 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6788 } 6789 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6790 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6791 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6792 DELAY(20); 6793 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6794 6795 /* 6796 * Install calculated narrow RSSI values 6797 */ 6798 if (nrssi1 >= 0x0020) 6799 nrssi1 -= 0x0040; 6800 if (nrssi0 == nrssi1) 6801 pg->pg_nrssi_slope = 0x00010000; 6802 else 6803 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6804 if (nrssi0 >= -4) { 6805 pg->pg_nrssi[0] = nrssi1; 6806 pg->pg_nrssi[1] = nrssi0; 6807 } 6808 6809 /* 6810 * Restore saved RF/PHY registers 6811 */ 6812 if (phy->rev >= 3) { 6813 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6814 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6815 save_phy3[phy3_idx]); 6816 } 6817 } 6818 if (phy->rev >= 2) { 6819 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6820 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6821 } 6822 6823 for (i = 0; i < SAVE_RF_MAX; ++i) 6824 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6825 6826 BWN_WRITE_2(mac, 0x03e2, ant_div); 6827 BWN_WRITE_2(mac, 0x03e6, phy0); 6828 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6829 6830 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6831 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6832 6833 bwn_spu_workaround(mac, phy->chan); 6834 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6835 bwn_set_original_gains(mac); 6836 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6837 if (phy->rev >= 3) { 6838 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6839 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6840 save_phy3[phy3_idx]); 6841 } 6842 } 6843 6844 delta = 0x1f - pg->pg_nrssi[0]; 6845 for (i = 0; i < 64; i++) { 6846 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6847 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6848 pg->pg_nrssi_lt[i] = tmp32; 6849 } 6850 6851 bwn_nrssi_threshold(mac); 6852 #undef SAVE_RF_MAX 6853 #undef SAVE_PHY_COMM_MAX 6854 #undef SAVE_PHY3_MAX 6855 } 6856 6857 static void 6858 bwn_nrssi_offset(struct bwn_mac *mac) 6859 { 6860 #define SAVE_RF_MAX 2 6861 #define SAVE_PHY_COMM_MAX 10 6862 #define SAVE_PHY6_MAX 8 6863 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6864 { 0x7a, 0x43 }; 6865 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6866 0x0001, 0x0811, 0x0812, 0x0814, 6867 0x0815, 0x005a, 0x0059, 0x0058, 6868 0x000a, 0x0003 6869 }; 6870 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6871 0x002e, 0x002f, 0x080f, 0x0810, 6872 0x0801, 0x0060, 0x0014, 0x0478 6873 }; 6874 struct bwn_phy *phy = &mac->mac_phy; 6875 int i, phy6_idx = 0; 6876 uint16_t save_rf[SAVE_RF_MAX]; 6877 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6878 uint16_t save_phy6[SAVE_PHY6_MAX]; 6879 int16_t nrssi; 6880 uint16_t saved = 0xffff; 6881 6882 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6883 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6884 for (i = 0; i < SAVE_RF_MAX; ++i) 6885 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6886 6887 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6888 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6889 BWN_PHY_SET(mac, 0x0811, 0x000c); 6890 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6891 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6892 if (phy->rev >= 6) { 6893 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6894 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6895 6896 BWN_PHY_WRITE(mac, 0x002e, 0); 6897 BWN_PHY_WRITE(mac, 0x002f, 0); 6898 BWN_PHY_WRITE(mac, 0x080f, 0); 6899 BWN_PHY_WRITE(mac, 0x0810, 0); 6900 BWN_PHY_SET(mac, 0x0478, 0x0100); 6901 BWN_PHY_SET(mac, 0x0801, 0x0040); 6902 BWN_PHY_SET(mac, 0x0060, 0x0040); 6903 BWN_PHY_SET(mac, 0x0014, 0x0200); 6904 } 6905 BWN_RF_SET(mac, 0x007a, 0x0070); 6906 BWN_RF_SET(mac, 0x007a, 0x0080); 6907 DELAY(30); 6908 6909 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6910 if (nrssi >= 0x20) 6911 nrssi -= 0x40; 6912 if (nrssi == 31) { 6913 for (i = 7; i >= 4; i--) { 6914 BWN_RF_WRITE(mac, 0x007b, i); 6915 DELAY(20); 6916 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 6917 0x003f); 6918 if (nrssi >= 0x20) 6919 nrssi -= 0x40; 6920 if (nrssi < 31 && saved == 0xffff) 6921 saved = i; 6922 } 6923 if (saved == 0xffff) 6924 saved = 4; 6925 } else { 6926 BWN_RF_MASK(mac, 0x007a, 0x007f); 6927 if (phy->rev != 1) { 6928 BWN_PHY_SET(mac, 0x0814, 0x0001); 6929 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 6930 } 6931 BWN_PHY_SET(mac, 0x0811, 0x000c); 6932 BWN_PHY_SET(mac, 0x0812, 0x000c); 6933 BWN_PHY_SET(mac, 0x0811, 0x0030); 6934 BWN_PHY_SET(mac, 0x0812, 0x0030); 6935 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6936 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6937 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6938 if (phy->rev == 0) 6939 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 6940 else 6941 BWN_PHY_SET(mac, 0x000a, 0x2000); 6942 if (phy->rev != 1) { 6943 BWN_PHY_SET(mac, 0x0814, 0x0004); 6944 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 6945 } 6946 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6947 BWN_RF_SET(mac, 0x007a, 0x000f); 6948 bwn_set_all_gains(mac, 3, 0, 1); 6949 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 6950 DELAY(30); 6951 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6952 if (nrssi >= 0x20) 6953 nrssi -= 0x40; 6954 if (nrssi == -32) { 6955 for (i = 0; i < 4; i++) { 6956 BWN_RF_WRITE(mac, 0x007b, i); 6957 DELAY(20); 6958 nrssi = (int16_t)((BWN_PHY_READ(mac, 6959 0x047f) >> 8) & 0x003f); 6960 if (nrssi >= 0x20) 6961 nrssi -= 0x40; 6962 if (nrssi > -31 && saved == 0xffff) 6963 saved = i; 6964 } 6965 if (saved == 0xffff) 6966 saved = 3; 6967 } else 6968 saved = 0; 6969 } 6970 BWN_RF_WRITE(mac, 0x007b, saved); 6971 6972 /* 6973 * Restore saved RF/PHY registers 6974 */ 6975 if (phy->rev >= 6) { 6976 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 6977 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6978 save_phy6[phy6_idx]); 6979 } 6980 } 6981 if (phy->rev != 1) { 6982 for (i = 3; i < 5; i++) 6983 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 6984 save_phy_comm[i]); 6985 } 6986 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 6987 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6988 6989 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 6990 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6991 6992 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 6993 BWN_PHY_SET(mac, 0x0429, 0x8000); 6994 bwn_set_original_gains(mac); 6995 if (phy->rev >= 6) { 6996 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 6997 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6998 save_phy6[phy6_idx]); 6999 } 7000 } 7001 7002 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7003 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7004 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7005 } 7006 7007 static void 7008 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7009 int16_t third) 7010 { 7011 struct bwn_phy *phy = &mac->mac_phy; 7012 uint16_t i; 7013 uint16_t start = 0x08, end = 0x18; 7014 uint16_t tmp; 7015 uint16_t table; 7016 7017 if (phy->rev <= 1) { 7018 start = 0x10; 7019 end = 0x20; 7020 } 7021 7022 table = BWN_OFDMTAB_GAINX; 7023 if (phy->rev <= 1) 7024 table = BWN_OFDMTAB_GAINX_R1; 7025 for (i = 0; i < 4; i++) 7026 bwn_ofdmtab_write_2(mac, table, i, first); 7027 7028 for (i = start; i < end; i++) 7029 bwn_ofdmtab_write_2(mac, table, i, second); 7030 7031 if (third != -1) { 7032 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7033 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7034 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7035 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7036 } 7037 bwn_dummy_transmission(mac, 0, 1); 7038 } 7039 7040 static void 7041 bwn_set_original_gains(struct bwn_mac *mac) 7042 { 7043 struct bwn_phy *phy = &mac->mac_phy; 7044 uint16_t i, tmp; 7045 uint16_t table; 7046 uint16_t start = 0x0008, end = 0x0018; 7047 7048 if (phy->rev <= 1) { 7049 start = 0x0010; 7050 end = 0x0020; 7051 } 7052 7053 table = BWN_OFDMTAB_GAINX; 7054 if (phy->rev <= 1) 7055 table = BWN_OFDMTAB_GAINX_R1; 7056 for (i = 0; i < 4; i++) { 7057 tmp = (i & 0xfffc); 7058 tmp |= (i & 0x0001) << 1; 7059 tmp |= (i & 0x0002) >> 1; 7060 7061 bwn_ofdmtab_write_2(mac, table, i, tmp); 7062 } 7063 7064 for (i = start; i < end; i++) 7065 bwn_ofdmtab_write_2(mac, table, i, i - start); 7066 7067 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7068 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7069 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7070 bwn_dummy_transmission(mac, 0, 1); 7071 } 7072 7073 static void 7074 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7075 { 7076 struct bwn_phy *phy = &mac->mac_phy; 7077 struct bwn_phy_g *pg = &phy->phy_g; 7078 struct bwn_rfatt old_rfatt, rfatt; 7079 struct bwn_bbatt old_bbatt, bbatt; 7080 struct bwn_softc *sc = mac->mac_sc; 7081 uint8_t old_txctl = 0; 7082 7083 KASSERT(phy->type == BWN_PHYTYPE_G, 7084 ("%s:%d: fail", __func__, __LINE__)); 7085 7086 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7087 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7088 return; 7089 7090 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7091 7092 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7093 7094 if (!phy->gmode) 7095 return; 7096 bwn_hwpctl_early_init(mac); 7097 if (pg->pg_curtssi == 0) { 7098 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7099 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7100 } else { 7101 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7102 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7103 old_txctl = pg->pg_txctl; 7104 7105 bbatt.att = 11; 7106 if (phy->rf_rev == 8) { 7107 rfatt.att = 15; 7108 rfatt.padmix = 1; 7109 } else { 7110 rfatt.att = 9; 7111 rfatt.padmix = 0; 7112 } 7113 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7114 } 7115 bwn_dummy_transmission(mac, 0, 1); 7116 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7117 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7118 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7119 else 7120 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7121 &old_rfatt, old_txctl); 7122 } 7123 bwn_hwpctl_init_gphy(mac); 7124 7125 /* clear TSSI */ 7126 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7127 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7128 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7129 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7130 } 7131 7132 static void 7133 bwn_hwpctl_early_init(struct bwn_mac *mac) 7134 { 7135 struct bwn_phy *phy = &mac->mac_phy; 7136 7137 if (!bwn_has_hwpctl(mac)) { 7138 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7139 return; 7140 } 7141 7142 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7143 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7144 BWN_PHY_SET(mac, 0x047c, 0x0002); 7145 BWN_PHY_SET(mac, 0x047a, 0xf000); 7146 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7147 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7148 BWN_PHY_SET(mac, 0x005d, 0x8000); 7149 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7150 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7151 BWN_PHY_SET(mac, 0x0036, 0x0400); 7152 } else { 7153 BWN_PHY_SET(mac, 0x0036, 0x0200); 7154 BWN_PHY_SET(mac, 0x0036, 0x0400); 7155 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7156 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7157 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7158 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7159 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7160 } 7161 } 7162 7163 static void 7164 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7165 { 7166 struct bwn_phy *phy = &mac->mac_phy; 7167 struct bwn_phy_g *pg = &phy->phy_g; 7168 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7169 int i; 7170 uint16_t nr_written = 0, tmp, value; 7171 uint8_t rf, bb; 7172 7173 if (!bwn_has_hwpctl(mac)) { 7174 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7175 return; 7176 } 7177 7178 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7179 (pg->pg_idletssi - pg->pg_curtssi)); 7180 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7181 (pg->pg_idletssi - pg->pg_curtssi)); 7182 7183 for (i = 0; i < 32; i++) 7184 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7185 for (i = 32; i < 64; i++) 7186 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7187 for (i = 0; i < 64; i += 2) { 7188 value = (uint16_t) pg->pg_tssi2dbm[i]; 7189 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7190 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7191 } 7192 7193 for (rf = 0; rf < lo->rfatt.len; rf++) { 7194 for (bb = 0; bb < lo->bbatt.len; bb++) { 7195 if (nr_written >= 0x40) 7196 return; 7197 tmp = lo->bbatt.array[bb].att; 7198 tmp <<= 8; 7199 if (phy->rf_rev == 8) 7200 tmp |= 0x50; 7201 else 7202 tmp |= 0x40; 7203 tmp |= lo->rfatt.array[rf].att; 7204 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7205 nr_written++; 7206 } 7207 } 7208 7209 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7210 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7211 7212 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7213 BWN_PHY_SET(mac, 0x0478, 0x0800); 7214 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7215 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7216 7217 bwn_phy_g_dc_lookup_init(mac, 1); 7218 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7219 } 7220 7221 static void 7222 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7223 { 7224 struct bwn_softc *sc = mac->mac_sc; 7225 7226 if (spu != 0) 7227 bwn_spu_workaround(mac, channel); 7228 7229 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7230 7231 if (channel == 14) { 7232 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7233 bwn_hf_write(mac, 7234 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7235 else 7236 bwn_hf_write(mac, 7237 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7238 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7239 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7240 return; 7241 } 7242 7243 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7244 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7245 } 7246 7247 static uint16_t 7248 bwn_phy_g_chan2freq(uint8_t channel) 7249 { 7250 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7251 7252 KASSERT(channel >= 1 && channel <= 14, 7253 ("%s:%d: fail", __func__, __LINE__)); 7254 7255 return (bwn_phy_g_rf_channels[channel - 1]); 7256 } 7257 7258 static void 7259 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7260 const struct bwn_rfatt *rfatt, uint8_t txctl) 7261 { 7262 struct bwn_phy *phy = &mac->mac_phy; 7263 struct bwn_phy_g *pg = &phy->phy_g; 7264 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7265 uint16_t bb, rf; 7266 uint16_t tx_bias, tx_magn; 7267 7268 bb = bbatt->att; 7269 rf = rfatt->att; 7270 tx_bias = lo->tx_bias; 7271 tx_magn = lo->tx_magn; 7272 if (tx_bias == 0xff) 7273 tx_bias = 0; 7274 7275 pg->pg_txctl = txctl; 7276 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7277 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7278 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7279 bwn_phy_g_set_bbatt(mac, bb); 7280 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7281 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7282 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7283 else { 7284 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7285 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7286 } 7287 if (BWN_HAS_TXMAG(phy)) 7288 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7289 else 7290 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7291 bwn_lo_g_adjust(mac); 7292 } 7293 7294 static void 7295 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7296 uint16_t bbatt) 7297 { 7298 struct bwn_phy *phy = &mac->mac_phy; 7299 7300 if (phy->analog == 0) { 7301 BWN_WRITE_2(mac, BWN_PHY0, 7302 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7303 return; 7304 } 7305 if (phy->analog > 1) { 7306 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7307 return; 7308 } 7309 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7310 } 7311 7312 static uint16_t 7313 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7314 { 7315 struct bwn_phy *phy = &mac->mac_phy; 7316 struct bwn_phy_g *pg = &phy->phy_g; 7317 struct bwn_softc *sc = mac->mac_sc; 7318 int max_lb_gain; 7319 uint16_t extlna; 7320 uint16_t i; 7321 7322 if (phy->gmode == 0) 7323 return (0); 7324 7325 if (BWN_HAS_LOOPBACK(phy)) { 7326 max_lb_gain = pg->pg_max_lb_gain; 7327 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7328 if (max_lb_gain >= 0x46) { 7329 extlna = 0x3000; 7330 max_lb_gain -= 0x46; 7331 } else if (max_lb_gain >= 0x3a) { 7332 extlna = 0x1000; 7333 max_lb_gain -= 0x3a; 7334 } else if (max_lb_gain >= 0x2e) { 7335 extlna = 0x2000; 7336 max_lb_gain -= 0x2e; 7337 } else { 7338 extlna = 0; 7339 max_lb_gain -= 0x10; 7340 } 7341 7342 for (i = 0; i < 16; i++) { 7343 max_lb_gain -= (i * 6); 7344 if (max_lb_gain < 6) 7345 break; 7346 } 7347 7348 if ((phy->rev < 7) || 7349 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7350 if (reg == BWN_PHY_RFOVER) { 7351 return (0x1b3); 7352 } else if (reg == BWN_PHY_RFOVERVAL) { 7353 extlna |= (i << 8); 7354 switch (lpd) { 7355 case BWN_LPD(0, 1, 1): 7356 return (0x0f92); 7357 case BWN_LPD(0, 0, 1): 7358 case BWN_LPD(1, 0, 1): 7359 return (0x0092 | extlna); 7360 case BWN_LPD(1, 0, 0): 7361 return (0x0093 | extlna); 7362 } 7363 KASSERT(0 == 1, 7364 ("%s:%d: fail", __func__, __LINE__)); 7365 } 7366 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7367 } else { 7368 if (reg == BWN_PHY_RFOVER) 7369 return (0x9b3); 7370 if (reg == BWN_PHY_RFOVERVAL) { 7371 if (extlna) 7372 extlna |= 0x8000; 7373 extlna |= (i << 8); 7374 switch (lpd) { 7375 case BWN_LPD(0, 1, 1): 7376 return (0x8f92); 7377 case BWN_LPD(0, 0, 1): 7378 return (0x8092 | extlna); 7379 case BWN_LPD(1, 0, 1): 7380 return (0x2092 | extlna); 7381 case BWN_LPD(1, 0, 0): 7382 return (0x2093 | extlna); 7383 } 7384 KASSERT(0 == 1, 7385 ("%s:%d: fail", __func__, __LINE__)); 7386 } 7387 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7388 } 7389 return (0); 7390 } 7391 7392 if ((phy->rev < 7) || 7393 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7394 if (reg == BWN_PHY_RFOVER) { 7395 return (0x1b3); 7396 } else if (reg == BWN_PHY_RFOVERVAL) { 7397 switch (lpd) { 7398 case BWN_LPD(0, 1, 1): 7399 return (0x0fb2); 7400 case BWN_LPD(0, 0, 1): 7401 return (0x00b2); 7402 case BWN_LPD(1, 0, 1): 7403 return (0x30b2); 7404 case BWN_LPD(1, 0, 0): 7405 return (0x30b3); 7406 } 7407 KASSERT(0 == 1, 7408 ("%s:%d: fail", __func__, __LINE__)); 7409 } 7410 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7411 } else { 7412 if (reg == BWN_PHY_RFOVER) { 7413 return (0x9b3); 7414 } else if (reg == BWN_PHY_RFOVERVAL) { 7415 switch (lpd) { 7416 case BWN_LPD(0, 1, 1): 7417 return (0x8fb2); 7418 case BWN_LPD(0, 0, 1): 7419 return (0x80b2); 7420 case BWN_LPD(1, 0, 1): 7421 return (0x20b2); 7422 case BWN_LPD(1, 0, 0): 7423 return (0x20b3); 7424 } 7425 KASSERT(0 == 1, 7426 ("%s:%d: fail", __func__, __LINE__)); 7427 } 7428 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7429 } 7430 return (0); 7431 } 7432 7433 static void 7434 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7435 { 7436 7437 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7438 return; 7439 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7440 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7441 DELAY(1000); 7442 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7443 } 7444 7445 static int 7446 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7447 { 7448 struct bwn_softc *sc = mac->mac_sc; 7449 struct bwn_fw *fw = &mac->mac_fw; 7450 const uint8_t rev = siba_get_revid(sc->sc_dev); 7451 const char *filename; 7452 uint32_t high; 7453 int error; 7454 7455 /* microcode */ 7456 if (rev >= 5 && rev <= 10) 7457 filename = "ucode5"; 7458 else if (rev >= 11 && rev <= 12) 7459 filename = "ucode11"; 7460 else if (rev == 13) 7461 filename = "ucode13"; 7462 else if (rev == 14) 7463 filename = "ucode14"; 7464 else if (rev >= 15) 7465 filename = "ucode15"; 7466 else { 7467 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7468 bwn_release_firmware(mac); 7469 return (EOPNOTSUPP); 7470 } 7471 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7472 if (error) { 7473 bwn_release_firmware(mac); 7474 return (error); 7475 } 7476 7477 /* PCM */ 7478 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7479 if (rev >= 5 && rev <= 10) { 7480 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7481 if (error == ENOENT) 7482 fw->no_pcmfile = 1; 7483 else if (error) { 7484 bwn_release_firmware(mac); 7485 return (error); 7486 } 7487 } else if (rev < 11) { 7488 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7489 return (EOPNOTSUPP); 7490 } 7491 7492 /* initvals */ 7493 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7494 switch (mac->mac_phy.type) { 7495 case BWN_PHYTYPE_A: 7496 if (rev < 5 || rev > 10) 7497 goto fail1; 7498 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7499 filename = "a0g1initvals5"; 7500 else 7501 filename = "a0g0initvals5"; 7502 break; 7503 case BWN_PHYTYPE_G: 7504 if (rev >= 5 && rev <= 10) 7505 filename = "b0g0initvals5"; 7506 else if (rev >= 13) 7507 filename = "b0g0initvals13"; 7508 else 7509 goto fail1; 7510 break; 7511 case BWN_PHYTYPE_LP: 7512 if (rev == 13) 7513 filename = "lp0initvals13"; 7514 else if (rev == 14) 7515 filename = "lp0initvals14"; 7516 else if (rev >= 15) 7517 filename = "lp0initvals15"; 7518 else 7519 goto fail1; 7520 break; 7521 case BWN_PHYTYPE_N: 7522 if (rev >= 11 && rev <= 12) 7523 filename = "n0initvals11"; 7524 else 7525 goto fail1; 7526 break; 7527 default: 7528 goto fail1; 7529 } 7530 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7531 if (error) { 7532 bwn_release_firmware(mac); 7533 return (error); 7534 } 7535 7536 /* bandswitch initvals */ 7537 switch (mac->mac_phy.type) { 7538 case BWN_PHYTYPE_A: 7539 if (rev >= 5 && rev <= 10) { 7540 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7541 filename = "a0g1bsinitvals5"; 7542 else 7543 filename = "a0g0bsinitvals5"; 7544 } else if (rev >= 11) 7545 filename = NULL; 7546 else 7547 goto fail1; 7548 break; 7549 case BWN_PHYTYPE_G: 7550 if (rev >= 5 && rev <= 10) 7551 filename = "b0g0bsinitvals5"; 7552 else if (rev >= 11) 7553 filename = NULL; 7554 else 7555 goto fail1; 7556 break; 7557 case BWN_PHYTYPE_LP: 7558 if (rev == 13) 7559 filename = "lp0bsinitvals13"; 7560 else if (rev == 14) 7561 filename = "lp0bsinitvals14"; 7562 else if (rev >= 15) 7563 filename = "lp0bsinitvals15"; 7564 else 7565 goto fail1; 7566 break; 7567 case BWN_PHYTYPE_N: 7568 if (rev >= 11 && rev <= 12) 7569 filename = "n0bsinitvals11"; 7570 else 7571 goto fail1; 7572 break; 7573 default: 7574 goto fail1; 7575 } 7576 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7577 if (error) { 7578 bwn_release_firmware(mac); 7579 return (error); 7580 } 7581 return (0); 7582 fail1: 7583 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7584 bwn_release_firmware(mac); 7585 return (EOPNOTSUPP); 7586 } 7587 7588 static int 7589 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7590 const char *name, struct bwn_fwfile *bfw) 7591 { 7592 const struct bwn_fwhdr *hdr; 7593 struct bwn_softc *sc = mac->mac_sc; 7594 const struct firmware *fw; 7595 char namebuf[64]; 7596 7597 if (name == NULL) { 7598 bwn_do_release_fw(bfw); 7599 return (0); 7600 } 7601 if (bfw->filename != NULL) { 7602 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7603 return (0); 7604 bwn_do_release_fw(bfw); 7605 } 7606 7607 ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7608 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7609 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7610 wlan_assert_serialized(); 7611 wlan_serialize_exit(); 7612 fw = firmware_get(namebuf); 7613 wlan_serialize_enter(); 7614 if (fw == NULL) { 7615 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7616 namebuf); 7617 return (ENOENT); 7618 } 7619 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7620 goto fail; 7621 hdr = (const struct bwn_fwhdr *)(fw->data); 7622 switch (hdr->type) { 7623 case BWN_FWTYPE_UCODE: 7624 case BWN_FWTYPE_PCM: 7625 if (be32toh(hdr->size) != 7626 (fw->datasize - sizeof(struct bwn_fwhdr))) 7627 goto fail; 7628 /* FALLTHROUGH */ 7629 case BWN_FWTYPE_IV: 7630 if (hdr->ver != 1) 7631 goto fail; 7632 break; 7633 default: 7634 goto fail; 7635 } 7636 bfw->filename = name; 7637 bfw->fw = fw; 7638 bfw->type = type; 7639 return (0); 7640 fail: 7641 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7642 if (fw != NULL) 7643 firmware_put(fw, FIRMWARE_UNLOAD); 7644 return (EPROTO); 7645 } 7646 7647 static void 7648 bwn_release_firmware(struct bwn_mac *mac) 7649 { 7650 7651 bwn_do_release_fw(&mac->mac_fw.ucode); 7652 bwn_do_release_fw(&mac->mac_fw.pcm); 7653 bwn_do_release_fw(&mac->mac_fw.initvals); 7654 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7655 } 7656 7657 static void 7658 bwn_do_release_fw(struct bwn_fwfile *bfw) 7659 { 7660 7661 if (bfw->fw != NULL) 7662 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7663 bfw->fw = NULL; 7664 bfw->filename = NULL; 7665 } 7666 7667 static int 7668 bwn_fw_loaducode(struct bwn_mac *mac) 7669 { 7670 #define GETFWOFFSET(fwp, offset) \ 7671 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7672 #define GETFWSIZE(fwp, offset) \ 7673 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7674 struct bwn_softc *sc = mac->mac_sc; 7675 const uint32_t *data; 7676 unsigned int i; 7677 uint32_t ctl; 7678 uint16_t date, fwcaps, time; 7679 int error = 0; 7680 7681 ctl = BWN_READ_4(mac, BWN_MACCTL); 7682 ctl |= BWN_MACCTL_MCODE_JMP0; 7683 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7684 __LINE__)); 7685 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7686 for (i = 0; i < 64; i++) 7687 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7688 for (i = 0; i < 4096; i += 2) 7689 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7690 7691 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7692 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7693 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7694 i++) { 7695 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7696 DELAY(10); 7697 } 7698 7699 if (mac->mac_fw.pcm.fw) { 7700 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7701 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7702 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7703 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7704 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7705 sizeof(struct bwn_fwhdr)); i++) { 7706 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7707 DELAY(10); 7708 } 7709 } 7710 7711 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7712 BWN_WRITE_4(mac, BWN_MACCTL, 7713 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7714 BWN_MACCTL_MCODE_RUN); 7715 7716 for (i = 0; i < 21; i++) { 7717 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7718 break; 7719 if (i >= 20) { 7720 device_printf(sc->sc_dev, "ucode timeout\n"); 7721 error = ENXIO; 7722 goto error; 7723 } 7724 DELAY(50000); 7725 } 7726 BWN_READ_4(mac, BWN_INTR_REASON); 7727 7728 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7729 if (mac->mac_fw.rev <= 0x128) { 7730 device_printf(sc->sc_dev, "the firmware is too old\n"); 7731 error = EOPNOTSUPP; 7732 goto error; 7733 } 7734 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7735 BWN_SHARED_UCODE_PATCH); 7736 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7737 mac->mac_fw.opensource = (date == 0xffff); 7738 if (bwn_wme != 0) 7739 mac->mac_flags |= BWN_MAC_FLAG_WME; 7740 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7741 7742 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7743 if (mac->mac_fw.opensource == 0) { 7744 device_printf(sc->sc_dev, 7745 "firmware version (rev %u patch %u date %#x time %#x)\n", 7746 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7747 if (mac->mac_fw.no_pcmfile) 7748 device_printf(sc->sc_dev, 7749 "no HW crypto acceleration due to pcm5\n"); 7750 } else { 7751 mac->mac_fw.patch = time; 7752 fwcaps = bwn_fwcaps_read(mac); 7753 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7754 device_printf(sc->sc_dev, 7755 "disabling HW crypto acceleration\n"); 7756 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7757 } 7758 if (!(fwcaps & BWN_FWCAPS_WME)) { 7759 device_printf(sc->sc_dev, "disabling WME support\n"); 7760 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7761 } 7762 } 7763 7764 if (BWN_ISOLDFMT(mac)) 7765 device_printf(sc->sc_dev, "using old firmware image\n"); 7766 7767 return (0); 7768 7769 error: 7770 BWN_WRITE_4(mac, BWN_MACCTL, 7771 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7772 BWN_MACCTL_MCODE_JMP0); 7773 7774 return (error); 7775 #undef GETFWSIZE 7776 #undef GETFWOFFSET 7777 } 7778 7779 /* OpenFirmware only */ 7780 static uint16_t 7781 bwn_fwcaps_read(struct bwn_mac *mac) 7782 { 7783 7784 KASSERT(mac->mac_fw.opensource == 1, 7785 ("%s:%d: fail", __func__, __LINE__)); 7786 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7787 } 7788 7789 static int 7790 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7791 size_t count, size_t array_size) 7792 { 7793 #define GET_NEXTIV16(iv) \ 7794 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7795 sizeof(uint16_t) + sizeof(uint16_t))) 7796 #define GET_NEXTIV32(iv) \ 7797 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7798 sizeof(uint16_t) + sizeof(uint32_t))) 7799 struct bwn_softc *sc = mac->mac_sc; 7800 const struct bwn_fwinitvals *iv; 7801 uint16_t offset; 7802 size_t i; 7803 uint8_t bit32; 7804 7805 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7806 ("%s:%d: fail", __func__, __LINE__)); 7807 iv = ivals; 7808 for (i = 0; i < count; i++) { 7809 if (array_size < sizeof(iv->offset_size)) 7810 goto fail; 7811 array_size -= sizeof(iv->offset_size); 7812 offset = be16toh(iv->offset_size); 7813 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7814 offset &= BWN_FWINITVALS_OFFSET_MASK; 7815 if (offset >= 0x1000) 7816 goto fail; 7817 if (bit32) { 7818 if (array_size < sizeof(iv->data.d32)) 7819 goto fail; 7820 array_size -= sizeof(iv->data.d32); 7821 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7822 iv = GET_NEXTIV32(iv); 7823 } else { 7824 7825 if (array_size < sizeof(iv->data.d16)) 7826 goto fail; 7827 array_size -= sizeof(iv->data.d16); 7828 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7829 7830 iv = GET_NEXTIV16(iv); 7831 } 7832 } 7833 if (array_size != 0) 7834 goto fail; 7835 return (0); 7836 fail: 7837 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7838 return (EPROTO); 7839 #undef GET_NEXTIV16 7840 #undef GET_NEXTIV32 7841 } 7842 7843 static int 7844 bwn_switch_channel(struct bwn_mac *mac, int chan) 7845 { 7846 struct bwn_phy *phy = &(mac->mac_phy); 7847 struct bwn_softc *sc = mac->mac_sc; 7848 struct ifnet *ifp = sc->sc_ifp; 7849 struct ieee80211com *ic = ifp->if_l2com; 7850 uint16_t channelcookie, savedcookie; 7851 int error; 7852 7853 if (chan == 0xffff) 7854 chan = phy->get_default_chan(mac); 7855 7856 channelcookie = chan; 7857 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7858 channelcookie |= 0x100; 7859 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7860 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7861 error = phy->switch_channel(mac, chan); 7862 if (error) 7863 goto fail; 7864 7865 mac->mac_phy.chan = chan; 7866 DELAY(8000); 7867 return (0); 7868 fail: 7869 device_printf(sc->sc_dev, "failed to switch channel\n"); 7870 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7871 return (error); 7872 } 7873 7874 static uint16_t 7875 bwn_ant2phy(int antenna) 7876 { 7877 7878 switch (antenna) { 7879 case BWN_ANT0: 7880 return (BWN_TX_PHY_ANT0); 7881 case BWN_ANT1: 7882 return (BWN_TX_PHY_ANT1); 7883 case BWN_ANT2: 7884 return (BWN_TX_PHY_ANT2); 7885 case BWN_ANT3: 7886 return (BWN_TX_PHY_ANT3); 7887 case BWN_ANTAUTO: 7888 return (BWN_TX_PHY_ANT01AUTO); 7889 } 7890 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7891 return (0); 7892 } 7893 7894 static void 7895 bwn_wme_load(struct bwn_mac *mac) 7896 { 7897 struct bwn_softc *sc = mac->mac_sc; 7898 int i; 7899 7900 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7901 ("%s:%d: fail", __func__, __LINE__)); 7902 7903 bwn_mac_suspend(mac); 7904 for (i = 0; i < N(sc->sc_wmeParams); i++) 7905 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 7906 bwn_wme_shm_offsets[i]); 7907 bwn_mac_enable(mac); 7908 } 7909 7910 static void 7911 bwn_wme_loadparams(struct bwn_mac *mac, 7912 const struct wmeParams *p, uint16_t shm_offset) 7913 { 7914 #define SM(_v, _f) (((_v) << _f##_S) & _f) 7915 struct bwn_softc *sc = mac->mac_sc; 7916 uint16_t params[BWN_NR_WMEPARAMS]; 7917 int slot, tmp; 7918 unsigned int i; 7919 7920 slot = BWN_READ_2(mac, BWN_RNG) & 7921 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7922 7923 memset(¶ms, 0, sizeof(params)); 7924 7925 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 7926 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 7927 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 7928 7929 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 7930 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7931 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 7932 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7933 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 7934 params[BWN_WMEPARAM_BSLOTS] = slot; 7935 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 7936 7937 for (i = 0; i < N(params); i++) { 7938 if (i == BWN_WMEPARAM_STATUS) { 7939 tmp = bwn_shm_read_2(mac, BWN_SHARED, 7940 shm_offset + (i * 2)); 7941 tmp |= 0x100; 7942 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7943 tmp); 7944 } else { 7945 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7946 params[i]); 7947 } 7948 } 7949 } 7950 7951 static void 7952 bwn_mac_write_bssid(struct bwn_mac *mac) 7953 { 7954 struct bwn_softc *sc = mac->mac_sc; 7955 uint32_t tmp; 7956 int i; 7957 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 7958 7959 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 7960 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 7961 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 7962 IEEE80211_ADDR_LEN); 7963 7964 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 7965 tmp = (uint32_t) (mac_bssid[i + 0]); 7966 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 7967 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 7968 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 7969 bwn_ram_write(mac, 0x20 + i, tmp); 7970 } 7971 } 7972 7973 static void 7974 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 7975 const uint8_t *macaddr) 7976 { 7977 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 7978 uint16_t data; 7979 7980 if (mac == NULL) 7981 macaddr = zero; 7982 7983 offset |= 0x0020; 7984 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 7985 7986 data = macaddr[0]; 7987 data |= macaddr[1] << 8; 7988 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7989 data = macaddr[2]; 7990 data |= macaddr[3] << 8; 7991 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7992 data = macaddr[4]; 7993 data |= macaddr[5] << 8; 7994 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7995 } 7996 7997 static void 7998 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 7999 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8000 { 8001 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8002 uint8_t per_sta_keys_start = 8; 8003 8004 if (BWN_SEC_NEWAPI(mac)) 8005 per_sta_keys_start = 4; 8006 8007 KASSERT(index < mac->mac_max_nr_keys, 8008 ("%s:%d: fail", __func__, __LINE__)); 8009 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8010 ("%s:%d: fail", __func__, __LINE__)); 8011 8012 if (index >= per_sta_keys_start) 8013 bwn_key_macwrite(mac, index, NULL); 8014 if (key) 8015 memcpy(buf, key, key_len); 8016 bwn_key_write(mac, index, algorithm, buf); 8017 if (index >= per_sta_keys_start) 8018 bwn_key_macwrite(mac, index, mac_addr); 8019 8020 mac->mac_key[index].algorithm = algorithm; 8021 } 8022 8023 static void 8024 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8025 { 8026 struct bwn_softc *sc = mac->mac_sc; 8027 uint32_t addrtmp[2] = { 0, 0 }; 8028 uint8_t start = 8; 8029 8030 if (BWN_SEC_NEWAPI(mac)) 8031 start = 4; 8032 8033 KASSERT(index >= start, 8034 ("%s:%d: fail", __func__, __LINE__)); 8035 index -= start; 8036 8037 if (addr) { 8038 addrtmp[0] = addr[0]; 8039 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8040 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8041 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8042 addrtmp[1] = addr[4]; 8043 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8044 } 8045 8046 if (siba_get_revid(sc->sc_dev) >= 5) { 8047 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8048 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8049 } else { 8050 if (index >= 8) { 8051 bwn_shm_write_4(mac, BWN_SHARED, 8052 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8053 bwn_shm_write_2(mac, BWN_SHARED, 8054 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8055 } 8056 } 8057 } 8058 8059 static void 8060 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8061 const uint8_t *key) 8062 { 8063 unsigned int i; 8064 uint32_t offset; 8065 uint16_t kidx, value; 8066 8067 kidx = BWN_SEC_KEY2FW(mac, index); 8068 bwn_shm_write_2(mac, BWN_SHARED, 8069 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8070 8071 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8072 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8073 value = key[i]; 8074 value |= (uint16_t)(key[i + 1]) << 8; 8075 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8076 } 8077 } 8078 8079 static void 8080 bwn_phy_exit(struct bwn_mac *mac) 8081 { 8082 8083 mac->mac_phy.rf_onoff(mac, 0); 8084 if (mac->mac_phy.exit != NULL) 8085 mac->mac_phy.exit(mac); 8086 } 8087 8088 static void 8089 bwn_dma_free(struct bwn_mac *mac) 8090 { 8091 struct bwn_dma *dma; 8092 8093 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8094 return; 8095 dma = &mac->mac_method.dma; 8096 8097 bwn_dma_ringfree(&dma->rx); 8098 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8099 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8100 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8101 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8102 bwn_dma_ringfree(&dma->mcast); 8103 } 8104 8105 static void 8106 bwn_core_stop(struct bwn_mac *mac) 8107 { 8108 struct bwn_softc *sc = mac->mac_sc; 8109 8110 wlan_assert_serialized(); 8111 8112 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8113 return; 8114 8115 callout_stop(&sc->sc_rfswitch_ch); 8116 callout_stop(&sc->sc_task_ch); 8117 callout_stop(&sc->sc_watchdog_ch); 8118 sc->sc_watchdog_timer = 0; 8119 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8120 BWN_READ_4(mac, BWN_INTR_MASK); 8121 bwn_mac_suspend(mac); 8122 8123 mac->mac_status = BWN_MAC_STATUS_INITED; 8124 } 8125 8126 static int 8127 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8128 { 8129 struct bwn_mac *up_dev = NULL; 8130 struct bwn_mac *down_dev; 8131 struct bwn_mac *mac; 8132 int err, status; 8133 uint8_t gmode; 8134 8135 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8136 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8137 mac->mac_phy.supports_2ghz) { 8138 up_dev = mac; 8139 gmode = 1; 8140 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8141 mac->mac_phy.supports_5ghz) { 8142 up_dev = mac; 8143 gmode = 0; 8144 } else { 8145 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8146 return (EINVAL); 8147 } 8148 if (up_dev != NULL) 8149 break; 8150 } 8151 if (up_dev == NULL) { 8152 device_printf(sc->sc_dev, "Could not find a device\n"); 8153 return (ENODEV); 8154 } 8155 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8156 return (0); 8157 8158 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8159 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8160 8161 down_dev = sc->sc_curmac; 8162 status = down_dev->mac_status; 8163 if (status >= BWN_MAC_STATUS_STARTED) 8164 bwn_core_stop(down_dev); 8165 if (status >= BWN_MAC_STATUS_INITED) 8166 bwn_core_exit(down_dev); 8167 8168 if (down_dev != up_dev) 8169 bwn_phy_reset(down_dev); 8170 8171 up_dev->mac_phy.gmode = gmode; 8172 if (status >= BWN_MAC_STATUS_INITED) { 8173 err = bwn_core_init(up_dev); 8174 if (err) { 8175 device_printf(sc->sc_dev, 8176 "fatal: failed to initialize for %s-GHz\n", 8177 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8178 goto fail; 8179 } 8180 } 8181 if (status >= BWN_MAC_STATUS_STARTED) 8182 bwn_core_start(up_dev); 8183 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8184 sc->sc_curmac = up_dev; 8185 8186 return (0); 8187 fail: 8188 sc->sc_curmac = NULL; 8189 return (err); 8190 } 8191 8192 static void 8193 bwn_rf_turnon(struct bwn_mac *mac) 8194 { 8195 8196 bwn_mac_suspend(mac); 8197 mac->mac_phy.rf_onoff(mac, 1); 8198 mac->mac_phy.rf_on = 1; 8199 bwn_mac_enable(mac); 8200 } 8201 8202 static void 8203 bwn_rf_turnoff(struct bwn_mac *mac) 8204 { 8205 8206 bwn_mac_suspend(mac); 8207 mac->mac_phy.rf_onoff(mac, 0); 8208 mac->mac_phy.rf_on = 0; 8209 bwn_mac_enable(mac); 8210 } 8211 8212 static void 8213 bwn_phy_reset(struct bwn_mac *mac) 8214 { 8215 struct bwn_softc *sc = mac->mac_sc; 8216 8217 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8218 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8219 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8220 DELAY(1000); 8221 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8222 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8223 BWN_TGSLOW_PHYRESET); 8224 DELAY(1000); 8225 } 8226 8227 static int 8228 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8229 { 8230 struct bwn_vap *bvp = BWN_VAP(vap); 8231 struct ieee80211com *ic= vap->iv_ic; 8232 struct ifnet *ifp = ic->ic_ifp; 8233 enum ieee80211_state ostate = vap->iv_state; 8234 struct bwn_softc *sc = ifp->if_softc; 8235 struct bwn_mac *mac = sc->sc_curmac; 8236 int error; 8237 8238 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8239 ieee80211_state_name[vap->iv_state], 8240 ieee80211_state_name[nstate]); 8241 8242 error = bvp->bv_newstate(vap, nstate, arg); 8243 if (error != 0) 8244 return (error); 8245 8246 bwn_led_newstate(mac, nstate); 8247 8248 /* 8249 * Clear the BSSID when we stop a STA 8250 */ 8251 if (vap->iv_opmode == IEEE80211_M_STA) { 8252 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8253 /* 8254 * Clear out the BSSID. If we reassociate to 8255 * the same AP, this will reinialize things 8256 * correctly... 8257 */ 8258 if (ic->ic_opmode == IEEE80211_M_STA && 8259 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8260 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8261 bwn_set_macaddr(mac); 8262 } 8263 } 8264 } 8265 8266 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8267 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8268 /* XXX nothing to do? */ 8269 } else if (nstate == IEEE80211_S_RUN) { 8270 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8271 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8272 bwn_set_opmode(mac); 8273 bwn_set_pretbtt(mac); 8274 bwn_spu_setdelay(mac, 0); 8275 bwn_set_macaddr(mac); 8276 } 8277 8278 return (error); 8279 } 8280 8281 static void 8282 bwn_set_pretbtt(struct bwn_mac *mac) 8283 { 8284 struct bwn_softc *sc = mac->mac_sc; 8285 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8286 uint16_t pretbtt; 8287 8288 if (ic->ic_opmode == IEEE80211_M_IBSS) 8289 pretbtt = 2; 8290 else 8291 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8292 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8293 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8294 } 8295 8296 static void 8297 bwn_intr(void *arg) 8298 { 8299 struct bwn_mac *mac = arg; 8300 struct bwn_softc *sc = mac->mac_sc; 8301 uint32_t reason; 8302 8303 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8304 (sc->sc_flags & BWN_FLAG_INVALID)) 8305 return; 8306 8307 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8308 if (reason == 0xffffffff) /* shared IRQ */ 8309 return; 8310 reason &= mac->mac_intr_mask; 8311 if (reason == 0) 8312 return; 8313 8314 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00; 8315 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8316 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8317 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8318 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8319 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8320 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8321 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8322 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8323 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8324 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8325 8326 /* Disable interrupts. */ 8327 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8328 8329 mac->mac_reason_intr = reason; 8330 8331 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8332 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8333 8334 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask); 8335 return; 8336 } 8337 8338 static void 8339 bwn_intrtask(void *arg, int npending) 8340 { 8341 struct bwn_mac *mac = arg; 8342 struct bwn_softc *sc = mac->mac_sc; 8343 struct ifnet *ifp = sc->sc_ifp; 8344 uint32_t merged = 0; 8345 int i, tx = 0, rx = 0; 8346 8347 wlan_serialize_enter(); 8348 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8349 (sc->sc_flags & BWN_FLAG_INVALID)) { 8350 wlan_serialize_exit(); 8351 return; 8352 } 8353 8354 for (i = 0; i < N(mac->mac_reason); i++) 8355 merged |= mac->mac_reason[i]; 8356 8357 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8358 device_printf(sc->sc_dev, "MAC trans error\n"); 8359 8360 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8361 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8362 mac->mac_phy.txerrors--; 8363 if (mac->mac_phy.txerrors == 0) { 8364 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8365 bwn_restart(mac, "PHY TX errors"); 8366 } 8367 } 8368 8369 if (merged & BWN_DMAINTR_FATALMASK) { 8370 device_printf(sc->sc_dev, 8371 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8372 mac->mac_reason[0], mac->mac_reason[1], 8373 mac->mac_reason[2], mac->mac_reason[3], 8374 mac->mac_reason[4], mac->mac_reason[5]); 8375 bwn_restart(mac, "DMA error"); 8376 wlan_serialize_exit(); 8377 return; 8378 } 8379 8380 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8381 bwn_intr_ucode_debug(mac); 8382 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8383 bwn_intr_tbtt_indication(mac); 8384 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8385 bwn_intr_atim_end(mac); 8386 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8387 bwn_intr_beacon(mac); 8388 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8389 bwn_intr_pmq(mac); 8390 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8391 bwn_intr_noise(mac); 8392 8393 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8394 if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) { 8395 device_printf(sc->sc_dev, "RX descriptor overflow\n"); 8396 bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx); 8397 } 8398 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8399 bwn_dma_rx(mac->mac_method.dma.rx); 8400 rx = 1; 8401 } 8402 } else 8403 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8404 8405 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8406 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8407 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8408 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8409 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8410 8411 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8412 bwn_intr_txeof(mac); 8413 tx = 1; 8414 } 8415 8416 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8417 8418 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8419 int evt = BWN_LED_EVENT_NONE; 8420 8421 if (tx && rx) { 8422 if (sc->sc_rx_rate > sc->sc_tx_rate) 8423 evt = BWN_LED_EVENT_RX; 8424 else 8425 evt = BWN_LED_EVENT_TX; 8426 } else if (tx) { 8427 evt = BWN_LED_EVENT_TX; 8428 } else if (rx) { 8429 evt = BWN_LED_EVENT_RX; 8430 } else if (rx == 0) { 8431 evt = BWN_LED_EVENT_POLL; 8432 } 8433 8434 if (evt != BWN_LED_EVENT_NONE) 8435 bwn_led_event(mac, evt); 8436 } 8437 8438 if (!ifq_is_oactive(&ifp->if_snd)) { 8439 if (!ifq_is_empty(&ifp->if_snd)) 8440 bwn_start_locked(ifp); 8441 } 8442 8443 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8444 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8445 8446 wlan_serialize_exit(); 8447 } 8448 8449 static void 8450 bwn_restart(struct bwn_mac *mac, const char *msg) 8451 { 8452 struct bwn_softc *sc = mac->mac_sc; 8453 struct ifnet *ifp = sc->sc_ifp; 8454 struct ieee80211com *ic = ifp->if_l2com; 8455 8456 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8457 return; 8458 8459 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8460 ieee80211_runtask(ic, &mac->mac_hwreset); 8461 } 8462 8463 static void 8464 bwn_intr_ucode_debug(struct bwn_mac *mac) 8465 { 8466 struct bwn_softc *sc = mac->mac_sc; 8467 uint16_t reason; 8468 8469 if (mac->mac_fw.opensource == 0) 8470 return; 8471 8472 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8473 switch (reason) { 8474 case BWN_DEBUGINTR_PANIC: 8475 bwn_handle_fwpanic(mac); 8476 break; 8477 case BWN_DEBUGINTR_DUMP_SHM: 8478 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8479 break; 8480 case BWN_DEBUGINTR_DUMP_REGS: 8481 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8482 break; 8483 case BWN_DEBUGINTR_MARKER: 8484 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8485 break; 8486 default: 8487 device_printf(sc->sc_dev, 8488 "ucode debug unknown reason: %#x\n", reason); 8489 } 8490 8491 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8492 BWN_DEBUGINTR_ACK); 8493 } 8494 8495 static void 8496 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8497 { 8498 struct bwn_softc *sc = mac->mac_sc; 8499 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8500 8501 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8502 bwn_psctl(mac, 0); 8503 if (ic->ic_opmode == IEEE80211_M_IBSS) 8504 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8505 } 8506 8507 static void 8508 bwn_intr_atim_end(struct bwn_mac *mac) 8509 { 8510 8511 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8512 BWN_WRITE_4(mac, BWN_MACCMD, 8513 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8514 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8515 } 8516 } 8517 8518 static void 8519 bwn_intr_beacon(struct bwn_mac *mac) 8520 { 8521 struct bwn_softc *sc = mac->mac_sc; 8522 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8523 uint32_t cmd, beacon0, beacon1; 8524 8525 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8526 ic->ic_opmode == IEEE80211_M_MBSS) 8527 return; 8528 8529 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8530 8531 cmd = BWN_READ_4(mac, BWN_MACCMD); 8532 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8533 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8534 8535 if (beacon0 && beacon1) { 8536 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8537 mac->mac_intr_mask |= BWN_INTR_BEACON; 8538 return; 8539 } 8540 8541 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8542 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8543 bwn_load_beacon0(mac); 8544 bwn_load_beacon1(mac); 8545 cmd = BWN_READ_4(mac, BWN_MACCMD); 8546 cmd |= BWN_MACCMD_BEACON0_VALID; 8547 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8548 } else { 8549 if (!beacon0) { 8550 bwn_load_beacon0(mac); 8551 cmd = BWN_READ_4(mac, BWN_MACCMD); 8552 cmd |= BWN_MACCMD_BEACON0_VALID; 8553 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8554 } else if (!beacon1) { 8555 bwn_load_beacon1(mac); 8556 cmd = BWN_READ_4(mac, BWN_MACCMD); 8557 cmd |= BWN_MACCMD_BEACON1_VALID; 8558 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8559 } 8560 } 8561 } 8562 8563 static void 8564 bwn_intr_pmq(struct bwn_mac *mac) 8565 { 8566 uint32_t tmp; 8567 8568 while (1) { 8569 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8570 if (!(tmp & 0x00000008)) 8571 break; 8572 } 8573 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8574 } 8575 8576 static void 8577 bwn_intr_noise(struct bwn_mac *mac) 8578 { 8579 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8580 uint16_t tmp; 8581 uint8_t noise[4]; 8582 uint8_t i, j; 8583 int32_t average; 8584 8585 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8586 return; 8587 8588 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8589 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8590 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8591 noise[3] == 0x7f) 8592 goto new; 8593 8594 KASSERT(mac->mac_noise.noi_nsamples < 8, 8595 ("%s:%d: fail", __func__, __LINE__)); 8596 i = mac->mac_noise.noi_nsamples; 8597 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8598 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8599 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8600 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8601 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8602 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8603 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8604 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8605 mac->mac_noise.noi_nsamples++; 8606 if (mac->mac_noise.noi_nsamples == 8) { 8607 average = 0; 8608 for (i = 0; i < 8; i++) { 8609 for (j = 0; j < 4; j++) 8610 average += mac->mac_noise.noi_samples[i][j]; 8611 } 8612 average = (((average / 32) * 125) + 64) / 128; 8613 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8614 if (tmp >= 8) 8615 average += 2; 8616 else 8617 average -= 25; 8618 average -= (tmp == 8) ? 72 : 48; 8619 8620 mac->mac_stats.link_noise = average; 8621 mac->mac_noise.noi_running = 0; 8622 return; 8623 } 8624 new: 8625 bwn_noise_gensample(mac); 8626 } 8627 8628 static int 8629 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8630 { 8631 struct bwn_mac *mac = prq->prq_mac; 8632 struct bwn_softc *sc = mac->mac_sc; 8633 unsigned int i; 8634 8635 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8636 return (0); 8637 8638 for (i = 0; i < 5000; i++) { 8639 if (bwn_pio_rxeof(prq) == 0) 8640 break; 8641 } 8642 if (i >= 5000) 8643 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8644 return ((i > 0) ? 1 : 0); 8645 } 8646 8647 static void 8648 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr) 8649 { 8650 int curslot, prevslot; 8651 8652 curslot = dr->get_curslot(dr); 8653 if (curslot == 0) 8654 prevslot = dr->dr_numslots - 1; 8655 else 8656 prevslot = curslot - 1; 8657 dr->set_curslot(dr, prevslot); 8658 } 8659 8660 static void 8661 bwn_dma_rx(struct bwn_dma_ring *dr) 8662 { 8663 int slot, curslot; 8664 8665 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8666 curslot = dr->get_curslot(dr); 8667 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8668 ("%s:%d: fail", __func__, __LINE__)); 8669 8670 slot = dr->dr_curslot; 8671 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8672 bwn_dma_rxeof(dr, &slot); 8673 8674 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8675 BUS_DMASYNC_PREWRITE); 8676 8677 dr->set_curslot(dr, slot); 8678 dr->dr_curslot = slot; 8679 } 8680 8681 static void 8682 bwn_intr_txeof(struct bwn_mac *mac) 8683 { 8684 struct bwn_txstatus stat; 8685 uint32_t stat0, stat1; 8686 uint16_t tmp; 8687 8688 while (1) { 8689 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8690 if (!(stat0 & 0x00000001)) 8691 break; 8692 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8693 8694 stat.cookie = (stat0 >> 16); 8695 stat.seq = (stat1 & 0x0000ffff); 8696 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8697 tmp = (stat0 & 0x0000ffff); 8698 stat.framecnt = ((tmp & 0xf000) >> 12); 8699 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8700 stat.sreason = ((tmp & 0x001c) >> 2); 8701 stat.pm = (tmp & 0x0080) ? 1 : 0; 8702 stat.im = (tmp & 0x0040) ? 1 : 0; 8703 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8704 stat.ack = (tmp & 0x0002) ? 1 : 0; 8705 8706 bwn_handle_txeof(mac, &stat); 8707 } 8708 } 8709 8710 static void 8711 bwn_hwreset(void *arg, int npending) 8712 { 8713 struct bwn_mac *mac = arg; 8714 struct bwn_softc *sc = mac->mac_sc; 8715 int error = 0; 8716 int prev_status; 8717 8718 wlan_serialize_enter(); 8719 8720 prev_status = mac->mac_status; 8721 if (prev_status >= BWN_MAC_STATUS_STARTED) 8722 bwn_core_stop(mac); 8723 if (prev_status >= BWN_MAC_STATUS_INITED) 8724 bwn_core_exit(mac); 8725 8726 if (prev_status >= BWN_MAC_STATUS_INITED) { 8727 error = bwn_core_init(mac); 8728 if (error) 8729 goto out; 8730 } 8731 if (prev_status >= BWN_MAC_STATUS_STARTED) 8732 bwn_core_start(mac); 8733 out: 8734 if (error) { 8735 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8736 sc->sc_curmac = NULL; 8737 } 8738 wlan_serialize_exit(); 8739 } 8740 8741 static void 8742 bwn_handle_fwpanic(struct bwn_mac *mac) 8743 { 8744 struct bwn_softc *sc = mac->mac_sc; 8745 uint16_t reason; 8746 8747 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8748 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8749 8750 if (reason == BWN_FWPANIC_RESTART) 8751 bwn_restart(mac, "ucode panic"); 8752 } 8753 8754 static void 8755 bwn_load_beacon0(struct bwn_mac *mac) 8756 { 8757 8758 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8759 } 8760 8761 static void 8762 bwn_load_beacon1(struct bwn_mac *mac) 8763 { 8764 8765 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8766 } 8767 8768 static uint32_t 8769 bwn_jssi_read(struct bwn_mac *mac) 8770 { 8771 uint32_t val = 0; 8772 8773 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8774 val <<= 16; 8775 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8776 8777 return (val); 8778 } 8779 8780 static void 8781 bwn_noise_gensample(struct bwn_mac *mac) 8782 { 8783 uint32_t jssi = 0x7f7f7f7f; 8784 8785 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8786 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8787 BWN_WRITE_4(mac, BWN_MACCMD, 8788 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8789 } 8790 8791 static int 8792 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8793 { 8794 return (dr->dr_numslots - dr->dr_usedslot); 8795 } 8796 8797 static int 8798 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8799 { 8800 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8801 ("%s:%d: fail", __func__, __LINE__)); 8802 if (slot == dr->dr_numslots - 1) 8803 return (0); 8804 return (slot + 1); 8805 } 8806 8807 static void 8808 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8809 { 8810 struct bwn_mac *mac = dr->dr_mac; 8811 struct bwn_softc *sc = mac->mac_sc; 8812 struct bwn_dma *dma = &mac->mac_method.dma; 8813 struct bwn_dmadesc_generic *desc; 8814 struct bwn_dmadesc_meta *meta; 8815 struct bwn_rxhdr4 *rxhdr; 8816 struct ifnet *ifp = sc->sc_ifp; 8817 struct mbuf *m; 8818 uint32_t macstat; 8819 int32_t tmp; 8820 int cnt = 0; 8821 uint16_t len; 8822 8823 dr->getdesc(dr, *slot, &desc, &meta); 8824 8825 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8826 m = meta->mt_m; 8827 8828 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8829 ifp->if_ierrors++; 8830 return; 8831 } 8832 8833 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8834 len = le16toh(rxhdr->frame_len); 8835 if (len <= 0) { 8836 ifp->if_ierrors++; 8837 return; 8838 } 8839 if (bwn_dma_check_redzone(dr, m)) { 8840 device_printf(sc->sc_dev, "redzone error.\n"); 8841 bwn_dma_set_redzone(dr, m); 8842 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8843 BUS_DMASYNC_PREWRITE); 8844 return; 8845 } 8846 if (len > dr->dr_rx_bufsize) { 8847 tmp = len; 8848 while (1) { 8849 dr->getdesc(dr, *slot, &desc, &meta); 8850 bwn_dma_set_redzone(dr, meta->mt_m); 8851 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8852 BUS_DMASYNC_PREWRITE); 8853 *slot = bwn_dma_nextslot(dr, *slot); 8854 cnt++; 8855 tmp -= dr->dr_rx_bufsize; 8856 if (tmp <= 0) 8857 break; 8858 } 8859 device_printf(sc->sc_dev, "too small buffer " 8860 "(len %u buffer %u dropped %d)\n", 8861 len, dr->dr_rx_bufsize, cnt); 8862 return; 8863 } 8864 macstat = le32toh(rxhdr->mac_status); 8865 if (macstat & BWN_RX_MAC_FCSERR) { 8866 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8867 device_printf(sc->sc_dev, "RX drop\n"); 8868 return; 8869 } 8870 } 8871 8872 m->m_pkthdr.rcvif = ifp; 8873 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8874 m_adj(m, dr->dr_frameoffset); 8875 8876 bwn_rxeof(dr->dr_mac, m, rxhdr); 8877 } 8878 8879 static void 8880 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8881 { 8882 struct bwn_dma_ring *dr; 8883 struct bwn_dmadesc_generic *desc; 8884 struct bwn_dmadesc_meta *meta; 8885 struct bwn_pio_txqueue *tq; 8886 struct bwn_pio_txpkt *tp = NULL; 8887 struct bwn_softc *sc = mac->mac_sc; 8888 struct bwn_stats *stats = &mac->mac_stats; 8889 struct ieee80211_node *ni; 8890 struct ieee80211vap *vap; 8891 int retrycnt = 0, slot; 8892 8893 if (status->im) 8894 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8895 if (status->ampdu) 8896 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8897 if (status->rtscnt) { 8898 if (status->rtscnt == 0xf) 8899 stats->rtsfail++; 8900 else 8901 stats->rts++; 8902 } 8903 8904 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8905 if (status->ack) { 8906 dr = bwn_dma_parse_cookie(mac, status, 8907 status->cookie, &slot); 8908 if (dr == NULL) { 8909 device_printf(sc->sc_dev, 8910 "failed to parse cookie\n"); 8911 return; 8912 } 8913 while (1) { 8914 dr->getdesc(dr, slot, &desc, &meta); 8915 if (meta->mt_islast) { 8916 ni = meta->mt_ni; 8917 vap = ni->ni_vap; 8918 ieee80211_ratectl_tx_complete(vap, ni, 8919 status->ack ? 8920 IEEE80211_RATECTL_TX_SUCCESS : 8921 IEEE80211_RATECTL_TX_FAILURE, 8922 &retrycnt, 0); 8923 break; 8924 } 8925 slot = bwn_dma_nextslot(dr, slot); 8926 } 8927 } 8928 bwn_dma_handle_txeof(mac, status); 8929 } else { 8930 if (status->ack) { 8931 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 8932 if (tq == NULL) { 8933 device_printf(sc->sc_dev, 8934 "failed to parse cookie\n"); 8935 return; 8936 } 8937 ni = tp->tp_ni; 8938 vap = ni->ni_vap; 8939 ieee80211_ratectl_tx_complete(vap, ni, 8940 status->ack ? 8941 IEEE80211_RATECTL_TX_SUCCESS : 8942 IEEE80211_RATECTL_TX_FAILURE, 8943 &retrycnt, 0); 8944 } 8945 bwn_pio_handle_txeof(mac, status); 8946 } 8947 8948 bwn_phy_txpower_check(mac, 0); 8949 } 8950 8951 static uint8_t 8952 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 8953 { 8954 struct bwn_mac *mac = prq->prq_mac; 8955 struct bwn_softc *sc = mac->mac_sc; 8956 struct bwn_rxhdr4 rxhdr; 8957 struct ifnet *ifp = sc->sc_ifp; 8958 struct mbuf *m; 8959 uint32_t ctl32, macstat, v32; 8960 unsigned int i, padding; 8961 uint16_t ctl16, len, totlen, v16; 8962 unsigned char *mp; 8963 char *data; 8964 8965 memset(&rxhdr, 0, sizeof(rxhdr)); 8966 8967 if (prq->prq_rev >= 8) { 8968 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8969 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 8970 return (0); 8971 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 8972 BWN_PIO8_RXCTL_FRAMEREADY); 8973 for (i = 0; i < 10; i++) { 8974 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8975 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 8976 goto ready; 8977 DELAY(10); 8978 } 8979 } else { 8980 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8981 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 8982 return (0); 8983 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 8984 BWN_PIO_RXCTL_FRAMEREADY); 8985 for (i = 0; i < 10; i++) { 8986 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8987 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 8988 goto ready; 8989 DELAY(10); 8990 } 8991 } 8992 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 8993 return (1); 8994 ready: 8995 if (prq->prq_rev >= 8) 8996 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8997 prq->prq_base + BWN_PIO8_RXDATA); 8998 else 8999 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9000 prq->prq_base + BWN_PIO_RXDATA); 9001 len = le16toh(rxhdr.frame_len); 9002 if (len > 0x700) { 9003 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9004 goto error; 9005 } 9006 if (len == 0) { 9007 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9008 goto error; 9009 } 9010 9011 macstat = le32toh(rxhdr.mac_status); 9012 if (macstat & BWN_RX_MAC_FCSERR) { 9013 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9014 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9015 goto error; 9016 } 9017 } 9018 9019 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9020 totlen = len + padding; 9021 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9022 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9023 if (m == NULL) { 9024 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9025 goto error; 9026 } 9027 mp = mtod(m, unsigned char *); 9028 if (prq->prq_rev >= 8) { 9029 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9030 prq->prq_base + BWN_PIO8_RXDATA); 9031 if (totlen & 3) { 9032 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9033 data = &(mp[totlen - 1]); 9034 switch (totlen & 3) { 9035 case 3: 9036 *data = (v32 >> 16); 9037 data--; 9038 case 2: 9039 *data = (v32 >> 8); 9040 data--; 9041 case 1: 9042 *data = v32; 9043 } 9044 } 9045 } else { 9046 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9047 prq->prq_base + BWN_PIO_RXDATA); 9048 if (totlen & 1) { 9049 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9050 mp[totlen - 1] = v16; 9051 } 9052 } 9053 9054 m->m_pkthdr.rcvif = ifp; 9055 m->m_len = m->m_pkthdr.len = totlen; 9056 9057 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9058 9059 return (1); 9060 error: 9061 if (prq->prq_rev >= 8) 9062 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9063 BWN_PIO8_RXCTL_DATAREADY); 9064 else 9065 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9066 return (1); 9067 } 9068 9069 static int 9070 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9071 struct bwn_dmadesc_meta *meta, int init) 9072 { 9073 struct bwn_mac *mac = dr->dr_mac; 9074 struct bwn_dma *dma = &mac->mac_method.dma; 9075 struct bwn_rxhdr4 *hdr; 9076 bus_dmamap_t map; 9077 bus_addr_t paddr; 9078 struct mbuf *m; 9079 int error; 9080 9081 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9082 if (m == NULL) { 9083 error = ENOBUFS; 9084 9085 /* 9086 * If the NIC is up and running, we need to: 9087 * - Clear RX buffer's header. 9088 * - Restore RX descriptor settings. 9089 */ 9090 if (init) 9091 return (error); 9092 else 9093 goto back; 9094 } 9095 m->m_len = m->m_pkthdr.len = MCLBYTES; 9096 9097 bwn_dma_set_redzone(dr, m); 9098 9099 /* 9100 * Try to load RX buf into temporary DMA map 9101 */ 9102 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9103 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9104 if (error) { 9105 m_freem(m); 9106 9107 /* 9108 * See the comment above 9109 */ 9110 if (init) 9111 return (error); 9112 else 9113 goto back; 9114 } 9115 9116 if (!init) 9117 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9118 meta->mt_m = m; 9119 meta->mt_paddr = paddr; 9120 9121 /* 9122 * Swap RX buf's DMA map with the loaded temporary one 9123 */ 9124 map = meta->mt_dmap; 9125 meta->mt_dmap = dr->dr_spare_dmap; 9126 dr->dr_spare_dmap = map; 9127 9128 back: 9129 /* 9130 * Clear RX buf header 9131 */ 9132 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9133 bzero(hdr, sizeof(*hdr)); 9134 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9135 BUS_DMASYNC_PREWRITE); 9136 9137 /* 9138 * Setup RX buf descriptor 9139 */ 9140 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9141 sizeof(*hdr), 0, 0, 0); 9142 return (error); 9143 } 9144 9145 static void 9146 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9147 bus_size_t mapsz __unused, int error) 9148 { 9149 9150 if (!error) { 9151 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9152 *((bus_addr_t *)arg) = seg->ds_addr; 9153 } 9154 } 9155 9156 static int 9157 bwn_hwrate2ieeerate(int rate) 9158 { 9159 9160 switch (rate) { 9161 case BWN_CCK_RATE_1MB: 9162 return (2); 9163 case BWN_CCK_RATE_2MB: 9164 return (4); 9165 case BWN_CCK_RATE_5MB: 9166 return (11); 9167 case BWN_CCK_RATE_11MB: 9168 return (22); 9169 case BWN_OFDM_RATE_6MB: 9170 return (12); 9171 case BWN_OFDM_RATE_9MB: 9172 return (18); 9173 case BWN_OFDM_RATE_12MB: 9174 return (24); 9175 case BWN_OFDM_RATE_18MB: 9176 return (36); 9177 case BWN_OFDM_RATE_24MB: 9178 return (48); 9179 case BWN_OFDM_RATE_36MB: 9180 return (72); 9181 case BWN_OFDM_RATE_48MB: 9182 return (96); 9183 case BWN_OFDM_RATE_54MB: 9184 return (108); 9185 default: 9186 kprintf("Ooops\n"); 9187 return (0); 9188 } 9189 } 9190 9191 static void 9192 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9193 { 9194 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9195 struct bwn_plcp6 *plcp; 9196 struct bwn_softc *sc = mac->mac_sc; 9197 struct ieee80211_frame_min *wh; 9198 struct ieee80211_node *ni; 9199 struct ifnet *ifp = sc->sc_ifp; 9200 struct ieee80211com *ic = ifp->if_l2com; 9201 uint32_t macstat; 9202 int padding, rate, rssi = 0, noise = 0, type; 9203 uint16_t phytype, phystat0, phystat3, chanstat; 9204 unsigned char *mp = mtod(m, unsigned char *); 9205 static int rx_mac_dec_rpt = 0; 9206 9207 phystat0 = le16toh(rxhdr->phy_status0); 9208 phystat3 = le16toh(rxhdr->phy_status3); 9209 macstat = le32toh(rxhdr->mac_status); 9210 chanstat = le16toh(rxhdr->channel); 9211 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9212 9213 if (macstat & BWN_RX_MAC_FCSERR) 9214 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9215 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9216 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9217 if (macstat & BWN_RX_MAC_DECERR) 9218 goto drop; 9219 9220 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9221 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9222 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9223 m->m_pkthdr.len); 9224 goto drop; 9225 } 9226 plcp = (struct bwn_plcp6 *)(mp + padding); 9227 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9228 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9229 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9230 m->m_pkthdr.len); 9231 goto drop; 9232 } 9233 wh = mtod(m, struct ieee80211_frame_min *); 9234 9235 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9236 device_printf(sc->sc_dev, 9237 "RX decryption attempted (old %d keyidx %#x)\n", 9238 BWN_ISOLDFMT(mac), 9239 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9240 9241 /* XXX calculating RSSI & noise & antenna */ 9242 9243 if (phystat0 & BWN_RX_PHYST0_OFDM) 9244 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9245 phytype == BWN_PHYTYPE_A); 9246 else 9247 rate = bwn_plcp_get_cckrate(mac, plcp); 9248 if (rate == -1) { 9249 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9250 goto drop; 9251 } 9252 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9253 9254 /* RX radio tap */ 9255 if (ieee80211_radiotap_active(ic)) 9256 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9257 m_adj(m, -IEEE80211_CRC_LEN); 9258 9259 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9260 noise = mac->mac_stats.link_noise; 9261 9262 ifp->if_ipackets++; 9263 9264 ni = ieee80211_find_rxnode(ic, wh); 9265 if (ni != NULL) { 9266 type = ieee80211_input(ni, m, rssi, noise); 9267 ieee80211_free_node(ni); 9268 } else 9269 type = ieee80211_input_all(ic, m, rssi, noise); 9270 9271 return; 9272 drop: 9273 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9274 } 9275 9276 static void 9277 bwn_dma_handle_txeof(struct bwn_mac *mac, 9278 const struct bwn_txstatus *status) 9279 { 9280 struct bwn_dma *dma = &mac->mac_method.dma; 9281 struct bwn_dma_ring *dr; 9282 struct bwn_dmadesc_generic *desc; 9283 struct bwn_dmadesc_meta *meta; 9284 struct bwn_softc *sc = mac->mac_sc; 9285 struct ieee80211_node *ni; 9286 struct ifnet *ifp = sc->sc_ifp; 9287 struct mbuf *m; 9288 int slot; 9289 9290 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9291 if (dr == NULL) { 9292 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9293 return; 9294 } 9295 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9296 9297 while (1) { 9298 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9299 ("%s:%d: fail", __func__, __LINE__)); 9300 dr->getdesc(dr, slot, &desc, &meta); 9301 9302 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 9303 bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap, 9304 BUS_DMASYNC_POSTWRITE); 9305 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 9306 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9307 } 9308 9309 if (meta->mt_islast) { 9310 KASSERT(meta->mt_m != NULL, 9311 ("%s:%d: fail", __func__, __LINE__)); 9312 9313 ni = meta->mt_ni; 9314 m = meta->mt_m; 9315 if (ni != NULL) { 9316 /* 9317 * Do any tx complete callback. Note this must 9318 * be done before releasing the node reference. 9319 */ 9320 if (m->m_flags & M_TXCB) 9321 ieee80211_process_callback(ni, m, 0); 9322 ieee80211_free_node(ni); 9323 meta->mt_ni = NULL; 9324 } 9325 m_freem(m); 9326 meta->mt_m = NULL; 9327 } else { 9328 KASSERT(meta->mt_m == NULL, 9329 ("%s:%d: fail", __func__, __LINE__)); 9330 } 9331 9332 dr->dr_usedslot--; 9333 if (meta->mt_islast) { 9334 ifp->if_opackets++; 9335 break; 9336 } 9337 slot = bwn_dma_nextslot(dr, slot); 9338 } 9339 sc->sc_watchdog_timer = 0; 9340 if (dr->dr_stop) { 9341 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9342 ("%s:%d: fail", __func__, __LINE__)); 9343 ifq_clr_oactive(&ifp->if_snd); 9344 dr->dr_stop = 0; 9345 } 9346 } 9347 9348 static void 9349 bwn_pio_handle_txeof(struct bwn_mac *mac, 9350 const struct bwn_txstatus *status) 9351 { 9352 struct bwn_pio_txqueue *tq; 9353 struct bwn_pio_txpkt *tp = NULL; 9354 struct bwn_softc *sc = mac->mac_sc; 9355 struct ifnet *ifp = sc->sc_ifp; 9356 9357 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9358 if (tq == NULL) 9359 return; 9360 9361 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9362 tq->tq_free++; 9363 9364 if (tp->tp_ni != NULL) { 9365 /* 9366 * Do any tx complete callback. Note this must 9367 * be done before releasing the node reference. 9368 */ 9369 if (tp->tp_m->m_flags & M_TXCB) 9370 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9371 ieee80211_free_node(tp->tp_ni); 9372 tp->tp_ni = NULL; 9373 } 9374 m_freem(tp->tp_m); 9375 tp->tp_m = NULL; 9376 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9377 9378 ifp->if_opackets++; 9379 9380 sc->sc_watchdog_timer = 0; 9381 if (tq->tq_stop) { 9382 ifq_clr_oactive(&ifp->if_snd); 9383 tq->tq_stop = 0; 9384 } 9385 } 9386 9387 static void 9388 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9389 { 9390 struct bwn_softc *sc = mac->mac_sc; 9391 struct bwn_phy *phy = &mac->mac_phy; 9392 struct ifnet *ifp = sc->sc_ifp; 9393 struct ieee80211com *ic = ifp->if_l2com; 9394 unsigned long now; 9395 int result; 9396 9397 BWN_GETTIME(now); 9398 9399 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9400 return; 9401 phy->nexttime = now + 2 * 1000; 9402 9403 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9404 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9405 return; 9406 9407 if (phy->recalc_txpwr != NULL) { 9408 result = phy->recalc_txpwr(mac, 9409 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9410 if (result == BWN_TXPWR_RES_DONE) 9411 return; 9412 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9413 ("%s: fail", __func__)); 9414 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9415 9416 ieee80211_runtask(ic, &mac->mac_txpower); 9417 } 9418 } 9419 9420 static uint16_t 9421 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9422 { 9423 9424 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9425 } 9426 9427 static uint32_t 9428 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9429 { 9430 9431 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9432 } 9433 9434 static void 9435 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9436 { 9437 9438 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9439 } 9440 9441 static void 9442 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9443 { 9444 9445 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9446 } 9447 9448 static int 9449 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9450 { 9451 9452 switch (rate) { 9453 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9454 case 12: 9455 return (BWN_OFDM_RATE_6MB); 9456 case 18: 9457 return (BWN_OFDM_RATE_9MB); 9458 case 24: 9459 return (BWN_OFDM_RATE_12MB); 9460 case 36: 9461 return (BWN_OFDM_RATE_18MB); 9462 case 48: 9463 return (BWN_OFDM_RATE_24MB); 9464 case 72: 9465 return (BWN_OFDM_RATE_36MB); 9466 case 96: 9467 return (BWN_OFDM_RATE_48MB); 9468 case 108: 9469 return (BWN_OFDM_RATE_54MB); 9470 /* CCK rates (NB: not IEEE std, device-specific) */ 9471 case 2: 9472 return (BWN_CCK_RATE_1MB); 9473 case 4: 9474 return (BWN_CCK_RATE_2MB); 9475 case 11: 9476 return (BWN_CCK_RATE_5MB); 9477 case 22: 9478 return (BWN_CCK_RATE_11MB); 9479 } 9480 9481 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9482 return (BWN_CCK_RATE_1MB); 9483 } 9484 9485 static int 9486 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9487 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9488 { 9489 const struct bwn_phy *phy = &mac->mac_phy; 9490 struct bwn_softc *sc = mac->mac_sc; 9491 struct ieee80211_frame *wh; 9492 struct ieee80211_frame *protwh; 9493 struct ieee80211_frame_cts *cts; 9494 struct ieee80211_frame_rts *rts; 9495 const struct ieee80211_txparam *tp; 9496 struct ieee80211vap *vap = ni->ni_vap; 9497 struct ifnet *ifp = sc->sc_ifp; 9498 struct ieee80211com *ic = ifp->if_l2com; 9499 struct mbuf *mprot; 9500 unsigned int len; 9501 uint32_t macctl = 0; 9502 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9503 uint16_t phyctl = 0; 9504 uint8_t rate, rate_fb; 9505 9506 wh = mtod(m, struct ieee80211_frame *); 9507 memset(txhdr, 0, sizeof(*txhdr)); 9508 9509 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9510 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9511 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9512 9513 /* 9514 * Find TX rate 9515 */ 9516 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9517 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9518 rate = rate_fb = tp->mgmtrate; 9519 else if (ismcast) 9520 rate = rate_fb = tp->mcastrate; 9521 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9522 rate = rate_fb = tp->ucastrate; 9523 else { 9524 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9525 rate = ni->ni_txrate; 9526 9527 if (rix > 0) 9528 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9529 IEEE80211_RATE_VAL; 9530 else 9531 rate_fb = rate; 9532 } 9533 9534 sc->sc_tx_rate = rate; 9535 9536 rate = bwn_ieeerate2hwrate(sc, rate); 9537 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9538 9539 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9540 bwn_plcp_getcck(rate); 9541 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9542 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9543 9544 if ((rate_fb == rate) || 9545 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9546 (*(u_int16_t *)wh->i_dur == htole16(0))) 9547 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9548 else 9549 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9550 m->m_pkthdr.len, rate, isshort); 9551 9552 /* XXX TX encryption */ 9553 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9554 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9555 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9556 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9557 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9558 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9559 9560 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9561 BWN_TX_EFT_FB_CCK; 9562 txhdr->chan = phy->chan; 9563 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9564 BWN_TX_PHY_ENC_CCK; 9565 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9566 rate == BWN_CCK_RATE_11MB)) 9567 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9568 9569 /* XXX TX antenna selection */ 9570 9571 switch (bwn_antenna_sanitize(mac, 0)) { 9572 case 0: 9573 phyctl |= BWN_TX_PHY_ANT01AUTO; 9574 break; 9575 case 1: 9576 phyctl |= BWN_TX_PHY_ANT0; 9577 break; 9578 case 2: 9579 phyctl |= BWN_TX_PHY_ANT1; 9580 break; 9581 case 3: 9582 phyctl |= BWN_TX_PHY_ANT2; 9583 break; 9584 case 4: 9585 phyctl |= BWN_TX_PHY_ANT3; 9586 break; 9587 default: 9588 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9589 } 9590 9591 if (!ismcast) 9592 macctl |= BWN_TX_MAC_ACK; 9593 9594 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9595 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9596 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9597 macctl |= BWN_TX_MAC_LONGFRAME; 9598 9599 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9600 /* XXX RTS rate is always 1MB??? */ 9601 rts_rate = BWN_CCK_RATE_1MB; 9602 rts_rate_fb = bwn_get_fbrate(rts_rate); 9603 9604 protdur = ieee80211_compute_duration(ic->ic_rt, 9605 m->m_pkthdr.len, rate, isshort) + 9606 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9607 9608 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9609 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9610 (txhdr->body.old.rts_frame) : 9611 (txhdr->body.new.rts_frame)); 9612 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9613 protdur); 9614 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9615 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9616 mprot->m_pkthdr.len); 9617 m_freem(mprot); 9618 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9619 len = sizeof(struct ieee80211_frame_cts); 9620 } else { 9621 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9622 (txhdr->body.old.rts_frame) : 9623 (txhdr->body.new.rts_frame)); 9624 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9625 isshort); 9626 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9627 wh->i_addr2, protdur); 9628 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9629 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9630 mprot->m_pkthdr.len); 9631 m_freem(mprot); 9632 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9633 len = sizeof(struct ieee80211_frame_rts); 9634 } 9635 len += IEEE80211_CRC_LEN; 9636 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9637 &txhdr->body.old.rts_plcp : 9638 &txhdr->body.new.rts_plcp), len, rts_rate); 9639 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9640 rts_rate_fb); 9641 9642 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9643 (&txhdr->body.old.rts_frame) : 9644 (&txhdr->body.new.rts_frame)); 9645 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9646 9647 if (BWN_ISOFDMRATE(rts_rate)) { 9648 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9649 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9650 } else { 9651 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9652 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9653 } 9654 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9655 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9656 } 9657 9658 if (BWN_ISOLDFMT(mac)) 9659 txhdr->body.old.cookie = htole16(cookie); 9660 else 9661 txhdr->body.new.cookie = htole16(cookie); 9662 9663 txhdr->macctl = htole32(macctl); 9664 txhdr->phyctl = htole16(phyctl); 9665 9666 /* 9667 * TX radio tap 9668 */ 9669 if (ieee80211_radiotap_active_vap(vap)) { 9670 sc->sc_tx_th.wt_flags = 0; 9671 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9672 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9673 if (isshort && 9674 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9675 rate == BWN_CCK_RATE_11MB)) 9676 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9677 sc->sc_tx_th.wt_rate = rate; 9678 9679 ieee80211_radiotap_tx(vap, m); 9680 } 9681 9682 return (0); 9683 } 9684 9685 static void 9686 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9687 const uint8_t rate) 9688 { 9689 uint32_t d, plen; 9690 uint8_t *raw = plcp->o.raw; 9691 9692 if (BWN_ISOFDMRATE(rate)) { 9693 d = bwn_plcp_getofdm(rate); 9694 KASSERT(!(octets & 0xf000), 9695 ("%s:%d: fail", __func__, __LINE__)); 9696 d |= (octets << 5); 9697 plcp->o.data = htole32(d); 9698 } else { 9699 plen = octets * 16 / rate; 9700 if ((octets * 16 % rate) > 0) { 9701 plen++; 9702 if ((rate == BWN_CCK_RATE_11MB) 9703 && ((octets * 8 % 11) < 4)) { 9704 raw[1] = 0x84; 9705 } else 9706 raw[1] = 0x04; 9707 } else 9708 raw[1] = 0x04; 9709 plcp->o.data |= htole32(plen << 16); 9710 raw[0] = bwn_plcp_getcck(rate); 9711 } 9712 } 9713 9714 static uint8_t 9715 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9716 { 9717 struct bwn_softc *sc = mac->mac_sc; 9718 uint8_t mask; 9719 9720 if (n == 0) 9721 return (0); 9722 if (mac->mac_phy.gmode) 9723 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9724 else 9725 mask = siba_sprom_get_ant_a(sc->sc_dev); 9726 if (!(mask & (1 << (n - 1)))) 9727 return (0); 9728 return (n); 9729 } 9730 9731 static uint8_t 9732 bwn_get_fbrate(uint8_t bitrate) 9733 { 9734 switch (bitrate) { 9735 case BWN_CCK_RATE_1MB: 9736 return (BWN_CCK_RATE_1MB); 9737 case BWN_CCK_RATE_2MB: 9738 return (BWN_CCK_RATE_1MB); 9739 case BWN_CCK_RATE_5MB: 9740 return (BWN_CCK_RATE_2MB); 9741 case BWN_CCK_RATE_11MB: 9742 return (BWN_CCK_RATE_5MB); 9743 case BWN_OFDM_RATE_6MB: 9744 return (BWN_CCK_RATE_5MB); 9745 case BWN_OFDM_RATE_9MB: 9746 return (BWN_OFDM_RATE_6MB); 9747 case BWN_OFDM_RATE_12MB: 9748 return (BWN_OFDM_RATE_9MB); 9749 case BWN_OFDM_RATE_18MB: 9750 return (BWN_OFDM_RATE_12MB); 9751 case BWN_OFDM_RATE_24MB: 9752 return (BWN_OFDM_RATE_18MB); 9753 case BWN_OFDM_RATE_36MB: 9754 return (BWN_OFDM_RATE_24MB); 9755 case BWN_OFDM_RATE_48MB: 9756 return (BWN_OFDM_RATE_36MB); 9757 case BWN_OFDM_RATE_54MB: 9758 return (BWN_OFDM_RATE_48MB); 9759 } 9760 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9761 return (0); 9762 } 9763 9764 static uint32_t 9765 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9766 uint32_t ctl, const void *_data, int len) 9767 { 9768 struct bwn_softc *sc = mac->mac_sc; 9769 uint32_t value = 0; 9770 const uint8_t *data = _data; 9771 9772 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9773 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9774 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9775 9776 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9777 tq->tq_base + BWN_PIO8_TXDATA); 9778 if (len & 3) { 9779 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9780 BWN_PIO8_TXCTL_24_31); 9781 data = &(data[len - 1]); 9782 switch (len & 3) { 9783 case 3: 9784 ctl |= BWN_PIO8_TXCTL_16_23; 9785 value |= (uint32_t)(*data) << 16; 9786 data--; 9787 case 2: 9788 ctl |= BWN_PIO8_TXCTL_8_15; 9789 value |= (uint32_t)(*data) << 8; 9790 data--; 9791 case 1: 9792 value |= (uint32_t)(*data); 9793 } 9794 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9795 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9796 } 9797 9798 return (ctl); 9799 } 9800 9801 static void 9802 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9803 uint16_t offset, uint32_t value) 9804 { 9805 9806 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9807 } 9808 9809 static uint16_t 9810 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9811 uint16_t ctl, const void *_data, int len) 9812 { 9813 struct bwn_softc *sc = mac->mac_sc; 9814 const uint8_t *data = _data; 9815 9816 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9817 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9818 9819 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9820 tq->tq_base + BWN_PIO_TXDATA); 9821 if (len & 1) { 9822 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9823 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9824 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9825 } 9826 9827 return (ctl); 9828 } 9829 9830 static uint16_t 9831 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9832 uint16_t ctl, struct mbuf *m0) 9833 { 9834 int i, j = 0; 9835 uint16_t data = 0; 9836 const uint8_t *buf; 9837 struct mbuf *m = m0; 9838 9839 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9840 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9841 9842 for (; m != NULL; m = m->m_next) { 9843 buf = mtod(m, const uint8_t *); 9844 for (i = 0; i < m->m_len; i++) { 9845 if (!((j++) % 2)) 9846 data |= buf[i]; 9847 else { 9848 data |= (buf[i] << 8); 9849 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9850 data = 0; 9851 } 9852 } 9853 } 9854 if (m0->m_pkthdr.len % 2) { 9855 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9856 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9857 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9858 } 9859 9860 return (ctl); 9861 } 9862 9863 static void 9864 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9865 { 9866 9867 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9868 return; 9869 BWN_WRITE_2(mac, 0x684, 510 + time); 9870 9871 /* 9872 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a 9873 * a severe performance penalty (especially when sending). 9874 */ 9875 #if 0 9876 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9877 #endif 9878 } 9879 9880 static struct bwn_dma_ring * 9881 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9882 { 9883 9884 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9885 return (mac->mac_method.dma.wme[WME_AC_BE]); 9886 9887 switch (prio) { 9888 case 3: 9889 return (mac->mac_method.dma.wme[WME_AC_VO]); 9890 case 2: 9891 return (mac->mac_method.dma.wme[WME_AC_VI]); 9892 case 0: 9893 return (mac->mac_method.dma.wme[WME_AC_BE]); 9894 case 1: 9895 return (mac->mac_method.dma.wme[WME_AC_BK]); 9896 } 9897 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9898 return (NULL); 9899 } 9900 9901 static int 9902 bwn_dma_getslot(struct bwn_dma_ring *dr) 9903 { 9904 int slot; 9905 9906 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9907 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 9908 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 9909 9910 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 9911 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 9912 dr->dr_curslot = slot; 9913 dr->dr_usedslot++; 9914 9915 return (slot); 9916 } 9917 9918 static int 9919 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 9920 { 9921 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 9922 unsigned int a, b, c, d; 9923 unsigned int avg; 9924 uint32_t tmp; 9925 9926 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 9927 a = tmp & 0xff; 9928 b = (tmp >> 8) & 0xff; 9929 c = (tmp >> 16) & 0xff; 9930 d = (tmp >> 24) & 0xff; 9931 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 9932 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 9933 return (ENOENT); 9934 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 9935 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 9936 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 9937 9938 if (ofdm) { 9939 a = (a + 32) & 0x3f; 9940 b = (b + 32) & 0x3f; 9941 c = (c + 32) & 0x3f; 9942 d = (d + 32) & 0x3f; 9943 } 9944 9945 avg = (a + b + c + d + 2) / 4; 9946 if (ofdm) { 9947 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 9948 & BWN_HF_4DB_CCK_POWERBOOST) 9949 avg = (avg >= 13) ? (avg - 13) : 0; 9950 } 9951 return (avg); 9952 } 9953 9954 static void 9955 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 9956 { 9957 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 9958 int rfatt = *rfattp; 9959 int bbatt = *bbattp; 9960 9961 while (1) { 9962 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 9963 break; 9964 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 9965 break; 9966 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 9967 break; 9968 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 9969 break; 9970 if (bbatt > lo->bbatt.max) { 9971 bbatt -= 4; 9972 rfatt += 1; 9973 continue; 9974 } 9975 if (bbatt < lo->bbatt.min) { 9976 bbatt += 4; 9977 rfatt -= 1; 9978 continue; 9979 } 9980 if (rfatt > lo->rfatt.max) { 9981 rfatt -= 1; 9982 bbatt += 4; 9983 continue; 9984 } 9985 if (rfatt < lo->rfatt.min) { 9986 rfatt += 1; 9987 bbatt -= 4; 9988 continue; 9989 } 9990 break; 9991 } 9992 9993 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 9994 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 9995 } 9996 9997 static void 9998 bwn_phy_lock(struct bwn_mac *mac) 9999 { 10000 struct bwn_softc *sc = mac->mac_sc; 10001 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10002 10003 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10004 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10005 10006 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10007 bwn_psctl(mac, BWN_PS_AWAKE); 10008 } 10009 10010 static void 10011 bwn_phy_unlock(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, 0); 10021 } 10022 10023 static void 10024 bwn_rf_lock(struct bwn_mac *mac) 10025 { 10026 10027 BWN_WRITE_4(mac, BWN_MACCTL, 10028 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10029 BWN_READ_4(mac, BWN_MACCTL); 10030 DELAY(10); 10031 } 10032 10033 static void 10034 bwn_rf_unlock(struct bwn_mac *mac) 10035 { 10036 10037 BWN_READ_2(mac, BWN_PHYVER); 10038 BWN_WRITE_4(mac, BWN_MACCTL, 10039 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10040 } 10041 10042 static struct bwn_pio_txqueue * 10043 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10044 struct bwn_pio_txpkt **pack) 10045 { 10046 struct bwn_pio *pio = &mac->mac_method.pio; 10047 struct bwn_pio_txqueue *tq = NULL; 10048 unsigned int index; 10049 10050 switch (cookie & 0xf000) { 10051 case 0x1000: 10052 tq = &pio->wme[WME_AC_BK]; 10053 break; 10054 case 0x2000: 10055 tq = &pio->wme[WME_AC_BE]; 10056 break; 10057 case 0x3000: 10058 tq = &pio->wme[WME_AC_VI]; 10059 break; 10060 case 0x4000: 10061 tq = &pio->wme[WME_AC_VO]; 10062 break; 10063 case 0x5000: 10064 tq = &pio->mcast; 10065 break; 10066 } 10067 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10068 if (tq == NULL) 10069 return (NULL); 10070 index = (cookie & 0x0fff); 10071 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10072 if (index >= N(tq->tq_pkts)) 10073 return (NULL); 10074 *pack = &tq->tq_pkts[index]; 10075 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10076 return (tq); 10077 } 10078 10079 static void 10080 bwn_txpwr(void *arg, int npending) 10081 { 10082 struct bwn_mac *mac = arg; 10083 10084 wlan_serialize_enter(); 10085 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10086 mac->mac_phy.set_txpwr != NULL) 10087 mac->mac_phy.set_txpwr(mac); 10088 wlan_serialize_exit(); 10089 } 10090 10091 static void 10092 bwn_task_15s(struct bwn_mac *mac) 10093 { 10094 uint16_t reg; 10095 10096 if (mac->mac_fw.opensource) { 10097 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10098 if (reg) { 10099 bwn_restart(mac, "fw watchdog"); 10100 return; 10101 } 10102 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10103 } 10104 if (mac->mac_phy.task_15s) 10105 mac->mac_phy.task_15s(mac); 10106 10107 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10108 } 10109 10110 static void 10111 bwn_task_30s(struct bwn_mac *mac) 10112 { 10113 10114 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10115 return; 10116 mac->mac_noise.noi_running = 1; 10117 mac->mac_noise.noi_nsamples = 0; 10118 10119 bwn_noise_gensample(mac); 10120 } 10121 10122 static void 10123 bwn_task_60s(struct bwn_mac *mac) 10124 { 10125 10126 if (mac->mac_phy.task_60s) 10127 mac->mac_phy.task_60s(mac); 10128 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10129 } 10130 10131 static void 10132 bwn_tasks(void *arg) 10133 { 10134 struct bwn_mac *mac = arg; 10135 struct bwn_softc *sc = mac->mac_sc; 10136 10137 wlan_serialize_enter(); 10138 10139 if (mac->mac_status != BWN_MAC_STATUS_STARTED) { 10140 wlan_serialize_exit(); 10141 return; 10142 } 10143 10144 if (mac->mac_task_state % 4 == 0) 10145 bwn_task_60s(mac); 10146 if (mac->mac_task_state % 2 == 0) 10147 bwn_task_30s(mac); 10148 bwn_task_15s(mac); 10149 10150 mac->mac_task_state++; 10151 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10152 wlan_serialize_exit(); 10153 } 10154 10155 static int 10156 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10157 { 10158 struct bwn_softc *sc = mac->mac_sc; 10159 10160 KASSERT(a == 0, ("not support APHY\n")); 10161 10162 switch (plcp->o.raw[0] & 0xf) { 10163 case 0xb: 10164 return (BWN_OFDM_RATE_6MB); 10165 case 0xf: 10166 return (BWN_OFDM_RATE_9MB); 10167 case 0xa: 10168 return (BWN_OFDM_RATE_12MB); 10169 case 0xe: 10170 return (BWN_OFDM_RATE_18MB); 10171 case 0x9: 10172 return (BWN_OFDM_RATE_24MB); 10173 case 0xd: 10174 return (BWN_OFDM_RATE_36MB); 10175 case 0x8: 10176 return (BWN_OFDM_RATE_48MB); 10177 case 0xc: 10178 return (BWN_OFDM_RATE_54MB); 10179 } 10180 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10181 plcp->o.raw[0] & 0xf); 10182 return (-1); 10183 } 10184 10185 static int 10186 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10187 { 10188 struct bwn_softc *sc = mac->mac_sc; 10189 10190 switch (plcp->o.raw[0]) { 10191 case 0x0a: 10192 return (BWN_CCK_RATE_1MB); 10193 case 0x14: 10194 return (BWN_CCK_RATE_2MB); 10195 case 0x37: 10196 return (BWN_CCK_RATE_5MB); 10197 case 0x6e: 10198 return (BWN_CCK_RATE_11MB); 10199 } 10200 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10201 return (-1); 10202 } 10203 10204 static void 10205 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10206 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10207 int rssi, int noise) 10208 { 10209 struct bwn_softc *sc = mac->mac_sc; 10210 const struct ieee80211_frame_min *wh; 10211 uint64_t tsf; 10212 uint16_t low_mactime_now; 10213 10214 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10215 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10216 10217 wh = mtod(m, const struct ieee80211_frame_min *); 10218 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10219 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10220 10221 bwn_tsf_read(mac, &tsf); 10222 low_mactime_now = tsf; 10223 tsf = tsf & ~0xffffULL; 10224 tsf += le16toh(rxhdr->mac_time); 10225 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10226 tsf -= 0x10000; 10227 10228 sc->sc_rx_th.wr_tsf = tsf; 10229 sc->sc_rx_th.wr_rate = rate; 10230 sc->sc_rx_th.wr_antsignal = rssi; 10231 sc->sc_rx_th.wr_antnoise = noise; 10232 } 10233 10234 static void 10235 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10236 { 10237 uint32_t low, high; 10238 10239 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10240 ("%s:%d: fail", __func__, __LINE__)); 10241 10242 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10243 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10244 *tsf = high; 10245 *tsf <<= 32; 10246 *tsf |= low; 10247 } 10248 10249 static int 10250 bwn_dma_attach(struct bwn_mac *mac) 10251 { 10252 struct bwn_dma *dma = &mac->mac_method.dma; 10253 struct bwn_softc *sc = mac->mac_sc; 10254 bus_addr_t lowaddr = 0; 10255 int error; 10256 10257 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10258 return (0); 10259 10260 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10261 10262 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10263 10264 dma->dmatype = bwn_dma_gettype(mac); 10265 if (dma->dmatype == BWN_DMA_30BIT) 10266 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10267 else if (dma->dmatype == BWN_DMA_32BIT) 10268 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10269 else 10270 lowaddr = BUS_SPACE_MAXADDR; 10271 10272 /* 10273 * Create top level DMA tag 10274 */ 10275 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10276 BWN_ALIGN, 0, /* alignment, bounds */ 10277 lowaddr, /* lowaddr */ 10278 BUS_SPACE_MAXADDR, /* highaddr */ 10279 NULL, NULL, /* filter, filterarg */ 10280 MAXBSIZE, /* maxsize */ 10281 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10282 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10283 0, /* flags */ 10284 &dma->parent_dtag); 10285 if (error) { 10286 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10287 return (error); 10288 } 10289 10290 /* 10291 * Create TX/RX mbuf DMA tag 10292 */ 10293 error = bus_dma_tag_create(dma->parent_dtag, 10294 4, 10295 0, 10296 BUS_SPACE_MAXADDR, 10297 BUS_SPACE_MAXADDR, 10298 NULL, NULL, 10299 MCLBYTES, 10300 1, 10301 BUS_SPACE_MAXSIZE_32BIT, 10302 0, 10303 &dma->rxbuf_dtag); 10304 if (error) { 10305 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10306 goto fail0; 10307 } 10308 error = bus_dma_tag_create(dma->parent_dtag, 10309 4, 10310 0, 10311 BUS_SPACE_MAXADDR, 10312 BUS_SPACE_MAXADDR, 10313 NULL, NULL, 10314 MCLBYTES, 10315 1, 10316 BUS_SPACE_MAXSIZE_32BIT, 10317 0, 10318 &dma->txbuf_dtag); 10319 if (error) { 10320 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10321 goto fail1; 10322 } 10323 10324 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10325 if (dma->wme[WME_AC_BK] == NULL) 10326 goto fail2; 10327 10328 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10329 if (dma->wme[WME_AC_BE] == NULL) 10330 goto fail3; 10331 10332 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10333 if (dma->wme[WME_AC_VI] == NULL) 10334 goto fail4; 10335 10336 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10337 if (dma->wme[WME_AC_VO] == NULL) 10338 goto fail5; 10339 10340 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10341 if (dma->mcast == NULL) 10342 goto fail6; 10343 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10344 if (dma->rx == NULL) 10345 goto fail7; 10346 10347 return (error); 10348 10349 fail7: bwn_dma_ringfree(&dma->mcast); 10350 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10351 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10352 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10353 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10354 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10355 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10356 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10357 return (error); 10358 } 10359 10360 static struct bwn_dma_ring * 10361 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10362 uint16_t cookie, int *slot) 10363 { 10364 struct bwn_dma *dma = &mac->mac_method.dma; 10365 struct bwn_dma_ring *dr; 10366 struct bwn_softc *sc = mac->mac_sc; 10367 10368 switch (cookie & 0xf000) { 10369 case 0x1000: 10370 dr = dma->wme[WME_AC_BK]; 10371 break; 10372 case 0x2000: 10373 dr = dma->wme[WME_AC_BE]; 10374 break; 10375 case 0x3000: 10376 dr = dma->wme[WME_AC_VI]; 10377 break; 10378 case 0x4000: 10379 dr = dma->wme[WME_AC_VO]; 10380 break; 10381 case 0x5000: 10382 dr = dma->mcast; 10383 break; 10384 default: 10385 dr = NULL; 10386 KASSERT(0 == 1, 10387 ("invalid cookie value %d", cookie & 0xf000)); 10388 } 10389 *slot = (cookie & 0x0fff); 10390 if (*slot < 0 || *slot >= dr->dr_numslots) { 10391 /* 10392 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10393 * that it occurs events which have same H/W sequence numbers. 10394 * When it's occurred just prints a WARNING msgs and ignores. 10395 */ 10396 KASSERT(status->seq == dma->lastseq, 10397 ("%s:%d: fail", __func__, __LINE__)); 10398 device_printf(sc->sc_dev, 10399 "out of slot ranges (0 < %d < %d)\n", *slot, 10400 dr->dr_numslots); 10401 return (NULL); 10402 } 10403 dma->lastseq = status->seq; 10404 return (dr); 10405 } 10406 10407 static void 10408 bwn_dma_stop(struct bwn_mac *mac) 10409 { 10410 struct bwn_dma *dma; 10411 10412 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10413 return; 10414 dma = &mac->mac_method.dma; 10415 10416 bwn_dma_ringstop(&dma->rx); 10417 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10418 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10419 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10420 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10421 bwn_dma_ringstop(&dma->mcast); 10422 } 10423 10424 static void 10425 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10426 { 10427 10428 if (dr == NULL) 10429 return; 10430 10431 bwn_dma_cleanup(*dr); 10432 } 10433 10434 static void 10435 bwn_pio_stop(struct bwn_mac *mac) 10436 { 10437 struct bwn_pio *pio; 10438 10439 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10440 return; 10441 pio = &mac->mac_method.pio; 10442 10443 bwn_destroy_queue_tx(&pio->mcast); 10444 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10445 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10446 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10447 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10448 } 10449 10450 static void 10451 bwn_led_attach(struct bwn_mac *mac) 10452 { 10453 struct bwn_softc *sc = mac->mac_sc; 10454 const uint8_t *led_act = NULL; 10455 uint16_t val[BWN_LED_MAX]; 10456 int i; 10457 10458 sc->sc_led_idle = (2350 * hz) / 1000; 10459 sc->sc_led_blink = 1; 10460 10461 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10462 if (siba_get_pci_subvendor(sc->sc_dev) == 10463 bwn_vendor_led_act[i].vid) { 10464 led_act = bwn_vendor_led_act[i].led_act; 10465 break; 10466 } 10467 } 10468 if (led_act == NULL) 10469 led_act = bwn_default_led_act; 10470 10471 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10472 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10473 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10474 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10475 10476 for (i = 0; i < BWN_LED_MAX; ++i) { 10477 struct bwn_led *led = &sc->sc_leds[i]; 10478 10479 if (val[i] == 0xff) { 10480 led->led_act = led_act[i]; 10481 } else { 10482 if (val[i] & BWN_LED_ACT_LOW) 10483 led->led_flags |= BWN_LED_F_ACTLOW; 10484 led->led_act = val[i] & BWN_LED_ACT_MASK; 10485 } 10486 led->led_mask = (1 << i); 10487 10488 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10489 led->led_act == BWN_LED_ACT_BLINK_POLL || 10490 led->led_act == BWN_LED_ACT_BLINK) { 10491 led->led_flags |= BWN_LED_F_BLINK; 10492 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10493 led->led_flags |= BWN_LED_F_POLLABLE; 10494 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10495 led->led_flags |= BWN_LED_F_SLOW; 10496 10497 if (sc->sc_blink_led == NULL) { 10498 sc->sc_blink_led = led; 10499 if (led->led_flags & BWN_LED_F_SLOW) 10500 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10501 } 10502 } 10503 10504 DPRINTF(sc, BWN_DEBUG_LED, 10505 "%dth led, act %d, lowact %d\n", i, 10506 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10507 } 10508 callout_init(&sc->sc_led_blink_ch); 10509 } 10510 10511 static __inline uint16_t 10512 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10513 { 10514 10515 if (led->led_flags & BWN_LED_F_ACTLOW) 10516 on = !on; 10517 if (on) 10518 val |= led->led_mask; 10519 else 10520 val &= ~led->led_mask; 10521 return val; 10522 } 10523 10524 static void 10525 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10526 { 10527 struct bwn_softc *sc = mac->mac_sc; 10528 struct ifnet *ifp = sc->sc_ifp; 10529 struct ieee80211com *ic = ifp->if_l2com; 10530 uint16_t val; 10531 int i; 10532 10533 if (nstate == IEEE80211_S_INIT) { 10534 callout_stop(&sc->sc_led_blink_ch); 10535 sc->sc_led_blinking = 0; 10536 } 10537 10538 if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0) 10539 return; 10540 10541 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10542 for (i = 0; i < BWN_LED_MAX; ++i) { 10543 struct bwn_led *led = &sc->sc_leds[i]; 10544 int on; 10545 10546 if (led->led_act == BWN_LED_ACT_UNKN || 10547 led->led_act == BWN_LED_ACT_NULL) 10548 continue; 10549 10550 if ((led->led_flags & BWN_LED_F_BLINK) && 10551 nstate != IEEE80211_S_INIT) 10552 continue; 10553 10554 switch (led->led_act) { 10555 case BWN_LED_ACT_ON: /* Always on */ 10556 on = 1; 10557 break; 10558 case BWN_LED_ACT_OFF: /* Always off */ 10559 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10560 on = 0; 10561 break; 10562 default: 10563 on = 1; 10564 switch (nstate) { 10565 case IEEE80211_S_INIT: 10566 on = 0; 10567 break; 10568 case IEEE80211_S_RUN: 10569 if (led->led_act == BWN_LED_ACT_11G && 10570 ic->ic_curmode != IEEE80211_MODE_11G) 10571 on = 0; 10572 break; 10573 default: 10574 if (led->led_act == BWN_LED_ACT_ASSOC) 10575 on = 0; 10576 break; 10577 } 10578 break; 10579 } 10580 10581 val = bwn_led_onoff(led, val, on); 10582 } 10583 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10584 } 10585 10586 static void 10587 bwn_led_event(struct bwn_mac *mac, int event) 10588 { 10589 struct bwn_softc *sc = mac->mac_sc; 10590 struct bwn_led *led = sc->sc_blink_led; 10591 int rate; 10592 10593 if (event == BWN_LED_EVENT_POLL) { 10594 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10595 return; 10596 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10597 return; 10598 } 10599 10600 sc->sc_led_ticks = ticks; 10601 if (sc->sc_led_blinking) 10602 return; 10603 10604 switch (event) { 10605 case BWN_LED_EVENT_RX: 10606 rate = sc->sc_rx_rate; 10607 break; 10608 case BWN_LED_EVENT_TX: 10609 rate = sc->sc_tx_rate; 10610 break; 10611 case BWN_LED_EVENT_POLL: 10612 rate = 0; 10613 break; 10614 default: 10615 panic("unknown LED event %d\n", event); 10616 break; 10617 } 10618 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10619 bwn_led_duration[rate].off_dur); 10620 } 10621 10622 static void 10623 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10624 { 10625 struct bwn_softc *sc = mac->mac_sc; 10626 struct bwn_led *led = sc->sc_blink_led; 10627 uint16_t val; 10628 10629 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10630 val = bwn_led_onoff(led, val, 1); 10631 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10632 10633 if (led->led_flags & BWN_LED_F_SLOW) { 10634 BWN_LED_SLOWDOWN(on_dur); 10635 BWN_LED_SLOWDOWN(off_dur); 10636 } 10637 10638 sc->sc_led_blinking = 1; 10639 sc->sc_led_blink_offdur = off_dur; 10640 10641 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10642 } 10643 10644 static void 10645 bwn_led_blink_next(void *arg) 10646 { 10647 struct bwn_mac *mac = arg; 10648 struct bwn_softc *sc = mac->mac_sc; 10649 uint16_t val; 10650 10651 wlan_serialize_enter(); 10652 10653 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10654 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10655 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10656 10657 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10658 bwn_led_blink_end, mac); 10659 wlan_serialize_exit(); 10660 } 10661 10662 static void 10663 bwn_led_blink_end(void *arg) 10664 { 10665 struct bwn_mac *mac = arg; 10666 struct bwn_softc *sc = mac->mac_sc; 10667 10668 sc->sc_led_blinking = 0; 10669 } 10670 10671 static int 10672 bwn_suspend(device_t dev) 10673 { 10674 struct bwn_softc *sc = device_get_softc(dev); 10675 10676 wlan_serialize_enter(); 10677 bwn_stop(sc, 1); 10678 wlan_serialize_exit(); 10679 10680 return (0); 10681 } 10682 10683 static int 10684 bwn_resume(device_t dev) 10685 { 10686 struct bwn_softc *sc = device_get_softc(dev); 10687 struct ifnet *ifp = sc->sc_ifp; 10688 10689 wlan_serialize_enter(); 10690 if (ifp->if_flags & IFF_UP) 10691 bwn_init(sc); 10692 wlan_serialize_exit(); 10693 return (0); 10694 } 10695 10696 static void 10697 bwn_rfswitch(void *arg) 10698 { 10699 struct bwn_softc *sc = arg; 10700 struct bwn_mac *mac = sc->sc_curmac; 10701 int cur = 0, prev = 0; 10702 10703 wlan_serialize_enter(); 10704 10705 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10706 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10707 10708 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10709 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10710 & BWN_RF_HWENABLED_HI_MASK)) 10711 cur = 1; 10712 } else { 10713 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10714 & BWN_RF_HWENABLED_LO_MASK) 10715 cur = 1; 10716 } 10717 10718 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10719 prev = 1; 10720 10721 if (cur != prev) { 10722 if (cur) 10723 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10724 else 10725 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10726 10727 device_printf(sc->sc_dev, 10728 "status of RF switch is changed to %s\n", 10729 cur ? "ON" : "OFF"); 10730 if (cur != mac->mac_phy.rf_on) { 10731 if (cur) 10732 bwn_rf_turnon(mac); 10733 else 10734 bwn_rf_turnoff(mac); 10735 } 10736 } 10737 10738 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 10739 wlan_serialize_exit(); 10740 } 10741 10742 static void 10743 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10744 { 10745 struct bwn_phy *phy = &mac->mac_phy; 10746 struct bwn_phy_lp *plp = &phy->phy_lp; 10747 10748 plp->plp_antenna = BWN_ANT_DEFAULT; 10749 } 10750 10751 static int 10752 bwn_phy_lp_init(struct bwn_mac *mac) 10753 { 10754 static const struct bwn_stxtable tables[] = { 10755 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10756 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10757 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10758 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10759 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10760 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10761 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10762 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10763 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10764 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10765 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10766 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10767 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10768 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10769 { 2, 11, 0x40, 0, 0x0f } 10770 }; 10771 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10772 struct bwn_softc *sc = mac->mac_sc; 10773 const struct bwn_stxtable *st; 10774 struct ifnet *ifp = sc->sc_ifp; 10775 struct ieee80211com *ic = ifp->if_l2com; 10776 int i, error; 10777 uint16_t tmp; 10778 10779 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10780 bwn_phy_lp_bbinit(mac); 10781 10782 /* initialize RF */ 10783 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10784 DELAY(1); 10785 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10786 DELAY(1); 10787 10788 if (mac->mac_phy.rf_ver == 0x2062) 10789 bwn_phy_lp_b2062_init(mac); 10790 else { 10791 bwn_phy_lp_b2063_init(mac); 10792 10793 /* synchronize stx table. */ 10794 for (i = 0; i < N(tables); i++) { 10795 st = &tables[i]; 10796 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10797 tmp >>= st->st_rfshift; 10798 tmp <<= st->st_physhift; 10799 BWN_PHY_SETMASK(mac, 10800 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10801 ~(st->st_mask << st->st_physhift), tmp); 10802 } 10803 10804 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10805 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10806 } 10807 10808 /* calibrate RC */ 10809 if (mac->mac_phy.rev >= 2) 10810 bwn_phy_lp_rxcal_r2(mac); 10811 else if (!plp->plp_rccap) { 10812 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10813 bwn_phy_lp_rccal_r12(mac); 10814 } else 10815 bwn_phy_lp_set_rccap(mac); 10816 10817 error = bwn_phy_lp_switch_channel(mac, 7); 10818 if (error) 10819 device_printf(sc->sc_dev, 10820 "failed to change channel 7 (%d)\n", error); 10821 bwn_phy_lp_txpctl_init(mac); 10822 bwn_phy_lp_calib(mac); 10823 return (0); 10824 } 10825 10826 static uint16_t 10827 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10828 { 10829 10830 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10831 return (BWN_READ_2(mac, BWN_PHYDATA)); 10832 } 10833 10834 static void 10835 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10836 { 10837 10838 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10839 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10840 } 10841 10842 static void 10843 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10844 uint16_t set) 10845 { 10846 10847 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10848 BWN_WRITE_2(mac, BWN_PHYDATA, 10849 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10850 } 10851 10852 static uint16_t 10853 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10854 { 10855 10856 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10857 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10858 reg |= 0x100; 10859 if (mac->mac_phy.rev >= 2) 10860 reg |= 0x200; 10861 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10862 return BWN_READ_2(mac, BWN_RFDATALO); 10863 } 10864 10865 static void 10866 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10867 { 10868 10869 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10870 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10871 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10872 } 10873 10874 static void 10875 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10876 { 10877 10878 if (on) { 10879 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10880 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10881 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10882 return; 10883 } 10884 10885 if (mac->mac_phy.rev >= 2) { 10886 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10887 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10888 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10889 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10890 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10891 return; 10892 } 10893 10894 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10895 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10896 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10897 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10898 } 10899 10900 static int 10901 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10902 { 10903 struct bwn_phy *phy = &mac->mac_phy; 10904 struct bwn_phy_lp *plp = &phy->phy_lp; 10905 int error; 10906 10907 if (phy->rf_ver == 0x2063) { 10908 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 10909 if (error) 10910 return (error); 10911 } else { 10912 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 10913 if (error) 10914 return (error); 10915 bwn_phy_lp_set_anafilter(mac, chan); 10916 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 10917 } 10918 10919 plp->plp_chan = chan; 10920 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 10921 return (0); 10922 } 10923 10924 static uint32_t 10925 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 10926 { 10927 struct bwn_softc *sc = mac->mac_sc; 10928 struct ifnet *ifp = sc->sc_ifp; 10929 struct ieee80211com *ic = ifp->if_l2com; 10930 10931 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 10932 } 10933 10934 static void 10935 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 10936 { 10937 struct bwn_phy *phy = &mac->mac_phy; 10938 struct bwn_phy_lp *plp = &phy->phy_lp; 10939 10940 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 10941 return; 10942 10943 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 10944 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 10945 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 10946 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 10947 plp->plp_antenna = antenna; 10948 } 10949 10950 static void 10951 bwn_phy_lp_task_60s(struct bwn_mac *mac) 10952 { 10953 10954 bwn_phy_lp_calib(mac); 10955 } 10956 10957 static void 10958 bwn_phy_lp_readsprom(struct bwn_mac *mac) 10959 { 10960 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10961 struct bwn_softc *sc = mac->mac_sc; 10962 struct ifnet *ifp = sc->sc_ifp; 10963 struct ieee80211com *ic = ifp->if_l2com; 10964 10965 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 10966 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 10967 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 10968 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 10969 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 10970 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 10971 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 10972 return; 10973 } 10974 10975 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 10976 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 10977 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 10978 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 10979 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 10980 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 10981 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 10982 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 10983 } 10984 10985 static void 10986 bwn_phy_lp_bbinit(struct bwn_mac *mac) 10987 { 10988 10989 bwn_phy_lp_tblinit(mac); 10990 if (mac->mac_phy.rev >= 2) 10991 bwn_phy_lp_bbinit_r2(mac); 10992 else 10993 bwn_phy_lp_bbinit_r01(mac); 10994 } 10995 10996 static void 10997 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 10998 { 10999 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11000 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11001 struct bwn_softc *sc = mac->mac_sc; 11002 struct ifnet *ifp = sc->sc_ifp; 11003 struct ieee80211com *ic = ifp->if_l2com; 11004 11005 bwn_phy_lp_set_txgain(mac, 11006 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11007 bwn_phy_lp_set_bbmult(mac, 150); 11008 } 11009 11010 static void 11011 bwn_phy_lp_calib(struct bwn_mac *mac) 11012 { 11013 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11014 struct bwn_softc *sc = mac->mac_sc; 11015 struct ifnet *ifp = sc->sc_ifp; 11016 struct ieee80211com *ic = ifp->if_l2com; 11017 const struct bwn_rxcompco *rc = NULL; 11018 struct bwn_txgain ogain; 11019 int i, omode, oafeovr, orf, obbmult; 11020 uint8_t mode, fc = 0; 11021 11022 if (plp->plp_chanfullcal != plp->plp_chan) { 11023 plp->plp_chanfullcal = plp->plp_chan; 11024 fc = 1; 11025 } 11026 11027 bwn_mac_suspend(mac); 11028 11029 /* BlueTooth Coexistance Override */ 11030 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11031 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11032 11033 if (mac->mac_phy.rev >= 2) 11034 bwn_phy_lp_digflt_save(mac); 11035 bwn_phy_lp_get_txpctlmode(mac); 11036 mode = plp->plp_txpctlmode; 11037 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11038 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11039 bwn_phy_lp_bugfix(mac); 11040 if (mac->mac_phy.rev >= 2 && fc == 1) { 11041 bwn_phy_lp_get_txpctlmode(mac); 11042 omode = plp->plp_txpctlmode; 11043 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11044 if (oafeovr) 11045 ogain = bwn_phy_lp_get_txgain(mac); 11046 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11047 obbmult = bwn_phy_lp_get_bbmult(mac); 11048 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11049 if (oafeovr) 11050 bwn_phy_lp_set_txgain(mac, &ogain); 11051 bwn_phy_lp_set_bbmult(mac, obbmult); 11052 bwn_phy_lp_set_txpctlmode(mac, omode); 11053 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11054 } 11055 bwn_phy_lp_set_txpctlmode(mac, mode); 11056 if (mac->mac_phy.rev >= 2) 11057 bwn_phy_lp_digflt_restore(mac); 11058 11059 /* do RX IQ Calculation; assumes that noise is true. */ 11060 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11061 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11062 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11063 rc = &bwn_rxcompco_5354[i]; 11064 } 11065 } else if (mac->mac_phy.rev >= 2) 11066 rc = &bwn_rxcompco_r2; 11067 else { 11068 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11069 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11070 rc = &bwn_rxcompco_r12[i]; 11071 } 11072 } 11073 if (rc == NULL) 11074 goto fail; 11075 11076 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11077 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11078 11079 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11080 11081 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11082 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11083 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11084 } else { 11085 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11086 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11087 } 11088 11089 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11090 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11091 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11092 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11093 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11094 bwn_phy_lp_set_deaf(mac, 0); 11095 /* XXX no checking return value? */ 11096 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11097 bwn_phy_lp_clear_deaf(mac, 0); 11098 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11099 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11100 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11101 11102 /* disable RX GAIN override. */ 11103 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11104 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11105 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11106 if (mac->mac_phy.rev >= 2) { 11107 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11108 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11109 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11110 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11111 } 11112 } else { 11113 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11114 } 11115 11116 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11117 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11118 fail: 11119 bwn_mac_enable(mac); 11120 } 11121 11122 static void 11123 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11124 { 11125 11126 if (on) { 11127 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11128 return; 11129 } 11130 11131 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11132 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11133 } 11134 11135 static int 11136 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11137 { 11138 static const struct bwn_b206x_chan *bc = NULL; 11139 struct bwn_softc *sc = mac->mac_sc; 11140 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11141 tmp[6]; 11142 uint16_t old, scale, tmp16; 11143 int i, div; 11144 11145 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11146 if (bwn_b2063_chantable[i].bc_chan == chan) { 11147 bc = &bwn_b2063_chantable[i]; 11148 break; 11149 } 11150 } 11151 if (bc == NULL) 11152 return (EINVAL); 11153 11154 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11155 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11156 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11157 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11158 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11159 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11160 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11161 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11162 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11163 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11164 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11165 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11166 11167 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11168 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11169 11170 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11171 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11172 freqref = freqxtal * 3; 11173 div = (freqxtal <= 26000000 ? 1 : 2); 11174 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11175 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11176 999999) / 1000000) + 1; 11177 11178 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11179 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11180 0xfff8, timeout >> 2); 11181 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11182 0xff9f,timeout << 5); 11183 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11184 11185 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11186 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11187 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11188 11189 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11190 (timeoutref + 1)) - 1; 11191 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11192 0xf0, count >> 8); 11193 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11194 11195 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11196 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11197 while (tmp[1] >= freqref) { 11198 tmp[0]++; 11199 tmp[1] -= freqref; 11200 } 11201 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11202 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11203 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11204 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11205 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11206 11207 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11208 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11209 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11210 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11211 11212 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11213 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11214 11215 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11216 scale = 1; 11217 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11218 } else { 11219 scale = 0; 11220 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11221 } 11222 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11223 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11224 11225 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11226 (scale + 1); 11227 if (tmp[5] > 150) 11228 tmp[5] = 0; 11229 11230 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11231 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11232 11233 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11234 if (freqxtal > 26000000) 11235 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11236 else 11237 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11238 11239 if (val[0] == 45) 11240 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11241 else 11242 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11243 11244 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11245 DELAY(1); 11246 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11247 11248 /* VCO Calibration */ 11249 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11250 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11251 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11252 DELAY(1); 11253 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11254 DELAY(1); 11255 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11256 DELAY(1); 11257 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11258 DELAY(300); 11259 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11260 11261 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11262 return (0); 11263 } 11264 11265 static int 11266 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11267 { 11268 struct bwn_softc *sc = mac->mac_sc; 11269 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11270 const struct bwn_b206x_chan *bc = NULL; 11271 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11272 uint32_t tmp[9]; 11273 int i; 11274 11275 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11276 if (bwn_b2062_chantable[i].bc_chan == chan) { 11277 bc = &bwn_b2062_chantable[i]; 11278 break; 11279 } 11280 } 11281 11282 if (bc == NULL) 11283 return (EINVAL); 11284 11285 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11286 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11287 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11288 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11289 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11290 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11291 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11292 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11293 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11294 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11295 11296 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11297 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11298 bwn_phy_lp_b2062_reset_pllbias(mac); 11299 tmp[0] = freqxtal / 1000; 11300 tmp[1] = plp->plp_div * 1000; 11301 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11302 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11303 tmp[2] *= 2; 11304 tmp[3] = 48 * tmp[0]; 11305 tmp[5] = tmp[2] / tmp[3]; 11306 tmp[6] = tmp[2] % tmp[3]; 11307 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11308 tmp[4] = tmp[6] * 0x100; 11309 tmp[5] = tmp[4] / tmp[3]; 11310 tmp[6] = tmp[4] % tmp[3]; 11311 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11312 tmp[4] = tmp[6] * 0x100; 11313 tmp[5] = tmp[4] / tmp[3]; 11314 tmp[6] = tmp[4] % tmp[3]; 11315 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11316 tmp[4] = tmp[6] * 0x100; 11317 tmp[5] = tmp[4] / tmp[3]; 11318 tmp[6] = tmp[4] % tmp[3]; 11319 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11320 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11321 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11322 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11323 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11324 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11325 11326 bwn_phy_lp_b2062_vco_calib(mac); 11327 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11328 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11329 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11330 bwn_phy_lp_b2062_reset_pllbias(mac); 11331 bwn_phy_lp_b2062_vco_calib(mac); 11332 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11333 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11334 return (EIO); 11335 } 11336 } 11337 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11338 return (0); 11339 } 11340 11341 static void 11342 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11343 { 11344 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11345 uint16_t tmp = (channel == 14); 11346 11347 if (mac->mac_phy.rev < 2) { 11348 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11349 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11350 bwn_phy_lp_set_rccap(mac); 11351 return; 11352 } 11353 11354 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11355 } 11356 11357 static void 11358 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11359 { 11360 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11361 struct bwn_softc *sc = mac->mac_sc; 11362 struct ifnet *ifp = sc->sc_ifp; 11363 struct ieee80211com *ic = ifp->if_l2com; 11364 uint16_t iso, tmp[3]; 11365 11366 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11367 11368 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11369 iso = plp->plp_txisoband_m; 11370 else if (freq <= 5320) 11371 iso = plp->plp_txisoband_l; 11372 else if (freq <= 5700) 11373 iso = plp->plp_txisoband_m; 11374 else 11375 iso = plp->plp_txisoband_h; 11376 11377 tmp[0] = ((iso - 26) / 12) << 12; 11378 tmp[1] = tmp[0] + 0x1000; 11379 tmp[2] = tmp[0] + 0x2000; 11380 11381 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11382 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11383 } 11384 11385 static void 11386 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11387 { 11388 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11389 int i; 11390 static const uint16_t addr[] = { 11391 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11392 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11393 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11394 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11395 BWN_PHY_OFDM(0xcf), 11396 }; 11397 static const uint16_t val[] = { 11398 0xde5e, 0xe832, 0xe331, 0x4d26, 11399 0x0026, 0x1420, 0x0020, 0xfe08, 11400 0x0008, 11401 }; 11402 11403 for (i = 0; i < N(addr); i++) { 11404 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11405 BWN_PHY_WRITE(mac, addr[i], val[i]); 11406 } 11407 } 11408 11409 static void 11410 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11411 { 11412 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11413 struct bwn_softc *sc = mac->mac_sc; 11414 uint16_t ctl; 11415 11416 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11417 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11418 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11419 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11420 break; 11421 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11422 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11423 break; 11424 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11425 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11426 break; 11427 default: 11428 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11429 device_printf(sc->sc_dev, "unknown command mode\n"); 11430 break; 11431 } 11432 } 11433 11434 static void 11435 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11436 { 11437 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11438 uint16_t ctl; 11439 uint8_t old; 11440 11441 bwn_phy_lp_get_txpctlmode(mac); 11442 old = plp->plp_txpctlmode; 11443 if (old == mode) 11444 return; 11445 plp->plp_txpctlmode = mode; 11446 11447 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11448 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11449 plp->plp_tssiidx); 11450 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11451 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11452 11453 /* disable TX GAIN override */ 11454 if (mac->mac_phy.rev < 2) 11455 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11456 else { 11457 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11458 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11459 } 11460 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11461 11462 plp->plp_txpwridx = -1; 11463 } 11464 if (mac->mac_phy.rev >= 2) { 11465 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11466 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11467 else 11468 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11469 } 11470 11471 /* writes TX Power Control mode */ 11472 switch (plp->plp_txpctlmode) { 11473 case BWN_PHYLP_TXPCTL_OFF: 11474 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11475 break; 11476 case BWN_PHYLP_TXPCTL_ON_HW: 11477 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11478 break; 11479 case BWN_PHYLP_TXPCTL_ON_SW: 11480 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11481 break; 11482 default: 11483 ctl = 0; 11484 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11485 } 11486 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11487 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11488 } 11489 11490 static void 11491 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11492 { 11493 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11494 const unsigned int size = 256; 11495 struct bwn_txgain tg; 11496 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11497 uint16_t tssinpt, tssiidx, value[2]; 11498 uint8_t mode; 11499 int8_t txpwridx; 11500 11501 tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF, 11502 M_INTWAIT | M_ZERO); 11503 11504 bwn_phy_lp_get_txpctlmode(mac); 11505 mode = plp->plp_txpctlmode; 11506 txpwridx = plp->plp_txpwridx; 11507 tssinpt = plp->plp_tssinpt; 11508 tssiidx = plp->plp_tssiidx; 11509 11510 bwn_tab_read_multi(mac, 11511 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11512 BWN_TAB_4(7, 0x140), size, tabs); 11513 11514 bwn_phy_lp_tblinit(mac); 11515 bwn_phy_lp_bbinit(mac); 11516 bwn_phy_lp_txpctl_init(mac); 11517 bwn_phy_lp_rf_onoff(mac, 1); 11518 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11519 11520 bwn_tab_write_multi(mac, 11521 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11522 BWN_TAB_4(7, 0x140), size, tabs); 11523 11524 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11525 plp->plp_tssinpt = tssinpt; 11526 plp->plp_tssiidx = tssiidx; 11527 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11528 if (txpwridx != -1) { 11529 /* set TX power by index */ 11530 plp->plp_txpwridx = txpwridx; 11531 bwn_phy_lp_get_txpctlmode(mac); 11532 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11533 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11534 if (mac->mac_phy.rev >= 2) { 11535 rxcomp = bwn_tab_read(mac, 11536 BWN_TAB_4(7, txpwridx + 320)); 11537 txgain = bwn_tab_read(mac, 11538 BWN_TAB_4(7, txpwridx + 192)); 11539 tg.tg_pad = (txgain >> 16) & 0xff; 11540 tg.tg_gm = txgain & 0xff; 11541 tg.tg_pga = (txgain >> 8) & 0xff; 11542 tg.tg_dac = (rxcomp >> 28) & 0xff; 11543 bwn_phy_lp_set_txgain(mac, &tg); 11544 } else { 11545 rxcomp = bwn_tab_read(mac, 11546 BWN_TAB_4(10, txpwridx + 320)); 11547 txgain = bwn_tab_read(mac, 11548 BWN_TAB_4(10, txpwridx + 192)); 11549 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11550 0xf800, (txgain >> 4) & 0x7fff); 11551 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11552 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11553 } 11554 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11555 11556 /* set TX IQCC */ 11557 value[0] = (rxcomp >> 10) & 0x3ff; 11558 value[1] = rxcomp & 0x3ff; 11559 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11560 11561 coeff = bwn_tab_read(mac, 11562 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11563 BWN_TAB_4(10, txpwridx + 448)); 11564 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11565 if (mac->mac_phy.rev >= 2) { 11566 rfpwr = bwn_tab_read(mac, 11567 BWN_TAB_4(7, txpwridx + 576)); 11568 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11569 rfpwr & 0xffff); 11570 } 11571 bwn_phy_lp_set_txgain_override(mac); 11572 } 11573 if (plp->plp_rccap) 11574 bwn_phy_lp_set_rccap(mac); 11575 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11576 bwn_phy_lp_set_txpctlmode(mac, mode); 11577 kfree(tabs, M_DEVBUF); 11578 } 11579 11580 static void 11581 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11582 { 11583 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11584 int i; 11585 static const uint16_t addr[] = { 11586 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11587 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11588 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11589 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11590 BWN_PHY_OFDM(0xcf), 11591 }; 11592 11593 for (i = 0; i < N(addr); i++) 11594 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11595 } 11596 11597 static void 11598 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11599 { 11600 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11601 11602 if (mac->mac_phy.rev < 2) { 11603 bwn_phy_lp_tblinit_r01(mac); 11604 bwn_phy_lp_tblinit_txgain(mac); 11605 bwn_phy_lp_set_gaintbl(mac, freq); 11606 return; 11607 } 11608 11609 bwn_phy_lp_tblinit_r2(mac); 11610 bwn_phy_lp_tblinit_txgain(mac); 11611 } 11612 11613 struct bwn_wpair { 11614 uint16_t reg; 11615 uint16_t value; 11616 }; 11617 11618 struct bwn_smpair { 11619 uint16_t offset; 11620 uint16_t mask; 11621 uint16_t set; 11622 }; 11623 11624 static void 11625 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11626 { 11627 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11628 struct bwn_softc *sc = mac->mac_sc; 11629 struct ifnet *ifp = sc->sc_ifp; 11630 struct ieee80211com *ic = ifp->if_l2com; 11631 static const struct bwn_wpair v1[] = { 11632 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11633 { BWN_PHY_AFE_CTL, 0x8800 }, 11634 { BWN_PHY_AFE_CTL_OVR, 0 }, 11635 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11636 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11637 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11638 { BWN_PHY_OFDM(0xf9), 0 }, 11639 { BWN_PHY_TR_LOOKUP_1, 0 } 11640 }; 11641 static const struct bwn_smpair v2[] = { 11642 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11643 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11644 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11645 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11646 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11647 }; 11648 static const struct bwn_smpair v3[] = { 11649 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11650 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11651 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11652 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11653 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11654 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11655 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11656 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11657 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11658 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11659 11660 }; 11661 int i; 11662 11663 for (i = 0; i < N(v1); i++) 11664 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11665 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11666 for (i = 0; i < N(v2); i++) 11667 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11668 11669 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11670 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11671 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11672 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11673 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11674 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11675 } else { 11676 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11677 } 11678 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11679 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11680 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11681 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11682 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11683 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11684 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11685 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11686 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11687 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11688 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11689 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11690 (siba_get_chiprev(sc->sc_dev) == 0)) { 11691 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11692 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11693 } else { 11694 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11695 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11696 } 11697 for (i = 0; i < N(v3); i++) 11698 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11699 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11700 (siba_get_chiprev(sc->sc_dev) == 0)) { 11701 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11702 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11703 } 11704 11705 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11706 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11707 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11708 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11709 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11710 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11711 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11712 } else 11713 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11714 11715 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11716 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11717 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11718 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11719 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11720 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11721 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11722 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11723 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11724 11725 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11726 (siba_get_chiprev(sc->sc_dev) == 0)) { 11727 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11728 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11729 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11730 } 11731 11732 bwn_phy_lp_digflt_save(mac); 11733 } 11734 11735 static void 11736 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11737 { 11738 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11739 struct bwn_softc *sc = mac->mac_sc; 11740 struct ifnet *ifp = sc->sc_ifp; 11741 struct ieee80211com *ic = ifp->if_l2com; 11742 static const struct bwn_smpair v1[] = { 11743 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11744 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11745 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11746 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11747 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11748 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11749 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11750 }; 11751 static const struct bwn_smpair v2[] = { 11752 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11753 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11754 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11755 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11756 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11757 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11758 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11759 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11760 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11761 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11762 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11763 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11764 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11765 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11766 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11767 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11768 }; 11769 static const struct bwn_smpair v3[] = { 11770 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11771 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11772 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11773 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11774 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11775 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11776 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11777 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11778 }; 11779 static const struct bwn_smpair v4[] = { 11780 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11781 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11782 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11783 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11784 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11785 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11786 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11787 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11788 }; 11789 static const struct bwn_smpair v5[] = { 11790 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11791 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11792 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11793 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11794 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11795 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11796 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11797 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11798 }; 11799 int i; 11800 uint16_t tmp, tmp2; 11801 11802 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11803 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11804 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11805 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11806 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11807 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11808 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11809 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11810 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11811 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11812 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11813 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11814 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11815 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11816 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11817 for (i = 0; i < N(v1); i++) 11818 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11819 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11820 0xff00, plp->plp_rxpwroffset); 11821 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11822 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11823 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11824 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11825 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11826 if (mac->mac_phy.rev == 0) 11827 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11828 0xffcf, 0x0010); 11829 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11830 } else { 11831 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11832 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11833 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11834 } 11835 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11836 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11837 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11838 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11839 else 11840 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11841 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11842 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11843 0xfff9, (plp->plp_bxarch << 1)); 11844 if (mac->mac_phy.rev == 1 && 11845 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11846 for (i = 0; i < N(v2); i++) 11847 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11848 v2[i].set); 11849 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11850 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11851 ((mac->mac_phy.rev == 0) && 11852 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11853 for (i = 0; i < N(v3); i++) 11854 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11855 v3[i].set); 11856 } else if (mac->mac_phy.rev == 1 || 11857 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11858 for (i = 0; i < N(v4); i++) 11859 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11860 v4[i].set); 11861 } else { 11862 for (i = 0; i < N(v5); i++) 11863 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11864 v5[i].set); 11865 } 11866 if (mac->mac_phy.rev == 1 && 11867 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11868 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11869 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11870 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11871 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11872 } 11873 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11874 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11875 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11876 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11877 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11878 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11879 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11880 } 11881 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11882 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11883 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11884 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11885 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11886 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11887 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11888 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11889 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11890 } else { 11891 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11892 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11893 } 11894 if (mac->mac_phy.rev == 1) { 11895 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11896 tmp2 = (tmp & 0x03e0) >> 5; 11897 tmp2 |= tmp2 << 5; 11898 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11899 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 11900 tmp2 = (tmp & 0x1f00) >> 8; 11901 tmp2 |= tmp2 << 5; 11902 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 11903 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 11904 tmp2 = tmp & 0x00ff; 11905 tmp2 |= tmp << 8; 11906 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 11907 } 11908 } 11909 11910 struct bwn_b2062_freq { 11911 uint16_t freq; 11912 uint8_t value[6]; 11913 }; 11914 11915 static void 11916 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 11917 { 11918 #define CALC_CTL7(freq, div) \ 11919 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 11920 #define CALC_CTL18(freq, div) \ 11921 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 11922 #define CALC_CTL19(freq, div) \ 11923 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 11924 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11925 struct bwn_softc *sc = mac->mac_sc; 11926 struct ifnet *ifp = sc->sc_ifp; 11927 struct ieee80211com *ic = ifp->if_l2com; 11928 static const struct bwn_b2062_freq freqdata_tab[] = { 11929 { 12000, { 6, 6, 6, 6, 10, 6 } }, 11930 { 13000, { 4, 4, 4, 4, 11, 7 } }, 11931 { 14400, { 3, 3, 3, 3, 12, 7 } }, 11932 { 16200, { 3, 3, 3, 3, 13, 8 } }, 11933 { 18000, { 2, 2, 2, 2, 14, 8 } }, 11934 { 19200, { 1, 1, 1, 1, 14, 9 } } 11935 }; 11936 static const struct bwn_wpair v1[] = { 11937 { BWN_B2062_N_TXCTL3, 0 }, 11938 { BWN_B2062_N_TXCTL4, 0 }, 11939 { BWN_B2062_N_TXCTL5, 0 }, 11940 { BWN_B2062_N_TXCTL6, 0 }, 11941 { BWN_B2062_N_PDNCTL0, 0x40 }, 11942 { BWN_B2062_N_PDNCTL0, 0 }, 11943 { BWN_B2062_N_CALIB_TS, 0x10 }, 11944 { BWN_B2062_N_CALIB_TS, 0 } 11945 }; 11946 const struct bwn_b2062_freq *f = NULL; 11947 uint32_t xtalfreq, ref; 11948 unsigned int i; 11949 11950 bwn_phy_lp_b2062_tblinit(mac); 11951 11952 for (i = 0; i < N(v1); i++) 11953 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 11954 if (mac->mac_phy.rev > 0) 11955 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 11956 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 11957 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11958 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 11959 else 11960 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 11961 11962 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 11963 ("%s:%d: fail", __func__, __LINE__)); 11964 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11965 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 11966 11967 if (xtalfreq <= 30000000) { 11968 plp->plp_div = 1; 11969 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 11970 } else { 11971 plp->plp_div = 2; 11972 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 11973 } 11974 11975 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 11976 CALC_CTL7(xtalfreq, plp->plp_div)); 11977 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 11978 CALC_CTL18(xtalfreq, plp->plp_div)); 11979 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 11980 CALC_CTL19(xtalfreq, plp->plp_div)); 11981 11982 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 11983 ref &= 0xffff; 11984 for (i = 0; i < N(freqdata_tab); i++) { 11985 if (ref < freqdata_tab[i].freq) { 11986 f = &freqdata_tab[i]; 11987 break; 11988 } 11989 } 11990 if (f == NULL) 11991 f = &freqdata_tab[N(freqdata_tab) - 1]; 11992 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 11993 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 11994 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 11995 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 11996 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 11997 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 11998 #undef CALC_CTL7 11999 #undef CALC_CTL18 12000 #undef CALC_CTL19 12001 } 12002 12003 static void 12004 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12005 { 12006 12007 bwn_phy_lp_b2063_tblinit(mac); 12008 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12009 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12010 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12011 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12012 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12013 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12014 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12015 if (mac->mac_phy.rev == 2) { 12016 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12017 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12018 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12019 } else { 12020 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12021 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12022 } 12023 } 12024 12025 static void 12026 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12027 { 12028 struct bwn_softc *sc = mac->mac_sc; 12029 static const struct bwn_wpair v1[] = { 12030 { BWN_B2063_RX_BB_SP8, 0x0 }, 12031 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12032 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12033 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12034 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12035 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12036 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12037 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12038 }; 12039 static const struct bwn_wpair v2[] = { 12040 { BWN_B2063_TX_BB_SP3, 0x0 }, 12041 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12042 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12043 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12044 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12045 }; 12046 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12047 int i; 12048 uint8_t tmp; 12049 12050 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12051 12052 for (i = 0; i < 2; i++) 12053 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12054 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12055 for (i = 2; i < N(v1); i++) 12056 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12057 for (i = 0; i < 10000; i++) { 12058 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12059 break; 12060 DELAY(1000); 12061 } 12062 12063 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12064 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12065 12066 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12067 12068 for (i = 0; i < N(v2); i++) 12069 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12070 if (freqxtal == 24000000) { 12071 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12072 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12073 } else { 12074 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12075 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12076 } 12077 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12078 for (i = 0; i < 10000; i++) { 12079 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12080 break; 12081 DELAY(1000); 12082 } 12083 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12084 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12085 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12086 } 12087 12088 static void 12089 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12090 { 12091 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12092 struct bwn_softc *sc = mac->mac_sc; 12093 struct bwn_phy_lp_iq_est ie; 12094 struct bwn_txgain tx_gains; 12095 static const uint32_t pwrtbl[21] = { 12096 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12097 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12098 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12099 0x0004c, 0x0002c, 0x0001a, 12100 }; 12101 uint32_t npwr, ipwr, sqpwr, tmp; 12102 int loopback, i, j, sum, error; 12103 uint16_t save[7]; 12104 uint8_t txo, bbmult, txpctlmode; 12105 12106 error = bwn_phy_lp_switch_channel(mac, 7); 12107 if (error) 12108 device_printf(sc->sc_dev, 12109 "failed to change channel to 7 (%d)\n", error); 12110 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12111 bbmult = bwn_phy_lp_get_bbmult(mac); 12112 if (txo) 12113 tx_gains = bwn_phy_lp_get_txgain(mac); 12114 12115 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12116 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12117 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12118 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12119 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12120 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12121 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12122 12123 bwn_phy_lp_get_txpctlmode(mac); 12124 txpctlmode = plp->plp_txpctlmode; 12125 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12126 12127 /* disable CRS */ 12128 bwn_phy_lp_set_deaf(mac, 1); 12129 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12130 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12131 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12132 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12133 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12134 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12135 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12136 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12137 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12138 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12139 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12140 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12141 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12142 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12143 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12144 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12145 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12146 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12147 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12148 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12149 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12150 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12151 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12152 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12153 12154 loopback = bwn_phy_lp_loopback(mac); 12155 if (loopback == -1) 12156 goto done; 12157 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12158 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12159 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12160 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12161 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12162 12163 tmp = 0; 12164 memset(&ie, 0, sizeof(ie)); 12165 for (i = 128; i <= 159; i++) { 12166 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12167 sum = 0; 12168 for (j = 5; j <= 25; j++) { 12169 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12170 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12171 goto done; 12172 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12173 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12174 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12175 12); 12176 sum += ((ipwr - npwr) * (ipwr - npwr)); 12177 if ((i == 128) || (sum < tmp)) { 12178 plp->plp_rccap = i; 12179 tmp = sum; 12180 } 12181 } 12182 } 12183 bwn_phy_lp_ddfs_turnoff(mac); 12184 done: 12185 /* restore CRS */ 12186 bwn_phy_lp_clear_deaf(mac, 1); 12187 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12188 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12189 12190 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12191 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12192 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12193 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12194 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12195 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12196 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12197 12198 bwn_phy_lp_set_bbmult(mac, bbmult); 12199 if (txo) 12200 bwn_phy_lp_set_txgain(mac, &tx_gains); 12201 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12202 if (plp->plp_rccap) 12203 bwn_phy_lp_set_rccap(mac); 12204 } 12205 12206 static void 12207 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12208 { 12209 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12210 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12211 12212 if (mac->mac_phy.rev == 1) 12213 rc_cap = MIN(rc_cap + 5, 15); 12214 12215 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12216 MAX(plp->plp_rccap - 4, 0x80)); 12217 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12218 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12219 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12220 } 12221 12222 static uint32_t 12223 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12224 { 12225 uint32_t i, q, r; 12226 12227 if (div == 0) 12228 return (0); 12229 12230 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12231 q <<= 1; 12232 if (r << 1 >= div) { 12233 q++; 12234 r = (r << 1) - div; 12235 } 12236 } 12237 if (r << 1 >= div) 12238 q++; 12239 return (q); 12240 } 12241 12242 static void 12243 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12244 { 12245 struct bwn_softc *sc = mac->mac_sc; 12246 12247 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12248 DELAY(20); 12249 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12250 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12251 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12252 } else { 12253 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12254 } 12255 DELAY(5); 12256 } 12257 12258 static void 12259 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12260 { 12261 12262 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12263 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12264 DELAY(200); 12265 } 12266 12267 static void 12268 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12269 { 12270 #define FLAG_A 0x01 12271 #define FLAG_G 0x02 12272 struct bwn_softc *sc = mac->mac_sc; 12273 struct ifnet *ifp = sc->sc_ifp; 12274 struct ieee80211com *ic = ifp->if_l2com; 12275 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12276 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12277 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12278 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12279 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12280 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12281 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12282 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12283 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12284 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12285 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12286 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12287 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12288 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12289 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12290 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12291 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12292 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12293 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12294 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12295 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12296 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12297 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12298 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12299 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12300 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12301 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12302 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12303 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12304 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12305 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12306 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12307 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12308 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12309 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12310 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12311 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12312 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12313 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12314 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12315 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12316 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12317 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12318 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12319 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12320 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12321 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12322 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12323 }; 12324 const struct bwn_b206x_rfinit_entry *br; 12325 unsigned int i; 12326 12327 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12328 br = &bwn_b2062_init_tab[i]; 12329 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12330 if (br->br_flags & FLAG_G) 12331 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12332 } else { 12333 if (br->br_flags & FLAG_A) 12334 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12335 } 12336 } 12337 #undef FLAG_A 12338 #undef FLAG_B 12339 } 12340 12341 static void 12342 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12343 { 12344 #define FLAG_A 0x01 12345 #define FLAG_G 0x02 12346 struct bwn_softc *sc = mac->mac_sc; 12347 struct ifnet *ifp = sc->sc_ifp; 12348 struct ieee80211com *ic = ifp->if_l2com; 12349 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12350 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12351 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12352 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12353 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12354 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12355 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12356 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12357 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12358 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12359 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12360 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12361 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12362 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12363 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12364 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12365 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12366 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12367 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12368 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12369 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12370 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12371 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12372 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12373 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12374 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12375 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12376 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12377 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12378 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12379 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12380 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12381 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12382 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12383 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12384 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12385 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12386 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12387 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12388 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12389 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12390 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12391 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12392 }; 12393 const struct bwn_b206x_rfinit_entry *br; 12394 unsigned int i; 12395 12396 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12397 br = &bwn_b2063_init_tab[i]; 12398 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12399 if (br->br_flags & FLAG_G) 12400 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12401 } else { 12402 if (br->br_flags & FLAG_A) 12403 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12404 } 12405 } 12406 #undef FLAG_A 12407 #undef FLAG_B 12408 } 12409 12410 static void 12411 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12412 int count, void *_data) 12413 { 12414 unsigned int i; 12415 uint32_t offset, type; 12416 uint8_t *data = _data; 12417 12418 type = BWN_TAB_GETTYPE(typenoffset); 12419 offset = BWN_TAB_GETOFFSET(typenoffset); 12420 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12421 12422 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12423 12424 for (i = 0; i < count; i++) { 12425 switch (type) { 12426 case BWN_TAB_8BIT: 12427 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12428 data++; 12429 break; 12430 case BWN_TAB_16BIT: 12431 *((uint16_t *)data) = BWN_PHY_READ(mac, 12432 BWN_PHY_TABLEDATALO); 12433 data += 2; 12434 break; 12435 case BWN_TAB_32BIT: 12436 *((uint32_t *)data) = BWN_PHY_READ(mac, 12437 BWN_PHY_TABLEDATAHI); 12438 *((uint32_t *)data) <<= 16; 12439 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12440 BWN_PHY_TABLEDATALO); 12441 data += 4; 12442 break; 12443 default: 12444 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12445 } 12446 } 12447 } 12448 12449 static void 12450 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12451 int count, const void *_data) 12452 { 12453 uint32_t offset, type, value; 12454 const uint8_t *data = _data; 12455 unsigned int i; 12456 12457 type = BWN_TAB_GETTYPE(typenoffset); 12458 offset = BWN_TAB_GETOFFSET(typenoffset); 12459 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12460 12461 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12462 12463 for (i = 0; i < count; i++) { 12464 switch (type) { 12465 case BWN_TAB_8BIT: 12466 value = *data; 12467 data++; 12468 KASSERT(!(value & ~0xff), 12469 ("%s:%d: fail", __func__, __LINE__)); 12470 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12471 break; 12472 case BWN_TAB_16BIT: 12473 value = *((const uint16_t *)data); 12474 data += 2; 12475 KASSERT(!(value & ~0xffff), 12476 ("%s:%d: fail", __func__, __LINE__)); 12477 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12478 break; 12479 case BWN_TAB_32BIT: 12480 value = *((const uint32_t *)data); 12481 data += 4; 12482 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12483 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12484 break; 12485 default: 12486 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12487 } 12488 } 12489 } 12490 12491 static struct bwn_txgain 12492 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12493 { 12494 struct bwn_txgain tg; 12495 uint16_t tmp; 12496 12497 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12498 if (mac->mac_phy.rev < 2) { 12499 tmp = BWN_PHY_READ(mac, 12500 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12501 tg.tg_gm = tmp & 0x0007; 12502 tg.tg_pga = (tmp & 0x0078) >> 3; 12503 tg.tg_pad = (tmp & 0x780) >> 7; 12504 return (tg); 12505 } 12506 12507 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12508 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12509 tg.tg_gm = tmp & 0xff; 12510 tg.tg_pga = (tmp >> 8) & 0xff; 12511 return (tg); 12512 } 12513 12514 static uint8_t 12515 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12516 { 12517 12518 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12519 } 12520 12521 static void 12522 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12523 { 12524 uint16_t pa; 12525 12526 if (mac->mac_phy.rev < 2) { 12527 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12528 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12529 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12530 bwn_phy_lp_set_txgain_override(mac); 12531 return; 12532 } 12533 12534 pa = bwn_phy_lp_get_pa_gain(mac); 12535 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12536 (tg->tg_pga << 8) | tg->tg_gm); 12537 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12538 tg->tg_pad | (pa << 6)); 12539 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12540 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12541 tg->tg_pad | (pa << 8)); 12542 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12543 bwn_phy_lp_set_txgain_override(mac); 12544 } 12545 12546 static void 12547 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12548 { 12549 12550 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12551 } 12552 12553 static void 12554 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12555 { 12556 uint16_t trsw = (tx << 1) | rx; 12557 12558 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12559 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12560 } 12561 12562 static void 12563 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12564 { 12565 struct bwn_softc *sc = mac->mac_sc; 12566 struct ifnet *ifp = sc->sc_ifp; 12567 struct ieee80211com *ic = ifp->if_l2com; 12568 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12569 12570 if (mac->mac_phy.rev < 2) { 12571 trsw = gain & 0x1; 12572 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12573 ext_lna = (gain & 2) >> 1; 12574 12575 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12576 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12577 0xfbff, ext_lna << 10); 12578 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12579 0xf7ff, ext_lna << 11); 12580 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12581 } else { 12582 low_gain = gain & 0xffff; 12583 high_gain = (gain >> 16) & 0xf; 12584 ext_lna = (gain >> 21) & 0x1; 12585 trsw = ~(gain >> 20) & 0x1; 12586 12587 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12588 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12589 0xfdff, ext_lna << 9); 12590 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12591 0xfbff, ext_lna << 10); 12592 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12593 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12594 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12595 tmp = (gain >> 2) & 0x3; 12596 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12597 0xe7ff, tmp<<11); 12598 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12599 tmp << 3); 12600 } 12601 } 12602 12603 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12604 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12605 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12606 if (mac->mac_phy.rev >= 2) { 12607 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12608 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12609 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12610 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12611 } 12612 return; 12613 } 12614 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12615 } 12616 12617 static void 12618 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12619 { 12620 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12621 12622 if (user) 12623 plp->plp_crsusr_off = 1; 12624 else 12625 plp->plp_crssys_off = 1; 12626 12627 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12628 } 12629 12630 static void 12631 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12632 { 12633 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12634 struct bwn_softc *sc = mac->mac_sc; 12635 struct ifnet *ifp = sc->sc_ifp; 12636 struct ieee80211com *ic = ifp->if_l2com; 12637 12638 if (user) 12639 plp->plp_crsusr_off = 0; 12640 else 12641 plp->plp_crssys_off = 0; 12642 12643 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12644 return; 12645 12646 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12647 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12648 else 12649 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12650 } 12651 12652 static unsigned int 12653 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12654 { 12655 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12656 static uint8_t sqrt_table[256] = { 12657 10, 14, 17, 20, 22, 24, 26, 28, 12658 30, 31, 33, 34, 36, 37, 38, 40, 12659 41, 42, 43, 44, 45, 46, 47, 48, 12660 50, 50, 51, 52, 53, 54, 55, 56, 12661 57, 58, 59, 60, 60, 61, 62, 63, 12662 64, 64, 65, 66, 67, 67, 68, 69, 12663 70, 70, 71, 72, 72, 73, 74, 74, 12664 75, 76, 76, 77, 78, 78, 79, 80, 12665 80, 81, 81, 82, 83, 83, 84, 84, 12666 85, 86, 86, 87, 87, 88, 88, 89, 12667 90, 90, 91, 91, 92, 92, 93, 93, 12668 94, 94, 95, 95, 96, 96, 97, 97, 12669 98, 98, 99, 100, 100, 100, 101, 101, 12670 102, 102, 103, 103, 104, 104, 105, 105, 12671 106, 106, 107, 107, 108, 108, 109, 109, 12672 110, 110, 110, 111, 111, 112, 112, 113, 12673 113, 114, 114, 114, 115, 115, 116, 116, 12674 117, 117, 117, 118, 118, 119, 119, 120, 12675 120, 120, 121, 121, 122, 122, 122, 123, 12676 123, 124, 124, 124, 125, 125, 126, 126, 12677 126, 127, 127, 128, 128, 128, 129, 129, 12678 130, 130, 130, 131, 131, 131, 132, 132, 12679 133, 133, 133, 134, 134, 134, 135, 135, 12680 136, 136, 136, 137, 137, 137, 138, 138, 12681 138, 139, 139, 140, 140, 140, 141, 141, 12682 141, 142, 142, 142, 143, 143, 143, 144, 12683 144, 144, 145, 145, 145, 146, 146, 146, 12684 147, 147, 147, 148, 148, 148, 149, 149, 12685 150, 150, 150, 150, 151, 151, 151, 152, 12686 152, 152, 153, 153, 153, 154, 154, 154, 12687 155, 155, 155, 156, 156, 156, 157, 157, 12688 157, 158, 158, 158, 159, 159, 159, 160 12689 }; 12690 12691 if (x == 0) 12692 return (0); 12693 if (x >= 256) { 12694 unsigned int tmp; 12695 12696 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12697 /* do nothing */ ; 12698 return (tmp); 12699 } 12700 return (sqrt_table[x - 1] / 10); 12701 } 12702 12703 static int 12704 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12705 { 12706 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12707 int _t; \ 12708 _t = _x - 20; \ 12709 if (_t >= 0) { \ 12710 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12711 } else { \ 12712 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12713 } \ 12714 } while (0) 12715 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12716 int _t; \ 12717 _t = _x - 11; \ 12718 if (_t >= 0) \ 12719 _v = (_y << (31 - _x)) / (_z >> _t); \ 12720 else \ 12721 _v = (_y << (31 - _x)) / (_z << -_t); \ 12722 } while (0) 12723 struct bwn_phy_lp_iq_est ie; 12724 uint16_t v0, v1; 12725 int tmp[2], ret; 12726 12727 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12728 v0 = v1 >> 8; 12729 v1 |= 0xff; 12730 12731 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12732 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12733 12734 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12735 if (ret == 0) 12736 goto done; 12737 12738 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12739 ret = 0; 12740 goto done; 12741 } 12742 12743 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12744 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12745 12746 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12747 v0 = tmp[0] >> 3; 12748 v1 = tmp[1] >> 4; 12749 done: 12750 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12751 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12752 return ret; 12753 #undef CALC_COEFF 12754 #undef CALC_COEFF2 12755 } 12756 12757 static void 12758 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12759 { 12760 static const uint16_t noisescale[] = { 12761 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12762 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12763 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12764 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12765 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12766 }; 12767 static const uint16_t crsgainnft[] = { 12768 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12769 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12770 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12771 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12772 0x013d, 12773 }; 12774 static const uint16_t filterctl[] = { 12775 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12776 0xff53, 0x0127, 12777 }; 12778 static const uint32_t psctl[] = { 12779 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12780 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12781 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12782 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12783 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12784 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12785 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12786 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12787 }; 12788 static const uint16_t ofdmcckgain_r0[] = { 12789 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12790 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12791 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12792 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12793 0x755d, 12794 }; 12795 static const uint16_t ofdmcckgain_r1[] = { 12796 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12797 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12798 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12799 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12800 0x755d, 12801 }; 12802 static const uint16_t gaindelta[] = { 12803 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12804 0x0000, 12805 }; 12806 static const uint32_t txpwrctl[] = { 12807 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12808 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12809 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12810 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12811 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12812 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12813 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12814 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12815 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12816 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12817 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12818 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12819 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12820 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12821 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12822 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12823 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12824 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12825 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12826 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12827 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12828 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12829 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12830 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12831 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12832 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12833 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12834 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12835 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12836 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12837 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12838 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12839 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12840 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12841 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12842 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12843 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12844 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12845 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12846 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12847 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12848 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12849 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12850 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12851 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12852 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12853 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12854 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12855 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12856 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12857 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12858 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12859 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12860 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12861 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12862 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12863 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12864 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12865 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12866 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12867 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12868 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12869 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12870 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12871 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12872 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12873 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12874 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12875 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12876 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12877 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12878 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12879 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12880 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12881 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12882 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12883 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12884 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12885 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12886 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12887 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12888 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12889 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12890 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12891 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12892 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12893 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12894 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12895 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12896 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12897 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12898 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12899 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 12900 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 12901 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 12902 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 12903 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 12904 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 12905 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 12906 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 12907 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 12908 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 12909 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 12910 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 12911 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 12912 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 12913 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 12914 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 12915 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 12916 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 12917 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 12918 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 12919 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 12920 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 12921 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 12922 0x00000702, 12923 }; 12924 12925 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 12926 12927 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 12928 bwn_tab_sigsq_tbl); 12929 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 12930 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 12931 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 12932 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 12933 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 12934 bwn_tab_pllfrac_tbl); 12935 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 12936 bwn_tabl_iqlocal_tbl); 12937 if (mac->mac_phy.rev == 0) { 12938 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 12939 ofdmcckgain_r0); 12940 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 12941 ofdmcckgain_r0); 12942 } else { 12943 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 12944 ofdmcckgain_r1); 12945 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 12946 ofdmcckgain_r1); 12947 } 12948 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 12949 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 12950 } 12951 12952 static void 12953 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 12954 { 12955 struct bwn_softc *sc = mac->mac_sc; 12956 int i; 12957 static const uint16_t noisescale[] = { 12958 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12959 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12960 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12961 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12962 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12963 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12964 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 12965 }; 12966 static const uint32_t filterctl[] = { 12967 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 12968 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 12969 }; 12970 static const uint32_t psctl[] = { 12971 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 12972 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 12973 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 12974 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 12975 }; 12976 static const uint32_t gainidx[] = { 12977 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12978 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12979 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12980 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 12981 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 12982 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 12983 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 12984 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 12985 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 12986 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 12987 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 12988 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 12989 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 12990 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 12991 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 12992 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12993 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12994 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12995 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 12996 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 12997 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 12998 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 12999 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13000 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13001 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13002 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13003 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13004 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13005 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13006 0x0000001a, 0x64ca55ad, 0x0000001a 13007 }; 13008 static const uint16_t auxgainidx[] = { 13009 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13010 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13011 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13012 0x0004, 0x0016 13013 }; 13014 static const uint16_t swctl[] = { 13015 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13016 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13017 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13018 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13019 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13020 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13021 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13022 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13023 }; 13024 static const uint8_t hf[] = { 13025 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13026 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13027 }; 13028 static const uint32_t gainval[] = { 13029 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13030 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13031 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13032 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13033 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13034 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13035 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13036 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13037 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13038 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13039 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13040 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13041 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13042 0x000000f1, 0x00000000, 0x00000000 13043 }; 13044 static const uint16_t gain[] = { 13045 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13046 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13047 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13048 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13049 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13050 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13051 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13052 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13053 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13054 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13055 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13056 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13057 }; 13058 static const uint32_t papdeps[] = { 13059 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13060 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13061 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13062 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13063 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13064 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13065 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13066 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13067 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13068 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13069 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13070 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13071 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13072 }; 13073 static const uint32_t papdmult[] = { 13074 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13075 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13076 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13077 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13078 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13079 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13080 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13081 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13082 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13083 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13084 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13085 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13086 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13087 }; 13088 static const uint32_t gainidx_a0[] = { 13089 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13090 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13091 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13092 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13093 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13094 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13095 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13096 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13097 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13098 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13099 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13100 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13101 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13102 }; 13103 static const uint16_t auxgainidx_a0[] = { 13104 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13105 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13106 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13107 0x0002, 0x0014 13108 }; 13109 static const uint32_t gainval_a0[] = { 13110 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13111 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13112 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13113 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13114 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13115 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13116 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13117 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13118 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13119 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13120 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13121 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13122 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13123 0x000000f7, 0x00000000, 0x00000000 13124 }; 13125 static const uint16_t gain_a0[] = { 13126 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13127 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13128 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13129 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13130 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13131 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13132 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13133 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13134 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13135 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13136 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13137 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13138 }; 13139 13140 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13141 13142 for (i = 0; i < 704; i++) 13143 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13144 13145 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13146 bwn_tab_sigsq_tbl); 13147 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13148 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13149 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13150 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13151 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13152 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13153 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13154 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13155 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13156 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13157 bwn_tab_pllfrac_tbl); 13158 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13159 bwn_tabl_iqlocal_tbl); 13160 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13161 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13162 13163 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13164 (siba_get_chiprev(sc->sc_dev) == 0)) { 13165 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13166 gainidx_a0); 13167 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13168 auxgainidx_a0); 13169 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13170 gainval_a0); 13171 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13172 } 13173 } 13174 13175 static void 13176 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13177 { 13178 struct bwn_softc *sc = mac->mac_sc; 13179 struct ifnet *ifp = sc->sc_ifp; 13180 struct ieee80211com *ic = ifp->if_l2com; 13181 static struct bwn_txgain_entry txgain_r2[] = { 13182 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13183 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13184 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13185 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13186 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13187 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13188 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13189 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13190 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13191 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13192 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13193 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13194 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13195 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13196 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13197 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13198 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13199 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13200 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13201 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13202 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13203 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13204 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13205 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13206 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13207 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13208 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13209 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13210 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13211 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13212 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13213 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13214 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13215 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13216 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13217 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13218 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13219 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13220 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13221 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13222 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13223 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13224 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13225 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13226 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13227 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13228 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13229 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13230 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13231 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13232 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13233 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13234 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13235 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13236 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13237 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13238 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13239 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13240 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13241 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13242 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13243 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13244 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13245 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13246 }; 13247 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13248 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13249 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13250 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13251 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13252 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13253 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13254 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13255 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13256 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13257 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13258 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13259 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13260 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13261 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13262 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13263 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13264 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13265 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13266 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13267 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13268 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13269 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13270 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13271 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13272 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13273 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13274 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13275 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13276 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13277 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13278 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13279 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13280 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13281 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13282 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13283 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13284 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13285 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13286 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13287 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13288 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13289 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13290 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13291 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13292 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13293 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13294 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13295 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13296 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13297 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13298 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13299 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13300 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13301 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13302 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13303 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13304 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13305 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13306 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13307 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13308 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13309 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13310 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13311 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13312 }; 13313 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13314 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13315 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13316 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13317 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13318 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13319 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13320 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13321 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13322 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13323 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13324 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13325 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13326 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13327 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13328 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13329 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13330 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13331 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13332 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13333 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13334 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13335 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13336 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13337 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13338 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13339 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13340 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13341 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13342 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13343 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13344 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13345 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13346 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13347 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13348 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13349 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13350 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13351 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13352 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13353 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13354 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13355 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13356 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13357 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13358 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13359 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13360 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13361 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13362 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13363 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13364 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13365 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13366 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13367 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13368 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13369 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13370 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13371 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13372 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13373 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13374 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13375 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13376 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13377 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13378 }; 13379 static struct bwn_txgain_entry txgain_r0[] = { 13380 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13381 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13382 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13383 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13384 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13385 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13386 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13387 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13388 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13389 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13390 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13391 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13392 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13393 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13394 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13395 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13396 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13397 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13398 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13399 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13400 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13401 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13402 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13403 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13404 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13405 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13406 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13407 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13408 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13409 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13410 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13411 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13412 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13413 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13414 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13415 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13416 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13417 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13418 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13419 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13420 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13421 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13422 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13423 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13424 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13425 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13426 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13427 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13428 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13429 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13430 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13431 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13432 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13433 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13434 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13435 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13436 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13437 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13438 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13439 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13440 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13441 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13442 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13443 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13444 }; 13445 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13446 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13447 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13448 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13449 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13450 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13451 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13452 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13453 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13454 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13455 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13456 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13457 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13458 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13459 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13460 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13461 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13462 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13463 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13464 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13465 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13466 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13467 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13468 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13469 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13470 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13471 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13472 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13473 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13474 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13475 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13476 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13477 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13478 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13479 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13480 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13481 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13482 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13483 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13484 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13485 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13486 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13487 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13488 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13489 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13490 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13491 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13492 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13493 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13494 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13495 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13496 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13497 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13498 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13499 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13500 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13501 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13502 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13503 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13504 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13505 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13506 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13507 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13508 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13509 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13510 }; 13511 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13512 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13513 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13514 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13515 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13516 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13517 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13518 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13519 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13520 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13521 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13522 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13523 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13524 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13525 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13526 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13527 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13528 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13529 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13530 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13531 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13532 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13533 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13534 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13535 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13536 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13537 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13538 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13539 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13540 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13541 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13542 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13543 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13544 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13545 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13546 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13547 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13548 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13549 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13550 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13551 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13552 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13553 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13554 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13555 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13556 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13557 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13558 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13559 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13560 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13561 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13562 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13563 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13564 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13565 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13566 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13567 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13568 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13569 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13570 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13571 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13572 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13573 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13574 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13575 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13576 }; 13577 static struct bwn_txgain_entry txgain_r1[] = { 13578 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13579 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13580 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13581 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13582 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13583 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13584 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13585 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13586 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13587 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13588 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13589 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13590 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13591 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13592 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13593 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13594 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13595 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13596 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13597 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13598 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13599 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13600 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13601 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13602 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13603 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13604 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13605 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13606 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13607 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13608 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13609 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13610 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13611 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13612 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13613 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13614 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13615 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13616 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13617 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13618 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13619 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13620 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13621 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13622 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13623 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13624 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13625 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13626 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13627 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13628 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13629 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13630 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13631 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13632 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13633 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13634 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13635 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13636 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13637 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13638 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13639 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13640 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13641 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13642 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13643 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13644 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13645 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13646 { 7, 11, 6, 0, 71 } 13647 }; 13648 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13649 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13650 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13651 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13652 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13653 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13654 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13655 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13656 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13657 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13658 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13659 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13660 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13661 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13662 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13663 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13664 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13665 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13666 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13667 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13668 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13669 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13670 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13671 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13672 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13673 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13674 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13675 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13676 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13677 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13678 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13679 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13680 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13681 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13682 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13683 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13684 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13685 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13686 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13687 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13688 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13689 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13690 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13691 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13692 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13693 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13694 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13695 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13696 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13697 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13698 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13699 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13700 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13701 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13702 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13703 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13704 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13705 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13706 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13707 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13708 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13709 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13710 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13711 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13712 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13713 }; 13714 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13715 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13716 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13717 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13718 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13719 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13720 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13721 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13722 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13723 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13724 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13725 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13726 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13727 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13728 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13729 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13730 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13731 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13732 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13733 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13734 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13735 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13736 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13737 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13738 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13739 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13740 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13741 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13742 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13743 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13744 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13745 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13746 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13747 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13748 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13749 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13750 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13751 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13752 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13753 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13754 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13755 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13756 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13757 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13758 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13759 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13760 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13761 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13762 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13763 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13764 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13765 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13766 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13767 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13768 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13769 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13770 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13771 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13772 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13773 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13774 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13775 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13776 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13777 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13778 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13779 }; 13780 13781 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13782 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13783 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13784 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13785 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13786 txgain_2ghz_r2); 13787 else 13788 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13789 txgain_5ghz_r2); 13790 return; 13791 } 13792 13793 if (mac->mac_phy.rev == 0) { 13794 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13795 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13796 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13797 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13798 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13799 txgain_2ghz_r0); 13800 else 13801 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13802 txgain_5ghz_r0); 13803 return; 13804 } 13805 13806 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13807 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13808 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13809 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13810 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13811 else 13812 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13813 } 13814 13815 static void 13816 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13817 { 13818 uint32_t offset, type; 13819 13820 type = BWN_TAB_GETTYPE(typeoffset); 13821 offset = BWN_TAB_GETOFFSET(typeoffset); 13822 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13823 13824 switch (type) { 13825 case BWN_TAB_8BIT: 13826 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13827 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13828 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13829 break; 13830 case BWN_TAB_16BIT: 13831 KASSERT(!(value & ~0xffff), 13832 ("%s:%d: fail", __func__, __LINE__)); 13833 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13834 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13835 break; 13836 case BWN_TAB_32BIT: 13837 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13838 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13839 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13840 break; 13841 default: 13842 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13843 } 13844 } 13845 13846 static int 13847 bwn_phy_lp_loopback(struct bwn_mac *mac) 13848 { 13849 struct bwn_phy_lp_iq_est ie; 13850 int i, index = -1; 13851 uint32_t tmp; 13852 13853 memset(&ie, 0, sizeof(ie)); 13854 13855 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13856 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13857 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13858 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13859 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13860 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13861 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13862 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13863 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13864 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13865 for (i = 0; i < 32; i++) { 13866 bwn_phy_lp_set_rxgain_idx(mac, i); 13867 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13868 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13869 continue; 13870 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13871 if ((tmp > 4000) && (tmp < 10000)) { 13872 index = i; 13873 break; 13874 } 13875 } 13876 bwn_phy_lp_ddfs_turnoff(mac); 13877 return (index); 13878 } 13879 13880 static void 13881 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13882 { 13883 13884 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13885 } 13886 13887 static void 13888 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13889 int incr1, int incr2, int scale_idx) 13890 { 13891 13892 bwn_phy_lp_ddfs_turnoff(mac); 13893 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13894 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13895 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13896 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13897 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13898 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13899 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 13900 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 13901 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 13902 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 13903 } 13904 13905 static uint8_t 13906 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 13907 struct bwn_phy_lp_iq_est *ie) 13908 { 13909 int i; 13910 13911 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 13912 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 13913 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 13914 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 13915 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 13916 13917 for (i = 0; i < 500; i++) { 13918 if (!(BWN_PHY_READ(mac, 13919 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 13920 break; 13921 DELAY(1000); 13922 } 13923 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 13924 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13925 return 0; 13926 } 13927 13928 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 13929 ie->ie_iqprod <<= 16; 13930 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 13931 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 13932 ie->ie_ipwr <<= 16; 13933 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 13934 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 13935 ie->ie_qpwr <<= 16; 13936 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 13937 13938 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13939 return 1; 13940 } 13941 13942 static uint32_t 13943 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 13944 { 13945 uint32_t offset, type, value; 13946 13947 type = BWN_TAB_GETTYPE(typeoffset); 13948 offset = BWN_TAB_GETOFFSET(typeoffset); 13949 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13950 13951 switch (type) { 13952 case BWN_TAB_8BIT: 13953 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13954 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 13955 break; 13956 case BWN_TAB_16BIT: 13957 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13958 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13959 break; 13960 case BWN_TAB_32BIT: 13961 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13962 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 13963 value <<= 16; 13964 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13965 break; 13966 default: 13967 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13968 value = 0; 13969 } 13970 13971 return (value); 13972 } 13973 13974 static void 13975 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 13976 { 13977 13978 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 13979 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 13980 } 13981 13982 static void 13983 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 13984 { 13985 uint16_t ctl; 13986 13987 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 13988 ctl |= dac << 7; 13989 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 13990 } 13991 13992 static void 13993 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 13994 { 13995 13996 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 13997 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 13998 } 13999 14000 static void 14001 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14002 { 14003 14004 if (mac->mac_phy.rev < 2) 14005 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14006 else { 14007 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14008 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14009 } 14010 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14011 } 14012 14013 static uint16_t 14014 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14015 { 14016 14017 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14018 } 14019 14020 static uint8_t 14021 bwn_nbits(int32_t val) 14022 { 14023 uint32_t tmp; 14024 uint8_t nbits = 0; 14025 14026 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14027 nbits++; 14028 return (nbits); 14029 } 14030 14031 static void 14032 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14033 struct bwn_txgain_entry *table) 14034 { 14035 int i; 14036 14037 for (i = offset; i < count; i++) 14038 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14039 } 14040 14041 static void 14042 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14043 struct bwn_txgain_entry data) 14044 { 14045 14046 if (mac->mac_phy.rev >= 2) 14047 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14048 else 14049 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14050 } 14051 14052 static void 14053 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14054 struct bwn_txgain_entry te) 14055 { 14056 struct bwn_softc *sc = mac->mac_sc; 14057 struct ifnet *ifp = sc->sc_ifp; 14058 struct ieee80211com *ic = ifp->if_l2com; 14059 uint32_t tmp; 14060 14061 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14062 14063 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14064 if (mac->mac_phy.rev >= 3) { 14065 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14066 (0x10 << 24) : (0x70 << 24)); 14067 } else { 14068 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14069 (0x14 << 24) : (0x7f << 24)); 14070 } 14071 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14072 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14073 te.te_bbmult << 20 | te.te_dac << 28); 14074 } 14075 14076 static void 14077 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14078 struct bwn_txgain_entry te) 14079 { 14080 14081 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14082 14083 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14084 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14085 te.te_dac); 14086 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14087 } 14088 14089 static void 14090 bwn_sysctl_node(struct bwn_softc *sc) 14091 { 14092 struct bwn_mac *mac; 14093 struct bwn_stats *stats; 14094 struct sysctl_ctx_list *ctx; 14095 struct sysctl_oid *tree; 14096 14097 /* XXX assume that count of MAC is only 1. */ 14098 14099 if ((mac = sc->sc_curmac) == NULL) 14100 return; 14101 stats = &mac->mac_stats; 14102 14103 ctx = device_get_sysctl_ctx(sc->sc_dev); 14104 tree = device_get_sysctl_tree(sc->sc_dev); 14105 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14106 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14107 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14108 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14109 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14110 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14111 14112 #ifdef BWN_DEBUG 14113 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14114 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14115 #endif 14116 } 14117 14118 static device_method_t bwn_methods[] = { 14119 /* Device interface */ 14120 DEVMETHOD(device_probe, bwn_probe), 14121 DEVMETHOD(device_attach, bwn_attach), 14122 DEVMETHOD(device_detach, bwn_detach), 14123 DEVMETHOD(device_suspend, bwn_suspend), 14124 DEVMETHOD(device_resume, bwn_resume), 14125 DEVMETHOD_END 14126 }; 14127 static driver_t bwn_driver = { 14128 "bwn", 14129 bwn_methods, 14130 sizeof(struct bwn_softc) 14131 }; 14132 static devclass_t bwn_devclass; 14133 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, NULL, NULL); 14134 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14135 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14136 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14137 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14138