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_extcap(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 | IEEE80211_C_RATECTL /* use ratectl */ 1074 ; 1075 1076 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1077 1078 /* call MI attach routine. */ 1079 ieee80211_ifattach(ic, 1080 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1081 siba_sprom_get_mac_80211a(sc->sc_dev) : 1082 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1083 1084 ic->ic_headroom = sizeof(struct bwn_txhdr); 1085 1086 /* override default methods */ 1087 ic->ic_raw_xmit = bwn_raw_xmit; 1088 ic->ic_updateslot = bwn_updateslot; 1089 ic->ic_update_promisc = bwn_update_promisc; 1090 ic->ic_wme.wme_update = bwn_wme_update; 1091 1092 ic->ic_scan_start = bwn_scan_start; 1093 ic->ic_scan_end = bwn_scan_end; 1094 ic->ic_set_channel = bwn_set_channel; 1095 1096 ic->ic_vap_create = bwn_vap_create; 1097 ic->ic_vap_delete = bwn_vap_delete; 1098 1099 ieee80211_radiotap_attach(ic, 1100 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1101 BWN_TX_RADIOTAP_PRESENT, 1102 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1103 BWN_RX_RADIOTAP_PRESENT); 1104 1105 bwn_sysctl_node(sc); 1106 1107 if (bootverbose) 1108 ieee80211_announce(ic); 1109 return (0); 1110 } 1111 1112 static void 1113 bwn_phy_detach(struct bwn_mac *mac) 1114 { 1115 1116 if (mac->mac_phy.detach != NULL) 1117 mac->mac_phy.detach(mac); 1118 } 1119 1120 static int 1121 bwn_detach(device_t dev) 1122 { 1123 struct bwn_softc *sc = device_get_softc(dev); 1124 struct bwn_mac *mac = sc->sc_curmac; 1125 struct ifnet *ifp = sc->sc_ifp; 1126 struct ieee80211com *ic = ifp->if_l2com; 1127 int i; 1128 1129 sc->sc_flags |= BWN_FLAG_INVALID; 1130 1131 if (device_is_attached(sc->sc_dev)) { 1132 bwn_stop(sc, 1); 1133 bwn_dma_free(mac); 1134 callout_drain(&sc->sc_led_blink_ch); 1135 callout_drain(&sc->sc_rfswitch_ch); 1136 callout_drain(&sc->sc_task_ch); 1137 callout_drain(&sc->sc_watchdog_ch); 1138 bwn_phy_detach(mac); 1139 if (ifp != NULL) { 1140 ieee80211_draintask(ic, &mac->mac_hwreset); 1141 ieee80211_draintask(ic, &mac->mac_txpower); 1142 ieee80211_ifdetach(ic); 1143 if_free(ifp); 1144 } 1145 } 1146 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1147 taskqueue_free(sc->sc_tq); 1148 1149 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1150 if (mac->mac_intrhand[i] != NULL) { 1151 bus_teardown_intr(dev, mac->mac_res_irq[i], 1152 mac->mac_intrhand[i]); 1153 mac->mac_intrhand[i] = NULL; 1154 } 1155 } 1156 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1157 if (mac->mac_msi != 0) 1158 pci_release_msi(dev); 1159 1160 BWN_LOCK_DESTROY(sc); 1161 return (0); 1162 } 1163 1164 static int 1165 bwn_attach_pre(struct bwn_softc *sc) 1166 { 1167 struct ifnet *ifp; 1168 int error = 0; 1169 1170 BWN_LOCK_INIT(sc); 1171 TAILQ_INIT(&sc->sc_maclist); 1172 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1173 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1174 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1175 1176 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1177 taskqueue_thread_enqueue, &sc->sc_tq); 1178 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1179 "%s taskq", device_get_nameunit(sc->sc_dev)); 1180 1181 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1182 if (ifp == NULL) { 1183 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1184 error = ENOSPC; 1185 goto fail; 1186 } 1187 1188 /* set these up early for if_printf use */ 1189 if_initname(ifp, device_get_name(sc->sc_dev), 1190 device_get_unit(sc->sc_dev)); 1191 1192 ifp->if_softc = sc; 1193 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1194 ifp->if_init = bwn_init; 1195 ifp->if_ioctl = bwn_ioctl; 1196 ifp->if_start = bwn_start; 1197 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 1198 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 1199 IFQ_SET_READY(&ifp->if_snd); 1200 1201 return (0); 1202 1203 fail: BWN_LOCK_DESTROY(sc); 1204 return (error); 1205 } 1206 1207 static void 1208 bwn_sprom_bugfixes(device_t dev) 1209 { 1210 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1211 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1212 (siba_get_pci_device(dev) == _device) && \ 1213 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1214 (siba_get_pci_subdevice(dev) == _subdevice)) 1215 1216 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1217 siba_get_pci_subdevice(dev) == 0x4e && 1218 siba_get_pci_revid(dev) > 0x40) 1219 siba_sprom_set_bf_lo(dev, 1220 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1221 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1222 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1223 siba_sprom_set_bf_lo(dev, 1224 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1225 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1226 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1227 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1228 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1229 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1230 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1231 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1232 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1233 siba_sprom_set_bf_lo(dev, 1234 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1235 } 1236 #undef BWN_ISDEV 1237 } 1238 1239 static int 1240 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1241 { 1242 #define IS_RUNNING(ifp) \ 1243 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1244 struct bwn_softc *sc = ifp->if_softc; 1245 struct ieee80211com *ic = ifp->if_l2com; 1246 struct ifreq *ifr = (struct ifreq *)data; 1247 int error = 0, startall; 1248 1249 switch (cmd) { 1250 case SIOCSIFFLAGS: 1251 startall = 0; 1252 if (IS_RUNNING(ifp)) { 1253 bwn_update_promisc(ifp); 1254 } else if (ifp->if_flags & IFF_UP) { 1255 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1256 bwn_init(sc); 1257 startall = 1; 1258 } 1259 } else 1260 bwn_stop(sc, 1); 1261 if (startall) 1262 ieee80211_start_all(ic); 1263 break; 1264 case SIOCGIFMEDIA: 1265 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1266 break; 1267 case SIOCGIFADDR: 1268 error = ether_ioctl(ifp, cmd, data); 1269 break; 1270 default: 1271 error = EINVAL; 1272 break; 1273 } 1274 return (error); 1275 } 1276 1277 static void 1278 bwn_start(struct ifnet *ifp) 1279 { 1280 struct bwn_softc *sc = ifp->if_softc; 1281 1282 BWN_LOCK(sc); 1283 bwn_start_locked(ifp); 1284 BWN_UNLOCK(sc); 1285 } 1286 1287 static void 1288 bwn_start_locked(struct ifnet *ifp) 1289 { 1290 struct bwn_softc *sc = ifp->if_softc; 1291 struct bwn_mac *mac = sc->sc_curmac; 1292 struct ieee80211_frame *wh; 1293 struct ieee80211_node *ni; 1294 struct ieee80211_key *k; 1295 struct mbuf *m; 1296 1297 BWN_ASSERT_LOCKED(sc); 1298 1299 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1300 mac->mac_status < BWN_MAC_STATUS_STARTED) 1301 return; 1302 1303 for (;;) { 1304 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1305 if (m == NULL) 1306 break; 1307 1308 if (bwn_tx_isfull(sc, m)) 1309 break; 1310 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1311 if (ni == NULL) { 1312 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1313 m_freem(m); 1314 ifp->if_oerrors++; 1315 continue; 1316 } 1317 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1318 wh = mtod(m, struct ieee80211_frame *); 1319 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1320 k = ieee80211_crypto_encap(ni, m); 1321 if (k == NULL) { 1322 ieee80211_free_node(ni); 1323 m_freem(m); 1324 ifp->if_oerrors++; 1325 continue; 1326 } 1327 } 1328 wh = NULL; /* Catch any invalid use */ 1329 1330 if (bwn_tx_start(sc, ni, m) != 0) { 1331 if (ni != NULL) 1332 ieee80211_free_node(ni); 1333 ifp->if_oerrors++; 1334 continue; 1335 } 1336 1337 sc->sc_watchdog_timer = 5; 1338 } 1339 } 1340 1341 static int 1342 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1343 { 1344 struct bwn_dma_ring *dr; 1345 struct bwn_mac *mac = sc->sc_curmac; 1346 struct bwn_pio_txqueue *tq; 1347 struct ifnet *ifp = sc->sc_ifp; 1348 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1349 1350 BWN_ASSERT_LOCKED(sc); 1351 1352 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1353 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1354 if (dr->dr_stop == 1 || 1355 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1356 dr->dr_stop = 1; 1357 goto full; 1358 } 1359 } else { 1360 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1361 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1362 pktlen > (tq->tq_size - tq->tq_used)) { 1363 tq->tq_stop = 1; 1364 goto full; 1365 } 1366 } 1367 return (0); 1368 full: 1369 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1370 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1371 return (1); 1372 } 1373 1374 static int 1375 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1376 { 1377 struct bwn_mac *mac = sc->sc_curmac; 1378 int error; 1379 1380 BWN_ASSERT_LOCKED(sc); 1381 1382 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1383 m_freem(m); 1384 return (ENXIO); 1385 } 1386 1387 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1388 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1389 if (error) { 1390 m_freem(m); 1391 return (error); 1392 } 1393 return (0); 1394 } 1395 1396 static int 1397 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1398 { 1399 struct bwn_pio_txpkt *tp; 1400 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1401 struct bwn_softc *sc = mac->mac_sc; 1402 struct bwn_txhdr txhdr; 1403 struct mbuf *m_new; 1404 uint32_t ctl32; 1405 int error; 1406 uint16_t ctl16; 1407 1408 BWN_ASSERT_LOCKED(sc); 1409 1410 /* XXX TODO send packets after DTIM */ 1411 1412 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1413 tp = TAILQ_FIRST(&tq->tq_pktlist); 1414 tp->tp_ni = ni; 1415 tp->tp_m = m; 1416 1417 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1418 if (error) { 1419 device_printf(sc->sc_dev, "tx fail\n"); 1420 return (error); 1421 } 1422 1423 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1424 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1425 tq->tq_free--; 1426 1427 if (siba_get_revid(sc->sc_dev) >= 8) { 1428 /* 1429 * XXX please removes m_defrag(9) 1430 */ 1431 m_new = m_defrag(m, M_DONTWAIT); 1432 if (m_new == NULL) { 1433 device_printf(sc->sc_dev, 1434 "%s: can't defrag TX buffer\n", 1435 __func__); 1436 return (ENOBUFS); 1437 } 1438 if (m_new->m_next != NULL) 1439 device_printf(sc->sc_dev, 1440 "TODO: fragmented packets for PIO\n"); 1441 tp->tp_m = m_new; 1442 1443 /* send HEADER */ 1444 ctl32 = bwn_pio_write_multi_4(mac, tq, 1445 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1446 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1447 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1448 /* send BODY */ 1449 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1450 mtod(m_new, const void *), m_new->m_pkthdr.len); 1451 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1452 ctl32 | BWN_PIO8_TXCTL_EOF); 1453 } else { 1454 ctl16 = bwn_pio_write_multi_2(mac, tq, 1455 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1456 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1457 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1458 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1459 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1460 ctl16 | BWN_PIO_TXCTL_EOF); 1461 } 1462 1463 return (0); 1464 } 1465 1466 static struct bwn_pio_txqueue * 1467 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1468 { 1469 1470 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1471 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1472 1473 switch (prio) { 1474 case 0: 1475 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1476 case 1: 1477 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1478 case 2: 1479 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1480 case 3: 1481 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1482 } 1483 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1484 return (NULL); 1485 } 1486 1487 static int 1488 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1489 { 1490 #define BWN_GET_TXHDRCACHE(slot) \ 1491 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1492 struct bwn_dma *dma = &mac->mac_method.dma; 1493 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1494 struct bwn_dmadesc_generic *desc; 1495 struct bwn_dmadesc_meta *mt; 1496 struct bwn_softc *sc = mac->mac_sc; 1497 struct ifnet *ifp = sc->sc_ifp; 1498 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1499 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1500 1501 BWN_ASSERT_LOCKED(sc); 1502 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1503 1504 /* XXX send after DTIM */ 1505 1506 slot = bwn_dma_getslot(dr); 1507 dr->getdesc(dr, slot, &desc, &mt); 1508 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1509 ("%s:%d: fail", __func__, __LINE__)); 1510 1511 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1512 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1513 BWN_DMA_COOKIE(dr, slot)); 1514 if (error) 1515 goto fail; 1516 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1517 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1518 &mt->mt_paddr, BUS_DMA_NOWAIT); 1519 if (error) { 1520 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1521 __func__, error); 1522 goto fail; 1523 } 1524 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1525 BUS_DMASYNC_PREWRITE); 1526 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1527 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1528 BUS_DMASYNC_PREWRITE); 1529 1530 slot = bwn_dma_getslot(dr); 1531 dr->getdesc(dr, slot, &desc, &mt); 1532 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1533 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1534 mt->mt_m = m; 1535 mt->mt_ni = ni; 1536 1537 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1538 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1539 if (error && error != EFBIG) { 1540 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1541 __func__, error); 1542 goto fail; 1543 } 1544 if (error) { /* error == EFBIG */ 1545 struct mbuf *m_new; 1546 1547 m_new = m_defrag(m, M_DONTWAIT); 1548 if (m_new == NULL) { 1549 if_printf(ifp, "%s: can't defrag TX buffer\n", 1550 __func__); 1551 error = ENOBUFS; 1552 goto fail; 1553 } else { 1554 m = m_new; 1555 } 1556 1557 mt->mt_m = m; 1558 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1559 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1560 if (error) { 1561 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1562 __func__, error); 1563 goto fail; 1564 } 1565 } 1566 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1567 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1568 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1569 BUS_DMASYNC_PREWRITE); 1570 1571 /* XXX send after DTIM */ 1572 1573 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1574 return (0); 1575 fail: 1576 dr->dr_curslot = backup[0]; 1577 dr->dr_usedslot = backup[1]; 1578 return (error); 1579 #undef BWN_GET_TXHDRCACHE 1580 } 1581 1582 static void 1583 bwn_watchdog(void *arg) 1584 { 1585 struct bwn_softc *sc = arg; 1586 struct ifnet *ifp = sc->sc_ifp; 1587 1588 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1589 if_printf(ifp, "device timeout\n"); 1590 ifp->if_oerrors++; 1591 } 1592 callout_schedule(&sc->sc_watchdog_ch, hz); 1593 } 1594 1595 static int 1596 bwn_attach_core(struct bwn_mac *mac) 1597 { 1598 struct bwn_softc *sc = mac->mac_sc; 1599 int error, have_bg = 0, have_a = 0; 1600 uint32_t high; 1601 1602 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1603 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1604 1605 siba_powerup(sc->sc_dev, 0); 1606 1607 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1608 bwn_reset_core(mac, 1609 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1610 error = bwn_phy_getinfo(mac, high); 1611 if (error) 1612 goto fail; 1613 1614 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1615 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1616 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1617 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1618 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1619 have_a = have_bg = 0; 1620 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1621 have_a = 1; 1622 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1623 mac->mac_phy.type == BWN_PHYTYPE_N || 1624 mac->mac_phy.type == BWN_PHYTYPE_LP) 1625 have_bg = 1; 1626 else 1627 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1628 mac->mac_phy.type)); 1629 } 1630 /* XXX turns off PHY A because it's not supported */ 1631 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1632 mac->mac_phy.type != BWN_PHYTYPE_N) { 1633 have_a = 0; 1634 have_bg = 1; 1635 } 1636 1637 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1638 mac->mac_phy.attach = bwn_phy_g_attach; 1639 mac->mac_phy.detach = bwn_phy_g_detach; 1640 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1641 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1642 mac->mac_phy.init = bwn_phy_g_init; 1643 mac->mac_phy.exit = bwn_phy_g_exit; 1644 mac->mac_phy.phy_read = bwn_phy_g_read; 1645 mac->mac_phy.phy_write = bwn_phy_g_write; 1646 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1647 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1648 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1649 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1650 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1651 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1652 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1653 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1654 mac->mac_phy.set_im = bwn_phy_g_im; 1655 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1656 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1657 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1658 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1659 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1660 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1661 mac->mac_phy.init = bwn_phy_lp_init; 1662 mac->mac_phy.phy_read = bwn_phy_lp_read; 1663 mac->mac_phy.phy_write = bwn_phy_lp_write; 1664 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1665 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1666 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1667 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1668 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1669 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1670 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1671 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1672 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1673 } else { 1674 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1675 mac->mac_phy.type); 1676 error = ENXIO; 1677 goto fail; 1678 } 1679 1680 mac->mac_phy.gmode = have_bg; 1681 if (mac->mac_phy.attach != NULL) { 1682 error = mac->mac_phy.attach(mac); 1683 if (error) { 1684 device_printf(sc->sc_dev, "failed\n"); 1685 goto fail; 1686 } 1687 } 1688 1689 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1690 1691 error = bwn_chiptest(mac); 1692 if (error) 1693 goto fail; 1694 error = bwn_setup_channels(mac, have_bg, have_a); 1695 if (error) { 1696 device_printf(sc->sc_dev, "failed to setup channels\n"); 1697 goto fail; 1698 } 1699 1700 if (sc->sc_curmac == NULL) 1701 sc->sc_curmac = mac; 1702 1703 error = bwn_dma_attach(mac); 1704 if (error != 0) { 1705 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1706 goto fail; 1707 } 1708 1709 mac->mac_phy.switch_analog(mac, 0); 1710 1711 siba_dev_down(sc->sc_dev, 0); 1712 fail: 1713 siba_powerdown(sc->sc_dev); 1714 return (error); 1715 } 1716 1717 static void 1718 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1719 { 1720 struct bwn_softc *sc = mac->mac_sc; 1721 uint32_t low, ctl; 1722 1723 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1724 1725 siba_dev_up(sc->sc_dev, flags); 1726 DELAY(2000); 1727 1728 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1729 ~BWN_TGSLOW_PHYRESET; 1730 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1731 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1732 DELAY(1000); 1733 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1734 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1735 DELAY(1000); 1736 1737 if (mac->mac_phy.switch_analog != NULL) 1738 mac->mac_phy.switch_analog(mac, 1); 1739 1740 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1741 if (flags & BWN_TGSLOW_SUPPORT_G) 1742 ctl |= BWN_MACCTL_GMODE; 1743 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1744 } 1745 1746 static int 1747 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1748 { 1749 struct bwn_phy *phy = &mac->mac_phy; 1750 struct bwn_softc *sc = mac->mac_sc; 1751 uint32_t tmp; 1752 1753 /* PHY */ 1754 tmp = BWN_READ_2(mac, BWN_PHYVER); 1755 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1756 phy->rf_on = 1; 1757 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1758 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1759 phy->rev = (tmp & BWN_PHYVER_VERSION); 1760 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1761 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1762 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1763 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1764 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1765 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1766 goto unsupphy; 1767 1768 /* RADIO */ 1769 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1770 if (siba_get_chiprev(sc->sc_dev) == 0) 1771 tmp = 0x3205017f; 1772 else if (siba_get_chiprev(sc->sc_dev) == 1) 1773 tmp = 0x4205017f; 1774 else 1775 tmp = 0x5205017f; 1776 } else { 1777 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1778 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1779 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1780 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1781 } 1782 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1783 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1784 phy->rf_manuf = (tmp & 0x00000fff); 1785 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1786 goto unsupradio; 1787 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1788 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1789 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1790 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1791 (phy->type == BWN_PHYTYPE_N && 1792 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1793 (phy->type == BWN_PHYTYPE_LP && 1794 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1795 goto unsupradio; 1796 1797 return (0); 1798 unsupphy: 1799 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1800 "analog %#x)\n", 1801 phy->type, phy->rev, phy->analog); 1802 return (ENXIO); 1803 unsupradio: 1804 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1805 "rev %#x)\n", 1806 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1807 return (ENXIO); 1808 } 1809 1810 static int 1811 bwn_chiptest(struct bwn_mac *mac) 1812 { 1813 #define TESTVAL0 0x55aaaa55 1814 #define TESTVAL1 0xaa5555aa 1815 struct bwn_softc *sc = mac->mac_sc; 1816 uint32_t v, backup; 1817 1818 BWN_LOCK(sc); 1819 1820 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1821 1822 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1823 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1824 goto error; 1825 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1826 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1827 goto error; 1828 1829 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1830 1831 if ((siba_get_revid(sc->sc_dev) >= 3) && 1832 (siba_get_revid(sc->sc_dev) <= 10)) { 1833 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1834 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1835 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1836 goto error; 1837 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1838 goto error; 1839 } 1840 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1841 1842 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1843 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1844 goto error; 1845 1846 BWN_UNLOCK(sc); 1847 return (0); 1848 error: 1849 BWN_UNLOCK(sc); 1850 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1851 return (ENODEV); 1852 } 1853 1854 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1855 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1856 1857 static int 1858 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1859 { 1860 struct bwn_softc *sc = mac->mac_sc; 1861 struct ifnet *ifp = sc->sc_ifp; 1862 struct ieee80211com *ic = ifp->if_l2com; 1863 1864 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1865 ic->ic_nchans = 0; 1866 1867 if (have_bg) 1868 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1869 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1870 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1871 if (have_a) 1872 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1873 &ic->ic_nchans, &bwn_chantable_n, 1874 IEEE80211_CHAN_HTA); 1875 } else { 1876 if (have_a) 1877 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1878 &ic->ic_nchans, &bwn_chantable_a, 1879 IEEE80211_CHAN_A); 1880 } 1881 1882 mac->mac_phy.supports_2ghz = have_bg; 1883 mac->mac_phy.supports_5ghz = have_a; 1884 1885 return (ic->ic_nchans == 0 ? ENXIO : 0); 1886 } 1887 1888 static uint32_t 1889 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1890 { 1891 uint32_t ret; 1892 1893 BWN_ASSERT_LOCKED(mac->mac_sc); 1894 1895 if (way == BWN_SHARED) { 1896 KASSERT((offset & 0x0001) == 0, 1897 ("%s:%d warn", __func__, __LINE__)); 1898 if (offset & 0x0003) { 1899 bwn_shm_ctlword(mac, way, offset >> 2); 1900 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1901 ret <<= 16; 1902 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1903 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1904 goto out; 1905 } 1906 offset >>= 2; 1907 } 1908 bwn_shm_ctlword(mac, way, offset); 1909 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1910 out: 1911 return (ret); 1912 } 1913 1914 static uint16_t 1915 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1916 { 1917 uint16_t ret; 1918 1919 BWN_ASSERT_LOCKED(mac->mac_sc); 1920 1921 if (way == BWN_SHARED) { 1922 KASSERT((offset & 0x0001) == 0, 1923 ("%s:%d warn", __func__, __LINE__)); 1924 if (offset & 0x0003) { 1925 bwn_shm_ctlword(mac, way, offset >> 2); 1926 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1927 goto out; 1928 } 1929 offset >>= 2; 1930 } 1931 bwn_shm_ctlword(mac, way, offset); 1932 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1933 out: 1934 1935 return (ret); 1936 } 1937 1938 static void 1939 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1940 uint16_t offset) 1941 { 1942 uint32_t control; 1943 1944 control = way; 1945 control <<= 16; 1946 control |= offset; 1947 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1948 } 1949 1950 static void 1951 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1952 uint32_t value) 1953 { 1954 BWN_ASSERT_LOCKED(mac->mac_sc); 1955 1956 if (way == BWN_SHARED) { 1957 KASSERT((offset & 0x0001) == 0, 1958 ("%s:%d warn", __func__, __LINE__)); 1959 if (offset & 0x0003) { 1960 bwn_shm_ctlword(mac, way, offset >> 2); 1961 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1962 (value >> 16) & 0xffff); 1963 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1964 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1965 return; 1966 } 1967 offset >>= 2; 1968 } 1969 bwn_shm_ctlword(mac, way, offset); 1970 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1971 } 1972 1973 static void 1974 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1975 uint16_t value) 1976 { 1977 BWN_ASSERT_LOCKED(mac->mac_sc); 1978 1979 if (way == BWN_SHARED) { 1980 KASSERT((offset & 0x0001) == 0, 1981 ("%s:%d warn", __func__, __LINE__)); 1982 if (offset & 0x0003) { 1983 bwn_shm_ctlword(mac, way, offset >> 2); 1984 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1985 return; 1986 } 1987 offset >>= 2; 1988 } 1989 bwn_shm_ctlword(mac, way, offset); 1990 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1991 } 1992 1993 static void 1994 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1995 int txpow) 1996 { 1997 1998 c->ic_freq = freq; 1999 c->ic_flags = flags; 2000 c->ic_ieee = ieee; 2001 c->ic_minpower = 0; 2002 c->ic_maxpower = 2 * txpow; 2003 c->ic_maxregpower = txpow; 2004 } 2005 2006 static void 2007 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2008 const struct bwn_channelinfo *ci, int flags) 2009 { 2010 struct ieee80211_channel *c; 2011 int i; 2012 2013 c = &chans[*nchans]; 2014 2015 for (i = 0; i < ci->nchannels; i++) { 2016 const struct bwn_channel *hc; 2017 2018 hc = &ci->channels[i]; 2019 if (*nchans >= maxchans) 2020 break; 2021 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2022 c++, (*nchans)++; 2023 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2024 /* g channel have a separate b-only entry */ 2025 if (*nchans >= maxchans) 2026 break; 2027 c[0] = c[-1]; 2028 c[-1].ic_flags = IEEE80211_CHAN_B; 2029 c++, (*nchans)++; 2030 } 2031 if (flags == IEEE80211_CHAN_HTG) { 2032 /* HT g channel have a separate g-only entry */ 2033 if (*nchans >= maxchans) 2034 break; 2035 c[-1].ic_flags = IEEE80211_CHAN_G; 2036 c[0] = c[-1]; 2037 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2038 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2039 c++, (*nchans)++; 2040 } 2041 if (flags == IEEE80211_CHAN_HTA) { 2042 /* HT a channel have a separate a-only entry */ 2043 if (*nchans >= maxchans) 2044 break; 2045 c[-1].ic_flags = IEEE80211_CHAN_A; 2046 c[0] = c[-1]; 2047 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2048 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2049 c++, (*nchans)++; 2050 } 2051 } 2052 } 2053 2054 static int 2055 bwn_phy_g_attach(struct bwn_mac *mac) 2056 { 2057 struct bwn_softc *sc = mac->mac_sc; 2058 struct bwn_phy *phy = &mac->mac_phy; 2059 struct bwn_phy_g *pg = &phy->phy_g; 2060 unsigned int i; 2061 int16_t pab0, pab1, pab2; 2062 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2063 int8_t bg; 2064 2065 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2066 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2067 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2068 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2069 2070 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2071 device_printf(sc->sc_dev, "not supported anymore\n"); 2072 2073 pg->pg_flags = 0; 2074 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2075 pab2 == -1) { 2076 pg->pg_idletssi = 52; 2077 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2078 return (0); 2079 } 2080 2081 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2082 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2083 if (pg->pg_tssi2dbm == NULL) { 2084 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2085 return (ENOMEM); 2086 } 2087 for (i = 0; i < 64; i++) { 2088 int32_t m1, m2, f, q, delta; 2089 int8_t j = 0; 2090 2091 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2092 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2093 f = 256; 2094 2095 do { 2096 if (j > 15) { 2097 device_printf(sc->sc_dev, 2098 "failed to generate tssi2dBm\n"); 2099 free(pg->pg_tssi2dbm, M_DEVBUF); 2100 return (ENOMEM); 2101 } 2102 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2103 f, 2048); 2104 delta = abs(q - f); 2105 f = q; 2106 j++; 2107 } while (delta >= 2); 2108 2109 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2110 128); 2111 } 2112 2113 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2114 return (0); 2115 } 2116 2117 static void 2118 bwn_phy_g_detach(struct bwn_mac *mac) 2119 { 2120 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2121 2122 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2123 free(pg->pg_tssi2dbm, M_DEVBUF); 2124 pg->pg_tssi2dbm = NULL; 2125 } 2126 pg->pg_flags = 0; 2127 } 2128 2129 static void 2130 bwn_phy_g_init_pre(struct bwn_mac *mac) 2131 { 2132 struct bwn_phy *phy = &mac->mac_phy; 2133 struct bwn_phy_g *pg = &phy->phy_g; 2134 void *tssi2dbm; 2135 int idletssi; 2136 unsigned int i; 2137 2138 tssi2dbm = pg->pg_tssi2dbm; 2139 idletssi = pg->pg_idletssi; 2140 2141 memset(pg, 0, sizeof(*pg)); 2142 2143 pg->pg_tssi2dbm = tssi2dbm; 2144 pg->pg_idletssi = idletssi; 2145 2146 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2147 2148 for (i = 0; i < N(pg->pg_nrssi); i++) 2149 pg->pg_nrssi[i] = -1000; 2150 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2151 pg->pg_nrssi_lt[i] = i; 2152 pg->pg_lofcal = 0xffff; 2153 pg->pg_initval = 0xffff; 2154 pg->pg_immode = BWN_IMMODE_NONE; 2155 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2156 pg->pg_avgtssi = 0xff; 2157 2158 pg->pg_loctl.tx_bias = 0xff; 2159 TAILQ_INIT(&pg->pg_loctl.calib_list); 2160 } 2161 2162 static int 2163 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2164 { 2165 struct bwn_phy *phy = &mac->mac_phy; 2166 struct bwn_phy_g *pg = &phy->phy_g; 2167 struct bwn_softc *sc = mac->mac_sc; 2168 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2169 static const struct bwn_rfatt rfatt0[] = { 2170 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2171 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2172 { 3, 1 }, { 4, 1 } 2173 }; 2174 static const struct bwn_rfatt rfatt1[] = { 2175 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2176 { 14, 1 } 2177 }; 2178 static const struct bwn_rfatt rfatt2[] = { 2179 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2180 { 9, 1 } 2181 }; 2182 static const struct bwn_bbatt bbatt_0[] = { 2183 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2184 }; 2185 2186 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2187 2188 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2189 pg->pg_bbatt.att = 0; 2190 else 2191 pg->pg_bbatt.att = 2; 2192 2193 /* prepare Radio Attenuation */ 2194 pg->pg_rfatt.padmix = 0; 2195 2196 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2197 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2198 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2199 pg->pg_rfatt.att = 2; 2200 goto done; 2201 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2202 pg->pg_rfatt.att = 3; 2203 goto done; 2204 } 2205 } 2206 2207 if (phy->type == BWN_PHYTYPE_A) { 2208 pg->pg_rfatt.att = 0x60; 2209 goto done; 2210 } 2211 2212 switch (phy->rf_ver) { 2213 case 0x2050: 2214 switch (phy->rf_rev) { 2215 case 0: 2216 pg->pg_rfatt.att = 5; 2217 goto done; 2218 case 1: 2219 if (phy->type == BWN_PHYTYPE_G) { 2220 if (siba_get_pci_subvendor(sc->sc_dev) == 2221 SIBA_BOARDVENDOR_BCM && 2222 siba_get_pci_subdevice(sc->sc_dev) == 2223 SIBA_BOARD_BCM4309G && 2224 siba_get_pci_revid(sc->sc_dev) >= 30) 2225 pg->pg_rfatt.att = 3; 2226 else if (siba_get_pci_subvendor(sc->sc_dev) == 2227 SIBA_BOARDVENDOR_BCM && 2228 siba_get_pci_subdevice(sc->sc_dev) == 2229 SIBA_BOARD_BU4306) 2230 pg->pg_rfatt.att = 3; 2231 else 2232 pg->pg_rfatt.att = 1; 2233 } else { 2234 if (siba_get_pci_subvendor(sc->sc_dev) == 2235 SIBA_BOARDVENDOR_BCM && 2236 siba_get_pci_subdevice(sc->sc_dev) == 2237 SIBA_BOARD_BCM4309G && 2238 siba_get_pci_revid(sc->sc_dev) >= 30) 2239 pg->pg_rfatt.att = 7; 2240 else 2241 pg->pg_rfatt.att = 6; 2242 } 2243 goto done; 2244 case 2: 2245 if (phy->type == BWN_PHYTYPE_G) { 2246 if (siba_get_pci_subvendor(sc->sc_dev) == 2247 SIBA_BOARDVENDOR_BCM && 2248 siba_get_pci_subdevice(sc->sc_dev) == 2249 SIBA_BOARD_BCM4309G && 2250 siba_get_pci_revid(sc->sc_dev) >= 30) 2251 pg->pg_rfatt.att = 3; 2252 else if (siba_get_pci_subvendor(sc->sc_dev) == 2253 SIBA_BOARDVENDOR_BCM && 2254 siba_get_pci_subdevice(sc->sc_dev) == 2255 SIBA_BOARD_BU4306) 2256 pg->pg_rfatt.att = 5; 2257 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2258 pg->pg_rfatt.att = 4; 2259 else 2260 pg->pg_rfatt.att = 3; 2261 } else 2262 pg->pg_rfatt.att = 6; 2263 goto done; 2264 case 3: 2265 pg->pg_rfatt.att = 5; 2266 goto done; 2267 case 4: 2268 case 5: 2269 pg->pg_rfatt.att = 1; 2270 goto done; 2271 case 6: 2272 case 7: 2273 pg->pg_rfatt.att = 5; 2274 goto done; 2275 case 8: 2276 pg->pg_rfatt.att = 0xa; 2277 pg->pg_rfatt.padmix = 1; 2278 goto done; 2279 case 9: 2280 default: 2281 pg->pg_rfatt.att = 5; 2282 goto done; 2283 } 2284 break; 2285 case 0x2053: 2286 switch (phy->rf_rev) { 2287 case 1: 2288 pg->pg_rfatt.att = 6; 2289 goto done; 2290 } 2291 break; 2292 } 2293 pg->pg_rfatt.att = 5; 2294 done: 2295 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2296 2297 if (!bwn_has_hwpctl(mac)) { 2298 lo->rfatt.array = rfatt0; 2299 lo->rfatt.len = N(rfatt0); 2300 lo->rfatt.min = 0; 2301 lo->rfatt.max = 9; 2302 goto genbbatt; 2303 } 2304 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2305 lo->rfatt.array = rfatt1; 2306 lo->rfatt.len = N(rfatt1); 2307 lo->rfatt.min = 0; 2308 lo->rfatt.max = 14; 2309 goto genbbatt; 2310 } 2311 lo->rfatt.array = rfatt2; 2312 lo->rfatt.len = N(rfatt2); 2313 lo->rfatt.min = 0; 2314 lo->rfatt.max = 9; 2315 genbbatt: 2316 lo->bbatt.array = bbatt_0; 2317 lo->bbatt.len = N(bbatt_0); 2318 lo->bbatt.min = 0; 2319 lo->bbatt.max = 8; 2320 2321 BWN_READ_4(mac, BWN_MACCTL); 2322 if (phy->rev == 1) { 2323 phy->gmode = 0; 2324 bwn_reset_core(mac, 0); 2325 bwn_phy_g_init_sub(mac); 2326 phy->gmode = 1; 2327 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2328 } 2329 return (0); 2330 } 2331 2332 static uint16_t 2333 bwn_phy_g_txctl(struct bwn_mac *mac) 2334 { 2335 struct bwn_phy *phy = &mac->mac_phy; 2336 2337 if (phy->rf_ver != 0x2050) 2338 return (0); 2339 if (phy->rf_rev == 1) 2340 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2341 if (phy->rf_rev < 6) 2342 return (BWN_TXCTL_PA2DB); 2343 if (phy->rf_rev == 8) 2344 return (BWN_TXCTL_TXMIX); 2345 return (0); 2346 } 2347 2348 static int 2349 bwn_phy_g_init(struct bwn_mac *mac) 2350 { 2351 2352 bwn_phy_g_init_sub(mac); 2353 return (0); 2354 } 2355 2356 static void 2357 bwn_phy_g_exit(struct bwn_mac *mac) 2358 { 2359 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2360 struct bwn_lo_calib *cal, *tmp; 2361 2362 if (lo == NULL) 2363 return; 2364 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2365 TAILQ_REMOVE(&lo->calib_list, cal, list); 2366 free(cal, M_DEVBUF); 2367 } 2368 } 2369 2370 static uint16_t 2371 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2372 { 2373 2374 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2375 return (BWN_READ_2(mac, BWN_PHYDATA)); 2376 } 2377 2378 static void 2379 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2380 { 2381 2382 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2383 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2384 } 2385 2386 static uint16_t 2387 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2388 { 2389 2390 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2391 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2392 return (BWN_READ_2(mac, BWN_RFDATALO)); 2393 } 2394 2395 static void 2396 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2397 { 2398 2399 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2400 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2401 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2402 } 2403 2404 static int 2405 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2406 { 2407 2408 return (mac->mac_phy.rev >= 6); 2409 } 2410 2411 static void 2412 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2413 { 2414 struct bwn_phy *phy = &mac->mac_phy; 2415 struct bwn_phy_g *pg = &phy->phy_g; 2416 unsigned int channel; 2417 uint16_t rfover, rfoverval; 2418 2419 if (on) { 2420 if (phy->rf_on) 2421 return; 2422 2423 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2424 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2425 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2426 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2427 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2428 pg->pg_radioctx_over); 2429 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2430 pg->pg_radioctx_overval); 2431 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2432 } 2433 channel = phy->chan; 2434 bwn_phy_g_switch_chan(mac, 6, 1); 2435 bwn_phy_g_switch_chan(mac, channel, 0); 2436 return; 2437 } 2438 2439 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2440 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2441 pg->pg_radioctx_over = rfover; 2442 pg->pg_radioctx_overval = rfoverval; 2443 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2444 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2445 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2446 } 2447 2448 static int 2449 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2450 { 2451 2452 if ((newchan < 1) || (newchan > 14)) 2453 return (EINVAL); 2454 bwn_phy_g_switch_chan(mac, newchan, 0); 2455 2456 return (0); 2457 } 2458 2459 static uint32_t 2460 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2461 { 2462 2463 return (1); 2464 } 2465 2466 static void 2467 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2468 { 2469 struct bwn_phy *phy = &mac->mac_phy; 2470 uint64_t hf; 2471 int autodiv = 0; 2472 uint16_t tmp; 2473 2474 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2475 autodiv = 1; 2476 2477 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2478 bwn_hf_write(mac, hf); 2479 2480 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2481 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2482 ((autodiv ? BWN_ANTAUTO1 : antenna) 2483 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2484 2485 if (autodiv) { 2486 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2487 if (antenna == BWN_ANTAUTO1) 2488 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2489 else 2490 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2491 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2492 } 2493 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2494 if (autodiv) 2495 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2496 else 2497 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2498 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2499 if (phy->rev >= 2) { 2500 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2501 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2502 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2503 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2504 0x15); 2505 if (phy->rev == 2) 2506 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2507 else 2508 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2509 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2510 8); 2511 } 2512 if (phy->rev >= 6) 2513 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2514 2515 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2516 bwn_hf_write(mac, hf); 2517 } 2518 2519 static int 2520 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2521 { 2522 struct bwn_phy *phy = &mac->mac_phy; 2523 struct bwn_phy_g *pg = &phy->phy_g; 2524 2525 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2526 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2527 2528 if (phy->rev == 0 || !phy->gmode) 2529 return (ENODEV); 2530 2531 pg->pg_aci_wlan_automatic = 0; 2532 return (0); 2533 } 2534 2535 static int 2536 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2537 { 2538 struct bwn_phy *phy = &mac->mac_phy; 2539 struct bwn_phy_g *pg = &phy->phy_g; 2540 struct bwn_softc *sc = mac->mac_sc; 2541 unsigned int tssi; 2542 int cck, ofdm; 2543 int power; 2544 int rfatt, bbatt; 2545 unsigned int max; 2546 2547 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2548 2549 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2550 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2551 if (cck < 0 && ofdm < 0) { 2552 if (ignore_tssi == 0) 2553 return (BWN_TXPWR_RES_DONE); 2554 cck = 0; 2555 ofdm = 0; 2556 } 2557 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2558 if (pg->pg_avgtssi != 0xff) 2559 tssi = (tssi + pg->pg_avgtssi) / 2; 2560 pg->pg_avgtssi = tssi; 2561 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2562 2563 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2564 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2565 max -= 3; 2566 if (max >= 120) { 2567 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2568 max = 80; 2569 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2570 } 2571 2572 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2573 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2574 tssi, 0x00), 0x3f)]); 2575 if (power == 0) 2576 return (BWN_TXPWR_RES_DONE); 2577 2578 rfatt = -((power + 7) / 8); 2579 bbatt = (-(power / 2)) - (4 * rfatt); 2580 if ((rfatt == 0) && (bbatt == 0)) 2581 return (BWN_TXPWR_RES_DONE); 2582 pg->pg_bbatt_delta = bbatt; 2583 pg->pg_rfatt_delta = rfatt; 2584 return (BWN_TXPWR_RES_NEED_ADJUST); 2585 } 2586 2587 static void 2588 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2589 { 2590 struct bwn_phy *phy = &mac->mac_phy; 2591 struct bwn_phy_g *pg = &phy->phy_g; 2592 struct bwn_softc *sc = mac->mac_sc; 2593 int rfatt, bbatt; 2594 uint8_t txctl; 2595 2596 bwn_mac_suspend(mac); 2597 2598 BWN_ASSERT_LOCKED(sc); 2599 2600 bbatt = pg->pg_bbatt.att; 2601 bbatt += pg->pg_bbatt_delta; 2602 rfatt = pg->pg_rfatt.att; 2603 rfatt += pg->pg_rfatt_delta; 2604 2605 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2606 txctl = pg->pg_txctl; 2607 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2608 if (rfatt <= 1) { 2609 if (txctl == 0) { 2610 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2611 rfatt += 2; 2612 bbatt += 2; 2613 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2614 BWN_BFL_PACTRL) { 2615 bbatt += 4 * (rfatt - 2); 2616 rfatt = 2; 2617 } 2618 } else if (rfatt > 4 && txctl) { 2619 txctl = 0; 2620 if (bbatt < 3) { 2621 rfatt -= 3; 2622 bbatt += 2; 2623 } else { 2624 rfatt -= 2; 2625 bbatt -= 2; 2626 } 2627 } 2628 } 2629 pg->pg_txctl = txctl; 2630 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2631 pg->pg_rfatt.att = rfatt; 2632 pg->pg_bbatt.att = bbatt; 2633 2634 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2635 2636 bwn_phy_lock(mac); 2637 bwn_rf_lock(mac); 2638 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2639 pg->pg_txctl); 2640 bwn_rf_unlock(mac); 2641 bwn_phy_unlock(mac); 2642 2643 bwn_mac_enable(mac); 2644 } 2645 2646 static void 2647 bwn_phy_g_task_15s(struct bwn_mac *mac) 2648 { 2649 struct bwn_phy *phy = &mac->mac_phy; 2650 struct bwn_phy_g *pg = &phy->phy_g; 2651 struct bwn_softc *sc = mac->mac_sc; 2652 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2653 unsigned long expire, now; 2654 struct bwn_lo_calib *cal, *tmp; 2655 uint8_t expired = 0; 2656 2657 bwn_mac_suspend(mac); 2658 2659 if (lo == NULL) 2660 goto fail; 2661 2662 BWN_GETTIME(now); 2663 if (bwn_has_hwpctl(mac)) { 2664 expire = now - BWN_LO_PWRVEC_EXPIRE; 2665 if (time_before(lo->pwr_vec_read_time, expire)) { 2666 bwn_lo_get_powervector(mac); 2667 bwn_phy_g_dc_lookup_init(mac, 0); 2668 } 2669 goto fail; 2670 } 2671 2672 expire = now - BWN_LO_CALIB_EXPIRE; 2673 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2674 if (!time_before(cal->calib_time, expire)) 2675 continue; 2676 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2677 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2678 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2679 expired = 1; 2680 } 2681 2682 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2683 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2684 cal->ctl.i, cal->ctl.q); 2685 2686 TAILQ_REMOVE(&lo->calib_list, cal, list); 2687 free(cal, M_DEVBUF); 2688 } 2689 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2690 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2691 &pg->pg_rfatt); 2692 if (cal == NULL) { 2693 device_printf(sc->sc_dev, 2694 "failed to recalibrate LO\n"); 2695 goto fail; 2696 } 2697 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2698 bwn_lo_write(mac, &cal->ctl); 2699 } 2700 2701 fail: 2702 bwn_mac_enable(mac); 2703 } 2704 2705 static void 2706 bwn_phy_g_task_60s(struct bwn_mac *mac) 2707 { 2708 struct bwn_phy *phy = &mac->mac_phy; 2709 struct bwn_softc *sc = mac->mac_sc; 2710 uint8_t old = phy->chan; 2711 2712 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2713 return; 2714 2715 bwn_mac_suspend(mac); 2716 bwn_nrssi_slope_11g(mac); 2717 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2718 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2719 bwn_switch_channel(mac, old); 2720 } 2721 bwn_mac_enable(mac); 2722 } 2723 2724 static void 2725 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2726 { 2727 2728 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2729 } 2730 2731 static int 2732 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2733 const struct ieee80211_bpf_params *params) 2734 { 2735 struct ieee80211com *ic = ni->ni_ic; 2736 struct ifnet *ifp = ic->ic_ifp; 2737 struct bwn_softc *sc = ifp->if_softc; 2738 struct bwn_mac *mac = sc->sc_curmac; 2739 2740 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2741 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2742 ieee80211_free_node(ni); 2743 m_freem(m); 2744 return (ENETDOWN); 2745 } 2746 2747 BWN_LOCK(sc); 2748 if (bwn_tx_isfull(sc, m)) { 2749 ieee80211_free_node(ni); 2750 m_freem(m); 2751 ifp->if_oerrors++; 2752 BWN_UNLOCK(sc); 2753 return (ENOBUFS); 2754 } 2755 2756 if (bwn_tx_start(sc, ni, m) != 0) { 2757 if (ni != NULL) 2758 ieee80211_free_node(ni); 2759 ifp->if_oerrors++; 2760 } 2761 sc->sc_watchdog_timer = 5; 2762 BWN_UNLOCK(sc); 2763 return (0); 2764 } 2765 2766 /* 2767 * Callback from the 802.11 layer to update the slot time 2768 * based on the current setting. We use it to notify the 2769 * firmware of ERP changes and the f/w takes care of things 2770 * like slot time and preamble. 2771 */ 2772 static void 2773 bwn_updateslot(struct ifnet *ifp) 2774 { 2775 struct bwn_softc *sc = ifp->if_softc; 2776 struct ieee80211com *ic = ifp->if_l2com; 2777 struct bwn_mac *mac; 2778 2779 BWN_LOCK(sc); 2780 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2781 mac = (struct bwn_mac *)sc->sc_curmac; 2782 bwn_set_slot_time(mac, 2783 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2784 } 2785 BWN_UNLOCK(sc); 2786 } 2787 2788 /* 2789 * Callback from the 802.11 layer after a promiscuous mode change. 2790 * Note this interface does not check the operating mode as this 2791 * is an internal callback and we are expected to honor the current 2792 * state (e.g. this is used for setting the interface in promiscuous 2793 * mode when operating in hostap mode to do ACS). 2794 */ 2795 static void 2796 bwn_update_promisc(struct ifnet *ifp) 2797 { 2798 struct bwn_softc *sc = ifp->if_softc; 2799 struct bwn_mac *mac = sc->sc_curmac; 2800 2801 BWN_LOCK(sc); 2802 mac = sc->sc_curmac; 2803 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2804 if (ifp->if_flags & IFF_PROMISC) 2805 sc->sc_filters |= BWN_MACCTL_PROMISC; 2806 else 2807 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2808 bwn_set_opmode(mac); 2809 } 2810 BWN_UNLOCK(sc); 2811 } 2812 2813 /* 2814 * Callback from the 802.11 layer to update WME parameters. 2815 */ 2816 static int 2817 bwn_wme_update(struct ieee80211com *ic) 2818 { 2819 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2820 struct bwn_mac *mac = sc->sc_curmac; 2821 struct wmeParams *wmep; 2822 int i; 2823 2824 BWN_LOCK(sc); 2825 mac = sc->sc_curmac; 2826 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2827 bwn_mac_suspend(mac); 2828 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2829 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2830 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2831 } 2832 bwn_mac_enable(mac); 2833 } 2834 BWN_UNLOCK(sc); 2835 return (0); 2836 } 2837 2838 static void 2839 bwn_scan_start(struct ieee80211com *ic) 2840 { 2841 struct ifnet *ifp = ic->ic_ifp; 2842 struct bwn_softc *sc = ifp->if_softc; 2843 struct bwn_mac *mac; 2844 2845 BWN_LOCK(sc); 2846 mac = sc->sc_curmac; 2847 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2848 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2849 bwn_set_opmode(mac); 2850 /* disable CFP update during scan */ 2851 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2852 } 2853 BWN_UNLOCK(sc); 2854 } 2855 2856 static void 2857 bwn_scan_end(struct ieee80211com *ic) 2858 { 2859 struct ifnet *ifp = ic->ic_ifp; 2860 struct bwn_softc *sc = ifp->if_softc; 2861 struct bwn_mac *mac; 2862 2863 BWN_LOCK(sc); 2864 mac = sc->sc_curmac; 2865 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2866 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2867 bwn_set_opmode(mac); 2868 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2869 } 2870 BWN_UNLOCK(sc); 2871 } 2872 2873 static void 2874 bwn_set_channel(struct ieee80211com *ic) 2875 { 2876 struct ifnet *ifp = ic->ic_ifp; 2877 struct bwn_softc *sc = ifp->if_softc; 2878 struct bwn_mac *mac = sc->sc_curmac; 2879 struct bwn_phy *phy = &mac->mac_phy; 2880 int chan, error; 2881 2882 BWN_LOCK(sc); 2883 2884 error = bwn_switch_band(sc, ic->ic_curchan); 2885 if (error) 2886 goto fail;; 2887 bwn_mac_suspend(mac); 2888 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2889 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2890 if (chan != phy->chan) 2891 bwn_switch_channel(mac, chan); 2892 2893 /* TX power level */ 2894 if (ic->ic_curchan->ic_maxpower != 0 && 2895 ic->ic_curchan->ic_maxpower != phy->txpower) { 2896 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2897 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2898 BWN_TXPWR_IGNORE_TSSI); 2899 } 2900 2901 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2902 if (phy->set_antenna) 2903 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2904 2905 if (sc->sc_rf_enabled != phy->rf_on) { 2906 if (sc->sc_rf_enabled) { 2907 bwn_rf_turnon(mac); 2908 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2909 device_printf(sc->sc_dev, 2910 "please turns on the RF switch\n"); 2911 } else 2912 bwn_rf_turnoff(mac); 2913 } 2914 2915 bwn_mac_enable(mac); 2916 2917 fail: 2918 /* 2919 * Setup radio tap channel freq and flags 2920 */ 2921 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2922 htole16(ic->ic_curchan->ic_freq); 2923 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2924 htole16(ic->ic_curchan->ic_flags & 0xffff); 2925 2926 BWN_UNLOCK(sc); 2927 } 2928 2929 static struct ieee80211vap * 2930 bwn_vap_create(struct ieee80211com *ic, 2931 const char name[IFNAMSIZ], int unit, int opmode, int flags, 2932 const uint8_t bssid[IEEE80211_ADDR_LEN], 2933 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2934 { 2935 struct ifnet *ifp = ic->ic_ifp; 2936 struct bwn_softc *sc = ifp->if_softc; 2937 struct ieee80211vap *vap; 2938 struct bwn_vap *bvp; 2939 uint8_t mac[IEEE80211_ADDR_LEN]; 2940 2941 IEEE80211_ADDR_COPY(mac, mac0); 2942 switch (opmode) { 2943 case IEEE80211_M_HOSTAP: 2944 case IEEE80211_M_MBSS: 2945 case IEEE80211_M_STA: 2946 case IEEE80211_M_WDS: 2947 case IEEE80211_M_MONITOR: 2948 case IEEE80211_M_IBSS: 2949 case IEEE80211_M_AHDEMO: 2950 break; 2951 default: 2952 return (NULL); 2953 } 2954 2955 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2956 2957 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 2958 M_80211_VAP, M_NOWAIT | M_ZERO); 2959 if (bvp == NULL) { 2960 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 2961 return (NULL); 2962 } 2963 vap = &bvp->bv_vap; 2964 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2965 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2966 /* override with driver methods */ 2967 bvp->bv_newstate = vap->iv_newstate; 2968 vap->iv_newstate = bwn_newstate; 2969 2970 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2971 vap->iv_max_aid = BWN_STAID_MAX; 2972 2973 ieee80211_ratectl_init(vap); 2974 2975 /* complete setup */ 2976 ieee80211_vap_attach(vap, ieee80211_media_change, 2977 ieee80211_media_status); 2978 return (vap); 2979 } 2980 2981 static void 2982 bwn_vap_delete(struct ieee80211vap *vap) 2983 { 2984 struct bwn_vap *bvp = BWN_VAP(vap); 2985 2986 ieee80211_ratectl_deinit(vap); 2987 ieee80211_vap_detach(vap); 2988 free(bvp, M_80211_VAP); 2989 } 2990 2991 static void 2992 bwn_init(void *arg) 2993 { 2994 struct bwn_softc *sc = arg; 2995 struct ifnet *ifp = sc->sc_ifp; 2996 struct ieee80211com *ic = ifp->if_l2com; 2997 int error = 0; 2998 2999 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 3000 __func__, ifp->if_flags); 3001 3002 BWN_LOCK(sc); 3003 error = bwn_init_locked(sc); 3004 BWN_UNLOCK(sc); 3005 3006 if (error == 0) 3007 ieee80211_start_all(ic); /* start all vap's */ 3008 } 3009 3010 static int 3011 bwn_init_locked(struct bwn_softc *sc) 3012 { 3013 struct bwn_mac *mac; 3014 struct ifnet *ifp = sc->sc_ifp; 3015 int error; 3016 3017 BWN_ASSERT_LOCKED(sc); 3018 3019 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3020 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3021 sc->sc_filters = 0; 3022 bwn_wme_clear(sc); 3023 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3024 sc->sc_rf_enabled = 1; 3025 3026 mac = sc->sc_curmac; 3027 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3028 error = bwn_core_init(mac); 3029 if (error != 0) 3030 return (error); 3031 } 3032 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3033 bwn_core_start(mac); 3034 3035 bwn_set_opmode(mac); 3036 bwn_set_pretbtt(mac); 3037 bwn_spu_setdelay(mac, 0); 3038 bwn_set_macaddr(mac); 3039 3040 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3041 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3042 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3043 3044 return (0); 3045 } 3046 3047 static void 3048 bwn_stop(struct bwn_softc *sc, int statechg) 3049 { 3050 3051 BWN_LOCK(sc); 3052 bwn_stop_locked(sc, statechg); 3053 BWN_UNLOCK(sc); 3054 } 3055 3056 static void 3057 bwn_stop_locked(struct bwn_softc *sc, int statechg) 3058 { 3059 struct bwn_mac *mac = sc->sc_curmac; 3060 struct ifnet *ifp = sc->sc_ifp; 3061 3062 BWN_ASSERT_LOCKED(sc); 3063 3064 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3065 /* XXX FIXME opmode not based on VAP */ 3066 bwn_set_opmode(mac); 3067 bwn_set_macaddr(mac); 3068 } 3069 3070 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3071 bwn_core_stop(mac); 3072 3073 callout_stop(&sc->sc_led_blink_ch); 3074 sc->sc_led_blinking = 0; 3075 3076 bwn_core_exit(mac); 3077 sc->sc_rf_enabled = 0; 3078 3079 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3080 } 3081 3082 static void 3083 bwn_wme_clear(struct bwn_softc *sc) 3084 { 3085 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3086 struct wmeParams *p; 3087 unsigned int i; 3088 3089 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3090 ("%s:%d: fail", __func__, __LINE__)); 3091 3092 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3093 p = &(sc->sc_wmeParams[i]); 3094 3095 switch (bwn_wme_shm_offsets[i]) { 3096 case BWN_WME_VOICE: 3097 p->wmep_txopLimit = 0; 3098 p->wmep_aifsn = 2; 3099 /* XXX FIXME: log2(cwmin) */ 3100 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3101 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3102 break; 3103 case BWN_WME_VIDEO: 3104 p->wmep_txopLimit = 0; 3105 p->wmep_aifsn = 2; 3106 /* XXX FIXME: log2(cwmin) */ 3107 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3108 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3109 break; 3110 case BWN_WME_BESTEFFORT: 3111 p->wmep_txopLimit = 0; 3112 p->wmep_aifsn = 3; 3113 /* XXX FIXME: log2(cwmin) */ 3114 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3115 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3116 break; 3117 case BWN_WME_BACKGROUND: 3118 p->wmep_txopLimit = 0; 3119 p->wmep_aifsn = 7; 3120 /* XXX FIXME: log2(cwmin) */ 3121 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3122 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3123 break; 3124 default: 3125 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3126 } 3127 } 3128 } 3129 3130 static int 3131 bwn_core_init(struct bwn_mac *mac) 3132 { 3133 struct bwn_softc *sc = mac->mac_sc; 3134 uint64_t hf; 3135 int error; 3136 3137 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3138 ("%s:%d: fail", __func__, __LINE__)); 3139 3140 siba_powerup(sc->sc_dev, 0); 3141 if (!siba_dev_isup(sc->sc_dev)) 3142 bwn_reset_core(mac, 3143 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3144 3145 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3146 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3147 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3148 BWN_GETTIME(mac->mac_phy.nexttime); 3149 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3150 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3151 mac->mac_stats.link_noise = -95; 3152 mac->mac_reason_intr = 0; 3153 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3154 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3155 #ifdef BWN_DEBUG 3156 if (sc->sc_debug & BWN_DEBUG_XMIT) 3157 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3158 #endif 3159 mac->mac_suspended = 1; 3160 mac->mac_task_state = 0; 3161 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3162 3163 mac->mac_phy.init_pre(mac); 3164 3165 siba_pcicore_intr(sc->sc_dev); 3166 3167 siba_fix_imcfglobug(sc->sc_dev); 3168 bwn_bt_disable(mac); 3169 if (mac->mac_phy.prepare_hw) { 3170 error = mac->mac_phy.prepare_hw(mac); 3171 if (error) 3172 goto fail0; 3173 } 3174 error = bwn_chip_init(mac); 3175 if (error) 3176 goto fail0; 3177 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3178 siba_get_revid(sc->sc_dev)); 3179 hf = bwn_hf_read(mac); 3180 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3181 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3182 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3183 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3184 if (mac->mac_phy.rev == 1) 3185 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3186 } 3187 if (mac->mac_phy.rf_ver == 0x2050) { 3188 if (mac->mac_phy.rf_rev < 6) 3189 hf |= BWN_HF_FORCE_VCO_RECALC; 3190 if (mac->mac_phy.rf_rev == 6) 3191 hf |= BWN_HF_4318_TSSI; 3192 } 3193 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3194 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3195 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3196 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3197 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3198 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3199 bwn_hf_write(mac, hf); 3200 3201 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3202 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3204 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3205 3206 bwn_rate_init(mac); 3207 bwn_set_phytxctl(mac); 3208 3209 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3210 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3211 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3212 3213 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3214 bwn_pio_init(mac); 3215 else 3216 bwn_dma_init(mac); 3217 if (error) 3218 goto fail1; 3219 bwn_wme_init(mac); 3220 bwn_spu_setdelay(mac, 1); 3221 bwn_bt_enable(mac); 3222 3223 siba_powerup(sc->sc_dev, 3224 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3225 bwn_set_macaddr(mac); 3226 bwn_crypt_init(mac); 3227 3228 /* XXX LED initializatin */ 3229 3230 mac->mac_status = BWN_MAC_STATUS_INITED; 3231 3232 return (error); 3233 3234 fail1: 3235 bwn_chip_exit(mac); 3236 fail0: 3237 siba_powerdown(sc->sc_dev); 3238 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3239 ("%s:%d: fail", __func__, __LINE__)); 3240 return (error); 3241 } 3242 3243 static void 3244 bwn_core_start(struct bwn_mac *mac) 3245 { 3246 struct bwn_softc *sc = mac->mac_sc; 3247 uint32_t tmp; 3248 3249 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3250 ("%s:%d: fail", __func__, __LINE__)); 3251 3252 if (siba_get_revid(sc->sc_dev) < 5) 3253 return; 3254 3255 while (1) { 3256 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3257 if (!(tmp & 0x00000001)) 3258 break; 3259 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3260 } 3261 3262 bwn_mac_enable(mac); 3263 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3264 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3265 3266 mac->mac_status = BWN_MAC_STATUS_STARTED; 3267 } 3268 3269 static void 3270 bwn_core_exit(struct bwn_mac *mac) 3271 { 3272 struct bwn_softc *sc = mac->mac_sc; 3273 uint32_t macctl; 3274 3275 BWN_ASSERT_LOCKED(mac->mac_sc); 3276 3277 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3278 ("%s:%d: fail", __func__, __LINE__)); 3279 3280 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3281 return; 3282 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3283 3284 macctl = BWN_READ_4(mac, BWN_MACCTL); 3285 macctl &= ~BWN_MACCTL_MCODE_RUN; 3286 macctl |= BWN_MACCTL_MCODE_JMP0; 3287 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3288 3289 bwn_dma_stop(mac); 3290 bwn_pio_stop(mac); 3291 bwn_chip_exit(mac); 3292 mac->mac_phy.switch_analog(mac, 0); 3293 siba_dev_down(sc->sc_dev, 0); 3294 siba_powerdown(sc->sc_dev); 3295 } 3296 3297 static void 3298 bwn_bt_disable(struct bwn_mac *mac) 3299 { 3300 struct bwn_softc *sc = mac->mac_sc; 3301 3302 (void)sc; 3303 /* XXX do nothing yet */ 3304 } 3305 3306 static int 3307 bwn_chip_init(struct bwn_mac *mac) 3308 { 3309 struct bwn_softc *sc = mac->mac_sc; 3310 struct bwn_phy *phy = &mac->mac_phy; 3311 uint32_t macctl; 3312 int error; 3313 3314 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3315 if (phy->gmode) 3316 macctl |= BWN_MACCTL_GMODE; 3317 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3318 3319 error = bwn_fw_fillinfo(mac); 3320 if (error) 3321 return (error); 3322 error = bwn_fw_loaducode(mac); 3323 if (error) 3324 return (error); 3325 3326 error = bwn_gpio_init(mac); 3327 if (error) 3328 return (error); 3329 3330 error = bwn_fw_loadinitvals(mac); 3331 if (error) { 3332 siba_gpio_set(sc->sc_dev, 0); 3333 return (error); 3334 } 3335 phy->switch_analog(mac, 1); 3336 error = bwn_phy_init(mac); 3337 if (error) { 3338 siba_gpio_set(sc->sc_dev, 0); 3339 return (error); 3340 } 3341 if (phy->set_im) 3342 phy->set_im(mac, BWN_IMMODE_NONE); 3343 if (phy->set_antenna) 3344 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3345 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3346 3347 if (phy->type == BWN_PHYTYPE_B) 3348 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3349 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3350 if (siba_get_revid(sc->sc_dev) < 5) 3351 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3352 3353 BWN_WRITE_4(mac, BWN_MACCTL, 3354 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3355 BWN_WRITE_4(mac, BWN_MACCTL, 3356 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3357 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3358 3359 bwn_set_opmode(mac); 3360 if (siba_get_revid(sc->sc_dev) < 3) { 3361 BWN_WRITE_2(mac, 0x060e, 0x0000); 3362 BWN_WRITE_2(mac, 0x0610, 0x8000); 3363 BWN_WRITE_2(mac, 0x0604, 0x0000); 3364 BWN_WRITE_2(mac, 0x0606, 0x0200); 3365 } else { 3366 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3367 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3368 } 3369 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3370 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3371 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3372 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3373 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3374 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3375 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3376 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3377 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3378 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3379 return (error); 3380 } 3381 3382 /* read hostflags */ 3383 static uint64_t 3384 bwn_hf_read(struct bwn_mac *mac) 3385 { 3386 uint64_t ret; 3387 3388 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3389 ret <<= 16; 3390 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3391 ret <<= 16; 3392 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3393 return (ret); 3394 } 3395 3396 static void 3397 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3398 { 3399 3400 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3401 (value & 0x00000000ffffull)); 3402 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3403 (value & 0x0000ffff0000ull) >> 16); 3404 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3405 (value & 0xffff00000000ULL) >> 32); 3406 } 3407 3408 static void 3409 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3410 { 3411 3412 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3413 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3414 } 3415 3416 static void 3417 bwn_rate_init(struct bwn_mac *mac) 3418 { 3419 3420 switch (mac->mac_phy.type) { 3421 case BWN_PHYTYPE_A: 3422 case BWN_PHYTYPE_G: 3423 case BWN_PHYTYPE_LP: 3424 case BWN_PHYTYPE_N: 3425 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3426 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3427 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3428 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3429 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3430 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3431 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3432 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3433 break; 3434 /* FALLTHROUGH */ 3435 case BWN_PHYTYPE_B: 3436 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3437 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3438 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3439 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3440 break; 3441 default: 3442 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3443 } 3444 } 3445 3446 static void 3447 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3448 { 3449 uint16_t offset; 3450 3451 if (ofdm) { 3452 offset = 0x480; 3453 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3454 } else { 3455 offset = 0x4c0; 3456 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3457 } 3458 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3459 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3460 } 3461 3462 static uint8_t 3463 bwn_plcp_getcck(const uint8_t bitrate) 3464 { 3465 3466 switch (bitrate) { 3467 case BWN_CCK_RATE_1MB: 3468 return (0x0a); 3469 case BWN_CCK_RATE_2MB: 3470 return (0x14); 3471 case BWN_CCK_RATE_5MB: 3472 return (0x37); 3473 case BWN_CCK_RATE_11MB: 3474 return (0x6e); 3475 } 3476 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3477 return (0); 3478 } 3479 3480 static uint8_t 3481 bwn_plcp_getofdm(const uint8_t bitrate) 3482 { 3483 3484 switch (bitrate) { 3485 case BWN_OFDM_RATE_6MB: 3486 return (0xb); 3487 case BWN_OFDM_RATE_9MB: 3488 return (0xf); 3489 case BWN_OFDM_RATE_12MB: 3490 return (0xa); 3491 case BWN_OFDM_RATE_18MB: 3492 return (0xe); 3493 case BWN_OFDM_RATE_24MB: 3494 return (0x9); 3495 case BWN_OFDM_RATE_36MB: 3496 return (0xd); 3497 case BWN_OFDM_RATE_48MB: 3498 return (0x8); 3499 case BWN_OFDM_RATE_54MB: 3500 return (0xc); 3501 } 3502 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3503 return (0); 3504 } 3505 3506 static void 3507 bwn_set_phytxctl(struct bwn_mac *mac) 3508 { 3509 uint16_t ctl; 3510 3511 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3512 BWN_TX_PHY_TXPWR); 3513 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3514 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3515 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3516 } 3517 3518 static void 3519 bwn_pio_init(struct bwn_mac *mac) 3520 { 3521 struct bwn_pio *pio = &mac->mac_method.pio; 3522 3523 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3524 & ~BWN_MACCTL_BIGENDIAN); 3525 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3526 3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3528 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3529 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3530 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3531 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3532 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3533 } 3534 3535 static void 3536 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3537 int index) 3538 { 3539 struct bwn_pio_txpkt *tp; 3540 struct bwn_softc *sc = mac->mac_sc; 3541 unsigned int i; 3542 3543 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3544 tq->tq_index = index; 3545 3546 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3547 if (siba_get_revid(sc->sc_dev) >= 8) 3548 tq->tq_size = 1920; 3549 else { 3550 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3551 tq->tq_size -= 80; 3552 } 3553 3554 TAILQ_INIT(&tq->tq_pktlist); 3555 for (i = 0; i < N(tq->tq_pkts); i++) { 3556 tp = &(tq->tq_pkts[i]); 3557 tp->tp_index = i; 3558 tp->tp_queue = tq; 3559 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3560 } 3561 } 3562 3563 static uint16_t 3564 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3565 { 3566 struct bwn_softc *sc = mac->mac_sc; 3567 static const uint16_t bases[] = { 3568 BWN_PIO_BASE0, 3569 BWN_PIO_BASE1, 3570 BWN_PIO_BASE2, 3571 BWN_PIO_BASE3, 3572 BWN_PIO_BASE4, 3573 BWN_PIO_BASE5, 3574 BWN_PIO_BASE6, 3575 BWN_PIO_BASE7, 3576 }; 3577 static const uint16_t bases_rev11[] = { 3578 BWN_PIO11_BASE0, 3579 BWN_PIO11_BASE1, 3580 BWN_PIO11_BASE2, 3581 BWN_PIO11_BASE3, 3582 BWN_PIO11_BASE4, 3583 BWN_PIO11_BASE5, 3584 }; 3585 3586 if (siba_get_revid(sc->sc_dev) >= 11) { 3587 if (index >= N(bases_rev11)) 3588 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3589 return (bases_rev11[index]); 3590 } 3591 if (index >= N(bases)) 3592 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3593 return (bases[index]); 3594 } 3595 3596 static void 3597 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3598 int index) 3599 { 3600 struct bwn_softc *sc = mac->mac_sc; 3601 3602 prq->prq_mac = mac; 3603 prq->prq_rev = siba_get_revid(sc->sc_dev); 3604 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3605 bwn_dma_rxdirectfifo(mac, index, 1); 3606 } 3607 3608 static void 3609 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3610 { 3611 if (tq == NULL) 3612 return; 3613 bwn_pio_cancel_tx_packets(tq); 3614 } 3615 3616 static void 3617 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3618 { 3619 3620 bwn_destroy_pioqueue_tx(pio); 3621 } 3622 3623 static uint16_t 3624 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3625 uint16_t offset) 3626 { 3627 3628 return (BWN_READ_2(mac, tq->tq_base + offset)); 3629 } 3630 3631 static void 3632 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3633 { 3634 uint32_t ctl; 3635 int type; 3636 uint16_t base; 3637 3638 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3639 base = bwn_dma_base(type, idx); 3640 if (type == BWN_DMA_64BIT) { 3641 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3642 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3643 if (enable) 3644 ctl |= BWN_DMA64_RXDIRECTFIFO; 3645 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3646 } else { 3647 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3648 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3649 if (enable) 3650 ctl |= BWN_DMA32_RXDIRECTFIFO; 3651 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3652 } 3653 } 3654 3655 static uint64_t 3656 bwn_dma_mask(struct bwn_mac *mac) 3657 { 3658 uint32_t tmp; 3659 uint16_t base; 3660 3661 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3662 if (tmp & SIBA_TGSHIGH_DMA64) 3663 return (BWN_DMA_BIT_MASK(64)); 3664 base = bwn_dma_base(0, 0); 3665 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3666 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3667 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3668 return (BWN_DMA_BIT_MASK(32)); 3669 3670 return (BWN_DMA_BIT_MASK(30)); 3671 } 3672 3673 static int 3674 bwn_dma_mask2type(uint64_t dmamask) 3675 { 3676 3677 if (dmamask == BWN_DMA_BIT_MASK(30)) 3678 return (BWN_DMA_30BIT); 3679 if (dmamask == BWN_DMA_BIT_MASK(32)) 3680 return (BWN_DMA_32BIT); 3681 if (dmamask == BWN_DMA_BIT_MASK(64)) 3682 return (BWN_DMA_64BIT); 3683 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3684 return (BWN_DMA_30BIT); 3685 } 3686 3687 static void 3688 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3689 { 3690 struct bwn_pio_txpkt *tp; 3691 unsigned int i; 3692 3693 for (i = 0; i < N(tq->tq_pkts); i++) { 3694 tp = &(tq->tq_pkts[i]); 3695 if (tp->tp_m) { 3696 m_freem(tp->tp_m); 3697 tp->tp_m = NULL; 3698 } 3699 } 3700 } 3701 3702 static uint16_t 3703 bwn_dma_base(int type, int controller_idx) 3704 { 3705 static const uint16_t map64[] = { 3706 BWN_DMA64_BASE0, 3707 BWN_DMA64_BASE1, 3708 BWN_DMA64_BASE2, 3709 BWN_DMA64_BASE3, 3710 BWN_DMA64_BASE4, 3711 BWN_DMA64_BASE5, 3712 }; 3713 static const uint16_t map32[] = { 3714 BWN_DMA32_BASE0, 3715 BWN_DMA32_BASE1, 3716 BWN_DMA32_BASE2, 3717 BWN_DMA32_BASE3, 3718 BWN_DMA32_BASE4, 3719 BWN_DMA32_BASE5, 3720 }; 3721 3722 if (type == BWN_DMA_64BIT) { 3723 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3724 ("%s:%d: fail", __func__, __LINE__)); 3725 return (map64[controller_idx]); 3726 } 3727 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3728 ("%s:%d: fail", __func__, __LINE__)); 3729 return (map32[controller_idx]); 3730 } 3731 3732 static void 3733 bwn_dma_init(struct bwn_mac *mac) 3734 { 3735 struct bwn_dma *dma = &mac->mac_method.dma; 3736 3737 /* setup TX DMA channels. */ 3738 bwn_dma_setup(dma->wme[WME_AC_BK]); 3739 bwn_dma_setup(dma->wme[WME_AC_BE]); 3740 bwn_dma_setup(dma->wme[WME_AC_VI]); 3741 bwn_dma_setup(dma->wme[WME_AC_VO]); 3742 bwn_dma_setup(dma->mcast); 3743 /* setup RX DMA channel. */ 3744 bwn_dma_setup(dma->rx); 3745 } 3746 3747 static struct bwn_dma_ring * 3748 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3749 int for_tx, int type) 3750 { 3751 struct bwn_dma *dma = &mac->mac_method.dma; 3752 struct bwn_dma_ring *dr; 3753 struct bwn_dmadesc_generic *desc; 3754 struct bwn_dmadesc_meta *mt; 3755 struct bwn_softc *sc = mac->mac_sc; 3756 int error, i; 3757 3758 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3759 if (dr == NULL) 3760 goto out; 3761 dr->dr_numslots = BWN_RXRING_SLOTS; 3762 if (for_tx) 3763 dr->dr_numslots = BWN_TXRING_SLOTS; 3764 3765 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3766 M_DEVBUF, M_NOWAIT | M_ZERO); 3767 if (dr->dr_meta == NULL) 3768 goto fail0; 3769 3770 dr->dr_type = type; 3771 dr->dr_mac = mac; 3772 dr->dr_base = bwn_dma_base(type, controller_index); 3773 dr->dr_index = controller_index; 3774 if (type == BWN_DMA_64BIT) { 3775 dr->getdesc = bwn_dma_64_getdesc; 3776 dr->setdesc = bwn_dma_64_setdesc; 3777 dr->start_transfer = bwn_dma_64_start_transfer; 3778 dr->suspend = bwn_dma_64_suspend; 3779 dr->resume = bwn_dma_64_resume; 3780 dr->get_curslot = bwn_dma_64_get_curslot; 3781 dr->set_curslot = bwn_dma_64_set_curslot; 3782 } else { 3783 dr->getdesc = bwn_dma_32_getdesc; 3784 dr->setdesc = bwn_dma_32_setdesc; 3785 dr->start_transfer = bwn_dma_32_start_transfer; 3786 dr->suspend = bwn_dma_32_suspend; 3787 dr->resume = bwn_dma_32_resume; 3788 dr->get_curslot = bwn_dma_32_get_curslot; 3789 dr->set_curslot = bwn_dma_32_set_curslot; 3790 } 3791 if (for_tx) { 3792 dr->dr_tx = 1; 3793 dr->dr_curslot = -1; 3794 } else { 3795 if (dr->dr_index == 0) { 3796 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3797 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3798 } else 3799 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3800 } 3801 3802 error = bwn_dma_allocringmemory(dr); 3803 if (error) 3804 goto fail2; 3805 3806 if (for_tx) { 3807 /* 3808 * Assumption: BWN_TXRING_SLOTS can be divided by 3809 * BWN_TX_SLOTS_PER_FRAME 3810 */ 3811 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3812 ("%s:%d: fail", __func__, __LINE__)); 3813 3814 dr->dr_txhdr_cache = 3815 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3816 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3817 KASSERT(dr->dr_txhdr_cache != NULL, 3818 ("%s:%d: fail", __func__, __LINE__)); 3819 3820 /* 3821 * Create TX ring DMA stuffs 3822 */ 3823 error = bus_dma_tag_create(dma->parent_dtag, 3824 BWN_ALIGN, 0, 3825 BUS_SPACE_MAXADDR, 3826 BUS_SPACE_MAXADDR, 3827 NULL, NULL, 3828 BWN_HDRSIZE(mac), 3829 1, 3830 BUS_SPACE_MAXSIZE_32BIT, 3831 0, 3832 NULL, NULL, 3833 &dr->dr_txring_dtag); 3834 if (error) { 3835 device_printf(sc->sc_dev, 3836 "can't create TX ring DMA tag: TODO frees\n"); 3837 goto fail1; 3838 } 3839 3840 for (i = 0; i < dr->dr_numslots; i += 2) { 3841 dr->getdesc(dr, i, &desc, &mt); 3842 3843 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3844 mt->mt_m = NULL; 3845 mt->mt_ni = NULL; 3846 mt->mt_islast = 0; 3847 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3848 &mt->mt_dmap); 3849 if (error) { 3850 device_printf(sc->sc_dev, 3851 "can't create RX buf DMA map\n"); 3852 goto fail1; 3853 } 3854 3855 dr->getdesc(dr, i + 1, &desc, &mt); 3856 3857 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3858 mt->mt_m = NULL; 3859 mt->mt_ni = NULL; 3860 mt->mt_islast = 1; 3861 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3862 &mt->mt_dmap); 3863 if (error) { 3864 device_printf(sc->sc_dev, 3865 "can't create RX buf DMA map\n"); 3866 goto fail1; 3867 } 3868 } 3869 } else { 3870 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3871 &dr->dr_spare_dmap); 3872 if (error) { 3873 device_printf(sc->sc_dev, 3874 "can't create RX buf DMA map\n"); 3875 goto out; /* XXX wrong! */ 3876 } 3877 3878 for (i = 0; i < dr->dr_numslots; i++) { 3879 dr->getdesc(dr, i, &desc, &mt); 3880 3881 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3882 &mt->mt_dmap); 3883 if (error) { 3884 device_printf(sc->sc_dev, 3885 "can't create RX buf DMA map\n"); 3886 goto out; /* XXX wrong! */ 3887 } 3888 error = bwn_dma_newbuf(dr, desc, mt, 1); 3889 if (error) { 3890 device_printf(sc->sc_dev, 3891 "failed to allocate RX buf\n"); 3892 goto out; /* XXX wrong! */ 3893 } 3894 } 3895 3896 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3897 BUS_DMASYNC_PREWRITE); 3898 3899 dr->dr_usedslot = dr->dr_numslots; 3900 } 3901 3902 out: 3903 return (dr); 3904 3905 fail2: 3906 free(dr->dr_txhdr_cache, M_DEVBUF); 3907 fail1: 3908 free(dr->dr_meta, M_DEVBUF); 3909 fail0: 3910 free(dr, M_DEVBUF); 3911 return (NULL); 3912 } 3913 3914 static void 3915 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3916 { 3917 3918 if (dr == NULL) 3919 return; 3920 3921 bwn_dma_free_descbufs(*dr); 3922 bwn_dma_free_ringmemory(*dr); 3923 3924 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3925 free((*dr)->dr_meta, M_DEVBUF); 3926 free(*dr, M_DEVBUF); 3927 3928 *dr = NULL; 3929 } 3930 3931 static void 3932 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3933 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3934 { 3935 struct bwn_dmadesc32 *desc; 3936 3937 *meta = &(dr->dr_meta[slot]); 3938 desc = dr->dr_ring_descbase; 3939 desc = &(desc[slot]); 3940 3941 *gdesc = (struct bwn_dmadesc_generic *)desc; 3942 } 3943 3944 static void 3945 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3946 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3947 int start, int end, int irq) 3948 { 3949 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3950 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3951 uint32_t addr, addrext, ctl; 3952 int slot; 3953 3954 slot = (int)(&(desc->dma.dma32) - descbase); 3955 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3956 ("%s:%d: fail", __func__, __LINE__)); 3957 3958 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3959 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3960 addr |= siba_dma_translation(sc->sc_dev); 3961 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3962 if (slot == dr->dr_numslots - 1) 3963 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3964 if (start) 3965 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3966 if (end) 3967 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3968 if (irq) 3969 ctl |= BWN_DMA32_DCTL_IRQ; 3970 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3971 & BWN_DMA32_DCTL_ADDREXT_MASK; 3972 3973 desc->dma.dma32.control = htole32(ctl); 3974 desc->dma.dma32.address = htole32(addr); 3975 } 3976 3977 static void 3978 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3979 { 3980 3981 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3982 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3983 } 3984 3985 static void 3986 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3987 { 3988 3989 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3990 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3991 } 3992 3993 static void 3994 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3995 { 3996 3997 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3998 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3999 } 4000 4001 static int 4002 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4003 { 4004 uint32_t val; 4005 4006 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4007 val &= BWN_DMA32_RXDPTR; 4008 4009 return (val / sizeof(struct bwn_dmadesc32)); 4010 } 4011 4012 static void 4013 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4014 { 4015 4016 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4017 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4018 } 4019 4020 static void 4021 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4022 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4023 { 4024 struct bwn_dmadesc64 *desc; 4025 4026 *meta = &(dr->dr_meta[slot]); 4027 desc = dr->dr_ring_descbase; 4028 desc = &(desc[slot]); 4029 4030 *gdesc = (struct bwn_dmadesc_generic *)desc; 4031 } 4032 4033 static void 4034 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4035 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4036 int start, int end, int irq) 4037 { 4038 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4039 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4040 int slot; 4041 uint32_t ctl0 = 0, ctl1 = 0; 4042 uint32_t addrlo, addrhi; 4043 uint32_t addrext; 4044 4045 slot = (int)(&(desc->dma.dma64) - descbase); 4046 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4047 ("%s:%d: fail", __func__, __LINE__)); 4048 4049 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4050 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4051 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4052 30; 4053 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 4054 if (slot == dr->dr_numslots - 1) 4055 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4056 if (start) 4057 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4058 if (end) 4059 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4060 if (irq) 4061 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4062 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4063 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4064 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4065 4066 desc->dma.dma64.control0 = htole32(ctl0); 4067 desc->dma.dma64.control1 = htole32(ctl1); 4068 desc->dma.dma64.address_low = htole32(addrlo); 4069 desc->dma.dma64.address_high = htole32(addrhi); 4070 } 4071 4072 static void 4073 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4074 { 4075 4076 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4077 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4078 } 4079 4080 static void 4081 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4082 { 4083 4084 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4085 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4086 } 4087 4088 static void 4089 bwn_dma_64_resume(struct bwn_dma_ring *dr) 4090 { 4091 4092 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4093 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4094 } 4095 4096 static int 4097 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4098 { 4099 uint32_t val; 4100 4101 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4102 val &= BWN_DMA64_RXSTATDPTR; 4103 4104 return (val / sizeof(struct bwn_dmadesc64)); 4105 } 4106 4107 static void 4108 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4109 { 4110 4111 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4112 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4113 } 4114 4115 static int 4116 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4117 { 4118 struct bwn_mac *mac = dr->dr_mac; 4119 struct bwn_dma *dma = &mac->mac_method.dma; 4120 struct bwn_softc *sc = mac->mac_sc; 4121 int error; 4122 4123 error = bus_dma_tag_create(dma->parent_dtag, 4124 BWN_ALIGN, 0, 4125 BUS_SPACE_MAXADDR, 4126 BUS_SPACE_MAXADDR, 4127 NULL, NULL, 4128 BWN_DMA_RINGMEMSIZE, 4129 1, 4130 BUS_SPACE_MAXSIZE_32BIT, 4131 0, 4132 NULL, NULL, 4133 &dr->dr_ring_dtag); 4134 if (error) { 4135 device_printf(sc->sc_dev, 4136 "can't create TX ring DMA tag: TODO frees\n"); 4137 return (-1); 4138 } 4139 4140 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4141 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4142 &dr->dr_ring_dmap); 4143 if (error) { 4144 device_printf(sc->sc_dev, 4145 "can't allocate DMA mem: TODO frees\n"); 4146 return (-1); 4147 } 4148 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4149 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4150 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4151 if (error) { 4152 device_printf(sc->sc_dev, 4153 "can't load DMA mem: TODO free\n"); 4154 return (-1); 4155 } 4156 4157 return (0); 4158 } 4159 4160 static void 4161 bwn_dma_setup(struct bwn_dma_ring *dr) 4162 { 4163 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4164 uint64_t ring64; 4165 uint32_t addrext, ring32, value; 4166 uint32_t trans = siba_dma_translation(sc->sc_dev); 4167 4168 if (dr->dr_tx) { 4169 dr->dr_curslot = -1; 4170 4171 if (dr->dr_type == BWN_DMA_64BIT) { 4172 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4173 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4174 >> 30; 4175 value = BWN_DMA64_TXENABLE; 4176 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4177 & BWN_DMA64_TXADDREXT_MASK; 4178 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4179 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4180 (ring64 & 0xffffffff)); 4181 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4182 ((ring64 >> 32) & 4183 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4184 } else { 4185 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4186 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4187 value = BWN_DMA32_TXENABLE; 4188 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4189 & BWN_DMA32_TXADDREXT_MASK; 4190 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4191 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4192 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4193 } 4194 return; 4195 } 4196 4197 /* 4198 * set for RX 4199 */ 4200 dr->dr_usedslot = dr->dr_numslots; 4201 4202 if (dr->dr_type == BWN_DMA_64BIT) { 4203 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4204 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4205 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4206 value |= BWN_DMA64_RXENABLE; 4207 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4208 & BWN_DMA64_RXADDREXT_MASK; 4209 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4210 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4211 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4212 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4213 | (trans << 1)); 4214 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4215 sizeof(struct bwn_dmadesc64)); 4216 } else { 4217 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4218 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4219 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4220 value |= BWN_DMA32_RXENABLE; 4221 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4222 & BWN_DMA32_RXADDREXT_MASK; 4223 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4224 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4225 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4226 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4227 sizeof(struct bwn_dmadesc32)); 4228 } 4229 } 4230 4231 static void 4232 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4233 { 4234 4235 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4236 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4237 dr->dr_ring_dmap); 4238 } 4239 4240 static void 4241 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4242 { 4243 4244 if (dr->dr_tx) { 4245 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4246 if (dr->dr_type == BWN_DMA_64BIT) { 4247 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4248 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4249 } else 4250 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4251 } else { 4252 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4253 if (dr->dr_type == BWN_DMA_64BIT) { 4254 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4255 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4256 } else 4257 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4258 } 4259 } 4260 4261 static void 4262 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4263 { 4264 struct bwn_dmadesc_generic *desc; 4265 struct bwn_dmadesc_meta *meta; 4266 struct bwn_mac *mac = dr->dr_mac; 4267 struct bwn_dma *dma = &mac->mac_method.dma; 4268 struct bwn_softc *sc = mac->mac_sc; 4269 int i; 4270 4271 if (!dr->dr_usedslot) 4272 return; 4273 for (i = 0; i < dr->dr_numslots; i++) { 4274 dr->getdesc(dr, i, &desc, &meta); 4275 4276 if (meta->mt_m == NULL) { 4277 if (!dr->dr_tx) 4278 device_printf(sc->sc_dev, "%s: not TX?\n", 4279 __func__); 4280 continue; 4281 } 4282 if (dr->dr_tx) { 4283 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4284 bus_dmamap_unload(dr->dr_txring_dtag, 4285 meta->mt_dmap); 4286 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4287 bus_dmamap_unload(dma->txbuf_dtag, 4288 meta->mt_dmap); 4289 } else 4290 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4291 bwn_dma_free_descbuf(dr, meta); 4292 } 4293 } 4294 4295 static int 4296 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4297 int type) 4298 { 4299 struct bwn_softc *sc = mac->mac_sc; 4300 uint32_t value; 4301 int i; 4302 uint16_t offset; 4303 4304 for (i = 0; i < 10; i++) { 4305 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4306 BWN_DMA32_TXSTATUS; 4307 value = BWN_READ_4(mac, base + offset); 4308 if (type == BWN_DMA_64BIT) { 4309 value &= BWN_DMA64_TXSTAT; 4310 if (value == BWN_DMA64_TXSTAT_DISABLED || 4311 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4312 value == BWN_DMA64_TXSTAT_STOPPED) 4313 break; 4314 } else { 4315 value &= BWN_DMA32_TXSTATE; 4316 if (value == BWN_DMA32_TXSTAT_DISABLED || 4317 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4318 value == BWN_DMA32_TXSTAT_STOPPED) 4319 break; 4320 } 4321 DELAY(1000); 4322 } 4323 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4324 BWN_WRITE_4(mac, base + offset, 0); 4325 for (i = 0; i < 10; i++) { 4326 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4327 BWN_DMA32_TXSTATUS; 4328 value = BWN_READ_4(mac, base + offset); 4329 if (type == BWN_DMA_64BIT) { 4330 value &= BWN_DMA64_TXSTAT; 4331 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4332 i = -1; 4333 break; 4334 } 4335 } else { 4336 value &= BWN_DMA32_TXSTATE; 4337 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4338 i = -1; 4339 break; 4340 } 4341 } 4342 DELAY(1000); 4343 } 4344 if (i != -1) { 4345 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4346 return (ENODEV); 4347 } 4348 DELAY(1000); 4349 4350 return (0); 4351 } 4352 4353 static int 4354 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4355 int type) 4356 { 4357 struct bwn_softc *sc = mac->mac_sc; 4358 uint32_t value; 4359 int i; 4360 uint16_t offset; 4361 4362 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4363 BWN_WRITE_4(mac, base + offset, 0); 4364 for (i = 0; i < 10; i++) { 4365 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4366 BWN_DMA32_RXSTATUS; 4367 value = BWN_READ_4(mac, base + offset); 4368 if (type == BWN_DMA_64BIT) { 4369 value &= BWN_DMA64_RXSTAT; 4370 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4371 i = -1; 4372 break; 4373 } 4374 } else { 4375 value &= BWN_DMA32_RXSTATE; 4376 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4377 i = -1; 4378 break; 4379 } 4380 } 4381 DELAY(1000); 4382 } 4383 if (i != -1) { 4384 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4385 return (ENODEV); 4386 } 4387 4388 return (0); 4389 } 4390 4391 static void 4392 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4393 struct bwn_dmadesc_meta *meta) 4394 { 4395 4396 if (meta->mt_m != NULL) { 4397 m_freem(meta->mt_m); 4398 meta->mt_m = NULL; 4399 } 4400 if (meta->mt_ni != NULL) { 4401 ieee80211_free_node(meta->mt_ni); 4402 meta->mt_ni = NULL; 4403 } 4404 } 4405 4406 static void 4407 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4408 { 4409 struct bwn_rxhdr4 *rxhdr; 4410 unsigned char *frame; 4411 4412 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4413 rxhdr->frame_len = 0; 4414 4415 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4416 sizeof(struct bwn_plcp6) + 2, 4417 ("%s:%d: fail", __func__, __LINE__)); 4418 frame = mtod(m, char *) + dr->dr_frameoffset; 4419 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4420 } 4421 4422 static uint8_t 4423 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4424 { 4425 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4426 4427 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4428 == 0xff); 4429 } 4430 4431 static void 4432 bwn_wme_init(struct bwn_mac *mac) 4433 { 4434 4435 bwn_wme_load(mac); 4436 4437 /* enable WME support. */ 4438 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4439 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4440 BWN_IFSCTL_USE_EDCF); 4441 } 4442 4443 static void 4444 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4445 { 4446 struct bwn_softc *sc = mac->mac_sc; 4447 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4448 uint16_t delay; /* microsec */ 4449 4450 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4451 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4452 delay = 500; 4453 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4454 delay = max(delay, (uint16_t)2400); 4455 4456 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4457 } 4458 4459 static void 4460 bwn_bt_enable(struct bwn_mac *mac) 4461 { 4462 struct bwn_softc *sc = mac->mac_sc; 4463 uint64_t hf; 4464 4465 if (bwn_bluetooth == 0) 4466 return; 4467 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4468 return; 4469 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4470 return; 4471 4472 hf = bwn_hf_read(mac); 4473 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4474 hf |= BWN_HF_BT_COEXISTALT; 4475 else 4476 hf |= BWN_HF_BT_COEXIST; 4477 bwn_hf_write(mac, hf); 4478 } 4479 4480 static void 4481 bwn_set_macaddr(struct bwn_mac *mac) 4482 { 4483 4484 bwn_mac_write_bssid(mac); 4485 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4486 } 4487 4488 static void 4489 bwn_clear_keys(struct bwn_mac *mac) 4490 { 4491 int i; 4492 4493 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4494 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4495 ("%s:%d: fail", __func__, __LINE__)); 4496 4497 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4498 NULL, BWN_SEC_KEYSIZE, NULL); 4499 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4500 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4501 NULL, BWN_SEC_KEYSIZE, NULL); 4502 } 4503 mac->mac_key[i].keyconf = NULL; 4504 } 4505 } 4506 4507 static void 4508 bwn_crypt_init(struct bwn_mac *mac) 4509 { 4510 struct bwn_softc *sc = mac->mac_sc; 4511 4512 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4513 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4514 ("%s:%d: fail", __func__, __LINE__)); 4515 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4516 mac->mac_ktp *= 2; 4517 if (siba_get_revid(sc->sc_dev) >= 5) 4518 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4519 bwn_clear_keys(mac); 4520 } 4521 4522 static void 4523 bwn_chip_exit(struct bwn_mac *mac) 4524 { 4525 struct bwn_softc *sc = mac->mac_sc; 4526 4527 bwn_phy_exit(mac); 4528 siba_gpio_set(sc->sc_dev, 0); 4529 } 4530 4531 static int 4532 bwn_fw_fillinfo(struct bwn_mac *mac) 4533 { 4534 int error; 4535 4536 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4537 if (error == 0) 4538 return (0); 4539 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4540 if (error == 0) 4541 return (0); 4542 return (error); 4543 } 4544 4545 static int 4546 bwn_gpio_init(struct bwn_mac *mac) 4547 { 4548 struct bwn_softc *sc = mac->mac_sc; 4549 uint32_t mask = 0x1f, set = 0xf, value; 4550 4551 BWN_WRITE_4(mac, BWN_MACCTL, 4552 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4553 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4554 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4555 4556 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4557 mask |= 0x0060; 4558 set |= 0x0060; 4559 } 4560 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4561 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4562 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4563 mask |= 0x0200; 4564 set |= 0x0200; 4565 } 4566 if (siba_get_revid(sc->sc_dev) >= 2) 4567 mask |= 0x0010; 4568 4569 value = siba_gpio_get(sc->sc_dev); 4570 if (value == -1) 4571 return (0); 4572 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4573 4574 return (0); 4575 } 4576 4577 static int 4578 bwn_fw_loadinitvals(struct bwn_mac *mac) 4579 { 4580 #define GETFWOFFSET(fwp, offset) \ 4581 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4582 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4583 const struct bwn_fwhdr *hdr; 4584 struct bwn_fw *fw = &mac->mac_fw; 4585 int error; 4586 4587 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4588 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4589 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4590 if (error) 4591 return (error); 4592 if (fw->initvals_band.fw) { 4593 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4594 error = bwn_fwinitvals_write(mac, 4595 GETFWOFFSET(fw->initvals_band, hdr_len), 4596 be32toh(hdr->size), 4597 fw->initvals_band.fw->datasize - hdr_len); 4598 } 4599 return (error); 4600 #undef GETFWOFFSET 4601 } 4602 4603 static int 4604 bwn_phy_init(struct bwn_mac *mac) 4605 { 4606 struct bwn_softc *sc = mac->mac_sc; 4607 int error; 4608 4609 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4610 mac->mac_phy.rf_onoff(mac, 1); 4611 error = mac->mac_phy.init(mac); 4612 if (error) { 4613 device_printf(sc->sc_dev, "PHY init failed\n"); 4614 goto fail0; 4615 } 4616 error = bwn_switch_channel(mac, 4617 mac->mac_phy.get_default_chan(mac)); 4618 if (error) { 4619 device_printf(sc->sc_dev, 4620 "failed to switch default channel\n"); 4621 goto fail1; 4622 } 4623 return (0); 4624 fail1: 4625 if (mac->mac_phy.exit) 4626 mac->mac_phy.exit(mac); 4627 fail0: 4628 mac->mac_phy.rf_onoff(mac, 0); 4629 4630 return (error); 4631 } 4632 4633 static void 4634 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4635 { 4636 uint16_t ant; 4637 uint16_t tmp; 4638 4639 ant = bwn_ant2phy(antenna); 4640 4641 /* For ACK/CTS */ 4642 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4643 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4644 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4645 /* For Probe Resposes */ 4646 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4647 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4648 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4649 } 4650 4651 static void 4652 bwn_set_opmode(struct bwn_mac *mac) 4653 { 4654 struct bwn_softc *sc = mac->mac_sc; 4655 struct ifnet *ifp = sc->sc_ifp; 4656 struct ieee80211com *ic = ifp->if_l2com; 4657 uint32_t ctl; 4658 uint16_t cfp_pretbtt; 4659 4660 ctl = BWN_READ_4(mac, BWN_MACCTL); 4661 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4662 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4663 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4664 ctl |= BWN_MACCTL_STA; 4665 4666 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4667 ic->ic_opmode == IEEE80211_M_MBSS) 4668 ctl |= BWN_MACCTL_HOSTAP; 4669 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4670 ctl &= ~BWN_MACCTL_STA; 4671 ctl |= sc->sc_filters; 4672 4673 if (siba_get_revid(sc->sc_dev) <= 4) 4674 ctl |= BWN_MACCTL_PROMISC; 4675 4676 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4677 4678 cfp_pretbtt = 2; 4679 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4680 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4681 siba_get_chiprev(sc->sc_dev) == 3) 4682 cfp_pretbtt = 100; 4683 else 4684 cfp_pretbtt = 50; 4685 } 4686 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4687 } 4688 4689 static int 4690 bwn_dma_gettype(struct bwn_mac *mac) 4691 { 4692 uint32_t tmp; 4693 uint16_t base; 4694 4695 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4696 if (tmp & SIBA_TGSHIGH_DMA64) 4697 return (BWN_DMA_64BIT); 4698 base = bwn_dma_base(0, 0); 4699 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4700 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4701 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4702 return (BWN_DMA_32BIT); 4703 4704 return (BWN_DMA_30BIT); 4705 } 4706 4707 static void 4708 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4709 { 4710 if (!error) { 4711 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4712 *((bus_addr_t *)arg) = seg->ds_addr; 4713 } 4714 } 4715 4716 static void 4717 bwn_phy_g_init_sub(struct bwn_mac *mac) 4718 { 4719 struct bwn_phy *phy = &mac->mac_phy; 4720 struct bwn_phy_g *pg = &phy->phy_g; 4721 struct bwn_softc *sc = mac->mac_sc; 4722 uint16_t i, tmp; 4723 4724 if (phy->rev == 1) 4725 bwn_phy_init_b5(mac); 4726 else 4727 bwn_phy_init_b6(mac); 4728 4729 if (phy->rev >= 2 || phy->gmode) 4730 bwn_phy_init_a(mac); 4731 4732 if (phy->rev >= 2) { 4733 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4734 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4735 } 4736 if (phy->rev == 2) { 4737 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4738 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4739 } 4740 if (phy->rev > 5) { 4741 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4742 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4743 } 4744 if (phy->gmode || phy->rev >= 2) { 4745 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4746 tmp &= BWN_PHYVER_VERSION; 4747 if (tmp == 3 || tmp == 5) { 4748 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4749 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4750 } 4751 if (tmp == 5) { 4752 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4753 0x1f00); 4754 } 4755 } 4756 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4757 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4758 if (phy->rf_rev == 8) { 4759 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4760 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4761 } 4762 if (BWN_HAS_LOOPBACK(phy)) 4763 bwn_loopback_calcgain(mac); 4764 4765 if (phy->rf_rev != 8) { 4766 if (pg->pg_initval == 0xffff) 4767 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4768 else 4769 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4770 } 4771 bwn_lo_g_init(mac); 4772 if (BWN_HAS_TXMAG(phy)) { 4773 BWN_RF_WRITE(mac, 0x52, 4774 (BWN_RF_READ(mac, 0x52) & 0xff00) 4775 | pg->pg_loctl.tx_bias | 4776 pg->pg_loctl.tx_magn); 4777 } else { 4778 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4779 } 4780 if (phy->rev >= 6) { 4781 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4782 (pg->pg_loctl.tx_bias << 12)); 4783 } 4784 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4785 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4786 else 4787 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4788 if (phy->rev < 2) 4789 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4790 else 4791 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4792 if (phy->gmode || phy->rev >= 2) { 4793 bwn_lo_g_adjust(mac); 4794 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4795 } 4796 4797 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4798 for (i = 0; i < 64; i++) { 4799 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4800 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4801 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4802 -32), 31)); 4803 } 4804 bwn_nrssi_threshold(mac); 4805 } else if (phy->gmode || phy->rev >= 2) { 4806 if (pg->pg_nrssi[0] == -1000) { 4807 KASSERT(pg->pg_nrssi[1] == -1000, 4808 ("%s:%d: fail", __func__, __LINE__)); 4809 bwn_nrssi_slope_11g(mac); 4810 } else 4811 bwn_nrssi_threshold(mac); 4812 } 4813 if (phy->rf_rev == 8) 4814 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4815 bwn_phy_hwpctl_init(mac); 4816 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4817 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4818 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4819 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4820 } 4821 } 4822 4823 static uint8_t 4824 bwn_has_hwpctl(struct bwn_mac *mac) 4825 { 4826 4827 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4828 return (0); 4829 return (mac->mac_phy.use_hwpctl(mac)); 4830 } 4831 4832 static void 4833 bwn_phy_init_b5(struct bwn_mac *mac) 4834 { 4835 struct bwn_phy *phy = &mac->mac_phy; 4836 struct bwn_phy_g *pg = &phy->phy_g; 4837 struct bwn_softc *sc = mac->mac_sc; 4838 uint16_t offset, value; 4839 uint8_t old_channel; 4840 4841 if (phy->analog == 1) 4842 BWN_RF_SET(mac, 0x007a, 0x0050); 4843 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4844 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4845 value = 0x2120; 4846 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4847 BWN_PHY_WRITE(mac, offset, value); 4848 value += 0x202; 4849 } 4850 } 4851 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4852 if (phy->rf_ver == 0x2050) 4853 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4854 4855 if (phy->gmode || phy->rev >= 2) { 4856 if (phy->rf_ver == 0x2050) { 4857 BWN_RF_SET(mac, 0x007a, 0x0020); 4858 BWN_RF_SET(mac, 0x0051, 0x0004); 4859 } 4860 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4861 4862 BWN_PHY_SET(mac, 0x0802, 0x0100); 4863 BWN_PHY_SET(mac, 0x042b, 0x2000); 4864 4865 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4866 4867 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4868 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4869 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4870 } 4871 4872 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4873 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4874 4875 if (phy->analog == 1) { 4876 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4877 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4878 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4879 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4880 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4881 } else 4882 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4883 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4884 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4885 4886 if (phy->analog == 1) 4887 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4888 else 4889 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4890 4891 if (phy->analog == 0) 4892 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4893 4894 old_channel = phy->chan; 4895 bwn_phy_g_switch_chan(mac, 7, 0); 4896 4897 if (phy->rf_ver != 0x2050) { 4898 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4899 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4900 } 4901 4902 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4903 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4904 4905 if (phy->rf_ver == 0x2050) { 4906 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4907 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4908 } 4909 4910 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4911 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4912 BWN_RF_SET(mac, 0x007a, 0x0007); 4913 4914 bwn_phy_g_switch_chan(mac, old_channel, 0); 4915 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4916 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4917 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4918 4919 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4920 pg->pg_txctl); 4921 4922 if (phy->rf_ver == 0x2050) 4923 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4924 4925 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4926 } 4927 4928 static void 4929 bwn_loopback_calcgain(struct bwn_mac *mac) 4930 { 4931 struct bwn_phy *phy = &mac->mac_phy; 4932 struct bwn_phy_g *pg = &phy->phy_g; 4933 struct bwn_softc *sc = mac->mac_sc; 4934 uint16_t backup_phy[16] = { 0 }; 4935 uint16_t backup_radio[3]; 4936 uint16_t backup_bband; 4937 uint16_t i, j, loop_i_max; 4938 uint16_t trsw_rx; 4939 uint16_t loop1_outer_done, loop1_inner_done; 4940 4941 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4942 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4943 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4944 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4945 if (phy->rev != 1) { 4946 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4947 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4948 } 4949 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4950 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4951 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4952 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4953 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4954 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4955 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4956 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4957 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4958 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4959 backup_bband = pg->pg_bbatt.att; 4960 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4961 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4962 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4963 4964 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4965 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4966 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4967 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4968 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4969 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4970 if (phy->rev != 1) { 4971 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4972 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4973 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4974 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4975 } 4976 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4977 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4978 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4979 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4980 4981 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4982 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4983 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4984 4985 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4986 if (phy->rev != 1) { 4987 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4988 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4989 } 4990 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4991 4992 if (phy->rf_rev == 8) 4993 BWN_RF_WRITE(mac, 0x43, 0x000f); 4994 else { 4995 BWN_RF_WRITE(mac, 0x52, 0); 4996 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4997 } 4998 bwn_phy_g_set_bbatt(mac, 11); 4999 5000 if (phy->rev >= 3) 5001 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5002 else 5003 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5004 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5005 5006 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5007 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5008 5009 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5010 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5011 5012 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 5013 if (phy->rev >= 7) { 5014 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5015 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5016 } 5017 } 5018 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5019 5020 j = 0; 5021 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5022 for (i = 0; i < loop_i_max; i++) { 5023 for (j = 0; j < 16; j++) { 5024 BWN_RF_WRITE(mac, 0x43, i); 5025 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5026 (j << 8)); 5027 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5028 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5029 DELAY(20); 5030 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5031 goto done0; 5032 } 5033 } 5034 done0: 5035 loop1_outer_done = i; 5036 loop1_inner_done = j; 5037 if (j >= 8) { 5038 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5039 trsw_rx = 0x1b; 5040 for (j = j - 8; j < 16; j++) { 5041 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5042 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5043 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5044 DELAY(20); 5045 trsw_rx -= 3; 5046 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5047 goto done1; 5048 } 5049 } else 5050 trsw_rx = 0x18; 5051 done1: 5052 5053 if (phy->rev != 1) { 5054 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5055 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5056 } 5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5059 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5060 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5061 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5062 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5063 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5064 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5065 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5066 5067 bwn_phy_g_set_bbatt(mac, backup_bband); 5068 5069 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5070 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5071 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5072 5073 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5074 DELAY(10); 5075 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5076 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5077 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5078 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5079 5080 pg->pg_max_lb_gain = 5081 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5082 pg->pg_trsw_rx_gain = trsw_rx * 2; 5083 } 5084 5085 static uint16_t 5086 bwn_rf_init_bcm2050(struct bwn_mac *mac) 5087 { 5088 struct bwn_phy *phy = &mac->mac_phy; 5089 uint32_t tmp1 = 0, tmp2 = 0; 5090 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5091 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5092 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5093 static const uint8_t rcc_table[] = { 5094 0x02, 0x03, 0x01, 0x0f, 5095 0x06, 0x07, 0x05, 0x0f, 5096 0x0a, 0x0b, 0x09, 0x0f, 5097 0x0e, 0x0f, 0x0d, 0x0f, 5098 }; 5099 5100 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5101 rfoverval = rfover = cck3 = 0; 5102 radio0 = BWN_RF_READ(mac, 0x43); 5103 radio1 = BWN_RF_READ(mac, 0x51); 5104 radio2 = BWN_RF_READ(mac, 0x52); 5105 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5106 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5107 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5108 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5109 5110 if (phy->type == BWN_PHYTYPE_B) { 5111 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5112 reg0 = BWN_READ_2(mac, 0x3ec); 5113 5114 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5115 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5116 } else if (phy->gmode || phy->rev >= 2) { 5117 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5118 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5119 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5120 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5121 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5122 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5123 5124 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5125 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5126 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5127 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5128 if (BWN_HAS_LOOPBACK(phy)) { 5129 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5130 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5131 if (phy->rev >= 3) 5132 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5133 else 5134 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5135 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5136 } 5137 5138 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5139 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5140 BWN_LPD(0, 1, 1))); 5141 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5142 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5143 } 5144 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5145 5146 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5147 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5148 reg1 = BWN_READ_2(mac, 0x3e6); 5149 reg2 = BWN_READ_2(mac, 0x3f4); 5150 5151 if (phy->analog == 0) 5152 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5153 else { 5154 if (phy->analog >= 2) 5155 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5156 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5157 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5158 } 5159 5160 reg = BWN_RF_READ(mac, 0x60); 5161 index = (reg & 0x001e) >> 1; 5162 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5163 5164 if (phy->type == BWN_PHYTYPE_B) 5165 BWN_RF_WRITE(mac, 0x78, 0x26); 5166 if (phy->gmode || phy->rev >= 2) { 5167 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5168 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5169 BWN_LPD(0, 1, 1))); 5170 } 5171 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5172 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5173 if (phy->gmode || phy->rev >= 2) { 5174 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5175 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5176 BWN_LPD(0, 0, 1))); 5177 } 5178 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5179 BWN_RF_SET(mac, 0x51, 0x0004); 5180 if (phy->rf_rev == 8) 5181 BWN_RF_WRITE(mac, 0x43, 0x1f); 5182 else { 5183 BWN_RF_WRITE(mac, 0x52, 0); 5184 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5185 } 5186 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5187 5188 for (i = 0; i < 16; i++) { 5189 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5190 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5191 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5192 if (phy->gmode || phy->rev >= 2) { 5193 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5194 bwn_rf_2050_rfoverval(mac, 5195 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5196 } 5197 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5198 DELAY(10); 5199 if (phy->gmode || phy->rev >= 2) { 5200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5201 bwn_rf_2050_rfoverval(mac, 5202 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5203 } 5204 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5205 DELAY(10); 5206 if (phy->gmode || phy->rev >= 2) { 5207 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5208 bwn_rf_2050_rfoverval(mac, 5209 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5210 } 5211 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5212 DELAY(20); 5213 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5214 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5215 if (phy->gmode || phy->rev >= 2) { 5216 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5217 bwn_rf_2050_rfoverval(mac, 5218 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5219 } 5220 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5221 } 5222 DELAY(10); 5223 5224 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5225 tmp1++; 5226 tmp1 >>= 9; 5227 5228 for (i = 0; i < 16; i++) { 5229 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5230 BWN_RF_WRITE(mac, 0x78, radio78); 5231 DELAY(10); 5232 for (j = 0; j < 16; j++) { 5233 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5234 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5235 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5236 if (phy->gmode || phy->rev >= 2) { 5237 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5238 bwn_rf_2050_rfoverval(mac, 5239 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5240 } 5241 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5242 DELAY(10); 5243 if (phy->gmode || phy->rev >= 2) { 5244 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5245 bwn_rf_2050_rfoverval(mac, 5246 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5247 } 5248 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5249 DELAY(10); 5250 if (phy->gmode || phy->rev >= 2) { 5251 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5252 bwn_rf_2050_rfoverval(mac, 5253 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5254 } 5255 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5256 DELAY(10); 5257 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5258 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5259 if (phy->gmode || phy->rev >= 2) { 5260 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5261 bwn_rf_2050_rfoverval(mac, 5262 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5263 } 5264 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5265 } 5266 tmp2++; 5267 tmp2 >>= 8; 5268 if (tmp1 < tmp2) 5269 break; 5270 } 5271 5272 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5273 BWN_RF_WRITE(mac, 0x51, radio1); 5274 BWN_RF_WRITE(mac, 0x52, radio2); 5275 BWN_RF_WRITE(mac, 0x43, radio0); 5276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5277 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5278 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5279 BWN_WRITE_2(mac, 0x3e6, reg1); 5280 if (phy->analog != 0) 5281 BWN_WRITE_2(mac, 0x3f4, reg2); 5282 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5283 bwn_spu_workaround(mac, phy->chan); 5284 if (phy->type == BWN_PHYTYPE_B) { 5285 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5286 BWN_WRITE_2(mac, 0x3ec, reg0); 5287 } else if (phy->gmode) { 5288 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5289 BWN_READ_2(mac, BWN_PHY_RADIO) 5290 & 0x7fff); 5291 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5292 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5293 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5294 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5295 analogoverval); 5296 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5297 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5298 if (BWN_HAS_LOOPBACK(phy)) { 5299 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5300 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5301 } 5302 } 5303 5304 return ((i > 15) ? radio78 : rcc); 5305 } 5306 5307 static void 5308 bwn_phy_init_b6(struct bwn_mac *mac) 5309 { 5310 struct bwn_phy *phy = &mac->mac_phy; 5311 struct bwn_phy_g *pg = &phy->phy_g; 5312 struct bwn_softc *sc = mac->mac_sc; 5313 uint16_t offset, val; 5314 uint8_t old_channel; 5315 5316 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5317 ("%s:%d: fail", __func__, __LINE__)); 5318 5319 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5320 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5321 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5322 BWN_RF_WRITE(mac, 0x51, 0x37); 5323 BWN_RF_WRITE(mac, 0x52, 0x70); 5324 BWN_RF_WRITE(mac, 0x53, 0xb3); 5325 BWN_RF_WRITE(mac, 0x54, 0x9b); 5326 BWN_RF_WRITE(mac, 0x5a, 0x88); 5327 BWN_RF_WRITE(mac, 0x5b, 0x88); 5328 BWN_RF_WRITE(mac, 0x5d, 0x88); 5329 BWN_RF_WRITE(mac, 0x5e, 0x88); 5330 BWN_RF_WRITE(mac, 0x7d, 0x88); 5331 bwn_hf_write(mac, 5332 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5333 } 5334 if (phy->rf_rev == 8) { 5335 BWN_RF_WRITE(mac, 0x51, 0); 5336 BWN_RF_WRITE(mac, 0x52, 0x40); 5337 BWN_RF_WRITE(mac, 0x53, 0xb7); 5338 BWN_RF_WRITE(mac, 0x54, 0x98); 5339 BWN_RF_WRITE(mac, 0x5a, 0x88); 5340 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5341 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5342 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5343 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5344 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5345 } else { 5346 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5347 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5348 } 5349 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5350 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5351 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5352 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5353 } 5354 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5355 BWN_PHY_WRITE(mac, offset, val); 5356 val -= 0x0202; 5357 } 5358 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5359 BWN_PHY_WRITE(mac, offset, val); 5360 val -= 0x0202; 5361 } 5362 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5363 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5364 val += 0x0202; 5365 } 5366 if (phy->type == BWN_PHYTYPE_G) { 5367 BWN_RF_SET(mac, 0x007a, 0x0020); 5368 BWN_RF_SET(mac, 0x0051, 0x0004); 5369 BWN_PHY_SET(mac, 0x0802, 0x0100); 5370 BWN_PHY_SET(mac, 0x042b, 0x2000); 5371 BWN_PHY_WRITE(mac, 0x5b, 0); 5372 BWN_PHY_WRITE(mac, 0x5c, 0); 5373 } 5374 5375 old_channel = phy->chan; 5376 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5377 5378 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5379 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5380 DELAY(40); 5381 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5382 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5383 BWN_RF_WRITE(mac, 0x50, 0x20); 5384 } 5385 if (phy->rf_rev <= 2) { 5386 BWN_RF_WRITE(mac, 0x7c, 0x20); 5387 BWN_RF_WRITE(mac, 0x5a, 0x70); 5388 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5389 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5390 } 5391 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5392 5393 bwn_phy_g_switch_chan(mac, old_channel, 0); 5394 5395 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5396 if (phy->rf_rev >= 6) 5397 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5398 else 5399 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5400 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5401 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5402 pg->pg_txctl); 5403 if (phy->rf_rev <= 5) 5404 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5405 if (phy->rf_rev <= 2) 5406 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5407 5408 if (phy->analog == 4) { 5409 BWN_WRITE_2(mac, 0x3e4, 9); 5410 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5411 } else 5412 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5413 if (phy->type == BWN_PHYTYPE_B) 5414 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5415 else if (phy->type == BWN_PHYTYPE_G) 5416 BWN_WRITE_2(mac, 0x03e6, 0x0); 5417 } 5418 5419 static void 5420 bwn_phy_init_a(struct bwn_mac *mac) 5421 { 5422 struct bwn_phy *phy = &mac->mac_phy; 5423 struct bwn_softc *sc = mac->mac_sc; 5424 5425 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5426 ("%s:%d: fail", __func__, __LINE__)); 5427 5428 if (phy->rev >= 6) { 5429 if (phy->type == BWN_PHYTYPE_A) 5430 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5431 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5432 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5433 else 5434 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5435 } 5436 5437 bwn_wa_init(mac); 5438 5439 if (phy->type == BWN_PHYTYPE_G && 5440 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5441 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5442 } 5443 5444 static void 5445 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5446 { 5447 int i; 5448 5449 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5450 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5451 } 5452 5453 static void 5454 bwn_wa_agc(struct bwn_mac *mac) 5455 { 5456 struct bwn_phy *phy = &mac->mac_phy; 5457 5458 if (phy->rev == 1) { 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5464 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5467 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5468 } else { 5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5470 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5471 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5472 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5473 } 5474 5475 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5476 0x5700); 5477 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5478 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5479 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5480 BWN_RF_SET(mac, 0x7a, 0x0008); 5481 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5482 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5483 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5484 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5485 if (phy->rev == 1) 5486 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5494 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5495 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5496 if (phy->rev == 1) { 5497 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5498 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5499 } else { 5500 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5501 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5502 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5503 if (phy->rev >= 6) { 5504 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5505 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5506 (uint16_t)~0xf000, 0x3000); 5507 } 5508 } 5509 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5510 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5511 if (phy->rev == 1) { 5512 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5513 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5514 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5515 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5520 } else { 5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5522 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5523 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5524 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5525 } 5526 if (phy->rev >= 6) { 5527 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5528 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5529 } 5530 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5531 } 5532 5533 static void 5534 bwn_wa_grev1(struct bwn_mac *mac) 5535 { 5536 struct bwn_phy *phy = &mac->mac_phy; 5537 int i; 5538 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5539 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5540 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5541 5542 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5543 5544 /* init CRSTHRES and ANTDWELL */ 5545 if (phy->rev == 1) { 5546 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5547 } else if (phy->rev == 2) { 5548 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5549 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5550 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5551 } else { 5552 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5553 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5554 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5555 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5556 } 5557 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5558 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5559 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5560 5561 /* XXX support PHY-A??? */ 5562 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5563 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5564 bwn_tab_finefreqg[i]); 5565 5566 /* XXX support PHY-A??? */ 5567 if (phy->rev == 1) 5568 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5569 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5570 bwn_tab_noise_g1[i]); 5571 else 5572 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5573 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5574 bwn_tab_noise_g2[i]); 5575 5576 5577 for (i = 0; i < N(bwn_tab_rotor); i++) 5578 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5579 bwn_tab_rotor[i]); 5580 5581 /* XXX support PHY-A??? */ 5582 if (phy->rev >= 6) { 5583 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5584 BWN_PHY_ENCORE_EN) 5585 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5586 else 5587 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5588 } else 5589 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5590 5591 for (i = 0; i < N(bwn_tab_retard); i++) 5592 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5593 bwn_tab_retard[i]); 5594 5595 if (phy->rev == 1) { 5596 for (i = 0; i < 16; i++) 5597 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5598 i, 0x0020); 5599 } else { 5600 for (i = 0; i < 32; i++) 5601 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5602 } 5603 5604 bwn_wa_agc(mac); 5605 } 5606 5607 static void 5608 bwn_wa_grev26789(struct bwn_mac *mac) 5609 { 5610 struct bwn_phy *phy = &mac->mac_phy; 5611 int i; 5612 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5613 uint16_t ofdmrev; 5614 5615 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5616 5617 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5618 5619 /* init CRSTHRES and ANTDWELL */ 5620 if (phy->rev == 1) 5621 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5622 else if (phy->rev == 2) { 5623 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5624 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5625 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5626 } else { 5627 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5628 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5629 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5630 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5631 } 5632 5633 for (i = 0; i < 64; i++) 5634 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5635 5636 /* XXX support PHY-A??? */ 5637 if (phy->rev == 1) 5638 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5639 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5640 bwn_tab_noise_g1[i]); 5641 else 5642 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5643 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5644 bwn_tab_noise_g2[i]); 5645 5646 /* XXX support PHY-A??? */ 5647 if (phy->rev >= 6) { 5648 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5649 BWN_PHY_ENCORE_EN) 5650 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5651 else 5652 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5653 } else 5654 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5655 5656 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5657 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5658 bwn_tab_sigmasqr2[i]); 5659 5660 if (phy->rev == 1) { 5661 for (i = 0; i < 16; i++) 5662 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5663 0x0020); 5664 } else { 5665 for (i = 0; i < 32; i++) 5666 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5667 } 5668 5669 bwn_wa_agc(mac); 5670 5671 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5672 if (ofdmrev > 2) { 5673 if (phy->type == BWN_PHYTYPE_A) 5674 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5675 else 5676 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5677 } else { 5678 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5679 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5680 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5681 } 5682 5683 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5684 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5685 } 5686 5687 static void 5688 bwn_wa_init(struct bwn_mac *mac) 5689 { 5690 struct bwn_phy *phy = &mac->mac_phy; 5691 struct bwn_softc *sc = mac->mac_sc; 5692 5693 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5694 5695 switch (phy->rev) { 5696 case 1: 5697 bwn_wa_grev1(mac); 5698 break; 5699 case 2: 5700 case 6: 5701 case 7: 5702 case 8: 5703 case 9: 5704 bwn_wa_grev26789(mac); 5705 break; 5706 default: 5707 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5708 } 5709 5710 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5711 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5712 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5713 if (phy->rev < 2) { 5714 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5715 0x0002); 5716 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5717 0x0001); 5718 } else { 5719 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5720 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5721 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5722 BWN_BFL_EXTLNA) && 5723 (phy->rev >= 7)) { 5724 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5725 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5726 0x0020, 0x0001); 5727 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5728 0x0021, 0x0001); 5729 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5730 0x0022, 0x0001); 5731 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5732 0x0023, 0x0000); 5733 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5734 0x0000, 0x0000); 5735 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5736 0x0003, 0x0002); 5737 } 5738 } 5739 } 5740 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5741 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5742 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5743 } 5744 5745 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5746 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5747 } 5748 5749 static void 5750 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5751 uint16_t value) 5752 { 5753 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5754 uint16_t addr; 5755 5756 addr = table + offset; 5757 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5758 (addr - 1 != pg->pg_ofdmtab_addr)) { 5759 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5760 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5761 } 5762 pg->pg_ofdmtab_addr = addr; 5763 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5764 } 5765 5766 static void 5767 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5768 uint32_t value) 5769 { 5770 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5771 uint16_t addr; 5772 5773 addr = table + offset; 5774 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5775 (addr - 1 != pg->pg_ofdmtab_addr)) { 5776 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5777 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5778 } 5779 pg->pg_ofdmtab_addr = addr; 5780 5781 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5782 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5783 } 5784 5785 static void 5786 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5787 uint16_t value) 5788 { 5789 5790 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5791 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5792 } 5793 5794 static void 5795 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5796 { 5797 struct bwn_phy *phy = &mac->mac_phy; 5798 struct bwn_softc *sc = mac->mac_sc; 5799 unsigned int i, max_loop; 5800 uint16_t value; 5801 uint32_t buffer[5] = { 5802 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5803 }; 5804 5805 if (ofdm) { 5806 max_loop = 0x1e; 5807 buffer[0] = 0x000201cc; 5808 } else { 5809 max_loop = 0xfa; 5810 buffer[0] = 0x000b846e; 5811 } 5812 5813 BWN_ASSERT_LOCKED(mac->mac_sc); 5814 5815 for (i = 0; i < 5; i++) 5816 bwn_ram_write(mac, i * 4, buffer[i]); 5817 5818 BWN_WRITE_2(mac, 0x0568, 0x0000); 5819 BWN_WRITE_2(mac, 0x07c0, 5820 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5821 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5822 BWN_WRITE_2(mac, 0x050c, value); 5823 if (phy->type == BWN_PHYTYPE_LP) 5824 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5825 BWN_WRITE_2(mac, 0x0508, 0x0000); 5826 BWN_WRITE_2(mac, 0x050a, 0x0000); 5827 BWN_WRITE_2(mac, 0x054c, 0x0000); 5828 BWN_WRITE_2(mac, 0x056a, 0x0014); 5829 BWN_WRITE_2(mac, 0x0568, 0x0826); 5830 BWN_WRITE_2(mac, 0x0500, 0x0000); 5831 if (phy->type == BWN_PHYTYPE_LP) 5832 BWN_WRITE_2(mac, 0x0502, 0x0050); 5833 else 5834 BWN_WRITE_2(mac, 0x0502, 0x0030); 5835 5836 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5837 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5838 for (i = 0x00; i < max_loop; i++) { 5839 value = BWN_READ_2(mac, 0x050e); 5840 if (value & 0x0080) 5841 break; 5842 DELAY(10); 5843 } 5844 for (i = 0x00; i < 0x0a; i++) { 5845 value = BWN_READ_2(mac, 0x050e); 5846 if (value & 0x0400) 5847 break; 5848 DELAY(10); 5849 } 5850 for (i = 0x00; i < 0x19; i++) { 5851 value = BWN_READ_2(mac, 0x0690); 5852 if (!(value & 0x0100)) 5853 break; 5854 DELAY(10); 5855 } 5856 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5857 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5858 } 5859 5860 static void 5861 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5862 { 5863 uint32_t macctl; 5864 5865 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5866 5867 macctl = BWN_READ_4(mac, BWN_MACCTL); 5868 if (macctl & BWN_MACCTL_BIGENDIAN) 5869 printf("TODO: need swap\n"); 5870 5871 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5872 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5873 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5874 } 5875 5876 static void 5877 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5878 { 5879 uint16_t value; 5880 5881 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5882 ("%s:%d: fail", __func__, __LINE__)); 5883 5884 value = (uint8_t) (ctl->q); 5885 value |= ((uint8_t) (ctl->i)) << 8; 5886 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5887 } 5888 5889 static uint16_t 5890 bwn_lo_calcfeed(struct bwn_mac *mac, 5891 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5892 { 5893 struct bwn_phy *phy = &mac->mac_phy; 5894 struct bwn_softc *sc = mac->mac_sc; 5895 uint16_t rfover; 5896 uint16_t feedthrough; 5897 5898 if (phy->gmode) { 5899 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5900 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5901 5902 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5903 ("%s:%d: fail", __func__, __LINE__)); 5904 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5905 ("%s:%d: fail", __func__, __LINE__)); 5906 5907 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5908 5909 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5910 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5911 phy->rev > 6) 5912 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5913 5914 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5915 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5916 DELAY(10); 5917 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5918 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5919 DELAY(10); 5920 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5921 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5922 DELAY(10); 5923 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5924 } else { 5925 pga |= BWN_PHY_PGACTL_UNKNOWN; 5926 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5927 DELAY(10); 5928 pga |= BWN_PHY_PGACTL_LOWBANDW; 5929 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5930 DELAY(10); 5931 pga |= BWN_PHY_PGACTL_LPF; 5932 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5933 } 5934 DELAY(21); 5935 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5936 5937 return (feedthrough); 5938 } 5939 5940 static uint16_t 5941 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5942 uint16_t *value, uint16_t *pad_mix_gain) 5943 { 5944 struct bwn_phy *phy = &mac->mac_phy; 5945 uint16_t reg, v, padmix; 5946 5947 if (phy->type == BWN_PHYTYPE_B) { 5948 v = 0x30; 5949 if (phy->rf_rev <= 5) { 5950 reg = 0x43; 5951 padmix = 0; 5952 } else { 5953 reg = 0x52; 5954 padmix = 5; 5955 } 5956 } else { 5957 if (phy->rev >= 2 && phy->rf_rev == 8) { 5958 reg = 0x43; 5959 v = 0x10; 5960 padmix = 2; 5961 } else { 5962 reg = 0x52; 5963 v = 0x30; 5964 padmix = 5; 5965 } 5966 } 5967 if (value) 5968 *value = v; 5969 if (pad_mix_gain) 5970 *pad_mix_gain = padmix; 5971 5972 return (reg); 5973 } 5974 5975 static void 5976 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5977 { 5978 struct bwn_phy *phy = &mac->mac_phy; 5979 struct bwn_phy_g *pg = &phy->phy_g; 5980 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5981 uint16_t reg, mask; 5982 uint16_t trsw_rx, pga; 5983 uint16_t rf_pctl_reg; 5984 5985 static const uint8_t tx_bias_values[] = { 5986 0x09, 0x08, 0x0a, 0x01, 0x00, 5987 0x02, 0x05, 0x04, 0x06, 5988 }; 5989 static const uint8_t tx_magn_values[] = { 5990 0x70, 0x40, 5991 }; 5992 5993 if (!BWN_HAS_LOOPBACK(phy)) { 5994 rf_pctl_reg = 6; 5995 trsw_rx = 2; 5996 pga = 0; 5997 } else { 5998 int lb_gain; 5999 6000 trsw_rx = 0; 6001 lb_gain = pg->pg_max_lb_gain / 2; 6002 if (lb_gain > 10) { 6003 rf_pctl_reg = 0; 6004 pga = abs(10 - lb_gain) / 6; 6005 pga = MIN(MAX(pga, 0), 15); 6006 } else { 6007 int cmp_val; 6008 int tmp; 6009 6010 pga = 0; 6011 cmp_val = 0x24; 6012 if ((phy->rev >= 2) && 6013 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6014 cmp_val = 0x3c; 6015 tmp = lb_gain; 6016 if ((10 - lb_gain) < cmp_val) 6017 tmp = (10 - lb_gain); 6018 if (tmp < 0) 6019 tmp += 6; 6020 else 6021 tmp += 3; 6022 cmp_val /= 4; 6023 tmp /= 4; 6024 if (tmp >= cmp_val) 6025 rf_pctl_reg = cmp_val; 6026 else 6027 rf_pctl_reg = tmp; 6028 } 6029 } 6030 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6031 bwn_phy_g_set_bbatt(mac, 2); 6032 6033 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6034 mask = ~mask; 6035 BWN_RF_MASK(mac, reg, mask); 6036 6037 if (BWN_HAS_TXMAG(phy)) { 6038 int i, j; 6039 int feedthrough; 6040 int min_feedth = 0xffff; 6041 uint8_t tx_magn, tx_bias; 6042 6043 for (i = 0; i < N(tx_magn_values); i++) { 6044 tx_magn = tx_magn_values[i]; 6045 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6046 for (j = 0; j < N(tx_bias_values); j++) { 6047 tx_bias = tx_bias_values[j]; 6048 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6049 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6050 trsw_rx); 6051 if (feedthrough < min_feedth) { 6052 lo->tx_bias = tx_bias; 6053 lo->tx_magn = tx_magn; 6054 min_feedth = feedthrough; 6055 } 6056 if (lo->tx_bias == 0) 6057 break; 6058 } 6059 BWN_RF_WRITE(mac, 0x52, 6060 (BWN_RF_READ(mac, 0x52) 6061 & 0xff00) | lo->tx_bias | lo-> 6062 tx_magn); 6063 } 6064 } else { 6065 lo->tx_magn = 0; 6066 lo->tx_bias = 0; 6067 BWN_RF_MASK(mac, 0x52, 0xfff0); 6068 } 6069 6070 BWN_GETTIME(lo->txctl_measured_time); 6071 } 6072 6073 static void 6074 bwn_lo_get_powervector(struct bwn_mac *mac) 6075 { 6076 struct bwn_phy *phy = &mac->mac_phy; 6077 struct bwn_phy_g *pg = &phy->phy_g; 6078 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6079 int i; 6080 uint64_t tmp; 6081 uint64_t power_vector = 0; 6082 6083 for (i = 0; i < 8; i += 2) { 6084 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6085 power_vector |= (tmp << (i * 8)); 6086 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6087 } 6088 if (power_vector) 6089 lo->power_vector = power_vector; 6090 6091 BWN_GETTIME(lo->pwr_vec_read_time); 6092 } 6093 6094 static void 6095 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6096 int use_trsw_rx) 6097 { 6098 struct bwn_phy *phy = &mac->mac_phy; 6099 struct bwn_phy_g *pg = &phy->phy_g; 6100 uint16_t tmp; 6101 6102 if (max_rx_gain < 0) 6103 max_rx_gain = 0; 6104 6105 if (BWN_HAS_LOOPBACK(phy)) { 6106 int trsw_rx = 0; 6107 int trsw_rx_gain; 6108 6109 if (use_trsw_rx) { 6110 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6111 if (max_rx_gain >= trsw_rx_gain) { 6112 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6113 trsw_rx = 0x20; 6114 } 6115 } else 6116 trsw_rx_gain = max_rx_gain; 6117 if (trsw_rx_gain < 9) { 6118 pg->pg_lna_lod_gain = 0; 6119 } else { 6120 pg->pg_lna_lod_gain = 1; 6121 trsw_rx_gain -= 8; 6122 } 6123 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6124 pg->pg_pga_gain = trsw_rx_gain / 3; 6125 if (pg->pg_pga_gain >= 5) { 6126 pg->pg_pga_gain -= 5; 6127 pg->pg_lna_gain = 2; 6128 } else 6129 pg->pg_lna_gain = 0; 6130 } else { 6131 pg->pg_lna_gain = 0; 6132 pg->pg_trsw_rx_gain = 0x20; 6133 if (max_rx_gain >= 0x14) { 6134 pg->pg_lna_lod_gain = 1; 6135 pg->pg_pga_gain = 2; 6136 } else if (max_rx_gain >= 0x12) { 6137 pg->pg_lna_lod_gain = 1; 6138 pg->pg_pga_gain = 1; 6139 } else if (max_rx_gain >= 0xf) { 6140 pg->pg_lna_lod_gain = 1; 6141 pg->pg_pga_gain = 0; 6142 } else { 6143 pg->pg_lna_lod_gain = 0; 6144 pg->pg_pga_gain = 0; 6145 } 6146 } 6147 6148 tmp = BWN_RF_READ(mac, 0x7a); 6149 if (pg->pg_lna_lod_gain == 0) 6150 tmp &= ~0x0008; 6151 else 6152 tmp |= 0x0008; 6153 BWN_RF_WRITE(mac, 0x7a, tmp); 6154 } 6155 6156 static void 6157 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6158 { 6159 struct bwn_phy *phy = &mac->mac_phy; 6160 struct bwn_phy_g *pg = &phy->phy_g; 6161 struct bwn_softc *sc = mac->mac_sc; 6162 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6163 struct timespec ts; 6164 uint16_t tmp; 6165 6166 if (bwn_has_hwpctl(mac)) { 6167 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6168 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6169 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6170 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6171 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6172 6173 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6174 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6175 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6176 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6177 } 6178 if (phy->type == BWN_PHYTYPE_B && 6179 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6180 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6181 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6182 } 6183 if (phy->rev >= 2) { 6184 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6185 sav->phy_analogoverval = 6186 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6187 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6188 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6189 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6190 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6191 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6192 6193 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6194 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6195 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6196 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6197 if (phy->type == BWN_PHYTYPE_G) { 6198 if ((phy->rev >= 7) && 6199 (siba_sprom_get_bf_lo(sc->sc_dev) & 6200 BWN_BFL_EXTLNA)) { 6201 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6202 } else { 6203 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6204 } 6205 } else { 6206 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6207 } 6208 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6209 } 6210 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6211 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6212 sav->rf0 = BWN_RF_READ(mac, 0x43); 6213 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6214 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6215 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6216 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6217 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6218 6219 if (!BWN_HAS_TXMAG(phy)) { 6220 sav->rf2 = BWN_RF_READ(mac, 0x52); 6221 sav->rf2 &= 0x00f0; 6222 } 6223 if (phy->type == BWN_PHYTYPE_B) { 6224 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6225 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6226 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6227 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6228 } else { 6229 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6230 | 0x8000); 6231 } 6232 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6233 & 0xf000); 6234 6235 tmp = 6236 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6237 BWN_PHY_WRITE(mac, tmp, 0x007f); 6238 6239 tmp = sav->phy_syncctl; 6240 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6241 tmp = sav->rf1; 6242 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6243 6244 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6245 if (phy->type == BWN_PHYTYPE_G || 6246 (phy->type == BWN_PHYTYPE_B && 6247 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6248 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6249 } else 6250 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6251 if (phy->rev >= 2) 6252 bwn_dummy_transmission(mac, 0, 1); 6253 bwn_phy_g_switch_chan(mac, 6, 0); 6254 BWN_RF_READ(mac, 0x51); 6255 if (phy->type == BWN_PHYTYPE_G) 6256 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6257 6258 nanouptime(&ts); 6259 if (time_before(lo->txctl_measured_time, 6260 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6261 bwn_lo_measure_txctl_values(mac); 6262 6263 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6264 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6265 else { 6266 if (phy->type == BWN_PHYTYPE_B) 6267 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6268 else 6269 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6270 } 6271 } 6272 6273 static void 6274 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6275 { 6276 struct bwn_phy *phy = &mac->mac_phy; 6277 struct bwn_phy_g *pg = &phy->phy_g; 6278 uint16_t tmp; 6279 6280 if (phy->rev >= 2) { 6281 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6282 tmp = (pg->pg_pga_gain << 8); 6283 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6284 DELAY(5); 6285 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6286 DELAY(2); 6287 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6288 } else { 6289 tmp = (pg->pg_pga_gain | 0xefa0); 6290 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6291 } 6292 if (phy->type == BWN_PHYTYPE_G) { 6293 if (phy->rev >= 3) 6294 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6295 else 6296 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6297 if (phy->rev >= 2) 6298 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6299 else 6300 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6301 } 6302 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6303 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6304 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6305 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6306 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6307 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6308 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6309 if (!BWN_HAS_TXMAG(phy)) { 6310 tmp = sav->rf2; 6311 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6312 } 6313 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6314 if (phy->type == BWN_PHYTYPE_B && 6315 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6316 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6317 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6318 } 6319 if (phy->rev >= 2) { 6320 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6321 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6322 sav->phy_analogoverval); 6323 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6324 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6325 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6326 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6327 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6328 } 6329 if (bwn_has_hwpctl(mac)) { 6330 tmp = (sav->phy_lomask & 0xbfff); 6331 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6332 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6333 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6334 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6335 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6336 } 6337 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6338 } 6339 6340 static int 6341 bwn_lo_probe_loctl(struct bwn_mac *mac, 6342 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6343 { 6344 struct bwn_phy *phy = &mac->mac_phy; 6345 struct bwn_phy_g *pg = &phy->phy_g; 6346 struct bwn_loctl orig, test; 6347 struct bwn_loctl prev = { -100, -100 }; 6348 static const struct bwn_loctl modifiers[] = { 6349 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6350 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6351 }; 6352 int begin, end, lower = 0, i; 6353 uint16_t feedth; 6354 6355 if (d->curstate == 0) { 6356 begin = 1; 6357 end = 8; 6358 } else if (d->curstate % 2 == 0) { 6359 begin = d->curstate - 1; 6360 end = d->curstate + 1; 6361 } else { 6362 begin = d->curstate - 2; 6363 end = d->curstate + 2; 6364 } 6365 if (begin < 1) 6366 begin += 8; 6367 if (end > 8) 6368 end -= 8; 6369 6370 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6371 i = begin; 6372 d->curstate = i; 6373 while (1) { 6374 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6375 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6376 test.i += modifiers[i - 1].i * d->multipler; 6377 test.q += modifiers[i - 1].q * d->multipler; 6378 if ((test.i != prev.i || test.q != prev.q) && 6379 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6380 bwn_lo_write(mac, &test); 6381 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6382 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6383 if (feedth < d->feedth) { 6384 memcpy(probe, &test, 6385 sizeof(struct bwn_loctl)); 6386 lower = 1; 6387 d->feedth = feedth; 6388 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6389 break; 6390 } 6391 } 6392 memcpy(&prev, &test, sizeof(prev)); 6393 if (i == end) 6394 break; 6395 if (i == 8) 6396 i = 1; 6397 else 6398 i++; 6399 d->curstate = i; 6400 } 6401 6402 return (lower); 6403 } 6404 6405 static void 6406 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6407 { 6408 struct bwn_phy *phy = &mac->mac_phy; 6409 struct bwn_phy_g *pg = &phy->phy_g; 6410 struct bwn_lo_g_sm d; 6411 struct bwn_loctl probe; 6412 int lower, repeat, cnt = 0; 6413 uint16_t feedth; 6414 6415 d.nmeasure = 0; 6416 d.multipler = 1; 6417 if (BWN_HAS_LOOPBACK(phy)) 6418 d.multipler = 3; 6419 6420 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6421 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6422 6423 do { 6424 bwn_lo_write(mac, &d.loctl); 6425 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6426 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6427 if (feedth < 0x258) { 6428 if (feedth >= 0x12c) 6429 *rxgain += 6; 6430 else 6431 *rxgain += 3; 6432 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6433 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6434 } 6435 d.feedth = feedth; 6436 d.curstate = 0; 6437 do { 6438 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6439 ("%s:%d: fail", __func__, __LINE__)); 6440 memcpy(&probe, &d.loctl, 6441 sizeof(struct bwn_loctl)); 6442 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6443 if (!lower) 6444 break; 6445 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6446 break; 6447 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6448 d.nmeasure++; 6449 } while (d.nmeasure < 24); 6450 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6451 6452 if (BWN_HAS_LOOPBACK(phy)) { 6453 if (d.feedth > 0x1194) 6454 *rxgain -= 6; 6455 else if (d.feedth < 0x5dc) 6456 *rxgain += 3; 6457 if (cnt == 0) { 6458 if (d.feedth <= 0x5dc) { 6459 d.multipler = 1; 6460 cnt++; 6461 } else 6462 d.multipler = 2; 6463 } else if (cnt == 2) 6464 d.multipler = 1; 6465 } 6466 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6467 } while (++cnt < repeat); 6468 } 6469 6470 static struct bwn_lo_calib * 6471 bwn_lo_calibset(struct bwn_mac *mac, 6472 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6473 { 6474 struct bwn_phy *phy = &mac->mac_phy; 6475 struct bwn_phy_g *pg = &phy->phy_g; 6476 struct bwn_loctl loctl = { 0, 0 }; 6477 struct bwn_lo_calib *cal; 6478 struct bwn_lo_g_value sval = { 0 }; 6479 int rxgain; 6480 uint16_t pad, reg, value; 6481 6482 sval.old_channel = phy->chan; 6483 bwn_mac_suspend(mac); 6484 bwn_lo_save(mac, &sval); 6485 6486 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6487 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6488 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6489 6490 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6491 if (rfatt->padmix) 6492 rxgain -= pad; 6493 if (BWN_HAS_LOOPBACK(phy)) 6494 rxgain += pg->pg_max_lb_gain; 6495 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6496 bwn_phy_g_set_bbatt(mac, bbatt->att); 6497 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6498 6499 bwn_lo_restore(mac, &sval); 6500 bwn_mac_enable(mac); 6501 6502 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6503 if (!cal) { 6504 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6505 return (NULL); 6506 } 6507 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6508 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6509 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6510 6511 BWN_GETTIME(cal->calib_time); 6512 6513 return (cal); 6514 } 6515 6516 static struct bwn_lo_calib * 6517 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6518 const struct bwn_rfatt *rfatt) 6519 { 6520 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6521 struct bwn_lo_calib *c; 6522 6523 TAILQ_FOREACH(c, &lo->calib_list, list) { 6524 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6525 continue; 6526 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6527 continue; 6528 return (c); 6529 } 6530 6531 c = bwn_lo_calibset(mac, bbatt, rfatt); 6532 if (!c) 6533 return (NULL); 6534 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6535 6536 return (c); 6537 } 6538 6539 static void 6540 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6541 { 6542 struct bwn_phy *phy = &mac->mac_phy; 6543 struct bwn_phy_g *pg = &phy->phy_g; 6544 struct bwn_softc *sc = mac->mac_sc; 6545 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6546 const struct bwn_rfatt *rfatt; 6547 const struct bwn_bbatt *bbatt; 6548 uint64_t pvector; 6549 int i; 6550 int rf_offset, bb_offset; 6551 uint8_t changed = 0; 6552 6553 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6554 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6555 ("%s:%d: fail", __func__, __LINE__)); 6556 6557 pvector = lo->power_vector; 6558 if (!update && !pvector) 6559 return; 6560 6561 bwn_mac_suspend(mac); 6562 6563 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6564 struct bwn_lo_calib *cal; 6565 int idx; 6566 uint16_t val; 6567 6568 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6569 continue; 6570 bb_offset = i / lo->rfatt.len; 6571 rf_offset = i % lo->rfatt.len; 6572 bbatt = &(lo->bbatt.array[bb_offset]); 6573 rfatt = &(lo->rfatt.array[rf_offset]); 6574 6575 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6576 if (!cal) { 6577 device_printf(sc->sc_dev, "LO: Could not " 6578 "calibrate DC table entry\n"); 6579 continue; 6580 } 6581 val = (uint8_t)(cal->ctl.q); 6582 val |= ((uint8_t)(cal->ctl.i)) << 4; 6583 free(cal, M_DEVBUF); 6584 6585 idx = i / 2; 6586 if (i % 2) 6587 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6588 | ((val & 0x00ff) << 8); 6589 else 6590 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6591 | (val & 0x00ff); 6592 changed = 1; 6593 } 6594 if (changed) { 6595 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6596 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6597 } 6598 bwn_mac_enable(mac); 6599 } 6600 6601 static void 6602 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6603 { 6604 6605 if (!rf->padmix) 6606 return; 6607 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6608 rf->att = 4; 6609 } 6610 6611 static void 6612 bwn_lo_g_adjust(struct bwn_mac *mac) 6613 { 6614 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6615 struct bwn_lo_calib *cal; 6616 struct bwn_rfatt rf; 6617 6618 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6619 bwn_lo_fixup_rfatt(&rf); 6620 6621 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6622 if (!cal) 6623 return; 6624 bwn_lo_write(mac, &cal->ctl); 6625 } 6626 6627 static void 6628 bwn_lo_g_init(struct bwn_mac *mac) 6629 { 6630 6631 if (!bwn_has_hwpctl(mac)) 6632 return; 6633 6634 bwn_lo_get_powervector(mac); 6635 bwn_phy_g_dc_lookup_init(mac, 1); 6636 } 6637 6638 static void 6639 bwn_mac_suspend(struct bwn_mac *mac) 6640 { 6641 struct bwn_softc *sc = mac->mac_sc; 6642 int i; 6643 uint32_t tmp; 6644 6645 KASSERT(mac->mac_suspended >= 0, 6646 ("%s:%d: fail", __func__, __LINE__)); 6647 6648 if (mac->mac_suspended == 0) { 6649 bwn_psctl(mac, BWN_PS_AWAKE); 6650 BWN_WRITE_4(mac, BWN_MACCTL, 6651 BWN_READ_4(mac, BWN_MACCTL) 6652 & ~BWN_MACCTL_ON); 6653 BWN_READ_4(mac, BWN_MACCTL); 6654 for (i = 35; i; i--) { 6655 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6656 if (tmp & BWN_INTR_MAC_SUSPENDED) 6657 goto out; 6658 DELAY(10); 6659 } 6660 for (i = 40; i; i--) { 6661 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6662 if (tmp & BWN_INTR_MAC_SUSPENDED) 6663 goto out; 6664 DELAY(1000); 6665 } 6666 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6667 } 6668 out: 6669 mac->mac_suspended++; 6670 } 6671 6672 static void 6673 bwn_mac_enable(struct bwn_mac *mac) 6674 { 6675 struct bwn_softc *sc = mac->mac_sc; 6676 uint16_t state; 6677 6678 state = bwn_shm_read_2(mac, BWN_SHARED, 6679 BWN_SHARED_UCODESTAT); 6680 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6681 state != BWN_SHARED_UCODESTAT_SLEEP) 6682 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6683 6684 mac->mac_suspended--; 6685 KASSERT(mac->mac_suspended >= 0, 6686 ("%s:%d: fail", __func__, __LINE__)); 6687 if (mac->mac_suspended == 0) { 6688 BWN_WRITE_4(mac, BWN_MACCTL, 6689 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6690 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6691 BWN_READ_4(mac, BWN_MACCTL); 6692 BWN_READ_4(mac, BWN_INTR_REASON); 6693 bwn_psctl(mac, 0); 6694 } 6695 } 6696 6697 static void 6698 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6699 { 6700 struct bwn_softc *sc = mac->mac_sc; 6701 int i; 6702 uint16_t ucstat; 6703 6704 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6705 ("%s:%d: fail", __func__, __LINE__)); 6706 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6707 ("%s:%d: fail", __func__, __LINE__)); 6708 6709 /* XXX forcibly awake and hwps-off */ 6710 6711 BWN_WRITE_4(mac, BWN_MACCTL, 6712 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6713 ~BWN_MACCTL_HWPS); 6714 BWN_READ_4(mac, BWN_MACCTL); 6715 if (siba_get_revid(sc->sc_dev) >= 5) { 6716 for (i = 0; i < 100; i++) { 6717 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6718 BWN_SHARED_UCODESTAT); 6719 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6720 break; 6721 DELAY(10); 6722 } 6723 } 6724 } 6725 6726 static int16_t 6727 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6728 { 6729 6730 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6731 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6732 } 6733 6734 static void 6735 bwn_nrssi_threshold(struct bwn_mac *mac) 6736 { 6737 struct bwn_phy *phy = &mac->mac_phy; 6738 struct bwn_phy_g *pg = &phy->phy_g; 6739 struct bwn_softc *sc = mac->mac_sc; 6740 int32_t a, b; 6741 int16_t tmp16; 6742 uint16_t tmpu16; 6743 6744 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6745 6746 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6747 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6748 a = 0x13; 6749 b = 0x12; 6750 } else { 6751 a = 0xe; 6752 b = 0x11; 6753 } 6754 6755 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6756 a += (pg->pg_nrssi[0] << 6); 6757 a += (a < 32) ? 31 : 32; 6758 a = a >> 6; 6759 a = MIN(MAX(a, -31), 31); 6760 6761 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6762 b += (pg->pg_nrssi[0] << 6); 6763 if (b < 32) 6764 b += 31; 6765 else 6766 b += 32; 6767 b = b >> 6; 6768 b = MIN(MAX(b, -31), 31); 6769 6770 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6771 tmpu16 |= ((uint32_t)b & 0x0000003f); 6772 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6773 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6774 return; 6775 } 6776 6777 tmp16 = bwn_nrssi_read(mac, 0x20); 6778 if (tmp16 >= 0x20) 6779 tmp16 -= 0x40; 6780 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6781 } 6782 6783 static void 6784 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6785 { 6786 #define SAVE_RF_MAX 3 6787 #define SAVE_PHY_COMM_MAX 4 6788 #define SAVE_PHY3_MAX 8 6789 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6790 { 0x7a, 0x52, 0x43 }; 6791 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6792 { 0x15, 0x5a, 0x59, 0x58 }; 6793 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6794 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6795 0x0801, 0x0060, 0x0014, 0x0478 6796 }; 6797 struct bwn_phy *phy = &mac->mac_phy; 6798 struct bwn_phy_g *pg = &phy->phy_g; 6799 int32_t i, tmp32, phy3_idx = 0; 6800 uint16_t delta, tmp; 6801 uint16_t save_rf[SAVE_RF_MAX]; 6802 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6803 uint16_t save_phy3[SAVE_PHY3_MAX]; 6804 uint16_t ant_div, phy0, chan_ex; 6805 int16_t nrssi0, nrssi1; 6806 6807 KASSERT(phy->type == BWN_PHYTYPE_G, 6808 ("%s:%d: fail", __func__, __LINE__)); 6809 6810 if (phy->rf_rev >= 9) 6811 return; 6812 if (phy->rf_rev == 8) 6813 bwn_nrssi_offset(mac); 6814 6815 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6816 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6817 6818 /* 6819 * Save RF/PHY registers for later restoration 6820 */ 6821 ant_div = BWN_READ_2(mac, 0x03e2); 6822 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6823 for (i = 0; i < SAVE_RF_MAX; ++i) 6824 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6825 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6826 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6827 6828 phy0 = BWN_READ_2(mac, BWN_PHY0); 6829 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6830 if (phy->rev >= 3) { 6831 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6832 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6833 BWN_PHY_WRITE(mac, 0x002e, 0); 6834 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6835 switch (phy->rev) { 6836 case 4: 6837 case 6: 6838 case 7: 6839 BWN_PHY_SET(mac, 0x0478, 0x0100); 6840 BWN_PHY_SET(mac, 0x0801, 0x0040); 6841 break; 6842 case 3: 6843 case 5: 6844 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6845 break; 6846 } 6847 BWN_PHY_SET(mac, 0x0060, 0x0040); 6848 BWN_PHY_SET(mac, 0x0014, 0x0200); 6849 } 6850 /* 6851 * Calculate nrssi0 6852 */ 6853 BWN_RF_SET(mac, 0x007a, 0x0070); 6854 bwn_set_all_gains(mac, 0, 8, 0); 6855 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6856 if (phy->rev >= 2) { 6857 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6858 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6859 } 6860 BWN_RF_SET(mac, 0x007a, 0x0080); 6861 DELAY(20); 6862 6863 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6864 if (nrssi0 >= 0x0020) 6865 nrssi0 -= 0x0040; 6866 6867 /* 6868 * Calculate nrssi1 6869 */ 6870 BWN_RF_MASK(mac, 0x007a, 0x007f); 6871 if (phy->rev >= 2) 6872 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6873 6874 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6875 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6876 BWN_RF_SET(mac, 0x007a, 0x000f); 6877 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6878 if (phy->rev >= 2) { 6879 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6880 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6881 } 6882 6883 bwn_set_all_gains(mac, 3, 0, 1); 6884 if (phy->rf_rev == 8) { 6885 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6886 } else { 6887 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6888 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6889 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6890 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6891 } 6892 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6893 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6894 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6895 DELAY(20); 6896 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6897 6898 /* 6899 * Install calculated narrow RSSI values 6900 */ 6901 if (nrssi1 >= 0x0020) 6902 nrssi1 -= 0x0040; 6903 if (nrssi0 == nrssi1) 6904 pg->pg_nrssi_slope = 0x00010000; 6905 else 6906 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6907 if (nrssi0 >= -4) { 6908 pg->pg_nrssi[0] = nrssi1; 6909 pg->pg_nrssi[1] = nrssi0; 6910 } 6911 6912 /* 6913 * Restore saved RF/PHY registers 6914 */ 6915 if (phy->rev >= 3) { 6916 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6917 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6918 save_phy3[phy3_idx]); 6919 } 6920 } 6921 if (phy->rev >= 2) { 6922 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6923 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6924 } 6925 6926 for (i = 0; i < SAVE_RF_MAX; ++i) 6927 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6928 6929 BWN_WRITE_2(mac, 0x03e2, ant_div); 6930 BWN_WRITE_2(mac, 0x03e6, phy0); 6931 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6932 6933 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6934 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6935 6936 bwn_spu_workaround(mac, phy->chan); 6937 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6938 bwn_set_original_gains(mac); 6939 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6940 if (phy->rev >= 3) { 6941 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6942 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6943 save_phy3[phy3_idx]); 6944 } 6945 } 6946 6947 delta = 0x1f - pg->pg_nrssi[0]; 6948 for (i = 0; i < 64; i++) { 6949 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6950 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6951 pg->pg_nrssi_lt[i] = tmp32; 6952 } 6953 6954 bwn_nrssi_threshold(mac); 6955 #undef SAVE_RF_MAX 6956 #undef SAVE_PHY_COMM_MAX 6957 #undef SAVE_PHY3_MAX 6958 } 6959 6960 static void 6961 bwn_nrssi_offset(struct bwn_mac *mac) 6962 { 6963 #define SAVE_RF_MAX 2 6964 #define SAVE_PHY_COMM_MAX 10 6965 #define SAVE_PHY6_MAX 8 6966 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6967 { 0x7a, 0x43 }; 6968 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6969 0x0001, 0x0811, 0x0812, 0x0814, 6970 0x0815, 0x005a, 0x0059, 0x0058, 6971 0x000a, 0x0003 6972 }; 6973 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6974 0x002e, 0x002f, 0x080f, 0x0810, 6975 0x0801, 0x0060, 0x0014, 0x0478 6976 }; 6977 struct bwn_phy *phy = &mac->mac_phy; 6978 int i, phy6_idx = 0; 6979 uint16_t save_rf[SAVE_RF_MAX]; 6980 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6981 uint16_t save_phy6[SAVE_PHY6_MAX]; 6982 int16_t nrssi; 6983 uint16_t saved = 0xffff; 6984 6985 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6986 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6987 for (i = 0; i < SAVE_RF_MAX; ++i) 6988 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6989 6990 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6991 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6992 BWN_PHY_SET(mac, 0x0811, 0x000c); 6993 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6994 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6995 if (phy->rev >= 6) { 6996 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6997 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6998 6999 BWN_PHY_WRITE(mac, 0x002e, 0); 7000 BWN_PHY_WRITE(mac, 0x002f, 0); 7001 BWN_PHY_WRITE(mac, 0x080f, 0); 7002 BWN_PHY_WRITE(mac, 0x0810, 0); 7003 BWN_PHY_SET(mac, 0x0478, 0x0100); 7004 BWN_PHY_SET(mac, 0x0801, 0x0040); 7005 BWN_PHY_SET(mac, 0x0060, 0x0040); 7006 BWN_PHY_SET(mac, 0x0014, 0x0200); 7007 } 7008 BWN_RF_SET(mac, 0x007a, 0x0070); 7009 BWN_RF_SET(mac, 0x007a, 0x0080); 7010 DELAY(30); 7011 7012 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7013 if (nrssi >= 0x20) 7014 nrssi -= 0x40; 7015 if (nrssi == 31) { 7016 for (i = 7; i >= 4; i--) { 7017 BWN_RF_WRITE(mac, 0x007b, i); 7018 DELAY(20); 7019 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7020 0x003f); 7021 if (nrssi >= 0x20) 7022 nrssi -= 0x40; 7023 if (nrssi < 31 && saved == 0xffff) 7024 saved = i; 7025 } 7026 if (saved == 0xffff) 7027 saved = 4; 7028 } else { 7029 BWN_RF_MASK(mac, 0x007a, 0x007f); 7030 if (phy->rev != 1) { 7031 BWN_PHY_SET(mac, 0x0814, 0x0001); 7032 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7033 } 7034 BWN_PHY_SET(mac, 0x0811, 0x000c); 7035 BWN_PHY_SET(mac, 0x0812, 0x000c); 7036 BWN_PHY_SET(mac, 0x0811, 0x0030); 7037 BWN_PHY_SET(mac, 0x0812, 0x0030); 7038 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7039 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7040 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7041 if (phy->rev == 0) 7042 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7043 else 7044 BWN_PHY_SET(mac, 0x000a, 0x2000); 7045 if (phy->rev != 1) { 7046 BWN_PHY_SET(mac, 0x0814, 0x0004); 7047 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7048 } 7049 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7050 BWN_RF_SET(mac, 0x007a, 0x000f); 7051 bwn_set_all_gains(mac, 3, 0, 1); 7052 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7053 DELAY(30); 7054 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7055 if (nrssi >= 0x20) 7056 nrssi -= 0x40; 7057 if (nrssi == -32) { 7058 for (i = 0; i < 4; i++) { 7059 BWN_RF_WRITE(mac, 0x007b, i); 7060 DELAY(20); 7061 nrssi = (int16_t)((BWN_PHY_READ(mac, 7062 0x047f) >> 8) & 0x003f); 7063 if (nrssi >= 0x20) 7064 nrssi -= 0x40; 7065 if (nrssi > -31 && saved == 0xffff) 7066 saved = i; 7067 } 7068 if (saved == 0xffff) 7069 saved = 3; 7070 } else 7071 saved = 0; 7072 } 7073 BWN_RF_WRITE(mac, 0x007b, saved); 7074 7075 /* 7076 * Restore saved RF/PHY registers 7077 */ 7078 if (phy->rev >= 6) { 7079 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7080 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7081 save_phy6[phy6_idx]); 7082 } 7083 } 7084 if (phy->rev != 1) { 7085 for (i = 3; i < 5; i++) 7086 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7087 save_phy_comm[i]); 7088 } 7089 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7090 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7091 7092 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7093 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7094 7095 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7096 BWN_PHY_SET(mac, 0x0429, 0x8000); 7097 bwn_set_original_gains(mac); 7098 if (phy->rev >= 6) { 7099 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7100 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7101 save_phy6[phy6_idx]); 7102 } 7103 } 7104 7105 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7106 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7107 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7108 } 7109 7110 static void 7111 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7112 int16_t third) 7113 { 7114 struct bwn_phy *phy = &mac->mac_phy; 7115 uint16_t i; 7116 uint16_t start = 0x08, end = 0x18; 7117 uint16_t tmp; 7118 uint16_t table; 7119 7120 if (phy->rev <= 1) { 7121 start = 0x10; 7122 end = 0x20; 7123 } 7124 7125 table = BWN_OFDMTAB_GAINX; 7126 if (phy->rev <= 1) 7127 table = BWN_OFDMTAB_GAINX_R1; 7128 for (i = 0; i < 4; i++) 7129 bwn_ofdmtab_write_2(mac, table, i, first); 7130 7131 for (i = start; i < end; i++) 7132 bwn_ofdmtab_write_2(mac, table, i, second); 7133 7134 if (third != -1) { 7135 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7136 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7137 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7138 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7139 } 7140 bwn_dummy_transmission(mac, 0, 1); 7141 } 7142 7143 static void 7144 bwn_set_original_gains(struct bwn_mac *mac) 7145 { 7146 struct bwn_phy *phy = &mac->mac_phy; 7147 uint16_t i, tmp; 7148 uint16_t table; 7149 uint16_t start = 0x0008, end = 0x0018; 7150 7151 if (phy->rev <= 1) { 7152 start = 0x0010; 7153 end = 0x0020; 7154 } 7155 7156 table = BWN_OFDMTAB_GAINX; 7157 if (phy->rev <= 1) 7158 table = BWN_OFDMTAB_GAINX_R1; 7159 for (i = 0; i < 4; i++) { 7160 tmp = (i & 0xfffc); 7161 tmp |= (i & 0x0001) << 1; 7162 tmp |= (i & 0x0002) >> 1; 7163 7164 bwn_ofdmtab_write_2(mac, table, i, tmp); 7165 } 7166 7167 for (i = start; i < end; i++) 7168 bwn_ofdmtab_write_2(mac, table, i, i - start); 7169 7170 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7171 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7172 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7173 bwn_dummy_transmission(mac, 0, 1); 7174 } 7175 7176 static void 7177 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7178 { 7179 struct bwn_phy *phy = &mac->mac_phy; 7180 struct bwn_phy_g *pg = &phy->phy_g; 7181 struct bwn_rfatt old_rfatt, rfatt; 7182 struct bwn_bbatt old_bbatt, bbatt; 7183 struct bwn_softc *sc = mac->mac_sc; 7184 uint8_t old_txctl = 0; 7185 7186 KASSERT(phy->type == BWN_PHYTYPE_G, 7187 ("%s:%d: fail", __func__, __LINE__)); 7188 7189 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7190 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7191 return; 7192 7193 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7194 7195 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7196 7197 if (!phy->gmode) 7198 return; 7199 bwn_hwpctl_early_init(mac); 7200 if (pg->pg_curtssi == 0) { 7201 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7202 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7203 } else { 7204 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7205 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7206 old_txctl = pg->pg_txctl; 7207 7208 bbatt.att = 11; 7209 if (phy->rf_rev == 8) { 7210 rfatt.att = 15; 7211 rfatt.padmix = 1; 7212 } else { 7213 rfatt.att = 9; 7214 rfatt.padmix = 0; 7215 } 7216 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7217 } 7218 bwn_dummy_transmission(mac, 0, 1); 7219 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7220 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7221 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7222 else 7223 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7224 &old_rfatt, old_txctl); 7225 } 7226 bwn_hwpctl_init_gphy(mac); 7227 7228 /* clear TSSI */ 7229 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7230 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7231 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7232 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7233 } 7234 7235 static void 7236 bwn_hwpctl_early_init(struct bwn_mac *mac) 7237 { 7238 struct bwn_phy *phy = &mac->mac_phy; 7239 7240 if (!bwn_has_hwpctl(mac)) { 7241 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7242 return; 7243 } 7244 7245 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7246 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7247 BWN_PHY_SET(mac, 0x047c, 0x0002); 7248 BWN_PHY_SET(mac, 0x047a, 0xf000); 7249 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7250 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7251 BWN_PHY_SET(mac, 0x005d, 0x8000); 7252 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7253 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7254 BWN_PHY_SET(mac, 0x0036, 0x0400); 7255 } else { 7256 BWN_PHY_SET(mac, 0x0036, 0x0200); 7257 BWN_PHY_SET(mac, 0x0036, 0x0400); 7258 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7259 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7260 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7261 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7262 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7263 } 7264 } 7265 7266 static void 7267 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7268 { 7269 struct bwn_phy *phy = &mac->mac_phy; 7270 struct bwn_phy_g *pg = &phy->phy_g; 7271 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7272 int i; 7273 uint16_t nr_written = 0, tmp, value; 7274 uint8_t rf, bb; 7275 7276 if (!bwn_has_hwpctl(mac)) { 7277 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7278 return; 7279 } 7280 7281 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7282 (pg->pg_idletssi - pg->pg_curtssi)); 7283 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7284 (pg->pg_idletssi - pg->pg_curtssi)); 7285 7286 for (i = 0; i < 32; i++) 7287 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7288 for (i = 32; i < 64; i++) 7289 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7290 for (i = 0; i < 64; i += 2) { 7291 value = (uint16_t) pg->pg_tssi2dbm[i]; 7292 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7293 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7294 } 7295 7296 for (rf = 0; rf < lo->rfatt.len; rf++) { 7297 for (bb = 0; bb < lo->bbatt.len; bb++) { 7298 if (nr_written >= 0x40) 7299 return; 7300 tmp = lo->bbatt.array[bb].att; 7301 tmp <<= 8; 7302 if (phy->rf_rev == 8) 7303 tmp |= 0x50; 7304 else 7305 tmp |= 0x40; 7306 tmp |= lo->rfatt.array[rf].att; 7307 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7308 nr_written++; 7309 } 7310 } 7311 7312 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7313 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7314 7315 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7316 BWN_PHY_SET(mac, 0x0478, 0x0800); 7317 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7318 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7319 7320 bwn_phy_g_dc_lookup_init(mac, 1); 7321 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7322 } 7323 7324 static void 7325 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7326 { 7327 struct bwn_softc *sc = mac->mac_sc; 7328 7329 if (spu != 0) 7330 bwn_spu_workaround(mac, channel); 7331 7332 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7333 7334 if (channel == 14) { 7335 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7336 bwn_hf_write(mac, 7337 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7338 else 7339 bwn_hf_write(mac, 7340 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7341 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7342 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7343 return; 7344 } 7345 7346 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7347 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7348 } 7349 7350 static uint16_t 7351 bwn_phy_g_chan2freq(uint8_t channel) 7352 { 7353 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7354 7355 KASSERT(channel >= 1 && channel <= 14, 7356 ("%s:%d: fail", __func__, __LINE__)); 7357 7358 return (bwn_phy_g_rf_channels[channel - 1]); 7359 } 7360 7361 static void 7362 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7363 const struct bwn_rfatt *rfatt, uint8_t txctl) 7364 { 7365 struct bwn_phy *phy = &mac->mac_phy; 7366 struct bwn_phy_g *pg = &phy->phy_g; 7367 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7368 uint16_t bb, rf; 7369 uint16_t tx_bias, tx_magn; 7370 7371 bb = bbatt->att; 7372 rf = rfatt->att; 7373 tx_bias = lo->tx_bias; 7374 tx_magn = lo->tx_magn; 7375 if (tx_bias == 0xff) 7376 tx_bias = 0; 7377 7378 pg->pg_txctl = txctl; 7379 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7380 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7381 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7382 bwn_phy_g_set_bbatt(mac, bb); 7383 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7384 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7385 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7386 else { 7387 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7388 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7389 } 7390 if (BWN_HAS_TXMAG(phy)) 7391 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7392 else 7393 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7394 bwn_lo_g_adjust(mac); 7395 } 7396 7397 static void 7398 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7399 uint16_t bbatt) 7400 { 7401 struct bwn_phy *phy = &mac->mac_phy; 7402 7403 if (phy->analog == 0) { 7404 BWN_WRITE_2(mac, BWN_PHY0, 7405 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7406 return; 7407 } 7408 if (phy->analog > 1) { 7409 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7410 return; 7411 } 7412 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7413 } 7414 7415 static uint16_t 7416 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7417 { 7418 struct bwn_phy *phy = &mac->mac_phy; 7419 struct bwn_phy_g *pg = &phy->phy_g; 7420 struct bwn_softc *sc = mac->mac_sc; 7421 int max_lb_gain; 7422 uint16_t extlna; 7423 uint16_t i; 7424 7425 if (phy->gmode == 0) 7426 return (0); 7427 7428 if (BWN_HAS_LOOPBACK(phy)) { 7429 max_lb_gain = pg->pg_max_lb_gain; 7430 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7431 if (max_lb_gain >= 0x46) { 7432 extlna = 0x3000; 7433 max_lb_gain -= 0x46; 7434 } else if (max_lb_gain >= 0x3a) { 7435 extlna = 0x1000; 7436 max_lb_gain -= 0x3a; 7437 } else if (max_lb_gain >= 0x2e) { 7438 extlna = 0x2000; 7439 max_lb_gain -= 0x2e; 7440 } else { 7441 extlna = 0; 7442 max_lb_gain -= 0x10; 7443 } 7444 7445 for (i = 0; i < 16; i++) { 7446 max_lb_gain -= (i * 6); 7447 if (max_lb_gain < 6) 7448 break; 7449 } 7450 7451 if ((phy->rev < 7) || 7452 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7453 if (reg == BWN_PHY_RFOVER) { 7454 return (0x1b3); 7455 } else if (reg == BWN_PHY_RFOVERVAL) { 7456 extlna |= (i << 8); 7457 switch (lpd) { 7458 case BWN_LPD(0, 1, 1): 7459 return (0x0f92); 7460 case BWN_LPD(0, 0, 1): 7461 case BWN_LPD(1, 0, 1): 7462 return (0x0092 | extlna); 7463 case BWN_LPD(1, 0, 0): 7464 return (0x0093 | extlna); 7465 } 7466 KASSERT(0 == 1, 7467 ("%s:%d: fail", __func__, __LINE__)); 7468 } 7469 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7470 } else { 7471 if (reg == BWN_PHY_RFOVER) 7472 return (0x9b3); 7473 if (reg == BWN_PHY_RFOVERVAL) { 7474 if (extlna) 7475 extlna |= 0x8000; 7476 extlna |= (i << 8); 7477 switch (lpd) { 7478 case BWN_LPD(0, 1, 1): 7479 return (0x8f92); 7480 case BWN_LPD(0, 0, 1): 7481 return (0x8092 | extlna); 7482 case BWN_LPD(1, 0, 1): 7483 return (0x2092 | extlna); 7484 case BWN_LPD(1, 0, 0): 7485 return (0x2093 | extlna); 7486 } 7487 KASSERT(0 == 1, 7488 ("%s:%d: fail", __func__, __LINE__)); 7489 } 7490 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7491 } 7492 return (0); 7493 } 7494 7495 if ((phy->rev < 7) || 7496 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7497 if (reg == BWN_PHY_RFOVER) { 7498 return (0x1b3); 7499 } else if (reg == BWN_PHY_RFOVERVAL) { 7500 switch (lpd) { 7501 case BWN_LPD(0, 1, 1): 7502 return (0x0fb2); 7503 case BWN_LPD(0, 0, 1): 7504 return (0x00b2); 7505 case BWN_LPD(1, 0, 1): 7506 return (0x30b2); 7507 case BWN_LPD(1, 0, 0): 7508 return (0x30b3); 7509 } 7510 KASSERT(0 == 1, 7511 ("%s:%d: fail", __func__, __LINE__)); 7512 } 7513 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7514 } else { 7515 if (reg == BWN_PHY_RFOVER) { 7516 return (0x9b3); 7517 } else if (reg == BWN_PHY_RFOVERVAL) { 7518 switch (lpd) { 7519 case BWN_LPD(0, 1, 1): 7520 return (0x8fb2); 7521 case BWN_LPD(0, 0, 1): 7522 return (0x80b2); 7523 case BWN_LPD(1, 0, 1): 7524 return (0x20b2); 7525 case BWN_LPD(1, 0, 0): 7526 return (0x20b3); 7527 } 7528 KASSERT(0 == 1, 7529 ("%s:%d: fail", __func__, __LINE__)); 7530 } 7531 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7532 } 7533 return (0); 7534 } 7535 7536 static void 7537 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7538 { 7539 7540 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7541 return; 7542 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7543 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7544 DELAY(1000); 7545 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7546 } 7547 7548 static int 7549 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7550 { 7551 struct bwn_softc *sc = mac->mac_sc; 7552 struct bwn_fw *fw = &mac->mac_fw; 7553 const uint8_t rev = siba_get_revid(sc->sc_dev); 7554 const char *filename; 7555 uint32_t high; 7556 int error; 7557 7558 /* microcode */ 7559 if (rev >= 5 && rev <= 10) 7560 filename = "ucode5"; 7561 else if (rev >= 11 && rev <= 12) 7562 filename = "ucode11"; 7563 else if (rev == 13) 7564 filename = "ucode13"; 7565 else if (rev == 14) 7566 filename = "ucode14"; 7567 else if (rev >= 15) 7568 filename = "ucode15"; 7569 else { 7570 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7571 bwn_release_firmware(mac); 7572 return (EOPNOTSUPP); 7573 } 7574 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7575 if (error) { 7576 bwn_release_firmware(mac); 7577 return (error); 7578 } 7579 7580 /* PCM */ 7581 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7582 if (rev >= 5 && rev <= 10) { 7583 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7584 if (error == ENOENT) 7585 fw->no_pcmfile = 1; 7586 else if (error) { 7587 bwn_release_firmware(mac); 7588 return (error); 7589 } 7590 } else if (rev < 11) { 7591 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7592 return (EOPNOTSUPP); 7593 } 7594 7595 /* initvals */ 7596 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7597 switch (mac->mac_phy.type) { 7598 case BWN_PHYTYPE_A: 7599 if (rev < 5 || rev > 10) 7600 goto fail1; 7601 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7602 filename = "a0g1initvals5"; 7603 else 7604 filename = "a0g0initvals5"; 7605 break; 7606 case BWN_PHYTYPE_G: 7607 if (rev >= 5 && rev <= 10) 7608 filename = "b0g0initvals5"; 7609 else if (rev >= 13) 7610 filename = "b0g0initvals13"; 7611 else 7612 goto fail1; 7613 break; 7614 case BWN_PHYTYPE_LP: 7615 if (rev == 13) 7616 filename = "lp0initvals13"; 7617 else if (rev == 14) 7618 filename = "lp0initvals14"; 7619 else if (rev >= 15) 7620 filename = "lp0initvals15"; 7621 else 7622 goto fail1; 7623 break; 7624 case BWN_PHYTYPE_N: 7625 if (rev >= 11 && rev <= 12) 7626 filename = "n0initvals11"; 7627 else 7628 goto fail1; 7629 break; 7630 default: 7631 goto fail1; 7632 } 7633 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7634 if (error) { 7635 bwn_release_firmware(mac); 7636 return (error); 7637 } 7638 7639 /* bandswitch initvals */ 7640 switch (mac->mac_phy.type) { 7641 case BWN_PHYTYPE_A: 7642 if (rev >= 5 && rev <= 10) { 7643 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7644 filename = "a0g1bsinitvals5"; 7645 else 7646 filename = "a0g0bsinitvals5"; 7647 } else if (rev >= 11) 7648 filename = NULL; 7649 else 7650 goto fail1; 7651 break; 7652 case BWN_PHYTYPE_G: 7653 if (rev >= 5 && rev <= 10) 7654 filename = "b0g0bsinitvals5"; 7655 else if (rev >= 11) 7656 filename = NULL; 7657 else 7658 goto fail1; 7659 break; 7660 case BWN_PHYTYPE_LP: 7661 if (rev == 13) 7662 filename = "lp0bsinitvals13"; 7663 else if (rev == 14) 7664 filename = "lp0bsinitvals14"; 7665 else if (rev >= 15) 7666 filename = "lp0bsinitvals15"; 7667 else 7668 goto fail1; 7669 break; 7670 case BWN_PHYTYPE_N: 7671 if (rev >= 11 && rev <= 12) 7672 filename = "n0bsinitvals11"; 7673 else 7674 goto fail1; 7675 break; 7676 default: 7677 goto fail1; 7678 } 7679 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7680 if (error) { 7681 bwn_release_firmware(mac); 7682 return (error); 7683 } 7684 return (0); 7685 fail1: 7686 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7687 bwn_release_firmware(mac); 7688 return (EOPNOTSUPP); 7689 } 7690 7691 static int 7692 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7693 const char *name, struct bwn_fwfile *bfw) 7694 { 7695 const struct bwn_fwhdr *hdr; 7696 struct bwn_softc *sc = mac->mac_sc; 7697 const struct firmware *fw; 7698 char namebuf[64]; 7699 7700 if (name == NULL) { 7701 bwn_do_release_fw(bfw); 7702 return (0); 7703 } 7704 if (bfw->filename != NULL) { 7705 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7706 return (0); 7707 bwn_do_release_fw(bfw); 7708 } 7709 7710 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7711 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7712 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7713 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7714 fw = firmware_get(namebuf); 7715 if (fw == NULL) { 7716 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7717 namebuf); 7718 return (ENOENT); 7719 } 7720 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7721 goto fail; 7722 hdr = (const struct bwn_fwhdr *)(fw->data); 7723 switch (hdr->type) { 7724 case BWN_FWTYPE_UCODE: 7725 case BWN_FWTYPE_PCM: 7726 if (be32toh(hdr->size) != 7727 (fw->datasize - sizeof(struct bwn_fwhdr))) 7728 goto fail; 7729 /* FALLTHROUGH */ 7730 case BWN_FWTYPE_IV: 7731 if (hdr->ver != 1) 7732 goto fail; 7733 break; 7734 default: 7735 goto fail; 7736 } 7737 bfw->filename = name; 7738 bfw->fw = fw; 7739 bfw->type = type; 7740 return (0); 7741 fail: 7742 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7743 if (fw != NULL) 7744 firmware_put(fw, FIRMWARE_UNLOAD); 7745 return (EPROTO); 7746 } 7747 7748 static void 7749 bwn_release_firmware(struct bwn_mac *mac) 7750 { 7751 7752 bwn_do_release_fw(&mac->mac_fw.ucode); 7753 bwn_do_release_fw(&mac->mac_fw.pcm); 7754 bwn_do_release_fw(&mac->mac_fw.initvals); 7755 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7756 } 7757 7758 static void 7759 bwn_do_release_fw(struct bwn_fwfile *bfw) 7760 { 7761 7762 if (bfw->fw != NULL) 7763 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7764 bfw->fw = NULL; 7765 bfw->filename = NULL; 7766 } 7767 7768 static int 7769 bwn_fw_loaducode(struct bwn_mac *mac) 7770 { 7771 #define GETFWOFFSET(fwp, offset) \ 7772 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7773 #define GETFWSIZE(fwp, offset) \ 7774 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7775 struct bwn_softc *sc = mac->mac_sc; 7776 const uint32_t *data; 7777 unsigned int i; 7778 uint32_t ctl; 7779 uint16_t date, fwcaps, time; 7780 int error = 0; 7781 7782 ctl = BWN_READ_4(mac, BWN_MACCTL); 7783 ctl |= BWN_MACCTL_MCODE_JMP0; 7784 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7785 __LINE__)); 7786 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7787 for (i = 0; i < 64; i++) 7788 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7789 for (i = 0; i < 4096; i += 2) 7790 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7791 7792 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7793 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7794 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7795 i++) { 7796 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7797 DELAY(10); 7798 } 7799 7800 if (mac->mac_fw.pcm.fw) { 7801 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7802 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7803 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7804 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7805 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7806 sizeof(struct bwn_fwhdr)); i++) { 7807 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7808 DELAY(10); 7809 } 7810 } 7811 7812 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7813 BWN_WRITE_4(mac, BWN_MACCTL, 7814 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7815 BWN_MACCTL_MCODE_RUN); 7816 7817 for (i = 0; i < 21; i++) { 7818 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7819 break; 7820 if (i >= 20) { 7821 device_printf(sc->sc_dev, "ucode timeout\n"); 7822 error = ENXIO; 7823 goto error; 7824 } 7825 DELAY(50000); 7826 } 7827 BWN_READ_4(mac, BWN_INTR_REASON); 7828 7829 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7830 if (mac->mac_fw.rev <= 0x128) { 7831 device_printf(sc->sc_dev, "the firmware is too old\n"); 7832 error = EOPNOTSUPP; 7833 goto error; 7834 } 7835 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7836 BWN_SHARED_UCODE_PATCH); 7837 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7838 mac->mac_fw.opensource = (date == 0xffff); 7839 if (bwn_wme != 0) 7840 mac->mac_flags |= BWN_MAC_FLAG_WME; 7841 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7842 7843 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7844 if (mac->mac_fw.opensource == 0) { 7845 device_printf(sc->sc_dev, 7846 "firmware version (rev %u patch %u date %#x time %#x)\n", 7847 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7848 if (mac->mac_fw.no_pcmfile) 7849 device_printf(sc->sc_dev, 7850 "no HW crypto acceleration due to pcm5\n"); 7851 } else { 7852 mac->mac_fw.patch = time; 7853 fwcaps = bwn_fwcaps_read(mac); 7854 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7855 device_printf(sc->sc_dev, 7856 "disabling HW crypto acceleration\n"); 7857 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7858 } 7859 if (!(fwcaps & BWN_FWCAPS_WME)) { 7860 device_printf(sc->sc_dev, "disabling WME support\n"); 7861 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7862 } 7863 } 7864 7865 if (BWN_ISOLDFMT(mac)) 7866 device_printf(sc->sc_dev, "using old firmware image\n"); 7867 7868 return (0); 7869 7870 error: 7871 BWN_WRITE_4(mac, BWN_MACCTL, 7872 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7873 BWN_MACCTL_MCODE_JMP0); 7874 7875 return (error); 7876 #undef GETFWSIZE 7877 #undef GETFWOFFSET 7878 } 7879 7880 /* OpenFirmware only */ 7881 static uint16_t 7882 bwn_fwcaps_read(struct bwn_mac *mac) 7883 { 7884 7885 KASSERT(mac->mac_fw.opensource == 1, 7886 ("%s:%d: fail", __func__, __LINE__)); 7887 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7888 } 7889 7890 static int 7891 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7892 size_t count, size_t array_size) 7893 { 7894 #define GET_NEXTIV16(iv) \ 7895 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7896 sizeof(uint16_t) + sizeof(uint16_t))) 7897 #define GET_NEXTIV32(iv) \ 7898 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7899 sizeof(uint16_t) + sizeof(uint32_t))) 7900 struct bwn_softc *sc = mac->mac_sc; 7901 const struct bwn_fwinitvals *iv; 7902 uint16_t offset; 7903 size_t i; 7904 uint8_t bit32; 7905 7906 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7907 ("%s:%d: fail", __func__, __LINE__)); 7908 iv = ivals; 7909 for (i = 0; i < count; i++) { 7910 if (array_size < sizeof(iv->offset_size)) 7911 goto fail; 7912 array_size -= sizeof(iv->offset_size); 7913 offset = be16toh(iv->offset_size); 7914 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7915 offset &= BWN_FWINITVALS_OFFSET_MASK; 7916 if (offset >= 0x1000) 7917 goto fail; 7918 if (bit32) { 7919 if (array_size < sizeof(iv->data.d32)) 7920 goto fail; 7921 array_size -= sizeof(iv->data.d32); 7922 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7923 iv = GET_NEXTIV32(iv); 7924 } else { 7925 7926 if (array_size < sizeof(iv->data.d16)) 7927 goto fail; 7928 array_size -= sizeof(iv->data.d16); 7929 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7930 7931 iv = GET_NEXTIV16(iv); 7932 } 7933 } 7934 if (array_size != 0) 7935 goto fail; 7936 return (0); 7937 fail: 7938 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7939 return (EPROTO); 7940 #undef GET_NEXTIV16 7941 #undef GET_NEXTIV32 7942 } 7943 7944 static int 7945 bwn_switch_channel(struct bwn_mac *mac, int chan) 7946 { 7947 struct bwn_phy *phy = &(mac->mac_phy); 7948 struct bwn_softc *sc = mac->mac_sc; 7949 struct ifnet *ifp = sc->sc_ifp; 7950 struct ieee80211com *ic = ifp->if_l2com; 7951 uint16_t channelcookie, savedcookie; 7952 int error; 7953 7954 if (chan == 0xffff) 7955 chan = phy->get_default_chan(mac); 7956 7957 channelcookie = chan; 7958 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7959 channelcookie |= 0x100; 7960 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7961 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7962 error = phy->switch_channel(mac, chan); 7963 if (error) 7964 goto fail; 7965 7966 mac->mac_phy.chan = chan; 7967 DELAY(8000); 7968 return (0); 7969 fail: 7970 device_printf(sc->sc_dev, "failed to switch channel\n"); 7971 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7972 return (error); 7973 } 7974 7975 static uint16_t 7976 bwn_ant2phy(int antenna) 7977 { 7978 7979 switch (antenna) { 7980 case BWN_ANT0: 7981 return (BWN_TX_PHY_ANT0); 7982 case BWN_ANT1: 7983 return (BWN_TX_PHY_ANT1); 7984 case BWN_ANT2: 7985 return (BWN_TX_PHY_ANT2); 7986 case BWN_ANT3: 7987 return (BWN_TX_PHY_ANT3); 7988 case BWN_ANTAUTO: 7989 return (BWN_TX_PHY_ANT01AUTO); 7990 } 7991 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7992 return (0); 7993 } 7994 7995 static void 7996 bwn_wme_load(struct bwn_mac *mac) 7997 { 7998 struct bwn_softc *sc = mac->mac_sc; 7999 int i; 8000 8001 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 8002 ("%s:%d: fail", __func__, __LINE__)); 8003 8004 bwn_mac_suspend(mac); 8005 for (i = 0; i < N(sc->sc_wmeParams); i++) 8006 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8007 bwn_wme_shm_offsets[i]); 8008 bwn_mac_enable(mac); 8009 } 8010 8011 static void 8012 bwn_wme_loadparams(struct bwn_mac *mac, 8013 const struct wmeParams *p, uint16_t shm_offset) 8014 { 8015 #define SM(_v, _f) (((_v) << _f##_S) & _f) 8016 struct bwn_softc *sc = mac->mac_sc; 8017 uint16_t params[BWN_NR_WMEPARAMS]; 8018 int slot, tmp; 8019 unsigned int i; 8020 8021 slot = BWN_READ_2(mac, BWN_RNG) & 8022 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8023 8024 memset(¶ms, 0, sizeof(params)); 8025 8026 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8027 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8028 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8029 8030 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8031 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8032 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8033 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8034 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8035 params[BWN_WMEPARAM_BSLOTS] = slot; 8036 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8037 8038 for (i = 0; i < N(params); i++) { 8039 if (i == BWN_WMEPARAM_STATUS) { 8040 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8041 shm_offset + (i * 2)); 8042 tmp |= 0x100; 8043 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8044 tmp); 8045 } else { 8046 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8047 params[i]); 8048 } 8049 } 8050 } 8051 8052 static void 8053 bwn_mac_write_bssid(struct bwn_mac *mac) 8054 { 8055 struct bwn_softc *sc = mac->mac_sc; 8056 uint32_t tmp; 8057 int i; 8058 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8059 8060 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8061 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8062 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8063 IEEE80211_ADDR_LEN); 8064 8065 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8066 tmp = (uint32_t) (mac_bssid[i + 0]); 8067 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8068 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8069 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8070 bwn_ram_write(mac, 0x20 + i, tmp); 8071 } 8072 } 8073 8074 static void 8075 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8076 const uint8_t *macaddr) 8077 { 8078 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8079 uint16_t data; 8080 8081 if (!mac) 8082 macaddr = zero; 8083 8084 offset |= 0x0020; 8085 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8086 8087 data = macaddr[0]; 8088 data |= macaddr[1] << 8; 8089 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8090 data = macaddr[2]; 8091 data |= macaddr[3] << 8; 8092 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8093 data = macaddr[4]; 8094 data |= macaddr[5] << 8; 8095 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8096 } 8097 8098 static void 8099 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8100 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8101 { 8102 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8103 uint8_t per_sta_keys_start = 8; 8104 8105 if (BWN_SEC_NEWAPI(mac)) 8106 per_sta_keys_start = 4; 8107 8108 KASSERT(index < mac->mac_max_nr_keys, 8109 ("%s:%d: fail", __func__, __LINE__)); 8110 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8111 ("%s:%d: fail", __func__, __LINE__)); 8112 8113 if (index >= per_sta_keys_start) 8114 bwn_key_macwrite(mac, index, NULL); 8115 if (key) 8116 memcpy(buf, key, key_len); 8117 bwn_key_write(mac, index, algorithm, buf); 8118 if (index >= per_sta_keys_start) 8119 bwn_key_macwrite(mac, index, mac_addr); 8120 8121 mac->mac_key[index].algorithm = algorithm; 8122 } 8123 8124 static void 8125 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8126 { 8127 struct bwn_softc *sc = mac->mac_sc; 8128 uint32_t addrtmp[2] = { 0, 0 }; 8129 uint8_t start = 8; 8130 8131 if (BWN_SEC_NEWAPI(mac)) 8132 start = 4; 8133 8134 KASSERT(index >= start, 8135 ("%s:%d: fail", __func__, __LINE__)); 8136 index -= start; 8137 8138 if (addr) { 8139 addrtmp[0] = addr[0]; 8140 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8141 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8142 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8143 addrtmp[1] = addr[4]; 8144 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8145 } 8146 8147 if (siba_get_revid(sc->sc_dev) >= 5) { 8148 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8149 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8150 } else { 8151 if (index >= 8) { 8152 bwn_shm_write_4(mac, BWN_SHARED, 8153 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8154 bwn_shm_write_2(mac, BWN_SHARED, 8155 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8156 } 8157 } 8158 } 8159 8160 static void 8161 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8162 const uint8_t *key) 8163 { 8164 unsigned int i; 8165 uint32_t offset; 8166 uint16_t kidx, value; 8167 8168 kidx = BWN_SEC_KEY2FW(mac, index); 8169 bwn_shm_write_2(mac, BWN_SHARED, 8170 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8171 8172 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8173 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8174 value = key[i]; 8175 value |= (uint16_t)(key[i + 1]) << 8; 8176 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8177 } 8178 } 8179 8180 static void 8181 bwn_phy_exit(struct bwn_mac *mac) 8182 { 8183 8184 mac->mac_phy.rf_onoff(mac, 0); 8185 if (mac->mac_phy.exit != NULL) 8186 mac->mac_phy.exit(mac); 8187 } 8188 8189 static void 8190 bwn_dma_free(struct bwn_mac *mac) 8191 { 8192 struct bwn_dma *dma; 8193 8194 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8195 return; 8196 dma = &mac->mac_method.dma; 8197 8198 bwn_dma_ringfree(&dma->rx); 8199 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8200 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8201 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8202 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8203 bwn_dma_ringfree(&dma->mcast); 8204 } 8205 8206 static void 8207 bwn_core_stop(struct bwn_mac *mac) 8208 { 8209 struct bwn_softc *sc = mac->mac_sc; 8210 8211 BWN_ASSERT_LOCKED(sc); 8212 8213 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8214 return; 8215 8216 callout_stop(&sc->sc_rfswitch_ch); 8217 callout_stop(&sc->sc_task_ch); 8218 callout_stop(&sc->sc_watchdog_ch); 8219 sc->sc_watchdog_timer = 0; 8220 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8221 BWN_READ_4(mac, BWN_INTR_MASK); 8222 bwn_mac_suspend(mac); 8223 8224 mac->mac_status = BWN_MAC_STATUS_INITED; 8225 } 8226 8227 static int 8228 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8229 { 8230 struct bwn_mac *up_dev = NULL; 8231 struct bwn_mac *down_dev; 8232 struct bwn_mac *mac; 8233 int err, status; 8234 uint8_t gmode; 8235 8236 BWN_ASSERT_LOCKED(sc); 8237 8238 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8239 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8240 mac->mac_phy.supports_2ghz) { 8241 up_dev = mac; 8242 gmode = 1; 8243 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8244 mac->mac_phy.supports_5ghz) { 8245 up_dev = mac; 8246 gmode = 0; 8247 } else { 8248 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8249 return (EINVAL); 8250 } 8251 if (up_dev != NULL) 8252 break; 8253 } 8254 if (up_dev == NULL) { 8255 device_printf(sc->sc_dev, "Could not find a device\n"); 8256 return (ENODEV); 8257 } 8258 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8259 return (0); 8260 8261 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8262 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8263 8264 down_dev = sc->sc_curmac;; 8265 status = down_dev->mac_status; 8266 if (status >= BWN_MAC_STATUS_STARTED) 8267 bwn_core_stop(down_dev); 8268 if (status >= BWN_MAC_STATUS_INITED) 8269 bwn_core_exit(down_dev); 8270 8271 if (down_dev != up_dev) 8272 bwn_phy_reset(down_dev); 8273 8274 up_dev->mac_phy.gmode = gmode; 8275 if (status >= BWN_MAC_STATUS_INITED) { 8276 err = bwn_core_init(up_dev); 8277 if (err) { 8278 device_printf(sc->sc_dev, 8279 "fatal: failed to initialize for %s-GHz\n", 8280 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8281 goto fail; 8282 } 8283 } 8284 if (status >= BWN_MAC_STATUS_STARTED) 8285 bwn_core_start(up_dev); 8286 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8287 sc->sc_curmac = up_dev; 8288 8289 return (0); 8290 fail: 8291 sc->sc_curmac = NULL; 8292 return (err); 8293 } 8294 8295 static void 8296 bwn_rf_turnon(struct bwn_mac *mac) 8297 { 8298 8299 bwn_mac_suspend(mac); 8300 mac->mac_phy.rf_onoff(mac, 1); 8301 mac->mac_phy.rf_on = 1; 8302 bwn_mac_enable(mac); 8303 } 8304 8305 static void 8306 bwn_rf_turnoff(struct bwn_mac *mac) 8307 { 8308 8309 bwn_mac_suspend(mac); 8310 mac->mac_phy.rf_onoff(mac, 0); 8311 mac->mac_phy.rf_on = 0; 8312 bwn_mac_enable(mac); 8313 } 8314 8315 static void 8316 bwn_phy_reset(struct bwn_mac *mac) 8317 { 8318 struct bwn_softc *sc = mac->mac_sc; 8319 8320 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8321 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8322 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8323 DELAY(1000); 8324 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8325 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8326 BWN_TGSLOW_PHYRESET); 8327 DELAY(1000); 8328 } 8329 8330 static int 8331 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8332 { 8333 const struct ieee80211_txparam *tp; 8334 struct bwn_vap *bvp = BWN_VAP(vap); 8335 struct ieee80211com *ic= vap->iv_ic; 8336 struct ifnet *ifp = ic->ic_ifp; 8337 enum ieee80211_state ostate = vap->iv_state; 8338 struct bwn_softc *sc = ifp->if_softc; 8339 struct bwn_mac *mac = sc->sc_curmac; 8340 int error; 8341 8342 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8343 ieee80211_state_name[vap->iv_state], 8344 ieee80211_state_name[nstate]); 8345 8346 error = bvp->bv_newstate(vap, nstate, arg); 8347 if (error != 0) 8348 return (error); 8349 8350 BWN_LOCK(sc); 8351 8352 bwn_led_newstate(mac, nstate); 8353 8354 /* 8355 * Clear the BSSID when we stop a STA 8356 */ 8357 if (vap->iv_opmode == IEEE80211_M_STA) { 8358 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8359 /* 8360 * Clear out the BSSID. If we reassociate to 8361 * the same AP, this will reinialize things 8362 * correctly... 8363 */ 8364 if (ic->ic_opmode == IEEE80211_M_STA && 8365 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8366 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8367 bwn_set_macaddr(mac); 8368 } 8369 } 8370 } 8371 8372 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8373 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8374 /* XXX nothing to do? */ 8375 } else if (nstate == IEEE80211_S_RUN) { 8376 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8377 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8378 bwn_set_opmode(mac); 8379 bwn_set_pretbtt(mac); 8380 bwn_spu_setdelay(mac, 0); 8381 bwn_set_macaddr(mac); 8382 8383 /* Initializes ratectl for a node. */ 8384 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 8385 if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) 8386 ieee80211_ratectl_node_init(vap->iv_bss); 8387 } 8388 8389 BWN_UNLOCK(sc); 8390 8391 return (error); 8392 } 8393 8394 static void 8395 bwn_set_pretbtt(struct bwn_mac *mac) 8396 { 8397 struct bwn_softc *sc = mac->mac_sc; 8398 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8399 uint16_t pretbtt; 8400 8401 if (ic->ic_opmode == IEEE80211_M_IBSS) 8402 pretbtt = 2; 8403 else 8404 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8405 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8406 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8407 } 8408 8409 static int 8410 bwn_intr(void *arg) 8411 { 8412 struct bwn_mac *mac = arg; 8413 struct bwn_softc *sc = mac->mac_sc; 8414 uint32_t reason; 8415 8416 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8417 (sc->sc_flags & BWN_FLAG_INVALID)) 8418 return (FILTER_STRAY); 8419 8420 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8421 if (reason == 0xffffffff) /* shared IRQ */ 8422 return (FILTER_STRAY); 8423 reason &= mac->mac_intr_mask; 8424 if (reason == 0) 8425 return (FILTER_HANDLED); 8426 8427 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8428 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8429 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8430 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8431 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8432 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8433 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8434 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8435 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8436 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8437 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8438 8439 /* Disable interrupts. */ 8440 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8441 8442 mac->mac_reason_intr = reason; 8443 8444 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8445 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8446 8447 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8448 return (FILTER_HANDLED); 8449 } 8450 8451 static void 8452 bwn_intrtask(void *arg, int npending) 8453 { 8454 struct bwn_mac *mac = arg; 8455 struct bwn_softc *sc = mac->mac_sc; 8456 struct ifnet *ifp = sc->sc_ifp; 8457 uint32_t merged = 0; 8458 int i, tx = 0, rx = 0; 8459 8460 BWN_LOCK(sc); 8461 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8462 (sc->sc_flags & BWN_FLAG_INVALID)) { 8463 BWN_UNLOCK(sc); 8464 return; 8465 } 8466 8467 for (i = 0; i < N(mac->mac_reason); i++) 8468 merged |= mac->mac_reason[i]; 8469 8470 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8471 device_printf(sc->sc_dev, "MAC trans error\n"); 8472 8473 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8474 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8475 mac->mac_phy.txerrors--; 8476 if (mac->mac_phy.txerrors == 0) { 8477 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8478 bwn_restart(mac, "PHY TX errors"); 8479 } 8480 } 8481 8482 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8483 if (merged & BWN_DMAINTR_FATALMASK) { 8484 device_printf(sc->sc_dev, 8485 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8486 mac->mac_reason[0], mac->mac_reason[1], 8487 mac->mac_reason[2], mac->mac_reason[3], 8488 mac->mac_reason[4], mac->mac_reason[5]); 8489 bwn_restart(mac, "DMA error"); 8490 BWN_UNLOCK(sc); 8491 return; 8492 } 8493 if (merged & BWN_DMAINTR_NONFATALMASK) { 8494 device_printf(sc->sc_dev, 8495 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8496 mac->mac_reason[0], mac->mac_reason[1], 8497 mac->mac_reason[2], mac->mac_reason[3], 8498 mac->mac_reason[4], mac->mac_reason[5]); 8499 } 8500 } 8501 8502 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8503 bwn_intr_ucode_debug(mac); 8504 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8505 bwn_intr_tbtt_indication(mac); 8506 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8507 bwn_intr_atim_end(mac); 8508 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8509 bwn_intr_beacon(mac); 8510 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8511 bwn_intr_pmq(mac); 8512 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8513 bwn_intr_noise(mac); 8514 8515 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8516 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8517 bwn_dma_rx(mac->mac_method.dma.rx); 8518 rx = 1; 8519 } 8520 } else 8521 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8522 8523 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8524 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8525 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8526 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8527 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8528 8529 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8530 bwn_intr_txeof(mac); 8531 tx = 1; 8532 } 8533 8534 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8535 8536 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8537 int evt = BWN_LED_EVENT_NONE; 8538 8539 if (tx && rx) { 8540 if (sc->sc_rx_rate > sc->sc_tx_rate) 8541 evt = BWN_LED_EVENT_RX; 8542 else 8543 evt = BWN_LED_EVENT_TX; 8544 } else if (tx) { 8545 evt = BWN_LED_EVENT_TX; 8546 } else if (rx) { 8547 evt = BWN_LED_EVENT_RX; 8548 } else if (rx == 0) { 8549 evt = BWN_LED_EVENT_POLL; 8550 } 8551 8552 if (evt != BWN_LED_EVENT_NONE) 8553 bwn_led_event(mac, evt); 8554 } 8555 8556 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8557 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8558 bwn_start_locked(ifp); 8559 } 8560 8561 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8562 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8563 8564 BWN_UNLOCK(sc); 8565 } 8566 8567 static void 8568 bwn_restart(struct bwn_mac *mac, const char *msg) 8569 { 8570 struct bwn_softc *sc = mac->mac_sc; 8571 struct ifnet *ifp = sc->sc_ifp; 8572 struct ieee80211com *ic = ifp->if_l2com; 8573 8574 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8575 return; 8576 8577 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8578 ieee80211_runtask(ic, &mac->mac_hwreset); 8579 } 8580 8581 static void 8582 bwn_intr_ucode_debug(struct bwn_mac *mac) 8583 { 8584 struct bwn_softc *sc = mac->mac_sc; 8585 uint16_t reason; 8586 8587 if (mac->mac_fw.opensource == 0) 8588 return; 8589 8590 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8591 switch (reason) { 8592 case BWN_DEBUGINTR_PANIC: 8593 bwn_handle_fwpanic(mac); 8594 break; 8595 case BWN_DEBUGINTR_DUMP_SHM: 8596 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8597 break; 8598 case BWN_DEBUGINTR_DUMP_REGS: 8599 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8600 break; 8601 case BWN_DEBUGINTR_MARKER: 8602 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8603 break; 8604 default: 8605 device_printf(sc->sc_dev, 8606 "ucode debug unknown reason: %#x\n", reason); 8607 } 8608 8609 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8610 BWN_DEBUGINTR_ACK); 8611 } 8612 8613 static void 8614 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8615 { 8616 struct bwn_softc *sc = mac->mac_sc; 8617 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8618 8619 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8620 bwn_psctl(mac, 0); 8621 if (ic->ic_opmode == IEEE80211_M_IBSS) 8622 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8623 } 8624 8625 static void 8626 bwn_intr_atim_end(struct bwn_mac *mac) 8627 { 8628 8629 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8630 BWN_WRITE_4(mac, BWN_MACCMD, 8631 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8632 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8633 } 8634 } 8635 8636 static void 8637 bwn_intr_beacon(struct bwn_mac *mac) 8638 { 8639 struct bwn_softc *sc = mac->mac_sc; 8640 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8641 uint32_t cmd, beacon0, beacon1; 8642 8643 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8644 ic->ic_opmode == IEEE80211_M_MBSS) 8645 return; 8646 8647 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8648 8649 cmd = BWN_READ_4(mac, BWN_MACCMD); 8650 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8651 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8652 8653 if (beacon0 && beacon1) { 8654 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8655 mac->mac_intr_mask |= BWN_INTR_BEACON; 8656 return; 8657 } 8658 8659 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8660 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8661 bwn_load_beacon0(mac); 8662 bwn_load_beacon1(mac); 8663 cmd = BWN_READ_4(mac, BWN_MACCMD); 8664 cmd |= BWN_MACCMD_BEACON0_VALID; 8665 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8666 } else { 8667 if (!beacon0) { 8668 bwn_load_beacon0(mac); 8669 cmd = BWN_READ_4(mac, BWN_MACCMD); 8670 cmd |= BWN_MACCMD_BEACON0_VALID; 8671 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8672 } else if (!beacon1) { 8673 bwn_load_beacon1(mac); 8674 cmd = BWN_READ_4(mac, BWN_MACCMD); 8675 cmd |= BWN_MACCMD_BEACON1_VALID; 8676 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8677 } 8678 } 8679 } 8680 8681 static void 8682 bwn_intr_pmq(struct bwn_mac *mac) 8683 { 8684 uint32_t tmp; 8685 8686 while (1) { 8687 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8688 if (!(tmp & 0x00000008)) 8689 break; 8690 } 8691 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8692 } 8693 8694 static void 8695 bwn_intr_noise(struct bwn_mac *mac) 8696 { 8697 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8698 uint16_t tmp; 8699 uint8_t noise[4]; 8700 uint8_t i, j; 8701 int32_t average; 8702 8703 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8704 return; 8705 8706 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8707 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8708 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8709 noise[3] == 0x7f) 8710 goto new; 8711 8712 KASSERT(mac->mac_noise.noi_nsamples < 8, 8713 ("%s:%d: fail", __func__, __LINE__)); 8714 i = mac->mac_noise.noi_nsamples; 8715 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8716 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8717 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8718 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8719 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8720 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8721 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8722 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8723 mac->mac_noise.noi_nsamples++; 8724 if (mac->mac_noise.noi_nsamples == 8) { 8725 average = 0; 8726 for (i = 0; i < 8; i++) { 8727 for (j = 0; j < 4; j++) 8728 average += mac->mac_noise.noi_samples[i][j]; 8729 } 8730 average = (((average / 32) * 125) + 64) / 128; 8731 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8732 if (tmp >= 8) 8733 average += 2; 8734 else 8735 average -= 25; 8736 average -= (tmp == 8) ? 72 : 48; 8737 8738 mac->mac_stats.link_noise = average; 8739 mac->mac_noise.noi_running = 0; 8740 return; 8741 } 8742 new: 8743 bwn_noise_gensample(mac); 8744 } 8745 8746 static int 8747 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8748 { 8749 struct bwn_mac *mac = prq->prq_mac; 8750 struct bwn_softc *sc = mac->mac_sc; 8751 unsigned int i; 8752 8753 BWN_ASSERT_LOCKED(sc); 8754 8755 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8756 return (0); 8757 8758 for (i = 0; i < 5000; i++) { 8759 if (bwn_pio_rxeof(prq) == 0) 8760 break; 8761 } 8762 if (i >= 5000) 8763 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8764 return ((i > 0) ? 1 : 0); 8765 } 8766 8767 static void 8768 bwn_dma_rx(struct bwn_dma_ring *dr) 8769 { 8770 int slot, curslot; 8771 8772 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8773 curslot = dr->get_curslot(dr); 8774 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8775 ("%s:%d: fail", __func__, __LINE__)); 8776 8777 slot = dr->dr_curslot; 8778 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8779 bwn_dma_rxeof(dr, &slot); 8780 8781 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8782 BUS_DMASYNC_PREWRITE); 8783 8784 dr->set_curslot(dr, slot); 8785 dr->dr_curslot = slot; 8786 } 8787 8788 static void 8789 bwn_intr_txeof(struct bwn_mac *mac) 8790 { 8791 struct bwn_txstatus stat; 8792 uint32_t stat0, stat1; 8793 uint16_t tmp; 8794 8795 BWN_ASSERT_LOCKED(mac->mac_sc); 8796 8797 while (1) { 8798 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8799 if (!(stat0 & 0x00000001)) 8800 break; 8801 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8802 8803 stat.cookie = (stat0 >> 16); 8804 stat.seq = (stat1 & 0x0000ffff); 8805 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8806 tmp = (stat0 & 0x0000ffff); 8807 stat.framecnt = ((tmp & 0xf000) >> 12); 8808 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8809 stat.sreason = ((tmp & 0x001c) >> 2); 8810 stat.pm = (tmp & 0x0080) ? 1 : 0; 8811 stat.im = (tmp & 0x0040) ? 1 : 0; 8812 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8813 stat.ack = (tmp & 0x0002) ? 1 : 0; 8814 8815 bwn_handle_txeof(mac, &stat); 8816 } 8817 } 8818 8819 static void 8820 bwn_hwreset(void *arg, int npending) 8821 { 8822 struct bwn_mac *mac = arg; 8823 struct bwn_softc *sc = mac->mac_sc; 8824 int error = 0; 8825 int prev_status; 8826 8827 BWN_LOCK(sc); 8828 8829 prev_status = mac->mac_status; 8830 if (prev_status >= BWN_MAC_STATUS_STARTED) 8831 bwn_core_stop(mac); 8832 if (prev_status >= BWN_MAC_STATUS_INITED) 8833 bwn_core_exit(mac); 8834 8835 if (prev_status >= BWN_MAC_STATUS_INITED) { 8836 error = bwn_core_init(mac); 8837 if (error) 8838 goto out; 8839 } 8840 if (prev_status >= BWN_MAC_STATUS_STARTED) 8841 bwn_core_start(mac); 8842 out: 8843 if (error) { 8844 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8845 sc->sc_curmac = NULL; 8846 } 8847 BWN_UNLOCK(sc); 8848 } 8849 8850 static void 8851 bwn_handle_fwpanic(struct bwn_mac *mac) 8852 { 8853 struct bwn_softc *sc = mac->mac_sc; 8854 uint16_t reason; 8855 8856 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8857 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8858 8859 if (reason == BWN_FWPANIC_RESTART) 8860 bwn_restart(mac, "ucode panic"); 8861 } 8862 8863 static void 8864 bwn_load_beacon0(struct bwn_mac *mac) 8865 { 8866 8867 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8868 } 8869 8870 static void 8871 bwn_load_beacon1(struct bwn_mac *mac) 8872 { 8873 8874 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8875 } 8876 8877 static uint32_t 8878 bwn_jssi_read(struct bwn_mac *mac) 8879 { 8880 uint32_t val = 0; 8881 8882 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8883 val <<= 16; 8884 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8885 8886 return (val); 8887 } 8888 8889 static void 8890 bwn_noise_gensample(struct bwn_mac *mac) 8891 { 8892 uint32_t jssi = 0x7f7f7f7f; 8893 8894 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8895 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8896 BWN_WRITE_4(mac, BWN_MACCMD, 8897 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8898 } 8899 8900 static int 8901 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8902 { 8903 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8904 8905 return (dr->dr_numslots - dr->dr_usedslot); 8906 } 8907 8908 static int 8909 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8910 { 8911 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8912 8913 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8914 ("%s:%d: fail", __func__, __LINE__)); 8915 if (slot == dr->dr_numslots - 1) 8916 return (0); 8917 return (slot + 1); 8918 } 8919 8920 static void 8921 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8922 { 8923 struct bwn_mac *mac = dr->dr_mac; 8924 struct bwn_softc *sc = mac->mac_sc; 8925 struct bwn_dma *dma = &mac->mac_method.dma; 8926 struct bwn_dmadesc_generic *desc; 8927 struct bwn_dmadesc_meta *meta; 8928 struct bwn_rxhdr4 *rxhdr; 8929 struct ifnet *ifp = sc->sc_ifp; 8930 struct mbuf *m; 8931 uint32_t macstat; 8932 int32_t tmp; 8933 int cnt = 0; 8934 uint16_t len; 8935 8936 dr->getdesc(dr, *slot, &desc, &meta); 8937 8938 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8939 m = meta->mt_m; 8940 8941 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8942 ifp->if_ierrors++; 8943 return; 8944 } 8945 8946 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8947 len = le16toh(rxhdr->frame_len); 8948 if (len <= 0) { 8949 ifp->if_ierrors++; 8950 return; 8951 } 8952 if (bwn_dma_check_redzone(dr, m)) { 8953 device_printf(sc->sc_dev, "redzone error.\n"); 8954 bwn_dma_set_redzone(dr, m); 8955 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8956 BUS_DMASYNC_PREWRITE); 8957 return; 8958 } 8959 if (len > dr->dr_rx_bufsize) { 8960 tmp = len; 8961 while (1) { 8962 dr->getdesc(dr, *slot, &desc, &meta); 8963 bwn_dma_set_redzone(dr, meta->mt_m); 8964 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8965 BUS_DMASYNC_PREWRITE); 8966 *slot = bwn_dma_nextslot(dr, *slot); 8967 cnt++; 8968 tmp -= dr->dr_rx_bufsize; 8969 if (tmp <= 0) 8970 break; 8971 } 8972 device_printf(sc->sc_dev, "too small buffer " 8973 "(len %u buffer %u dropped %d)\n", 8974 len, dr->dr_rx_bufsize, cnt); 8975 return; 8976 } 8977 macstat = le32toh(rxhdr->mac_status); 8978 if (macstat & BWN_RX_MAC_FCSERR) { 8979 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8980 device_printf(sc->sc_dev, "RX drop\n"); 8981 return; 8982 } 8983 } 8984 8985 m->m_pkthdr.rcvif = ifp; 8986 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8987 m_adj(m, dr->dr_frameoffset); 8988 8989 bwn_rxeof(dr->dr_mac, m, rxhdr); 8990 } 8991 8992 static void 8993 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8994 { 8995 struct bwn_dma_ring *dr; 8996 struct bwn_dmadesc_generic *desc; 8997 struct bwn_dmadesc_meta *meta; 8998 struct bwn_pio_txqueue *tq; 8999 struct bwn_pio_txpkt *tp = NULL; 9000 struct bwn_softc *sc = mac->mac_sc; 9001 struct bwn_stats *stats = &mac->mac_stats; 9002 struct ieee80211_node *ni; 9003 struct ieee80211vap *vap; 9004 int retrycnt = 0, slot; 9005 9006 BWN_ASSERT_LOCKED(mac->mac_sc); 9007 9008 if (status->im) 9009 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9010 if (status->ampdu) 9011 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9012 if (status->rtscnt) { 9013 if (status->rtscnt == 0xf) 9014 stats->rtsfail++; 9015 else 9016 stats->rts++; 9017 } 9018 9019 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9020 if (status->ack) { 9021 dr = bwn_dma_parse_cookie(mac, status, 9022 status->cookie, &slot); 9023 if (dr == NULL) { 9024 device_printf(sc->sc_dev, 9025 "failed to parse cookie\n"); 9026 return; 9027 } 9028 while (1) { 9029 dr->getdesc(dr, slot, &desc, &meta); 9030 if (meta->mt_islast) { 9031 ni = meta->mt_ni; 9032 vap = ni->ni_vap; 9033 ieee80211_ratectl_tx_complete(vap, ni, 9034 status->ack ? 9035 IEEE80211_RATECTL_TX_SUCCESS : 9036 IEEE80211_RATECTL_TX_FAILURE, 9037 &retrycnt, 0); 9038 break; 9039 } 9040 slot = bwn_dma_nextslot(dr, slot); 9041 } 9042 } 9043 bwn_dma_handle_txeof(mac, status); 9044 } else { 9045 if (status->ack) { 9046 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9047 if (tq == NULL) { 9048 device_printf(sc->sc_dev, 9049 "failed to parse cookie\n"); 9050 return; 9051 } 9052 ni = tp->tp_ni; 9053 vap = ni->ni_vap; 9054 ieee80211_ratectl_tx_complete(vap, ni, 9055 status->ack ? 9056 IEEE80211_RATECTL_TX_SUCCESS : 9057 IEEE80211_RATECTL_TX_FAILURE, 9058 &retrycnt, 0); 9059 } 9060 bwn_pio_handle_txeof(mac, status); 9061 } 9062 9063 bwn_phy_txpower_check(mac, 0); 9064 } 9065 9066 static uint8_t 9067 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9068 { 9069 struct bwn_mac *mac = prq->prq_mac; 9070 struct bwn_softc *sc = mac->mac_sc; 9071 struct bwn_rxhdr4 rxhdr; 9072 struct ifnet *ifp = sc->sc_ifp; 9073 struct mbuf *m; 9074 uint32_t ctl32, macstat, v32; 9075 unsigned int i, padding; 9076 uint16_t ctl16, len, totlen, v16; 9077 unsigned char *mp; 9078 char *data; 9079 9080 memset(&rxhdr, 0, sizeof(rxhdr)); 9081 9082 if (prq->prq_rev >= 8) { 9083 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9084 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9085 return (0); 9086 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9087 BWN_PIO8_RXCTL_FRAMEREADY); 9088 for (i = 0; i < 10; i++) { 9089 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9090 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9091 goto ready; 9092 DELAY(10); 9093 } 9094 } else { 9095 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9096 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9097 return (0); 9098 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9099 BWN_PIO_RXCTL_FRAMEREADY); 9100 for (i = 0; i < 10; i++) { 9101 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9102 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9103 goto ready; 9104 DELAY(10); 9105 } 9106 } 9107 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9108 return (1); 9109 ready: 9110 if (prq->prq_rev >= 8) 9111 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9112 prq->prq_base + BWN_PIO8_RXDATA); 9113 else 9114 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9115 prq->prq_base + BWN_PIO_RXDATA); 9116 len = le16toh(rxhdr.frame_len); 9117 if (len > 0x700) { 9118 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9119 goto error; 9120 } 9121 if (len == 0) { 9122 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9123 goto error; 9124 } 9125 9126 macstat = le32toh(rxhdr.mac_status); 9127 if (macstat & BWN_RX_MAC_FCSERR) { 9128 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9129 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9130 goto error; 9131 } 9132 } 9133 9134 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9135 totlen = len + padding; 9136 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9137 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9138 if (m == NULL) { 9139 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9140 goto error; 9141 } 9142 mp = mtod(m, unsigned char *); 9143 if (prq->prq_rev >= 8) { 9144 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9145 prq->prq_base + BWN_PIO8_RXDATA); 9146 if (totlen & 3) { 9147 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9148 data = &(mp[totlen - 1]); 9149 switch (totlen & 3) { 9150 case 3: 9151 *data = (v32 >> 16); 9152 data--; 9153 case 2: 9154 *data = (v32 >> 8); 9155 data--; 9156 case 1: 9157 *data = v32; 9158 } 9159 } 9160 } else { 9161 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9162 prq->prq_base + BWN_PIO_RXDATA); 9163 if (totlen & 1) { 9164 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9165 mp[totlen - 1] = v16; 9166 } 9167 } 9168 9169 m->m_pkthdr.rcvif = ifp; 9170 m->m_len = m->m_pkthdr.len = totlen; 9171 9172 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9173 9174 return (1); 9175 error: 9176 if (prq->prq_rev >= 8) 9177 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9178 BWN_PIO8_RXCTL_DATAREADY); 9179 else 9180 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9181 return (1); 9182 } 9183 9184 static int 9185 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9186 struct bwn_dmadesc_meta *meta, int init) 9187 { 9188 struct bwn_mac *mac = dr->dr_mac; 9189 struct bwn_dma *dma = &mac->mac_method.dma; 9190 struct bwn_rxhdr4 *hdr; 9191 bus_dmamap_t map; 9192 bus_addr_t paddr; 9193 struct mbuf *m; 9194 int error; 9195 9196 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 9197 if (m == NULL) { 9198 error = ENOBUFS; 9199 9200 /* 9201 * If the NIC is up and running, we need to: 9202 * - Clear RX buffer's header. 9203 * - Restore RX descriptor settings. 9204 */ 9205 if (init) 9206 return (error); 9207 else 9208 goto back; 9209 } 9210 m->m_len = m->m_pkthdr.len = MCLBYTES; 9211 9212 bwn_dma_set_redzone(dr, m); 9213 9214 /* 9215 * Try to load RX buf into temporary DMA map 9216 */ 9217 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9218 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9219 if (error) { 9220 m_freem(m); 9221 9222 /* 9223 * See the comment above 9224 */ 9225 if (init) 9226 return (error); 9227 else 9228 goto back; 9229 } 9230 9231 if (!init) 9232 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9233 meta->mt_m = m; 9234 meta->mt_paddr = paddr; 9235 9236 /* 9237 * Swap RX buf's DMA map with the loaded temporary one 9238 */ 9239 map = meta->mt_dmap; 9240 meta->mt_dmap = dr->dr_spare_dmap; 9241 dr->dr_spare_dmap = map; 9242 9243 back: 9244 /* 9245 * Clear RX buf header 9246 */ 9247 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9248 bzero(hdr, sizeof(*hdr)); 9249 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9250 BUS_DMASYNC_PREWRITE); 9251 9252 /* 9253 * Setup RX buf descriptor 9254 */ 9255 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len - 9256 sizeof(*hdr), 0, 0, 0); 9257 return (error); 9258 } 9259 9260 static void 9261 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9262 bus_size_t mapsz __unused, int error) 9263 { 9264 9265 if (!error) { 9266 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9267 *((bus_addr_t *)arg) = seg->ds_addr; 9268 } 9269 } 9270 9271 static int 9272 bwn_hwrate2ieeerate(int rate) 9273 { 9274 9275 switch (rate) { 9276 case BWN_CCK_RATE_1MB: 9277 return (2); 9278 case BWN_CCK_RATE_2MB: 9279 return (4); 9280 case BWN_CCK_RATE_5MB: 9281 return (11); 9282 case BWN_CCK_RATE_11MB: 9283 return (22); 9284 case BWN_OFDM_RATE_6MB: 9285 return (12); 9286 case BWN_OFDM_RATE_9MB: 9287 return (18); 9288 case BWN_OFDM_RATE_12MB: 9289 return (24); 9290 case BWN_OFDM_RATE_18MB: 9291 return (36); 9292 case BWN_OFDM_RATE_24MB: 9293 return (48); 9294 case BWN_OFDM_RATE_36MB: 9295 return (72); 9296 case BWN_OFDM_RATE_48MB: 9297 return (96); 9298 case BWN_OFDM_RATE_54MB: 9299 return (108); 9300 default: 9301 printf("Ooops\n"); 9302 return (0); 9303 } 9304 } 9305 9306 static void 9307 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9308 { 9309 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9310 struct bwn_plcp6 *plcp; 9311 struct bwn_softc *sc = mac->mac_sc; 9312 struct ieee80211_frame_min *wh; 9313 struct ieee80211_node *ni; 9314 struct ifnet *ifp = sc->sc_ifp; 9315 struct ieee80211com *ic = ifp->if_l2com; 9316 uint32_t macstat; 9317 int padding, rate, rssi = 0, noise = 0, type; 9318 uint16_t phytype, phystat0, phystat3, chanstat; 9319 unsigned char *mp = mtod(m, unsigned char *); 9320 static int rx_mac_dec_rpt = 0; 9321 9322 BWN_ASSERT_LOCKED(sc); 9323 9324 phystat0 = le16toh(rxhdr->phy_status0); 9325 phystat3 = le16toh(rxhdr->phy_status3); 9326 macstat = le32toh(rxhdr->mac_status); 9327 chanstat = le16toh(rxhdr->channel); 9328 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9329 9330 if (macstat & BWN_RX_MAC_FCSERR) 9331 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9332 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9333 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9334 if (macstat & BWN_RX_MAC_DECERR) 9335 goto drop; 9336 9337 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9338 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9339 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9340 m->m_pkthdr.len); 9341 goto drop; 9342 } 9343 plcp = (struct bwn_plcp6 *)(mp + padding); 9344 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9345 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9346 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9347 m->m_pkthdr.len); 9348 goto drop; 9349 } 9350 wh = mtod(m, struct ieee80211_frame_min *); 9351 9352 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9353 device_printf(sc->sc_dev, 9354 "RX decryption attempted (old %d keyidx %#x)\n", 9355 BWN_ISOLDFMT(mac), 9356 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9357 9358 /* XXX calculating RSSI & noise & antenna */ 9359 9360 if (phystat0 & BWN_RX_PHYST0_OFDM) 9361 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9362 phytype == BWN_PHYTYPE_A); 9363 else 9364 rate = bwn_plcp_get_cckrate(mac, plcp); 9365 if (rate == -1) { 9366 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9367 goto drop; 9368 } 9369 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9370 9371 /* RX radio tap */ 9372 if (ieee80211_radiotap_active(ic)) 9373 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9374 m_adj(m, -IEEE80211_CRC_LEN); 9375 9376 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9377 noise = mac->mac_stats.link_noise; 9378 9379 ifp->if_ipackets++; 9380 9381 BWN_UNLOCK(sc); 9382 9383 ni = ieee80211_find_rxnode(ic, wh); 9384 if (ni != NULL) { 9385 type = ieee80211_input(ni, m, rssi, noise); 9386 ieee80211_free_node(ni); 9387 } else 9388 type = ieee80211_input_all(ic, m, rssi, noise); 9389 9390 BWN_LOCK(sc); 9391 return; 9392 drop: 9393 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9394 } 9395 9396 static void 9397 bwn_dma_handle_txeof(struct bwn_mac *mac, 9398 const struct bwn_txstatus *status) 9399 { 9400 struct bwn_dma *dma = &mac->mac_method.dma; 9401 struct bwn_dma_ring *dr; 9402 struct bwn_dmadesc_generic *desc; 9403 struct bwn_dmadesc_meta *meta; 9404 struct bwn_softc *sc = mac->mac_sc; 9405 struct ieee80211_node *ni; 9406 struct ifnet *ifp = sc->sc_ifp; 9407 struct mbuf *m; 9408 int slot; 9409 9410 BWN_ASSERT_LOCKED(sc); 9411 9412 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9413 if (dr == NULL) { 9414 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9415 return; 9416 } 9417 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9418 9419 while (1) { 9420 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9421 ("%s:%d: fail", __func__, __LINE__)); 9422 dr->getdesc(dr, slot, &desc, &meta); 9423 9424 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9425 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9426 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9427 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9428 9429 if (meta->mt_islast) { 9430 KASSERT(meta->mt_m != NULL, 9431 ("%s:%d: fail", __func__, __LINE__)); 9432 9433 ni = meta->mt_ni; 9434 m = meta->mt_m; 9435 if (ni != NULL) { 9436 /* 9437 * Do any tx complete callback. Note this must 9438 * be done before releasing the node reference. 9439 */ 9440 if (m->m_flags & M_TXCB) 9441 ieee80211_process_callback(ni, m, 0); 9442 ieee80211_free_node(ni); 9443 meta->mt_ni = NULL; 9444 } 9445 m_freem(m); 9446 meta->mt_m = NULL; 9447 } else { 9448 KASSERT(meta->mt_m == NULL, 9449 ("%s:%d: fail", __func__, __LINE__)); 9450 } 9451 9452 dr->dr_usedslot--; 9453 if (meta->mt_islast) { 9454 ifp->if_opackets++; 9455 break; 9456 } 9457 slot = bwn_dma_nextslot(dr, slot); 9458 } 9459 sc->sc_watchdog_timer = 0; 9460 if (dr->dr_stop) { 9461 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9462 ("%s:%d: fail", __func__, __LINE__)); 9463 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9464 dr->dr_stop = 0; 9465 } 9466 } 9467 9468 static void 9469 bwn_pio_handle_txeof(struct bwn_mac *mac, 9470 const struct bwn_txstatus *status) 9471 { 9472 struct bwn_pio_txqueue *tq; 9473 struct bwn_pio_txpkt *tp = NULL; 9474 struct bwn_softc *sc = mac->mac_sc; 9475 struct ifnet *ifp = sc->sc_ifp; 9476 9477 BWN_ASSERT_LOCKED(sc); 9478 9479 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9480 if (tq == NULL) 9481 return; 9482 9483 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9484 tq->tq_free++; 9485 9486 if (tp->tp_ni != NULL) { 9487 /* 9488 * Do any tx complete callback. Note this must 9489 * be done before releasing the node reference. 9490 */ 9491 if (tp->tp_m->m_flags & M_TXCB) 9492 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9493 ieee80211_free_node(tp->tp_ni); 9494 tp->tp_ni = NULL; 9495 } 9496 m_freem(tp->tp_m); 9497 tp->tp_m = NULL; 9498 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9499 9500 ifp->if_opackets++; 9501 9502 sc->sc_watchdog_timer = 0; 9503 if (tq->tq_stop) { 9504 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9505 tq->tq_stop = 0; 9506 } 9507 } 9508 9509 static void 9510 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9511 { 9512 struct bwn_softc *sc = mac->mac_sc; 9513 struct bwn_phy *phy = &mac->mac_phy; 9514 struct ifnet *ifp = sc->sc_ifp; 9515 struct ieee80211com *ic = ifp->if_l2com; 9516 unsigned long now; 9517 int result; 9518 9519 BWN_GETTIME(now); 9520 9521 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9522 return; 9523 phy->nexttime = now + 2 * 1000; 9524 9525 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9526 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9527 return; 9528 9529 if (phy->recalc_txpwr != NULL) { 9530 result = phy->recalc_txpwr(mac, 9531 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9532 if (result == BWN_TXPWR_RES_DONE) 9533 return; 9534 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9535 ("%s: fail", __func__)); 9536 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9537 9538 ieee80211_runtask(ic, &mac->mac_txpower); 9539 } 9540 } 9541 9542 static uint16_t 9543 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9544 { 9545 9546 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9547 } 9548 9549 static uint32_t 9550 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9551 { 9552 9553 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9554 } 9555 9556 static void 9557 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9558 { 9559 9560 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9561 } 9562 9563 static void 9564 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9565 { 9566 9567 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9568 } 9569 9570 static int 9571 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9572 { 9573 9574 switch (rate) { 9575 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9576 case 12: 9577 return (BWN_OFDM_RATE_6MB); 9578 case 18: 9579 return (BWN_OFDM_RATE_9MB); 9580 case 24: 9581 return (BWN_OFDM_RATE_12MB); 9582 case 36: 9583 return (BWN_OFDM_RATE_18MB); 9584 case 48: 9585 return (BWN_OFDM_RATE_24MB); 9586 case 72: 9587 return (BWN_OFDM_RATE_36MB); 9588 case 96: 9589 return (BWN_OFDM_RATE_48MB); 9590 case 108: 9591 return (BWN_OFDM_RATE_54MB); 9592 /* CCK rates (NB: not IEEE std, device-specific) */ 9593 case 2: 9594 return (BWN_CCK_RATE_1MB); 9595 case 4: 9596 return (BWN_CCK_RATE_2MB); 9597 case 11: 9598 return (BWN_CCK_RATE_5MB); 9599 case 22: 9600 return (BWN_CCK_RATE_11MB); 9601 } 9602 9603 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9604 return (BWN_CCK_RATE_1MB); 9605 } 9606 9607 static int 9608 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9609 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9610 { 9611 const struct bwn_phy *phy = &mac->mac_phy; 9612 struct bwn_softc *sc = mac->mac_sc; 9613 struct ieee80211_frame *wh; 9614 struct ieee80211_frame *protwh; 9615 struct ieee80211_frame_cts *cts; 9616 struct ieee80211_frame_rts *rts; 9617 const struct ieee80211_txparam *tp; 9618 struct ieee80211vap *vap = ni->ni_vap; 9619 struct ifnet *ifp = sc->sc_ifp; 9620 struct ieee80211com *ic = ifp->if_l2com; 9621 struct mbuf *mprot; 9622 unsigned int len; 9623 uint32_t macctl = 0; 9624 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9625 uint16_t phyctl = 0; 9626 uint8_t rate, rate_fb; 9627 9628 wh = mtod(m, struct ieee80211_frame *); 9629 memset(txhdr, 0, sizeof(*txhdr)); 9630 9631 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9632 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9633 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9634 9635 /* 9636 * Find TX rate 9637 */ 9638 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9639 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9640 rate = rate_fb = tp->mgmtrate; 9641 else if (ismcast) 9642 rate = rate_fb = tp->mcastrate; 9643 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9644 rate = rate_fb = tp->ucastrate; 9645 else { 9646 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9647 rate = ni->ni_txrate; 9648 9649 if (rix > 0) 9650 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9651 IEEE80211_RATE_VAL; 9652 else 9653 rate_fb = rate; 9654 } 9655 9656 sc->sc_tx_rate = rate; 9657 9658 rate = bwn_ieeerate2hwrate(sc, rate); 9659 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9660 9661 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9662 bwn_plcp_getcck(rate); 9663 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9664 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9665 9666 if ((rate_fb == rate) || 9667 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9668 (*(u_int16_t *)wh->i_dur == htole16(0))) 9669 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9670 else 9671 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9672 m->m_pkthdr.len, rate, isshort); 9673 9674 /* XXX TX encryption */ 9675 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9676 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9677 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9678 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9679 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9680 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9681 9682 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9683 BWN_TX_EFT_FB_CCK; 9684 txhdr->chan = phy->chan; 9685 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9686 BWN_TX_PHY_ENC_CCK; 9687 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9688 rate == BWN_CCK_RATE_11MB)) 9689 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9690 9691 /* XXX TX antenna selection */ 9692 9693 switch (bwn_antenna_sanitize(mac, 0)) { 9694 case 0: 9695 phyctl |= BWN_TX_PHY_ANT01AUTO; 9696 break; 9697 case 1: 9698 phyctl |= BWN_TX_PHY_ANT0; 9699 break; 9700 case 2: 9701 phyctl |= BWN_TX_PHY_ANT1; 9702 break; 9703 case 3: 9704 phyctl |= BWN_TX_PHY_ANT2; 9705 break; 9706 case 4: 9707 phyctl |= BWN_TX_PHY_ANT3; 9708 break; 9709 default: 9710 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9711 } 9712 9713 if (!ismcast) 9714 macctl |= BWN_TX_MAC_ACK; 9715 9716 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9717 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9718 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9719 macctl |= BWN_TX_MAC_LONGFRAME; 9720 9721 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9722 /* XXX RTS rate is always 1MB??? */ 9723 rts_rate = BWN_CCK_RATE_1MB; 9724 rts_rate_fb = bwn_get_fbrate(rts_rate); 9725 9726 protdur = ieee80211_compute_duration(ic->ic_rt, 9727 m->m_pkthdr.len, rate, isshort) + 9728 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9729 9730 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9731 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9732 (txhdr->body.old.rts_frame) : 9733 (txhdr->body.new.rts_frame)); 9734 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9735 protdur); 9736 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9737 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9738 mprot->m_pkthdr.len); 9739 m_freem(mprot); 9740 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9741 len = sizeof(struct ieee80211_frame_cts); 9742 } else { 9743 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9744 (txhdr->body.old.rts_frame) : 9745 (txhdr->body.new.rts_frame)); 9746 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9747 isshort); 9748 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9749 wh->i_addr2, protdur); 9750 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9751 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9752 mprot->m_pkthdr.len); 9753 m_freem(mprot); 9754 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9755 len = sizeof(struct ieee80211_frame_rts); 9756 } 9757 len += IEEE80211_CRC_LEN; 9758 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9759 &txhdr->body.old.rts_plcp : 9760 &txhdr->body.new.rts_plcp), len, rts_rate); 9761 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9762 rts_rate_fb); 9763 9764 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9765 (&txhdr->body.old.rts_frame) : 9766 (&txhdr->body.new.rts_frame)); 9767 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9768 9769 if (BWN_ISOFDMRATE(rts_rate)) { 9770 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9771 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9772 } else { 9773 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9774 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9775 } 9776 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9777 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9778 } 9779 9780 if (BWN_ISOLDFMT(mac)) 9781 txhdr->body.old.cookie = htole16(cookie); 9782 else 9783 txhdr->body.new.cookie = htole16(cookie); 9784 9785 txhdr->macctl = htole32(macctl); 9786 txhdr->phyctl = htole16(phyctl); 9787 9788 /* 9789 * TX radio tap 9790 */ 9791 if (ieee80211_radiotap_active_vap(vap)) { 9792 sc->sc_tx_th.wt_flags = 0; 9793 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 9794 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9795 if (isshort && 9796 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9797 rate == BWN_CCK_RATE_11MB)) 9798 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9799 sc->sc_tx_th.wt_rate = rate; 9800 9801 ieee80211_radiotap_tx(vap, m); 9802 } 9803 9804 return (0); 9805 } 9806 9807 static void 9808 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9809 const uint8_t rate) 9810 { 9811 uint32_t d, plen; 9812 uint8_t *raw = plcp->o.raw; 9813 9814 if (BWN_ISOFDMRATE(rate)) { 9815 d = bwn_plcp_getofdm(rate); 9816 KASSERT(!(octets & 0xf000), 9817 ("%s:%d: fail", __func__, __LINE__)); 9818 d |= (octets << 5); 9819 plcp->o.data = htole32(d); 9820 } else { 9821 plen = octets * 16 / rate; 9822 if ((octets * 16 % rate) > 0) { 9823 plen++; 9824 if ((rate == BWN_CCK_RATE_11MB) 9825 && ((octets * 8 % 11) < 4)) { 9826 raw[1] = 0x84; 9827 } else 9828 raw[1] = 0x04; 9829 } else 9830 raw[1] = 0x04; 9831 plcp->o.data |= htole32(plen << 16); 9832 raw[0] = bwn_plcp_getcck(rate); 9833 } 9834 } 9835 9836 static uint8_t 9837 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9838 { 9839 struct bwn_softc *sc = mac->mac_sc; 9840 uint8_t mask; 9841 9842 if (n == 0) 9843 return (0); 9844 if (mac->mac_phy.gmode) 9845 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9846 else 9847 mask = siba_sprom_get_ant_a(sc->sc_dev); 9848 if (!(mask & (1 << (n - 1)))) 9849 return (0); 9850 return (n); 9851 } 9852 9853 static uint8_t 9854 bwn_get_fbrate(uint8_t bitrate) 9855 { 9856 switch (bitrate) { 9857 case BWN_CCK_RATE_1MB: 9858 return (BWN_CCK_RATE_1MB); 9859 case BWN_CCK_RATE_2MB: 9860 return (BWN_CCK_RATE_1MB); 9861 case BWN_CCK_RATE_5MB: 9862 return (BWN_CCK_RATE_2MB); 9863 case BWN_CCK_RATE_11MB: 9864 return (BWN_CCK_RATE_5MB); 9865 case BWN_OFDM_RATE_6MB: 9866 return (BWN_CCK_RATE_5MB); 9867 case BWN_OFDM_RATE_9MB: 9868 return (BWN_OFDM_RATE_6MB); 9869 case BWN_OFDM_RATE_12MB: 9870 return (BWN_OFDM_RATE_9MB); 9871 case BWN_OFDM_RATE_18MB: 9872 return (BWN_OFDM_RATE_12MB); 9873 case BWN_OFDM_RATE_24MB: 9874 return (BWN_OFDM_RATE_18MB); 9875 case BWN_OFDM_RATE_36MB: 9876 return (BWN_OFDM_RATE_24MB); 9877 case BWN_OFDM_RATE_48MB: 9878 return (BWN_OFDM_RATE_36MB); 9879 case BWN_OFDM_RATE_54MB: 9880 return (BWN_OFDM_RATE_48MB); 9881 } 9882 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9883 return (0); 9884 } 9885 9886 static uint32_t 9887 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9888 uint32_t ctl, const void *_data, int len) 9889 { 9890 struct bwn_softc *sc = mac->mac_sc; 9891 uint32_t value = 0; 9892 const uint8_t *data = _data; 9893 9894 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9895 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9896 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9897 9898 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9899 tq->tq_base + BWN_PIO8_TXDATA); 9900 if (len & 3) { 9901 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9902 BWN_PIO8_TXCTL_24_31); 9903 data = &(data[len - 1]); 9904 switch (len & 3) { 9905 case 3: 9906 ctl |= BWN_PIO8_TXCTL_16_23; 9907 value |= (uint32_t)(*data) << 16; 9908 data--; 9909 case 2: 9910 ctl |= BWN_PIO8_TXCTL_8_15; 9911 value |= (uint32_t)(*data) << 8; 9912 data--; 9913 case 1: 9914 value |= (uint32_t)(*data); 9915 } 9916 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9917 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9918 } 9919 9920 return (ctl); 9921 } 9922 9923 static void 9924 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9925 uint16_t offset, uint32_t value) 9926 { 9927 9928 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9929 } 9930 9931 static uint16_t 9932 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9933 uint16_t ctl, const void *_data, int len) 9934 { 9935 struct bwn_softc *sc = mac->mac_sc; 9936 const uint8_t *data = _data; 9937 9938 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9939 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9940 9941 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9942 tq->tq_base + BWN_PIO_TXDATA); 9943 if (len & 1) { 9944 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9945 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9946 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9947 } 9948 9949 return (ctl); 9950 } 9951 9952 static uint16_t 9953 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9954 uint16_t ctl, struct mbuf *m0) 9955 { 9956 int i, j = 0; 9957 uint16_t data = 0; 9958 const uint8_t *buf; 9959 struct mbuf *m = m0; 9960 9961 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9962 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9963 9964 for (; m != NULL; m = m->m_next) { 9965 buf = mtod(m, const uint8_t *); 9966 for (i = 0; i < m->m_len; i++) { 9967 if (!((j++) % 2)) 9968 data |= buf[i]; 9969 else { 9970 data |= (buf[i] << 8); 9971 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9972 data = 0; 9973 } 9974 } 9975 } 9976 if (m0->m_pkthdr.len % 2) { 9977 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9978 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9979 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9980 } 9981 9982 return (ctl); 9983 } 9984 9985 static void 9986 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9987 { 9988 9989 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9990 return; 9991 BWN_WRITE_2(mac, 0x684, 510 + time); 9992 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9993 } 9994 9995 static struct bwn_dma_ring * 9996 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9997 { 9998 9999 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 10000 return (mac->mac_method.dma.wme[WME_AC_BE]); 10001 10002 switch (prio) { 10003 case 3: 10004 return (mac->mac_method.dma.wme[WME_AC_VO]); 10005 case 2: 10006 return (mac->mac_method.dma.wme[WME_AC_VI]); 10007 case 0: 10008 return (mac->mac_method.dma.wme[WME_AC_BE]); 10009 case 1: 10010 return (mac->mac_method.dma.wme[WME_AC_BK]); 10011 } 10012 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10013 return (NULL); 10014 } 10015 10016 static int 10017 bwn_dma_getslot(struct bwn_dma_ring *dr) 10018 { 10019 int slot; 10020 10021 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10022 10023 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10024 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10025 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10026 10027 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10028 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10029 dr->dr_curslot = slot; 10030 dr->dr_usedslot++; 10031 10032 return (slot); 10033 } 10034 10035 static int 10036 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10037 { 10038 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10039 unsigned int a, b, c, d; 10040 unsigned int avg; 10041 uint32_t tmp; 10042 10043 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10044 a = tmp & 0xff; 10045 b = (tmp >> 8) & 0xff; 10046 c = (tmp >> 16) & 0xff; 10047 d = (tmp >> 24) & 0xff; 10048 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10049 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10050 return (ENOENT); 10051 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10052 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10053 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10054 10055 if (ofdm) { 10056 a = (a + 32) & 0x3f; 10057 b = (b + 32) & 0x3f; 10058 c = (c + 32) & 0x3f; 10059 d = (d + 32) & 0x3f; 10060 } 10061 10062 avg = (a + b + c + d + 2) / 4; 10063 if (ofdm) { 10064 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10065 & BWN_HF_4DB_CCK_POWERBOOST) 10066 avg = (avg >= 13) ? (avg - 13) : 0; 10067 } 10068 return (avg); 10069 } 10070 10071 static void 10072 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10073 { 10074 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10075 int rfatt = *rfattp; 10076 int bbatt = *bbattp; 10077 10078 while (1) { 10079 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10080 break; 10081 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10082 break; 10083 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10084 break; 10085 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10086 break; 10087 if (bbatt > lo->bbatt.max) { 10088 bbatt -= 4; 10089 rfatt += 1; 10090 continue; 10091 } 10092 if (bbatt < lo->bbatt.min) { 10093 bbatt += 4; 10094 rfatt -= 1; 10095 continue; 10096 } 10097 if (rfatt > lo->rfatt.max) { 10098 rfatt -= 1; 10099 bbatt += 4; 10100 continue; 10101 } 10102 if (rfatt < lo->rfatt.min) { 10103 rfatt += 1; 10104 bbatt -= 4; 10105 continue; 10106 } 10107 break; 10108 } 10109 10110 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10111 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10112 } 10113 10114 static void 10115 bwn_phy_lock(struct bwn_mac *mac) 10116 { 10117 struct bwn_softc *sc = mac->mac_sc; 10118 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10119 10120 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10121 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10122 10123 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10124 bwn_psctl(mac, BWN_PS_AWAKE); 10125 } 10126 10127 static void 10128 bwn_phy_unlock(struct bwn_mac *mac) 10129 { 10130 struct bwn_softc *sc = mac->mac_sc; 10131 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10132 10133 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10134 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10135 10136 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10137 bwn_psctl(mac, 0); 10138 } 10139 10140 static void 10141 bwn_rf_lock(struct bwn_mac *mac) 10142 { 10143 10144 BWN_WRITE_4(mac, BWN_MACCTL, 10145 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10146 BWN_READ_4(mac, BWN_MACCTL); 10147 DELAY(10); 10148 } 10149 10150 static void 10151 bwn_rf_unlock(struct bwn_mac *mac) 10152 { 10153 10154 BWN_READ_2(mac, BWN_PHYVER); 10155 BWN_WRITE_4(mac, BWN_MACCTL, 10156 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10157 } 10158 10159 static struct bwn_pio_txqueue * 10160 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10161 struct bwn_pio_txpkt **pack) 10162 { 10163 struct bwn_pio *pio = &mac->mac_method.pio; 10164 struct bwn_pio_txqueue *tq = NULL; 10165 unsigned int index; 10166 10167 switch (cookie & 0xf000) { 10168 case 0x1000: 10169 tq = &pio->wme[WME_AC_BK]; 10170 break; 10171 case 0x2000: 10172 tq = &pio->wme[WME_AC_BE]; 10173 break; 10174 case 0x3000: 10175 tq = &pio->wme[WME_AC_VI]; 10176 break; 10177 case 0x4000: 10178 tq = &pio->wme[WME_AC_VO]; 10179 break; 10180 case 0x5000: 10181 tq = &pio->mcast; 10182 break; 10183 } 10184 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10185 if (tq == NULL) 10186 return (NULL); 10187 index = (cookie & 0x0fff); 10188 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10189 if (index >= N(tq->tq_pkts)) 10190 return (NULL); 10191 *pack = &tq->tq_pkts[index]; 10192 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10193 return (tq); 10194 } 10195 10196 static void 10197 bwn_txpwr(void *arg, int npending) 10198 { 10199 struct bwn_mac *mac = arg; 10200 struct bwn_softc *sc = mac->mac_sc; 10201 10202 BWN_LOCK(sc); 10203 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10204 mac->mac_phy.set_txpwr != NULL) 10205 mac->mac_phy.set_txpwr(mac); 10206 BWN_UNLOCK(sc); 10207 } 10208 10209 static void 10210 bwn_task_15s(struct bwn_mac *mac) 10211 { 10212 uint16_t reg; 10213 10214 if (mac->mac_fw.opensource) { 10215 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10216 if (reg) { 10217 bwn_restart(mac, "fw watchdog"); 10218 return; 10219 } 10220 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10221 } 10222 if (mac->mac_phy.task_15s) 10223 mac->mac_phy.task_15s(mac); 10224 10225 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10226 } 10227 10228 static void 10229 bwn_task_30s(struct bwn_mac *mac) 10230 { 10231 10232 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10233 return; 10234 mac->mac_noise.noi_running = 1; 10235 mac->mac_noise.noi_nsamples = 0; 10236 10237 bwn_noise_gensample(mac); 10238 } 10239 10240 static void 10241 bwn_task_60s(struct bwn_mac *mac) 10242 { 10243 10244 if (mac->mac_phy.task_60s) 10245 mac->mac_phy.task_60s(mac); 10246 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10247 } 10248 10249 static void 10250 bwn_tasks(void *arg) 10251 { 10252 struct bwn_mac *mac = arg; 10253 struct bwn_softc *sc = mac->mac_sc; 10254 10255 BWN_ASSERT_LOCKED(sc); 10256 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10257 return; 10258 10259 if (mac->mac_task_state % 4 == 0) 10260 bwn_task_60s(mac); 10261 if (mac->mac_task_state % 2 == 0) 10262 bwn_task_30s(mac); 10263 bwn_task_15s(mac); 10264 10265 mac->mac_task_state++; 10266 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10267 } 10268 10269 static int 10270 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10271 { 10272 struct bwn_softc *sc = mac->mac_sc; 10273 10274 KASSERT(a == 0, ("not support APHY\n")); 10275 10276 switch (plcp->o.raw[0] & 0xf) { 10277 case 0xb: 10278 return (BWN_OFDM_RATE_6MB); 10279 case 0xf: 10280 return (BWN_OFDM_RATE_9MB); 10281 case 0xa: 10282 return (BWN_OFDM_RATE_12MB); 10283 case 0xe: 10284 return (BWN_OFDM_RATE_18MB); 10285 case 0x9: 10286 return (BWN_OFDM_RATE_24MB); 10287 case 0xd: 10288 return (BWN_OFDM_RATE_36MB); 10289 case 0x8: 10290 return (BWN_OFDM_RATE_48MB); 10291 case 0xc: 10292 return (BWN_OFDM_RATE_54MB); 10293 } 10294 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10295 plcp->o.raw[0] & 0xf); 10296 return (-1); 10297 } 10298 10299 static int 10300 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10301 { 10302 struct bwn_softc *sc = mac->mac_sc; 10303 10304 switch (plcp->o.raw[0]) { 10305 case 0x0a: 10306 return (BWN_CCK_RATE_1MB); 10307 case 0x14: 10308 return (BWN_CCK_RATE_2MB); 10309 case 0x37: 10310 return (BWN_CCK_RATE_5MB); 10311 case 0x6e: 10312 return (BWN_CCK_RATE_11MB); 10313 } 10314 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10315 return (-1); 10316 } 10317 10318 static void 10319 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10320 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10321 int rssi, int noise) 10322 { 10323 struct bwn_softc *sc = mac->mac_sc; 10324 const struct ieee80211_frame_min *wh; 10325 uint64_t tsf; 10326 uint16_t low_mactime_now; 10327 10328 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10329 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10330 10331 wh = mtod(m, const struct ieee80211_frame_min *); 10332 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 10333 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10334 10335 bwn_tsf_read(mac, &tsf); 10336 low_mactime_now = tsf; 10337 tsf = tsf & ~0xffffULL; 10338 tsf += le16toh(rxhdr->mac_time); 10339 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10340 tsf -= 0x10000; 10341 10342 sc->sc_rx_th.wr_tsf = tsf; 10343 sc->sc_rx_th.wr_rate = rate; 10344 sc->sc_rx_th.wr_antsignal = rssi; 10345 sc->sc_rx_th.wr_antnoise = noise; 10346 } 10347 10348 static void 10349 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10350 { 10351 uint32_t low, high; 10352 10353 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10354 ("%s:%d: fail", __func__, __LINE__)); 10355 10356 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10357 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10358 *tsf = high; 10359 *tsf <<= 32; 10360 *tsf |= low; 10361 } 10362 10363 static int 10364 bwn_dma_attach(struct bwn_mac *mac) 10365 { 10366 struct bwn_dma *dma = &mac->mac_method.dma; 10367 struct bwn_softc *sc = mac->mac_sc; 10368 bus_addr_t lowaddr = 0; 10369 int error; 10370 10371 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10372 return (0); 10373 10374 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10375 10376 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10377 10378 dma->dmatype = bwn_dma_gettype(mac); 10379 if (dma->dmatype == BWN_DMA_30BIT) 10380 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10381 else if (dma->dmatype == BWN_DMA_32BIT) 10382 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10383 else 10384 lowaddr = BUS_SPACE_MAXADDR; 10385 10386 /* 10387 * Create top level DMA tag 10388 */ 10389 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10390 BWN_ALIGN, 0, /* alignment, bounds */ 10391 lowaddr, /* lowaddr */ 10392 BUS_SPACE_MAXADDR, /* highaddr */ 10393 NULL, NULL, /* filter, filterarg */ 10394 MAXBSIZE, /* maxsize */ 10395 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10396 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10397 0, /* flags */ 10398 NULL, NULL, /* lockfunc, lockarg */ 10399 &dma->parent_dtag); 10400 if (error) { 10401 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10402 return (error); 10403 } 10404 10405 /* 10406 * Create TX/RX mbuf DMA tag 10407 */ 10408 error = bus_dma_tag_create(dma->parent_dtag, 10409 1, 10410 0, 10411 BUS_SPACE_MAXADDR, 10412 BUS_SPACE_MAXADDR, 10413 NULL, NULL, 10414 MCLBYTES, 10415 1, 10416 BUS_SPACE_MAXSIZE_32BIT, 10417 0, 10418 NULL, NULL, 10419 &dma->rxbuf_dtag); 10420 if (error) { 10421 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10422 goto fail0; 10423 } 10424 error = bus_dma_tag_create(dma->parent_dtag, 10425 1, 10426 0, 10427 BUS_SPACE_MAXADDR, 10428 BUS_SPACE_MAXADDR, 10429 NULL, NULL, 10430 MCLBYTES, 10431 1, 10432 BUS_SPACE_MAXSIZE_32BIT, 10433 0, 10434 NULL, NULL, 10435 &dma->txbuf_dtag); 10436 if (error) { 10437 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10438 goto fail1; 10439 } 10440 10441 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10442 if (!dma->wme[WME_AC_BK]) 10443 goto fail2; 10444 10445 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10446 if (!dma->wme[WME_AC_BE]) 10447 goto fail3; 10448 10449 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10450 if (!dma->wme[WME_AC_VI]) 10451 goto fail4; 10452 10453 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10454 if (!dma->wme[WME_AC_VO]) 10455 goto fail5; 10456 10457 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10458 if (!dma->mcast) 10459 goto fail6; 10460 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10461 if (!dma->rx) 10462 goto fail7; 10463 10464 return (error); 10465 10466 fail7: bwn_dma_ringfree(&dma->mcast); 10467 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10468 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10469 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10470 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10471 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10472 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10473 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10474 return (error); 10475 } 10476 10477 static struct bwn_dma_ring * 10478 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10479 uint16_t cookie, int *slot) 10480 { 10481 struct bwn_dma *dma = &mac->mac_method.dma; 10482 struct bwn_dma_ring *dr; 10483 struct bwn_softc *sc = mac->mac_sc; 10484 10485 BWN_ASSERT_LOCKED(mac->mac_sc); 10486 10487 switch (cookie & 0xf000) { 10488 case 0x1000: 10489 dr = dma->wme[WME_AC_BK]; 10490 break; 10491 case 0x2000: 10492 dr = dma->wme[WME_AC_BE]; 10493 break; 10494 case 0x3000: 10495 dr = dma->wme[WME_AC_VI]; 10496 break; 10497 case 0x4000: 10498 dr = dma->wme[WME_AC_VO]; 10499 break; 10500 case 0x5000: 10501 dr = dma->mcast; 10502 break; 10503 default: 10504 dr = NULL; 10505 KASSERT(0 == 1, 10506 ("invalid cookie value %d", cookie & 0xf000)); 10507 } 10508 *slot = (cookie & 0x0fff); 10509 if (*slot < 0 || *slot >= dr->dr_numslots) { 10510 /* 10511 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10512 * that it occurs events which have same H/W sequence numbers. 10513 * When it's occurred just prints a WARNING msgs and ignores. 10514 */ 10515 KASSERT(status->seq == dma->lastseq, 10516 ("%s:%d: fail", __func__, __LINE__)); 10517 device_printf(sc->sc_dev, 10518 "out of slot ranges (0 < %d < %d)\n", *slot, 10519 dr->dr_numslots); 10520 return (NULL); 10521 } 10522 dma->lastseq = status->seq; 10523 return (dr); 10524 } 10525 10526 static void 10527 bwn_dma_stop(struct bwn_mac *mac) 10528 { 10529 struct bwn_dma *dma; 10530 10531 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10532 return; 10533 dma = &mac->mac_method.dma; 10534 10535 bwn_dma_ringstop(&dma->rx); 10536 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10537 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10538 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10539 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10540 bwn_dma_ringstop(&dma->mcast); 10541 } 10542 10543 static void 10544 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10545 { 10546 10547 if (dr == NULL) 10548 return; 10549 10550 bwn_dma_cleanup(*dr); 10551 } 10552 10553 static void 10554 bwn_pio_stop(struct bwn_mac *mac) 10555 { 10556 struct bwn_pio *pio; 10557 10558 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10559 return; 10560 pio = &mac->mac_method.pio; 10561 10562 bwn_destroy_queue_tx(&pio->mcast); 10563 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10564 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10565 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10566 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10567 } 10568 10569 static void 10570 bwn_led_attach(struct bwn_mac *mac) 10571 { 10572 struct bwn_softc *sc = mac->mac_sc; 10573 const uint8_t *led_act = NULL; 10574 uint16_t val[BWN_LED_MAX]; 10575 int i; 10576 10577 sc->sc_led_idle = (2350 * hz) / 1000; 10578 sc->sc_led_blink = 1; 10579 10580 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10581 if (siba_get_pci_subvendor(sc->sc_dev) == 10582 bwn_vendor_led_act[i].vid) { 10583 led_act = bwn_vendor_led_act[i].led_act; 10584 break; 10585 } 10586 } 10587 if (led_act == NULL) 10588 led_act = bwn_default_led_act; 10589 10590 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10591 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10592 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10593 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10594 10595 for (i = 0; i < BWN_LED_MAX; ++i) { 10596 struct bwn_led *led = &sc->sc_leds[i]; 10597 10598 if (val[i] == 0xff) { 10599 led->led_act = led_act[i]; 10600 } else { 10601 if (val[i] & BWN_LED_ACT_LOW) 10602 led->led_flags |= BWN_LED_F_ACTLOW; 10603 led->led_act = val[i] & BWN_LED_ACT_MASK; 10604 } 10605 led->led_mask = (1 << i); 10606 10607 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10608 led->led_act == BWN_LED_ACT_BLINK_POLL || 10609 led->led_act == BWN_LED_ACT_BLINK) { 10610 led->led_flags |= BWN_LED_F_BLINK; 10611 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10612 led->led_flags |= BWN_LED_F_POLLABLE; 10613 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10614 led->led_flags |= BWN_LED_F_SLOW; 10615 10616 if (sc->sc_blink_led == NULL) { 10617 sc->sc_blink_led = led; 10618 if (led->led_flags & BWN_LED_F_SLOW) 10619 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10620 } 10621 } 10622 10623 DPRINTF(sc, BWN_DEBUG_LED, 10624 "%dth led, act %d, lowact %d\n", i, 10625 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10626 } 10627 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10628 } 10629 10630 static __inline uint16_t 10631 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10632 { 10633 10634 if (led->led_flags & BWN_LED_F_ACTLOW) 10635 on = !on; 10636 if (on) 10637 val |= led->led_mask; 10638 else 10639 val &= ~led->led_mask; 10640 return val; 10641 } 10642 10643 static void 10644 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10645 { 10646 struct bwn_softc *sc = mac->mac_sc; 10647 struct ifnet *ifp = sc->sc_ifp; 10648 struct ieee80211com *ic = ifp->if_l2com; 10649 uint16_t val; 10650 int i; 10651 10652 if (nstate == IEEE80211_S_INIT) { 10653 callout_stop(&sc->sc_led_blink_ch); 10654 sc->sc_led_blinking = 0; 10655 } 10656 10657 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10658 return; 10659 10660 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10661 for (i = 0; i < BWN_LED_MAX; ++i) { 10662 struct bwn_led *led = &sc->sc_leds[i]; 10663 int on; 10664 10665 if (led->led_act == BWN_LED_ACT_UNKN || 10666 led->led_act == BWN_LED_ACT_NULL) 10667 continue; 10668 10669 if ((led->led_flags & BWN_LED_F_BLINK) && 10670 nstate != IEEE80211_S_INIT) 10671 continue; 10672 10673 switch (led->led_act) { 10674 case BWN_LED_ACT_ON: /* Always on */ 10675 on = 1; 10676 break; 10677 case BWN_LED_ACT_OFF: /* Always off */ 10678 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10679 on = 0; 10680 break; 10681 default: 10682 on = 1; 10683 switch (nstate) { 10684 case IEEE80211_S_INIT: 10685 on = 0; 10686 break; 10687 case IEEE80211_S_RUN: 10688 if (led->led_act == BWN_LED_ACT_11G && 10689 ic->ic_curmode != IEEE80211_MODE_11G) 10690 on = 0; 10691 break; 10692 default: 10693 if (led->led_act == BWN_LED_ACT_ASSOC) 10694 on = 0; 10695 break; 10696 } 10697 break; 10698 } 10699 10700 val = bwn_led_onoff(led, val, on); 10701 } 10702 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10703 } 10704 10705 static void 10706 bwn_led_event(struct bwn_mac *mac, int event) 10707 { 10708 struct bwn_softc *sc = mac->mac_sc; 10709 struct bwn_led *led = sc->sc_blink_led; 10710 int rate; 10711 10712 if (event == BWN_LED_EVENT_POLL) { 10713 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10714 return; 10715 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10716 return; 10717 } 10718 10719 sc->sc_led_ticks = ticks; 10720 if (sc->sc_led_blinking) 10721 return; 10722 10723 switch (event) { 10724 case BWN_LED_EVENT_RX: 10725 rate = sc->sc_rx_rate; 10726 break; 10727 case BWN_LED_EVENT_TX: 10728 rate = sc->sc_tx_rate; 10729 break; 10730 case BWN_LED_EVENT_POLL: 10731 rate = 0; 10732 break; 10733 default: 10734 panic("unknown LED event %d\n", event); 10735 break; 10736 } 10737 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10738 bwn_led_duration[rate].off_dur); 10739 } 10740 10741 static void 10742 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10743 { 10744 struct bwn_softc *sc = mac->mac_sc; 10745 struct bwn_led *led = sc->sc_blink_led; 10746 uint16_t val; 10747 10748 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10749 val = bwn_led_onoff(led, val, 1); 10750 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10751 10752 if (led->led_flags & BWN_LED_F_SLOW) { 10753 BWN_LED_SLOWDOWN(on_dur); 10754 BWN_LED_SLOWDOWN(off_dur); 10755 } 10756 10757 sc->sc_led_blinking = 1; 10758 sc->sc_led_blink_offdur = off_dur; 10759 10760 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10761 } 10762 10763 static void 10764 bwn_led_blink_next(void *arg) 10765 { 10766 struct bwn_mac *mac = arg; 10767 struct bwn_softc *sc = mac->mac_sc; 10768 uint16_t val; 10769 10770 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10771 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10772 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10773 10774 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10775 bwn_led_blink_end, mac); 10776 } 10777 10778 static void 10779 bwn_led_blink_end(void *arg) 10780 { 10781 struct bwn_mac *mac = arg; 10782 struct bwn_softc *sc = mac->mac_sc; 10783 10784 sc->sc_led_blinking = 0; 10785 } 10786 10787 static int 10788 bwn_suspend(device_t dev) 10789 { 10790 struct bwn_softc *sc = device_get_softc(dev); 10791 10792 bwn_stop(sc, 1); 10793 return (0); 10794 } 10795 10796 static int 10797 bwn_resume(device_t dev) 10798 { 10799 struct bwn_softc *sc = device_get_softc(dev); 10800 struct ifnet *ifp = sc->sc_ifp; 10801 10802 if (ifp->if_flags & IFF_UP) 10803 bwn_init(sc); 10804 return (0); 10805 } 10806 10807 static void 10808 bwn_rfswitch(void *arg) 10809 { 10810 struct bwn_softc *sc = arg; 10811 struct bwn_mac *mac = sc->sc_curmac; 10812 int cur = 0, prev = 0; 10813 10814 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10815 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10816 10817 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10818 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10819 & BWN_RF_HWENABLED_HI_MASK)) 10820 cur = 1; 10821 } else { 10822 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10823 & BWN_RF_HWENABLED_LO_MASK) 10824 cur = 1; 10825 } 10826 10827 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10828 prev = 1; 10829 10830 if (cur != prev) { 10831 if (cur) 10832 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10833 else 10834 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10835 10836 device_printf(sc->sc_dev, 10837 "status of RF switch is changed to %s\n", 10838 cur ? "ON" : "OFF"); 10839 if (cur != mac->mac_phy.rf_on) { 10840 if (cur) 10841 bwn_rf_turnon(mac); 10842 else 10843 bwn_rf_turnoff(mac); 10844 } 10845 } 10846 10847 callout_schedule(&sc->sc_rfswitch_ch, hz); 10848 } 10849 10850 static void 10851 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10852 { 10853 struct bwn_phy *phy = &mac->mac_phy; 10854 struct bwn_phy_lp *plp = &phy->phy_lp; 10855 10856 plp->plp_antenna = BWN_ANT_DEFAULT; 10857 } 10858 10859 static int 10860 bwn_phy_lp_init(struct bwn_mac *mac) 10861 { 10862 static const struct bwn_stxtable tables[] = { 10863 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10864 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10865 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10866 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10867 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10868 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10869 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10870 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10871 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10872 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10873 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10874 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10875 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10876 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10877 { 2, 11, 0x40, 0, 0x0f } 10878 }; 10879 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10880 struct bwn_softc *sc = mac->mac_sc; 10881 const struct bwn_stxtable *st; 10882 struct ifnet *ifp = sc->sc_ifp; 10883 struct ieee80211com *ic = ifp->if_l2com; 10884 int i, error; 10885 uint16_t tmp; 10886 10887 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10888 bwn_phy_lp_bbinit(mac); 10889 10890 /* initialize RF */ 10891 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10892 DELAY(1); 10893 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10894 DELAY(1); 10895 10896 if (mac->mac_phy.rf_ver == 0x2062) 10897 bwn_phy_lp_b2062_init(mac); 10898 else { 10899 bwn_phy_lp_b2063_init(mac); 10900 10901 /* synchronize stx table. */ 10902 for (i = 0; i < N(tables); i++) { 10903 st = &tables[i]; 10904 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10905 tmp >>= st->st_rfshift; 10906 tmp <<= st->st_physhift; 10907 BWN_PHY_SETMASK(mac, 10908 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10909 ~(st->st_mask << st->st_physhift), tmp); 10910 } 10911 10912 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10913 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10914 } 10915 10916 /* calibrate RC */ 10917 if (mac->mac_phy.rev >= 2) 10918 bwn_phy_lp_rxcal_r2(mac); 10919 else if (!plp->plp_rccap) { 10920 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10921 bwn_phy_lp_rccal_r12(mac); 10922 } else 10923 bwn_phy_lp_set_rccap(mac); 10924 10925 error = bwn_phy_lp_switch_channel(mac, 7); 10926 if (error) 10927 device_printf(sc->sc_dev, 10928 "failed to change channel 7 (%d)\n", error); 10929 bwn_phy_lp_txpctl_init(mac); 10930 bwn_phy_lp_calib(mac); 10931 return (0); 10932 } 10933 10934 static uint16_t 10935 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10936 { 10937 10938 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10939 return (BWN_READ_2(mac, BWN_PHYDATA)); 10940 } 10941 10942 static void 10943 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10944 { 10945 10946 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10947 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10948 } 10949 10950 static void 10951 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10952 uint16_t set) 10953 { 10954 10955 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10956 BWN_WRITE_2(mac, BWN_PHYDATA, 10957 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10958 } 10959 10960 static uint16_t 10961 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10962 { 10963 10964 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10965 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10966 reg |= 0x100; 10967 if (mac->mac_phy.rev >= 2) 10968 reg |= 0x200; 10969 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10970 return BWN_READ_2(mac, BWN_RFDATALO); 10971 } 10972 10973 static void 10974 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10975 { 10976 10977 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10978 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10979 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10980 } 10981 10982 static void 10983 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10984 { 10985 10986 if (on) { 10987 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10988 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10989 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10990 return; 10991 } 10992 10993 if (mac->mac_phy.rev >= 2) { 10994 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10995 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10996 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10997 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10998 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10999 return; 11000 } 11001 11002 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 11003 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 11004 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 11005 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 11006 } 11007 11008 static int 11009 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11010 { 11011 struct bwn_phy *phy = &mac->mac_phy; 11012 struct bwn_phy_lp *plp = &phy->phy_lp; 11013 int error; 11014 11015 if (phy->rf_ver == 0x2063) { 11016 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11017 if (error) 11018 return (error); 11019 } else { 11020 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11021 if (error) 11022 return (error); 11023 bwn_phy_lp_set_anafilter(mac, chan); 11024 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11025 } 11026 11027 plp->plp_chan = chan; 11028 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11029 return (0); 11030 } 11031 11032 static uint32_t 11033 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11034 { 11035 struct bwn_softc *sc = mac->mac_sc; 11036 struct ifnet *ifp = sc->sc_ifp; 11037 struct ieee80211com *ic = ifp->if_l2com; 11038 11039 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11040 } 11041 11042 static void 11043 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11044 { 11045 struct bwn_phy *phy = &mac->mac_phy; 11046 struct bwn_phy_lp *plp = &phy->phy_lp; 11047 11048 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11049 return; 11050 11051 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11052 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11053 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11054 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11055 plp->plp_antenna = antenna; 11056 } 11057 11058 static void 11059 bwn_phy_lp_task_60s(struct bwn_mac *mac) 11060 { 11061 11062 bwn_phy_lp_calib(mac); 11063 } 11064 11065 static void 11066 bwn_phy_lp_readsprom(struct bwn_mac *mac) 11067 { 11068 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11069 struct bwn_softc *sc = mac->mac_sc; 11070 struct ifnet *ifp = sc->sc_ifp; 11071 struct ieee80211com *ic = ifp->if_l2com; 11072 11073 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11074 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 11075 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 11076 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 11077 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 11078 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 11079 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 11080 return; 11081 } 11082 11083 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 11084 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 11085 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 11086 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 11087 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 11088 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 11089 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 11090 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 11091 } 11092 11093 static void 11094 bwn_phy_lp_bbinit(struct bwn_mac *mac) 11095 { 11096 11097 bwn_phy_lp_tblinit(mac); 11098 if (mac->mac_phy.rev >= 2) 11099 bwn_phy_lp_bbinit_r2(mac); 11100 else 11101 bwn_phy_lp_bbinit_r01(mac); 11102 } 11103 11104 static void 11105 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11106 { 11107 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11108 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11109 struct bwn_softc *sc = mac->mac_sc; 11110 struct ifnet *ifp = sc->sc_ifp; 11111 struct ieee80211com *ic = ifp->if_l2com; 11112 11113 bwn_phy_lp_set_txgain(mac, 11114 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11115 bwn_phy_lp_set_bbmult(mac, 150); 11116 } 11117 11118 static void 11119 bwn_phy_lp_calib(struct bwn_mac *mac) 11120 { 11121 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11122 struct bwn_softc *sc = mac->mac_sc; 11123 struct ifnet *ifp = sc->sc_ifp; 11124 struct ieee80211com *ic = ifp->if_l2com; 11125 const struct bwn_rxcompco *rc = NULL; 11126 struct bwn_txgain ogain; 11127 int i, omode, oafeovr, orf, obbmult; 11128 uint8_t mode, fc = 0; 11129 11130 if (plp->plp_chanfullcal != plp->plp_chan) { 11131 plp->plp_chanfullcal = plp->plp_chan; 11132 fc = 1; 11133 } 11134 11135 bwn_mac_suspend(mac); 11136 11137 /* BlueTooth Coexistance Override */ 11138 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11139 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11140 11141 if (mac->mac_phy.rev >= 2) 11142 bwn_phy_lp_digflt_save(mac); 11143 bwn_phy_lp_get_txpctlmode(mac); 11144 mode = plp->plp_txpctlmode; 11145 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11146 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11147 bwn_phy_lp_bugfix(mac); 11148 if (mac->mac_phy.rev >= 2 && fc == 1) { 11149 bwn_phy_lp_get_txpctlmode(mac); 11150 omode = plp->plp_txpctlmode; 11151 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11152 if (oafeovr) 11153 ogain = bwn_phy_lp_get_txgain(mac); 11154 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11155 obbmult = bwn_phy_lp_get_bbmult(mac); 11156 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11157 if (oafeovr) 11158 bwn_phy_lp_set_txgain(mac, &ogain); 11159 bwn_phy_lp_set_bbmult(mac, obbmult); 11160 bwn_phy_lp_set_txpctlmode(mac, omode); 11161 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11162 } 11163 bwn_phy_lp_set_txpctlmode(mac, mode); 11164 if (mac->mac_phy.rev >= 2) 11165 bwn_phy_lp_digflt_restore(mac); 11166 11167 /* do RX IQ Calculation; assumes that noise is true. */ 11168 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11169 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11170 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11171 rc = &bwn_rxcompco_5354[i]; 11172 } 11173 } else if (mac->mac_phy.rev >= 2) 11174 rc = &bwn_rxcompco_r2; 11175 else { 11176 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11177 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11178 rc = &bwn_rxcompco_r12[i]; 11179 } 11180 } 11181 if (rc == NULL) 11182 goto fail; 11183 11184 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11185 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11186 11187 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11188 11189 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11190 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11191 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11192 } else { 11193 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11194 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11195 } 11196 11197 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11198 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11199 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11200 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11201 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11202 bwn_phy_lp_set_deaf(mac, 0); 11203 /* XXX no checking return value? */ 11204 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11205 bwn_phy_lp_clear_deaf(mac, 0); 11206 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11207 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11208 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11209 11210 /* disable RX GAIN override. */ 11211 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11212 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11213 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11214 if (mac->mac_phy.rev >= 2) { 11215 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11216 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11217 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11218 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11219 } 11220 } else { 11221 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11222 } 11223 11224 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11225 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11226 fail: 11227 bwn_mac_enable(mac); 11228 } 11229 11230 static void 11231 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11232 { 11233 11234 if (on) { 11235 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11236 return; 11237 } 11238 11239 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11240 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11241 } 11242 11243 static int 11244 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11245 { 11246 static const struct bwn_b206x_chan *bc = NULL; 11247 struct bwn_softc *sc = mac->mac_sc; 11248 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11249 tmp[6]; 11250 uint16_t old, scale, tmp16; 11251 int i, div; 11252 11253 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11254 if (bwn_b2063_chantable[i].bc_chan == chan) { 11255 bc = &bwn_b2063_chantable[i]; 11256 break; 11257 } 11258 } 11259 if (bc == NULL) 11260 return (EINVAL); 11261 11262 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11263 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11264 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11265 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11266 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11267 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11268 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11269 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11270 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11271 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11272 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11273 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11274 11275 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11276 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11277 11278 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11279 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11280 freqref = freqxtal * 3; 11281 div = (freqxtal <= 26000000 ? 1 : 2); 11282 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11283 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11284 999999) / 1000000) + 1; 11285 11286 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11287 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11288 0xfff8, timeout >> 2); 11289 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11290 0xff9f,timeout << 5); 11291 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11292 11293 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11294 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11295 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11296 11297 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11298 (timeoutref + 1)) - 1; 11299 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11300 0xf0, count >> 8); 11301 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11302 11303 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11304 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11305 while (tmp[1] >= freqref) { 11306 tmp[0]++; 11307 tmp[1] -= freqref; 11308 } 11309 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11310 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11311 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11312 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11313 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11314 11315 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11316 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11317 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11318 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11319 11320 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11321 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11322 11323 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11324 scale = 1; 11325 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11326 } else { 11327 scale = 0; 11328 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11329 } 11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11331 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11332 11333 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11334 (scale + 1); 11335 if (tmp[5] > 150) 11336 tmp[5] = 0; 11337 11338 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11339 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11340 11341 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11342 if (freqxtal > 26000000) 11343 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11344 else 11345 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11346 11347 if (val[0] == 45) 11348 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11349 else 11350 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11351 11352 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11353 DELAY(1); 11354 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11355 11356 /* VCO Calibration */ 11357 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11358 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11359 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11360 DELAY(1); 11361 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11362 DELAY(1); 11363 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11364 DELAY(1); 11365 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11366 DELAY(300); 11367 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11368 11369 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11370 return (0); 11371 } 11372 11373 static int 11374 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11375 { 11376 struct bwn_softc *sc = mac->mac_sc; 11377 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11378 const struct bwn_b206x_chan *bc = NULL; 11379 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11380 uint32_t tmp[9]; 11381 int i; 11382 11383 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11384 if (bwn_b2062_chantable[i].bc_chan == chan) { 11385 bc = &bwn_b2062_chantable[i]; 11386 break; 11387 } 11388 } 11389 11390 if (bc == NULL) 11391 return (EINVAL); 11392 11393 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11394 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11395 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11396 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11397 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11398 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11399 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11400 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11401 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11402 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11403 11404 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11405 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11406 bwn_phy_lp_b2062_reset_pllbias(mac); 11407 tmp[0] = freqxtal / 1000; 11408 tmp[1] = plp->plp_div * 1000; 11409 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11410 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11411 tmp[2] *= 2; 11412 tmp[3] = 48 * tmp[0]; 11413 tmp[5] = tmp[2] / tmp[3]; 11414 tmp[6] = tmp[2] % tmp[3]; 11415 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11416 tmp[4] = tmp[6] * 0x100; 11417 tmp[5] = tmp[4] / tmp[3]; 11418 tmp[6] = tmp[4] % tmp[3]; 11419 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11420 tmp[4] = tmp[6] * 0x100; 11421 tmp[5] = tmp[4] / tmp[3]; 11422 tmp[6] = tmp[4] % tmp[3]; 11423 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11424 tmp[4] = tmp[6] * 0x100; 11425 tmp[5] = tmp[4] / tmp[3]; 11426 tmp[6] = tmp[4] % tmp[3]; 11427 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11428 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11429 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11430 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11431 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11432 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11433 11434 bwn_phy_lp_b2062_vco_calib(mac); 11435 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11436 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11437 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11438 bwn_phy_lp_b2062_reset_pllbias(mac); 11439 bwn_phy_lp_b2062_vco_calib(mac); 11440 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11441 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11442 return (EIO); 11443 } 11444 } 11445 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11446 return (0); 11447 } 11448 11449 static void 11450 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11451 { 11452 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11453 uint16_t tmp = (channel == 14); 11454 11455 if (mac->mac_phy.rev < 2) { 11456 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11457 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11458 bwn_phy_lp_set_rccap(mac); 11459 return; 11460 } 11461 11462 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11463 } 11464 11465 static void 11466 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11467 { 11468 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11469 struct bwn_softc *sc = mac->mac_sc; 11470 struct ifnet *ifp = sc->sc_ifp; 11471 struct ieee80211com *ic = ifp->if_l2com; 11472 uint16_t iso, tmp[3]; 11473 11474 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11475 11476 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11477 iso = plp->plp_txisoband_m; 11478 else if (freq <= 5320) 11479 iso = plp->plp_txisoband_l; 11480 else if (freq <= 5700) 11481 iso = plp->plp_txisoband_m; 11482 else 11483 iso = plp->plp_txisoband_h; 11484 11485 tmp[0] = ((iso - 26) / 12) << 12; 11486 tmp[1] = tmp[0] + 0x1000; 11487 tmp[2] = tmp[0] + 0x2000; 11488 11489 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11490 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11491 } 11492 11493 static void 11494 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11495 { 11496 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11497 int i; 11498 static const uint16_t addr[] = { 11499 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11500 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11501 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11502 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11503 BWN_PHY_OFDM(0xcf), 11504 }; 11505 static const uint16_t val[] = { 11506 0xde5e, 0xe832, 0xe331, 0x4d26, 11507 0x0026, 0x1420, 0x0020, 0xfe08, 11508 0x0008, 11509 }; 11510 11511 for (i = 0; i < N(addr); i++) { 11512 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11513 BWN_PHY_WRITE(mac, addr[i], val[i]); 11514 } 11515 } 11516 11517 static void 11518 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11519 { 11520 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11521 struct bwn_softc *sc = mac->mac_sc; 11522 uint16_t ctl; 11523 11524 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11525 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11526 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11527 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11528 break; 11529 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11530 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11531 break; 11532 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11533 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11534 break; 11535 default: 11536 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11537 device_printf(sc->sc_dev, "unknown command mode\n"); 11538 break; 11539 } 11540 } 11541 11542 static void 11543 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11544 { 11545 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11546 uint16_t ctl; 11547 uint8_t old; 11548 11549 bwn_phy_lp_get_txpctlmode(mac); 11550 old = plp->plp_txpctlmode; 11551 if (old == mode) 11552 return; 11553 plp->plp_txpctlmode = mode; 11554 11555 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11556 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11557 plp->plp_tssiidx); 11558 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11559 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11560 11561 /* disable TX GAIN override */ 11562 if (mac->mac_phy.rev < 2) 11563 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11564 else { 11565 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11566 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11567 } 11568 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11569 11570 plp->plp_txpwridx = -1; 11571 } 11572 if (mac->mac_phy.rev >= 2) { 11573 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11574 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11575 else 11576 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11577 } 11578 11579 /* writes TX Power Control mode */ 11580 switch (plp->plp_txpctlmode) { 11581 case BWN_PHYLP_TXPCTL_OFF: 11582 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11583 break; 11584 case BWN_PHYLP_TXPCTL_ON_HW: 11585 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11586 break; 11587 case BWN_PHYLP_TXPCTL_ON_SW: 11588 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11589 break; 11590 default: 11591 ctl = 0; 11592 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11593 } 11594 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11595 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11596 } 11597 11598 static void 11599 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11600 { 11601 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11602 struct bwn_softc *sc = mac->mac_sc; 11603 const unsigned int size = 256; 11604 struct bwn_txgain tg; 11605 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11606 uint16_t tssinpt, tssiidx, value[2]; 11607 uint8_t mode; 11608 int8_t txpwridx; 11609 11610 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11611 M_NOWAIT | M_ZERO); 11612 if (tabs == NULL) { 11613 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11614 return; 11615 } 11616 11617 bwn_phy_lp_get_txpctlmode(mac); 11618 mode = plp->plp_txpctlmode; 11619 txpwridx = plp->plp_txpwridx; 11620 tssinpt = plp->plp_tssinpt; 11621 tssiidx = plp->plp_tssiidx; 11622 11623 bwn_tab_read_multi(mac, 11624 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11625 BWN_TAB_4(7, 0x140), size, tabs); 11626 11627 bwn_phy_lp_tblinit(mac); 11628 bwn_phy_lp_bbinit(mac); 11629 bwn_phy_lp_txpctl_init(mac); 11630 bwn_phy_lp_rf_onoff(mac, 1); 11631 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11632 11633 bwn_tab_write_multi(mac, 11634 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11635 BWN_TAB_4(7, 0x140), size, tabs); 11636 11637 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11638 plp->plp_tssinpt = tssinpt; 11639 plp->plp_tssiidx = tssiidx; 11640 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11641 if (txpwridx != -1) { 11642 /* set TX power by index */ 11643 plp->plp_txpwridx = txpwridx; 11644 bwn_phy_lp_get_txpctlmode(mac); 11645 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11646 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11647 if (mac->mac_phy.rev >= 2) { 11648 rxcomp = bwn_tab_read(mac, 11649 BWN_TAB_4(7, txpwridx + 320)); 11650 txgain = bwn_tab_read(mac, 11651 BWN_TAB_4(7, txpwridx + 192)); 11652 tg.tg_pad = (txgain >> 16) & 0xff; 11653 tg.tg_gm = txgain & 0xff; 11654 tg.tg_pga = (txgain >> 8) & 0xff; 11655 tg.tg_dac = (rxcomp >> 28) & 0xff; 11656 bwn_phy_lp_set_txgain(mac, &tg); 11657 } else { 11658 rxcomp = bwn_tab_read(mac, 11659 BWN_TAB_4(10, txpwridx + 320)); 11660 txgain = bwn_tab_read(mac, 11661 BWN_TAB_4(10, txpwridx + 192)); 11662 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11663 0xf800, (txgain >> 4) & 0x7fff); 11664 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11665 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11666 } 11667 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11668 11669 /* set TX IQCC */ 11670 value[0] = (rxcomp >> 10) & 0x3ff; 11671 value[1] = rxcomp & 0x3ff; 11672 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11673 11674 coeff = bwn_tab_read(mac, 11675 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11676 BWN_TAB_4(10, txpwridx + 448)); 11677 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11678 if (mac->mac_phy.rev >= 2) { 11679 rfpwr = bwn_tab_read(mac, 11680 BWN_TAB_4(7, txpwridx + 576)); 11681 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11682 rfpwr & 0xffff); 11683 } 11684 bwn_phy_lp_set_txgain_override(mac); 11685 } 11686 if (plp->plp_rccap) 11687 bwn_phy_lp_set_rccap(mac); 11688 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11689 bwn_phy_lp_set_txpctlmode(mac, mode); 11690 free(tabs, M_DEVBUF); 11691 } 11692 11693 static void 11694 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11695 { 11696 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11697 int i; 11698 static const uint16_t addr[] = { 11699 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11700 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11701 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11702 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11703 BWN_PHY_OFDM(0xcf), 11704 }; 11705 11706 for (i = 0; i < N(addr); i++) 11707 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11708 } 11709 11710 static void 11711 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11712 { 11713 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11714 11715 if (mac->mac_phy.rev < 2) { 11716 bwn_phy_lp_tblinit_r01(mac); 11717 bwn_phy_lp_tblinit_txgain(mac); 11718 bwn_phy_lp_set_gaintbl(mac, freq); 11719 return; 11720 } 11721 11722 bwn_phy_lp_tblinit_r2(mac); 11723 bwn_phy_lp_tblinit_txgain(mac); 11724 } 11725 11726 struct bwn_wpair { 11727 uint16_t reg; 11728 uint16_t value; 11729 }; 11730 11731 struct bwn_smpair { 11732 uint16_t offset; 11733 uint16_t mask; 11734 uint16_t set; 11735 }; 11736 11737 static void 11738 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11739 { 11740 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11741 struct bwn_softc *sc = mac->mac_sc; 11742 struct ifnet *ifp = sc->sc_ifp; 11743 struct ieee80211com *ic = ifp->if_l2com; 11744 static const struct bwn_wpair v1[] = { 11745 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11746 { BWN_PHY_AFE_CTL, 0x8800 }, 11747 { BWN_PHY_AFE_CTL_OVR, 0 }, 11748 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11749 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11750 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11751 { BWN_PHY_OFDM(0xf9), 0 }, 11752 { BWN_PHY_TR_LOOKUP_1, 0 } 11753 }; 11754 static const struct bwn_smpair v2[] = { 11755 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11756 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11757 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11758 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11759 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11760 }; 11761 static const struct bwn_smpair v3[] = { 11762 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11763 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11764 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11765 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11766 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11767 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11768 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11769 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11770 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11771 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11772 11773 }; 11774 int i; 11775 11776 for (i = 0; i < N(v1); i++) 11777 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11778 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11779 for (i = 0; i < N(v2); i++) 11780 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11781 11782 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11783 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11784 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11785 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11786 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11787 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11788 } else { 11789 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11790 } 11791 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11792 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11793 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11794 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11795 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11796 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11797 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11798 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11799 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11800 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11801 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11802 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11803 (siba_get_chiprev(sc->sc_dev) == 0)) { 11804 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11805 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11806 } else { 11807 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11808 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11809 } 11810 for (i = 0; i < N(v3); i++) 11811 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11812 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11813 (siba_get_chiprev(sc->sc_dev) == 0)) { 11814 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11815 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11816 } 11817 11818 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11819 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11820 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11821 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11822 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11823 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11824 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11825 } else 11826 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11827 11828 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11829 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11830 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11831 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11832 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11833 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11834 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11835 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11836 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11837 11838 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11839 (siba_get_chiprev(sc->sc_dev) == 0)) { 11840 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11841 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11842 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11843 } 11844 11845 bwn_phy_lp_digflt_save(mac); 11846 } 11847 11848 static void 11849 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11850 { 11851 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11852 struct bwn_softc *sc = mac->mac_sc; 11853 struct ifnet *ifp = sc->sc_ifp; 11854 struct ieee80211com *ic = ifp->if_l2com; 11855 static const struct bwn_smpair v1[] = { 11856 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11857 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11858 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11859 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11860 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11861 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11862 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11863 }; 11864 static const struct bwn_smpair v2[] = { 11865 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11866 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11867 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11868 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11869 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11870 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11871 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11872 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11873 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11874 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11875 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11876 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11877 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11878 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11879 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11880 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11881 }; 11882 static const struct bwn_smpair v3[] = { 11883 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11884 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11885 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11886 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11887 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11888 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11889 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11890 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11891 }; 11892 static const struct bwn_smpair v4[] = { 11893 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11894 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11895 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11896 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11897 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11898 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11899 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11900 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11901 }; 11902 static const struct bwn_smpair v5[] = { 11903 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11904 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11905 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11906 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11907 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11908 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11909 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11910 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11911 }; 11912 int i; 11913 uint16_t tmp, tmp2; 11914 11915 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11916 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11917 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11918 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11919 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11920 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11921 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11922 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11923 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11924 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11925 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11926 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11927 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11928 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11929 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11930 for (i = 0; i < N(v1); i++) 11931 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11932 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11933 0xff00, plp->plp_rxpwroffset); 11934 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11935 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11936 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11937 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11938 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11939 if (mac->mac_phy.rev == 0) 11940 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11941 0xffcf, 0x0010); 11942 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11943 } else { 11944 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11945 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11946 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11947 } 11948 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11949 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11950 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11951 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11952 else 11953 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11954 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11955 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11956 0xfff9, (plp->plp_bxarch << 1)); 11957 if (mac->mac_phy.rev == 1 && 11958 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11959 for (i = 0; i < N(v2); i++) 11960 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11961 v2[i].set); 11962 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11963 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11964 ((mac->mac_phy.rev == 0) && 11965 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11966 for (i = 0; i < N(v3); i++) 11967 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11968 v3[i].set); 11969 } else if (mac->mac_phy.rev == 1 || 11970 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11971 for (i = 0; i < N(v4); i++) 11972 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11973 v4[i].set); 11974 } else { 11975 for (i = 0; i < N(v5); i++) 11976 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11977 v5[i].set); 11978 } 11979 if (mac->mac_phy.rev == 1 && 11980 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11981 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11982 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11983 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11984 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11985 } 11986 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11987 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11988 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11989 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11990 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11991 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11992 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11993 } 11994 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11995 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11996 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11997 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11998 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11999 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 12000 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 12001 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 12002 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 12003 } else { 12004 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 12005 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 12006 } 12007 if (mac->mac_phy.rev == 1) { 12008 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 12009 tmp2 = (tmp & 0x03e0) >> 5; 12010 tmp2 |= tmp2 << 5; 12011 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12012 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12013 tmp2 = (tmp & 0x1f00) >> 8; 12014 tmp2 |= tmp2 << 5; 12015 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12016 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12017 tmp2 = tmp & 0x00ff; 12018 tmp2 |= tmp << 8; 12019 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12020 } 12021 } 12022 12023 struct bwn_b2062_freq { 12024 uint16_t freq; 12025 uint8_t value[6]; 12026 }; 12027 12028 static void 12029 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12030 { 12031 #define CALC_CTL7(freq, div) \ 12032 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12033 #define CALC_CTL18(freq, div) \ 12034 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12035 #define CALC_CTL19(freq, div) \ 12036 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12037 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12038 struct bwn_softc *sc = mac->mac_sc; 12039 struct ifnet *ifp = sc->sc_ifp; 12040 struct ieee80211com *ic = ifp->if_l2com; 12041 static const struct bwn_b2062_freq freqdata_tab[] = { 12042 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12043 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12044 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12045 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12046 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12047 { 19200, { 1, 1, 1, 1, 14, 9 } } 12048 }; 12049 static const struct bwn_wpair v1[] = { 12050 { BWN_B2062_N_TXCTL3, 0 }, 12051 { BWN_B2062_N_TXCTL4, 0 }, 12052 { BWN_B2062_N_TXCTL5, 0 }, 12053 { BWN_B2062_N_TXCTL6, 0 }, 12054 { BWN_B2062_N_PDNCTL0, 0x40 }, 12055 { BWN_B2062_N_PDNCTL0, 0 }, 12056 { BWN_B2062_N_CALIB_TS, 0x10 }, 12057 { BWN_B2062_N_CALIB_TS, 0 } 12058 }; 12059 const struct bwn_b2062_freq *f = NULL; 12060 uint32_t xtalfreq, ref; 12061 unsigned int i; 12062 12063 bwn_phy_lp_b2062_tblinit(mac); 12064 12065 for (i = 0; i < N(v1); i++) 12066 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12067 if (mac->mac_phy.rev > 0) 12068 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12069 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12070 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12071 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12072 else 12073 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12074 12075 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 12076 ("%s:%d: fail", __func__, __LINE__)); 12077 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12078 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12079 12080 if (xtalfreq <= 30000000) { 12081 plp->plp_div = 1; 12082 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12083 } else { 12084 plp->plp_div = 2; 12085 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12086 } 12087 12088 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12089 CALC_CTL7(xtalfreq, plp->plp_div)); 12090 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12091 CALC_CTL18(xtalfreq, plp->plp_div)); 12092 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12093 CALC_CTL19(xtalfreq, plp->plp_div)); 12094 12095 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12096 ref &= 0xffff; 12097 for (i = 0; i < N(freqdata_tab); i++) { 12098 if (ref < freqdata_tab[i].freq) { 12099 f = &freqdata_tab[i]; 12100 break; 12101 } 12102 } 12103 if (f == NULL) 12104 f = &freqdata_tab[N(freqdata_tab) - 1]; 12105 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12106 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12107 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12108 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12109 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12110 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12111 #undef CALC_CTL7 12112 #undef CALC_CTL18 12113 #undef CALC_CTL19 12114 } 12115 12116 static void 12117 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12118 { 12119 12120 bwn_phy_lp_b2063_tblinit(mac); 12121 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12122 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12123 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12124 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12125 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12126 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12127 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12128 if (mac->mac_phy.rev == 2) { 12129 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12130 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12131 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12132 } else { 12133 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12134 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12135 } 12136 } 12137 12138 static void 12139 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12140 { 12141 struct bwn_softc *sc = mac->mac_sc; 12142 static const struct bwn_wpair v1[] = { 12143 { BWN_B2063_RX_BB_SP8, 0x0 }, 12144 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12145 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12146 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12147 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12148 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12149 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12150 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12151 }; 12152 static const struct bwn_wpair v2[] = { 12153 { BWN_B2063_TX_BB_SP3, 0x0 }, 12154 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12155 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12156 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12157 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12158 }; 12159 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12160 int i; 12161 uint8_t tmp; 12162 12163 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12164 12165 for (i = 0; i < 2; i++) 12166 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12167 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12168 for (i = 2; i < N(v1); i++) 12169 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12170 for (i = 0; i < 10000; i++) { 12171 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12172 break; 12173 DELAY(1000); 12174 } 12175 12176 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12177 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12178 12179 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12180 12181 for (i = 0; i < N(v2); i++) 12182 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12183 if (freqxtal == 24000000) { 12184 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12185 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12186 } else { 12187 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12188 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12189 } 12190 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12191 for (i = 0; i < 10000; i++) { 12192 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12193 break; 12194 DELAY(1000); 12195 } 12196 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12197 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12198 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12199 } 12200 12201 static void 12202 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12203 { 12204 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12205 struct bwn_softc *sc = mac->mac_sc; 12206 struct bwn_phy_lp_iq_est ie; 12207 struct bwn_txgain tx_gains; 12208 static const uint32_t pwrtbl[21] = { 12209 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12210 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12211 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12212 0x0004c, 0x0002c, 0x0001a, 12213 }; 12214 uint32_t npwr, ipwr, sqpwr, tmp; 12215 int loopback, i, j, sum, error; 12216 uint16_t save[7]; 12217 uint8_t txo, bbmult, txpctlmode; 12218 12219 error = bwn_phy_lp_switch_channel(mac, 7); 12220 if (error) 12221 device_printf(sc->sc_dev, 12222 "failed to change channel to 7 (%d)\n", error); 12223 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12224 bbmult = bwn_phy_lp_get_bbmult(mac); 12225 if (txo) 12226 tx_gains = bwn_phy_lp_get_txgain(mac); 12227 12228 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12229 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12230 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12231 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12232 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12233 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12234 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12235 12236 bwn_phy_lp_get_txpctlmode(mac); 12237 txpctlmode = plp->plp_txpctlmode; 12238 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12239 12240 /* disable CRS */ 12241 bwn_phy_lp_set_deaf(mac, 1); 12242 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12243 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12244 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12245 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12246 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12247 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12248 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12249 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12250 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12251 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12252 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12253 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12254 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12255 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12256 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12257 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12258 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12259 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12260 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12261 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12262 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12263 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12264 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12265 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12266 12267 loopback = bwn_phy_lp_loopback(mac); 12268 if (loopback == -1) 12269 goto done; 12270 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12271 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12272 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12273 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12274 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12275 12276 tmp = 0; 12277 memset(&ie, 0, sizeof(ie)); 12278 for (i = 128; i <= 159; i++) { 12279 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12280 sum = 0; 12281 for (j = 5; j <= 25; j++) { 12282 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12283 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12284 goto done; 12285 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12286 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12287 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12288 12); 12289 sum += ((ipwr - npwr) * (ipwr - npwr)); 12290 if ((i == 128) || (sum < tmp)) { 12291 plp->plp_rccap = i; 12292 tmp = sum; 12293 } 12294 } 12295 } 12296 bwn_phy_lp_ddfs_turnoff(mac); 12297 done: 12298 /* restore CRS */ 12299 bwn_phy_lp_clear_deaf(mac, 1); 12300 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12301 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12302 12303 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12304 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12305 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12306 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12307 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12308 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12309 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12310 12311 bwn_phy_lp_set_bbmult(mac, bbmult); 12312 if (txo) 12313 bwn_phy_lp_set_txgain(mac, &tx_gains); 12314 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12315 if (plp->plp_rccap) 12316 bwn_phy_lp_set_rccap(mac); 12317 } 12318 12319 static void 12320 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12321 { 12322 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12323 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12324 12325 if (mac->mac_phy.rev == 1) 12326 rc_cap = MIN(rc_cap + 5, 15); 12327 12328 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12329 MAX(plp->plp_rccap - 4, 0x80)); 12330 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12331 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12332 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12333 } 12334 12335 static uint32_t 12336 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12337 { 12338 uint32_t i, q, r; 12339 12340 if (div == 0) 12341 return (0); 12342 12343 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12344 q <<= 1; 12345 if (r << 1 >= div) { 12346 q++; 12347 r = (r << 1) - div; 12348 } 12349 } 12350 if (r << 1 >= div) 12351 q++; 12352 return (q); 12353 } 12354 12355 static void 12356 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12357 { 12358 struct bwn_softc *sc = mac->mac_sc; 12359 12360 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12361 DELAY(20); 12362 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12363 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12364 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12365 } else { 12366 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12367 } 12368 DELAY(5); 12369 } 12370 12371 static void 12372 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12373 { 12374 12375 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12376 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12377 DELAY(200); 12378 } 12379 12380 static void 12381 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12382 { 12383 #define FLAG_A 0x01 12384 #define FLAG_G 0x02 12385 struct bwn_softc *sc = mac->mac_sc; 12386 struct ifnet *ifp = sc->sc_ifp; 12387 struct ieee80211com *ic = ifp->if_l2com; 12388 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12389 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12390 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12391 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12392 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12393 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12394 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12395 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12396 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12397 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12398 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12399 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12400 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12401 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12402 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12403 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12404 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12405 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12406 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12407 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12408 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12409 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12410 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12411 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12412 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12413 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12414 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12415 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12416 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12417 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12418 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12419 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12420 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12421 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12422 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12423 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12424 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12425 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12426 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12427 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12428 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12429 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12430 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12431 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12432 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12433 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12434 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12435 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12436 }; 12437 const struct bwn_b206x_rfinit_entry *br; 12438 unsigned int i; 12439 12440 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12441 br = &bwn_b2062_init_tab[i]; 12442 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12443 if (br->br_flags & FLAG_G) 12444 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12445 } else { 12446 if (br->br_flags & FLAG_A) 12447 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12448 } 12449 } 12450 #undef FLAG_A 12451 #undef FLAG_B 12452 } 12453 12454 static void 12455 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12456 { 12457 #define FLAG_A 0x01 12458 #define FLAG_G 0x02 12459 struct bwn_softc *sc = mac->mac_sc; 12460 struct ifnet *ifp = sc->sc_ifp; 12461 struct ieee80211com *ic = ifp->if_l2com; 12462 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12463 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12464 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12465 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12466 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12467 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12468 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12469 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12470 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12471 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12472 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12473 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12474 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12475 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12476 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12477 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12478 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12479 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12480 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12481 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12482 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12483 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12484 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12485 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12486 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12487 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12488 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12489 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12490 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12491 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12492 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12493 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12494 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12495 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12496 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12497 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12498 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12499 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12500 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12501 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12502 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12503 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12504 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12505 }; 12506 const struct bwn_b206x_rfinit_entry *br; 12507 unsigned int i; 12508 12509 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12510 br = &bwn_b2063_init_tab[i]; 12511 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12512 if (br->br_flags & FLAG_G) 12513 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12514 } else { 12515 if (br->br_flags & FLAG_A) 12516 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12517 } 12518 } 12519 #undef FLAG_A 12520 #undef FLAG_B 12521 } 12522 12523 static void 12524 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12525 int count, void *_data) 12526 { 12527 unsigned int i; 12528 uint32_t offset, type; 12529 uint8_t *data = _data; 12530 12531 type = BWN_TAB_GETTYPE(typenoffset); 12532 offset = BWN_TAB_GETOFFSET(typenoffset); 12533 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12534 12535 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12536 12537 for (i = 0; i < count; i++) { 12538 switch (type) { 12539 case BWN_TAB_8BIT: 12540 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12541 data++; 12542 break; 12543 case BWN_TAB_16BIT: 12544 *((uint16_t *)data) = BWN_PHY_READ(mac, 12545 BWN_PHY_TABLEDATALO); 12546 data += 2; 12547 break; 12548 case BWN_TAB_32BIT: 12549 *((uint32_t *)data) = BWN_PHY_READ(mac, 12550 BWN_PHY_TABLEDATAHI); 12551 *((uint32_t *)data) <<= 16; 12552 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12553 BWN_PHY_TABLEDATALO); 12554 data += 4; 12555 break; 12556 default: 12557 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12558 } 12559 } 12560 } 12561 12562 static void 12563 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12564 int count, const void *_data) 12565 { 12566 uint32_t offset, type, value; 12567 const uint8_t *data = _data; 12568 unsigned int i; 12569 12570 type = BWN_TAB_GETTYPE(typenoffset); 12571 offset = BWN_TAB_GETOFFSET(typenoffset); 12572 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12573 12574 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12575 12576 for (i = 0; i < count; i++) { 12577 switch (type) { 12578 case BWN_TAB_8BIT: 12579 value = *data; 12580 data++; 12581 KASSERT(!(value & ~0xff), 12582 ("%s:%d: fail", __func__, __LINE__)); 12583 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12584 break; 12585 case BWN_TAB_16BIT: 12586 value = *((const uint16_t *)data); 12587 data += 2; 12588 KASSERT(!(value & ~0xffff), 12589 ("%s:%d: fail", __func__, __LINE__)); 12590 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12591 break; 12592 case BWN_TAB_32BIT: 12593 value = *((const uint32_t *)data); 12594 data += 4; 12595 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12596 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12597 break; 12598 default: 12599 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12600 } 12601 } 12602 } 12603 12604 static struct bwn_txgain 12605 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12606 { 12607 struct bwn_txgain tg; 12608 uint16_t tmp; 12609 12610 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12611 if (mac->mac_phy.rev < 2) { 12612 tmp = BWN_PHY_READ(mac, 12613 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12614 tg.tg_gm = tmp & 0x0007; 12615 tg.tg_pga = (tmp & 0x0078) >> 3; 12616 tg.tg_pad = (tmp & 0x780) >> 7; 12617 return (tg); 12618 } 12619 12620 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12621 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12622 tg.tg_gm = tmp & 0xff; 12623 tg.tg_pga = (tmp >> 8) & 0xff; 12624 return (tg); 12625 } 12626 12627 static uint8_t 12628 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12629 { 12630 12631 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12632 } 12633 12634 static void 12635 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12636 { 12637 uint16_t pa; 12638 12639 if (mac->mac_phy.rev < 2) { 12640 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12641 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12642 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12643 bwn_phy_lp_set_txgain_override(mac); 12644 return; 12645 } 12646 12647 pa = bwn_phy_lp_get_pa_gain(mac); 12648 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12649 (tg->tg_pga << 8) | tg->tg_gm); 12650 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12651 tg->tg_pad | (pa << 6)); 12652 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12653 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12654 tg->tg_pad | (pa << 8)); 12655 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12656 bwn_phy_lp_set_txgain_override(mac); 12657 } 12658 12659 static void 12660 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12661 { 12662 12663 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12664 } 12665 12666 static void 12667 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12668 { 12669 uint16_t trsw = (tx << 1) | rx; 12670 12671 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12672 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12673 } 12674 12675 static void 12676 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12677 { 12678 struct bwn_softc *sc = mac->mac_sc; 12679 struct ifnet *ifp = sc->sc_ifp; 12680 struct ieee80211com *ic = ifp->if_l2com; 12681 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12682 12683 if (mac->mac_phy.rev < 2) { 12684 trsw = gain & 0x1; 12685 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12686 ext_lna = (gain & 2) >> 1; 12687 12688 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12689 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12690 0xfbff, ext_lna << 10); 12691 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12692 0xf7ff, ext_lna << 11); 12693 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12694 } else { 12695 low_gain = gain & 0xffff; 12696 high_gain = (gain >> 16) & 0xf; 12697 ext_lna = (gain >> 21) & 0x1; 12698 trsw = ~(gain >> 20) & 0x1; 12699 12700 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12701 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12702 0xfdff, ext_lna << 9); 12703 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12704 0xfbff, ext_lna << 10); 12705 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12706 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12707 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12708 tmp = (gain >> 2) & 0x3; 12709 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12710 0xe7ff, tmp<<11); 12711 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12712 tmp << 3); 12713 } 12714 } 12715 12716 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12717 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12718 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12719 if (mac->mac_phy.rev >= 2) { 12720 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12721 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12722 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12723 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12724 } 12725 return; 12726 } 12727 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12728 } 12729 12730 static void 12731 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12732 { 12733 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12734 12735 if (user) 12736 plp->plp_crsusr_off = 1; 12737 else 12738 plp->plp_crssys_off = 1; 12739 12740 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12741 } 12742 12743 static void 12744 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12745 { 12746 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12747 struct bwn_softc *sc = mac->mac_sc; 12748 struct ifnet *ifp = sc->sc_ifp; 12749 struct ieee80211com *ic = ifp->if_l2com; 12750 12751 if (user) 12752 plp->plp_crsusr_off = 0; 12753 else 12754 plp->plp_crssys_off = 0; 12755 12756 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12757 return; 12758 12759 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12760 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12761 else 12762 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12763 } 12764 12765 static unsigned int 12766 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12767 { 12768 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12769 static uint8_t sqrt_table[256] = { 12770 10, 14, 17, 20, 22, 24, 26, 28, 12771 30, 31, 33, 34, 36, 37, 38, 40, 12772 41, 42, 43, 44, 45, 46, 47, 48, 12773 50, 50, 51, 52, 53, 54, 55, 56, 12774 57, 58, 59, 60, 60, 61, 62, 63, 12775 64, 64, 65, 66, 67, 67, 68, 69, 12776 70, 70, 71, 72, 72, 73, 74, 74, 12777 75, 76, 76, 77, 78, 78, 79, 80, 12778 80, 81, 81, 82, 83, 83, 84, 84, 12779 85, 86, 86, 87, 87, 88, 88, 89, 12780 90, 90, 91, 91, 92, 92, 93, 93, 12781 94, 94, 95, 95, 96, 96, 97, 97, 12782 98, 98, 99, 100, 100, 100, 101, 101, 12783 102, 102, 103, 103, 104, 104, 105, 105, 12784 106, 106, 107, 107, 108, 108, 109, 109, 12785 110, 110, 110, 111, 111, 112, 112, 113, 12786 113, 114, 114, 114, 115, 115, 116, 116, 12787 117, 117, 117, 118, 118, 119, 119, 120, 12788 120, 120, 121, 121, 122, 122, 122, 123, 12789 123, 124, 124, 124, 125, 125, 126, 126, 12790 126, 127, 127, 128, 128, 128, 129, 129, 12791 130, 130, 130, 131, 131, 131, 132, 132, 12792 133, 133, 133, 134, 134, 134, 135, 135, 12793 136, 136, 136, 137, 137, 137, 138, 138, 12794 138, 139, 139, 140, 140, 140, 141, 141, 12795 141, 142, 142, 142, 143, 143, 143, 144, 12796 144, 144, 145, 145, 145, 146, 146, 146, 12797 147, 147, 147, 148, 148, 148, 149, 149, 12798 150, 150, 150, 150, 151, 151, 151, 152, 12799 152, 152, 153, 153, 153, 154, 154, 154, 12800 155, 155, 155, 156, 156, 156, 157, 157, 12801 157, 158, 158, 158, 159, 159, 159, 160 12802 }; 12803 12804 if (x == 0) 12805 return (0); 12806 if (x >= 256) { 12807 unsigned int tmp; 12808 12809 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12810 /* do nothing */ ; 12811 return (tmp); 12812 } 12813 return (sqrt_table[x - 1] / 10); 12814 } 12815 12816 static int 12817 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12818 { 12819 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12820 int _t; \ 12821 _t = _x - 20; \ 12822 if (_t >= 0) { \ 12823 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12824 } else { \ 12825 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12826 } \ 12827 } while (0) 12828 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12829 int _t; \ 12830 _t = _x - 11; \ 12831 if (_t >= 0) \ 12832 _v = (_y << (31 - _x)) / (_z >> _t); \ 12833 else \ 12834 _v = (_y << (31 - _x)) / (_z << -_t); \ 12835 } while (0) 12836 struct bwn_phy_lp_iq_est ie; 12837 uint16_t v0, v1; 12838 int tmp[2], ret; 12839 12840 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12841 v0 = v1 >> 8; 12842 v1 |= 0xff; 12843 12844 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12845 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12846 12847 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12848 if (ret == 0) 12849 goto done; 12850 12851 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12852 ret = 0; 12853 goto done; 12854 } 12855 12856 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12857 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12858 12859 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12860 v0 = tmp[0] >> 3; 12861 v1 = tmp[1] >> 4; 12862 done: 12863 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12864 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12865 return ret; 12866 #undef CALC_COEFF 12867 #undef CALC_COEFF2 12868 } 12869 12870 static void 12871 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12872 { 12873 static const uint16_t noisescale[] = { 12874 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12875 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12876 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12877 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12878 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12879 }; 12880 static const uint16_t crsgainnft[] = { 12881 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12882 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12883 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12884 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12885 0x013d, 12886 }; 12887 static const uint16_t filterctl[] = { 12888 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12889 0xff53, 0x0127, 12890 }; 12891 static const uint32_t psctl[] = { 12892 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12893 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12894 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12895 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12896 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12897 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12898 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12899 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12900 }; 12901 static const uint16_t ofdmcckgain_r0[] = { 12902 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12903 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12904 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12905 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12906 0x755d, 12907 }; 12908 static const uint16_t ofdmcckgain_r1[] = { 12909 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12910 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12911 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12912 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12913 0x755d, 12914 }; 12915 static const uint16_t gaindelta[] = { 12916 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12917 0x0000, 12918 }; 12919 static const uint32_t txpwrctl[] = { 12920 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12921 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12922 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12923 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12924 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12925 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12926 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12927 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12928 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12929 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12930 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12931 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12932 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000, 12948 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12949 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12950 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12951 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12952 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12953 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12954 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12955 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12956 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12957 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12958 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12959 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12960 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12961 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12962 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12963 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12964 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12965 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12966 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12967 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12968 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12969 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12970 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12971 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12972 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12973 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12974 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12975 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12976 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12977 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12978 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12979 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12980 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12981 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12982 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12983 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12984 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12985 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12986 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12987 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12988 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12989 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12990 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12991 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12992 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12993 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12994 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12995 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12996 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12997 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12998 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12999 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13000 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13001 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13002 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13003 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13004 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13005 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13006 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13007 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 13008 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13009 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13010 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13011 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13012 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13013 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13014 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13015 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13016 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13017 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13018 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13019 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13020 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13021 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13022 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13023 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13024 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13025 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13026 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13027 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13028 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13029 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13030 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13031 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13032 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13033 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13034 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13035 0x00000702, 13036 }; 13037 13038 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13039 13040 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13041 bwn_tab_sigsq_tbl); 13042 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13043 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13044 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13045 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13046 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13047 bwn_tab_pllfrac_tbl); 13048 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13049 bwn_tabl_iqlocal_tbl); 13050 if (mac->mac_phy.rev == 0) { 13051 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13052 ofdmcckgain_r0); 13053 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13054 ofdmcckgain_r0); 13055 } else { 13056 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13057 ofdmcckgain_r1); 13058 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13059 ofdmcckgain_r1); 13060 } 13061 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13062 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13063 } 13064 13065 static void 13066 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13067 { 13068 struct bwn_softc *sc = mac->mac_sc; 13069 int i; 13070 static const uint16_t noisescale[] = { 13071 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13072 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13073 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13074 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13075 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13076 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13077 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13078 }; 13079 static const uint32_t filterctl[] = { 13080 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13081 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13082 }; 13083 static const uint32_t psctl[] = { 13084 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13085 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13086 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13087 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13088 }; 13089 static const uint32_t gainidx[] = { 13090 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13091 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13092 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13093 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13094 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13095 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13096 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13097 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13098 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13099 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13100 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13101 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13102 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13103 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13104 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13105 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13106 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13107 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13108 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13109 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13110 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13111 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13112 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13113 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13114 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13115 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13116 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13117 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13118 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13119 0x0000001a, 0x64ca55ad, 0x0000001a 13120 }; 13121 static const uint16_t auxgainidx[] = { 13122 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13123 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13124 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13125 0x0004, 0x0016 13126 }; 13127 static const uint16_t swctl[] = { 13128 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13129 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13130 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13131 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13132 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13133 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13134 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13135 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13136 }; 13137 static const uint8_t hf[] = { 13138 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13139 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13140 }; 13141 static const uint32_t gainval[] = { 13142 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13143 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13144 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13145 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13146 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13147 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13148 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13149 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13150 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13151 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13152 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13153 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13154 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13155 0x000000f1, 0x00000000, 0x00000000 13156 }; 13157 static const uint16_t gain[] = { 13158 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13159 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13160 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13161 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13162 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13163 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13164 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13165 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13166 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13167 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13168 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13169 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13170 }; 13171 static const uint32_t papdeps[] = { 13172 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13173 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13174 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13175 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13176 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13177 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13178 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13179 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13180 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13181 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13182 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13183 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13184 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13185 }; 13186 static const uint32_t papdmult[] = { 13187 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13188 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13189 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13190 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13191 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13192 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13193 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13194 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13195 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13196 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13197 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13198 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13199 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13200 }; 13201 static const uint32_t gainidx_a0[] = { 13202 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13203 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13204 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13205 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13206 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13207 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13208 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13209 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13210 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13211 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13212 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13213 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13214 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13215 }; 13216 static const uint16_t auxgainidx_a0[] = { 13217 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13218 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13219 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13220 0x0002, 0x0014 13221 }; 13222 static const uint32_t gainval_a0[] = { 13223 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13224 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13225 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13226 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13227 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13228 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13229 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13230 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13231 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13232 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13233 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13234 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13236 0x000000f7, 0x00000000, 0x00000000 13237 }; 13238 static const uint16_t gain_a0[] = { 13239 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13240 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13241 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13242 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13243 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13244 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13245 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13246 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13247 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13248 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13249 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13250 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13251 }; 13252 13253 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13254 13255 for (i = 0; i < 704; i++) 13256 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13257 13258 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13259 bwn_tab_sigsq_tbl); 13260 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13261 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13262 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13263 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13264 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13265 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13266 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13267 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13268 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13269 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13270 bwn_tab_pllfrac_tbl); 13271 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13272 bwn_tabl_iqlocal_tbl); 13273 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13274 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13275 13276 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13277 (siba_get_chiprev(sc->sc_dev) == 0)) { 13278 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13279 gainidx_a0); 13280 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13281 auxgainidx_a0); 13282 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13283 gainval_a0); 13284 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13285 } 13286 } 13287 13288 static void 13289 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13290 { 13291 struct bwn_softc *sc = mac->mac_sc; 13292 struct ifnet *ifp = sc->sc_ifp; 13293 struct ieee80211com *ic = ifp->if_l2com; 13294 static struct bwn_txgain_entry txgain_r2[] = { 13295 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13296 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13297 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13298 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13299 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13300 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13301 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13302 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13303 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13304 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13305 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13306 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13307 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13308 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13309 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13310 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13311 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13312 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13313 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13314 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13315 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13316 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13317 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13318 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13319 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13320 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13321 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13322 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13323 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13324 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13325 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13326 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13327 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13328 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13329 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13330 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13331 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13332 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13333 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13334 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13335 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13336 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13337 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13338 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13339 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13340 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13341 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13342 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13343 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13344 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13345 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13346 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13347 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13348 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13349 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13350 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13351 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13352 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13353 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13354 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13355 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13356 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13357 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13358 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13359 }; 13360 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13361 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13362 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13363 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13364 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13365 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13366 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13367 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13368 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13369 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13370 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13371 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13372 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13373 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13374 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13375 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13376 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13377 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13378 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13379 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13380 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13381 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13382 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13383 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13384 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13385 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13386 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13387 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13388 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13389 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13390 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13391 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13392 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13393 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13394 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13395 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13396 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13397 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13398 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13399 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13400 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13401 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13402 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13403 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13404 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13405 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13406 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13407 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13408 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13409 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13410 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13411 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13412 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13413 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13414 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13415 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13416 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13417 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13418 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13419 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13420 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13421 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13422 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13423 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13424 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13425 }; 13426 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13427 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13428 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13429 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13430 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13431 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13432 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13433 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13434 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13435 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13436 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13437 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13438 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13439 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13440 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13441 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13442 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13443 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13444 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13445 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13446 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13447 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13448 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13449 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13450 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13451 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13452 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13453 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13454 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13455 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13456 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13457 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13458 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13459 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13460 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13461 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13462 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13463 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13464 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13465 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13466 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13467 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13468 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13469 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13470 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13471 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13472 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13473 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13474 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13475 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13476 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13477 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13478 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13479 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13480 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13481 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13482 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13483 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13484 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13485 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13486 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13487 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13488 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13489 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13490 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13491 }; 13492 static struct bwn_txgain_entry txgain_r0[] = { 13493 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13494 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13495 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13496 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13497 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13498 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13499 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13500 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13501 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13502 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13503 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13504 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13505 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13506 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13507 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13508 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13509 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13510 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13511 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13512 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13513 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13514 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13515 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13516 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13517 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13518 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13519 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13520 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13521 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13522 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13523 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13524 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13525 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13526 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13527 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13528 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13529 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13530 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13531 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13532 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13533 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13534 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13535 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13536 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13537 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13538 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13539 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13540 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13541 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13542 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13543 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13544 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13545 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13546 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13547 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13548 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13549 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13550 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13551 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13552 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13553 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13554 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13555 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13556 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13557 }; 13558 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13559 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13560 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13561 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13562 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13563 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13564 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13565 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13566 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13567 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13568 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13569 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13570 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13571 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13572 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13573 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13574 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13575 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13576 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13577 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13578 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13579 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13580 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13581 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13582 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13583 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13584 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13585 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13586 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13587 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13588 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13589 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13590 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13591 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13592 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13593 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13594 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13595 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13596 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13597 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13598 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13599 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13600 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13601 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13602 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13603 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13604 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13605 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13606 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13607 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13608 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13609 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13610 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13611 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13612 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13613 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13614 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13615 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13616 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13617 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13618 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13619 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13620 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13621 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13622 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13623 }; 13624 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13625 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13626 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13627 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13628 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13629 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13630 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13631 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13632 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13633 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13634 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13635 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13636 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13637 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13638 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13639 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13640 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13641 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13642 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13643 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13644 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13645 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13646 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13647 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13648 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13649 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13650 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13651 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13652 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13653 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13654 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13655 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13656 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13657 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13658 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13659 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13660 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13661 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13662 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13663 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13664 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13665 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13666 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13667 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13668 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13669 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13670 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13671 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13672 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13673 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13674 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13675 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13676 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13677 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13678 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13679 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13680 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13681 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13682 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13683 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13684 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13685 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13686 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13687 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13688 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13689 }; 13690 static struct bwn_txgain_entry txgain_r1[] = { 13691 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13692 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13693 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13694 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13695 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13696 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13697 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13698 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13699 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13700 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13701 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13702 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13703 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13704 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13705 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13706 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13707 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13708 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13709 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13710 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13711 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13712 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13713 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13714 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13715 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13716 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13717 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13718 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13719 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13720 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13721 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13722 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13723 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13724 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13725 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13726 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13727 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13728 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13729 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13730 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13731 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13732 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13733 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13734 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13735 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13736 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13737 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13738 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13739 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13740 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13741 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13742 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13743 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13744 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13745 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13746 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13747 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13748 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13749 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13750 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13751 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13752 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13753 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13754 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13755 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13756 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13757 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13758 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13759 { 7, 11, 6, 0, 71 } 13760 }; 13761 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13762 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13763 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13764 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13765 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13766 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13767 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13768 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13769 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13770 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13771 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13772 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13773 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13774 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13775 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13776 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13777 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13778 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13779 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13780 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13781 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13782 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13783 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13784 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13785 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13786 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13787 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13788 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13789 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13790 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13791 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13792 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13793 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13794 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13795 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13796 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13797 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13798 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13799 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13800 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13801 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13802 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13803 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13804 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13805 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13806 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13807 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13808 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13809 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13810 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13811 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13812 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13813 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13814 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13815 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13816 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13817 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13818 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13819 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13820 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13821 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13822 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13823 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13824 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13825 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13826 }; 13827 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13828 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13829 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13830 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13831 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13832 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13833 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13834 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13835 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13836 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13837 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13838 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13839 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13840 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13841 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13842 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13843 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13844 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13845 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13846 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13847 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13848 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13849 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13850 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13851 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13852 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13853 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13854 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13855 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13856 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13857 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13858 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13859 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13860 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13861 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13862 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13863 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13864 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13865 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13866 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13867 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13868 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13869 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13870 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13871 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13872 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13873 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13874 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13875 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13876 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13877 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13878 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13879 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13880 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13881 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13882 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13883 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13884 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13885 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13886 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13887 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13888 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13889 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13890 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13891 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13892 }; 13893 13894 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13895 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13896 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13897 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13898 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13899 txgain_2ghz_r2); 13900 else 13901 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13902 txgain_5ghz_r2); 13903 return; 13904 } 13905 13906 if (mac->mac_phy.rev == 0) { 13907 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13908 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13909 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13910 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13911 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13912 txgain_2ghz_r0); 13913 else 13914 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13915 txgain_5ghz_r0); 13916 return; 13917 } 13918 13919 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13920 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13921 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13922 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13923 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13924 else 13925 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13926 } 13927 13928 static void 13929 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13930 { 13931 uint32_t offset, type; 13932 13933 type = BWN_TAB_GETTYPE(typeoffset); 13934 offset = BWN_TAB_GETOFFSET(typeoffset); 13935 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13936 13937 switch (type) { 13938 case BWN_TAB_8BIT: 13939 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13940 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13941 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13942 break; 13943 case BWN_TAB_16BIT: 13944 KASSERT(!(value & ~0xffff), 13945 ("%s:%d: fail", __func__, __LINE__)); 13946 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13947 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13948 break; 13949 case BWN_TAB_32BIT: 13950 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13951 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13952 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13953 break; 13954 default: 13955 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13956 } 13957 } 13958 13959 static int 13960 bwn_phy_lp_loopback(struct bwn_mac *mac) 13961 { 13962 struct bwn_phy_lp_iq_est ie; 13963 int i, index = -1; 13964 uint32_t tmp; 13965 13966 memset(&ie, 0, sizeof(ie)); 13967 13968 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13969 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13970 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13971 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13972 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13973 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13974 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13975 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13976 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13977 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13978 for (i = 0; i < 32; i++) { 13979 bwn_phy_lp_set_rxgain_idx(mac, i); 13980 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13981 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13982 continue; 13983 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13984 if ((tmp > 4000) && (tmp < 10000)) { 13985 index = i; 13986 break; 13987 } 13988 } 13989 bwn_phy_lp_ddfs_turnoff(mac); 13990 return (index); 13991 } 13992 13993 static void 13994 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13995 { 13996 13997 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13998 } 13999 14000 static void 14001 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 14002 int incr1, int incr2, int scale_idx) 14003 { 14004 14005 bwn_phy_lp_ddfs_turnoff(mac); 14006 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 14007 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 14008 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 14009 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14010 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14011 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14012 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14013 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14014 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14015 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14016 } 14017 14018 static uint8_t 14019 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14020 struct bwn_phy_lp_iq_est *ie) 14021 { 14022 int i; 14023 14024 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14025 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14026 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14027 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14028 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14029 14030 for (i = 0; i < 500; i++) { 14031 if (!(BWN_PHY_READ(mac, 14032 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14033 break; 14034 DELAY(1000); 14035 } 14036 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14037 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14038 return 0; 14039 } 14040 14041 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14042 ie->ie_iqprod <<= 16; 14043 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14044 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14045 ie->ie_ipwr <<= 16; 14046 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14047 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14048 ie->ie_qpwr <<= 16; 14049 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14050 14051 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14052 return 1; 14053 } 14054 14055 static uint32_t 14056 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14057 { 14058 uint32_t offset, type, value; 14059 14060 type = BWN_TAB_GETTYPE(typeoffset); 14061 offset = BWN_TAB_GETOFFSET(typeoffset); 14062 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14063 14064 switch (type) { 14065 case BWN_TAB_8BIT: 14066 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14067 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14068 break; 14069 case BWN_TAB_16BIT: 14070 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14071 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14072 break; 14073 case BWN_TAB_32BIT: 14074 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14075 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14076 value <<= 16; 14077 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14078 break; 14079 default: 14080 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14081 value = 0; 14082 } 14083 14084 return (value); 14085 } 14086 14087 static void 14088 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14089 { 14090 14091 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14092 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14093 } 14094 14095 static void 14096 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14097 { 14098 uint16_t ctl; 14099 14100 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14101 ctl |= dac << 7; 14102 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14103 } 14104 14105 static void 14106 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14107 { 14108 14109 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14110 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14111 } 14112 14113 static void 14114 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14115 { 14116 14117 if (mac->mac_phy.rev < 2) 14118 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14119 else { 14120 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14121 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14122 } 14123 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14124 } 14125 14126 static uint16_t 14127 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14128 { 14129 14130 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14131 } 14132 14133 static uint8_t 14134 bwn_nbits(int32_t val) 14135 { 14136 uint32_t tmp; 14137 uint8_t nbits = 0; 14138 14139 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14140 nbits++; 14141 return (nbits); 14142 } 14143 14144 static void 14145 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14146 struct bwn_txgain_entry *table) 14147 { 14148 int i; 14149 14150 for (i = offset; i < count; i++) 14151 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14152 } 14153 14154 static void 14155 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14156 struct bwn_txgain_entry data) 14157 { 14158 14159 if (mac->mac_phy.rev >= 2) 14160 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14161 else 14162 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14163 } 14164 14165 static void 14166 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14167 struct bwn_txgain_entry te) 14168 { 14169 struct bwn_softc *sc = mac->mac_sc; 14170 struct ifnet *ifp = sc->sc_ifp; 14171 struct ieee80211com *ic = ifp->if_l2com; 14172 uint32_t tmp; 14173 14174 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14175 14176 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14177 if (mac->mac_phy.rev >= 3) { 14178 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14179 (0x10 << 24) : (0x70 << 24)); 14180 } else { 14181 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14182 (0x14 << 24) : (0x7f << 24)); 14183 } 14184 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14185 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14186 te.te_bbmult << 20 | te.te_dac << 28); 14187 } 14188 14189 static void 14190 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14191 struct bwn_txgain_entry te) 14192 { 14193 14194 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14195 14196 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14197 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14198 te.te_dac); 14199 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14200 } 14201 14202 static void 14203 bwn_sysctl_node(struct bwn_softc *sc) 14204 { 14205 device_t dev = sc->sc_dev; 14206 struct bwn_mac *mac; 14207 struct bwn_stats *stats; 14208 14209 /* XXX assume that count of MAC is only 1. */ 14210 14211 if ((mac = sc->sc_curmac) == NULL) 14212 return; 14213 stats = &mac->mac_stats; 14214 14215 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14216 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14217 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14218 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14219 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14220 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14221 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14222 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14223 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14224 14225 #ifdef BWN_DEBUG 14226 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14227 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14228 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14229 #endif 14230 } 14231 14232 static device_method_t bwn_methods[] = { 14233 /* Device interface */ 14234 DEVMETHOD(device_probe, bwn_probe), 14235 DEVMETHOD(device_attach, bwn_attach), 14236 DEVMETHOD(device_detach, bwn_detach), 14237 DEVMETHOD(device_suspend, bwn_suspend), 14238 DEVMETHOD(device_resume, bwn_resume), 14239 KOBJMETHOD_END 14240 }; 14241 static driver_t bwn_driver = { 14242 "bwn", 14243 bwn_methods, 14244 sizeof(struct bwn_softc) 14245 }; 14246 static devclass_t bwn_devclass; 14247 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14248 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14249 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14250 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14251 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14252