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$"); 32 33 /* 34 * The Broadcom Wireless LAN controller driver. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/module.h> 40 #include <sys/kernel.h> 41 #include <sys/endian.h> 42 #include <sys/errno.h> 43 #include <sys/firmware.h> 44 #include <sys/lock.h> 45 #include <sys/mutex.h> 46 #include <machine/bus.h> 47 #include <machine/resource.h> 48 #include <sys/bus.h> 49 #include <sys/rman.h> 50 #include <sys/socket.h> 51 #include <sys/sockio.h> 52 53 #include <net/ethernet.h> 54 #include <net/if.h> 55 #include <net/if_arp.h> 56 #include <net/if_dl.h> 57 #include <net/if_llc.h> 58 #include <net/if_media.h> 59 #include <net/if_types.h> 60 61 #include <dev/pci/pcivar.h> 62 #include <dev/pci/pcireg.h> 63 #include <dev/siba/siba_ids.h> 64 #include <dev/siba/sibareg.h> 65 #include <dev/siba/sibavar.h> 66 67 #include <net80211/ieee80211_var.h> 68 #include <net80211/ieee80211_radiotap.h> 69 #include <net80211/ieee80211_regdomain.h> 70 #include <net80211/ieee80211_phy.h> 71 #include <net80211/ieee80211_ratectl.h> 72 73 #include <dev/bwn/if_bwnreg.h> 74 #include <dev/bwn/if_bwnvar.h> 75 76 SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters"); 77 78 /* 79 * Tunable & sysctl variables. 80 */ 81 82 #ifdef BWN_DEBUG 83 static int bwn_debug = 0; 84 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0, 85 "Broadcom debugging printfs"); 86 TUNABLE_INT("hw.bwn.debug", &bwn_debug); 87 enum { 88 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 89 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 90 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 91 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 92 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 93 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 94 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 95 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 96 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 97 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 98 BWN_DEBUG_NODE = 0x00000400, /* node management */ 99 BWN_DEBUG_LED = 0x00000800, /* led management */ 100 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 101 BWN_DEBUG_LO = 0x00002000, /* LO */ 102 BWN_DEBUG_FW = 0x00004000, /* firmware */ 103 BWN_DEBUG_WME = 0x00008000, /* WME */ 104 BWN_DEBUG_RF = 0x00010000, /* RF */ 105 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 106 BWN_DEBUG_ANY = 0xffffffff 107 }; 108 #define DPRINTF(sc, m, fmt, ...) do { \ 109 if (sc->sc_debug & (m)) \ 110 printf(fmt, __VA_ARGS__); \ 111 } while (0) 112 #else 113 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 114 #endif 115 116 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 117 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 118 "uses Bad Frames Preemption"); 119 static int bwn_bluetooth = 1; 120 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 121 "turns on Bluetooth Coexistence"); 122 static int bwn_hwpctl = 0; 123 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 124 "uses H/W power control"); 125 static int bwn_msi_disable = 0; /* MSI disabled */ 126 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable); 127 static int bwn_usedma = 1; 128 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 129 "uses DMA"); 130 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 131 static int bwn_wme = 1; 132 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 133 "uses WME support"); 134 135 static int bwn_attach_pre(struct bwn_softc *); 136 static int bwn_attach_post(struct bwn_softc *); 137 static void bwn_sprom_bugfixes(device_t); 138 static void bwn_init(void *); 139 static int bwn_init_locked(struct bwn_softc *); 140 static int bwn_ioctl(struct ifnet *, u_long, caddr_t); 141 static void bwn_start(struct ifnet *); 142 static int bwn_attach_core(struct bwn_mac *); 143 static void bwn_reset_core(struct bwn_mac *, uint32_t); 144 static int bwn_phy_getinfo(struct bwn_mac *, int); 145 static int bwn_chiptest(struct bwn_mac *); 146 static int bwn_setup_channels(struct bwn_mac *, int, int); 147 static int bwn_phy_g_attach(struct bwn_mac *); 148 static void bwn_phy_g_detach(struct bwn_mac *); 149 static void bwn_phy_g_init_pre(struct bwn_mac *); 150 static int bwn_phy_g_prepare_hw(struct bwn_mac *); 151 static int bwn_phy_g_init(struct bwn_mac *); 152 static void bwn_phy_g_exit(struct bwn_mac *); 153 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 154 static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 155 uint16_t); 156 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 157 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 158 uint16_t); 159 static int bwn_phy_g_hwpctl(struct bwn_mac *); 160 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 161 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 162 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 163 static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 164 static int bwn_phy_g_im(struct bwn_mac *, int); 165 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 166 static void bwn_phy_g_set_txpwr(struct bwn_mac *); 167 static void bwn_phy_g_task_15s(struct bwn_mac *); 168 static void bwn_phy_g_task_60s(struct bwn_mac *); 169 static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 170 static void bwn_phy_switch_analog(struct bwn_mac *, int); 171 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 172 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 173 uint16_t); 174 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 175 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 176 uint32_t); 177 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 178 uint16_t); 179 static void bwn_addchannels(struct ieee80211_channel [], int, int *, 180 const struct bwn_channelinfo *, int); 181 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 182 const struct ieee80211_bpf_params *); 183 static void bwn_updateslot(struct ifnet *); 184 static void bwn_update_promisc(struct ifnet *); 185 static void bwn_wme_init(struct bwn_mac *); 186 static int bwn_wme_update(struct ieee80211com *); 187 static void bwn_wme_clear(struct bwn_softc *); 188 static void bwn_wme_load(struct bwn_mac *); 189 static void bwn_wme_loadparams(struct bwn_mac *, 190 const struct wmeParams *, uint16_t); 191 static void bwn_scan_start(struct ieee80211com *); 192 static void bwn_scan_end(struct ieee80211com *); 193 static void bwn_set_channel(struct ieee80211com *); 194 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 195 const char [IFNAMSIZ], int, int, 196 int, const uint8_t [IEEE80211_ADDR_LEN], 197 const uint8_t [IEEE80211_ADDR_LEN]); 198 static void bwn_vap_delete(struct ieee80211vap *); 199 static void bwn_stop(struct bwn_softc *, int); 200 static void bwn_stop_locked(struct bwn_softc *, int); 201 static int bwn_core_init(struct bwn_mac *); 202 static void bwn_core_start(struct bwn_mac *); 203 static void bwn_core_exit(struct bwn_mac *); 204 static void bwn_bt_disable(struct bwn_mac *); 205 static int bwn_chip_init(struct bwn_mac *); 206 static uint64_t bwn_hf_read(struct bwn_mac *); 207 static void bwn_hf_write(struct bwn_mac *, uint64_t); 208 static void bwn_set_txretry(struct bwn_mac *, int, int); 209 static void bwn_rate_init(struct bwn_mac *); 210 static void bwn_set_phytxctl(struct bwn_mac *); 211 static void bwn_spu_setdelay(struct bwn_mac *, int); 212 static void bwn_bt_enable(struct bwn_mac *); 213 static void bwn_set_macaddr(struct bwn_mac *); 214 static void bwn_crypt_init(struct bwn_mac *); 215 static void bwn_chip_exit(struct bwn_mac *); 216 static int bwn_fw_fillinfo(struct bwn_mac *); 217 static int bwn_fw_loaducode(struct bwn_mac *); 218 static int bwn_gpio_init(struct bwn_mac *); 219 static int bwn_fw_loadinitvals(struct bwn_mac *); 220 static int bwn_phy_init(struct bwn_mac *); 221 static void bwn_set_txantenna(struct bwn_mac *, int); 222 static void bwn_set_opmode(struct bwn_mac *); 223 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 224 static uint8_t bwn_plcp_getcck(const uint8_t); 225 static uint8_t bwn_plcp_getofdm(const uint8_t); 226 static void bwn_pio_init(struct bwn_mac *); 227 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 228 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 229 int); 230 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 231 struct bwn_pio_rxqueue *, int); 232 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 233 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 234 uint16_t); 235 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 236 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 237 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 238 static void bwn_pio_handle_txeof(struct bwn_mac *, 239 const struct bwn_txstatus *); 240 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 241 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 242 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 243 uint16_t); 244 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 245 uint32_t); 246 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 247 struct mbuf *); 248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 249 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 250 struct bwn_pio_txqueue *, uint32_t, const void *, int); 251 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 252 uint16_t, uint32_t); 253 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 254 struct bwn_pio_txqueue *, uint16_t, const void *, int); 255 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 256 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 258 uint16_t, struct bwn_pio_txpkt **); 259 static void bwn_dma_init(struct bwn_mac *); 260 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 261 static int bwn_dma_mask2type(uint64_t); 262 static uint64_t bwn_dma_mask(struct bwn_mac *); 263 static uint16_t bwn_dma_base(int, int); 264 static void bwn_dma_ringfree(struct bwn_dma_ring **); 265 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 266 int, struct bwn_dmadesc_generic **, 267 struct bwn_dmadesc_meta **); 268 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 269 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 270 int, int); 271 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 272 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 273 static void bwn_dma_32_resume(struct bwn_dma_ring *); 274 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 275 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 276 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 277 int, struct bwn_dmadesc_generic **, 278 struct bwn_dmadesc_meta **); 279 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 280 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 281 int, int); 282 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 283 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 284 static void bwn_dma_64_resume(struct bwn_dma_ring *); 285 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 286 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 287 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 288 static void bwn_dma_setup(struct bwn_dma_ring *); 289 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 290 static void bwn_dma_cleanup(struct bwn_dma_ring *); 291 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 292 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 293 static void bwn_dma_rx(struct bwn_dma_ring *); 294 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 295 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 296 struct bwn_dmadesc_meta *); 297 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 298 static int bwn_dma_gettype(struct bwn_mac *); 299 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 300 static int bwn_dma_freeslot(struct bwn_dma_ring *); 301 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 302 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 303 static int bwn_dma_newbuf(struct bwn_dma_ring *, 304 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 305 int); 306 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 307 bus_size_t, int); 308 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 309 static void bwn_dma_handle_txeof(struct bwn_mac *, 310 const struct bwn_txstatus *); 311 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 312 struct mbuf *); 313 static int bwn_dma_getslot(struct bwn_dma_ring *); 314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 315 uint8_t); 316 static int bwn_dma_attach(struct bwn_mac *); 317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 318 int, int, int); 319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 320 const struct bwn_txstatus *, uint16_t, int *); 321 static void bwn_dma_free(struct bwn_mac *); 322 static void bwn_phy_g_init_sub(struct bwn_mac *); 323 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 324 static void bwn_phy_init_b5(struct bwn_mac *); 325 static void bwn_phy_init_b6(struct bwn_mac *); 326 static void bwn_phy_init_a(struct bwn_mac *); 327 static void bwn_loopback_calcgain(struct bwn_mac *); 328 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 329 static void bwn_lo_g_init(struct bwn_mac *); 330 static void bwn_lo_g_adjust(struct bwn_mac *); 331 static void bwn_lo_get_powervector(struct bwn_mac *); 332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 333 const struct bwn_bbatt *, const struct bwn_rfatt *); 334 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 335 static void bwn_phy_hwpctl_init(struct bwn_mac *); 336 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 337 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 338 const struct bwn_bbatt *, const struct bwn_rfatt *, 339 uint8_t); 340 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 341 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 342 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 343 static void bwn_wa_init(struct bwn_mac *); 344 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 345 uint16_t); 346 static void bwn_dummy_transmission(struct bwn_mac *, int, int); 347 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 348 uint32_t); 349 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 350 uint16_t); 351 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 352 static void bwn_mac_suspend(struct bwn_mac *); 353 static void bwn_mac_enable(struct bwn_mac *); 354 static void bwn_psctl(struct bwn_mac *, uint32_t); 355 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 356 static void bwn_nrssi_offset(struct bwn_mac *); 357 static void bwn_nrssi_threshold(struct bwn_mac *); 358 static void bwn_nrssi_slope_11g(struct bwn_mac *); 359 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 360 int16_t); 361 static void bwn_set_original_gains(struct bwn_mac *); 362 static void bwn_hwpctl_early_init(struct bwn_mac *); 363 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 364 static uint16_t bwn_phy_g_chan2freq(uint8_t); 365 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 366 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 367 const char *, struct bwn_fwfile *); 368 static void bwn_release_firmware(struct bwn_mac *); 369 static void bwn_do_release_fw(struct bwn_fwfile *); 370 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 371 static int bwn_fwinitvals_write(struct bwn_mac *, 372 const struct bwn_fwinitvals *, size_t, size_t); 373 static int bwn_switch_channel(struct bwn_mac *, int); 374 static uint16_t bwn_ant2phy(int); 375 static void bwn_mac_write_bssid(struct bwn_mac *); 376 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 377 const uint8_t *); 378 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 379 const uint8_t *, size_t, const uint8_t *); 380 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 381 const uint8_t *); 382 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 383 const uint8_t *); 384 static void bwn_phy_exit(struct bwn_mac *); 385 static void bwn_core_stop(struct bwn_mac *); 386 static int bwn_switch_band(struct bwn_softc *, 387 struct ieee80211_channel *); 388 static void bwn_phy_reset(struct bwn_mac *); 389 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 390 static void bwn_set_pretbtt(struct bwn_mac *); 391 static int bwn_intr(void *); 392 static void bwn_intrtask(void *, int); 393 static void bwn_restart(struct bwn_mac *, const char *); 394 static void bwn_intr_ucode_debug(struct bwn_mac *); 395 static void bwn_intr_tbtt_indication(struct bwn_mac *); 396 static void bwn_intr_atim_end(struct bwn_mac *); 397 static void bwn_intr_beacon(struct bwn_mac *); 398 static void bwn_intr_pmq(struct bwn_mac *); 399 static void bwn_intr_noise(struct bwn_mac *); 400 static void bwn_intr_txeof(struct bwn_mac *); 401 static void bwn_hwreset(void *, int); 402 static void bwn_handle_fwpanic(struct bwn_mac *); 403 static void bwn_load_beacon0(struct bwn_mac *); 404 static void bwn_load_beacon1(struct bwn_mac *); 405 static uint32_t bwn_jssi_read(struct bwn_mac *); 406 static void bwn_noise_gensample(struct bwn_mac *); 407 static void bwn_handle_txeof(struct bwn_mac *, 408 const struct bwn_txstatus *); 409 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 410 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 411 static void bwn_start_locked(struct ifnet *); 412 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 413 struct mbuf *); 414 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 415 static int bwn_set_txhdr(struct bwn_mac *, 416 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 417 uint16_t); 418 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 419 const uint8_t); 420 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 421 static uint8_t bwn_get_fbrate(uint8_t); 422 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 423 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 424 static void bwn_phy_lock(struct bwn_mac *); 425 static void bwn_phy_unlock(struct bwn_mac *); 426 static void bwn_rf_lock(struct bwn_mac *); 427 static void bwn_rf_unlock(struct bwn_mac *); 428 static void bwn_txpwr(void *, int); 429 static void bwn_tasks(void *); 430 static void bwn_task_15s(struct bwn_mac *); 431 static void bwn_task_30s(struct bwn_mac *); 432 static void bwn_task_60s(struct bwn_mac *); 433 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 434 uint8_t); 435 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 436 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 437 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 438 int, int); 439 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 440 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 441 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 442 static void bwn_watchdog(void *); 443 static void bwn_dma_stop(struct bwn_mac *); 444 static void bwn_pio_stop(struct bwn_mac *); 445 static void bwn_dma_ringstop(struct bwn_dma_ring **); 446 static void bwn_led_attach(struct bwn_mac *); 447 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 448 static void bwn_led_event(struct bwn_mac *, int); 449 static void bwn_led_blink_start(struct bwn_mac *, int, int); 450 static void bwn_led_blink_next(void *); 451 static void bwn_led_blink_end(void *); 452 static void bwn_rfswitch(void *); 453 static void bwn_rf_turnon(struct bwn_mac *); 454 static void bwn_rf_turnoff(struct bwn_mac *); 455 static void bwn_phy_lp_init_pre(struct bwn_mac *); 456 static int bwn_phy_lp_init(struct bwn_mac *); 457 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 458 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 459 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 460 uint16_t); 461 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 462 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 463 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 464 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 465 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 466 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 467 static void bwn_phy_lp_task_60s(struct bwn_mac *); 468 static void bwn_phy_lp_readsprom(struct bwn_mac *); 469 static void bwn_phy_lp_bbinit(struct bwn_mac *); 470 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 471 static void bwn_phy_lp_calib(struct bwn_mac *); 472 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 473 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 474 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 475 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 476 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 477 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 478 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 479 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 480 static void bwn_phy_lp_bugfix(struct bwn_mac *); 481 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 482 static void bwn_phy_lp_tblinit(struct bwn_mac *); 483 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 484 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 485 static void bwn_phy_lp_b2062_init(struct bwn_mac *); 486 static void bwn_phy_lp_b2063_init(struct bwn_mac *); 487 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 488 static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 489 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 490 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 491 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 492 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 493 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 494 const void *); 495 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 496 static struct bwn_txgain 497 bwn_phy_lp_get_txgain(struct bwn_mac *); 498 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 499 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 500 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 501 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 502 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 503 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 504 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 505 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 506 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 507 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 508 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 509 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 510 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 511 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 512 static int bwn_phy_lp_loopback(struct bwn_mac *); 513 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 514 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 515 int); 516 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 517 struct bwn_phy_lp_iq_est *); 518 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 519 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 520 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 521 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 522 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 523 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 524 static uint8_t bwn_nbits(int32_t); 525 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 526 struct bwn_txgain_entry *); 527 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 528 struct bwn_txgain_entry); 529 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 530 struct bwn_txgain_entry); 531 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 532 struct bwn_txgain_entry); 533 static void bwn_sysctl_node(struct bwn_softc *); 534 535 static struct resource_spec bwn_res_spec_legacy[] = { 536 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 537 { -1, 0, 0 } 538 }; 539 540 static struct resource_spec bwn_res_spec_msi[] = { 541 { SYS_RES_IRQ, 1, RF_ACTIVE }, 542 { -1, 0, 0 } 543 }; 544 545 static const struct bwn_channelinfo bwn_chantable_bg = { 546 .channels = { 547 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 548 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 549 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 550 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 551 { 2472, 13, 30 }, { 2484, 14, 30 } }, 552 .nchannels = 14 553 }; 554 555 static const struct bwn_channelinfo bwn_chantable_a = { 556 .channels = { 557 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 558 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 559 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 560 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 561 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 562 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 563 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 564 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 565 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 566 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 567 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 568 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 569 { 6080, 216, 30 } }, 570 .nchannels = 37 571 }; 572 573 static const struct bwn_channelinfo bwn_chantable_n = { 574 .channels = { 575 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 576 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 577 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 578 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 579 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 580 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 581 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 582 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 583 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 584 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 585 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 586 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 587 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 588 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 589 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 590 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 591 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 592 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 593 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 594 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 595 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 596 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 597 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 598 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 599 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 600 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 601 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 602 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 603 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 604 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 605 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 606 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 607 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 608 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 609 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 610 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 611 { 6130, 226, 30 }, { 6140, 228, 30 } }, 612 .nchannels = 110 613 }; 614 615 static const uint8_t bwn_b2063_chantable_data[33][12] = { 616 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 617 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 618 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 619 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 620 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 621 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 622 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 623 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 624 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 625 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 626 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 627 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 628 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 629 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 630 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 631 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 632 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 633 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 634 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 635 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 636 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 637 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 638 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 639 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 640 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 641 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 642 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 643 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 646 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 647 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 648 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 649 }; 650 651 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 652 { 1, 2412, bwn_b2063_chantable_data[0] }, 653 { 2, 2417, bwn_b2063_chantable_data[0] }, 654 { 3, 2422, bwn_b2063_chantable_data[0] }, 655 { 4, 2427, bwn_b2063_chantable_data[1] }, 656 { 5, 2432, bwn_b2063_chantable_data[1] }, 657 { 6, 2437, bwn_b2063_chantable_data[1] }, 658 { 7, 2442, bwn_b2063_chantable_data[1] }, 659 { 8, 2447, bwn_b2063_chantable_data[1] }, 660 { 9, 2452, bwn_b2063_chantable_data[2] }, 661 { 10, 2457, bwn_b2063_chantable_data[2] }, 662 { 11, 2462, bwn_b2063_chantable_data[3] }, 663 { 12, 2467, bwn_b2063_chantable_data[3] }, 664 { 13, 2472, bwn_b2063_chantable_data[3] }, 665 { 14, 2484, bwn_b2063_chantable_data[4] }, 666 { 34, 5170, bwn_b2063_chantable_data[5] }, 667 { 36, 5180, bwn_b2063_chantable_data[6] }, 668 { 38, 5190, bwn_b2063_chantable_data[7] }, 669 { 40, 5200, bwn_b2063_chantable_data[8] }, 670 { 42, 5210, bwn_b2063_chantable_data[9] }, 671 { 44, 5220, bwn_b2063_chantable_data[10] }, 672 { 46, 5230, bwn_b2063_chantable_data[11] }, 673 { 48, 5240, bwn_b2063_chantable_data[12] }, 674 { 52, 5260, bwn_b2063_chantable_data[13] }, 675 { 56, 5280, bwn_b2063_chantable_data[14] }, 676 { 60, 5300, bwn_b2063_chantable_data[14] }, 677 { 64, 5320, bwn_b2063_chantable_data[15] }, 678 { 100, 5500, bwn_b2063_chantable_data[16] }, 679 { 104, 5520, bwn_b2063_chantable_data[17] }, 680 { 108, 5540, bwn_b2063_chantable_data[18] }, 681 { 112, 5560, bwn_b2063_chantable_data[19] }, 682 { 116, 5580, bwn_b2063_chantable_data[20] }, 683 { 120, 5600, bwn_b2063_chantable_data[21] }, 684 { 124, 5620, bwn_b2063_chantable_data[21] }, 685 { 128, 5640, bwn_b2063_chantable_data[22] }, 686 { 132, 5660, bwn_b2063_chantable_data[22] }, 687 { 136, 5680, bwn_b2063_chantable_data[22] }, 688 { 140, 5700, bwn_b2063_chantable_data[23] }, 689 { 149, 5745, bwn_b2063_chantable_data[23] }, 690 { 153, 5765, bwn_b2063_chantable_data[23] }, 691 { 157, 5785, bwn_b2063_chantable_data[23] }, 692 { 161, 5805, bwn_b2063_chantable_data[23] }, 693 { 165, 5825, bwn_b2063_chantable_data[23] }, 694 { 184, 4920, bwn_b2063_chantable_data[24] }, 695 { 188, 4940, bwn_b2063_chantable_data[25] }, 696 { 192, 4960, bwn_b2063_chantable_data[26] }, 697 { 196, 4980, bwn_b2063_chantable_data[27] }, 698 { 200, 5000, bwn_b2063_chantable_data[28] }, 699 { 204, 5020, bwn_b2063_chantable_data[29] }, 700 { 208, 5040, bwn_b2063_chantable_data[30] }, 701 { 212, 5060, bwn_b2063_chantable_data[31] }, 702 { 216, 5080, bwn_b2063_chantable_data[32] } 703 }; 704 705 static const uint8_t bwn_b2062_chantable_data[22][12] = { 706 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 707 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 708 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 719 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 720 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 721 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 722 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 723 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 724 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 727 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 728 }; 729 730 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 731 { 1, 2412, bwn_b2062_chantable_data[0] }, 732 { 2, 2417, bwn_b2062_chantable_data[0] }, 733 { 3, 2422, bwn_b2062_chantable_data[0] }, 734 { 4, 2427, bwn_b2062_chantable_data[0] }, 735 { 5, 2432, bwn_b2062_chantable_data[0] }, 736 { 6, 2437, bwn_b2062_chantable_data[0] }, 737 { 7, 2442, bwn_b2062_chantable_data[0] }, 738 { 8, 2447, bwn_b2062_chantable_data[0] }, 739 { 9, 2452, bwn_b2062_chantable_data[0] }, 740 { 10, 2457, bwn_b2062_chantable_data[0] }, 741 { 11, 2462, bwn_b2062_chantable_data[0] }, 742 { 12, 2467, bwn_b2062_chantable_data[0] }, 743 { 13, 2472, bwn_b2062_chantable_data[0] }, 744 { 14, 2484, bwn_b2062_chantable_data[0] }, 745 { 34, 5170, bwn_b2062_chantable_data[1] }, 746 { 38, 5190, bwn_b2062_chantable_data[2] }, 747 { 42, 5210, bwn_b2062_chantable_data[2] }, 748 { 46, 5230, bwn_b2062_chantable_data[3] }, 749 { 36, 5180, bwn_b2062_chantable_data[4] }, 750 { 40, 5200, bwn_b2062_chantable_data[5] }, 751 { 44, 5220, bwn_b2062_chantable_data[6] }, 752 { 48, 5240, bwn_b2062_chantable_data[3] }, 753 { 52, 5260, bwn_b2062_chantable_data[3] }, 754 { 56, 5280, bwn_b2062_chantable_data[3] }, 755 { 60, 5300, bwn_b2062_chantable_data[7] }, 756 { 64, 5320, bwn_b2062_chantable_data[8] }, 757 { 100, 5500, bwn_b2062_chantable_data[9] }, 758 { 104, 5520, bwn_b2062_chantable_data[10] }, 759 { 108, 5540, bwn_b2062_chantable_data[10] }, 760 { 112, 5560, bwn_b2062_chantable_data[10] }, 761 { 116, 5580, bwn_b2062_chantable_data[11] }, 762 { 120, 5600, bwn_b2062_chantable_data[12] }, 763 { 124, 5620, bwn_b2062_chantable_data[12] }, 764 { 128, 5640, bwn_b2062_chantable_data[12] }, 765 { 132, 5660, bwn_b2062_chantable_data[12] }, 766 { 136, 5680, bwn_b2062_chantable_data[12] }, 767 { 140, 5700, bwn_b2062_chantable_data[12] }, 768 { 149, 5745, bwn_b2062_chantable_data[12] }, 769 { 153, 5765, bwn_b2062_chantable_data[12] }, 770 { 157, 5785, bwn_b2062_chantable_data[12] }, 771 { 161, 5805, bwn_b2062_chantable_data[12] }, 772 { 165, 5825, bwn_b2062_chantable_data[12] }, 773 { 184, 4920, bwn_b2062_chantable_data[13] }, 774 { 188, 4940, bwn_b2062_chantable_data[14] }, 775 { 192, 4960, bwn_b2062_chantable_data[15] }, 776 { 196, 4980, bwn_b2062_chantable_data[16] }, 777 { 200, 5000, bwn_b2062_chantable_data[17] }, 778 { 204, 5020, bwn_b2062_chantable_data[18] }, 779 { 208, 5040, bwn_b2062_chantable_data[19] }, 780 { 212, 5060, bwn_b2062_chantable_data[20] }, 781 { 216, 5080, bwn_b2062_chantable_data[21] } 782 }; 783 784 /* for LP PHY */ 785 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 786 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 787 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 788 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 789 { 13, -66, 13 }, { 14, -66, 13 }, 790 }; 791 792 /* for LP PHY */ 793 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 794 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 795 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 796 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 797 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 798 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 799 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 800 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 801 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 802 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 803 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 804 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 805 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 806 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 807 }; 808 809 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 810 811 static const uint8_t bwn_tab_sigsq_tbl[] = { 812 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 813 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 814 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 815 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 816 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 817 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 818 }; 819 820 static const uint8_t bwn_tab_pllfrac_tbl[] = { 821 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 822 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 823 }; 824 825 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 826 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 827 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 830 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 831 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 832 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 838 }; 839 840 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 841 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 842 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 843 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 844 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 845 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 846 847 #define VENDOR_LED_ACT(vendor) \ 848 { \ 849 .vid = PCI_VENDOR_##vendor, \ 850 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 851 } 852 853 static const struct { 854 uint16_t vid; 855 uint8_t led_act[BWN_LED_MAX]; 856 } bwn_vendor_led_act[] = { 857 VENDOR_LED_ACT(COMPAQ), 858 VENDOR_LED_ACT(ASUSTEK) 859 }; 860 861 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 862 { BWN_VENDOR_LED_ACT_DEFAULT }; 863 864 #undef VENDOR_LED_ACT 865 866 static const struct { 867 int on_dur; 868 int off_dur; 869 } bwn_led_duration[109] = { 870 [0] = { 400, 100 }, 871 [2] = { 150, 75 }, 872 [4] = { 90, 45 }, 873 [11] = { 66, 34 }, 874 [12] = { 53, 26 }, 875 [18] = { 42, 21 }, 876 [22] = { 35, 17 }, 877 [24] = { 32, 16 }, 878 [36] = { 21, 10 }, 879 [48] = { 16, 8 }, 880 [72] = { 11, 5 }, 881 [96] = { 9, 4 }, 882 [108] = { 7, 3 } 883 }; 884 885 static const uint16_t bwn_wme_shm_offsets[] = { 886 [0] = BWN_WME_BESTEFFORT, 887 [1] = BWN_WME_BACKGROUND, 888 [2] = BWN_WME_VOICE, 889 [3] = BWN_WME_VIDEO, 890 }; 891 892 static const struct siba_devid bwn_devs[] = { 893 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 894 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 895 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 896 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 897 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 898 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 899 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 900 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 901 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 902 }; 903 904 static int 905 bwn_probe(device_t dev) 906 { 907 int i; 908 909 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 910 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 911 siba_get_device(dev) == bwn_devs[i].sd_device && 912 siba_get_revid(dev) == bwn_devs[i].sd_rev) 913 return (BUS_PROBE_DEFAULT); 914 } 915 916 return (ENXIO); 917 } 918 919 static int 920 bwn_attach(device_t dev) 921 { 922 struct bwn_mac *mac; 923 struct bwn_softc *sc = device_get_softc(dev); 924 int error, i, msic, reg; 925 926 sc->sc_dev = dev; 927 #ifdef BWN_DEBUG 928 sc->sc_debug = bwn_debug; 929 #endif 930 931 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 932 error = bwn_attach_pre(sc); 933 if (error != 0) 934 return (error); 935 bwn_sprom_bugfixes(dev); 936 sc->sc_flags |= BWN_FLAG_ATTACHED; 937 } 938 939 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 940 if (siba_get_pci_device(dev) != 0x4313 && 941 siba_get_pci_device(dev) != 0x431a && 942 siba_get_pci_device(dev) != 0x4321) { 943 device_printf(sc->sc_dev, 944 "skip 802.11 cores\n"); 945 return (ENODEV); 946 } 947 } 948 949 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, 950 M_NOWAIT | M_ZERO); 951 if (mac == NULL) 952 return (ENOMEM); 953 mac->mac_sc = sc; 954 mac->mac_status = BWN_MAC_STATUS_UNINIT; 955 if (bwn_bfp != 0) 956 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 957 958 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 959 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 960 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 961 962 error = bwn_attach_core(mac); 963 if (error) 964 goto fail0; 965 bwn_led_attach(mac); 966 967 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 968 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 969 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 970 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 971 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 972 mac->mac_phy.rf_rev); 973 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 974 device_printf(sc->sc_dev, "DMA (%d bits)\n", 975 mac->mac_method.dma.dmatype); 976 else 977 device_printf(sc->sc_dev, "PIO\n"); 978 979 /* 980 * setup PCI resources and interrupt. 981 */ 982 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { 983 msic = pci_msi_count(dev); 984 if (bootverbose) 985 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 986 } else 987 msic = 0; 988 989 mac->mac_intr_spec = bwn_res_spec_legacy; 990 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 991 if (pci_alloc_msi(dev, &msic) == 0) { 992 device_printf(sc->sc_dev, 993 "Using %d MSI messages\n", msic); 994 mac->mac_intr_spec = bwn_res_spec_msi; 995 mac->mac_msi = 1; 996 } 997 } 998 999 error = bus_alloc_resources(dev, mac->mac_intr_spec, 1000 mac->mac_res_irq); 1001 if (error) { 1002 device_printf(sc->sc_dev, 1003 "couldn't allocate IRQ resources (%d)\n", error); 1004 goto fail1; 1005 } 1006 1007 if (mac->mac_msi == 0) 1008 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1009 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1010 &mac->mac_intrhand[0]); 1011 else { 1012 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1013 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1014 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1015 &mac->mac_intrhand[i]); 1016 if (error != 0) { 1017 device_printf(sc->sc_dev, 1018 "couldn't setup interrupt (%d)\n", error); 1019 break; 1020 } 1021 } 1022 } 1023 1024 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1025 1026 /* 1027 * calls attach-post routine 1028 */ 1029 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1030 bwn_attach_post(sc); 1031 1032 return (0); 1033 fail1: 1034 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1035 pci_release_msi(dev); 1036 fail0: 1037 free(mac, M_DEVBUF); 1038 return (error); 1039 } 1040 1041 static int 1042 bwn_is_valid_ether_addr(uint8_t *addr) 1043 { 1044 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1045 1046 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1047 return (FALSE); 1048 1049 return (TRUE); 1050 } 1051 1052 static int 1053 bwn_attach_post(struct bwn_softc *sc) 1054 { 1055 struct ieee80211com *ic; 1056 struct ifnet *ifp = sc->sc_ifp; 1057 1058 ic = ifp->if_l2com; 1059 ic->ic_ifp = ifp; 1060 /* XXX not right but it's not used anywhere important */ 1061 ic->ic_phytype = IEEE80211_T_OFDM; 1062 ic->ic_opmode = IEEE80211_M_STA; 1063 ic->ic_caps = 1064 IEEE80211_C_STA /* station mode supported */ 1065 | IEEE80211_C_MONITOR /* monitor mode */ 1066 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1067 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1068 | IEEE80211_C_SHSLOT /* short slot time supported */ 1069 | IEEE80211_C_WME /* WME/WMM supported */ 1070 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1071 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1072 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1073 ; 1074 1075 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1076 1077 /* call MI attach routine. */ 1078 ieee80211_ifattach(ic, 1079 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1080 siba_sprom_get_mac_80211a(sc->sc_dev) : 1081 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1082 1083 ic->ic_headroom = sizeof(struct bwn_txhdr); 1084 1085 /* override default methods */ 1086 ic->ic_raw_xmit = bwn_raw_xmit; 1087 ic->ic_updateslot = bwn_updateslot; 1088 ic->ic_update_promisc = bwn_update_promisc; 1089 ic->ic_wme.wme_update = bwn_wme_update; 1090 1091 ic->ic_scan_start = bwn_scan_start; 1092 ic->ic_scan_end = bwn_scan_end; 1093 ic->ic_set_channel = bwn_set_channel; 1094 1095 ic->ic_vap_create = bwn_vap_create; 1096 ic->ic_vap_delete = bwn_vap_delete; 1097 1098 ieee80211_radiotap_attach(ic, 1099 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1100 BWN_TX_RADIOTAP_PRESENT, 1101 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1102 BWN_RX_RADIOTAP_PRESENT); 1103 1104 bwn_sysctl_node(sc); 1105 1106 if (bootverbose) 1107 ieee80211_announce(ic); 1108 return (0); 1109 } 1110 1111 static void 1112 bwn_phy_detach(struct bwn_mac *mac) 1113 { 1114 1115 if (mac->mac_phy.detach != NULL) 1116 mac->mac_phy.detach(mac); 1117 } 1118 1119 static int 1120 bwn_detach(device_t dev) 1121 { 1122 struct bwn_softc *sc = device_get_softc(dev); 1123 struct bwn_mac *mac = sc->sc_curmac; 1124 struct ifnet *ifp = sc->sc_ifp; 1125 struct ieee80211com *ic = ifp->if_l2com; 1126 int i; 1127 1128 sc->sc_flags |= BWN_FLAG_INVALID; 1129 1130 if (device_is_attached(sc->sc_dev)) { 1131 bwn_stop(sc, 1); 1132 bwn_dma_free(mac); 1133 callout_drain(&sc->sc_led_blink_ch); 1134 callout_drain(&sc->sc_rfswitch_ch); 1135 callout_drain(&sc->sc_task_ch); 1136 callout_drain(&sc->sc_watchdog_ch); 1137 bwn_phy_detach(mac); 1138 if (ifp != NULL) { 1139 ieee80211_draintask(ic, &mac->mac_hwreset); 1140 ieee80211_draintask(ic, &mac->mac_txpower); 1141 ieee80211_ifdetach(ic); 1142 if_free(ifp); 1143 } 1144 } 1145 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1146 taskqueue_free(sc->sc_tq); 1147 1148 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1149 if (mac->mac_intrhand[i] != NULL) { 1150 bus_teardown_intr(dev, mac->mac_res_irq[i], 1151 mac->mac_intrhand[i]); 1152 mac->mac_intrhand[i] = NULL; 1153 } 1154 } 1155 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1156 if (mac->mac_msi != 0) 1157 pci_release_msi(dev); 1158 1159 BWN_LOCK_DESTROY(sc); 1160 return (0); 1161 } 1162 1163 static int 1164 bwn_attach_pre(struct bwn_softc *sc) 1165 { 1166 struct ifnet *ifp; 1167 int error = 0; 1168 1169 BWN_LOCK_INIT(sc); 1170 TAILQ_INIT(&sc->sc_maclist); 1171 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1172 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1173 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1174 1175 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1176 taskqueue_thread_enqueue, &sc->sc_tq); 1177 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1178 "%s taskq", device_get_nameunit(sc->sc_dev)); 1179 1180 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1181 if (ifp == NULL) { 1182 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1183 error = ENOSPC; 1184 goto fail; 1185 } 1186 1187 /* set these up early for if_printf use */ 1188 if_initname(ifp, device_get_name(sc->sc_dev), 1189 device_get_unit(sc->sc_dev)); 1190 1191 ifp->if_softc = sc; 1192 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1193 ifp->if_init = bwn_init; 1194 ifp->if_ioctl = bwn_ioctl; 1195 ifp->if_start = bwn_start; 1196 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 1197 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 1198 IFQ_SET_READY(&ifp->if_snd); 1199 1200 return (0); 1201 1202 fail: BWN_LOCK_DESTROY(sc); 1203 return (error); 1204 } 1205 1206 static void 1207 bwn_sprom_bugfixes(device_t dev) 1208 { 1209 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1210 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1211 (siba_get_pci_device(dev) == _device) && \ 1212 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1213 (siba_get_pci_subdevice(dev) == _subdevice)) 1214 1215 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1216 siba_get_pci_subdevice(dev) == 0x4e && 1217 siba_get_pci_revid(dev) > 0x40) 1218 siba_sprom_set_bf_lo(dev, 1219 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1220 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1221 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1222 siba_sprom_set_bf_lo(dev, 1223 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1224 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1225 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1226 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1227 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1228 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1229 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1230 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1231 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1232 siba_sprom_set_bf_lo(dev, 1233 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1234 } 1235 #undef BWN_ISDEV 1236 } 1237 1238 static int 1239 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1240 { 1241 #define IS_RUNNING(ifp) \ 1242 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1243 struct bwn_softc *sc = ifp->if_softc; 1244 struct ieee80211com *ic = ifp->if_l2com; 1245 struct ifreq *ifr = (struct ifreq *)data; 1246 int error = 0, startall; 1247 1248 switch (cmd) { 1249 case SIOCSIFFLAGS: 1250 startall = 0; 1251 if (IS_RUNNING(ifp)) { 1252 bwn_update_promisc(ifp); 1253 } else if (ifp->if_flags & IFF_UP) { 1254 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1255 bwn_init(sc); 1256 startall = 1; 1257 } 1258 } else 1259 bwn_stop(sc, 1); 1260 if (startall) 1261 ieee80211_start_all(ic); 1262 break; 1263 case SIOCGIFMEDIA: 1264 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1265 break; 1266 case SIOCGIFADDR: 1267 error = ether_ioctl(ifp, cmd, data); 1268 break; 1269 default: 1270 error = EINVAL; 1271 break; 1272 } 1273 return (error); 1274 } 1275 1276 static void 1277 bwn_start(struct ifnet *ifp) 1278 { 1279 struct bwn_softc *sc = ifp->if_softc; 1280 1281 BWN_LOCK(sc); 1282 bwn_start_locked(ifp); 1283 BWN_UNLOCK(sc); 1284 } 1285 1286 static void 1287 bwn_start_locked(struct ifnet *ifp) 1288 { 1289 struct bwn_softc *sc = ifp->if_softc; 1290 struct bwn_mac *mac = sc->sc_curmac; 1291 struct ieee80211_frame *wh; 1292 struct ieee80211_node *ni; 1293 struct ieee80211_key *k; 1294 struct mbuf *m; 1295 1296 BWN_ASSERT_LOCKED(sc); 1297 1298 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1299 mac->mac_status < BWN_MAC_STATUS_STARTED) 1300 return; 1301 1302 for (;;) { 1303 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1304 if (m == NULL) 1305 break; 1306 1307 if (bwn_tx_isfull(sc, m)) 1308 break; 1309 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1310 if (ni == NULL) { 1311 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1312 m_freem(m); 1313 ifp->if_oerrors++; 1314 continue; 1315 } 1316 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1317 wh = mtod(m, struct ieee80211_frame *); 1318 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1319 k = ieee80211_crypto_encap(ni, m); 1320 if (k == NULL) { 1321 ieee80211_free_node(ni); 1322 m_freem(m); 1323 ifp->if_oerrors++; 1324 continue; 1325 } 1326 } 1327 wh = NULL; /* Catch any invalid use */ 1328 1329 if (bwn_tx_start(sc, ni, m) != 0) { 1330 if (ni != NULL) 1331 ieee80211_free_node(ni); 1332 ifp->if_oerrors++; 1333 continue; 1334 } 1335 1336 sc->sc_watchdog_timer = 5; 1337 } 1338 } 1339 1340 static int 1341 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1342 { 1343 struct bwn_dma_ring *dr; 1344 struct bwn_mac *mac = sc->sc_curmac; 1345 struct bwn_pio_txqueue *tq; 1346 struct ifnet *ifp = sc->sc_ifp; 1347 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1348 1349 BWN_ASSERT_LOCKED(sc); 1350 1351 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1352 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1353 if (dr->dr_stop == 1 || 1354 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1355 dr->dr_stop = 1; 1356 goto full; 1357 } 1358 } else { 1359 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1360 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1361 pktlen > (tq->tq_size - tq->tq_used)) { 1362 tq->tq_stop = 1; 1363 goto full; 1364 } 1365 } 1366 return (0); 1367 full: 1368 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1369 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1370 return (1); 1371 } 1372 1373 static int 1374 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1375 { 1376 struct bwn_mac *mac = sc->sc_curmac; 1377 int error; 1378 1379 BWN_ASSERT_LOCKED(sc); 1380 1381 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1382 m_freem(m); 1383 return (ENXIO); 1384 } 1385 1386 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1387 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1388 if (error) { 1389 m_freem(m); 1390 return (error); 1391 } 1392 return (0); 1393 } 1394 1395 static int 1396 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1397 { 1398 struct bwn_pio_txpkt *tp; 1399 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1400 struct bwn_softc *sc = mac->mac_sc; 1401 struct bwn_txhdr txhdr; 1402 struct mbuf *m_new; 1403 uint32_t ctl32; 1404 int error; 1405 uint16_t ctl16; 1406 1407 BWN_ASSERT_LOCKED(sc); 1408 1409 /* XXX TODO send packets after DTIM */ 1410 1411 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1412 tp = TAILQ_FIRST(&tq->tq_pktlist); 1413 tp->tp_ni = ni; 1414 tp->tp_m = m; 1415 1416 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1417 if (error) { 1418 device_printf(sc->sc_dev, "tx fail\n"); 1419 return (error); 1420 } 1421 1422 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1423 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1424 tq->tq_free--; 1425 1426 if (siba_get_revid(sc->sc_dev) >= 8) { 1427 /* 1428 * XXX please removes m_defrag(9) 1429 */ 1430 m_new = m_defrag(m, M_DONTWAIT); 1431 if (m_new == NULL) { 1432 device_printf(sc->sc_dev, 1433 "%s: can't defrag TX buffer\n", 1434 __func__); 1435 return (ENOBUFS); 1436 } 1437 if (m_new->m_next != NULL) 1438 device_printf(sc->sc_dev, 1439 "TODO: fragmented packets for PIO\n"); 1440 tp->tp_m = m_new; 1441 1442 /* send HEADER */ 1443 ctl32 = bwn_pio_write_multi_4(mac, tq, 1444 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1445 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1446 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1447 /* send BODY */ 1448 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1449 mtod(m_new, const void *), m_new->m_pkthdr.len); 1450 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1451 ctl32 | BWN_PIO8_TXCTL_EOF); 1452 } else { 1453 ctl16 = bwn_pio_write_multi_2(mac, tq, 1454 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1455 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1456 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1457 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1458 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1459 ctl16 | BWN_PIO_TXCTL_EOF); 1460 } 1461 1462 return (0); 1463 } 1464 1465 static struct bwn_pio_txqueue * 1466 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1467 { 1468 1469 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1470 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1471 1472 switch (prio) { 1473 case 0: 1474 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1475 case 1: 1476 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1477 case 2: 1478 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1479 case 3: 1480 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1481 } 1482 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1483 return (NULL); 1484 } 1485 1486 static int 1487 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1488 { 1489 #define BWN_GET_TXHDRCACHE(slot) \ 1490 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1491 struct bwn_dma *dma = &mac->mac_method.dma; 1492 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1493 struct bwn_dmadesc_generic *desc; 1494 struct bwn_dmadesc_meta *mt; 1495 struct bwn_softc *sc = mac->mac_sc; 1496 struct ifnet *ifp = sc->sc_ifp; 1497 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1498 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1499 1500 BWN_ASSERT_LOCKED(sc); 1501 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1502 1503 /* XXX send after DTIM */ 1504 1505 slot = bwn_dma_getslot(dr); 1506 dr->getdesc(dr, slot, &desc, &mt); 1507 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1508 ("%s:%d: fail", __func__, __LINE__)); 1509 1510 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1511 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1512 BWN_DMA_COOKIE(dr, slot)); 1513 if (error) 1514 goto fail; 1515 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1516 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1517 &mt->mt_paddr, BUS_DMA_NOWAIT); 1518 if (error) { 1519 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1520 __func__, error); 1521 goto fail; 1522 } 1523 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1524 BUS_DMASYNC_PREWRITE); 1525 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1526 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1527 BUS_DMASYNC_PREWRITE); 1528 1529 slot = bwn_dma_getslot(dr); 1530 dr->getdesc(dr, slot, &desc, &mt); 1531 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1532 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1533 mt->mt_m = m; 1534 mt->mt_ni = ni; 1535 1536 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1537 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1538 if (error && error != EFBIG) { 1539 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1540 __func__, error); 1541 goto fail; 1542 } 1543 if (error) { /* error == EFBIG */ 1544 struct mbuf *m_new; 1545 1546 m_new = m_defrag(m, M_DONTWAIT); 1547 if (m_new == NULL) { 1548 if_printf(ifp, "%s: can't defrag TX buffer\n", 1549 __func__); 1550 error = ENOBUFS; 1551 goto fail; 1552 } else { 1553 m = m_new; 1554 } 1555 1556 mt->mt_m = m; 1557 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1558 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1559 if (error) { 1560 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1561 __func__, error); 1562 goto fail; 1563 } 1564 } 1565 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1566 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1567 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1568 BUS_DMASYNC_PREWRITE); 1569 1570 /* XXX send after DTIM */ 1571 1572 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1573 return (0); 1574 fail: 1575 dr->dr_curslot = backup[0]; 1576 dr->dr_usedslot = backup[1]; 1577 return (error); 1578 #undef BWN_GET_TXHDRCACHE 1579 } 1580 1581 static void 1582 bwn_watchdog(void *arg) 1583 { 1584 struct bwn_softc *sc = arg; 1585 struct ifnet *ifp = sc->sc_ifp; 1586 1587 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1588 if_printf(ifp, "device timeout\n"); 1589 ifp->if_oerrors++; 1590 } 1591 callout_schedule(&sc->sc_watchdog_ch, hz); 1592 } 1593 1594 static int 1595 bwn_attach_core(struct bwn_mac *mac) 1596 { 1597 struct bwn_softc *sc = mac->mac_sc; 1598 int error, have_bg = 0, have_a = 0; 1599 uint32_t high; 1600 1601 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1602 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1603 1604 siba_powerup(sc->sc_dev, 0); 1605 1606 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1607 bwn_reset_core(mac, 1608 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1609 error = bwn_phy_getinfo(mac, high); 1610 if (error) 1611 goto fail; 1612 1613 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1614 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1615 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1616 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1617 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1618 have_a = have_bg = 0; 1619 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1620 have_a = 1; 1621 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1622 mac->mac_phy.type == BWN_PHYTYPE_N || 1623 mac->mac_phy.type == BWN_PHYTYPE_LP) 1624 have_bg = 1; 1625 else 1626 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1627 mac->mac_phy.type)); 1628 } 1629 /* XXX turns off PHY A because it's not supported */ 1630 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1631 mac->mac_phy.type != BWN_PHYTYPE_N) { 1632 have_a = 0; 1633 have_bg = 1; 1634 } 1635 1636 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1637 mac->mac_phy.attach = bwn_phy_g_attach; 1638 mac->mac_phy.detach = bwn_phy_g_detach; 1639 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1640 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1641 mac->mac_phy.init = bwn_phy_g_init; 1642 mac->mac_phy.exit = bwn_phy_g_exit; 1643 mac->mac_phy.phy_read = bwn_phy_g_read; 1644 mac->mac_phy.phy_write = bwn_phy_g_write; 1645 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1646 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1647 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1648 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1649 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1650 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1651 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1652 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1653 mac->mac_phy.set_im = bwn_phy_g_im; 1654 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1655 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1656 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1657 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1658 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1659 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1660 mac->mac_phy.init = bwn_phy_lp_init; 1661 mac->mac_phy.phy_read = bwn_phy_lp_read; 1662 mac->mac_phy.phy_write = bwn_phy_lp_write; 1663 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1664 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1665 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1666 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1667 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1668 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1669 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1670 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1671 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1672 } else { 1673 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1674 mac->mac_phy.type); 1675 error = ENXIO; 1676 goto fail; 1677 } 1678 1679 mac->mac_phy.gmode = have_bg; 1680 if (mac->mac_phy.attach != NULL) { 1681 error = mac->mac_phy.attach(mac); 1682 if (error) { 1683 device_printf(sc->sc_dev, "failed\n"); 1684 goto fail; 1685 } 1686 } 1687 1688 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1689 1690 error = bwn_chiptest(mac); 1691 if (error) 1692 goto fail; 1693 error = bwn_setup_channels(mac, have_bg, have_a); 1694 if (error) { 1695 device_printf(sc->sc_dev, "failed to setup channels\n"); 1696 goto fail; 1697 } 1698 1699 if (sc->sc_curmac == NULL) 1700 sc->sc_curmac = mac; 1701 1702 error = bwn_dma_attach(mac); 1703 if (error != 0) { 1704 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1705 goto fail; 1706 } 1707 1708 mac->mac_phy.switch_analog(mac, 0); 1709 1710 siba_dev_down(sc->sc_dev, 0); 1711 fail: 1712 siba_powerdown(sc->sc_dev); 1713 return (error); 1714 } 1715 1716 static void 1717 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1718 { 1719 struct bwn_softc *sc = mac->mac_sc; 1720 uint32_t low, ctl; 1721 1722 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1723 1724 siba_dev_up(sc->sc_dev, flags); 1725 DELAY(2000); 1726 1727 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1728 ~BWN_TGSLOW_PHYRESET; 1729 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1730 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1731 DELAY(1000); 1732 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1733 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1734 DELAY(1000); 1735 1736 if (mac->mac_phy.switch_analog != NULL) 1737 mac->mac_phy.switch_analog(mac, 1); 1738 1739 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1740 if (flags & BWN_TGSLOW_SUPPORT_G) 1741 ctl |= BWN_MACCTL_GMODE; 1742 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1743 } 1744 1745 static int 1746 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1747 { 1748 struct bwn_phy *phy = &mac->mac_phy; 1749 struct bwn_softc *sc = mac->mac_sc; 1750 uint32_t tmp; 1751 1752 /* PHY */ 1753 tmp = BWN_READ_2(mac, BWN_PHYVER); 1754 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1755 phy->rf_on = 1; 1756 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1757 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1758 phy->rev = (tmp & BWN_PHYVER_VERSION); 1759 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1760 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1761 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1762 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1763 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1764 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1765 goto unsupphy; 1766 1767 /* RADIO */ 1768 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1769 if (siba_get_chiprev(sc->sc_dev) == 0) 1770 tmp = 0x3205017f; 1771 else if (siba_get_chiprev(sc->sc_dev) == 1) 1772 tmp = 0x4205017f; 1773 else 1774 tmp = 0x5205017f; 1775 } else { 1776 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1777 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1778 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1779 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1780 } 1781 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1782 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1783 phy->rf_manuf = (tmp & 0x00000fff); 1784 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1785 goto unsupradio; 1786 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1787 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1788 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1789 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1790 (phy->type == BWN_PHYTYPE_N && 1791 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1792 (phy->type == BWN_PHYTYPE_LP && 1793 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1794 goto unsupradio; 1795 1796 return (0); 1797 unsupphy: 1798 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1799 "analog %#x)\n", 1800 phy->type, phy->rev, phy->analog); 1801 return (ENXIO); 1802 unsupradio: 1803 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1804 "rev %#x)\n", 1805 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1806 return (ENXIO); 1807 } 1808 1809 static int 1810 bwn_chiptest(struct bwn_mac *mac) 1811 { 1812 #define TESTVAL0 0x55aaaa55 1813 #define TESTVAL1 0xaa5555aa 1814 struct bwn_softc *sc = mac->mac_sc; 1815 uint32_t v, backup; 1816 1817 BWN_LOCK(sc); 1818 1819 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1820 1821 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1822 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1823 goto error; 1824 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1825 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1826 goto error; 1827 1828 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1829 1830 if ((siba_get_revid(sc->sc_dev) >= 3) && 1831 (siba_get_revid(sc->sc_dev) <= 10)) { 1832 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1833 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1834 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1835 goto error; 1836 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1837 goto error; 1838 } 1839 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1840 1841 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1842 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1843 goto error; 1844 1845 BWN_UNLOCK(sc); 1846 return (0); 1847 error: 1848 BWN_UNLOCK(sc); 1849 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1850 return (ENODEV); 1851 } 1852 1853 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1854 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1855 1856 static int 1857 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1858 { 1859 struct bwn_softc *sc = mac->mac_sc; 1860 struct ifnet *ifp = sc->sc_ifp; 1861 struct ieee80211com *ic = ifp->if_l2com; 1862 1863 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1864 ic->ic_nchans = 0; 1865 1866 if (have_bg) 1867 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1868 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1869 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1870 if (have_a) 1871 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1872 &ic->ic_nchans, &bwn_chantable_n, 1873 IEEE80211_CHAN_HTA); 1874 } else { 1875 if (have_a) 1876 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1877 &ic->ic_nchans, &bwn_chantable_a, 1878 IEEE80211_CHAN_A); 1879 } 1880 1881 mac->mac_phy.supports_2ghz = have_bg; 1882 mac->mac_phy.supports_5ghz = have_a; 1883 1884 return (ic->ic_nchans == 0 ? ENXIO : 0); 1885 } 1886 1887 static uint32_t 1888 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1889 { 1890 uint32_t ret; 1891 1892 BWN_ASSERT_LOCKED(mac->mac_sc); 1893 1894 if (way == BWN_SHARED) { 1895 KASSERT((offset & 0x0001) == 0, 1896 ("%s:%d warn", __func__, __LINE__)); 1897 if (offset & 0x0003) { 1898 bwn_shm_ctlword(mac, way, offset >> 2); 1899 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1900 ret <<= 16; 1901 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1902 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1903 goto out; 1904 } 1905 offset >>= 2; 1906 } 1907 bwn_shm_ctlword(mac, way, offset); 1908 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1909 out: 1910 return (ret); 1911 } 1912 1913 static uint16_t 1914 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1915 { 1916 uint16_t ret; 1917 1918 BWN_ASSERT_LOCKED(mac->mac_sc); 1919 1920 if (way == BWN_SHARED) { 1921 KASSERT((offset & 0x0001) == 0, 1922 ("%s:%d warn", __func__, __LINE__)); 1923 if (offset & 0x0003) { 1924 bwn_shm_ctlword(mac, way, offset >> 2); 1925 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1926 goto out; 1927 } 1928 offset >>= 2; 1929 } 1930 bwn_shm_ctlword(mac, way, offset); 1931 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1932 out: 1933 1934 return (ret); 1935 } 1936 1937 static void 1938 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1939 uint16_t offset) 1940 { 1941 uint32_t control; 1942 1943 control = way; 1944 control <<= 16; 1945 control |= offset; 1946 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1947 } 1948 1949 static void 1950 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1951 uint32_t value) 1952 { 1953 BWN_ASSERT_LOCKED(mac->mac_sc); 1954 1955 if (way == BWN_SHARED) { 1956 KASSERT((offset & 0x0001) == 0, 1957 ("%s:%d warn", __func__, __LINE__)); 1958 if (offset & 0x0003) { 1959 bwn_shm_ctlword(mac, way, offset >> 2); 1960 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1961 (value >> 16) & 0xffff); 1962 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1963 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1964 return; 1965 } 1966 offset >>= 2; 1967 } 1968 bwn_shm_ctlword(mac, way, offset); 1969 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1970 } 1971 1972 static void 1973 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1974 uint16_t value) 1975 { 1976 BWN_ASSERT_LOCKED(mac->mac_sc); 1977 1978 if (way == BWN_SHARED) { 1979 KASSERT((offset & 0x0001) == 0, 1980 ("%s:%d warn", __func__, __LINE__)); 1981 if (offset & 0x0003) { 1982 bwn_shm_ctlword(mac, way, offset >> 2); 1983 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1984 return; 1985 } 1986 offset >>= 2; 1987 } 1988 bwn_shm_ctlword(mac, way, offset); 1989 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1990 } 1991 1992 static void 1993 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1994 int txpow) 1995 { 1996 1997 c->ic_freq = freq; 1998 c->ic_flags = flags; 1999 c->ic_ieee = ieee; 2000 c->ic_minpower = 0; 2001 c->ic_maxpower = 2 * txpow; 2002 c->ic_maxregpower = txpow; 2003 } 2004 2005 static void 2006 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2007 const struct bwn_channelinfo *ci, int flags) 2008 { 2009 struct ieee80211_channel *c; 2010 int i; 2011 2012 c = &chans[*nchans]; 2013 2014 for (i = 0; i < ci->nchannels; i++) { 2015 const struct bwn_channel *hc; 2016 2017 hc = &ci->channels[i]; 2018 if (*nchans >= maxchans) 2019 break; 2020 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2021 c++, (*nchans)++; 2022 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2023 /* g channel have a separate b-only entry */ 2024 if (*nchans >= maxchans) 2025 break; 2026 c[0] = c[-1]; 2027 c[-1].ic_flags = IEEE80211_CHAN_B; 2028 c++, (*nchans)++; 2029 } 2030 if (flags == IEEE80211_CHAN_HTG) { 2031 /* HT g channel have a separate g-only entry */ 2032 if (*nchans >= maxchans) 2033 break; 2034 c[-1].ic_flags = IEEE80211_CHAN_G; 2035 c[0] = c[-1]; 2036 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2037 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2038 c++, (*nchans)++; 2039 } 2040 if (flags == IEEE80211_CHAN_HTA) { 2041 /* HT a channel have a separate a-only entry */ 2042 if (*nchans >= maxchans) 2043 break; 2044 c[-1].ic_flags = IEEE80211_CHAN_A; 2045 c[0] = c[-1]; 2046 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2047 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2048 c++, (*nchans)++; 2049 } 2050 } 2051 } 2052 2053 static int 2054 bwn_phy_g_attach(struct bwn_mac *mac) 2055 { 2056 struct bwn_softc *sc = mac->mac_sc; 2057 struct bwn_phy *phy = &mac->mac_phy; 2058 struct bwn_phy_g *pg = &phy->phy_g; 2059 unsigned int i; 2060 int16_t pab0, pab1, pab2; 2061 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2062 int8_t bg; 2063 2064 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2065 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2066 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2067 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2068 2069 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2070 device_printf(sc->sc_dev, "not supported anymore\n"); 2071 2072 pg->pg_flags = 0; 2073 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2074 pab2 == -1) { 2075 pg->pg_idletssi = 52; 2076 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2077 return (0); 2078 } 2079 2080 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2081 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2082 if (pg->pg_tssi2dbm == NULL) { 2083 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2084 return (ENOMEM); 2085 } 2086 for (i = 0; i < 64; i++) { 2087 int32_t m1, m2, f, q, delta; 2088 int8_t j = 0; 2089 2090 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2091 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2092 f = 256; 2093 2094 do { 2095 if (j > 15) { 2096 device_printf(sc->sc_dev, 2097 "failed to generate tssi2dBm\n"); 2098 free(pg->pg_tssi2dbm, M_DEVBUF); 2099 return (ENOMEM); 2100 } 2101 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2102 f, 2048); 2103 delta = abs(q - f); 2104 f = q; 2105 j++; 2106 } while (delta >= 2); 2107 2108 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2109 128); 2110 } 2111 2112 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2113 return (0); 2114 } 2115 2116 static void 2117 bwn_phy_g_detach(struct bwn_mac *mac) 2118 { 2119 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2120 2121 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2122 free(pg->pg_tssi2dbm, M_DEVBUF); 2123 pg->pg_tssi2dbm = NULL; 2124 } 2125 pg->pg_flags = 0; 2126 } 2127 2128 static void 2129 bwn_phy_g_init_pre(struct bwn_mac *mac) 2130 { 2131 struct bwn_phy *phy = &mac->mac_phy; 2132 struct bwn_phy_g *pg = &phy->phy_g; 2133 void *tssi2dbm; 2134 int idletssi; 2135 unsigned int i; 2136 2137 tssi2dbm = pg->pg_tssi2dbm; 2138 idletssi = pg->pg_idletssi; 2139 2140 memset(pg, 0, sizeof(*pg)); 2141 2142 pg->pg_tssi2dbm = tssi2dbm; 2143 pg->pg_idletssi = idletssi; 2144 2145 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2146 2147 for (i = 0; i < N(pg->pg_nrssi); i++) 2148 pg->pg_nrssi[i] = -1000; 2149 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2150 pg->pg_nrssi_lt[i] = i; 2151 pg->pg_lofcal = 0xffff; 2152 pg->pg_initval = 0xffff; 2153 pg->pg_immode = BWN_IMMODE_NONE; 2154 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2155 pg->pg_avgtssi = 0xff; 2156 2157 pg->pg_loctl.tx_bias = 0xff; 2158 TAILQ_INIT(&pg->pg_loctl.calib_list); 2159 } 2160 2161 static int 2162 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2163 { 2164 struct bwn_phy *phy = &mac->mac_phy; 2165 struct bwn_phy_g *pg = &phy->phy_g; 2166 struct bwn_softc *sc = mac->mac_sc; 2167 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2168 static const struct bwn_rfatt rfatt0[] = { 2169 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2170 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2171 { 3, 1 }, { 4, 1 } 2172 }; 2173 static const struct bwn_rfatt rfatt1[] = { 2174 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2175 { 14, 1 } 2176 }; 2177 static const struct bwn_rfatt rfatt2[] = { 2178 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2179 { 9, 1 } 2180 }; 2181 static const struct bwn_bbatt bbatt_0[] = { 2182 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2183 }; 2184 2185 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2186 2187 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2188 pg->pg_bbatt.att = 0; 2189 else 2190 pg->pg_bbatt.att = 2; 2191 2192 /* prepare Radio Attenuation */ 2193 pg->pg_rfatt.padmix = 0; 2194 2195 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2196 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2197 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2198 pg->pg_rfatt.att = 2; 2199 goto done; 2200 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2201 pg->pg_rfatt.att = 3; 2202 goto done; 2203 } 2204 } 2205 2206 if (phy->type == BWN_PHYTYPE_A) { 2207 pg->pg_rfatt.att = 0x60; 2208 goto done; 2209 } 2210 2211 switch (phy->rf_ver) { 2212 case 0x2050: 2213 switch (phy->rf_rev) { 2214 case 0: 2215 pg->pg_rfatt.att = 5; 2216 goto done; 2217 case 1: 2218 if (phy->type == BWN_PHYTYPE_G) { 2219 if (siba_get_pci_subvendor(sc->sc_dev) == 2220 SIBA_BOARDVENDOR_BCM && 2221 siba_get_pci_subdevice(sc->sc_dev) == 2222 SIBA_BOARD_BCM4309G && 2223 siba_get_pci_revid(sc->sc_dev) >= 30) 2224 pg->pg_rfatt.att = 3; 2225 else if (siba_get_pci_subvendor(sc->sc_dev) == 2226 SIBA_BOARDVENDOR_BCM && 2227 siba_get_pci_subdevice(sc->sc_dev) == 2228 SIBA_BOARD_BU4306) 2229 pg->pg_rfatt.att = 3; 2230 else 2231 pg->pg_rfatt.att = 1; 2232 } else { 2233 if (siba_get_pci_subvendor(sc->sc_dev) == 2234 SIBA_BOARDVENDOR_BCM && 2235 siba_get_pci_subdevice(sc->sc_dev) == 2236 SIBA_BOARD_BCM4309G && 2237 siba_get_pci_revid(sc->sc_dev) >= 30) 2238 pg->pg_rfatt.att = 7; 2239 else 2240 pg->pg_rfatt.att = 6; 2241 } 2242 goto done; 2243 case 2: 2244 if (phy->type == BWN_PHYTYPE_G) { 2245 if (siba_get_pci_subvendor(sc->sc_dev) == 2246 SIBA_BOARDVENDOR_BCM && 2247 siba_get_pci_subdevice(sc->sc_dev) == 2248 SIBA_BOARD_BCM4309G && 2249 siba_get_pci_revid(sc->sc_dev) >= 30) 2250 pg->pg_rfatt.att = 3; 2251 else if (siba_get_pci_subvendor(sc->sc_dev) == 2252 SIBA_BOARDVENDOR_BCM && 2253 siba_get_pci_subdevice(sc->sc_dev) == 2254 SIBA_BOARD_BU4306) 2255 pg->pg_rfatt.att = 5; 2256 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2257 pg->pg_rfatt.att = 4; 2258 else 2259 pg->pg_rfatt.att = 3; 2260 } else 2261 pg->pg_rfatt.att = 6; 2262 goto done; 2263 case 3: 2264 pg->pg_rfatt.att = 5; 2265 goto done; 2266 case 4: 2267 case 5: 2268 pg->pg_rfatt.att = 1; 2269 goto done; 2270 case 6: 2271 case 7: 2272 pg->pg_rfatt.att = 5; 2273 goto done; 2274 case 8: 2275 pg->pg_rfatt.att = 0xa; 2276 pg->pg_rfatt.padmix = 1; 2277 goto done; 2278 case 9: 2279 default: 2280 pg->pg_rfatt.att = 5; 2281 goto done; 2282 } 2283 break; 2284 case 0x2053: 2285 switch (phy->rf_rev) { 2286 case 1: 2287 pg->pg_rfatt.att = 6; 2288 goto done; 2289 } 2290 break; 2291 } 2292 pg->pg_rfatt.att = 5; 2293 done: 2294 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2295 2296 if (!bwn_has_hwpctl(mac)) { 2297 lo->rfatt.array = rfatt0; 2298 lo->rfatt.len = N(rfatt0); 2299 lo->rfatt.min = 0; 2300 lo->rfatt.max = 9; 2301 goto genbbatt; 2302 } 2303 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2304 lo->rfatt.array = rfatt1; 2305 lo->rfatt.len = N(rfatt1); 2306 lo->rfatt.min = 0; 2307 lo->rfatt.max = 14; 2308 goto genbbatt; 2309 } 2310 lo->rfatt.array = rfatt2; 2311 lo->rfatt.len = N(rfatt2); 2312 lo->rfatt.min = 0; 2313 lo->rfatt.max = 9; 2314 genbbatt: 2315 lo->bbatt.array = bbatt_0; 2316 lo->bbatt.len = N(bbatt_0); 2317 lo->bbatt.min = 0; 2318 lo->bbatt.max = 8; 2319 2320 BWN_READ_4(mac, BWN_MACCTL); 2321 if (phy->rev == 1) { 2322 phy->gmode = 0; 2323 bwn_reset_core(mac, 0); 2324 bwn_phy_g_init_sub(mac); 2325 phy->gmode = 1; 2326 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2327 } 2328 return (0); 2329 } 2330 2331 static uint16_t 2332 bwn_phy_g_txctl(struct bwn_mac *mac) 2333 { 2334 struct bwn_phy *phy = &mac->mac_phy; 2335 2336 if (phy->rf_ver != 0x2050) 2337 return (0); 2338 if (phy->rf_rev == 1) 2339 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2340 if (phy->rf_rev < 6) 2341 return (BWN_TXCTL_PA2DB); 2342 if (phy->rf_rev == 8) 2343 return (BWN_TXCTL_TXMIX); 2344 return (0); 2345 } 2346 2347 static int 2348 bwn_phy_g_init(struct bwn_mac *mac) 2349 { 2350 2351 bwn_phy_g_init_sub(mac); 2352 return (0); 2353 } 2354 2355 static void 2356 bwn_phy_g_exit(struct bwn_mac *mac) 2357 { 2358 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2359 struct bwn_lo_calib *cal, *tmp; 2360 2361 if (lo == NULL) 2362 return; 2363 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2364 TAILQ_REMOVE(&lo->calib_list, cal, list); 2365 free(cal, M_DEVBUF); 2366 } 2367 } 2368 2369 static uint16_t 2370 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2371 { 2372 2373 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2374 return (BWN_READ_2(mac, BWN_PHYDATA)); 2375 } 2376 2377 static void 2378 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2379 { 2380 2381 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2382 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2383 } 2384 2385 static uint16_t 2386 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2387 { 2388 2389 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2390 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2391 return (BWN_READ_2(mac, BWN_RFDATALO)); 2392 } 2393 2394 static void 2395 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2396 { 2397 2398 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2399 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2400 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2401 } 2402 2403 static int 2404 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2405 { 2406 2407 return (mac->mac_phy.rev >= 6); 2408 } 2409 2410 static void 2411 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2412 { 2413 struct bwn_phy *phy = &mac->mac_phy; 2414 struct bwn_phy_g *pg = &phy->phy_g; 2415 unsigned int channel; 2416 uint16_t rfover, rfoverval; 2417 2418 if (on) { 2419 if (phy->rf_on) 2420 return; 2421 2422 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2423 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2424 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2425 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2426 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2427 pg->pg_radioctx_over); 2428 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2429 pg->pg_radioctx_overval); 2430 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2431 } 2432 channel = phy->chan; 2433 bwn_phy_g_switch_chan(mac, 6, 1); 2434 bwn_phy_g_switch_chan(mac, channel, 0); 2435 return; 2436 } 2437 2438 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2439 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2440 pg->pg_radioctx_over = rfover; 2441 pg->pg_radioctx_overval = rfoverval; 2442 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2443 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2444 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2445 } 2446 2447 static int 2448 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2449 { 2450 2451 if ((newchan < 1) || (newchan > 14)) 2452 return (EINVAL); 2453 bwn_phy_g_switch_chan(mac, newchan, 0); 2454 2455 return (0); 2456 } 2457 2458 static uint32_t 2459 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2460 { 2461 2462 return (1); 2463 } 2464 2465 static void 2466 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2467 { 2468 struct bwn_phy *phy = &mac->mac_phy; 2469 uint64_t hf; 2470 int autodiv = 0; 2471 uint16_t tmp; 2472 2473 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2474 autodiv = 1; 2475 2476 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2477 bwn_hf_write(mac, hf); 2478 2479 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2480 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2481 ((autodiv ? BWN_ANTAUTO1 : antenna) 2482 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2483 2484 if (autodiv) { 2485 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2486 if (antenna == BWN_ANTAUTO1) 2487 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2488 else 2489 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2490 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2491 } 2492 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2493 if (autodiv) 2494 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2495 else 2496 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2497 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2498 if (phy->rev >= 2) { 2499 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2500 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2501 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2502 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2503 0x15); 2504 if (phy->rev == 2) 2505 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2506 else 2507 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2508 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2509 8); 2510 } 2511 if (phy->rev >= 6) 2512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2513 2514 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2515 bwn_hf_write(mac, hf); 2516 } 2517 2518 static int 2519 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2520 { 2521 struct bwn_phy *phy = &mac->mac_phy; 2522 struct bwn_phy_g *pg = &phy->phy_g; 2523 2524 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2525 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2526 2527 if (phy->rev == 0 || !phy->gmode) 2528 return (ENODEV); 2529 2530 pg->pg_aci_wlan_automatic = 0; 2531 return (0); 2532 } 2533 2534 static int 2535 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2536 { 2537 struct bwn_phy *phy = &mac->mac_phy; 2538 struct bwn_phy_g *pg = &phy->phy_g; 2539 struct bwn_softc *sc = mac->mac_sc; 2540 unsigned int tssi; 2541 int cck, ofdm; 2542 int power; 2543 int rfatt, bbatt; 2544 unsigned int max; 2545 2546 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2547 2548 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2549 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2550 if (cck < 0 && ofdm < 0) { 2551 if (ignore_tssi == 0) 2552 return (BWN_TXPWR_RES_DONE); 2553 cck = 0; 2554 ofdm = 0; 2555 } 2556 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2557 if (pg->pg_avgtssi != 0xff) 2558 tssi = (tssi + pg->pg_avgtssi) / 2; 2559 pg->pg_avgtssi = tssi; 2560 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2561 2562 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2563 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2564 max -= 3; 2565 if (max >= 120) { 2566 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2567 max = 80; 2568 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2569 } 2570 2571 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2572 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2573 tssi, 0x00), 0x3f)]); 2574 if (power == 0) 2575 return (BWN_TXPWR_RES_DONE); 2576 2577 rfatt = -((power + 7) / 8); 2578 bbatt = (-(power / 2)) - (4 * rfatt); 2579 if ((rfatt == 0) && (bbatt == 0)) 2580 return (BWN_TXPWR_RES_DONE); 2581 pg->pg_bbatt_delta = bbatt; 2582 pg->pg_rfatt_delta = rfatt; 2583 return (BWN_TXPWR_RES_NEED_ADJUST); 2584 } 2585 2586 static void 2587 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2588 { 2589 struct bwn_phy *phy = &mac->mac_phy; 2590 struct bwn_phy_g *pg = &phy->phy_g; 2591 struct bwn_softc *sc = mac->mac_sc; 2592 int rfatt, bbatt; 2593 uint8_t txctl; 2594 2595 bwn_mac_suspend(mac); 2596 2597 BWN_ASSERT_LOCKED(sc); 2598 2599 bbatt = pg->pg_bbatt.att; 2600 bbatt += pg->pg_bbatt_delta; 2601 rfatt = pg->pg_rfatt.att; 2602 rfatt += pg->pg_rfatt_delta; 2603 2604 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2605 txctl = pg->pg_txctl; 2606 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2607 if (rfatt <= 1) { 2608 if (txctl == 0) { 2609 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2610 rfatt += 2; 2611 bbatt += 2; 2612 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2613 BWN_BFL_PACTRL) { 2614 bbatt += 4 * (rfatt - 2); 2615 rfatt = 2; 2616 } 2617 } else if (rfatt > 4 && txctl) { 2618 txctl = 0; 2619 if (bbatt < 3) { 2620 rfatt -= 3; 2621 bbatt += 2; 2622 } else { 2623 rfatt -= 2; 2624 bbatt -= 2; 2625 } 2626 } 2627 } 2628 pg->pg_txctl = txctl; 2629 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2630 pg->pg_rfatt.att = rfatt; 2631 pg->pg_bbatt.att = bbatt; 2632 2633 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2634 2635 bwn_phy_lock(mac); 2636 bwn_rf_lock(mac); 2637 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2638 pg->pg_txctl); 2639 bwn_rf_unlock(mac); 2640 bwn_phy_unlock(mac); 2641 2642 bwn_mac_enable(mac); 2643 } 2644 2645 static void 2646 bwn_phy_g_task_15s(struct bwn_mac *mac) 2647 { 2648 struct bwn_phy *phy = &mac->mac_phy; 2649 struct bwn_phy_g *pg = &phy->phy_g; 2650 struct bwn_softc *sc = mac->mac_sc; 2651 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2652 unsigned long expire, now; 2653 struct bwn_lo_calib *cal, *tmp; 2654 uint8_t expired = 0; 2655 2656 bwn_mac_suspend(mac); 2657 2658 if (lo == NULL) 2659 goto fail; 2660 2661 BWN_GETTIME(now); 2662 if (bwn_has_hwpctl(mac)) { 2663 expire = now - BWN_LO_PWRVEC_EXPIRE; 2664 if (time_before(lo->pwr_vec_read_time, expire)) { 2665 bwn_lo_get_powervector(mac); 2666 bwn_phy_g_dc_lookup_init(mac, 0); 2667 } 2668 goto fail; 2669 } 2670 2671 expire = now - BWN_LO_CALIB_EXPIRE; 2672 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2673 if (!time_before(cal->calib_time, expire)) 2674 continue; 2675 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2676 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2677 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2678 expired = 1; 2679 } 2680 2681 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2682 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2683 cal->ctl.i, cal->ctl.q); 2684 2685 TAILQ_REMOVE(&lo->calib_list, cal, list); 2686 free(cal, M_DEVBUF); 2687 } 2688 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2689 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2690 &pg->pg_rfatt); 2691 if (cal == NULL) { 2692 device_printf(sc->sc_dev, 2693 "failed to recalibrate LO\n"); 2694 goto fail; 2695 } 2696 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2697 bwn_lo_write(mac, &cal->ctl); 2698 } 2699 2700 fail: 2701 bwn_mac_enable(mac); 2702 } 2703 2704 static void 2705 bwn_phy_g_task_60s(struct bwn_mac *mac) 2706 { 2707 struct bwn_phy *phy = &mac->mac_phy; 2708 struct bwn_softc *sc = mac->mac_sc; 2709 uint8_t old = phy->chan; 2710 2711 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2712 return; 2713 2714 bwn_mac_suspend(mac); 2715 bwn_nrssi_slope_11g(mac); 2716 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2717 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2718 bwn_switch_channel(mac, old); 2719 } 2720 bwn_mac_enable(mac); 2721 } 2722 2723 static void 2724 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2725 { 2726 2727 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2728 } 2729 2730 static int 2731 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2732 const struct ieee80211_bpf_params *params) 2733 { 2734 struct ieee80211com *ic = ni->ni_ic; 2735 struct ifnet *ifp = ic->ic_ifp; 2736 struct bwn_softc *sc = ifp->if_softc; 2737 struct bwn_mac *mac = sc->sc_curmac; 2738 2739 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2740 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2741 ieee80211_free_node(ni); 2742 m_freem(m); 2743 return (ENETDOWN); 2744 } 2745 2746 BWN_LOCK(sc); 2747 if (bwn_tx_isfull(sc, m)) { 2748 ieee80211_free_node(ni); 2749 m_freem(m); 2750 ifp->if_oerrors++; 2751 BWN_UNLOCK(sc); 2752 return (ENOBUFS); 2753 } 2754 2755 if (bwn_tx_start(sc, ni, m) != 0) { 2756 if (ni != NULL) 2757 ieee80211_free_node(ni); 2758 ifp->if_oerrors++; 2759 } 2760 sc->sc_watchdog_timer = 5; 2761 BWN_UNLOCK(sc); 2762 return (0); 2763 } 2764 2765 /* 2766 * Callback from the 802.11 layer to update the slot time 2767 * based on the current setting. We use it to notify the 2768 * firmware of ERP changes and the f/w takes care of things 2769 * like slot time and preamble. 2770 */ 2771 static void 2772 bwn_updateslot(struct ifnet *ifp) 2773 { 2774 struct bwn_softc *sc = ifp->if_softc; 2775 struct ieee80211com *ic = ifp->if_l2com; 2776 struct bwn_mac *mac; 2777 2778 BWN_LOCK(sc); 2779 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2780 mac = (struct bwn_mac *)sc->sc_curmac; 2781 bwn_set_slot_time(mac, 2782 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2783 } 2784 BWN_UNLOCK(sc); 2785 } 2786 2787 /* 2788 * Callback from the 802.11 layer after a promiscuous mode change. 2789 * Note this interface does not check the operating mode as this 2790 * is an internal callback and we are expected to honor the current 2791 * state (e.g. this is used for setting the interface in promiscuous 2792 * mode when operating in hostap mode to do ACS). 2793 */ 2794 static void 2795 bwn_update_promisc(struct ifnet *ifp) 2796 { 2797 struct bwn_softc *sc = ifp->if_softc; 2798 struct bwn_mac *mac = sc->sc_curmac; 2799 2800 BWN_LOCK(sc); 2801 mac = sc->sc_curmac; 2802 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2803 if (ifp->if_flags & IFF_PROMISC) 2804 sc->sc_filters |= BWN_MACCTL_PROMISC; 2805 else 2806 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2807 bwn_set_opmode(mac); 2808 } 2809 BWN_UNLOCK(sc); 2810 } 2811 2812 /* 2813 * Callback from the 802.11 layer to update WME parameters. 2814 */ 2815 static int 2816 bwn_wme_update(struct ieee80211com *ic) 2817 { 2818 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2819 struct bwn_mac *mac = sc->sc_curmac; 2820 struct wmeParams *wmep; 2821 int i; 2822 2823 BWN_LOCK(sc); 2824 mac = sc->sc_curmac; 2825 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2826 bwn_mac_suspend(mac); 2827 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2828 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2829 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2830 } 2831 bwn_mac_enable(mac); 2832 } 2833 BWN_UNLOCK(sc); 2834 return (0); 2835 } 2836 2837 static void 2838 bwn_scan_start(struct ieee80211com *ic) 2839 { 2840 struct ifnet *ifp = ic->ic_ifp; 2841 struct bwn_softc *sc = ifp->if_softc; 2842 struct bwn_mac *mac; 2843 2844 BWN_LOCK(sc); 2845 mac = sc->sc_curmac; 2846 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2847 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2848 bwn_set_opmode(mac); 2849 /* disable CFP update during scan */ 2850 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2851 } 2852 BWN_UNLOCK(sc); 2853 } 2854 2855 static void 2856 bwn_scan_end(struct ieee80211com *ic) 2857 { 2858 struct ifnet *ifp = ic->ic_ifp; 2859 struct bwn_softc *sc = ifp->if_softc; 2860 struct bwn_mac *mac; 2861 2862 BWN_LOCK(sc); 2863 mac = sc->sc_curmac; 2864 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2865 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2866 bwn_set_opmode(mac); 2867 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2868 } 2869 BWN_UNLOCK(sc); 2870 } 2871 2872 static void 2873 bwn_set_channel(struct ieee80211com *ic) 2874 { 2875 struct ifnet *ifp = ic->ic_ifp; 2876 struct bwn_softc *sc = ifp->if_softc; 2877 struct bwn_mac *mac = sc->sc_curmac; 2878 struct bwn_phy *phy = &mac->mac_phy; 2879 int chan, error; 2880 2881 BWN_LOCK(sc); 2882 2883 error = bwn_switch_band(sc, ic->ic_curchan); 2884 if (error) 2885 goto fail; 2886 bwn_mac_suspend(mac); 2887 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2888 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2889 if (chan != phy->chan) 2890 bwn_switch_channel(mac, chan); 2891 2892 /* TX power level */ 2893 if (ic->ic_curchan->ic_maxpower != 0 && 2894 ic->ic_curchan->ic_maxpower != phy->txpower) { 2895 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2896 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2897 BWN_TXPWR_IGNORE_TSSI); 2898 } 2899 2900 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2901 if (phy->set_antenna) 2902 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2903 2904 if (sc->sc_rf_enabled != phy->rf_on) { 2905 if (sc->sc_rf_enabled) { 2906 bwn_rf_turnon(mac); 2907 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2908 device_printf(sc->sc_dev, 2909 "please turn on the RF switch\n"); 2910 } else 2911 bwn_rf_turnoff(mac); 2912 } 2913 2914 bwn_mac_enable(mac); 2915 2916 fail: 2917 /* 2918 * Setup radio tap channel freq and flags 2919 */ 2920 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2921 htole16(ic->ic_curchan->ic_freq); 2922 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2923 htole16(ic->ic_curchan->ic_flags & 0xffff); 2924 2925 BWN_UNLOCK(sc); 2926 } 2927 2928 static struct ieee80211vap * 2929 bwn_vap_create(struct ieee80211com *ic, 2930 const char name[IFNAMSIZ], int unit, int opmode, int flags, 2931 const uint8_t bssid[IEEE80211_ADDR_LEN], 2932 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2933 { 2934 struct ifnet *ifp = ic->ic_ifp; 2935 struct bwn_softc *sc = ifp->if_softc; 2936 struct ieee80211vap *vap; 2937 struct bwn_vap *bvp; 2938 uint8_t mac[IEEE80211_ADDR_LEN]; 2939 2940 IEEE80211_ADDR_COPY(mac, mac0); 2941 switch (opmode) { 2942 case IEEE80211_M_HOSTAP: 2943 case IEEE80211_M_MBSS: 2944 case IEEE80211_M_STA: 2945 case IEEE80211_M_WDS: 2946 case IEEE80211_M_MONITOR: 2947 case IEEE80211_M_IBSS: 2948 case IEEE80211_M_AHDEMO: 2949 break; 2950 default: 2951 return (NULL); 2952 } 2953 2954 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2955 2956 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 2957 M_80211_VAP, M_NOWAIT | M_ZERO); 2958 if (bvp == NULL) { 2959 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 2960 return (NULL); 2961 } 2962 vap = &bvp->bv_vap; 2963 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2964 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2965 /* override with driver methods */ 2966 bvp->bv_newstate = vap->iv_newstate; 2967 vap->iv_newstate = bwn_newstate; 2968 2969 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2970 vap->iv_max_aid = BWN_STAID_MAX; 2971 2972 ieee80211_ratectl_init(vap); 2973 2974 /* complete setup */ 2975 ieee80211_vap_attach(vap, ieee80211_media_change, 2976 ieee80211_media_status); 2977 return (vap); 2978 } 2979 2980 static void 2981 bwn_vap_delete(struct ieee80211vap *vap) 2982 { 2983 struct bwn_vap *bvp = BWN_VAP(vap); 2984 2985 ieee80211_ratectl_deinit(vap); 2986 ieee80211_vap_detach(vap); 2987 free(bvp, M_80211_VAP); 2988 } 2989 2990 static void 2991 bwn_init(void *arg) 2992 { 2993 struct bwn_softc *sc = arg; 2994 struct ifnet *ifp = sc->sc_ifp; 2995 struct ieee80211com *ic = ifp->if_l2com; 2996 int error = 0; 2997 2998 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 2999 __func__, ifp->if_flags); 3000 3001 BWN_LOCK(sc); 3002 error = bwn_init_locked(sc); 3003 BWN_UNLOCK(sc); 3004 3005 if (error == 0) 3006 ieee80211_start_all(ic); /* start all vap's */ 3007 } 3008 3009 static int 3010 bwn_init_locked(struct bwn_softc *sc) 3011 { 3012 struct bwn_mac *mac; 3013 struct ifnet *ifp = sc->sc_ifp; 3014 int error; 3015 3016 BWN_ASSERT_LOCKED(sc); 3017 3018 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3019 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3020 sc->sc_filters = 0; 3021 bwn_wme_clear(sc); 3022 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3023 sc->sc_rf_enabled = 1; 3024 3025 mac = sc->sc_curmac; 3026 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3027 error = bwn_core_init(mac); 3028 if (error != 0) 3029 return (error); 3030 } 3031 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3032 bwn_core_start(mac); 3033 3034 bwn_set_opmode(mac); 3035 bwn_set_pretbtt(mac); 3036 bwn_spu_setdelay(mac, 0); 3037 bwn_set_macaddr(mac); 3038 3039 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3040 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3041 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3042 3043 return (0); 3044 } 3045 3046 static void 3047 bwn_stop(struct bwn_softc *sc, int statechg) 3048 { 3049 3050 BWN_LOCK(sc); 3051 bwn_stop_locked(sc, statechg); 3052 BWN_UNLOCK(sc); 3053 } 3054 3055 static void 3056 bwn_stop_locked(struct bwn_softc *sc, int statechg) 3057 { 3058 struct bwn_mac *mac = sc->sc_curmac; 3059 struct ifnet *ifp = sc->sc_ifp; 3060 3061 BWN_ASSERT_LOCKED(sc); 3062 3063 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3064 /* XXX FIXME opmode not based on VAP */ 3065 bwn_set_opmode(mac); 3066 bwn_set_macaddr(mac); 3067 } 3068 3069 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3070 bwn_core_stop(mac); 3071 3072 callout_stop(&sc->sc_led_blink_ch); 3073 sc->sc_led_blinking = 0; 3074 3075 bwn_core_exit(mac); 3076 sc->sc_rf_enabled = 0; 3077 3078 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3079 } 3080 3081 static void 3082 bwn_wme_clear(struct bwn_softc *sc) 3083 { 3084 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3085 struct wmeParams *p; 3086 unsigned int i; 3087 3088 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3089 ("%s:%d: fail", __func__, __LINE__)); 3090 3091 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3092 p = &(sc->sc_wmeParams[i]); 3093 3094 switch (bwn_wme_shm_offsets[i]) { 3095 case BWN_WME_VOICE: 3096 p->wmep_txopLimit = 0; 3097 p->wmep_aifsn = 2; 3098 /* XXX FIXME: log2(cwmin) */ 3099 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3100 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3101 break; 3102 case BWN_WME_VIDEO: 3103 p->wmep_txopLimit = 0; 3104 p->wmep_aifsn = 2; 3105 /* XXX FIXME: log2(cwmin) */ 3106 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3107 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3108 break; 3109 case BWN_WME_BESTEFFORT: 3110 p->wmep_txopLimit = 0; 3111 p->wmep_aifsn = 3; 3112 /* XXX FIXME: log2(cwmin) */ 3113 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3114 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3115 break; 3116 case BWN_WME_BACKGROUND: 3117 p->wmep_txopLimit = 0; 3118 p->wmep_aifsn = 7; 3119 /* XXX FIXME: log2(cwmin) */ 3120 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3121 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3122 break; 3123 default: 3124 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3125 } 3126 } 3127 } 3128 3129 static int 3130 bwn_core_init(struct bwn_mac *mac) 3131 { 3132 struct bwn_softc *sc = mac->mac_sc; 3133 uint64_t hf; 3134 int error; 3135 3136 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3137 ("%s:%d: fail", __func__, __LINE__)); 3138 3139 siba_powerup(sc->sc_dev, 0); 3140 if (!siba_dev_isup(sc->sc_dev)) 3141 bwn_reset_core(mac, 3142 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3143 3144 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3145 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3146 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3147 BWN_GETTIME(mac->mac_phy.nexttime); 3148 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3149 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3150 mac->mac_stats.link_noise = -95; 3151 mac->mac_reason_intr = 0; 3152 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3153 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3154 #ifdef BWN_DEBUG 3155 if (sc->sc_debug & BWN_DEBUG_XMIT) 3156 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3157 #endif 3158 mac->mac_suspended = 1; 3159 mac->mac_task_state = 0; 3160 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3161 3162 mac->mac_phy.init_pre(mac); 3163 3164 siba_pcicore_intr(sc->sc_dev); 3165 3166 siba_fix_imcfglobug(sc->sc_dev); 3167 bwn_bt_disable(mac); 3168 if (mac->mac_phy.prepare_hw) { 3169 error = mac->mac_phy.prepare_hw(mac); 3170 if (error) 3171 goto fail0; 3172 } 3173 error = bwn_chip_init(mac); 3174 if (error) 3175 goto fail0; 3176 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3177 siba_get_revid(sc->sc_dev)); 3178 hf = bwn_hf_read(mac); 3179 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3180 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3181 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3182 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3183 if (mac->mac_phy.rev == 1) 3184 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3185 } 3186 if (mac->mac_phy.rf_ver == 0x2050) { 3187 if (mac->mac_phy.rf_rev < 6) 3188 hf |= BWN_HF_FORCE_VCO_RECALC; 3189 if (mac->mac_phy.rf_rev == 6) 3190 hf |= BWN_HF_4318_TSSI; 3191 } 3192 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3193 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3194 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3195 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3196 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3197 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3198 bwn_hf_write(mac, hf); 3199 3200 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3201 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3202 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3204 3205 bwn_rate_init(mac); 3206 bwn_set_phytxctl(mac); 3207 3208 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3209 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3210 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3211 3212 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3213 bwn_pio_init(mac); 3214 else 3215 bwn_dma_init(mac); 3216 bwn_wme_init(mac); 3217 bwn_spu_setdelay(mac, 1); 3218 bwn_bt_enable(mac); 3219 3220 siba_powerup(sc->sc_dev, 3221 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3222 bwn_set_macaddr(mac); 3223 bwn_crypt_init(mac); 3224 3225 /* XXX LED initializatin */ 3226 3227 mac->mac_status = BWN_MAC_STATUS_INITED; 3228 3229 return (error); 3230 3231 fail0: 3232 siba_powerdown(sc->sc_dev); 3233 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3234 ("%s:%d: fail", __func__, __LINE__)); 3235 return (error); 3236 } 3237 3238 static void 3239 bwn_core_start(struct bwn_mac *mac) 3240 { 3241 struct bwn_softc *sc = mac->mac_sc; 3242 uint32_t tmp; 3243 3244 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3245 ("%s:%d: fail", __func__, __LINE__)); 3246 3247 if (siba_get_revid(sc->sc_dev) < 5) 3248 return; 3249 3250 while (1) { 3251 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3252 if (!(tmp & 0x00000001)) 3253 break; 3254 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3255 } 3256 3257 bwn_mac_enable(mac); 3258 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3259 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3260 3261 mac->mac_status = BWN_MAC_STATUS_STARTED; 3262 } 3263 3264 static void 3265 bwn_core_exit(struct bwn_mac *mac) 3266 { 3267 struct bwn_softc *sc = mac->mac_sc; 3268 uint32_t macctl; 3269 3270 BWN_ASSERT_LOCKED(mac->mac_sc); 3271 3272 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3273 ("%s:%d: fail", __func__, __LINE__)); 3274 3275 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3276 return; 3277 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3278 3279 macctl = BWN_READ_4(mac, BWN_MACCTL); 3280 macctl &= ~BWN_MACCTL_MCODE_RUN; 3281 macctl |= BWN_MACCTL_MCODE_JMP0; 3282 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3283 3284 bwn_dma_stop(mac); 3285 bwn_pio_stop(mac); 3286 bwn_chip_exit(mac); 3287 mac->mac_phy.switch_analog(mac, 0); 3288 siba_dev_down(sc->sc_dev, 0); 3289 siba_powerdown(sc->sc_dev); 3290 } 3291 3292 static void 3293 bwn_bt_disable(struct bwn_mac *mac) 3294 { 3295 struct bwn_softc *sc = mac->mac_sc; 3296 3297 (void)sc; 3298 /* XXX do nothing yet */ 3299 } 3300 3301 static int 3302 bwn_chip_init(struct bwn_mac *mac) 3303 { 3304 struct bwn_softc *sc = mac->mac_sc; 3305 struct bwn_phy *phy = &mac->mac_phy; 3306 uint32_t macctl; 3307 int error; 3308 3309 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3310 if (phy->gmode) 3311 macctl |= BWN_MACCTL_GMODE; 3312 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3313 3314 error = bwn_fw_fillinfo(mac); 3315 if (error) 3316 return (error); 3317 error = bwn_fw_loaducode(mac); 3318 if (error) 3319 return (error); 3320 3321 error = bwn_gpio_init(mac); 3322 if (error) 3323 return (error); 3324 3325 error = bwn_fw_loadinitvals(mac); 3326 if (error) { 3327 siba_gpio_set(sc->sc_dev, 0); 3328 return (error); 3329 } 3330 phy->switch_analog(mac, 1); 3331 error = bwn_phy_init(mac); 3332 if (error) { 3333 siba_gpio_set(sc->sc_dev, 0); 3334 return (error); 3335 } 3336 if (phy->set_im) 3337 phy->set_im(mac, BWN_IMMODE_NONE); 3338 if (phy->set_antenna) 3339 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3340 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3341 3342 if (phy->type == BWN_PHYTYPE_B) 3343 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3344 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3345 if (siba_get_revid(sc->sc_dev) < 5) 3346 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3347 3348 BWN_WRITE_4(mac, BWN_MACCTL, 3349 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3350 BWN_WRITE_4(mac, BWN_MACCTL, 3351 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3352 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3353 3354 bwn_set_opmode(mac); 3355 if (siba_get_revid(sc->sc_dev) < 3) { 3356 BWN_WRITE_2(mac, 0x060e, 0x0000); 3357 BWN_WRITE_2(mac, 0x0610, 0x8000); 3358 BWN_WRITE_2(mac, 0x0604, 0x0000); 3359 BWN_WRITE_2(mac, 0x0606, 0x0200); 3360 } else { 3361 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3362 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3363 } 3364 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3365 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3366 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3367 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3368 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3369 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3370 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3371 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3372 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3373 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3374 return (error); 3375 } 3376 3377 /* read hostflags */ 3378 static uint64_t 3379 bwn_hf_read(struct bwn_mac *mac) 3380 { 3381 uint64_t ret; 3382 3383 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3384 ret <<= 16; 3385 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3386 ret <<= 16; 3387 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3388 return (ret); 3389 } 3390 3391 static void 3392 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3393 { 3394 3395 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3396 (value & 0x00000000ffffull)); 3397 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3398 (value & 0x0000ffff0000ull) >> 16); 3399 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3400 (value & 0xffff00000000ULL) >> 32); 3401 } 3402 3403 static void 3404 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3405 { 3406 3407 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3408 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3409 } 3410 3411 static void 3412 bwn_rate_init(struct bwn_mac *mac) 3413 { 3414 3415 switch (mac->mac_phy.type) { 3416 case BWN_PHYTYPE_A: 3417 case BWN_PHYTYPE_G: 3418 case BWN_PHYTYPE_LP: 3419 case BWN_PHYTYPE_N: 3420 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3421 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3422 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3423 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3424 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3425 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3426 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3427 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3428 break; 3429 /* FALLTHROUGH */ 3430 case BWN_PHYTYPE_B: 3431 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3432 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3433 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3434 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3435 break; 3436 default: 3437 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3438 } 3439 } 3440 3441 static void 3442 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3443 { 3444 uint16_t offset; 3445 3446 if (ofdm) { 3447 offset = 0x480; 3448 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3449 } else { 3450 offset = 0x4c0; 3451 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3452 } 3453 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3454 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3455 } 3456 3457 static uint8_t 3458 bwn_plcp_getcck(const uint8_t bitrate) 3459 { 3460 3461 switch (bitrate) { 3462 case BWN_CCK_RATE_1MB: 3463 return (0x0a); 3464 case BWN_CCK_RATE_2MB: 3465 return (0x14); 3466 case BWN_CCK_RATE_5MB: 3467 return (0x37); 3468 case BWN_CCK_RATE_11MB: 3469 return (0x6e); 3470 } 3471 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3472 return (0); 3473 } 3474 3475 static uint8_t 3476 bwn_plcp_getofdm(const uint8_t bitrate) 3477 { 3478 3479 switch (bitrate) { 3480 case BWN_OFDM_RATE_6MB: 3481 return (0xb); 3482 case BWN_OFDM_RATE_9MB: 3483 return (0xf); 3484 case BWN_OFDM_RATE_12MB: 3485 return (0xa); 3486 case BWN_OFDM_RATE_18MB: 3487 return (0xe); 3488 case BWN_OFDM_RATE_24MB: 3489 return (0x9); 3490 case BWN_OFDM_RATE_36MB: 3491 return (0xd); 3492 case BWN_OFDM_RATE_48MB: 3493 return (0x8); 3494 case BWN_OFDM_RATE_54MB: 3495 return (0xc); 3496 } 3497 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3498 return (0); 3499 } 3500 3501 static void 3502 bwn_set_phytxctl(struct bwn_mac *mac) 3503 { 3504 uint16_t ctl; 3505 3506 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3507 BWN_TX_PHY_TXPWR); 3508 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3509 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3510 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3511 } 3512 3513 static void 3514 bwn_pio_init(struct bwn_mac *mac) 3515 { 3516 struct bwn_pio *pio = &mac->mac_method.pio; 3517 3518 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3519 & ~BWN_MACCTL_BIGENDIAN); 3520 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3521 3522 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3523 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3524 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3525 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3526 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3527 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3528 } 3529 3530 static void 3531 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3532 int index) 3533 { 3534 struct bwn_pio_txpkt *tp; 3535 struct bwn_softc *sc = mac->mac_sc; 3536 unsigned int i; 3537 3538 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3539 tq->tq_index = index; 3540 3541 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3542 if (siba_get_revid(sc->sc_dev) >= 8) 3543 tq->tq_size = 1920; 3544 else { 3545 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3546 tq->tq_size -= 80; 3547 } 3548 3549 TAILQ_INIT(&tq->tq_pktlist); 3550 for (i = 0; i < N(tq->tq_pkts); i++) { 3551 tp = &(tq->tq_pkts[i]); 3552 tp->tp_index = i; 3553 tp->tp_queue = tq; 3554 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3555 } 3556 } 3557 3558 static uint16_t 3559 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3560 { 3561 struct bwn_softc *sc = mac->mac_sc; 3562 static const uint16_t bases[] = { 3563 BWN_PIO_BASE0, 3564 BWN_PIO_BASE1, 3565 BWN_PIO_BASE2, 3566 BWN_PIO_BASE3, 3567 BWN_PIO_BASE4, 3568 BWN_PIO_BASE5, 3569 BWN_PIO_BASE6, 3570 BWN_PIO_BASE7, 3571 }; 3572 static const uint16_t bases_rev11[] = { 3573 BWN_PIO11_BASE0, 3574 BWN_PIO11_BASE1, 3575 BWN_PIO11_BASE2, 3576 BWN_PIO11_BASE3, 3577 BWN_PIO11_BASE4, 3578 BWN_PIO11_BASE5, 3579 }; 3580 3581 if (siba_get_revid(sc->sc_dev) >= 11) { 3582 if (index >= N(bases_rev11)) 3583 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3584 return (bases_rev11[index]); 3585 } 3586 if (index >= N(bases)) 3587 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3588 return (bases[index]); 3589 } 3590 3591 static void 3592 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3593 int index) 3594 { 3595 struct bwn_softc *sc = mac->mac_sc; 3596 3597 prq->prq_mac = mac; 3598 prq->prq_rev = siba_get_revid(sc->sc_dev); 3599 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3600 bwn_dma_rxdirectfifo(mac, index, 1); 3601 } 3602 3603 static void 3604 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3605 { 3606 if (tq == NULL) 3607 return; 3608 bwn_pio_cancel_tx_packets(tq); 3609 } 3610 3611 static void 3612 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3613 { 3614 3615 bwn_destroy_pioqueue_tx(pio); 3616 } 3617 3618 static uint16_t 3619 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3620 uint16_t offset) 3621 { 3622 3623 return (BWN_READ_2(mac, tq->tq_base + offset)); 3624 } 3625 3626 static void 3627 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3628 { 3629 uint32_t ctl; 3630 int type; 3631 uint16_t base; 3632 3633 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3634 base = bwn_dma_base(type, idx); 3635 if (type == BWN_DMA_64BIT) { 3636 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3637 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3638 if (enable) 3639 ctl |= BWN_DMA64_RXDIRECTFIFO; 3640 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3641 } else { 3642 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3643 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3644 if (enable) 3645 ctl |= BWN_DMA32_RXDIRECTFIFO; 3646 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3647 } 3648 } 3649 3650 static uint64_t 3651 bwn_dma_mask(struct bwn_mac *mac) 3652 { 3653 uint32_t tmp; 3654 uint16_t base; 3655 3656 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3657 if (tmp & SIBA_TGSHIGH_DMA64) 3658 return (BWN_DMA_BIT_MASK(64)); 3659 base = bwn_dma_base(0, 0); 3660 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3661 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3662 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3663 return (BWN_DMA_BIT_MASK(32)); 3664 3665 return (BWN_DMA_BIT_MASK(30)); 3666 } 3667 3668 static int 3669 bwn_dma_mask2type(uint64_t dmamask) 3670 { 3671 3672 if (dmamask == BWN_DMA_BIT_MASK(30)) 3673 return (BWN_DMA_30BIT); 3674 if (dmamask == BWN_DMA_BIT_MASK(32)) 3675 return (BWN_DMA_32BIT); 3676 if (dmamask == BWN_DMA_BIT_MASK(64)) 3677 return (BWN_DMA_64BIT); 3678 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3679 return (BWN_DMA_30BIT); 3680 } 3681 3682 static void 3683 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3684 { 3685 struct bwn_pio_txpkt *tp; 3686 unsigned int i; 3687 3688 for (i = 0; i < N(tq->tq_pkts); i++) { 3689 tp = &(tq->tq_pkts[i]); 3690 if (tp->tp_m) { 3691 m_freem(tp->tp_m); 3692 tp->tp_m = NULL; 3693 } 3694 } 3695 } 3696 3697 static uint16_t 3698 bwn_dma_base(int type, int controller_idx) 3699 { 3700 static const uint16_t map64[] = { 3701 BWN_DMA64_BASE0, 3702 BWN_DMA64_BASE1, 3703 BWN_DMA64_BASE2, 3704 BWN_DMA64_BASE3, 3705 BWN_DMA64_BASE4, 3706 BWN_DMA64_BASE5, 3707 }; 3708 static const uint16_t map32[] = { 3709 BWN_DMA32_BASE0, 3710 BWN_DMA32_BASE1, 3711 BWN_DMA32_BASE2, 3712 BWN_DMA32_BASE3, 3713 BWN_DMA32_BASE4, 3714 BWN_DMA32_BASE5, 3715 }; 3716 3717 if (type == BWN_DMA_64BIT) { 3718 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3719 ("%s:%d: fail", __func__, __LINE__)); 3720 return (map64[controller_idx]); 3721 } 3722 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3723 ("%s:%d: fail", __func__, __LINE__)); 3724 return (map32[controller_idx]); 3725 } 3726 3727 static void 3728 bwn_dma_init(struct bwn_mac *mac) 3729 { 3730 struct bwn_dma *dma = &mac->mac_method.dma; 3731 3732 /* setup TX DMA channels. */ 3733 bwn_dma_setup(dma->wme[WME_AC_BK]); 3734 bwn_dma_setup(dma->wme[WME_AC_BE]); 3735 bwn_dma_setup(dma->wme[WME_AC_VI]); 3736 bwn_dma_setup(dma->wme[WME_AC_VO]); 3737 bwn_dma_setup(dma->mcast); 3738 /* setup RX DMA channel. */ 3739 bwn_dma_setup(dma->rx); 3740 } 3741 3742 static struct bwn_dma_ring * 3743 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3744 int for_tx, int type) 3745 { 3746 struct bwn_dma *dma = &mac->mac_method.dma; 3747 struct bwn_dma_ring *dr; 3748 struct bwn_dmadesc_generic *desc; 3749 struct bwn_dmadesc_meta *mt; 3750 struct bwn_softc *sc = mac->mac_sc; 3751 int error, i; 3752 3753 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3754 if (dr == NULL) 3755 goto out; 3756 dr->dr_numslots = BWN_RXRING_SLOTS; 3757 if (for_tx) 3758 dr->dr_numslots = BWN_TXRING_SLOTS; 3759 3760 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3761 M_DEVBUF, M_NOWAIT | M_ZERO); 3762 if (dr->dr_meta == NULL) 3763 goto fail0; 3764 3765 dr->dr_type = type; 3766 dr->dr_mac = mac; 3767 dr->dr_base = bwn_dma_base(type, controller_index); 3768 dr->dr_index = controller_index; 3769 if (type == BWN_DMA_64BIT) { 3770 dr->getdesc = bwn_dma_64_getdesc; 3771 dr->setdesc = bwn_dma_64_setdesc; 3772 dr->start_transfer = bwn_dma_64_start_transfer; 3773 dr->suspend = bwn_dma_64_suspend; 3774 dr->resume = bwn_dma_64_resume; 3775 dr->get_curslot = bwn_dma_64_get_curslot; 3776 dr->set_curslot = bwn_dma_64_set_curslot; 3777 } else { 3778 dr->getdesc = bwn_dma_32_getdesc; 3779 dr->setdesc = bwn_dma_32_setdesc; 3780 dr->start_transfer = bwn_dma_32_start_transfer; 3781 dr->suspend = bwn_dma_32_suspend; 3782 dr->resume = bwn_dma_32_resume; 3783 dr->get_curslot = bwn_dma_32_get_curslot; 3784 dr->set_curslot = bwn_dma_32_set_curslot; 3785 } 3786 if (for_tx) { 3787 dr->dr_tx = 1; 3788 dr->dr_curslot = -1; 3789 } else { 3790 if (dr->dr_index == 0) { 3791 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3792 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3793 } else 3794 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3795 } 3796 3797 error = bwn_dma_allocringmemory(dr); 3798 if (error) 3799 goto fail2; 3800 3801 if (for_tx) { 3802 /* 3803 * Assumption: BWN_TXRING_SLOTS can be divided by 3804 * BWN_TX_SLOTS_PER_FRAME 3805 */ 3806 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3807 ("%s:%d: fail", __func__, __LINE__)); 3808 3809 dr->dr_txhdr_cache = 3810 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3811 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3812 KASSERT(dr->dr_txhdr_cache != NULL, 3813 ("%s:%d: fail", __func__, __LINE__)); 3814 3815 /* 3816 * Create TX ring DMA stuffs 3817 */ 3818 error = bus_dma_tag_create(dma->parent_dtag, 3819 BWN_ALIGN, 0, 3820 BUS_SPACE_MAXADDR, 3821 BUS_SPACE_MAXADDR, 3822 NULL, NULL, 3823 BWN_HDRSIZE(mac), 3824 1, 3825 BUS_SPACE_MAXSIZE_32BIT, 3826 0, 3827 NULL, NULL, 3828 &dr->dr_txring_dtag); 3829 if (error) { 3830 device_printf(sc->sc_dev, 3831 "can't create TX ring DMA tag: TODO frees\n"); 3832 goto fail1; 3833 } 3834 3835 for (i = 0; i < dr->dr_numslots; i += 2) { 3836 dr->getdesc(dr, i, &desc, &mt); 3837 3838 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3839 mt->mt_m = NULL; 3840 mt->mt_ni = NULL; 3841 mt->mt_islast = 0; 3842 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3843 &mt->mt_dmap); 3844 if (error) { 3845 device_printf(sc->sc_dev, 3846 "can't create RX buf DMA map\n"); 3847 goto fail1; 3848 } 3849 3850 dr->getdesc(dr, i + 1, &desc, &mt); 3851 3852 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3853 mt->mt_m = NULL; 3854 mt->mt_ni = NULL; 3855 mt->mt_islast = 1; 3856 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3857 &mt->mt_dmap); 3858 if (error) { 3859 device_printf(sc->sc_dev, 3860 "can't create RX buf DMA map\n"); 3861 goto fail1; 3862 } 3863 } 3864 } else { 3865 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3866 &dr->dr_spare_dmap); 3867 if (error) { 3868 device_printf(sc->sc_dev, 3869 "can't create RX buf DMA map\n"); 3870 goto out; /* XXX wrong! */ 3871 } 3872 3873 for (i = 0; i < dr->dr_numslots; i++) { 3874 dr->getdesc(dr, i, &desc, &mt); 3875 3876 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3877 &mt->mt_dmap); 3878 if (error) { 3879 device_printf(sc->sc_dev, 3880 "can't create RX buf DMA map\n"); 3881 goto out; /* XXX wrong! */ 3882 } 3883 error = bwn_dma_newbuf(dr, desc, mt, 1); 3884 if (error) { 3885 device_printf(sc->sc_dev, 3886 "failed to allocate RX buf\n"); 3887 goto out; /* XXX wrong! */ 3888 } 3889 } 3890 3891 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3892 BUS_DMASYNC_PREWRITE); 3893 3894 dr->dr_usedslot = dr->dr_numslots; 3895 } 3896 3897 out: 3898 return (dr); 3899 3900 fail2: 3901 free(dr->dr_txhdr_cache, M_DEVBUF); 3902 fail1: 3903 free(dr->dr_meta, M_DEVBUF); 3904 fail0: 3905 free(dr, M_DEVBUF); 3906 return (NULL); 3907 } 3908 3909 static void 3910 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3911 { 3912 3913 if (dr == NULL) 3914 return; 3915 3916 bwn_dma_free_descbufs(*dr); 3917 bwn_dma_free_ringmemory(*dr); 3918 3919 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3920 free((*dr)->dr_meta, M_DEVBUF); 3921 free(*dr, M_DEVBUF); 3922 3923 *dr = NULL; 3924 } 3925 3926 static void 3927 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3928 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3929 { 3930 struct bwn_dmadesc32 *desc; 3931 3932 *meta = &(dr->dr_meta[slot]); 3933 desc = dr->dr_ring_descbase; 3934 desc = &(desc[slot]); 3935 3936 *gdesc = (struct bwn_dmadesc_generic *)desc; 3937 } 3938 3939 static void 3940 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3941 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3942 int start, int end, int irq) 3943 { 3944 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3945 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3946 uint32_t addr, addrext, ctl; 3947 int slot; 3948 3949 slot = (int)(&(desc->dma.dma32) - descbase); 3950 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3951 ("%s:%d: fail", __func__, __LINE__)); 3952 3953 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3954 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3955 addr |= siba_dma_translation(sc->sc_dev); 3956 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3957 if (slot == dr->dr_numslots - 1) 3958 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3959 if (start) 3960 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3961 if (end) 3962 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3963 if (irq) 3964 ctl |= BWN_DMA32_DCTL_IRQ; 3965 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3966 & BWN_DMA32_DCTL_ADDREXT_MASK; 3967 3968 desc->dma.dma32.control = htole32(ctl); 3969 desc->dma.dma32.address = htole32(addr); 3970 } 3971 3972 static void 3973 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3974 { 3975 3976 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3977 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3978 } 3979 3980 static void 3981 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3982 { 3983 3984 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3985 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3986 } 3987 3988 static void 3989 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3990 { 3991 3992 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3993 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3994 } 3995 3996 static int 3997 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3998 { 3999 uint32_t val; 4000 4001 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4002 val &= BWN_DMA32_RXDPTR; 4003 4004 return (val / sizeof(struct bwn_dmadesc32)); 4005 } 4006 4007 static void 4008 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4009 { 4010 4011 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4012 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4013 } 4014 4015 static void 4016 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4017 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4018 { 4019 struct bwn_dmadesc64 *desc; 4020 4021 *meta = &(dr->dr_meta[slot]); 4022 desc = dr->dr_ring_descbase; 4023 desc = &(desc[slot]); 4024 4025 *gdesc = (struct bwn_dmadesc_generic *)desc; 4026 } 4027 4028 static void 4029 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4030 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4031 int start, int end, int irq) 4032 { 4033 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4034 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4035 int slot; 4036 uint32_t ctl0 = 0, ctl1 = 0; 4037 uint32_t addrlo, addrhi; 4038 uint32_t addrext; 4039 4040 slot = (int)(&(desc->dma.dma64) - descbase); 4041 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4042 ("%s:%d: fail", __func__, __LINE__)); 4043 4044 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4045 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4046 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4047 30; 4048 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 4049 if (slot == dr->dr_numslots - 1) 4050 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4051 if (start) 4052 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4053 if (end) 4054 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4055 if (irq) 4056 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4057 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4058 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4059 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4060 4061 desc->dma.dma64.control0 = htole32(ctl0); 4062 desc->dma.dma64.control1 = htole32(ctl1); 4063 desc->dma.dma64.address_low = htole32(addrlo); 4064 desc->dma.dma64.address_high = htole32(addrhi); 4065 } 4066 4067 static void 4068 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4069 { 4070 4071 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4072 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4073 } 4074 4075 static void 4076 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4077 { 4078 4079 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4080 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4081 } 4082 4083 static void 4084 bwn_dma_64_resume(struct bwn_dma_ring *dr) 4085 { 4086 4087 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4088 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4089 } 4090 4091 static int 4092 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4093 { 4094 uint32_t val; 4095 4096 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4097 val &= BWN_DMA64_RXSTATDPTR; 4098 4099 return (val / sizeof(struct bwn_dmadesc64)); 4100 } 4101 4102 static void 4103 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4104 { 4105 4106 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4107 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4108 } 4109 4110 static int 4111 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4112 { 4113 struct bwn_mac *mac = dr->dr_mac; 4114 struct bwn_dma *dma = &mac->mac_method.dma; 4115 struct bwn_softc *sc = mac->mac_sc; 4116 int error; 4117 4118 error = bus_dma_tag_create(dma->parent_dtag, 4119 BWN_ALIGN, 0, 4120 BUS_SPACE_MAXADDR, 4121 BUS_SPACE_MAXADDR, 4122 NULL, NULL, 4123 BWN_DMA_RINGMEMSIZE, 4124 1, 4125 BUS_SPACE_MAXSIZE_32BIT, 4126 0, 4127 NULL, NULL, 4128 &dr->dr_ring_dtag); 4129 if (error) { 4130 device_printf(sc->sc_dev, 4131 "can't create TX ring DMA tag: TODO frees\n"); 4132 return (-1); 4133 } 4134 4135 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4136 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4137 &dr->dr_ring_dmap); 4138 if (error) { 4139 device_printf(sc->sc_dev, 4140 "can't allocate DMA mem: TODO frees\n"); 4141 return (-1); 4142 } 4143 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4144 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4145 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4146 if (error) { 4147 device_printf(sc->sc_dev, 4148 "can't load DMA mem: TODO free\n"); 4149 return (-1); 4150 } 4151 4152 return (0); 4153 } 4154 4155 static void 4156 bwn_dma_setup(struct bwn_dma_ring *dr) 4157 { 4158 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4159 uint64_t ring64; 4160 uint32_t addrext, ring32, value; 4161 uint32_t trans = siba_dma_translation(sc->sc_dev); 4162 4163 if (dr->dr_tx) { 4164 dr->dr_curslot = -1; 4165 4166 if (dr->dr_type == BWN_DMA_64BIT) { 4167 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4168 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4169 >> 30; 4170 value = BWN_DMA64_TXENABLE; 4171 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4172 & BWN_DMA64_TXADDREXT_MASK; 4173 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4174 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4175 (ring64 & 0xffffffff)); 4176 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4177 ((ring64 >> 32) & 4178 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4179 } else { 4180 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4181 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4182 value = BWN_DMA32_TXENABLE; 4183 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4184 & BWN_DMA32_TXADDREXT_MASK; 4185 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4186 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4187 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4188 } 4189 return; 4190 } 4191 4192 /* 4193 * set for RX 4194 */ 4195 dr->dr_usedslot = dr->dr_numslots; 4196 4197 if (dr->dr_type == BWN_DMA_64BIT) { 4198 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4199 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4200 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4201 value |= BWN_DMA64_RXENABLE; 4202 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4203 & BWN_DMA64_RXADDREXT_MASK; 4204 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4205 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4206 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4207 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4208 | (trans << 1)); 4209 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4210 sizeof(struct bwn_dmadesc64)); 4211 } else { 4212 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4213 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4214 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4215 value |= BWN_DMA32_RXENABLE; 4216 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4217 & BWN_DMA32_RXADDREXT_MASK; 4218 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4219 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4220 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4221 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4222 sizeof(struct bwn_dmadesc32)); 4223 } 4224 } 4225 4226 static void 4227 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4228 { 4229 4230 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4231 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4232 dr->dr_ring_dmap); 4233 } 4234 4235 static void 4236 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4237 { 4238 4239 if (dr->dr_tx) { 4240 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4241 if (dr->dr_type == BWN_DMA_64BIT) { 4242 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4243 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4244 } else 4245 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4246 } else { 4247 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4248 if (dr->dr_type == BWN_DMA_64BIT) { 4249 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4250 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4251 } else 4252 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4253 } 4254 } 4255 4256 static void 4257 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4258 { 4259 struct bwn_dmadesc_generic *desc; 4260 struct bwn_dmadesc_meta *meta; 4261 struct bwn_mac *mac = dr->dr_mac; 4262 struct bwn_dma *dma = &mac->mac_method.dma; 4263 struct bwn_softc *sc = mac->mac_sc; 4264 int i; 4265 4266 if (!dr->dr_usedslot) 4267 return; 4268 for (i = 0; i < dr->dr_numslots; i++) { 4269 dr->getdesc(dr, i, &desc, &meta); 4270 4271 if (meta->mt_m == NULL) { 4272 if (!dr->dr_tx) 4273 device_printf(sc->sc_dev, "%s: not TX?\n", 4274 __func__); 4275 continue; 4276 } 4277 if (dr->dr_tx) { 4278 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4279 bus_dmamap_unload(dr->dr_txring_dtag, 4280 meta->mt_dmap); 4281 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4282 bus_dmamap_unload(dma->txbuf_dtag, 4283 meta->mt_dmap); 4284 } else 4285 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4286 bwn_dma_free_descbuf(dr, meta); 4287 } 4288 } 4289 4290 static int 4291 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4292 int type) 4293 { 4294 struct bwn_softc *sc = mac->mac_sc; 4295 uint32_t value; 4296 int i; 4297 uint16_t offset; 4298 4299 for (i = 0; i < 10; i++) { 4300 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4301 BWN_DMA32_TXSTATUS; 4302 value = BWN_READ_4(mac, base + offset); 4303 if (type == BWN_DMA_64BIT) { 4304 value &= BWN_DMA64_TXSTAT; 4305 if (value == BWN_DMA64_TXSTAT_DISABLED || 4306 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4307 value == BWN_DMA64_TXSTAT_STOPPED) 4308 break; 4309 } else { 4310 value &= BWN_DMA32_TXSTATE; 4311 if (value == BWN_DMA32_TXSTAT_DISABLED || 4312 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4313 value == BWN_DMA32_TXSTAT_STOPPED) 4314 break; 4315 } 4316 DELAY(1000); 4317 } 4318 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4319 BWN_WRITE_4(mac, base + offset, 0); 4320 for (i = 0; i < 10; i++) { 4321 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4322 BWN_DMA32_TXSTATUS; 4323 value = BWN_READ_4(mac, base + offset); 4324 if (type == BWN_DMA_64BIT) { 4325 value &= BWN_DMA64_TXSTAT; 4326 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4327 i = -1; 4328 break; 4329 } 4330 } else { 4331 value &= BWN_DMA32_TXSTATE; 4332 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4333 i = -1; 4334 break; 4335 } 4336 } 4337 DELAY(1000); 4338 } 4339 if (i != -1) { 4340 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4341 return (ENODEV); 4342 } 4343 DELAY(1000); 4344 4345 return (0); 4346 } 4347 4348 static int 4349 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4350 int type) 4351 { 4352 struct bwn_softc *sc = mac->mac_sc; 4353 uint32_t value; 4354 int i; 4355 uint16_t offset; 4356 4357 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4358 BWN_WRITE_4(mac, base + offset, 0); 4359 for (i = 0; i < 10; i++) { 4360 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4361 BWN_DMA32_RXSTATUS; 4362 value = BWN_READ_4(mac, base + offset); 4363 if (type == BWN_DMA_64BIT) { 4364 value &= BWN_DMA64_RXSTAT; 4365 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4366 i = -1; 4367 break; 4368 } 4369 } else { 4370 value &= BWN_DMA32_RXSTATE; 4371 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4372 i = -1; 4373 break; 4374 } 4375 } 4376 DELAY(1000); 4377 } 4378 if (i != -1) { 4379 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4380 return (ENODEV); 4381 } 4382 4383 return (0); 4384 } 4385 4386 static void 4387 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4388 struct bwn_dmadesc_meta *meta) 4389 { 4390 4391 if (meta->mt_m != NULL) { 4392 m_freem(meta->mt_m); 4393 meta->mt_m = NULL; 4394 } 4395 if (meta->mt_ni != NULL) { 4396 ieee80211_free_node(meta->mt_ni); 4397 meta->mt_ni = NULL; 4398 } 4399 } 4400 4401 static void 4402 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4403 { 4404 struct bwn_rxhdr4 *rxhdr; 4405 unsigned char *frame; 4406 4407 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4408 rxhdr->frame_len = 0; 4409 4410 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4411 sizeof(struct bwn_plcp6) + 2, 4412 ("%s:%d: fail", __func__, __LINE__)); 4413 frame = mtod(m, char *) + dr->dr_frameoffset; 4414 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4415 } 4416 4417 static uint8_t 4418 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4419 { 4420 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4421 4422 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4423 == 0xff); 4424 } 4425 4426 static void 4427 bwn_wme_init(struct bwn_mac *mac) 4428 { 4429 4430 bwn_wme_load(mac); 4431 4432 /* enable WME support. */ 4433 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4434 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4435 BWN_IFSCTL_USE_EDCF); 4436 } 4437 4438 static void 4439 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4440 { 4441 struct bwn_softc *sc = mac->mac_sc; 4442 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4443 uint16_t delay; /* microsec */ 4444 4445 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4446 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4447 delay = 500; 4448 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4449 delay = max(delay, (uint16_t)2400); 4450 4451 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4452 } 4453 4454 static void 4455 bwn_bt_enable(struct bwn_mac *mac) 4456 { 4457 struct bwn_softc *sc = mac->mac_sc; 4458 uint64_t hf; 4459 4460 if (bwn_bluetooth == 0) 4461 return; 4462 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4463 return; 4464 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4465 return; 4466 4467 hf = bwn_hf_read(mac); 4468 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4469 hf |= BWN_HF_BT_COEXISTALT; 4470 else 4471 hf |= BWN_HF_BT_COEXIST; 4472 bwn_hf_write(mac, hf); 4473 } 4474 4475 static void 4476 bwn_set_macaddr(struct bwn_mac *mac) 4477 { 4478 4479 bwn_mac_write_bssid(mac); 4480 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4481 } 4482 4483 static void 4484 bwn_clear_keys(struct bwn_mac *mac) 4485 { 4486 int i; 4487 4488 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4489 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4490 ("%s:%d: fail", __func__, __LINE__)); 4491 4492 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4493 NULL, BWN_SEC_KEYSIZE, NULL); 4494 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4495 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4496 NULL, BWN_SEC_KEYSIZE, NULL); 4497 } 4498 mac->mac_key[i].keyconf = NULL; 4499 } 4500 } 4501 4502 static void 4503 bwn_crypt_init(struct bwn_mac *mac) 4504 { 4505 struct bwn_softc *sc = mac->mac_sc; 4506 4507 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4508 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4509 ("%s:%d: fail", __func__, __LINE__)); 4510 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4511 mac->mac_ktp *= 2; 4512 if (siba_get_revid(sc->sc_dev) >= 5) 4513 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4514 bwn_clear_keys(mac); 4515 } 4516 4517 static void 4518 bwn_chip_exit(struct bwn_mac *mac) 4519 { 4520 struct bwn_softc *sc = mac->mac_sc; 4521 4522 bwn_phy_exit(mac); 4523 siba_gpio_set(sc->sc_dev, 0); 4524 } 4525 4526 static int 4527 bwn_fw_fillinfo(struct bwn_mac *mac) 4528 { 4529 int error; 4530 4531 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4532 if (error == 0) 4533 return (0); 4534 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4535 if (error == 0) 4536 return (0); 4537 return (error); 4538 } 4539 4540 static int 4541 bwn_gpio_init(struct bwn_mac *mac) 4542 { 4543 struct bwn_softc *sc = mac->mac_sc; 4544 uint32_t mask = 0x1f, set = 0xf, value; 4545 4546 BWN_WRITE_4(mac, BWN_MACCTL, 4547 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4548 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4549 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4550 4551 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4552 mask |= 0x0060; 4553 set |= 0x0060; 4554 } 4555 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4556 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4557 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4558 mask |= 0x0200; 4559 set |= 0x0200; 4560 } 4561 if (siba_get_revid(sc->sc_dev) >= 2) 4562 mask |= 0x0010; 4563 4564 value = siba_gpio_get(sc->sc_dev); 4565 if (value == -1) 4566 return (0); 4567 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4568 4569 return (0); 4570 } 4571 4572 static int 4573 bwn_fw_loadinitvals(struct bwn_mac *mac) 4574 { 4575 #define GETFWOFFSET(fwp, offset) \ 4576 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4577 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4578 const struct bwn_fwhdr *hdr; 4579 struct bwn_fw *fw = &mac->mac_fw; 4580 int error; 4581 4582 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4583 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4584 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4585 if (error) 4586 return (error); 4587 if (fw->initvals_band.fw) { 4588 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4589 error = bwn_fwinitvals_write(mac, 4590 GETFWOFFSET(fw->initvals_band, hdr_len), 4591 be32toh(hdr->size), 4592 fw->initvals_band.fw->datasize - hdr_len); 4593 } 4594 return (error); 4595 #undef GETFWOFFSET 4596 } 4597 4598 static int 4599 bwn_phy_init(struct bwn_mac *mac) 4600 { 4601 struct bwn_softc *sc = mac->mac_sc; 4602 int error; 4603 4604 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4605 mac->mac_phy.rf_onoff(mac, 1); 4606 error = mac->mac_phy.init(mac); 4607 if (error) { 4608 device_printf(sc->sc_dev, "PHY init failed\n"); 4609 goto fail0; 4610 } 4611 error = bwn_switch_channel(mac, 4612 mac->mac_phy.get_default_chan(mac)); 4613 if (error) { 4614 device_printf(sc->sc_dev, 4615 "failed to switch default channel\n"); 4616 goto fail1; 4617 } 4618 return (0); 4619 fail1: 4620 if (mac->mac_phy.exit) 4621 mac->mac_phy.exit(mac); 4622 fail0: 4623 mac->mac_phy.rf_onoff(mac, 0); 4624 4625 return (error); 4626 } 4627 4628 static void 4629 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4630 { 4631 uint16_t ant; 4632 uint16_t tmp; 4633 4634 ant = bwn_ant2phy(antenna); 4635 4636 /* For ACK/CTS */ 4637 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4638 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4639 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4640 /* For Probe Resposes */ 4641 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4642 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4643 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4644 } 4645 4646 static void 4647 bwn_set_opmode(struct bwn_mac *mac) 4648 { 4649 struct bwn_softc *sc = mac->mac_sc; 4650 struct ifnet *ifp = sc->sc_ifp; 4651 struct ieee80211com *ic = ifp->if_l2com; 4652 uint32_t ctl; 4653 uint16_t cfp_pretbtt; 4654 4655 ctl = BWN_READ_4(mac, BWN_MACCTL); 4656 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4657 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4658 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4659 ctl |= BWN_MACCTL_STA; 4660 4661 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4662 ic->ic_opmode == IEEE80211_M_MBSS) 4663 ctl |= BWN_MACCTL_HOSTAP; 4664 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4665 ctl &= ~BWN_MACCTL_STA; 4666 ctl |= sc->sc_filters; 4667 4668 if (siba_get_revid(sc->sc_dev) <= 4) 4669 ctl |= BWN_MACCTL_PROMISC; 4670 4671 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4672 4673 cfp_pretbtt = 2; 4674 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4675 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4676 siba_get_chiprev(sc->sc_dev) == 3) 4677 cfp_pretbtt = 100; 4678 else 4679 cfp_pretbtt = 50; 4680 } 4681 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4682 } 4683 4684 static int 4685 bwn_dma_gettype(struct bwn_mac *mac) 4686 { 4687 uint32_t tmp; 4688 uint16_t base; 4689 4690 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4691 if (tmp & SIBA_TGSHIGH_DMA64) 4692 return (BWN_DMA_64BIT); 4693 base = bwn_dma_base(0, 0); 4694 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4695 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4696 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4697 return (BWN_DMA_32BIT); 4698 4699 return (BWN_DMA_30BIT); 4700 } 4701 4702 static void 4703 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4704 { 4705 if (!error) { 4706 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4707 *((bus_addr_t *)arg) = seg->ds_addr; 4708 } 4709 } 4710 4711 static void 4712 bwn_phy_g_init_sub(struct bwn_mac *mac) 4713 { 4714 struct bwn_phy *phy = &mac->mac_phy; 4715 struct bwn_phy_g *pg = &phy->phy_g; 4716 struct bwn_softc *sc = mac->mac_sc; 4717 uint16_t i, tmp; 4718 4719 if (phy->rev == 1) 4720 bwn_phy_init_b5(mac); 4721 else 4722 bwn_phy_init_b6(mac); 4723 4724 if (phy->rev >= 2 || phy->gmode) 4725 bwn_phy_init_a(mac); 4726 4727 if (phy->rev >= 2) { 4728 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4729 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4730 } 4731 if (phy->rev == 2) { 4732 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4733 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4734 } 4735 if (phy->rev > 5) { 4736 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4737 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4738 } 4739 if (phy->gmode || phy->rev >= 2) { 4740 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4741 tmp &= BWN_PHYVER_VERSION; 4742 if (tmp == 3 || tmp == 5) { 4743 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4744 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4745 } 4746 if (tmp == 5) { 4747 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4748 0x1f00); 4749 } 4750 } 4751 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4752 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4753 if (phy->rf_rev == 8) { 4754 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4755 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4756 } 4757 if (BWN_HAS_LOOPBACK(phy)) 4758 bwn_loopback_calcgain(mac); 4759 4760 if (phy->rf_rev != 8) { 4761 if (pg->pg_initval == 0xffff) 4762 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4763 else 4764 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4765 } 4766 bwn_lo_g_init(mac); 4767 if (BWN_HAS_TXMAG(phy)) { 4768 BWN_RF_WRITE(mac, 0x52, 4769 (BWN_RF_READ(mac, 0x52) & 0xff00) 4770 | pg->pg_loctl.tx_bias | 4771 pg->pg_loctl.tx_magn); 4772 } else { 4773 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4774 } 4775 if (phy->rev >= 6) { 4776 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4777 (pg->pg_loctl.tx_bias << 12)); 4778 } 4779 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4780 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4781 else 4782 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4783 if (phy->rev < 2) 4784 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4785 else 4786 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4787 if (phy->gmode || phy->rev >= 2) { 4788 bwn_lo_g_adjust(mac); 4789 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4790 } 4791 4792 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4793 for (i = 0; i < 64; i++) { 4794 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4795 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4796 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4797 -32), 31)); 4798 } 4799 bwn_nrssi_threshold(mac); 4800 } else if (phy->gmode || phy->rev >= 2) { 4801 if (pg->pg_nrssi[0] == -1000) { 4802 KASSERT(pg->pg_nrssi[1] == -1000, 4803 ("%s:%d: fail", __func__, __LINE__)); 4804 bwn_nrssi_slope_11g(mac); 4805 } else 4806 bwn_nrssi_threshold(mac); 4807 } 4808 if (phy->rf_rev == 8) 4809 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4810 bwn_phy_hwpctl_init(mac); 4811 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4812 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4813 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4814 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4815 } 4816 } 4817 4818 static uint8_t 4819 bwn_has_hwpctl(struct bwn_mac *mac) 4820 { 4821 4822 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4823 return (0); 4824 return (mac->mac_phy.use_hwpctl(mac)); 4825 } 4826 4827 static void 4828 bwn_phy_init_b5(struct bwn_mac *mac) 4829 { 4830 struct bwn_phy *phy = &mac->mac_phy; 4831 struct bwn_phy_g *pg = &phy->phy_g; 4832 struct bwn_softc *sc = mac->mac_sc; 4833 uint16_t offset, value; 4834 uint8_t old_channel; 4835 4836 if (phy->analog == 1) 4837 BWN_RF_SET(mac, 0x007a, 0x0050); 4838 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4839 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4840 value = 0x2120; 4841 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4842 BWN_PHY_WRITE(mac, offset, value); 4843 value += 0x202; 4844 } 4845 } 4846 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4847 if (phy->rf_ver == 0x2050) 4848 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4849 4850 if (phy->gmode || phy->rev >= 2) { 4851 if (phy->rf_ver == 0x2050) { 4852 BWN_RF_SET(mac, 0x007a, 0x0020); 4853 BWN_RF_SET(mac, 0x0051, 0x0004); 4854 } 4855 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4856 4857 BWN_PHY_SET(mac, 0x0802, 0x0100); 4858 BWN_PHY_SET(mac, 0x042b, 0x2000); 4859 4860 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4861 4862 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4863 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4864 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4865 } 4866 4867 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4868 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4869 4870 if (phy->analog == 1) { 4871 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4872 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4873 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4874 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4875 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4876 } else 4877 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4878 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4879 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4880 4881 if (phy->analog == 1) 4882 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4883 else 4884 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4885 4886 if (phy->analog == 0) 4887 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4888 4889 old_channel = phy->chan; 4890 bwn_phy_g_switch_chan(mac, 7, 0); 4891 4892 if (phy->rf_ver != 0x2050) { 4893 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4894 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4895 } 4896 4897 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4898 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4899 4900 if (phy->rf_ver == 0x2050) { 4901 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4902 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4903 } 4904 4905 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4906 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4907 BWN_RF_SET(mac, 0x007a, 0x0007); 4908 4909 bwn_phy_g_switch_chan(mac, old_channel, 0); 4910 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4911 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4912 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4913 4914 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4915 pg->pg_txctl); 4916 4917 if (phy->rf_ver == 0x2050) 4918 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4919 4920 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4921 } 4922 4923 static void 4924 bwn_loopback_calcgain(struct bwn_mac *mac) 4925 { 4926 struct bwn_phy *phy = &mac->mac_phy; 4927 struct bwn_phy_g *pg = &phy->phy_g; 4928 struct bwn_softc *sc = mac->mac_sc; 4929 uint16_t backup_phy[16] = { 0 }; 4930 uint16_t backup_radio[3]; 4931 uint16_t backup_bband; 4932 uint16_t i, j, loop_i_max; 4933 uint16_t trsw_rx; 4934 uint16_t loop1_outer_done, loop1_inner_done; 4935 4936 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4937 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4938 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4939 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4940 if (phy->rev != 1) { 4941 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4942 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4943 } 4944 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4945 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4946 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4947 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4948 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4949 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4950 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4951 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4952 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4953 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4954 backup_bband = pg->pg_bbatt.att; 4955 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4956 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4957 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4958 4959 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4960 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4961 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4962 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4963 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4964 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4965 if (phy->rev != 1) { 4966 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4967 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4968 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4969 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4970 } 4971 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4972 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4973 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4974 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4975 4976 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4977 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4978 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4979 4980 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4981 if (phy->rev != 1) { 4982 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4983 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4984 } 4985 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4986 4987 if (phy->rf_rev == 8) 4988 BWN_RF_WRITE(mac, 0x43, 0x000f); 4989 else { 4990 BWN_RF_WRITE(mac, 0x52, 0); 4991 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4992 } 4993 bwn_phy_g_set_bbatt(mac, 11); 4994 4995 if (phy->rev >= 3) 4996 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4997 else 4998 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4999 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5000 5001 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5002 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5003 5004 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5005 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5006 5007 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 5008 if (phy->rev >= 7) { 5009 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5010 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5011 } 5012 } 5013 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5014 5015 j = 0; 5016 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5017 for (i = 0; i < loop_i_max; i++) { 5018 for (j = 0; j < 16; j++) { 5019 BWN_RF_WRITE(mac, 0x43, i); 5020 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5021 (j << 8)); 5022 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5023 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5024 DELAY(20); 5025 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5026 goto done0; 5027 } 5028 } 5029 done0: 5030 loop1_outer_done = i; 5031 loop1_inner_done = j; 5032 if (j >= 8) { 5033 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5034 trsw_rx = 0x1b; 5035 for (j = j - 8; j < 16; j++) { 5036 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5037 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5038 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5039 DELAY(20); 5040 trsw_rx -= 3; 5041 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5042 goto done1; 5043 } 5044 } else 5045 trsw_rx = 0x18; 5046 done1: 5047 5048 if (phy->rev != 1) { 5049 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5050 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5051 } 5052 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5053 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5054 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5055 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5057 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5058 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5059 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5060 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5061 5062 bwn_phy_g_set_bbatt(mac, backup_bband); 5063 5064 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5065 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5066 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5067 5068 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5069 DELAY(10); 5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5071 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5072 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5073 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5074 5075 pg->pg_max_lb_gain = 5076 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5077 pg->pg_trsw_rx_gain = trsw_rx * 2; 5078 } 5079 5080 static uint16_t 5081 bwn_rf_init_bcm2050(struct bwn_mac *mac) 5082 { 5083 struct bwn_phy *phy = &mac->mac_phy; 5084 uint32_t tmp1 = 0, tmp2 = 0; 5085 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5086 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5087 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5088 static const uint8_t rcc_table[] = { 5089 0x02, 0x03, 0x01, 0x0f, 5090 0x06, 0x07, 0x05, 0x0f, 5091 0x0a, 0x0b, 0x09, 0x0f, 5092 0x0e, 0x0f, 0x0d, 0x0f, 5093 }; 5094 5095 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5096 rfoverval = rfover = cck3 = 0; 5097 radio0 = BWN_RF_READ(mac, 0x43); 5098 radio1 = BWN_RF_READ(mac, 0x51); 5099 radio2 = BWN_RF_READ(mac, 0x52); 5100 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5101 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5102 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5103 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5104 5105 if (phy->type == BWN_PHYTYPE_B) { 5106 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5107 reg0 = BWN_READ_2(mac, 0x3ec); 5108 5109 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5110 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5111 } else if (phy->gmode || phy->rev >= 2) { 5112 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5113 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5114 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5115 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5116 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5117 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5118 5119 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5120 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5121 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5122 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5123 if (BWN_HAS_LOOPBACK(phy)) { 5124 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5125 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5126 if (phy->rev >= 3) 5127 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5128 else 5129 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5130 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5131 } 5132 5133 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5134 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5135 BWN_LPD(0, 1, 1))); 5136 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5137 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5138 } 5139 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5140 5141 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5142 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5143 reg1 = BWN_READ_2(mac, 0x3e6); 5144 reg2 = BWN_READ_2(mac, 0x3f4); 5145 5146 if (phy->analog == 0) 5147 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5148 else { 5149 if (phy->analog >= 2) 5150 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5151 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5152 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5153 } 5154 5155 reg = BWN_RF_READ(mac, 0x60); 5156 index = (reg & 0x001e) >> 1; 5157 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5158 5159 if (phy->type == BWN_PHYTYPE_B) 5160 BWN_RF_WRITE(mac, 0x78, 0x26); 5161 if (phy->gmode || phy->rev >= 2) { 5162 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5163 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5164 BWN_LPD(0, 1, 1))); 5165 } 5166 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5167 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5168 if (phy->gmode || phy->rev >= 2) { 5169 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5170 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5171 BWN_LPD(0, 0, 1))); 5172 } 5173 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5174 BWN_RF_SET(mac, 0x51, 0x0004); 5175 if (phy->rf_rev == 8) 5176 BWN_RF_WRITE(mac, 0x43, 0x1f); 5177 else { 5178 BWN_RF_WRITE(mac, 0x52, 0); 5179 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5180 } 5181 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5182 5183 for (i = 0; i < 16; i++) { 5184 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5185 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5186 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5187 if (phy->gmode || phy->rev >= 2) { 5188 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5189 bwn_rf_2050_rfoverval(mac, 5190 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5191 } 5192 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5193 DELAY(10); 5194 if (phy->gmode || phy->rev >= 2) { 5195 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5196 bwn_rf_2050_rfoverval(mac, 5197 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5198 } 5199 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5200 DELAY(10); 5201 if (phy->gmode || phy->rev >= 2) { 5202 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5203 bwn_rf_2050_rfoverval(mac, 5204 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5205 } 5206 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5207 DELAY(20); 5208 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5209 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5210 if (phy->gmode || phy->rev >= 2) { 5211 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5212 bwn_rf_2050_rfoverval(mac, 5213 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5214 } 5215 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5216 } 5217 DELAY(10); 5218 5219 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5220 tmp1++; 5221 tmp1 >>= 9; 5222 5223 for (i = 0; i < 16; i++) { 5224 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5225 BWN_RF_WRITE(mac, 0x78, radio78); 5226 DELAY(10); 5227 for (j = 0; j < 16; j++) { 5228 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5229 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5231 if (phy->gmode || phy->rev >= 2) { 5232 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5233 bwn_rf_2050_rfoverval(mac, 5234 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5235 } 5236 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5237 DELAY(10); 5238 if (phy->gmode || phy->rev >= 2) { 5239 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5240 bwn_rf_2050_rfoverval(mac, 5241 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5242 } 5243 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5244 DELAY(10); 5245 if (phy->gmode || phy->rev >= 2) { 5246 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5247 bwn_rf_2050_rfoverval(mac, 5248 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5249 } 5250 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5251 DELAY(10); 5252 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5253 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5254 if (phy->gmode || phy->rev >= 2) { 5255 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5256 bwn_rf_2050_rfoverval(mac, 5257 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5258 } 5259 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5260 } 5261 tmp2++; 5262 tmp2 >>= 8; 5263 if (tmp1 < tmp2) 5264 break; 5265 } 5266 5267 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5268 BWN_RF_WRITE(mac, 0x51, radio1); 5269 BWN_RF_WRITE(mac, 0x52, radio2); 5270 BWN_RF_WRITE(mac, 0x43, radio0); 5271 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5272 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5273 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5274 BWN_WRITE_2(mac, 0x3e6, reg1); 5275 if (phy->analog != 0) 5276 BWN_WRITE_2(mac, 0x3f4, reg2); 5277 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5278 bwn_spu_workaround(mac, phy->chan); 5279 if (phy->type == BWN_PHYTYPE_B) { 5280 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5281 BWN_WRITE_2(mac, 0x3ec, reg0); 5282 } else if (phy->gmode) { 5283 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5284 BWN_READ_2(mac, BWN_PHY_RADIO) 5285 & 0x7fff); 5286 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5287 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5288 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5289 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5290 analogoverval); 5291 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5292 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5293 if (BWN_HAS_LOOPBACK(phy)) { 5294 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5295 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5296 } 5297 } 5298 5299 return ((i > 15) ? radio78 : rcc); 5300 } 5301 5302 static void 5303 bwn_phy_init_b6(struct bwn_mac *mac) 5304 { 5305 struct bwn_phy *phy = &mac->mac_phy; 5306 struct bwn_phy_g *pg = &phy->phy_g; 5307 struct bwn_softc *sc = mac->mac_sc; 5308 uint16_t offset, val; 5309 uint8_t old_channel; 5310 5311 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5312 ("%s:%d: fail", __func__, __LINE__)); 5313 5314 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5315 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5316 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5317 BWN_RF_WRITE(mac, 0x51, 0x37); 5318 BWN_RF_WRITE(mac, 0x52, 0x70); 5319 BWN_RF_WRITE(mac, 0x53, 0xb3); 5320 BWN_RF_WRITE(mac, 0x54, 0x9b); 5321 BWN_RF_WRITE(mac, 0x5a, 0x88); 5322 BWN_RF_WRITE(mac, 0x5b, 0x88); 5323 BWN_RF_WRITE(mac, 0x5d, 0x88); 5324 BWN_RF_WRITE(mac, 0x5e, 0x88); 5325 BWN_RF_WRITE(mac, 0x7d, 0x88); 5326 bwn_hf_write(mac, 5327 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5328 } 5329 if (phy->rf_rev == 8) { 5330 BWN_RF_WRITE(mac, 0x51, 0); 5331 BWN_RF_WRITE(mac, 0x52, 0x40); 5332 BWN_RF_WRITE(mac, 0x53, 0xb7); 5333 BWN_RF_WRITE(mac, 0x54, 0x98); 5334 BWN_RF_WRITE(mac, 0x5a, 0x88); 5335 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5336 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5337 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5338 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5339 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5340 } else { 5341 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5342 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5343 } 5344 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5345 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5346 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5347 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5348 } 5349 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5350 BWN_PHY_WRITE(mac, offset, val); 5351 val -= 0x0202; 5352 } 5353 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5354 BWN_PHY_WRITE(mac, offset, val); 5355 val -= 0x0202; 5356 } 5357 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5358 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5359 val += 0x0202; 5360 } 5361 if (phy->type == BWN_PHYTYPE_G) { 5362 BWN_RF_SET(mac, 0x007a, 0x0020); 5363 BWN_RF_SET(mac, 0x0051, 0x0004); 5364 BWN_PHY_SET(mac, 0x0802, 0x0100); 5365 BWN_PHY_SET(mac, 0x042b, 0x2000); 5366 BWN_PHY_WRITE(mac, 0x5b, 0); 5367 BWN_PHY_WRITE(mac, 0x5c, 0); 5368 } 5369 5370 old_channel = phy->chan; 5371 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5372 5373 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5374 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5375 DELAY(40); 5376 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5377 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5378 BWN_RF_WRITE(mac, 0x50, 0x20); 5379 } 5380 if (phy->rf_rev <= 2) { 5381 BWN_RF_WRITE(mac, 0x7c, 0x20); 5382 BWN_RF_WRITE(mac, 0x5a, 0x70); 5383 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5384 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5385 } 5386 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5387 5388 bwn_phy_g_switch_chan(mac, old_channel, 0); 5389 5390 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5391 if (phy->rf_rev >= 6) 5392 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5393 else 5394 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5395 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5396 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5397 pg->pg_txctl); 5398 if (phy->rf_rev <= 5) 5399 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5400 if (phy->rf_rev <= 2) 5401 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5402 5403 if (phy->analog == 4) { 5404 BWN_WRITE_2(mac, 0x3e4, 9); 5405 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5406 } else 5407 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5408 if (phy->type == BWN_PHYTYPE_B) 5409 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5410 else if (phy->type == BWN_PHYTYPE_G) 5411 BWN_WRITE_2(mac, 0x03e6, 0x0); 5412 } 5413 5414 static void 5415 bwn_phy_init_a(struct bwn_mac *mac) 5416 { 5417 struct bwn_phy *phy = &mac->mac_phy; 5418 struct bwn_softc *sc = mac->mac_sc; 5419 5420 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5421 ("%s:%d: fail", __func__, __LINE__)); 5422 5423 if (phy->rev >= 6) { 5424 if (phy->type == BWN_PHYTYPE_A) 5425 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5426 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5427 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5428 else 5429 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5430 } 5431 5432 bwn_wa_init(mac); 5433 5434 if (phy->type == BWN_PHYTYPE_G && 5435 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5436 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5437 } 5438 5439 static void 5440 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5441 { 5442 int i; 5443 5444 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5445 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5446 } 5447 5448 static void 5449 bwn_wa_agc(struct bwn_mac *mac) 5450 { 5451 struct bwn_phy *phy = &mac->mac_phy; 5452 5453 if (phy->rev == 1) { 5454 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5455 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5456 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5462 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5463 } else { 5464 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5467 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5468 } 5469 5470 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5471 0x5700); 5472 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5473 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5474 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5475 BWN_RF_SET(mac, 0x7a, 0x0008); 5476 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5477 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5478 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5479 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5480 if (phy->rev == 1) 5481 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5482 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5483 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5484 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5491 if (phy->rev == 1) { 5492 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5494 } else { 5495 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5496 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5497 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5498 if (phy->rev >= 6) { 5499 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5500 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5501 (uint16_t)~0xf000, 0x3000); 5502 } 5503 } 5504 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5505 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5506 if (phy->rev == 1) { 5507 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5508 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5509 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5510 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5511 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5512 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5513 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5515 } else { 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5520 } 5521 if (phy->rev >= 6) { 5522 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5523 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5524 } 5525 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5526 } 5527 5528 static void 5529 bwn_wa_grev1(struct bwn_mac *mac) 5530 { 5531 struct bwn_phy *phy = &mac->mac_phy; 5532 int i; 5533 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5534 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5535 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5536 5537 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5538 5539 /* init CRSTHRES and ANTDWELL */ 5540 if (phy->rev == 1) { 5541 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5542 } else if (phy->rev == 2) { 5543 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5544 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5545 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5546 } else { 5547 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5548 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5549 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5550 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5551 } 5552 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5553 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5554 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5555 5556 /* XXX support PHY-A??? */ 5557 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5559 bwn_tab_finefreqg[i]); 5560 5561 /* XXX support PHY-A??? */ 5562 if (phy->rev == 1) 5563 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5564 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5565 bwn_tab_noise_g1[i]); 5566 else 5567 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5568 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5569 bwn_tab_noise_g2[i]); 5570 5571 5572 for (i = 0; i < N(bwn_tab_rotor); i++) 5573 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5574 bwn_tab_rotor[i]); 5575 5576 /* XXX support PHY-A??? */ 5577 if (phy->rev >= 6) { 5578 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5579 BWN_PHY_ENCORE_EN) 5580 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5581 else 5582 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5583 } else 5584 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5585 5586 for (i = 0; i < N(bwn_tab_retard); i++) 5587 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5588 bwn_tab_retard[i]); 5589 5590 if (phy->rev == 1) { 5591 for (i = 0; i < 16; i++) 5592 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5593 i, 0x0020); 5594 } else { 5595 for (i = 0; i < 32; i++) 5596 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5597 } 5598 5599 bwn_wa_agc(mac); 5600 } 5601 5602 static void 5603 bwn_wa_grev26789(struct bwn_mac *mac) 5604 { 5605 struct bwn_phy *phy = &mac->mac_phy; 5606 int i; 5607 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5608 uint16_t ofdmrev; 5609 5610 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5611 5612 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5613 5614 /* init CRSTHRES and ANTDWELL */ 5615 if (phy->rev == 1) 5616 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5617 else if (phy->rev == 2) { 5618 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5619 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5620 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5621 } else { 5622 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5623 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5624 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5625 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5626 } 5627 5628 for (i = 0; i < 64; i++) 5629 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5630 5631 /* XXX support PHY-A??? */ 5632 if (phy->rev == 1) 5633 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5634 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5635 bwn_tab_noise_g1[i]); 5636 else 5637 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5639 bwn_tab_noise_g2[i]); 5640 5641 /* XXX support PHY-A??? */ 5642 if (phy->rev >= 6) { 5643 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5644 BWN_PHY_ENCORE_EN) 5645 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5646 else 5647 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5648 } else 5649 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5650 5651 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5652 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5653 bwn_tab_sigmasqr2[i]); 5654 5655 if (phy->rev == 1) { 5656 for (i = 0; i < 16; i++) 5657 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5658 0x0020); 5659 } else { 5660 for (i = 0; i < 32; i++) 5661 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5662 } 5663 5664 bwn_wa_agc(mac); 5665 5666 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5667 if (ofdmrev > 2) { 5668 if (phy->type == BWN_PHYTYPE_A) 5669 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5670 else 5671 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5672 } else { 5673 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5674 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5675 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5676 } 5677 5678 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5679 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5680 } 5681 5682 static void 5683 bwn_wa_init(struct bwn_mac *mac) 5684 { 5685 struct bwn_phy *phy = &mac->mac_phy; 5686 struct bwn_softc *sc = mac->mac_sc; 5687 5688 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5689 5690 switch (phy->rev) { 5691 case 1: 5692 bwn_wa_grev1(mac); 5693 break; 5694 case 2: 5695 case 6: 5696 case 7: 5697 case 8: 5698 case 9: 5699 bwn_wa_grev26789(mac); 5700 break; 5701 default: 5702 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5703 } 5704 5705 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5706 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5707 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5708 if (phy->rev < 2) { 5709 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5710 0x0002); 5711 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5712 0x0001); 5713 } else { 5714 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5715 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5716 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5717 BWN_BFL_EXTLNA) && 5718 (phy->rev >= 7)) { 5719 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5720 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5721 0x0020, 0x0001); 5722 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5723 0x0021, 0x0001); 5724 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5725 0x0022, 0x0001); 5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5727 0x0023, 0x0000); 5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5729 0x0000, 0x0000); 5730 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5731 0x0003, 0x0002); 5732 } 5733 } 5734 } 5735 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5736 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5737 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5738 } 5739 5740 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5741 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5742 } 5743 5744 static void 5745 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5746 uint16_t value) 5747 { 5748 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5749 uint16_t addr; 5750 5751 addr = table + offset; 5752 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5753 (addr - 1 != pg->pg_ofdmtab_addr)) { 5754 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5755 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5756 } 5757 pg->pg_ofdmtab_addr = addr; 5758 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5759 } 5760 5761 static void 5762 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5763 uint32_t value) 5764 { 5765 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5766 uint16_t addr; 5767 5768 addr = table + offset; 5769 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5770 (addr - 1 != pg->pg_ofdmtab_addr)) { 5771 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5772 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5773 } 5774 pg->pg_ofdmtab_addr = addr; 5775 5776 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5777 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5778 } 5779 5780 static void 5781 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5782 uint16_t value) 5783 { 5784 5785 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5786 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5787 } 5788 5789 static void 5790 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5791 { 5792 struct bwn_phy *phy = &mac->mac_phy; 5793 struct bwn_softc *sc = mac->mac_sc; 5794 unsigned int i, max_loop; 5795 uint16_t value; 5796 uint32_t buffer[5] = { 5797 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5798 }; 5799 5800 if (ofdm) { 5801 max_loop = 0x1e; 5802 buffer[0] = 0x000201cc; 5803 } else { 5804 max_loop = 0xfa; 5805 buffer[0] = 0x000b846e; 5806 } 5807 5808 BWN_ASSERT_LOCKED(mac->mac_sc); 5809 5810 for (i = 0; i < 5; i++) 5811 bwn_ram_write(mac, i * 4, buffer[i]); 5812 5813 BWN_WRITE_2(mac, 0x0568, 0x0000); 5814 BWN_WRITE_2(mac, 0x07c0, 5815 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5816 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5817 BWN_WRITE_2(mac, 0x050c, value); 5818 if (phy->type == BWN_PHYTYPE_LP) 5819 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5820 BWN_WRITE_2(mac, 0x0508, 0x0000); 5821 BWN_WRITE_2(mac, 0x050a, 0x0000); 5822 BWN_WRITE_2(mac, 0x054c, 0x0000); 5823 BWN_WRITE_2(mac, 0x056a, 0x0014); 5824 BWN_WRITE_2(mac, 0x0568, 0x0826); 5825 BWN_WRITE_2(mac, 0x0500, 0x0000); 5826 if (phy->type == BWN_PHYTYPE_LP) 5827 BWN_WRITE_2(mac, 0x0502, 0x0050); 5828 else 5829 BWN_WRITE_2(mac, 0x0502, 0x0030); 5830 5831 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5832 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5833 for (i = 0x00; i < max_loop; i++) { 5834 value = BWN_READ_2(mac, 0x050e); 5835 if (value & 0x0080) 5836 break; 5837 DELAY(10); 5838 } 5839 for (i = 0x00; i < 0x0a; i++) { 5840 value = BWN_READ_2(mac, 0x050e); 5841 if (value & 0x0400) 5842 break; 5843 DELAY(10); 5844 } 5845 for (i = 0x00; i < 0x19; i++) { 5846 value = BWN_READ_2(mac, 0x0690); 5847 if (!(value & 0x0100)) 5848 break; 5849 DELAY(10); 5850 } 5851 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5852 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5853 } 5854 5855 static void 5856 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5857 { 5858 uint32_t macctl; 5859 5860 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5861 5862 macctl = BWN_READ_4(mac, BWN_MACCTL); 5863 if (macctl & BWN_MACCTL_BIGENDIAN) 5864 printf("TODO: need swap\n"); 5865 5866 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5867 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5868 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5869 } 5870 5871 static void 5872 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5873 { 5874 uint16_t value; 5875 5876 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5877 ("%s:%d: fail", __func__, __LINE__)); 5878 5879 value = (uint8_t) (ctl->q); 5880 value |= ((uint8_t) (ctl->i)) << 8; 5881 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5882 } 5883 5884 static uint16_t 5885 bwn_lo_calcfeed(struct bwn_mac *mac, 5886 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5887 { 5888 struct bwn_phy *phy = &mac->mac_phy; 5889 struct bwn_softc *sc = mac->mac_sc; 5890 uint16_t rfover; 5891 uint16_t feedthrough; 5892 5893 if (phy->gmode) { 5894 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5895 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5896 5897 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5898 ("%s:%d: fail", __func__, __LINE__)); 5899 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5900 ("%s:%d: fail", __func__, __LINE__)); 5901 5902 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5903 5904 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5905 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5906 phy->rev > 6) 5907 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5908 5909 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5910 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5911 DELAY(10); 5912 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5913 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5914 DELAY(10); 5915 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5916 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5917 DELAY(10); 5918 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5919 } else { 5920 pga |= BWN_PHY_PGACTL_UNKNOWN; 5921 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5922 DELAY(10); 5923 pga |= BWN_PHY_PGACTL_LOWBANDW; 5924 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5925 DELAY(10); 5926 pga |= BWN_PHY_PGACTL_LPF; 5927 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5928 } 5929 DELAY(21); 5930 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5931 5932 return (feedthrough); 5933 } 5934 5935 static uint16_t 5936 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5937 uint16_t *value, uint16_t *pad_mix_gain) 5938 { 5939 struct bwn_phy *phy = &mac->mac_phy; 5940 uint16_t reg, v, padmix; 5941 5942 if (phy->type == BWN_PHYTYPE_B) { 5943 v = 0x30; 5944 if (phy->rf_rev <= 5) { 5945 reg = 0x43; 5946 padmix = 0; 5947 } else { 5948 reg = 0x52; 5949 padmix = 5; 5950 } 5951 } else { 5952 if (phy->rev >= 2 && phy->rf_rev == 8) { 5953 reg = 0x43; 5954 v = 0x10; 5955 padmix = 2; 5956 } else { 5957 reg = 0x52; 5958 v = 0x30; 5959 padmix = 5; 5960 } 5961 } 5962 if (value) 5963 *value = v; 5964 if (pad_mix_gain) 5965 *pad_mix_gain = padmix; 5966 5967 return (reg); 5968 } 5969 5970 static void 5971 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5972 { 5973 struct bwn_phy *phy = &mac->mac_phy; 5974 struct bwn_phy_g *pg = &phy->phy_g; 5975 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5976 uint16_t reg, mask; 5977 uint16_t trsw_rx, pga; 5978 uint16_t rf_pctl_reg; 5979 5980 static const uint8_t tx_bias_values[] = { 5981 0x09, 0x08, 0x0a, 0x01, 0x00, 5982 0x02, 0x05, 0x04, 0x06, 5983 }; 5984 static const uint8_t tx_magn_values[] = { 5985 0x70, 0x40, 5986 }; 5987 5988 if (!BWN_HAS_LOOPBACK(phy)) { 5989 rf_pctl_reg = 6; 5990 trsw_rx = 2; 5991 pga = 0; 5992 } else { 5993 int lb_gain; 5994 5995 trsw_rx = 0; 5996 lb_gain = pg->pg_max_lb_gain / 2; 5997 if (lb_gain > 10) { 5998 rf_pctl_reg = 0; 5999 pga = abs(10 - lb_gain) / 6; 6000 pga = MIN(MAX(pga, 0), 15); 6001 } else { 6002 int cmp_val; 6003 int tmp; 6004 6005 pga = 0; 6006 cmp_val = 0x24; 6007 if ((phy->rev >= 2) && 6008 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6009 cmp_val = 0x3c; 6010 tmp = lb_gain; 6011 if ((10 - lb_gain) < cmp_val) 6012 tmp = (10 - lb_gain); 6013 if (tmp < 0) 6014 tmp += 6; 6015 else 6016 tmp += 3; 6017 cmp_val /= 4; 6018 tmp /= 4; 6019 if (tmp >= cmp_val) 6020 rf_pctl_reg = cmp_val; 6021 else 6022 rf_pctl_reg = tmp; 6023 } 6024 } 6025 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6026 bwn_phy_g_set_bbatt(mac, 2); 6027 6028 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6029 mask = ~mask; 6030 BWN_RF_MASK(mac, reg, mask); 6031 6032 if (BWN_HAS_TXMAG(phy)) { 6033 int i, j; 6034 int feedthrough; 6035 int min_feedth = 0xffff; 6036 uint8_t tx_magn, tx_bias; 6037 6038 for (i = 0; i < N(tx_magn_values); i++) { 6039 tx_magn = tx_magn_values[i]; 6040 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6041 for (j = 0; j < N(tx_bias_values); j++) { 6042 tx_bias = tx_bias_values[j]; 6043 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6044 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6045 trsw_rx); 6046 if (feedthrough < min_feedth) { 6047 lo->tx_bias = tx_bias; 6048 lo->tx_magn = tx_magn; 6049 min_feedth = feedthrough; 6050 } 6051 if (lo->tx_bias == 0) 6052 break; 6053 } 6054 BWN_RF_WRITE(mac, 0x52, 6055 (BWN_RF_READ(mac, 0x52) 6056 & 0xff00) | lo->tx_bias | lo-> 6057 tx_magn); 6058 } 6059 } else { 6060 lo->tx_magn = 0; 6061 lo->tx_bias = 0; 6062 BWN_RF_MASK(mac, 0x52, 0xfff0); 6063 } 6064 6065 BWN_GETTIME(lo->txctl_measured_time); 6066 } 6067 6068 static void 6069 bwn_lo_get_powervector(struct bwn_mac *mac) 6070 { 6071 struct bwn_phy *phy = &mac->mac_phy; 6072 struct bwn_phy_g *pg = &phy->phy_g; 6073 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6074 int i; 6075 uint64_t tmp; 6076 uint64_t power_vector = 0; 6077 6078 for (i = 0; i < 8; i += 2) { 6079 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6080 power_vector |= (tmp << (i * 8)); 6081 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6082 } 6083 if (power_vector) 6084 lo->power_vector = power_vector; 6085 6086 BWN_GETTIME(lo->pwr_vec_read_time); 6087 } 6088 6089 static void 6090 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6091 int use_trsw_rx) 6092 { 6093 struct bwn_phy *phy = &mac->mac_phy; 6094 struct bwn_phy_g *pg = &phy->phy_g; 6095 uint16_t tmp; 6096 6097 if (max_rx_gain < 0) 6098 max_rx_gain = 0; 6099 6100 if (BWN_HAS_LOOPBACK(phy)) { 6101 int trsw_rx = 0; 6102 int trsw_rx_gain; 6103 6104 if (use_trsw_rx) { 6105 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6106 if (max_rx_gain >= trsw_rx_gain) { 6107 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6108 trsw_rx = 0x20; 6109 } 6110 } else 6111 trsw_rx_gain = max_rx_gain; 6112 if (trsw_rx_gain < 9) { 6113 pg->pg_lna_lod_gain = 0; 6114 } else { 6115 pg->pg_lna_lod_gain = 1; 6116 trsw_rx_gain -= 8; 6117 } 6118 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6119 pg->pg_pga_gain = trsw_rx_gain / 3; 6120 if (pg->pg_pga_gain >= 5) { 6121 pg->pg_pga_gain -= 5; 6122 pg->pg_lna_gain = 2; 6123 } else 6124 pg->pg_lna_gain = 0; 6125 } else { 6126 pg->pg_lna_gain = 0; 6127 pg->pg_trsw_rx_gain = 0x20; 6128 if (max_rx_gain >= 0x14) { 6129 pg->pg_lna_lod_gain = 1; 6130 pg->pg_pga_gain = 2; 6131 } else if (max_rx_gain >= 0x12) { 6132 pg->pg_lna_lod_gain = 1; 6133 pg->pg_pga_gain = 1; 6134 } else if (max_rx_gain >= 0xf) { 6135 pg->pg_lna_lod_gain = 1; 6136 pg->pg_pga_gain = 0; 6137 } else { 6138 pg->pg_lna_lod_gain = 0; 6139 pg->pg_pga_gain = 0; 6140 } 6141 } 6142 6143 tmp = BWN_RF_READ(mac, 0x7a); 6144 if (pg->pg_lna_lod_gain == 0) 6145 tmp &= ~0x0008; 6146 else 6147 tmp |= 0x0008; 6148 BWN_RF_WRITE(mac, 0x7a, tmp); 6149 } 6150 6151 static void 6152 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6153 { 6154 struct bwn_phy *phy = &mac->mac_phy; 6155 struct bwn_phy_g *pg = &phy->phy_g; 6156 struct bwn_softc *sc = mac->mac_sc; 6157 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6158 struct timespec ts; 6159 uint16_t tmp; 6160 6161 if (bwn_has_hwpctl(mac)) { 6162 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6163 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6164 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6165 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6166 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6167 6168 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6169 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6170 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6171 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6172 } 6173 if (phy->type == BWN_PHYTYPE_B && 6174 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6175 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6176 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6177 } 6178 if (phy->rev >= 2) { 6179 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6180 sav->phy_analogoverval = 6181 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6182 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6183 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6184 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6185 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6186 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6187 6188 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6189 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6190 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6191 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6192 if (phy->type == BWN_PHYTYPE_G) { 6193 if ((phy->rev >= 7) && 6194 (siba_sprom_get_bf_lo(sc->sc_dev) & 6195 BWN_BFL_EXTLNA)) { 6196 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6197 } else { 6198 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6199 } 6200 } else { 6201 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6202 } 6203 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6204 } 6205 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6206 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6207 sav->rf0 = BWN_RF_READ(mac, 0x43); 6208 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6209 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6210 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6211 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6212 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6213 6214 if (!BWN_HAS_TXMAG(phy)) { 6215 sav->rf2 = BWN_RF_READ(mac, 0x52); 6216 sav->rf2 &= 0x00f0; 6217 } 6218 if (phy->type == BWN_PHYTYPE_B) { 6219 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6220 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6221 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6222 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6223 } else { 6224 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6225 | 0x8000); 6226 } 6227 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6228 & 0xf000); 6229 6230 tmp = 6231 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6232 BWN_PHY_WRITE(mac, tmp, 0x007f); 6233 6234 tmp = sav->phy_syncctl; 6235 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6236 tmp = sav->rf1; 6237 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6238 6239 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6240 if (phy->type == BWN_PHYTYPE_G || 6241 (phy->type == BWN_PHYTYPE_B && 6242 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6243 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6244 } else 6245 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6246 if (phy->rev >= 2) 6247 bwn_dummy_transmission(mac, 0, 1); 6248 bwn_phy_g_switch_chan(mac, 6, 0); 6249 BWN_RF_READ(mac, 0x51); 6250 if (phy->type == BWN_PHYTYPE_G) 6251 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6252 6253 nanouptime(&ts); 6254 if (time_before(lo->txctl_measured_time, 6255 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6256 bwn_lo_measure_txctl_values(mac); 6257 6258 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6259 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6260 else { 6261 if (phy->type == BWN_PHYTYPE_B) 6262 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6263 else 6264 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6265 } 6266 } 6267 6268 static void 6269 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6270 { 6271 struct bwn_phy *phy = &mac->mac_phy; 6272 struct bwn_phy_g *pg = &phy->phy_g; 6273 uint16_t tmp; 6274 6275 if (phy->rev >= 2) { 6276 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6277 tmp = (pg->pg_pga_gain << 8); 6278 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6279 DELAY(5); 6280 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6281 DELAY(2); 6282 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6283 } else { 6284 tmp = (pg->pg_pga_gain | 0xefa0); 6285 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6286 } 6287 if (phy->type == BWN_PHYTYPE_G) { 6288 if (phy->rev >= 3) 6289 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6290 else 6291 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6292 if (phy->rev >= 2) 6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6294 else 6295 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6296 } 6297 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6298 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6299 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6300 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6301 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6302 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6303 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6304 if (!BWN_HAS_TXMAG(phy)) { 6305 tmp = sav->rf2; 6306 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6307 } 6308 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6309 if (phy->type == BWN_PHYTYPE_B && 6310 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6311 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6312 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6313 } 6314 if (phy->rev >= 2) { 6315 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6316 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6317 sav->phy_analogoverval); 6318 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6319 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6320 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6321 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6322 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6323 } 6324 if (bwn_has_hwpctl(mac)) { 6325 tmp = (sav->phy_lomask & 0xbfff); 6326 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6327 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6328 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6329 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6330 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6331 } 6332 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6333 } 6334 6335 static int 6336 bwn_lo_probe_loctl(struct bwn_mac *mac, 6337 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6338 { 6339 struct bwn_phy *phy = &mac->mac_phy; 6340 struct bwn_phy_g *pg = &phy->phy_g; 6341 struct bwn_loctl orig, test; 6342 struct bwn_loctl prev = { -100, -100 }; 6343 static const struct bwn_loctl modifiers[] = { 6344 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6345 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6346 }; 6347 int begin, end, lower = 0, i; 6348 uint16_t feedth; 6349 6350 if (d->curstate == 0) { 6351 begin = 1; 6352 end = 8; 6353 } else if (d->curstate % 2 == 0) { 6354 begin = d->curstate - 1; 6355 end = d->curstate + 1; 6356 } else { 6357 begin = d->curstate - 2; 6358 end = d->curstate + 2; 6359 } 6360 if (begin < 1) 6361 begin += 8; 6362 if (end > 8) 6363 end -= 8; 6364 6365 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6366 i = begin; 6367 d->curstate = i; 6368 while (1) { 6369 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6370 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6371 test.i += modifiers[i - 1].i * d->multipler; 6372 test.q += modifiers[i - 1].q * d->multipler; 6373 if ((test.i != prev.i || test.q != prev.q) && 6374 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6375 bwn_lo_write(mac, &test); 6376 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6377 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6378 if (feedth < d->feedth) { 6379 memcpy(probe, &test, 6380 sizeof(struct bwn_loctl)); 6381 lower = 1; 6382 d->feedth = feedth; 6383 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6384 break; 6385 } 6386 } 6387 memcpy(&prev, &test, sizeof(prev)); 6388 if (i == end) 6389 break; 6390 if (i == 8) 6391 i = 1; 6392 else 6393 i++; 6394 d->curstate = i; 6395 } 6396 6397 return (lower); 6398 } 6399 6400 static void 6401 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6402 { 6403 struct bwn_phy *phy = &mac->mac_phy; 6404 struct bwn_phy_g *pg = &phy->phy_g; 6405 struct bwn_lo_g_sm d; 6406 struct bwn_loctl probe; 6407 int lower, repeat, cnt = 0; 6408 uint16_t feedth; 6409 6410 d.nmeasure = 0; 6411 d.multipler = 1; 6412 if (BWN_HAS_LOOPBACK(phy)) 6413 d.multipler = 3; 6414 6415 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6416 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6417 6418 do { 6419 bwn_lo_write(mac, &d.loctl); 6420 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6421 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6422 if (feedth < 0x258) { 6423 if (feedth >= 0x12c) 6424 *rxgain += 6; 6425 else 6426 *rxgain += 3; 6427 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6428 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6429 } 6430 d.feedth = feedth; 6431 d.curstate = 0; 6432 do { 6433 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6434 ("%s:%d: fail", __func__, __LINE__)); 6435 memcpy(&probe, &d.loctl, 6436 sizeof(struct bwn_loctl)); 6437 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6438 if (!lower) 6439 break; 6440 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6441 break; 6442 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6443 d.nmeasure++; 6444 } while (d.nmeasure < 24); 6445 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6446 6447 if (BWN_HAS_LOOPBACK(phy)) { 6448 if (d.feedth > 0x1194) 6449 *rxgain -= 6; 6450 else if (d.feedth < 0x5dc) 6451 *rxgain += 3; 6452 if (cnt == 0) { 6453 if (d.feedth <= 0x5dc) { 6454 d.multipler = 1; 6455 cnt++; 6456 } else 6457 d.multipler = 2; 6458 } else if (cnt == 2) 6459 d.multipler = 1; 6460 } 6461 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6462 } while (++cnt < repeat); 6463 } 6464 6465 static struct bwn_lo_calib * 6466 bwn_lo_calibset(struct bwn_mac *mac, 6467 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6468 { 6469 struct bwn_phy *phy = &mac->mac_phy; 6470 struct bwn_phy_g *pg = &phy->phy_g; 6471 struct bwn_loctl loctl = { 0, 0 }; 6472 struct bwn_lo_calib *cal; 6473 struct bwn_lo_g_value sval = { 0 }; 6474 int rxgain; 6475 uint16_t pad, reg, value; 6476 6477 sval.old_channel = phy->chan; 6478 bwn_mac_suspend(mac); 6479 bwn_lo_save(mac, &sval); 6480 6481 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6482 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6483 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6484 6485 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6486 if (rfatt->padmix) 6487 rxgain -= pad; 6488 if (BWN_HAS_LOOPBACK(phy)) 6489 rxgain += pg->pg_max_lb_gain; 6490 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6491 bwn_phy_g_set_bbatt(mac, bbatt->att); 6492 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6493 6494 bwn_lo_restore(mac, &sval); 6495 bwn_mac_enable(mac); 6496 6497 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6498 if (!cal) { 6499 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6500 return (NULL); 6501 } 6502 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6503 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6504 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6505 6506 BWN_GETTIME(cal->calib_time); 6507 6508 return (cal); 6509 } 6510 6511 static struct bwn_lo_calib * 6512 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6513 const struct bwn_rfatt *rfatt) 6514 { 6515 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6516 struct bwn_lo_calib *c; 6517 6518 TAILQ_FOREACH(c, &lo->calib_list, list) { 6519 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6520 continue; 6521 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6522 continue; 6523 return (c); 6524 } 6525 6526 c = bwn_lo_calibset(mac, bbatt, rfatt); 6527 if (!c) 6528 return (NULL); 6529 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6530 6531 return (c); 6532 } 6533 6534 static void 6535 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6536 { 6537 struct bwn_phy *phy = &mac->mac_phy; 6538 struct bwn_phy_g *pg = &phy->phy_g; 6539 struct bwn_softc *sc = mac->mac_sc; 6540 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6541 const struct bwn_rfatt *rfatt; 6542 const struct bwn_bbatt *bbatt; 6543 uint64_t pvector; 6544 int i; 6545 int rf_offset, bb_offset; 6546 uint8_t changed = 0; 6547 6548 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6549 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6550 ("%s:%d: fail", __func__, __LINE__)); 6551 6552 pvector = lo->power_vector; 6553 if (!update && !pvector) 6554 return; 6555 6556 bwn_mac_suspend(mac); 6557 6558 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6559 struct bwn_lo_calib *cal; 6560 int idx; 6561 uint16_t val; 6562 6563 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6564 continue; 6565 bb_offset = i / lo->rfatt.len; 6566 rf_offset = i % lo->rfatt.len; 6567 bbatt = &(lo->bbatt.array[bb_offset]); 6568 rfatt = &(lo->rfatt.array[rf_offset]); 6569 6570 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6571 if (!cal) { 6572 device_printf(sc->sc_dev, "LO: Could not " 6573 "calibrate DC table entry\n"); 6574 continue; 6575 } 6576 val = (uint8_t)(cal->ctl.q); 6577 val |= ((uint8_t)(cal->ctl.i)) << 4; 6578 free(cal, M_DEVBUF); 6579 6580 idx = i / 2; 6581 if (i % 2) 6582 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6583 | ((val & 0x00ff) << 8); 6584 else 6585 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6586 | (val & 0x00ff); 6587 changed = 1; 6588 } 6589 if (changed) { 6590 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6591 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6592 } 6593 bwn_mac_enable(mac); 6594 } 6595 6596 static void 6597 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6598 { 6599 6600 if (!rf->padmix) 6601 return; 6602 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6603 rf->att = 4; 6604 } 6605 6606 static void 6607 bwn_lo_g_adjust(struct bwn_mac *mac) 6608 { 6609 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6610 struct bwn_lo_calib *cal; 6611 struct bwn_rfatt rf; 6612 6613 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6614 bwn_lo_fixup_rfatt(&rf); 6615 6616 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6617 if (!cal) 6618 return; 6619 bwn_lo_write(mac, &cal->ctl); 6620 } 6621 6622 static void 6623 bwn_lo_g_init(struct bwn_mac *mac) 6624 { 6625 6626 if (!bwn_has_hwpctl(mac)) 6627 return; 6628 6629 bwn_lo_get_powervector(mac); 6630 bwn_phy_g_dc_lookup_init(mac, 1); 6631 } 6632 6633 static void 6634 bwn_mac_suspend(struct bwn_mac *mac) 6635 { 6636 struct bwn_softc *sc = mac->mac_sc; 6637 int i; 6638 uint32_t tmp; 6639 6640 KASSERT(mac->mac_suspended >= 0, 6641 ("%s:%d: fail", __func__, __LINE__)); 6642 6643 if (mac->mac_suspended == 0) { 6644 bwn_psctl(mac, BWN_PS_AWAKE); 6645 BWN_WRITE_4(mac, BWN_MACCTL, 6646 BWN_READ_4(mac, BWN_MACCTL) 6647 & ~BWN_MACCTL_ON); 6648 BWN_READ_4(mac, BWN_MACCTL); 6649 for (i = 35; i; i--) { 6650 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6651 if (tmp & BWN_INTR_MAC_SUSPENDED) 6652 goto out; 6653 DELAY(10); 6654 } 6655 for (i = 40; i; i--) { 6656 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6657 if (tmp & BWN_INTR_MAC_SUSPENDED) 6658 goto out; 6659 DELAY(1000); 6660 } 6661 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6662 } 6663 out: 6664 mac->mac_suspended++; 6665 } 6666 6667 static void 6668 bwn_mac_enable(struct bwn_mac *mac) 6669 { 6670 struct bwn_softc *sc = mac->mac_sc; 6671 uint16_t state; 6672 6673 state = bwn_shm_read_2(mac, BWN_SHARED, 6674 BWN_SHARED_UCODESTAT); 6675 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6676 state != BWN_SHARED_UCODESTAT_SLEEP) 6677 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6678 6679 mac->mac_suspended--; 6680 KASSERT(mac->mac_suspended >= 0, 6681 ("%s:%d: fail", __func__, __LINE__)); 6682 if (mac->mac_suspended == 0) { 6683 BWN_WRITE_4(mac, BWN_MACCTL, 6684 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6685 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6686 BWN_READ_4(mac, BWN_MACCTL); 6687 BWN_READ_4(mac, BWN_INTR_REASON); 6688 bwn_psctl(mac, 0); 6689 } 6690 } 6691 6692 static void 6693 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6694 { 6695 struct bwn_softc *sc = mac->mac_sc; 6696 int i; 6697 uint16_t ucstat; 6698 6699 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6700 ("%s:%d: fail", __func__, __LINE__)); 6701 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6702 ("%s:%d: fail", __func__, __LINE__)); 6703 6704 /* XXX forcibly awake and hwps-off */ 6705 6706 BWN_WRITE_4(mac, BWN_MACCTL, 6707 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6708 ~BWN_MACCTL_HWPS); 6709 BWN_READ_4(mac, BWN_MACCTL); 6710 if (siba_get_revid(sc->sc_dev) >= 5) { 6711 for (i = 0; i < 100; i++) { 6712 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6713 BWN_SHARED_UCODESTAT); 6714 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6715 break; 6716 DELAY(10); 6717 } 6718 } 6719 } 6720 6721 static int16_t 6722 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6723 { 6724 6725 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6726 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6727 } 6728 6729 static void 6730 bwn_nrssi_threshold(struct bwn_mac *mac) 6731 { 6732 struct bwn_phy *phy = &mac->mac_phy; 6733 struct bwn_phy_g *pg = &phy->phy_g; 6734 struct bwn_softc *sc = mac->mac_sc; 6735 int32_t a, b; 6736 int16_t tmp16; 6737 uint16_t tmpu16; 6738 6739 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6740 6741 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6742 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6743 a = 0x13; 6744 b = 0x12; 6745 } else { 6746 a = 0xe; 6747 b = 0x11; 6748 } 6749 6750 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6751 a += (pg->pg_nrssi[0] << 6); 6752 a += (a < 32) ? 31 : 32; 6753 a = a >> 6; 6754 a = MIN(MAX(a, -31), 31); 6755 6756 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6757 b += (pg->pg_nrssi[0] << 6); 6758 if (b < 32) 6759 b += 31; 6760 else 6761 b += 32; 6762 b = b >> 6; 6763 b = MIN(MAX(b, -31), 31); 6764 6765 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6766 tmpu16 |= ((uint32_t)b & 0x0000003f); 6767 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6768 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6769 return; 6770 } 6771 6772 tmp16 = bwn_nrssi_read(mac, 0x20); 6773 if (tmp16 >= 0x20) 6774 tmp16 -= 0x40; 6775 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6776 } 6777 6778 static void 6779 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6780 { 6781 #define SAVE_RF_MAX 3 6782 #define SAVE_PHY_COMM_MAX 4 6783 #define SAVE_PHY3_MAX 8 6784 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6785 { 0x7a, 0x52, 0x43 }; 6786 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6787 { 0x15, 0x5a, 0x59, 0x58 }; 6788 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6789 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6790 0x0801, 0x0060, 0x0014, 0x0478 6791 }; 6792 struct bwn_phy *phy = &mac->mac_phy; 6793 struct bwn_phy_g *pg = &phy->phy_g; 6794 int32_t i, tmp32, phy3_idx = 0; 6795 uint16_t delta, tmp; 6796 uint16_t save_rf[SAVE_RF_MAX]; 6797 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6798 uint16_t save_phy3[SAVE_PHY3_MAX]; 6799 uint16_t ant_div, phy0, chan_ex; 6800 int16_t nrssi0, nrssi1; 6801 6802 KASSERT(phy->type == BWN_PHYTYPE_G, 6803 ("%s:%d: fail", __func__, __LINE__)); 6804 6805 if (phy->rf_rev >= 9) 6806 return; 6807 if (phy->rf_rev == 8) 6808 bwn_nrssi_offset(mac); 6809 6810 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6811 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6812 6813 /* 6814 * Save RF/PHY registers for later restoration 6815 */ 6816 ant_div = BWN_READ_2(mac, 0x03e2); 6817 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6818 for (i = 0; i < SAVE_RF_MAX; ++i) 6819 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6820 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6821 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6822 6823 phy0 = BWN_READ_2(mac, BWN_PHY0); 6824 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6825 if (phy->rev >= 3) { 6826 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6827 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6828 BWN_PHY_WRITE(mac, 0x002e, 0); 6829 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6830 switch (phy->rev) { 6831 case 4: 6832 case 6: 6833 case 7: 6834 BWN_PHY_SET(mac, 0x0478, 0x0100); 6835 BWN_PHY_SET(mac, 0x0801, 0x0040); 6836 break; 6837 case 3: 6838 case 5: 6839 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6840 break; 6841 } 6842 BWN_PHY_SET(mac, 0x0060, 0x0040); 6843 BWN_PHY_SET(mac, 0x0014, 0x0200); 6844 } 6845 /* 6846 * Calculate nrssi0 6847 */ 6848 BWN_RF_SET(mac, 0x007a, 0x0070); 6849 bwn_set_all_gains(mac, 0, 8, 0); 6850 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6851 if (phy->rev >= 2) { 6852 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6853 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6854 } 6855 BWN_RF_SET(mac, 0x007a, 0x0080); 6856 DELAY(20); 6857 6858 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6859 if (nrssi0 >= 0x0020) 6860 nrssi0 -= 0x0040; 6861 6862 /* 6863 * Calculate nrssi1 6864 */ 6865 BWN_RF_MASK(mac, 0x007a, 0x007f); 6866 if (phy->rev >= 2) 6867 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6868 6869 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6870 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6871 BWN_RF_SET(mac, 0x007a, 0x000f); 6872 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6873 if (phy->rev >= 2) { 6874 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6875 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6876 } 6877 6878 bwn_set_all_gains(mac, 3, 0, 1); 6879 if (phy->rf_rev == 8) { 6880 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6881 } else { 6882 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6883 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6884 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6885 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6886 } 6887 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6888 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6889 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6890 DELAY(20); 6891 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6892 6893 /* 6894 * Install calculated narrow RSSI values 6895 */ 6896 if (nrssi1 >= 0x0020) 6897 nrssi1 -= 0x0040; 6898 if (nrssi0 == nrssi1) 6899 pg->pg_nrssi_slope = 0x00010000; 6900 else 6901 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6902 if (nrssi0 >= -4) { 6903 pg->pg_nrssi[0] = nrssi1; 6904 pg->pg_nrssi[1] = nrssi0; 6905 } 6906 6907 /* 6908 * Restore saved RF/PHY registers 6909 */ 6910 if (phy->rev >= 3) { 6911 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6912 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6913 save_phy3[phy3_idx]); 6914 } 6915 } 6916 if (phy->rev >= 2) { 6917 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6918 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6919 } 6920 6921 for (i = 0; i < SAVE_RF_MAX; ++i) 6922 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6923 6924 BWN_WRITE_2(mac, 0x03e2, ant_div); 6925 BWN_WRITE_2(mac, 0x03e6, phy0); 6926 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6927 6928 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6929 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6930 6931 bwn_spu_workaround(mac, phy->chan); 6932 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6933 bwn_set_original_gains(mac); 6934 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6935 if (phy->rev >= 3) { 6936 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6937 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6938 save_phy3[phy3_idx]); 6939 } 6940 } 6941 6942 delta = 0x1f - pg->pg_nrssi[0]; 6943 for (i = 0; i < 64; i++) { 6944 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6945 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6946 pg->pg_nrssi_lt[i] = tmp32; 6947 } 6948 6949 bwn_nrssi_threshold(mac); 6950 #undef SAVE_RF_MAX 6951 #undef SAVE_PHY_COMM_MAX 6952 #undef SAVE_PHY3_MAX 6953 } 6954 6955 static void 6956 bwn_nrssi_offset(struct bwn_mac *mac) 6957 { 6958 #define SAVE_RF_MAX 2 6959 #define SAVE_PHY_COMM_MAX 10 6960 #define SAVE_PHY6_MAX 8 6961 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6962 { 0x7a, 0x43 }; 6963 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6964 0x0001, 0x0811, 0x0812, 0x0814, 6965 0x0815, 0x005a, 0x0059, 0x0058, 6966 0x000a, 0x0003 6967 }; 6968 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6969 0x002e, 0x002f, 0x080f, 0x0810, 6970 0x0801, 0x0060, 0x0014, 0x0478 6971 }; 6972 struct bwn_phy *phy = &mac->mac_phy; 6973 int i, phy6_idx = 0; 6974 uint16_t save_rf[SAVE_RF_MAX]; 6975 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6976 uint16_t save_phy6[SAVE_PHY6_MAX]; 6977 int16_t nrssi; 6978 uint16_t saved = 0xffff; 6979 6980 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6981 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6982 for (i = 0; i < SAVE_RF_MAX; ++i) 6983 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6984 6985 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6986 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6987 BWN_PHY_SET(mac, 0x0811, 0x000c); 6988 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6989 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6990 if (phy->rev >= 6) { 6991 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6992 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6993 6994 BWN_PHY_WRITE(mac, 0x002e, 0); 6995 BWN_PHY_WRITE(mac, 0x002f, 0); 6996 BWN_PHY_WRITE(mac, 0x080f, 0); 6997 BWN_PHY_WRITE(mac, 0x0810, 0); 6998 BWN_PHY_SET(mac, 0x0478, 0x0100); 6999 BWN_PHY_SET(mac, 0x0801, 0x0040); 7000 BWN_PHY_SET(mac, 0x0060, 0x0040); 7001 BWN_PHY_SET(mac, 0x0014, 0x0200); 7002 } 7003 BWN_RF_SET(mac, 0x007a, 0x0070); 7004 BWN_RF_SET(mac, 0x007a, 0x0080); 7005 DELAY(30); 7006 7007 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7008 if (nrssi >= 0x20) 7009 nrssi -= 0x40; 7010 if (nrssi == 31) { 7011 for (i = 7; i >= 4; i--) { 7012 BWN_RF_WRITE(mac, 0x007b, i); 7013 DELAY(20); 7014 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7015 0x003f); 7016 if (nrssi >= 0x20) 7017 nrssi -= 0x40; 7018 if (nrssi < 31 && saved == 0xffff) 7019 saved = i; 7020 } 7021 if (saved == 0xffff) 7022 saved = 4; 7023 } else { 7024 BWN_RF_MASK(mac, 0x007a, 0x007f); 7025 if (phy->rev != 1) { 7026 BWN_PHY_SET(mac, 0x0814, 0x0001); 7027 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7028 } 7029 BWN_PHY_SET(mac, 0x0811, 0x000c); 7030 BWN_PHY_SET(mac, 0x0812, 0x000c); 7031 BWN_PHY_SET(mac, 0x0811, 0x0030); 7032 BWN_PHY_SET(mac, 0x0812, 0x0030); 7033 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7034 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7035 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7036 if (phy->rev == 0) 7037 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7038 else 7039 BWN_PHY_SET(mac, 0x000a, 0x2000); 7040 if (phy->rev != 1) { 7041 BWN_PHY_SET(mac, 0x0814, 0x0004); 7042 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7043 } 7044 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7045 BWN_RF_SET(mac, 0x007a, 0x000f); 7046 bwn_set_all_gains(mac, 3, 0, 1); 7047 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7048 DELAY(30); 7049 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7050 if (nrssi >= 0x20) 7051 nrssi -= 0x40; 7052 if (nrssi == -32) { 7053 for (i = 0; i < 4; i++) { 7054 BWN_RF_WRITE(mac, 0x007b, i); 7055 DELAY(20); 7056 nrssi = (int16_t)((BWN_PHY_READ(mac, 7057 0x047f) >> 8) & 0x003f); 7058 if (nrssi >= 0x20) 7059 nrssi -= 0x40; 7060 if (nrssi > -31 && saved == 0xffff) 7061 saved = i; 7062 } 7063 if (saved == 0xffff) 7064 saved = 3; 7065 } else 7066 saved = 0; 7067 } 7068 BWN_RF_WRITE(mac, 0x007b, saved); 7069 7070 /* 7071 * Restore saved RF/PHY registers 7072 */ 7073 if (phy->rev >= 6) { 7074 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7075 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7076 save_phy6[phy6_idx]); 7077 } 7078 } 7079 if (phy->rev != 1) { 7080 for (i = 3; i < 5; i++) 7081 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7082 save_phy_comm[i]); 7083 } 7084 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7085 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7086 7087 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7088 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7089 7090 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7091 BWN_PHY_SET(mac, 0x0429, 0x8000); 7092 bwn_set_original_gains(mac); 7093 if (phy->rev >= 6) { 7094 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7095 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7096 save_phy6[phy6_idx]); 7097 } 7098 } 7099 7100 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7101 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7102 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7103 } 7104 7105 static void 7106 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7107 int16_t third) 7108 { 7109 struct bwn_phy *phy = &mac->mac_phy; 7110 uint16_t i; 7111 uint16_t start = 0x08, end = 0x18; 7112 uint16_t tmp; 7113 uint16_t table; 7114 7115 if (phy->rev <= 1) { 7116 start = 0x10; 7117 end = 0x20; 7118 } 7119 7120 table = BWN_OFDMTAB_GAINX; 7121 if (phy->rev <= 1) 7122 table = BWN_OFDMTAB_GAINX_R1; 7123 for (i = 0; i < 4; i++) 7124 bwn_ofdmtab_write_2(mac, table, i, first); 7125 7126 for (i = start; i < end; i++) 7127 bwn_ofdmtab_write_2(mac, table, i, second); 7128 7129 if (third != -1) { 7130 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7131 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7132 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7133 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7134 } 7135 bwn_dummy_transmission(mac, 0, 1); 7136 } 7137 7138 static void 7139 bwn_set_original_gains(struct bwn_mac *mac) 7140 { 7141 struct bwn_phy *phy = &mac->mac_phy; 7142 uint16_t i, tmp; 7143 uint16_t table; 7144 uint16_t start = 0x0008, end = 0x0018; 7145 7146 if (phy->rev <= 1) { 7147 start = 0x0010; 7148 end = 0x0020; 7149 } 7150 7151 table = BWN_OFDMTAB_GAINX; 7152 if (phy->rev <= 1) 7153 table = BWN_OFDMTAB_GAINX_R1; 7154 for (i = 0; i < 4; i++) { 7155 tmp = (i & 0xfffc); 7156 tmp |= (i & 0x0001) << 1; 7157 tmp |= (i & 0x0002) >> 1; 7158 7159 bwn_ofdmtab_write_2(mac, table, i, tmp); 7160 } 7161 7162 for (i = start; i < end; i++) 7163 bwn_ofdmtab_write_2(mac, table, i, i - start); 7164 7165 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7166 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7167 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7168 bwn_dummy_transmission(mac, 0, 1); 7169 } 7170 7171 static void 7172 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7173 { 7174 struct bwn_phy *phy = &mac->mac_phy; 7175 struct bwn_phy_g *pg = &phy->phy_g; 7176 struct bwn_rfatt old_rfatt, rfatt; 7177 struct bwn_bbatt old_bbatt, bbatt; 7178 struct bwn_softc *sc = mac->mac_sc; 7179 uint8_t old_txctl = 0; 7180 7181 KASSERT(phy->type == BWN_PHYTYPE_G, 7182 ("%s:%d: fail", __func__, __LINE__)); 7183 7184 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7185 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7186 return; 7187 7188 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7189 7190 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7191 7192 if (!phy->gmode) 7193 return; 7194 bwn_hwpctl_early_init(mac); 7195 if (pg->pg_curtssi == 0) { 7196 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7197 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7198 } else { 7199 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7200 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7201 old_txctl = pg->pg_txctl; 7202 7203 bbatt.att = 11; 7204 if (phy->rf_rev == 8) { 7205 rfatt.att = 15; 7206 rfatt.padmix = 1; 7207 } else { 7208 rfatt.att = 9; 7209 rfatt.padmix = 0; 7210 } 7211 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7212 } 7213 bwn_dummy_transmission(mac, 0, 1); 7214 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7215 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7216 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7217 else 7218 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7219 &old_rfatt, old_txctl); 7220 } 7221 bwn_hwpctl_init_gphy(mac); 7222 7223 /* clear TSSI */ 7224 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7225 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7226 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7227 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7228 } 7229 7230 static void 7231 bwn_hwpctl_early_init(struct bwn_mac *mac) 7232 { 7233 struct bwn_phy *phy = &mac->mac_phy; 7234 7235 if (!bwn_has_hwpctl(mac)) { 7236 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7237 return; 7238 } 7239 7240 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7241 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7242 BWN_PHY_SET(mac, 0x047c, 0x0002); 7243 BWN_PHY_SET(mac, 0x047a, 0xf000); 7244 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7245 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7246 BWN_PHY_SET(mac, 0x005d, 0x8000); 7247 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7248 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7249 BWN_PHY_SET(mac, 0x0036, 0x0400); 7250 } else { 7251 BWN_PHY_SET(mac, 0x0036, 0x0200); 7252 BWN_PHY_SET(mac, 0x0036, 0x0400); 7253 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7254 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7255 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7256 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7257 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7258 } 7259 } 7260 7261 static void 7262 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7263 { 7264 struct bwn_phy *phy = &mac->mac_phy; 7265 struct bwn_phy_g *pg = &phy->phy_g; 7266 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7267 int i; 7268 uint16_t nr_written = 0, tmp, value; 7269 uint8_t rf, bb; 7270 7271 if (!bwn_has_hwpctl(mac)) { 7272 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7273 return; 7274 } 7275 7276 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7277 (pg->pg_idletssi - pg->pg_curtssi)); 7278 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7279 (pg->pg_idletssi - pg->pg_curtssi)); 7280 7281 for (i = 0; i < 32; i++) 7282 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7283 for (i = 32; i < 64; i++) 7284 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7285 for (i = 0; i < 64; i += 2) { 7286 value = (uint16_t) pg->pg_tssi2dbm[i]; 7287 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7288 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7289 } 7290 7291 for (rf = 0; rf < lo->rfatt.len; rf++) { 7292 for (bb = 0; bb < lo->bbatt.len; bb++) { 7293 if (nr_written >= 0x40) 7294 return; 7295 tmp = lo->bbatt.array[bb].att; 7296 tmp <<= 8; 7297 if (phy->rf_rev == 8) 7298 tmp |= 0x50; 7299 else 7300 tmp |= 0x40; 7301 tmp |= lo->rfatt.array[rf].att; 7302 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7303 nr_written++; 7304 } 7305 } 7306 7307 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7308 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7309 7310 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7311 BWN_PHY_SET(mac, 0x0478, 0x0800); 7312 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7313 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7314 7315 bwn_phy_g_dc_lookup_init(mac, 1); 7316 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7317 } 7318 7319 static void 7320 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7321 { 7322 struct bwn_softc *sc = mac->mac_sc; 7323 7324 if (spu != 0) 7325 bwn_spu_workaround(mac, channel); 7326 7327 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7328 7329 if (channel == 14) { 7330 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7331 bwn_hf_write(mac, 7332 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7333 else 7334 bwn_hf_write(mac, 7335 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7336 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7337 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7338 return; 7339 } 7340 7341 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7342 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7343 } 7344 7345 static uint16_t 7346 bwn_phy_g_chan2freq(uint8_t channel) 7347 { 7348 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7349 7350 KASSERT(channel >= 1 && channel <= 14, 7351 ("%s:%d: fail", __func__, __LINE__)); 7352 7353 return (bwn_phy_g_rf_channels[channel - 1]); 7354 } 7355 7356 static void 7357 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7358 const struct bwn_rfatt *rfatt, uint8_t txctl) 7359 { 7360 struct bwn_phy *phy = &mac->mac_phy; 7361 struct bwn_phy_g *pg = &phy->phy_g; 7362 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7363 uint16_t bb, rf; 7364 uint16_t tx_bias, tx_magn; 7365 7366 bb = bbatt->att; 7367 rf = rfatt->att; 7368 tx_bias = lo->tx_bias; 7369 tx_magn = lo->tx_magn; 7370 if (tx_bias == 0xff) 7371 tx_bias = 0; 7372 7373 pg->pg_txctl = txctl; 7374 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7375 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7376 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7377 bwn_phy_g_set_bbatt(mac, bb); 7378 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7379 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7380 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7381 else { 7382 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7383 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7384 } 7385 if (BWN_HAS_TXMAG(phy)) 7386 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7387 else 7388 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7389 bwn_lo_g_adjust(mac); 7390 } 7391 7392 static void 7393 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7394 uint16_t bbatt) 7395 { 7396 struct bwn_phy *phy = &mac->mac_phy; 7397 7398 if (phy->analog == 0) { 7399 BWN_WRITE_2(mac, BWN_PHY0, 7400 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7401 return; 7402 } 7403 if (phy->analog > 1) { 7404 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7405 return; 7406 } 7407 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7408 } 7409 7410 static uint16_t 7411 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7412 { 7413 struct bwn_phy *phy = &mac->mac_phy; 7414 struct bwn_phy_g *pg = &phy->phy_g; 7415 struct bwn_softc *sc = mac->mac_sc; 7416 int max_lb_gain; 7417 uint16_t extlna; 7418 uint16_t i; 7419 7420 if (phy->gmode == 0) 7421 return (0); 7422 7423 if (BWN_HAS_LOOPBACK(phy)) { 7424 max_lb_gain = pg->pg_max_lb_gain; 7425 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7426 if (max_lb_gain >= 0x46) { 7427 extlna = 0x3000; 7428 max_lb_gain -= 0x46; 7429 } else if (max_lb_gain >= 0x3a) { 7430 extlna = 0x1000; 7431 max_lb_gain -= 0x3a; 7432 } else if (max_lb_gain >= 0x2e) { 7433 extlna = 0x2000; 7434 max_lb_gain -= 0x2e; 7435 } else { 7436 extlna = 0; 7437 max_lb_gain -= 0x10; 7438 } 7439 7440 for (i = 0; i < 16; i++) { 7441 max_lb_gain -= (i * 6); 7442 if (max_lb_gain < 6) 7443 break; 7444 } 7445 7446 if ((phy->rev < 7) || 7447 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7448 if (reg == BWN_PHY_RFOVER) { 7449 return (0x1b3); 7450 } else if (reg == BWN_PHY_RFOVERVAL) { 7451 extlna |= (i << 8); 7452 switch (lpd) { 7453 case BWN_LPD(0, 1, 1): 7454 return (0x0f92); 7455 case BWN_LPD(0, 0, 1): 7456 case BWN_LPD(1, 0, 1): 7457 return (0x0092 | extlna); 7458 case BWN_LPD(1, 0, 0): 7459 return (0x0093 | extlna); 7460 } 7461 KASSERT(0 == 1, 7462 ("%s:%d: fail", __func__, __LINE__)); 7463 } 7464 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7465 } else { 7466 if (reg == BWN_PHY_RFOVER) 7467 return (0x9b3); 7468 if (reg == BWN_PHY_RFOVERVAL) { 7469 if (extlna) 7470 extlna |= 0x8000; 7471 extlna |= (i << 8); 7472 switch (lpd) { 7473 case BWN_LPD(0, 1, 1): 7474 return (0x8f92); 7475 case BWN_LPD(0, 0, 1): 7476 return (0x8092 | extlna); 7477 case BWN_LPD(1, 0, 1): 7478 return (0x2092 | extlna); 7479 case BWN_LPD(1, 0, 0): 7480 return (0x2093 | extlna); 7481 } 7482 KASSERT(0 == 1, 7483 ("%s:%d: fail", __func__, __LINE__)); 7484 } 7485 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7486 } 7487 return (0); 7488 } 7489 7490 if ((phy->rev < 7) || 7491 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7492 if (reg == BWN_PHY_RFOVER) { 7493 return (0x1b3); 7494 } else if (reg == BWN_PHY_RFOVERVAL) { 7495 switch (lpd) { 7496 case BWN_LPD(0, 1, 1): 7497 return (0x0fb2); 7498 case BWN_LPD(0, 0, 1): 7499 return (0x00b2); 7500 case BWN_LPD(1, 0, 1): 7501 return (0x30b2); 7502 case BWN_LPD(1, 0, 0): 7503 return (0x30b3); 7504 } 7505 KASSERT(0 == 1, 7506 ("%s:%d: fail", __func__, __LINE__)); 7507 } 7508 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7509 } else { 7510 if (reg == BWN_PHY_RFOVER) { 7511 return (0x9b3); 7512 } else if (reg == BWN_PHY_RFOVERVAL) { 7513 switch (lpd) { 7514 case BWN_LPD(0, 1, 1): 7515 return (0x8fb2); 7516 case BWN_LPD(0, 0, 1): 7517 return (0x80b2); 7518 case BWN_LPD(1, 0, 1): 7519 return (0x20b2); 7520 case BWN_LPD(1, 0, 0): 7521 return (0x20b3); 7522 } 7523 KASSERT(0 == 1, 7524 ("%s:%d: fail", __func__, __LINE__)); 7525 } 7526 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7527 } 7528 return (0); 7529 } 7530 7531 static void 7532 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7533 { 7534 7535 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7536 return; 7537 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7538 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7539 DELAY(1000); 7540 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7541 } 7542 7543 static int 7544 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7545 { 7546 struct bwn_softc *sc = mac->mac_sc; 7547 struct bwn_fw *fw = &mac->mac_fw; 7548 const uint8_t rev = siba_get_revid(sc->sc_dev); 7549 const char *filename; 7550 uint32_t high; 7551 int error; 7552 7553 /* microcode */ 7554 if (rev >= 5 && rev <= 10) 7555 filename = "ucode5"; 7556 else if (rev >= 11 && rev <= 12) 7557 filename = "ucode11"; 7558 else if (rev == 13) 7559 filename = "ucode13"; 7560 else if (rev == 14) 7561 filename = "ucode14"; 7562 else if (rev >= 15) 7563 filename = "ucode15"; 7564 else { 7565 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7566 bwn_release_firmware(mac); 7567 return (EOPNOTSUPP); 7568 } 7569 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7570 if (error) { 7571 bwn_release_firmware(mac); 7572 return (error); 7573 } 7574 7575 /* PCM */ 7576 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7577 if (rev >= 5 && rev <= 10) { 7578 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7579 if (error == ENOENT) 7580 fw->no_pcmfile = 1; 7581 else if (error) { 7582 bwn_release_firmware(mac); 7583 return (error); 7584 } 7585 } else if (rev < 11) { 7586 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7587 return (EOPNOTSUPP); 7588 } 7589 7590 /* initvals */ 7591 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7592 switch (mac->mac_phy.type) { 7593 case BWN_PHYTYPE_A: 7594 if (rev < 5 || rev > 10) 7595 goto fail1; 7596 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7597 filename = "a0g1initvals5"; 7598 else 7599 filename = "a0g0initvals5"; 7600 break; 7601 case BWN_PHYTYPE_G: 7602 if (rev >= 5 && rev <= 10) 7603 filename = "b0g0initvals5"; 7604 else if (rev >= 13) 7605 filename = "b0g0initvals13"; 7606 else 7607 goto fail1; 7608 break; 7609 case BWN_PHYTYPE_LP: 7610 if (rev == 13) 7611 filename = "lp0initvals13"; 7612 else if (rev == 14) 7613 filename = "lp0initvals14"; 7614 else if (rev >= 15) 7615 filename = "lp0initvals15"; 7616 else 7617 goto fail1; 7618 break; 7619 case BWN_PHYTYPE_N: 7620 if (rev >= 11 && rev <= 12) 7621 filename = "n0initvals11"; 7622 else 7623 goto fail1; 7624 break; 7625 default: 7626 goto fail1; 7627 } 7628 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7629 if (error) { 7630 bwn_release_firmware(mac); 7631 return (error); 7632 } 7633 7634 /* bandswitch initvals */ 7635 switch (mac->mac_phy.type) { 7636 case BWN_PHYTYPE_A: 7637 if (rev >= 5 && rev <= 10) { 7638 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7639 filename = "a0g1bsinitvals5"; 7640 else 7641 filename = "a0g0bsinitvals5"; 7642 } else if (rev >= 11) 7643 filename = NULL; 7644 else 7645 goto fail1; 7646 break; 7647 case BWN_PHYTYPE_G: 7648 if (rev >= 5 && rev <= 10) 7649 filename = "b0g0bsinitvals5"; 7650 else if (rev >= 11) 7651 filename = NULL; 7652 else 7653 goto fail1; 7654 break; 7655 case BWN_PHYTYPE_LP: 7656 if (rev == 13) 7657 filename = "lp0bsinitvals13"; 7658 else if (rev == 14) 7659 filename = "lp0bsinitvals14"; 7660 else if (rev >= 15) 7661 filename = "lp0bsinitvals15"; 7662 else 7663 goto fail1; 7664 break; 7665 case BWN_PHYTYPE_N: 7666 if (rev >= 11 && rev <= 12) 7667 filename = "n0bsinitvals11"; 7668 else 7669 goto fail1; 7670 break; 7671 default: 7672 goto fail1; 7673 } 7674 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7675 if (error) { 7676 bwn_release_firmware(mac); 7677 return (error); 7678 } 7679 return (0); 7680 fail1: 7681 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7682 bwn_release_firmware(mac); 7683 return (EOPNOTSUPP); 7684 } 7685 7686 static int 7687 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7688 const char *name, struct bwn_fwfile *bfw) 7689 { 7690 const struct bwn_fwhdr *hdr; 7691 struct bwn_softc *sc = mac->mac_sc; 7692 const struct firmware *fw; 7693 char namebuf[64]; 7694 7695 if (name == NULL) { 7696 bwn_do_release_fw(bfw); 7697 return (0); 7698 } 7699 if (bfw->filename != NULL) { 7700 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7701 return (0); 7702 bwn_do_release_fw(bfw); 7703 } 7704 7705 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7706 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7707 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7708 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7709 fw = firmware_get(namebuf); 7710 if (fw == NULL) { 7711 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7712 namebuf); 7713 return (ENOENT); 7714 } 7715 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7716 goto fail; 7717 hdr = (const struct bwn_fwhdr *)(fw->data); 7718 switch (hdr->type) { 7719 case BWN_FWTYPE_UCODE: 7720 case BWN_FWTYPE_PCM: 7721 if (be32toh(hdr->size) != 7722 (fw->datasize - sizeof(struct bwn_fwhdr))) 7723 goto fail; 7724 /* FALLTHROUGH */ 7725 case BWN_FWTYPE_IV: 7726 if (hdr->ver != 1) 7727 goto fail; 7728 break; 7729 default: 7730 goto fail; 7731 } 7732 bfw->filename = name; 7733 bfw->fw = fw; 7734 bfw->type = type; 7735 return (0); 7736 fail: 7737 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7738 if (fw != NULL) 7739 firmware_put(fw, FIRMWARE_UNLOAD); 7740 return (EPROTO); 7741 } 7742 7743 static void 7744 bwn_release_firmware(struct bwn_mac *mac) 7745 { 7746 7747 bwn_do_release_fw(&mac->mac_fw.ucode); 7748 bwn_do_release_fw(&mac->mac_fw.pcm); 7749 bwn_do_release_fw(&mac->mac_fw.initvals); 7750 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7751 } 7752 7753 static void 7754 bwn_do_release_fw(struct bwn_fwfile *bfw) 7755 { 7756 7757 if (bfw->fw != NULL) 7758 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7759 bfw->fw = NULL; 7760 bfw->filename = NULL; 7761 } 7762 7763 static int 7764 bwn_fw_loaducode(struct bwn_mac *mac) 7765 { 7766 #define GETFWOFFSET(fwp, offset) \ 7767 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7768 #define GETFWSIZE(fwp, offset) \ 7769 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7770 struct bwn_softc *sc = mac->mac_sc; 7771 const uint32_t *data; 7772 unsigned int i; 7773 uint32_t ctl; 7774 uint16_t date, fwcaps, time; 7775 int error = 0; 7776 7777 ctl = BWN_READ_4(mac, BWN_MACCTL); 7778 ctl |= BWN_MACCTL_MCODE_JMP0; 7779 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7780 __LINE__)); 7781 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7782 for (i = 0; i < 64; i++) 7783 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7784 for (i = 0; i < 4096; i += 2) 7785 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7786 7787 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7788 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7789 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7790 i++) { 7791 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7792 DELAY(10); 7793 } 7794 7795 if (mac->mac_fw.pcm.fw) { 7796 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7797 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7798 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7799 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7800 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7801 sizeof(struct bwn_fwhdr)); i++) { 7802 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7803 DELAY(10); 7804 } 7805 } 7806 7807 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7808 BWN_WRITE_4(mac, BWN_MACCTL, 7809 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7810 BWN_MACCTL_MCODE_RUN); 7811 7812 for (i = 0; i < 21; i++) { 7813 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7814 break; 7815 if (i >= 20) { 7816 device_printf(sc->sc_dev, "ucode timeout\n"); 7817 error = ENXIO; 7818 goto error; 7819 } 7820 DELAY(50000); 7821 } 7822 BWN_READ_4(mac, BWN_INTR_REASON); 7823 7824 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7825 if (mac->mac_fw.rev <= 0x128) { 7826 device_printf(sc->sc_dev, "the firmware is too old\n"); 7827 error = EOPNOTSUPP; 7828 goto error; 7829 } 7830 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7831 BWN_SHARED_UCODE_PATCH); 7832 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7833 mac->mac_fw.opensource = (date == 0xffff); 7834 if (bwn_wme != 0) 7835 mac->mac_flags |= BWN_MAC_FLAG_WME; 7836 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7837 7838 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7839 if (mac->mac_fw.opensource == 0) { 7840 device_printf(sc->sc_dev, 7841 "firmware version (rev %u patch %u date %#x time %#x)\n", 7842 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7843 if (mac->mac_fw.no_pcmfile) 7844 device_printf(sc->sc_dev, 7845 "no HW crypto acceleration due to pcm5\n"); 7846 } else { 7847 mac->mac_fw.patch = time; 7848 fwcaps = bwn_fwcaps_read(mac); 7849 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7850 device_printf(sc->sc_dev, 7851 "disabling HW crypto acceleration\n"); 7852 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7853 } 7854 if (!(fwcaps & BWN_FWCAPS_WME)) { 7855 device_printf(sc->sc_dev, "disabling WME support\n"); 7856 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7857 } 7858 } 7859 7860 if (BWN_ISOLDFMT(mac)) 7861 device_printf(sc->sc_dev, "using old firmware image\n"); 7862 7863 return (0); 7864 7865 error: 7866 BWN_WRITE_4(mac, BWN_MACCTL, 7867 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7868 BWN_MACCTL_MCODE_JMP0); 7869 7870 return (error); 7871 #undef GETFWSIZE 7872 #undef GETFWOFFSET 7873 } 7874 7875 /* OpenFirmware only */ 7876 static uint16_t 7877 bwn_fwcaps_read(struct bwn_mac *mac) 7878 { 7879 7880 KASSERT(mac->mac_fw.opensource == 1, 7881 ("%s:%d: fail", __func__, __LINE__)); 7882 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7883 } 7884 7885 static int 7886 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7887 size_t count, size_t array_size) 7888 { 7889 #define GET_NEXTIV16(iv) \ 7890 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7891 sizeof(uint16_t) + sizeof(uint16_t))) 7892 #define GET_NEXTIV32(iv) \ 7893 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7894 sizeof(uint16_t) + sizeof(uint32_t))) 7895 struct bwn_softc *sc = mac->mac_sc; 7896 const struct bwn_fwinitvals *iv; 7897 uint16_t offset; 7898 size_t i; 7899 uint8_t bit32; 7900 7901 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7902 ("%s:%d: fail", __func__, __LINE__)); 7903 iv = ivals; 7904 for (i = 0; i < count; i++) { 7905 if (array_size < sizeof(iv->offset_size)) 7906 goto fail; 7907 array_size -= sizeof(iv->offset_size); 7908 offset = be16toh(iv->offset_size); 7909 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7910 offset &= BWN_FWINITVALS_OFFSET_MASK; 7911 if (offset >= 0x1000) 7912 goto fail; 7913 if (bit32) { 7914 if (array_size < sizeof(iv->data.d32)) 7915 goto fail; 7916 array_size -= sizeof(iv->data.d32); 7917 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7918 iv = GET_NEXTIV32(iv); 7919 } else { 7920 7921 if (array_size < sizeof(iv->data.d16)) 7922 goto fail; 7923 array_size -= sizeof(iv->data.d16); 7924 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7925 7926 iv = GET_NEXTIV16(iv); 7927 } 7928 } 7929 if (array_size != 0) 7930 goto fail; 7931 return (0); 7932 fail: 7933 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7934 return (EPROTO); 7935 #undef GET_NEXTIV16 7936 #undef GET_NEXTIV32 7937 } 7938 7939 static int 7940 bwn_switch_channel(struct bwn_mac *mac, int chan) 7941 { 7942 struct bwn_phy *phy = &(mac->mac_phy); 7943 struct bwn_softc *sc = mac->mac_sc; 7944 struct ifnet *ifp = sc->sc_ifp; 7945 struct ieee80211com *ic = ifp->if_l2com; 7946 uint16_t channelcookie, savedcookie; 7947 int error; 7948 7949 if (chan == 0xffff) 7950 chan = phy->get_default_chan(mac); 7951 7952 channelcookie = chan; 7953 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7954 channelcookie |= 0x100; 7955 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7956 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7957 error = phy->switch_channel(mac, chan); 7958 if (error) 7959 goto fail; 7960 7961 mac->mac_phy.chan = chan; 7962 DELAY(8000); 7963 return (0); 7964 fail: 7965 device_printf(sc->sc_dev, "failed to switch channel\n"); 7966 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7967 return (error); 7968 } 7969 7970 static uint16_t 7971 bwn_ant2phy(int antenna) 7972 { 7973 7974 switch (antenna) { 7975 case BWN_ANT0: 7976 return (BWN_TX_PHY_ANT0); 7977 case BWN_ANT1: 7978 return (BWN_TX_PHY_ANT1); 7979 case BWN_ANT2: 7980 return (BWN_TX_PHY_ANT2); 7981 case BWN_ANT3: 7982 return (BWN_TX_PHY_ANT3); 7983 case BWN_ANTAUTO: 7984 return (BWN_TX_PHY_ANT01AUTO); 7985 } 7986 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7987 return (0); 7988 } 7989 7990 static void 7991 bwn_wme_load(struct bwn_mac *mac) 7992 { 7993 struct bwn_softc *sc = mac->mac_sc; 7994 int i; 7995 7996 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7997 ("%s:%d: fail", __func__, __LINE__)); 7998 7999 bwn_mac_suspend(mac); 8000 for (i = 0; i < N(sc->sc_wmeParams); i++) 8001 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8002 bwn_wme_shm_offsets[i]); 8003 bwn_mac_enable(mac); 8004 } 8005 8006 static void 8007 bwn_wme_loadparams(struct bwn_mac *mac, 8008 const struct wmeParams *p, uint16_t shm_offset) 8009 { 8010 #define SM(_v, _f) (((_v) << _f##_S) & _f) 8011 struct bwn_softc *sc = mac->mac_sc; 8012 uint16_t params[BWN_NR_WMEPARAMS]; 8013 int slot, tmp; 8014 unsigned int i; 8015 8016 slot = BWN_READ_2(mac, BWN_RNG) & 8017 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8018 8019 memset(¶ms, 0, sizeof(params)); 8020 8021 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8022 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8023 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8024 8025 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8026 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8027 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8028 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8029 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8030 params[BWN_WMEPARAM_BSLOTS] = slot; 8031 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8032 8033 for (i = 0; i < N(params); i++) { 8034 if (i == BWN_WMEPARAM_STATUS) { 8035 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8036 shm_offset + (i * 2)); 8037 tmp |= 0x100; 8038 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8039 tmp); 8040 } else { 8041 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8042 params[i]); 8043 } 8044 } 8045 } 8046 8047 static void 8048 bwn_mac_write_bssid(struct bwn_mac *mac) 8049 { 8050 struct bwn_softc *sc = mac->mac_sc; 8051 uint32_t tmp; 8052 int i; 8053 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8054 8055 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8056 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8057 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8058 IEEE80211_ADDR_LEN); 8059 8060 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8061 tmp = (uint32_t) (mac_bssid[i + 0]); 8062 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8063 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8064 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8065 bwn_ram_write(mac, 0x20 + i, tmp); 8066 } 8067 } 8068 8069 static void 8070 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8071 const uint8_t *macaddr) 8072 { 8073 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8074 uint16_t data; 8075 8076 if (!mac) 8077 macaddr = zero; 8078 8079 offset |= 0x0020; 8080 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8081 8082 data = macaddr[0]; 8083 data |= macaddr[1] << 8; 8084 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8085 data = macaddr[2]; 8086 data |= macaddr[3] << 8; 8087 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8088 data = macaddr[4]; 8089 data |= macaddr[5] << 8; 8090 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8091 } 8092 8093 static void 8094 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8095 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8096 { 8097 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8098 uint8_t per_sta_keys_start = 8; 8099 8100 if (BWN_SEC_NEWAPI(mac)) 8101 per_sta_keys_start = 4; 8102 8103 KASSERT(index < mac->mac_max_nr_keys, 8104 ("%s:%d: fail", __func__, __LINE__)); 8105 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8106 ("%s:%d: fail", __func__, __LINE__)); 8107 8108 if (index >= per_sta_keys_start) 8109 bwn_key_macwrite(mac, index, NULL); 8110 if (key) 8111 memcpy(buf, key, key_len); 8112 bwn_key_write(mac, index, algorithm, buf); 8113 if (index >= per_sta_keys_start) 8114 bwn_key_macwrite(mac, index, mac_addr); 8115 8116 mac->mac_key[index].algorithm = algorithm; 8117 } 8118 8119 static void 8120 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8121 { 8122 struct bwn_softc *sc = mac->mac_sc; 8123 uint32_t addrtmp[2] = { 0, 0 }; 8124 uint8_t start = 8; 8125 8126 if (BWN_SEC_NEWAPI(mac)) 8127 start = 4; 8128 8129 KASSERT(index >= start, 8130 ("%s:%d: fail", __func__, __LINE__)); 8131 index -= start; 8132 8133 if (addr) { 8134 addrtmp[0] = addr[0]; 8135 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8136 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8137 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8138 addrtmp[1] = addr[4]; 8139 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8140 } 8141 8142 if (siba_get_revid(sc->sc_dev) >= 5) { 8143 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8144 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8145 } else { 8146 if (index >= 8) { 8147 bwn_shm_write_4(mac, BWN_SHARED, 8148 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8149 bwn_shm_write_2(mac, BWN_SHARED, 8150 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8151 } 8152 } 8153 } 8154 8155 static void 8156 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8157 const uint8_t *key) 8158 { 8159 unsigned int i; 8160 uint32_t offset; 8161 uint16_t kidx, value; 8162 8163 kidx = BWN_SEC_KEY2FW(mac, index); 8164 bwn_shm_write_2(mac, BWN_SHARED, 8165 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8166 8167 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8168 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8169 value = key[i]; 8170 value |= (uint16_t)(key[i + 1]) << 8; 8171 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8172 } 8173 } 8174 8175 static void 8176 bwn_phy_exit(struct bwn_mac *mac) 8177 { 8178 8179 mac->mac_phy.rf_onoff(mac, 0); 8180 if (mac->mac_phy.exit != NULL) 8181 mac->mac_phy.exit(mac); 8182 } 8183 8184 static void 8185 bwn_dma_free(struct bwn_mac *mac) 8186 { 8187 struct bwn_dma *dma; 8188 8189 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8190 return; 8191 dma = &mac->mac_method.dma; 8192 8193 bwn_dma_ringfree(&dma->rx); 8194 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8195 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8196 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8197 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8198 bwn_dma_ringfree(&dma->mcast); 8199 } 8200 8201 static void 8202 bwn_core_stop(struct bwn_mac *mac) 8203 { 8204 struct bwn_softc *sc = mac->mac_sc; 8205 8206 BWN_ASSERT_LOCKED(sc); 8207 8208 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8209 return; 8210 8211 callout_stop(&sc->sc_rfswitch_ch); 8212 callout_stop(&sc->sc_task_ch); 8213 callout_stop(&sc->sc_watchdog_ch); 8214 sc->sc_watchdog_timer = 0; 8215 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8216 BWN_READ_4(mac, BWN_INTR_MASK); 8217 bwn_mac_suspend(mac); 8218 8219 mac->mac_status = BWN_MAC_STATUS_INITED; 8220 } 8221 8222 static int 8223 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8224 { 8225 struct bwn_mac *up_dev = NULL; 8226 struct bwn_mac *down_dev; 8227 struct bwn_mac *mac; 8228 int err, status; 8229 uint8_t gmode; 8230 8231 BWN_ASSERT_LOCKED(sc); 8232 8233 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8234 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8235 mac->mac_phy.supports_2ghz) { 8236 up_dev = mac; 8237 gmode = 1; 8238 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8239 mac->mac_phy.supports_5ghz) { 8240 up_dev = mac; 8241 gmode = 0; 8242 } else { 8243 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8244 return (EINVAL); 8245 } 8246 if (up_dev != NULL) 8247 break; 8248 } 8249 if (up_dev == NULL) { 8250 device_printf(sc->sc_dev, "Could not find a device\n"); 8251 return (ENODEV); 8252 } 8253 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8254 return (0); 8255 8256 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8257 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8258 8259 down_dev = sc->sc_curmac; 8260 status = down_dev->mac_status; 8261 if (status >= BWN_MAC_STATUS_STARTED) 8262 bwn_core_stop(down_dev); 8263 if (status >= BWN_MAC_STATUS_INITED) 8264 bwn_core_exit(down_dev); 8265 8266 if (down_dev != up_dev) 8267 bwn_phy_reset(down_dev); 8268 8269 up_dev->mac_phy.gmode = gmode; 8270 if (status >= BWN_MAC_STATUS_INITED) { 8271 err = bwn_core_init(up_dev); 8272 if (err) { 8273 device_printf(sc->sc_dev, 8274 "fatal: failed to initialize for %s-GHz\n", 8275 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8276 goto fail; 8277 } 8278 } 8279 if (status >= BWN_MAC_STATUS_STARTED) 8280 bwn_core_start(up_dev); 8281 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8282 sc->sc_curmac = up_dev; 8283 8284 return (0); 8285 fail: 8286 sc->sc_curmac = NULL; 8287 return (err); 8288 } 8289 8290 static void 8291 bwn_rf_turnon(struct bwn_mac *mac) 8292 { 8293 8294 bwn_mac_suspend(mac); 8295 mac->mac_phy.rf_onoff(mac, 1); 8296 mac->mac_phy.rf_on = 1; 8297 bwn_mac_enable(mac); 8298 } 8299 8300 static void 8301 bwn_rf_turnoff(struct bwn_mac *mac) 8302 { 8303 8304 bwn_mac_suspend(mac); 8305 mac->mac_phy.rf_onoff(mac, 0); 8306 mac->mac_phy.rf_on = 0; 8307 bwn_mac_enable(mac); 8308 } 8309 8310 static void 8311 bwn_phy_reset(struct bwn_mac *mac) 8312 { 8313 struct bwn_softc *sc = mac->mac_sc; 8314 8315 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8316 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8317 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8318 DELAY(1000); 8319 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8320 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8321 BWN_TGSLOW_PHYRESET); 8322 DELAY(1000); 8323 } 8324 8325 static int 8326 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8327 { 8328 struct bwn_vap *bvp = BWN_VAP(vap); 8329 struct ieee80211com *ic= vap->iv_ic; 8330 struct ifnet *ifp = ic->ic_ifp; 8331 enum ieee80211_state ostate = vap->iv_state; 8332 struct bwn_softc *sc = ifp->if_softc; 8333 struct bwn_mac *mac = sc->sc_curmac; 8334 int error; 8335 8336 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8337 ieee80211_state_name[vap->iv_state], 8338 ieee80211_state_name[nstate]); 8339 8340 error = bvp->bv_newstate(vap, nstate, arg); 8341 if (error != 0) 8342 return (error); 8343 8344 BWN_LOCK(sc); 8345 8346 bwn_led_newstate(mac, nstate); 8347 8348 /* 8349 * Clear the BSSID when we stop a STA 8350 */ 8351 if (vap->iv_opmode == IEEE80211_M_STA) { 8352 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8353 /* 8354 * Clear out the BSSID. If we reassociate to 8355 * the same AP, this will reinialize things 8356 * correctly... 8357 */ 8358 if (ic->ic_opmode == IEEE80211_M_STA && 8359 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8360 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8361 bwn_set_macaddr(mac); 8362 } 8363 } 8364 } 8365 8366 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8367 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8368 /* XXX nothing to do? */ 8369 } else if (nstate == IEEE80211_S_RUN) { 8370 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8371 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8372 bwn_set_opmode(mac); 8373 bwn_set_pretbtt(mac); 8374 bwn_spu_setdelay(mac, 0); 8375 bwn_set_macaddr(mac); 8376 } 8377 8378 BWN_UNLOCK(sc); 8379 8380 return (error); 8381 } 8382 8383 static void 8384 bwn_set_pretbtt(struct bwn_mac *mac) 8385 { 8386 struct bwn_softc *sc = mac->mac_sc; 8387 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8388 uint16_t pretbtt; 8389 8390 if (ic->ic_opmode == IEEE80211_M_IBSS) 8391 pretbtt = 2; 8392 else 8393 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8394 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8395 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8396 } 8397 8398 static int 8399 bwn_intr(void *arg) 8400 { 8401 struct bwn_mac *mac = arg; 8402 struct bwn_softc *sc = mac->mac_sc; 8403 uint32_t reason; 8404 8405 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8406 (sc->sc_flags & BWN_FLAG_INVALID)) 8407 return (FILTER_STRAY); 8408 8409 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8410 if (reason == 0xffffffff) /* shared IRQ */ 8411 return (FILTER_STRAY); 8412 reason &= mac->mac_intr_mask; 8413 if (reason == 0) 8414 return (FILTER_HANDLED); 8415 8416 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8417 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8418 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8419 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8420 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8421 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8422 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8423 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8424 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8425 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8426 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8427 8428 /* Disable interrupts. */ 8429 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8430 8431 mac->mac_reason_intr = reason; 8432 8433 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8434 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8435 8436 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8437 return (FILTER_HANDLED); 8438 } 8439 8440 static void 8441 bwn_intrtask(void *arg, int npending) 8442 { 8443 struct bwn_mac *mac = arg; 8444 struct bwn_softc *sc = mac->mac_sc; 8445 struct ifnet *ifp = sc->sc_ifp; 8446 uint32_t merged = 0; 8447 int i, tx = 0, rx = 0; 8448 8449 BWN_LOCK(sc); 8450 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8451 (sc->sc_flags & BWN_FLAG_INVALID)) { 8452 BWN_UNLOCK(sc); 8453 return; 8454 } 8455 8456 for (i = 0; i < N(mac->mac_reason); i++) 8457 merged |= mac->mac_reason[i]; 8458 8459 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8460 device_printf(sc->sc_dev, "MAC trans error\n"); 8461 8462 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8463 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8464 mac->mac_phy.txerrors--; 8465 if (mac->mac_phy.txerrors == 0) { 8466 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8467 bwn_restart(mac, "PHY TX errors"); 8468 } 8469 } 8470 8471 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8472 if (merged & BWN_DMAINTR_FATALMASK) { 8473 device_printf(sc->sc_dev, 8474 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8475 mac->mac_reason[0], mac->mac_reason[1], 8476 mac->mac_reason[2], mac->mac_reason[3], 8477 mac->mac_reason[4], mac->mac_reason[5]); 8478 bwn_restart(mac, "DMA error"); 8479 BWN_UNLOCK(sc); 8480 return; 8481 } 8482 if (merged & BWN_DMAINTR_NONFATALMASK) { 8483 device_printf(sc->sc_dev, 8484 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8485 mac->mac_reason[0], mac->mac_reason[1], 8486 mac->mac_reason[2], mac->mac_reason[3], 8487 mac->mac_reason[4], mac->mac_reason[5]); 8488 } 8489 } 8490 8491 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8492 bwn_intr_ucode_debug(mac); 8493 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8494 bwn_intr_tbtt_indication(mac); 8495 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8496 bwn_intr_atim_end(mac); 8497 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8498 bwn_intr_beacon(mac); 8499 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8500 bwn_intr_pmq(mac); 8501 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8502 bwn_intr_noise(mac); 8503 8504 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8505 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8506 bwn_dma_rx(mac->mac_method.dma.rx); 8507 rx = 1; 8508 } 8509 } else 8510 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8511 8512 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8513 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8514 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8515 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8516 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8517 8518 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8519 bwn_intr_txeof(mac); 8520 tx = 1; 8521 } 8522 8523 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8524 8525 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8526 int evt = BWN_LED_EVENT_NONE; 8527 8528 if (tx && rx) { 8529 if (sc->sc_rx_rate > sc->sc_tx_rate) 8530 evt = BWN_LED_EVENT_RX; 8531 else 8532 evt = BWN_LED_EVENT_TX; 8533 } else if (tx) { 8534 evt = BWN_LED_EVENT_TX; 8535 } else if (rx) { 8536 evt = BWN_LED_EVENT_RX; 8537 } else if (rx == 0) { 8538 evt = BWN_LED_EVENT_POLL; 8539 } 8540 8541 if (evt != BWN_LED_EVENT_NONE) 8542 bwn_led_event(mac, evt); 8543 } 8544 8545 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8546 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8547 bwn_start_locked(ifp); 8548 } 8549 8550 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8551 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8552 8553 BWN_UNLOCK(sc); 8554 } 8555 8556 static void 8557 bwn_restart(struct bwn_mac *mac, const char *msg) 8558 { 8559 struct bwn_softc *sc = mac->mac_sc; 8560 struct ifnet *ifp = sc->sc_ifp; 8561 struct ieee80211com *ic = ifp->if_l2com; 8562 8563 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8564 return; 8565 8566 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8567 ieee80211_runtask(ic, &mac->mac_hwreset); 8568 } 8569 8570 static void 8571 bwn_intr_ucode_debug(struct bwn_mac *mac) 8572 { 8573 struct bwn_softc *sc = mac->mac_sc; 8574 uint16_t reason; 8575 8576 if (mac->mac_fw.opensource == 0) 8577 return; 8578 8579 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8580 switch (reason) { 8581 case BWN_DEBUGINTR_PANIC: 8582 bwn_handle_fwpanic(mac); 8583 break; 8584 case BWN_DEBUGINTR_DUMP_SHM: 8585 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8586 break; 8587 case BWN_DEBUGINTR_DUMP_REGS: 8588 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8589 break; 8590 case BWN_DEBUGINTR_MARKER: 8591 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8592 break; 8593 default: 8594 device_printf(sc->sc_dev, 8595 "ucode debug unknown reason: %#x\n", reason); 8596 } 8597 8598 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8599 BWN_DEBUGINTR_ACK); 8600 } 8601 8602 static void 8603 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8604 { 8605 struct bwn_softc *sc = mac->mac_sc; 8606 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8607 8608 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8609 bwn_psctl(mac, 0); 8610 if (ic->ic_opmode == IEEE80211_M_IBSS) 8611 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8612 } 8613 8614 static void 8615 bwn_intr_atim_end(struct bwn_mac *mac) 8616 { 8617 8618 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8619 BWN_WRITE_4(mac, BWN_MACCMD, 8620 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8621 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8622 } 8623 } 8624 8625 static void 8626 bwn_intr_beacon(struct bwn_mac *mac) 8627 { 8628 struct bwn_softc *sc = mac->mac_sc; 8629 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8630 uint32_t cmd, beacon0, beacon1; 8631 8632 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8633 ic->ic_opmode == IEEE80211_M_MBSS) 8634 return; 8635 8636 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8637 8638 cmd = BWN_READ_4(mac, BWN_MACCMD); 8639 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8640 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8641 8642 if (beacon0 && beacon1) { 8643 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8644 mac->mac_intr_mask |= BWN_INTR_BEACON; 8645 return; 8646 } 8647 8648 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8649 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8650 bwn_load_beacon0(mac); 8651 bwn_load_beacon1(mac); 8652 cmd = BWN_READ_4(mac, BWN_MACCMD); 8653 cmd |= BWN_MACCMD_BEACON0_VALID; 8654 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8655 } else { 8656 if (!beacon0) { 8657 bwn_load_beacon0(mac); 8658 cmd = BWN_READ_4(mac, BWN_MACCMD); 8659 cmd |= BWN_MACCMD_BEACON0_VALID; 8660 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8661 } else if (!beacon1) { 8662 bwn_load_beacon1(mac); 8663 cmd = BWN_READ_4(mac, BWN_MACCMD); 8664 cmd |= BWN_MACCMD_BEACON1_VALID; 8665 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8666 } 8667 } 8668 } 8669 8670 static void 8671 bwn_intr_pmq(struct bwn_mac *mac) 8672 { 8673 uint32_t tmp; 8674 8675 while (1) { 8676 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8677 if (!(tmp & 0x00000008)) 8678 break; 8679 } 8680 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8681 } 8682 8683 static void 8684 bwn_intr_noise(struct bwn_mac *mac) 8685 { 8686 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8687 uint16_t tmp; 8688 uint8_t noise[4]; 8689 uint8_t i, j; 8690 int32_t average; 8691 8692 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8693 return; 8694 8695 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8696 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8697 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8698 noise[3] == 0x7f) 8699 goto new; 8700 8701 KASSERT(mac->mac_noise.noi_nsamples < 8, 8702 ("%s:%d: fail", __func__, __LINE__)); 8703 i = mac->mac_noise.noi_nsamples; 8704 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8705 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8706 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8707 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8708 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8709 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8710 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8711 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8712 mac->mac_noise.noi_nsamples++; 8713 if (mac->mac_noise.noi_nsamples == 8) { 8714 average = 0; 8715 for (i = 0; i < 8; i++) { 8716 for (j = 0; j < 4; j++) 8717 average += mac->mac_noise.noi_samples[i][j]; 8718 } 8719 average = (((average / 32) * 125) + 64) / 128; 8720 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8721 if (tmp >= 8) 8722 average += 2; 8723 else 8724 average -= 25; 8725 average -= (tmp == 8) ? 72 : 48; 8726 8727 mac->mac_stats.link_noise = average; 8728 mac->mac_noise.noi_running = 0; 8729 return; 8730 } 8731 new: 8732 bwn_noise_gensample(mac); 8733 } 8734 8735 static int 8736 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8737 { 8738 struct bwn_mac *mac = prq->prq_mac; 8739 struct bwn_softc *sc = mac->mac_sc; 8740 unsigned int i; 8741 8742 BWN_ASSERT_LOCKED(sc); 8743 8744 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8745 return (0); 8746 8747 for (i = 0; i < 5000; i++) { 8748 if (bwn_pio_rxeof(prq) == 0) 8749 break; 8750 } 8751 if (i >= 5000) 8752 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8753 return ((i > 0) ? 1 : 0); 8754 } 8755 8756 static void 8757 bwn_dma_rx(struct bwn_dma_ring *dr) 8758 { 8759 int slot, curslot; 8760 8761 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8762 curslot = dr->get_curslot(dr); 8763 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8764 ("%s:%d: fail", __func__, __LINE__)); 8765 8766 slot = dr->dr_curslot; 8767 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8768 bwn_dma_rxeof(dr, &slot); 8769 8770 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8771 BUS_DMASYNC_PREWRITE); 8772 8773 dr->set_curslot(dr, slot); 8774 dr->dr_curslot = slot; 8775 } 8776 8777 static void 8778 bwn_intr_txeof(struct bwn_mac *mac) 8779 { 8780 struct bwn_txstatus stat; 8781 uint32_t stat0, stat1; 8782 uint16_t tmp; 8783 8784 BWN_ASSERT_LOCKED(mac->mac_sc); 8785 8786 while (1) { 8787 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8788 if (!(stat0 & 0x00000001)) 8789 break; 8790 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8791 8792 stat.cookie = (stat0 >> 16); 8793 stat.seq = (stat1 & 0x0000ffff); 8794 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8795 tmp = (stat0 & 0x0000ffff); 8796 stat.framecnt = ((tmp & 0xf000) >> 12); 8797 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8798 stat.sreason = ((tmp & 0x001c) >> 2); 8799 stat.pm = (tmp & 0x0080) ? 1 : 0; 8800 stat.im = (tmp & 0x0040) ? 1 : 0; 8801 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8802 stat.ack = (tmp & 0x0002) ? 1 : 0; 8803 8804 bwn_handle_txeof(mac, &stat); 8805 } 8806 } 8807 8808 static void 8809 bwn_hwreset(void *arg, int npending) 8810 { 8811 struct bwn_mac *mac = arg; 8812 struct bwn_softc *sc = mac->mac_sc; 8813 int error = 0; 8814 int prev_status; 8815 8816 BWN_LOCK(sc); 8817 8818 prev_status = mac->mac_status; 8819 if (prev_status >= BWN_MAC_STATUS_STARTED) 8820 bwn_core_stop(mac); 8821 if (prev_status >= BWN_MAC_STATUS_INITED) 8822 bwn_core_exit(mac); 8823 8824 if (prev_status >= BWN_MAC_STATUS_INITED) { 8825 error = bwn_core_init(mac); 8826 if (error) 8827 goto out; 8828 } 8829 if (prev_status >= BWN_MAC_STATUS_STARTED) 8830 bwn_core_start(mac); 8831 out: 8832 if (error) { 8833 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8834 sc->sc_curmac = NULL; 8835 } 8836 BWN_UNLOCK(sc); 8837 } 8838 8839 static void 8840 bwn_handle_fwpanic(struct bwn_mac *mac) 8841 { 8842 struct bwn_softc *sc = mac->mac_sc; 8843 uint16_t reason; 8844 8845 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8846 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8847 8848 if (reason == BWN_FWPANIC_RESTART) 8849 bwn_restart(mac, "ucode panic"); 8850 } 8851 8852 static void 8853 bwn_load_beacon0(struct bwn_mac *mac) 8854 { 8855 8856 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8857 } 8858 8859 static void 8860 bwn_load_beacon1(struct bwn_mac *mac) 8861 { 8862 8863 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8864 } 8865 8866 static uint32_t 8867 bwn_jssi_read(struct bwn_mac *mac) 8868 { 8869 uint32_t val = 0; 8870 8871 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8872 val <<= 16; 8873 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8874 8875 return (val); 8876 } 8877 8878 static void 8879 bwn_noise_gensample(struct bwn_mac *mac) 8880 { 8881 uint32_t jssi = 0x7f7f7f7f; 8882 8883 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8884 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8885 BWN_WRITE_4(mac, BWN_MACCMD, 8886 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8887 } 8888 8889 static int 8890 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8891 { 8892 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8893 8894 return (dr->dr_numslots - dr->dr_usedslot); 8895 } 8896 8897 static int 8898 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8899 { 8900 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8901 8902 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8903 ("%s:%d: fail", __func__, __LINE__)); 8904 if (slot == dr->dr_numslots - 1) 8905 return (0); 8906 return (slot + 1); 8907 } 8908 8909 static void 8910 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8911 { 8912 struct bwn_mac *mac = dr->dr_mac; 8913 struct bwn_softc *sc = mac->mac_sc; 8914 struct bwn_dma *dma = &mac->mac_method.dma; 8915 struct bwn_dmadesc_generic *desc; 8916 struct bwn_dmadesc_meta *meta; 8917 struct bwn_rxhdr4 *rxhdr; 8918 struct ifnet *ifp = sc->sc_ifp; 8919 struct mbuf *m; 8920 uint32_t macstat; 8921 int32_t tmp; 8922 int cnt = 0; 8923 uint16_t len; 8924 8925 dr->getdesc(dr, *slot, &desc, &meta); 8926 8927 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8928 m = meta->mt_m; 8929 8930 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8931 ifp->if_ierrors++; 8932 return; 8933 } 8934 8935 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8936 len = le16toh(rxhdr->frame_len); 8937 if (len <= 0) { 8938 ifp->if_ierrors++; 8939 return; 8940 } 8941 if (bwn_dma_check_redzone(dr, m)) { 8942 device_printf(sc->sc_dev, "redzone error.\n"); 8943 bwn_dma_set_redzone(dr, m); 8944 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8945 BUS_DMASYNC_PREWRITE); 8946 return; 8947 } 8948 if (len > dr->dr_rx_bufsize) { 8949 tmp = len; 8950 while (1) { 8951 dr->getdesc(dr, *slot, &desc, &meta); 8952 bwn_dma_set_redzone(dr, meta->mt_m); 8953 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8954 BUS_DMASYNC_PREWRITE); 8955 *slot = bwn_dma_nextslot(dr, *slot); 8956 cnt++; 8957 tmp -= dr->dr_rx_bufsize; 8958 if (tmp <= 0) 8959 break; 8960 } 8961 device_printf(sc->sc_dev, "too small buffer " 8962 "(len %u buffer %u dropped %d)\n", 8963 len, dr->dr_rx_bufsize, cnt); 8964 return; 8965 } 8966 macstat = le32toh(rxhdr->mac_status); 8967 if (macstat & BWN_RX_MAC_FCSERR) { 8968 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8969 device_printf(sc->sc_dev, "RX drop\n"); 8970 return; 8971 } 8972 } 8973 8974 m->m_pkthdr.rcvif = ifp; 8975 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8976 m_adj(m, dr->dr_frameoffset); 8977 8978 bwn_rxeof(dr->dr_mac, m, rxhdr); 8979 } 8980 8981 static void 8982 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8983 { 8984 struct bwn_dma_ring *dr; 8985 struct bwn_dmadesc_generic *desc; 8986 struct bwn_dmadesc_meta *meta; 8987 struct bwn_pio_txqueue *tq; 8988 struct bwn_pio_txpkt *tp = NULL; 8989 struct bwn_softc *sc = mac->mac_sc; 8990 struct bwn_stats *stats = &mac->mac_stats; 8991 struct ieee80211_node *ni; 8992 struct ieee80211vap *vap; 8993 int retrycnt = 0, slot; 8994 8995 BWN_ASSERT_LOCKED(mac->mac_sc); 8996 8997 if (status->im) 8998 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8999 if (status->ampdu) 9000 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9001 if (status->rtscnt) { 9002 if (status->rtscnt == 0xf) 9003 stats->rtsfail++; 9004 else 9005 stats->rts++; 9006 } 9007 9008 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9009 if (status->ack) { 9010 dr = bwn_dma_parse_cookie(mac, status, 9011 status->cookie, &slot); 9012 if (dr == NULL) { 9013 device_printf(sc->sc_dev, 9014 "failed to parse cookie\n"); 9015 return; 9016 } 9017 while (1) { 9018 dr->getdesc(dr, slot, &desc, &meta); 9019 if (meta->mt_islast) { 9020 ni = meta->mt_ni; 9021 vap = ni->ni_vap; 9022 ieee80211_ratectl_tx_complete(vap, ni, 9023 status->ack ? 9024 IEEE80211_RATECTL_TX_SUCCESS : 9025 IEEE80211_RATECTL_TX_FAILURE, 9026 &retrycnt, 0); 9027 break; 9028 } 9029 slot = bwn_dma_nextslot(dr, slot); 9030 } 9031 } 9032 bwn_dma_handle_txeof(mac, status); 9033 } else { 9034 if (status->ack) { 9035 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9036 if (tq == NULL) { 9037 device_printf(sc->sc_dev, 9038 "failed to parse cookie\n"); 9039 return; 9040 } 9041 ni = tp->tp_ni; 9042 vap = ni->ni_vap; 9043 ieee80211_ratectl_tx_complete(vap, ni, 9044 status->ack ? 9045 IEEE80211_RATECTL_TX_SUCCESS : 9046 IEEE80211_RATECTL_TX_FAILURE, 9047 &retrycnt, 0); 9048 } 9049 bwn_pio_handle_txeof(mac, status); 9050 } 9051 9052 bwn_phy_txpower_check(mac, 0); 9053 } 9054 9055 static uint8_t 9056 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9057 { 9058 struct bwn_mac *mac = prq->prq_mac; 9059 struct bwn_softc *sc = mac->mac_sc; 9060 struct bwn_rxhdr4 rxhdr; 9061 struct ifnet *ifp = sc->sc_ifp; 9062 struct mbuf *m; 9063 uint32_t ctl32, macstat, v32; 9064 unsigned int i, padding; 9065 uint16_t ctl16, len, totlen, v16; 9066 unsigned char *mp; 9067 char *data; 9068 9069 memset(&rxhdr, 0, sizeof(rxhdr)); 9070 9071 if (prq->prq_rev >= 8) { 9072 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9073 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9074 return (0); 9075 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9076 BWN_PIO8_RXCTL_FRAMEREADY); 9077 for (i = 0; i < 10; i++) { 9078 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9079 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9080 goto ready; 9081 DELAY(10); 9082 } 9083 } else { 9084 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9085 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9086 return (0); 9087 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9088 BWN_PIO_RXCTL_FRAMEREADY); 9089 for (i = 0; i < 10; i++) { 9090 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9091 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9092 goto ready; 9093 DELAY(10); 9094 } 9095 } 9096 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9097 return (1); 9098 ready: 9099 if (prq->prq_rev >= 8) 9100 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9101 prq->prq_base + BWN_PIO8_RXDATA); 9102 else 9103 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9104 prq->prq_base + BWN_PIO_RXDATA); 9105 len = le16toh(rxhdr.frame_len); 9106 if (len > 0x700) { 9107 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9108 goto error; 9109 } 9110 if (len == 0) { 9111 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9112 goto error; 9113 } 9114 9115 macstat = le32toh(rxhdr.mac_status); 9116 if (macstat & BWN_RX_MAC_FCSERR) { 9117 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9118 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9119 goto error; 9120 } 9121 } 9122 9123 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9124 totlen = len + padding; 9125 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9126 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9127 if (m == NULL) { 9128 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9129 goto error; 9130 } 9131 mp = mtod(m, unsigned char *); 9132 if (prq->prq_rev >= 8) { 9133 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9134 prq->prq_base + BWN_PIO8_RXDATA); 9135 if (totlen & 3) { 9136 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9137 data = &(mp[totlen - 1]); 9138 switch (totlen & 3) { 9139 case 3: 9140 *data = (v32 >> 16); 9141 data--; 9142 case 2: 9143 *data = (v32 >> 8); 9144 data--; 9145 case 1: 9146 *data = v32; 9147 } 9148 } 9149 } else { 9150 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9151 prq->prq_base + BWN_PIO_RXDATA); 9152 if (totlen & 1) { 9153 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9154 mp[totlen - 1] = v16; 9155 } 9156 } 9157 9158 m->m_pkthdr.rcvif = ifp; 9159 m->m_len = m->m_pkthdr.len = totlen; 9160 9161 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9162 9163 return (1); 9164 error: 9165 if (prq->prq_rev >= 8) 9166 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9167 BWN_PIO8_RXCTL_DATAREADY); 9168 else 9169 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9170 return (1); 9171 } 9172 9173 static int 9174 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9175 struct bwn_dmadesc_meta *meta, int init) 9176 { 9177 struct bwn_mac *mac = dr->dr_mac; 9178 struct bwn_dma *dma = &mac->mac_method.dma; 9179 struct bwn_rxhdr4 *hdr; 9180 bus_dmamap_t map; 9181 bus_addr_t paddr; 9182 struct mbuf *m; 9183 int error; 9184 9185 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9186 if (m == NULL) { 9187 error = ENOBUFS; 9188 9189 /* 9190 * If the NIC is up and running, we need to: 9191 * - Clear RX buffer's header. 9192 * - Restore RX descriptor settings. 9193 */ 9194 if (init) 9195 return (error); 9196 else 9197 goto back; 9198 } 9199 m->m_len = m->m_pkthdr.len = MCLBYTES; 9200 9201 bwn_dma_set_redzone(dr, m); 9202 9203 /* 9204 * Try to load RX buf into temporary DMA map 9205 */ 9206 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9207 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9208 if (error) { 9209 m_freem(m); 9210 9211 /* 9212 * See the comment above 9213 */ 9214 if (init) 9215 return (error); 9216 else 9217 goto back; 9218 } 9219 9220 if (!init) 9221 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9222 meta->mt_m = m; 9223 meta->mt_paddr = paddr; 9224 9225 /* 9226 * Swap RX buf's DMA map with the loaded temporary one 9227 */ 9228 map = meta->mt_dmap; 9229 meta->mt_dmap = dr->dr_spare_dmap; 9230 dr->dr_spare_dmap = map; 9231 9232 back: 9233 /* 9234 * Clear RX buf header 9235 */ 9236 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9237 bzero(hdr, sizeof(*hdr)); 9238 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9239 BUS_DMASYNC_PREWRITE); 9240 9241 /* 9242 * Setup RX buf descriptor 9243 */ 9244 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len - 9245 sizeof(*hdr), 0, 0, 0); 9246 return (error); 9247 } 9248 9249 static void 9250 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9251 bus_size_t mapsz __unused, int error) 9252 { 9253 9254 if (!error) { 9255 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9256 *((bus_addr_t *)arg) = seg->ds_addr; 9257 } 9258 } 9259 9260 static int 9261 bwn_hwrate2ieeerate(int rate) 9262 { 9263 9264 switch (rate) { 9265 case BWN_CCK_RATE_1MB: 9266 return (2); 9267 case BWN_CCK_RATE_2MB: 9268 return (4); 9269 case BWN_CCK_RATE_5MB: 9270 return (11); 9271 case BWN_CCK_RATE_11MB: 9272 return (22); 9273 case BWN_OFDM_RATE_6MB: 9274 return (12); 9275 case BWN_OFDM_RATE_9MB: 9276 return (18); 9277 case BWN_OFDM_RATE_12MB: 9278 return (24); 9279 case BWN_OFDM_RATE_18MB: 9280 return (36); 9281 case BWN_OFDM_RATE_24MB: 9282 return (48); 9283 case BWN_OFDM_RATE_36MB: 9284 return (72); 9285 case BWN_OFDM_RATE_48MB: 9286 return (96); 9287 case BWN_OFDM_RATE_54MB: 9288 return (108); 9289 default: 9290 printf("Ooops\n"); 9291 return (0); 9292 } 9293 } 9294 9295 static void 9296 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9297 { 9298 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9299 struct bwn_plcp6 *plcp; 9300 struct bwn_softc *sc = mac->mac_sc; 9301 struct ieee80211_frame_min *wh; 9302 struct ieee80211_node *ni; 9303 struct ifnet *ifp = sc->sc_ifp; 9304 struct ieee80211com *ic = ifp->if_l2com; 9305 uint32_t macstat; 9306 int padding, rate, rssi = 0, noise = 0, type; 9307 uint16_t phytype, phystat0, phystat3, chanstat; 9308 unsigned char *mp = mtod(m, unsigned char *); 9309 static int rx_mac_dec_rpt = 0; 9310 9311 BWN_ASSERT_LOCKED(sc); 9312 9313 phystat0 = le16toh(rxhdr->phy_status0); 9314 phystat3 = le16toh(rxhdr->phy_status3); 9315 macstat = le32toh(rxhdr->mac_status); 9316 chanstat = le16toh(rxhdr->channel); 9317 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9318 9319 if (macstat & BWN_RX_MAC_FCSERR) 9320 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9321 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9322 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9323 if (macstat & BWN_RX_MAC_DECERR) 9324 goto drop; 9325 9326 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9327 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9328 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9329 m->m_pkthdr.len); 9330 goto drop; 9331 } 9332 plcp = (struct bwn_plcp6 *)(mp + padding); 9333 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9334 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9335 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9336 m->m_pkthdr.len); 9337 goto drop; 9338 } 9339 wh = mtod(m, struct ieee80211_frame_min *); 9340 9341 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9342 device_printf(sc->sc_dev, 9343 "RX decryption attempted (old %d keyidx %#x)\n", 9344 BWN_ISOLDFMT(mac), 9345 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9346 9347 /* XXX calculating RSSI & noise & antenna */ 9348 9349 if (phystat0 & BWN_RX_PHYST0_OFDM) 9350 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9351 phytype == BWN_PHYTYPE_A); 9352 else 9353 rate = bwn_plcp_get_cckrate(mac, plcp); 9354 if (rate == -1) { 9355 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9356 goto drop; 9357 } 9358 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9359 9360 /* RX radio tap */ 9361 if (ieee80211_radiotap_active(ic)) 9362 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9363 m_adj(m, -IEEE80211_CRC_LEN); 9364 9365 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9366 noise = mac->mac_stats.link_noise; 9367 9368 ifp->if_ipackets++; 9369 9370 BWN_UNLOCK(sc); 9371 9372 ni = ieee80211_find_rxnode(ic, wh); 9373 if (ni != NULL) { 9374 type = ieee80211_input(ni, m, rssi, noise); 9375 ieee80211_free_node(ni); 9376 } else 9377 type = ieee80211_input_all(ic, m, rssi, noise); 9378 9379 BWN_LOCK(sc); 9380 return; 9381 drop: 9382 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9383 } 9384 9385 static void 9386 bwn_dma_handle_txeof(struct bwn_mac *mac, 9387 const struct bwn_txstatus *status) 9388 { 9389 struct bwn_dma *dma = &mac->mac_method.dma; 9390 struct bwn_dma_ring *dr; 9391 struct bwn_dmadesc_generic *desc; 9392 struct bwn_dmadesc_meta *meta; 9393 struct bwn_softc *sc = mac->mac_sc; 9394 struct ieee80211_node *ni; 9395 struct ifnet *ifp = sc->sc_ifp; 9396 struct mbuf *m; 9397 int slot; 9398 9399 BWN_ASSERT_LOCKED(sc); 9400 9401 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9402 if (dr == NULL) { 9403 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9404 return; 9405 } 9406 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9407 9408 while (1) { 9409 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9410 ("%s:%d: fail", __func__, __LINE__)); 9411 dr->getdesc(dr, slot, &desc, &meta); 9412 9413 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9414 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9415 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9416 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9417 9418 if (meta->mt_islast) { 9419 KASSERT(meta->mt_m != NULL, 9420 ("%s:%d: fail", __func__, __LINE__)); 9421 9422 ni = meta->mt_ni; 9423 m = meta->mt_m; 9424 if (ni != NULL) { 9425 /* 9426 * Do any tx complete callback. Note this must 9427 * be done before releasing the node reference. 9428 */ 9429 if (m->m_flags & M_TXCB) 9430 ieee80211_process_callback(ni, m, 0); 9431 ieee80211_free_node(ni); 9432 meta->mt_ni = NULL; 9433 } 9434 m_freem(m); 9435 meta->mt_m = NULL; 9436 } else { 9437 KASSERT(meta->mt_m == NULL, 9438 ("%s:%d: fail", __func__, __LINE__)); 9439 } 9440 9441 dr->dr_usedslot--; 9442 if (meta->mt_islast) { 9443 ifp->if_opackets++; 9444 break; 9445 } 9446 slot = bwn_dma_nextslot(dr, slot); 9447 } 9448 sc->sc_watchdog_timer = 0; 9449 if (dr->dr_stop) { 9450 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9451 ("%s:%d: fail", __func__, __LINE__)); 9452 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9453 dr->dr_stop = 0; 9454 } 9455 } 9456 9457 static void 9458 bwn_pio_handle_txeof(struct bwn_mac *mac, 9459 const struct bwn_txstatus *status) 9460 { 9461 struct bwn_pio_txqueue *tq; 9462 struct bwn_pio_txpkt *tp = NULL; 9463 struct bwn_softc *sc = mac->mac_sc; 9464 struct ifnet *ifp = sc->sc_ifp; 9465 9466 BWN_ASSERT_LOCKED(sc); 9467 9468 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9469 if (tq == NULL) 9470 return; 9471 9472 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9473 tq->tq_free++; 9474 9475 if (tp->tp_ni != NULL) { 9476 /* 9477 * Do any tx complete callback. Note this must 9478 * be done before releasing the node reference. 9479 */ 9480 if (tp->tp_m->m_flags & M_TXCB) 9481 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9482 ieee80211_free_node(tp->tp_ni); 9483 tp->tp_ni = NULL; 9484 } 9485 m_freem(tp->tp_m); 9486 tp->tp_m = NULL; 9487 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9488 9489 ifp->if_opackets++; 9490 9491 sc->sc_watchdog_timer = 0; 9492 if (tq->tq_stop) { 9493 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9494 tq->tq_stop = 0; 9495 } 9496 } 9497 9498 static void 9499 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9500 { 9501 struct bwn_softc *sc = mac->mac_sc; 9502 struct bwn_phy *phy = &mac->mac_phy; 9503 struct ifnet *ifp = sc->sc_ifp; 9504 struct ieee80211com *ic = ifp->if_l2com; 9505 unsigned long now; 9506 int result; 9507 9508 BWN_GETTIME(now); 9509 9510 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9511 return; 9512 phy->nexttime = now + 2 * 1000; 9513 9514 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9515 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9516 return; 9517 9518 if (phy->recalc_txpwr != NULL) { 9519 result = phy->recalc_txpwr(mac, 9520 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9521 if (result == BWN_TXPWR_RES_DONE) 9522 return; 9523 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9524 ("%s: fail", __func__)); 9525 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9526 9527 ieee80211_runtask(ic, &mac->mac_txpower); 9528 } 9529 } 9530 9531 static uint16_t 9532 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9533 { 9534 9535 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9536 } 9537 9538 static uint32_t 9539 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9540 { 9541 9542 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9543 } 9544 9545 static void 9546 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9547 { 9548 9549 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9550 } 9551 9552 static void 9553 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9554 { 9555 9556 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9557 } 9558 9559 static int 9560 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9561 { 9562 9563 switch (rate) { 9564 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9565 case 12: 9566 return (BWN_OFDM_RATE_6MB); 9567 case 18: 9568 return (BWN_OFDM_RATE_9MB); 9569 case 24: 9570 return (BWN_OFDM_RATE_12MB); 9571 case 36: 9572 return (BWN_OFDM_RATE_18MB); 9573 case 48: 9574 return (BWN_OFDM_RATE_24MB); 9575 case 72: 9576 return (BWN_OFDM_RATE_36MB); 9577 case 96: 9578 return (BWN_OFDM_RATE_48MB); 9579 case 108: 9580 return (BWN_OFDM_RATE_54MB); 9581 /* CCK rates (NB: not IEEE std, device-specific) */ 9582 case 2: 9583 return (BWN_CCK_RATE_1MB); 9584 case 4: 9585 return (BWN_CCK_RATE_2MB); 9586 case 11: 9587 return (BWN_CCK_RATE_5MB); 9588 case 22: 9589 return (BWN_CCK_RATE_11MB); 9590 } 9591 9592 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9593 return (BWN_CCK_RATE_1MB); 9594 } 9595 9596 static int 9597 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9598 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9599 { 9600 const struct bwn_phy *phy = &mac->mac_phy; 9601 struct bwn_softc *sc = mac->mac_sc; 9602 struct ieee80211_frame *wh; 9603 struct ieee80211_frame *protwh; 9604 struct ieee80211_frame_cts *cts; 9605 struct ieee80211_frame_rts *rts; 9606 const struct ieee80211_txparam *tp; 9607 struct ieee80211vap *vap = ni->ni_vap; 9608 struct ifnet *ifp = sc->sc_ifp; 9609 struct ieee80211com *ic = ifp->if_l2com; 9610 struct mbuf *mprot; 9611 unsigned int len; 9612 uint32_t macctl = 0; 9613 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9614 uint16_t phyctl = 0; 9615 uint8_t rate, rate_fb; 9616 9617 wh = mtod(m, struct ieee80211_frame *); 9618 memset(txhdr, 0, sizeof(*txhdr)); 9619 9620 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9621 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9622 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9623 9624 /* 9625 * Find TX rate 9626 */ 9627 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9628 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9629 rate = rate_fb = tp->mgmtrate; 9630 else if (ismcast) 9631 rate = rate_fb = tp->mcastrate; 9632 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9633 rate = rate_fb = tp->ucastrate; 9634 else { 9635 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9636 rate = ni->ni_txrate; 9637 9638 if (rix > 0) 9639 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9640 IEEE80211_RATE_VAL; 9641 else 9642 rate_fb = rate; 9643 } 9644 9645 sc->sc_tx_rate = rate; 9646 9647 rate = bwn_ieeerate2hwrate(sc, rate); 9648 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9649 9650 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9651 bwn_plcp_getcck(rate); 9652 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9653 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9654 9655 if ((rate_fb == rate) || 9656 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9657 (*(u_int16_t *)wh->i_dur == htole16(0))) 9658 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9659 else 9660 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9661 m->m_pkthdr.len, rate, isshort); 9662 9663 /* XXX TX encryption */ 9664 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9665 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9666 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9667 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9668 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9669 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9670 9671 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9672 BWN_TX_EFT_FB_CCK; 9673 txhdr->chan = phy->chan; 9674 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9675 BWN_TX_PHY_ENC_CCK; 9676 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9677 rate == BWN_CCK_RATE_11MB)) 9678 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9679 9680 /* XXX TX antenna selection */ 9681 9682 switch (bwn_antenna_sanitize(mac, 0)) { 9683 case 0: 9684 phyctl |= BWN_TX_PHY_ANT01AUTO; 9685 break; 9686 case 1: 9687 phyctl |= BWN_TX_PHY_ANT0; 9688 break; 9689 case 2: 9690 phyctl |= BWN_TX_PHY_ANT1; 9691 break; 9692 case 3: 9693 phyctl |= BWN_TX_PHY_ANT2; 9694 break; 9695 case 4: 9696 phyctl |= BWN_TX_PHY_ANT3; 9697 break; 9698 default: 9699 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9700 } 9701 9702 if (!ismcast) 9703 macctl |= BWN_TX_MAC_ACK; 9704 9705 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9706 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9707 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9708 macctl |= BWN_TX_MAC_LONGFRAME; 9709 9710 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9711 /* XXX RTS rate is always 1MB??? */ 9712 rts_rate = BWN_CCK_RATE_1MB; 9713 rts_rate_fb = bwn_get_fbrate(rts_rate); 9714 9715 protdur = ieee80211_compute_duration(ic->ic_rt, 9716 m->m_pkthdr.len, rate, isshort) + 9717 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9718 9719 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9720 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9721 (txhdr->body.old.rts_frame) : 9722 (txhdr->body.new.rts_frame)); 9723 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9724 protdur); 9725 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9726 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9727 mprot->m_pkthdr.len); 9728 m_freem(mprot); 9729 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9730 len = sizeof(struct ieee80211_frame_cts); 9731 } else { 9732 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9733 (txhdr->body.old.rts_frame) : 9734 (txhdr->body.new.rts_frame)); 9735 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9736 isshort); 9737 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9738 wh->i_addr2, protdur); 9739 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9740 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9741 mprot->m_pkthdr.len); 9742 m_freem(mprot); 9743 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9744 len = sizeof(struct ieee80211_frame_rts); 9745 } 9746 len += IEEE80211_CRC_LEN; 9747 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9748 &txhdr->body.old.rts_plcp : 9749 &txhdr->body.new.rts_plcp), len, rts_rate); 9750 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9751 rts_rate_fb); 9752 9753 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9754 (&txhdr->body.old.rts_frame) : 9755 (&txhdr->body.new.rts_frame)); 9756 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9757 9758 if (BWN_ISOFDMRATE(rts_rate)) { 9759 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9760 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9761 } else { 9762 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9763 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9764 } 9765 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9766 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9767 } 9768 9769 if (BWN_ISOLDFMT(mac)) 9770 txhdr->body.old.cookie = htole16(cookie); 9771 else 9772 txhdr->body.new.cookie = htole16(cookie); 9773 9774 txhdr->macctl = htole32(macctl); 9775 txhdr->phyctl = htole16(phyctl); 9776 9777 /* 9778 * TX radio tap 9779 */ 9780 if (ieee80211_radiotap_active_vap(vap)) { 9781 sc->sc_tx_th.wt_flags = 0; 9782 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9783 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9784 if (isshort && 9785 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9786 rate == BWN_CCK_RATE_11MB)) 9787 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9788 sc->sc_tx_th.wt_rate = rate; 9789 9790 ieee80211_radiotap_tx(vap, m); 9791 } 9792 9793 return (0); 9794 } 9795 9796 static void 9797 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9798 const uint8_t rate) 9799 { 9800 uint32_t d, plen; 9801 uint8_t *raw = plcp->o.raw; 9802 9803 if (BWN_ISOFDMRATE(rate)) { 9804 d = bwn_plcp_getofdm(rate); 9805 KASSERT(!(octets & 0xf000), 9806 ("%s:%d: fail", __func__, __LINE__)); 9807 d |= (octets << 5); 9808 plcp->o.data = htole32(d); 9809 } else { 9810 plen = octets * 16 / rate; 9811 if ((octets * 16 % rate) > 0) { 9812 plen++; 9813 if ((rate == BWN_CCK_RATE_11MB) 9814 && ((octets * 8 % 11) < 4)) { 9815 raw[1] = 0x84; 9816 } else 9817 raw[1] = 0x04; 9818 } else 9819 raw[1] = 0x04; 9820 plcp->o.data |= htole32(plen << 16); 9821 raw[0] = bwn_plcp_getcck(rate); 9822 } 9823 } 9824 9825 static uint8_t 9826 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9827 { 9828 struct bwn_softc *sc = mac->mac_sc; 9829 uint8_t mask; 9830 9831 if (n == 0) 9832 return (0); 9833 if (mac->mac_phy.gmode) 9834 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9835 else 9836 mask = siba_sprom_get_ant_a(sc->sc_dev); 9837 if (!(mask & (1 << (n - 1)))) 9838 return (0); 9839 return (n); 9840 } 9841 9842 static uint8_t 9843 bwn_get_fbrate(uint8_t bitrate) 9844 { 9845 switch (bitrate) { 9846 case BWN_CCK_RATE_1MB: 9847 return (BWN_CCK_RATE_1MB); 9848 case BWN_CCK_RATE_2MB: 9849 return (BWN_CCK_RATE_1MB); 9850 case BWN_CCK_RATE_5MB: 9851 return (BWN_CCK_RATE_2MB); 9852 case BWN_CCK_RATE_11MB: 9853 return (BWN_CCK_RATE_5MB); 9854 case BWN_OFDM_RATE_6MB: 9855 return (BWN_CCK_RATE_5MB); 9856 case BWN_OFDM_RATE_9MB: 9857 return (BWN_OFDM_RATE_6MB); 9858 case BWN_OFDM_RATE_12MB: 9859 return (BWN_OFDM_RATE_9MB); 9860 case BWN_OFDM_RATE_18MB: 9861 return (BWN_OFDM_RATE_12MB); 9862 case BWN_OFDM_RATE_24MB: 9863 return (BWN_OFDM_RATE_18MB); 9864 case BWN_OFDM_RATE_36MB: 9865 return (BWN_OFDM_RATE_24MB); 9866 case BWN_OFDM_RATE_48MB: 9867 return (BWN_OFDM_RATE_36MB); 9868 case BWN_OFDM_RATE_54MB: 9869 return (BWN_OFDM_RATE_48MB); 9870 } 9871 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9872 return (0); 9873 } 9874 9875 static uint32_t 9876 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9877 uint32_t ctl, const void *_data, int len) 9878 { 9879 struct bwn_softc *sc = mac->mac_sc; 9880 uint32_t value = 0; 9881 const uint8_t *data = _data; 9882 9883 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9884 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9885 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9886 9887 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9888 tq->tq_base + BWN_PIO8_TXDATA); 9889 if (len & 3) { 9890 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9891 BWN_PIO8_TXCTL_24_31); 9892 data = &(data[len - 1]); 9893 switch (len & 3) { 9894 case 3: 9895 ctl |= BWN_PIO8_TXCTL_16_23; 9896 value |= (uint32_t)(*data) << 16; 9897 data--; 9898 case 2: 9899 ctl |= BWN_PIO8_TXCTL_8_15; 9900 value |= (uint32_t)(*data) << 8; 9901 data--; 9902 case 1: 9903 value |= (uint32_t)(*data); 9904 } 9905 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9906 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9907 } 9908 9909 return (ctl); 9910 } 9911 9912 static void 9913 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9914 uint16_t offset, uint32_t value) 9915 { 9916 9917 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9918 } 9919 9920 static uint16_t 9921 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9922 uint16_t ctl, const void *_data, int len) 9923 { 9924 struct bwn_softc *sc = mac->mac_sc; 9925 const uint8_t *data = _data; 9926 9927 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9928 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9929 9930 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9931 tq->tq_base + BWN_PIO_TXDATA); 9932 if (len & 1) { 9933 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9934 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9935 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9936 } 9937 9938 return (ctl); 9939 } 9940 9941 static uint16_t 9942 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9943 uint16_t ctl, struct mbuf *m0) 9944 { 9945 int i, j = 0; 9946 uint16_t data = 0; 9947 const uint8_t *buf; 9948 struct mbuf *m = m0; 9949 9950 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9951 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9952 9953 for (; m != NULL; m = m->m_next) { 9954 buf = mtod(m, const uint8_t *); 9955 for (i = 0; i < m->m_len; i++) { 9956 if (!((j++) % 2)) 9957 data |= buf[i]; 9958 else { 9959 data |= (buf[i] << 8); 9960 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9961 data = 0; 9962 } 9963 } 9964 } 9965 if (m0->m_pkthdr.len % 2) { 9966 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9967 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9968 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9969 } 9970 9971 return (ctl); 9972 } 9973 9974 static void 9975 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9976 { 9977 9978 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9979 return; 9980 BWN_WRITE_2(mac, 0x684, 510 + time); 9981 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9982 } 9983 9984 static struct bwn_dma_ring * 9985 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9986 { 9987 9988 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9989 return (mac->mac_method.dma.wme[WME_AC_BE]); 9990 9991 switch (prio) { 9992 case 3: 9993 return (mac->mac_method.dma.wme[WME_AC_VO]); 9994 case 2: 9995 return (mac->mac_method.dma.wme[WME_AC_VI]); 9996 case 0: 9997 return (mac->mac_method.dma.wme[WME_AC_BE]); 9998 case 1: 9999 return (mac->mac_method.dma.wme[WME_AC_BK]); 10000 } 10001 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10002 return (NULL); 10003 } 10004 10005 static int 10006 bwn_dma_getslot(struct bwn_dma_ring *dr) 10007 { 10008 int slot; 10009 10010 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10011 10012 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10013 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10014 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10015 10016 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10017 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10018 dr->dr_curslot = slot; 10019 dr->dr_usedslot++; 10020 10021 return (slot); 10022 } 10023 10024 static int 10025 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10026 { 10027 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10028 unsigned int a, b, c, d; 10029 unsigned int avg; 10030 uint32_t tmp; 10031 10032 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10033 a = tmp & 0xff; 10034 b = (tmp >> 8) & 0xff; 10035 c = (tmp >> 16) & 0xff; 10036 d = (tmp >> 24) & 0xff; 10037 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10038 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10039 return (ENOENT); 10040 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10041 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10042 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10043 10044 if (ofdm) { 10045 a = (a + 32) & 0x3f; 10046 b = (b + 32) & 0x3f; 10047 c = (c + 32) & 0x3f; 10048 d = (d + 32) & 0x3f; 10049 } 10050 10051 avg = (a + b + c + d + 2) / 4; 10052 if (ofdm) { 10053 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10054 & BWN_HF_4DB_CCK_POWERBOOST) 10055 avg = (avg >= 13) ? (avg - 13) : 0; 10056 } 10057 return (avg); 10058 } 10059 10060 static void 10061 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10062 { 10063 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10064 int rfatt = *rfattp; 10065 int bbatt = *bbattp; 10066 10067 while (1) { 10068 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10069 break; 10070 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10071 break; 10072 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10073 break; 10074 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10075 break; 10076 if (bbatt > lo->bbatt.max) { 10077 bbatt -= 4; 10078 rfatt += 1; 10079 continue; 10080 } 10081 if (bbatt < lo->bbatt.min) { 10082 bbatt += 4; 10083 rfatt -= 1; 10084 continue; 10085 } 10086 if (rfatt > lo->rfatt.max) { 10087 rfatt -= 1; 10088 bbatt += 4; 10089 continue; 10090 } 10091 if (rfatt < lo->rfatt.min) { 10092 rfatt += 1; 10093 bbatt -= 4; 10094 continue; 10095 } 10096 break; 10097 } 10098 10099 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10100 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10101 } 10102 10103 static void 10104 bwn_phy_lock(struct bwn_mac *mac) 10105 { 10106 struct bwn_softc *sc = mac->mac_sc; 10107 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10108 10109 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10110 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10111 10112 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10113 bwn_psctl(mac, BWN_PS_AWAKE); 10114 } 10115 10116 static void 10117 bwn_phy_unlock(struct bwn_mac *mac) 10118 { 10119 struct bwn_softc *sc = mac->mac_sc; 10120 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10121 10122 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10123 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10124 10125 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10126 bwn_psctl(mac, 0); 10127 } 10128 10129 static void 10130 bwn_rf_lock(struct bwn_mac *mac) 10131 { 10132 10133 BWN_WRITE_4(mac, BWN_MACCTL, 10134 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10135 BWN_READ_4(mac, BWN_MACCTL); 10136 DELAY(10); 10137 } 10138 10139 static void 10140 bwn_rf_unlock(struct bwn_mac *mac) 10141 { 10142 10143 BWN_READ_2(mac, BWN_PHYVER); 10144 BWN_WRITE_4(mac, BWN_MACCTL, 10145 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10146 } 10147 10148 static struct bwn_pio_txqueue * 10149 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10150 struct bwn_pio_txpkt **pack) 10151 { 10152 struct bwn_pio *pio = &mac->mac_method.pio; 10153 struct bwn_pio_txqueue *tq = NULL; 10154 unsigned int index; 10155 10156 switch (cookie & 0xf000) { 10157 case 0x1000: 10158 tq = &pio->wme[WME_AC_BK]; 10159 break; 10160 case 0x2000: 10161 tq = &pio->wme[WME_AC_BE]; 10162 break; 10163 case 0x3000: 10164 tq = &pio->wme[WME_AC_VI]; 10165 break; 10166 case 0x4000: 10167 tq = &pio->wme[WME_AC_VO]; 10168 break; 10169 case 0x5000: 10170 tq = &pio->mcast; 10171 break; 10172 } 10173 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10174 if (tq == NULL) 10175 return (NULL); 10176 index = (cookie & 0x0fff); 10177 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10178 if (index >= N(tq->tq_pkts)) 10179 return (NULL); 10180 *pack = &tq->tq_pkts[index]; 10181 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10182 return (tq); 10183 } 10184 10185 static void 10186 bwn_txpwr(void *arg, int npending) 10187 { 10188 struct bwn_mac *mac = arg; 10189 struct bwn_softc *sc = mac->mac_sc; 10190 10191 BWN_LOCK(sc); 10192 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10193 mac->mac_phy.set_txpwr != NULL) 10194 mac->mac_phy.set_txpwr(mac); 10195 BWN_UNLOCK(sc); 10196 } 10197 10198 static void 10199 bwn_task_15s(struct bwn_mac *mac) 10200 { 10201 uint16_t reg; 10202 10203 if (mac->mac_fw.opensource) { 10204 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10205 if (reg) { 10206 bwn_restart(mac, "fw watchdog"); 10207 return; 10208 } 10209 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10210 } 10211 if (mac->mac_phy.task_15s) 10212 mac->mac_phy.task_15s(mac); 10213 10214 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10215 } 10216 10217 static void 10218 bwn_task_30s(struct bwn_mac *mac) 10219 { 10220 10221 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10222 return; 10223 mac->mac_noise.noi_running = 1; 10224 mac->mac_noise.noi_nsamples = 0; 10225 10226 bwn_noise_gensample(mac); 10227 } 10228 10229 static void 10230 bwn_task_60s(struct bwn_mac *mac) 10231 { 10232 10233 if (mac->mac_phy.task_60s) 10234 mac->mac_phy.task_60s(mac); 10235 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10236 } 10237 10238 static void 10239 bwn_tasks(void *arg) 10240 { 10241 struct bwn_mac *mac = arg; 10242 struct bwn_softc *sc = mac->mac_sc; 10243 10244 BWN_ASSERT_LOCKED(sc); 10245 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10246 return; 10247 10248 if (mac->mac_task_state % 4 == 0) 10249 bwn_task_60s(mac); 10250 if (mac->mac_task_state % 2 == 0) 10251 bwn_task_30s(mac); 10252 bwn_task_15s(mac); 10253 10254 mac->mac_task_state++; 10255 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10256 } 10257 10258 static int 10259 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10260 { 10261 struct bwn_softc *sc = mac->mac_sc; 10262 10263 KASSERT(a == 0, ("not support APHY\n")); 10264 10265 switch (plcp->o.raw[0] & 0xf) { 10266 case 0xb: 10267 return (BWN_OFDM_RATE_6MB); 10268 case 0xf: 10269 return (BWN_OFDM_RATE_9MB); 10270 case 0xa: 10271 return (BWN_OFDM_RATE_12MB); 10272 case 0xe: 10273 return (BWN_OFDM_RATE_18MB); 10274 case 0x9: 10275 return (BWN_OFDM_RATE_24MB); 10276 case 0xd: 10277 return (BWN_OFDM_RATE_36MB); 10278 case 0x8: 10279 return (BWN_OFDM_RATE_48MB); 10280 case 0xc: 10281 return (BWN_OFDM_RATE_54MB); 10282 } 10283 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10284 plcp->o.raw[0] & 0xf); 10285 return (-1); 10286 } 10287 10288 static int 10289 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10290 { 10291 struct bwn_softc *sc = mac->mac_sc; 10292 10293 switch (plcp->o.raw[0]) { 10294 case 0x0a: 10295 return (BWN_CCK_RATE_1MB); 10296 case 0x14: 10297 return (BWN_CCK_RATE_2MB); 10298 case 0x37: 10299 return (BWN_CCK_RATE_5MB); 10300 case 0x6e: 10301 return (BWN_CCK_RATE_11MB); 10302 } 10303 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10304 return (-1); 10305 } 10306 10307 static void 10308 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10309 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10310 int rssi, int noise) 10311 { 10312 struct bwn_softc *sc = mac->mac_sc; 10313 const struct ieee80211_frame_min *wh; 10314 uint64_t tsf; 10315 uint16_t low_mactime_now; 10316 10317 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10318 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10319 10320 wh = mtod(m, const struct ieee80211_frame_min *); 10321 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10322 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10323 10324 bwn_tsf_read(mac, &tsf); 10325 low_mactime_now = tsf; 10326 tsf = tsf & ~0xffffULL; 10327 tsf += le16toh(rxhdr->mac_time); 10328 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10329 tsf -= 0x10000; 10330 10331 sc->sc_rx_th.wr_tsf = tsf; 10332 sc->sc_rx_th.wr_rate = rate; 10333 sc->sc_rx_th.wr_antsignal = rssi; 10334 sc->sc_rx_th.wr_antnoise = noise; 10335 } 10336 10337 static void 10338 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10339 { 10340 uint32_t low, high; 10341 10342 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10343 ("%s:%d: fail", __func__, __LINE__)); 10344 10345 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10346 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10347 *tsf = high; 10348 *tsf <<= 32; 10349 *tsf |= low; 10350 } 10351 10352 static int 10353 bwn_dma_attach(struct bwn_mac *mac) 10354 { 10355 struct bwn_dma *dma = &mac->mac_method.dma; 10356 struct bwn_softc *sc = mac->mac_sc; 10357 bus_addr_t lowaddr = 0; 10358 int error; 10359 10360 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10361 return (0); 10362 10363 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10364 10365 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10366 10367 dma->dmatype = bwn_dma_gettype(mac); 10368 if (dma->dmatype == BWN_DMA_30BIT) 10369 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10370 else if (dma->dmatype == BWN_DMA_32BIT) 10371 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10372 else 10373 lowaddr = BUS_SPACE_MAXADDR; 10374 10375 /* 10376 * Create top level DMA tag 10377 */ 10378 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10379 BWN_ALIGN, 0, /* alignment, bounds */ 10380 lowaddr, /* lowaddr */ 10381 BUS_SPACE_MAXADDR, /* highaddr */ 10382 NULL, NULL, /* filter, filterarg */ 10383 MAXBSIZE, /* maxsize */ 10384 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10385 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10386 0, /* flags */ 10387 NULL, NULL, /* lockfunc, lockarg */ 10388 &dma->parent_dtag); 10389 if (error) { 10390 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10391 return (error); 10392 } 10393 10394 /* 10395 * Create TX/RX mbuf DMA tag 10396 */ 10397 error = bus_dma_tag_create(dma->parent_dtag, 10398 1, 10399 0, 10400 BUS_SPACE_MAXADDR, 10401 BUS_SPACE_MAXADDR, 10402 NULL, NULL, 10403 MCLBYTES, 10404 1, 10405 BUS_SPACE_MAXSIZE_32BIT, 10406 0, 10407 NULL, NULL, 10408 &dma->rxbuf_dtag); 10409 if (error) { 10410 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10411 goto fail0; 10412 } 10413 error = bus_dma_tag_create(dma->parent_dtag, 10414 1, 10415 0, 10416 BUS_SPACE_MAXADDR, 10417 BUS_SPACE_MAXADDR, 10418 NULL, NULL, 10419 MCLBYTES, 10420 1, 10421 BUS_SPACE_MAXSIZE_32BIT, 10422 0, 10423 NULL, NULL, 10424 &dma->txbuf_dtag); 10425 if (error) { 10426 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10427 goto fail1; 10428 } 10429 10430 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10431 if (!dma->wme[WME_AC_BK]) 10432 goto fail2; 10433 10434 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10435 if (!dma->wme[WME_AC_BE]) 10436 goto fail3; 10437 10438 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10439 if (!dma->wme[WME_AC_VI]) 10440 goto fail4; 10441 10442 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10443 if (!dma->wme[WME_AC_VO]) 10444 goto fail5; 10445 10446 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10447 if (!dma->mcast) 10448 goto fail6; 10449 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10450 if (!dma->rx) 10451 goto fail7; 10452 10453 return (error); 10454 10455 fail7: bwn_dma_ringfree(&dma->mcast); 10456 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10457 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10458 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10459 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10460 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10461 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10462 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10463 return (error); 10464 } 10465 10466 static struct bwn_dma_ring * 10467 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10468 uint16_t cookie, int *slot) 10469 { 10470 struct bwn_dma *dma = &mac->mac_method.dma; 10471 struct bwn_dma_ring *dr; 10472 struct bwn_softc *sc = mac->mac_sc; 10473 10474 BWN_ASSERT_LOCKED(mac->mac_sc); 10475 10476 switch (cookie & 0xf000) { 10477 case 0x1000: 10478 dr = dma->wme[WME_AC_BK]; 10479 break; 10480 case 0x2000: 10481 dr = dma->wme[WME_AC_BE]; 10482 break; 10483 case 0x3000: 10484 dr = dma->wme[WME_AC_VI]; 10485 break; 10486 case 0x4000: 10487 dr = dma->wme[WME_AC_VO]; 10488 break; 10489 case 0x5000: 10490 dr = dma->mcast; 10491 break; 10492 default: 10493 dr = NULL; 10494 KASSERT(0 == 1, 10495 ("invalid cookie value %d", cookie & 0xf000)); 10496 } 10497 *slot = (cookie & 0x0fff); 10498 if (*slot < 0 || *slot >= dr->dr_numslots) { 10499 /* 10500 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10501 * that it occurs events which have same H/W sequence numbers. 10502 * When it's occurred just prints a WARNING msgs and ignores. 10503 */ 10504 KASSERT(status->seq == dma->lastseq, 10505 ("%s:%d: fail", __func__, __LINE__)); 10506 device_printf(sc->sc_dev, 10507 "out of slot ranges (0 < %d < %d)\n", *slot, 10508 dr->dr_numslots); 10509 return (NULL); 10510 } 10511 dma->lastseq = status->seq; 10512 return (dr); 10513 } 10514 10515 static void 10516 bwn_dma_stop(struct bwn_mac *mac) 10517 { 10518 struct bwn_dma *dma; 10519 10520 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10521 return; 10522 dma = &mac->mac_method.dma; 10523 10524 bwn_dma_ringstop(&dma->rx); 10525 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10526 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10527 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10528 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10529 bwn_dma_ringstop(&dma->mcast); 10530 } 10531 10532 static void 10533 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10534 { 10535 10536 if (dr == NULL) 10537 return; 10538 10539 bwn_dma_cleanup(*dr); 10540 } 10541 10542 static void 10543 bwn_pio_stop(struct bwn_mac *mac) 10544 { 10545 struct bwn_pio *pio; 10546 10547 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10548 return; 10549 pio = &mac->mac_method.pio; 10550 10551 bwn_destroy_queue_tx(&pio->mcast); 10552 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10553 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10554 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10555 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10556 } 10557 10558 static void 10559 bwn_led_attach(struct bwn_mac *mac) 10560 { 10561 struct bwn_softc *sc = mac->mac_sc; 10562 const uint8_t *led_act = NULL; 10563 uint16_t val[BWN_LED_MAX]; 10564 int i; 10565 10566 sc->sc_led_idle = (2350 * hz) / 1000; 10567 sc->sc_led_blink = 1; 10568 10569 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10570 if (siba_get_pci_subvendor(sc->sc_dev) == 10571 bwn_vendor_led_act[i].vid) { 10572 led_act = bwn_vendor_led_act[i].led_act; 10573 break; 10574 } 10575 } 10576 if (led_act == NULL) 10577 led_act = bwn_default_led_act; 10578 10579 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10580 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10581 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10582 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10583 10584 for (i = 0; i < BWN_LED_MAX; ++i) { 10585 struct bwn_led *led = &sc->sc_leds[i]; 10586 10587 if (val[i] == 0xff) { 10588 led->led_act = led_act[i]; 10589 } else { 10590 if (val[i] & BWN_LED_ACT_LOW) 10591 led->led_flags |= BWN_LED_F_ACTLOW; 10592 led->led_act = val[i] & BWN_LED_ACT_MASK; 10593 } 10594 led->led_mask = (1 << i); 10595 10596 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10597 led->led_act == BWN_LED_ACT_BLINK_POLL || 10598 led->led_act == BWN_LED_ACT_BLINK) { 10599 led->led_flags |= BWN_LED_F_BLINK; 10600 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10601 led->led_flags |= BWN_LED_F_POLLABLE; 10602 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10603 led->led_flags |= BWN_LED_F_SLOW; 10604 10605 if (sc->sc_blink_led == NULL) { 10606 sc->sc_blink_led = led; 10607 if (led->led_flags & BWN_LED_F_SLOW) 10608 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10609 } 10610 } 10611 10612 DPRINTF(sc, BWN_DEBUG_LED, 10613 "%dth led, act %d, lowact %d\n", i, 10614 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10615 } 10616 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10617 } 10618 10619 static __inline uint16_t 10620 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10621 { 10622 10623 if (led->led_flags & BWN_LED_F_ACTLOW) 10624 on = !on; 10625 if (on) 10626 val |= led->led_mask; 10627 else 10628 val &= ~led->led_mask; 10629 return val; 10630 } 10631 10632 static void 10633 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10634 { 10635 struct bwn_softc *sc = mac->mac_sc; 10636 struct ifnet *ifp = sc->sc_ifp; 10637 struct ieee80211com *ic = ifp->if_l2com; 10638 uint16_t val; 10639 int i; 10640 10641 if (nstate == IEEE80211_S_INIT) { 10642 callout_stop(&sc->sc_led_blink_ch); 10643 sc->sc_led_blinking = 0; 10644 } 10645 10646 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10647 return; 10648 10649 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10650 for (i = 0; i < BWN_LED_MAX; ++i) { 10651 struct bwn_led *led = &sc->sc_leds[i]; 10652 int on; 10653 10654 if (led->led_act == BWN_LED_ACT_UNKN || 10655 led->led_act == BWN_LED_ACT_NULL) 10656 continue; 10657 10658 if ((led->led_flags & BWN_LED_F_BLINK) && 10659 nstate != IEEE80211_S_INIT) 10660 continue; 10661 10662 switch (led->led_act) { 10663 case BWN_LED_ACT_ON: /* Always on */ 10664 on = 1; 10665 break; 10666 case BWN_LED_ACT_OFF: /* Always off */ 10667 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10668 on = 0; 10669 break; 10670 default: 10671 on = 1; 10672 switch (nstate) { 10673 case IEEE80211_S_INIT: 10674 on = 0; 10675 break; 10676 case IEEE80211_S_RUN: 10677 if (led->led_act == BWN_LED_ACT_11G && 10678 ic->ic_curmode != IEEE80211_MODE_11G) 10679 on = 0; 10680 break; 10681 default: 10682 if (led->led_act == BWN_LED_ACT_ASSOC) 10683 on = 0; 10684 break; 10685 } 10686 break; 10687 } 10688 10689 val = bwn_led_onoff(led, val, on); 10690 } 10691 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10692 } 10693 10694 static void 10695 bwn_led_event(struct bwn_mac *mac, int event) 10696 { 10697 struct bwn_softc *sc = mac->mac_sc; 10698 struct bwn_led *led = sc->sc_blink_led; 10699 int rate; 10700 10701 if (event == BWN_LED_EVENT_POLL) { 10702 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10703 return; 10704 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10705 return; 10706 } 10707 10708 sc->sc_led_ticks = ticks; 10709 if (sc->sc_led_blinking) 10710 return; 10711 10712 switch (event) { 10713 case BWN_LED_EVENT_RX: 10714 rate = sc->sc_rx_rate; 10715 break; 10716 case BWN_LED_EVENT_TX: 10717 rate = sc->sc_tx_rate; 10718 break; 10719 case BWN_LED_EVENT_POLL: 10720 rate = 0; 10721 break; 10722 default: 10723 panic("unknown LED event %d\n", event); 10724 break; 10725 } 10726 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10727 bwn_led_duration[rate].off_dur); 10728 } 10729 10730 static void 10731 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10732 { 10733 struct bwn_softc *sc = mac->mac_sc; 10734 struct bwn_led *led = sc->sc_blink_led; 10735 uint16_t val; 10736 10737 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10738 val = bwn_led_onoff(led, val, 1); 10739 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10740 10741 if (led->led_flags & BWN_LED_F_SLOW) { 10742 BWN_LED_SLOWDOWN(on_dur); 10743 BWN_LED_SLOWDOWN(off_dur); 10744 } 10745 10746 sc->sc_led_blinking = 1; 10747 sc->sc_led_blink_offdur = off_dur; 10748 10749 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10750 } 10751 10752 static void 10753 bwn_led_blink_next(void *arg) 10754 { 10755 struct bwn_mac *mac = arg; 10756 struct bwn_softc *sc = mac->mac_sc; 10757 uint16_t val; 10758 10759 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10760 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10761 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10762 10763 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10764 bwn_led_blink_end, mac); 10765 } 10766 10767 static void 10768 bwn_led_blink_end(void *arg) 10769 { 10770 struct bwn_mac *mac = arg; 10771 struct bwn_softc *sc = mac->mac_sc; 10772 10773 sc->sc_led_blinking = 0; 10774 } 10775 10776 static int 10777 bwn_suspend(device_t dev) 10778 { 10779 struct bwn_softc *sc = device_get_softc(dev); 10780 10781 bwn_stop(sc, 1); 10782 return (0); 10783 } 10784 10785 static int 10786 bwn_resume(device_t dev) 10787 { 10788 struct bwn_softc *sc = device_get_softc(dev); 10789 struct ifnet *ifp = sc->sc_ifp; 10790 10791 if (ifp->if_flags & IFF_UP) 10792 bwn_init(sc); 10793 return (0); 10794 } 10795 10796 static void 10797 bwn_rfswitch(void *arg) 10798 { 10799 struct bwn_softc *sc = arg; 10800 struct bwn_mac *mac = sc->sc_curmac; 10801 int cur = 0, prev = 0; 10802 10803 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10804 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10805 10806 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10807 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10808 & BWN_RF_HWENABLED_HI_MASK)) 10809 cur = 1; 10810 } else { 10811 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10812 & BWN_RF_HWENABLED_LO_MASK) 10813 cur = 1; 10814 } 10815 10816 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10817 prev = 1; 10818 10819 if (cur != prev) { 10820 if (cur) 10821 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10822 else 10823 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10824 10825 device_printf(sc->sc_dev, 10826 "status of RF switch is changed to %s\n", 10827 cur ? "ON" : "OFF"); 10828 if (cur != mac->mac_phy.rf_on) { 10829 if (cur) 10830 bwn_rf_turnon(mac); 10831 else 10832 bwn_rf_turnoff(mac); 10833 } 10834 } 10835 10836 callout_schedule(&sc->sc_rfswitch_ch, hz); 10837 } 10838 10839 static void 10840 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10841 { 10842 struct bwn_phy *phy = &mac->mac_phy; 10843 struct bwn_phy_lp *plp = &phy->phy_lp; 10844 10845 plp->plp_antenna = BWN_ANT_DEFAULT; 10846 } 10847 10848 static int 10849 bwn_phy_lp_init(struct bwn_mac *mac) 10850 { 10851 static const struct bwn_stxtable tables[] = { 10852 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10853 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10854 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10855 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10856 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10857 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10858 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10859 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10860 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10861 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10862 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10863 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10864 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10865 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10866 { 2, 11, 0x40, 0, 0x0f } 10867 }; 10868 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10869 struct bwn_softc *sc = mac->mac_sc; 10870 const struct bwn_stxtable *st; 10871 struct ifnet *ifp = sc->sc_ifp; 10872 struct ieee80211com *ic = ifp->if_l2com; 10873 int i, error; 10874 uint16_t tmp; 10875 10876 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10877 bwn_phy_lp_bbinit(mac); 10878 10879 /* initialize RF */ 10880 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10881 DELAY(1); 10882 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10883 DELAY(1); 10884 10885 if (mac->mac_phy.rf_ver == 0x2062) 10886 bwn_phy_lp_b2062_init(mac); 10887 else { 10888 bwn_phy_lp_b2063_init(mac); 10889 10890 /* synchronize stx table. */ 10891 for (i = 0; i < N(tables); i++) { 10892 st = &tables[i]; 10893 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10894 tmp >>= st->st_rfshift; 10895 tmp <<= st->st_physhift; 10896 BWN_PHY_SETMASK(mac, 10897 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10898 ~(st->st_mask << st->st_physhift), tmp); 10899 } 10900 10901 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10902 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10903 } 10904 10905 /* calibrate RC */ 10906 if (mac->mac_phy.rev >= 2) 10907 bwn_phy_lp_rxcal_r2(mac); 10908 else if (!plp->plp_rccap) { 10909 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10910 bwn_phy_lp_rccal_r12(mac); 10911 } else 10912 bwn_phy_lp_set_rccap(mac); 10913 10914 error = bwn_phy_lp_switch_channel(mac, 7); 10915 if (error) 10916 device_printf(sc->sc_dev, 10917 "failed to change channel 7 (%d)\n", error); 10918 bwn_phy_lp_txpctl_init(mac); 10919 bwn_phy_lp_calib(mac); 10920 return (0); 10921 } 10922 10923 static uint16_t 10924 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10925 { 10926 10927 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10928 return (BWN_READ_2(mac, BWN_PHYDATA)); 10929 } 10930 10931 static void 10932 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10933 { 10934 10935 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10936 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10937 } 10938 10939 static void 10940 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10941 uint16_t set) 10942 { 10943 10944 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10945 BWN_WRITE_2(mac, BWN_PHYDATA, 10946 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10947 } 10948 10949 static uint16_t 10950 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10951 { 10952 10953 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10954 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10955 reg |= 0x100; 10956 if (mac->mac_phy.rev >= 2) 10957 reg |= 0x200; 10958 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10959 return BWN_READ_2(mac, BWN_RFDATALO); 10960 } 10961 10962 static void 10963 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10964 { 10965 10966 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10967 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10968 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10969 } 10970 10971 static void 10972 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10973 { 10974 10975 if (on) { 10976 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10977 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10978 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10979 return; 10980 } 10981 10982 if (mac->mac_phy.rev >= 2) { 10983 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10984 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10985 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10986 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10987 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10988 return; 10989 } 10990 10991 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10992 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10993 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10994 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10995 } 10996 10997 static int 10998 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10999 { 11000 struct bwn_phy *phy = &mac->mac_phy; 11001 struct bwn_phy_lp *plp = &phy->phy_lp; 11002 int error; 11003 11004 if (phy->rf_ver == 0x2063) { 11005 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11006 if (error) 11007 return (error); 11008 } else { 11009 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11010 if (error) 11011 return (error); 11012 bwn_phy_lp_set_anafilter(mac, chan); 11013 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11014 } 11015 11016 plp->plp_chan = chan; 11017 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11018 return (0); 11019 } 11020 11021 static uint32_t 11022 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11023 { 11024 struct bwn_softc *sc = mac->mac_sc; 11025 struct ifnet *ifp = sc->sc_ifp; 11026 struct ieee80211com *ic = ifp->if_l2com; 11027 11028 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11029 } 11030 11031 static void 11032 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11033 { 11034 struct bwn_phy *phy = &mac->mac_phy; 11035 struct bwn_phy_lp *plp = &phy->phy_lp; 11036 11037 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11038 return; 11039 11040 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11041 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11042 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11043 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11044 plp->plp_antenna = antenna; 11045 } 11046 11047 static void 11048 bwn_phy_lp_task_60s(struct bwn_mac *mac) 11049 { 11050 11051 bwn_phy_lp_calib(mac); 11052 } 11053 11054 static void 11055 bwn_phy_lp_readsprom(struct bwn_mac *mac) 11056 { 11057 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11058 struct bwn_softc *sc = mac->mac_sc; 11059 struct ifnet *ifp = sc->sc_ifp; 11060 struct ieee80211com *ic = ifp->if_l2com; 11061 11062 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11063 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 11064 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 11065 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 11066 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 11067 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 11068 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 11069 return; 11070 } 11071 11072 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 11073 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 11074 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 11075 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 11076 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 11077 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 11078 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 11079 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 11080 } 11081 11082 static void 11083 bwn_phy_lp_bbinit(struct bwn_mac *mac) 11084 { 11085 11086 bwn_phy_lp_tblinit(mac); 11087 if (mac->mac_phy.rev >= 2) 11088 bwn_phy_lp_bbinit_r2(mac); 11089 else 11090 bwn_phy_lp_bbinit_r01(mac); 11091 } 11092 11093 static void 11094 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11095 { 11096 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11097 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11098 struct bwn_softc *sc = mac->mac_sc; 11099 struct ifnet *ifp = sc->sc_ifp; 11100 struct ieee80211com *ic = ifp->if_l2com; 11101 11102 bwn_phy_lp_set_txgain(mac, 11103 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11104 bwn_phy_lp_set_bbmult(mac, 150); 11105 } 11106 11107 static void 11108 bwn_phy_lp_calib(struct bwn_mac *mac) 11109 { 11110 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11111 struct bwn_softc *sc = mac->mac_sc; 11112 struct ifnet *ifp = sc->sc_ifp; 11113 struct ieee80211com *ic = ifp->if_l2com; 11114 const struct bwn_rxcompco *rc = NULL; 11115 struct bwn_txgain ogain; 11116 int i, omode, oafeovr, orf, obbmult; 11117 uint8_t mode, fc = 0; 11118 11119 if (plp->plp_chanfullcal != plp->plp_chan) { 11120 plp->plp_chanfullcal = plp->plp_chan; 11121 fc = 1; 11122 } 11123 11124 bwn_mac_suspend(mac); 11125 11126 /* BlueTooth Coexistance Override */ 11127 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11128 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11129 11130 if (mac->mac_phy.rev >= 2) 11131 bwn_phy_lp_digflt_save(mac); 11132 bwn_phy_lp_get_txpctlmode(mac); 11133 mode = plp->plp_txpctlmode; 11134 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11135 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11136 bwn_phy_lp_bugfix(mac); 11137 if (mac->mac_phy.rev >= 2 && fc == 1) { 11138 bwn_phy_lp_get_txpctlmode(mac); 11139 omode = plp->plp_txpctlmode; 11140 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11141 if (oafeovr) 11142 ogain = bwn_phy_lp_get_txgain(mac); 11143 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11144 obbmult = bwn_phy_lp_get_bbmult(mac); 11145 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11146 if (oafeovr) 11147 bwn_phy_lp_set_txgain(mac, &ogain); 11148 bwn_phy_lp_set_bbmult(mac, obbmult); 11149 bwn_phy_lp_set_txpctlmode(mac, omode); 11150 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11151 } 11152 bwn_phy_lp_set_txpctlmode(mac, mode); 11153 if (mac->mac_phy.rev >= 2) 11154 bwn_phy_lp_digflt_restore(mac); 11155 11156 /* do RX IQ Calculation; assumes that noise is true. */ 11157 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11158 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11159 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11160 rc = &bwn_rxcompco_5354[i]; 11161 } 11162 } else if (mac->mac_phy.rev >= 2) 11163 rc = &bwn_rxcompco_r2; 11164 else { 11165 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11166 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11167 rc = &bwn_rxcompco_r12[i]; 11168 } 11169 } 11170 if (rc == NULL) 11171 goto fail; 11172 11173 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11174 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11175 11176 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11177 11178 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11179 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11180 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11181 } else { 11182 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11183 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11184 } 11185 11186 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11187 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11188 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11189 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11190 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11191 bwn_phy_lp_set_deaf(mac, 0); 11192 /* XXX no checking return value? */ 11193 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11194 bwn_phy_lp_clear_deaf(mac, 0); 11195 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11196 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11197 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11198 11199 /* disable RX GAIN override. */ 11200 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11201 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11202 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11203 if (mac->mac_phy.rev >= 2) { 11204 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11205 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11206 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11207 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11208 } 11209 } else { 11210 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11211 } 11212 11213 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11214 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11215 fail: 11216 bwn_mac_enable(mac); 11217 } 11218 11219 static void 11220 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11221 { 11222 11223 if (on) { 11224 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11225 return; 11226 } 11227 11228 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11229 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11230 } 11231 11232 static int 11233 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11234 { 11235 static const struct bwn_b206x_chan *bc = NULL; 11236 struct bwn_softc *sc = mac->mac_sc; 11237 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11238 tmp[6]; 11239 uint16_t old, scale, tmp16; 11240 int i, div; 11241 11242 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11243 if (bwn_b2063_chantable[i].bc_chan == chan) { 11244 bc = &bwn_b2063_chantable[i]; 11245 break; 11246 } 11247 } 11248 if (bc == NULL) 11249 return (EINVAL); 11250 11251 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11252 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11253 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11254 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11255 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11256 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11257 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11258 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11259 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11260 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11261 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11262 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11263 11264 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11265 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11266 11267 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11268 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11269 freqref = freqxtal * 3; 11270 div = (freqxtal <= 26000000 ? 1 : 2); 11271 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11272 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11273 999999) / 1000000) + 1; 11274 11275 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11276 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11277 0xfff8, timeout >> 2); 11278 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11279 0xff9f,timeout << 5); 11280 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11281 11282 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11283 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11284 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11285 11286 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11287 (timeoutref + 1)) - 1; 11288 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11289 0xf0, count >> 8); 11290 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11291 11292 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11293 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11294 while (tmp[1] >= freqref) { 11295 tmp[0]++; 11296 tmp[1] -= freqref; 11297 } 11298 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11299 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11300 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11301 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11302 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11303 11304 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11305 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11306 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11307 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11308 11309 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11310 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11311 11312 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11313 scale = 1; 11314 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11315 } else { 11316 scale = 0; 11317 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11318 } 11319 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11320 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11321 11322 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11323 (scale + 1); 11324 if (tmp[5] > 150) 11325 tmp[5] = 0; 11326 11327 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11328 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11329 11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11331 if (freqxtal > 26000000) 11332 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11333 else 11334 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11335 11336 if (val[0] == 45) 11337 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11338 else 11339 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11340 11341 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11342 DELAY(1); 11343 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11344 11345 /* VCO Calibration */ 11346 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11347 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11348 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11349 DELAY(1); 11350 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11351 DELAY(1); 11352 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11353 DELAY(1); 11354 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11355 DELAY(300); 11356 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11357 11358 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11359 return (0); 11360 } 11361 11362 static int 11363 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11364 { 11365 struct bwn_softc *sc = mac->mac_sc; 11366 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11367 const struct bwn_b206x_chan *bc = NULL; 11368 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11369 uint32_t tmp[9]; 11370 int i; 11371 11372 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11373 if (bwn_b2062_chantable[i].bc_chan == chan) { 11374 bc = &bwn_b2062_chantable[i]; 11375 break; 11376 } 11377 } 11378 11379 if (bc == NULL) 11380 return (EINVAL); 11381 11382 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11383 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11384 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11385 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11386 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11387 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11388 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11389 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11390 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11391 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11392 11393 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11394 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11395 bwn_phy_lp_b2062_reset_pllbias(mac); 11396 tmp[0] = freqxtal / 1000; 11397 tmp[1] = plp->plp_div * 1000; 11398 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11399 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11400 tmp[2] *= 2; 11401 tmp[3] = 48 * tmp[0]; 11402 tmp[5] = tmp[2] / tmp[3]; 11403 tmp[6] = tmp[2] % tmp[3]; 11404 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11405 tmp[4] = tmp[6] * 0x100; 11406 tmp[5] = tmp[4] / tmp[3]; 11407 tmp[6] = tmp[4] % tmp[3]; 11408 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11409 tmp[4] = tmp[6] * 0x100; 11410 tmp[5] = tmp[4] / tmp[3]; 11411 tmp[6] = tmp[4] % tmp[3]; 11412 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11413 tmp[4] = tmp[6] * 0x100; 11414 tmp[5] = tmp[4] / tmp[3]; 11415 tmp[6] = tmp[4] % tmp[3]; 11416 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11417 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11418 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11419 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11420 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11421 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11422 11423 bwn_phy_lp_b2062_vco_calib(mac); 11424 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11425 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11426 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11427 bwn_phy_lp_b2062_reset_pllbias(mac); 11428 bwn_phy_lp_b2062_vco_calib(mac); 11429 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11430 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11431 return (EIO); 11432 } 11433 } 11434 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11435 return (0); 11436 } 11437 11438 static void 11439 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11440 { 11441 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11442 uint16_t tmp = (channel == 14); 11443 11444 if (mac->mac_phy.rev < 2) { 11445 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11446 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11447 bwn_phy_lp_set_rccap(mac); 11448 return; 11449 } 11450 11451 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11452 } 11453 11454 static void 11455 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11456 { 11457 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11458 struct bwn_softc *sc = mac->mac_sc; 11459 struct ifnet *ifp = sc->sc_ifp; 11460 struct ieee80211com *ic = ifp->if_l2com; 11461 uint16_t iso, tmp[3]; 11462 11463 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11464 11465 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11466 iso = plp->plp_txisoband_m; 11467 else if (freq <= 5320) 11468 iso = plp->plp_txisoband_l; 11469 else if (freq <= 5700) 11470 iso = plp->plp_txisoband_m; 11471 else 11472 iso = plp->plp_txisoband_h; 11473 11474 tmp[0] = ((iso - 26) / 12) << 12; 11475 tmp[1] = tmp[0] + 0x1000; 11476 tmp[2] = tmp[0] + 0x2000; 11477 11478 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11479 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11480 } 11481 11482 static void 11483 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11484 { 11485 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11486 int i; 11487 static const uint16_t addr[] = { 11488 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11489 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11490 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11491 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11492 BWN_PHY_OFDM(0xcf), 11493 }; 11494 static const uint16_t val[] = { 11495 0xde5e, 0xe832, 0xe331, 0x4d26, 11496 0x0026, 0x1420, 0x0020, 0xfe08, 11497 0x0008, 11498 }; 11499 11500 for (i = 0; i < N(addr); i++) { 11501 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11502 BWN_PHY_WRITE(mac, addr[i], val[i]); 11503 } 11504 } 11505 11506 static void 11507 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11508 { 11509 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11510 struct bwn_softc *sc = mac->mac_sc; 11511 uint16_t ctl; 11512 11513 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11514 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11515 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11516 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11517 break; 11518 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11519 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11520 break; 11521 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11522 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11523 break; 11524 default: 11525 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11526 device_printf(sc->sc_dev, "unknown command mode\n"); 11527 break; 11528 } 11529 } 11530 11531 static void 11532 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11533 { 11534 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11535 uint16_t ctl; 11536 uint8_t old; 11537 11538 bwn_phy_lp_get_txpctlmode(mac); 11539 old = plp->plp_txpctlmode; 11540 if (old == mode) 11541 return; 11542 plp->plp_txpctlmode = mode; 11543 11544 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11545 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11546 plp->plp_tssiidx); 11547 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11548 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11549 11550 /* disable TX GAIN override */ 11551 if (mac->mac_phy.rev < 2) 11552 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11553 else { 11554 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11555 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11556 } 11557 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11558 11559 plp->plp_txpwridx = -1; 11560 } 11561 if (mac->mac_phy.rev >= 2) { 11562 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11563 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11564 else 11565 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11566 } 11567 11568 /* writes TX Power Control mode */ 11569 switch (plp->plp_txpctlmode) { 11570 case BWN_PHYLP_TXPCTL_OFF: 11571 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11572 break; 11573 case BWN_PHYLP_TXPCTL_ON_HW: 11574 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11575 break; 11576 case BWN_PHYLP_TXPCTL_ON_SW: 11577 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11578 break; 11579 default: 11580 ctl = 0; 11581 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11582 } 11583 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11584 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11585 } 11586 11587 static void 11588 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11589 { 11590 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11591 struct bwn_softc *sc = mac->mac_sc; 11592 const unsigned int size = 256; 11593 struct bwn_txgain tg; 11594 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11595 uint16_t tssinpt, tssiidx, value[2]; 11596 uint8_t mode; 11597 int8_t txpwridx; 11598 11599 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11600 M_NOWAIT | M_ZERO); 11601 if (tabs == NULL) { 11602 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11603 return; 11604 } 11605 11606 bwn_phy_lp_get_txpctlmode(mac); 11607 mode = plp->plp_txpctlmode; 11608 txpwridx = plp->plp_txpwridx; 11609 tssinpt = plp->plp_tssinpt; 11610 tssiidx = plp->plp_tssiidx; 11611 11612 bwn_tab_read_multi(mac, 11613 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11614 BWN_TAB_4(7, 0x140), size, tabs); 11615 11616 bwn_phy_lp_tblinit(mac); 11617 bwn_phy_lp_bbinit(mac); 11618 bwn_phy_lp_txpctl_init(mac); 11619 bwn_phy_lp_rf_onoff(mac, 1); 11620 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11621 11622 bwn_tab_write_multi(mac, 11623 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11624 BWN_TAB_4(7, 0x140), size, tabs); 11625 11626 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11627 plp->plp_tssinpt = tssinpt; 11628 plp->plp_tssiidx = tssiidx; 11629 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11630 if (txpwridx != -1) { 11631 /* set TX power by index */ 11632 plp->plp_txpwridx = txpwridx; 11633 bwn_phy_lp_get_txpctlmode(mac); 11634 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11635 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11636 if (mac->mac_phy.rev >= 2) { 11637 rxcomp = bwn_tab_read(mac, 11638 BWN_TAB_4(7, txpwridx + 320)); 11639 txgain = bwn_tab_read(mac, 11640 BWN_TAB_4(7, txpwridx + 192)); 11641 tg.tg_pad = (txgain >> 16) & 0xff; 11642 tg.tg_gm = txgain & 0xff; 11643 tg.tg_pga = (txgain >> 8) & 0xff; 11644 tg.tg_dac = (rxcomp >> 28) & 0xff; 11645 bwn_phy_lp_set_txgain(mac, &tg); 11646 } else { 11647 rxcomp = bwn_tab_read(mac, 11648 BWN_TAB_4(10, txpwridx + 320)); 11649 txgain = bwn_tab_read(mac, 11650 BWN_TAB_4(10, txpwridx + 192)); 11651 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11652 0xf800, (txgain >> 4) & 0x7fff); 11653 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11654 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11655 } 11656 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11657 11658 /* set TX IQCC */ 11659 value[0] = (rxcomp >> 10) & 0x3ff; 11660 value[1] = rxcomp & 0x3ff; 11661 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11662 11663 coeff = bwn_tab_read(mac, 11664 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11665 BWN_TAB_4(10, txpwridx + 448)); 11666 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11667 if (mac->mac_phy.rev >= 2) { 11668 rfpwr = bwn_tab_read(mac, 11669 BWN_TAB_4(7, txpwridx + 576)); 11670 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11671 rfpwr & 0xffff); 11672 } 11673 bwn_phy_lp_set_txgain_override(mac); 11674 } 11675 if (plp->plp_rccap) 11676 bwn_phy_lp_set_rccap(mac); 11677 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11678 bwn_phy_lp_set_txpctlmode(mac, mode); 11679 free(tabs, M_DEVBUF); 11680 } 11681 11682 static void 11683 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11684 { 11685 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11686 int i; 11687 static const uint16_t addr[] = { 11688 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11689 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11690 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11691 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11692 BWN_PHY_OFDM(0xcf), 11693 }; 11694 11695 for (i = 0; i < N(addr); i++) 11696 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11697 } 11698 11699 static void 11700 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11701 { 11702 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11703 11704 if (mac->mac_phy.rev < 2) { 11705 bwn_phy_lp_tblinit_r01(mac); 11706 bwn_phy_lp_tblinit_txgain(mac); 11707 bwn_phy_lp_set_gaintbl(mac, freq); 11708 return; 11709 } 11710 11711 bwn_phy_lp_tblinit_r2(mac); 11712 bwn_phy_lp_tblinit_txgain(mac); 11713 } 11714 11715 struct bwn_wpair { 11716 uint16_t reg; 11717 uint16_t value; 11718 }; 11719 11720 struct bwn_smpair { 11721 uint16_t offset; 11722 uint16_t mask; 11723 uint16_t set; 11724 }; 11725 11726 static void 11727 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11728 { 11729 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11730 struct bwn_softc *sc = mac->mac_sc; 11731 struct ifnet *ifp = sc->sc_ifp; 11732 struct ieee80211com *ic = ifp->if_l2com; 11733 static const struct bwn_wpair v1[] = { 11734 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11735 { BWN_PHY_AFE_CTL, 0x8800 }, 11736 { BWN_PHY_AFE_CTL_OVR, 0 }, 11737 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11738 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11739 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11740 { BWN_PHY_OFDM(0xf9), 0 }, 11741 { BWN_PHY_TR_LOOKUP_1, 0 } 11742 }; 11743 static const struct bwn_smpair v2[] = { 11744 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11745 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11746 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11747 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11748 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11749 }; 11750 static const struct bwn_smpair v3[] = { 11751 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11752 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11753 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11754 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11755 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11756 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11757 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11758 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11759 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11760 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11761 11762 }; 11763 int i; 11764 11765 for (i = 0; i < N(v1); i++) 11766 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11767 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11768 for (i = 0; i < N(v2); i++) 11769 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11770 11771 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11772 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11773 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11774 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11775 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11776 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11777 } else { 11778 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11779 } 11780 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11781 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11782 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11783 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11784 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11785 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11786 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11787 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11788 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11789 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11790 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11791 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11792 (siba_get_chiprev(sc->sc_dev) == 0)) { 11793 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11794 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11795 } else { 11796 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11797 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11798 } 11799 for (i = 0; i < N(v3); i++) 11800 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11801 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11802 (siba_get_chiprev(sc->sc_dev) == 0)) { 11803 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11804 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11805 } 11806 11807 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11808 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11809 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11810 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11811 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11812 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11813 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11814 } else 11815 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11816 11817 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11818 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11819 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11820 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11821 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11822 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11823 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11824 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11825 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11826 11827 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11828 (siba_get_chiprev(sc->sc_dev) == 0)) { 11829 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11830 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11831 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11832 } 11833 11834 bwn_phy_lp_digflt_save(mac); 11835 } 11836 11837 static void 11838 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11839 { 11840 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11841 struct bwn_softc *sc = mac->mac_sc; 11842 struct ifnet *ifp = sc->sc_ifp; 11843 struct ieee80211com *ic = ifp->if_l2com; 11844 static const struct bwn_smpair v1[] = { 11845 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11846 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11847 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11848 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11849 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11850 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11851 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11852 }; 11853 static const struct bwn_smpair v2[] = { 11854 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11855 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11856 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11857 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11858 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11859 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11860 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11861 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11862 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11863 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11864 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11865 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11866 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11867 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11868 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11869 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11870 }; 11871 static const struct bwn_smpair v3[] = { 11872 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11873 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11874 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11875 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11876 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11877 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11878 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11879 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11880 }; 11881 static const struct bwn_smpair v4[] = { 11882 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11883 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11884 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11885 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11886 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11887 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11888 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11889 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11890 }; 11891 static const struct bwn_smpair v5[] = { 11892 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11893 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11894 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11895 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11896 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11897 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11898 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11899 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11900 }; 11901 int i; 11902 uint16_t tmp, tmp2; 11903 11904 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11905 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11906 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11907 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11908 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11909 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11910 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11911 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11912 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11913 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11914 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11915 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11916 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11917 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11918 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11919 for (i = 0; i < N(v1); i++) 11920 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11921 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11922 0xff00, plp->plp_rxpwroffset); 11923 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11924 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11925 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11926 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11927 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11928 if (mac->mac_phy.rev == 0) 11929 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11930 0xffcf, 0x0010); 11931 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11932 } else { 11933 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11934 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11935 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11936 } 11937 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11938 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11939 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11940 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11941 else 11942 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11943 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11944 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11945 0xfff9, (plp->plp_bxarch << 1)); 11946 if (mac->mac_phy.rev == 1 && 11947 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11948 for (i = 0; i < N(v2); i++) 11949 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11950 v2[i].set); 11951 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11952 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11953 ((mac->mac_phy.rev == 0) && 11954 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11955 for (i = 0; i < N(v3); i++) 11956 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11957 v3[i].set); 11958 } else if (mac->mac_phy.rev == 1 || 11959 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11960 for (i = 0; i < N(v4); i++) 11961 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11962 v4[i].set); 11963 } else { 11964 for (i = 0; i < N(v5); i++) 11965 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11966 v5[i].set); 11967 } 11968 if (mac->mac_phy.rev == 1 && 11969 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11970 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11971 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11972 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11973 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11974 } 11975 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11976 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11977 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11978 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11979 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11980 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11981 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11982 } 11983 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11984 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11985 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11986 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11987 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11988 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11989 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11990 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11991 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11992 } else { 11993 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11994 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11995 } 11996 if (mac->mac_phy.rev == 1) { 11997 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11998 tmp2 = (tmp & 0x03e0) >> 5; 11999 tmp2 |= tmp2 << 5; 12000 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12001 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12002 tmp2 = (tmp & 0x1f00) >> 8; 12003 tmp2 |= tmp2 << 5; 12004 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12005 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12006 tmp2 = tmp & 0x00ff; 12007 tmp2 |= tmp << 8; 12008 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12009 } 12010 } 12011 12012 struct bwn_b2062_freq { 12013 uint16_t freq; 12014 uint8_t value[6]; 12015 }; 12016 12017 static void 12018 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12019 { 12020 #define CALC_CTL7(freq, div) \ 12021 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12022 #define CALC_CTL18(freq, div) \ 12023 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12024 #define CALC_CTL19(freq, div) \ 12025 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12026 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12027 struct bwn_softc *sc = mac->mac_sc; 12028 struct ifnet *ifp = sc->sc_ifp; 12029 struct ieee80211com *ic = ifp->if_l2com; 12030 static const struct bwn_b2062_freq freqdata_tab[] = { 12031 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12032 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12033 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12034 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12035 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12036 { 19200, { 1, 1, 1, 1, 14, 9 } } 12037 }; 12038 static const struct bwn_wpair v1[] = { 12039 { BWN_B2062_N_TXCTL3, 0 }, 12040 { BWN_B2062_N_TXCTL4, 0 }, 12041 { BWN_B2062_N_TXCTL5, 0 }, 12042 { BWN_B2062_N_TXCTL6, 0 }, 12043 { BWN_B2062_N_PDNCTL0, 0x40 }, 12044 { BWN_B2062_N_PDNCTL0, 0 }, 12045 { BWN_B2062_N_CALIB_TS, 0x10 }, 12046 { BWN_B2062_N_CALIB_TS, 0 } 12047 }; 12048 const struct bwn_b2062_freq *f = NULL; 12049 uint32_t xtalfreq, ref; 12050 unsigned int i; 12051 12052 bwn_phy_lp_b2062_tblinit(mac); 12053 12054 for (i = 0; i < N(v1); i++) 12055 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12056 if (mac->mac_phy.rev > 0) 12057 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12058 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12059 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12060 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12061 else 12062 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12063 12064 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 12065 ("%s:%d: fail", __func__, __LINE__)); 12066 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12067 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12068 12069 if (xtalfreq <= 30000000) { 12070 plp->plp_div = 1; 12071 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12072 } else { 12073 plp->plp_div = 2; 12074 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12075 } 12076 12077 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12078 CALC_CTL7(xtalfreq, plp->plp_div)); 12079 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12080 CALC_CTL18(xtalfreq, plp->plp_div)); 12081 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12082 CALC_CTL19(xtalfreq, plp->plp_div)); 12083 12084 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12085 ref &= 0xffff; 12086 for (i = 0; i < N(freqdata_tab); i++) { 12087 if (ref < freqdata_tab[i].freq) { 12088 f = &freqdata_tab[i]; 12089 break; 12090 } 12091 } 12092 if (f == NULL) 12093 f = &freqdata_tab[N(freqdata_tab) - 1]; 12094 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12095 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12096 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12097 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12098 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12099 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12100 #undef CALC_CTL7 12101 #undef CALC_CTL18 12102 #undef CALC_CTL19 12103 } 12104 12105 static void 12106 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12107 { 12108 12109 bwn_phy_lp_b2063_tblinit(mac); 12110 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12111 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12112 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12113 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12114 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12115 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12116 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12117 if (mac->mac_phy.rev == 2) { 12118 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12119 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12120 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12121 } else { 12122 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12123 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12124 } 12125 } 12126 12127 static void 12128 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12129 { 12130 struct bwn_softc *sc = mac->mac_sc; 12131 static const struct bwn_wpair v1[] = { 12132 { BWN_B2063_RX_BB_SP8, 0x0 }, 12133 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12134 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12135 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12136 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12137 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12138 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12139 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12140 }; 12141 static const struct bwn_wpair v2[] = { 12142 { BWN_B2063_TX_BB_SP3, 0x0 }, 12143 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12144 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12145 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12146 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12147 }; 12148 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12149 int i; 12150 uint8_t tmp; 12151 12152 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12153 12154 for (i = 0; i < 2; i++) 12155 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12156 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12157 for (i = 2; i < N(v1); i++) 12158 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12159 for (i = 0; i < 10000; i++) { 12160 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12161 break; 12162 DELAY(1000); 12163 } 12164 12165 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12166 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12167 12168 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12169 12170 for (i = 0; i < N(v2); i++) 12171 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12172 if (freqxtal == 24000000) { 12173 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12174 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12175 } else { 12176 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12177 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12178 } 12179 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12180 for (i = 0; i < 10000; i++) { 12181 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12182 break; 12183 DELAY(1000); 12184 } 12185 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12186 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12187 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12188 } 12189 12190 static void 12191 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12192 { 12193 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12194 struct bwn_softc *sc = mac->mac_sc; 12195 struct bwn_phy_lp_iq_est ie; 12196 struct bwn_txgain tx_gains; 12197 static const uint32_t pwrtbl[21] = { 12198 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12199 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12200 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12201 0x0004c, 0x0002c, 0x0001a, 12202 }; 12203 uint32_t npwr, ipwr, sqpwr, tmp; 12204 int loopback, i, j, sum, error; 12205 uint16_t save[7]; 12206 uint8_t txo, bbmult, txpctlmode; 12207 12208 error = bwn_phy_lp_switch_channel(mac, 7); 12209 if (error) 12210 device_printf(sc->sc_dev, 12211 "failed to change channel to 7 (%d)\n", error); 12212 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12213 bbmult = bwn_phy_lp_get_bbmult(mac); 12214 if (txo) 12215 tx_gains = bwn_phy_lp_get_txgain(mac); 12216 12217 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12218 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12219 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12220 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12221 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12222 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12223 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12224 12225 bwn_phy_lp_get_txpctlmode(mac); 12226 txpctlmode = plp->plp_txpctlmode; 12227 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12228 12229 /* disable CRS */ 12230 bwn_phy_lp_set_deaf(mac, 1); 12231 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12232 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12233 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12234 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12235 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12236 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12237 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12238 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12239 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12240 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12241 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12242 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12243 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12244 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12245 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12246 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12247 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12248 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12249 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12250 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12251 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12252 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12253 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12254 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12255 12256 loopback = bwn_phy_lp_loopback(mac); 12257 if (loopback == -1) 12258 goto done; 12259 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12260 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12261 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12262 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12263 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12264 12265 tmp = 0; 12266 memset(&ie, 0, sizeof(ie)); 12267 for (i = 128; i <= 159; i++) { 12268 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12269 sum = 0; 12270 for (j = 5; j <= 25; j++) { 12271 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12272 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12273 goto done; 12274 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12275 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12276 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12277 12); 12278 sum += ((ipwr - npwr) * (ipwr - npwr)); 12279 if ((i == 128) || (sum < tmp)) { 12280 plp->plp_rccap = i; 12281 tmp = sum; 12282 } 12283 } 12284 } 12285 bwn_phy_lp_ddfs_turnoff(mac); 12286 done: 12287 /* restore CRS */ 12288 bwn_phy_lp_clear_deaf(mac, 1); 12289 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12290 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12291 12292 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12293 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12294 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12295 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12296 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12297 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12298 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12299 12300 bwn_phy_lp_set_bbmult(mac, bbmult); 12301 if (txo) 12302 bwn_phy_lp_set_txgain(mac, &tx_gains); 12303 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12304 if (plp->plp_rccap) 12305 bwn_phy_lp_set_rccap(mac); 12306 } 12307 12308 static void 12309 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12310 { 12311 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12312 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12313 12314 if (mac->mac_phy.rev == 1) 12315 rc_cap = MIN(rc_cap + 5, 15); 12316 12317 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12318 MAX(plp->plp_rccap - 4, 0x80)); 12319 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12320 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12321 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12322 } 12323 12324 static uint32_t 12325 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12326 { 12327 uint32_t i, q, r; 12328 12329 if (div == 0) 12330 return (0); 12331 12332 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12333 q <<= 1; 12334 if (r << 1 >= div) { 12335 q++; 12336 r = (r << 1) - div; 12337 } 12338 } 12339 if (r << 1 >= div) 12340 q++; 12341 return (q); 12342 } 12343 12344 static void 12345 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12346 { 12347 struct bwn_softc *sc = mac->mac_sc; 12348 12349 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12350 DELAY(20); 12351 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12352 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12353 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12354 } else { 12355 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12356 } 12357 DELAY(5); 12358 } 12359 12360 static void 12361 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12362 { 12363 12364 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12365 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12366 DELAY(200); 12367 } 12368 12369 static void 12370 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12371 { 12372 #define FLAG_A 0x01 12373 #define FLAG_G 0x02 12374 struct bwn_softc *sc = mac->mac_sc; 12375 struct ifnet *ifp = sc->sc_ifp; 12376 struct ieee80211com *ic = ifp->if_l2com; 12377 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12378 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12379 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12380 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12381 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12382 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12383 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12384 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12385 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12386 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12387 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12388 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12389 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12390 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12391 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12392 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12393 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12394 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12395 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12396 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12397 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12398 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12399 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12400 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12401 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12402 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12403 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12404 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12405 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12406 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12407 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12408 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12409 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12410 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12411 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12412 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12413 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12414 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12415 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12416 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12417 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12418 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12419 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12420 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12421 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12422 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12423 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12424 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12425 }; 12426 const struct bwn_b206x_rfinit_entry *br; 12427 unsigned int i; 12428 12429 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12430 br = &bwn_b2062_init_tab[i]; 12431 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12432 if (br->br_flags & FLAG_G) 12433 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12434 } else { 12435 if (br->br_flags & FLAG_A) 12436 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12437 } 12438 } 12439 #undef FLAG_A 12440 #undef FLAG_B 12441 } 12442 12443 static void 12444 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12445 { 12446 #define FLAG_A 0x01 12447 #define FLAG_G 0x02 12448 struct bwn_softc *sc = mac->mac_sc; 12449 struct ifnet *ifp = sc->sc_ifp; 12450 struct ieee80211com *ic = ifp->if_l2com; 12451 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12452 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12453 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12454 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12455 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12456 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12457 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12458 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12459 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12460 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12461 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12462 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12463 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12464 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12465 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12466 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12467 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12468 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12469 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12470 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12471 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12472 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12473 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12474 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12475 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12476 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12477 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12478 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12479 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12480 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12481 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12482 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12483 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12484 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12485 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12486 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12487 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12488 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12489 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12490 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12491 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12492 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12493 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12494 }; 12495 const struct bwn_b206x_rfinit_entry *br; 12496 unsigned int i; 12497 12498 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12499 br = &bwn_b2063_init_tab[i]; 12500 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12501 if (br->br_flags & FLAG_G) 12502 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12503 } else { 12504 if (br->br_flags & FLAG_A) 12505 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12506 } 12507 } 12508 #undef FLAG_A 12509 #undef FLAG_B 12510 } 12511 12512 static void 12513 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12514 int count, void *_data) 12515 { 12516 unsigned int i; 12517 uint32_t offset, type; 12518 uint8_t *data = _data; 12519 12520 type = BWN_TAB_GETTYPE(typenoffset); 12521 offset = BWN_TAB_GETOFFSET(typenoffset); 12522 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12523 12524 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12525 12526 for (i = 0; i < count; i++) { 12527 switch (type) { 12528 case BWN_TAB_8BIT: 12529 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12530 data++; 12531 break; 12532 case BWN_TAB_16BIT: 12533 *((uint16_t *)data) = BWN_PHY_READ(mac, 12534 BWN_PHY_TABLEDATALO); 12535 data += 2; 12536 break; 12537 case BWN_TAB_32BIT: 12538 *((uint32_t *)data) = BWN_PHY_READ(mac, 12539 BWN_PHY_TABLEDATAHI); 12540 *((uint32_t *)data) <<= 16; 12541 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12542 BWN_PHY_TABLEDATALO); 12543 data += 4; 12544 break; 12545 default: 12546 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12547 } 12548 } 12549 } 12550 12551 static void 12552 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12553 int count, const void *_data) 12554 { 12555 uint32_t offset, type, value; 12556 const uint8_t *data = _data; 12557 unsigned int i; 12558 12559 type = BWN_TAB_GETTYPE(typenoffset); 12560 offset = BWN_TAB_GETOFFSET(typenoffset); 12561 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12562 12563 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12564 12565 for (i = 0; i < count; i++) { 12566 switch (type) { 12567 case BWN_TAB_8BIT: 12568 value = *data; 12569 data++; 12570 KASSERT(!(value & ~0xff), 12571 ("%s:%d: fail", __func__, __LINE__)); 12572 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12573 break; 12574 case BWN_TAB_16BIT: 12575 value = *((const uint16_t *)data); 12576 data += 2; 12577 KASSERT(!(value & ~0xffff), 12578 ("%s:%d: fail", __func__, __LINE__)); 12579 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12580 break; 12581 case BWN_TAB_32BIT: 12582 value = *((const uint32_t *)data); 12583 data += 4; 12584 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12585 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12586 break; 12587 default: 12588 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12589 } 12590 } 12591 } 12592 12593 static struct bwn_txgain 12594 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12595 { 12596 struct bwn_txgain tg; 12597 uint16_t tmp; 12598 12599 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12600 if (mac->mac_phy.rev < 2) { 12601 tmp = BWN_PHY_READ(mac, 12602 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12603 tg.tg_gm = tmp & 0x0007; 12604 tg.tg_pga = (tmp & 0x0078) >> 3; 12605 tg.tg_pad = (tmp & 0x780) >> 7; 12606 return (tg); 12607 } 12608 12609 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12610 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12611 tg.tg_gm = tmp & 0xff; 12612 tg.tg_pga = (tmp >> 8) & 0xff; 12613 return (tg); 12614 } 12615 12616 static uint8_t 12617 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12618 { 12619 12620 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12621 } 12622 12623 static void 12624 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12625 { 12626 uint16_t pa; 12627 12628 if (mac->mac_phy.rev < 2) { 12629 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12630 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12631 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12632 bwn_phy_lp_set_txgain_override(mac); 12633 return; 12634 } 12635 12636 pa = bwn_phy_lp_get_pa_gain(mac); 12637 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12638 (tg->tg_pga << 8) | tg->tg_gm); 12639 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12640 tg->tg_pad | (pa << 6)); 12641 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12642 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12643 tg->tg_pad | (pa << 8)); 12644 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12645 bwn_phy_lp_set_txgain_override(mac); 12646 } 12647 12648 static void 12649 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12650 { 12651 12652 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12653 } 12654 12655 static void 12656 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12657 { 12658 uint16_t trsw = (tx << 1) | rx; 12659 12660 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12661 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12662 } 12663 12664 static void 12665 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12666 { 12667 struct bwn_softc *sc = mac->mac_sc; 12668 struct ifnet *ifp = sc->sc_ifp; 12669 struct ieee80211com *ic = ifp->if_l2com; 12670 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12671 12672 if (mac->mac_phy.rev < 2) { 12673 trsw = gain & 0x1; 12674 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12675 ext_lna = (gain & 2) >> 1; 12676 12677 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12678 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12679 0xfbff, ext_lna << 10); 12680 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12681 0xf7ff, ext_lna << 11); 12682 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12683 } else { 12684 low_gain = gain & 0xffff; 12685 high_gain = (gain >> 16) & 0xf; 12686 ext_lna = (gain >> 21) & 0x1; 12687 trsw = ~(gain >> 20) & 0x1; 12688 12689 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12690 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12691 0xfdff, ext_lna << 9); 12692 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12693 0xfbff, ext_lna << 10); 12694 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12695 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12696 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12697 tmp = (gain >> 2) & 0x3; 12698 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12699 0xe7ff, tmp<<11); 12700 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12701 tmp << 3); 12702 } 12703 } 12704 12705 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12706 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12707 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12708 if (mac->mac_phy.rev >= 2) { 12709 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12710 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12711 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12712 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12713 } 12714 return; 12715 } 12716 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12717 } 12718 12719 static void 12720 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12721 { 12722 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12723 12724 if (user) 12725 plp->plp_crsusr_off = 1; 12726 else 12727 plp->plp_crssys_off = 1; 12728 12729 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12730 } 12731 12732 static void 12733 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12734 { 12735 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12736 struct bwn_softc *sc = mac->mac_sc; 12737 struct ifnet *ifp = sc->sc_ifp; 12738 struct ieee80211com *ic = ifp->if_l2com; 12739 12740 if (user) 12741 plp->plp_crsusr_off = 0; 12742 else 12743 plp->plp_crssys_off = 0; 12744 12745 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12746 return; 12747 12748 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12749 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12750 else 12751 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12752 } 12753 12754 static unsigned int 12755 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12756 { 12757 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12758 static uint8_t sqrt_table[256] = { 12759 10, 14, 17, 20, 22, 24, 26, 28, 12760 30, 31, 33, 34, 36, 37, 38, 40, 12761 41, 42, 43, 44, 45, 46, 47, 48, 12762 50, 50, 51, 52, 53, 54, 55, 56, 12763 57, 58, 59, 60, 60, 61, 62, 63, 12764 64, 64, 65, 66, 67, 67, 68, 69, 12765 70, 70, 71, 72, 72, 73, 74, 74, 12766 75, 76, 76, 77, 78, 78, 79, 80, 12767 80, 81, 81, 82, 83, 83, 84, 84, 12768 85, 86, 86, 87, 87, 88, 88, 89, 12769 90, 90, 91, 91, 92, 92, 93, 93, 12770 94, 94, 95, 95, 96, 96, 97, 97, 12771 98, 98, 99, 100, 100, 100, 101, 101, 12772 102, 102, 103, 103, 104, 104, 105, 105, 12773 106, 106, 107, 107, 108, 108, 109, 109, 12774 110, 110, 110, 111, 111, 112, 112, 113, 12775 113, 114, 114, 114, 115, 115, 116, 116, 12776 117, 117, 117, 118, 118, 119, 119, 120, 12777 120, 120, 121, 121, 122, 122, 122, 123, 12778 123, 124, 124, 124, 125, 125, 126, 126, 12779 126, 127, 127, 128, 128, 128, 129, 129, 12780 130, 130, 130, 131, 131, 131, 132, 132, 12781 133, 133, 133, 134, 134, 134, 135, 135, 12782 136, 136, 136, 137, 137, 137, 138, 138, 12783 138, 139, 139, 140, 140, 140, 141, 141, 12784 141, 142, 142, 142, 143, 143, 143, 144, 12785 144, 144, 145, 145, 145, 146, 146, 146, 12786 147, 147, 147, 148, 148, 148, 149, 149, 12787 150, 150, 150, 150, 151, 151, 151, 152, 12788 152, 152, 153, 153, 153, 154, 154, 154, 12789 155, 155, 155, 156, 156, 156, 157, 157, 12790 157, 158, 158, 158, 159, 159, 159, 160 12791 }; 12792 12793 if (x == 0) 12794 return (0); 12795 if (x >= 256) { 12796 unsigned int tmp; 12797 12798 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12799 /* do nothing */ ; 12800 return (tmp); 12801 } 12802 return (sqrt_table[x - 1] / 10); 12803 } 12804 12805 static int 12806 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12807 { 12808 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12809 int _t; \ 12810 _t = _x - 20; \ 12811 if (_t >= 0) { \ 12812 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12813 } else { \ 12814 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12815 } \ 12816 } while (0) 12817 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12818 int _t; \ 12819 _t = _x - 11; \ 12820 if (_t >= 0) \ 12821 _v = (_y << (31 - _x)) / (_z >> _t); \ 12822 else \ 12823 _v = (_y << (31 - _x)) / (_z << -_t); \ 12824 } while (0) 12825 struct bwn_phy_lp_iq_est ie; 12826 uint16_t v0, v1; 12827 int tmp[2], ret; 12828 12829 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12830 v0 = v1 >> 8; 12831 v1 |= 0xff; 12832 12833 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12834 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12835 12836 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12837 if (ret == 0) 12838 goto done; 12839 12840 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12841 ret = 0; 12842 goto done; 12843 } 12844 12845 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12846 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12847 12848 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12849 v0 = tmp[0] >> 3; 12850 v1 = tmp[1] >> 4; 12851 done: 12852 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12853 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12854 return ret; 12855 #undef CALC_COEFF 12856 #undef CALC_COEFF2 12857 } 12858 12859 static void 12860 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12861 { 12862 static const uint16_t noisescale[] = { 12863 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12864 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12865 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12866 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12867 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12868 }; 12869 static const uint16_t crsgainnft[] = { 12870 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12871 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12872 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12873 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12874 0x013d, 12875 }; 12876 static const uint16_t filterctl[] = { 12877 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12878 0xff53, 0x0127, 12879 }; 12880 static const uint32_t psctl[] = { 12881 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12882 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12883 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12884 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12885 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12886 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12887 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12888 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12889 }; 12890 static const uint16_t ofdmcckgain_r0[] = { 12891 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12892 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12893 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12894 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12895 0x755d, 12896 }; 12897 static const uint16_t ofdmcckgain_r1[] = { 12898 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12899 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12900 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12901 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12902 0x755d, 12903 }; 12904 static const uint16_t gaindelta[] = { 12905 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12906 0x0000, 12907 }; 12908 static const uint32_t txpwrctl[] = { 12909 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12910 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12911 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12912 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12913 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12914 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12915 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12916 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12917 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12918 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12919 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12920 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12921 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12922 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12923 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12924 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12925 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12926 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12939 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12940 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12941 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12947 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12948 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12949 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12950 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12951 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12952 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12953 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12954 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12955 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12956 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12957 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12958 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12959 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12960 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12961 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12962 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12963 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12964 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12965 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12966 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12967 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12968 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12969 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12970 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12971 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12972 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12973 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12974 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12975 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12976 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12977 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12978 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12979 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12980 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12981 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12982 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12983 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12984 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12985 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12986 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12987 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12988 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12989 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12990 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12991 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12992 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12993 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12994 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12995 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12996 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12997 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12998 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12999 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13000 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13001 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13002 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13003 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13004 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13005 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13006 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13007 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13008 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13009 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13010 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13011 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13012 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13013 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13014 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13015 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13016 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13017 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13018 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13019 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13020 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13021 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13022 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13023 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13024 0x00000702, 13025 }; 13026 13027 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13028 13029 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13030 bwn_tab_sigsq_tbl); 13031 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13032 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13033 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13034 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13035 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13036 bwn_tab_pllfrac_tbl); 13037 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13038 bwn_tabl_iqlocal_tbl); 13039 if (mac->mac_phy.rev == 0) { 13040 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13041 ofdmcckgain_r0); 13042 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13043 ofdmcckgain_r0); 13044 } else { 13045 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13046 ofdmcckgain_r1); 13047 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13048 ofdmcckgain_r1); 13049 } 13050 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13051 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13052 } 13053 13054 static void 13055 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13056 { 13057 struct bwn_softc *sc = mac->mac_sc; 13058 int i; 13059 static const uint16_t noisescale[] = { 13060 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13061 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13062 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13063 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13064 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13065 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13066 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13067 }; 13068 static const uint32_t filterctl[] = { 13069 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13070 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13071 }; 13072 static const uint32_t psctl[] = { 13073 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13074 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13075 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13076 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13077 }; 13078 static const uint32_t gainidx[] = { 13079 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13080 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13081 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13082 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13083 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13084 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13085 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13086 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13087 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13088 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13089 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13090 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13091 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13092 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13093 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13094 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13095 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13096 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13097 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13098 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13099 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13100 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13101 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13102 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13103 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13104 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13105 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13106 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13107 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13108 0x0000001a, 0x64ca55ad, 0x0000001a 13109 }; 13110 static const uint16_t auxgainidx[] = { 13111 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13112 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13113 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13114 0x0004, 0x0016 13115 }; 13116 static const uint16_t swctl[] = { 13117 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13118 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13119 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13120 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13121 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13122 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13123 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13124 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13125 }; 13126 static const uint8_t hf[] = { 13127 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13128 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13129 }; 13130 static const uint32_t gainval[] = { 13131 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13132 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13133 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13134 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13135 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13136 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13137 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13138 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13139 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13141 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13142 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13143 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13144 0x000000f1, 0x00000000, 0x00000000 13145 }; 13146 static const uint16_t gain[] = { 13147 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13148 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13149 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13150 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13151 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13152 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13153 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13154 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13155 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13156 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13157 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13158 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13159 }; 13160 static const uint32_t papdeps[] = { 13161 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13162 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13163 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13164 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13165 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13166 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13167 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13168 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13169 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13170 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13171 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13172 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13173 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13174 }; 13175 static const uint32_t papdmult[] = { 13176 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13177 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13178 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13179 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13180 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13181 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13182 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13183 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13184 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13185 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13186 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13187 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13188 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13189 }; 13190 static const uint32_t gainidx_a0[] = { 13191 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13192 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13193 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13194 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13195 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13196 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13197 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13198 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13199 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13200 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13201 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13202 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13203 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13204 }; 13205 static const uint16_t auxgainidx_a0[] = { 13206 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13207 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13208 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13209 0x0002, 0x0014 13210 }; 13211 static const uint32_t gainval_a0[] = { 13212 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13213 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13214 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13215 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13216 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13217 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13218 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13219 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13220 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13222 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13223 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13225 0x000000f7, 0x00000000, 0x00000000 13226 }; 13227 static const uint16_t gain_a0[] = { 13228 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13229 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13230 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13231 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13232 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13233 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13234 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13235 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13236 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13237 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13238 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13239 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13240 }; 13241 13242 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13243 13244 for (i = 0; i < 704; i++) 13245 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13246 13247 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13248 bwn_tab_sigsq_tbl); 13249 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13250 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13251 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13252 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13253 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13254 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13255 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13256 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13257 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13258 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13259 bwn_tab_pllfrac_tbl); 13260 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13261 bwn_tabl_iqlocal_tbl); 13262 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13263 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13264 13265 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13266 (siba_get_chiprev(sc->sc_dev) == 0)) { 13267 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13268 gainidx_a0); 13269 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13270 auxgainidx_a0); 13271 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13272 gainval_a0); 13273 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13274 } 13275 } 13276 13277 static void 13278 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13279 { 13280 struct bwn_softc *sc = mac->mac_sc; 13281 struct ifnet *ifp = sc->sc_ifp; 13282 struct ieee80211com *ic = ifp->if_l2com; 13283 static struct bwn_txgain_entry txgain_r2[] = { 13284 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13285 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13286 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13287 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13288 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13289 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13290 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13291 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13292 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13293 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13294 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13295 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13296 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13297 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13298 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13299 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13300 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13301 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13302 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13303 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13304 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13305 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13306 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13307 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13308 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13309 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13310 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13311 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13312 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13313 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13314 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13315 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13316 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13317 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13318 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13319 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13320 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13321 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13322 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13323 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13324 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13325 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13326 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13327 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13328 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13329 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13330 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13331 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13332 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13333 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13334 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13335 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13336 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13337 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13338 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13339 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13340 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13341 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13342 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13343 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13344 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13345 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13346 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13347 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13348 }; 13349 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13350 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13351 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13352 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13353 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13354 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13355 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13356 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13357 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13358 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13359 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13360 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13361 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13362 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13363 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13364 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13365 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13366 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13367 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13368 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13369 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13370 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13371 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13372 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13373 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13374 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13375 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13376 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13377 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13378 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13379 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13380 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13381 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13382 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13383 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13384 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13385 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13386 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13387 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13388 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13389 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13390 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13391 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13392 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13393 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13394 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13395 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13396 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13397 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13398 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13399 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13400 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13401 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13402 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13403 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13404 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13405 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13406 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13407 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13408 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13409 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13410 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13411 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13412 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13413 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13414 }; 13415 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13416 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13417 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13418 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13419 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13420 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13421 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13422 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13423 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13424 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13425 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13426 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13427 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13428 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13429 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13430 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13431 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13432 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13433 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13434 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13435 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13436 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13437 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13438 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13439 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13440 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13441 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13442 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13443 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13444 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13445 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13446 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13447 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13448 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13449 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13450 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13451 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13452 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13453 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13454 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13455 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13456 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13457 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13458 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13459 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13460 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13461 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13462 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13463 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13464 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13465 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13466 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13467 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13468 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13469 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13470 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13471 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13472 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13473 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13474 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13475 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13476 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13477 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13478 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13479 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13480 }; 13481 static struct bwn_txgain_entry txgain_r0[] = { 13482 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13483 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13484 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13485 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13486 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13487 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13488 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13489 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13490 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13491 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13492 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13493 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13494 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13495 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13496 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13497 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13498 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13499 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13500 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13501 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13502 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13503 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13504 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13505 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13506 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13507 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13508 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13509 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13510 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13511 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13512 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13513 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13514 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13515 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13516 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13517 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13518 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13519 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13520 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13521 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13522 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13523 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13524 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13525 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13526 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13527 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13528 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13529 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13530 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13531 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13532 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13533 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13534 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13535 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13536 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13537 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13538 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13539 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13540 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13541 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13542 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13543 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13544 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13545 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13546 }; 13547 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13548 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13549 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13550 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13551 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13552 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13553 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13554 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13555 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13556 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13557 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13558 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13559 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13560 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13561 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13562 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13563 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13564 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13565 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13566 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13567 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13568 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13569 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13570 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13571 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13572 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13573 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13574 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13575 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13576 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13577 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13578 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13579 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13580 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13581 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13582 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13583 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13584 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13585 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13586 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13587 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13588 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13589 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13590 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13591 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13592 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13593 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13594 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13595 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13596 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13597 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13598 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13599 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13600 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13601 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13602 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13603 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13604 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13605 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13606 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13607 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13608 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13609 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13610 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13611 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13612 }; 13613 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13614 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13615 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13616 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13617 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13618 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13619 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13620 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13621 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13622 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13623 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13624 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13625 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13626 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13627 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13628 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13629 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13630 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13631 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13632 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13633 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13634 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13635 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13636 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13637 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13638 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13639 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13640 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13641 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13642 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13643 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13644 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13645 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13646 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13647 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13648 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13649 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13650 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13651 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13652 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13653 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13654 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13655 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13656 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13657 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13658 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13659 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13660 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13661 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13662 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13663 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13664 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13665 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13666 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13667 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13668 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13669 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13670 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13671 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13672 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13673 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13674 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13675 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13676 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13677 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13678 }; 13679 static struct bwn_txgain_entry txgain_r1[] = { 13680 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13681 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13682 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13683 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13684 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13685 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13686 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13687 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13688 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13689 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13690 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13691 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13692 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13693 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13694 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13695 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13696 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13697 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13698 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13699 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13700 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13701 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13702 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13703 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13704 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13705 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13706 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13707 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13708 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13709 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13710 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13711 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13712 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13713 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13714 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13715 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13716 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13717 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13718 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13719 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13720 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13721 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13722 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13723 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13724 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13725 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13726 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13727 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13728 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13729 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13730 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13731 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13732 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13733 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13734 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13735 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13736 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13737 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13738 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13739 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13740 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13741 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13742 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13743 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13744 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13745 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13746 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13747 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13748 { 7, 11, 6, 0, 71 } 13749 }; 13750 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13751 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13752 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13753 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13754 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13755 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13756 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13757 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13758 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13759 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13760 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13761 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13762 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13763 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13764 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13765 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13766 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13767 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13768 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13769 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13770 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13771 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13772 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13773 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13774 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13775 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13776 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13777 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13778 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13779 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13780 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13781 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13782 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13783 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13784 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13785 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13786 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13787 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13788 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13789 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13790 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13791 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13792 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13793 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13794 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13795 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13796 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13797 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13798 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13799 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13800 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13801 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13802 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13803 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13804 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13805 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13806 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13807 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13808 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13809 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13810 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13811 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13812 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13813 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13814 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13815 }; 13816 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13817 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13818 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13819 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13820 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13821 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13822 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13823 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13824 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13825 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13826 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13827 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13828 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13829 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13830 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13831 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13832 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13833 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13834 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13835 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13836 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13837 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13838 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13839 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13840 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13841 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13842 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13843 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13844 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13845 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13846 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13847 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13848 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13849 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13850 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13851 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13852 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13853 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13854 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13855 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13856 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13857 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13858 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13859 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13860 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13861 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13862 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13863 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13864 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13865 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13866 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13867 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13868 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13869 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13870 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13871 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13872 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13873 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13874 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13875 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13876 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13877 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13878 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13879 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13880 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13881 }; 13882 13883 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13884 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13885 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13886 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13887 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13888 txgain_2ghz_r2); 13889 else 13890 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13891 txgain_5ghz_r2); 13892 return; 13893 } 13894 13895 if (mac->mac_phy.rev == 0) { 13896 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13897 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13898 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13899 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13900 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13901 txgain_2ghz_r0); 13902 else 13903 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13904 txgain_5ghz_r0); 13905 return; 13906 } 13907 13908 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13909 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13910 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13911 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13912 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13913 else 13914 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13915 } 13916 13917 static void 13918 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13919 { 13920 uint32_t offset, type; 13921 13922 type = BWN_TAB_GETTYPE(typeoffset); 13923 offset = BWN_TAB_GETOFFSET(typeoffset); 13924 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13925 13926 switch (type) { 13927 case BWN_TAB_8BIT: 13928 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13929 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13930 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13931 break; 13932 case BWN_TAB_16BIT: 13933 KASSERT(!(value & ~0xffff), 13934 ("%s:%d: fail", __func__, __LINE__)); 13935 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13936 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13937 break; 13938 case BWN_TAB_32BIT: 13939 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13940 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13941 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13942 break; 13943 default: 13944 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13945 } 13946 } 13947 13948 static int 13949 bwn_phy_lp_loopback(struct bwn_mac *mac) 13950 { 13951 struct bwn_phy_lp_iq_est ie; 13952 int i, index = -1; 13953 uint32_t tmp; 13954 13955 memset(&ie, 0, sizeof(ie)); 13956 13957 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13958 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13959 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13960 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13961 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13962 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13964 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13965 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13966 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13967 for (i = 0; i < 32; i++) { 13968 bwn_phy_lp_set_rxgain_idx(mac, i); 13969 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13970 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13971 continue; 13972 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13973 if ((tmp > 4000) && (tmp < 10000)) { 13974 index = i; 13975 break; 13976 } 13977 } 13978 bwn_phy_lp_ddfs_turnoff(mac); 13979 return (index); 13980 } 13981 13982 static void 13983 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13984 { 13985 13986 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13987 } 13988 13989 static void 13990 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13991 int incr1, int incr2, int scale_idx) 13992 { 13993 13994 bwn_phy_lp_ddfs_turnoff(mac); 13995 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13996 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13997 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13998 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13999 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14000 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14002 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14003 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14004 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14005 } 14006 14007 static uint8_t 14008 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14009 struct bwn_phy_lp_iq_est *ie) 14010 { 14011 int i; 14012 14013 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14014 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14015 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14016 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14017 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14018 14019 for (i = 0; i < 500; i++) { 14020 if (!(BWN_PHY_READ(mac, 14021 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14022 break; 14023 DELAY(1000); 14024 } 14025 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14026 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14027 return 0; 14028 } 14029 14030 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14031 ie->ie_iqprod <<= 16; 14032 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14033 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14034 ie->ie_ipwr <<= 16; 14035 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14036 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14037 ie->ie_qpwr <<= 16; 14038 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14039 14040 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14041 return 1; 14042 } 14043 14044 static uint32_t 14045 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14046 { 14047 uint32_t offset, type, value; 14048 14049 type = BWN_TAB_GETTYPE(typeoffset); 14050 offset = BWN_TAB_GETOFFSET(typeoffset); 14051 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14052 14053 switch (type) { 14054 case BWN_TAB_8BIT: 14055 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14056 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14057 break; 14058 case BWN_TAB_16BIT: 14059 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14060 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14061 break; 14062 case BWN_TAB_32BIT: 14063 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14064 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14065 value <<= 16; 14066 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14067 break; 14068 default: 14069 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14070 value = 0; 14071 } 14072 14073 return (value); 14074 } 14075 14076 static void 14077 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14078 { 14079 14080 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14081 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14082 } 14083 14084 static void 14085 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14086 { 14087 uint16_t ctl; 14088 14089 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14090 ctl |= dac << 7; 14091 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14092 } 14093 14094 static void 14095 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14096 { 14097 14098 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14099 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14100 } 14101 14102 static void 14103 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14104 { 14105 14106 if (mac->mac_phy.rev < 2) 14107 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14108 else { 14109 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14110 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14111 } 14112 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14113 } 14114 14115 static uint16_t 14116 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14117 { 14118 14119 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14120 } 14121 14122 static uint8_t 14123 bwn_nbits(int32_t val) 14124 { 14125 uint32_t tmp; 14126 uint8_t nbits = 0; 14127 14128 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14129 nbits++; 14130 return (nbits); 14131 } 14132 14133 static void 14134 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14135 struct bwn_txgain_entry *table) 14136 { 14137 int i; 14138 14139 for (i = offset; i < count; i++) 14140 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14141 } 14142 14143 static void 14144 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14145 struct bwn_txgain_entry data) 14146 { 14147 14148 if (mac->mac_phy.rev >= 2) 14149 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14150 else 14151 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14152 } 14153 14154 static void 14155 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14156 struct bwn_txgain_entry te) 14157 { 14158 struct bwn_softc *sc = mac->mac_sc; 14159 struct ifnet *ifp = sc->sc_ifp; 14160 struct ieee80211com *ic = ifp->if_l2com; 14161 uint32_t tmp; 14162 14163 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14164 14165 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14166 if (mac->mac_phy.rev >= 3) { 14167 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14168 (0x10 << 24) : (0x70 << 24)); 14169 } else { 14170 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14171 (0x14 << 24) : (0x7f << 24)); 14172 } 14173 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14174 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14175 te.te_bbmult << 20 | te.te_dac << 28); 14176 } 14177 14178 static void 14179 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14180 struct bwn_txgain_entry te) 14181 { 14182 14183 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14184 14185 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14186 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14187 te.te_dac); 14188 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14189 } 14190 14191 static void 14192 bwn_sysctl_node(struct bwn_softc *sc) 14193 { 14194 device_t dev = sc->sc_dev; 14195 struct bwn_mac *mac; 14196 struct bwn_stats *stats; 14197 14198 /* XXX assume that count of MAC is only 1. */ 14199 14200 if ((mac = sc->sc_curmac) == NULL) 14201 return; 14202 stats = &mac->mac_stats; 14203 14204 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14205 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14206 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14207 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14208 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14209 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14210 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14211 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14212 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14213 14214 #ifdef BWN_DEBUG 14215 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14216 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14217 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14218 #endif 14219 } 14220 14221 static device_method_t bwn_methods[] = { 14222 /* Device interface */ 14223 DEVMETHOD(device_probe, bwn_probe), 14224 DEVMETHOD(device_attach, bwn_attach), 14225 DEVMETHOD(device_detach, bwn_detach), 14226 DEVMETHOD(device_suspend, bwn_suspend), 14227 DEVMETHOD(device_resume, bwn_resume), 14228 KOBJMETHOD_END 14229 }; 14230 static driver_t bwn_driver = { 14231 "bwn", 14232 bwn_methods, 14233 sizeof(struct bwn_softc) 14234 }; 14235 static devclass_t bwn_devclass; 14236 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14237 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14238 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14239 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14240 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14241