1 /*- 2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD: head/sys/dev/bwn/if_bwn.c 260444 2014-01-08 08:06:56Z kevlo $"); 32 33 /* 34 * The Broadcom Wireless LAN controller driver. 35 */ 36 37 #include <opt_wlan.h> 38 #include <opt_bwn.h> 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/module.h> 43 #include <sys/kernel.h> 44 #include <sys/endian.h> 45 #include <sys/errno.h> 46 #include <sys/firmware.h> 47 #include <sys/bus_resource.h> 48 #include <sys/bus.h> 49 #include <sys/rman.h> 50 #include <sys/socket.h> 51 #include <sys/sockio.h> 52 53 #include <net/ethernet.h> 54 #include <net/if.h> 55 #include <net/if_var.h> 56 #include <net/if_arp.h> 57 #include <net/if_dl.h> 58 #include <net/if_llc.h> 59 #include <net/if_media.h> 60 #include <net/if_types.h> 61 #include <net/ifq_var.h> 62 63 #include <bus/pci/pcivar.h> 64 #include <bus/pci/pcireg.h> 65 #include <dev/netif/bwn/siba/siba_ids.h> 66 #include <dev/netif/bwn/siba/sibareg.h> 67 #include <dev/netif/bwn/siba/sibavar.h> 68 69 #include <netproto/802_11/ieee80211_var.h> 70 #include <netproto/802_11/ieee80211_radiotap.h> 71 #include <netproto/802_11/ieee80211_regdomain.h> 72 #include <netproto/802_11/ieee80211_phy.h> 73 #include <netproto/802_11/ieee80211_ratectl.h> 74 75 #include "if_bwnreg.h" 76 #include "if_bwnvar.h" 77 78 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, 79 "Broadcom driver parameters"); 80 81 /* 82 * Tunable & sysctl variables. 83 */ 84 85 #ifdef BWN_DEBUG 86 static int bwn_debug = 0; 87 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0, 88 "Broadcom debugging printfs"); 89 TUNABLE_INT("hw.bwn.debug", &bwn_debug); 90 enum { 91 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 92 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 93 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 94 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 95 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 96 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 97 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 98 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 99 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 100 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 101 BWN_DEBUG_NODE = 0x00000400, /* node management */ 102 BWN_DEBUG_LED = 0x00000800, /* led management */ 103 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 104 BWN_DEBUG_LO = 0x00002000, /* LO */ 105 BWN_DEBUG_FW = 0x00004000, /* firmware */ 106 BWN_DEBUG_WME = 0x00008000, /* WME */ 107 BWN_DEBUG_RF = 0x00010000, /* RF */ 108 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 109 BWN_DEBUG_ANY = 0xffffffff 110 }; 111 #define DPRINTF(sc, m, fmt, ...) do { \ 112 if (sc->sc_debug & (m)) \ 113 kprintf(fmt, __VA_ARGS__); \ 114 } while (0) 115 #else 116 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 117 #endif 118 119 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 120 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 121 "uses Bad Frames Preemption"); 122 static int bwn_bluetooth = 1; 123 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 124 "turns on Bluetooth Coexistence"); 125 static int bwn_hwpctl = 0; 126 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 127 "uses H/W power control"); 128 static int bwn_msi_enable = 1; 129 TUNABLE_INT("hw.bwn.msi.enable", &bwn_msi_enable); 130 static int bwn_usedma = 1; 131 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 132 "uses DMA"); 133 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 134 static int bwn_wme = 1; 135 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 136 "uses WME support"); 137 138 static int bwn_attach_pre(struct bwn_softc *); 139 static int bwn_attach_post(struct bwn_softc *); 140 static void bwn_sprom_bugfixes(device_t); 141 static void bwn_init(void *); 142 static int bwn_init_locked(struct bwn_softc *); 143 static int bwn_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *); 144 static void bwn_start(struct ifnet *, struct ifaltq_subque *); 145 static int bwn_attach_core(struct bwn_mac *); 146 static void bwn_reset_core(struct bwn_mac *, uint32_t); 147 static int bwn_phy_getinfo(struct bwn_mac *, int); 148 static int bwn_chiptest(struct bwn_mac *); 149 static int bwn_setup_channels(struct bwn_mac *, int, int); 150 static int bwn_phy_g_attach(struct bwn_mac *); 151 static void bwn_phy_g_detach(struct bwn_mac *); 152 static void bwn_phy_g_init_pre(struct bwn_mac *); 153 static int bwn_phy_g_prepare_hw(struct bwn_mac *); 154 static int bwn_phy_g_init(struct bwn_mac *); 155 static void bwn_phy_g_exit(struct bwn_mac *); 156 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 157 static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 158 uint16_t); 159 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 160 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 161 uint16_t); 162 static int bwn_phy_g_hwpctl(struct bwn_mac *); 163 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 164 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 165 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 166 static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 167 static int bwn_phy_g_im(struct bwn_mac *, int); 168 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 169 static void bwn_phy_g_set_txpwr(struct bwn_mac *); 170 static void bwn_phy_g_task_15s(struct bwn_mac *); 171 static void bwn_phy_g_task_60s(struct bwn_mac *); 172 static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 173 static void bwn_phy_switch_analog(struct bwn_mac *, int); 174 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 175 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 176 uint16_t); 177 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 178 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 179 uint32_t); 180 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 181 uint16_t); 182 static void bwn_addchannels(struct ieee80211_channel [], int, int *, 183 const struct bwn_channelinfo *, int); 184 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 185 const struct ieee80211_bpf_params *); 186 static void bwn_updateslot(struct ifnet *); 187 static void bwn_update_promisc(struct ifnet *); 188 static void bwn_wme_init(struct bwn_mac *); 189 static int bwn_wme_update(struct ieee80211com *); 190 static void bwn_wme_clear(struct bwn_softc *); 191 static void bwn_wme_load(struct bwn_mac *); 192 static void bwn_wme_loadparams(struct bwn_mac *, 193 const struct wmeParams *, uint16_t); 194 static void bwn_scan_start(struct ieee80211com *); 195 static void bwn_scan_end(struct ieee80211com *); 196 static void bwn_set_channel(struct ieee80211com *); 197 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 198 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 199 const uint8_t [IEEE80211_ADDR_LEN], 200 const uint8_t [IEEE80211_ADDR_LEN]); 201 static void bwn_vap_delete(struct ieee80211vap *); 202 static void bwn_stop(struct bwn_softc *, int); 203 static void bwn_stop_locked(struct bwn_softc *, int); 204 static int bwn_core_init(struct bwn_mac *); 205 static void bwn_core_start(struct bwn_mac *); 206 static void bwn_core_exit(struct bwn_mac *); 207 static void bwn_bt_disable(struct bwn_mac *); 208 static int bwn_chip_init(struct bwn_mac *); 209 static uint64_t bwn_hf_read(struct bwn_mac *); 210 static void bwn_hf_write(struct bwn_mac *, uint64_t); 211 static void bwn_set_txretry(struct bwn_mac *, int, int); 212 static void bwn_rate_init(struct bwn_mac *); 213 static void bwn_set_phytxctl(struct bwn_mac *); 214 static void bwn_spu_setdelay(struct bwn_mac *, int); 215 static void bwn_bt_enable(struct bwn_mac *); 216 static void bwn_set_macaddr(struct bwn_mac *); 217 static void bwn_crypt_init(struct bwn_mac *); 218 static void bwn_chip_exit(struct bwn_mac *); 219 static int bwn_fw_fillinfo(struct bwn_mac *); 220 static int bwn_fw_loaducode(struct bwn_mac *); 221 static int bwn_gpio_init(struct bwn_mac *); 222 static int bwn_fw_loadinitvals(struct bwn_mac *); 223 static int bwn_phy_init(struct bwn_mac *); 224 static void bwn_set_txantenna(struct bwn_mac *, int); 225 static void bwn_set_opmode(struct bwn_mac *); 226 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 227 static uint8_t bwn_plcp_getcck(const uint8_t); 228 static uint8_t bwn_plcp_getofdm(const uint8_t); 229 static void bwn_pio_init(struct bwn_mac *); 230 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 231 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 232 int); 233 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 234 struct bwn_pio_rxqueue *, int); 235 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 236 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 237 uint16_t); 238 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 239 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 240 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 241 static void bwn_pio_handle_txeof(struct bwn_mac *, 242 const struct bwn_txstatus *); 243 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 244 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 245 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 246 uint16_t); 247 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 248 uint32_t); 249 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 250 struct mbuf *); 251 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 252 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 253 struct bwn_pio_txqueue *, uint32_t, const void *, int); 254 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 255 uint16_t, uint32_t); 256 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 257 struct bwn_pio_txqueue *, uint16_t, const void *, int); 258 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 259 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 260 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 261 uint16_t, struct bwn_pio_txpkt **); 262 static void bwn_dma_init(struct bwn_mac *); 263 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 264 static int bwn_dma_mask2type(uint64_t); 265 static uint64_t bwn_dma_mask(struct bwn_mac *); 266 static uint16_t bwn_dma_base(int, int); 267 static void bwn_dma_ringfree(struct bwn_dma_ring **); 268 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 269 int, struct bwn_dmadesc_generic **, 270 struct bwn_dmadesc_meta **); 271 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 272 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 273 int, int); 274 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 275 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 276 static void bwn_dma_32_resume(struct bwn_dma_ring *); 277 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 278 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 279 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 280 int, struct bwn_dmadesc_generic **, 281 struct bwn_dmadesc_meta **); 282 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 283 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 284 int, int); 285 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 286 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 287 static void bwn_dma_64_resume(struct bwn_dma_ring *); 288 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 289 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 290 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 291 static void bwn_dma_setup(struct bwn_dma_ring *); 292 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 293 static void bwn_dma_cleanup(struct bwn_dma_ring *); 294 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 295 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 296 static void bwn_dma_rx_handle_overflow(struct bwn_dma_ring *); 297 static void bwn_dma_rx(struct bwn_dma_ring *); 298 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 299 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 300 struct bwn_dmadesc_meta *); 301 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 302 static int bwn_dma_gettype(struct bwn_mac *); 303 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 304 static int bwn_dma_freeslot(struct bwn_dma_ring *); 305 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 306 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 307 static int bwn_dma_newbuf(struct bwn_dma_ring *, 308 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 309 int); 310 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 311 bus_size_t, int); 312 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 313 static void bwn_dma_handle_txeof(struct bwn_mac *, 314 const struct bwn_txstatus *); 315 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 316 struct mbuf *); 317 static int bwn_dma_getslot(struct bwn_dma_ring *); 318 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 319 uint8_t); 320 static int bwn_dma_attach(struct bwn_mac *); 321 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 322 int, int, int); 323 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 324 const struct bwn_txstatus *, uint16_t, int *); 325 static void bwn_dma_free(struct bwn_mac *); 326 static void bwn_phy_g_init_sub(struct bwn_mac *); 327 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 328 static void bwn_phy_init_b5(struct bwn_mac *); 329 static void bwn_phy_init_b6(struct bwn_mac *); 330 static void bwn_phy_init_a(struct bwn_mac *); 331 static void bwn_loopback_calcgain(struct bwn_mac *); 332 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 333 static void bwn_lo_g_init(struct bwn_mac *); 334 static void bwn_lo_g_adjust(struct bwn_mac *); 335 static void bwn_lo_get_powervector(struct bwn_mac *); 336 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 337 const struct bwn_bbatt *, const struct bwn_rfatt *); 338 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 339 static void bwn_phy_hwpctl_init(struct bwn_mac *); 340 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 341 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 342 const struct bwn_bbatt *, const struct bwn_rfatt *, 343 uint8_t); 344 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 345 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 346 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 347 static void bwn_wa_init(struct bwn_mac *); 348 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 349 uint16_t); 350 static void bwn_dummy_transmission(struct bwn_mac *, int, int); 351 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 352 uint32_t); 353 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 354 uint16_t); 355 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 356 static void bwn_mac_suspend(struct bwn_mac *); 357 static void bwn_mac_enable(struct bwn_mac *); 358 static void bwn_psctl(struct bwn_mac *, uint32_t); 359 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 360 static void bwn_nrssi_offset(struct bwn_mac *); 361 static void bwn_nrssi_threshold(struct bwn_mac *); 362 static void bwn_nrssi_slope_11g(struct bwn_mac *); 363 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 364 int16_t); 365 static void bwn_set_original_gains(struct bwn_mac *); 366 static void bwn_hwpctl_early_init(struct bwn_mac *); 367 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 368 static uint16_t bwn_phy_g_chan2freq(uint8_t); 369 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 370 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 371 const char *, struct bwn_fwfile *); 372 static void bwn_release_firmware(struct bwn_mac *); 373 static void bwn_do_release_fw(struct bwn_fwfile *); 374 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 375 static int bwn_fwinitvals_write(struct bwn_mac *, 376 const struct bwn_fwinitvals *, size_t, size_t); 377 static int bwn_switch_channel(struct bwn_mac *, int); 378 static uint16_t bwn_ant2phy(int); 379 static void bwn_mac_write_bssid(struct bwn_mac *); 380 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 381 const uint8_t *); 382 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 383 const uint8_t *, size_t, const uint8_t *); 384 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 385 const uint8_t *); 386 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 387 const uint8_t *); 388 static void bwn_phy_exit(struct bwn_mac *); 389 static void bwn_core_stop(struct bwn_mac *); 390 static int bwn_switch_band(struct bwn_softc *, 391 struct ieee80211_channel *); 392 static void bwn_phy_reset(struct bwn_mac *); 393 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 394 static void bwn_set_pretbtt(struct bwn_mac *); 395 static void bwn_intr(void *); 396 static void bwn_intrtask(void *, int); 397 static void bwn_restart(struct bwn_mac *, const char *); 398 static void bwn_intr_ucode_debug(struct bwn_mac *); 399 static void bwn_intr_tbtt_indication(struct bwn_mac *); 400 static void bwn_intr_atim_end(struct bwn_mac *); 401 static void bwn_intr_beacon(struct bwn_mac *); 402 static void bwn_intr_pmq(struct bwn_mac *); 403 static void bwn_intr_noise(struct bwn_mac *); 404 static void bwn_intr_txeof(struct bwn_mac *); 405 static void bwn_hwreset(void *, int); 406 static void bwn_handle_fwpanic(struct bwn_mac *); 407 static void bwn_load_beacon0(struct bwn_mac *); 408 static void bwn_load_beacon1(struct bwn_mac *); 409 static uint32_t bwn_jssi_read(struct bwn_mac *); 410 static void bwn_noise_gensample(struct bwn_mac *); 411 static void bwn_handle_txeof(struct bwn_mac *, 412 const struct bwn_txstatus *); 413 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 414 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 415 static void bwn_start_locked(struct ifnet *); 416 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 417 struct mbuf *); 418 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 419 static int bwn_set_txhdr(struct bwn_mac *, 420 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 421 uint16_t); 422 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 423 const uint8_t); 424 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 425 static uint8_t bwn_get_fbrate(uint8_t); 426 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 427 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 428 static void bwn_phy_lock(struct bwn_mac *); 429 static void bwn_phy_unlock(struct bwn_mac *); 430 static void bwn_rf_lock(struct bwn_mac *); 431 static void bwn_rf_unlock(struct bwn_mac *); 432 static void bwn_txpwr(void *, int); 433 static void bwn_tasks(void *); 434 static void bwn_task_15s(struct bwn_mac *); 435 static void bwn_task_30s(struct bwn_mac *); 436 static void bwn_task_60s(struct bwn_mac *); 437 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 438 uint8_t); 439 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 440 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 441 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 442 int, int); 443 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 444 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 445 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 446 static void bwn_watchdog(void *); 447 static void bwn_dma_stop(struct bwn_mac *); 448 static void bwn_pio_stop(struct bwn_mac *); 449 static void bwn_dma_ringstop(struct bwn_dma_ring **); 450 static void bwn_led_attach(struct bwn_mac *); 451 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 452 static void bwn_led_event(struct bwn_mac *, int); 453 static void bwn_led_blink_start(struct bwn_mac *, int, int); 454 static void bwn_led_blink_next(void *); 455 static void bwn_led_blink_end(void *); 456 static void bwn_rfswitch(void *); 457 static void bwn_rf_turnon(struct bwn_mac *); 458 static void bwn_rf_turnoff(struct bwn_mac *); 459 static void bwn_phy_lp_init_pre(struct bwn_mac *); 460 static int bwn_phy_lp_init(struct bwn_mac *); 461 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 462 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 463 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 464 uint16_t); 465 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 466 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 467 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 468 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 469 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 470 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 471 static void bwn_phy_lp_task_60s(struct bwn_mac *); 472 static void bwn_phy_lp_readsprom(struct bwn_mac *); 473 static void bwn_phy_lp_bbinit(struct bwn_mac *); 474 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 475 static void bwn_phy_lp_calib(struct bwn_mac *); 476 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 477 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 478 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 479 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 480 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 481 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 482 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 483 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 484 static void bwn_phy_lp_bugfix(struct bwn_mac *); 485 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 486 static void bwn_phy_lp_tblinit(struct bwn_mac *); 487 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 488 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 489 static void bwn_phy_lp_b2062_init(struct bwn_mac *); 490 static void bwn_phy_lp_b2063_init(struct bwn_mac *); 491 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 492 static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 493 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 494 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 495 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 496 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 497 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 498 const void *); 499 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 500 static struct bwn_txgain 501 bwn_phy_lp_get_txgain(struct bwn_mac *); 502 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 503 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 504 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 505 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 506 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 507 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 508 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 509 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 510 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 511 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 512 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 513 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 514 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 515 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 516 static int bwn_phy_lp_loopback(struct bwn_mac *); 517 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 518 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 519 int); 520 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 521 struct bwn_phy_lp_iq_est *); 522 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 523 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 524 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 525 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 526 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 527 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 528 static uint8_t bwn_nbits(int32_t); 529 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 530 struct bwn_txgain_entry *); 531 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 532 struct bwn_txgain_entry); 533 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 534 struct bwn_txgain_entry); 535 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 536 struct bwn_txgain_entry); 537 static void bwn_sysctl_node(struct bwn_softc *); 538 539 static const struct bwn_channelinfo bwn_chantable_bg = { 540 .channels = { 541 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 542 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 543 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 544 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 545 { 2472, 13, 30 }, { 2484, 14, 30 } }, 546 .nchannels = 14 547 }; 548 549 static const struct bwn_channelinfo bwn_chantable_a = { 550 .channels = { 551 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 552 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 553 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 554 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 555 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 556 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 557 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 558 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 559 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 560 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 561 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 562 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 563 { 6080, 216, 30 } }, 564 .nchannels = 37 565 }; 566 567 static const struct bwn_channelinfo bwn_chantable_n = { 568 .channels = { 569 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 570 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 571 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 572 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 573 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 574 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 575 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 576 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 577 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 578 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 579 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 580 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 581 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 582 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 583 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 584 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 585 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 586 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 587 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 588 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 589 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 590 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 591 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 592 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 593 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 594 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 595 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 596 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 597 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 598 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 599 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 600 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 601 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 602 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 603 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 604 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 605 { 6130, 226, 30 }, { 6140, 228, 30 } }, 606 .nchannels = 110 607 }; 608 609 static const uint8_t bwn_b2063_chantable_data[33][12] = { 610 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 611 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 612 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 613 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 614 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 615 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 616 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 617 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 618 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 619 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 620 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 621 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 622 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 623 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 624 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 625 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 626 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 627 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 628 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 629 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 630 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 631 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 632 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 633 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 634 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 635 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 636 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 637 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 638 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 639 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 640 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 641 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 642 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 643 }; 644 645 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 646 { 1, 2412, bwn_b2063_chantable_data[0] }, 647 { 2, 2417, bwn_b2063_chantable_data[0] }, 648 { 3, 2422, bwn_b2063_chantable_data[0] }, 649 { 4, 2427, bwn_b2063_chantable_data[1] }, 650 { 5, 2432, bwn_b2063_chantable_data[1] }, 651 { 6, 2437, bwn_b2063_chantable_data[1] }, 652 { 7, 2442, bwn_b2063_chantable_data[1] }, 653 { 8, 2447, bwn_b2063_chantable_data[1] }, 654 { 9, 2452, bwn_b2063_chantable_data[2] }, 655 { 10, 2457, bwn_b2063_chantable_data[2] }, 656 { 11, 2462, bwn_b2063_chantable_data[3] }, 657 { 12, 2467, bwn_b2063_chantable_data[3] }, 658 { 13, 2472, bwn_b2063_chantable_data[3] }, 659 { 14, 2484, bwn_b2063_chantable_data[4] }, 660 { 34, 5170, bwn_b2063_chantable_data[5] }, 661 { 36, 5180, bwn_b2063_chantable_data[6] }, 662 { 38, 5190, bwn_b2063_chantable_data[7] }, 663 { 40, 5200, bwn_b2063_chantable_data[8] }, 664 { 42, 5210, bwn_b2063_chantable_data[9] }, 665 { 44, 5220, bwn_b2063_chantable_data[10] }, 666 { 46, 5230, bwn_b2063_chantable_data[11] }, 667 { 48, 5240, bwn_b2063_chantable_data[12] }, 668 { 52, 5260, bwn_b2063_chantable_data[13] }, 669 { 56, 5280, bwn_b2063_chantable_data[14] }, 670 { 60, 5300, bwn_b2063_chantable_data[14] }, 671 { 64, 5320, bwn_b2063_chantable_data[15] }, 672 { 100, 5500, bwn_b2063_chantable_data[16] }, 673 { 104, 5520, bwn_b2063_chantable_data[17] }, 674 { 108, 5540, bwn_b2063_chantable_data[18] }, 675 { 112, 5560, bwn_b2063_chantable_data[19] }, 676 { 116, 5580, bwn_b2063_chantable_data[20] }, 677 { 120, 5600, bwn_b2063_chantable_data[21] }, 678 { 124, 5620, bwn_b2063_chantable_data[21] }, 679 { 128, 5640, bwn_b2063_chantable_data[22] }, 680 { 132, 5660, bwn_b2063_chantable_data[22] }, 681 { 136, 5680, bwn_b2063_chantable_data[22] }, 682 { 140, 5700, bwn_b2063_chantable_data[23] }, 683 { 149, 5745, bwn_b2063_chantable_data[23] }, 684 { 153, 5765, bwn_b2063_chantable_data[23] }, 685 { 157, 5785, bwn_b2063_chantable_data[23] }, 686 { 161, 5805, bwn_b2063_chantable_data[23] }, 687 { 165, 5825, bwn_b2063_chantable_data[23] }, 688 { 184, 4920, bwn_b2063_chantable_data[24] }, 689 { 188, 4940, bwn_b2063_chantable_data[25] }, 690 { 192, 4960, bwn_b2063_chantable_data[26] }, 691 { 196, 4980, bwn_b2063_chantable_data[27] }, 692 { 200, 5000, bwn_b2063_chantable_data[28] }, 693 { 204, 5020, bwn_b2063_chantable_data[29] }, 694 { 208, 5040, bwn_b2063_chantable_data[30] }, 695 { 212, 5060, bwn_b2063_chantable_data[31] }, 696 { 216, 5080, bwn_b2063_chantable_data[32] } 697 }; 698 699 static const uint8_t bwn_b2062_chantable_data[22][12] = { 700 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 701 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 702 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 703 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 704 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 705 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 706 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 707 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 708 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 713 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 714 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 715 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 716 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 717 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 718 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 719 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 720 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 721 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 722 }; 723 724 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 725 { 1, 2412, bwn_b2062_chantable_data[0] }, 726 { 2, 2417, bwn_b2062_chantable_data[0] }, 727 { 3, 2422, bwn_b2062_chantable_data[0] }, 728 { 4, 2427, bwn_b2062_chantable_data[0] }, 729 { 5, 2432, bwn_b2062_chantable_data[0] }, 730 { 6, 2437, bwn_b2062_chantable_data[0] }, 731 { 7, 2442, bwn_b2062_chantable_data[0] }, 732 { 8, 2447, bwn_b2062_chantable_data[0] }, 733 { 9, 2452, bwn_b2062_chantable_data[0] }, 734 { 10, 2457, bwn_b2062_chantable_data[0] }, 735 { 11, 2462, bwn_b2062_chantable_data[0] }, 736 { 12, 2467, bwn_b2062_chantable_data[0] }, 737 { 13, 2472, bwn_b2062_chantable_data[0] }, 738 { 14, 2484, bwn_b2062_chantable_data[0] }, 739 { 34, 5170, bwn_b2062_chantable_data[1] }, 740 { 38, 5190, bwn_b2062_chantable_data[2] }, 741 { 42, 5210, bwn_b2062_chantable_data[2] }, 742 { 46, 5230, bwn_b2062_chantable_data[3] }, 743 { 36, 5180, bwn_b2062_chantable_data[4] }, 744 { 40, 5200, bwn_b2062_chantable_data[5] }, 745 { 44, 5220, bwn_b2062_chantable_data[6] }, 746 { 48, 5240, bwn_b2062_chantable_data[3] }, 747 { 52, 5260, bwn_b2062_chantable_data[3] }, 748 { 56, 5280, bwn_b2062_chantable_data[3] }, 749 { 60, 5300, bwn_b2062_chantable_data[7] }, 750 { 64, 5320, bwn_b2062_chantable_data[8] }, 751 { 100, 5500, bwn_b2062_chantable_data[9] }, 752 { 104, 5520, bwn_b2062_chantable_data[10] }, 753 { 108, 5540, bwn_b2062_chantable_data[10] }, 754 { 112, 5560, bwn_b2062_chantable_data[10] }, 755 { 116, 5580, bwn_b2062_chantable_data[11] }, 756 { 120, 5600, bwn_b2062_chantable_data[12] }, 757 { 124, 5620, bwn_b2062_chantable_data[12] }, 758 { 128, 5640, bwn_b2062_chantable_data[12] }, 759 { 132, 5660, bwn_b2062_chantable_data[12] }, 760 { 136, 5680, bwn_b2062_chantable_data[12] }, 761 { 140, 5700, bwn_b2062_chantable_data[12] }, 762 { 149, 5745, bwn_b2062_chantable_data[12] }, 763 { 153, 5765, bwn_b2062_chantable_data[12] }, 764 { 157, 5785, bwn_b2062_chantable_data[12] }, 765 { 161, 5805, bwn_b2062_chantable_data[12] }, 766 { 165, 5825, bwn_b2062_chantable_data[12] }, 767 { 184, 4920, bwn_b2062_chantable_data[13] }, 768 { 188, 4940, bwn_b2062_chantable_data[14] }, 769 { 192, 4960, bwn_b2062_chantable_data[15] }, 770 { 196, 4980, bwn_b2062_chantable_data[16] }, 771 { 200, 5000, bwn_b2062_chantable_data[17] }, 772 { 204, 5020, bwn_b2062_chantable_data[18] }, 773 { 208, 5040, bwn_b2062_chantable_data[19] }, 774 { 212, 5060, bwn_b2062_chantable_data[20] }, 775 { 216, 5080, bwn_b2062_chantable_data[21] } 776 }; 777 778 /* for LP PHY */ 779 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 780 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 781 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 782 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 783 { 13, -66, 13 }, { 14, -66, 13 }, 784 }; 785 786 /* for LP PHY */ 787 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 788 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 789 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 790 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 791 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 792 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 793 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 794 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 795 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 796 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 797 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 798 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 799 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 800 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 801 }; 802 803 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 804 805 static const uint8_t bwn_tab_sigsq_tbl[] = { 806 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 807 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 808 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 809 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 810 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 811 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 812 }; 813 814 static const uint8_t bwn_tab_pllfrac_tbl[] = { 815 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 816 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 817 }; 818 819 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 820 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 821 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 822 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 823 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 824 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 825 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 826 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 827 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 831 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 832 }; 833 834 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 835 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 836 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 837 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 838 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 839 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 840 841 #define VENDOR_LED_ACT(vendor) \ 842 { \ 843 .vid = PCI_VENDOR_##vendor, \ 844 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 845 } 846 847 static const struct { 848 uint16_t vid; 849 uint8_t led_act[BWN_LED_MAX]; 850 } bwn_vendor_led_act[] = { 851 VENDOR_LED_ACT(COMPAQ), 852 VENDOR_LED_ACT(ASUSTEK) 853 }; 854 855 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 856 { BWN_VENDOR_LED_ACT_DEFAULT }; 857 858 #undef VENDOR_LED_ACT 859 860 static const struct { 861 int on_dur; 862 int off_dur; 863 } bwn_led_duration[109] = { 864 [0] = { 400, 100 }, 865 [2] = { 150, 75 }, 866 [4] = { 90, 45 }, 867 [11] = { 66, 34 }, 868 [12] = { 53, 26 }, 869 [18] = { 42, 21 }, 870 [22] = { 35, 17 }, 871 [24] = { 32, 16 }, 872 [36] = { 21, 10 }, 873 [48] = { 16, 8 }, 874 [72] = { 11, 5 }, 875 [96] = { 9, 4 }, 876 [108] = { 7, 3 } 877 }; 878 879 static const uint16_t bwn_wme_shm_offsets[] = { 880 [0] = BWN_WME_BESTEFFORT, 881 [1] = BWN_WME_BACKGROUND, 882 [2] = BWN_WME_VOICE, 883 [3] = BWN_WME_VIDEO, 884 }; 885 886 static const struct siba_devid bwn_devs[] = { 887 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 888 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 889 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 890 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 891 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 892 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 893 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 894 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 895 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 896 }; 897 898 static int 899 bwn_probe(device_t dev) 900 { 901 int i; 902 903 wlan_serialize_enter(); 904 905 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 906 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 907 siba_get_device(dev) == bwn_devs[i].sd_device && 908 siba_get_revid(dev) == bwn_devs[i].sd_rev) { 909 wlan_serialize_exit(); 910 return (BUS_PROBE_DEFAULT); 911 } 912 } 913 wlan_serialize_exit(); 914 return (ENXIO); 915 } 916 917 static int 918 bwn_attach(device_t dev) 919 { 920 struct bwn_mac *mac; 921 struct bwn_softc *sc = device_get_softc(dev); 922 int error; 923 u_int irq_flags; 924 925 wlan_serialize_enter(); 926 927 sc->sc_dev = dev; 928 #ifdef BWN_DEBUG 929 sc->sc_debug = bwn_debug; 930 #endif 931 932 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 933 error = bwn_attach_pre(sc); 934 if (error != 0) { 935 wlan_serialize_exit(); 936 return (error); 937 } 938 bwn_sprom_bugfixes(dev); 939 sc->sc_flags |= BWN_FLAG_ATTACHED; 940 } 941 942 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 943 if (siba_get_pci_device(dev) != 0x4313 && 944 siba_get_pci_device(dev) != 0x431a && 945 siba_get_pci_device(dev) != 0x4321) { 946 device_printf(sc->sc_dev, 947 "skip 802.11 cores\n"); 948 wlan_serialize_exit(); 949 return (ENODEV); 950 } 951 } 952 953 mac = (struct bwn_mac *)kmalloc(sizeof(*mac), M_DEVBUF, 954 M_INTWAIT | M_ZERO); 955 mac->mac_sc = sc; 956 mac->mac_status = BWN_MAC_STATUS_UNINIT; 957 if (bwn_bfp != 0) 958 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 959 960 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 961 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 962 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 963 964 error = bwn_attach_core(mac); 965 if (error) 966 goto fail0; 967 bwn_led_attach(mac); 968 969 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 970 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 971 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 972 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 973 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 974 mac->mac_phy.rf_rev); 975 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 976 device_printf(sc->sc_dev, "DMA (%d bits)\n", 977 mac->mac_method.dma.dmatype); 978 else 979 device_printf(sc->sc_dev, "PIO\n"); 980 981 /* Allocate IRQ resource. */ 982 sc->bwn_irq_rid = 0; 983 sc->bwn_irq_type = pci_alloc_1intr(sc->sc_dev, bwn_msi_enable, 984 &sc->bwn_irq_rid, &irq_flags); 985 if ((sc->bwn_irq = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ, 986 &sc->bwn_irq_rid, irq_flags)) == NULL) { 987 device_printf(sc->sc_dev, "Cannot allocate interrupt\n"); 988 goto fail1; 989 } 990 if (bus_setup_intr(sc->sc_dev, sc->bwn_irq, INTR_MPSAFE, 991 bwn_intr, mac, &sc->bwn_intr, &wlan_global_serializer)) { 992 device_printf(sc->sc_dev, "Cannot set up interrupt\n"); 993 return (EINVAL); 994 } 995 996 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 997 998 /* 999 * calls attach-post routine 1000 */ 1001 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1002 bwn_attach_post(sc); 1003 1004 wlan_serialize_exit(); 1005 return (0); 1006 fail1: 1007 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI) 1008 pci_release_msi(dev); 1009 fail0: 1010 kfree(mac, M_DEVBUF); 1011 wlan_serialize_exit(); 1012 return (error); 1013 } 1014 1015 static int 1016 bwn_is_valid_ether_addr(uint8_t *addr) 1017 { 1018 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1019 1020 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1021 return (FALSE); 1022 1023 return (TRUE); 1024 } 1025 1026 static int 1027 bwn_attach_post(struct bwn_softc *sc) 1028 { 1029 struct ieee80211com *ic; 1030 struct ifnet *ifp = sc->sc_ifp; 1031 1032 ic = ifp->if_l2com; 1033 ic->ic_ifp = ifp; 1034 /* XXX not right but it's not used anywhere important */ 1035 ic->ic_phytype = IEEE80211_T_OFDM; 1036 ic->ic_opmode = IEEE80211_M_STA; 1037 ic->ic_caps = 1038 IEEE80211_C_STA /* station mode supported */ 1039 | IEEE80211_C_MONITOR /* monitor mode */ 1040 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1041 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1042 | IEEE80211_C_SHSLOT /* short slot time supported */ 1043 | IEEE80211_C_WME /* WME/WMM supported */ 1044 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1045 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1046 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1047 ; 1048 1049 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1050 1051 /* call MI attach routine. */ 1052 ieee80211_ifattach(ic, 1053 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1054 siba_sprom_get_mac_80211a(sc->sc_dev) : 1055 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1056 1057 ic->ic_headroom = sizeof(struct bwn_txhdr); 1058 1059 /* override default methods */ 1060 ic->ic_raw_xmit = bwn_raw_xmit; 1061 ic->ic_updateslot = bwn_updateslot; 1062 ic->ic_update_promisc = bwn_update_promisc; 1063 ic->ic_wme.wme_update = bwn_wme_update; 1064 1065 ic->ic_scan_start = bwn_scan_start; 1066 ic->ic_scan_end = bwn_scan_end; 1067 ic->ic_set_channel = bwn_set_channel; 1068 1069 ic->ic_vap_create = bwn_vap_create; 1070 ic->ic_vap_delete = bwn_vap_delete; 1071 1072 ieee80211_radiotap_attach(ic, 1073 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1074 BWN_TX_RADIOTAP_PRESENT, 1075 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1076 BWN_RX_RADIOTAP_PRESENT); 1077 1078 bwn_sysctl_node(sc); 1079 1080 if (bootverbose) 1081 ieee80211_announce(ic); 1082 return (0); 1083 } 1084 1085 static void 1086 bwn_phy_detach(struct bwn_mac *mac) 1087 { 1088 1089 if (mac->mac_phy.detach != NULL) 1090 mac->mac_phy.detach(mac); 1091 } 1092 1093 static int 1094 bwn_detach(device_t dev) 1095 { 1096 struct bwn_softc *sc = device_get_softc(dev); 1097 struct bwn_mac *mac = sc->sc_curmac; 1098 struct ifnet *ifp = sc->sc_ifp; 1099 struct ieee80211com *ic = ifp->if_l2com; 1100 1101 wlan_serialize_enter(); 1102 1103 sc->sc_flags |= BWN_FLAG_INVALID; 1104 1105 if (device_is_attached(sc->sc_dev)) { 1106 bwn_stop(sc, 1); 1107 bwn_dma_free(mac); 1108 callout_stop_sync(&sc->sc_led_blink_ch); 1109 callout_stop_sync(&sc->sc_rfswitch_ch); 1110 callout_stop_sync(&sc->sc_task_ch); 1111 callout_stop_sync(&sc->sc_watchdog_ch); 1112 bwn_phy_detach(mac); 1113 if (ifp != NULL) { 1114 wlan_serialize_exit(); 1115 ieee80211_draintask(ic, &mac->mac_hwreset); 1116 ieee80211_draintask(ic, &mac->mac_txpower); 1117 wlan_serialize_enter(); 1118 ieee80211_ifdetach(ic); 1119 if_free(ifp); 1120 } 1121 } 1122 wlan_serialize_exit(); 1123 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1124 taskqueue_free(sc->sc_tq); 1125 wlan_serialize_enter(); 1126 1127 if (sc->bwn_intr) 1128 bus_teardown_intr(dev, sc->bwn_irq, sc->bwn_intr); 1129 if (sc->bwn_irq != NULL) 1130 bus_release_resource(dev, SYS_RES_IRQ, sc->bwn_irq_rid, 1131 sc->bwn_irq); 1132 1133 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI) 1134 pci_release_msi(dev); 1135 1136 if (sc->sc_sysctl_tree) { 1137 sysctl_ctx_free(&sc->sc_sysctl_ctx); 1138 sc->sc_sysctl_tree = NULL; 1139 } 1140 1141 wlan_serialize_exit(); 1142 return (0); 1143 } 1144 1145 static int 1146 bwn_attach_pre(struct bwn_softc *sc) 1147 { 1148 struct ifnet *ifp; 1149 int error = 0; 1150 1151 TAILQ_INIT(&sc->sc_maclist); 1152 callout_init(&sc->sc_rfswitch_ch); 1153 callout_init(&sc->sc_task_ch); 1154 callout_init(&sc->sc_watchdog_ch); 1155 1156 sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK, 1157 taskqueue_thread_enqueue, &sc->sc_tq); 1158 taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1, 1159 "%s taskq", device_get_nameunit(sc->sc_dev)); 1160 1161 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1162 if (ifp == NULL) { 1163 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1164 error = ENOSPC; 1165 goto fail; 1166 } 1167 1168 /* set these up early for if_printf use */ 1169 if_initname(ifp, device_get_name(sc->sc_dev), 1170 device_get_unit(sc->sc_dev)); 1171 1172 /* prepare sysctl tree for use in sub modules */ 1173 sysctl_ctx_init(&sc->sc_sysctl_ctx); 1174 sc->sc_sysctl_tree = SYSCTL_ADD_NODE(&sc->sc_sysctl_ctx, 1175 SYSCTL_STATIC_CHILDREN(_hw), 1176 OID_AUTO, 1177 device_get_nameunit(sc->sc_dev), 1178 CTLFLAG_RD, 0, ""); 1179 1180 ifp->if_softc = sc; 1181 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1182 ifp->if_init = bwn_init; 1183 ifp->if_ioctl = bwn_ioctl; 1184 ifp->if_start = bwn_start; 1185 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); 1186 1187 return (0); 1188 1189 fail: 1190 return (error); 1191 } 1192 1193 static void 1194 bwn_sprom_bugfixes(device_t dev) 1195 { 1196 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1197 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1198 (siba_get_pci_device(dev) == _device) && \ 1199 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1200 (siba_get_pci_subdevice(dev) == _subdevice)) 1201 1202 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1203 siba_get_pci_subdevice(dev) == 0x4e && 1204 siba_get_pci_revid(dev) > 0x40) 1205 siba_sprom_set_bf_lo(dev, 1206 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1207 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1208 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1209 siba_sprom_set_bf_lo(dev, 1210 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1211 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1212 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1213 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1214 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1215 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1216 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1217 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1218 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1219 siba_sprom_set_bf_lo(dev, 1220 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1221 } 1222 #undef BWN_ISDEV 1223 } 1224 1225 static int 1226 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, 1227 struct ucred *cr __unused) 1228 { 1229 #define IS_RUNNING(ifp) \ 1230 ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING)) 1231 struct bwn_softc *sc = ifp->if_softc; 1232 struct ieee80211com *ic = ifp->if_l2com; 1233 struct ifreq *ifr = (struct ifreq *)data; 1234 int error = 0; 1235 1236 switch (cmd) { 1237 case SIOCSIFFLAGS: 1238 if (IS_RUNNING(ifp)) { 1239 bwn_update_promisc(ifp); 1240 } else if (ifp->if_flags & IFF_UP) { 1241 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1242 bwn_init(sc); 1243 } 1244 } else 1245 bwn_stop(sc, 1); 1246 break; 1247 case SIOCGIFMEDIA: 1248 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1249 break; 1250 case SIOCGIFADDR: 1251 error = ether_ioctl(ifp, cmd, data); 1252 break; 1253 default: 1254 error = EINVAL; 1255 break; 1256 } 1257 return (error); 1258 } 1259 1260 static void 1261 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) 1262 { 1263 wlan_assert_serialized(); 1264 bwn_start_locked(ifp); 1265 } 1266 1267 static void 1268 bwn_start_locked(struct ifnet *ifp) 1269 { 1270 struct bwn_softc *sc = ifp->if_softc; 1271 struct bwn_mac *mac = sc->sc_curmac; 1272 struct ieee80211_frame *wh; 1273 struct ieee80211_node *ni; 1274 struct ieee80211_key *k; 1275 struct mbuf *m; 1276 1277 wlan_assert_serialized(); 1278 1279 if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL || 1280 mac->mac_status < BWN_MAC_STATUS_STARTED) 1281 return; 1282 1283 for (;;) { 1284 m = ifq_dequeue(&ifp->if_snd); /* XXX: LOCK */ 1285 if (m == NULL) 1286 break; 1287 1288 if (bwn_tx_isfull(sc, m)) 1289 break; 1290 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1291 if (ni == NULL) { 1292 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1293 m_freem(m); 1294 ifp->if_oerrors++; 1295 continue; 1296 } 1297 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1298 wh = mtod(m, struct ieee80211_frame *); 1299 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1300 k = ieee80211_crypto_encap(ni, m); 1301 if (k == NULL) { 1302 ieee80211_free_node(ni); 1303 m_freem(m); 1304 ifp->if_oerrors++; 1305 continue; 1306 } 1307 } 1308 wh = NULL; /* Catch any invalid use */ 1309 1310 if (bwn_tx_start(sc, ni, m) != 0) { 1311 if (ni != NULL) 1312 ieee80211_free_node(ni); 1313 ifp->if_oerrors++; 1314 continue; 1315 } 1316 1317 sc->sc_watchdog_timer = 5; 1318 } 1319 } 1320 1321 static int 1322 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1323 { 1324 struct bwn_dma_ring *dr; 1325 struct bwn_mac *mac = sc->sc_curmac; 1326 struct bwn_pio_txqueue *tq; 1327 struct ifnet *ifp = sc->sc_ifp; 1328 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1329 1330 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1331 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1332 if (dr->dr_stop == 1 || 1333 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1334 dr->dr_stop = 1; 1335 goto full; 1336 } 1337 } else { 1338 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1339 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1340 pktlen > (tq->tq_size - tq->tq_used)) { 1341 tq->tq_stop = 1; 1342 goto full; 1343 } 1344 } 1345 return (0); 1346 full: 1347 ifq_prepend(&ifp->if_snd, m); 1348 ifq_set_oactive(&ifp->if_snd); 1349 return (1); 1350 } 1351 1352 static int 1353 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1354 { 1355 struct bwn_mac *mac = sc->sc_curmac; 1356 int error; 1357 1358 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1359 m_freem(m); 1360 return (ENXIO); 1361 } 1362 1363 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1364 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1365 if (error) { 1366 m_freem(m); 1367 return (error); 1368 } 1369 return (0); 1370 } 1371 1372 static int 1373 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1374 { 1375 struct bwn_pio_txpkt *tp; 1376 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1377 struct bwn_softc *sc = mac->mac_sc; 1378 struct bwn_txhdr txhdr; 1379 struct mbuf *m_new; 1380 uint32_t ctl32; 1381 int error; 1382 uint16_t ctl16; 1383 1384 /* XXX TODO send packets after DTIM */ 1385 1386 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1387 tp = TAILQ_FIRST(&tq->tq_pktlist); 1388 tp->tp_ni = ni; 1389 tp->tp_m = m; 1390 1391 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1392 if (error) { 1393 device_printf(sc->sc_dev, "tx fail\n"); 1394 return (error); 1395 } 1396 1397 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1398 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1399 tq->tq_free--; 1400 1401 if (siba_get_revid(sc->sc_dev) >= 8) { 1402 /* 1403 * XXX please removes m_defrag(9) 1404 */ 1405 m_new = m_defrag(m, M_INTWAIT); 1406 if (m_new == NULL) { 1407 device_printf(sc->sc_dev, 1408 "%s: can't defrag TX buffer\n", 1409 __func__); 1410 return (ENOBUFS); 1411 } 1412 if (m_new->m_next != NULL) 1413 device_printf(sc->sc_dev, 1414 "TODO: fragmented packets for PIO\n"); 1415 tp->tp_m = m_new; 1416 1417 /* send HEADER */ 1418 ctl32 = bwn_pio_write_multi_4(mac, tq, 1419 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1420 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1421 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1422 /* send BODY */ 1423 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1424 mtod(m_new, const void *), m_new->m_pkthdr.len); 1425 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1426 ctl32 | BWN_PIO8_TXCTL_EOF); 1427 } else { 1428 ctl16 = bwn_pio_write_multi_2(mac, tq, 1429 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1430 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1431 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1432 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1433 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1434 ctl16 | BWN_PIO_TXCTL_EOF); 1435 } 1436 1437 return (0); 1438 } 1439 1440 static struct bwn_pio_txqueue * 1441 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1442 { 1443 1444 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1445 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1446 1447 switch (prio) { 1448 case 0: 1449 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1450 case 1: 1451 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1452 case 2: 1453 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1454 case 3: 1455 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1456 } 1457 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1458 return (NULL); 1459 } 1460 1461 static int 1462 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1463 { 1464 #define BWN_GET_TXHDRCACHE(slot) \ 1465 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)]) 1466 struct bwn_dma *dma = &mac->mac_method.dma; 1467 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1468 struct bwn_dmadesc_generic *desc; 1469 struct bwn_dmadesc_meta *mt; 1470 struct bwn_softc *sc = mac->mac_sc; 1471 struct ifnet *ifp = sc->sc_ifp; 1472 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1473 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1474 1475 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1476 1477 /* XXX send after DTIM */ 1478 1479 slot = bwn_dma_getslot(dr); 1480 dr->getdesc(dr, slot, &desc, &mt); 1481 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1482 ("%s:%d: fail", __func__, __LINE__)); 1483 1484 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1485 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1486 BWN_DMA_COOKIE(dr, slot)); 1487 if (error) 1488 goto fail; 1489 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1490 BUS_DMASYNC_PREWRITE); 1491 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1492 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1493 BUS_DMASYNC_PREWRITE); 1494 1495 slot = bwn_dma_getslot(dr); 1496 dr->getdesc(dr, slot, &desc, &mt); 1497 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1498 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1499 mt->mt_m = m; 1500 mt->mt_ni = ni; 1501 1502 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1503 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1504 if (error && error != EFBIG) { 1505 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1506 __func__, error); 1507 goto fail; 1508 } 1509 if (error) { /* error == EFBIG */ 1510 struct mbuf *m_new; 1511 1512 m_new = m_defrag(m, M_INTWAIT); 1513 if (m_new == NULL) { 1514 if_printf(ifp, "%s: can't defrag TX buffer\n", 1515 __func__); 1516 error = ENOBUFS; 1517 goto fail; 1518 } else { 1519 m = m_new; 1520 } 1521 1522 mt->mt_m = m; 1523 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1524 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1525 if (error) { 1526 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1527 __func__, error); 1528 goto fail; 1529 } 1530 } 1531 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1532 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1533 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1534 BUS_DMASYNC_PREWRITE); 1535 1536 /* XXX send after DTIM */ 1537 1538 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1539 return (0); 1540 fail: 1541 dr->dr_curslot = backup[0]; 1542 dr->dr_usedslot = backup[1]; 1543 return (error); 1544 #undef BWN_GET_TXHDRCACHE 1545 } 1546 1547 static void 1548 bwn_watchdog(void *arg) 1549 { 1550 struct bwn_softc *sc = arg; 1551 struct ifnet *ifp = sc->sc_ifp; 1552 1553 wlan_serialize_enter(); 1554 1555 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1556 if_printf(ifp, "device timeout\n"); 1557 ifp->if_oerrors++; 1558 } 1559 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 1560 wlan_serialize_exit(); 1561 } 1562 1563 static int 1564 bwn_attach_core(struct bwn_mac *mac) 1565 { 1566 struct bwn_softc *sc = mac->mac_sc; 1567 int error, have_bg = 0, have_a = 0; 1568 uint32_t high; 1569 1570 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1571 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1572 1573 siba_powerup(sc->sc_dev, 0); 1574 1575 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1576 bwn_reset_core(mac, 1577 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1578 error = bwn_phy_getinfo(mac, high); 1579 if (error) 1580 goto fail; 1581 1582 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1583 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1584 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1585 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1586 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1587 have_a = have_bg = 0; 1588 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1589 have_a = 1; 1590 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1591 mac->mac_phy.type == BWN_PHYTYPE_N || 1592 mac->mac_phy.type == BWN_PHYTYPE_LP) 1593 have_bg = 1; 1594 else 1595 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1596 mac->mac_phy.type)); 1597 } 1598 /* XXX turns off PHY A because it's not supported */ 1599 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1600 mac->mac_phy.type != BWN_PHYTYPE_N) { 1601 have_a = 0; 1602 have_bg = 1; 1603 } 1604 1605 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1606 mac->mac_phy.attach = bwn_phy_g_attach; 1607 mac->mac_phy.detach = bwn_phy_g_detach; 1608 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1609 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1610 mac->mac_phy.init = bwn_phy_g_init; 1611 mac->mac_phy.exit = bwn_phy_g_exit; 1612 mac->mac_phy.phy_read = bwn_phy_g_read; 1613 mac->mac_phy.phy_write = bwn_phy_g_write; 1614 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1615 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1616 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1617 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1618 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1619 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1620 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1621 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1622 mac->mac_phy.set_im = bwn_phy_g_im; 1623 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1624 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1625 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1626 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1627 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1628 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1629 mac->mac_phy.init = bwn_phy_lp_init; 1630 mac->mac_phy.phy_read = bwn_phy_lp_read; 1631 mac->mac_phy.phy_write = bwn_phy_lp_write; 1632 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1633 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1634 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1635 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1636 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1637 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1638 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1639 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1640 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1641 } else { 1642 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1643 mac->mac_phy.type); 1644 error = ENXIO; 1645 goto fail; 1646 } 1647 1648 mac->mac_phy.gmode = have_bg; 1649 if (mac->mac_phy.attach != NULL) { 1650 error = mac->mac_phy.attach(mac); 1651 if (error) { 1652 device_printf(sc->sc_dev, "failed\n"); 1653 goto fail; 1654 } 1655 } 1656 1657 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1658 1659 error = bwn_chiptest(mac); 1660 if (error) 1661 goto fail; 1662 error = bwn_setup_channels(mac, have_bg, have_a); 1663 if (error) { 1664 device_printf(sc->sc_dev, "failed to setup channels\n"); 1665 goto fail; 1666 } 1667 1668 if (sc->sc_curmac == NULL) 1669 sc->sc_curmac = mac; 1670 1671 wlan_assert_serialized(); 1672 wlan_serialize_exit(); 1673 error = bwn_dma_attach(mac); 1674 wlan_serialize_enter(); 1675 if (error != 0) { 1676 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1677 goto fail; 1678 } 1679 1680 mac->mac_phy.switch_analog(mac, 0); 1681 1682 siba_dev_down(sc->sc_dev, 0); 1683 fail: 1684 siba_powerdown(sc->sc_dev); 1685 return (error); 1686 } 1687 1688 static void 1689 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1690 { 1691 struct bwn_softc *sc = mac->mac_sc; 1692 uint32_t low, ctl; 1693 1694 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1695 1696 siba_dev_up(sc->sc_dev, flags); 1697 DELAY(2000); 1698 1699 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1700 ~BWN_TGSLOW_PHYRESET; 1701 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1702 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1703 DELAY(1000); 1704 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1705 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1706 DELAY(1000); 1707 1708 if (mac->mac_phy.switch_analog != NULL) 1709 mac->mac_phy.switch_analog(mac, 1); 1710 1711 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1712 if (flags & BWN_TGSLOW_SUPPORT_G) 1713 ctl |= BWN_MACCTL_GMODE; 1714 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1715 } 1716 1717 static int 1718 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1719 { 1720 struct bwn_phy *phy = &mac->mac_phy; 1721 struct bwn_softc *sc = mac->mac_sc; 1722 uint32_t tmp; 1723 1724 /* PHY */ 1725 tmp = BWN_READ_2(mac, BWN_PHYVER); 1726 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1727 phy->rf_on = 1; 1728 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1729 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1730 phy->rev = (tmp & BWN_PHYVER_VERSION); 1731 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1732 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1733 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1734 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1735 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1736 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1737 goto unsupphy; 1738 1739 /* RADIO */ 1740 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1741 if (siba_get_chiprev(sc->sc_dev) == 0) 1742 tmp = 0x3205017f; 1743 else if (siba_get_chiprev(sc->sc_dev) == 1) 1744 tmp = 0x4205017f; 1745 else 1746 tmp = 0x5205017f; 1747 } else { 1748 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1749 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1750 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1751 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1752 } 1753 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1754 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1755 phy->rf_manuf = (tmp & 0x00000fff); 1756 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1757 goto unsupradio; 1758 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1759 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1760 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1761 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1762 (phy->type == BWN_PHYTYPE_N && 1763 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1764 (phy->type == BWN_PHYTYPE_LP && 1765 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1766 goto unsupradio; 1767 1768 return (0); 1769 unsupphy: 1770 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1771 "analog %#x)\n", 1772 phy->type, phy->rev, phy->analog); 1773 return (ENXIO); 1774 unsupradio: 1775 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1776 "rev %#x)\n", 1777 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1778 return (ENXIO); 1779 } 1780 1781 static int 1782 bwn_chiptest(struct bwn_mac *mac) 1783 { 1784 #define TESTVAL0 0x55aaaa55 1785 #define TESTVAL1 0xaa5555aa 1786 struct bwn_softc *sc = mac->mac_sc; 1787 uint32_t v, backup; 1788 1789 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1790 1791 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1792 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1793 goto error; 1794 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1795 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1796 goto error; 1797 1798 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1799 1800 if ((siba_get_revid(sc->sc_dev) >= 3) && 1801 (siba_get_revid(sc->sc_dev) <= 10)) { 1802 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1803 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1804 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1805 goto error; 1806 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1807 goto error; 1808 } 1809 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1810 1811 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1812 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1813 goto error; 1814 1815 return (0); 1816 error: 1817 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1818 return (ENODEV); 1819 } 1820 1821 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1822 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1823 1824 static int 1825 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1826 { 1827 struct bwn_softc *sc = mac->mac_sc; 1828 struct ifnet *ifp = sc->sc_ifp; 1829 struct ieee80211com *ic = ifp->if_l2com; 1830 1831 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1832 ic->ic_nchans = 0; 1833 1834 if (have_bg) 1835 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1836 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1837 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1838 if (have_a) 1839 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1840 &ic->ic_nchans, &bwn_chantable_n, 1841 IEEE80211_CHAN_HTA); 1842 } else { 1843 if (have_a) 1844 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1845 &ic->ic_nchans, &bwn_chantable_a, 1846 IEEE80211_CHAN_A); 1847 } 1848 1849 mac->mac_phy.supports_2ghz = have_bg; 1850 mac->mac_phy.supports_5ghz = have_a; 1851 1852 return (ic->ic_nchans == 0 ? ENXIO : 0); 1853 } 1854 1855 static uint32_t 1856 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1857 { 1858 uint32_t ret; 1859 1860 if (way == BWN_SHARED) { 1861 KASSERT((offset & 0x0001) == 0, 1862 ("%s:%d warn", __func__, __LINE__)); 1863 if (offset & 0x0003) { 1864 bwn_shm_ctlword(mac, way, offset >> 2); 1865 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1866 ret <<= 16; 1867 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1868 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1869 goto out; 1870 } 1871 offset >>= 2; 1872 } 1873 bwn_shm_ctlword(mac, way, offset); 1874 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1875 out: 1876 return (ret); 1877 } 1878 1879 static uint16_t 1880 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1881 { 1882 uint16_t ret; 1883 1884 if (way == BWN_SHARED) { 1885 KASSERT((offset & 0x0001) == 0, 1886 ("%s:%d warn", __func__, __LINE__)); 1887 if (offset & 0x0003) { 1888 bwn_shm_ctlword(mac, way, offset >> 2); 1889 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1890 goto out; 1891 } 1892 offset >>= 2; 1893 } 1894 bwn_shm_ctlword(mac, way, offset); 1895 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1896 out: 1897 1898 return (ret); 1899 } 1900 1901 static void 1902 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1903 uint16_t offset) 1904 { 1905 uint32_t control; 1906 1907 control = way; 1908 control <<= 16; 1909 control |= offset; 1910 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1911 } 1912 1913 static void 1914 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1915 uint32_t value) 1916 { 1917 if (way == BWN_SHARED) { 1918 KASSERT((offset & 0x0001) == 0, 1919 ("%s:%d warn", __func__, __LINE__)); 1920 if (offset & 0x0003) { 1921 bwn_shm_ctlword(mac, way, offset >> 2); 1922 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1923 (value >> 16) & 0xffff); 1924 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1925 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1926 return; 1927 } 1928 offset >>= 2; 1929 } 1930 bwn_shm_ctlword(mac, way, offset); 1931 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1932 } 1933 1934 static void 1935 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1936 uint16_t value) 1937 { 1938 if (way == BWN_SHARED) { 1939 KASSERT((offset & 0x0001) == 0, 1940 ("%s:%d warn", __func__, __LINE__)); 1941 if (offset & 0x0003) { 1942 bwn_shm_ctlword(mac, way, offset >> 2); 1943 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1944 return; 1945 } 1946 offset >>= 2; 1947 } 1948 bwn_shm_ctlword(mac, way, offset); 1949 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1950 } 1951 1952 static void 1953 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1954 int txpow) 1955 { 1956 1957 c->ic_freq = freq; 1958 c->ic_flags = flags; 1959 c->ic_ieee = ieee; 1960 c->ic_minpower = 0; 1961 c->ic_maxpower = 2 * txpow; 1962 c->ic_maxregpower = txpow; 1963 } 1964 1965 static void 1966 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 1967 const struct bwn_channelinfo *ci, int flags) 1968 { 1969 struct ieee80211_channel *c; 1970 int i; 1971 1972 c = &chans[*nchans]; 1973 1974 for (i = 0; i < ci->nchannels; i++) { 1975 const struct bwn_channel *hc; 1976 1977 hc = &ci->channels[i]; 1978 if (*nchans >= maxchans) 1979 break; 1980 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 1981 c++, (*nchans)++; 1982 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 1983 /* g channel have a separate b-only entry */ 1984 if (*nchans >= maxchans) 1985 break; 1986 c[0] = c[-1]; 1987 c[-1].ic_flags = IEEE80211_CHAN_B; 1988 c++, (*nchans)++; 1989 } 1990 if (flags == IEEE80211_CHAN_HTG) { 1991 /* HT g channel have a separate g-only entry */ 1992 if (*nchans >= maxchans) 1993 break; 1994 c[-1].ic_flags = IEEE80211_CHAN_G; 1995 c[0] = c[-1]; 1996 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1997 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1998 c++, (*nchans)++; 1999 } 2000 if (flags == IEEE80211_CHAN_HTA) { 2001 /* HT a channel have a separate a-only entry */ 2002 if (*nchans >= maxchans) 2003 break; 2004 c[-1].ic_flags = IEEE80211_CHAN_A; 2005 c[0] = c[-1]; 2006 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2007 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2008 c++, (*nchans)++; 2009 } 2010 } 2011 } 2012 2013 static int 2014 bwn_phy_g_attach(struct bwn_mac *mac) 2015 { 2016 struct bwn_softc *sc = mac->mac_sc; 2017 struct bwn_phy *phy = &mac->mac_phy; 2018 struct bwn_phy_g *pg = &phy->phy_g; 2019 unsigned int i; 2020 int16_t pab0, pab1, pab2; 2021 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2022 int8_t bg; 2023 2024 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2025 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2026 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2027 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2028 2029 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2030 device_printf(sc->sc_dev, "not supported anymore\n"); 2031 2032 pg->pg_flags = 0; 2033 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2034 pab2 == -1) { 2035 pg->pg_idletssi = 52; 2036 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2037 return (0); 2038 } 2039 2040 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2041 pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO); 2042 for (i = 0; i < 64; i++) { 2043 int32_t m1, m2, f, q, delta; 2044 int8_t j = 0; 2045 2046 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2047 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2048 f = 256; 2049 2050 do { 2051 if (j > 15) { 2052 device_printf(sc->sc_dev, 2053 "failed to generate tssi2dBm\n"); 2054 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2055 return (ENOMEM); 2056 } 2057 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2058 f, 2048); 2059 delta = abs(q - f); 2060 f = q; 2061 j++; 2062 } while (delta >= 2); 2063 2064 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2065 128); 2066 } 2067 2068 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2069 return (0); 2070 } 2071 2072 static void 2073 bwn_phy_g_detach(struct bwn_mac *mac) 2074 { 2075 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2076 2077 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2078 kfree(pg->pg_tssi2dbm, M_DEVBUF); 2079 pg->pg_tssi2dbm = NULL; 2080 } 2081 pg->pg_flags = 0; 2082 } 2083 2084 static void 2085 bwn_phy_g_init_pre(struct bwn_mac *mac) 2086 { 2087 struct bwn_phy *phy = &mac->mac_phy; 2088 struct bwn_phy_g *pg = &phy->phy_g; 2089 void *tssi2dbm; 2090 int idletssi; 2091 unsigned int i; 2092 2093 tssi2dbm = pg->pg_tssi2dbm; 2094 idletssi = pg->pg_idletssi; 2095 2096 memset(pg, 0, sizeof(*pg)); 2097 2098 pg->pg_tssi2dbm = tssi2dbm; 2099 pg->pg_idletssi = idletssi; 2100 2101 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2102 2103 for (i = 0; i < N(pg->pg_nrssi); i++) 2104 pg->pg_nrssi[i] = -1000; 2105 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2106 pg->pg_nrssi_lt[i] = i; 2107 pg->pg_lofcal = 0xffff; 2108 pg->pg_initval = 0xffff; 2109 pg->pg_immode = BWN_IMMODE_NONE; 2110 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2111 pg->pg_avgtssi = 0xff; 2112 2113 pg->pg_loctl.tx_bias = 0xff; 2114 TAILQ_INIT(&pg->pg_loctl.calib_list); 2115 } 2116 2117 static int 2118 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2119 { 2120 struct bwn_phy *phy = &mac->mac_phy; 2121 struct bwn_phy_g *pg = &phy->phy_g; 2122 struct bwn_softc *sc = mac->mac_sc; 2123 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2124 static const struct bwn_rfatt rfatt0[] = { 2125 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2126 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2127 { 3, 1 }, { 4, 1 } 2128 }; 2129 static const struct bwn_rfatt rfatt1[] = { 2130 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2131 { 14, 1 } 2132 }; 2133 static const struct bwn_rfatt rfatt2[] = { 2134 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2135 { 9, 1 } 2136 }; 2137 static const struct bwn_bbatt bbatt_0[] = { 2138 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2139 }; 2140 2141 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2142 2143 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2144 pg->pg_bbatt.att = 0; 2145 else 2146 pg->pg_bbatt.att = 2; 2147 2148 /* prepare Radio Attenuation */ 2149 pg->pg_rfatt.padmix = 0; 2150 2151 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2152 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2153 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2154 pg->pg_rfatt.att = 2; 2155 goto done; 2156 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2157 pg->pg_rfatt.att = 3; 2158 goto done; 2159 } 2160 } 2161 2162 if (phy->type == BWN_PHYTYPE_A) { 2163 pg->pg_rfatt.att = 0x60; 2164 goto done; 2165 } 2166 2167 switch (phy->rf_ver) { 2168 case 0x2050: 2169 switch (phy->rf_rev) { 2170 case 0: 2171 pg->pg_rfatt.att = 5; 2172 goto done; 2173 case 1: 2174 if (phy->type == BWN_PHYTYPE_G) { 2175 if (siba_get_pci_subvendor(sc->sc_dev) == 2176 SIBA_BOARDVENDOR_BCM && 2177 siba_get_pci_subdevice(sc->sc_dev) == 2178 SIBA_BOARD_BCM4309G && 2179 siba_get_pci_revid(sc->sc_dev) >= 30) 2180 pg->pg_rfatt.att = 3; 2181 else if (siba_get_pci_subvendor(sc->sc_dev) == 2182 SIBA_BOARDVENDOR_BCM && 2183 siba_get_pci_subdevice(sc->sc_dev) == 2184 SIBA_BOARD_BU4306) 2185 pg->pg_rfatt.att = 3; 2186 else 2187 pg->pg_rfatt.att = 1; 2188 } else { 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 = 7; 2195 else 2196 pg->pg_rfatt.att = 6; 2197 } 2198 goto done; 2199 case 2: 2200 if (phy->type == BWN_PHYTYPE_G) { 2201 if (siba_get_pci_subvendor(sc->sc_dev) == 2202 SIBA_BOARDVENDOR_BCM && 2203 siba_get_pci_subdevice(sc->sc_dev) == 2204 SIBA_BOARD_BCM4309G && 2205 siba_get_pci_revid(sc->sc_dev) >= 30) 2206 pg->pg_rfatt.att = 3; 2207 else if (siba_get_pci_subvendor(sc->sc_dev) == 2208 SIBA_BOARDVENDOR_BCM && 2209 siba_get_pci_subdevice(sc->sc_dev) == 2210 SIBA_BOARD_BU4306) 2211 pg->pg_rfatt.att = 5; 2212 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2213 pg->pg_rfatt.att = 4; 2214 else 2215 pg->pg_rfatt.att = 3; 2216 } else 2217 pg->pg_rfatt.att = 6; 2218 goto done; 2219 case 3: 2220 pg->pg_rfatt.att = 5; 2221 goto done; 2222 case 4: 2223 case 5: 2224 pg->pg_rfatt.att = 1; 2225 goto done; 2226 case 6: 2227 case 7: 2228 pg->pg_rfatt.att = 5; 2229 goto done; 2230 case 8: 2231 pg->pg_rfatt.att = 0xa; 2232 pg->pg_rfatt.padmix = 1; 2233 goto done; 2234 case 9: 2235 default: 2236 pg->pg_rfatt.att = 5; 2237 goto done; 2238 } 2239 break; 2240 case 0x2053: 2241 switch (phy->rf_rev) { 2242 case 1: 2243 pg->pg_rfatt.att = 6; 2244 goto done; 2245 } 2246 break; 2247 } 2248 pg->pg_rfatt.att = 5; 2249 done: 2250 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2251 2252 if (!bwn_has_hwpctl(mac)) { 2253 lo->rfatt.array = rfatt0; 2254 lo->rfatt.len = N(rfatt0); 2255 lo->rfatt.min = 0; 2256 lo->rfatt.max = 9; 2257 goto genbbatt; 2258 } 2259 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2260 lo->rfatt.array = rfatt1; 2261 lo->rfatt.len = N(rfatt1); 2262 lo->rfatt.min = 0; 2263 lo->rfatt.max = 14; 2264 goto genbbatt; 2265 } 2266 lo->rfatt.array = rfatt2; 2267 lo->rfatt.len = N(rfatt2); 2268 lo->rfatt.min = 0; 2269 lo->rfatt.max = 9; 2270 genbbatt: 2271 lo->bbatt.array = bbatt_0; 2272 lo->bbatt.len = N(bbatt_0); 2273 lo->bbatt.min = 0; 2274 lo->bbatt.max = 8; 2275 2276 BWN_READ_4(mac, BWN_MACCTL); 2277 if (phy->rev == 1) { 2278 phy->gmode = 0; 2279 bwn_reset_core(mac, 0); 2280 bwn_phy_g_init_sub(mac); 2281 phy->gmode = 1; 2282 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2283 } 2284 return (0); 2285 } 2286 2287 static uint16_t 2288 bwn_phy_g_txctl(struct bwn_mac *mac) 2289 { 2290 struct bwn_phy *phy = &mac->mac_phy; 2291 2292 if (phy->rf_ver != 0x2050) 2293 return (0); 2294 if (phy->rf_rev == 1) 2295 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2296 if (phy->rf_rev < 6) 2297 return (BWN_TXCTL_PA2DB); 2298 if (phy->rf_rev == 8) 2299 return (BWN_TXCTL_TXMIX); 2300 return (0); 2301 } 2302 2303 static int 2304 bwn_phy_g_init(struct bwn_mac *mac) 2305 { 2306 2307 bwn_phy_g_init_sub(mac); 2308 return (0); 2309 } 2310 2311 static void 2312 bwn_phy_g_exit(struct bwn_mac *mac) 2313 { 2314 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2315 struct bwn_lo_calib *cal, *tmp; 2316 2317 if (lo == NULL) 2318 return; 2319 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2320 TAILQ_REMOVE(&lo->calib_list, cal, list); 2321 kfree(cal, M_DEVBUF); 2322 } 2323 } 2324 2325 static uint16_t 2326 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2327 { 2328 2329 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2330 return (BWN_READ_2(mac, BWN_PHYDATA)); 2331 } 2332 2333 static void 2334 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2335 { 2336 2337 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2338 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2339 } 2340 2341 static uint16_t 2342 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2343 { 2344 2345 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2346 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2347 return (BWN_READ_2(mac, BWN_RFDATALO)); 2348 } 2349 2350 static void 2351 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2352 { 2353 2354 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2355 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2356 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2357 } 2358 2359 static int 2360 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2361 { 2362 2363 return (mac->mac_phy.rev >= 6); 2364 } 2365 2366 static void 2367 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2368 { 2369 struct bwn_phy *phy = &mac->mac_phy; 2370 struct bwn_phy_g *pg = &phy->phy_g; 2371 unsigned int channel; 2372 uint16_t rfover, rfoverval; 2373 2374 if (on) { 2375 if (phy->rf_on) 2376 return; 2377 2378 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2379 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2380 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2381 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2382 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2383 pg->pg_radioctx_over); 2384 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2385 pg->pg_radioctx_overval); 2386 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2387 } 2388 channel = phy->chan; 2389 bwn_phy_g_switch_chan(mac, 6, 1); 2390 bwn_phy_g_switch_chan(mac, channel, 0); 2391 return; 2392 } 2393 2394 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2395 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2396 pg->pg_radioctx_over = rfover; 2397 pg->pg_radioctx_overval = rfoverval; 2398 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2399 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2400 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2401 } 2402 2403 static int 2404 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2405 { 2406 2407 if ((newchan < 1) || (newchan > 14)) 2408 return (EINVAL); 2409 bwn_phy_g_switch_chan(mac, newchan, 0); 2410 2411 return (0); 2412 } 2413 2414 static uint32_t 2415 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2416 { 2417 2418 return (1); 2419 } 2420 2421 static void 2422 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2423 { 2424 struct bwn_phy *phy = &mac->mac_phy; 2425 uint64_t hf; 2426 int autodiv = 0; 2427 uint16_t tmp; 2428 2429 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2430 autodiv = 1; 2431 2432 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2433 bwn_hf_write(mac, hf); 2434 2435 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2436 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2437 ((autodiv ? BWN_ANTAUTO1 : antenna) 2438 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2439 2440 if (autodiv) { 2441 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2442 if (antenna == BWN_ANTAUTO1) 2443 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2444 else 2445 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2446 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2447 } 2448 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2449 if (autodiv) 2450 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2451 else 2452 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2453 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2454 if (phy->rev >= 2) { 2455 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2456 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2457 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2458 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2459 0x15); 2460 if (phy->rev == 2) 2461 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2462 else 2463 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2464 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2465 8); 2466 } 2467 if (phy->rev >= 6) 2468 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2469 2470 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2471 bwn_hf_write(mac, hf); 2472 } 2473 2474 static int 2475 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2476 { 2477 struct bwn_phy *phy = &mac->mac_phy; 2478 struct bwn_phy_g *pg = &phy->phy_g; 2479 2480 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2481 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2482 2483 if (phy->rev == 0 || !phy->gmode) 2484 return (ENODEV); 2485 2486 pg->pg_aci_wlan_automatic = 0; 2487 return (0); 2488 } 2489 2490 static int 2491 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2492 { 2493 struct bwn_phy *phy = &mac->mac_phy; 2494 struct bwn_phy_g *pg = &phy->phy_g; 2495 struct bwn_softc *sc = mac->mac_sc; 2496 unsigned int tssi; 2497 int cck, ofdm; 2498 int power; 2499 int rfatt, bbatt; 2500 unsigned int max; 2501 2502 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2503 2504 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2505 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2506 if (cck < 0 && ofdm < 0) { 2507 if (ignore_tssi == 0) 2508 return (BWN_TXPWR_RES_DONE); 2509 cck = 0; 2510 ofdm = 0; 2511 } 2512 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2513 if (pg->pg_avgtssi != 0xff) 2514 tssi = (tssi + pg->pg_avgtssi) / 2; 2515 pg->pg_avgtssi = tssi; 2516 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2517 2518 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2519 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2520 max -= 3; 2521 if (max >= 120) { 2522 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2523 max = 80; 2524 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2525 } 2526 2527 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2528 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2529 tssi, 0x00), 0x3f)]); 2530 if (power == 0) 2531 return (BWN_TXPWR_RES_DONE); 2532 2533 rfatt = -((power + 7) / 8); 2534 bbatt = (-(power / 2)) - (4 * rfatt); 2535 if ((rfatt == 0) && (bbatt == 0)) 2536 return (BWN_TXPWR_RES_DONE); 2537 pg->pg_bbatt_delta = bbatt; 2538 pg->pg_rfatt_delta = rfatt; 2539 return (BWN_TXPWR_RES_NEED_ADJUST); 2540 } 2541 2542 static void 2543 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2544 { 2545 struct bwn_phy *phy = &mac->mac_phy; 2546 struct bwn_phy_g *pg = &phy->phy_g; 2547 struct bwn_softc *sc = mac->mac_sc; 2548 int rfatt, bbatt; 2549 uint8_t txctl; 2550 2551 bwn_mac_suspend(mac); 2552 2553 bbatt = pg->pg_bbatt.att; 2554 bbatt += pg->pg_bbatt_delta; 2555 rfatt = pg->pg_rfatt.att; 2556 rfatt += pg->pg_rfatt_delta; 2557 2558 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2559 txctl = pg->pg_txctl; 2560 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2561 if (rfatt <= 1) { 2562 if (txctl == 0) { 2563 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2564 rfatt += 2; 2565 bbatt += 2; 2566 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2567 BWN_BFL_PACTRL) { 2568 bbatt += 4 * (rfatt - 2); 2569 rfatt = 2; 2570 } 2571 } else if (rfatt > 4 && txctl) { 2572 txctl = 0; 2573 if (bbatt < 3) { 2574 rfatt -= 3; 2575 bbatt += 2; 2576 } else { 2577 rfatt -= 2; 2578 bbatt -= 2; 2579 } 2580 } 2581 } 2582 pg->pg_txctl = txctl; 2583 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2584 pg->pg_rfatt.att = rfatt; 2585 pg->pg_bbatt.att = bbatt; 2586 2587 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2588 2589 bwn_phy_lock(mac); 2590 bwn_rf_lock(mac); 2591 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2592 pg->pg_txctl); 2593 bwn_rf_unlock(mac); 2594 bwn_phy_unlock(mac); 2595 2596 bwn_mac_enable(mac); 2597 } 2598 2599 static void 2600 bwn_phy_g_task_15s(struct bwn_mac *mac) 2601 { 2602 struct bwn_phy *phy = &mac->mac_phy; 2603 struct bwn_phy_g *pg = &phy->phy_g; 2604 struct bwn_softc *sc = mac->mac_sc; 2605 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2606 unsigned long expire, now; 2607 struct bwn_lo_calib *cal, *tmp; 2608 uint8_t expired = 0; 2609 2610 bwn_mac_suspend(mac); 2611 2612 if (lo == NULL) 2613 goto fail; 2614 2615 BWN_GETTIME(now); 2616 if (bwn_has_hwpctl(mac)) { 2617 expire = now - BWN_LO_PWRVEC_EXPIRE; 2618 if (time_before(lo->pwr_vec_read_time, expire)) { 2619 bwn_lo_get_powervector(mac); 2620 bwn_phy_g_dc_lookup_init(mac, 0); 2621 } 2622 goto fail; 2623 } 2624 2625 expire = now - BWN_LO_CALIB_EXPIRE; 2626 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) { 2627 if (!time_before(cal->calib_time, expire)) 2628 continue; 2629 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2630 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2631 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2632 expired = 1; 2633 } 2634 2635 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2636 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2637 cal->ctl.i, cal->ctl.q); 2638 2639 TAILQ_REMOVE(&lo->calib_list, cal, list); 2640 kfree(cal, M_DEVBUF); 2641 } 2642 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2643 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2644 &pg->pg_rfatt); 2645 if (cal == NULL) { /* XXX ivadasz: can't happen */ 2646 device_printf(sc->sc_dev, 2647 "failed to recalibrate LO\n"); 2648 goto fail; 2649 } 2650 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2651 bwn_lo_write(mac, &cal->ctl); 2652 } 2653 2654 fail: 2655 bwn_mac_enable(mac); 2656 } 2657 2658 static void 2659 bwn_phy_g_task_60s(struct bwn_mac *mac) 2660 { 2661 struct bwn_phy *phy = &mac->mac_phy; 2662 struct bwn_softc *sc = mac->mac_sc; 2663 uint8_t old = phy->chan; 2664 2665 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2666 return; 2667 2668 bwn_mac_suspend(mac); 2669 bwn_nrssi_slope_11g(mac); 2670 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2671 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2672 bwn_switch_channel(mac, old); 2673 } 2674 bwn_mac_enable(mac); 2675 } 2676 2677 static void 2678 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2679 { 2680 2681 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2682 } 2683 2684 static int 2685 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2686 const struct ieee80211_bpf_params *params) 2687 { 2688 struct ieee80211com *ic = ni->ni_ic; 2689 struct ifnet *ifp = ic->ic_ifp; 2690 struct bwn_softc *sc = ifp->if_softc; 2691 struct bwn_mac *mac = sc->sc_curmac; 2692 2693 if ((ifp->if_flags & IFF_RUNNING) == 0 || 2694 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2695 ieee80211_free_node(ni); 2696 m_freem(m); 2697 return (ENETDOWN); 2698 } 2699 2700 if (bwn_tx_isfull(sc, m)) { 2701 ieee80211_free_node(ni); 2702 m_freem(m); 2703 ifp->if_oerrors++; 2704 return (ENOBUFS); 2705 } 2706 2707 if (bwn_tx_start(sc, ni, m) != 0) { 2708 if (ni != NULL) 2709 ieee80211_free_node(ni); 2710 ifp->if_oerrors++; 2711 } 2712 sc->sc_watchdog_timer = 5; 2713 return (0); 2714 } 2715 2716 /* 2717 * Callback from the 802.11 layer to update the slot time 2718 * based on the current setting. We use it to notify the 2719 * firmware of ERP changes and the f/w takes care of things 2720 * like slot time and preamble. 2721 */ 2722 static void 2723 bwn_updateslot(struct ifnet *ifp) 2724 { 2725 struct bwn_softc *sc = ifp->if_softc; 2726 struct ieee80211com *ic = ifp->if_l2com; 2727 struct bwn_mac *mac; 2728 2729 if (ifp->if_flags & IFF_RUNNING) { 2730 mac = (struct bwn_mac *)sc->sc_curmac; 2731 bwn_set_slot_time(mac, 2732 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2733 } 2734 } 2735 2736 /* 2737 * Callback from the 802.11 layer after a promiscuous mode change. 2738 * Note this interface does not check the operating mode as this 2739 * is an internal callback and we are expected to honor the current 2740 * state (e.g. this is used for setting the interface in promiscuous 2741 * mode when operating in hostap mode to do ACS). 2742 */ 2743 static void 2744 bwn_update_promisc(struct ifnet *ifp) 2745 { 2746 struct bwn_softc *sc = ifp->if_softc; 2747 struct bwn_mac *mac = sc->sc_curmac; 2748 2749 mac = sc->sc_curmac; 2750 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2751 if (ifp->if_flags & IFF_PROMISC) 2752 sc->sc_filters |= BWN_MACCTL_PROMISC; 2753 else 2754 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2755 bwn_set_opmode(mac); 2756 } 2757 } 2758 2759 /* 2760 * Callback from the 802.11 layer to update WME parameters. 2761 */ 2762 static int 2763 bwn_wme_update(struct ieee80211com *ic) 2764 { 2765 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2766 struct bwn_mac *mac = sc->sc_curmac; 2767 struct wmeParams *wmep; 2768 int i; 2769 2770 mac = sc->sc_curmac; 2771 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2772 bwn_mac_suspend(mac); 2773 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2774 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2775 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2776 } 2777 bwn_mac_enable(mac); 2778 } 2779 return (0); 2780 } 2781 2782 static void 2783 bwn_scan_start(struct ieee80211com *ic) 2784 { 2785 struct ifnet *ifp = ic->ic_ifp; 2786 struct bwn_softc *sc = ifp->if_softc; 2787 struct bwn_mac *mac; 2788 2789 mac = sc->sc_curmac; 2790 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2791 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2792 bwn_set_opmode(mac); 2793 /* disable CFP update during scan */ 2794 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2795 } 2796 } 2797 2798 static void 2799 bwn_scan_end(struct ieee80211com *ic) 2800 { 2801 struct ifnet *ifp = ic->ic_ifp; 2802 struct bwn_softc *sc = ifp->if_softc; 2803 struct bwn_mac *mac; 2804 2805 mac = sc->sc_curmac; 2806 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2807 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2808 bwn_set_opmode(mac); 2809 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2810 } 2811 } 2812 2813 static void 2814 bwn_set_channel(struct ieee80211com *ic) 2815 { 2816 struct ifnet *ifp = ic->ic_ifp; 2817 struct bwn_softc *sc = ifp->if_softc; 2818 struct bwn_mac *mac = sc->sc_curmac; 2819 struct bwn_phy *phy = &mac->mac_phy; 2820 int chan, error; 2821 2822 error = bwn_switch_band(sc, ic->ic_curchan); 2823 if (error) 2824 goto fail; 2825 bwn_mac_suspend(mac); 2826 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2827 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2828 if (chan != phy->chan) 2829 bwn_switch_channel(mac, chan); 2830 2831 /* TX power level */ 2832 if (ic->ic_curchan->ic_maxpower != 0 && 2833 ic->ic_curchan->ic_maxpower != phy->txpower) { 2834 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2835 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2836 BWN_TXPWR_IGNORE_TSSI); 2837 } 2838 2839 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2840 if (phy->set_antenna) 2841 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2842 2843 if (sc->sc_rf_enabled != phy->rf_on) { 2844 if (sc->sc_rf_enabled) { 2845 bwn_rf_turnon(mac); 2846 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2847 device_printf(sc->sc_dev, 2848 "please turn on the RF switch\n"); 2849 } else 2850 bwn_rf_turnoff(mac); 2851 } 2852 2853 bwn_mac_enable(mac); 2854 2855 fail: 2856 /* 2857 * Setup radio tap channel freq and flags 2858 */ 2859 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2860 htole16(ic->ic_curchan->ic_freq); 2861 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2862 htole16(ic->ic_curchan->ic_flags & 0xffff); 2863 } 2864 2865 static struct ieee80211vap * 2866 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2867 enum ieee80211_opmode opmode, int flags, 2868 const uint8_t bssid[IEEE80211_ADDR_LEN], 2869 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2870 { 2871 struct ifnet *ifp = ic->ic_ifp; 2872 struct bwn_softc *sc = ifp->if_softc; 2873 struct ieee80211vap *vap; 2874 struct bwn_vap *bvp; 2875 uint8_t mac[IEEE80211_ADDR_LEN]; 2876 2877 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 2878 return NULL; 2879 2880 IEEE80211_ADDR_COPY(mac, mac0); 2881 switch (opmode) { 2882 case IEEE80211_M_HOSTAP: 2883 case IEEE80211_M_MBSS: 2884 case IEEE80211_M_STA: 2885 case IEEE80211_M_WDS: 2886 case IEEE80211_M_MONITOR: 2887 case IEEE80211_M_IBSS: 2888 case IEEE80211_M_AHDEMO: 2889 break; 2890 default: 2891 return (NULL); 2892 } 2893 2894 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2895 2896 bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap), 2897 M_80211_VAP, M_INTWAIT | M_ZERO); 2898 vap = &bvp->bv_vap; 2899 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2900 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2901 /* override with driver methods */ 2902 bvp->bv_newstate = vap->iv_newstate; 2903 vap->iv_newstate = bwn_newstate; 2904 2905 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2906 vap->iv_max_aid = BWN_STAID_MAX; 2907 2908 ieee80211_ratectl_init(vap); 2909 2910 /* complete setup */ 2911 ieee80211_vap_attach(vap, ieee80211_media_change, 2912 ieee80211_media_status); 2913 ic->ic_opmode = opmode; 2914 return (vap); 2915 } 2916 2917 static void 2918 bwn_vap_delete(struct ieee80211vap *vap) 2919 { 2920 struct bwn_vap *bvp = BWN_VAP(vap); 2921 2922 ieee80211_ratectl_deinit(vap); 2923 ieee80211_vap_detach(vap); 2924 kfree(bvp, M_80211_VAP); 2925 } 2926 2927 static void 2928 bwn_init(void *arg) 2929 { 2930 struct bwn_softc *sc = arg; 2931 struct ifnet *ifp = sc->sc_ifp; 2932 struct ieee80211com *ic = ifp->if_l2com; 2933 int error = 0; 2934 2935 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 2936 __func__, ifp->if_flags); 2937 2938 wlan_assert_serialized(); 2939 error = bwn_init_locked(sc); 2940 2941 if (error == 0) 2942 ieee80211_start_all(ic); /* start all vap's */ 2943 } 2944 2945 static int 2946 bwn_init_locked(struct bwn_softc *sc) 2947 { 2948 struct bwn_mac *mac; 2949 struct ifnet *ifp = sc->sc_ifp; 2950 int error; 2951 2952 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2953 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2954 sc->sc_filters = 0; 2955 bwn_wme_clear(sc); 2956 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2957 sc->sc_rf_enabled = 1; 2958 2959 mac = sc->sc_curmac; 2960 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2961 error = bwn_core_init(mac); 2962 if (error != 0) 2963 return (error); 2964 } 2965 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2966 bwn_core_start(mac); 2967 2968 bwn_set_opmode(mac); 2969 bwn_set_pretbtt(mac); 2970 bwn_spu_setdelay(mac, 0); 2971 bwn_set_macaddr(mac); 2972 2973 ifp->if_flags |= IFF_RUNNING; 2974 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2975 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2976 2977 return (0); 2978 } 2979 2980 static void 2981 bwn_stop(struct bwn_softc *sc, int statechg) 2982 { 2983 2984 wlan_assert_serialized(); 2985 bwn_stop_locked(sc, statechg); 2986 } 2987 2988 static void 2989 bwn_stop_locked(struct bwn_softc *sc, int statechg) 2990 { 2991 struct bwn_mac *mac = sc->sc_curmac; 2992 struct ifnet *ifp = sc->sc_ifp; 2993 2994 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2995 /* XXX FIXME opmode not based on VAP */ 2996 bwn_set_opmode(mac); 2997 bwn_set_macaddr(mac); 2998 } 2999 3000 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3001 bwn_core_stop(mac); 3002 3003 callout_stop(&sc->sc_led_blink_ch); 3004 sc->sc_led_blinking = 0; 3005 3006 bwn_core_exit(mac); 3007 sc->sc_rf_enabled = 0; 3008 3009 ifp->if_flags &= ~IFF_RUNNING; 3010 ifq_clr_oactive(&ifp->if_snd); 3011 } 3012 3013 static void 3014 bwn_wme_clear(struct bwn_softc *sc) 3015 { 3016 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3017 struct wmeParams *p; 3018 unsigned int i; 3019 3020 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3021 ("%s:%d: fail", __func__, __LINE__)); 3022 3023 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3024 p = &(sc->sc_wmeParams[i]); 3025 3026 switch (bwn_wme_shm_offsets[i]) { 3027 case BWN_WME_VOICE: 3028 p->wmep_txopLimit = 0; 3029 p->wmep_aifsn = 2; 3030 /* XXX FIXME: log2(cwmin) */ 3031 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3032 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3033 break; 3034 case BWN_WME_VIDEO: 3035 p->wmep_txopLimit = 0; 3036 p->wmep_aifsn = 2; 3037 /* XXX FIXME: log2(cwmin) */ 3038 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3039 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3040 break; 3041 case BWN_WME_BESTEFFORT: 3042 p->wmep_txopLimit = 0; 3043 p->wmep_aifsn = 3; 3044 /* XXX FIXME: log2(cwmin) */ 3045 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3046 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3047 break; 3048 case BWN_WME_BACKGROUND: 3049 p->wmep_txopLimit = 0; 3050 p->wmep_aifsn = 7; 3051 /* XXX FIXME: log2(cwmin) */ 3052 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3053 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3054 break; 3055 default: 3056 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3057 } 3058 } 3059 } 3060 3061 static int 3062 bwn_core_init(struct bwn_mac *mac) 3063 { 3064 struct bwn_softc *sc = mac->mac_sc; 3065 uint64_t hf; 3066 int error; 3067 3068 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3069 ("%s:%d: fail", __func__, __LINE__)); 3070 3071 siba_powerup(sc->sc_dev, 0); 3072 if (!siba_dev_isup(sc->sc_dev)) 3073 bwn_reset_core(mac, 3074 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3075 3076 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3077 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3078 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3079 BWN_GETTIME(mac->mac_phy.nexttime); 3080 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3081 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3082 mac->mac_stats.link_noise = -95; 3083 mac->mac_reason_intr = 0; 3084 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3085 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3086 #ifdef BWN_DEBUG 3087 if (sc->sc_debug & BWN_DEBUG_XMIT) 3088 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3089 #endif 3090 mac->mac_suspended = 1; 3091 mac->mac_task_state = 0; 3092 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3093 3094 mac->mac_phy.init_pre(mac); 3095 3096 siba_pcicore_intr(sc->sc_dev); 3097 3098 siba_fix_imcfglobug(sc->sc_dev); 3099 bwn_bt_disable(mac); 3100 if (mac->mac_phy.prepare_hw) { 3101 error = mac->mac_phy.prepare_hw(mac); 3102 if (error) 3103 goto fail0; 3104 } 3105 error = bwn_chip_init(mac); 3106 if (error) 3107 goto fail0; 3108 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3109 siba_get_revid(sc->sc_dev)); 3110 hf = bwn_hf_read(mac); 3111 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3112 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3113 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3114 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3115 if (mac->mac_phy.rev == 1) 3116 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3117 } 3118 if (mac->mac_phy.rf_ver == 0x2050) { 3119 if (mac->mac_phy.rf_rev < 6) 3120 hf |= BWN_HF_FORCE_VCO_RECALC; 3121 if (mac->mac_phy.rf_rev == 6) 3122 hf |= BWN_HF_4318_TSSI; 3123 } 3124 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3125 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3126 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3127 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3128 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3129 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3130 bwn_hf_write(mac, hf); 3131 3132 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3133 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3134 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3135 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3136 3137 bwn_rate_init(mac); 3138 bwn_set_phytxctl(mac); 3139 3140 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3141 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3142 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3143 3144 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3145 bwn_pio_init(mac); 3146 else 3147 bwn_dma_init(mac); 3148 bwn_wme_init(mac); 3149 bwn_spu_setdelay(mac, 1); 3150 bwn_bt_enable(mac); 3151 3152 siba_powerup(sc->sc_dev, 3153 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3154 bwn_set_macaddr(mac); 3155 bwn_crypt_init(mac); 3156 3157 /* XXX LED initializatin */ 3158 3159 mac->mac_status = BWN_MAC_STATUS_INITED; 3160 3161 return (error); 3162 3163 fail0: 3164 siba_powerdown(sc->sc_dev); 3165 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3166 ("%s:%d: fail", __func__, __LINE__)); 3167 return (error); 3168 } 3169 3170 static void 3171 bwn_core_start(struct bwn_mac *mac) 3172 { 3173 struct bwn_softc *sc = mac->mac_sc; 3174 uint32_t tmp; 3175 3176 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3177 ("%s:%d: fail", __func__, __LINE__)); 3178 3179 if (siba_get_revid(sc->sc_dev) < 5) 3180 return; 3181 3182 while (1) { 3183 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3184 if (!(tmp & 0x00000001)) 3185 break; 3186 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3187 } 3188 3189 bwn_mac_enable(mac); 3190 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3191 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3192 3193 mac->mac_status = BWN_MAC_STATUS_STARTED; 3194 } 3195 3196 static void 3197 bwn_core_exit(struct bwn_mac *mac) 3198 { 3199 struct bwn_softc *sc = mac->mac_sc; 3200 uint32_t macctl; 3201 3202 wlan_assert_serialized(); 3203 3204 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3205 ("%s:%d: fail", __func__, __LINE__)); 3206 3207 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3208 return; 3209 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3210 3211 macctl = BWN_READ_4(mac, BWN_MACCTL); 3212 macctl &= ~BWN_MACCTL_MCODE_RUN; 3213 macctl |= BWN_MACCTL_MCODE_JMP0; 3214 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3215 3216 bwn_dma_stop(mac); 3217 bwn_pio_stop(mac); 3218 bwn_chip_exit(mac); 3219 mac->mac_phy.switch_analog(mac, 0); 3220 siba_dev_down(sc->sc_dev, 0); 3221 siba_powerdown(sc->sc_dev); 3222 } 3223 3224 static void 3225 bwn_bt_disable(struct bwn_mac *mac) 3226 { 3227 struct bwn_softc *sc = mac->mac_sc; 3228 3229 (void)sc; 3230 /* XXX do nothing yet */ 3231 } 3232 3233 static int 3234 bwn_chip_init(struct bwn_mac *mac) 3235 { 3236 struct bwn_softc *sc = mac->mac_sc; 3237 struct bwn_phy *phy = &mac->mac_phy; 3238 uint32_t macctl; 3239 int error; 3240 3241 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3242 if (phy->gmode) 3243 macctl |= BWN_MACCTL_GMODE; 3244 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3245 3246 error = bwn_fw_fillinfo(mac); 3247 if (error) 3248 return (error); 3249 error = bwn_fw_loaducode(mac); 3250 if (error) 3251 return (error); 3252 3253 error = bwn_gpio_init(mac); 3254 if (error) 3255 return (error); 3256 3257 error = bwn_fw_loadinitvals(mac); 3258 if (error) { 3259 siba_gpio_set(sc->sc_dev, 0); 3260 return (error); 3261 } 3262 phy->switch_analog(mac, 1); 3263 error = bwn_phy_init(mac); 3264 if (error) { 3265 siba_gpio_set(sc->sc_dev, 0); 3266 return (error); 3267 } 3268 if (phy->set_im) 3269 phy->set_im(mac, BWN_IMMODE_NONE); 3270 if (phy->set_antenna) 3271 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3272 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3273 3274 if (phy->type == BWN_PHYTYPE_B) 3275 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3276 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3277 if (siba_get_revid(sc->sc_dev) < 5) 3278 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3279 3280 BWN_WRITE_4(mac, BWN_MACCTL, 3281 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3282 BWN_WRITE_4(mac, BWN_MACCTL, 3283 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3284 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3285 3286 bwn_set_opmode(mac); 3287 if (siba_get_revid(sc->sc_dev) < 3) { 3288 BWN_WRITE_2(mac, 0x060e, 0x0000); 3289 BWN_WRITE_2(mac, 0x0610, 0x8000); 3290 BWN_WRITE_2(mac, 0x0604, 0x0000); 3291 BWN_WRITE_2(mac, 0x0606, 0x0200); 3292 } else { 3293 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3294 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3295 } 3296 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3297 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00); 3298 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3299 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3300 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3301 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3302 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3303 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3304 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3305 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3306 return (error); 3307 } 3308 3309 /* read hostflags */ 3310 static uint64_t 3311 bwn_hf_read(struct bwn_mac *mac) 3312 { 3313 uint64_t ret; 3314 3315 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3316 ret <<= 16; 3317 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3318 ret <<= 16; 3319 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3320 return (ret); 3321 } 3322 3323 static void 3324 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3325 { 3326 3327 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3328 (value & 0x00000000ffffull)); 3329 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3330 (value & 0x0000ffff0000ull) >> 16); 3331 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3332 (value & 0xffff00000000ULL) >> 32); 3333 } 3334 3335 static void 3336 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3337 { 3338 3339 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3340 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3341 } 3342 3343 static void 3344 bwn_rate_init(struct bwn_mac *mac) 3345 { 3346 3347 switch (mac->mac_phy.type) { 3348 case BWN_PHYTYPE_A: 3349 case BWN_PHYTYPE_G: 3350 case BWN_PHYTYPE_LP: 3351 case BWN_PHYTYPE_N: 3352 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3353 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3354 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3355 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3356 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3357 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3358 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3359 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3360 break; 3361 /* FALLTHROUGH */ 3362 case BWN_PHYTYPE_B: 3363 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3364 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3365 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3366 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3367 break; 3368 default: 3369 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3370 } 3371 } 3372 3373 static void 3374 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3375 { 3376 uint16_t offset; 3377 3378 if (ofdm) { 3379 offset = 0x480; 3380 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3381 } else { 3382 offset = 0x4c0; 3383 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3384 } 3385 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3386 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3387 } 3388 3389 static uint8_t 3390 bwn_plcp_getcck(const uint8_t bitrate) 3391 { 3392 3393 switch (bitrate) { 3394 case BWN_CCK_RATE_1MB: 3395 return (0x0a); 3396 case BWN_CCK_RATE_2MB: 3397 return (0x14); 3398 case BWN_CCK_RATE_5MB: 3399 return (0x37); 3400 case BWN_CCK_RATE_11MB: 3401 return (0x6e); 3402 } 3403 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3404 return (0); 3405 } 3406 3407 static uint8_t 3408 bwn_plcp_getofdm(const uint8_t bitrate) 3409 { 3410 3411 switch (bitrate) { 3412 case BWN_OFDM_RATE_6MB: 3413 return (0xb); 3414 case BWN_OFDM_RATE_9MB: 3415 return (0xf); 3416 case BWN_OFDM_RATE_12MB: 3417 return (0xa); 3418 case BWN_OFDM_RATE_18MB: 3419 return (0xe); 3420 case BWN_OFDM_RATE_24MB: 3421 return (0x9); 3422 case BWN_OFDM_RATE_36MB: 3423 return (0xd); 3424 case BWN_OFDM_RATE_48MB: 3425 return (0x8); 3426 case BWN_OFDM_RATE_54MB: 3427 return (0xc); 3428 } 3429 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3430 return (0); 3431 } 3432 3433 static void 3434 bwn_set_phytxctl(struct bwn_mac *mac) 3435 { 3436 uint16_t ctl; 3437 3438 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3439 BWN_TX_PHY_TXPWR); 3440 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3441 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3442 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3443 } 3444 3445 static void 3446 bwn_pio_init(struct bwn_mac *mac) 3447 { 3448 struct bwn_pio *pio = &mac->mac_method.pio; 3449 3450 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3451 & ~BWN_MACCTL_BIGENDIAN); 3452 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3453 3454 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3455 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3456 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3457 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3458 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3459 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3460 } 3461 3462 static void 3463 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3464 int index) 3465 { 3466 struct bwn_pio_txpkt *tp; 3467 struct bwn_softc *sc = mac->mac_sc; 3468 unsigned int i; 3469 3470 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3471 tq->tq_index = index; 3472 3473 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3474 if (siba_get_revid(sc->sc_dev) >= 8) 3475 tq->tq_size = 1920; 3476 else { 3477 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3478 tq->tq_size -= 80; 3479 } 3480 3481 TAILQ_INIT(&tq->tq_pktlist); 3482 for (i = 0; i < N(tq->tq_pkts); i++) { 3483 tp = &(tq->tq_pkts[i]); 3484 tp->tp_index = i; 3485 tp->tp_queue = tq; 3486 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3487 } 3488 } 3489 3490 static uint16_t 3491 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3492 { 3493 struct bwn_softc *sc = mac->mac_sc; 3494 static const uint16_t bases[] = { 3495 BWN_PIO_BASE0, 3496 BWN_PIO_BASE1, 3497 BWN_PIO_BASE2, 3498 BWN_PIO_BASE3, 3499 BWN_PIO_BASE4, 3500 BWN_PIO_BASE5, 3501 BWN_PIO_BASE6, 3502 BWN_PIO_BASE7, 3503 }; 3504 static const uint16_t bases_rev11[] = { 3505 BWN_PIO11_BASE0, 3506 BWN_PIO11_BASE1, 3507 BWN_PIO11_BASE2, 3508 BWN_PIO11_BASE3, 3509 BWN_PIO11_BASE4, 3510 BWN_PIO11_BASE5, 3511 }; 3512 3513 if (siba_get_revid(sc->sc_dev) >= 11) { 3514 if (index >= N(bases_rev11)) 3515 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3516 return (bases_rev11[index]); 3517 } 3518 if (index >= N(bases)) 3519 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3520 return (bases[index]); 3521 } 3522 3523 static void 3524 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3525 int index) 3526 { 3527 struct bwn_softc *sc = mac->mac_sc; 3528 3529 prq->prq_mac = mac; 3530 prq->prq_rev = siba_get_revid(sc->sc_dev); 3531 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3532 bwn_dma_rxdirectfifo(mac, index, 1); 3533 } 3534 3535 static void 3536 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3537 { 3538 if (tq == NULL) 3539 return; 3540 bwn_pio_cancel_tx_packets(tq); 3541 } 3542 3543 static void 3544 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3545 { 3546 3547 bwn_destroy_pioqueue_tx(pio); 3548 } 3549 3550 static uint16_t 3551 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3552 uint16_t offset) 3553 { 3554 3555 return (BWN_READ_2(mac, tq->tq_base + offset)); 3556 } 3557 3558 static void 3559 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3560 { 3561 uint32_t ctl; 3562 int type; 3563 uint16_t base; 3564 3565 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3566 base = bwn_dma_base(type, idx); 3567 if (type == BWN_DMA_64BIT) { 3568 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3569 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3570 if (enable) 3571 ctl |= BWN_DMA64_RXDIRECTFIFO; 3572 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3573 } else { 3574 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3575 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3576 if (enable) 3577 ctl |= BWN_DMA32_RXDIRECTFIFO; 3578 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3579 } 3580 } 3581 3582 static uint64_t 3583 bwn_dma_mask(struct bwn_mac *mac) 3584 { 3585 uint32_t tmp; 3586 uint16_t base; 3587 3588 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3589 if (tmp & SIBA_TGSHIGH_DMA64) 3590 return (BWN_DMA_BIT_MASK(64)); 3591 base = bwn_dma_base(0, 0); 3592 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3593 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3594 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3595 return (BWN_DMA_BIT_MASK(32)); 3596 3597 return (BWN_DMA_BIT_MASK(30)); 3598 } 3599 3600 static int 3601 bwn_dma_mask2type(uint64_t dmamask) 3602 { 3603 3604 if (dmamask == BWN_DMA_BIT_MASK(30)) 3605 return (BWN_DMA_30BIT); 3606 if (dmamask == BWN_DMA_BIT_MASK(32)) 3607 return (BWN_DMA_32BIT); 3608 if (dmamask == BWN_DMA_BIT_MASK(64)) 3609 return (BWN_DMA_64BIT); 3610 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3611 return (BWN_DMA_30BIT); 3612 } 3613 3614 static void 3615 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3616 { 3617 struct bwn_pio_txpkt *tp; 3618 unsigned int i; 3619 3620 for (i = 0; i < N(tq->tq_pkts); i++) { 3621 tp = &(tq->tq_pkts[i]); 3622 if (tp->tp_m) { 3623 m_freem(tp->tp_m); 3624 tp->tp_m = NULL; 3625 } 3626 } 3627 } 3628 3629 static uint16_t 3630 bwn_dma_base(int type, int controller_idx) 3631 { 3632 static const uint16_t map64[] = { 3633 BWN_DMA64_BASE0, 3634 BWN_DMA64_BASE1, 3635 BWN_DMA64_BASE2, 3636 BWN_DMA64_BASE3, 3637 BWN_DMA64_BASE4, 3638 BWN_DMA64_BASE5, 3639 }; 3640 static const uint16_t map32[] = { 3641 BWN_DMA32_BASE0, 3642 BWN_DMA32_BASE1, 3643 BWN_DMA32_BASE2, 3644 BWN_DMA32_BASE3, 3645 BWN_DMA32_BASE4, 3646 BWN_DMA32_BASE5, 3647 }; 3648 3649 if (type == BWN_DMA_64BIT) { 3650 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3651 ("%s:%d: fail", __func__, __LINE__)); 3652 return (map64[controller_idx]); 3653 } 3654 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3655 ("%s:%d: fail", __func__, __LINE__)); 3656 return (map32[controller_idx]); 3657 } 3658 3659 static void 3660 bwn_dma_init(struct bwn_mac *mac) 3661 { 3662 struct bwn_dma *dma = &mac->mac_method.dma; 3663 3664 /* setup TX DMA channels. */ 3665 bwn_dma_setup(dma->wme[WME_AC_BK]); 3666 bwn_dma_setup(dma->wme[WME_AC_BE]); 3667 bwn_dma_setup(dma->wme[WME_AC_VI]); 3668 bwn_dma_setup(dma->wme[WME_AC_VO]); 3669 bwn_dma_setup(dma->mcast); 3670 /* setup RX DMA channel. */ 3671 bwn_dma_setup(dma->rx); 3672 } 3673 3674 static struct bwn_dma_ring * 3675 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3676 int for_tx, int type) 3677 { 3678 struct bwn_dma *dma = &mac->mac_method.dma; 3679 struct bwn_dma_ring *dr; 3680 struct bwn_dmadesc_generic *desc; 3681 struct bwn_dmadesc_meta *mt; 3682 struct bwn_softc *sc = mac->mac_sc; 3683 int error, i; 3684 3685 dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO); 3686 dr->dr_numslots = BWN_RXRING_SLOTS; 3687 if (for_tx) 3688 dr->dr_numslots = BWN_TXRING_SLOTS; 3689 3690 dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3691 M_DEVBUF, M_INTWAIT | M_ZERO); 3692 3693 dr->dr_type = type; 3694 dr->dr_mac = mac; 3695 dr->dr_base = bwn_dma_base(type, controller_index); 3696 dr->dr_index = controller_index; 3697 if (type == BWN_DMA_64BIT) { 3698 dr->getdesc = bwn_dma_64_getdesc; 3699 dr->setdesc = bwn_dma_64_setdesc; 3700 dr->start_transfer = bwn_dma_64_start_transfer; 3701 dr->suspend = bwn_dma_64_suspend; 3702 dr->resume = bwn_dma_64_resume; 3703 dr->get_curslot = bwn_dma_64_get_curslot; 3704 dr->set_curslot = bwn_dma_64_set_curslot; 3705 } else { 3706 dr->getdesc = bwn_dma_32_getdesc; 3707 dr->setdesc = bwn_dma_32_setdesc; 3708 dr->start_transfer = bwn_dma_32_start_transfer; 3709 dr->suspend = bwn_dma_32_suspend; 3710 dr->resume = bwn_dma_32_resume; 3711 dr->get_curslot = bwn_dma_32_get_curslot; 3712 dr->set_curslot = bwn_dma_32_set_curslot; 3713 } 3714 if (for_tx) { 3715 dr->dr_tx = 1; 3716 dr->dr_curslot = -1; 3717 } else { 3718 if (dr->dr_index == 0) { 3719 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3720 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3721 } else 3722 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3723 } 3724 3725 error = bwn_dma_allocringmemory(dr); 3726 if (error) 3727 goto fail1; 3728 3729 if (for_tx) { 3730 /* 3731 * Assumption: BWN_TXRING_SLOTS can be divided by 3732 * BWN_TX_SLOTS_PER_FRAME 3733 */ 3734 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3735 ("%s:%d: fail", __func__, __LINE__)); 3736 3737 /* 3738 * Create TX ring DMA stuffs 3739 */ 3740 dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag, 3741 4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3742 BWN_MAX_HDRSIZE(mac), 3743 BUS_DMA_WAITOK | BUS_DMA_ZERO, 3744 &dr->dr_txring_dtag, &dr->dr_txring_dmap, 3745 &dr->dr_txring_paddr); 3746 if (dr->dr_txhdr_cache == NULL) { 3747 device_printf(sc->sc_dev, 3748 "can't create TX ring DMA memory\n"); 3749 goto fail1; 3750 } 3751 3752 for (i = 0; i < dr->dr_numslots; i += 2) { 3753 dr->getdesc(dr, i, &desc, &mt); 3754 3755 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3756 mt->mt_m = NULL; 3757 mt->mt_ni = NULL; 3758 mt->mt_islast = 0; 3759 mt->mt_dmap = dr->dr_txring_dmap; 3760 mt->mt_paddr = dr->dr_txring_paddr + 3761 (i / BWN_TX_SLOTS_PER_FRAME) * 3762 BWN_MAX_HDRSIZE(mac); 3763 3764 dr->getdesc(dr, i + 1, &desc, &mt); 3765 3766 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3767 mt->mt_m = NULL; 3768 mt->mt_ni = NULL; 3769 mt->mt_islast = 1; 3770 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3771 &mt->mt_dmap); 3772 if (error) { 3773 device_printf(sc->sc_dev, 3774 "can't create RX buf DMA map\n"); 3775 goto fail2; 3776 } 3777 } 3778 } else { 3779 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3780 &dr->dr_spare_dmap); 3781 if (error) { 3782 device_printf(sc->sc_dev, 3783 "can't create RX buf DMA map\n"); 3784 goto out; /* XXX wrong! */ 3785 } 3786 3787 for (i = 0; i < dr->dr_numslots; i++) { 3788 dr->getdesc(dr, i, &desc, &mt); 3789 3790 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3791 &mt->mt_dmap); 3792 if (error) { 3793 device_printf(sc->sc_dev, 3794 "can't create RX buf DMA map\n"); 3795 goto out; /* XXX wrong! */ 3796 } 3797 error = bwn_dma_newbuf(dr, desc, mt, 1); 3798 if (error) { 3799 device_printf(sc->sc_dev, 3800 "failed to allocate RX buf\n"); 3801 goto out; /* XXX wrong! */ 3802 } 3803 } 3804 3805 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3806 BUS_DMASYNC_PREWRITE); 3807 3808 dr->dr_usedslot = dr->dr_numslots; 3809 } 3810 3811 out: 3812 return (dr); 3813 3814 fail2: 3815 /* XXX free up dma allocations */ 3816 fail1: 3817 kfree(dr->dr_meta, M_DEVBUF); 3818 kfree(dr, M_DEVBUF); 3819 return (NULL); 3820 } 3821 3822 static void 3823 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3824 { 3825 3826 if (dr == NULL) 3827 return; 3828 3829 bwn_dma_free_descbufs(*dr); 3830 bwn_dma_free_ringmemory(*dr); 3831 3832 if ((*dr)->dr_meta != NULL) 3833 kfree((*dr)->dr_meta, M_DEVBUF); 3834 kfree(*dr, M_DEVBUF); 3835 3836 *dr = NULL; 3837 } 3838 3839 static void 3840 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3841 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3842 { 3843 struct bwn_dmadesc32 *desc; 3844 3845 *meta = &(dr->dr_meta[slot]); 3846 desc = dr->dr_ring_descbase; 3847 desc = &(desc[slot]); 3848 3849 *gdesc = (struct bwn_dmadesc_generic *)desc; 3850 } 3851 3852 static void 3853 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3854 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3855 int start, int end, int irq) 3856 { 3857 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3858 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3859 uint32_t addr, addrext, ctl; 3860 int slot; 3861 3862 slot = (int)(&(desc->dma.dma32) - descbase); 3863 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3864 ("%s:%d: fail", __func__, __LINE__)); 3865 3866 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3867 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3868 addr |= siba_dma_translation(sc->sc_dev); 3869 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3870 if (slot == dr->dr_numslots - 1) 3871 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3872 if (start) 3873 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3874 if (end) 3875 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3876 if (irq) 3877 ctl |= BWN_DMA32_DCTL_IRQ; 3878 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3879 & BWN_DMA32_DCTL_ADDREXT_MASK; 3880 3881 desc->dma.dma32.control = htole32(ctl); 3882 desc->dma.dma32.address = htole32(addr); 3883 } 3884 3885 static void 3886 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3887 { 3888 3889 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3890 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3891 } 3892 3893 static void 3894 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3895 { 3896 3897 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3898 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3899 } 3900 3901 static void 3902 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3903 { 3904 3905 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3906 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3907 } 3908 3909 static int 3910 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3911 { 3912 uint32_t val; 3913 3914 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3915 val &= BWN_DMA32_RXDPTR; 3916 3917 return (val / sizeof(struct bwn_dmadesc32)); 3918 } 3919 3920 static void 3921 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3922 { 3923 3924 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3925 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3926 } 3927 3928 static void 3929 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3930 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3931 { 3932 struct bwn_dmadesc64 *desc; 3933 3934 *meta = &(dr->dr_meta[slot]); 3935 desc = dr->dr_ring_descbase; 3936 desc = &(desc[slot]); 3937 3938 *gdesc = (struct bwn_dmadesc_generic *)desc; 3939 } 3940 3941 static void 3942 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3943 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3944 int start, int end, int irq) 3945 { 3946 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3947 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3948 int slot; 3949 uint32_t ctl0 = 0, ctl1 = 0; 3950 uint32_t addrlo, addrhi; 3951 uint32_t addrext; 3952 3953 slot = (int)(&(desc->dma.dma64) - descbase); 3954 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3955 ("%s:%d: fail", __func__, __LINE__)); 3956 3957 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3958 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3959 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3960 30; 3961 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3962 if (slot == dr->dr_numslots - 1) 3963 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3964 if (start) 3965 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3966 if (end) 3967 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3968 if (irq) 3969 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3970 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3971 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3972 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3973 3974 desc->dma.dma64.control0 = htole32(ctl0); 3975 desc->dma.dma64.control1 = htole32(ctl1); 3976 desc->dma.dma64.address_low = htole32(addrlo); 3977 desc->dma.dma64.address_high = htole32(addrhi); 3978 } 3979 3980 static void 3981 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3982 { 3983 3984 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3985 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3986 } 3987 3988 static void 3989 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3990 { 3991 3992 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3993 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3994 } 3995 3996 static void 3997 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3998 { 3999 4000 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4001 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4002 } 4003 4004 static int 4005 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4006 { 4007 uint32_t val; 4008 4009 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4010 val &= BWN_DMA64_RXSTATDPTR; 4011 4012 return (val / sizeof(struct bwn_dmadesc64)); 4013 } 4014 4015 static void 4016 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4017 { 4018 4019 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4020 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4021 } 4022 4023 static int 4024 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4025 { 4026 struct bwn_mac *mac = dr->dr_mac; 4027 struct bwn_dma *dma = &mac->mac_method.dma; 4028 struct bwn_softc *sc = mac->mac_sc; 4029 int error; 4030 4031 error = bus_dma_tag_create(dma->parent_dtag, 4032 BWN_ALIGN, 0, 4033 BUS_SPACE_MAXADDR, 4034 BUS_SPACE_MAXADDR, 4035 NULL, NULL, 4036 BWN_DMA_RINGMEMSIZE, 4037 1, 4038 BUS_SPACE_MAXSIZE_32BIT, 4039 0, 4040 &dr->dr_ring_dtag); 4041 if (error) { 4042 device_printf(sc->sc_dev, 4043 "can't create TX ring DMA tag: TODO frees\n"); 4044 return (-1); 4045 } 4046 4047 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4048 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4049 &dr->dr_ring_dmap); 4050 if (error) { 4051 device_printf(sc->sc_dev, 4052 "can't allocate DMA mem: TODO frees\n"); 4053 return (-1); 4054 } 4055 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4056 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4057 bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0); 4058 if (error) { 4059 device_printf(sc->sc_dev, 4060 "can't load DMA mem: TODO free\n"); 4061 return (-1); 4062 } 4063 4064 return (0); 4065 } 4066 4067 static void 4068 bwn_dma_setup(struct bwn_dma_ring *dr) 4069 { 4070 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4071 uint64_t ring64; 4072 uint32_t addrext, ring32, value; 4073 uint32_t trans = siba_dma_translation(sc->sc_dev); 4074 4075 if (dr->dr_tx) { 4076 dr->dr_curslot = -1; 4077 4078 if (dr->dr_type == BWN_DMA_64BIT) { 4079 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4080 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4081 >> 30; 4082 value = BWN_DMA64_TXENABLE; 4083 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4084 & BWN_DMA64_TXADDREXT_MASK; 4085 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4086 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4087 (ring64 & 0xffffffff)); 4088 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4089 ((ring64 >> 32) & 4090 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4091 } else { 4092 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4093 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4094 value = BWN_DMA32_TXENABLE; 4095 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4096 & BWN_DMA32_TXADDREXT_MASK; 4097 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4098 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4099 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4100 } 4101 return; 4102 } 4103 4104 /* 4105 * set for RX 4106 */ 4107 dr->dr_usedslot = dr->dr_numslots; 4108 4109 if (dr->dr_type == BWN_DMA_64BIT) { 4110 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4111 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4112 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4113 value |= BWN_DMA64_RXENABLE; 4114 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4115 & BWN_DMA64_RXADDREXT_MASK; 4116 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4117 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4118 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4119 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4120 | (trans << 1)); 4121 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4122 sizeof(struct bwn_dmadesc64)); 4123 } else { 4124 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4125 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4126 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4127 value |= BWN_DMA32_RXENABLE; 4128 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4129 & BWN_DMA32_RXADDREXT_MASK; 4130 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4131 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4132 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4133 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4134 sizeof(struct bwn_dmadesc32)); 4135 } 4136 } 4137 4138 static void 4139 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4140 { 4141 4142 if (dr->dr_tx) { 4143 bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap); 4144 if (dr->dr_txhdr_cache != NULL) 4145 bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache, 4146 dr->dr_txring_dmap); 4147 bus_dma_tag_destroy(dr->dr_txring_dtag); 4148 } 4149 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4150 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4151 dr->dr_ring_dmap); 4152 bus_dma_tag_destroy(dr->dr_ring_dtag); 4153 } 4154 4155 static void 4156 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4157 { 4158 4159 if (dr->dr_tx) { 4160 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4161 if (dr->dr_type == BWN_DMA_64BIT) { 4162 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4163 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4164 } else 4165 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4166 } else { 4167 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4168 if (dr->dr_type == BWN_DMA_64BIT) { 4169 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4170 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4171 } else 4172 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4173 } 4174 } 4175 4176 static void 4177 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4178 { 4179 struct bwn_dmadesc_generic *desc; 4180 struct bwn_dmadesc_meta *meta; 4181 struct bwn_mac *mac = dr->dr_mac; 4182 struct bwn_dma *dma = &mac->mac_method.dma; 4183 struct bwn_softc *sc = mac->mac_sc; 4184 int i; 4185 4186 if (!dr->dr_usedslot) 4187 return; 4188 for (i = 0; i < dr->dr_numslots; i++) { 4189 dr->getdesc(dr, i, &desc, &meta); 4190 4191 if (meta->mt_m == NULL) { 4192 if (!dr->dr_tx) 4193 device_printf(sc->sc_dev, "%s: not TX?\n", 4194 __func__); 4195 continue; 4196 } 4197 if (dr->dr_tx) { 4198 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 4199 /* Nothing */ 4200 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 4201 bus_dmamap_unload(dma->txbuf_dtag, 4202 meta->mt_dmap); 4203 } 4204 } else 4205 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4206 bwn_dma_free_descbuf(dr, meta); 4207 } 4208 } 4209 4210 static int 4211 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4212 int type) 4213 { 4214 struct bwn_softc *sc = mac->mac_sc; 4215 uint32_t value; 4216 int i; 4217 uint16_t offset; 4218 4219 for (i = 0; i < 10; i++) { 4220 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4221 BWN_DMA32_TXSTATUS; 4222 value = BWN_READ_4(mac, base + offset); 4223 if (type == BWN_DMA_64BIT) { 4224 value &= BWN_DMA64_TXSTAT; 4225 if (value == BWN_DMA64_TXSTAT_DISABLED || 4226 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4227 value == BWN_DMA64_TXSTAT_STOPPED) 4228 break; 4229 } else { 4230 value &= BWN_DMA32_TXSTATE; 4231 if (value == BWN_DMA32_TXSTAT_DISABLED || 4232 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4233 value == BWN_DMA32_TXSTAT_STOPPED) 4234 break; 4235 } 4236 DELAY(1000); 4237 } 4238 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4239 BWN_WRITE_4(mac, base + offset, 0); 4240 for (i = 0; i < 10; i++) { 4241 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4242 BWN_DMA32_TXSTATUS; 4243 value = BWN_READ_4(mac, base + offset); 4244 if (type == BWN_DMA_64BIT) { 4245 value &= BWN_DMA64_TXSTAT; 4246 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4247 i = -1; 4248 break; 4249 } 4250 } else { 4251 value &= BWN_DMA32_TXSTATE; 4252 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4253 i = -1; 4254 break; 4255 } 4256 } 4257 DELAY(1000); 4258 } 4259 if (i != -1) { 4260 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4261 return (ENODEV); 4262 } 4263 DELAY(1000); 4264 4265 return (0); 4266 } 4267 4268 static int 4269 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4270 int type) 4271 { 4272 struct bwn_softc *sc = mac->mac_sc; 4273 uint32_t value; 4274 int i; 4275 uint16_t offset; 4276 4277 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4278 BWN_WRITE_4(mac, base + offset, 0); 4279 for (i = 0; i < 10; i++) { 4280 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4281 BWN_DMA32_RXSTATUS; 4282 value = BWN_READ_4(mac, base + offset); 4283 if (type == BWN_DMA_64BIT) { 4284 value &= BWN_DMA64_RXSTAT; 4285 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4286 i = -1; 4287 break; 4288 } 4289 } else { 4290 value &= BWN_DMA32_RXSTATE; 4291 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4292 i = -1; 4293 break; 4294 } 4295 } 4296 DELAY(1000); 4297 } 4298 if (i != -1) { 4299 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4300 return (ENODEV); 4301 } 4302 4303 return (0); 4304 } 4305 4306 static void 4307 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4308 struct bwn_dmadesc_meta *meta) 4309 { 4310 4311 if (meta->mt_m != NULL) { 4312 m_freem(meta->mt_m); 4313 meta->mt_m = NULL; 4314 } 4315 if (meta->mt_ni != NULL) { 4316 ieee80211_free_node(meta->mt_ni); 4317 meta->mt_ni = NULL; 4318 } 4319 } 4320 4321 static void 4322 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4323 { 4324 struct bwn_rxhdr4 *rxhdr; 4325 unsigned char *frame; 4326 4327 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4328 rxhdr->frame_len = 0; 4329 4330 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4331 sizeof(struct bwn_plcp6) + 2, 4332 ("%s:%d: fail", __func__, __LINE__)); 4333 frame = mtod(m, char *) + dr->dr_frameoffset; 4334 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4335 } 4336 4337 static uint8_t 4338 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4339 { 4340 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4341 4342 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4343 == 0xff); 4344 } 4345 4346 static void 4347 bwn_wme_init(struct bwn_mac *mac) 4348 { 4349 4350 bwn_wme_load(mac); 4351 4352 /* enable WME support. */ 4353 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4354 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4355 BWN_IFSCTL_USE_EDCF); 4356 } 4357 4358 static void 4359 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4360 { 4361 struct bwn_softc *sc = mac->mac_sc; 4362 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4363 uint16_t delay; /* microsec */ 4364 4365 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4366 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4367 delay = 500; 4368 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4369 delay = max(delay, (uint16_t)2400); 4370 4371 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4372 } 4373 4374 static void 4375 bwn_bt_enable(struct bwn_mac *mac) 4376 { 4377 struct bwn_softc *sc = mac->mac_sc; 4378 uint64_t hf; 4379 4380 if (bwn_bluetooth == 0) 4381 return; 4382 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4383 return; 4384 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4385 return; 4386 4387 hf = bwn_hf_read(mac); 4388 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4389 hf |= BWN_HF_BT_COEXISTALT; 4390 else 4391 hf |= BWN_HF_BT_COEXIST; 4392 bwn_hf_write(mac, hf); 4393 } 4394 4395 static void 4396 bwn_set_macaddr(struct bwn_mac *mac) 4397 { 4398 4399 bwn_mac_write_bssid(mac); 4400 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4401 } 4402 4403 static void 4404 bwn_clear_keys(struct bwn_mac *mac) 4405 { 4406 int i; 4407 4408 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4409 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4410 ("%s:%d: fail", __func__, __LINE__)); 4411 4412 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4413 NULL, BWN_SEC_KEYSIZE, NULL); 4414 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4415 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4416 NULL, BWN_SEC_KEYSIZE, NULL); 4417 } 4418 mac->mac_key[i].keyconf = NULL; 4419 } 4420 } 4421 4422 static void 4423 bwn_crypt_init(struct bwn_mac *mac) 4424 { 4425 struct bwn_softc *sc = mac->mac_sc; 4426 4427 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4428 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4429 ("%s:%d: fail", __func__, __LINE__)); 4430 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4431 mac->mac_ktp *= 2; 4432 if (siba_get_revid(sc->sc_dev) >= 5) 4433 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4434 bwn_clear_keys(mac); 4435 } 4436 4437 static void 4438 bwn_chip_exit(struct bwn_mac *mac) 4439 { 4440 struct bwn_softc *sc = mac->mac_sc; 4441 4442 bwn_phy_exit(mac); 4443 siba_gpio_set(sc->sc_dev, 0); 4444 } 4445 4446 static int 4447 bwn_fw_fillinfo(struct bwn_mac *mac) 4448 { 4449 int error; 4450 4451 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4452 if (error == 0) 4453 return (0); 4454 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4455 if (error == 0) 4456 return (0); 4457 return (error); 4458 } 4459 4460 static int 4461 bwn_gpio_init(struct bwn_mac *mac) 4462 { 4463 struct bwn_softc *sc = mac->mac_sc; 4464 uint32_t mask = 0x1f, set = 0xf, value; 4465 4466 BWN_WRITE_4(mac, BWN_MACCTL, 4467 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4468 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4469 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4470 4471 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4472 mask |= 0x0060; 4473 set |= 0x0060; 4474 } 4475 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4476 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4477 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4478 mask |= 0x0200; 4479 set |= 0x0200; 4480 } 4481 if (siba_get_revid(sc->sc_dev) >= 2) 4482 mask |= 0x0010; 4483 4484 value = siba_gpio_get(sc->sc_dev); 4485 if (value == -1) 4486 return (0); 4487 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4488 4489 return (0); 4490 } 4491 4492 static int 4493 bwn_fw_loadinitvals(struct bwn_mac *mac) 4494 { 4495 #define GETFWOFFSET(fwp, offset) \ 4496 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4497 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4498 const struct bwn_fwhdr *hdr; 4499 struct bwn_fw *fw = &mac->mac_fw; 4500 int error; 4501 4502 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4503 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4504 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4505 if (error) 4506 return (error); 4507 if (fw->initvals_band.fw) { 4508 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4509 error = bwn_fwinitvals_write(mac, 4510 GETFWOFFSET(fw->initvals_band, hdr_len), 4511 be32toh(hdr->size), 4512 fw->initvals_band.fw->datasize - hdr_len); 4513 } 4514 return (error); 4515 #undef GETFWOFFSET 4516 } 4517 4518 static int 4519 bwn_phy_init(struct bwn_mac *mac) 4520 { 4521 struct bwn_softc *sc = mac->mac_sc; 4522 int error; 4523 4524 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4525 mac->mac_phy.rf_onoff(mac, 1); 4526 error = mac->mac_phy.init(mac); 4527 if (error) { 4528 device_printf(sc->sc_dev, "PHY init failed\n"); 4529 goto fail0; 4530 } 4531 error = bwn_switch_channel(mac, 4532 mac->mac_phy.get_default_chan(mac)); 4533 if (error) { 4534 device_printf(sc->sc_dev, 4535 "failed to switch default channel\n"); 4536 goto fail1; 4537 } 4538 return (0); 4539 fail1: 4540 if (mac->mac_phy.exit) 4541 mac->mac_phy.exit(mac); 4542 fail0: 4543 mac->mac_phy.rf_onoff(mac, 0); 4544 4545 return (error); 4546 } 4547 4548 static void 4549 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4550 { 4551 uint16_t ant; 4552 uint16_t tmp; 4553 4554 ant = bwn_ant2phy(antenna); 4555 4556 /* For ACK/CTS */ 4557 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4558 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4559 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4560 /* For Probe Resposes */ 4561 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4562 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4563 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4564 } 4565 4566 static void 4567 bwn_set_opmode(struct bwn_mac *mac) 4568 { 4569 struct bwn_softc *sc = mac->mac_sc; 4570 struct ifnet *ifp = sc->sc_ifp; 4571 struct ieee80211com *ic = ifp->if_l2com; 4572 uint32_t ctl; 4573 uint16_t cfp_pretbtt; 4574 4575 ctl = BWN_READ_4(mac, BWN_MACCTL); 4576 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4577 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4578 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4579 ctl |= BWN_MACCTL_STA; 4580 4581 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4582 ic->ic_opmode == IEEE80211_M_MBSS) 4583 ctl |= BWN_MACCTL_HOSTAP; 4584 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4585 ctl &= ~BWN_MACCTL_STA; 4586 ctl |= sc->sc_filters; 4587 4588 if (siba_get_revid(sc->sc_dev) <= 4) 4589 ctl |= BWN_MACCTL_PROMISC; 4590 4591 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4592 4593 cfp_pretbtt = 2; 4594 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4595 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4596 siba_get_chiprev(sc->sc_dev) == 3) 4597 cfp_pretbtt = 100; 4598 else 4599 cfp_pretbtt = 50; 4600 } 4601 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4602 } 4603 4604 static int 4605 bwn_dma_gettype(struct bwn_mac *mac) 4606 { 4607 uint32_t tmp; 4608 uint16_t base; 4609 4610 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4611 if (tmp & SIBA_TGSHIGH_DMA64) 4612 return (BWN_DMA_64BIT); 4613 base = bwn_dma_base(0, 0); 4614 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4615 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4616 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4617 return (BWN_DMA_32BIT); 4618 4619 return (BWN_DMA_30BIT); 4620 } 4621 4622 static void 4623 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4624 { 4625 if (!error) { 4626 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4627 *((bus_addr_t *)arg) = seg->ds_addr; 4628 } 4629 } 4630 4631 static void 4632 bwn_phy_g_init_sub(struct bwn_mac *mac) 4633 { 4634 struct bwn_phy *phy = &mac->mac_phy; 4635 struct bwn_phy_g *pg = &phy->phy_g; 4636 struct bwn_softc *sc = mac->mac_sc; 4637 uint16_t i, tmp; 4638 4639 if (phy->rev == 1) 4640 bwn_phy_init_b5(mac); 4641 else 4642 bwn_phy_init_b6(mac); 4643 4644 if (phy->rev >= 2 || phy->gmode) 4645 bwn_phy_init_a(mac); 4646 4647 if (phy->rev >= 2) { 4648 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4649 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4650 } 4651 if (phy->rev == 2) { 4652 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4653 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4654 } 4655 if (phy->rev > 5) { 4656 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4657 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4658 } 4659 if (phy->gmode || phy->rev >= 2) { 4660 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4661 tmp &= BWN_PHYVER_VERSION; 4662 if (tmp == 3 || tmp == 5) { 4663 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4664 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4665 } 4666 if (tmp == 5) { 4667 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4668 0x1f00); 4669 } 4670 } 4671 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4672 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4673 if (phy->rf_rev == 8) { 4674 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4675 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4676 } 4677 if (BWN_HAS_LOOPBACK(phy)) 4678 bwn_loopback_calcgain(mac); 4679 4680 if (phy->rf_rev != 8) { 4681 if (pg->pg_initval == 0xffff) 4682 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4683 else 4684 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4685 } 4686 bwn_lo_g_init(mac); 4687 if (BWN_HAS_TXMAG(phy)) { 4688 BWN_RF_WRITE(mac, 0x52, 4689 (BWN_RF_READ(mac, 0x52) & 0xff00) 4690 | pg->pg_loctl.tx_bias | 4691 pg->pg_loctl.tx_magn); 4692 } else { 4693 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4694 } 4695 if (phy->rev >= 6) { 4696 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4697 (pg->pg_loctl.tx_bias << 12)); 4698 } 4699 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4700 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4701 else 4702 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4703 if (phy->rev < 2) 4704 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4705 else 4706 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4707 if (phy->gmode || phy->rev >= 2) { 4708 bwn_lo_g_adjust(mac); 4709 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4710 } 4711 4712 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4713 for (i = 0; i < 64; i++) { 4714 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4715 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4716 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4717 -32), 31)); 4718 } 4719 bwn_nrssi_threshold(mac); 4720 } else if (phy->gmode || phy->rev >= 2) { 4721 if (pg->pg_nrssi[0] == -1000) { 4722 KASSERT(pg->pg_nrssi[1] == -1000, 4723 ("%s:%d: fail", __func__, __LINE__)); 4724 bwn_nrssi_slope_11g(mac); 4725 } else 4726 bwn_nrssi_threshold(mac); 4727 } 4728 if (phy->rf_rev == 8) 4729 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4730 bwn_phy_hwpctl_init(mac); 4731 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4732 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4733 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4734 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4735 } 4736 } 4737 4738 static uint8_t 4739 bwn_has_hwpctl(struct bwn_mac *mac) 4740 { 4741 4742 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4743 return (0); 4744 return (mac->mac_phy.use_hwpctl(mac)); 4745 } 4746 4747 static void 4748 bwn_phy_init_b5(struct bwn_mac *mac) 4749 { 4750 struct bwn_phy *phy = &mac->mac_phy; 4751 struct bwn_phy_g *pg = &phy->phy_g; 4752 struct bwn_softc *sc = mac->mac_sc; 4753 uint16_t offset, value; 4754 uint8_t old_channel; 4755 4756 if (phy->analog == 1) 4757 BWN_RF_SET(mac, 0x007a, 0x0050); 4758 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4759 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4760 value = 0x2120; 4761 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4762 BWN_PHY_WRITE(mac, offset, value); 4763 value += 0x202; 4764 } 4765 } 4766 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4767 if (phy->rf_ver == 0x2050) 4768 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4769 4770 if (phy->gmode || phy->rev >= 2) { 4771 if (phy->rf_ver == 0x2050) { 4772 BWN_RF_SET(mac, 0x007a, 0x0020); 4773 BWN_RF_SET(mac, 0x0051, 0x0004); 4774 } 4775 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4776 4777 BWN_PHY_SET(mac, 0x0802, 0x0100); 4778 BWN_PHY_SET(mac, 0x042b, 0x2000); 4779 4780 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4781 4782 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4783 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4784 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4785 } 4786 4787 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4788 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4789 4790 if (phy->analog == 1) { 4791 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4792 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4793 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4794 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4795 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4796 } else 4797 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4798 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4799 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4800 4801 if (phy->analog == 1) 4802 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4803 else 4804 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4805 4806 if (phy->analog == 0) 4807 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4808 4809 old_channel = phy->chan; 4810 bwn_phy_g_switch_chan(mac, 7, 0); 4811 4812 if (phy->rf_ver != 0x2050) { 4813 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4814 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4815 } 4816 4817 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4818 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4819 4820 if (phy->rf_ver == 0x2050) { 4821 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4822 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4823 } 4824 4825 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4826 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4827 BWN_RF_SET(mac, 0x007a, 0x0007); 4828 4829 bwn_phy_g_switch_chan(mac, old_channel, 0); 4830 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4831 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4832 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4833 4834 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4835 pg->pg_txctl); 4836 4837 if (phy->rf_ver == 0x2050) 4838 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4839 4840 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4841 } 4842 4843 static void 4844 bwn_loopback_calcgain(struct bwn_mac *mac) 4845 { 4846 struct bwn_phy *phy = &mac->mac_phy; 4847 struct bwn_phy_g *pg = &phy->phy_g; 4848 struct bwn_softc *sc = mac->mac_sc; 4849 uint16_t backup_phy[16] = { 0 }; 4850 uint16_t backup_radio[3]; 4851 uint16_t backup_bband; 4852 uint16_t i, j, loop_i_max; 4853 uint16_t trsw_rx; 4854 uint16_t loop1_outer_done, loop1_inner_done; 4855 4856 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4857 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4858 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4859 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4860 if (phy->rev != 1) { 4861 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4862 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4863 } 4864 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4865 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4866 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4867 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4868 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4869 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4870 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4871 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4872 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4873 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4874 backup_bband = pg->pg_bbatt.att; 4875 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4876 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4877 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4878 4879 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4880 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4881 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4882 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4883 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4884 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4885 if (phy->rev != 1) { 4886 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4887 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4888 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4889 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4890 } 4891 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4892 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4893 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4894 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4895 4896 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4897 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4898 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4899 4900 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4901 if (phy->rev != 1) { 4902 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4903 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4904 } 4905 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4906 4907 if (phy->rf_rev == 8) 4908 BWN_RF_WRITE(mac, 0x43, 0x000f); 4909 else { 4910 BWN_RF_WRITE(mac, 0x52, 0); 4911 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4912 } 4913 bwn_phy_g_set_bbatt(mac, 11); 4914 4915 if (phy->rev >= 3) 4916 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4917 else 4918 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4919 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4920 4921 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 4922 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 4923 4924 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 4925 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 4926 4927 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 4928 if (phy->rev >= 7) { 4929 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 4930 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 4931 } 4932 } 4933 BWN_RF_MASK(mac, 0x7a, 0x00f7); 4934 4935 j = 0; 4936 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 4937 for (i = 0; i < loop_i_max; i++) { 4938 for (j = 0; j < 16; j++) { 4939 BWN_RF_WRITE(mac, 0x43, i); 4940 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 4941 (j << 8)); 4942 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4943 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4944 DELAY(20); 4945 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4946 goto done0; 4947 } 4948 } 4949 done0: 4950 loop1_outer_done = i; 4951 loop1_inner_done = j; 4952 if (j >= 8) { 4953 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 4954 trsw_rx = 0x1b; 4955 for (j = j - 8; j < 16; j++) { 4956 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 4957 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4958 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4959 DELAY(20); 4960 trsw_rx -= 3; 4961 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4962 goto done1; 4963 } 4964 } else 4965 trsw_rx = 0x18; 4966 done1: 4967 4968 if (phy->rev != 1) { 4969 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 4970 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 4971 } 4972 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 4973 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 4974 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 4975 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 4976 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 4977 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 4978 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 4979 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 4980 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 4981 4982 bwn_phy_g_set_bbatt(mac, backup_bband); 4983 4984 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 4985 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 4986 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 4987 4988 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 4989 DELAY(10); 4990 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 4991 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 4992 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 4993 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 4994 4995 pg->pg_max_lb_gain = 4996 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 4997 pg->pg_trsw_rx_gain = trsw_rx * 2; 4998 } 4999 5000 static uint16_t 5001 bwn_rf_init_bcm2050(struct bwn_mac *mac) 5002 { 5003 struct bwn_phy *phy = &mac->mac_phy; 5004 uint32_t tmp1 = 0, tmp2 = 0; 5005 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5006 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5007 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5008 static const uint8_t rcc_table[] = { 5009 0x02, 0x03, 0x01, 0x0f, 5010 0x06, 0x07, 0x05, 0x0f, 5011 0x0a, 0x0b, 0x09, 0x0f, 5012 0x0e, 0x0f, 0x0d, 0x0f, 5013 }; 5014 5015 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5016 rfoverval = rfover = cck3 = 0; 5017 radio0 = BWN_RF_READ(mac, 0x43); 5018 radio1 = BWN_RF_READ(mac, 0x51); 5019 radio2 = BWN_RF_READ(mac, 0x52); 5020 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5021 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5022 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5023 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5024 5025 if (phy->type == BWN_PHYTYPE_B) { 5026 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5027 reg0 = BWN_READ_2(mac, 0x3ec); 5028 5029 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5030 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5031 } else if (phy->gmode || phy->rev >= 2) { 5032 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5033 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5034 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5035 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5036 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5037 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5038 5039 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5040 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5041 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5042 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5043 if (BWN_HAS_LOOPBACK(phy)) { 5044 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5045 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5046 if (phy->rev >= 3) 5047 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5048 else 5049 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5050 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5051 } 5052 5053 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5054 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5055 BWN_LPD(0, 1, 1))); 5056 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5057 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5058 } 5059 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5060 5061 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5062 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5063 reg1 = BWN_READ_2(mac, 0x3e6); 5064 reg2 = BWN_READ_2(mac, 0x3f4); 5065 5066 if (phy->analog == 0) 5067 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5068 else { 5069 if (phy->analog >= 2) 5070 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5071 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5072 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5073 } 5074 5075 reg = BWN_RF_READ(mac, 0x60); 5076 index = (reg & 0x001e) >> 1; 5077 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5078 5079 if (phy->type == BWN_PHYTYPE_B) 5080 BWN_RF_WRITE(mac, 0x78, 0x26); 5081 if (phy->gmode || phy->rev >= 2) { 5082 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5083 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5084 BWN_LPD(0, 1, 1))); 5085 } 5086 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5087 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5088 if (phy->gmode || phy->rev >= 2) { 5089 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5090 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5091 BWN_LPD(0, 0, 1))); 5092 } 5093 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5094 BWN_RF_SET(mac, 0x51, 0x0004); 5095 if (phy->rf_rev == 8) 5096 BWN_RF_WRITE(mac, 0x43, 0x1f); 5097 else { 5098 BWN_RF_WRITE(mac, 0x52, 0); 5099 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5100 } 5101 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5102 5103 for (i = 0; i < 16; i++) { 5104 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5105 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5106 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5107 if (phy->gmode || phy->rev >= 2) { 5108 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5109 bwn_rf_2050_rfoverval(mac, 5110 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5111 } 5112 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5113 DELAY(10); 5114 if (phy->gmode || phy->rev >= 2) { 5115 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5116 bwn_rf_2050_rfoverval(mac, 5117 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5118 } 5119 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5120 DELAY(10); 5121 if (phy->gmode || phy->rev >= 2) { 5122 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5123 bwn_rf_2050_rfoverval(mac, 5124 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5125 } 5126 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5127 DELAY(20); 5128 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5129 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5130 if (phy->gmode || phy->rev >= 2) { 5131 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5132 bwn_rf_2050_rfoverval(mac, 5133 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5134 } 5135 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5136 } 5137 DELAY(10); 5138 5139 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5140 tmp1++; 5141 tmp1 >>= 9; 5142 5143 for (i = 0; i < 16; i++) { 5144 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5145 BWN_RF_WRITE(mac, 0x78, radio78); 5146 DELAY(10); 5147 for (j = 0; j < 16; j++) { 5148 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5149 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5150 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5151 if (phy->gmode || phy->rev >= 2) { 5152 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5153 bwn_rf_2050_rfoverval(mac, 5154 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5155 } 5156 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5157 DELAY(10); 5158 if (phy->gmode || phy->rev >= 2) { 5159 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5160 bwn_rf_2050_rfoverval(mac, 5161 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5162 } 5163 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5164 DELAY(10); 5165 if (phy->gmode || phy->rev >= 2) { 5166 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5167 bwn_rf_2050_rfoverval(mac, 5168 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5169 } 5170 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5171 DELAY(10); 5172 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5173 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5174 if (phy->gmode || phy->rev >= 2) { 5175 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5176 bwn_rf_2050_rfoverval(mac, 5177 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5178 } 5179 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5180 } 5181 tmp2++; 5182 tmp2 >>= 8; 5183 if (tmp1 < tmp2) 5184 break; 5185 } 5186 5187 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5188 BWN_RF_WRITE(mac, 0x51, radio1); 5189 BWN_RF_WRITE(mac, 0x52, radio2); 5190 BWN_RF_WRITE(mac, 0x43, radio0); 5191 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5192 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5193 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5194 BWN_WRITE_2(mac, 0x3e6, reg1); 5195 if (phy->analog != 0) 5196 BWN_WRITE_2(mac, 0x3f4, reg2); 5197 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5198 bwn_spu_workaround(mac, phy->chan); 5199 if (phy->type == BWN_PHYTYPE_B) { 5200 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5201 BWN_WRITE_2(mac, 0x3ec, reg0); 5202 } else if (phy->gmode) { 5203 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5204 BWN_READ_2(mac, BWN_PHY_RADIO) 5205 & 0x7fff); 5206 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5207 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5208 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5209 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5210 analogoverval); 5211 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5212 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5213 if (BWN_HAS_LOOPBACK(phy)) { 5214 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5215 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5216 } 5217 } 5218 5219 return ((i > 15) ? radio78 : rcc); 5220 } 5221 5222 static void 5223 bwn_phy_init_b6(struct bwn_mac *mac) 5224 { 5225 struct bwn_phy *phy = &mac->mac_phy; 5226 struct bwn_phy_g *pg = &phy->phy_g; 5227 struct bwn_softc *sc = mac->mac_sc; 5228 uint16_t offset, val; 5229 uint8_t old_channel; 5230 5231 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5232 ("%s:%d: fail", __func__, __LINE__)); 5233 5234 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5235 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5236 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5237 BWN_RF_WRITE(mac, 0x51, 0x37); 5238 BWN_RF_WRITE(mac, 0x52, 0x70); 5239 BWN_RF_WRITE(mac, 0x53, 0xb3); 5240 BWN_RF_WRITE(mac, 0x54, 0x9b); 5241 BWN_RF_WRITE(mac, 0x5a, 0x88); 5242 BWN_RF_WRITE(mac, 0x5b, 0x88); 5243 BWN_RF_WRITE(mac, 0x5d, 0x88); 5244 BWN_RF_WRITE(mac, 0x5e, 0x88); 5245 BWN_RF_WRITE(mac, 0x7d, 0x88); 5246 bwn_hf_write(mac, 5247 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5248 } 5249 if (phy->rf_rev == 8) { 5250 BWN_RF_WRITE(mac, 0x51, 0); 5251 BWN_RF_WRITE(mac, 0x52, 0x40); 5252 BWN_RF_WRITE(mac, 0x53, 0xb7); 5253 BWN_RF_WRITE(mac, 0x54, 0x98); 5254 BWN_RF_WRITE(mac, 0x5a, 0x88); 5255 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5256 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5257 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5258 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5259 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5260 } else { 5261 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5262 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5263 } 5264 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5265 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5266 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5267 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5268 } 5269 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5270 BWN_PHY_WRITE(mac, offset, val); 5271 val -= 0x0202; 5272 } 5273 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5274 BWN_PHY_WRITE(mac, offset, val); 5275 val -= 0x0202; 5276 } 5277 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5278 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5279 val += 0x0202; 5280 } 5281 if (phy->type == BWN_PHYTYPE_G) { 5282 BWN_RF_SET(mac, 0x007a, 0x0020); 5283 BWN_RF_SET(mac, 0x0051, 0x0004); 5284 BWN_PHY_SET(mac, 0x0802, 0x0100); 5285 BWN_PHY_SET(mac, 0x042b, 0x2000); 5286 BWN_PHY_WRITE(mac, 0x5b, 0); 5287 BWN_PHY_WRITE(mac, 0x5c, 0); 5288 } 5289 5290 old_channel = phy->chan; 5291 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5292 5293 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5294 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5295 DELAY(40); 5296 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5297 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5298 BWN_RF_WRITE(mac, 0x50, 0x20); 5299 } 5300 if (phy->rf_rev <= 2) { 5301 BWN_RF_WRITE(mac, 0x7c, 0x20); 5302 BWN_RF_WRITE(mac, 0x5a, 0x70); 5303 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5304 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5305 } 5306 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5307 5308 bwn_phy_g_switch_chan(mac, old_channel, 0); 5309 5310 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5311 if (phy->rf_rev >= 6) 5312 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5313 else 5314 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5315 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5316 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5317 pg->pg_txctl); 5318 if (phy->rf_rev <= 5) 5319 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5320 if (phy->rf_rev <= 2) 5321 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5322 5323 if (phy->analog == 4) { 5324 BWN_WRITE_2(mac, 0x3e4, 9); 5325 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5326 } else 5327 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5328 if (phy->type == BWN_PHYTYPE_B) 5329 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5330 else if (phy->type == BWN_PHYTYPE_G) 5331 BWN_WRITE_2(mac, 0x03e6, 0x0); 5332 } 5333 5334 static void 5335 bwn_phy_init_a(struct bwn_mac *mac) 5336 { 5337 struct bwn_phy *phy = &mac->mac_phy; 5338 struct bwn_softc *sc = mac->mac_sc; 5339 5340 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5341 ("%s:%d: fail", __func__, __LINE__)); 5342 5343 if (phy->rev >= 6) { 5344 if (phy->type == BWN_PHYTYPE_A) 5345 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5346 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5347 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5348 else 5349 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5350 } 5351 5352 bwn_wa_init(mac); 5353 5354 if (phy->type == BWN_PHYTYPE_G && 5355 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5356 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5357 } 5358 5359 static void 5360 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5361 { 5362 int i; 5363 5364 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5365 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5366 } 5367 5368 static void 5369 bwn_wa_agc(struct bwn_mac *mac) 5370 { 5371 struct bwn_phy *phy = &mac->mac_phy; 5372 5373 if (phy->rev == 1) { 5374 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5375 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5376 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5377 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5378 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5379 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5380 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5381 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5382 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5383 } else { 5384 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5385 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5386 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5387 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5388 } 5389 5390 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5391 0x5700); 5392 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5393 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5394 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5395 BWN_RF_SET(mac, 0x7a, 0x0008); 5396 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5397 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5398 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5399 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5400 if (phy->rev == 1) 5401 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5402 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5403 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5404 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5405 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5406 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5407 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5408 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5409 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5410 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5411 if (phy->rev == 1) { 5412 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5413 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5414 } else { 5415 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5416 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5417 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5418 if (phy->rev >= 6) { 5419 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5420 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5421 (uint16_t)~0xf000, 0x3000); 5422 } 5423 } 5424 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5425 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5426 if (phy->rev == 1) { 5427 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5428 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5429 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5430 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5431 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5432 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5433 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5434 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5435 } else { 5436 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5437 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5438 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5439 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5440 } 5441 if (phy->rev >= 6) { 5442 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5443 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5444 } 5445 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5446 } 5447 5448 static void 5449 bwn_wa_grev1(struct bwn_mac *mac) 5450 { 5451 struct bwn_phy *phy = &mac->mac_phy; 5452 int i; 5453 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5454 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5455 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5456 5457 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5458 5459 /* init CRSTHRES and ANTDWELL */ 5460 if (phy->rev == 1) { 5461 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5462 } else if (phy->rev == 2) { 5463 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5464 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5465 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5466 } else { 5467 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5468 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5469 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5470 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5471 } 5472 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5473 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5474 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5475 5476 /* XXX support PHY-A??? */ 5477 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5478 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5479 bwn_tab_finefreqg[i]); 5480 5481 /* XXX support PHY-A??? */ 5482 if (phy->rev == 1) 5483 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5484 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5485 bwn_tab_noise_g1[i]); 5486 else 5487 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5488 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5489 bwn_tab_noise_g2[i]); 5490 5491 5492 for (i = 0; i < N(bwn_tab_rotor); i++) 5493 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5494 bwn_tab_rotor[i]); 5495 5496 /* XXX support PHY-A??? */ 5497 if (phy->rev >= 6) { 5498 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5499 BWN_PHY_ENCORE_EN) 5500 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5501 else 5502 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5503 } else 5504 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5505 5506 for (i = 0; i < N(bwn_tab_retard); i++) 5507 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5508 bwn_tab_retard[i]); 5509 5510 if (phy->rev == 1) { 5511 for (i = 0; i < 16; i++) 5512 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5513 i, 0x0020); 5514 } else { 5515 for (i = 0; i < 32; i++) 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5517 } 5518 5519 bwn_wa_agc(mac); 5520 } 5521 5522 static void 5523 bwn_wa_grev26789(struct bwn_mac *mac) 5524 { 5525 struct bwn_phy *phy = &mac->mac_phy; 5526 int i; 5527 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5528 uint16_t ofdmrev; 5529 5530 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5531 5532 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5533 5534 /* init CRSTHRES and ANTDWELL */ 5535 if (phy->rev == 1) 5536 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5537 else if (phy->rev == 2) { 5538 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5539 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5540 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5541 } else { 5542 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5543 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5544 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5545 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5546 } 5547 5548 for (i = 0; i < 64; i++) 5549 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5550 5551 /* XXX support PHY-A??? */ 5552 if (phy->rev == 1) 5553 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5554 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5555 bwn_tab_noise_g1[i]); 5556 else 5557 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5559 bwn_tab_noise_g2[i]); 5560 5561 /* XXX support PHY-A??? */ 5562 if (phy->rev >= 6) { 5563 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5564 BWN_PHY_ENCORE_EN) 5565 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5566 else 5567 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5568 } else 5569 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5570 5571 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5573 bwn_tab_sigmasqr2[i]); 5574 5575 if (phy->rev == 1) { 5576 for (i = 0; i < 16; i++) 5577 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5578 0x0020); 5579 } else { 5580 for (i = 0; i < 32; i++) 5581 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5582 } 5583 5584 bwn_wa_agc(mac); 5585 5586 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5587 if (ofdmrev > 2) { 5588 if (phy->type == BWN_PHYTYPE_A) 5589 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5590 else 5591 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5592 } else { 5593 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5594 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5595 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5596 } 5597 5598 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5599 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5600 } 5601 5602 static void 5603 bwn_wa_init(struct bwn_mac *mac) 5604 { 5605 struct bwn_phy *phy = &mac->mac_phy; 5606 struct bwn_softc *sc = mac->mac_sc; 5607 5608 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5609 5610 switch (phy->rev) { 5611 case 1: 5612 bwn_wa_grev1(mac); 5613 break; 5614 case 2: 5615 case 6: 5616 case 7: 5617 case 8: 5618 case 9: 5619 bwn_wa_grev26789(mac); 5620 break; 5621 default: 5622 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5623 } 5624 5625 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5626 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5627 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5628 if (phy->rev < 2) { 5629 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5630 0x0002); 5631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5632 0x0001); 5633 } else { 5634 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5635 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5636 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5637 BWN_BFL_EXTLNA) && 5638 (phy->rev >= 7)) { 5639 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5640 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5641 0x0020, 0x0001); 5642 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5643 0x0021, 0x0001); 5644 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5645 0x0022, 0x0001); 5646 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5647 0x0023, 0x0000); 5648 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5649 0x0000, 0x0000); 5650 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5651 0x0003, 0x0002); 5652 } 5653 } 5654 } 5655 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5656 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5657 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5658 } 5659 5660 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5661 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5662 } 5663 5664 static void 5665 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5666 uint16_t value) 5667 { 5668 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5669 uint16_t addr; 5670 5671 addr = table + offset; 5672 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5673 (addr - 1 != pg->pg_ofdmtab_addr)) { 5674 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5675 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5676 } 5677 pg->pg_ofdmtab_addr = addr; 5678 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5679 } 5680 5681 static void 5682 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5683 uint32_t value) 5684 { 5685 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5686 uint16_t addr; 5687 5688 addr = table + offset; 5689 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5690 (addr - 1 != pg->pg_ofdmtab_addr)) { 5691 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5692 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5693 } 5694 pg->pg_ofdmtab_addr = addr; 5695 5696 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5697 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5698 } 5699 5700 static void 5701 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5702 uint16_t value) 5703 { 5704 5705 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5706 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5707 } 5708 5709 static void 5710 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5711 { 5712 struct bwn_phy *phy = &mac->mac_phy; 5713 struct bwn_softc *sc = mac->mac_sc; 5714 unsigned int i, max_loop; 5715 uint16_t value; 5716 uint32_t buffer[5] = { 5717 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5718 }; 5719 5720 if (ofdm) { 5721 max_loop = 0x1e; 5722 buffer[0] = 0x000201cc; 5723 } else { 5724 max_loop = 0xfa; 5725 buffer[0] = 0x000b846e; 5726 } 5727 5728 for (i = 0; i < 5; i++) 5729 bwn_ram_write(mac, i * 4, buffer[i]); 5730 5731 BWN_WRITE_2(mac, 0x0568, 0x0000); 5732 BWN_WRITE_2(mac, 0x07c0, 5733 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5734 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5735 BWN_WRITE_2(mac, 0x050c, value); 5736 if (phy->type == BWN_PHYTYPE_LP) 5737 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5738 BWN_WRITE_2(mac, 0x0508, 0x0000); 5739 BWN_WRITE_2(mac, 0x050a, 0x0000); 5740 BWN_WRITE_2(mac, 0x054c, 0x0000); 5741 BWN_WRITE_2(mac, 0x056a, 0x0014); 5742 BWN_WRITE_2(mac, 0x0568, 0x0826); 5743 BWN_WRITE_2(mac, 0x0500, 0x0000); 5744 if (phy->type == BWN_PHYTYPE_LP) 5745 BWN_WRITE_2(mac, 0x0502, 0x0050); 5746 else 5747 BWN_WRITE_2(mac, 0x0502, 0x0030); 5748 5749 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5750 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5751 for (i = 0x00; i < max_loop; i++) { 5752 value = BWN_READ_2(mac, 0x050e); 5753 if (value & 0x0080) 5754 break; 5755 DELAY(10); 5756 } 5757 for (i = 0x00; i < 0x0a; i++) { 5758 value = BWN_READ_2(mac, 0x050e); 5759 if (value & 0x0400) 5760 break; 5761 DELAY(10); 5762 } 5763 for (i = 0x00; i < 0x19; i++) { 5764 value = BWN_READ_2(mac, 0x0690); 5765 if (!(value & 0x0100)) 5766 break; 5767 DELAY(10); 5768 } 5769 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5770 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5771 } 5772 5773 static void 5774 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5775 { 5776 uint32_t macctl; 5777 5778 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5779 5780 macctl = BWN_READ_4(mac, BWN_MACCTL); 5781 if (macctl & BWN_MACCTL_BIGENDIAN) 5782 kprintf("TODO: need swap\n"); 5783 5784 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5785 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5786 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5787 } 5788 5789 static void 5790 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5791 { 5792 uint16_t value; 5793 5794 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5795 ("%s:%d: fail", __func__, __LINE__)); 5796 5797 value = (uint8_t) (ctl->q); 5798 value |= ((uint8_t) (ctl->i)) << 8; 5799 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5800 } 5801 5802 static uint16_t 5803 bwn_lo_calcfeed(struct bwn_mac *mac, 5804 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5805 { 5806 struct bwn_phy *phy = &mac->mac_phy; 5807 struct bwn_softc *sc = mac->mac_sc; 5808 uint16_t rfover; 5809 uint16_t feedthrough; 5810 5811 if (phy->gmode) { 5812 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5813 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5814 5815 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5816 ("%s:%d: fail", __func__, __LINE__)); 5817 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5818 ("%s:%d: fail", __func__, __LINE__)); 5819 5820 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5821 5822 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5823 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5824 phy->rev > 6) 5825 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5826 5827 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5828 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5829 DELAY(10); 5830 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5831 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5832 DELAY(10); 5833 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5834 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5835 DELAY(10); 5836 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5837 } else { 5838 pga |= BWN_PHY_PGACTL_UNKNOWN; 5839 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5840 DELAY(10); 5841 pga |= BWN_PHY_PGACTL_LOWBANDW; 5842 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5843 DELAY(10); 5844 pga |= BWN_PHY_PGACTL_LPF; 5845 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5846 } 5847 DELAY(21); 5848 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5849 5850 return (feedthrough); 5851 } 5852 5853 static uint16_t 5854 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5855 uint16_t *value, uint16_t *pad_mix_gain) 5856 { 5857 struct bwn_phy *phy = &mac->mac_phy; 5858 uint16_t reg, v, padmix; 5859 5860 if (phy->type == BWN_PHYTYPE_B) { 5861 v = 0x30; 5862 if (phy->rf_rev <= 5) { 5863 reg = 0x43; 5864 padmix = 0; 5865 } else { 5866 reg = 0x52; 5867 padmix = 5; 5868 } 5869 } else { 5870 if (phy->rev >= 2 && phy->rf_rev == 8) { 5871 reg = 0x43; 5872 v = 0x10; 5873 padmix = 2; 5874 } else { 5875 reg = 0x52; 5876 v = 0x30; 5877 padmix = 5; 5878 } 5879 } 5880 if (value) 5881 *value = v; 5882 if (pad_mix_gain) 5883 *pad_mix_gain = padmix; 5884 5885 return (reg); 5886 } 5887 5888 static void 5889 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5890 { 5891 struct bwn_phy *phy = &mac->mac_phy; 5892 struct bwn_phy_g *pg = &phy->phy_g; 5893 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5894 uint16_t reg, mask; 5895 uint16_t trsw_rx, pga; 5896 uint16_t rf_pctl_reg; 5897 5898 static const uint8_t tx_bias_values[] = { 5899 0x09, 0x08, 0x0a, 0x01, 0x00, 5900 0x02, 0x05, 0x04, 0x06, 5901 }; 5902 static const uint8_t tx_magn_values[] = { 5903 0x70, 0x40, 5904 }; 5905 5906 if (!BWN_HAS_LOOPBACK(phy)) { 5907 rf_pctl_reg = 6; 5908 trsw_rx = 2; 5909 pga = 0; 5910 } else { 5911 int lb_gain; 5912 5913 trsw_rx = 0; 5914 lb_gain = pg->pg_max_lb_gain / 2; 5915 if (lb_gain > 10) { 5916 rf_pctl_reg = 0; 5917 pga = abs(10 - lb_gain) / 6; 5918 pga = MIN(MAX(pga, 0), 15); 5919 } else { 5920 int cmp_val; 5921 int tmp; 5922 5923 pga = 0; 5924 cmp_val = 0x24; 5925 if ((phy->rev >= 2) && 5926 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 5927 cmp_val = 0x3c; 5928 tmp = lb_gain; 5929 if ((10 - lb_gain) < cmp_val) 5930 tmp = (10 - lb_gain); 5931 if (tmp < 0) 5932 tmp += 6; 5933 else 5934 tmp += 3; 5935 cmp_val /= 4; 5936 tmp /= 4; 5937 if (tmp >= cmp_val) 5938 rf_pctl_reg = cmp_val; 5939 else 5940 rf_pctl_reg = tmp; 5941 } 5942 } 5943 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 5944 bwn_phy_g_set_bbatt(mac, 2); 5945 5946 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 5947 mask = ~mask; 5948 BWN_RF_MASK(mac, reg, mask); 5949 5950 if (BWN_HAS_TXMAG(phy)) { 5951 int i, j; 5952 int feedthrough; 5953 int min_feedth = 0xffff; 5954 uint8_t tx_magn, tx_bias; 5955 5956 for (i = 0; i < N(tx_magn_values); i++) { 5957 tx_magn = tx_magn_values[i]; 5958 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 5959 for (j = 0; j < N(tx_bias_values); j++) { 5960 tx_bias = tx_bias_values[j]; 5961 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 5962 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 5963 trsw_rx); 5964 if (feedthrough < min_feedth) { 5965 lo->tx_bias = tx_bias; 5966 lo->tx_magn = tx_magn; 5967 min_feedth = feedthrough; 5968 } 5969 if (lo->tx_bias == 0) 5970 break; 5971 } 5972 BWN_RF_WRITE(mac, 0x52, 5973 (BWN_RF_READ(mac, 0x52) 5974 & 0xff00) | lo->tx_bias | lo-> 5975 tx_magn); 5976 } 5977 } else { 5978 lo->tx_magn = 0; 5979 lo->tx_bias = 0; 5980 BWN_RF_MASK(mac, 0x52, 0xfff0); 5981 } 5982 5983 BWN_GETTIME(lo->txctl_measured_time); 5984 } 5985 5986 static void 5987 bwn_lo_get_powervector(struct bwn_mac *mac) 5988 { 5989 struct bwn_phy *phy = &mac->mac_phy; 5990 struct bwn_phy_g *pg = &phy->phy_g; 5991 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5992 int i; 5993 uint64_t tmp; 5994 uint64_t power_vector = 0; 5995 5996 for (i = 0; i < 8; i += 2) { 5997 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 5998 power_vector |= (tmp << (i * 8)); 5999 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6000 } 6001 if (power_vector) 6002 lo->power_vector = power_vector; 6003 6004 BWN_GETTIME(lo->pwr_vec_read_time); 6005 } 6006 6007 static void 6008 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6009 int use_trsw_rx) 6010 { 6011 struct bwn_phy *phy = &mac->mac_phy; 6012 struct bwn_phy_g *pg = &phy->phy_g; 6013 uint16_t tmp; 6014 6015 if (max_rx_gain < 0) 6016 max_rx_gain = 0; 6017 6018 if (BWN_HAS_LOOPBACK(phy)) { 6019 int trsw_rx = 0; 6020 int trsw_rx_gain; 6021 6022 if (use_trsw_rx) { 6023 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6024 if (max_rx_gain >= trsw_rx_gain) { 6025 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6026 trsw_rx = 0x20; 6027 } 6028 } else 6029 trsw_rx_gain = max_rx_gain; 6030 if (trsw_rx_gain < 9) { 6031 pg->pg_lna_lod_gain = 0; 6032 } else { 6033 pg->pg_lna_lod_gain = 1; 6034 trsw_rx_gain -= 8; 6035 } 6036 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6037 pg->pg_pga_gain = trsw_rx_gain / 3; 6038 if (pg->pg_pga_gain >= 5) { 6039 pg->pg_pga_gain -= 5; 6040 pg->pg_lna_gain = 2; 6041 } else 6042 pg->pg_lna_gain = 0; 6043 } else { 6044 pg->pg_lna_gain = 0; 6045 pg->pg_trsw_rx_gain = 0x20; 6046 if (max_rx_gain >= 0x14) { 6047 pg->pg_lna_lod_gain = 1; 6048 pg->pg_pga_gain = 2; 6049 } else if (max_rx_gain >= 0x12) { 6050 pg->pg_lna_lod_gain = 1; 6051 pg->pg_pga_gain = 1; 6052 } else if (max_rx_gain >= 0xf) { 6053 pg->pg_lna_lod_gain = 1; 6054 pg->pg_pga_gain = 0; 6055 } else { 6056 pg->pg_lna_lod_gain = 0; 6057 pg->pg_pga_gain = 0; 6058 } 6059 } 6060 6061 tmp = BWN_RF_READ(mac, 0x7a); 6062 if (pg->pg_lna_lod_gain == 0) 6063 tmp &= ~0x0008; 6064 else 6065 tmp |= 0x0008; 6066 BWN_RF_WRITE(mac, 0x7a, tmp); 6067 } 6068 6069 static void 6070 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6071 { 6072 struct bwn_phy *phy = &mac->mac_phy; 6073 struct bwn_phy_g *pg = &phy->phy_g; 6074 struct bwn_softc *sc = mac->mac_sc; 6075 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6076 struct timespec ts; 6077 uint16_t tmp; 6078 6079 if (bwn_has_hwpctl(mac)) { 6080 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6081 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6082 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6083 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6084 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6085 6086 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6087 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6088 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6089 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6090 } 6091 if (phy->type == BWN_PHYTYPE_B && 6092 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6093 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6094 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6095 } 6096 if (phy->rev >= 2) { 6097 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6098 sav->phy_analogoverval = 6099 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6100 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6101 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6102 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6103 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6104 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6105 6106 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6107 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6108 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6109 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6110 if (phy->type == BWN_PHYTYPE_G) { 6111 if ((phy->rev >= 7) && 6112 (siba_sprom_get_bf_lo(sc->sc_dev) & 6113 BWN_BFL_EXTLNA)) { 6114 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6115 } else { 6116 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6117 } 6118 } else { 6119 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6120 } 6121 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6122 } 6123 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6124 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6125 sav->rf0 = BWN_RF_READ(mac, 0x43); 6126 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6127 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6128 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6129 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6130 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6131 6132 if (!BWN_HAS_TXMAG(phy)) { 6133 sav->rf2 = BWN_RF_READ(mac, 0x52); 6134 sav->rf2 &= 0x00f0; 6135 } 6136 if (phy->type == BWN_PHYTYPE_B) { 6137 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6138 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6139 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6140 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6141 } else { 6142 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6143 | 0x8000); 6144 } 6145 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6146 & 0xf000); 6147 6148 tmp = 6149 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6150 BWN_PHY_WRITE(mac, tmp, 0x007f); 6151 6152 tmp = sav->phy_syncctl; 6153 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6154 tmp = sav->rf1; 6155 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6156 6157 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6158 if (phy->type == BWN_PHYTYPE_G || 6159 (phy->type == BWN_PHYTYPE_B && 6160 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6161 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6162 } else 6163 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6164 if (phy->rev >= 2) 6165 bwn_dummy_transmission(mac, 0, 1); 6166 bwn_phy_g_switch_chan(mac, 6, 0); 6167 BWN_RF_READ(mac, 0x51); 6168 if (phy->type == BWN_PHYTYPE_G) 6169 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6170 6171 nanouptime(&ts); 6172 if (time_before(lo->txctl_measured_time, 6173 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6174 bwn_lo_measure_txctl_values(mac); 6175 6176 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6177 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6178 else { 6179 if (phy->type == BWN_PHYTYPE_B) 6180 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6181 else 6182 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6183 } 6184 } 6185 6186 static void 6187 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6188 { 6189 struct bwn_phy *phy = &mac->mac_phy; 6190 struct bwn_phy_g *pg = &phy->phy_g; 6191 uint16_t tmp; 6192 6193 if (phy->rev >= 2) { 6194 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6195 tmp = (pg->pg_pga_gain << 8); 6196 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6197 DELAY(5); 6198 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6199 DELAY(2); 6200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6201 } else { 6202 tmp = (pg->pg_pga_gain | 0xefa0); 6203 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6204 } 6205 if (phy->type == BWN_PHYTYPE_G) { 6206 if (phy->rev >= 3) 6207 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6208 else 6209 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6210 if (phy->rev >= 2) 6211 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6212 else 6213 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6214 } 6215 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6216 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6217 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6218 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6219 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6220 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6221 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6222 if (!BWN_HAS_TXMAG(phy)) { 6223 tmp = sav->rf2; 6224 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6225 } 6226 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6227 if (phy->type == BWN_PHYTYPE_B && 6228 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6229 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6231 } 6232 if (phy->rev >= 2) { 6233 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6234 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6235 sav->phy_analogoverval); 6236 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6237 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6238 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6239 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6240 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6241 } 6242 if (bwn_has_hwpctl(mac)) { 6243 tmp = (sav->phy_lomask & 0xbfff); 6244 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6245 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6246 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6248 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6249 } 6250 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6251 } 6252 6253 static int 6254 bwn_lo_probe_loctl(struct bwn_mac *mac, 6255 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6256 { 6257 struct bwn_phy *phy = &mac->mac_phy; 6258 struct bwn_phy_g *pg = &phy->phy_g; 6259 struct bwn_loctl orig, test; 6260 struct bwn_loctl prev = { -100, -100 }; 6261 static const struct bwn_loctl modifiers[] = { 6262 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6263 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6264 }; 6265 int begin, end, lower = 0, i; 6266 uint16_t feedth; 6267 6268 if (d->curstate == 0) { 6269 begin = 1; 6270 end = 8; 6271 } else if (d->curstate % 2 == 0) { 6272 begin = d->curstate - 1; 6273 end = d->curstate + 1; 6274 } else { 6275 begin = d->curstate - 2; 6276 end = d->curstate + 2; 6277 } 6278 if (begin < 1) 6279 begin += 8; 6280 if (end > 8) 6281 end -= 8; 6282 6283 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6284 i = begin; 6285 d->curstate = i; 6286 while (1) { 6287 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6288 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6289 test.i += modifiers[i - 1].i * d->multipler; 6290 test.q += modifiers[i - 1].q * d->multipler; 6291 if ((test.i != prev.i || test.q != prev.q) && 6292 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6293 bwn_lo_write(mac, &test); 6294 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6295 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6296 if (feedth < d->feedth) { 6297 memcpy(probe, &test, 6298 sizeof(struct bwn_loctl)); 6299 lower = 1; 6300 d->feedth = feedth; 6301 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6302 break; 6303 } 6304 } 6305 memcpy(&prev, &test, sizeof(prev)); 6306 if (i == end) 6307 break; 6308 if (i == 8) 6309 i = 1; 6310 else 6311 i++; 6312 d->curstate = i; 6313 } 6314 6315 return (lower); 6316 } 6317 6318 static void 6319 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6320 { 6321 struct bwn_phy *phy = &mac->mac_phy; 6322 struct bwn_phy_g *pg = &phy->phy_g; 6323 struct bwn_lo_g_sm d; 6324 struct bwn_loctl probe; 6325 int lower, repeat, cnt = 0; 6326 uint16_t feedth; 6327 6328 d.nmeasure = 0; 6329 d.multipler = 1; 6330 if (BWN_HAS_LOOPBACK(phy)) 6331 d.multipler = 3; 6332 6333 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6334 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6335 6336 do { 6337 bwn_lo_write(mac, &d.loctl); 6338 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6339 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6340 if (feedth < 0x258) { 6341 if (feedth >= 0x12c) 6342 *rxgain += 6; 6343 else 6344 *rxgain += 3; 6345 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6346 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6347 } 6348 d.feedth = feedth; 6349 d.curstate = 0; 6350 do { 6351 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6352 ("%s:%d: fail", __func__, __LINE__)); 6353 memcpy(&probe, &d.loctl, 6354 sizeof(struct bwn_loctl)); 6355 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6356 if (!lower) 6357 break; 6358 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6359 break; 6360 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6361 d.nmeasure++; 6362 } while (d.nmeasure < 24); 6363 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6364 6365 if (BWN_HAS_LOOPBACK(phy)) { 6366 if (d.feedth > 0x1194) 6367 *rxgain -= 6; 6368 else if (d.feedth < 0x5dc) 6369 *rxgain += 3; 6370 if (cnt == 0) { 6371 if (d.feedth <= 0x5dc) { 6372 d.multipler = 1; 6373 cnt++; 6374 } else 6375 d.multipler = 2; 6376 } else if (cnt == 2) 6377 d.multipler = 1; 6378 } 6379 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6380 } while (++cnt < repeat); 6381 } 6382 6383 static struct bwn_lo_calib * 6384 bwn_lo_calibset(struct bwn_mac *mac, 6385 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6386 { 6387 struct bwn_phy *phy = &mac->mac_phy; 6388 struct bwn_phy_g *pg = &phy->phy_g; 6389 struct bwn_loctl loctl = { 0, 0 }; 6390 struct bwn_lo_calib *cal; 6391 struct bwn_lo_g_value sval = { 0 }; 6392 int rxgain; 6393 uint16_t pad, reg, value; 6394 6395 sval.old_channel = phy->chan; 6396 bwn_mac_suspend(mac); 6397 bwn_lo_save(mac, &sval); 6398 6399 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6400 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6401 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6402 6403 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6404 if (rfatt->padmix) 6405 rxgain -= pad; 6406 if (BWN_HAS_LOOPBACK(phy)) 6407 rxgain += pg->pg_max_lb_gain; 6408 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6409 bwn_phy_g_set_bbatt(mac, bbatt->att); 6410 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6411 6412 bwn_lo_restore(mac, &sval); 6413 bwn_mac_enable(mac); 6414 6415 cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO); 6416 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6417 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6418 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6419 6420 BWN_GETTIME(cal->calib_time); 6421 6422 return (cal); 6423 } 6424 6425 static struct bwn_lo_calib * 6426 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6427 const struct bwn_rfatt *rfatt) 6428 { 6429 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6430 struct bwn_lo_calib *c; 6431 6432 TAILQ_FOREACH(c, &lo->calib_list, list) { 6433 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6434 continue; 6435 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6436 continue; 6437 return (c); 6438 } 6439 6440 c = bwn_lo_calibset(mac, bbatt, rfatt); 6441 if (c == NULL) /* XXX ivadasz: can't happen */ 6442 return (NULL); 6443 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6444 6445 return (c); 6446 } 6447 6448 static void 6449 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6450 { 6451 struct bwn_phy *phy = &mac->mac_phy; 6452 struct bwn_phy_g *pg = &phy->phy_g; 6453 struct bwn_softc *sc = mac->mac_sc; 6454 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6455 const struct bwn_rfatt *rfatt; 6456 const struct bwn_bbatt *bbatt; 6457 uint64_t pvector; 6458 int i; 6459 int rf_offset, bb_offset; 6460 uint8_t changed = 0; 6461 6462 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6463 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6464 ("%s:%d: fail", __func__, __LINE__)); 6465 6466 pvector = lo->power_vector; 6467 if (!update && !pvector) 6468 return; 6469 6470 bwn_mac_suspend(mac); 6471 6472 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6473 struct bwn_lo_calib *cal; 6474 int idx; 6475 uint16_t val; 6476 6477 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6478 continue; 6479 bb_offset = i / lo->rfatt.len; 6480 rf_offset = i % lo->rfatt.len; 6481 bbatt = &(lo->bbatt.array[bb_offset]); 6482 rfatt = &(lo->rfatt.array[rf_offset]); 6483 6484 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6485 if (cal == NULL) { /* XXX ivadasz: can't happen */ 6486 device_printf(sc->sc_dev, "LO: Could not " 6487 "calibrate DC table entry\n"); 6488 continue; 6489 } 6490 val = (uint8_t)(cal->ctl.q); 6491 val |= ((uint8_t)(cal->ctl.i)) << 4; 6492 kfree(cal, M_DEVBUF); 6493 6494 idx = i / 2; 6495 if (i % 2) 6496 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6497 | ((val & 0x00ff) << 8); 6498 else 6499 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6500 | (val & 0x00ff); 6501 changed = 1; 6502 } 6503 if (changed) { 6504 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6505 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6506 } 6507 bwn_mac_enable(mac); 6508 } 6509 6510 static void 6511 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6512 { 6513 6514 if (!rf->padmix) 6515 return; 6516 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6517 rf->att = 4; 6518 } 6519 6520 static void 6521 bwn_lo_g_adjust(struct bwn_mac *mac) 6522 { 6523 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6524 struct bwn_lo_calib *cal; 6525 struct bwn_rfatt rf; 6526 6527 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6528 bwn_lo_fixup_rfatt(&rf); 6529 6530 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6531 if (cal == NULL) /* XXX ivadasz: can't happen */ 6532 return; 6533 bwn_lo_write(mac, &cal->ctl); 6534 } 6535 6536 static void 6537 bwn_lo_g_init(struct bwn_mac *mac) 6538 { 6539 6540 if (!bwn_has_hwpctl(mac)) 6541 return; 6542 6543 bwn_lo_get_powervector(mac); 6544 bwn_phy_g_dc_lookup_init(mac, 1); 6545 } 6546 6547 static void 6548 bwn_mac_suspend(struct bwn_mac *mac) 6549 { 6550 struct bwn_softc *sc = mac->mac_sc; 6551 int i; 6552 uint32_t tmp; 6553 6554 KASSERT(mac->mac_suspended >= 0, 6555 ("%s:%d: fail", __func__, __LINE__)); 6556 6557 if (mac->mac_suspended == 0) { 6558 bwn_psctl(mac, BWN_PS_AWAKE); 6559 BWN_WRITE_4(mac, BWN_MACCTL, 6560 BWN_READ_4(mac, BWN_MACCTL) 6561 & ~BWN_MACCTL_ON); 6562 BWN_READ_4(mac, BWN_MACCTL); 6563 for (i = 35; i; i--) { 6564 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6565 if (tmp & BWN_INTR_MAC_SUSPENDED) 6566 goto out; 6567 DELAY(10); 6568 } 6569 for (i = 40; i; i--) { 6570 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6571 if (tmp & BWN_INTR_MAC_SUSPENDED) 6572 goto out; 6573 DELAY(1000); 6574 } 6575 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6576 } 6577 out: 6578 mac->mac_suspended++; 6579 } 6580 6581 static void 6582 bwn_mac_enable(struct bwn_mac *mac) 6583 { 6584 struct bwn_softc *sc = mac->mac_sc; 6585 uint16_t state; 6586 6587 state = bwn_shm_read_2(mac, BWN_SHARED, 6588 BWN_SHARED_UCODESTAT); 6589 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6590 state != BWN_SHARED_UCODESTAT_SLEEP) 6591 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6592 6593 mac->mac_suspended--; 6594 KASSERT(mac->mac_suspended >= 0, 6595 ("%s:%d: fail", __func__, __LINE__)); 6596 if (mac->mac_suspended == 0) { 6597 BWN_WRITE_4(mac, BWN_MACCTL, 6598 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6599 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6600 BWN_READ_4(mac, BWN_MACCTL); 6601 BWN_READ_4(mac, BWN_INTR_REASON); 6602 bwn_psctl(mac, 0); 6603 } 6604 } 6605 6606 static void 6607 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6608 { 6609 struct bwn_softc *sc = mac->mac_sc; 6610 int i; 6611 uint16_t ucstat; 6612 6613 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6614 ("%s:%d: fail", __func__, __LINE__)); 6615 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6616 ("%s:%d: fail", __func__, __LINE__)); 6617 6618 /* XXX forcibly awake and hwps-off */ 6619 6620 BWN_WRITE_4(mac, BWN_MACCTL, 6621 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6622 ~BWN_MACCTL_HWPS); 6623 BWN_READ_4(mac, BWN_MACCTL); 6624 if (siba_get_revid(sc->sc_dev) >= 5) { 6625 for (i = 0; i < 100; i++) { 6626 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6627 BWN_SHARED_UCODESTAT); 6628 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6629 break; 6630 DELAY(10); 6631 } 6632 } 6633 } 6634 6635 static int16_t 6636 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6637 { 6638 6639 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6640 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6641 } 6642 6643 static void 6644 bwn_nrssi_threshold(struct bwn_mac *mac) 6645 { 6646 struct bwn_phy *phy = &mac->mac_phy; 6647 struct bwn_phy_g *pg = &phy->phy_g; 6648 struct bwn_softc *sc = mac->mac_sc; 6649 int32_t a, b; 6650 int16_t tmp16; 6651 uint16_t tmpu16; 6652 6653 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6654 6655 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6656 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6657 a = 0x13; 6658 b = 0x12; 6659 } else { 6660 a = 0xe; 6661 b = 0x11; 6662 } 6663 6664 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6665 a += (pg->pg_nrssi[0] << 6); 6666 a += (a < 32) ? 31 : 32; 6667 a = a >> 6; 6668 a = MIN(MAX(a, -31), 31); 6669 6670 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6671 b += (pg->pg_nrssi[0] << 6); 6672 if (b < 32) 6673 b += 31; 6674 else 6675 b += 32; 6676 b = b >> 6; 6677 b = MIN(MAX(b, -31), 31); 6678 6679 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6680 tmpu16 |= ((uint32_t)b & 0x0000003f); 6681 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6682 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6683 return; 6684 } 6685 6686 tmp16 = bwn_nrssi_read(mac, 0x20); 6687 if (tmp16 >= 0x20) 6688 tmp16 -= 0x40; 6689 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6690 } 6691 6692 static void 6693 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6694 { 6695 #define SAVE_RF_MAX 3 6696 #define SAVE_PHY_COMM_MAX 4 6697 #define SAVE_PHY3_MAX 8 6698 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6699 { 0x7a, 0x52, 0x43 }; 6700 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6701 { 0x15, 0x5a, 0x59, 0x58 }; 6702 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6703 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6704 0x0801, 0x0060, 0x0014, 0x0478 6705 }; 6706 struct bwn_phy *phy = &mac->mac_phy; 6707 struct bwn_phy_g *pg = &phy->phy_g; 6708 int32_t i, tmp32, phy3_idx = 0; 6709 uint16_t delta, tmp; 6710 uint16_t save_rf[SAVE_RF_MAX]; 6711 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6712 uint16_t save_phy3[SAVE_PHY3_MAX]; 6713 uint16_t ant_div, phy0, chan_ex; 6714 int16_t nrssi0, nrssi1; 6715 6716 KASSERT(phy->type == BWN_PHYTYPE_G, 6717 ("%s:%d: fail", __func__, __LINE__)); 6718 6719 if (phy->rf_rev >= 9) 6720 return; 6721 if (phy->rf_rev == 8) 6722 bwn_nrssi_offset(mac); 6723 6724 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6725 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6726 6727 /* 6728 * Save RF/PHY registers for later restoration 6729 */ 6730 ant_div = BWN_READ_2(mac, 0x03e2); 6731 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6732 for (i = 0; i < SAVE_RF_MAX; ++i) 6733 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6734 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6735 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6736 6737 phy0 = BWN_READ_2(mac, BWN_PHY0); 6738 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6739 if (phy->rev >= 3) { 6740 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6741 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6742 BWN_PHY_WRITE(mac, 0x002e, 0); 6743 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6744 switch (phy->rev) { 6745 case 4: 6746 case 6: 6747 case 7: 6748 BWN_PHY_SET(mac, 0x0478, 0x0100); 6749 BWN_PHY_SET(mac, 0x0801, 0x0040); 6750 break; 6751 case 3: 6752 case 5: 6753 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6754 break; 6755 } 6756 BWN_PHY_SET(mac, 0x0060, 0x0040); 6757 BWN_PHY_SET(mac, 0x0014, 0x0200); 6758 } 6759 /* 6760 * Calculate nrssi0 6761 */ 6762 BWN_RF_SET(mac, 0x007a, 0x0070); 6763 bwn_set_all_gains(mac, 0, 8, 0); 6764 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6765 if (phy->rev >= 2) { 6766 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6767 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6768 } 6769 BWN_RF_SET(mac, 0x007a, 0x0080); 6770 DELAY(20); 6771 6772 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6773 if (nrssi0 >= 0x0020) 6774 nrssi0 -= 0x0040; 6775 6776 /* 6777 * Calculate nrssi1 6778 */ 6779 BWN_RF_MASK(mac, 0x007a, 0x007f); 6780 if (phy->rev >= 2) 6781 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6782 6783 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6784 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6785 BWN_RF_SET(mac, 0x007a, 0x000f); 6786 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6787 if (phy->rev >= 2) { 6788 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6789 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6790 } 6791 6792 bwn_set_all_gains(mac, 3, 0, 1); 6793 if (phy->rf_rev == 8) { 6794 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6795 } else { 6796 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6797 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6798 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6799 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6800 } 6801 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6802 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6803 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6804 DELAY(20); 6805 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6806 6807 /* 6808 * Install calculated narrow RSSI values 6809 */ 6810 if (nrssi1 >= 0x0020) 6811 nrssi1 -= 0x0040; 6812 if (nrssi0 == nrssi1) 6813 pg->pg_nrssi_slope = 0x00010000; 6814 else 6815 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6816 if (nrssi0 >= -4) { 6817 pg->pg_nrssi[0] = nrssi1; 6818 pg->pg_nrssi[1] = nrssi0; 6819 } 6820 6821 /* 6822 * Restore saved RF/PHY registers 6823 */ 6824 if (phy->rev >= 3) { 6825 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6826 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6827 save_phy3[phy3_idx]); 6828 } 6829 } 6830 if (phy->rev >= 2) { 6831 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6832 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6833 } 6834 6835 for (i = 0; i < SAVE_RF_MAX; ++i) 6836 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6837 6838 BWN_WRITE_2(mac, 0x03e2, ant_div); 6839 BWN_WRITE_2(mac, 0x03e6, phy0); 6840 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6841 6842 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6843 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6844 6845 bwn_spu_workaround(mac, phy->chan); 6846 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6847 bwn_set_original_gains(mac); 6848 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6849 if (phy->rev >= 3) { 6850 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6851 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6852 save_phy3[phy3_idx]); 6853 } 6854 } 6855 6856 delta = 0x1f - pg->pg_nrssi[0]; 6857 for (i = 0; i < 64; i++) { 6858 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6859 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6860 pg->pg_nrssi_lt[i] = tmp32; 6861 } 6862 6863 bwn_nrssi_threshold(mac); 6864 #undef SAVE_RF_MAX 6865 #undef SAVE_PHY_COMM_MAX 6866 #undef SAVE_PHY3_MAX 6867 } 6868 6869 static void 6870 bwn_nrssi_offset(struct bwn_mac *mac) 6871 { 6872 #define SAVE_RF_MAX 2 6873 #define SAVE_PHY_COMM_MAX 10 6874 #define SAVE_PHY6_MAX 8 6875 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6876 { 0x7a, 0x43 }; 6877 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6878 0x0001, 0x0811, 0x0812, 0x0814, 6879 0x0815, 0x005a, 0x0059, 0x0058, 6880 0x000a, 0x0003 6881 }; 6882 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6883 0x002e, 0x002f, 0x080f, 0x0810, 6884 0x0801, 0x0060, 0x0014, 0x0478 6885 }; 6886 struct bwn_phy *phy = &mac->mac_phy; 6887 int i, phy6_idx = 0; 6888 uint16_t save_rf[SAVE_RF_MAX]; 6889 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6890 uint16_t save_phy6[SAVE_PHY6_MAX]; 6891 int16_t nrssi; 6892 uint16_t saved = 0xffff; 6893 6894 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6895 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6896 for (i = 0; i < SAVE_RF_MAX; ++i) 6897 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6898 6899 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6900 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6901 BWN_PHY_SET(mac, 0x0811, 0x000c); 6902 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6903 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6904 if (phy->rev >= 6) { 6905 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6906 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6907 6908 BWN_PHY_WRITE(mac, 0x002e, 0); 6909 BWN_PHY_WRITE(mac, 0x002f, 0); 6910 BWN_PHY_WRITE(mac, 0x080f, 0); 6911 BWN_PHY_WRITE(mac, 0x0810, 0); 6912 BWN_PHY_SET(mac, 0x0478, 0x0100); 6913 BWN_PHY_SET(mac, 0x0801, 0x0040); 6914 BWN_PHY_SET(mac, 0x0060, 0x0040); 6915 BWN_PHY_SET(mac, 0x0014, 0x0200); 6916 } 6917 BWN_RF_SET(mac, 0x007a, 0x0070); 6918 BWN_RF_SET(mac, 0x007a, 0x0080); 6919 DELAY(30); 6920 6921 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6922 if (nrssi >= 0x20) 6923 nrssi -= 0x40; 6924 if (nrssi == 31) { 6925 for (i = 7; i >= 4; i--) { 6926 BWN_RF_WRITE(mac, 0x007b, i); 6927 DELAY(20); 6928 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 6929 0x003f); 6930 if (nrssi >= 0x20) 6931 nrssi -= 0x40; 6932 if (nrssi < 31 && saved == 0xffff) 6933 saved = i; 6934 } 6935 if (saved == 0xffff) 6936 saved = 4; 6937 } else { 6938 BWN_RF_MASK(mac, 0x007a, 0x007f); 6939 if (phy->rev != 1) { 6940 BWN_PHY_SET(mac, 0x0814, 0x0001); 6941 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 6942 } 6943 BWN_PHY_SET(mac, 0x0811, 0x000c); 6944 BWN_PHY_SET(mac, 0x0812, 0x000c); 6945 BWN_PHY_SET(mac, 0x0811, 0x0030); 6946 BWN_PHY_SET(mac, 0x0812, 0x0030); 6947 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6948 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6949 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6950 if (phy->rev == 0) 6951 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 6952 else 6953 BWN_PHY_SET(mac, 0x000a, 0x2000); 6954 if (phy->rev != 1) { 6955 BWN_PHY_SET(mac, 0x0814, 0x0004); 6956 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 6957 } 6958 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6959 BWN_RF_SET(mac, 0x007a, 0x000f); 6960 bwn_set_all_gains(mac, 3, 0, 1); 6961 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 6962 DELAY(30); 6963 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6964 if (nrssi >= 0x20) 6965 nrssi -= 0x40; 6966 if (nrssi == -32) { 6967 for (i = 0; i < 4; i++) { 6968 BWN_RF_WRITE(mac, 0x007b, i); 6969 DELAY(20); 6970 nrssi = (int16_t)((BWN_PHY_READ(mac, 6971 0x047f) >> 8) & 0x003f); 6972 if (nrssi >= 0x20) 6973 nrssi -= 0x40; 6974 if (nrssi > -31 && saved == 0xffff) 6975 saved = i; 6976 } 6977 if (saved == 0xffff) 6978 saved = 3; 6979 } else 6980 saved = 0; 6981 } 6982 BWN_RF_WRITE(mac, 0x007b, saved); 6983 6984 /* 6985 * Restore saved RF/PHY registers 6986 */ 6987 if (phy->rev >= 6) { 6988 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 6989 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6990 save_phy6[phy6_idx]); 6991 } 6992 } 6993 if (phy->rev != 1) { 6994 for (i = 3; i < 5; i++) 6995 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 6996 save_phy_comm[i]); 6997 } 6998 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 6999 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7000 7001 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7002 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7003 7004 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7005 BWN_PHY_SET(mac, 0x0429, 0x8000); 7006 bwn_set_original_gains(mac); 7007 if (phy->rev >= 6) { 7008 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7009 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7010 save_phy6[phy6_idx]); 7011 } 7012 } 7013 7014 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7015 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7016 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7017 } 7018 7019 static void 7020 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7021 int16_t third) 7022 { 7023 struct bwn_phy *phy = &mac->mac_phy; 7024 uint16_t i; 7025 uint16_t start = 0x08, end = 0x18; 7026 uint16_t tmp; 7027 uint16_t table; 7028 7029 if (phy->rev <= 1) { 7030 start = 0x10; 7031 end = 0x20; 7032 } 7033 7034 table = BWN_OFDMTAB_GAINX; 7035 if (phy->rev <= 1) 7036 table = BWN_OFDMTAB_GAINX_R1; 7037 for (i = 0; i < 4; i++) 7038 bwn_ofdmtab_write_2(mac, table, i, first); 7039 7040 for (i = start; i < end; i++) 7041 bwn_ofdmtab_write_2(mac, table, i, second); 7042 7043 if (third != -1) { 7044 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7045 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7046 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7047 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7048 } 7049 bwn_dummy_transmission(mac, 0, 1); 7050 } 7051 7052 static void 7053 bwn_set_original_gains(struct bwn_mac *mac) 7054 { 7055 struct bwn_phy *phy = &mac->mac_phy; 7056 uint16_t i, tmp; 7057 uint16_t table; 7058 uint16_t start = 0x0008, end = 0x0018; 7059 7060 if (phy->rev <= 1) { 7061 start = 0x0010; 7062 end = 0x0020; 7063 } 7064 7065 table = BWN_OFDMTAB_GAINX; 7066 if (phy->rev <= 1) 7067 table = BWN_OFDMTAB_GAINX_R1; 7068 for (i = 0; i < 4; i++) { 7069 tmp = (i & 0xfffc); 7070 tmp |= (i & 0x0001) << 1; 7071 tmp |= (i & 0x0002) >> 1; 7072 7073 bwn_ofdmtab_write_2(mac, table, i, tmp); 7074 } 7075 7076 for (i = start; i < end; i++) 7077 bwn_ofdmtab_write_2(mac, table, i, i - start); 7078 7079 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7080 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7081 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7082 bwn_dummy_transmission(mac, 0, 1); 7083 } 7084 7085 static void 7086 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7087 { 7088 struct bwn_phy *phy = &mac->mac_phy; 7089 struct bwn_phy_g *pg = &phy->phy_g; 7090 struct bwn_rfatt old_rfatt, rfatt; 7091 struct bwn_bbatt old_bbatt, bbatt; 7092 struct bwn_softc *sc = mac->mac_sc; 7093 uint8_t old_txctl = 0; 7094 7095 KASSERT(phy->type == BWN_PHYTYPE_G, 7096 ("%s:%d: fail", __func__, __LINE__)); 7097 7098 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7099 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7100 return; 7101 7102 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7103 7104 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7105 7106 if (!phy->gmode) 7107 return; 7108 bwn_hwpctl_early_init(mac); 7109 if (pg->pg_curtssi == 0) { 7110 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7111 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7112 } else { 7113 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7114 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7115 old_txctl = pg->pg_txctl; 7116 7117 bbatt.att = 11; 7118 if (phy->rf_rev == 8) { 7119 rfatt.att = 15; 7120 rfatt.padmix = 1; 7121 } else { 7122 rfatt.att = 9; 7123 rfatt.padmix = 0; 7124 } 7125 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7126 } 7127 bwn_dummy_transmission(mac, 0, 1); 7128 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7129 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7130 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7131 else 7132 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7133 &old_rfatt, old_txctl); 7134 } 7135 bwn_hwpctl_init_gphy(mac); 7136 7137 /* clear TSSI */ 7138 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7139 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7140 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7141 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7142 } 7143 7144 static void 7145 bwn_hwpctl_early_init(struct bwn_mac *mac) 7146 { 7147 struct bwn_phy *phy = &mac->mac_phy; 7148 7149 if (!bwn_has_hwpctl(mac)) { 7150 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7151 return; 7152 } 7153 7154 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7155 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7156 BWN_PHY_SET(mac, 0x047c, 0x0002); 7157 BWN_PHY_SET(mac, 0x047a, 0xf000); 7158 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7159 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7160 BWN_PHY_SET(mac, 0x005d, 0x8000); 7161 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7162 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7163 BWN_PHY_SET(mac, 0x0036, 0x0400); 7164 } else { 7165 BWN_PHY_SET(mac, 0x0036, 0x0200); 7166 BWN_PHY_SET(mac, 0x0036, 0x0400); 7167 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7168 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7169 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7170 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7171 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7172 } 7173 } 7174 7175 static void 7176 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7177 { 7178 struct bwn_phy *phy = &mac->mac_phy; 7179 struct bwn_phy_g *pg = &phy->phy_g; 7180 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7181 int i; 7182 uint16_t nr_written = 0, tmp, value; 7183 uint8_t rf, bb; 7184 7185 if (!bwn_has_hwpctl(mac)) { 7186 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7187 return; 7188 } 7189 7190 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7191 (pg->pg_idletssi - pg->pg_curtssi)); 7192 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7193 (pg->pg_idletssi - pg->pg_curtssi)); 7194 7195 for (i = 0; i < 32; i++) 7196 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7197 for (i = 32; i < 64; i++) 7198 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7199 for (i = 0; i < 64; i += 2) { 7200 value = (uint16_t) pg->pg_tssi2dbm[i]; 7201 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7202 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7203 } 7204 7205 for (rf = 0; rf < lo->rfatt.len; rf++) { 7206 for (bb = 0; bb < lo->bbatt.len; bb++) { 7207 if (nr_written >= 0x40) 7208 return; 7209 tmp = lo->bbatt.array[bb].att; 7210 tmp <<= 8; 7211 if (phy->rf_rev == 8) 7212 tmp |= 0x50; 7213 else 7214 tmp |= 0x40; 7215 tmp |= lo->rfatt.array[rf].att; 7216 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7217 nr_written++; 7218 } 7219 } 7220 7221 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7222 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7223 7224 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7225 BWN_PHY_SET(mac, 0x0478, 0x0800); 7226 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7227 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7228 7229 bwn_phy_g_dc_lookup_init(mac, 1); 7230 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7231 } 7232 7233 static void 7234 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7235 { 7236 struct bwn_softc *sc = mac->mac_sc; 7237 7238 if (spu != 0) 7239 bwn_spu_workaround(mac, channel); 7240 7241 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7242 7243 if (channel == 14) { 7244 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7245 bwn_hf_write(mac, 7246 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7247 else 7248 bwn_hf_write(mac, 7249 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7250 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7251 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7252 return; 7253 } 7254 7255 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7256 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7257 } 7258 7259 static uint16_t 7260 bwn_phy_g_chan2freq(uint8_t channel) 7261 { 7262 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7263 7264 KASSERT(channel >= 1 && channel <= 14, 7265 ("%s:%d: fail", __func__, __LINE__)); 7266 7267 return (bwn_phy_g_rf_channels[channel - 1]); 7268 } 7269 7270 static void 7271 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7272 const struct bwn_rfatt *rfatt, uint8_t txctl) 7273 { 7274 struct bwn_phy *phy = &mac->mac_phy; 7275 struct bwn_phy_g *pg = &phy->phy_g; 7276 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7277 uint16_t bb, rf; 7278 uint16_t tx_bias, tx_magn; 7279 7280 bb = bbatt->att; 7281 rf = rfatt->att; 7282 tx_bias = lo->tx_bias; 7283 tx_magn = lo->tx_magn; 7284 if (tx_bias == 0xff) 7285 tx_bias = 0; 7286 7287 pg->pg_txctl = txctl; 7288 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7289 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7290 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7291 bwn_phy_g_set_bbatt(mac, bb); 7292 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7293 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7294 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7295 else { 7296 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7297 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7298 } 7299 if (BWN_HAS_TXMAG(phy)) 7300 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7301 else 7302 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7303 bwn_lo_g_adjust(mac); 7304 } 7305 7306 static void 7307 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7308 uint16_t bbatt) 7309 { 7310 struct bwn_phy *phy = &mac->mac_phy; 7311 7312 if (phy->analog == 0) { 7313 BWN_WRITE_2(mac, BWN_PHY0, 7314 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7315 return; 7316 } 7317 if (phy->analog > 1) { 7318 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7319 return; 7320 } 7321 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7322 } 7323 7324 static uint16_t 7325 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7326 { 7327 struct bwn_phy *phy = &mac->mac_phy; 7328 struct bwn_phy_g *pg = &phy->phy_g; 7329 struct bwn_softc *sc = mac->mac_sc; 7330 int max_lb_gain; 7331 uint16_t extlna; 7332 uint16_t i; 7333 7334 if (phy->gmode == 0) 7335 return (0); 7336 7337 if (BWN_HAS_LOOPBACK(phy)) { 7338 max_lb_gain = pg->pg_max_lb_gain; 7339 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7340 if (max_lb_gain >= 0x46) { 7341 extlna = 0x3000; 7342 max_lb_gain -= 0x46; 7343 } else if (max_lb_gain >= 0x3a) { 7344 extlna = 0x1000; 7345 max_lb_gain -= 0x3a; 7346 } else if (max_lb_gain >= 0x2e) { 7347 extlna = 0x2000; 7348 max_lb_gain -= 0x2e; 7349 } else { 7350 extlna = 0; 7351 max_lb_gain -= 0x10; 7352 } 7353 7354 for (i = 0; i < 16; i++) { 7355 max_lb_gain -= (i * 6); 7356 if (max_lb_gain < 6) 7357 break; 7358 } 7359 7360 if ((phy->rev < 7) || 7361 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7362 if (reg == BWN_PHY_RFOVER) { 7363 return (0x1b3); 7364 } else if (reg == BWN_PHY_RFOVERVAL) { 7365 extlna |= (i << 8); 7366 switch (lpd) { 7367 case BWN_LPD(0, 1, 1): 7368 return (0x0f92); 7369 case BWN_LPD(0, 0, 1): 7370 case BWN_LPD(1, 0, 1): 7371 return (0x0092 | extlna); 7372 case BWN_LPD(1, 0, 0): 7373 return (0x0093 | extlna); 7374 } 7375 KASSERT(0 == 1, 7376 ("%s:%d: fail", __func__, __LINE__)); 7377 } 7378 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7379 } else { 7380 if (reg == BWN_PHY_RFOVER) 7381 return (0x9b3); 7382 if (reg == BWN_PHY_RFOVERVAL) { 7383 if (extlna) 7384 extlna |= 0x8000; 7385 extlna |= (i << 8); 7386 switch (lpd) { 7387 case BWN_LPD(0, 1, 1): 7388 return (0x8f92); 7389 case BWN_LPD(0, 0, 1): 7390 return (0x8092 | extlna); 7391 case BWN_LPD(1, 0, 1): 7392 return (0x2092 | extlna); 7393 case BWN_LPD(1, 0, 0): 7394 return (0x2093 | extlna); 7395 } 7396 KASSERT(0 == 1, 7397 ("%s:%d: fail", __func__, __LINE__)); 7398 } 7399 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7400 } 7401 return (0); 7402 } 7403 7404 if ((phy->rev < 7) || 7405 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7406 if (reg == BWN_PHY_RFOVER) { 7407 return (0x1b3); 7408 } else if (reg == BWN_PHY_RFOVERVAL) { 7409 switch (lpd) { 7410 case BWN_LPD(0, 1, 1): 7411 return (0x0fb2); 7412 case BWN_LPD(0, 0, 1): 7413 return (0x00b2); 7414 case BWN_LPD(1, 0, 1): 7415 return (0x30b2); 7416 case BWN_LPD(1, 0, 0): 7417 return (0x30b3); 7418 } 7419 KASSERT(0 == 1, 7420 ("%s:%d: fail", __func__, __LINE__)); 7421 } 7422 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7423 } else { 7424 if (reg == BWN_PHY_RFOVER) { 7425 return (0x9b3); 7426 } else if (reg == BWN_PHY_RFOVERVAL) { 7427 switch (lpd) { 7428 case BWN_LPD(0, 1, 1): 7429 return (0x8fb2); 7430 case BWN_LPD(0, 0, 1): 7431 return (0x80b2); 7432 case BWN_LPD(1, 0, 1): 7433 return (0x20b2); 7434 case BWN_LPD(1, 0, 0): 7435 return (0x20b3); 7436 } 7437 KASSERT(0 == 1, 7438 ("%s:%d: fail", __func__, __LINE__)); 7439 } 7440 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7441 } 7442 return (0); 7443 } 7444 7445 static void 7446 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7447 { 7448 7449 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7450 return; 7451 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7452 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7453 DELAY(1000); 7454 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7455 } 7456 7457 static int 7458 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7459 { 7460 struct bwn_softc *sc = mac->mac_sc; 7461 struct bwn_fw *fw = &mac->mac_fw; 7462 const uint8_t rev = siba_get_revid(sc->sc_dev); 7463 const char *filename; 7464 uint32_t high; 7465 int error; 7466 7467 /* microcode */ 7468 if (rev >= 5 && rev <= 10) 7469 filename = "ucode5"; 7470 else if (rev >= 11 && rev <= 12) 7471 filename = "ucode11"; 7472 else if (rev == 13) 7473 filename = "ucode13"; 7474 else if (rev == 14) 7475 filename = "ucode14"; 7476 else if (rev >= 15) 7477 filename = "ucode15"; 7478 else { 7479 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7480 bwn_release_firmware(mac); 7481 return (EOPNOTSUPP); 7482 } 7483 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7484 if (error) { 7485 bwn_release_firmware(mac); 7486 return (error); 7487 } 7488 7489 /* PCM */ 7490 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7491 if (rev >= 5 && rev <= 10) { 7492 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7493 if (error == ENOENT) 7494 fw->no_pcmfile = 1; 7495 else if (error) { 7496 bwn_release_firmware(mac); 7497 return (error); 7498 } 7499 } else if (rev < 11) { 7500 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7501 return (EOPNOTSUPP); 7502 } 7503 7504 /* initvals */ 7505 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7506 switch (mac->mac_phy.type) { 7507 case BWN_PHYTYPE_A: 7508 if (rev < 5 || rev > 10) 7509 goto fail1; 7510 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7511 filename = "a0g1initvals5"; 7512 else 7513 filename = "a0g0initvals5"; 7514 break; 7515 case BWN_PHYTYPE_G: 7516 if (rev >= 5 && rev <= 10) 7517 filename = "b0g0initvals5"; 7518 else if (rev >= 13) 7519 filename = "b0g0initvals13"; 7520 else 7521 goto fail1; 7522 break; 7523 case BWN_PHYTYPE_LP: 7524 if (rev == 13) 7525 filename = "lp0initvals13"; 7526 else if (rev == 14) 7527 filename = "lp0initvals14"; 7528 else if (rev >= 15) 7529 filename = "lp0initvals15"; 7530 else 7531 goto fail1; 7532 break; 7533 case BWN_PHYTYPE_N: 7534 if (rev >= 11 && rev <= 12) 7535 filename = "n0initvals11"; 7536 else 7537 goto fail1; 7538 break; 7539 default: 7540 goto fail1; 7541 } 7542 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7543 if (error) { 7544 bwn_release_firmware(mac); 7545 return (error); 7546 } 7547 7548 /* bandswitch initvals */ 7549 switch (mac->mac_phy.type) { 7550 case BWN_PHYTYPE_A: 7551 if (rev >= 5 && rev <= 10) { 7552 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7553 filename = "a0g1bsinitvals5"; 7554 else 7555 filename = "a0g0bsinitvals5"; 7556 } else if (rev >= 11) 7557 filename = NULL; 7558 else 7559 goto fail1; 7560 break; 7561 case BWN_PHYTYPE_G: 7562 if (rev >= 5 && rev <= 10) 7563 filename = "b0g0bsinitvals5"; 7564 else if (rev >= 11) 7565 filename = NULL; 7566 else 7567 goto fail1; 7568 break; 7569 case BWN_PHYTYPE_LP: 7570 if (rev == 13) 7571 filename = "lp0bsinitvals13"; 7572 else if (rev == 14) 7573 filename = "lp0bsinitvals14"; 7574 else if (rev >= 15) 7575 filename = "lp0bsinitvals15"; 7576 else 7577 goto fail1; 7578 break; 7579 case BWN_PHYTYPE_N: 7580 if (rev >= 11 && rev <= 12) 7581 filename = "n0bsinitvals11"; 7582 else 7583 goto fail1; 7584 break; 7585 default: 7586 goto fail1; 7587 } 7588 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7589 if (error) { 7590 bwn_release_firmware(mac); 7591 return (error); 7592 } 7593 return (0); 7594 fail1: 7595 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7596 bwn_release_firmware(mac); 7597 return (EOPNOTSUPP); 7598 } 7599 7600 static int 7601 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7602 const char *name, struct bwn_fwfile *bfw) 7603 { 7604 const struct bwn_fwhdr *hdr; 7605 struct bwn_softc *sc = mac->mac_sc; 7606 const struct firmware *fw; 7607 char namebuf[64]; 7608 7609 if (name == NULL) { 7610 bwn_do_release_fw(bfw); 7611 return (0); 7612 } 7613 if (bfw->filename != NULL) { 7614 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7615 return (0); 7616 bwn_do_release_fw(bfw); 7617 } 7618 7619 ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7620 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7621 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7622 wlan_assert_serialized(); 7623 wlan_serialize_exit(); 7624 fw = firmware_get(namebuf); 7625 wlan_serialize_enter(); 7626 if (fw == NULL) { 7627 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7628 namebuf); 7629 return (ENOENT); 7630 } 7631 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7632 goto fail; 7633 hdr = (const struct bwn_fwhdr *)(fw->data); 7634 switch (hdr->type) { 7635 case BWN_FWTYPE_UCODE: 7636 case BWN_FWTYPE_PCM: 7637 if (be32toh(hdr->size) != 7638 (fw->datasize - sizeof(struct bwn_fwhdr))) 7639 goto fail; 7640 /* FALLTHROUGH */ 7641 case BWN_FWTYPE_IV: 7642 if (hdr->ver != 1) 7643 goto fail; 7644 break; 7645 default: 7646 goto fail; 7647 } 7648 bfw->filename = name; 7649 bfw->fw = fw; 7650 bfw->type = type; 7651 return (0); 7652 fail: 7653 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7654 if (fw != NULL) 7655 firmware_put(fw, FIRMWARE_UNLOAD); 7656 return (EPROTO); 7657 } 7658 7659 static void 7660 bwn_release_firmware(struct bwn_mac *mac) 7661 { 7662 7663 bwn_do_release_fw(&mac->mac_fw.ucode); 7664 bwn_do_release_fw(&mac->mac_fw.pcm); 7665 bwn_do_release_fw(&mac->mac_fw.initvals); 7666 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7667 } 7668 7669 static void 7670 bwn_do_release_fw(struct bwn_fwfile *bfw) 7671 { 7672 7673 if (bfw->fw != NULL) 7674 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7675 bfw->fw = NULL; 7676 bfw->filename = NULL; 7677 } 7678 7679 static int 7680 bwn_fw_loaducode(struct bwn_mac *mac) 7681 { 7682 #define GETFWOFFSET(fwp, offset) \ 7683 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7684 #define GETFWSIZE(fwp, offset) \ 7685 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7686 struct bwn_softc *sc = mac->mac_sc; 7687 const uint32_t *data; 7688 unsigned int i; 7689 uint32_t ctl; 7690 uint16_t date, fwcaps, time; 7691 int error = 0; 7692 7693 ctl = BWN_READ_4(mac, BWN_MACCTL); 7694 ctl |= BWN_MACCTL_MCODE_JMP0; 7695 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7696 __LINE__)); 7697 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7698 for (i = 0; i < 64; i++) 7699 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7700 for (i = 0; i < 4096; i += 2) 7701 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7702 7703 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7704 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7705 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7706 i++) { 7707 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7708 DELAY(10); 7709 } 7710 7711 if (mac->mac_fw.pcm.fw) { 7712 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7713 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7714 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7715 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7716 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7717 sizeof(struct bwn_fwhdr)); i++) { 7718 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7719 DELAY(10); 7720 } 7721 } 7722 7723 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7724 BWN_WRITE_4(mac, BWN_MACCTL, 7725 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7726 BWN_MACCTL_MCODE_RUN); 7727 7728 for (i = 0; i < 21; i++) { 7729 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7730 break; 7731 if (i >= 20) { 7732 device_printf(sc->sc_dev, "ucode timeout\n"); 7733 error = ENXIO; 7734 goto error; 7735 } 7736 DELAY(50000); 7737 } 7738 BWN_READ_4(mac, BWN_INTR_REASON); 7739 7740 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7741 if (mac->mac_fw.rev <= 0x128) { 7742 device_printf(sc->sc_dev, "the firmware is too old\n"); 7743 error = EOPNOTSUPP; 7744 goto error; 7745 } 7746 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7747 BWN_SHARED_UCODE_PATCH); 7748 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7749 mac->mac_fw.opensource = (date == 0xffff); 7750 if (bwn_wme != 0) 7751 mac->mac_flags |= BWN_MAC_FLAG_WME; 7752 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7753 7754 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7755 if (mac->mac_fw.opensource == 0) { 7756 device_printf(sc->sc_dev, 7757 "firmware version (rev %u patch %u date %#x time %#x)\n", 7758 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7759 if (mac->mac_fw.no_pcmfile) 7760 device_printf(sc->sc_dev, 7761 "no HW crypto acceleration due to pcm5\n"); 7762 } else { 7763 mac->mac_fw.patch = time; 7764 fwcaps = bwn_fwcaps_read(mac); 7765 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7766 device_printf(sc->sc_dev, 7767 "disabling HW crypto acceleration\n"); 7768 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7769 } 7770 if (!(fwcaps & BWN_FWCAPS_WME)) { 7771 device_printf(sc->sc_dev, "disabling WME support\n"); 7772 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7773 } 7774 } 7775 7776 if (BWN_ISOLDFMT(mac)) 7777 device_printf(sc->sc_dev, "using old firmware image\n"); 7778 7779 return (0); 7780 7781 error: 7782 BWN_WRITE_4(mac, BWN_MACCTL, 7783 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7784 BWN_MACCTL_MCODE_JMP0); 7785 7786 return (error); 7787 #undef GETFWSIZE 7788 #undef GETFWOFFSET 7789 } 7790 7791 /* OpenFirmware only */ 7792 static uint16_t 7793 bwn_fwcaps_read(struct bwn_mac *mac) 7794 { 7795 7796 KASSERT(mac->mac_fw.opensource == 1, 7797 ("%s:%d: fail", __func__, __LINE__)); 7798 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7799 } 7800 7801 static int 7802 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7803 size_t count, size_t array_size) 7804 { 7805 #define GET_NEXTIV16(iv) \ 7806 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7807 sizeof(uint16_t) + sizeof(uint16_t))) 7808 #define GET_NEXTIV32(iv) \ 7809 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7810 sizeof(uint16_t) + sizeof(uint32_t))) 7811 struct bwn_softc *sc = mac->mac_sc; 7812 const struct bwn_fwinitvals *iv; 7813 uint16_t offset; 7814 size_t i; 7815 uint8_t bit32; 7816 7817 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7818 ("%s:%d: fail", __func__, __LINE__)); 7819 iv = ivals; 7820 for (i = 0; i < count; i++) { 7821 if (array_size < sizeof(iv->offset_size)) 7822 goto fail; 7823 array_size -= sizeof(iv->offset_size); 7824 offset = be16toh(iv->offset_size); 7825 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7826 offset &= BWN_FWINITVALS_OFFSET_MASK; 7827 if (offset >= 0x1000) 7828 goto fail; 7829 if (bit32) { 7830 if (array_size < sizeof(iv->data.d32)) 7831 goto fail; 7832 array_size -= sizeof(iv->data.d32); 7833 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7834 iv = GET_NEXTIV32(iv); 7835 } else { 7836 7837 if (array_size < sizeof(iv->data.d16)) 7838 goto fail; 7839 array_size -= sizeof(iv->data.d16); 7840 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7841 7842 iv = GET_NEXTIV16(iv); 7843 } 7844 } 7845 if (array_size != 0) 7846 goto fail; 7847 return (0); 7848 fail: 7849 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7850 return (EPROTO); 7851 #undef GET_NEXTIV16 7852 #undef GET_NEXTIV32 7853 } 7854 7855 static int 7856 bwn_switch_channel(struct bwn_mac *mac, int chan) 7857 { 7858 struct bwn_phy *phy = &(mac->mac_phy); 7859 struct bwn_softc *sc = mac->mac_sc; 7860 struct ifnet *ifp = sc->sc_ifp; 7861 struct ieee80211com *ic = ifp->if_l2com; 7862 uint16_t channelcookie, savedcookie; 7863 int error; 7864 7865 if (chan == 0xffff) 7866 chan = phy->get_default_chan(mac); 7867 7868 channelcookie = chan; 7869 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7870 channelcookie |= 0x100; 7871 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7872 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7873 error = phy->switch_channel(mac, chan); 7874 if (error) 7875 goto fail; 7876 7877 mac->mac_phy.chan = chan; 7878 DELAY(8000); 7879 return (0); 7880 fail: 7881 device_printf(sc->sc_dev, "failed to switch channel\n"); 7882 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7883 return (error); 7884 } 7885 7886 static uint16_t 7887 bwn_ant2phy(int antenna) 7888 { 7889 7890 switch (antenna) { 7891 case BWN_ANT0: 7892 return (BWN_TX_PHY_ANT0); 7893 case BWN_ANT1: 7894 return (BWN_TX_PHY_ANT1); 7895 case BWN_ANT2: 7896 return (BWN_TX_PHY_ANT2); 7897 case BWN_ANT3: 7898 return (BWN_TX_PHY_ANT3); 7899 case BWN_ANTAUTO: 7900 return (BWN_TX_PHY_ANT01AUTO); 7901 } 7902 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7903 return (0); 7904 } 7905 7906 static void 7907 bwn_wme_load(struct bwn_mac *mac) 7908 { 7909 struct bwn_softc *sc = mac->mac_sc; 7910 int i; 7911 7912 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7913 ("%s:%d: fail", __func__, __LINE__)); 7914 7915 bwn_mac_suspend(mac); 7916 for (i = 0; i < N(sc->sc_wmeParams); i++) 7917 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 7918 bwn_wme_shm_offsets[i]); 7919 bwn_mac_enable(mac); 7920 } 7921 7922 static void 7923 bwn_wme_loadparams(struct bwn_mac *mac, 7924 const struct wmeParams *p, uint16_t shm_offset) 7925 { 7926 #define SM(_v, _f) (((_v) << _f##_S) & _f) 7927 struct bwn_softc *sc = mac->mac_sc; 7928 uint16_t params[BWN_NR_WMEPARAMS]; 7929 int slot, tmp; 7930 unsigned int i; 7931 7932 slot = BWN_READ_2(mac, BWN_RNG) & 7933 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7934 7935 memset(¶ms, 0, sizeof(params)); 7936 7937 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 7938 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 7939 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 7940 7941 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 7942 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7943 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 7944 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7945 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 7946 params[BWN_WMEPARAM_BSLOTS] = slot; 7947 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 7948 7949 for (i = 0; i < N(params); i++) { 7950 if (i == BWN_WMEPARAM_STATUS) { 7951 tmp = bwn_shm_read_2(mac, BWN_SHARED, 7952 shm_offset + (i * 2)); 7953 tmp |= 0x100; 7954 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7955 tmp); 7956 } else { 7957 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7958 params[i]); 7959 } 7960 } 7961 } 7962 7963 static void 7964 bwn_mac_write_bssid(struct bwn_mac *mac) 7965 { 7966 struct bwn_softc *sc = mac->mac_sc; 7967 uint32_t tmp; 7968 int i; 7969 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 7970 7971 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 7972 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 7973 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 7974 IEEE80211_ADDR_LEN); 7975 7976 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 7977 tmp = (uint32_t) (mac_bssid[i + 0]); 7978 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 7979 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 7980 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 7981 bwn_ram_write(mac, 0x20 + i, tmp); 7982 } 7983 } 7984 7985 static void 7986 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 7987 const uint8_t *macaddr) 7988 { 7989 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 7990 uint16_t data; 7991 7992 if (mac == NULL) 7993 macaddr = zero; 7994 7995 offset |= 0x0020; 7996 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 7997 7998 data = macaddr[0]; 7999 data |= macaddr[1] << 8; 8000 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8001 data = macaddr[2]; 8002 data |= macaddr[3] << 8; 8003 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8004 data = macaddr[4]; 8005 data |= macaddr[5] << 8; 8006 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8007 } 8008 8009 static void 8010 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8011 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8012 { 8013 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8014 uint8_t per_sta_keys_start = 8; 8015 8016 if (BWN_SEC_NEWAPI(mac)) 8017 per_sta_keys_start = 4; 8018 8019 KASSERT(index < mac->mac_max_nr_keys, 8020 ("%s:%d: fail", __func__, __LINE__)); 8021 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8022 ("%s:%d: fail", __func__, __LINE__)); 8023 8024 if (index >= per_sta_keys_start) 8025 bwn_key_macwrite(mac, index, NULL); 8026 if (key) 8027 memcpy(buf, key, key_len); 8028 bwn_key_write(mac, index, algorithm, buf); 8029 if (index >= per_sta_keys_start) 8030 bwn_key_macwrite(mac, index, mac_addr); 8031 8032 mac->mac_key[index].algorithm = algorithm; 8033 } 8034 8035 static void 8036 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8037 { 8038 struct bwn_softc *sc = mac->mac_sc; 8039 uint32_t addrtmp[2] = { 0, 0 }; 8040 uint8_t start = 8; 8041 8042 if (BWN_SEC_NEWAPI(mac)) 8043 start = 4; 8044 8045 KASSERT(index >= start, 8046 ("%s:%d: fail", __func__, __LINE__)); 8047 index -= start; 8048 8049 if (addr) { 8050 addrtmp[0] = addr[0]; 8051 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8052 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8053 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8054 addrtmp[1] = addr[4]; 8055 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8056 } 8057 8058 if (siba_get_revid(sc->sc_dev) >= 5) { 8059 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8060 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8061 } else { 8062 if (index >= 8) { 8063 bwn_shm_write_4(mac, BWN_SHARED, 8064 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8065 bwn_shm_write_2(mac, BWN_SHARED, 8066 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8067 } 8068 } 8069 } 8070 8071 static void 8072 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8073 const uint8_t *key) 8074 { 8075 unsigned int i; 8076 uint32_t offset; 8077 uint16_t kidx, value; 8078 8079 kidx = BWN_SEC_KEY2FW(mac, index); 8080 bwn_shm_write_2(mac, BWN_SHARED, 8081 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8082 8083 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8084 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8085 value = key[i]; 8086 value |= (uint16_t)(key[i + 1]) << 8; 8087 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8088 } 8089 } 8090 8091 static void 8092 bwn_phy_exit(struct bwn_mac *mac) 8093 { 8094 8095 mac->mac_phy.rf_onoff(mac, 0); 8096 if (mac->mac_phy.exit != NULL) 8097 mac->mac_phy.exit(mac); 8098 } 8099 8100 static void 8101 bwn_dma_free(struct bwn_mac *mac) 8102 { 8103 struct bwn_dma *dma; 8104 8105 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8106 return; 8107 dma = &mac->mac_method.dma; 8108 8109 bwn_dma_ringfree(&dma->rx); 8110 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8111 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8112 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8113 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8114 bwn_dma_ringfree(&dma->mcast); 8115 } 8116 8117 static void 8118 bwn_core_stop(struct bwn_mac *mac) 8119 { 8120 struct bwn_softc *sc = mac->mac_sc; 8121 8122 wlan_assert_serialized(); 8123 8124 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8125 return; 8126 8127 callout_stop(&sc->sc_rfswitch_ch); 8128 callout_stop(&sc->sc_task_ch); 8129 callout_stop(&sc->sc_watchdog_ch); 8130 sc->sc_watchdog_timer = 0; 8131 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8132 BWN_READ_4(mac, BWN_INTR_MASK); 8133 bwn_mac_suspend(mac); 8134 8135 mac->mac_status = BWN_MAC_STATUS_INITED; 8136 } 8137 8138 static int 8139 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8140 { 8141 struct bwn_mac *up_dev = NULL; 8142 struct bwn_mac *down_dev; 8143 struct bwn_mac *mac; 8144 int err, status; 8145 uint8_t gmode; 8146 8147 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8148 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8149 mac->mac_phy.supports_2ghz) { 8150 up_dev = mac; 8151 gmode = 1; 8152 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8153 mac->mac_phy.supports_5ghz) { 8154 up_dev = mac; 8155 gmode = 0; 8156 } else { 8157 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8158 return (EINVAL); 8159 } 8160 if (up_dev != NULL) 8161 break; 8162 } 8163 if (up_dev == NULL) { 8164 device_printf(sc->sc_dev, "Could not find a device\n"); 8165 return (ENODEV); 8166 } 8167 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8168 return (0); 8169 8170 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8171 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8172 8173 down_dev = sc->sc_curmac; 8174 status = down_dev->mac_status; 8175 if (status >= BWN_MAC_STATUS_STARTED) 8176 bwn_core_stop(down_dev); 8177 if (status >= BWN_MAC_STATUS_INITED) 8178 bwn_core_exit(down_dev); 8179 8180 if (down_dev != up_dev) 8181 bwn_phy_reset(down_dev); 8182 8183 up_dev->mac_phy.gmode = gmode; 8184 if (status >= BWN_MAC_STATUS_INITED) { 8185 err = bwn_core_init(up_dev); 8186 if (err) { 8187 device_printf(sc->sc_dev, 8188 "fatal: failed to initialize for %s-GHz\n", 8189 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8190 goto fail; 8191 } 8192 } 8193 if (status >= BWN_MAC_STATUS_STARTED) 8194 bwn_core_start(up_dev); 8195 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8196 sc->sc_curmac = up_dev; 8197 8198 return (0); 8199 fail: 8200 sc->sc_curmac = NULL; 8201 return (err); 8202 } 8203 8204 static void 8205 bwn_rf_turnon(struct bwn_mac *mac) 8206 { 8207 8208 bwn_mac_suspend(mac); 8209 mac->mac_phy.rf_onoff(mac, 1); 8210 mac->mac_phy.rf_on = 1; 8211 bwn_mac_enable(mac); 8212 } 8213 8214 static void 8215 bwn_rf_turnoff(struct bwn_mac *mac) 8216 { 8217 8218 bwn_mac_suspend(mac); 8219 mac->mac_phy.rf_onoff(mac, 0); 8220 mac->mac_phy.rf_on = 0; 8221 bwn_mac_enable(mac); 8222 } 8223 8224 static void 8225 bwn_phy_reset(struct bwn_mac *mac) 8226 { 8227 struct bwn_softc *sc = mac->mac_sc; 8228 8229 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8230 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8231 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8232 DELAY(1000); 8233 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8234 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8235 BWN_TGSLOW_PHYRESET); 8236 DELAY(1000); 8237 } 8238 8239 static int 8240 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8241 { 8242 struct bwn_vap *bvp = BWN_VAP(vap); 8243 struct ieee80211com *ic= vap->iv_ic; 8244 struct ifnet *ifp = ic->ic_ifp; 8245 enum ieee80211_state ostate = vap->iv_state; 8246 struct bwn_softc *sc = ifp->if_softc; 8247 struct bwn_mac *mac = sc->sc_curmac; 8248 int error; 8249 8250 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8251 ieee80211_state_name[vap->iv_state], 8252 ieee80211_state_name[nstate]); 8253 8254 error = bvp->bv_newstate(vap, nstate, arg); 8255 if (error != 0) 8256 return (error); 8257 8258 bwn_led_newstate(mac, nstate); 8259 8260 /* 8261 * Clear the BSSID when we stop a STA 8262 */ 8263 if (vap->iv_opmode == IEEE80211_M_STA) { 8264 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8265 /* 8266 * Clear out the BSSID. If we reassociate to 8267 * the same AP, this will reinialize things 8268 * correctly... 8269 */ 8270 if (ic->ic_opmode == IEEE80211_M_STA && 8271 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8272 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8273 bwn_set_macaddr(mac); 8274 } 8275 } 8276 } 8277 8278 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8279 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8280 /* XXX nothing to do? */ 8281 } else if (nstate == IEEE80211_S_RUN) { 8282 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8283 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8284 bwn_set_opmode(mac); 8285 bwn_set_pretbtt(mac); 8286 bwn_spu_setdelay(mac, 0); 8287 bwn_set_macaddr(mac); 8288 } 8289 8290 return (error); 8291 } 8292 8293 static void 8294 bwn_set_pretbtt(struct bwn_mac *mac) 8295 { 8296 struct bwn_softc *sc = mac->mac_sc; 8297 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8298 uint16_t pretbtt; 8299 8300 if (ic->ic_opmode == IEEE80211_M_IBSS) 8301 pretbtt = 2; 8302 else 8303 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8304 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8305 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8306 } 8307 8308 static void 8309 bwn_intr(void *arg) 8310 { 8311 struct bwn_mac *mac = arg; 8312 struct bwn_softc *sc = mac->mac_sc; 8313 uint32_t reason; 8314 8315 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8316 (sc->sc_flags & BWN_FLAG_INVALID)) 8317 return; 8318 8319 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8320 if (reason == 0xffffffff) /* shared IRQ */ 8321 return; 8322 reason &= mac->mac_intr_mask; 8323 if (reason == 0) 8324 return; 8325 8326 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00; 8327 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8328 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8329 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8330 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8331 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8332 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8333 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8334 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8335 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8336 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8337 8338 /* Disable interrupts. */ 8339 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8340 8341 mac->mac_reason_intr = reason; 8342 8343 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8344 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8345 8346 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask); 8347 return; 8348 } 8349 8350 static void 8351 bwn_intrtask(void *arg, int npending) 8352 { 8353 struct bwn_mac *mac = arg; 8354 struct bwn_softc *sc = mac->mac_sc; 8355 struct ifnet *ifp = sc->sc_ifp; 8356 uint32_t merged = 0; 8357 int i, tx = 0, rx = 0; 8358 8359 wlan_serialize_enter(); 8360 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8361 (sc->sc_flags & BWN_FLAG_INVALID)) { 8362 wlan_serialize_exit(); 8363 return; 8364 } 8365 8366 for (i = 0; i < N(mac->mac_reason); i++) 8367 merged |= mac->mac_reason[i]; 8368 8369 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8370 device_printf(sc->sc_dev, "MAC trans error\n"); 8371 8372 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8373 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8374 mac->mac_phy.txerrors--; 8375 if (mac->mac_phy.txerrors == 0) { 8376 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8377 bwn_restart(mac, "PHY TX errors"); 8378 } 8379 } 8380 8381 if (merged & BWN_DMAINTR_FATALMASK) { 8382 device_printf(sc->sc_dev, 8383 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8384 mac->mac_reason[0], mac->mac_reason[1], 8385 mac->mac_reason[2], mac->mac_reason[3], 8386 mac->mac_reason[4], mac->mac_reason[5]); 8387 bwn_restart(mac, "DMA error"); 8388 wlan_serialize_exit(); 8389 return; 8390 } 8391 8392 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8393 bwn_intr_ucode_debug(mac); 8394 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8395 bwn_intr_tbtt_indication(mac); 8396 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8397 bwn_intr_atim_end(mac); 8398 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8399 bwn_intr_beacon(mac); 8400 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8401 bwn_intr_pmq(mac); 8402 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8403 bwn_intr_noise(mac); 8404 8405 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8406 if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) { 8407 device_printf(sc->sc_dev, "RX descriptor overflow\n"); 8408 bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx); 8409 } 8410 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8411 bwn_dma_rx(mac->mac_method.dma.rx); 8412 rx = 1; 8413 } 8414 } else 8415 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8416 8417 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8418 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8419 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8420 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8421 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8422 8423 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8424 bwn_intr_txeof(mac); 8425 tx = 1; 8426 } 8427 8428 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8429 8430 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8431 int evt = BWN_LED_EVENT_NONE; 8432 8433 if (tx && rx) { 8434 if (sc->sc_rx_rate > sc->sc_tx_rate) 8435 evt = BWN_LED_EVENT_RX; 8436 else 8437 evt = BWN_LED_EVENT_TX; 8438 } else if (tx) { 8439 evt = BWN_LED_EVENT_TX; 8440 } else if (rx) { 8441 evt = BWN_LED_EVENT_RX; 8442 } else if (rx == 0) { 8443 evt = BWN_LED_EVENT_POLL; 8444 } 8445 8446 if (evt != BWN_LED_EVENT_NONE) 8447 bwn_led_event(mac, evt); 8448 } 8449 8450 if (!ifq_is_oactive(&ifp->if_snd)) { 8451 if (!ifq_is_empty(&ifp->if_snd)) 8452 bwn_start_locked(ifp); 8453 } 8454 8455 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8456 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8457 8458 wlan_serialize_exit(); 8459 } 8460 8461 static void 8462 bwn_restart(struct bwn_mac *mac, const char *msg) 8463 { 8464 struct bwn_softc *sc = mac->mac_sc; 8465 struct ifnet *ifp = sc->sc_ifp; 8466 struct ieee80211com *ic = ifp->if_l2com; 8467 8468 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8469 return; 8470 8471 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8472 ieee80211_runtask(ic, &mac->mac_hwreset); 8473 } 8474 8475 static void 8476 bwn_intr_ucode_debug(struct bwn_mac *mac) 8477 { 8478 struct bwn_softc *sc = mac->mac_sc; 8479 uint16_t reason; 8480 8481 if (mac->mac_fw.opensource == 0) 8482 return; 8483 8484 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8485 switch (reason) { 8486 case BWN_DEBUGINTR_PANIC: 8487 bwn_handle_fwpanic(mac); 8488 break; 8489 case BWN_DEBUGINTR_DUMP_SHM: 8490 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8491 break; 8492 case BWN_DEBUGINTR_DUMP_REGS: 8493 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8494 break; 8495 case BWN_DEBUGINTR_MARKER: 8496 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8497 break; 8498 default: 8499 device_printf(sc->sc_dev, 8500 "ucode debug unknown reason: %#x\n", reason); 8501 } 8502 8503 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8504 BWN_DEBUGINTR_ACK); 8505 } 8506 8507 static void 8508 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8509 { 8510 struct bwn_softc *sc = mac->mac_sc; 8511 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8512 8513 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8514 bwn_psctl(mac, 0); 8515 if (ic->ic_opmode == IEEE80211_M_IBSS) 8516 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8517 } 8518 8519 static void 8520 bwn_intr_atim_end(struct bwn_mac *mac) 8521 { 8522 8523 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8524 BWN_WRITE_4(mac, BWN_MACCMD, 8525 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8526 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8527 } 8528 } 8529 8530 static void 8531 bwn_intr_beacon(struct bwn_mac *mac) 8532 { 8533 struct bwn_softc *sc = mac->mac_sc; 8534 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8535 uint32_t cmd, beacon0, beacon1; 8536 8537 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8538 ic->ic_opmode == IEEE80211_M_MBSS) 8539 return; 8540 8541 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8542 8543 cmd = BWN_READ_4(mac, BWN_MACCMD); 8544 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8545 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8546 8547 if (beacon0 && beacon1) { 8548 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8549 mac->mac_intr_mask |= BWN_INTR_BEACON; 8550 return; 8551 } 8552 8553 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8554 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8555 bwn_load_beacon0(mac); 8556 bwn_load_beacon1(mac); 8557 cmd = BWN_READ_4(mac, BWN_MACCMD); 8558 cmd |= BWN_MACCMD_BEACON0_VALID; 8559 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8560 } else { 8561 if (!beacon0) { 8562 bwn_load_beacon0(mac); 8563 cmd = BWN_READ_4(mac, BWN_MACCMD); 8564 cmd |= BWN_MACCMD_BEACON0_VALID; 8565 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8566 } else if (!beacon1) { 8567 bwn_load_beacon1(mac); 8568 cmd = BWN_READ_4(mac, BWN_MACCMD); 8569 cmd |= BWN_MACCMD_BEACON1_VALID; 8570 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8571 } 8572 } 8573 } 8574 8575 static void 8576 bwn_intr_pmq(struct bwn_mac *mac) 8577 { 8578 uint32_t tmp; 8579 8580 while (1) { 8581 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8582 if (!(tmp & 0x00000008)) 8583 break; 8584 } 8585 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8586 } 8587 8588 static void 8589 bwn_intr_noise(struct bwn_mac *mac) 8590 { 8591 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8592 uint16_t tmp; 8593 uint8_t noise[4]; 8594 uint8_t i, j; 8595 int32_t average; 8596 8597 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8598 return; 8599 8600 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8601 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8602 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8603 noise[3] == 0x7f) 8604 goto new; 8605 8606 KASSERT(mac->mac_noise.noi_nsamples < 8, 8607 ("%s:%d: fail", __func__, __LINE__)); 8608 i = mac->mac_noise.noi_nsamples; 8609 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8610 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8611 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8612 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8613 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8614 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8615 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8616 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8617 mac->mac_noise.noi_nsamples++; 8618 if (mac->mac_noise.noi_nsamples == 8) { 8619 average = 0; 8620 for (i = 0; i < 8; i++) { 8621 for (j = 0; j < 4; j++) 8622 average += mac->mac_noise.noi_samples[i][j]; 8623 } 8624 average = (((average / 32) * 125) + 64) / 128; 8625 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8626 if (tmp >= 8) 8627 average += 2; 8628 else 8629 average -= 25; 8630 average -= (tmp == 8) ? 72 : 48; 8631 8632 mac->mac_stats.link_noise = average; 8633 mac->mac_noise.noi_running = 0; 8634 return; 8635 } 8636 new: 8637 bwn_noise_gensample(mac); 8638 } 8639 8640 static int 8641 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8642 { 8643 struct bwn_mac *mac = prq->prq_mac; 8644 struct bwn_softc *sc = mac->mac_sc; 8645 unsigned int i; 8646 8647 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8648 return (0); 8649 8650 for (i = 0; i < 5000; i++) { 8651 if (bwn_pio_rxeof(prq) == 0) 8652 break; 8653 } 8654 if (i >= 5000) 8655 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8656 return ((i > 0) ? 1 : 0); 8657 } 8658 8659 static void 8660 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr) 8661 { 8662 int curslot, prevslot; 8663 8664 curslot = dr->get_curslot(dr); 8665 if (curslot == 0) 8666 prevslot = dr->dr_numslots - 1; 8667 else 8668 prevslot = curslot - 1; 8669 dr->set_curslot(dr, prevslot); 8670 } 8671 8672 static void 8673 bwn_dma_rx(struct bwn_dma_ring *dr) 8674 { 8675 int slot, curslot; 8676 8677 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8678 curslot = dr->get_curslot(dr); 8679 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8680 ("%s:%d: fail", __func__, __LINE__)); 8681 8682 slot = dr->dr_curslot; 8683 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8684 bwn_dma_rxeof(dr, &slot); 8685 8686 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8687 BUS_DMASYNC_PREWRITE); 8688 8689 dr->set_curslot(dr, slot); 8690 dr->dr_curslot = slot; 8691 } 8692 8693 static void 8694 bwn_intr_txeof(struct bwn_mac *mac) 8695 { 8696 struct bwn_txstatus stat; 8697 uint32_t stat0, stat1; 8698 uint16_t tmp; 8699 8700 while (1) { 8701 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8702 if (!(stat0 & 0x00000001)) 8703 break; 8704 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8705 8706 stat.cookie = (stat0 >> 16); 8707 stat.seq = (stat1 & 0x0000ffff); 8708 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8709 tmp = (stat0 & 0x0000ffff); 8710 stat.framecnt = ((tmp & 0xf000) >> 12); 8711 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8712 stat.sreason = ((tmp & 0x001c) >> 2); 8713 stat.pm = (tmp & 0x0080) ? 1 : 0; 8714 stat.im = (tmp & 0x0040) ? 1 : 0; 8715 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8716 stat.ack = (tmp & 0x0002) ? 1 : 0; 8717 8718 bwn_handle_txeof(mac, &stat); 8719 } 8720 } 8721 8722 static void 8723 bwn_hwreset(void *arg, int npending) 8724 { 8725 struct bwn_mac *mac = arg; 8726 struct bwn_softc *sc = mac->mac_sc; 8727 int error = 0; 8728 int prev_status; 8729 8730 wlan_serialize_enter(); 8731 8732 prev_status = mac->mac_status; 8733 if (prev_status >= BWN_MAC_STATUS_STARTED) 8734 bwn_core_stop(mac); 8735 if (prev_status >= BWN_MAC_STATUS_INITED) 8736 bwn_core_exit(mac); 8737 8738 if (prev_status >= BWN_MAC_STATUS_INITED) { 8739 error = bwn_core_init(mac); 8740 if (error) 8741 goto out; 8742 } 8743 if (prev_status >= BWN_MAC_STATUS_STARTED) 8744 bwn_core_start(mac); 8745 out: 8746 if (error) { 8747 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8748 sc->sc_curmac = NULL; 8749 } 8750 wlan_serialize_exit(); 8751 } 8752 8753 static void 8754 bwn_handle_fwpanic(struct bwn_mac *mac) 8755 { 8756 struct bwn_softc *sc = mac->mac_sc; 8757 uint16_t reason; 8758 8759 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8760 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8761 8762 if (reason == BWN_FWPANIC_RESTART) 8763 bwn_restart(mac, "ucode panic"); 8764 } 8765 8766 static void 8767 bwn_load_beacon0(struct bwn_mac *mac) 8768 { 8769 8770 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8771 } 8772 8773 static void 8774 bwn_load_beacon1(struct bwn_mac *mac) 8775 { 8776 8777 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8778 } 8779 8780 static uint32_t 8781 bwn_jssi_read(struct bwn_mac *mac) 8782 { 8783 uint32_t val = 0; 8784 8785 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8786 val <<= 16; 8787 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8788 8789 return (val); 8790 } 8791 8792 static void 8793 bwn_noise_gensample(struct bwn_mac *mac) 8794 { 8795 uint32_t jssi = 0x7f7f7f7f; 8796 8797 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8798 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8799 BWN_WRITE_4(mac, BWN_MACCMD, 8800 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8801 } 8802 8803 static int 8804 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8805 { 8806 return (dr->dr_numslots - dr->dr_usedslot); 8807 } 8808 8809 static int 8810 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8811 { 8812 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8813 ("%s:%d: fail", __func__, __LINE__)); 8814 if (slot == dr->dr_numslots - 1) 8815 return (0); 8816 return (slot + 1); 8817 } 8818 8819 static void 8820 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8821 { 8822 struct bwn_mac *mac = dr->dr_mac; 8823 struct bwn_softc *sc = mac->mac_sc; 8824 struct bwn_dma *dma = &mac->mac_method.dma; 8825 struct bwn_dmadesc_generic *desc; 8826 struct bwn_dmadesc_meta *meta; 8827 struct bwn_rxhdr4 *rxhdr; 8828 struct ifnet *ifp = sc->sc_ifp; 8829 struct mbuf *m; 8830 uint32_t macstat; 8831 int32_t tmp; 8832 int cnt = 0; 8833 uint16_t len; 8834 8835 dr->getdesc(dr, *slot, &desc, &meta); 8836 8837 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8838 m = meta->mt_m; 8839 8840 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8841 ifp->if_ierrors++; 8842 return; 8843 } 8844 8845 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8846 len = le16toh(rxhdr->frame_len); 8847 if (len <= 0) { 8848 ifp->if_ierrors++; 8849 return; 8850 } 8851 if (bwn_dma_check_redzone(dr, m)) { 8852 device_printf(sc->sc_dev, "redzone error.\n"); 8853 bwn_dma_set_redzone(dr, m); 8854 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8855 BUS_DMASYNC_PREWRITE); 8856 return; 8857 } 8858 if (len > dr->dr_rx_bufsize) { 8859 tmp = len; 8860 while (1) { 8861 dr->getdesc(dr, *slot, &desc, &meta); 8862 bwn_dma_set_redzone(dr, meta->mt_m); 8863 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8864 BUS_DMASYNC_PREWRITE); 8865 *slot = bwn_dma_nextslot(dr, *slot); 8866 cnt++; 8867 tmp -= dr->dr_rx_bufsize; 8868 if (tmp <= 0) 8869 break; 8870 } 8871 device_printf(sc->sc_dev, "too small buffer " 8872 "(len %u buffer %u dropped %d)\n", 8873 len, dr->dr_rx_bufsize, cnt); 8874 return; 8875 } 8876 macstat = le32toh(rxhdr->mac_status); 8877 if (macstat & BWN_RX_MAC_FCSERR) { 8878 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8879 device_printf(sc->sc_dev, "RX drop\n"); 8880 return; 8881 } 8882 } 8883 8884 m->m_pkthdr.rcvif = ifp; 8885 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8886 m_adj(m, dr->dr_frameoffset); 8887 8888 bwn_rxeof(dr->dr_mac, m, rxhdr); 8889 } 8890 8891 static void 8892 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8893 { 8894 struct bwn_dma_ring *dr; 8895 struct bwn_dmadesc_generic *desc; 8896 struct bwn_dmadesc_meta *meta; 8897 struct bwn_pio_txqueue *tq; 8898 struct bwn_pio_txpkt *tp = NULL; 8899 struct bwn_softc *sc = mac->mac_sc; 8900 struct bwn_stats *stats = &mac->mac_stats; 8901 struct ieee80211_node *ni; 8902 struct ieee80211vap *vap; 8903 int retrycnt = 0, slot; 8904 8905 if (status->im) 8906 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8907 if (status->ampdu) 8908 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8909 if (status->rtscnt) { 8910 if (status->rtscnt == 0xf) 8911 stats->rtsfail++; 8912 else 8913 stats->rts++; 8914 } 8915 8916 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8917 if (status->ack) { 8918 dr = bwn_dma_parse_cookie(mac, status, 8919 status->cookie, &slot); 8920 if (dr == NULL) { 8921 device_printf(sc->sc_dev, 8922 "failed to parse cookie\n"); 8923 return; 8924 } 8925 while (1) { 8926 dr->getdesc(dr, slot, &desc, &meta); 8927 if (meta->mt_islast) { 8928 ni = meta->mt_ni; 8929 vap = ni->ni_vap; 8930 ieee80211_ratectl_tx_complete(vap, ni, 8931 status->ack ? 8932 IEEE80211_RATECTL_TX_SUCCESS : 8933 IEEE80211_RATECTL_TX_FAILURE, 8934 &retrycnt, 0); 8935 break; 8936 } 8937 slot = bwn_dma_nextslot(dr, slot); 8938 } 8939 } 8940 bwn_dma_handle_txeof(mac, status); 8941 } else { 8942 if (status->ack) { 8943 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 8944 if (tq == NULL) { 8945 device_printf(sc->sc_dev, 8946 "failed to parse cookie\n"); 8947 return; 8948 } 8949 ni = tp->tp_ni; 8950 vap = ni->ni_vap; 8951 ieee80211_ratectl_tx_complete(vap, ni, 8952 status->ack ? 8953 IEEE80211_RATECTL_TX_SUCCESS : 8954 IEEE80211_RATECTL_TX_FAILURE, 8955 &retrycnt, 0); 8956 } 8957 bwn_pio_handle_txeof(mac, status); 8958 } 8959 8960 bwn_phy_txpower_check(mac, 0); 8961 } 8962 8963 static uint8_t 8964 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 8965 { 8966 struct bwn_mac *mac = prq->prq_mac; 8967 struct bwn_softc *sc = mac->mac_sc; 8968 struct bwn_rxhdr4 rxhdr; 8969 struct ifnet *ifp = sc->sc_ifp; 8970 struct mbuf *m; 8971 uint32_t ctl32, macstat, v32; 8972 unsigned int i, padding; 8973 uint16_t ctl16, len, totlen, v16; 8974 unsigned char *mp; 8975 char *data; 8976 8977 memset(&rxhdr, 0, sizeof(rxhdr)); 8978 8979 if (prq->prq_rev >= 8) { 8980 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8981 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 8982 return (0); 8983 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 8984 BWN_PIO8_RXCTL_FRAMEREADY); 8985 for (i = 0; i < 10; i++) { 8986 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8987 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 8988 goto ready; 8989 DELAY(10); 8990 } 8991 } else { 8992 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8993 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 8994 return (0); 8995 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 8996 BWN_PIO_RXCTL_FRAMEREADY); 8997 for (i = 0; i < 10; i++) { 8998 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8999 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9000 goto ready; 9001 DELAY(10); 9002 } 9003 } 9004 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9005 return (1); 9006 ready: 9007 if (prq->prq_rev >= 8) 9008 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9009 prq->prq_base + BWN_PIO8_RXDATA); 9010 else 9011 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9012 prq->prq_base + BWN_PIO_RXDATA); 9013 len = le16toh(rxhdr.frame_len); 9014 if (len > 0x700) { 9015 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9016 goto error; 9017 } 9018 if (len == 0) { 9019 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9020 goto error; 9021 } 9022 9023 macstat = le32toh(rxhdr.mac_status); 9024 if (macstat & BWN_RX_MAC_FCSERR) { 9025 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9026 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9027 goto error; 9028 } 9029 } 9030 9031 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9032 totlen = len + padding; 9033 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9034 m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR); 9035 if (m == NULL) { 9036 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9037 goto error; 9038 } 9039 mp = mtod(m, unsigned char *); 9040 if (prq->prq_rev >= 8) { 9041 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9042 prq->prq_base + BWN_PIO8_RXDATA); 9043 if (totlen & 3) { 9044 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9045 data = &(mp[totlen - 1]); 9046 switch (totlen & 3) { 9047 case 3: 9048 *data = (v32 >> 16); 9049 data--; 9050 case 2: 9051 *data = (v32 >> 8); 9052 data--; 9053 case 1: 9054 *data = v32; 9055 } 9056 } 9057 } else { 9058 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9059 prq->prq_base + BWN_PIO_RXDATA); 9060 if (totlen & 1) { 9061 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9062 mp[totlen - 1] = v16; 9063 } 9064 } 9065 9066 m->m_pkthdr.rcvif = ifp; 9067 m->m_len = m->m_pkthdr.len = totlen; 9068 9069 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9070 9071 return (1); 9072 error: 9073 if (prq->prq_rev >= 8) 9074 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9075 BWN_PIO8_RXCTL_DATAREADY); 9076 else 9077 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9078 return (1); 9079 } 9080 9081 static int 9082 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9083 struct bwn_dmadesc_meta *meta, int init) 9084 { 9085 struct bwn_mac *mac = dr->dr_mac; 9086 struct bwn_dma *dma = &mac->mac_method.dma; 9087 struct bwn_rxhdr4 *hdr; 9088 bus_dmamap_t map; 9089 bus_addr_t paddr; 9090 struct mbuf *m; 9091 int error; 9092 9093 m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR); 9094 if (m == NULL) { 9095 error = ENOBUFS; 9096 9097 /* 9098 * If the NIC is up and running, we need to: 9099 * - Clear RX buffer's header. 9100 * - Restore RX descriptor settings. 9101 */ 9102 if (init) 9103 return (error); 9104 else 9105 goto back; 9106 } 9107 m->m_len = m->m_pkthdr.len = MCLBYTES; 9108 9109 bwn_dma_set_redzone(dr, m); 9110 9111 /* 9112 * Try to load RX buf into temporary DMA map 9113 */ 9114 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9115 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9116 if (error) { 9117 m_freem(m); 9118 9119 /* 9120 * See the comment above 9121 */ 9122 if (init) 9123 return (error); 9124 else 9125 goto back; 9126 } 9127 9128 if (!init) 9129 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9130 meta->mt_m = m; 9131 meta->mt_paddr = paddr; 9132 9133 /* 9134 * Swap RX buf's DMA map with the loaded temporary one 9135 */ 9136 map = meta->mt_dmap; 9137 meta->mt_dmap = dr->dr_spare_dmap; 9138 dr->dr_spare_dmap = map; 9139 9140 back: 9141 /* 9142 * Clear RX buf header 9143 */ 9144 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9145 bzero(hdr, sizeof(*hdr)); 9146 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9147 BUS_DMASYNC_PREWRITE); 9148 9149 /* 9150 * Setup RX buf descriptor 9151 */ 9152 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9153 sizeof(*hdr), 0, 0, 0); 9154 return (error); 9155 } 9156 9157 static void 9158 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9159 bus_size_t mapsz __unused, int error) 9160 { 9161 9162 if (!error) { 9163 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9164 *((bus_addr_t *)arg) = seg->ds_addr; 9165 } 9166 } 9167 9168 static int 9169 bwn_hwrate2ieeerate(int rate) 9170 { 9171 9172 switch (rate) { 9173 case BWN_CCK_RATE_1MB: 9174 return (2); 9175 case BWN_CCK_RATE_2MB: 9176 return (4); 9177 case BWN_CCK_RATE_5MB: 9178 return (11); 9179 case BWN_CCK_RATE_11MB: 9180 return (22); 9181 case BWN_OFDM_RATE_6MB: 9182 return (12); 9183 case BWN_OFDM_RATE_9MB: 9184 return (18); 9185 case BWN_OFDM_RATE_12MB: 9186 return (24); 9187 case BWN_OFDM_RATE_18MB: 9188 return (36); 9189 case BWN_OFDM_RATE_24MB: 9190 return (48); 9191 case BWN_OFDM_RATE_36MB: 9192 return (72); 9193 case BWN_OFDM_RATE_48MB: 9194 return (96); 9195 case BWN_OFDM_RATE_54MB: 9196 return (108); 9197 default: 9198 kprintf("Ooops\n"); 9199 return (0); 9200 } 9201 } 9202 9203 static void 9204 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9205 { 9206 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9207 struct bwn_plcp6 *plcp; 9208 struct bwn_softc *sc = mac->mac_sc; 9209 struct ieee80211_frame_min *wh; 9210 struct ieee80211_node *ni; 9211 struct ifnet *ifp = sc->sc_ifp; 9212 struct ieee80211com *ic = ifp->if_l2com; 9213 uint32_t macstat; 9214 int padding, rate, rssi = 0, noise = 0, type; 9215 uint16_t phytype, phystat0, phystat3, chanstat; 9216 unsigned char *mp = mtod(m, unsigned char *); 9217 static int rx_mac_dec_rpt = 0; 9218 9219 phystat0 = le16toh(rxhdr->phy_status0); 9220 phystat3 = le16toh(rxhdr->phy_status3); 9221 macstat = le32toh(rxhdr->mac_status); 9222 chanstat = le16toh(rxhdr->channel); 9223 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9224 9225 if (macstat & BWN_RX_MAC_FCSERR) 9226 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9227 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9228 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9229 if (macstat & BWN_RX_MAC_DECERR) 9230 goto drop; 9231 9232 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9233 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9234 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9235 m->m_pkthdr.len); 9236 goto drop; 9237 } 9238 plcp = (struct bwn_plcp6 *)(mp + padding); 9239 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9240 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9241 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9242 m->m_pkthdr.len); 9243 goto drop; 9244 } 9245 wh = mtod(m, struct ieee80211_frame_min *); 9246 9247 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9248 device_printf(sc->sc_dev, 9249 "RX decryption attempted (old %d keyidx %#x)\n", 9250 BWN_ISOLDFMT(mac), 9251 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9252 9253 /* XXX calculating RSSI & noise & antenna */ 9254 9255 if (phystat0 & BWN_RX_PHYST0_OFDM) 9256 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9257 phytype == BWN_PHYTYPE_A); 9258 else 9259 rate = bwn_plcp_get_cckrate(mac, plcp); 9260 if (rate == -1) { 9261 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9262 goto drop; 9263 } 9264 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9265 9266 /* RX radio tap */ 9267 if (ieee80211_radiotap_active(ic)) 9268 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9269 m_adj(m, -IEEE80211_CRC_LEN); 9270 9271 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9272 noise = mac->mac_stats.link_noise; 9273 9274 ifp->if_ipackets++; 9275 9276 ni = ieee80211_find_rxnode(ic, wh); 9277 if (ni != NULL) { 9278 type = ieee80211_input(ni, m, rssi, noise); 9279 ieee80211_free_node(ni); 9280 } else 9281 type = ieee80211_input_all(ic, m, rssi, noise); 9282 9283 return; 9284 drop: 9285 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9286 } 9287 9288 static void 9289 bwn_dma_handle_txeof(struct bwn_mac *mac, 9290 const struct bwn_txstatus *status) 9291 { 9292 struct bwn_dma *dma = &mac->mac_method.dma; 9293 struct bwn_dma_ring *dr; 9294 struct bwn_dmadesc_generic *desc; 9295 struct bwn_dmadesc_meta *meta; 9296 struct bwn_softc *sc = mac->mac_sc; 9297 struct ieee80211_node *ni; 9298 struct ifnet *ifp = sc->sc_ifp; 9299 struct mbuf *m; 9300 int slot; 9301 9302 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9303 if (dr == NULL) { 9304 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9305 return; 9306 } 9307 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9308 9309 while (1) { 9310 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9311 ("%s:%d: fail", __func__, __LINE__)); 9312 dr->getdesc(dr, slot, &desc, &meta); 9313 9314 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 9315 bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap, 9316 BUS_DMASYNC_POSTWRITE); 9317 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 9318 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9319 } 9320 9321 if (meta->mt_islast) { 9322 KASSERT(meta->mt_m != NULL, 9323 ("%s:%d: fail", __func__, __LINE__)); 9324 9325 ni = meta->mt_ni; 9326 m = meta->mt_m; 9327 if (ni != NULL) { 9328 /* 9329 * Do any tx complete callback. Note this must 9330 * be done before releasing the node reference. 9331 */ 9332 if (m->m_flags & M_TXCB) 9333 ieee80211_process_callback(ni, m, 0); 9334 ieee80211_free_node(ni); 9335 meta->mt_ni = NULL; 9336 } 9337 m_freem(m); 9338 meta->mt_m = NULL; 9339 } else { 9340 KASSERT(meta->mt_m == NULL, 9341 ("%s:%d: fail", __func__, __LINE__)); 9342 } 9343 9344 dr->dr_usedslot--; 9345 if (meta->mt_islast) { 9346 ifp->if_opackets++; 9347 break; 9348 } 9349 slot = bwn_dma_nextslot(dr, slot); 9350 } 9351 sc->sc_watchdog_timer = 0; 9352 if (dr->dr_stop) { 9353 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9354 ("%s:%d: fail", __func__, __LINE__)); 9355 ifq_clr_oactive(&ifp->if_snd); 9356 dr->dr_stop = 0; 9357 } 9358 } 9359 9360 static void 9361 bwn_pio_handle_txeof(struct bwn_mac *mac, 9362 const struct bwn_txstatus *status) 9363 { 9364 struct bwn_pio_txqueue *tq; 9365 struct bwn_pio_txpkt *tp = NULL; 9366 struct bwn_softc *sc = mac->mac_sc; 9367 struct ifnet *ifp = sc->sc_ifp; 9368 9369 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9370 if (tq == NULL) 9371 return; 9372 9373 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9374 tq->tq_free++; 9375 9376 if (tp->tp_ni != NULL) { 9377 /* 9378 * Do any tx complete callback. Note this must 9379 * be done before releasing the node reference. 9380 */ 9381 if (tp->tp_m->m_flags & M_TXCB) 9382 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9383 ieee80211_free_node(tp->tp_ni); 9384 tp->tp_ni = NULL; 9385 } 9386 m_freem(tp->tp_m); 9387 tp->tp_m = NULL; 9388 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9389 9390 ifp->if_opackets++; 9391 9392 sc->sc_watchdog_timer = 0; 9393 if (tq->tq_stop) { 9394 ifq_clr_oactive(&ifp->if_snd); 9395 tq->tq_stop = 0; 9396 } 9397 } 9398 9399 static void 9400 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9401 { 9402 struct bwn_softc *sc = mac->mac_sc; 9403 struct bwn_phy *phy = &mac->mac_phy; 9404 struct ifnet *ifp = sc->sc_ifp; 9405 struct ieee80211com *ic = ifp->if_l2com; 9406 unsigned long now; 9407 int result; 9408 9409 BWN_GETTIME(now); 9410 9411 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9412 return; 9413 phy->nexttime = now + 2 * 1000; 9414 9415 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9416 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9417 return; 9418 9419 if (phy->recalc_txpwr != NULL) { 9420 result = phy->recalc_txpwr(mac, 9421 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9422 if (result == BWN_TXPWR_RES_DONE) 9423 return; 9424 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9425 ("%s: fail", __func__)); 9426 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9427 9428 ieee80211_runtask(ic, &mac->mac_txpower); 9429 } 9430 } 9431 9432 static uint16_t 9433 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9434 { 9435 9436 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9437 } 9438 9439 static uint32_t 9440 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9441 { 9442 9443 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9444 } 9445 9446 static void 9447 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9448 { 9449 9450 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9451 } 9452 9453 static void 9454 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9455 { 9456 9457 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9458 } 9459 9460 static int 9461 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9462 { 9463 9464 switch (rate) { 9465 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9466 case 12: 9467 return (BWN_OFDM_RATE_6MB); 9468 case 18: 9469 return (BWN_OFDM_RATE_9MB); 9470 case 24: 9471 return (BWN_OFDM_RATE_12MB); 9472 case 36: 9473 return (BWN_OFDM_RATE_18MB); 9474 case 48: 9475 return (BWN_OFDM_RATE_24MB); 9476 case 72: 9477 return (BWN_OFDM_RATE_36MB); 9478 case 96: 9479 return (BWN_OFDM_RATE_48MB); 9480 case 108: 9481 return (BWN_OFDM_RATE_54MB); 9482 /* CCK rates (NB: not IEEE std, device-specific) */ 9483 case 2: 9484 return (BWN_CCK_RATE_1MB); 9485 case 4: 9486 return (BWN_CCK_RATE_2MB); 9487 case 11: 9488 return (BWN_CCK_RATE_5MB); 9489 case 22: 9490 return (BWN_CCK_RATE_11MB); 9491 } 9492 9493 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9494 return (BWN_CCK_RATE_1MB); 9495 } 9496 9497 static int 9498 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9499 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9500 { 9501 const struct bwn_phy *phy = &mac->mac_phy; 9502 struct bwn_softc *sc = mac->mac_sc; 9503 struct ieee80211_frame *wh; 9504 struct ieee80211_frame *protwh; 9505 struct ieee80211_frame_cts *cts; 9506 struct ieee80211_frame_rts *rts; 9507 const struct ieee80211_txparam *tp; 9508 struct ieee80211vap *vap = ni->ni_vap; 9509 struct ifnet *ifp = sc->sc_ifp; 9510 struct ieee80211com *ic = ifp->if_l2com; 9511 struct mbuf *mprot; 9512 unsigned int len; 9513 uint32_t macctl = 0; 9514 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9515 uint16_t phyctl = 0; 9516 uint8_t rate, rate_fb; 9517 9518 wh = mtod(m, struct ieee80211_frame *); 9519 memset(txhdr, 0, sizeof(*txhdr)); 9520 9521 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9522 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9523 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9524 9525 /* 9526 * Find TX rate 9527 */ 9528 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9529 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9530 rate = rate_fb = tp->mgmtrate; 9531 else if (ismcast) 9532 rate = rate_fb = tp->mcastrate; 9533 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9534 rate = rate_fb = tp->ucastrate; 9535 else { 9536 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9537 rate = ni->ni_txrate; 9538 9539 if (rix > 0) 9540 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9541 IEEE80211_RATE_VAL; 9542 else 9543 rate_fb = rate; 9544 } 9545 9546 sc->sc_tx_rate = rate; 9547 9548 rate = bwn_ieeerate2hwrate(sc, rate); 9549 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9550 9551 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9552 bwn_plcp_getcck(rate); 9553 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9554 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9555 9556 if ((rate_fb == rate) || 9557 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9558 (*(u_int16_t *)wh->i_dur == htole16(0))) 9559 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9560 else 9561 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9562 m->m_pkthdr.len, rate, isshort); 9563 9564 /* XXX TX encryption */ 9565 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9566 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9567 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9568 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9569 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9570 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9571 9572 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9573 BWN_TX_EFT_FB_CCK; 9574 txhdr->chan = phy->chan; 9575 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9576 BWN_TX_PHY_ENC_CCK; 9577 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9578 rate == BWN_CCK_RATE_11MB)) 9579 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9580 9581 /* XXX TX antenna selection */ 9582 9583 switch (bwn_antenna_sanitize(mac, 0)) { 9584 case 0: 9585 phyctl |= BWN_TX_PHY_ANT01AUTO; 9586 break; 9587 case 1: 9588 phyctl |= BWN_TX_PHY_ANT0; 9589 break; 9590 case 2: 9591 phyctl |= BWN_TX_PHY_ANT1; 9592 break; 9593 case 3: 9594 phyctl |= BWN_TX_PHY_ANT2; 9595 break; 9596 case 4: 9597 phyctl |= BWN_TX_PHY_ANT3; 9598 break; 9599 default: 9600 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9601 } 9602 9603 if (!ismcast) 9604 macctl |= BWN_TX_MAC_ACK; 9605 9606 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9607 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9608 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9609 macctl |= BWN_TX_MAC_LONGFRAME; 9610 9611 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9612 /* XXX RTS rate is always 1MB??? */ 9613 rts_rate = BWN_CCK_RATE_1MB; 9614 rts_rate_fb = bwn_get_fbrate(rts_rate); 9615 9616 protdur = ieee80211_compute_duration(ic->ic_rt, 9617 m->m_pkthdr.len, rate, isshort) + 9618 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9619 9620 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9621 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9622 (txhdr->body.old.rts_frame) : 9623 (txhdr->body.new.rts_frame)); 9624 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9625 protdur); 9626 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9627 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9628 mprot->m_pkthdr.len); 9629 m_freem(mprot); 9630 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9631 len = sizeof(struct ieee80211_frame_cts); 9632 } else { 9633 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9634 (txhdr->body.old.rts_frame) : 9635 (txhdr->body.new.rts_frame)); 9636 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9637 isshort); 9638 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9639 wh->i_addr2, protdur); 9640 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9641 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9642 mprot->m_pkthdr.len); 9643 m_freem(mprot); 9644 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9645 len = sizeof(struct ieee80211_frame_rts); 9646 } 9647 len += IEEE80211_CRC_LEN; 9648 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9649 &txhdr->body.old.rts_plcp : 9650 &txhdr->body.new.rts_plcp), len, rts_rate); 9651 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9652 rts_rate_fb); 9653 9654 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9655 (&txhdr->body.old.rts_frame) : 9656 (&txhdr->body.new.rts_frame)); 9657 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9658 9659 if (BWN_ISOFDMRATE(rts_rate)) { 9660 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9661 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9662 } else { 9663 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9664 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9665 } 9666 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9667 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9668 } 9669 9670 if (BWN_ISOLDFMT(mac)) 9671 txhdr->body.old.cookie = htole16(cookie); 9672 else 9673 txhdr->body.new.cookie = htole16(cookie); 9674 9675 txhdr->macctl = htole32(macctl); 9676 txhdr->phyctl = htole16(phyctl); 9677 9678 /* 9679 * TX radio tap 9680 */ 9681 if (ieee80211_radiotap_active_vap(vap)) { 9682 sc->sc_tx_th.wt_flags = 0; 9683 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9684 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9685 if (isshort && 9686 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9687 rate == BWN_CCK_RATE_11MB)) 9688 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9689 sc->sc_tx_th.wt_rate = rate; 9690 9691 ieee80211_radiotap_tx(vap, m); 9692 } 9693 9694 return (0); 9695 } 9696 9697 static void 9698 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9699 const uint8_t rate) 9700 { 9701 uint32_t d, plen; 9702 uint8_t *raw = plcp->o.raw; 9703 9704 if (BWN_ISOFDMRATE(rate)) { 9705 d = bwn_plcp_getofdm(rate); 9706 KASSERT(!(octets & 0xf000), 9707 ("%s:%d: fail", __func__, __LINE__)); 9708 d |= (octets << 5); 9709 plcp->o.data = htole32(d); 9710 } else { 9711 plen = octets * 16 / rate; 9712 if ((octets * 16 % rate) > 0) { 9713 plen++; 9714 if ((rate == BWN_CCK_RATE_11MB) 9715 && ((octets * 8 % 11) < 4)) { 9716 raw[1] = 0x84; 9717 } else 9718 raw[1] = 0x04; 9719 } else 9720 raw[1] = 0x04; 9721 plcp->o.data |= htole32(plen << 16); 9722 raw[0] = bwn_plcp_getcck(rate); 9723 } 9724 } 9725 9726 static uint8_t 9727 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9728 { 9729 struct bwn_softc *sc = mac->mac_sc; 9730 uint8_t mask; 9731 9732 if (n == 0) 9733 return (0); 9734 if (mac->mac_phy.gmode) 9735 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9736 else 9737 mask = siba_sprom_get_ant_a(sc->sc_dev); 9738 if (!(mask & (1 << (n - 1)))) 9739 return (0); 9740 return (n); 9741 } 9742 9743 static uint8_t 9744 bwn_get_fbrate(uint8_t bitrate) 9745 { 9746 switch (bitrate) { 9747 case BWN_CCK_RATE_1MB: 9748 return (BWN_CCK_RATE_1MB); 9749 case BWN_CCK_RATE_2MB: 9750 return (BWN_CCK_RATE_1MB); 9751 case BWN_CCK_RATE_5MB: 9752 return (BWN_CCK_RATE_2MB); 9753 case BWN_CCK_RATE_11MB: 9754 return (BWN_CCK_RATE_5MB); 9755 case BWN_OFDM_RATE_6MB: 9756 return (BWN_CCK_RATE_5MB); 9757 case BWN_OFDM_RATE_9MB: 9758 return (BWN_OFDM_RATE_6MB); 9759 case BWN_OFDM_RATE_12MB: 9760 return (BWN_OFDM_RATE_9MB); 9761 case BWN_OFDM_RATE_18MB: 9762 return (BWN_OFDM_RATE_12MB); 9763 case BWN_OFDM_RATE_24MB: 9764 return (BWN_OFDM_RATE_18MB); 9765 case BWN_OFDM_RATE_36MB: 9766 return (BWN_OFDM_RATE_24MB); 9767 case BWN_OFDM_RATE_48MB: 9768 return (BWN_OFDM_RATE_36MB); 9769 case BWN_OFDM_RATE_54MB: 9770 return (BWN_OFDM_RATE_48MB); 9771 } 9772 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9773 return (0); 9774 } 9775 9776 static uint32_t 9777 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9778 uint32_t ctl, const void *_data, int len) 9779 { 9780 struct bwn_softc *sc = mac->mac_sc; 9781 uint32_t value = 0; 9782 const uint8_t *data = _data; 9783 9784 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9785 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9786 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9787 9788 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9789 tq->tq_base + BWN_PIO8_TXDATA); 9790 if (len & 3) { 9791 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9792 BWN_PIO8_TXCTL_24_31); 9793 data = &(data[len - 1]); 9794 switch (len & 3) { 9795 case 3: 9796 ctl |= BWN_PIO8_TXCTL_16_23; 9797 value |= (uint32_t)(*data) << 16; 9798 data--; 9799 case 2: 9800 ctl |= BWN_PIO8_TXCTL_8_15; 9801 value |= (uint32_t)(*data) << 8; 9802 data--; 9803 case 1: 9804 value |= (uint32_t)(*data); 9805 } 9806 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9807 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9808 } 9809 9810 return (ctl); 9811 } 9812 9813 static void 9814 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9815 uint16_t offset, uint32_t value) 9816 { 9817 9818 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9819 } 9820 9821 static uint16_t 9822 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9823 uint16_t ctl, const void *_data, int len) 9824 { 9825 struct bwn_softc *sc = mac->mac_sc; 9826 const uint8_t *data = _data; 9827 9828 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9829 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9830 9831 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9832 tq->tq_base + BWN_PIO_TXDATA); 9833 if (len & 1) { 9834 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9835 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9836 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9837 } 9838 9839 return (ctl); 9840 } 9841 9842 static uint16_t 9843 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9844 uint16_t ctl, struct mbuf *m0) 9845 { 9846 int i, j = 0; 9847 uint16_t data = 0; 9848 const uint8_t *buf; 9849 struct mbuf *m = m0; 9850 9851 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9852 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9853 9854 for (; m != NULL; m = m->m_next) { 9855 buf = mtod(m, const uint8_t *); 9856 for (i = 0; i < m->m_len; i++) { 9857 if (!((j++) % 2)) 9858 data |= buf[i]; 9859 else { 9860 data |= (buf[i] << 8); 9861 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9862 data = 0; 9863 } 9864 } 9865 } 9866 if (m0->m_pkthdr.len % 2) { 9867 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9868 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9869 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9870 } 9871 9872 return (ctl); 9873 } 9874 9875 static void 9876 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9877 { 9878 9879 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9880 return; 9881 BWN_WRITE_2(mac, 0x684, 510 + time); 9882 9883 /* 9884 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a 9885 * a severe performance penalty (especially when sending). 9886 */ 9887 #if 0 9888 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9889 #endif 9890 } 9891 9892 static struct bwn_dma_ring * 9893 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9894 { 9895 9896 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9897 return (mac->mac_method.dma.wme[WME_AC_BE]); 9898 9899 switch (prio) { 9900 case 3: 9901 return (mac->mac_method.dma.wme[WME_AC_VO]); 9902 case 2: 9903 return (mac->mac_method.dma.wme[WME_AC_VI]); 9904 case 0: 9905 return (mac->mac_method.dma.wme[WME_AC_BE]); 9906 case 1: 9907 return (mac->mac_method.dma.wme[WME_AC_BK]); 9908 } 9909 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9910 return (NULL); 9911 } 9912 9913 static int 9914 bwn_dma_getslot(struct bwn_dma_ring *dr) 9915 { 9916 int slot; 9917 9918 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9919 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 9920 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 9921 9922 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 9923 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 9924 dr->dr_curslot = slot; 9925 dr->dr_usedslot++; 9926 9927 return (slot); 9928 } 9929 9930 static int 9931 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 9932 { 9933 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 9934 unsigned int a, b, c, d; 9935 unsigned int avg; 9936 uint32_t tmp; 9937 9938 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 9939 a = tmp & 0xff; 9940 b = (tmp >> 8) & 0xff; 9941 c = (tmp >> 16) & 0xff; 9942 d = (tmp >> 24) & 0xff; 9943 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 9944 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 9945 return (ENOENT); 9946 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 9947 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 9948 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 9949 9950 if (ofdm) { 9951 a = (a + 32) & 0x3f; 9952 b = (b + 32) & 0x3f; 9953 c = (c + 32) & 0x3f; 9954 d = (d + 32) & 0x3f; 9955 } 9956 9957 avg = (a + b + c + d + 2) / 4; 9958 if (ofdm) { 9959 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 9960 & BWN_HF_4DB_CCK_POWERBOOST) 9961 avg = (avg >= 13) ? (avg - 13) : 0; 9962 } 9963 return (avg); 9964 } 9965 9966 static void 9967 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 9968 { 9969 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 9970 int rfatt = *rfattp; 9971 int bbatt = *bbattp; 9972 9973 while (1) { 9974 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 9975 break; 9976 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 9977 break; 9978 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 9979 break; 9980 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 9981 break; 9982 if (bbatt > lo->bbatt.max) { 9983 bbatt -= 4; 9984 rfatt += 1; 9985 continue; 9986 } 9987 if (bbatt < lo->bbatt.min) { 9988 bbatt += 4; 9989 rfatt -= 1; 9990 continue; 9991 } 9992 if (rfatt > lo->rfatt.max) { 9993 rfatt -= 1; 9994 bbatt += 4; 9995 continue; 9996 } 9997 if (rfatt < lo->rfatt.min) { 9998 rfatt += 1; 9999 bbatt -= 4; 10000 continue; 10001 } 10002 break; 10003 } 10004 10005 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10006 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10007 } 10008 10009 static void 10010 bwn_phy_lock(struct bwn_mac *mac) 10011 { 10012 struct bwn_softc *sc = mac->mac_sc; 10013 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10014 10015 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10016 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10017 10018 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10019 bwn_psctl(mac, BWN_PS_AWAKE); 10020 } 10021 10022 static void 10023 bwn_phy_unlock(struct bwn_mac *mac) 10024 { 10025 struct bwn_softc *sc = mac->mac_sc; 10026 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10027 10028 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10029 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10030 10031 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10032 bwn_psctl(mac, 0); 10033 } 10034 10035 static void 10036 bwn_rf_lock(struct bwn_mac *mac) 10037 { 10038 10039 BWN_WRITE_4(mac, BWN_MACCTL, 10040 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10041 BWN_READ_4(mac, BWN_MACCTL); 10042 DELAY(10); 10043 } 10044 10045 static void 10046 bwn_rf_unlock(struct bwn_mac *mac) 10047 { 10048 10049 BWN_READ_2(mac, BWN_PHYVER); 10050 BWN_WRITE_4(mac, BWN_MACCTL, 10051 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10052 } 10053 10054 static struct bwn_pio_txqueue * 10055 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10056 struct bwn_pio_txpkt **pack) 10057 { 10058 struct bwn_pio *pio = &mac->mac_method.pio; 10059 struct bwn_pio_txqueue *tq = NULL; 10060 unsigned int index; 10061 10062 switch (cookie & 0xf000) { 10063 case 0x1000: 10064 tq = &pio->wme[WME_AC_BK]; 10065 break; 10066 case 0x2000: 10067 tq = &pio->wme[WME_AC_BE]; 10068 break; 10069 case 0x3000: 10070 tq = &pio->wme[WME_AC_VI]; 10071 break; 10072 case 0x4000: 10073 tq = &pio->wme[WME_AC_VO]; 10074 break; 10075 case 0x5000: 10076 tq = &pio->mcast; 10077 break; 10078 } 10079 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10080 if (tq == NULL) 10081 return (NULL); 10082 index = (cookie & 0x0fff); 10083 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10084 if (index >= N(tq->tq_pkts)) 10085 return (NULL); 10086 *pack = &tq->tq_pkts[index]; 10087 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10088 return (tq); 10089 } 10090 10091 static void 10092 bwn_txpwr(void *arg, int npending) 10093 { 10094 struct bwn_mac *mac = arg; 10095 10096 wlan_serialize_enter(); 10097 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10098 mac->mac_phy.set_txpwr != NULL) 10099 mac->mac_phy.set_txpwr(mac); 10100 wlan_serialize_exit(); 10101 } 10102 10103 static void 10104 bwn_task_15s(struct bwn_mac *mac) 10105 { 10106 uint16_t reg; 10107 10108 if (mac->mac_fw.opensource) { 10109 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10110 if (reg) { 10111 bwn_restart(mac, "fw watchdog"); 10112 return; 10113 } 10114 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10115 } 10116 if (mac->mac_phy.task_15s) 10117 mac->mac_phy.task_15s(mac); 10118 10119 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10120 } 10121 10122 static void 10123 bwn_task_30s(struct bwn_mac *mac) 10124 { 10125 10126 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10127 return; 10128 mac->mac_noise.noi_running = 1; 10129 mac->mac_noise.noi_nsamples = 0; 10130 10131 bwn_noise_gensample(mac); 10132 } 10133 10134 static void 10135 bwn_task_60s(struct bwn_mac *mac) 10136 { 10137 10138 if (mac->mac_phy.task_60s) 10139 mac->mac_phy.task_60s(mac); 10140 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10141 } 10142 10143 static void 10144 bwn_tasks(void *arg) 10145 { 10146 struct bwn_mac *mac = arg; 10147 struct bwn_softc *sc = mac->mac_sc; 10148 10149 wlan_serialize_enter(); 10150 10151 if (mac->mac_status != BWN_MAC_STATUS_STARTED) { 10152 wlan_serialize_exit(); 10153 return; 10154 } 10155 10156 if (mac->mac_task_state % 4 == 0) 10157 bwn_task_60s(mac); 10158 if (mac->mac_task_state % 2 == 0) 10159 bwn_task_30s(mac); 10160 bwn_task_15s(mac); 10161 10162 mac->mac_task_state++; 10163 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10164 wlan_serialize_exit(); 10165 } 10166 10167 static int 10168 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10169 { 10170 struct bwn_softc *sc = mac->mac_sc; 10171 10172 KASSERT(a == 0, ("not support APHY\n")); 10173 10174 switch (plcp->o.raw[0] & 0xf) { 10175 case 0xb: 10176 return (BWN_OFDM_RATE_6MB); 10177 case 0xf: 10178 return (BWN_OFDM_RATE_9MB); 10179 case 0xa: 10180 return (BWN_OFDM_RATE_12MB); 10181 case 0xe: 10182 return (BWN_OFDM_RATE_18MB); 10183 case 0x9: 10184 return (BWN_OFDM_RATE_24MB); 10185 case 0xd: 10186 return (BWN_OFDM_RATE_36MB); 10187 case 0x8: 10188 return (BWN_OFDM_RATE_48MB); 10189 case 0xc: 10190 return (BWN_OFDM_RATE_54MB); 10191 } 10192 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10193 plcp->o.raw[0] & 0xf); 10194 return (-1); 10195 } 10196 10197 static int 10198 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10199 { 10200 struct bwn_softc *sc = mac->mac_sc; 10201 10202 switch (plcp->o.raw[0]) { 10203 case 0x0a: 10204 return (BWN_CCK_RATE_1MB); 10205 case 0x14: 10206 return (BWN_CCK_RATE_2MB); 10207 case 0x37: 10208 return (BWN_CCK_RATE_5MB); 10209 case 0x6e: 10210 return (BWN_CCK_RATE_11MB); 10211 } 10212 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10213 return (-1); 10214 } 10215 10216 static void 10217 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10218 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10219 int rssi, int noise) 10220 { 10221 struct bwn_softc *sc = mac->mac_sc; 10222 const struct ieee80211_frame_min *wh; 10223 uint64_t tsf; 10224 uint16_t low_mactime_now; 10225 10226 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10227 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10228 10229 wh = mtod(m, const struct ieee80211_frame_min *); 10230 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10231 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10232 10233 bwn_tsf_read(mac, &tsf); 10234 low_mactime_now = tsf; 10235 tsf = tsf & ~0xffffULL; 10236 tsf += le16toh(rxhdr->mac_time); 10237 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10238 tsf -= 0x10000; 10239 10240 sc->sc_rx_th.wr_tsf = tsf; 10241 sc->sc_rx_th.wr_rate = rate; 10242 sc->sc_rx_th.wr_antsignal = rssi; 10243 sc->sc_rx_th.wr_antnoise = noise; 10244 } 10245 10246 static void 10247 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10248 { 10249 uint32_t low, high; 10250 10251 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10252 ("%s:%d: fail", __func__, __LINE__)); 10253 10254 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10255 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10256 *tsf = high; 10257 *tsf <<= 32; 10258 *tsf |= low; 10259 } 10260 10261 static int 10262 bwn_dma_attach(struct bwn_mac *mac) 10263 { 10264 struct bwn_dma *dma = &mac->mac_method.dma; 10265 struct bwn_softc *sc = mac->mac_sc; 10266 bus_addr_t lowaddr = 0; 10267 int error; 10268 10269 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10270 return (0); 10271 10272 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10273 10274 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10275 10276 dma->dmatype = bwn_dma_gettype(mac); 10277 if (dma->dmatype == BWN_DMA_30BIT) 10278 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10279 else if (dma->dmatype == BWN_DMA_32BIT) 10280 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10281 else 10282 lowaddr = BUS_SPACE_MAXADDR; 10283 10284 /* 10285 * Create top level DMA tag 10286 */ 10287 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10288 BWN_ALIGN, 0, /* alignment, bounds */ 10289 lowaddr, /* lowaddr */ 10290 BUS_SPACE_MAXADDR, /* highaddr */ 10291 NULL, NULL, /* filter, filterarg */ 10292 MAXBSIZE, /* maxsize */ 10293 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10294 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10295 0, /* flags */ 10296 &dma->parent_dtag); 10297 if (error) { 10298 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10299 return (error); 10300 } 10301 10302 /* 10303 * Create TX/RX mbuf DMA tag 10304 */ 10305 error = bus_dma_tag_create(dma->parent_dtag, 10306 4, 10307 0, 10308 BUS_SPACE_MAXADDR, 10309 BUS_SPACE_MAXADDR, 10310 NULL, NULL, 10311 MCLBYTES, 10312 1, 10313 BUS_SPACE_MAXSIZE_32BIT, 10314 0, 10315 &dma->rxbuf_dtag); 10316 if (error) { 10317 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10318 goto fail0; 10319 } 10320 error = bus_dma_tag_create(dma->parent_dtag, 10321 4, 10322 0, 10323 BUS_SPACE_MAXADDR, 10324 BUS_SPACE_MAXADDR, 10325 NULL, NULL, 10326 MCLBYTES, 10327 1, 10328 BUS_SPACE_MAXSIZE_32BIT, 10329 0, 10330 &dma->txbuf_dtag); 10331 if (error) { 10332 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10333 goto fail1; 10334 } 10335 10336 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10337 if (dma->wme[WME_AC_BK] == NULL) 10338 goto fail2; 10339 10340 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10341 if (dma->wme[WME_AC_BE] == NULL) 10342 goto fail3; 10343 10344 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10345 if (dma->wme[WME_AC_VI] == NULL) 10346 goto fail4; 10347 10348 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10349 if (dma->wme[WME_AC_VO] == NULL) 10350 goto fail5; 10351 10352 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10353 if (dma->mcast == NULL) 10354 goto fail6; 10355 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10356 if (dma->rx == NULL) 10357 goto fail7; 10358 10359 return (error); 10360 10361 fail7: bwn_dma_ringfree(&dma->mcast); 10362 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10363 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10364 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10365 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10366 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10367 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10368 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10369 return (error); 10370 } 10371 10372 static struct bwn_dma_ring * 10373 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10374 uint16_t cookie, int *slot) 10375 { 10376 struct bwn_dma *dma = &mac->mac_method.dma; 10377 struct bwn_dma_ring *dr; 10378 struct bwn_softc *sc = mac->mac_sc; 10379 10380 switch (cookie & 0xf000) { 10381 case 0x1000: 10382 dr = dma->wme[WME_AC_BK]; 10383 break; 10384 case 0x2000: 10385 dr = dma->wme[WME_AC_BE]; 10386 break; 10387 case 0x3000: 10388 dr = dma->wme[WME_AC_VI]; 10389 break; 10390 case 0x4000: 10391 dr = dma->wme[WME_AC_VO]; 10392 break; 10393 case 0x5000: 10394 dr = dma->mcast; 10395 break; 10396 default: 10397 dr = NULL; 10398 KASSERT(0 == 1, 10399 ("invalid cookie value %d", cookie & 0xf000)); 10400 } 10401 *slot = (cookie & 0x0fff); 10402 if (*slot < 0 || *slot >= dr->dr_numslots) { 10403 /* 10404 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10405 * that it occurs events which have same H/W sequence numbers. 10406 * When it's occurred just prints a WARNING msgs and ignores. 10407 */ 10408 KASSERT(status->seq == dma->lastseq, 10409 ("%s:%d: fail", __func__, __LINE__)); 10410 device_printf(sc->sc_dev, 10411 "out of slot ranges (0 < %d < %d)\n", *slot, 10412 dr->dr_numslots); 10413 return (NULL); 10414 } 10415 dma->lastseq = status->seq; 10416 return (dr); 10417 } 10418 10419 static void 10420 bwn_dma_stop(struct bwn_mac *mac) 10421 { 10422 struct bwn_dma *dma; 10423 10424 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10425 return; 10426 dma = &mac->mac_method.dma; 10427 10428 bwn_dma_ringstop(&dma->rx); 10429 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10430 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10431 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10432 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10433 bwn_dma_ringstop(&dma->mcast); 10434 } 10435 10436 static void 10437 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10438 { 10439 10440 if (dr == NULL) 10441 return; 10442 10443 bwn_dma_cleanup(*dr); 10444 } 10445 10446 static void 10447 bwn_pio_stop(struct bwn_mac *mac) 10448 { 10449 struct bwn_pio *pio; 10450 10451 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10452 return; 10453 pio = &mac->mac_method.pio; 10454 10455 bwn_destroy_queue_tx(&pio->mcast); 10456 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10457 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10458 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10459 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10460 } 10461 10462 static void 10463 bwn_led_attach(struct bwn_mac *mac) 10464 { 10465 struct bwn_softc *sc = mac->mac_sc; 10466 const uint8_t *led_act = NULL; 10467 uint16_t val[BWN_LED_MAX]; 10468 int i; 10469 10470 sc->sc_led_idle = (2350 * hz) / 1000; 10471 sc->sc_led_blink = 1; 10472 10473 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10474 if (siba_get_pci_subvendor(sc->sc_dev) == 10475 bwn_vendor_led_act[i].vid) { 10476 led_act = bwn_vendor_led_act[i].led_act; 10477 break; 10478 } 10479 } 10480 if (led_act == NULL) 10481 led_act = bwn_default_led_act; 10482 10483 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10484 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10485 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10486 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10487 10488 for (i = 0; i < BWN_LED_MAX; ++i) { 10489 struct bwn_led *led = &sc->sc_leds[i]; 10490 10491 if (val[i] == 0xff) { 10492 led->led_act = led_act[i]; 10493 } else { 10494 if (val[i] & BWN_LED_ACT_LOW) 10495 led->led_flags |= BWN_LED_F_ACTLOW; 10496 led->led_act = val[i] & BWN_LED_ACT_MASK; 10497 } 10498 led->led_mask = (1 << i); 10499 10500 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10501 led->led_act == BWN_LED_ACT_BLINK_POLL || 10502 led->led_act == BWN_LED_ACT_BLINK) { 10503 led->led_flags |= BWN_LED_F_BLINK; 10504 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10505 led->led_flags |= BWN_LED_F_POLLABLE; 10506 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10507 led->led_flags |= BWN_LED_F_SLOW; 10508 10509 if (sc->sc_blink_led == NULL) { 10510 sc->sc_blink_led = led; 10511 if (led->led_flags & BWN_LED_F_SLOW) 10512 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10513 } 10514 } 10515 10516 DPRINTF(sc, BWN_DEBUG_LED, 10517 "%dth led, act %d, lowact %d\n", i, 10518 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10519 } 10520 callout_init(&sc->sc_led_blink_ch); 10521 } 10522 10523 static __inline uint16_t 10524 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10525 { 10526 10527 if (led->led_flags & BWN_LED_F_ACTLOW) 10528 on = !on; 10529 if (on) 10530 val |= led->led_mask; 10531 else 10532 val &= ~led->led_mask; 10533 return val; 10534 } 10535 10536 static void 10537 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10538 { 10539 struct bwn_softc *sc = mac->mac_sc; 10540 struct ifnet *ifp = sc->sc_ifp; 10541 struct ieee80211com *ic = ifp->if_l2com; 10542 uint16_t val; 10543 int i; 10544 10545 if (nstate == IEEE80211_S_INIT) { 10546 callout_stop(&sc->sc_led_blink_ch); 10547 sc->sc_led_blinking = 0; 10548 } 10549 10550 if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0) 10551 return; 10552 10553 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10554 for (i = 0; i < BWN_LED_MAX; ++i) { 10555 struct bwn_led *led = &sc->sc_leds[i]; 10556 int on; 10557 10558 if (led->led_act == BWN_LED_ACT_UNKN || 10559 led->led_act == BWN_LED_ACT_NULL) 10560 continue; 10561 10562 if ((led->led_flags & BWN_LED_F_BLINK) && 10563 nstate != IEEE80211_S_INIT) 10564 continue; 10565 10566 switch (led->led_act) { 10567 case BWN_LED_ACT_ON: /* Always on */ 10568 on = 1; 10569 break; 10570 case BWN_LED_ACT_OFF: /* Always off */ 10571 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10572 on = 0; 10573 break; 10574 default: 10575 on = 1; 10576 switch (nstate) { 10577 case IEEE80211_S_INIT: 10578 on = 0; 10579 break; 10580 case IEEE80211_S_RUN: 10581 if (led->led_act == BWN_LED_ACT_11G && 10582 ic->ic_curmode != IEEE80211_MODE_11G) 10583 on = 0; 10584 break; 10585 default: 10586 if (led->led_act == BWN_LED_ACT_ASSOC) 10587 on = 0; 10588 break; 10589 } 10590 break; 10591 } 10592 10593 val = bwn_led_onoff(led, val, on); 10594 } 10595 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10596 } 10597 10598 static void 10599 bwn_led_event(struct bwn_mac *mac, int event) 10600 { 10601 struct bwn_softc *sc = mac->mac_sc; 10602 struct bwn_led *led = sc->sc_blink_led; 10603 int rate; 10604 10605 if (event == BWN_LED_EVENT_POLL) { 10606 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10607 return; 10608 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10609 return; 10610 } 10611 10612 sc->sc_led_ticks = ticks; 10613 if (sc->sc_led_blinking) 10614 return; 10615 10616 switch (event) { 10617 case BWN_LED_EVENT_RX: 10618 rate = sc->sc_rx_rate; 10619 break; 10620 case BWN_LED_EVENT_TX: 10621 rate = sc->sc_tx_rate; 10622 break; 10623 case BWN_LED_EVENT_POLL: 10624 rate = 0; 10625 break; 10626 default: 10627 panic("unknown LED event %d\n", event); 10628 break; 10629 } 10630 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10631 bwn_led_duration[rate].off_dur); 10632 } 10633 10634 static void 10635 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10636 { 10637 struct bwn_softc *sc = mac->mac_sc; 10638 struct bwn_led *led = sc->sc_blink_led; 10639 uint16_t val; 10640 10641 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10642 val = bwn_led_onoff(led, val, 1); 10643 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10644 10645 if (led->led_flags & BWN_LED_F_SLOW) { 10646 BWN_LED_SLOWDOWN(on_dur); 10647 BWN_LED_SLOWDOWN(off_dur); 10648 } 10649 10650 sc->sc_led_blinking = 1; 10651 sc->sc_led_blink_offdur = off_dur; 10652 10653 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10654 } 10655 10656 static void 10657 bwn_led_blink_next(void *arg) 10658 { 10659 struct bwn_mac *mac = arg; 10660 struct bwn_softc *sc = mac->mac_sc; 10661 uint16_t val; 10662 10663 wlan_serialize_enter(); 10664 10665 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10666 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10667 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10668 10669 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10670 bwn_led_blink_end, mac); 10671 wlan_serialize_exit(); 10672 } 10673 10674 static void 10675 bwn_led_blink_end(void *arg) 10676 { 10677 struct bwn_mac *mac = arg; 10678 struct bwn_softc *sc = mac->mac_sc; 10679 10680 sc->sc_led_blinking = 0; 10681 } 10682 10683 static int 10684 bwn_suspend(device_t dev) 10685 { 10686 struct bwn_softc *sc = device_get_softc(dev); 10687 10688 wlan_serialize_enter(); 10689 bwn_stop(sc, 1); 10690 wlan_serialize_exit(); 10691 10692 return (0); 10693 } 10694 10695 static int 10696 bwn_resume(device_t dev) 10697 { 10698 struct bwn_softc *sc = device_get_softc(dev); 10699 struct ifnet *ifp = sc->sc_ifp; 10700 10701 wlan_serialize_enter(); 10702 if (ifp->if_flags & IFF_UP) 10703 bwn_init(sc); 10704 wlan_serialize_exit(); 10705 return (0); 10706 } 10707 10708 static void 10709 bwn_rfswitch(void *arg) 10710 { 10711 struct bwn_softc *sc = arg; 10712 struct bwn_mac *mac = sc->sc_curmac; 10713 int cur = 0, prev = 0; 10714 10715 wlan_serialize_enter(); 10716 10717 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10718 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10719 10720 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10721 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10722 & BWN_RF_HWENABLED_HI_MASK)) 10723 cur = 1; 10724 } else { 10725 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10726 & BWN_RF_HWENABLED_LO_MASK) 10727 cur = 1; 10728 } 10729 10730 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10731 prev = 1; 10732 10733 if (cur != prev) { 10734 if (cur) 10735 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10736 else 10737 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10738 10739 device_printf(sc->sc_dev, 10740 "status of RF switch is changed to %s\n", 10741 cur ? "ON" : "OFF"); 10742 if (cur != mac->mac_phy.rf_on) { 10743 if (cur) 10744 bwn_rf_turnon(mac); 10745 else 10746 bwn_rf_turnoff(mac); 10747 } 10748 } 10749 10750 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 10751 wlan_serialize_exit(); 10752 } 10753 10754 static void 10755 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10756 { 10757 struct bwn_phy *phy = &mac->mac_phy; 10758 struct bwn_phy_lp *plp = &phy->phy_lp; 10759 10760 plp->plp_antenna = BWN_ANT_DEFAULT; 10761 } 10762 10763 static int 10764 bwn_phy_lp_init(struct bwn_mac *mac) 10765 { 10766 static const struct bwn_stxtable tables[] = { 10767 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10768 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10769 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10770 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10771 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10772 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10773 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10774 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10775 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10776 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10777 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10778 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10779 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10780 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10781 { 2, 11, 0x40, 0, 0x0f } 10782 }; 10783 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10784 struct bwn_softc *sc = mac->mac_sc; 10785 const struct bwn_stxtable *st; 10786 struct ifnet *ifp = sc->sc_ifp; 10787 struct ieee80211com *ic = ifp->if_l2com; 10788 int i, error; 10789 uint16_t tmp; 10790 10791 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10792 bwn_phy_lp_bbinit(mac); 10793 10794 /* initialize RF */ 10795 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10796 DELAY(1); 10797 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10798 DELAY(1); 10799 10800 if (mac->mac_phy.rf_ver == 0x2062) 10801 bwn_phy_lp_b2062_init(mac); 10802 else { 10803 bwn_phy_lp_b2063_init(mac); 10804 10805 /* synchronize stx table. */ 10806 for (i = 0; i < N(tables); i++) { 10807 st = &tables[i]; 10808 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10809 tmp >>= st->st_rfshift; 10810 tmp <<= st->st_physhift; 10811 BWN_PHY_SETMASK(mac, 10812 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10813 ~(st->st_mask << st->st_physhift), tmp); 10814 } 10815 10816 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10817 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10818 } 10819 10820 /* calibrate RC */ 10821 if (mac->mac_phy.rev >= 2) 10822 bwn_phy_lp_rxcal_r2(mac); 10823 else if (!plp->plp_rccap) { 10824 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10825 bwn_phy_lp_rccal_r12(mac); 10826 } else 10827 bwn_phy_lp_set_rccap(mac); 10828 10829 error = bwn_phy_lp_switch_channel(mac, 7); 10830 if (error) 10831 device_printf(sc->sc_dev, 10832 "failed to change channel 7 (%d)\n", error); 10833 bwn_phy_lp_txpctl_init(mac); 10834 bwn_phy_lp_calib(mac); 10835 return (0); 10836 } 10837 10838 static uint16_t 10839 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10840 { 10841 10842 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10843 return (BWN_READ_2(mac, BWN_PHYDATA)); 10844 } 10845 10846 static void 10847 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10848 { 10849 10850 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10851 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10852 } 10853 10854 static void 10855 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10856 uint16_t set) 10857 { 10858 10859 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10860 BWN_WRITE_2(mac, BWN_PHYDATA, 10861 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10862 } 10863 10864 static uint16_t 10865 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10866 { 10867 10868 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10869 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10870 reg |= 0x100; 10871 if (mac->mac_phy.rev >= 2) 10872 reg |= 0x200; 10873 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10874 return BWN_READ_2(mac, BWN_RFDATALO); 10875 } 10876 10877 static void 10878 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10879 { 10880 10881 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10882 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10883 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10884 } 10885 10886 static void 10887 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10888 { 10889 10890 if (on) { 10891 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10892 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10893 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10894 return; 10895 } 10896 10897 if (mac->mac_phy.rev >= 2) { 10898 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10899 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10900 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10901 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10902 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10903 return; 10904 } 10905 10906 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10907 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10908 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10909 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10910 } 10911 10912 static int 10913 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10914 { 10915 struct bwn_phy *phy = &mac->mac_phy; 10916 struct bwn_phy_lp *plp = &phy->phy_lp; 10917 int error; 10918 10919 if (phy->rf_ver == 0x2063) { 10920 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 10921 if (error) 10922 return (error); 10923 } else { 10924 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 10925 if (error) 10926 return (error); 10927 bwn_phy_lp_set_anafilter(mac, chan); 10928 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 10929 } 10930 10931 plp->plp_chan = chan; 10932 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 10933 return (0); 10934 } 10935 10936 static uint32_t 10937 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 10938 { 10939 struct bwn_softc *sc = mac->mac_sc; 10940 struct ifnet *ifp = sc->sc_ifp; 10941 struct ieee80211com *ic = ifp->if_l2com; 10942 10943 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 10944 } 10945 10946 static void 10947 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 10948 { 10949 struct bwn_phy *phy = &mac->mac_phy; 10950 struct bwn_phy_lp *plp = &phy->phy_lp; 10951 10952 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 10953 return; 10954 10955 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 10956 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 10957 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 10958 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 10959 plp->plp_antenna = antenna; 10960 } 10961 10962 static void 10963 bwn_phy_lp_task_60s(struct bwn_mac *mac) 10964 { 10965 10966 bwn_phy_lp_calib(mac); 10967 } 10968 10969 static void 10970 bwn_phy_lp_readsprom(struct bwn_mac *mac) 10971 { 10972 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10973 struct bwn_softc *sc = mac->mac_sc; 10974 struct ifnet *ifp = sc->sc_ifp; 10975 struct ieee80211com *ic = ifp->if_l2com; 10976 10977 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 10978 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 10979 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 10980 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 10981 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 10982 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 10983 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 10984 return; 10985 } 10986 10987 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 10988 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 10989 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 10990 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 10991 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 10992 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 10993 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 10994 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 10995 } 10996 10997 static void 10998 bwn_phy_lp_bbinit(struct bwn_mac *mac) 10999 { 11000 11001 bwn_phy_lp_tblinit(mac); 11002 if (mac->mac_phy.rev >= 2) 11003 bwn_phy_lp_bbinit_r2(mac); 11004 else 11005 bwn_phy_lp_bbinit_r01(mac); 11006 } 11007 11008 static void 11009 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11010 { 11011 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11012 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11013 struct bwn_softc *sc = mac->mac_sc; 11014 struct ifnet *ifp = sc->sc_ifp; 11015 struct ieee80211com *ic = ifp->if_l2com; 11016 11017 bwn_phy_lp_set_txgain(mac, 11018 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11019 bwn_phy_lp_set_bbmult(mac, 150); 11020 } 11021 11022 static void 11023 bwn_phy_lp_calib(struct bwn_mac *mac) 11024 { 11025 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11026 struct bwn_softc *sc = mac->mac_sc; 11027 struct ifnet *ifp = sc->sc_ifp; 11028 struct ieee80211com *ic = ifp->if_l2com; 11029 const struct bwn_rxcompco *rc = NULL; 11030 struct bwn_txgain ogain; 11031 int i, omode, oafeovr, orf, obbmult; 11032 uint8_t mode, fc = 0; 11033 11034 if (plp->plp_chanfullcal != plp->plp_chan) { 11035 plp->plp_chanfullcal = plp->plp_chan; 11036 fc = 1; 11037 } 11038 11039 bwn_mac_suspend(mac); 11040 11041 /* BlueTooth Coexistance Override */ 11042 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11043 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11044 11045 if (mac->mac_phy.rev >= 2) 11046 bwn_phy_lp_digflt_save(mac); 11047 bwn_phy_lp_get_txpctlmode(mac); 11048 mode = plp->plp_txpctlmode; 11049 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11050 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11051 bwn_phy_lp_bugfix(mac); 11052 if (mac->mac_phy.rev >= 2 && fc == 1) { 11053 bwn_phy_lp_get_txpctlmode(mac); 11054 omode = plp->plp_txpctlmode; 11055 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11056 if (oafeovr) 11057 ogain = bwn_phy_lp_get_txgain(mac); 11058 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11059 obbmult = bwn_phy_lp_get_bbmult(mac); 11060 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11061 if (oafeovr) 11062 bwn_phy_lp_set_txgain(mac, &ogain); 11063 bwn_phy_lp_set_bbmult(mac, obbmult); 11064 bwn_phy_lp_set_txpctlmode(mac, omode); 11065 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11066 } 11067 bwn_phy_lp_set_txpctlmode(mac, mode); 11068 if (mac->mac_phy.rev >= 2) 11069 bwn_phy_lp_digflt_restore(mac); 11070 11071 /* do RX IQ Calculation; assumes that noise is true. */ 11072 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11073 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11074 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11075 rc = &bwn_rxcompco_5354[i]; 11076 } 11077 } else if (mac->mac_phy.rev >= 2) 11078 rc = &bwn_rxcompco_r2; 11079 else { 11080 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11081 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11082 rc = &bwn_rxcompco_r12[i]; 11083 } 11084 } 11085 if (rc == NULL) 11086 goto fail; 11087 11088 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11089 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11090 11091 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11092 11093 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11094 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11095 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11096 } else { 11097 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11098 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11099 } 11100 11101 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11102 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11103 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11104 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11105 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11106 bwn_phy_lp_set_deaf(mac, 0); 11107 /* XXX no checking return value? */ 11108 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11109 bwn_phy_lp_clear_deaf(mac, 0); 11110 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11111 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11112 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11113 11114 /* disable RX GAIN override. */ 11115 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11116 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11117 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11118 if (mac->mac_phy.rev >= 2) { 11119 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11120 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11121 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11122 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11123 } 11124 } else { 11125 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11126 } 11127 11128 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11129 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11130 fail: 11131 bwn_mac_enable(mac); 11132 } 11133 11134 static void 11135 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11136 { 11137 11138 if (on) { 11139 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11140 return; 11141 } 11142 11143 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11144 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11145 } 11146 11147 static int 11148 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11149 { 11150 static const struct bwn_b206x_chan *bc = NULL; 11151 struct bwn_softc *sc = mac->mac_sc; 11152 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11153 tmp[6]; 11154 uint16_t old, scale, tmp16; 11155 int i, div; 11156 11157 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11158 if (bwn_b2063_chantable[i].bc_chan == chan) { 11159 bc = &bwn_b2063_chantable[i]; 11160 break; 11161 } 11162 } 11163 if (bc == NULL) 11164 return (EINVAL); 11165 11166 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11167 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11168 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11169 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11170 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11171 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11172 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11173 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11174 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11175 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11176 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11177 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11178 11179 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11180 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11181 11182 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11183 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11184 freqref = freqxtal * 3; 11185 div = (freqxtal <= 26000000 ? 1 : 2); 11186 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11187 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11188 999999) / 1000000) + 1; 11189 11190 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11191 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11192 0xfff8, timeout >> 2); 11193 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11194 0xff9f,timeout << 5); 11195 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11196 11197 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11198 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11199 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11200 11201 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11202 (timeoutref + 1)) - 1; 11203 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11204 0xf0, count >> 8); 11205 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11206 11207 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11208 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11209 while (tmp[1] >= freqref) { 11210 tmp[0]++; 11211 tmp[1] -= freqref; 11212 } 11213 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11214 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11215 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11216 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11217 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11218 11219 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11220 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11221 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11222 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11223 11224 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11225 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11226 11227 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11228 scale = 1; 11229 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11230 } else { 11231 scale = 0; 11232 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11233 } 11234 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11235 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11236 11237 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11238 (scale + 1); 11239 if (tmp[5] > 150) 11240 tmp[5] = 0; 11241 11242 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11243 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11244 11245 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11246 if (freqxtal > 26000000) 11247 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11248 else 11249 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11250 11251 if (val[0] == 45) 11252 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11253 else 11254 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11255 11256 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11257 DELAY(1); 11258 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11259 11260 /* VCO Calibration */ 11261 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11262 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11263 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11264 DELAY(1); 11265 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11266 DELAY(1); 11267 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11268 DELAY(1); 11269 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11270 DELAY(300); 11271 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11272 11273 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11274 return (0); 11275 } 11276 11277 static int 11278 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11279 { 11280 struct bwn_softc *sc = mac->mac_sc; 11281 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11282 const struct bwn_b206x_chan *bc = NULL; 11283 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11284 uint32_t tmp[9]; 11285 int i; 11286 11287 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11288 if (bwn_b2062_chantable[i].bc_chan == chan) { 11289 bc = &bwn_b2062_chantable[i]; 11290 break; 11291 } 11292 } 11293 11294 if (bc == NULL) 11295 return (EINVAL); 11296 11297 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11298 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11299 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11300 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11301 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11302 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11303 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11304 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11305 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11306 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11307 11308 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11309 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11310 bwn_phy_lp_b2062_reset_pllbias(mac); 11311 tmp[0] = freqxtal / 1000; 11312 tmp[1] = plp->plp_div * 1000; 11313 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11314 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11315 tmp[2] *= 2; 11316 tmp[3] = 48 * tmp[0]; 11317 tmp[5] = tmp[2] / tmp[3]; 11318 tmp[6] = tmp[2] % tmp[3]; 11319 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11320 tmp[4] = tmp[6] * 0x100; 11321 tmp[5] = tmp[4] / tmp[3]; 11322 tmp[6] = tmp[4] % tmp[3]; 11323 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11324 tmp[4] = tmp[6] * 0x100; 11325 tmp[5] = tmp[4] / tmp[3]; 11326 tmp[6] = tmp[4] % tmp[3]; 11327 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11328 tmp[4] = tmp[6] * 0x100; 11329 tmp[5] = tmp[4] / tmp[3]; 11330 tmp[6] = tmp[4] % tmp[3]; 11331 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11332 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11333 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11334 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11335 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11336 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11337 11338 bwn_phy_lp_b2062_vco_calib(mac); 11339 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11340 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11341 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11342 bwn_phy_lp_b2062_reset_pllbias(mac); 11343 bwn_phy_lp_b2062_vco_calib(mac); 11344 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11345 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11346 return (EIO); 11347 } 11348 } 11349 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11350 return (0); 11351 } 11352 11353 static void 11354 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11355 { 11356 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11357 uint16_t tmp = (channel == 14); 11358 11359 if (mac->mac_phy.rev < 2) { 11360 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11361 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11362 bwn_phy_lp_set_rccap(mac); 11363 return; 11364 } 11365 11366 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11367 } 11368 11369 static void 11370 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11371 { 11372 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11373 struct bwn_softc *sc = mac->mac_sc; 11374 struct ifnet *ifp = sc->sc_ifp; 11375 struct ieee80211com *ic = ifp->if_l2com; 11376 uint16_t iso, tmp[3]; 11377 11378 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11379 11380 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11381 iso = plp->plp_txisoband_m; 11382 else if (freq <= 5320) 11383 iso = plp->plp_txisoband_l; 11384 else if (freq <= 5700) 11385 iso = plp->plp_txisoband_m; 11386 else 11387 iso = plp->plp_txisoband_h; 11388 11389 tmp[0] = ((iso - 26) / 12) << 12; 11390 tmp[1] = tmp[0] + 0x1000; 11391 tmp[2] = tmp[0] + 0x2000; 11392 11393 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11394 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11395 } 11396 11397 static void 11398 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11399 { 11400 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11401 int i; 11402 static const uint16_t addr[] = { 11403 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11404 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11405 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11406 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11407 BWN_PHY_OFDM(0xcf), 11408 }; 11409 static const uint16_t val[] = { 11410 0xde5e, 0xe832, 0xe331, 0x4d26, 11411 0x0026, 0x1420, 0x0020, 0xfe08, 11412 0x0008, 11413 }; 11414 11415 for (i = 0; i < N(addr); i++) { 11416 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11417 BWN_PHY_WRITE(mac, addr[i], val[i]); 11418 } 11419 } 11420 11421 static void 11422 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11423 { 11424 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11425 struct bwn_softc *sc = mac->mac_sc; 11426 uint16_t ctl; 11427 11428 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11429 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11430 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11431 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11432 break; 11433 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11434 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11435 break; 11436 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11437 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11438 break; 11439 default: 11440 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11441 device_printf(sc->sc_dev, "unknown command mode\n"); 11442 break; 11443 } 11444 } 11445 11446 static void 11447 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11448 { 11449 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11450 uint16_t ctl; 11451 uint8_t old; 11452 11453 bwn_phy_lp_get_txpctlmode(mac); 11454 old = plp->plp_txpctlmode; 11455 if (old == mode) 11456 return; 11457 plp->plp_txpctlmode = mode; 11458 11459 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11460 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11461 plp->plp_tssiidx); 11462 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11463 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11464 11465 /* disable TX GAIN override */ 11466 if (mac->mac_phy.rev < 2) 11467 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11468 else { 11469 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11470 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11471 } 11472 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11473 11474 plp->plp_txpwridx = -1; 11475 } 11476 if (mac->mac_phy.rev >= 2) { 11477 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11478 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11479 else 11480 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11481 } 11482 11483 /* writes TX Power Control mode */ 11484 switch (plp->plp_txpctlmode) { 11485 case BWN_PHYLP_TXPCTL_OFF: 11486 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11487 break; 11488 case BWN_PHYLP_TXPCTL_ON_HW: 11489 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11490 break; 11491 case BWN_PHYLP_TXPCTL_ON_SW: 11492 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11493 break; 11494 default: 11495 ctl = 0; 11496 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11497 } 11498 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11499 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11500 } 11501 11502 static void 11503 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11504 { 11505 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11506 const unsigned int size = 256; 11507 struct bwn_txgain tg; 11508 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11509 uint16_t tssinpt, tssiidx, value[2]; 11510 uint8_t mode; 11511 int8_t txpwridx; 11512 11513 tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF, 11514 M_INTWAIT | M_ZERO); 11515 11516 bwn_phy_lp_get_txpctlmode(mac); 11517 mode = plp->plp_txpctlmode; 11518 txpwridx = plp->plp_txpwridx; 11519 tssinpt = plp->plp_tssinpt; 11520 tssiidx = plp->plp_tssiidx; 11521 11522 bwn_tab_read_multi(mac, 11523 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11524 BWN_TAB_4(7, 0x140), size, tabs); 11525 11526 bwn_phy_lp_tblinit(mac); 11527 bwn_phy_lp_bbinit(mac); 11528 bwn_phy_lp_txpctl_init(mac); 11529 bwn_phy_lp_rf_onoff(mac, 1); 11530 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11531 11532 bwn_tab_write_multi(mac, 11533 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11534 BWN_TAB_4(7, 0x140), size, tabs); 11535 11536 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11537 plp->plp_tssinpt = tssinpt; 11538 plp->plp_tssiidx = tssiidx; 11539 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11540 if (txpwridx != -1) { 11541 /* set TX power by index */ 11542 plp->plp_txpwridx = txpwridx; 11543 bwn_phy_lp_get_txpctlmode(mac); 11544 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11545 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11546 if (mac->mac_phy.rev >= 2) { 11547 rxcomp = bwn_tab_read(mac, 11548 BWN_TAB_4(7, txpwridx + 320)); 11549 txgain = bwn_tab_read(mac, 11550 BWN_TAB_4(7, txpwridx + 192)); 11551 tg.tg_pad = (txgain >> 16) & 0xff; 11552 tg.tg_gm = txgain & 0xff; 11553 tg.tg_pga = (txgain >> 8) & 0xff; 11554 tg.tg_dac = (rxcomp >> 28) & 0xff; 11555 bwn_phy_lp_set_txgain(mac, &tg); 11556 } else { 11557 rxcomp = bwn_tab_read(mac, 11558 BWN_TAB_4(10, txpwridx + 320)); 11559 txgain = bwn_tab_read(mac, 11560 BWN_TAB_4(10, txpwridx + 192)); 11561 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11562 0xf800, (txgain >> 4) & 0x7fff); 11563 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11564 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11565 } 11566 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11567 11568 /* set TX IQCC */ 11569 value[0] = (rxcomp >> 10) & 0x3ff; 11570 value[1] = rxcomp & 0x3ff; 11571 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11572 11573 coeff = bwn_tab_read(mac, 11574 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11575 BWN_TAB_4(10, txpwridx + 448)); 11576 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11577 if (mac->mac_phy.rev >= 2) { 11578 rfpwr = bwn_tab_read(mac, 11579 BWN_TAB_4(7, txpwridx + 576)); 11580 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11581 rfpwr & 0xffff); 11582 } 11583 bwn_phy_lp_set_txgain_override(mac); 11584 } 11585 if (plp->plp_rccap) 11586 bwn_phy_lp_set_rccap(mac); 11587 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11588 bwn_phy_lp_set_txpctlmode(mac, mode); 11589 kfree(tabs, M_DEVBUF); 11590 } 11591 11592 static void 11593 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11594 { 11595 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11596 int i; 11597 static const uint16_t addr[] = { 11598 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11599 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11600 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11601 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11602 BWN_PHY_OFDM(0xcf), 11603 }; 11604 11605 for (i = 0; i < N(addr); i++) 11606 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11607 } 11608 11609 static void 11610 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11611 { 11612 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11613 11614 if (mac->mac_phy.rev < 2) { 11615 bwn_phy_lp_tblinit_r01(mac); 11616 bwn_phy_lp_tblinit_txgain(mac); 11617 bwn_phy_lp_set_gaintbl(mac, freq); 11618 return; 11619 } 11620 11621 bwn_phy_lp_tblinit_r2(mac); 11622 bwn_phy_lp_tblinit_txgain(mac); 11623 } 11624 11625 struct bwn_wpair { 11626 uint16_t reg; 11627 uint16_t value; 11628 }; 11629 11630 struct bwn_smpair { 11631 uint16_t offset; 11632 uint16_t mask; 11633 uint16_t set; 11634 }; 11635 11636 static void 11637 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11638 { 11639 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11640 struct bwn_softc *sc = mac->mac_sc; 11641 struct ifnet *ifp = sc->sc_ifp; 11642 struct ieee80211com *ic = ifp->if_l2com; 11643 static const struct bwn_wpair v1[] = { 11644 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11645 { BWN_PHY_AFE_CTL, 0x8800 }, 11646 { BWN_PHY_AFE_CTL_OVR, 0 }, 11647 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11648 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11649 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11650 { BWN_PHY_OFDM(0xf9), 0 }, 11651 { BWN_PHY_TR_LOOKUP_1, 0 } 11652 }; 11653 static const struct bwn_smpair v2[] = { 11654 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11655 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11656 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11657 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11658 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11659 }; 11660 static const struct bwn_smpair v3[] = { 11661 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11662 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11663 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11664 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11665 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11666 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11667 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11668 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11669 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11670 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11671 11672 }; 11673 int i; 11674 11675 for (i = 0; i < N(v1); i++) 11676 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11677 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11678 for (i = 0; i < N(v2); i++) 11679 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11680 11681 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11682 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11683 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11684 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11685 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11686 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11687 } else { 11688 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11689 } 11690 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11691 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11692 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11693 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11694 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11695 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11696 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11697 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11698 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11699 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11700 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11701 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11702 (siba_get_chiprev(sc->sc_dev) == 0)) { 11703 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11704 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11705 } else { 11706 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11707 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11708 } 11709 for (i = 0; i < N(v3); i++) 11710 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11711 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11712 (siba_get_chiprev(sc->sc_dev) == 0)) { 11713 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11714 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11715 } 11716 11717 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11718 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11719 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11720 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11721 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11722 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11723 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11724 } else 11725 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11726 11727 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11728 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11729 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11730 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11731 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11732 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11733 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11734 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11735 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11736 11737 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11738 (siba_get_chiprev(sc->sc_dev) == 0)) { 11739 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11740 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11741 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11742 } 11743 11744 bwn_phy_lp_digflt_save(mac); 11745 } 11746 11747 static void 11748 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11749 { 11750 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11751 struct bwn_softc *sc = mac->mac_sc; 11752 struct ifnet *ifp = sc->sc_ifp; 11753 struct ieee80211com *ic = ifp->if_l2com; 11754 static const struct bwn_smpair v1[] = { 11755 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11756 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11757 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11758 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11759 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11760 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11761 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11762 }; 11763 static const struct bwn_smpair v2[] = { 11764 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11765 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11766 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11767 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11768 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11769 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11770 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11771 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11772 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11773 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11774 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11775 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11776 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11777 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11778 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11779 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11780 }; 11781 static const struct bwn_smpair v3[] = { 11782 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11783 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11784 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11785 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11786 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11787 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11788 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11789 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11790 }; 11791 static const struct bwn_smpair v4[] = { 11792 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11793 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11794 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11795 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11796 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11797 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11798 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11799 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11800 }; 11801 static const struct bwn_smpair v5[] = { 11802 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11803 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11804 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11805 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11806 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11807 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11808 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11809 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11810 }; 11811 int i; 11812 uint16_t tmp, tmp2; 11813 11814 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11815 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11816 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11817 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11818 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11819 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11820 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11821 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11822 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11823 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11824 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11825 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11826 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11827 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11828 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11829 for (i = 0; i < N(v1); i++) 11830 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11831 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11832 0xff00, plp->plp_rxpwroffset); 11833 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11834 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11835 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11836 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11837 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11838 if (mac->mac_phy.rev == 0) 11839 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11840 0xffcf, 0x0010); 11841 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11842 } else { 11843 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11844 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11845 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11846 } 11847 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11848 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11849 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11850 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11851 else 11852 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11853 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11854 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11855 0xfff9, (plp->plp_bxarch << 1)); 11856 if (mac->mac_phy.rev == 1 && 11857 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11858 for (i = 0; i < N(v2); i++) 11859 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11860 v2[i].set); 11861 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11862 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11863 ((mac->mac_phy.rev == 0) && 11864 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11865 for (i = 0; i < N(v3); i++) 11866 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11867 v3[i].set); 11868 } else if (mac->mac_phy.rev == 1 || 11869 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11870 for (i = 0; i < N(v4); i++) 11871 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11872 v4[i].set); 11873 } else { 11874 for (i = 0; i < N(v5); i++) 11875 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11876 v5[i].set); 11877 } 11878 if (mac->mac_phy.rev == 1 && 11879 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11880 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11881 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11882 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11883 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11884 } 11885 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11886 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11887 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11888 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11889 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11890 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11891 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11892 } 11893 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11894 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11895 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11896 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11897 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11898 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11899 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11900 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11901 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11902 } else { 11903 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11904 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11905 } 11906 if (mac->mac_phy.rev == 1) { 11907 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11908 tmp2 = (tmp & 0x03e0) >> 5; 11909 tmp2 |= tmp2 << 5; 11910 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11911 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 11912 tmp2 = (tmp & 0x1f00) >> 8; 11913 tmp2 |= tmp2 << 5; 11914 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 11915 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 11916 tmp2 = tmp & 0x00ff; 11917 tmp2 |= tmp << 8; 11918 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 11919 } 11920 } 11921 11922 struct bwn_b2062_freq { 11923 uint16_t freq; 11924 uint8_t value[6]; 11925 }; 11926 11927 static void 11928 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 11929 { 11930 #define CALC_CTL7(freq, div) \ 11931 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 11932 #define CALC_CTL18(freq, div) \ 11933 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 11934 #define CALC_CTL19(freq, div) \ 11935 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 11936 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11937 struct bwn_softc *sc = mac->mac_sc; 11938 struct ifnet *ifp = sc->sc_ifp; 11939 struct ieee80211com *ic = ifp->if_l2com; 11940 static const struct bwn_b2062_freq freqdata_tab[] = { 11941 { 12000, { 6, 6, 6, 6, 10, 6 } }, 11942 { 13000, { 4, 4, 4, 4, 11, 7 } }, 11943 { 14400, { 3, 3, 3, 3, 12, 7 } }, 11944 { 16200, { 3, 3, 3, 3, 13, 8 } }, 11945 { 18000, { 2, 2, 2, 2, 14, 8 } }, 11946 { 19200, { 1, 1, 1, 1, 14, 9 } } 11947 }; 11948 static const struct bwn_wpair v1[] = { 11949 { BWN_B2062_N_TXCTL3, 0 }, 11950 { BWN_B2062_N_TXCTL4, 0 }, 11951 { BWN_B2062_N_TXCTL5, 0 }, 11952 { BWN_B2062_N_TXCTL6, 0 }, 11953 { BWN_B2062_N_PDNCTL0, 0x40 }, 11954 { BWN_B2062_N_PDNCTL0, 0 }, 11955 { BWN_B2062_N_CALIB_TS, 0x10 }, 11956 { BWN_B2062_N_CALIB_TS, 0 } 11957 }; 11958 const struct bwn_b2062_freq *f = NULL; 11959 uint32_t xtalfreq, ref; 11960 unsigned int i; 11961 11962 bwn_phy_lp_b2062_tblinit(mac); 11963 11964 for (i = 0; i < N(v1); i++) 11965 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 11966 if (mac->mac_phy.rev > 0) 11967 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 11968 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 11969 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11970 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 11971 else 11972 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 11973 11974 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 11975 ("%s:%d: fail", __func__, __LINE__)); 11976 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11977 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 11978 11979 if (xtalfreq <= 30000000) { 11980 plp->plp_div = 1; 11981 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 11982 } else { 11983 plp->plp_div = 2; 11984 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 11985 } 11986 11987 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 11988 CALC_CTL7(xtalfreq, plp->plp_div)); 11989 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 11990 CALC_CTL18(xtalfreq, plp->plp_div)); 11991 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 11992 CALC_CTL19(xtalfreq, plp->plp_div)); 11993 11994 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 11995 ref &= 0xffff; 11996 for (i = 0; i < N(freqdata_tab); i++) { 11997 if (ref < freqdata_tab[i].freq) { 11998 f = &freqdata_tab[i]; 11999 break; 12000 } 12001 } 12002 if (f == NULL) 12003 f = &freqdata_tab[N(freqdata_tab) - 1]; 12004 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12005 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12006 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12007 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12008 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12009 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12010 #undef CALC_CTL7 12011 #undef CALC_CTL18 12012 #undef CALC_CTL19 12013 } 12014 12015 static void 12016 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12017 { 12018 12019 bwn_phy_lp_b2063_tblinit(mac); 12020 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12021 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12022 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12023 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12024 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12025 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12026 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12027 if (mac->mac_phy.rev == 2) { 12028 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12029 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12030 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12031 } else { 12032 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12033 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12034 } 12035 } 12036 12037 static void 12038 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12039 { 12040 struct bwn_softc *sc = mac->mac_sc; 12041 static const struct bwn_wpair v1[] = { 12042 { BWN_B2063_RX_BB_SP8, 0x0 }, 12043 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12044 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12045 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12046 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12047 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12048 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12049 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12050 }; 12051 static const struct bwn_wpair v2[] = { 12052 { BWN_B2063_TX_BB_SP3, 0x0 }, 12053 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12054 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12055 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12056 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12057 }; 12058 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12059 int i; 12060 uint8_t tmp; 12061 12062 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12063 12064 for (i = 0; i < 2; i++) 12065 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12066 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12067 for (i = 2; i < N(v1); i++) 12068 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12069 for (i = 0; i < 10000; i++) { 12070 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12071 break; 12072 DELAY(1000); 12073 } 12074 12075 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12076 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12077 12078 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12079 12080 for (i = 0; i < N(v2); i++) 12081 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12082 if (freqxtal == 24000000) { 12083 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12084 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12085 } else { 12086 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12087 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12088 } 12089 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12090 for (i = 0; i < 10000; i++) { 12091 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12092 break; 12093 DELAY(1000); 12094 } 12095 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12096 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12097 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12098 } 12099 12100 static void 12101 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12102 { 12103 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12104 struct bwn_softc *sc = mac->mac_sc; 12105 struct bwn_phy_lp_iq_est ie; 12106 struct bwn_txgain tx_gains; 12107 static const uint32_t pwrtbl[21] = { 12108 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12109 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12110 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12111 0x0004c, 0x0002c, 0x0001a, 12112 }; 12113 uint32_t npwr, ipwr, sqpwr, tmp; 12114 int loopback, i, j, sum, error; 12115 uint16_t save[7]; 12116 uint8_t txo, bbmult, txpctlmode; 12117 12118 error = bwn_phy_lp_switch_channel(mac, 7); 12119 if (error) 12120 device_printf(sc->sc_dev, 12121 "failed to change channel to 7 (%d)\n", error); 12122 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12123 bbmult = bwn_phy_lp_get_bbmult(mac); 12124 if (txo) 12125 tx_gains = bwn_phy_lp_get_txgain(mac); 12126 12127 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12128 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12129 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12130 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12131 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12132 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12133 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12134 12135 bwn_phy_lp_get_txpctlmode(mac); 12136 txpctlmode = plp->plp_txpctlmode; 12137 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12138 12139 /* disable CRS */ 12140 bwn_phy_lp_set_deaf(mac, 1); 12141 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12142 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12143 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12144 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12145 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12146 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12147 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12148 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12149 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12150 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12151 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12152 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12153 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12154 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12155 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12156 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12157 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12158 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12159 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12160 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12161 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12162 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12163 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12164 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12165 12166 loopback = bwn_phy_lp_loopback(mac); 12167 if (loopback == -1) 12168 goto done; 12169 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12170 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12171 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12172 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12173 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12174 12175 tmp = 0; 12176 memset(&ie, 0, sizeof(ie)); 12177 for (i = 128; i <= 159; i++) { 12178 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12179 sum = 0; 12180 for (j = 5; j <= 25; j++) { 12181 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12182 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12183 goto done; 12184 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12185 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12186 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12187 12); 12188 sum += ((ipwr - npwr) * (ipwr - npwr)); 12189 if ((i == 128) || (sum < tmp)) { 12190 plp->plp_rccap = i; 12191 tmp = sum; 12192 } 12193 } 12194 } 12195 bwn_phy_lp_ddfs_turnoff(mac); 12196 done: 12197 /* restore CRS */ 12198 bwn_phy_lp_clear_deaf(mac, 1); 12199 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12200 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12201 12202 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12203 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12204 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12205 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12206 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12207 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12208 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12209 12210 bwn_phy_lp_set_bbmult(mac, bbmult); 12211 if (txo) 12212 bwn_phy_lp_set_txgain(mac, &tx_gains); 12213 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12214 if (plp->plp_rccap) 12215 bwn_phy_lp_set_rccap(mac); 12216 } 12217 12218 static void 12219 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12220 { 12221 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12222 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12223 12224 if (mac->mac_phy.rev == 1) 12225 rc_cap = MIN(rc_cap + 5, 15); 12226 12227 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12228 MAX(plp->plp_rccap - 4, 0x80)); 12229 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12230 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12231 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12232 } 12233 12234 static uint32_t 12235 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12236 { 12237 uint32_t i, q, r; 12238 12239 if (div == 0) 12240 return (0); 12241 12242 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12243 q <<= 1; 12244 if (r << 1 >= div) { 12245 q++; 12246 r = (r << 1) - div; 12247 } 12248 } 12249 if (r << 1 >= div) 12250 q++; 12251 return (q); 12252 } 12253 12254 static void 12255 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12256 { 12257 struct bwn_softc *sc = mac->mac_sc; 12258 12259 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12260 DELAY(20); 12261 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12262 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12263 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12264 } else { 12265 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12266 } 12267 DELAY(5); 12268 } 12269 12270 static void 12271 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12272 { 12273 12274 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12275 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12276 DELAY(200); 12277 } 12278 12279 static void 12280 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12281 { 12282 #define FLAG_A 0x01 12283 #define FLAG_G 0x02 12284 struct bwn_softc *sc = mac->mac_sc; 12285 struct ifnet *ifp = sc->sc_ifp; 12286 struct ieee80211com *ic = ifp->if_l2com; 12287 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12288 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12289 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12290 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12291 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12292 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12293 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12294 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12295 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12296 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12297 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12298 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12299 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12300 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12301 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12302 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12303 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12304 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12305 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12306 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12307 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12308 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12309 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12310 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12311 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12312 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12313 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12314 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12315 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12316 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12317 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12318 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12319 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12320 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12321 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12322 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12323 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12324 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12325 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12326 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12327 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12328 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12329 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12330 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12331 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12332 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12333 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12334 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12335 }; 12336 const struct bwn_b206x_rfinit_entry *br; 12337 unsigned int i; 12338 12339 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12340 br = &bwn_b2062_init_tab[i]; 12341 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12342 if (br->br_flags & FLAG_G) 12343 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12344 } else { 12345 if (br->br_flags & FLAG_A) 12346 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12347 } 12348 } 12349 #undef FLAG_A 12350 #undef FLAG_B 12351 } 12352 12353 static void 12354 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12355 { 12356 #define FLAG_A 0x01 12357 #define FLAG_G 0x02 12358 struct bwn_softc *sc = mac->mac_sc; 12359 struct ifnet *ifp = sc->sc_ifp; 12360 struct ieee80211com *ic = ifp->if_l2com; 12361 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12362 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12363 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12364 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12365 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12366 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12367 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12368 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12369 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12370 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12371 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12372 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12373 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12374 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12375 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12376 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12377 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12378 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12379 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12380 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12381 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12382 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12383 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12384 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12385 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12386 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12387 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12388 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12389 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12390 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12391 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12392 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12393 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12394 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12395 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12396 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12397 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12398 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12399 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12400 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12401 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12402 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12403 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12404 }; 12405 const struct bwn_b206x_rfinit_entry *br; 12406 unsigned int i; 12407 12408 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12409 br = &bwn_b2063_init_tab[i]; 12410 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12411 if (br->br_flags & FLAG_G) 12412 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12413 } else { 12414 if (br->br_flags & FLAG_A) 12415 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12416 } 12417 } 12418 #undef FLAG_A 12419 #undef FLAG_B 12420 } 12421 12422 static void 12423 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12424 int count, void *_data) 12425 { 12426 unsigned int i; 12427 uint32_t offset, type; 12428 uint8_t *data = _data; 12429 12430 type = BWN_TAB_GETTYPE(typenoffset); 12431 offset = BWN_TAB_GETOFFSET(typenoffset); 12432 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12433 12434 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12435 12436 for (i = 0; i < count; i++) { 12437 switch (type) { 12438 case BWN_TAB_8BIT: 12439 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12440 data++; 12441 break; 12442 case BWN_TAB_16BIT: 12443 *((uint16_t *)data) = BWN_PHY_READ(mac, 12444 BWN_PHY_TABLEDATALO); 12445 data += 2; 12446 break; 12447 case BWN_TAB_32BIT: 12448 *((uint32_t *)data) = BWN_PHY_READ(mac, 12449 BWN_PHY_TABLEDATAHI); 12450 *((uint32_t *)data) <<= 16; 12451 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12452 BWN_PHY_TABLEDATALO); 12453 data += 4; 12454 break; 12455 default: 12456 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12457 } 12458 } 12459 } 12460 12461 static void 12462 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12463 int count, const void *_data) 12464 { 12465 uint32_t offset, type, value; 12466 const uint8_t *data = _data; 12467 unsigned int i; 12468 12469 type = BWN_TAB_GETTYPE(typenoffset); 12470 offset = BWN_TAB_GETOFFSET(typenoffset); 12471 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12472 12473 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12474 12475 for (i = 0; i < count; i++) { 12476 switch (type) { 12477 case BWN_TAB_8BIT: 12478 value = *data; 12479 data++; 12480 KASSERT(!(value & ~0xff), 12481 ("%s:%d: fail", __func__, __LINE__)); 12482 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12483 break; 12484 case BWN_TAB_16BIT: 12485 value = *((const uint16_t *)data); 12486 data += 2; 12487 KASSERT(!(value & ~0xffff), 12488 ("%s:%d: fail", __func__, __LINE__)); 12489 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12490 break; 12491 case BWN_TAB_32BIT: 12492 value = *((const uint32_t *)data); 12493 data += 4; 12494 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12495 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12496 break; 12497 default: 12498 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12499 } 12500 } 12501 } 12502 12503 static struct bwn_txgain 12504 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12505 { 12506 struct bwn_txgain tg; 12507 uint16_t tmp; 12508 12509 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12510 if (mac->mac_phy.rev < 2) { 12511 tmp = BWN_PHY_READ(mac, 12512 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12513 tg.tg_gm = tmp & 0x0007; 12514 tg.tg_pga = (tmp & 0x0078) >> 3; 12515 tg.tg_pad = (tmp & 0x780) >> 7; 12516 return (tg); 12517 } 12518 12519 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12520 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12521 tg.tg_gm = tmp & 0xff; 12522 tg.tg_pga = (tmp >> 8) & 0xff; 12523 return (tg); 12524 } 12525 12526 static uint8_t 12527 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12528 { 12529 12530 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12531 } 12532 12533 static void 12534 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12535 { 12536 uint16_t pa; 12537 12538 if (mac->mac_phy.rev < 2) { 12539 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12540 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12541 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12542 bwn_phy_lp_set_txgain_override(mac); 12543 return; 12544 } 12545 12546 pa = bwn_phy_lp_get_pa_gain(mac); 12547 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12548 (tg->tg_pga << 8) | tg->tg_gm); 12549 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12550 tg->tg_pad | (pa << 6)); 12551 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12552 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12553 tg->tg_pad | (pa << 8)); 12554 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12555 bwn_phy_lp_set_txgain_override(mac); 12556 } 12557 12558 static void 12559 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12560 { 12561 12562 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12563 } 12564 12565 static void 12566 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12567 { 12568 uint16_t trsw = (tx << 1) | rx; 12569 12570 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12571 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12572 } 12573 12574 static void 12575 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12576 { 12577 struct bwn_softc *sc = mac->mac_sc; 12578 struct ifnet *ifp = sc->sc_ifp; 12579 struct ieee80211com *ic = ifp->if_l2com; 12580 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12581 12582 if (mac->mac_phy.rev < 2) { 12583 trsw = gain & 0x1; 12584 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12585 ext_lna = (gain & 2) >> 1; 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 0xfbff, ext_lna << 10); 12590 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12591 0xf7ff, ext_lna << 11); 12592 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12593 } else { 12594 low_gain = gain & 0xffff; 12595 high_gain = (gain >> 16) & 0xf; 12596 ext_lna = (gain >> 21) & 0x1; 12597 trsw = ~(gain >> 20) & 0x1; 12598 12599 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12600 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12601 0xfdff, ext_lna << 9); 12602 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12603 0xfbff, ext_lna << 10); 12604 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12605 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12606 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12607 tmp = (gain >> 2) & 0x3; 12608 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12609 0xe7ff, tmp<<11); 12610 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12611 tmp << 3); 12612 } 12613 } 12614 12615 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12616 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12617 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12618 if (mac->mac_phy.rev >= 2) { 12619 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12620 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12621 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12622 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12623 } 12624 return; 12625 } 12626 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12627 } 12628 12629 static void 12630 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12631 { 12632 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12633 12634 if (user) 12635 plp->plp_crsusr_off = 1; 12636 else 12637 plp->plp_crssys_off = 1; 12638 12639 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12640 } 12641 12642 static void 12643 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12644 { 12645 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12646 struct bwn_softc *sc = mac->mac_sc; 12647 struct ifnet *ifp = sc->sc_ifp; 12648 struct ieee80211com *ic = ifp->if_l2com; 12649 12650 if (user) 12651 plp->plp_crsusr_off = 0; 12652 else 12653 plp->plp_crssys_off = 0; 12654 12655 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12656 return; 12657 12658 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12659 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12660 else 12661 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12662 } 12663 12664 static unsigned int 12665 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12666 { 12667 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12668 static uint8_t sqrt_table[256] = { 12669 10, 14, 17, 20, 22, 24, 26, 28, 12670 30, 31, 33, 34, 36, 37, 38, 40, 12671 41, 42, 43, 44, 45, 46, 47, 48, 12672 50, 50, 51, 52, 53, 54, 55, 56, 12673 57, 58, 59, 60, 60, 61, 62, 63, 12674 64, 64, 65, 66, 67, 67, 68, 69, 12675 70, 70, 71, 72, 72, 73, 74, 74, 12676 75, 76, 76, 77, 78, 78, 79, 80, 12677 80, 81, 81, 82, 83, 83, 84, 84, 12678 85, 86, 86, 87, 87, 88, 88, 89, 12679 90, 90, 91, 91, 92, 92, 93, 93, 12680 94, 94, 95, 95, 96, 96, 97, 97, 12681 98, 98, 99, 100, 100, 100, 101, 101, 12682 102, 102, 103, 103, 104, 104, 105, 105, 12683 106, 106, 107, 107, 108, 108, 109, 109, 12684 110, 110, 110, 111, 111, 112, 112, 113, 12685 113, 114, 114, 114, 115, 115, 116, 116, 12686 117, 117, 117, 118, 118, 119, 119, 120, 12687 120, 120, 121, 121, 122, 122, 122, 123, 12688 123, 124, 124, 124, 125, 125, 126, 126, 12689 126, 127, 127, 128, 128, 128, 129, 129, 12690 130, 130, 130, 131, 131, 131, 132, 132, 12691 133, 133, 133, 134, 134, 134, 135, 135, 12692 136, 136, 136, 137, 137, 137, 138, 138, 12693 138, 139, 139, 140, 140, 140, 141, 141, 12694 141, 142, 142, 142, 143, 143, 143, 144, 12695 144, 144, 145, 145, 145, 146, 146, 146, 12696 147, 147, 147, 148, 148, 148, 149, 149, 12697 150, 150, 150, 150, 151, 151, 151, 152, 12698 152, 152, 153, 153, 153, 154, 154, 154, 12699 155, 155, 155, 156, 156, 156, 157, 157, 12700 157, 158, 158, 158, 159, 159, 159, 160 12701 }; 12702 12703 if (x == 0) 12704 return (0); 12705 if (x >= 256) { 12706 unsigned int tmp; 12707 12708 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12709 /* do nothing */ ; 12710 return (tmp); 12711 } 12712 return (sqrt_table[x - 1] / 10); 12713 } 12714 12715 static int 12716 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12717 { 12718 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12719 int _t; \ 12720 _t = _x - 20; \ 12721 if (_t >= 0) { \ 12722 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12723 } else { \ 12724 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12725 } \ 12726 } while (0) 12727 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12728 int _t; \ 12729 _t = _x - 11; \ 12730 if (_t >= 0) \ 12731 _v = (_y << (31 - _x)) / (_z >> _t); \ 12732 else \ 12733 _v = (_y << (31 - _x)) / (_z << -_t); \ 12734 } while (0) 12735 struct bwn_phy_lp_iq_est ie; 12736 uint16_t v0, v1; 12737 int tmp[2], ret; 12738 12739 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12740 v0 = v1 >> 8; 12741 v1 |= 0xff; 12742 12743 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12744 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12745 12746 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12747 if (ret == 0) 12748 goto done; 12749 12750 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12751 ret = 0; 12752 goto done; 12753 } 12754 12755 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12756 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12757 12758 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12759 v0 = tmp[0] >> 3; 12760 v1 = tmp[1] >> 4; 12761 done: 12762 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12763 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12764 return ret; 12765 #undef CALC_COEFF 12766 #undef CALC_COEFF2 12767 } 12768 12769 static void 12770 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12771 { 12772 static const uint16_t noisescale[] = { 12773 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12774 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12775 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12776 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12777 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12778 }; 12779 static const uint16_t crsgainnft[] = { 12780 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12781 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12782 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12783 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12784 0x013d, 12785 }; 12786 static const uint16_t filterctl[] = { 12787 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12788 0xff53, 0x0127, 12789 }; 12790 static const uint32_t psctl[] = { 12791 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12792 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12793 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12794 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12795 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12796 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12797 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12798 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12799 }; 12800 static const uint16_t ofdmcckgain_r0[] = { 12801 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12802 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12803 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12804 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12805 0x755d, 12806 }; 12807 static const uint16_t ofdmcckgain_r1[] = { 12808 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12809 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12810 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12811 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12812 0x755d, 12813 }; 12814 static const uint16_t gaindelta[] = { 12815 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12816 0x0000, 12817 }; 12818 static const uint32_t txpwrctl[] = { 12819 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12820 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12821 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12822 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12823 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12824 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12825 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12826 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12827 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12828 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12829 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12830 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12831 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000, 12846 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12847 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12848 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12849 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12850 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12851 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12852 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12853 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12854 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12855 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12856 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12857 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12858 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12859 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12860 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12861 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12862 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12863 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12864 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12865 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12866 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12867 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12868 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12869 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12870 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12871 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12872 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12873 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12874 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12875 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12876 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12877 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12878 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12879 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12880 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12881 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12882 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 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, 0x04200000, 0x04000000, 12897 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12898 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12899 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12900 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12901 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12902 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12903 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12904 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12905 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12906 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12907 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12908 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12909 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12910 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12911 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 12912 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 12913 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 12914 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 12915 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 12916 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 12917 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 12918 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 12919 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 12920 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 12921 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 12922 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 12923 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 12924 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 12925 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 12926 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 12927 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 12928 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 12929 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 12930 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 12931 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 12932 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 12933 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 12934 0x00000702, 12935 }; 12936 12937 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 12938 12939 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 12940 bwn_tab_sigsq_tbl); 12941 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 12942 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 12943 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 12944 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 12945 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 12946 bwn_tab_pllfrac_tbl); 12947 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 12948 bwn_tabl_iqlocal_tbl); 12949 if (mac->mac_phy.rev == 0) { 12950 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 12951 ofdmcckgain_r0); 12952 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 12953 ofdmcckgain_r0); 12954 } else { 12955 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 12956 ofdmcckgain_r1); 12957 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 12958 ofdmcckgain_r1); 12959 } 12960 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 12961 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 12962 } 12963 12964 static void 12965 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 12966 { 12967 struct bwn_softc *sc = mac->mac_sc; 12968 int i; 12969 static const uint16_t noisescale[] = { 12970 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12971 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12972 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12973 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12974 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12975 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12976 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 12977 }; 12978 static const uint32_t filterctl[] = { 12979 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 12980 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 12981 }; 12982 static const uint32_t psctl[] = { 12983 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 12984 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 12985 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 12986 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 12987 }; 12988 static const uint32_t gainidx[] = { 12989 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12990 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12991 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12992 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 12993 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 12994 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 12995 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 12996 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 12997 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 12998 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 12999 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13000 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13001 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13002 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13003 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13004 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13005 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13006 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13007 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13008 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13009 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13010 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13011 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13012 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13013 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13014 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13015 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13016 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13017 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13018 0x0000001a, 0x64ca55ad, 0x0000001a 13019 }; 13020 static const uint16_t auxgainidx[] = { 13021 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13022 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13023 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13024 0x0004, 0x0016 13025 }; 13026 static const uint16_t swctl[] = { 13027 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13028 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13029 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13030 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13031 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13032 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13033 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13034 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13035 }; 13036 static const uint8_t hf[] = { 13037 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13038 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13039 }; 13040 static const uint32_t gainval[] = { 13041 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13042 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13043 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13044 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13045 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13046 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13047 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13048 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13049 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13050 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13051 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13052 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13053 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13054 0x000000f1, 0x00000000, 0x00000000 13055 }; 13056 static const uint16_t gain[] = { 13057 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13058 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13059 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13060 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13061 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13062 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13063 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13064 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13065 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13066 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13067 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13068 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13069 }; 13070 static const uint32_t papdeps[] = { 13071 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13072 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13073 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13074 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13075 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13076 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13077 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13078 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13079 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13080 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13081 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13082 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13083 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13084 }; 13085 static const uint32_t papdmult[] = { 13086 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13087 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13088 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13089 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13090 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13091 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13092 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13093 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13094 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13095 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13096 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13097 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13098 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13099 }; 13100 static const uint32_t gainidx_a0[] = { 13101 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13102 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13103 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13104 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13105 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13106 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13107 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13108 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13109 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13110 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13111 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13112 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13113 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13114 }; 13115 static const uint16_t auxgainidx_a0[] = { 13116 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13117 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13118 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13119 0x0002, 0x0014 13120 }; 13121 static const uint32_t gainval_a0[] = { 13122 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13123 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13124 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13125 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13126 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13127 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13128 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13129 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13130 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13131 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13132 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13133 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13134 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13135 0x000000f7, 0x00000000, 0x00000000 13136 }; 13137 static const uint16_t gain_a0[] = { 13138 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13139 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13140 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13141 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13142 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13143 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13144 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13145 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13146 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13147 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13148 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13149 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13150 }; 13151 13152 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13153 13154 for (i = 0; i < 704; i++) 13155 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13156 13157 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13158 bwn_tab_sigsq_tbl); 13159 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13160 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13161 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13162 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13163 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13164 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13165 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13166 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13167 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13168 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13169 bwn_tab_pllfrac_tbl); 13170 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13171 bwn_tabl_iqlocal_tbl); 13172 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13173 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13174 13175 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13176 (siba_get_chiprev(sc->sc_dev) == 0)) { 13177 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13178 gainidx_a0); 13179 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13180 auxgainidx_a0); 13181 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13182 gainval_a0); 13183 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13184 } 13185 } 13186 13187 static void 13188 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13189 { 13190 struct bwn_softc *sc = mac->mac_sc; 13191 struct ifnet *ifp = sc->sc_ifp; 13192 struct ieee80211com *ic = ifp->if_l2com; 13193 static struct bwn_txgain_entry txgain_r2[] = { 13194 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13195 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13196 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13197 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13198 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13199 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13200 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13201 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13202 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13203 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13204 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13205 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13206 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13207 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13208 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13209 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13210 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13211 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13212 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13213 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13214 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13215 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13216 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13217 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13218 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13219 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13220 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13221 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13222 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13223 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13224 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13225 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13226 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13227 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13228 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13229 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13230 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13231 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13232 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13233 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13234 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13235 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13236 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13237 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13238 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13239 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13240 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13241 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13242 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13243 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13244 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13245 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13246 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13247 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13248 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13249 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13250 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13251 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13252 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13253 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13254 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13255 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13256 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13257 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13258 }; 13259 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13260 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13261 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13262 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13263 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13264 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13265 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13266 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13267 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13268 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13269 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13270 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13271 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13272 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13273 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13274 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13275 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13276 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13277 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13278 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13279 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13280 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13281 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13282 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13283 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13284 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13285 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13286 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13287 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13288 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13289 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13290 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13291 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13292 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13293 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13294 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13295 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13296 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13297 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13298 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13299 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13300 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13301 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13302 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13303 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13304 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13305 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13306 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13307 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13308 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13309 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13310 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13311 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13312 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13313 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13314 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13315 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13316 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13317 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13318 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13319 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13320 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13321 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13322 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13323 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13324 }; 13325 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13326 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13327 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13328 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13329 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13330 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13331 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13332 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13333 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13334 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13335 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13336 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13337 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13338 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13339 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13340 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13341 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13342 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13343 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13344 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13345 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13346 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13347 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13348 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13349 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13350 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13351 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13352 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13353 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13354 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13355 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13356 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13357 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13358 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13359 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13360 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13361 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13362 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13363 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13364 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13365 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13366 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13367 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13368 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13369 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13370 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13371 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13372 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13373 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13374 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13375 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13376 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13377 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13378 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13379 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13380 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13381 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13382 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13383 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13384 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13385 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13386 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13387 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13388 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13389 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13390 }; 13391 static struct bwn_txgain_entry txgain_r0[] = { 13392 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13393 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13394 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13395 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13396 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13397 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13398 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13399 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13400 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13401 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13402 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13403 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13404 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13405 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13406 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13407 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13408 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13409 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13410 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13411 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13412 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13413 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13414 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13415 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13416 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13417 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13418 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13419 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13420 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13421 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13422 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13423 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13424 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13425 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13426 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13427 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13428 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13429 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13430 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13431 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13432 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13433 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13434 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13435 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13436 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13437 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13438 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13439 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13440 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13441 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13442 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13443 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13444 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13445 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13446 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13447 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13448 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13449 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13450 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13451 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13452 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13453 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13454 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13455 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13456 }; 13457 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13458 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13459 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13460 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13461 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13462 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13463 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13464 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13465 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13466 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13467 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13468 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13469 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13470 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13471 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13472 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13473 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13474 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13475 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13476 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13477 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13478 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13479 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13480 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13481 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13482 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13483 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13484 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13485 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13486 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13487 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13488 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13489 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13490 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13491 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13492 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13493 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13494 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13495 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13496 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13497 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13498 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13499 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13500 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13501 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13502 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13503 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13504 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13505 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13506 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13507 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13508 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13509 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13510 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13511 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13512 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13513 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13514 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13515 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13516 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13517 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13518 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13519 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13520 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13521 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13522 }; 13523 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13524 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13525 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13526 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13527 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13528 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13529 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13530 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13531 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13532 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13533 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13534 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13535 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13536 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13537 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13538 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13539 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13540 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13541 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13542 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13543 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13544 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13545 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13546 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13547 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13548 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13549 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13550 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13551 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13552 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13553 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13554 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13555 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13556 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13557 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13558 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13559 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13560 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13561 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13562 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13563 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13564 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13565 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13566 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13567 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13568 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13569 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13570 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13571 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13572 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13573 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13574 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13575 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13576 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13577 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13578 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13579 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13580 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13581 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13582 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13583 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13584 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13585 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13586 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13587 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13588 }; 13589 static struct bwn_txgain_entry txgain_r1[] = { 13590 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13591 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13592 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13593 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13594 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13595 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13596 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13597 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13598 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13599 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13600 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13601 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13602 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13603 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13604 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13605 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13606 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13607 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13608 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13609 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13610 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13611 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13612 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13613 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13614 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13615 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13616 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13617 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13618 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13619 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13620 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13621 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13622 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13623 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13624 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13625 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13626 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13627 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13628 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13629 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13630 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13631 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13632 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13633 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13634 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13635 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13636 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13637 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13638 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13639 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13640 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13641 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13642 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13643 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13644 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13645 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13646 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13647 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13648 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13649 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13650 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13651 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13652 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13653 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13654 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13655 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13656 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13657 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13658 { 7, 11, 6, 0, 71 } 13659 }; 13660 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13661 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13662 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13663 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13664 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13665 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13666 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13667 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13668 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13669 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13670 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13671 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13672 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13673 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13674 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13675 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13676 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13677 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13678 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13679 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13680 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13681 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13682 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13683 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13684 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13685 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13686 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13687 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13688 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13689 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13690 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13691 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13692 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13693 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13694 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13695 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13696 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13697 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13698 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13699 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13700 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13701 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13702 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13703 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13704 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13705 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13706 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13707 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13708 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13709 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13710 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13711 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13712 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13713 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13714 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13715 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13716 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13717 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13718 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13719 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13720 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13721 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13722 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13723 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13724 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13725 }; 13726 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13727 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13728 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13729 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13730 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13731 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13732 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13733 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13734 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13735 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13736 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13737 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13738 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13739 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13740 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13741 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13742 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13743 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13744 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13745 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13746 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13747 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13748 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13749 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13750 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13751 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13752 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13753 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13754 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13755 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13756 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13757 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13758 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13759 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13760 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13761 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13762 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13763 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13764 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13765 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13766 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13767 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13768 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13769 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13770 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13771 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13772 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13773 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13774 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13775 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13776 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13777 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13778 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13779 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13780 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13781 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13782 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13783 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13784 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13785 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13786 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13787 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13788 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13789 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13790 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13791 }; 13792 13793 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13794 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13795 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13796 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13797 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13798 txgain_2ghz_r2); 13799 else 13800 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13801 txgain_5ghz_r2); 13802 return; 13803 } 13804 13805 if (mac->mac_phy.rev == 0) { 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_r0); 13809 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13810 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13811 txgain_2ghz_r0); 13812 else 13813 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13814 txgain_5ghz_r0); 13815 return; 13816 } 13817 13818 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13819 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13820 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13821 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13822 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13823 else 13824 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13825 } 13826 13827 static void 13828 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13829 { 13830 uint32_t offset, type; 13831 13832 type = BWN_TAB_GETTYPE(typeoffset); 13833 offset = BWN_TAB_GETOFFSET(typeoffset); 13834 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13835 13836 switch (type) { 13837 case BWN_TAB_8BIT: 13838 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13839 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13840 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13841 break; 13842 case BWN_TAB_16BIT: 13843 KASSERT(!(value & ~0xffff), 13844 ("%s:%d: fail", __func__, __LINE__)); 13845 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13846 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13847 break; 13848 case BWN_TAB_32BIT: 13849 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13850 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13851 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13852 break; 13853 default: 13854 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13855 } 13856 } 13857 13858 static int 13859 bwn_phy_lp_loopback(struct bwn_mac *mac) 13860 { 13861 struct bwn_phy_lp_iq_est ie; 13862 int i, index = -1; 13863 uint32_t tmp; 13864 13865 memset(&ie, 0, sizeof(ie)); 13866 13867 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13868 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13869 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13870 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13871 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13872 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13873 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13874 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13875 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13876 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13877 for (i = 0; i < 32; i++) { 13878 bwn_phy_lp_set_rxgain_idx(mac, i); 13879 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13880 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13881 continue; 13882 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13883 if ((tmp > 4000) && (tmp < 10000)) { 13884 index = i; 13885 break; 13886 } 13887 } 13888 bwn_phy_lp_ddfs_turnoff(mac); 13889 return (index); 13890 } 13891 13892 static void 13893 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13894 { 13895 13896 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13897 } 13898 13899 static void 13900 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13901 int incr1, int incr2, int scale_idx) 13902 { 13903 13904 bwn_phy_lp_ddfs_turnoff(mac); 13905 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13906 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13907 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13908 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13909 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13910 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13911 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 13912 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 13913 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 13914 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 13915 } 13916 13917 static uint8_t 13918 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 13919 struct bwn_phy_lp_iq_est *ie) 13920 { 13921 int i; 13922 13923 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 13924 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 13925 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 13926 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 13927 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 13928 13929 for (i = 0; i < 500; i++) { 13930 if (!(BWN_PHY_READ(mac, 13931 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 13932 break; 13933 DELAY(1000); 13934 } 13935 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 13936 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13937 return 0; 13938 } 13939 13940 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 13941 ie->ie_iqprod <<= 16; 13942 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 13943 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 13944 ie->ie_ipwr <<= 16; 13945 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 13946 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 13947 ie->ie_qpwr <<= 16; 13948 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 13949 13950 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13951 return 1; 13952 } 13953 13954 static uint32_t 13955 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 13956 { 13957 uint32_t offset, type, value; 13958 13959 type = BWN_TAB_GETTYPE(typeoffset); 13960 offset = BWN_TAB_GETOFFSET(typeoffset); 13961 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13962 13963 switch (type) { 13964 case BWN_TAB_8BIT: 13965 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13966 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 13967 break; 13968 case BWN_TAB_16BIT: 13969 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13970 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13971 break; 13972 case BWN_TAB_32BIT: 13973 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13974 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 13975 value <<= 16; 13976 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13977 break; 13978 default: 13979 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13980 value = 0; 13981 } 13982 13983 return (value); 13984 } 13985 13986 static void 13987 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 13988 { 13989 13990 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 13991 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 13992 } 13993 13994 static void 13995 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 13996 { 13997 uint16_t ctl; 13998 13999 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14000 ctl |= dac << 7; 14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14002 } 14003 14004 static void 14005 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14006 { 14007 14008 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14009 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14010 } 14011 14012 static void 14013 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14014 { 14015 14016 if (mac->mac_phy.rev < 2) 14017 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14018 else { 14019 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14020 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14021 } 14022 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14023 } 14024 14025 static uint16_t 14026 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14027 { 14028 14029 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14030 } 14031 14032 static uint8_t 14033 bwn_nbits(int32_t val) 14034 { 14035 uint32_t tmp; 14036 uint8_t nbits = 0; 14037 14038 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14039 nbits++; 14040 return (nbits); 14041 } 14042 14043 static void 14044 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14045 struct bwn_txgain_entry *table) 14046 { 14047 int i; 14048 14049 for (i = offset; i < count; i++) 14050 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14051 } 14052 14053 static void 14054 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14055 struct bwn_txgain_entry data) 14056 { 14057 14058 if (mac->mac_phy.rev >= 2) 14059 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14060 else 14061 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14062 } 14063 14064 static void 14065 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14066 struct bwn_txgain_entry te) 14067 { 14068 struct bwn_softc *sc = mac->mac_sc; 14069 struct ifnet *ifp = sc->sc_ifp; 14070 struct ieee80211com *ic = ifp->if_l2com; 14071 uint32_t tmp; 14072 14073 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14074 14075 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14076 if (mac->mac_phy.rev >= 3) { 14077 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14078 (0x10 << 24) : (0x70 << 24)); 14079 } else { 14080 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14081 (0x14 << 24) : (0x7f << 24)); 14082 } 14083 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14084 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14085 te.te_bbmult << 20 | te.te_dac << 28); 14086 } 14087 14088 static void 14089 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14090 struct bwn_txgain_entry te) 14091 { 14092 14093 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14094 14095 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14096 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14097 te.te_dac); 14098 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14099 } 14100 14101 static void 14102 bwn_sysctl_node(struct bwn_softc *sc) 14103 { 14104 struct bwn_mac *mac; 14105 struct bwn_stats *stats; 14106 struct sysctl_ctx_list *ctx; 14107 struct sysctl_oid *tree; 14108 14109 /* XXX assume that count of MAC is only 1. */ 14110 14111 if ((mac = sc->sc_curmac) == NULL) 14112 return; 14113 stats = &mac->mac_stats; 14114 14115 ctx = &sc->sc_sysctl_ctx; 14116 tree = sc->sc_sysctl_tree; 14117 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14118 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14119 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14120 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14121 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14122 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14123 14124 #ifdef BWN_DEBUG 14125 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 14126 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14127 #endif 14128 } 14129 14130 static device_method_t bwn_methods[] = { 14131 /* Device interface */ 14132 DEVMETHOD(device_probe, bwn_probe), 14133 DEVMETHOD(device_attach, bwn_attach), 14134 DEVMETHOD(device_detach, bwn_detach), 14135 DEVMETHOD(device_suspend, bwn_suspend), 14136 DEVMETHOD(device_resume, bwn_resume), 14137 DEVMETHOD_END 14138 }; 14139 static driver_t bwn_driver = { 14140 "bwn", 14141 bwn_methods, 14142 sizeof(struct bwn_softc) 14143 }; 14144 static devclass_t bwn_devclass; 14145 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14146 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14147 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14148 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14149 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14150