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_var.h> 56 #include <net/if_arp.h> 57 #include <net/if_dl.h> 58 #include <net/if_llc.h> 59 #include <net/if_media.h> 60 #include <net/if_types.h> 61 62 #include <dev/pci/pcivar.h> 63 #include <dev/pci/pcireg.h> 64 #include <dev/siba/siba_ids.h> 65 #include <dev/siba/sibareg.h> 66 #include <dev/siba/sibavar.h> 67 68 #include <net80211/ieee80211_var.h> 69 #include <net80211/ieee80211_radiotap.h> 70 #include <net80211/ieee80211_regdomain.h> 71 #include <net80211/ieee80211_phy.h> 72 #include <net80211/ieee80211_ratectl.h> 73 74 #include <dev/bwn/if_bwnreg.h> 75 #include <dev/bwn/if_bwnvar.h> 76 77 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, 78 "Broadcom driver parameters"); 79 80 /* 81 * Tunable & sysctl variables. 82 */ 83 84 #ifdef BWN_DEBUG 85 static int bwn_debug = 0; 86 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0, 87 "Broadcom debugging printfs"); 88 TUNABLE_INT("hw.bwn.debug", &bwn_debug); 89 enum { 90 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 91 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 92 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 93 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 94 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 95 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 96 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 97 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 98 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 99 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 100 BWN_DEBUG_NODE = 0x00000400, /* node management */ 101 BWN_DEBUG_LED = 0x00000800, /* led management */ 102 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 103 BWN_DEBUG_LO = 0x00002000, /* LO */ 104 BWN_DEBUG_FW = 0x00004000, /* firmware */ 105 BWN_DEBUG_WME = 0x00008000, /* WME */ 106 BWN_DEBUG_RF = 0x00010000, /* RF */ 107 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 108 BWN_DEBUG_ANY = 0xffffffff 109 }; 110 #define DPRINTF(sc, m, fmt, ...) do { \ 111 if (sc->sc_debug & (m)) \ 112 printf(fmt, __VA_ARGS__); \ 113 } while (0) 114 #else 115 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 116 #endif 117 118 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 119 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 120 "uses Bad Frames Preemption"); 121 static int bwn_bluetooth = 1; 122 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 123 "turns on Bluetooth Coexistence"); 124 static int bwn_hwpctl = 0; 125 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 126 "uses H/W power control"); 127 static int bwn_msi_disable = 0; /* MSI disabled */ 128 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable); 129 static int bwn_usedma = 1; 130 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 131 "uses DMA"); 132 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 133 static int bwn_wme = 1; 134 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 135 "uses WME support"); 136 137 static int bwn_attach_pre(struct bwn_softc *); 138 static int bwn_attach_post(struct bwn_softc *); 139 static void bwn_sprom_bugfixes(device_t); 140 static void bwn_init(void *); 141 static int bwn_init_locked(struct bwn_softc *); 142 static int bwn_ioctl(struct ifnet *, u_long, caddr_t); 143 static void bwn_start(struct ifnet *); 144 static int bwn_attach_core(struct bwn_mac *); 145 static void bwn_reset_core(struct bwn_mac *, uint32_t); 146 static int bwn_phy_getinfo(struct bwn_mac *, int); 147 static int bwn_chiptest(struct bwn_mac *); 148 static int bwn_setup_channels(struct bwn_mac *, int, int); 149 static int bwn_phy_g_attach(struct bwn_mac *); 150 static void bwn_phy_g_detach(struct bwn_mac *); 151 static void bwn_phy_g_init_pre(struct bwn_mac *); 152 static int bwn_phy_g_prepare_hw(struct bwn_mac *); 153 static int bwn_phy_g_init(struct bwn_mac *); 154 static void bwn_phy_g_exit(struct bwn_mac *); 155 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 156 static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 157 uint16_t); 158 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 159 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 160 uint16_t); 161 static int bwn_phy_g_hwpctl(struct bwn_mac *); 162 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 163 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 164 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 165 static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 166 static int bwn_phy_g_im(struct bwn_mac *, int); 167 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 168 static void bwn_phy_g_set_txpwr(struct bwn_mac *); 169 static void bwn_phy_g_task_15s(struct bwn_mac *); 170 static void bwn_phy_g_task_60s(struct bwn_mac *); 171 static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 172 static void bwn_phy_switch_analog(struct bwn_mac *, int); 173 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 174 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 175 uint16_t); 176 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 177 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 178 uint32_t); 179 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 180 uint16_t); 181 static void bwn_addchannels(struct ieee80211_channel [], int, int *, 182 const struct bwn_channelinfo *, int); 183 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 184 const struct ieee80211_bpf_params *); 185 static void bwn_updateslot(struct ifnet *); 186 static void bwn_update_promisc(struct ifnet *); 187 static void bwn_wme_init(struct bwn_mac *); 188 static int bwn_wme_update(struct ieee80211com *); 189 static void bwn_wme_clear(struct bwn_softc *); 190 static void bwn_wme_load(struct bwn_mac *); 191 static void bwn_wme_loadparams(struct bwn_mac *, 192 const struct wmeParams *, uint16_t); 193 static void bwn_scan_start(struct ieee80211com *); 194 static void bwn_scan_end(struct ieee80211com *); 195 static void bwn_set_channel(struct ieee80211com *); 196 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 197 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 198 const uint8_t [IEEE80211_ADDR_LEN], 199 const uint8_t [IEEE80211_ADDR_LEN]); 200 static void bwn_vap_delete(struct ieee80211vap *); 201 static void bwn_stop(struct bwn_softc *, int); 202 static void bwn_stop_locked(struct bwn_softc *, int); 203 static int bwn_core_init(struct bwn_mac *); 204 static void bwn_core_start(struct bwn_mac *); 205 static void bwn_core_exit(struct bwn_mac *); 206 static void bwn_bt_disable(struct bwn_mac *); 207 static int bwn_chip_init(struct bwn_mac *); 208 static uint64_t bwn_hf_read(struct bwn_mac *); 209 static void bwn_hf_write(struct bwn_mac *, uint64_t); 210 static void bwn_set_txretry(struct bwn_mac *, int, int); 211 static void bwn_rate_init(struct bwn_mac *); 212 static void bwn_set_phytxctl(struct bwn_mac *); 213 static void bwn_spu_setdelay(struct bwn_mac *, int); 214 static void bwn_bt_enable(struct bwn_mac *); 215 static void bwn_set_macaddr(struct bwn_mac *); 216 static void bwn_crypt_init(struct bwn_mac *); 217 static void bwn_chip_exit(struct bwn_mac *); 218 static int bwn_fw_fillinfo(struct bwn_mac *); 219 static int bwn_fw_loaducode(struct bwn_mac *); 220 static int bwn_gpio_init(struct bwn_mac *); 221 static int bwn_fw_loadinitvals(struct bwn_mac *); 222 static int bwn_phy_init(struct bwn_mac *); 223 static void bwn_set_txantenna(struct bwn_mac *, int); 224 static void bwn_set_opmode(struct bwn_mac *); 225 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 226 static uint8_t bwn_plcp_getcck(const uint8_t); 227 static uint8_t bwn_plcp_getofdm(const uint8_t); 228 static void bwn_pio_init(struct bwn_mac *); 229 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 230 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 231 int); 232 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 233 struct bwn_pio_rxqueue *, int); 234 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 235 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 236 uint16_t); 237 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 238 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 239 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 240 static void bwn_pio_handle_txeof(struct bwn_mac *, 241 const struct bwn_txstatus *); 242 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 243 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 244 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 245 uint16_t); 246 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 247 uint32_t); 248 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 249 struct mbuf *); 250 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 251 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 252 struct bwn_pio_txqueue *, uint32_t, const void *, int); 253 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 254 uint16_t, uint32_t); 255 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 256 struct bwn_pio_txqueue *, uint16_t, const void *, int); 257 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 258 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 259 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 260 uint16_t, struct bwn_pio_txpkt **); 261 static void bwn_dma_init(struct bwn_mac *); 262 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 263 static int bwn_dma_mask2type(uint64_t); 264 static uint64_t bwn_dma_mask(struct bwn_mac *); 265 static uint16_t bwn_dma_base(int, int); 266 static void bwn_dma_ringfree(struct bwn_dma_ring **); 267 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 268 int, struct bwn_dmadesc_generic **, 269 struct bwn_dmadesc_meta **); 270 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 271 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 272 int, int); 273 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 274 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 275 static void bwn_dma_32_resume(struct bwn_dma_ring *); 276 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 277 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 278 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 279 int, struct bwn_dmadesc_generic **, 280 struct bwn_dmadesc_meta **); 281 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 282 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 283 int, int); 284 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 285 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 286 static void bwn_dma_64_resume(struct bwn_dma_ring *); 287 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 288 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 289 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 290 static void bwn_dma_setup(struct bwn_dma_ring *); 291 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 292 static void bwn_dma_cleanup(struct bwn_dma_ring *); 293 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 294 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 295 static void bwn_dma_rx(struct bwn_dma_ring *); 296 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 297 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 298 struct bwn_dmadesc_meta *); 299 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 300 static int bwn_dma_gettype(struct bwn_mac *); 301 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 302 static int bwn_dma_freeslot(struct bwn_dma_ring *); 303 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 304 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 305 static int bwn_dma_newbuf(struct bwn_dma_ring *, 306 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 307 int); 308 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 309 bus_size_t, int); 310 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 311 static void bwn_dma_handle_txeof(struct bwn_mac *, 312 const struct bwn_txstatus *); 313 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 314 struct mbuf *); 315 static int bwn_dma_getslot(struct bwn_dma_ring *); 316 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 317 uint8_t); 318 static int bwn_dma_attach(struct bwn_mac *); 319 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 320 int, int, int); 321 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 322 const struct bwn_txstatus *, uint16_t, int *); 323 static void bwn_dma_free(struct bwn_mac *); 324 static void bwn_phy_g_init_sub(struct bwn_mac *); 325 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 326 static void bwn_phy_init_b5(struct bwn_mac *); 327 static void bwn_phy_init_b6(struct bwn_mac *); 328 static void bwn_phy_init_a(struct bwn_mac *); 329 static void bwn_loopback_calcgain(struct bwn_mac *); 330 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 331 static void bwn_lo_g_init(struct bwn_mac *); 332 static void bwn_lo_g_adjust(struct bwn_mac *); 333 static void bwn_lo_get_powervector(struct bwn_mac *); 334 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 335 const struct bwn_bbatt *, const struct bwn_rfatt *); 336 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 337 static void bwn_phy_hwpctl_init(struct bwn_mac *); 338 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 339 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 340 const struct bwn_bbatt *, const struct bwn_rfatt *, 341 uint8_t); 342 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 343 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 344 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 345 static void bwn_wa_init(struct bwn_mac *); 346 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 347 uint16_t); 348 static void bwn_dummy_transmission(struct bwn_mac *, int, int); 349 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 350 uint32_t); 351 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 352 uint16_t); 353 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 354 static void bwn_mac_suspend(struct bwn_mac *); 355 static void bwn_mac_enable(struct bwn_mac *); 356 static void bwn_psctl(struct bwn_mac *, uint32_t); 357 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 358 static void bwn_nrssi_offset(struct bwn_mac *); 359 static void bwn_nrssi_threshold(struct bwn_mac *); 360 static void bwn_nrssi_slope_11g(struct bwn_mac *); 361 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 362 int16_t); 363 static void bwn_set_original_gains(struct bwn_mac *); 364 static void bwn_hwpctl_early_init(struct bwn_mac *); 365 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 366 static uint16_t bwn_phy_g_chan2freq(uint8_t); 367 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 368 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 369 const char *, struct bwn_fwfile *); 370 static void bwn_release_firmware(struct bwn_mac *); 371 static void bwn_do_release_fw(struct bwn_fwfile *); 372 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 373 static int bwn_fwinitvals_write(struct bwn_mac *, 374 const struct bwn_fwinitvals *, size_t, size_t); 375 static int bwn_switch_channel(struct bwn_mac *, int); 376 static uint16_t bwn_ant2phy(int); 377 static void bwn_mac_write_bssid(struct bwn_mac *); 378 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 379 const uint8_t *); 380 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 381 const uint8_t *, size_t, const uint8_t *); 382 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 383 const uint8_t *); 384 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 385 const uint8_t *); 386 static void bwn_phy_exit(struct bwn_mac *); 387 static void bwn_core_stop(struct bwn_mac *); 388 static int bwn_switch_band(struct bwn_softc *, 389 struct ieee80211_channel *); 390 static void bwn_phy_reset(struct bwn_mac *); 391 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 392 static void bwn_set_pretbtt(struct bwn_mac *); 393 static int bwn_intr(void *); 394 static void bwn_intrtask(void *, int); 395 static void bwn_restart(struct bwn_mac *, const char *); 396 static void bwn_intr_ucode_debug(struct bwn_mac *); 397 static void bwn_intr_tbtt_indication(struct bwn_mac *); 398 static void bwn_intr_atim_end(struct bwn_mac *); 399 static void bwn_intr_beacon(struct bwn_mac *); 400 static void bwn_intr_pmq(struct bwn_mac *); 401 static void bwn_intr_noise(struct bwn_mac *); 402 static void bwn_intr_txeof(struct bwn_mac *); 403 static void bwn_hwreset(void *, int); 404 static void bwn_handle_fwpanic(struct bwn_mac *); 405 static void bwn_load_beacon0(struct bwn_mac *); 406 static void bwn_load_beacon1(struct bwn_mac *); 407 static uint32_t bwn_jssi_read(struct bwn_mac *); 408 static void bwn_noise_gensample(struct bwn_mac *); 409 static void bwn_handle_txeof(struct bwn_mac *, 410 const struct bwn_txstatus *); 411 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 412 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 413 static void bwn_start_locked(struct ifnet *); 414 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 415 struct mbuf *); 416 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 417 static int bwn_set_txhdr(struct bwn_mac *, 418 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 419 uint16_t); 420 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 421 const uint8_t); 422 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 423 static uint8_t bwn_get_fbrate(uint8_t); 424 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 425 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 426 static void bwn_phy_lock(struct bwn_mac *); 427 static void bwn_phy_unlock(struct bwn_mac *); 428 static void bwn_rf_lock(struct bwn_mac *); 429 static void bwn_rf_unlock(struct bwn_mac *); 430 static void bwn_txpwr(void *, int); 431 static void bwn_tasks(void *); 432 static void bwn_task_15s(struct bwn_mac *); 433 static void bwn_task_30s(struct bwn_mac *); 434 static void bwn_task_60s(struct bwn_mac *); 435 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 436 uint8_t); 437 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 438 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 439 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 440 int, int); 441 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 442 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 443 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 444 static void bwn_watchdog(void *); 445 static void bwn_dma_stop(struct bwn_mac *); 446 static void bwn_pio_stop(struct bwn_mac *); 447 static void bwn_dma_ringstop(struct bwn_dma_ring **); 448 static void bwn_led_attach(struct bwn_mac *); 449 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 450 static void bwn_led_event(struct bwn_mac *, int); 451 static void bwn_led_blink_start(struct bwn_mac *, int, int); 452 static void bwn_led_blink_next(void *); 453 static void bwn_led_blink_end(void *); 454 static void bwn_rfswitch(void *); 455 static void bwn_rf_turnon(struct bwn_mac *); 456 static void bwn_rf_turnoff(struct bwn_mac *); 457 static void bwn_phy_lp_init_pre(struct bwn_mac *); 458 static int bwn_phy_lp_init(struct bwn_mac *); 459 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 460 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 461 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 462 uint16_t); 463 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 464 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 465 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 466 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 467 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 468 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 469 static void bwn_phy_lp_task_60s(struct bwn_mac *); 470 static void bwn_phy_lp_readsprom(struct bwn_mac *); 471 static void bwn_phy_lp_bbinit(struct bwn_mac *); 472 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 473 static void bwn_phy_lp_calib(struct bwn_mac *); 474 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 475 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 476 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 477 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 478 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 479 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 480 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 481 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 482 static void bwn_phy_lp_bugfix(struct bwn_mac *); 483 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 484 static void bwn_phy_lp_tblinit(struct bwn_mac *); 485 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 486 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 487 static void bwn_phy_lp_b2062_init(struct bwn_mac *); 488 static void bwn_phy_lp_b2063_init(struct bwn_mac *); 489 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 490 static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 491 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 492 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 493 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 494 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 495 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 496 const void *); 497 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 498 static struct bwn_txgain 499 bwn_phy_lp_get_txgain(struct bwn_mac *); 500 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 501 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 502 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 503 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 504 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 505 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 506 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 507 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 508 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 509 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 510 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 511 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 512 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 513 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 514 static int bwn_phy_lp_loopback(struct bwn_mac *); 515 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 516 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 517 int); 518 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 519 struct bwn_phy_lp_iq_est *); 520 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 521 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 522 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 523 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 524 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 525 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 526 static uint8_t bwn_nbits(int32_t); 527 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 528 struct bwn_txgain_entry *); 529 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 530 struct bwn_txgain_entry); 531 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 532 struct bwn_txgain_entry); 533 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 534 struct bwn_txgain_entry); 535 static void bwn_sysctl_node(struct bwn_softc *); 536 537 static struct resource_spec bwn_res_spec_legacy[] = { 538 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 539 { -1, 0, 0 } 540 }; 541 542 static struct resource_spec bwn_res_spec_msi[] = { 543 { SYS_RES_IRQ, 1, RF_ACTIVE }, 544 { -1, 0, 0 } 545 }; 546 547 static const struct bwn_channelinfo bwn_chantable_bg = { 548 .channels = { 549 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 550 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 551 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 552 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 553 { 2472, 13, 30 }, { 2484, 14, 30 } }, 554 .nchannels = 14 555 }; 556 557 static const struct bwn_channelinfo bwn_chantable_a = { 558 .channels = { 559 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 560 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 561 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 562 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 563 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 564 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 565 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 566 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 567 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 568 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 569 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 570 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 571 { 6080, 216, 30 } }, 572 .nchannels = 37 573 }; 574 575 static const struct bwn_channelinfo bwn_chantable_n = { 576 .channels = { 577 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 578 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 579 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 580 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 581 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 582 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 583 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 584 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 585 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 586 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 587 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 588 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 589 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 590 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 591 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 592 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 593 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 594 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 595 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 596 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 597 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 598 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 599 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 600 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 601 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 602 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 603 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 604 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 605 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 606 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 607 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 608 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 609 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 610 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 611 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 612 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 613 { 6130, 226, 30 }, { 6140, 228, 30 } }, 614 .nchannels = 110 615 }; 616 617 static const uint8_t bwn_b2063_chantable_data[33][12] = { 618 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 619 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 620 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 621 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 622 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 623 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 624 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 625 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 626 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 627 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 628 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 629 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 630 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 631 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 632 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 633 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 634 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 635 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 636 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 637 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 638 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 639 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 640 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 641 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 642 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 643 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 644 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 646 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 647 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 648 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 649 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 650 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 651 }; 652 653 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 654 { 1, 2412, bwn_b2063_chantable_data[0] }, 655 { 2, 2417, bwn_b2063_chantable_data[0] }, 656 { 3, 2422, bwn_b2063_chantable_data[0] }, 657 { 4, 2427, bwn_b2063_chantable_data[1] }, 658 { 5, 2432, bwn_b2063_chantable_data[1] }, 659 { 6, 2437, bwn_b2063_chantable_data[1] }, 660 { 7, 2442, bwn_b2063_chantable_data[1] }, 661 { 8, 2447, bwn_b2063_chantable_data[1] }, 662 { 9, 2452, bwn_b2063_chantable_data[2] }, 663 { 10, 2457, bwn_b2063_chantable_data[2] }, 664 { 11, 2462, bwn_b2063_chantable_data[3] }, 665 { 12, 2467, bwn_b2063_chantable_data[3] }, 666 { 13, 2472, bwn_b2063_chantable_data[3] }, 667 { 14, 2484, bwn_b2063_chantable_data[4] }, 668 { 34, 5170, bwn_b2063_chantable_data[5] }, 669 { 36, 5180, bwn_b2063_chantable_data[6] }, 670 { 38, 5190, bwn_b2063_chantable_data[7] }, 671 { 40, 5200, bwn_b2063_chantable_data[8] }, 672 { 42, 5210, bwn_b2063_chantable_data[9] }, 673 { 44, 5220, bwn_b2063_chantable_data[10] }, 674 { 46, 5230, bwn_b2063_chantable_data[11] }, 675 { 48, 5240, bwn_b2063_chantable_data[12] }, 676 { 52, 5260, bwn_b2063_chantable_data[13] }, 677 { 56, 5280, bwn_b2063_chantable_data[14] }, 678 { 60, 5300, bwn_b2063_chantable_data[14] }, 679 { 64, 5320, bwn_b2063_chantable_data[15] }, 680 { 100, 5500, bwn_b2063_chantable_data[16] }, 681 { 104, 5520, bwn_b2063_chantable_data[17] }, 682 { 108, 5540, bwn_b2063_chantable_data[18] }, 683 { 112, 5560, bwn_b2063_chantable_data[19] }, 684 { 116, 5580, bwn_b2063_chantable_data[20] }, 685 { 120, 5600, bwn_b2063_chantable_data[21] }, 686 { 124, 5620, bwn_b2063_chantable_data[21] }, 687 { 128, 5640, bwn_b2063_chantable_data[22] }, 688 { 132, 5660, bwn_b2063_chantable_data[22] }, 689 { 136, 5680, bwn_b2063_chantable_data[22] }, 690 { 140, 5700, bwn_b2063_chantable_data[23] }, 691 { 149, 5745, bwn_b2063_chantable_data[23] }, 692 { 153, 5765, bwn_b2063_chantable_data[23] }, 693 { 157, 5785, bwn_b2063_chantable_data[23] }, 694 { 161, 5805, bwn_b2063_chantable_data[23] }, 695 { 165, 5825, bwn_b2063_chantable_data[23] }, 696 { 184, 4920, bwn_b2063_chantable_data[24] }, 697 { 188, 4940, bwn_b2063_chantable_data[25] }, 698 { 192, 4960, bwn_b2063_chantable_data[26] }, 699 { 196, 4980, bwn_b2063_chantable_data[27] }, 700 { 200, 5000, bwn_b2063_chantable_data[28] }, 701 { 204, 5020, bwn_b2063_chantable_data[29] }, 702 { 208, 5040, bwn_b2063_chantable_data[30] }, 703 { 212, 5060, bwn_b2063_chantable_data[31] }, 704 { 216, 5080, bwn_b2063_chantable_data[32] } 705 }; 706 707 static const uint8_t bwn_b2062_chantable_data[22][12] = { 708 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 709 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 719 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 720 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 721 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 722 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 723 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 724 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 727 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 728 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 729 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 730 }; 731 732 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 733 { 1, 2412, bwn_b2062_chantable_data[0] }, 734 { 2, 2417, bwn_b2062_chantable_data[0] }, 735 { 3, 2422, bwn_b2062_chantable_data[0] }, 736 { 4, 2427, bwn_b2062_chantable_data[0] }, 737 { 5, 2432, bwn_b2062_chantable_data[0] }, 738 { 6, 2437, bwn_b2062_chantable_data[0] }, 739 { 7, 2442, bwn_b2062_chantable_data[0] }, 740 { 8, 2447, bwn_b2062_chantable_data[0] }, 741 { 9, 2452, bwn_b2062_chantable_data[0] }, 742 { 10, 2457, bwn_b2062_chantable_data[0] }, 743 { 11, 2462, bwn_b2062_chantable_data[0] }, 744 { 12, 2467, bwn_b2062_chantable_data[0] }, 745 { 13, 2472, bwn_b2062_chantable_data[0] }, 746 { 14, 2484, bwn_b2062_chantable_data[0] }, 747 { 34, 5170, bwn_b2062_chantable_data[1] }, 748 { 38, 5190, bwn_b2062_chantable_data[2] }, 749 { 42, 5210, bwn_b2062_chantable_data[2] }, 750 { 46, 5230, bwn_b2062_chantable_data[3] }, 751 { 36, 5180, bwn_b2062_chantable_data[4] }, 752 { 40, 5200, bwn_b2062_chantable_data[5] }, 753 { 44, 5220, bwn_b2062_chantable_data[6] }, 754 { 48, 5240, bwn_b2062_chantable_data[3] }, 755 { 52, 5260, bwn_b2062_chantable_data[3] }, 756 { 56, 5280, bwn_b2062_chantable_data[3] }, 757 { 60, 5300, bwn_b2062_chantable_data[7] }, 758 { 64, 5320, bwn_b2062_chantable_data[8] }, 759 { 100, 5500, bwn_b2062_chantable_data[9] }, 760 { 104, 5520, bwn_b2062_chantable_data[10] }, 761 { 108, 5540, bwn_b2062_chantable_data[10] }, 762 { 112, 5560, bwn_b2062_chantable_data[10] }, 763 { 116, 5580, bwn_b2062_chantable_data[11] }, 764 { 120, 5600, bwn_b2062_chantable_data[12] }, 765 { 124, 5620, bwn_b2062_chantable_data[12] }, 766 { 128, 5640, bwn_b2062_chantable_data[12] }, 767 { 132, 5660, bwn_b2062_chantable_data[12] }, 768 { 136, 5680, bwn_b2062_chantable_data[12] }, 769 { 140, 5700, bwn_b2062_chantable_data[12] }, 770 { 149, 5745, bwn_b2062_chantable_data[12] }, 771 { 153, 5765, bwn_b2062_chantable_data[12] }, 772 { 157, 5785, bwn_b2062_chantable_data[12] }, 773 { 161, 5805, bwn_b2062_chantable_data[12] }, 774 { 165, 5825, bwn_b2062_chantable_data[12] }, 775 { 184, 4920, bwn_b2062_chantable_data[13] }, 776 { 188, 4940, bwn_b2062_chantable_data[14] }, 777 { 192, 4960, bwn_b2062_chantable_data[15] }, 778 { 196, 4980, bwn_b2062_chantable_data[16] }, 779 { 200, 5000, bwn_b2062_chantable_data[17] }, 780 { 204, 5020, bwn_b2062_chantable_data[18] }, 781 { 208, 5040, bwn_b2062_chantable_data[19] }, 782 { 212, 5060, bwn_b2062_chantable_data[20] }, 783 { 216, 5080, bwn_b2062_chantable_data[21] } 784 }; 785 786 /* for LP PHY */ 787 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 788 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 789 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 790 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 791 { 13, -66, 13 }, { 14, -66, 13 }, 792 }; 793 794 /* for LP PHY */ 795 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 796 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 797 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 798 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 799 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 800 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 801 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 802 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 803 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 804 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 805 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 806 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 807 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 808 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 809 }; 810 811 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 812 813 static const uint8_t bwn_tab_sigsq_tbl[] = { 814 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 815 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 816 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 817 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 818 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 819 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 820 }; 821 822 static const uint8_t bwn_tab_pllfrac_tbl[] = { 823 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 824 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 825 }; 826 827 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 828 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 829 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 831 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 832 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 833 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 838 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 839 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 840 }; 841 842 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 843 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 844 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 845 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 846 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 847 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 848 849 #define VENDOR_LED_ACT(vendor) \ 850 { \ 851 .vid = PCI_VENDOR_##vendor, \ 852 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 853 } 854 855 static const struct { 856 uint16_t vid; 857 uint8_t led_act[BWN_LED_MAX]; 858 } bwn_vendor_led_act[] = { 859 VENDOR_LED_ACT(COMPAQ), 860 VENDOR_LED_ACT(ASUSTEK) 861 }; 862 863 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 864 { BWN_VENDOR_LED_ACT_DEFAULT }; 865 866 #undef VENDOR_LED_ACT 867 868 static const struct { 869 int on_dur; 870 int off_dur; 871 } bwn_led_duration[109] = { 872 [0] = { 400, 100 }, 873 [2] = { 150, 75 }, 874 [4] = { 90, 45 }, 875 [11] = { 66, 34 }, 876 [12] = { 53, 26 }, 877 [18] = { 42, 21 }, 878 [22] = { 35, 17 }, 879 [24] = { 32, 16 }, 880 [36] = { 21, 10 }, 881 [48] = { 16, 8 }, 882 [72] = { 11, 5 }, 883 [96] = { 9, 4 }, 884 [108] = { 7, 3 } 885 }; 886 887 static const uint16_t bwn_wme_shm_offsets[] = { 888 [0] = BWN_WME_BESTEFFORT, 889 [1] = BWN_WME_BACKGROUND, 890 [2] = BWN_WME_VOICE, 891 [3] = BWN_WME_VIDEO, 892 }; 893 894 static const struct siba_devid bwn_devs[] = { 895 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 896 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 897 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 898 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 899 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 900 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 901 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 902 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 903 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 904 }; 905 906 static int 907 bwn_probe(device_t dev) 908 { 909 int i; 910 911 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 912 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 913 siba_get_device(dev) == bwn_devs[i].sd_device && 914 siba_get_revid(dev) == bwn_devs[i].sd_rev) 915 return (BUS_PROBE_DEFAULT); 916 } 917 918 return (ENXIO); 919 } 920 921 static int 922 bwn_attach(device_t dev) 923 { 924 struct bwn_mac *mac; 925 struct bwn_softc *sc = device_get_softc(dev); 926 int error, i, msic, reg; 927 928 sc->sc_dev = dev; 929 #ifdef BWN_DEBUG 930 sc->sc_debug = bwn_debug; 931 #endif 932 933 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 934 error = bwn_attach_pre(sc); 935 if (error != 0) 936 return (error); 937 bwn_sprom_bugfixes(dev); 938 sc->sc_flags |= BWN_FLAG_ATTACHED; 939 } 940 941 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 942 if (siba_get_pci_device(dev) != 0x4313 && 943 siba_get_pci_device(dev) != 0x431a && 944 siba_get_pci_device(dev) != 0x4321) { 945 device_printf(sc->sc_dev, 946 "skip 802.11 cores\n"); 947 return (ENODEV); 948 } 949 } 950 951 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, 952 M_NOWAIT | M_ZERO); 953 if (mac == NULL) 954 return (ENOMEM); 955 mac->mac_sc = sc; 956 mac->mac_status = BWN_MAC_STATUS_UNINIT; 957 if (bwn_bfp != 0) 958 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 959 960 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 961 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 962 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 963 964 error = bwn_attach_core(mac); 965 if (error) 966 goto fail0; 967 bwn_led_attach(mac); 968 969 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 970 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 971 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 972 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 973 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 974 mac->mac_phy.rf_rev); 975 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 976 device_printf(sc->sc_dev, "DMA (%d bits)\n", 977 mac->mac_method.dma.dmatype); 978 else 979 device_printf(sc->sc_dev, "PIO\n"); 980 981 /* 982 * setup PCI resources and interrupt. 983 */ 984 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { 985 msic = pci_msi_count(dev); 986 if (bootverbose) 987 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 988 } else 989 msic = 0; 990 991 mac->mac_intr_spec = bwn_res_spec_legacy; 992 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 993 if (pci_alloc_msi(dev, &msic) == 0) { 994 device_printf(sc->sc_dev, 995 "Using %d MSI messages\n", msic); 996 mac->mac_intr_spec = bwn_res_spec_msi; 997 mac->mac_msi = 1; 998 } 999 } 1000 1001 error = bus_alloc_resources(dev, mac->mac_intr_spec, 1002 mac->mac_res_irq); 1003 if (error) { 1004 device_printf(sc->sc_dev, 1005 "couldn't allocate IRQ resources (%d)\n", error); 1006 goto fail1; 1007 } 1008 1009 if (mac->mac_msi == 0) 1010 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1011 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1012 &mac->mac_intrhand[0]); 1013 else { 1014 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1015 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1016 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1017 &mac->mac_intrhand[i]); 1018 if (error != 0) { 1019 device_printf(sc->sc_dev, 1020 "couldn't setup interrupt (%d)\n", error); 1021 break; 1022 } 1023 } 1024 } 1025 1026 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1027 1028 /* 1029 * calls attach-post routine 1030 */ 1031 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1032 bwn_attach_post(sc); 1033 1034 return (0); 1035 fail1: 1036 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1037 pci_release_msi(dev); 1038 fail0: 1039 free(mac, M_DEVBUF); 1040 return (error); 1041 } 1042 1043 static int 1044 bwn_is_valid_ether_addr(uint8_t *addr) 1045 { 1046 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1047 1048 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1049 return (FALSE); 1050 1051 return (TRUE); 1052 } 1053 1054 static int 1055 bwn_attach_post(struct bwn_softc *sc) 1056 { 1057 struct ieee80211com *ic; 1058 struct ifnet *ifp = sc->sc_ifp; 1059 1060 ic = ifp->if_l2com; 1061 ic->ic_ifp = ifp; 1062 /* XXX not right but it's not used anywhere important */ 1063 ic->ic_phytype = IEEE80211_T_OFDM; 1064 ic->ic_opmode = IEEE80211_M_STA; 1065 ic->ic_caps = 1066 IEEE80211_C_STA /* station mode supported */ 1067 | IEEE80211_C_MONITOR /* monitor mode */ 1068 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1069 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1070 | IEEE80211_C_SHSLOT /* short slot time supported */ 1071 | IEEE80211_C_WME /* WME/WMM supported */ 1072 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1073 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1074 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1075 ; 1076 1077 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1078 1079 /* call MI attach routine. */ 1080 ieee80211_ifattach(ic, 1081 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1082 siba_sprom_get_mac_80211a(sc->sc_dev) : 1083 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1084 1085 ic->ic_headroom = sizeof(struct bwn_txhdr); 1086 1087 /* override default methods */ 1088 ic->ic_raw_xmit = bwn_raw_xmit; 1089 ic->ic_updateslot = bwn_updateslot; 1090 ic->ic_update_promisc = bwn_update_promisc; 1091 ic->ic_wme.wme_update = bwn_wme_update; 1092 1093 ic->ic_scan_start = bwn_scan_start; 1094 ic->ic_scan_end = bwn_scan_end; 1095 ic->ic_set_channel = bwn_set_channel; 1096 1097 ic->ic_vap_create = bwn_vap_create; 1098 ic->ic_vap_delete = bwn_vap_delete; 1099 1100 ieee80211_radiotap_attach(ic, 1101 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1102 BWN_TX_RADIOTAP_PRESENT, 1103 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1104 BWN_RX_RADIOTAP_PRESENT); 1105 1106 bwn_sysctl_node(sc); 1107 1108 if (bootverbose) 1109 ieee80211_announce(ic); 1110 return (0); 1111 } 1112 1113 static void 1114 bwn_phy_detach(struct bwn_mac *mac) 1115 { 1116 1117 if (mac->mac_phy.detach != NULL) 1118 mac->mac_phy.detach(mac); 1119 } 1120 1121 static int 1122 bwn_detach(device_t dev) 1123 { 1124 struct bwn_softc *sc = device_get_softc(dev); 1125 struct bwn_mac *mac = sc->sc_curmac; 1126 struct ifnet *ifp = sc->sc_ifp; 1127 struct ieee80211com *ic = ifp->if_l2com; 1128 int i; 1129 1130 sc->sc_flags |= BWN_FLAG_INVALID; 1131 1132 if (device_is_attached(sc->sc_dev)) { 1133 bwn_stop(sc, 1); 1134 bwn_dma_free(mac); 1135 callout_drain(&sc->sc_led_blink_ch); 1136 callout_drain(&sc->sc_rfswitch_ch); 1137 callout_drain(&sc->sc_task_ch); 1138 callout_drain(&sc->sc_watchdog_ch); 1139 bwn_phy_detach(mac); 1140 if (ifp != NULL) { 1141 ieee80211_draintask(ic, &mac->mac_hwreset); 1142 ieee80211_draintask(ic, &mac->mac_txpower); 1143 ieee80211_ifdetach(ic); 1144 if_free(ifp); 1145 } 1146 } 1147 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1148 taskqueue_free(sc->sc_tq); 1149 1150 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1151 if (mac->mac_intrhand[i] != NULL) { 1152 bus_teardown_intr(dev, mac->mac_res_irq[i], 1153 mac->mac_intrhand[i]); 1154 mac->mac_intrhand[i] = NULL; 1155 } 1156 } 1157 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1158 if (mac->mac_msi != 0) 1159 pci_release_msi(dev); 1160 1161 BWN_LOCK_DESTROY(sc); 1162 return (0); 1163 } 1164 1165 static int 1166 bwn_attach_pre(struct bwn_softc *sc) 1167 { 1168 struct ifnet *ifp; 1169 int error = 0; 1170 1171 BWN_LOCK_INIT(sc); 1172 TAILQ_INIT(&sc->sc_maclist); 1173 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1174 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1175 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1176 1177 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1178 taskqueue_thread_enqueue, &sc->sc_tq); 1179 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1180 "%s taskq", device_get_nameunit(sc->sc_dev)); 1181 1182 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1183 if (ifp == NULL) { 1184 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1185 error = ENOSPC; 1186 goto fail; 1187 } 1188 1189 /* set these up early for if_printf use */ 1190 if_initname(ifp, device_get_name(sc->sc_dev), 1191 device_get_unit(sc->sc_dev)); 1192 1193 ifp->if_softc = sc; 1194 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1195 ifp->if_init = bwn_init; 1196 ifp->if_ioctl = bwn_ioctl; 1197 ifp->if_start = bwn_start; 1198 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 1199 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 1200 IFQ_SET_READY(&ifp->if_snd); 1201 1202 return (0); 1203 1204 fail: BWN_LOCK_DESTROY(sc); 1205 return (error); 1206 } 1207 1208 static void 1209 bwn_sprom_bugfixes(device_t dev) 1210 { 1211 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1212 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1213 (siba_get_pci_device(dev) == _device) && \ 1214 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1215 (siba_get_pci_subdevice(dev) == _subdevice)) 1216 1217 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1218 siba_get_pci_subdevice(dev) == 0x4e && 1219 siba_get_pci_revid(dev) > 0x40) 1220 siba_sprom_set_bf_lo(dev, 1221 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1222 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1223 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1224 siba_sprom_set_bf_lo(dev, 1225 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1226 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1227 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1228 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1229 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1230 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1231 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1232 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1233 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1234 siba_sprom_set_bf_lo(dev, 1235 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1236 } 1237 #undef BWN_ISDEV 1238 } 1239 1240 static int 1241 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1242 { 1243 #define IS_RUNNING(ifp) \ 1244 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1245 struct bwn_softc *sc = ifp->if_softc; 1246 struct ieee80211com *ic = ifp->if_l2com; 1247 struct ifreq *ifr = (struct ifreq *)data; 1248 int error = 0, startall; 1249 1250 switch (cmd) { 1251 case SIOCSIFFLAGS: 1252 startall = 0; 1253 if (IS_RUNNING(ifp)) { 1254 bwn_update_promisc(ifp); 1255 } else if (ifp->if_flags & IFF_UP) { 1256 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1257 bwn_init(sc); 1258 startall = 1; 1259 } 1260 } else 1261 bwn_stop(sc, 1); 1262 if (startall) 1263 ieee80211_start_all(ic); 1264 break; 1265 case SIOCGIFMEDIA: 1266 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1267 break; 1268 case SIOCGIFADDR: 1269 error = ether_ioctl(ifp, cmd, data); 1270 break; 1271 default: 1272 error = EINVAL; 1273 break; 1274 } 1275 return (error); 1276 } 1277 1278 static void 1279 bwn_start(struct ifnet *ifp) 1280 { 1281 struct bwn_softc *sc = ifp->if_softc; 1282 1283 BWN_LOCK(sc); 1284 bwn_start_locked(ifp); 1285 BWN_UNLOCK(sc); 1286 } 1287 1288 static void 1289 bwn_start_locked(struct ifnet *ifp) 1290 { 1291 struct bwn_softc *sc = ifp->if_softc; 1292 struct bwn_mac *mac = sc->sc_curmac; 1293 struct ieee80211_frame *wh; 1294 struct ieee80211_node *ni; 1295 struct ieee80211_key *k; 1296 struct mbuf *m; 1297 1298 BWN_ASSERT_LOCKED(sc); 1299 1300 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1301 mac->mac_status < BWN_MAC_STATUS_STARTED) 1302 return; 1303 1304 for (;;) { 1305 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1306 if (m == NULL) 1307 break; 1308 1309 if (bwn_tx_isfull(sc, m)) 1310 break; 1311 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1312 if (ni == NULL) { 1313 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1314 m_freem(m); 1315 ifp->if_oerrors++; 1316 continue; 1317 } 1318 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1319 wh = mtod(m, struct ieee80211_frame *); 1320 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1321 k = ieee80211_crypto_encap(ni, m); 1322 if (k == NULL) { 1323 ieee80211_free_node(ni); 1324 m_freem(m); 1325 ifp->if_oerrors++; 1326 continue; 1327 } 1328 } 1329 wh = NULL; /* Catch any invalid use */ 1330 1331 if (bwn_tx_start(sc, ni, m) != 0) { 1332 if (ni != NULL) 1333 ieee80211_free_node(ni); 1334 ifp->if_oerrors++; 1335 continue; 1336 } 1337 1338 sc->sc_watchdog_timer = 5; 1339 } 1340 } 1341 1342 static int 1343 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1344 { 1345 struct bwn_dma_ring *dr; 1346 struct bwn_mac *mac = sc->sc_curmac; 1347 struct bwn_pio_txqueue *tq; 1348 struct ifnet *ifp = sc->sc_ifp; 1349 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1350 1351 BWN_ASSERT_LOCKED(sc); 1352 1353 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1354 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1355 if (dr->dr_stop == 1 || 1356 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1357 dr->dr_stop = 1; 1358 goto full; 1359 } 1360 } else { 1361 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1362 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1363 pktlen > (tq->tq_size - tq->tq_used)) { 1364 tq->tq_stop = 1; 1365 goto full; 1366 } 1367 } 1368 return (0); 1369 full: 1370 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1371 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1372 return (1); 1373 } 1374 1375 static int 1376 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1377 { 1378 struct bwn_mac *mac = sc->sc_curmac; 1379 int error; 1380 1381 BWN_ASSERT_LOCKED(sc); 1382 1383 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1384 m_freem(m); 1385 return (ENXIO); 1386 } 1387 1388 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1389 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1390 if (error) { 1391 m_freem(m); 1392 return (error); 1393 } 1394 return (0); 1395 } 1396 1397 static int 1398 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1399 { 1400 struct bwn_pio_txpkt *tp; 1401 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1402 struct bwn_softc *sc = mac->mac_sc; 1403 struct bwn_txhdr txhdr; 1404 struct mbuf *m_new; 1405 uint32_t ctl32; 1406 int error; 1407 uint16_t ctl16; 1408 1409 BWN_ASSERT_LOCKED(sc); 1410 1411 /* XXX TODO send packets after DTIM */ 1412 1413 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1414 tp = TAILQ_FIRST(&tq->tq_pktlist); 1415 tp->tp_ni = ni; 1416 tp->tp_m = m; 1417 1418 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1419 if (error) { 1420 device_printf(sc->sc_dev, "tx fail\n"); 1421 return (error); 1422 } 1423 1424 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1425 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1426 tq->tq_free--; 1427 1428 if (siba_get_revid(sc->sc_dev) >= 8) { 1429 /* 1430 * XXX please removes m_defrag(9) 1431 */ 1432 m_new = m_defrag(m, M_NOWAIT); 1433 if (m_new == NULL) { 1434 device_printf(sc->sc_dev, 1435 "%s: can't defrag TX buffer\n", 1436 __func__); 1437 return (ENOBUFS); 1438 } 1439 if (m_new->m_next != NULL) 1440 device_printf(sc->sc_dev, 1441 "TODO: fragmented packets for PIO\n"); 1442 tp->tp_m = m_new; 1443 1444 /* send HEADER */ 1445 ctl32 = bwn_pio_write_multi_4(mac, tq, 1446 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1447 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1448 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1449 /* send BODY */ 1450 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1451 mtod(m_new, const void *), m_new->m_pkthdr.len); 1452 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1453 ctl32 | BWN_PIO8_TXCTL_EOF); 1454 } else { 1455 ctl16 = bwn_pio_write_multi_2(mac, tq, 1456 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1457 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1458 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1459 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1460 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1461 ctl16 | BWN_PIO_TXCTL_EOF); 1462 } 1463 1464 return (0); 1465 } 1466 1467 static struct bwn_pio_txqueue * 1468 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1469 { 1470 1471 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1472 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1473 1474 switch (prio) { 1475 case 0: 1476 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1477 case 1: 1478 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1479 case 2: 1480 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1481 case 3: 1482 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1483 } 1484 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1485 return (NULL); 1486 } 1487 1488 static int 1489 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1490 { 1491 #define BWN_GET_TXHDRCACHE(slot) \ 1492 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1493 struct bwn_dma *dma = &mac->mac_method.dma; 1494 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1495 struct bwn_dmadesc_generic *desc; 1496 struct bwn_dmadesc_meta *mt; 1497 struct bwn_softc *sc = mac->mac_sc; 1498 struct ifnet *ifp = sc->sc_ifp; 1499 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1500 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1501 1502 BWN_ASSERT_LOCKED(sc); 1503 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1504 1505 /* XXX send after DTIM */ 1506 1507 slot = bwn_dma_getslot(dr); 1508 dr->getdesc(dr, slot, &desc, &mt); 1509 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1510 ("%s:%d: fail", __func__, __LINE__)); 1511 1512 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1513 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1514 BWN_DMA_COOKIE(dr, slot)); 1515 if (error) 1516 goto fail; 1517 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1518 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1519 &mt->mt_paddr, BUS_DMA_NOWAIT); 1520 if (error) { 1521 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1522 __func__, error); 1523 goto fail; 1524 } 1525 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1526 BUS_DMASYNC_PREWRITE); 1527 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1528 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1529 BUS_DMASYNC_PREWRITE); 1530 1531 slot = bwn_dma_getslot(dr); 1532 dr->getdesc(dr, slot, &desc, &mt); 1533 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1534 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1535 mt->mt_m = m; 1536 mt->mt_ni = ni; 1537 1538 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1539 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1540 if (error && error != EFBIG) { 1541 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1542 __func__, error); 1543 goto fail; 1544 } 1545 if (error) { /* error == EFBIG */ 1546 struct mbuf *m_new; 1547 1548 m_new = m_defrag(m, M_NOWAIT); 1549 if (m_new == NULL) { 1550 if_printf(ifp, "%s: can't defrag TX buffer\n", 1551 __func__); 1552 error = ENOBUFS; 1553 goto fail; 1554 } else { 1555 m = m_new; 1556 } 1557 1558 mt->mt_m = m; 1559 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1560 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1561 if (error) { 1562 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1563 __func__, error); 1564 goto fail; 1565 } 1566 } 1567 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1568 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1569 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1570 BUS_DMASYNC_PREWRITE); 1571 1572 /* XXX send after DTIM */ 1573 1574 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1575 return (0); 1576 fail: 1577 dr->dr_curslot = backup[0]; 1578 dr->dr_usedslot = backup[1]; 1579 return (error); 1580 #undef BWN_GET_TXHDRCACHE 1581 } 1582 1583 static void 1584 bwn_watchdog(void *arg) 1585 { 1586 struct bwn_softc *sc = arg; 1587 struct ifnet *ifp = sc->sc_ifp; 1588 1589 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1590 if_printf(ifp, "device timeout\n"); 1591 ifp->if_oerrors++; 1592 } 1593 callout_schedule(&sc->sc_watchdog_ch, hz); 1594 } 1595 1596 static int 1597 bwn_attach_core(struct bwn_mac *mac) 1598 { 1599 struct bwn_softc *sc = mac->mac_sc; 1600 int error, have_bg = 0, have_a = 0; 1601 uint32_t high; 1602 1603 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1604 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1605 1606 siba_powerup(sc->sc_dev, 0); 1607 1608 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1609 bwn_reset_core(mac, 1610 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1611 error = bwn_phy_getinfo(mac, high); 1612 if (error) 1613 goto fail; 1614 1615 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1616 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1617 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1618 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1619 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1620 have_a = have_bg = 0; 1621 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1622 have_a = 1; 1623 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1624 mac->mac_phy.type == BWN_PHYTYPE_N || 1625 mac->mac_phy.type == BWN_PHYTYPE_LP) 1626 have_bg = 1; 1627 else 1628 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1629 mac->mac_phy.type)); 1630 } 1631 /* XXX turns off PHY A because it's not supported */ 1632 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1633 mac->mac_phy.type != BWN_PHYTYPE_N) { 1634 have_a = 0; 1635 have_bg = 1; 1636 } 1637 1638 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1639 mac->mac_phy.attach = bwn_phy_g_attach; 1640 mac->mac_phy.detach = bwn_phy_g_detach; 1641 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1642 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1643 mac->mac_phy.init = bwn_phy_g_init; 1644 mac->mac_phy.exit = bwn_phy_g_exit; 1645 mac->mac_phy.phy_read = bwn_phy_g_read; 1646 mac->mac_phy.phy_write = bwn_phy_g_write; 1647 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1648 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1649 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1650 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1651 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1652 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1653 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1654 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1655 mac->mac_phy.set_im = bwn_phy_g_im; 1656 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1657 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1658 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1659 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1660 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1661 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1662 mac->mac_phy.init = bwn_phy_lp_init; 1663 mac->mac_phy.phy_read = bwn_phy_lp_read; 1664 mac->mac_phy.phy_write = bwn_phy_lp_write; 1665 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1666 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1667 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1668 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1669 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1670 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1671 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1672 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1673 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1674 } else { 1675 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1676 mac->mac_phy.type); 1677 error = ENXIO; 1678 goto fail; 1679 } 1680 1681 mac->mac_phy.gmode = have_bg; 1682 if (mac->mac_phy.attach != NULL) { 1683 error = mac->mac_phy.attach(mac); 1684 if (error) { 1685 device_printf(sc->sc_dev, "failed\n"); 1686 goto fail; 1687 } 1688 } 1689 1690 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1691 1692 error = bwn_chiptest(mac); 1693 if (error) 1694 goto fail; 1695 error = bwn_setup_channels(mac, have_bg, have_a); 1696 if (error) { 1697 device_printf(sc->sc_dev, "failed to setup channels\n"); 1698 goto fail; 1699 } 1700 1701 if (sc->sc_curmac == NULL) 1702 sc->sc_curmac = mac; 1703 1704 error = bwn_dma_attach(mac); 1705 if (error != 0) { 1706 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1707 goto fail; 1708 } 1709 1710 mac->mac_phy.switch_analog(mac, 0); 1711 1712 siba_dev_down(sc->sc_dev, 0); 1713 fail: 1714 siba_powerdown(sc->sc_dev); 1715 return (error); 1716 } 1717 1718 static void 1719 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1720 { 1721 struct bwn_softc *sc = mac->mac_sc; 1722 uint32_t low, ctl; 1723 1724 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1725 1726 siba_dev_up(sc->sc_dev, flags); 1727 DELAY(2000); 1728 1729 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1730 ~BWN_TGSLOW_PHYRESET; 1731 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1732 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1733 DELAY(1000); 1734 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1735 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1736 DELAY(1000); 1737 1738 if (mac->mac_phy.switch_analog != NULL) 1739 mac->mac_phy.switch_analog(mac, 1); 1740 1741 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1742 if (flags & BWN_TGSLOW_SUPPORT_G) 1743 ctl |= BWN_MACCTL_GMODE; 1744 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1745 } 1746 1747 static int 1748 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1749 { 1750 struct bwn_phy *phy = &mac->mac_phy; 1751 struct bwn_softc *sc = mac->mac_sc; 1752 uint32_t tmp; 1753 1754 /* PHY */ 1755 tmp = BWN_READ_2(mac, BWN_PHYVER); 1756 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1757 phy->rf_on = 1; 1758 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1759 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1760 phy->rev = (tmp & BWN_PHYVER_VERSION); 1761 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1762 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1763 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1764 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1765 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1766 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1767 goto unsupphy; 1768 1769 /* RADIO */ 1770 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1771 if (siba_get_chiprev(sc->sc_dev) == 0) 1772 tmp = 0x3205017f; 1773 else if (siba_get_chiprev(sc->sc_dev) == 1) 1774 tmp = 0x4205017f; 1775 else 1776 tmp = 0x5205017f; 1777 } else { 1778 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1779 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1780 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1781 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1782 } 1783 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1784 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1785 phy->rf_manuf = (tmp & 0x00000fff); 1786 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1787 goto unsupradio; 1788 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1789 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1790 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1791 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1792 (phy->type == BWN_PHYTYPE_N && 1793 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1794 (phy->type == BWN_PHYTYPE_LP && 1795 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1796 goto unsupradio; 1797 1798 return (0); 1799 unsupphy: 1800 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1801 "analog %#x)\n", 1802 phy->type, phy->rev, phy->analog); 1803 return (ENXIO); 1804 unsupradio: 1805 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1806 "rev %#x)\n", 1807 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1808 return (ENXIO); 1809 } 1810 1811 static int 1812 bwn_chiptest(struct bwn_mac *mac) 1813 { 1814 #define TESTVAL0 0x55aaaa55 1815 #define TESTVAL1 0xaa5555aa 1816 struct bwn_softc *sc = mac->mac_sc; 1817 uint32_t v, backup; 1818 1819 BWN_LOCK(sc); 1820 1821 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1822 1823 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1824 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1825 goto error; 1826 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1827 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1828 goto error; 1829 1830 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1831 1832 if ((siba_get_revid(sc->sc_dev) >= 3) && 1833 (siba_get_revid(sc->sc_dev) <= 10)) { 1834 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1835 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1836 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1837 goto error; 1838 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1839 goto error; 1840 } 1841 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1842 1843 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1844 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1845 goto error; 1846 1847 BWN_UNLOCK(sc); 1848 return (0); 1849 error: 1850 BWN_UNLOCK(sc); 1851 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1852 return (ENODEV); 1853 } 1854 1855 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1856 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1857 1858 static int 1859 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1860 { 1861 struct bwn_softc *sc = mac->mac_sc; 1862 struct ifnet *ifp = sc->sc_ifp; 1863 struct ieee80211com *ic = ifp->if_l2com; 1864 1865 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1866 ic->ic_nchans = 0; 1867 1868 if (have_bg) 1869 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1870 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1871 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1872 if (have_a) 1873 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1874 &ic->ic_nchans, &bwn_chantable_n, 1875 IEEE80211_CHAN_HTA); 1876 } else { 1877 if (have_a) 1878 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1879 &ic->ic_nchans, &bwn_chantable_a, 1880 IEEE80211_CHAN_A); 1881 } 1882 1883 mac->mac_phy.supports_2ghz = have_bg; 1884 mac->mac_phy.supports_5ghz = have_a; 1885 1886 return (ic->ic_nchans == 0 ? ENXIO : 0); 1887 } 1888 1889 static uint32_t 1890 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1891 { 1892 uint32_t ret; 1893 1894 BWN_ASSERT_LOCKED(mac->mac_sc); 1895 1896 if (way == BWN_SHARED) { 1897 KASSERT((offset & 0x0001) == 0, 1898 ("%s:%d warn", __func__, __LINE__)); 1899 if (offset & 0x0003) { 1900 bwn_shm_ctlword(mac, way, offset >> 2); 1901 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1902 ret <<= 16; 1903 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1904 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1905 goto out; 1906 } 1907 offset >>= 2; 1908 } 1909 bwn_shm_ctlword(mac, way, offset); 1910 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1911 out: 1912 return (ret); 1913 } 1914 1915 static uint16_t 1916 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1917 { 1918 uint16_t ret; 1919 1920 BWN_ASSERT_LOCKED(mac->mac_sc); 1921 1922 if (way == BWN_SHARED) { 1923 KASSERT((offset & 0x0001) == 0, 1924 ("%s:%d warn", __func__, __LINE__)); 1925 if (offset & 0x0003) { 1926 bwn_shm_ctlword(mac, way, offset >> 2); 1927 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1928 goto out; 1929 } 1930 offset >>= 2; 1931 } 1932 bwn_shm_ctlword(mac, way, offset); 1933 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1934 out: 1935 1936 return (ret); 1937 } 1938 1939 static void 1940 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1941 uint16_t offset) 1942 { 1943 uint32_t control; 1944 1945 control = way; 1946 control <<= 16; 1947 control |= offset; 1948 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1949 } 1950 1951 static void 1952 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1953 uint32_t value) 1954 { 1955 BWN_ASSERT_LOCKED(mac->mac_sc); 1956 1957 if (way == BWN_SHARED) { 1958 KASSERT((offset & 0x0001) == 0, 1959 ("%s:%d warn", __func__, __LINE__)); 1960 if (offset & 0x0003) { 1961 bwn_shm_ctlword(mac, way, offset >> 2); 1962 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1963 (value >> 16) & 0xffff); 1964 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1965 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1966 return; 1967 } 1968 offset >>= 2; 1969 } 1970 bwn_shm_ctlword(mac, way, offset); 1971 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1972 } 1973 1974 static void 1975 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1976 uint16_t value) 1977 { 1978 BWN_ASSERT_LOCKED(mac->mac_sc); 1979 1980 if (way == BWN_SHARED) { 1981 KASSERT((offset & 0x0001) == 0, 1982 ("%s:%d warn", __func__, __LINE__)); 1983 if (offset & 0x0003) { 1984 bwn_shm_ctlword(mac, way, offset >> 2); 1985 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1986 return; 1987 } 1988 offset >>= 2; 1989 } 1990 bwn_shm_ctlword(mac, way, offset); 1991 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1992 } 1993 1994 static void 1995 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1996 int txpow) 1997 { 1998 1999 c->ic_freq = freq; 2000 c->ic_flags = flags; 2001 c->ic_ieee = ieee; 2002 c->ic_minpower = 0; 2003 c->ic_maxpower = 2 * txpow; 2004 c->ic_maxregpower = txpow; 2005 } 2006 2007 static void 2008 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2009 const struct bwn_channelinfo *ci, int flags) 2010 { 2011 struct ieee80211_channel *c; 2012 int i; 2013 2014 c = &chans[*nchans]; 2015 2016 for (i = 0; i < ci->nchannels; i++) { 2017 const struct bwn_channel *hc; 2018 2019 hc = &ci->channels[i]; 2020 if (*nchans >= maxchans) 2021 break; 2022 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2023 c++, (*nchans)++; 2024 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2025 /* g channel have a separate b-only entry */ 2026 if (*nchans >= maxchans) 2027 break; 2028 c[0] = c[-1]; 2029 c[-1].ic_flags = IEEE80211_CHAN_B; 2030 c++, (*nchans)++; 2031 } 2032 if (flags == IEEE80211_CHAN_HTG) { 2033 /* HT g channel have a separate g-only entry */ 2034 if (*nchans >= maxchans) 2035 break; 2036 c[-1].ic_flags = IEEE80211_CHAN_G; 2037 c[0] = c[-1]; 2038 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2039 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2040 c++, (*nchans)++; 2041 } 2042 if (flags == IEEE80211_CHAN_HTA) { 2043 /* HT a channel have a separate a-only entry */ 2044 if (*nchans >= maxchans) 2045 break; 2046 c[-1].ic_flags = IEEE80211_CHAN_A; 2047 c[0] = c[-1]; 2048 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2049 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2050 c++, (*nchans)++; 2051 } 2052 } 2053 } 2054 2055 static int 2056 bwn_phy_g_attach(struct bwn_mac *mac) 2057 { 2058 struct bwn_softc *sc = mac->mac_sc; 2059 struct bwn_phy *phy = &mac->mac_phy; 2060 struct bwn_phy_g *pg = &phy->phy_g; 2061 unsigned int i; 2062 int16_t pab0, pab1, pab2; 2063 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2064 int8_t bg; 2065 2066 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2067 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2068 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2069 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2070 2071 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2072 device_printf(sc->sc_dev, "not supported anymore\n"); 2073 2074 pg->pg_flags = 0; 2075 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2076 pab2 == -1) { 2077 pg->pg_idletssi = 52; 2078 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2079 return (0); 2080 } 2081 2082 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2083 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2084 if (pg->pg_tssi2dbm == NULL) { 2085 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2086 return (ENOMEM); 2087 } 2088 for (i = 0; i < 64; i++) { 2089 int32_t m1, m2, f, q, delta; 2090 int8_t j = 0; 2091 2092 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2093 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2094 f = 256; 2095 2096 do { 2097 if (j > 15) { 2098 device_printf(sc->sc_dev, 2099 "failed to generate tssi2dBm\n"); 2100 free(pg->pg_tssi2dbm, M_DEVBUF); 2101 return (ENOMEM); 2102 } 2103 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2104 f, 2048); 2105 delta = abs(q - f); 2106 f = q; 2107 j++; 2108 } while (delta >= 2); 2109 2110 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2111 128); 2112 } 2113 2114 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2115 return (0); 2116 } 2117 2118 static void 2119 bwn_phy_g_detach(struct bwn_mac *mac) 2120 { 2121 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2122 2123 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2124 free(pg->pg_tssi2dbm, M_DEVBUF); 2125 pg->pg_tssi2dbm = NULL; 2126 } 2127 pg->pg_flags = 0; 2128 } 2129 2130 static void 2131 bwn_phy_g_init_pre(struct bwn_mac *mac) 2132 { 2133 struct bwn_phy *phy = &mac->mac_phy; 2134 struct bwn_phy_g *pg = &phy->phy_g; 2135 void *tssi2dbm; 2136 int idletssi; 2137 unsigned int i; 2138 2139 tssi2dbm = pg->pg_tssi2dbm; 2140 idletssi = pg->pg_idletssi; 2141 2142 memset(pg, 0, sizeof(*pg)); 2143 2144 pg->pg_tssi2dbm = tssi2dbm; 2145 pg->pg_idletssi = idletssi; 2146 2147 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2148 2149 for (i = 0; i < N(pg->pg_nrssi); i++) 2150 pg->pg_nrssi[i] = -1000; 2151 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2152 pg->pg_nrssi_lt[i] = i; 2153 pg->pg_lofcal = 0xffff; 2154 pg->pg_initval = 0xffff; 2155 pg->pg_immode = BWN_IMMODE_NONE; 2156 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2157 pg->pg_avgtssi = 0xff; 2158 2159 pg->pg_loctl.tx_bias = 0xff; 2160 TAILQ_INIT(&pg->pg_loctl.calib_list); 2161 } 2162 2163 static int 2164 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2165 { 2166 struct bwn_phy *phy = &mac->mac_phy; 2167 struct bwn_phy_g *pg = &phy->phy_g; 2168 struct bwn_softc *sc = mac->mac_sc; 2169 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2170 static const struct bwn_rfatt rfatt0[] = { 2171 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2172 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2173 { 3, 1 }, { 4, 1 } 2174 }; 2175 static const struct bwn_rfatt rfatt1[] = { 2176 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2177 { 14, 1 } 2178 }; 2179 static const struct bwn_rfatt rfatt2[] = { 2180 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2181 { 9, 1 } 2182 }; 2183 static const struct bwn_bbatt bbatt_0[] = { 2184 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2185 }; 2186 2187 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2188 2189 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2190 pg->pg_bbatt.att = 0; 2191 else 2192 pg->pg_bbatt.att = 2; 2193 2194 /* prepare Radio Attenuation */ 2195 pg->pg_rfatt.padmix = 0; 2196 2197 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2198 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2199 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2200 pg->pg_rfatt.att = 2; 2201 goto done; 2202 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2203 pg->pg_rfatt.att = 3; 2204 goto done; 2205 } 2206 } 2207 2208 if (phy->type == BWN_PHYTYPE_A) { 2209 pg->pg_rfatt.att = 0x60; 2210 goto done; 2211 } 2212 2213 switch (phy->rf_ver) { 2214 case 0x2050: 2215 switch (phy->rf_rev) { 2216 case 0: 2217 pg->pg_rfatt.att = 5; 2218 goto done; 2219 case 1: 2220 if (phy->type == BWN_PHYTYPE_G) { 2221 if (siba_get_pci_subvendor(sc->sc_dev) == 2222 SIBA_BOARDVENDOR_BCM && 2223 siba_get_pci_subdevice(sc->sc_dev) == 2224 SIBA_BOARD_BCM4309G && 2225 siba_get_pci_revid(sc->sc_dev) >= 30) 2226 pg->pg_rfatt.att = 3; 2227 else if (siba_get_pci_subvendor(sc->sc_dev) == 2228 SIBA_BOARDVENDOR_BCM && 2229 siba_get_pci_subdevice(sc->sc_dev) == 2230 SIBA_BOARD_BU4306) 2231 pg->pg_rfatt.att = 3; 2232 else 2233 pg->pg_rfatt.att = 1; 2234 } else { 2235 if (siba_get_pci_subvendor(sc->sc_dev) == 2236 SIBA_BOARDVENDOR_BCM && 2237 siba_get_pci_subdevice(sc->sc_dev) == 2238 SIBA_BOARD_BCM4309G && 2239 siba_get_pci_revid(sc->sc_dev) >= 30) 2240 pg->pg_rfatt.att = 7; 2241 else 2242 pg->pg_rfatt.att = 6; 2243 } 2244 goto done; 2245 case 2: 2246 if (phy->type == BWN_PHYTYPE_G) { 2247 if (siba_get_pci_subvendor(sc->sc_dev) == 2248 SIBA_BOARDVENDOR_BCM && 2249 siba_get_pci_subdevice(sc->sc_dev) == 2250 SIBA_BOARD_BCM4309G && 2251 siba_get_pci_revid(sc->sc_dev) >= 30) 2252 pg->pg_rfatt.att = 3; 2253 else if (siba_get_pci_subvendor(sc->sc_dev) == 2254 SIBA_BOARDVENDOR_BCM && 2255 siba_get_pci_subdevice(sc->sc_dev) == 2256 SIBA_BOARD_BU4306) 2257 pg->pg_rfatt.att = 5; 2258 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2259 pg->pg_rfatt.att = 4; 2260 else 2261 pg->pg_rfatt.att = 3; 2262 } else 2263 pg->pg_rfatt.att = 6; 2264 goto done; 2265 case 3: 2266 pg->pg_rfatt.att = 5; 2267 goto done; 2268 case 4: 2269 case 5: 2270 pg->pg_rfatt.att = 1; 2271 goto done; 2272 case 6: 2273 case 7: 2274 pg->pg_rfatt.att = 5; 2275 goto done; 2276 case 8: 2277 pg->pg_rfatt.att = 0xa; 2278 pg->pg_rfatt.padmix = 1; 2279 goto done; 2280 case 9: 2281 default: 2282 pg->pg_rfatt.att = 5; 2283 goto done; 2284 } 2285 break; 2286 case 0x2053: 2287 switch (phy->rf_rev) { 2288 case 1: 2289 pg->pg_rfatt.att = 6; 2290 goto done; 2291 } 2292 break; 2293 } 2294 pg->pg_rfatt.att = 5; 2295 done: 2296 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2297 2298 if (!bwn_has_hwpctl(mac)) { 2299 lo->rfatt.array = rfatt0; 2300 lo->rfatt.len = N(rfatt0); 2301 lo->rfatt.min = 0; 2302 lo->rfatt.max = 9; 2303 goto genbbatt; 2304 } 2305 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2306 lo->rfatt.array = rfatt1; 2307 lo->rfatt.len = N(rfatt1); 2308 lo->rfatt.min = 0; 2309 lo->rfatt.max = 14; 2310 goto genbbatt; 2311 } 2312 lo->rfatt.array = rfatt2; 2313 lo->rfatt.len = N(rfatt2); 2314 lo->rfatt.min = 0; 2315 lo->rfatt.max = 9; 2316 genbbatt: 2317 lo->bbatt.array = bbatt_0; 2318 lo->bbatt.len = N(bbatt_0); 2319 lo->bbatt.min = 0; 2320 lo->bbatt.max = 8; 2321 2322 BWN_READ_4(mac, BWN_MACCTL); 2323 if (phy->rev == 1) { 2324 phy->gmode = 0; 2325 bwn_reset_core(mac, 0); 2326 bwn_phy_g_init_sub(mac); 2327 phy->gmode = 1; 2328 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2329 } 2330 return (0); 2331 } 2332 2333 static uint16_t 2334 bwn_phy_g_txctl(struct bwn_mac *mac) 2335 { 2336 struct bwn_phy *phy = &mac->mac_phy; 2337 2338 if (phy->rf_ver != 0x2050) 2339 return (0); 2340 if (phy->rf_rev == 1) 2341 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2342 if (phy->rf_rev < 6) 2343 return (BWN_TXCTL_PA2DB); 2344 if (phy->rf_rev == 8) 2345 return (BWN_TXCTL_TXMIX); 2346 return (0); 2347 } 2348 2349 static int 2350 bwn_phy_g_init(struct bwn_mac *mac) 2351 { 2352 2353 bwn_phy_g_init_sub(mac); 2354 return (0); 2355 } 2356 2357 static void 2358 bwn_phy_g_exit(struct bwn_mac *mac) 2359 { 2360 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2361 struct bwn_lo_calib *cal, *tmp; 2362 2363 if (lo == NULL) 2364 return; 2365 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2366 TAILQ_REMOVE(&lo->calib_list, cal, list); 2367 free(cal, M_DEVBUF); 2368 } 2369 } 2370 2371 static uint16_t 2372 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2373 { 2374 2375 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2376 return (BWN_READ_2(mac, BWN_PHYDATA)); 2377 } 2378 2379 static void 2380 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2381 { 2382 2383 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2384 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2385 } 2386 2387 static uint16_t 2388 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2389 { 2390 2391 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2392 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2393 return (BWN_READ_2(mac, BWN_RFDATALO)); 2394 } 2395 2396 static void 2397 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2398 { 2399 2400 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2401 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2402 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2403 } 2404 2405 static int 2406 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2407 { 2408 2409 return (mac->mac_phy.rev >= 6); 2410 } 2411 2412 static void 2413 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2414 { 2415 struct bwn_phy *phy = &mac->mac_phy; 2416 struct bwn_phy_g *pg = &phy->phy_g; 2417 unsigned int channel; 2418 uint16_t rfover, rfoverval; 2419 2420 if (on) { 2421 if (phy->rf_on) 2422 return; 2423 2424 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2425 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2426 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2427 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2428 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2429 pg->pg_radioctx_over); 2430 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2431 pg->pg_radioctx_overval); 2432 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2433 } 2434 channel = phy->chan; 2435 bwn_phy_g_switch_chan(mac, 6, 1); 2436 bwn_phy_g_switch_chan(mac, channel, 0); 2437 return; 2438 } 2439 2440 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2441 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2442 pg->pg_radioctx_over = rfover; 2443 pg->pg_radioctx_overval = rfoverval; 2444 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2445 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2446 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2447 } 2448 2449 static int 2450 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2451 { 2452 2453 if ((newchan < 1) || (newchan > 14)) 2454 return (EINVAL); 2455 bwn_phy_g_switch_chan(mac, newchan, 0); 2456 2457 return (0); 2458 } 2459 2460 static uint32_t 2461 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2462 { 2463 2464 return (1); 2465 } 2466 2467 static void 2468 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2469 { 2470 struct bwn_phy *phy = &mac->mac_phy; 2471 uint64_t hf; 2472 int autodiv = 0; 2473 uint16_t tmp; 2474 2475 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2476 autodiv = 1; 2477 2478 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2479 bwn_hf_write(mac, hf); 2480 2481 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2482 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2483 ((autodiv ? BWN_ANTAUTO1 : antenna) 2484 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2485 2486 if (autodiv) { 2487 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2488 if (antenna == BWN_ANTAUTO1) 2489 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2490 else 2491 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2492 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2493 } 2494 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2495 if (autodiv) 2496 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2497 else 2498 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2499 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2500 if (phy->rev >= 2) { 2501 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2502 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2503 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2504 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2505 0x15); 2506 if (phy->rev == 2) 2507 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2508 else 2509 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2510 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2511 8); 2512 } 2513 if (phy->rev >= 6) 2514 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2515 2516 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2517 bwn_hf_write(mac, hf); 2518 } 2519 2520 static int 2521 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2522 { 2523 struct bwn_phy *phy = &mac->mac_phy; 2524 struct bwn_phy_g *pg = &phy->phy_g; 2525 2526 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2527 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2528 2529 if (phy->rev == 0 || !phy->gmode) 2530 return (ENODEV); 2531 2532 pg->pg_aci_wlan_automatic = 0; 2533 return (0); 2534 } 2535 2536 static int 2537 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2538 { 2539 struct bwn_phy *phy = &mac->mac_phy; 2540 struct bwn_phy_g *pg = &phy->phy_g; 2541 struct bwn_softc *sc = mac->mac_sc; 2542 unsigned int tssi; 2543 int cck, ofdm; 2544 int power; 2545 int rfatt, bbatt; 2546 unsigned int max; 2547 2548 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2549 2550 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2551 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2552 if (cck < 0 && ofdm < 0) { 2553 if (ignore_tssi == 0) 2554 return (BWN_TXPWR_RES_DONE); 2555 cck = 0; 2556 ofdm = 0; 2557 } 2558 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2559 if (pg->pg_avgtssi != 0xff) 2560 tssi = (tssi + pg->pg_avgtssi) / 2; 2561 pg->pg_avgtssi = tssi; 2562 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2563 2564 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2565 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2566 max -= 3; 2567 if (max >= 120) { 2568 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2569 max = 80; 2570 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2571 } 2572 2573 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2574 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2575 tssi, 0x00), 0x3f)]); 2576 if (power == 0) 2577 return (BWN_TXPWR_RES_DONE); 2578 2579 rfatt = -((power + 7) / 8); 2580 bbatt = (-(power / 2)) - (4 * rfatt); 2581 if ((rfatt == 0) && (bbatt == 0)) 2582 return (BWN_TXPWR_RES_DONE); 2583 pg->pg_bbatt_delta = bbatt; 2584 pg->pg_rfatt_delta = rfatt; 2585 return (BWN_TXPWR_RES_NEED_ADJUST); 2586 } 2587 2588 static void 2589 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2590 { 2591 struct bwn_phy *phy = &mac->mac_phy; 2592 struct bwn_phy_g *pg = &phy->phy_g; 2593 struct bwn_softc *sc = mac->mac_sc; 2594 int rfatt, bbatt; 2595 uint8_t txctl; 2596 2597 bwn_mac_suspend(mac); 2598 2599 BWN_ASSERT_LOCKED(sc); 2600 2601 bbatt = pg->pg_bbatt.att; 2602 bbatt += pg->pg_bbatt_delta; 2603 rfatt = pg->pg_rfatt.att; 2604 rfatt += pg->pg_rfatt_delta; 2605 2606 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2607 txctl = pg->pg_txctl; 2608 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2609 if (rfatt <= 1) { 2610 if (txctl == 0) { 2611 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2612 rfatt += 2; 2613 bbatt += 2; 2614 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2615 BWN_BFL_PACTRL) { 2616 bbatt += 4 * (rfatt - 2); 2617 rfatt = 2; 2618 } 2619 } else if (rfatt > 4 && txctl) { 2620 txctl = 0; 2621 if (bbatt < 3) { 2622 rfatt -= 3; 2623 bbatt += 2; 2624 } else { 2625 rfatt -= 2; 2626 bbatt -= 2; 2627 } 2628 } 2629 } 2630 pg->pg_txctl = txctl; 2631 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2632 pg->pg_rfatt.att = rfatt; 2633 pg->pg_bbatt.att = bbatt; 2634 2635 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2636 2637 bwn_phy_lock(mac); 2638 bwn_rf_lock(mac); 2639 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2640 pg->pg_txctl); 2641 bwn_rf_unlock(mac); 2642 bwn_phy_unlock(mac); 2643 2644 bwn_mac_enable(mac); 2645 } 2646 2647 static void 2648 bwn_phy_g_task_15s(struct bwn_mac *mac) 2649 { 2650 struct bwn_phy *phy = &mac->mac_phy; 2651 struct bwn_phy_g *pg = &phy->phy_g; 2652 struct bwn_softc *sc = mac->mac_sc; 2653 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2654 unsigned long expire, now; 2655 struct bwn_lo_calib *cal, *tmp; 2656 uint8_t expired = 0; 2657 2658 bwn_mac_suspend(mac); 2659 2660 if (lo == NULL) 2661 goto fail; 2662 2663 BWN_GETTIME(now); 2664 if (bwn_has_hwpctl(mac)) { 2665 expire = now - BWN_LO_PWRVEC_EXPIRE; 2666 if (time_before(lo->pwr_vec_read_time, expire)) { 2667 bwn_lo_get_powervector(mac); 2668 bwn_phy_g_dc_lookup_init(mac, 0); 2669 } 2670 goto fail; 2671 } 2672 2673 expire = now - BWN_LO_CALIB_EXPIRE; 2674 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2675 if (!time_before(cal->calib_time, expire)) 2676 continue; 2677 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2678 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2679 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2680 expired = 1; 2681 } 2682 2683 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2684 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2685 cal->ctl.i, cal->ctl.q); 2686 2687 TAILQ_REMOVE(&lo->calib_list, cal, list); 2688 free(cal, M_DEVBUF); 2689 } 2690 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2691 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2692 &pg->pg_rfatt); 2693 if (cal == NULL) { 2694 device_printf(sc->sc_dev, 2695 "failed to recalibrate LO\n"); 2696 goto fail; 2697 } 2698 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2699 bwn_lo_write(mac, &cal->ctl); 2700 } 2701 2702 fail: 2703 bwn_mac_enable(mac); 2704 } 2705 2706 static void 2707 bwn_phy_g_task_60s(struct bwn_mac *mac) 2708 { 2709 struct bwn_phy *phy = &mac->mac_phy; 2710 struct bwn_softc *sc = mac->mac_sc; 2711 uint8_t old = phy->chan; 2712 2713 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2714 return; 2715 2716 bwn_mac_suspend(mac); 2717 bwn_nrssi_slope_11g(mac); 2718 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2719 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2720 bwn_switch_channel(mac, old); 2721 } 2722 bwn_mac_enable(mac); 2723 } 2724 2725 static void 2726 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2727 { 2728 2729 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2730 } 2731 2732 static int 2733 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2734 const struct ieee80211_bpf_params *params) 2735 { 2736 struct ieee80211com *ic = ni->ni_ic; 2737 struct ifnet *ifp = ic->ic_ifp; 2738 struct bwn_softc *sc = ifp->if_softc; 2739 struct bwn_mac *mac = sc->sc_curmac; 2740 2741 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2742 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2743 ieee80211_free_node(ni); 2744 m_freem(m); 2745 return (ENETDOWN); 2746 } 2747 2748 BWN_LOCK(sc); 2749 if (bwn_tx_isfull(sc, m)) { 2750 ieee80211_free_node(ni); 2751 m_freem(m); 2752 ifp->if_oerrors++; 2753 BWN_UNLOCK(sc); 2754 return (ENOBUFS); 2755 } 2756 2757 if (bwn_tx_start(sc, ni, m) != 0) { 2758 if (ni != NULL) 2759 ieee80211_free_node(ni); 2760 ifp->if_oerrors++; 2761 } 2762 sc->sc_watchdog_timer = 5; 2763 BWN_UNLOCK(sc); 2764 return (0); 2765 } 2766 2767 /* 2768 * Callback from the 802.11 layer to update the slot time 2769 * based on the current setting. We use it to notify the 2770 * firmware of ERP changes and the f/w takes care of things 2771 * like slot time and preamble. 2772 */ 2773 static void 2774 bwn_updateslot(struct ifnet *ifp) 2775 { 2776 struct bwn_softc *sc = ifp->if_softc; 2777 struct ieee80211com *ic = ifp->if_l2com; 2778 struct bwn_mac *mac; 2779 2780 BWN_LOCK(sc); 2781 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2782 mac = (struct bwn_mac *)sc->sc_curmac; 2783 bwn_set_slot_time(mac, 2784 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2785 } 2786 BWN_UNLOCK(sc); 2787 } 2788 2789 /* 2790 * Callback from the 802.11 layer after a promiscuous mode change. 2791 * Note this interface does not check the operating mode as this 2792 * is an internal callback and we are expected to honor the current 2793 * state (e.g. this is used for setting the interface in promiscuous 2794 * mode when operating in hostap mode to do ACS). 2795 */ 2796 static void 2797 bwn_update_promisc(struct ifnet *ifp) 2798 { 2799 struct bwn_softc *sc = ifp->if_softc; 2800 struct bwn_mac *mac = sc->sc_curmac; 2801 2802 BWN_LOCK(sc); 2803 mac = sc->sc_curmac; 2804 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2805 if (ifp->if_flags & IFF_PROMISC) 2806 sc->sc_filters |= BWN_MACCTL_PROMISC; 2807 else 2808 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2809 bwn_set_opmode(mac); 2810 } 2811 BWN_UNLOCK(sc); 2812 } 2813 2814 /* 2815 * Callback from the 802.11 layer to update WME parameters. 2816 */ 2817 static int 2818 bwn_wme_update(struct ieee80211com *ic) 2819 { 2820 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2821 struct bwn_mac *mac = sc->sc_curmac; 2822 struct wmeParams *wmep; 2823 int i; 2824 2825 BWN_LOCK(sc); 2826 mac = sc->sc_curmac; 2827 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2828 bwn_mac_suspend(mac); 2829 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2830 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2831 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2832 } 2833 bwn_mac_enable(mac); 2834 } 2835 BWN_UNLOCK(sc); 2836 return (0); 2837 } 2838 2839 static void 2840 bwn_scan_start(struct ieee80211com *ic) 2841 { 2842 struct ifnet *ifp = ic->ic_ifp; 2843 struct bwn_softc *sc = ifp->if_softc; 2844 struct bwn_mac *mac; 2845 2846 BWN_LOCK(sc); 2847 mac = sc->sc_curmac; 2848 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2849 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2850 bwn_set_opmode(mac); 2851 /* disable CFP update during scan */ 2852 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2853 } 2854 BWN_UNLOCK(sc); 2855 } 2856 2857 static void 2858 bwn_scan_end(struct ieee80211com *ic) 2859 { 2860 struct ifnet *ifp = ic->ic_ifp; 2861 struct bwn_softc *sc = ifp->if_softc; 2862 struct bwn_mac *mac; 2863 2864 BWN_LOCK(sc); 2865 mac = sc->sc_curmac; 2866 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2867 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2868 bwn_set_opmode(mac); 2869 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2870 } 2871 BWN_UNLOCK(sc); 2872 } 2873 2874 static void 2875 bwn_set_channel(struct ieee80211com *ic) 2876 { 2877 struct ifnet *ifp = ic->ic_ifp; 2878 struct bwn_softc *sc = ifp->if_softc; 2879 struct bwn_mac *mac = sc->sc_curmac; 2880 struct bwn_phy *phy = &mac->mac_phy; 2881 int chan, error; 2882 2883 BWN_LOCK(sc); 2884 2885 error = bwn_switch_band(sc, ic->ic_curchan); 2886 if (error) 2887 goto fail; 2888 bwn_mac_suspend(mac); 2889 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2890 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2891 if (chan != phy->chan) 2892 bwn_switch_channel(mac, chan); 2893 2894 /* TX power level */ 2895 if (ic->ic_curchan->ic_maxpower != 0 && 2896 ic->ic_curchan->ic_maxpower != phy->txpower) { 2897 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2898 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2899 BWN_TXPWR_IGNORE_TSSI); 2900 } 2901 2902 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2903 if (phy->set_antenna) 2904 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2905 2906 if (sc->sc_rf_enabled != phy->rf_on) { 2907 if (sc->sc_rf_enabled) { 2908 bwn_rf_turnon(mac); 2909 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2910 device_printf(sc->sc_dev, 2911 "please turn on the RF switch\n"); 2912 } else 2913 bwn_rf_turnoff(mac); 2914 } 2915 2916 bwn_mac_enable(mac); 2917 2918 fail: 2919 /* 2920 * Setup radio tap channel freq and flags 2921 */ 2922 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2923 htole16(ic->ic_curchan->ic_freq); 2924 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2925 htole16(ic->ic_curchan->ic_flags & 0xffff); 2926 2927 BWN_UNLOCK(sc); 2928 } 2929 2930 static struct ieee80211vap * 2931 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2932 enum ieee80211_opmode opmode, int flags, 2933 const uint8_t bssid[IEEE80211_ADDR_LEN], 2934 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2935 { 2936 struct ifnet *ifp = ic->ic_ifp; 2937 struct bwn_softc *sc = ifp->if_softc; 2938 struct ieee80211vap *vap; 2939 struct bwn_vap *bvp; 2940 uint8_t mac[IEEE80211_ADDR_LEN]; 2941 2942 IEEE80211_ADDR_COPY(mac, mac0); 2943 switch (opmode) { 2944 case IEEE80211_M_HOSTAP: 2945 case IEEE80211_M_MBSS: 2946 case IEEE80211_M_STA: 2947 case IEEE80211_M_WDS: 2948 case IEEE80211_M_MONITOR: 2949 case IEEE80211_M_IBSS: 2950 case IEEE80211_M_AHDEMO: 2951 break; 2952 default: 2953 return (NULL); 2954 } 2955 2956 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2957 2958 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 2959 M_80211_VAP, M_NOWAIT | M_ZERO); 2960 if (bvp == NULL) { 2961 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 2962 return (NULL); 2963 } 2964 vap = &bvp->bv_vap; 2965 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2966 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2967 /* override with driver methods */ 2968 bvp->bv_newstate = vap->iv_newstate; 2969 vap->iv_newstate = bwn_newstate; 2970 2971 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2972 vap->iv_max_aid = BWN_STAID_MAX; 2973 2974 ieee80211_ratectl_init(vap); 2975 2976 /* complete setup */ 2977 ieee80211_vap_attach(vap, ieee80211_media_change, 2978 ieee80211_media_status); 2979 return (vap); 2980 } 2981 2982 static void 2983 bwn_vap_delete(struct ieee80211vap *vap) 2984 { 2985 struct bwn_vap *bvp = BWN_VAP(vap); 2986 2987 ieee80211_ratectl_deinit(vap); 2988 ieee80211_vap_detach(vap); 2989 free(bvp, M_80211_VAP); 2990 } 2991 2992 static void 2993 bwn_init(void *arg) 2994 { 2995 struct bwn_softc *sc = arg; 2996 struct ifnet *ifp = sc->sc_ifp; 2997 struct ieee80211com *ic = ifp->if_l2com; 2998 int error = 0; 2999 3000 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 3001 __func__, ifp->if_flags); 3002 3003 BWN_LOCK(sc); 3004 error = bwn_init_locked(sc); 3005 BWN_UNLOCK(sc); 3006 3007 if (error == 0) 3008 ieee80211_start_all(ic); /* start all vap's */ 3009 } 3010 3011 static int 3012 bwn_init_locked(struct bwn_softc *sc) 3013 { 3014 struct bwn_mac *mac; 3015 struct ifnet *ifp = sc->sc_ifp; 3016 int error; 3017 3018 BWN_ASSERT_LOCKED(sc); 3019 3020 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3021 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3022 sc->sc_filters = 0; 3023 bwn_wme_clear(sc); 3024 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3025 sc->sc_rf_enabled = 1; 3026 3027 mac = sc->sc_curmac; 3028 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3029 error = bwn_core_init(mac); 3030 if (error != 0) 3031 return (error); 3032 } 3033 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3034 bwn_core_start(mac); 3035 3036 bwn_set_opmode(mac); 3037 bwn_set_pretbtt(mac); 3038 bwn_spu_setdelay(mac, 0); 3039 bwn_set_macaddr(mac); 3040 3041 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3042 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3043 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3044 3045 return (0); 3046 } 3047 3048 static void 3049 bwn_stop(struct bwn_softc *sc, int statechg) 3050 { 3051 3052 BWN_LOCK(sc); 3053 bwn_stop_locked(sc, statechg); 3054 BWN_UNLOCK(sc); 3055 } 3056 3057 static void 3058 bwn_stop_locked(struct bwn_softc *sc, int statechg) 3059 { 3060 struct bwn_mac *mac = sc->sc_curmac; 3061 struct ifnet *ifp = sc->sc_ifp; 3062 3063 BWN_ASSERT_LOCKED(sc); 3064 3065 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3066 /* XXX FIXME opmode not based on VAP */ 3067 bwn_set_opmode(mac); 3068 bwn_set_macaddr(mac); 3069 } 3070 3071 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3072 bwn_core_stop(mac); 3073 3074 callout_stop(&sc->sc_led_blink_ch); 3075 sc->sc_led_blinking = 0; 3076 3077 bwn_core_exit(mac); 3078 sc->sc_rf_enabled = 0; 3079 3080 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3081 } 3082 3083 static void 3084 bwn_wme_clear(struct bwn_softc *sc) 3085 { 3086 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3087 struct wmeParams *p; 3088 unsigned int i; 3089 3090 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3091 ("%s:%d: fail", __func__, __LINE__)); 3092 3093 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3094 p = &(sc->sc_wmeParams[i]); 3095 3096 switch (bwn_wme_shm_offsets[i]) { 3097 case BWN_WME_VOICE: 3098 p->wmep_txopLimit = 0; 3099 p->wmep_aifsn = 2; 3100 /* XXX FIXME: log2(cwmin) */ 3101 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3102 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3103 break; 3104 case BWN_WME_VIDEO: 3105 p->wmep_txopLimit = 0; 3106 p->wmep_aifsn = 2; 3107 /* XXX FIXME: log2(cwmin) */ 3108 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3109 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3110 break; 3111 case BWN_WME_BESTEFFORT: 3112 p->wmep_txopLimit = 0; 3113 p->wmep_aifsn = 3; 3114 /* XXX FIXME: log2(cwmin) */ 3115 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3116 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3117 break; 3118 case BWN_WME_BACKGROUND: 3119 p->wmep_txopLimit = 0; 3120 p->wmep_aifsn = 7; 3121 /* XXX FIXME: log2(cwmin) */ 3122 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3123 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3124 break; 3125 default: 3126 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3127 } 3128 } 3129 } 3130 3131 static int 3132 bwn_core_init(struct bwn_mac *mac) 3133 { 3134 struct bwn_softc *sc = mac->mac_sc; 3135 uint64_t hf; 3136 int error; 3137 3138 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3139 ("%s:%d: fail", __func__, __LINE__)); 3140 3141 siba_powerup(sc->sc_dev, 0); 3142 if (!siba_dev_isup(sc->sc_dev)) 3143 bwn_reset_core(mac, 3144 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3145 3146 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3147 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3148 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3149 BWN_GETTIME(mac->mac_phy.nexttime); 3150 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3151 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3152 mac->mac_stats.link_noise = -95; 3153 mac->mac_reason_intr = 0; 3154 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3155 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3156 #ifdef BWN_DEBUG 3157 if (sc->sc_debug & BWN_DEBUG_XMIT) 3158 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3159 #endif 3160 mac->mac_suspended = 1; 3161 mac->mac_task_state = 0; 3162 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3163 3164 mac->mac_phy.init_pre(mac); 3165 3166 siba_pcicore_intr(sc->sc_dev); 3167 3168 siba_fix_imcfglobug(sc->sc_dev); 3169 bwn_bt_disable(mac); 3170 if (mac->mac_phy.prepare_hw) { 3171 error = mac->mac_phy.prepare_hw(mac); 3172 if (error) 3173 goto fail0; 3174 } 3175 error = bwn_chip_init(mac); 3176 if (error) 3177 goto fail0; 3178 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3179 siba_get_revid(sc->sc_dev)); 3180 hf = bwn_hf_read(mac); 3181 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3182 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3183 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3184 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3185 if (mac->mac_phy.rev == 1) 3186 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3187 } 3188 if (mac->mac_phy.rf_ver == 0x2050) { 3189 if (mac->mac_phy.rf_rev < 6) 3190 hf |= BWN_HF_FORCE_VCO_RECALC; 3191 if (mac->mac_phy.rf_rev == 6) 3192 hf |= BWN_HF_4318_TSSI; 3193 } 3194 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3195 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3196 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3197 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3198 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3199 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3200 bwn_hf_write(mac, hf); 3201 3202 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3204 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3205 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3206 3207 bwn_rate_init(mac); 3208 bwn_set_phytxctl(mac); 3209 3210 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3211 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3212 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3213 3214 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3215 bwn_pio_init(mac); 3216 else 3217 bwn_dma_init(mac); 3218 bwn_wme_init(mac); 3219 bwn_spu_setdelay(mac, 1); 3220 bwn_bt_enable(mac); 3221 3222 siba_powerup(sc->sc_dev, 3223 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3224 bwn_set_macaddr(mac); 3225 bwn_crypt_init(mac); 3226 3227 /* XXX LED initializatin */ 3228 3229 mac->mac_status = BWN_MAC_STATUS_INITED; 3230 3231 return (error); 3232 3233 fail0: 3234 siba_powerdown(sc->sc_dev); 3235 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3236 ("%s:%d: fail", __func__, __LINE__)); 3237 return (error); 3238 } 3239 3240 static void 3241 bwn_core_start(struct bwn_mac *mac) 3242 { 3243 struct bwn_softc *sc = mac->mac_sc; 3244 uint32_t tmp; 3245 3246 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3247 ("%s:%d: fail", __func__, __LINE__)); 3248 3249 if (siba_get_revid(sc->sc_dev) < 5) 3250 return; 3251 3252 while (1) { 3253 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3254 if (!(tmp & 0x00000001)) 3255 break; 3256 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3257 } 3258 3259 bwn_mac_enable(mac); 3260 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3261 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3262 3263 mac->mac_status = BWN_MAC_STATUS_STARTED; 3264 } 3265 3266 static void 3267 bwn_core_exit(struct bwn_mac *mac) 3268 { 3269 struct bwn_softc *sc = mac->mac_sc; 3270 uint32_t macctl; 3271 3272 BWN_ASSERT_LOCKED(mac->mac_sc); 3273 3274 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3275 ("%s:%d: fail", __func__, __LINE__)); 3276 3277 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3278 return; 3279 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3280 3281 macctl = BWN_READ_4(mac, BWN_MACCTL); 3282 macctl &= ~BWN_MACCTL_MCODE_RUN; 3283 macctl |= BWN_MACCTL_MCODE_JMP0; 3284 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3285 3286 bwn_dma_stop(mac); 3287 bwn_pio_stop(mac); 3288 bwn_chip_exit(mac); 3289 mac->mac_phy.switch_analog(mac, 0); 3290 siba_dev_down(sc->sc_dev, 0); 3291 siba_powerdown(sc->sc_dev); 3292 } 3293 3294 static void 3295 bwn_bt_disable(struct bwn_mac *mac) 3296 { 3297 struct bwn_softc *sc = mac->mac_sc; 3298 3299 (void)sc; 3300 /* XXX do nothing yet */ 3301 } 3302 3303 static int 3304 bwn_chip_init(struct bwn_mac *mac) 3305 { 3306 struct bwn_softc *sc = mac->mac_sc; 3307 struct bwn_phy *phy = &mac->mac_phy; 3308 uint32_t macctl; 3309 int error; 3310 3311 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3312 if (phy->gmode) 3313 macctl |= BWN_MACCTL_GMODE; 3314 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3315 3316 error = bwn_fw_fillinfo(mac); 3317 if (error) 3318 return (error); 3319 error = bwn_fw_loaducode(mac); 3320 if (error) 3321 return (error); 3322 3323 error = bwn_gpio_init(mac); 3324 if (error) 3325 return (error); 3326 3327 error = bwn_fw_loadinitvals(mac); 3328 if (error) { 3329 siba_gpio_set(sc->sc_dev, 0); 3330 return (error); 3331 } 3332 phy->switch_analog(mac, 1); 3333 error = bwn_phy_init(mac); 3334 if (error) { 3335 siba_gpio_set(sc->sc_dev, 0); 3336 return (error); 3337 } 3338 if (phy->set_im) 3339 phy->set_im(mac, BWN_IMMODE_NONE); 3340 if (phy->set_antenna) 3341 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3342 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3343 3344 if (phy->type == BWN_PHYTYPE_B) 3345 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3346 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3347 if (siba_get_revid(sc->sc_dev) < 5) 3348 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3349 3350 BWN_WRITE_4(mac, BWN_MACCTL, 3351 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3352 BWN_WRITE_4(mac, BWN_MACCTL, 3353 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3354 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3355 3356 bwn_set_opmode(mac); 3357 if (siba_get_revid(sc->sc_dev) < 3) { 3358 BWN_WRITE_2(mac, 0x060e, 0x0000); 3359 BWN_WRITE_2(mac, 0x0610, 0x8000); 3360 BWN_WRITE_2(mac, 0x0604, 0x0000); 3361 BWN_WRITE_2(mac, 0x0606, 0x0200); 3362 } else { 3363 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3364 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3365 } 3366 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3367 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3368 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3369 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3370 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3371 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3372 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3373 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3374 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3375 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3376 return (error); 3377 } 3378 3379 /* read hostflags */ 3380 static uint64_t 3381 bwn_hf_read(struct bwn_mac *mac) 3382 { 3383 uint64_t ret; 3384 3385 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3386 ret <<= 16; 3387 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3388 ret <<= 16; 3389 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3390 return (ret); 3391 } 3392 3393 static void 3394 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3395 { 3396 3397 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3398 (value & 0x00000000ffffull)); 3399 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3400 (value & 0x0000ffff0000ull) >> 16); 3401 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3402 (value & 0xffff00000000ULL) >> 32); 3403 } 3404 3405 static void 3406 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3407 { 3408 3409 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3410 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3411 } 3412 3413 static void 3414 bwn_rate_init(struct bwn_mac *mac) 3415 { 3416 3417 switch (mac->mac_phy.type) { 3418 case BWN_PHYTYPE_A: 3419 case BWN_PHYTYPE_G: 3420 case BWN_PHYTYPE_LP: 3421 case BWN_PHYTYPE_N: 3422 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3423 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3424 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3425 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3426 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3427 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3428 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3429 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3430 break; 3431 /* FALLTHROUGH */ 3432 case BWN_PHYTYPE_B: 3433 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3434 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3435 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3436 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3437 break; 3438 default: 3439 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3440 } 3441 } 3442 3443 static void 3444 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3445 { 3446 uint16_t offset; 3447 3448 if (ofdm) { 3449 offset = 0x480; 3450 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3451 } else { 3452 offset = 0x4c0; 3453 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3454 } 3455 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3456 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3457 } 3458 3459 static uint8_t 3460 bwn_plcp_getcck(const uint8_t bitrate) 3461 { 3462 3463 switch (bitrate) { 3464 case BWN_CCK_RATE_1MB: 3465 return (0x0a); 3466 case BWN_CCK_RATE_2MB: 3467 return (0x14); 3468 case BWN_CCK_RATE_5MB: 3469 return (0x37); 3470 case BWN_CCK_RATE_11MB: 3471 return (0x6e); 3472 } 3473 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3474 return (0); 3475 } 3476 3477 static uint8_t 3478 bwn_plcp_getofdm(const uint8_t bitrate) 3479 { 3480 3481 switch (bitrate) { 3482 case BWN_OFDM_RATE_6MB: 3483 return (0xb); 3484 case BWN_OFDM_RATE_9MB: 3485 return (0xf); 3486 case BWN_OFDM_RATE_12MB: 3487 return (0xa); 3488 case BWN_OFDM_RATE_18MB: 3489 return (0xe); 3490 case BWN_OFDM_RATE_24MB: 3491 return (0x9); 3492 case BWN_OFDM_RATE_36MB: 3493 return (0xd); 3494 case BWN_OFDM_RATE_48MB: 3495 return (0x8); 3496 case BWN_OFDM_RATE_54MB: 3497 return (0xc); 3498 } 3499 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3500 return (0); 3501 } 3502 3503 static void 3504 bwn_set_phytxctl(struct bwn_mac *mac) 3505 { 3506 uint16_t ctl; 3507 3508 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3509 BWN_TX_PHY_TXPWR); 3510 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3511 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3512 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3513 } 3514 3515 static void 3516 bwn_pio_init(struct bwn_mac *mac) 3517 { 3518 struct bwn_pio *pio = &mac->mac_method.pio; 3519 3520 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3521 & ~BWN_MACCTL_BIGENDIAN); 3522 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3523 3524 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3525 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3528 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3529 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3530 } 3531 3532 static void 3533 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3534 int index) 3535 { 3536 struct bwn_pio_txpkt *tp; 3537 struct bwn_softc *sc = mac->mac_sc; 3538 unsigned int i; 3539 3540 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3541 tq->tq_index = index; 3542 3543 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3544 if (siba_get_revid(sc->sc_dev) >= 8) 3545 tq->tq_size = 1920; 3546 else { 3547 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3548 tq->tq_size -= 80; 3549 } 3550 3551 TAILQ_INIT(&tq->tq_pktlist); 3552 for (i = 0; i < N(tq->tq_pkts); i++) { 3553 tp = &(tq->tq_pkts[i]); 3554 tp->tp_index = i; 3555 tp->tp_queue = tq; 3556 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3557 } 3558 } 3559 3560 static uint16_t 3561 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3562 { 3563 struct bwn_softc *sc = mac->mac_sc; 3564 static const uint16_t bases[] = { 3565 BWN_PIO_BASE0, 3566 BWN_PIO_BASE1, 3567 BWN_PIO_BASE2, 3568 BWN_PIO_BASE3, 3569 BWN_PIO_BASE4, 3570 BWN_PIO_BASE5, 3571 BWN_PIO_BASE6, 3572 BWN_PIO_BASE7, 3573 }; 3574 static const uint16_t bases_rev11[] = { 3575 BWN_PIO11_BASE0, 3576 BWN_PIO11_BASE1, 3577 BWN_PIO11_BASE2, 3578 BWN_PIO11_BASE3, 3579 BWN_PIO11_BASE4, 3580 BWN_PIO11_BASE5, 3581 }; 3582 3583 if (siba_get_revid(sc->sc_dev) >= 11) { 3584 if (index >= N(bases_rev11)) 3585 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3586 return (bases_rev11[index]); 3587 } 3588 if (index >= N(bases)) 3589 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3590 return (bases[index]); 3591 } 3592 3593 static void 3594 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3595 int index) 3596 { 3597 struct bwn_softc *sc = mac->mac_sc; 3598 3599 prq->prq_mac = mac; 3600 prq->prq_rev = siba_get_revid(sc->sc_dev); 3601 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3602 bwn_dma_rxdirectfifo(mac, index, 1); 3603 } 3604 3605 static void 3606 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3607 { 3608 if (tq == NULL) 3609 return; 3610 bwn_pio_cancel_tx_packets(tq); 3611 } 3612 3613 static void 3614 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3615 { 3616 3617 bwn_destroy_pioqueue_tx(pio); 3618 } 3619 3620 static uint16_t 3621 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3622 uint16_t offset) 3623 { 3624 3625 return (BWN_READ_2(mac, tq->tq_base + offset)); 3626 } 3627 3628 static void 3629 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3630 { 3631 uint32_t ctl; 3632 int type; 3633 uint16_t base; 3634 3635 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3636 base = bwn_dma_base(type, idx); 3637 if (type == BWN_DMA_64BIT) { 3638 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3639 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3640 if (enable) 3641 ctl |= BWN_DMA64_RXDIRECTFIFO; 3642 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3643 } else { 3644 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3645 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3646 if (enable) 3647 ctl |= BWN_DMA32_RXDIRECTFIFO; 3648 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3649 } 3650 } 3651 3652 static uint64_t 3653 bwn_dma_mask(struct bwn_mac *mac) 3654 { 3655 uint32_t tmp; 3656 uint16_t base; 3657 3658 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3659 if (tmp & SIBA_TGSHIGH_DMA64) 3660 return (BWN_DMA_BIT_MASK(64)); 3661 base = bwn_dma_base(0, 0); 3662 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3663 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3664 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3665 return (BWN_DMA_BIT_MASK(32)); 3666 3667 return (BWN_DMA_BIT_MASK(30)); 3668 } 3669 3670 static int 3671 bwn_dma_mask2type(uint64_t dmamask) 3672 { 3673 3674 if (dmamask == BWN_DMA_BIT_MASK(30)) 3675 return (BWN_DMA_30BIT); 3676 if (dmamask == BWN_DMA_BIT_MASK(32)) 3677 return (BWN_DMA_32BIT); 3678 if (dmamask == BWN_DMA_BIT_MASK(64)) 3679 return (BWN_DMA_64BIT); 3680 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3681 return (BWN_DMA_30BIT); 3682 } 3683 3684 static void 3685 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3686 { 3687 struct bwn_pio_txpkt *tp; 3688 unsigned int i; 3689 3690 for (i = 0; i < N(tq->tq_pkts); i++) { 3691 tp = &(tq->tq_pkts[i]); 3692 if (tp->tp_m) { 3693 m_freem(tp->tp_m); 3694 tp->tp_m = NULL; 3695 } 3696 } 3697 } 3698 3699 static uint16_t 3700 bwn_dma_base(int type, int controller_idx) 3701 { 3702 static const uint16_t map64[] = { 3703 BWN_DMA64_BASE0, 3704 BWN_DMA64_BASE1, 3705 BWN_DMA64_BASE2, 3706 BWN_DMA64_BASE3, 3707 BWN_DMA64_BASE4, 3708 BWN_DMA64_BASE5, 3709 }; 3710 static const uint16_t map32[] = { 3711 BWN_DMA32_BASE0, 3712 BWN_DMA32_BASE1, 3713 BWN_DMA32_BASE2, 3714 BWN_DMA32_BASE3, 3715 BWN_DMA32_BASE4, 3716 BWN_DMA32_BASE5, 3717 }; 3718 3719 if (type == BWN_DMA_64BIT) { 3720 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3721 ("%s:%d: fail", __func__, __LINE__)); 3722 return (map64[controller_idx]); 3723 } 3724 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3725 ("%s:%d: fail", __func__, __LINE__)); 3726 return (map32[controller_idx]); 3727 } 3728 3729 static void 3730 bwn_dma_init(struct bwn_mac *mac) 3731 { 3732 struct bwn_dma *dma = &mac->mac_method.dma; 3733 3734 /* setup TX DMA channels. */ 3735 bwn_dma_setup(dma->wme[WME_AC_BK]); 3736 bwn_dma_setup(dma->wme[WME_AC_BE]); 3737 bwn_dma_setup(dma->wme[WME_AC_VI]); 3738 bwn_dma_setup(dma->wme[WME_AC_VO]); 3739 bwn_dma_setup(dma->mcast); 3740 /* setup RX DMA channel. */ 3741 bwn_dma_setup(dma->rx); 3742 } 3743 3744 static struct bwn_dma_ring * 3745 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3746 int for_tx, int type) 3747 { 3748 struct bwn_dma *dma = &mac->mac_method.dma; 3749 struct bwn_dma_ring *dr; 3750 struct bwn_dmadesc_generic *desc; 3751 struct bwn_dmadesc_meta *mt; 3752 struct bwn_softc *sc = mac->mac_sc; 3753 int error, i; 3754 3755 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3756 if (dr == NULL) 3757 goto out; 3758 dr->dr_numslots = BWN_RXRING_SLOTS; 3759 if (for_tx) 3760 dr->dr_numslots = BWN_TXRING_SLOTS; 3761 3762 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3763 M_DEVBUF, M_NOWAIT | M_ZERO); 3764 if (dr->dr_meta == NULL) 3765 goto fail0; 3766 3767 dr->dr_type = type; 3768 dr->dr_mac = mac; 3769 dr->dr_base = bwn_dma_base(type, controller_index); 3770 dr->dr_index = controller_index; 3771 if (type == BWN_DMA_64BIT) { 3772 dr->getdesc = bwn_dma_64_getdesc; 3773 dr->setdesc = bwn_dma_64_setdesc; 3774 dr->start_transfer = bwn_dma_64_start_transfer; 3775 dr->suspend = bwn_dma_64_suspend; 3776 dr->resume = bwn_dma_64_resume; 3777 dr->get_curslot = bwn_dma_64_get_curslot; 3778 dr->set_curslot = bwn_dma_64_set_curslot; 3779 } else { 3780 dr->getdesc = bwn_dma_32_getdesc; 3781 dr->setdesc = bwn_dma_32_setdesc; 3782 dr->start_transfer = bwn_dma_32_start_transfer; 3783 dr->suspend = bwn_dma_32_suspend; 3784 dr->resume = bwn_dma_32_resume; 3785 dr->get_curslot = bwn_dma_32_get_curslot; 3786 dr->set_curslot = bwn_dma_32_set_curslot; 3787 } 3788 if (for_tx) { 3789 dr->dr_tx = 1; 3790 dr->dr_curslot = -1; 3791 } else { 3792 if (dr->dr_index == 0) { 3793 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3794 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3795 } else 3796 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3797 } 3798 3799 error = bwn_dma_allocringmemory(dr); 3800 if (error) 3801 goto fail2; 3802 3803 if (for_tx) { 3804 /* 3805 * Assumption: BWN_TXRING_SLOTS can be divided by 3806 * BWN_TX_SLOTS_PER_FRAME 3807 */ 3808 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3809 ("%s:%d: fail", __func__, __LINE__)); 3810 3811 dr->dr_txhdr_cache = 3812 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3813 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3814 KASSERT(dr->dr_txhdr_cache != NULL, 3815 ("%s:%d: fail", __func__, __LINE__)); 3816 3817 /* 3818 * Create TX ring DMA stuffs 3819 */ 3820 error = bus_dma_tag_create(dma->parent_dtag, 3821 BWN_ALIGN, 0, 3822 BUS_SPACE_MAXADDR, 3823 BUS_SPACE_MAXADDR, 3824 NULL, NULL, 3825 BWN_HDRSIZE(mac), 3826 1, 3827 BUS_SPACE_MAXSIZE_32BIT, 3828 0, 3829 NULL, NULL, 3830 &dr->dr_txring_dtag); 3831 if (error) { 3832 device_printf(sc->sc_dev, 3833 "can't create TX ring DMA tag: TODO frees\n"); 3834 goto fail1; 3835 } 3836 3837 for (i = 0; i < dr->dr_numslots; i += 2) { 3838 dr->getdesc(dr, i, &desc, &mt); 3839 3840 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3841 mt->mt_m = NULL; 3842 mt->mt_ni = NULL; 3843 mt->mt_islast = 0; 3844 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3845 &mt->mt_dmap); 3846 if (error) { 3847 device_printf(sc->sc_dev, 3848 "can't create RX buf DMA map\n"); 3849 goto fail1; 3850 } 3851 3852 dr->getdesc(dr, i + 1, &desc, &mt); 3853 3854 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3855 mt->mt_m = NULL; 3856 mt->mt_ni = NULL; 3857 mt->mt_islast = 1; 3858 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3859 &mt->mt_dmap); 3860 if (error) { 3861 device_printf(sc->sc_dev, 3862 "can't create RX buf DMA map\n"); 3863 goto fail1; 3864 } 3865 } 3866 } else { 3867 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3868 &dr->dr_spare_dmap); 3869 if (error) { 3870 device_printf(sc->sc_dev, 3871 "can't create RX buf DMA map\n"); 3872 goto out; /* XXX wrong! */ 3873 } 3874 3875 for (i = 0; i < dr->dr_numslots; i++) { 3876 dr->getdesc(dr, i, &desc, &mt); 3877 3878 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3879 &mt->mt_dmap); 3880 if (error) { 3881 device_printf(sc->sc_dev, 3882 "can't create RX buf DMA map\n"); 3883 goto out; /* XXX wrong! */ 3884 } 3885 error = bwn_dma_newbuf(dr, desc, mt, 1); 3886 if (error) { 3887 device_printf(sc->sc_dev, 3888 "failed to allocate RX buf\n"); 3889 goto out; /* XXX wrong! */ 3890 } 3891 } 3892 3893 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3894 BUS_DMASYNC_PREWRITE); 3895 3896 dr->dr_usedslot = dr->dr_numslots; 3897 } 3898 3899 out: 3900 return (dr); 3901 3902 fail2: 3903 free(dr->dr_txhdr_cache, M_DEVBUF); 3904 fail1: 3905 free(dr->dr_meta, M_DEVBUF); 3906 fail0: 3907 free(dr, M_DEVBUF); 3908 return (NULL); 3909 } 3910 3911 static void 3912 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3913 { 3914 3915 if (dr == NULL) 3916 return; 3917 3918 bwn_dma_free_descbufs(*dr); 3919 bwn_dma_free_ringmemory(*dr); 3920 3921 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3922 free((*dr)->dr_meta, M_DEVBUF); 3923 free(*dr, M_DEVBUF); 3924 3925 *dr = NULL; 3926 } 3927 3928 static void 3929 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3930 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3931 { 3932 struct bwn_dmadesc32 *desc; 3933 3934 *meta = &(dr->dr_meta[slot]); 3935 desc = dr->dr_ring_descbase; 3936 desc = &(desc[slot]); 3937 3938 *gdesc = (struct bwn_dmadesc_generic *)desc; 3939 } 3940 3941 static void 3942 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3943 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3944 int start, int end, int irq) 3945 { 3946 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3947 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3948 uint32_t addr, addrext, ctl; 3949 int slot; 3950 3951 slot = (int)(&(desc->dma.dma32) - descbase); 3952 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3953 ("%s:%d: fail", __func__, __LINE__)); 3954 3955 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3956 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3957 addr |= siba_dma_translation(sc->sc_dev); 3958 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3959 if (slot == dr->dr_numslots - 1) 3960 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3961 if (start) 3962 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3963 if (end) 3964 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3965 if (irq) 3966 ctl |= BWN_DMA32_DCTL_IRQ; 3967 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3968 & BWN_DMA32_DCTL_ADDREXT_MASK; 3969 3970 desc->dma.dma32.control = htole32(ctl); 3971 desc->dma.dma32.address = htole32(addr); 3972 } 3973 3974 static void 3975 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3976 { 3977 3978 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3979 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3980 } 3981 3982 static void 3983 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3984 { 3985 3986 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3987 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3988 } 3989 3990 static void 3991 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3992 { 3993 3994 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3995 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3996 } 3997 3998 static int 3999 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4000 { 4001 uint32_t val; 4002 4003 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4004 val &= BWN_DMA32_RXDPTR; 4005 4006 return (val / sizeof(struct bwn_dmadesc32)); 4007 } 4008 4009 static void 4010 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4011 { 4012 4013 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4014 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4015 } 4016 4017 static void 4018 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4019 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4020 { 4021 struct bwn_dmadesc64 *desc; 4022 4023 *meta = &(dr->dr_meta[slot]); 4024 desc = dr->dr_ring_descbase; 4025 desc = &(desc[slot]); 4026 4027 *gdesc = (struct bwn_dmadesc_generic *)desc; 4028 } 4029 4030 static void 4031 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4032 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4033 int start, int end, int irq) 4034 { 4035 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4036 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4037 int slot; 4038 uint32_t ctl0 = 0, ctl1 = 0; 4039 uint32_t addrlo, addrhi; 4040 uint32_t addrext; 4041 4042 slot = (int)(&(desc->dma.dma64) - descbase); 4043 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4044 ("%s:%d: fail", __func__, __LINE__)); 4045 4046 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4047 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4048 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4049 30; 4050 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 4051 if (slot == dr->dr_numslots - 1) 4052 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4053 if (start) 4054 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4055 if (end) 4056 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4057 if (irq) 4058 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4059 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4060 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4061 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4062 4063 desc->dma.dma64.control0 = htole32(ctl0); 4064 desc->dma.dma64.control1 = htole32(ctl1); 4065 desc->dma.dma64.address_low = htole32(addrlo); 4066 desc->dma.dma64.address_high = htole32(addrhi); 4067 } 4068 4069 static void 4070 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4071 { 4072 4073 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4074 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4075 } 4076 4077 static void 4078 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4079 { 4080 4081 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4082 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4083 } 4084 4085 static void 4086 bwn_dma_64_resume(struct bwn_dma_ring *dr) 4087 { 4088 4089 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4090 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4091 } 4092 4093 static int 4094 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4095 { 4096 uint32_t val; 4097 4098 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4099 val &= BWN_DMA64_RXSTATDPTR; 4100 4101 return (val / sizeof(struct bwn_dmadesc64)); 4102 } 4103 4104 static void 4105 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4106 { 4107 4108 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4109 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4110 } 4111 4112 static int 4113 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4114 { 4115 struct bwn_mac *mac = dr->dr_mac; 4116 struct bwn_dma *dma = &mac->mac_method.dma; 4117 struct bwn_softc *sc = mac->mac_sc; 4118 int error; 4119 4120 error = bus_dma_tag_create(dma->parent_dtag, 4121 BWN_ALIGN, 0, 4122 BUS_SPACE_MAXADDR, 4123 BUS_SPACE_MAXADDR, 4124 NULL, NULL, 4125 BWN_DMA_RINGMEMSIZE, 4126 1, 4127 BUS_SPACE_MAXSIZE_32BIT, 4128 0, 4129 NULL, NULL, 4130 &dr->dr_ring_dtag); 4131 if (error) { 4132 device_printf(sc->sc_dev, 4133 "can't create TX ring DMA tag: TODO frees\n"); 4134 return (-1); 4135 } 4136 4137 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4138 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4139 &dr->dr_ring_dmap); 4140 if (error) { 4141 device_printf(sc->sc_dev, 4142 "can't allocate DMA mem: TODO frees\n"); 4143 return (-1); 4144 } 4145 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4146 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4147 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4148 if (error) { 4149 device_printf(sc->sc_dev, 4150 "can't load DMA mem: TODO free\n"); 4151 return (-1); 4152 } 4153 4154 return (0); 4155 } 4156 4157 static void 4158 bwn_dma_setup(struct bwn_dma_ring *dr) 4159 { 4160 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4161 uint64_t ring64; 4162 uint32_t addrext, ring32, value; 4163 uint32_t trans = siba_dma_translation(sc->sc_dev); 4164 4165 if (dr->dr_tx) { 4166 dr->dr_curslot = -1; 4167 4168 if (dr->dr_type == BWN_DMA_64BIT) { 4169 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4170 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4171 >> 30; 4172 value = BWN_DMA64_TXENABLE; 4173 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4174 & BWN_DMA64_TXADDREXT_MASK; 4175 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4176 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4177 (ring64 & 0xffffffff)); 4178 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4179 ((ring64 >> 32) & 4180 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4181 } else { 4182 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4183 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4184 value = BWN_DMA32_TXENABLE; 4185 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4186 & BWN_DMA32_TXADDREXT_MASK; 4187 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4188 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4189 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4190 } 4191 return; 4192 } 4193 4194 /* 4195 * set for RX 4196 */ 4197 dr->dr_usedslot = dr->dr_numslots; 4198 4199 if (dr->dr_type == BWN_DMA_64BIT) { 4200 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4201 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4202 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4203 value |= BWN_DMA64_RXENABLE; 4204 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4205 & BWN_DMA64_RXADDREXT_MASK; 4206 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4207 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4208 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4209 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4210 | (trans << 1)); 4211 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4212 sizeof(struct bwn_dmadesc64)); 4213 } else { 4214 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4215 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4216 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4217 value |= BWN_DMA32_RXENABLE; 4218 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4219 & BWN_DMA32_RXADDREXT_MASK; 4220 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4221 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4222 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4223 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4224 sizeof(struct bwn_dmadesc32)); 4225 } 4226 } 4227 4228 static void 4229 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4230 { 4231 4232 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4233 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4234 dr->dr_ring_dmap); 4235 } 4236 4237 static void 4238 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4239 { 4240 4241 if (dr->dr_tx) { 4242 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4243 if (dr->dr_type == BWN_DMA_64BIT) { 4244 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4245 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4246 } else 4247 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4248 } else { 4249 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4250 if (dr->dr_type == BWN_DMA_64BIT) { 4251 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4252 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4253 } else 4254 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4255 } 4256 } 4257 4258 static void 4259 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4260 { 4261 struct bwn_dmadesc_generic *desc; 4262 struct bwn_dmadesc_meta *meta; 4263 struct bwn_mac *mac = dr->dr_mac; 4264 struct bwn_dma *dma = &mac->mac_method.dma; 4265 struct bwn_softc *sc = mac->mac_sc; 4266 int i; 4267 4268 if (!dr->dr_usedslot) 4269 return; 4270 for (i = 0; i < dr->dr_numslots; i++) { 4271 dr->getdesc(dr, i, &desc, &meta); 4272 4273 if (meta->mt_m == NULL) { 4274 if (!dr->dr_tx) 4275 device_printf(sc->sc_dev, "%s: not TX?\n", 4276 __func__); 4277 continue; 4278 } 4279 if (dr->dr_tx) { 4280 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4281 bus_dmamap_unload(dr->dr_txring_dtag, 4282 meta->mt_dmap); 4283 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4284 bus_dmamap_unload(dma->txbuf_dtag, 4285 meta->mt_dmap); 4286 } else 4287 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4288 bwn_dma_free_descbuf(dr, meta); 4289 } 4290 } 4291 4292 static int 4293 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4294 int type) 4295 { 4296 struct bwn_softc *sc = mac->mac_sc; 4297 uint32_t value; 4298 int i; 4299 uint16_t offset; 4300 4301 for (i = 0; i < 10; i++) { 4302 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4303 BWN_DMA32_TXSTATUS; 4304 value = BWN_READ_4(mac, base + offset); 4305 if (type == BWN_DMA_64BIT) { 4306 value &= BWN_DMA64_TXSTAT; 4307 if (value == BWN_DMA64_TXSTAT_DISABLED || 4308 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4309 value == BWN_DMA64_TXSTAT_STOPPED) 4310 break; 4311 } else { 4312 value &= BWN_DMA32_TXSTATE; 4313 if (value == BWN_DMA32_TXSTAT_DISABLED || 4314 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4315 value == BWN_DMA32_TXSTAT_STOPPED) 4316 break; 4317 } 4318 DELAY(1000); 4319 } 4320 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4321 BWN_WRITE_4(mac, base + offset, 0); 4322 for (i = 0; i < 10; i++) { 4323 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4324 BWN_DMA32_TXSTATUS; 4325 value = BWN_READ_4(mac, base + offset); 4326 if (type == BWN_DMA_64BIT) { 4327 value &= BWN_DMA64_TXSTAT; 4328 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4329 i = -1; 4330 break; 4331 } 4332 } else { 4333 value &= BWN_DMA32_TXSTATE; 4334 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4335 i = -1; 4336 break; 4337 } 4338 } 4339 DELAY(1000); 4340 } 4341 if (i != -1) { 4342 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4343 return (ENODEV); 4344 } 4345 DELAY(1000); 4346 4347 return (0); 4348 } 4349 4350 static int 4351 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4352 int type) 4353 { 4354 struct bwn_softc *sc = mac->mac_sc; 4355 uint32_t value; 4356 int i; 4357 uint16_t offset; 4358 4359 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4360 BWN_WRITE_4(mac, base + offset, 0); 4361 for (i = 0; i < 10; i++) { 4362 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4363 BWN_DMA32_RXSTATUS; 4364 value = BWN_READ_4(mac, base + offset); 4365 if (type == BWN_DMA_64BIT) { 4366 value &= BWN_DMA64_RXSTAT; 4367 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4368 i = -1; 4369 break; 4370 } 4371 } else { 4372 value &= BWN_DMA32_RXSTATE; 4373 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4374 i = -1; 4375 break; 4376 } 4377 } 4378 DELAY(1000); 4379 } 4380 if (i != -1) { 4381 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4382 return (ENODEV); 4383 } 4384 4385 return (0); 4386 } 4387 4388 static void 4389 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4390 struct bwn_dmadesc_meta *meta) 4391 { 4392 4393 if (meta->mt_m != NULL) { 4394 m_freem(meta->mt_m); 4395 meta->mt_m = NULL; 4396 } 4397 if (meta->mt_ni != NULL) { 4398 ieee80211_free_node(meta->mt_ni); 4399 meta->mt_ni = NULL; 4400 } 4401 } 4402 4403 static void 4404 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4405 { 4406 struct bwn_rxhdr4 *rxhdr; 4407 unsigned char *frame; 4408 4409 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4410 rxhdr->frame_len = 0; 4411 4412 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4413 sizeof(struct bwn_plcp6) + 2, 4414 ("%s:%d: fail", __func__, __LINE__)); 4415 frame = mtod(m, char *) + dr->dr_frameoffset; 4416 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4417 } 4418 4419 static uint8_t 4420 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4421 { 4422 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4423 4424 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4425 == 0xff); 4426 } 4427 4428 static void 4429 bwn_wme_init(struct bwn_mac *mac) 4430 { 4431 4432 bwn_wme_load(mac); 4433 4434 /* enable WME support. */ 4435 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4436 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4437 BWN_IFSCTL_USE_EDCF); 4438 } 4439 4440 static void 4441 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4442 { 4443 struct bwn_softc *sc = mac->mac_sc; 4444 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4445 uint16_t delay; /* microsec */ 4446 4447 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4448 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4449 delay = 500; 4450 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4451 delay = max(delay, (uint16_t)2400); 4452 4453 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4454 } 4455 4456 static void 4457 bwn_bt_enable(struct bwn_mac *mac) 4458 { 4459 struct bwn_softc *sc = mac->mac_sc; 4460 uint64_t hf; 4461 4462 if (bwn_bluetooth == 0) 4463 return; 4464 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4465 return; 4466 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4467 return; 4468 4469 hf = bwn_hf_read(mac); 4470 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4471 hf |= BWN_HF_BT_COEXISTALT; 4472 else 4473 hf |= BWN_HF_BT_COEXIST; 4474 bwn_hf_write(mac, hf); 4475 } 4476 4477 static void 4478 bwn_set_macaddr(struct bwn_mac *mac) 4479 { 4480 4481 bwn_mac_write_bssid(mac); 4482 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4483 } 4484 4485 static void 4486 bwn_clear_keys(struct bwn_mac *mac) 4487 { 4488 int i; 4489 4490 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4491 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4492 ("%s:%d: fail", __func__, __LINE__)); 4493 4494 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4495 NULL, BWN_SEC_KEYSIZE, NULL); 4496 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4497 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4498 NULL, BWN_SEC_KEYSIZE, NULL); 4499 } 4500 mac->mac_key[i].keyconf = NULL; 4501 } 4502 } 4503 4504 static void 4505 bwn_crypt_init(struct bwn_mac *mac) 4506 { 4507 struct bwn_softc *sc = mac->mac_sc; 4508 4509 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4510 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4511 ("%s:%d: fail", __func__, __LINE__)); 4512 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4513 mac->mac_ktp *= 2; 4514 if (siba_get_revid(sc->sc_dev) >= 5) 4515 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4516 bwn_clear_keys(mac); 4517 } 4518 4519 static void 4520 bwn_chip_exit(struct bwn_mac *mac) 4521 { 4522 struct bwn_softc *sc = mac->mac_sc; 4523 4524 bwn_phy_exit(mac); 4525 siba_gpio_set(sc->sc_dev, 0); 4526 } 4527 4528 static int 4529 bwn_fw_fillinfo(struct bwn_mac *mac) 4530 { 4531 int error; 4532 4533 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4534 if (error == 0) 4535 return (0); 4536 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4537 if (error == 0) 4538 return (0); 4539 return (error); 4540 } 4541 4542 static int 4543 bwn_gpio_init(struct bwn_mac *mac) 4544 { 4545 struct bwn_softc *sc = mac->mac_sc; 4546 uint32_t mask = 0x1f, set = 0xf, value; 4547 4548 BWN_WRITE_4(mac, BWN_MACCTL, 4549 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4550 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4551 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4552 4553 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4554 mask |= 0x0060; 4555 set |= 0x0060; 4556 } 4557 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4558 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4559 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4560 mask |= 0x0200; 4561 set |= 0x0200; 4562 } 4563 if (siba_get_revid(sc->sc_dev) >= 2) 4564 mask |= 0x0010; 4565 4566 value = siba_gpio_get(sc->sc_dev); 4567 if (value == -1) 4568 return (0); 4569 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4570 4571 return (0); 4572 } 4573 4574 static int 4575 bwn_fw_loadinitvals(struct bwn_mac *mac) 4576 { 4577 #define GETFWOFFSET(fwp, offset) \ 4578 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4579 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4580 const struct bwn_fwhdr *hdr; 4581 struct bwn_fw *fw = &mac->mac_fw; 4582 int error; 4583 4584 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4585 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4586 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4587 if (error) 4588 return (error); 4589 if (fw->initvals_band.fw) { 4590 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4591 error = bwn_fwinitvals_write(mac, 4592 GETFWOFFSET(fw->initvals_band, hdr_len), 4593 be32toh(hdr->size), 4594 fw->initvals_band.fw->datasize - hdr_len); 4595 } 4596 return (error); 4597 #undef GETFWOFFSET 4598 } 4599 4600 static int 4601 bwn_phy_init(struct bwn_mac *mac) 4602 { 4603 struct bwn_softc *sc = mac->mac_sc; 4604 int error; 4605 4606 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4607 mac->mac_phy.rf_onoff(mac, 1); 4608 error = mac->mac_phy.init(mac); 4609 if (error) { 4610 device_printf(sc->sc_dev, "PHY init failed\n"); 4611 goto fail0; 4612 } 4613 error = bwn_switch_channel(mac, 4614 mac->mac_phy.get_default_chan(mac)); 4615 if (error) { 4616 device_printf(sc->sc_dev, 4617 "failed to switch default channel\n"); 4618 goto fail1; 4619 } 4620 return (0); 4621 fail1: 4622 if (mac->mac_phy.exit) 4623 mac->mac_phy.exit(mac); 4624 fail0: 4625 mac->mac_phy.rf_onoff(mac, 0); 4626 4627 return (error); 4628 } 4629 4630 static void 4631 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4632 { 4633 uint16_t ant; 4634 uint16_t tmp; 4635 4636 ant = bwn_ant2phy(antenna); 4637 4638 /* For ACK/CTS */ 4639 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4640 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4641 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4642 /* For Probe Resposes */ 4643 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4644 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4645 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4646 } 4647 4648 static void 4649 bwn_set_opmode(struct bwn_mac *mac) 4650 { 4651 struct bwn_softc *sc = mac->mac_sc; 4652 struct ifnet *ifp = sc->sc_ifp; 4653 struct ieee80211com *ic = ifp->if_l2com; 4654 uint32_t ctl; 4655 uint16_t cfp_pretbtt; 4656 4657 ctl = BWN_READ_4(mac, BWN_MACCTL); 4658 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4659 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4660 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4661 ctl |= BWN_MACCTL_STA; 4662 4663 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4664 ic->ic_opmode == IEEE80211_M_MBSS) 4665 ctl |= BWN_MACCTL_HOSTAP; 4666 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4667 ctl &= ~BWN_MACCTL_STA; 4668 ctl |= sc->sc_filters; 4669 4670 if (siba_get_revid(sc->sc_dev) <= 4) 4671 ctl |= BWN_MACCTL_PROMISC; 4672 4673 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4674 4675 cfp_pretbtt = 2; 4676 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4677 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4678 siba_get_chiprev(sc->sc_dev) == 3) 4679 cfp_pretbtt = 100; 4680 else 4681 cfp_pretbtt = 50; 4682 } 4683 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4684 } 4685 4686 static int 4687 bwn_dma_gettype(struct bwn_mac *mac) 4688 { 4689 uint32_t tmp; 4690 uint16_t base; 4691 4692 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4693 if (tmp & SIBA_TGSHIGH_DMA64) 4694 return (BWN_DMA_64BIT); 4695 base = bwn_dma_base(0, 0); 4696 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4697 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4698 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4699 return (BWN_DMA_32BIT); 4700 4701 return (BWN_DMA_30BIT); 4702 } 4703 4704 static void 4705 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4706 { 4707 if (!error) { 4708 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4709 *((bus_addr_t *)arg) = seg->ds_addr; 4710 } 4711 } 4712 4713 static void 4714 bwn_phy_g_init_sub(struct bwn_mac *mac) 4715 { 4716 struct bwn_phy *phy = &mac->mac_phy; 4717 struct bwn_phy_g *pg = &phy->phy_g; 4718 struct bwn_softc *sc = mac->mac_sc; 4719 uint16_t i, tmp; 4720 4721 if (phy->rev == 1) 4722 bwn_phy_init_b5(mac); 4723 else 4724 bwn_phy_init_b6(mac); 4725 4726 if (phy->rev >= 2 || phy->gmode) 4727 bwn_phy_init_a(mac); 4728 4729 if (phy->rev >= 2) { 4730 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4731 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4732 } 4733 if (phy->rev == 2) { 4734 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4735 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4736 } 4737 if (phy->rev > 5) { 4738 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4739 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4740 } 4741 if (phy->gmode || phy->rev >= 2) { 4742 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4743 tmp &= BWN_PHYVER_VERSION; 4744 if (tmp == 3 || tmp == 5) { 4745 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4746 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4747 } 4748 if (tmp == 5) { 4749 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4750 0x1f00); 4751 } 4752 } 4753 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4754 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4755 if (phy->rf_rev == 8) { 4756 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4757 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4758 } 4759 if (BWN_HAS_LOOPBACK(phy)) 4760 bwn_loopback_calcgain(mac); 4761 4762 if (phy->rf_rev != 8) { 4763 if (pg->pg_initval == 0xffff) 4764 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4765 else 4766 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4767 } 4768 bwn_lo_g_init(mac); 4769 if (BWN_HAS_TXMAG(phy)) { 4770 BWN_RF_WRITE(mac, 0x52, 4771 (BWN_RF_READ(mac, 0x52) & 0xff00) 4772 | pg->pg_loctl.tx_bias | 4773 pg->pg_loctl.tx_magn); 4774 } else { 4775 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4776 } 4777 if (phy->rev >= 6) { 4778 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4779 (pg->pg_loctl.tx_bias << 12)); 4780 } 4781 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4782 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4783 else 4784 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4785 if (phy->rev < 2) 4786 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4787 else 4788 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4789 if (phy->gmode || phy->rev >= 2) { 4790 bwn_lo_g_adjust(mac); 4791 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4792 } 4793 4794 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4795 for (i = 0; i < 64; i++) { 4796 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4797 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4798 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4799 -32), 31)); 4800 } 4801 bwn_nrssi_threshold(mac); 4802 } else if (phy->gmode || phy->rev >= 2) { 4803 if (pg->pg_nrssi[0] == -1000) { 4804 KASSERT(pg->pg_nrssi[1] == -1000, 4805 ("%s:%d: fail", __func__, __LINE__)); 4806 bwn_nrssi_slope_11g(mac); 4807 } else 4808 bwn_nrssi_threshold(mac); 4809 } 4810 if (phy->rf_rev == 8) 4811 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4812 bwn_phy_hwpctl_init(mac); 4813 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4814 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4815 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4816 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4817 } 4818 } 4819 4820 static uint8_t 4821 bwn_has_hwpctl(struct bwn_mac *mac) 4822 { 4823 4824 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4825 return (0); 4826 return (mac->mac_phy.use_hwpctl(mac)); 4827 } 4828 4829 static void 4830 bwn_phy_init_b5(struct bwn_mac *mac) 4831 { 4832 struct bwn_phy *phy = &mac->mac_phy; 4833 struct bwn_phy_g *pg = &phy->phy_g; 4834 struct bwn_softc *sc = mac->mac_sc; 4835 uint16_t offset, value; 4836 uint8_t old_channel; 4837 4838 if (phy->analog == 1) 4839 BWN_RF_SET(mac, 0x007a, 0x0050); 4840 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4841 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4842 value = 0x2120; 4843 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4844 BWN_PHY_WRITE(mac, offset, value); 4845 value += 0x202; 4846 } 4847 } 4848 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4849 if (phy->rf_ver == 0x2050) 4850 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4851 4852 if (phy->gmode || phy->rev >= 2) { 4853 if (phy->rf_ver == 0x2050) { 4854 BWN_RF_SET(mac, 0x007a, 0x0020); 4855 BWN_RF_SET(mac, 0x0051, 0x0004); 4856 } 4857 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4858 4859 BWN_PHY_SET(mac, 0x0802, 0x0100); 4860 BWN_PHY_SET(mac, 0x042b, 0x2000); 4861 4862 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4863 4864 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4865 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4866 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4867 } 4868 4869 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4870 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4871 4872 if (phy->analog == 1) { 4873 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4874 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4875 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4876 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4877 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4878 } else 4879 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4880 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4881 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4882 4883 if (phy->analog == 1) 4884 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4885 else 4886 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4887 4888 if (phy->analog == 0) 4889 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4890 4891 old_channel = phy->chan; 4892 bwn_phy_g_switch_chan(mac, 7, 0); 4893 4894 if (phy->rf_ver != 0x2050) { 4895 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4896 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4897 } 4898 4899 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4900 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4901 4902 if (phy->rf_ver == 0x2050) { 4903 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4904 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4905 } 4906 4907 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4908 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4909 BWN_RF_SET(mac, 0x007a, 0x0007); 4910 4911 bwn_phy_g_switch_chan(mac, old_channel, 0); 4912 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4913 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4914 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4915 4916 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4917 pg->pg_txctl); 4918 4919 if (phy->rf_ver == 0x2050) 4920 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4921 4922 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4923 } 4924 4925 static void 4926 bwn_loopback_calcgain(struct bwn_mac *mac) 4927 { 4928 struct bwn_phy *phy = &mac->mac_phy; 4929 struct bwn_phy_g *pg = &phy->phy_g; 4930 struct bwn_softc *sc = mac->mac_sc; 4931 uint16_t backup_phy[16] = { 0 }; 4932 uint16_t backup_radio[3]; 4933 uint16_t backup_bband; 4934 uint16_t i, j, loop_i_max; 4935 uint16_t trsw_rx; 4936 uint16_t loop1_outer_done, loop1_inner_done; 4937 4938 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4939 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4940 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4941 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4942 if (phy->rev != 1) { 4943 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4944 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4945 } 4946 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4947 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4948 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4949 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4950 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4951 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4952 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4953 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4954 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4955 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4956 backup_bband = pg->pg_bbatt.att; 4957 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4958 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4959 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4960 4961 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4962 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4963 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4964 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4965 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4966 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4967 if (phy->rev != 1) { 4968 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4969 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4970 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4971 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4972 } 4973 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4974 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4975 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4976 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4977 4978 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4979 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4981 4982 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4983 if (phy->rev != 1) { 4984 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4985 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4986 } 4987 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4988 4989 if (phy->rf_rev == 8) 4990 BWN_RF_WRITE(mac, 0x43, 0x000f); 4991 else { 4992 BWN_RF_WRITE(mac, 0x52, 0); 4993 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4994 } 4995 bwn_phy_g_set_bbatt(mac, 11); 4996 4997 if (phy->rev >= 3) 4998 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4999 else 5000 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5001 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5002 5003 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5004 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5005 5006 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5007 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5008 5009 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 5010 if (phy->rev >= 7) { 5011 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5012 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5013 } 5014 } 5015 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5016 5017 j = 0; 5018 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5019 for (i = 0; i < loop_i_max; i++) { 5020 for (j = 0; j < 16; j++) { 5021 BWN_RF_WRITE(mac, 0x43, i); 5022 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5023 (j << 8)); 5024 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5025 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5026 DELAY(20); 5027 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5028 goto done0; 5029 } 5030 } 5031 done0: 5032 loop1_outer_done = i; 5033 loop1_inner_done = j; 5034 if (j >= 8) { 5035 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5036 trsw_rx = 0x1b; 5037 for (j = j - 8; j < 16; j++) { 5038 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5039 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5040 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5041 DELAY(20); 5042 trsw_rx -= 3; 5043 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5044 goto done1; 5045 } 5046 } else 5047 trsw_rx = 0x18; 5048 done1: 5049 5050 if (phy->rev != 1) { 5051 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5052 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5053 } 5054 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5055 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5059 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5060 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5061 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5062 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5063 5064 bwn_phy_g_set_bbatt(mac, backup_bband); 5065 5066 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5067 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5068 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5069 5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5071 DELAY(10); 5072 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5073 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5074 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5075 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5076 5077 pg->pg_max_lb_gain = 5078 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5079 pg->pg_trsw_rx_gain = trsw_rx * 2; 5080 } 5081 5082 static uint16_t 5083 bwn_rf_init_bcm2050(struct bwn_mac *mac) 5084 { 5085 struct bwn_phy *phy = &mac->mac_phy; 5086 uint32_t tmp1 = 0, tmp2 = 0; 5087 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5088 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5089 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5090 static const uint8_t rcc_table[] = { 5091 0x02, 0x03, 0x01, 0x0f, 5092 0x06, 0x07, 0x05, 0x0f, 5093 0x0a, 0x0b, 0x09, 0x0f, 5094 0x0e, 0x0f, 0x0d, 0x0f, 5095 }; 5096 5097 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5098 rfoverval = rfover = cck3 = 0; 5099 radio0 = BWN_RF_READ(mac, 0x43); 5100 radio1 = BWN_RF_READ(mac, 0x51); 5101 radio2 = BWN_RF_READ(mac, 0x52); 5102 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5103 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5104 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5105 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5106 5107 if (phy->type == BWN_PHYTYPE_B) { 5108 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5109 reg0 = BWN_READ_2(mac, 0x3ec); 5110 5111 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5112 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5113 } else if (phy->gmode || phy->rev >= 2) { 5114 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5115 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5116 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5117 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5118 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5119 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5120 5121 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5122 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5123 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5124 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5125 if (BWN_HAS_LOOPBACK(phy)) { 5126 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5127 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5128 if (phy->rev >= 3) 5129 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5130 else 5131 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5132 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5133 } 5134 5135 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5136 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5137 BWN_LPD(0, 1, 1))); 5138 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5139 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5140 } 5141 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5142 5143 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5144 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5145 reg1 = BWN_READ_2(mac, 0x3e6); 5146 reg2 = BWN_READ_2(mac, 0x3f4); 5147 5148 if (phy->analog == 0) 5149 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5150 else { 5151 if (phy->analog >= 2) 5152 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5153 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5154 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5155 } 5156 5157 reg = BWN_RF_READ(mac, 0x60); 5158 index = (reg & 0x001e) >> 1; 5159 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5160 5161 if (phy->type == BWN_PHYTYPE_B) 5162 BWN_RF_WRITE(mac, 0x78, 0x26); 5163 if (phy->gmode || phy->rev >= 2) { 5164 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5165 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5166 BWN_LPD(0, 1, 1))); 5167 } 5168 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5169 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5170 if (phy->gmode || phy->rev >= 2) { 5171 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5172 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5173 BWN_LPD(0, 0, 1))); 5174 } 5175 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5176 BWN_RF_SET(mac, 0x51, 0x0004); 5177 if (phy->rf_rev == 8) 5178 BWN_RF_WRITE(mac, 0x43, 0x1f); 5179 else { 5180 BWN_RF_WRITE(mac, 0x52, 0); 5181 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5182 } 5183 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5184 5185 for (i = 0; i < 16; i++) { 5186 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5187 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5189 if (phy->gmode || phy->rev >= 2) { 5190 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5191 bwn_rf_2050_rfoverval(mac, 5192 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5193 } 5194 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5195 DELAY(10); 5196 if (phy->gmode || phy->rev >= 2) { 5197 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5198 bwn_rf_2050_rfoverval(mac, 5199 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5200 } 5201 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5202 DELAY(10); 5203 if (phy->gmode || phy->rev >= 2) { 5204 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5205 bwn_rf_2050_rfoverval(mac, 5206 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5207 } 5208 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5209 DELAY(20); 5210 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5211 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5212 if (phy->gmode || phy->rev >= 2) { 5213 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5214 bwn_rf_2050_rfoverval(mac, 5215 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5216 } 5217 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5218 } 5219 DELAY(10); 5220 5221 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5222 tmp1++; 5223 tmp1 >>= 9; 5224 5225 for (i = 0; i < 16; i++) { 5226 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5227 BWN_RF_WRITE(mac, 0x78, radio78); 5228 DELAY(10); 5229 for (j = 0; j < 16; j++) { 5230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5231 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5233 if (phy->gmode || phy->rev >= 2) { 5234 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5235 bwn_rf_2050_rfoverval(mac, 5236 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5237 } 5238 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5239 DELAY(10); 5240 if (phy->gmode || phy->rev >= 2) { 5241 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5242 bwn_rf_2050_rfoverval(mac, 5243 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5244 } 5245 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5246 DELAY(10); 5247 if (phy->gmode || phy->rev >= 2) { 5248 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5249 bwn_rf_2050_rfoverval(mac, 5250 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5251 } 5252 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5253 DELAY(10); 5254 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5255 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5256 if (phy->gmode || phy->rev >= 2) { 5257 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5258 bwn_rf_2050_rfoverval(mac, 5259 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5260 } 5261 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5262 } 5263 tmp2++; 5264 tmp2 >>= 8; 5265 if (tmp1 < tmp2) 5266 break; 5267 } 5268 5269 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5270 BWN_RF_WRITE(mac, 0x51, radio1); 5271 BWN_RF_WRITE(mac, 0x52, radio2); 5272 BWN_RF_WRITE(mac, 0x43, radio0); 5273 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5274 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5276 BWN_WRITE_2(mac, 0x3e6, reg1); 5277 if (phy->analog != 0) 5278 BWN_WRITE_2(mac, 0x3f4, reg2); 5279 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5280 bwn_spu_workaround(mac, phy->chan); 5281 if (phy->type == BWN_PHYTYPE_B) { 5282 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5283 BWN_WRITE_2(mac, 0x3ec, reg0); 5284 } else if (phy->gmode) { 5285 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5286 BWN_READ_2(mac, BWN_PHY_RADIO) 5287 & 0x7fff); 5288 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5289 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5290 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5291 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5292 analogoverval); 5293 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5294 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5295 if (BWN_HAS_LOOPBACK(phy)) { 5296 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5297 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5298 } 5299 } 5300 5301 return ((i > 15) ? radio78 : rcc); 5302 } 5303 5304 static void 5305 bwn_phy_init_b6(struct bwn_mac *mac) 5306 { 5307 struct bwn_phy *phy = &mac->mac_phy; 5308 struct bwn_phy_g *pg = &phy->phy_g; 5309 struct bwn_softc *sc = mac->mac_sc; 5310 uint16_t offset, val; 5311 uint8_t old_channel; 5312 5313 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5314 ("%s:%d: fail", __func__, __LINE__)); 5315 5316 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5317 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5318 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5319 BWN_RF_WRITE(mac, 0x51, 0x37); 5320 BWN_RF_WRITE(mac, 0x52, 0x70); 5321 BWN_RF_WRITE(mac, 0x53, 0xb3); 5322 BWN_RF_WRITE(mac, 0x54, 0x9b); 5323 BWN_RF_WRITE(mac, 0x5a, 0x88); 5324 BWN_RF_WRITE(mac, 0x5b, 0x88); 5325 BWN_RF_WRITE(mac, 0x5d, 0x88); 5326 BWN_RF_WRITE(mac, 0x5e, 0x88); 5327 BWN_RF_WRITE(mac, 0x7d, 0x88); 5328 bwn_hf_write(mac, 5329 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5330 } 5331 if (phy->rf_rev == 8) { 5332 BWN_RF_WRITE(mac, 0x51, 0); 5333 BWN_RF_WRITE(mac, 0x52, 0x40); 5334 BWN_RF_WRITE(mac, 0x53, 0xb7); 5335 BWN_RF_WRITE(mac, 0x54, 0x98); 5336 BWN_RF_WRITE(mac, 0x5a, 0x88); 5337 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5338 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5339 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5340 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5341 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5342 } else { 5343 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5344 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5345 } 5346 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5347 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5348 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5349 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5350 } 5351 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5352 BWN_PHY_WRITE(mac, offset, val); 5353 val -= 0x0202; 5354 } 5355 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5356 BWN_PHY_WRITE(mac, offset, val); 5357 val -= 0x0202; 5358 } 5359 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5360 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5361 val += 0x0202; 5362 } 5363 if (phy->type == BWN_PHYTYPE_G) { 5364 BWN_RF_SET(mac, 0x007a, 0x0020); 5365 BWN_RF_SET(mac, 0x0051, 0x0004); 5366 BWN_PHY_SET(mac, 0x0802, 0x0100); 5367 BWN_PHY_SET(mac, 0x042b, 0x2000); 5368 BWN_PHY_WRITE(mac, 0x5b, 0); 5369 BWN_PHY_WRITE(mac, 0x5c, 0); 5370 } 5371 5372 old_channel = phy->chan; 5373 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5374 5375 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5376 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5377 DELAY(40); 5378 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5379 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5380 BWN_RF_WRITE(mac, 0x50, 0x20); 5381 } 5382 if (phy->rf_rev <= 2) { 5383 BWN_RF_WRITE(mac, 0x7c, 0x20); 5384 BWN_RF_WRITE(mac, 0x5a, 0x70); 5385 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5386 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5387 } 5388 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5389 5390 bwn_phy_g_switch_chan(mac, old_channel, 0); 5391 5392 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5393 if (phy->rf_rev >= 6) 5394 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5395 else 5396 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5397 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5398 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5399 pg->pg_txctl); 5400 if (phy->rf_rev <= 5) 5401 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5402 if (phy->rf_rev <= 2) 5403 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5404 5405 if (phy->analog == 4) { 5406 BWN_WRITE_2(mac, 0x3e4, 9); 5407 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5408 } else 5409 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5410 if (phy->type == BWN_PHYTYPE_B) 5411 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5412 else if (phy->type == BWN_PHYTYPE_G) 5413 BWN_WRITE_2(mac, 0x03e6, 0x0); 5414 } 5415 5416 static void 5417 bwn_phy_init_a(struct bwn_mac *mac) 5418 { 5419 struct bwn_phy *phy = &mac->mac_phy; 5420 struct bwn_softc *sc = mac->mac_sc; 5421 5422 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5423 ("%s:%d: fail", __func__, __LINE__)); 5424 5425 if (phy->rev >= 6) { 5426 if (phy->type == BWN_PHYTYPE_A) 5427 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5428 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5429 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5430 else 5431 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5432 } 5433 5434 bwn_wa_init(mac); 5435 5436 if (phy->type == BWN_PHYTYPE_G && 5437 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5438 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5439 } 5440 5441 static void 5442 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5443 { 5444 int i; 5445 5446 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5447 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5448 } 5449 5450 static void 5451 bwn_wa_agc(struct bwn_mac *mac) 5452 { 5453 struct bwn_phy *phy = &mac->mac_phy; 5454 5455 if (phy->rev == 1) { 5456 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5464 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5465 } else { 5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5467 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5470 } 5471 5472 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5473 0x5700); 5474 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5475 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5476 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5477 BWN_RF_SET(mac, 0x7a, 0x0008); 5478 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5479 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5480 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5481 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5482 if (phy->rev == 1) 5483 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5484 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5493 if (phy->rev == 1) { 5494 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5495 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5496 } else { 5497 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5498 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5499 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5500 if (phy->rev >= 6) { 5501 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5502 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5503 (uint16_t)~0xf000, 0x3000); 5504 } 5505 } 5506 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5507 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5508 if (phy->rev == 1) { 5509 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5510 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5511 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5513 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5517 } else { 5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5522 } 5523 if (phy->rev >= 6) { 5524 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5525 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5526 } 5527 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5528 } 5529 5530 static void 5531 bwn_wa_grev1(struct bwn_mac *mac) 5532 { 5533 struct bwn_phy *phy = &mac->mac_phy; 5534 int i; 5535 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5536 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5537 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5538 5539 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5540 5541 /* init CRSTHRES and ANTDWELL */ 5542 if (phy->rev == 1) { 5543 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5544 } else if (phy->rev == 2) { 5545 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5546 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5547 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5548 } else { 5549 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5550 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5551 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5552 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5553 } 5554 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5555 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5556 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5557 5558 /* XXX support PHY-A??? */ 5559 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5560 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5561 bwn_tab_finefreqg[i]); 5562 5563 /* XXX support PHY-A??? */ 5564 if (phy->rev == 1) 5565 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5567 bwn_tab_noise_g1[i]); 5568 else 5569 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5570 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5571 bwn_tab_noise_g2[i]); 5572 5573 5574 for (i = 0; i < N(bwn_tab_rotor); i++) 5575 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5576 bwn_tab_rotor[i]); 5577 5578 /* XXX support PHY-A??? */ 5579 if (phy->rev >= 6) { 5580 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5581 BWN_PHY_ENCORE_EN) 5582 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5583 else 5584 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5585 } else 5586 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5587 5588 for (i = 0; i < N(bwn_tab_retard); i++) 5589 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5590 bwn_tab_retard[i]); 5591 5592 if (phy->rev == 1) { 5593 for (i = 0; i < 16; i++) 5594 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5595 i, 0x0020); 5596 } else { 5597 for (i = 0; i < 32; i++) 5598 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5599 } 5600 5601 bwn_wa_agc(mac); 5602 } 5603 5604 static void 5605 bwn_wa_grev26789(struct bwn_mac *mac) 5606 { 5607 struct bwn_phy *phy = &mac->mac_phy; 5608 int i; 5609 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5610 uint16_t ofdmrev; 5611 5612 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5613 5614 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5615 5616 /* init CRSTHRES and ANTDWELL */ 5617 if (phy->rev == 1) 5618 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5619 else if (phy->rev == 2) { 5620 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5621 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5622 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5623 } else { 5624 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5625 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5626 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5627 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5628 } 5629 5630 for (i = 0; i < 64; i++) 5631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5632 5633 /* XXX support PHY-A??? */ 5634 if (phy->rev == 1) 5635 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5637 bwn_tab_noise_g1[i]); 5638 else 5639 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5640 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5641 bwn_tab_noise_g2[i]); 5642 5643 /* XXX support PHY-A??? */ 5644 if (phy->rev >= 6) { 5645 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5646 BWN_PHY_ENCORE_EN) 5647 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5648 else 5649 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5650 } else 5651 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5652 5653 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5654 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5655 bwn_tab_sigmasqr2[i]); 5656 5657 if (phy->rev == 1) { 5658 for (i = 0; i < 16; i++) 5659 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5660 0x0020); 5661 } else { 5662 for (i = 0; i < 32; i++) 5663 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5664 } 5665 5666 bwn_wa_agc(mac); 5667 5668 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5669 if (ofdmrev > 2) { 5670 if (phy->type == BWN_PHYTYPE_A) 5671 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5672 else 5673 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5674 } else { 5675 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5678 } 5679 5680 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5681 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5682 } 5683 5684 static void 5685 bwn_wa_init(struct bwn_mac *mac) 5686 { 5687 struct bwn_phy *phy = &mac->mac_phy; 5688 struct bwn_softc *sc = mac->mac_sc; 5689 5690 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5691 5692 switch (phy->rev) { 5693 case 1: 5694 bwn_wa_grev1(mac); 5695 break; 5696 case 2: 5697 case 6: 5698 case 7: 5699 case 8: 5700 case 9: 5701 bwn_wa_grev26789(mac); 5702 break; 5703 default: 5704 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5705 } 5706 5707 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5708 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5709 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5710 if (phy->rev < 2) { 5711 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5712 0x0002); 5713 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5714 0x0001); 5715 } else { 5716 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5717 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5718 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5719 BWN_BFL_EXTLNA) && 5720 (phy->rev >= 7)) { 5721 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5722 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5723 0x0020, 0x0001); 5724 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5725 0x0021, 0x0001); 5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5727 0x0022, 0x0001); 5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5729 0x0023, 0x0000); 5730 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5731 0x0000, 0x0000); 5732 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5733 0x0003, 0x0002); 5734 } 5735 } 5736 } 5737 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5738 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5739 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5740 } 5741 5742 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5743 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5744 } 5745 5746 static void 5747 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5748 uint16_t value) 5749 { 5750 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5751 uint16_t addr; 5752 5753 addr = table + offset; 5754 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5755 (addr - 1 != pg->pg_ofdmtab_addr)) { 5756 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5757 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5758 } 5759 pg->pg_ofdmtab_addr = addr; 5760 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5761 } 5762 5763 static void 5764 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5765 uint32_t value) 5766 { 5767 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5768 uint16_t addr; 5769 5770 addr = table + offset; 5771 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5772 (addr - 1 != pg->pg_ofdmtab_addr)) { 5773 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5774 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5775 } 5776 pg->pg_ofdmtab_addr = addr; 5777 5778 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5779 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5780 } 5781 5782 static void 5783 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5784 uint16_t value) 5785 { 5786 5787 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5788 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5789 } 5790 5791 static void 5792 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5793 { 5794 struct bwn_phy *phy = &mac->mac_phy; 5795 struct bwn_softc *sc = mac->mac_sc; 5796 unsigned int i, max_loop; 5797 uint16_t value; 5798 uint32_t buffer[5] = { 5799 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5800 }; 5801 5802 if (ofdm) { 5803 max_loop = 0x1e; 5804 buffer[0] = 0x000201cc; 5805 } else { 5806 max_loop = 0xfa; 5807 buffer[0] = 0x000b846e; 5808 } 5809 5810 BWN_ASSERT_LOCKED(mac->mac_sc); 5811 5812 for (i = 0; i < 5; i++) 5813 bwn_ram_write(mac, i * 4, buffer[i]); 5814 5815 BWN_WRITE_2(mac, 0x0568, 0x0000); 5816 BWN_WRITE_2(mac, 0x07c0, 5817 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5818 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5819 BWN_WRITE_2(mac, 0x050c, value); 5820 if (phy->type == BWN_PHYTYPE_LP) 5821 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5822 BWN_WRITE_2(mac, 0x0508, 0x0000); 5823 BWN_WRITE_2(mac, 0x050a, 0x0000); 5824 BWN_WRITE_2(mac, 0x054c, 0x0000); 5825 BWN_WRITE_2(mac, 0x056a, 0x0014); 5826 BWN_WRITE_2(mac, 0x0568, 0x0826); 5827 BWN_WRITE_2(mac, 0x0500, 0x0000); 5828 if (phy->type == BWN_PHYTYPE_LP) 5829 BWN_WRITE_2(mac, 0x0502, 0x0050); 5830 else 5831 BWN_WRITE_2(mac, 0x0502, 0x0030); 5832 5833 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5834 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5835 for (i = 0x00; i < max_loop; i++) { 5836 value = BWN_READ_2(mac, 0x050e); 5837 if (value & 0x0080) 5838 break; 5839 DELAY(10); 5840 } 5841 for (i = 0x00; i < 0x0a; i++) { 5842 value = BWN_READ_2(mac, 0x050e); 5843 if (value & 0x0400) 5844 break; 5845 DELAY(10); 5846 } 5847 for (i = 0x00; i < 0x19; i++) { 5848 value = BWN_READ_2(mac, 0x0690); 5849 if (!(value & 0x0100)) 5850 break; 5851 DELAY(10); 5852 } 5853 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5854 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5855 } 5856 5857 static void 5858 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5859 { 5860 uint32_t macctl; 5861 5862 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5863 5864 macctl = BWN_READ_4(mac, BWN_MACCTL); 5865 if (macctl & BWN_MACCTL_BIGENDIAN) 5866 printf("TODO: need swap\n"); 5867 5868 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5869 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5870 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5871 } 5872 5873 static void 5874 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5875 { 5876 uint16_t value; 5877 5878 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5879 ("%s:%d: fail", __func__, __LINE__)); 5880 5881 value = (uint8_t) (ctl->q); 5882 value |= ((uint8_t) (ctl->i)) << 8; 5883 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5884 } 5885 5886 static uint16_t 5887 bwn_lo_calcfeed(struct bwn_mac *mac, 5888 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5889 { 5890 struct bwn_phy *phy = &mac->mac_phy; 5891 struct bwn_softc *sc = mac->mac_sc; 5892 uint16_t rfover; 5893 uint16_t feedthrough; 5894 5895 if (phy->gmode) { 5896 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5897 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5898 5899 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5900 ("%s:%d: fail", __func__, __LINE__)); 5901 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5902 ("%s:%d: fail", __func__, __LINE__)); 5903 5904 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5905 5906 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5907 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5908 phy->rev > 6) 5909 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5910 5911 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5912 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5913 DELAY(10); 5914 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5915 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5916 DELAY(10); 5917 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5918 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5919 DELAY(10); 5920 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5921 } else { 5922 pga |= BWN_PHY_PGACTL_UNKNOWN; 5923 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5924 DELAY(10); 5925 pga |= BWN_PHY_PGACTL_LOWBANDW; 5926 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5927 DELAY(10); 5928 pga |= BWN_PHY_PGACTL_LPF; 5929 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5930 } 5931 DELAY(21); 5932 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5933 5934 return (feedthrough); 5935 } 5936 5937 static uint16_t 5938 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5939 uint16_t *value, uint16_t *pad_mix_gain) 5940 { 5941 struct bwn_phy *phy = &mac->mac_phy; 5942 uint16_t reg, v, padmix; 5943 5944 if (phy->type == BWN_PHYTYPE_B) { 5945 v = 0x30; 5946 if (phy->rf_rev <= 5) { 5947 reg = 0x43; 5948 padmix = 0; 5949 } else { 5950 reg = 0x52; 5951 padmix = 5; 5952 } 5953 } else { 5954 if (phy->rev >= 2 && phy->rf_rev == 8) { 5955 reg = 0x43; 5956 v = 0x10; 5957 padmix = 2; 5958 } else { 5959 reg = 0x52; 5960 v = 0x30; 5961 padmix = 5; 5962 } 5963 } 5964 if (value) 5965 *value = v; 5966 if (pad_mix_gain) 5967 *pad_mix_gain = padmix; 5968 5969 return (reg); 5970 } 5971 5972 static void 5973 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5974 { 5975 struct bwn_phy *phy = &mac->mac_phy; 5976 struct bwn_phy_g *pg = &phy->phy_g; 5977 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5978 uint16_t reg, mask; 5979 uint16_t trsw_rx, pga; 5980 uint16_t rf_pctl_reg; 5981 5982 static const uint8_t tx_bias_values[] = { 5983 0x09, 0x08, 0x0a, 0x01, 0x00, 5984 0x02, 0x05, 0x04, 0x06, 5985 }; 5986 static const uint8_t tx_magn_values[] = { 5987 0x70, 0x40, 5988 }; 5989 5990 if (!BWN_HAS_LOOPBACK(phy)) { 5991 rf_pctl_reg = 6; 5992 trsw_rx = 2; 5993 pga = 0; 5994 } else { 5995 int lb_gain; 5996 5997 trsw_rx = 0; 5998 lb_gain = pg->pg_max_lb_gain / 2; 5999 if (lb_gain > 10) { 6000 rf_pctl_reg = 0; 6001 pga = abs(10 - lb_gain) / 6; 6002 pga = MIN(MAX(pga, 0), 15); 6003 } else { 6004 int cmp_val; 6005 int tmp; 6006 6007 pga = 0; 6008 cmp_val = 0x24; 6009 if ((phy->rev >= 2) && 6010 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6011 cmp_val = 0x3c; 6012 tmp = lb_gain; 6013 if ((10 - lb_gain) < cmp_val) 6014 tmp = (10 - lb_gain); 6015 if (tmp < 0) 6016 tmp += 6; 6017 else 6018 tmp += 3; 6019 cmp_val /= 4; 6020 tmp /= 4; 6021 if (tmp >= cmp_val) 6022 rf_pctl_reg = cmp_val; 6023 else 6024 rf_pctl_reg = tmp; 6025 } 6026 } 6027 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6028 bwn_phy_g_set_bbatt(mac, 2); 6029 6030 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6031 mask = ~mask; 6032 BWN_RF_MASK(mac, reg, mask); 6033 6034 if (BWN_HAS_TXMAG(phy)) { 6035 int i, j; 6036 int feedthrough; 6037 int min_feedth = 0xffff; 6038 uint8_t tx_magn, tx_bias; 6039 6040 for (i = 0; i < N(tx_magn_values); i++) { 6041 tx_magn = tx_magn_values[i]; 6042 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6043 for (j = 0; j < N(tx_bias_values); j++) { 6044 tx_bias = tx_bias_values[j]; 6045 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6046 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6047 trsw_rx); 6048 if (feedthrough < min_feedth) { 6049 lo->tx_bias = tx_bias; 6050 lo->tx_magn = tx_magn; 6051 min_feedth = feedthrough; 6052 } 6053 if (lo->tx_bias == 0) 6054 break; 6055 } 6056 BWN_RF_WRITE(mac, 0x52, 6057 (BWN_RF_READ(mac, 0x52) 6058 & 0xff00) | lo->tx_bias | lo-> 6059 tx_magn); 6060 } 6061 } else { 6062 lo->tx_magn = 0; 6063 lo->tx_bias = 0; 6064 BWN_RF_MASK(mac, 0x52, 0xfff0); 6065 } 6066 6067 BWN_GETTIME(lo->txctl_measured_time); 6068 } 6069 6070 static void 6071 bwn_lo_get_powervector(struct bwn_mac *mac) 6072 { 6073 struct bwn_phy *phy = &mac->mac_phy; 6074 struct bwn_phy_g *pg = &phy->phy_g; 6075 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6076 int i; 6077 uint64_t tmp; 6078 uint64_t power_vector = 0; 6079 6080 for (i = 0; i < 8; i += 2) { 6081 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6082 power_vector |= (tmp << (i * 8)); 6083 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6084 } 6085 if (power_vector) 6086 lo->power_vector = power_vector; 6087 6088 BWN_GETTIME(lo->pwr_vec_read_time); 6089 } 6090 6091 static void 6092 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6093 int use_trsw_rx) 6094 { 6095 struct bwn_phy *phy = &mac->mac_phy; 6096 struct bwn_phy_g *pg = &phy->phy_g; 6097 uint16_t tmp; 6098 6099 if (max_rx_gain < 0) 6100 max_rx_gain = 0; 6101 6102 if (BWN_HAS_LOOPBACK(phy)) { 6103 int trsw_rx = 0; 6104 int trsw_rx_gain; 6105 6106 if (use_trsw_rx) { 6107 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6108 if (max_rx_gain >= trsw_rx_gain) { 6109 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6110 trsw_rx = 0x20; 6111 } 6112 } else 6113 trsw_rx_gain = max_rx_gain; 6114 if (trsw_rx_gain < 9) { 6115 pg->pg_lna_lod_gain = 0; 6116 } else { 6117 pg->pg_lna_lod_gain = 1; 6118 trsw_rx_gain -= 8; 6119 } 6120 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6121 pg->pg_pga_gain = trsw_rx_gain / 3; 6122 if (pg->pg_pga_gain >= 5) { 6123 pg->pg_pga_gain -= 5; 6124 pg->pg_lna_gain = 2; 6125 } else 6126 pg->pg_lna_gain = 0; 6127 } else { 6128 pg->pg_lna_gain = 0; 6129 pg->pg_trsw_rx_gain = 0x20; 6130 if (max_rx_gain >= 0x14) { 6131 pg->pg_lna_lod_gain = 1; 6132 pg->pg_pga_gain = 2; 6133 } else if (max_rx_gain >= 0x12) { 6134 pg->pg_lna_lod_gain = 1; 6135 pg->pg_pga_gain = 1; 6136 } else if (max_rx_gain >= 0xf) { 6137 pg->pg_lna_lod_gain = 1; 6138 pg->pg_pga_gain = 0; 6139 } else { 6140 pg->pg_lna_lod_gain = 0; 6141 pg->pg_pga_gain = 0; 6142 } 6143 } 6144 6145 tmp = BWN_RF_READ(mac, 0x7a); 6146 if (pg->pg_lna_lod_gain == 0) 6147 tmp &= ~0x0008; 6148 else 6149 tmp |= 0x0008; 6150 BWN_RF_WRITE(mac, 0x7a, tmp); 6151 } 6152 6153 static void 6154 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6155 { 6156 struct bwn_phy *phy = &mac->mac_phy; 6157 struct bwn_phy_g *pg = &phy->phy_g; 6158 struct bwn_softc *sc = mac->mac_sc; 6159 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6160 struct timespec ts; 6161 uint16_t tmp; 6162 6163 if (bwn_has_hwpctl(mac)) { 6164 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6165 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6166 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6167 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6168 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6169 6170 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6171 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6172 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6173 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6174 } 6175 if (phy->type == BWN_PHYTYPE_B && 6176 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6177 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6179 } 6180 if (phy->rev >= 2) { 6181 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6182 sav->phy_analogoverval = 6183 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6184 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6185 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6186 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6187 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6188 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6189 6190 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6191 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6192 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6193 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6194 if (phy->type == BWN_PHYTYPE_G) { 6195 if ((phy->rev >= 7) && 6196 (siba_sprom_get_bf_lo(sc->sc_dev) & 6197 BWN_BFL_EXTLNA)) { 6198 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6199 } else { 6200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6201 } 6202 } else { 6203 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6204 } 6205 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6206 } 6207 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6208 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6209 sav->rf0 = BWN_RF_READ(mac, 0x43); 6210 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6211 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6212 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6213 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6214 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6215 6216 if (!BWN_HAS_TXMAG(phy)) { 6217 sav->rf2 = BWN_RF_READ(mac, 0x52); 6218 sav->rf2 &= 0x00f0; 6219 } 6220 if (phy->type == BWN_PHYTYPE_B) { 6221 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6222 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6223 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6224 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6225 } else { 6226 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6227 | 0x8000); 6228 } 6229 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6230 & 0xf000); 6231 6232 tmp = 6233 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6234 BWN_PHY_WRITE(mac, tmp, 0x007f); 6235 6236 tmp = sav->phy_syncctl; 6237 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6238 tmp = sav->rf1; 6239 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6240 6241 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6242 if (phy->type == BWN_PHYTYPE_G || 6243 (phy->type == BWN_PHYTYPE_B && 6244 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6245 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6246 } else 6247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6248 if (phy->rev >= 2) 6249 bwn_dummy_transmission(mac, 0, 1); 6250 bwn_phy_g_switch_chan(mac, 6, 0); 6251 BWN_RF_READ(mac, 0x51); 6252 if (phy->type == BWN_PHYTYPE_G) 6253 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6254 6255 nanouptime(&ts); 6256 if (time_before(lo->txctl_measured_time, 6257 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6258 bwn_lo_measure_txctl_values(mac); 6259 6260 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6261 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6262 else { 6263 if (phy->type == BWN_PHYTYPE_B) 6264 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6265 else 6266 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6267 } 6268 } 6269 6270 static void 6271 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6272 { 6273 struct bwn_phy *phy = &mac->mac_phy; 6274 struct bwn_phy_g *pg = &phy->phy_g; 6275 uint16_t tmp; 6276 6277 if (phy->rev >= 2) { 6278 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6279 tmp = (pg->pg_pga_gain << 8); 6280 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6281 DELAY(5); 6282 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6283 DELAY(2); 6284 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6285 } else { 6286 tmp = (pg->pg_pga_gain | 0xefa0); 6287 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6288 } 6289 if (phy->type == BWN_PHYTYPE_G) { 6290 if (phy->rev >= 3) 6291 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6292 else 6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6294 if (phy->rev >= 2) 6295 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6296 else 6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6298 } 6299 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6300 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6301 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6302 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6303 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6304 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6305 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6306 if (!BWN_HAS_TXMAG(phy)) { 6307 tmp = sav->rf2; 6308 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6309 } 6310 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6311 if (phy->type == BWN_PHYTYPE_B && 6312 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6313 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6314 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6315 } 6316 if (phy->rev >= 2) { 6317 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6318 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6319 sav->phy_analogoverval); 6320 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6321 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6322 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6323 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6324 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6325 } 6326 if (bwn_has_hwpctl(mac)) { 6327 tmp = (sav->phy_lomask & 0xbfff); 6328 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6329 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6330 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6331 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6332 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6333 } 6334 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6335 } 6336 6337 static int 6338 bwn_lo_probe_loctl(struct bwn_mac *mac, 6339 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6340 { 6341 struct bwn_phy *phy = &mac->mac_phy; 6342 struct bwn_phy_g *pg = &phy->phy_g; 6343 struct bwn_loctl orig, test; 6344 struct bwn_loctl prev = { -100, -100 }; 6345 static const struct bwn_loctl modifiers[] = { 6346 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6347 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6348 }; 6349 int begin, end, lower = 0, i; 6350 uint16_t feedth; 6351 6352 if (d->curstate == 0) { 6353 begin = 1; 6354 end = 8; 6355 } else if (d->curstate % 2 == 0) { 6356 begin = d->curstate - 1; 6357 end = d->curstate + 1; 6358 } else { 6359 begin = d->curstate - 2; 6360 end = d->curstate + 2; 6361 } 6362 if (begin < 1) 6363 begin += 8; 6364 if (end > 8) 6365 end -= 8; 6366 6367 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6368 i = begin; 6369 d->curstate = i; 6370 while (1) { 6371 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6372 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6373 test.i += modifiers[i - 1].i * d->multipler; 6374 test.q += modifiers[i - 1].q * d->multipler; 6375 if ((test.i != prev.i || test.q != prev.q) && 6376 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6377 bwn_lo_write(mac, &test); 6378 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6379 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6380 if (feedth < d->feedth) { 6381 memcpy(probe, &test, 6382 sizeof(struct bwn_loctl)); 6383 lower = 1; 6384 d->feedth = feedth; 6385 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6386 break; 6387 } 6388 } 6389 memcpy(&prev, &test, sizeof(prev)); 6390 if (i == end) 6391 break; 6392 if (i == 8) 6393 i = 1; 6394 else 6395 i++; 6396 d->curstate = i; 6397 } 6398 6399 return (lower); 6400 } 6401 6402 static void 6403 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6404 { 6405 struct bwn_phy *phy = &mac->mac_phy; 6406 struct bwn_phy_g *pg = &phy->phy_g; 6407 struct bwn_lo_g_sm d; 6408 struct bwn_loctl probe; 6409 int lower, repeat, cnt = 0; 6410 uint16_t feedth; 6411 6412 d.nmeasure = 0; 6413 d.multipler = 1; 6414 if (BWN_HAS_LOOPBACK(phy)) 6415 d.multipler = 3; 6416 6417 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6418 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6419 6420 do { 6421 bwn_lo_write(mac, &d.loctl); 6422 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6423 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6424 if (feedth < 0x258) { 6425 if (feedth >= 0x12c) 6426 *rxgain += 6; 6427 else 6428 *rxgain += 3; 6429 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6430 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6431 } 6432 d.feedth = feedth; 6433 d.curstate = 0; 6434 do { 6435 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6436 ("%s:%d: fail", __func__, __LINE__)); 6437 memcpy(&probe, &d.loctl, 6438 sizeof(struct bwn_loctl)); 6439 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6440 if (!lower) 6441 break; 6442 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6443 break; 6444 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6445 d.nmeasure++; 6446 } while (d.nmeasure < 24); 6447 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6448 6449 if (BWN_HAS_LOOPBACK(phy)) { 6450 if (d.feedth > 0x1194) 6451 *rxgain -= 6; 6452 else if (d.feedth < 0x5dc) 6453 *rxgain += 3; 6454 if (cnt == 0) { 6455 if (d.feedth <= 0x5dc) { 6456 d.multipler = 1; 6457 cnt++; 6458 } else 6459 d.multipler = 2; 6460 } else if (cnt == 2) 6461 d.multipler = 1; 6462 } 6463 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6464 } while (++cnt < repeat); 6465 } 6466 6467 static struct bwn_lo_calib * 6468 bwn_lo_calibset(struct bwn_mac *mac, 6469 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6470 { 6471 struct bwn_phy *phy = &mac->mac_phy; 6472 struct bwn_phy_g *pg = &phy->phy_g; 6473 struct bwn_loctl loctl = { 0, 0 }; 6474 struct bwn_lo_calib *cal; 6475 struct bwn_lo_g_value sval = { 0 }; 6476 int rxgain; 6477 uint16_t pad, reg, value; 6478 6479 sval.old_channel = phy->chan; 6480 bwn_mac_suspend(mac); 6481 bwn_lo_save(mac, &sval); 6482 6483 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6484 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6485 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6486 6487 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6488 if (rfatt->padmix) 6489 rxgain -= pad; 6490 if (BWN_HAS_LOOPBACK(phy)) 6491 rxgain += pg->pg_max_lb_gain; 6492 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6493 bwn_phy_g_set_bbatt(mac, bbatt->att); 6494 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6495 6496 bwn_lo_restore(mac, &sval); 6497 bwn_mac_enable(mac); 6498 6499 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6500 if (!cal) { 6501 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6502 return (NULL); 6503 } 6504 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6505 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6506 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6507 6508 BWN_GETTIME(cal->calib_time); 6509 6510 return (cal); 6511 } 6512 6513 static struct bwn_lo_calib * 6514 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6515 const struct bwn_rfatt *rfatt) 6516 { 6517 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6518 struct bwn_lo_calib *c; 6519 6520 TAILQ_FOREACH(c, &lo->calib_list, list) { 6521 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6522 continue; 6523 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6524 continue; 6525 return (c); 6526 } 6527 6528 c = bwn_lo_calibset(mac, bbatt, rfatt); 6529 if (!c) 6530 return (NULL); 6531 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6532 6533 return (c); 6534 } 6535 6536 static void 6537 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6538 { 6539 struct bwn_phy *phy = &mac->mac_phy; 6540 struct bwn_phy_g *pg = &phy->phy_g; 6541 struct bwn_softc *sc = mac->mac_sc; 6542 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6543 const struct bwn_rfatt *rfatt; 6544 const struct bwn_bbatt *bbatt; 6545 uint64_t pvector; 6546 int i; 6547 int rf_offset, bb_offset; 6548 uint8_t changed = 0; 6549 6550 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6551 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6552 ("%s:%d: fail", __func__, __LINE__)); 6553 6554 pvector = lo->power_vector; 6555 if (!update && !pvector) 6556 return; 6557 6558 bwn_mac_suspend(mac); 6559 6560 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6561 struct bwn_lo_calib *cal; 6562 int idx; 6563 uint16_t val; 6564 6565 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6566 continue; 6567 bb_offset = i / lo->rfatt.len; 6568 rf_offset = i % lo->rfatt.len; 6569 bbatt = &(lo->bbatt.array[bb_offset]); 6570 rfatt = &(lo->rfatt.array[rf_offset]); 6571 6572 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6573 if (!cal) { 6574 device_printf(sc->sc_dev, "LO: Could not " 6575 "calibrate DC table entry\n"); 6576 continue; 6577 } 6578 val = (uint8_t)(cal->ctl.q); 6579 val |= ((uint8_t)(cal->ctl.i)) << 4; 6580 free(cal, M_DEVBUF); 6581 6582 idx = i / 2; 6583 if (i % 2) 6584 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6585 | ((val & 0x00ff) << 8); 6586 else 6587 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6588 | (val & 0x00ff); 6589 changed = 1; 6590 } 6591 if (changed) { 6592 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6593 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6594 } 6595 bwn_mac_enable(mac); 6596 } 6597 6598 static void 6599 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6600 { 6601 6602 if (!rf->padmix) 6603 return; 6604 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6605 rf->att = 4; 6606 } 6607 6608 static void 6609 bwn_lo_g_adjust(struct bwn_mac *mac) 6610 { 6611 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6612 struct bwn_lo_calib *cal; 6613 struct bwn_rfatt rf; 6614 6615 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6616 bwn_lo_fixup_rfatt(&rf); 6617 6618 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6619 if (!cal) 6620 return; 6621 bwn_lo_write(mac, &cal->ctl); 6622 } 6623 6624 static void 6625 bwn_lo_g_init(struct bwn_mac *mac) 6626 { 6627 6628 if (!bwn_has_hwpctl(mac)) 6629 return; 6630 6631 bwn_lo_get_powervector(mac); 6632 bwn_phy_g_dc_lookup_init(mac, 1); 6633 } 6634 6635 static void 6636 bwn_mac_suspend(struct bwn_mac *mac) 6637 { 6638 struct bwn_softc *sc = mac->mac_sc; 6639 int i; 6640 uint32_t tmp; 6641 6642 KASSERT(mac->mac_suspended >= 0, 6643 ("%s:%d: fail", __func__, __LINE__)); 6644 6645 if (mac->mac_suspended == 0) { 6646 bwn_psctl(mac, BWN_PS_AWAKE); 6647 BWN_WRITE_4(mac, BWN_MACCTL, 6648 BWN_READ_4(mac, BWN_MACCTL) 6649 & ~BWN_MACCTL_ON); 6650 BWN_READ_4(mac, BWN_MACCTL); 6651 for (i = 35; i; i--) { 6652 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6653 if (tmp & BWN_INTR_MAC_SUSPENDED) 6654 goto out; 6655 DELAY(10); 6656 } 6657 for (i = 40; i; i--) { 6658 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6659 if (tmp & BWN_INTR_MAC_SUSPENDED) 6660 goto out; 6661 DELAY(1000); 6662 } 6663 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6664 } 6665 out: 6666 mac->mac_suspended++; 6667 } 6668 6669 static void 6670 bwn_mac_enable(struct bwn_mac *mac) 6671 { 6672 struct bwn_softc *sc = mac->mac_sc; 6673 uint16_t state; 6674 6675 state = bwn_shm_read_2(mac, BWN_SHARED, 6676 BWN_SHARED_UCODESTAT); 6677 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6678 state != BWN_SHARED_UCODESTAT_SLEEP) 6679 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6680 6681 mac->mac_suspended--; 6682 KASSERT(mac->mac_suspended >= 0, 6683 ("%s:%d: fail", __func__, __LINE__)); 6684 if (mac->mac_suspended == 0) { 6685 BWN_WRITE_4(mac, BWN_MACCTL, 6686 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6687 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6688 BWN_READ_4(mac, BWN_MACCTL); 6689 BWN_READ_4(mac, BWN_INTR_REASON); 6690 bwn_psctl(mac, 0); 6691 } 6692 } 6693 6694 static void 6695 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6696 { 6697 struct bwn_softc *sc = mac->mac_sc; 6698 int i; 6699 uint16_t ucstat; 6700 6701 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6702 ("%s:%d: fail", __func__, __LINE__)); 6703 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6704 ("%s:%d: fail", __func__, __LINE__)); 6705 6706 /* XXX forcibly awake and hwps-off */ 6707 6708 BWN_WRITE_4(mac, BWN_MACCTL, 6709 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6710 ~BWN_MACCTL_HWPS); 6711 BWN_READ_4(mac, BWN_MACCTL); 6712 if (siba_get_revid(sc->sc_dev) >= 5) { 6713 for (i = 0; i < 100; i++) { 6714 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6715 BWN_SHARED_UCODESTAT); 6716 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6717 break; 6718 DELAY(10); 6719 } 6720 } 6721 } 6722 6723 static int16_t 6724 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6725 { 6726 6727 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6728 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6729 } 6730 6731 static void 6732 bwn_nrssi_threshold(struct bwn_mac *mac) 6733 { 6734 struct bwn_phy *phy = &mac->mac_phy; 6735 struct bwn_phy_g *pg = &phy->phy_g; 6736 struct bwn_softc *sc = mac->mac_sc; 6737 int32_t a, b; 6738 int16_t tmp16; 6739 uint16_t tmpu16; 6740 6741 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6742 6743 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6744 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6745 a = 0x13; 6746 b = 0x12; 6747 } else { 6748 a = 0xe; 6749 b = 0x11; 6750 } 6751 6752 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6753 a += (pg->pg_nrssi[0] << 6); 6754 a += (a < 32) ? 31 : 32; 6755 a = a >> 6; 6756 a = MIN(MAX(a, -31), 31); 6757 6758 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6759 b += (pg->pg_nrssi[0] << 6); 6760 if (b < 32) 6761 b += 31; 6762 else 6763 b += 32; 6764 b = b >> 6; 6765 b = MIN(MAX(b, -31), 31); 6766 6767 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6768 tmpu16 |= ((uint32_t)b & 0x0000003f); 6769 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6770 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6771 return; 6772 } 6773 6774 tmp16 = bwn_nrssi_read(mac, 0x20); 6775 if (tmp16 >= 0x20) 6776 tmp16 -= 0x40; 6777 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6778 } 6779 6780 static void 6781 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6782 { 6783 #define SAVE_RF_MAX 3 6784 #define SAVE_PHY_COMM_MAX 4 6785 #define SAVE_PHY3_MAX 8 6786 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6787 { 0x7a, 0x52, 0x43 }; 6788 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6789 { 0x15, 0x5a, 0x59, 0x58 }; 6790 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6791 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6792 0x0801, 0x0060, 0x0014, 0x0478 6793 }; 6794 struct bwn_phy *phy = &mac->mac_phy; 6795 struct bwn_phy_g *pg = &phy->phy_g; 6796 int32_t i, tmp32, phy3_idx = 0; 6797 uint16_t delta, tmp; 6798 uint16_t save_rf[SAVE_RF_MAX]; 6799 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6800 uint16_t save_phy3[SAVE_PHY3_MAX]; 6801 uint16_t ant_div, phy0, chan_ex; 6802 int16_t nrssi0, nrssi1; 6803 6804 KASSERT(phy->type == BWN_PHYTYPE_G, 6805 ("%s:%d: fail", __func__, __LINE__)); 6806 6807 if (phy->rf_rev >= 9) 6808 return; 6809 if (phy->rf_rev == 8) 6810 bwn_nrssi_offset(mac); 6811 6812 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6813 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6814 6815 /* 6816 * Save RF/PHY registers for later restoration 6817 */ 6818 ant_div = BWN_READ_2(mac, 0x03e2); 6819 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6820 for (i = 0; i < SAVE_RF_MAX; ++i) 6821 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6822 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6823 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6824 6825 phy0 = BWN_READ_2(mac, BWN_PHY0); 6826 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6827 if (phy->rev >= 3) { 6828 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6829 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6830 BWN_PHY_WRITE(mac, 0x002e, 0); 6831 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6832 switch (phy->rev) { 6833 case 4: 6834 case 6: 6835 case 7: 6836 BWN_PHY_SET(mac, 0x0478, 0x0100); 6837 BWN_PHY_SET(mac, 0x0801, 0x0040); 6838 break; 6839 case 3: 6840 case 5: 6841 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6842 break; 6843 } 6844 BWN_PHY_SET(mac, 0x0060, 0x0040); 6845 BWN_PHY_SET(mac, 0x0014, 0x0200); 6846 } 6847 /* 6848 * Calculate nrssi0 6849 */ 6850 BWN_RF_SET(mac, 0x007a, 0x0070); 6851 bwn_set_all_gains(mac, 0, 8, 0); 6852 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6853 if (phy->rev >= 2) { 6854 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6855 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6856 } 6857 BWN_RF_SET(mac, 0x007a, 0x0080); 6858 DELAY(20); 6859 6860 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6861 if (nrssi0 >= 0x0020) 6862 nrssi0 -= 0x0040; 6863 6864 /* 6865 * Calculate nrssi1 6866 */ 6867 BWN_RF_MASK(mac, 0x007a, 0x007f); 6868 if (phy->rev >= 2) 6869 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6870 6871 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6872 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6873 BWN_RF_SET(mac, 0x007a, 0x000f); 6874 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6875 if (phy->rev >= 2) { 6876 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6877 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6878 } 6879 6880 bwn_set_all_gains(mac, 3, 0, 1); 6881 if (phy->rf_rev == 8) { 6882 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6883 } else { 6884 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6885 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6886 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6887 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6888 } 6889 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6890 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6891 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6892 DELAY(20); 6893 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6894 6895 /* 6896 * Install calculated narrow RSSI values 6897 */ 6898 if (nrssi1 >= 0x0020) 6899 nrssi1 -= 0x0040; 6900 if (nrssi0 == nrssi1) 6901 pg->pg_nrssi_slope = 0x00010000; 6902 else 6903 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6904 if (nrssi0 >= -4) { 6905 pg->pg_nrssi[0] = nrssi1; 6906 pg->pg_nrssi[1] = nrssi0; 6907 } 6908 6909 /* 6910 * Restore saved RF/PHY registers 6911 */ 6912 if (phy->rev >= 3) { 6913 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6914 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6915 save_phy3[phy3_idx]); 6916 } 6917 } 6918 if (phy->rev >= 2) { 6919 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6920 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6921 } 6922 6923 for (i = 0; i < SAVE_RF_MAX; ++i) 6924 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6925 6926 BWN_WRITE_2(mac, 0x03e2, ant_div); 6927 BWN_WRITE_2(mac, 0x03e6, phy0); 6928 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6929 6930 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6931 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6932 6933 bwn_spu_workaround(mac, phy->chan); 6934 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6935 bwn_set_original_gains(mac); 6936 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6937 if (phy->rev >= 3) { 6938 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6939 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6940 save_phy3[phy3_idx]); 6941 } 6942 } 6943 6944 delta = 0x1f - pg->pg_nrssi[0]; 6945 for (i = 0; i < 64; i++) { 6946 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6947 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6948 pg->pg_nrssi_lt[i] = tmp32; 6949 } 6950 6951 bwn_nrssi_threshold(mac); 6952 #undef SAVE_RF_MAX 6953 #undef SAVE_PHY_COMM_MAX 6954 #undef SAVE_PHY3_MAX 6955 } 6956 6957 static void 6958 bwn_nrssi_offset(struct bwn_mac *mac) 6959 { 6960 #define SAVE_RF_MAX 2 6961 #define SAVE_PHY_COMM_MAX 10 6962 #define SAVE_PHY6_MAX 8 6963 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6964 { 0x7a, 0x43 }; 6965 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6966 0x0001, 0x0811, 0x0812, 0x0814, 6967 0x0815, 0x005a, 0x0059, 0x0058, 6968 0x000a, 0x0003 6969 }; 6970 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6971 0x002e, 0x002f, 0x080f, 0x0810, 6972 0x0801, 0x0060, 0x0014, 0x0478 6973 }; 6974 struct bwn_phy *phy = &mac->mac_phy; 6975 int i, phy6_idx = 0; 6976 uint16_t save_rf[SAVE_RF_MAX]; 6977 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6978 uint16_t save_phy6[SAVE_PHY6_MAX]; 6979 int16_t nrssi; 6980 uint16_t saved = 0xffff; 6981 6982 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6983 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6984 for (i = 0; i < SAVE_RF_MAX; ++i) 6985 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6986 6987 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6988 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6989 BWN_PHY_SET(mac, 0x0811, 0x000c); 6990 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6991 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6992 if (phy->rev >= 6) { 6993 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6994 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6995 6996 BWN_PHY_WRITE(mac, 0x002e, 0); 6997 BWN_PHY_WRITE(mac, 0x002f, 0); 6998 BWN_PHY_WRITE(mac, 0x080f, 0); 6999 BWN_PHY_WRITE(mac, 0x0810, 0); 7000 BWN_PHY_SET(mac, 0x0478, 0x0100); 7001 BWN_PHY_SET(mac, 0x0801, 0x0040); 7002 BWN_PHY_SET(mac, 0x0060, 0x0040); 7003 BWN_PHY_SET(mac, 0x0014, 0x0200); 7004 } 7005 BWN_RF_SET(mac, 0x007a, 0x0070); 7006 BWN_RF_SET(mac, 0x007a, 0x0080); 7007 DELAY(30); 7008 7009 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7010 if (nrssi >= 0x20) 7011 nrssi -= 0x40; 7012 if (nrssi == 31) { 7013 for (i = 7; i >= 4; i--) { 7014 BWN_RF_WRITE(mac, 0x007b, i); 7015 DELAY(20); 7016 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7017 0x003f); 7018 if (nrssi >= 0x20) 7019 nrssi -= 0x40; 7020 if (nrssi < 31 && saved == 0xffff) 7021 saved = i; 7022 } 7023 if (saved == 0xffff) 7024 saved = 4; 7025 } else { 7026 BWN_RF_MASK(mac, 0x007a, 0x007f); 7027 if (phy->rev != 1) { 7028 BWN_PHY_SET(mac, 0x0814, 0x0001); 7029 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7030 } 7031 BWN_PHY_SET(mac, 0x0811, 0x000c); 7032 BWN_PHY_SET(mac, 0x0812, 0x000c); 7033 BWN_PHY_SET(mac, 0x0811, 0x0030); 7034 BWN_PHY_SET(mac, 0x0812, 0x0030); 7035 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7036 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7037 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7038 if (phy->rev == 0) 7039 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7040 else 7041 BWN_PHY_SET(mac, 0x000a, 0x2000); 7042 if (phy->rev != 1) { 7043 BWN_PHY_SET(mac, 0x0814, 0x0004); 7044 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7045 } 7046 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7047 BWN_RF_SET(mac, 0x007a, 0x000f); 7048 bwn_set_all_gains(mac, 3, 0, 1); 7049 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7050 DELAY(30); 7051 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7052 if (nrssi >= 0x20) 7053 nrssi -= 0x40; 7054 if (nrssi == -32) { 7055 for (i = 0; i < 4; i++) { 7056 BWN_RF_WRITE(mac, 0x007b, i); 7057 DELAY(20); 7058 nrssi = (int16_t)((BWN_PHY_READ(mac, 7059 0x047f) >> 8) & 0x003f); 7060 if (nrssi >= 0x20) 7061 nrssi -= 0x40; 7062 if (nrssi > -31 && saved == 0xffff) 7063 saved = i; 7064 } 7065 if (saved == 0xffff) 7066 saved = 3; 7067 } else 7068 saved = 0; 7069 } 7070 BWN_RF_WRITE(mac, 0x007b, saved); 7071 7072 /* 7073 * Restore saved RF/PHY registers 7074 */ 7075 if (phy->rev >= 6) { 7076 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7077 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7078 save_phy6[phy6_idx]); 7079 } 7080 } 7081 if (phy->rev != 1) { 7082 for (i = 3; i < 5; i++) 7083 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7084 save_phy_comm[i]); 7085 } 7086 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7087 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7088 7089 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7090 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7091 7092 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7093 BWN_PHY_SET(mac, 0x0429, 0x8000); 7094 bwn_set_original_gains(mac); 7095 if (phy->rev >= 6) { 7096 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7097 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7098 save_phy6[phy6_idx]); 7099 } 7100 } 7101 7102 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7103 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7104 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7105 } 7106 7107 static void 7108 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7109 int16_t third) 7110 { 7111 struct bwn_phy *phy = &mac->mac_phy; 7112 uint16_t i; 7113 uint16_t start = 0x08, end = 0x18; 7114 uint16_t tmp; 7115 uint16_t table; 7116 7117 if (phy->rev <= 1) { 7118 start = 0x10; 7119 end = 0x20; 7120 } 7121 7122 table = BWN_OFDMTAB_GAINX; 7123 if (phy->rev <= 1) 7124 table = BWN_OFDMTAB_GAINX_R1; 7125 for (i = 0; i < 4; i++) 7126 bwn_ofdmtab_write_2(mac, table, i, first); 7127 7128 for (i = start; i < end; i++) 7129 bwn_ofdmtab_write_2(mac, table, i, second); 7130 7131 if (third != -1) { 7132 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7133 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7134 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7135 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7136 } 7137 bwn_dummy_transmission(mac, 0, 1); 7138 } 7139 7140 static void 7141 bwn_set_original_gains(struct bwn_mac *mac) 7142 { 7143 struct bwn_phy *phy = &mac->mac_phy; 7144 uint16_t i, tmp; 7145 uint16_t table; 7146 uint16_t start = 0x0008, end = 0x0018; 7147 7148 if (phy->rev <= 1) { 7149 start = 0x0010; 7150 end = 0x0020; 7151 } 7152 7153 table = BWN_OFDMTAB_GAINX; 7154 if (phy->rev <= 1) 7155 table = BWN_OFDMTAB_GAINX_R1; 7156 for (i = 0; i < 4; i++) { 7157 tmp = (i & 0xfffc); 7158 tmp |= (i & 0x0001) << 1; 7159 tmp |= (i & 0x0002) >> 1; 7160 7161 bwn_ofdmtab_write_2(mac, table, i, tmp); 7162 } 7163 7164 for (i = start; i < end; i++) 7165 bwn_ofdmtab_write_2(mac, table, i, i - start); 7166 7167 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7168 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7169 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7170 bwn_dummy_transmission(mac, 0, 1); 7171 } 7172 7173 static void 7174 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7175 { 7176 struct bwn_phy *phy = &mac->mac_phy; 7177 struct bwn_phy_g *pg = &phy->phy_g; 7178 struct bwn_rfatt old_rfatt, rfatt; 7179 struct bwn_bbatt old_bbatt, bbatt; 7180 struct bwn_softc *sc = mac->mac_sc; 7181 uint8_t old_txctl = 0; 7182 7183 KASSERT(phy->type == BWN_PHYTYPE_G, 7184 ("%s:%d: fail", __func__, __LINE__)); 7185 7186 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7187 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7188 return; 7189 7190 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7191 7192 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7193 7194 if (!phy->gmode) 7195 return; 7196 bwn_hwpctl_early_init(mac); 7197 if (pg->pg_curtssi == 0) { 7198 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7199 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7200 } else { 7201 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7202 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7203 old_txctl = pg->pg_txctl; 7204 7205 bbatt.att = 11; 7206 if (phy->rf_rev == 8) { 7207 rfatt.att = 15; 7208 rfatt.padmix = 1; 7209 } else { 7210 rfatt.att = 9; 7211 rfatt.padmix = 0; 7212 } 7213 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7214 } 7215 bwn_dummy_transmission(mac, 0, 1); 7216 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7217 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7218 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7219 else 7220 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7221 &old_rfatt, old_txctl); 7222 } 7223 bwn_hwpctl_init_gphy(mac); 7224 7225 /* clear TSSI */ 7226 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7227 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7228 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7229 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7230 } 7231 7232 static void 7233 bwn_hwpctl_early_init(struct bwn_mac *mac) 7234 { 7235 struct bwn_phy *phy = &mac->mac_phy; 7236 7237 if (!bwn_has_hwpctl(mac)) { 7238 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7239 return; 7240 } 7241 7242 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7243 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7244 BWN_PHY_SET(mac, 0x047c, 0x0002); 7245 BWN_PHY_SET(mac, 0x047a, 0xf000); 7246 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7247 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7248 BWN_PHY_SET(mac, 0x005d, 0x8000); 7249 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7250 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7251 BWN_PHY_SET(mac, 0x0036, 0x0400); 7252 } else { 7253 BWN_PHY_SET(mac, 0x0036, 0x0200); 7254 BWN_PHY_SET(mac, 0x0036, 0x0400); 7255 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7256 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7257 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7258 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7259 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7260 } 7261 } 7262 7263 static void 7264 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7265 { 7266 struct bwn_phy *phy = &mac->mac_phy; 7267 struct bwn_phy_g *pg = &phy->phy_g; 7268 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7269 int i; 7270 uint16_t nr_written = 0, tmp, value; 7271 uint8_t rf, bb; 7272 7273 if (!bwn_has_hwpctl(mac)) { 7274 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7275 return; 7276 } 7277 7278 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7279 (pg->pg_idletssi - pg->pg_curtssi)); 7280 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7281 (pg->pg_idletssi - pg->pg_curtssi)); 7282 7283 for (i = 0; i < 32; i++) 7284 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7285 for (i = 32; i < 64; i++) 7286 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7287 for (i = 0; i < 64; i += 2) { 7288 value = (uint16_t) pg->pg_tssi2dbm[i]; 7289 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7290 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7291 } 7292 7293 for (rf = 0; rf < lo->rfatt.len; rf++) { 7294 for (bb = 0; bb < lo->bbatt.len; bb++) { 7295 if (nr_written >= 0x40) 7296 return; 7297 tmp = lo->bbatt.array[bb].att; 7298 tmp <<= 8; 7299 if (phy->rf_rev == 8) 7300 tmp |= 0x50; 7301 else 7302 tmp |= 0x40; 7303 tmp |= lo->rfatt.array[rf].att; 7304 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7305 nr_written++; 7306 } 7307 } 7308 7309 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7310 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7311 7312 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7313 BWN_PHY_SET(mac, 0x0478, 0x0800); 7314 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7315 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7316 7317 bwn_phy_g_dc_lookup_init(mac, 1); 7318 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7319 } 7320 7321 static void 7322 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7323 { 7324 struct bwn_softc *sc = mac->mac_sc; 7325 7326 if (spu != 0) 7327 bwn_spu_workaround(mac, channel); 7328 7329 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7330 7331 if (channel == 14) { 7332 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7333 bwn_hf_write(mac, 7334 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7335 else 7336 bwn_hf_write(mac, 7337 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7338 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7339 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7340 return; 7341 } 7342 7343 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7344 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7345 } 7346 7347 static uint16_t 7348 bwn_phy_g_chan2freq(uint8_t channel) 7349 { 7350 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7351 7352 KASSERT(channel >= 1 && channel <= 14, 7353 ("%s:%d: fail", __func__, __LINE__)); 7354 7355 return (bwn_phy_g_rf_channels[channel - 1]); 7356 } 7357 7358 static void 7359 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7360 const struct bwn_rfatt *rfatt, uint8_t txctl) 7361 { 7362 struct bwn_phy *phy = &mac->mac_phy; 7363 struct bwn_phy_g *pg = &phy->phy_g; 7364 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7365 uint16_t bb, rf; 7366 uint16_t tx_bias, tx_magn; 7367 7368 bb = bbatt->att; 7369 rf = rfatt->att; 7370 tx_bias = lo->tx_bias; 7371 tx_magn = lo->tx_magn; 7372 if (tx_bias == 0xff) 7373 tx_bias = 0; 7374 7375 pg->pg_txctl = txctl; 7376 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7377 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7378 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7379 bwn_phy_g_set_bbatt(mac, bb); 7380 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7381 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7382 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7383 else { 7384 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7385 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7386 } 7387 if (BWN_HAS_TXMAG(phy)) 7388 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7389 else 7390 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7391 bwn_lo_g_adjust(mac); 7392 } 7393 7394 static void 7395 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7396 uint16_t bbatt) 7397 { 7398 struct bwn_phy *phy = &mac->mac_phy; 7399 7400 if (phy->analog == 0) { 7401 BWN_WRITE_2(mac, BWN_PHY0, 7402 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7403 return; 7404 } 7405 if (phy->analog > 1) { 7406 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7407 return; 7408 } 7409 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7410 } 7411 7412 static uint16_t 7413 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7414 { 7415 struct bwn_phy *phy = &mac->mac_phy; 7416 struct bwn_phy_g *pg = &phy->phy_g; 7417 struct bwn_softc *sc = mac->mac_sc; 7418 int max_lb_gain; 7419 uint16_t extlna; 7420 uint16_t i; 7421 7422 if (phy->gmode == 0) 7423 return (0); 7424 7425 if (BWN_HAS_LOOPBACK(phy)) { 7426 max_lb_gain = pg->pg_max_lb_gain; 7427 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7428 if (max_lb_gain >= 0x46) { 7429 extlna = 0x3000; 7430 max_lb_gain -= 0x46; 7431 } else if (max_lb_gain >= 0x3a) { 7432 extlna = 0x1000; 7433 max_lb_gain -= 0x3a; 7434 } else if (max_lb_gain >= 0x2e) { 7435 extlna = 0x2000; 7436 max_lb_gain -= 0x2e; 7437 } else { 7438 extlna = 0; 7439 max_lb_gain -= 0x10; 7440 } 7441 7442 for (i = 0; i < 16; i++) { 7443 max_lb_gain -= (i * 6); 7444 if (max_lb_gain < 6) 7445 break; 7446 } 7447 7448 if ((phy->rev < 7) || 7449 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7450 if (reg == BWN_PHY_RFOVER) { 7451 return (0x1b3); 7452 } else if (reg == BWN_PHY_RFOVERVAL) { 7453 extlna |= (i << 8); 7454 switch (lpd) { 7455 case BWN_LPD(0, 1, 1): 7456 return (0x0f92); 7457 case BWN_LPD(0, 0, 1): 7458 case BWN_LPD(1, 0, 1): 7459 return (0x0092 | extlna); 7460 case BWN_LPD(1, 0, 0): 7461 return (0x0093 | extlna); 7462 } 7463 KASSERT(0 == 1, 7464 ("%s:%d: fail", __func__, __LINE__)); 7465 } 7466 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7467 } else { 7468 if (reg == BWN_PHY_RFOVER) 7469 return (0x9b3); 7470 if (reg == BWN_PHY_RFOVERVAL) { 7471 if (extlna) 7472 extlna |= 0x8000; 7473 extlna |= (i << 8); 7474 switch (lpd) { 7475 case BWN_LPD(0, 1, 1): 7476 return (0x8f92); 7477 case BWN_LPD(0, 0, 1): 7478 return (0x8092 | extlna); 7479 case BWN_LPD(1, 0, 1): 7480 return (0x2092 | extlna); 7481 case BWN_LPD(1, 0, 0): 7482 return (0x2093 | extlna); 7483 } 7484 KASSERT(0 == 1, 7485 ("%s:%d: fail", __func__, __LINE__)); 7486 } 7487 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7488 } 7489 return (0); 7490 } 7491 7492 if ((phy->rev < 7) || 7493 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7494 if (reg == BWN_PHY_RFOVER) { 7495 return (0x1b3); 7496 } else if (reg == BWN_PHY_RFOVERVAL) { 7497 switch (lpd) { 7498 case BWN_LPD(0, 1, 1): 7499 return (0x0fb2); 7500 case BWN_LPD(0, 0, 1): 7501 return (0x00b2); 7502 case BWN_LPD(1, 0, 1): 7503 return (0x30b2); 7504 case BWN_LPD(1, 0, 0): 7505 return (0x30b3); 7506 } 7507 KASSERT(0 == 1, 7508 ("%s:%d: fail", __func__, __LINE__)); 7509 } 7510 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7511 } else { 7512 if (reg == BWN_PHY_RFOVER) { 7513 return (0x9b3); 7514 } else if (reg == BWN_PHY_RFOVERVAL) { 7515 switch (lpd) { 7516 case BWN_LPD(0, 1, 1): 7517 return (0x8fb2); 7518 case BWN_LPD(0, 0, 1): 7519 return (0x80b2); 7520 case BWN_LPD(1, 0, 1): 7521 return (0x20b2); 7522 case BWN_LPD(1, 0, 0): 7523 return (0x20b3); 7524 } 7525 KASSERT(0 == 1, 7526 ("%s:%d: fail", __func__, __LINE__)); 7527 } 7528 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7529 } 7530 return (0); 7531 } 7532 7533 static void 7534 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7535 { 7536 7537 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7538 return; 7539 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7540 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7541 DELAY(1000); 7542 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7543 } 7544 7545 static int 7546 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7547 { 7548 struct bwn_softc *sc = mac->mac_sc; 7549 struct bwn_fw *fw = &mac->mac_fw; 7550 const uint8_t rev = siba_get_revid(sc->sc_dev); 7551 const char *filename; 7552 uint32_t high; 7553 int error; 7554 7555 /* microcode */ 7556 if (rev >= 5 && rev <= 10) 7557 filename = "ucode5"; 7558 else if (rev >= 11 && rev <= 12) 7559 filename = "ucode11"; 7560 else if (rev == 13) 7561 filename = "ucode13"; 7562 else if (rev == 14) 7563 filename = "ucode14"; 7564 else if (rev >= 15) 7565 filename = "ucode15"; 7566 else { 7567 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7568 bwn_release_firmware(mac); 7569 return (EOPNOTSUPP); 7570 } 7571 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7572 if (error) { 7573 bwn_release_firmware(mac); 7574 return (error); 7575 } 7576 7577 /* PCM */ 7578 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7579 if (rev >= 5 && rev <= 10) { 7580 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7581 if (error == ENOENT) 7582 fw->no_pcmfile = 1; 7583 else if (error) { 7584 bwn_release_firmware(mac); 7585 return (error); 7586 } 7587 } else if (rev < 11) { 7588 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7589 return (EOPNOTSUPP); 7590 } 7591 7592 /* initvals */ 7593 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7594 switch (mac->mac_phy.type) { 7595 case BWN_PHYTYPE_A: 7596 if (rev < 5 || rev > 10) 7597 goto fail1; 7598 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7599 filename = "a0g1initvals5"; 7600 else 7601 filename = "a0g0initvals5"; 7602 break; 7603 case BWN_PHYTYPE_G: 7604 if (rev >= 5 && rev <= 10) 7605 filename = "b0g0initvals5"; 7606 else if (rev >= 13) 7607 filename = "b0g0initvals13"; 7608 else 7609 goto fail1; 7610 break; 7611 case BWN_PHYTYPE_LP: 7612 if (rev == 13) 7613 filename = "lp0initvals13"; 7614 else if (rev == 14) 7615 filename = "lp0initvals14"; 7616 else if (rev >= 15) 7617 filename = "lp0initvals15"; 7618 else 7619 goto fail1; 7620 break; 7621 case BWN_PHYTYPE_N: 7622 if (rev >= 11 && rev <= 12) 7623 filename = "n0initvals11"; 7624 else 7625 goto fail1; 7626 break; 7627 default: 7628 goto fail1; 7629 } 7630 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7631 if (error) { 7632 bwn_release_firmware(mac); 7633 return (error); 7634 } 7635 7636 /* bandswitch initvals */ 7637 switch (mac->mac_phy.type) { 7638 case BWN_PHYTYPE_A: 7639 if (rev >= 5 && rev <= 10) { 7640 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7641 filename = "a0g1bsinitvals5"; 7642 else 7643 filename = "a0g0bsinitvals5"; 7644 } else if (rev >= 11) 7645 filename = NULL; 7646 else 7647 goto fail1; 7648 break; 7649 case BWN_PHYTYPE_G: 7650 if (rev >= 5 && rev <= 10) 7651 filename = "b0g0bsinitvals5"; 7652 else if (rev >= 11) 7653 filename = NULL; 7654 else 7655 goto fail1; 7656 break; 7657 case BWN_PHYTYPE_LP: 7658 if (rev == 13) 7659 filename = "lp0bsinitvals13"; 7660 else if (rev == 14) 7661 filename = "lp0bsinitvals14"; 7662 else if (rev >= 15) 7663 filename = "lp0bsinitvals15"; 7664 else 7665 goto fail1; 7666 break; 7667 case BWN_PHYTYPE_N: 7668 if (rev >= 11 && rev <= 12) 7669 filename = "n0bsinitvals11"; 7670 else 7671 goto fail1; 7672 break; 7673 default: 7674 goto fail1; 7675 } 7676 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7677 if (error) { 7678 bwn_release_firmware(mac); 7679 return (error); 7680 } 7681 return (0); 7682 fail1: 7683 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7684 bwn_release_firmware(mac); 7685 return (EOPNOTSUPP); 7686 } 7687 7688 static int 7689 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7690 const char *name, struct bwn_fwfile *bfw) 7691 { 7692 const struct bwn_fwhdr *hdr; 7693 struct bwn_softc *sc = mac->mac_sc; 7694 const struct firmware *fw; 7695 char namebuf[64]; 7696 7697 if (name == NULL) { 7698 bwn_do_release_fw(bfw); 7699 return (0); 7700 } 7701 if (bfw->filename != NULL) { 7702 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7703 return (0); 7704 bwn_do_release_fw(bfw); 7705 } 7706 7707 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7708 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7709 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7710 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7711 fw = firmware_get(namebuf); 7712 if (fw == NULL) { 7713 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7714 namebuf); 7715 return (ENOENT); 7716 } 7717 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7718 goto fail; 7719 hdr = (const struct bwn_fwhdr *)(fw->data); 7720 switch (hdr->type) { 7721 case BWN_FWTYPE_UCODE: 7722 case BWN_FWTYPE_PCM: 7723 if (be32toh(hdr->size) != 7724 (fw->datasize - sizeof(struct bwn_fwhdr))) 7725 goto fail; 7726 /* FALLTHROUGH */ 7727 case BWN_FWTYPE_IV: 7728 if (hdr->ver != 1) 7729 goto fail; 7730 break; 7731 default: 7732 goto fail; 7733 } 7734 bfw->filename = name; 7735 bfw->fw = fw; 7736 bfw->type = type; 7737 return (0); 7738 fail: 7739 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7740 if (fw != NULL) 7741 firmware_put(fw, FIRMWARE_UNLOAD); 7742 return (EPROTO); 7743 } 7744 7745 static void 7746 bwn_release_firmware(struct bwn_mac *mac) 7747 { 7748 7749 bwn_do_release_fw(&mac->mac_fw.ucode); 7750 bwn_do_release_fw(&mac->mac_fw.pcm); 7751 bwn_do_release_fw(&mac->mac_fw.initvals); 7752 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7753 } 7754 7755 static void 7756 bwn_do_release_fw(struct bwn_fwfile *bfw) 7757 { 7758 7759 if (bfw->fw != NULL) 7760 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7761 bfw->fw = NULL; 7762 bfw->filename = NULL; 7763 } 7764 7765 static int 7766 bwn_fw_loaducode(struct bwn_mac *mac) 7767 { 7768 #define GETFWOFFSET(fwp, offset) \ 7769 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7770 #define GETFWSIZE(fwp, offset) \ 7771 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7772 struct bwn_softc *sc = mac->mac_sc; 7773 const uint32_t *data; 7774 unsigned int i; 7775 uint32_t ctl; 7776 uint16_t date, fwcaps, time; 7777 int error = 0; 7778 7779 ctl = BWN_READ_4(mac, BWN_MACCTL); 7780 ctl |= BWN_MACCTL_MCODE_JMP0; 7781 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7782 __LINE__)); 7783 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7784 for (i = 0; i < 64; i++) 7785 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7786 for (i = 0; i < 4096; i += 2) 7787 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7788 7789 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7790 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7791 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7792 i++) { 7793 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7794 DELAY(10); 7795 } 7796 7797 if (mac->mac_fw.pcm.fw) { 7798 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7799 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7800 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7801 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7802 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7803 sizeof(struct bwn_fwhdr)); i++) { 7804 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7805 DELAY(10); 7806 } 7807 } 7808 7809 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7810 BWN_WRITE_4(mac, BWN_MACCTL, 7811 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7812 BWN_MACCTL_MCODE_RUN); 7813 7814 for (i = 0; i < 21; i++) { 7815 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7816 break; 7817 if (i >= 20) { 7818 device_printf(sc->sc_dev, "ucode timeout\n"); 7819 error = ENXIO; 7820 goto error; 7821 } 7822 DELAY(50000); 7823 } 7824 BWN_READ_4(mac, BWN_INTR_REASON); 7825 7826 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7827 if (mac->mac_fw.rev <= 0x128) { 7828 device_printf(sc->sc_dev, "the firmware is too old\n"); 7829 error = EOPNOTSUPP; 7830 goto error; 7831 } 7832 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7833 BWN_SHARED_UCODE_PATCH); 7834 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7835 mac->mac_fw.opensource = (date == 0xffff); 7836 if (bwn_wme != 0) 7837 mac->mac_flags |= BWN_MAC_FLAG_WME; 7838 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7839 7840 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7841 if (mac->mac_fw.opensource == 0) { 7842 device_printf(sc->sc_dev, 7843 "firmware version (rev %u patch %u date %#x time %#x)\n", 7844 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7845 if (mac->mac_fw.no_pcmfile) 7846 device_printf(sc->sc_dev, 7847 "no HW crypto acceleration due to pcm5\n"); 7848 } else { 7849 mac->mac_fw.patch = time; 7850 fwcaps = bwn_fwcaps_read(mac); 7851 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7852 device_printf(sc->sc_dev, 7853 "disabling HW crypto acceleration\n"); 7854 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7855 } 7856 if (!(fwcaps & BWN_FWCAPS_WME)) { 7857 device_printf(sc->sc_dev, "disabling WME support\n"); 7858 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7859 } 7860 } 7861 7862 if (BWN_ISOLDFMT(mac)) 7863 device_printf(sc->sc_dev, "using old firmware image\n"); 7864 7865 return (0); 7866 7867 error: 7868 BWN_WRITE_4(mac, BWN_MACCTL, 7869 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7870 BWN_MACCTL_MCODE_JMP0); 7871 7872 return (error); 7873 #undef GETFWSIZE 7874 #undef GETFWOFFSET 7875 } 7876 7877 /* OpenFirmware only */ 7878 static uint16_t 7879 bwn_fwcaps_read(struct bwn_mac *mac) 7880 { 7881 7882 KASSERT(mac->mac_fw.opensource == 1, 7883 ("%s:%d: fail", __func__, __LINE__)); 7884 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7885 } 7886 7887 static int 7888 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7889 size_t count, size_t array_size) 7890 { 7891 #define GET_NEXTIV16(iv) \ 7892 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7893 sizeof(uint16_t) + sizeof(uint16_t))) 7894 #define GET_NEXTIV32(iv) \ 7895 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7896 sizeof(uint16_t) + sizeof(uint32_t))) 7897 struct bwn_softc *sc = mac->mac_sc; 7898 const struct bwn_fwinitvals *iv; 7899 uint16_t offset; 7900 size_t i; 7901 uint8_t bit32; 7902 7903 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7904 ("%s:%d: fail", __func__, __LINE__)); 7905 iv = ivals; 7906 for (i = 0; i < count; i++) { 7907 if (array_size < sizeof(iv->offset_size)) 7908 goto fail; 7909 array_size -= sizeof(iv->offset_size); 7910 offset = be16toh(iv->offset_size); 7911 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7912 offset &= BWN_FWINITVALS_OFFSET_MASK; 7913 if (offset >= 0x1000) 7914 goto fail; 7915 if (bit32) { 7916 if (array_size < sizeof(iv->data.d32)) 7917 goto fail; 7918 array_size -= sizeof(iv->data.d32); 7919 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7920 iv = GET_NEXTIV32(iv); 7921 } else { 7922 7923 if (array_size < sizeof(iv->data.d16)) 7924 goto fail; 7925 array_size -= sizeof(iv->data.d16); 7926 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7927 7928 iv = GET_NEXTIV16(iv); 7929 } 7930 } 7931 if (array_size != 0) 7932 goto fail; 7933 return (0); 7934 fail: 7935 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7936 return (EPROTO); 7937 #undef GET_NEXTIV16 7938 #undef GET_NEXTIV32 7939 } 7940 7941 static int 7942 bwn_switch_channel(struct bwn_mac *mac, int chan) 7943 { 7944 struct bwn_phy *phy = &(mac->mac_phy); 7945 struct bwn_softc *sc = mac->mac_sc; 7946 struct ifnet *ifp = sc->sc_ifp; 7947 struct ieee80211com *ic = ifp->if_l2com; 7948 uint16_t channelcookie, savedcookie; 7949 int error; 7950 7951 if (chan == 0xffff) 7952 chan = phy->get_default_chan(mac); 7953 7954 channelcookie = chan; 7955 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7956 channelcookie |= 0x100; 7957 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7958 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7959 error = phy->switch_channel(mac, chan); 7960 if (error) 7961 goto fail; 7962 7963 mac->mac_phy.chan = chan; 7964 DELAY(8000); 7965 return (0); 7966 fail: 7967 device_printf(sc->sc_dev, "failed to switch channel\n"); 7968 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7969 return (error); 7970 } 7971 7972 static uint16_t 7973 bwn_ant2phy(int antenna) 7974 { 7975 7976 switch (antenna) { 7977 case BWN_ANT0: 7978 return (BWN_TX_PHY_ANT0); 7979 case BWN_ANT1: 7980 return (BWN_TX_PHY_ANT1); 7981 case BWN_ANT2: 7982 return (BWN_TX_PHY_ANT2); 7983 case BWN_ANT3: 7984 return (BWN_TX_PHY_ANT3); 7985 case BWN_ANTAUTO: 7986 return (BWN_TX_PHY_ANT01AUTO); 7987 } 7988 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7989 return (0); 7990 } 7991 7992 static void 7993 bwn_wme_load(struct bwn_mac *mac) 7994 { 7995 struct bwn_softc *sc = mac->mac_sc; 7996 int i; 7997 7998 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7999 ("%s:%d: fail", __func__, __LINE__)); 8000 8001 bwn_mac_suspend(mac); 8002 for (i = 0; i < N(sc->sc_wmeParams); i++) 8003 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8004 bwn_wme_shm_offsets[i]); 8005 bwn_mac_enable(mac); 8006 } 8007 8008 static void 8009 bwn_wme_loadparams(struct bwn_mac *mac, 8010 const struct wmeParams *p, uint16_t shm_offset) 8011 { 8012 #define SM(_v, _f) (((_v) << _f##_S) & _f) 8013 struct bwn_softc *sc = mac->mac_sc; 8014 uint16_t params[BWN_NR_WMEPARAMS]; 8015 int slot, tmp; 8016 unsigned int i; 8017 8018 slot = BWN_READ_2(mac, BWN_RNG) & 8019 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8020 8021 memset(¶ms, 0, sizeof(params)); 8022 8023 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8024 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8025 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8026 8027 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8028 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8029 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8030 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8031 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8032 params[BWN_WMEPARAM_BSLOTS] = slot; 8033 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8034 8035 for (i = 0; i < N(params); i++) { 8036 if (i == BWN_WMEPARAM_STATUS) { 8037 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8038 shm_offset + (i * 2)); 8039 tmp |= 0x100; 8040 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8041 tmp); 8042 } else { 8043 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8044 params[i]); 8045 } 8046 } 8047 } 8048 8049 static void 8050 bwn_mac_write_bssid(struct bwn_mac *mac) 8051 { 8052 struct bwn_softc *sc = mac->mac_sc; 8053 uint32_t tmp; 8054 int i; 8055 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8056 8057 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8058 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8059 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8060 IEEE80211_ADDR_LEN); 8061 8062 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8063 tmp = (uint32_t) (mac_bssid[i + 0]); 8064 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8065 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8066 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8067 bwn_ram_write(mac, 0x20 + i, tmp); 8068 } 8069 } 8070 8071 static void 8072 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8073 const uint8_t *macaddr) 8074 { 8075 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8076 uint16_t data; 8077 8078 if (!mac) 8079 macaddr = zero; 8080 8081 offset |= 0x0020; 8082 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8083 8084 data = macaddr[0]; 8085 data |= macaddr[1] << 8; 8086 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8087 data = macaddr[2]; 8088 data |= macaddr[3] << 8; 8089 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8090 data = macaddr[4]; 8091 data |= macaddr[5] << 8; 8092 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8093 } 8094 8095 static void 8096 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8097 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8098 { 8099 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8100 uint8_t per_sta_keys_start = 8; 8101 8102 if (BWN_SEC_NEWAPI(mac)) 8103 per_sta_keys_start = 4; 8104 8105 KASSERT(index < mac->mac_max_nr_keys, 8106 ("%s:%d: fail", __func__, __LINE__)); 8107 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8108 ("%s:%d: fail", __func__, __LINE__)); 8109 8110 if (index >= per_sta_keys_start) 8111 bwn_key_macwrite(mac, index, NULL); 8112 if (key) 8113 memcpy(buf, key, key_len); 8114 bwn_key_write(mac, index, algorithm, buf); 8115 if (index >= per_sta_keys_start) 8116 bwn_key_macwrite(mac, index, mac_addr); 8117 8118 mac->mac_key[index].algorithm = algorithm; 8119 } 8120 8121 static void 8122 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8123 { 8124 struct bwn_softc *sc = mac->mac_sc; 8125 uint32_t addrtmp[2] = { 0, 0 }; 8126 uint8_t start = 8; 8127 8128 if (BWN_SEC_NEWAPI(mac)) 8129 start = 4; 8130 8131 KASSERT(index >= start, 8132 ("%s:%d: fail", __func__, __LINE__)); 8133 index -= start; 8134 8135 if (addr) { 8136 addrtmp[0] = addr[0]; 8137 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8138 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8139 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8140 addrtmp[1] = addr[4]; 8141 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8142 } 8143 8144 if (siba_get_revid(sc->sc_dev) >= 5) { 8145 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8146 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8147 } else { 8148 if (index >= 8) { 8149 bwn_shm_write_4(mac, BWN_SHARED, 8150 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8151 bwn_shm_write_2(mac, BWN_SHARED, 8152 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8153 } 8154 } 8155 } 8156 8157 static void 8158 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8159 const uint8_t *key) 8160 { 8161 unsigned int i; 8162 uint32_t offset; 8163 uint16_t kidx, value; 8164 8165 kidx = BWN_SEC_KEY2FW(mac, index); 8166 bwn_shm_write_2(mac, BWN_SHARED, 8167 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8168 8169 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8170 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8171 value = key[i]; 8172 value |= (uint16_t)(key[i + 1]) << 8; 8173 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8174 } 8175 } 8176 8177 static void 8178 bwn_phy_exit(struct bwn_mac *mac) 8179 { 8180 8181 mac->mac_phy.rf_onoff(mac, 0); 8182 if (mac->mac_phy.exit != NULL) 8183 mac->mac_phy.exit(mac); 8184 } 8185 8186 static void 8187 bwn_dma_free(struct bwn_mac *mac) 8188 { 8189 struct bwn_dma *dma; 8190 8191 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8192 return; 8193 dma = &mac->mac_method.dma; 8194 8195 bwn_dma_ringfree(&dma->rx); 8196 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8197 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8198 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8199 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8200 bwn_dma_ringfree(&dma->mcast); 8201 } 8202 8203 static void 8204 bwn_core_stop(struct bwn_mac *mac) 8205 { 8206 struct bwn_softc *sc = mac->mac_sc; 8207 8208 BWN_ASSERT_LOCKED(sc); 8209 8210 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8211 return; 8212 8213 callout_stop(&sc->sc_rfswitch_ch); 8214 callout_stop(&sc->sc_task_ch); 8215 callout_stop(&sc->sc_watchdog_ch); 8216 sc->sc_watchdog_timer = 0; 8217 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8218 BWN_READ_4(mac, BWN_INTR_MASK); 8219 bwn_mac_suspend(mac); 8220 8221 mac->mac_status = BWN_MAC_STATUS_INITED; 8222 } 8223 8224 static int 8225 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8226 { 8227 struct bwn_mac *up_dev = NULL; 8228 struct bwn_mac *down_dev; 8229 struct bwn_mac *mac; 8230 int err, status; 8231 uint8_t gmode; 8232 8233 BWN_ASSERT_LOCKED(sc); 8234 8235 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8236 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8237 mac->mac_phy.supports_2ghz) { 8238 up_dev = mac; 8239 gmode = 1; 8240 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8241 mac->mac_phy.supports_5ghz) { 8242 up_dev = mac; 8243 gmode = 0; 8244 } else { 8245 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8246 return (EINVAL); 8247 } 8248 if (up_dev != NULL) 8249 break; 8250 } 8251 if (up_dev == NULL) { 8252 device_printf(sc->sc_dev, "Could not find a device\n"); 8253 return (ENODEV); 8254 } 8255 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8256 return (0); 8257 8258 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8259 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8260 8261 down_dev = sc->sc_curmac; 8262 status = down_dev->mac_status; 8263 if (status >= BWN_MAC_STATUS_STARTED) 8264 bwn_core_stop(down_dev); 8265 if (status >= BWN_MAC_STATUS_INITED) 8266 bwn_core_exit(down_dev); 8267 8268 if (down_dev != up_dev) 8269 bwn_phy_reset(down_dev); 8270 8271 up_dev->mac_phy.gmode = gmode; 8272 if (status >= BWN_MAC_STATUS_INITED) { 8273 err = bwn_core_init(up_dev); 8274 if (err) { 8275 device_printf(sc->sc_dev, 8276 "fatal: failed to initialize for %s-GHz\n", 8277 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8278 goto fail; 8279 } 8280 } 8281 if (status >= BWN_MAC_STATUS_STARTED) 8282 bwn_core_start(up_dev); 8283 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8284 sc->sc_curmac = up_dev; 8285 8286 return (0); 8287 fail: 8288 sc->sc_curmac = NULL; 8289 return (err); 8290 } 8291 8292 static void 8293 bwn_rf_turnon(struct bwn_mac *mac) 8294 { 8295 8296 bwn_mac_suspend(mac); 8297 mac->mac_phy.rf_onoff(mac, 1); 8298 mac->mac_phy.rf_on = 1; 8299 bwn_mac_enable(mac); 8300 } 8301 8302 static void 8303 bwn_rf_turnoff(struct bwn_mac *mac) 8304 { 8305 8306 bwn_mac_suspend(mac); 8307 mac->mac_phy.rf_onoff(mac, 0); 8308 mac->mac_phy.rf_on = 0; 8309 bwn_mac_enable(mac); 8310 } 8311 8312 static void 8313 bwn_phy_reset(struct bwn_mac *mac) 8314 { 8315 struct bwn_softc *sc = mac->mac_sc; 8316 8317 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8318 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8319 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8320 DELAY(1000); 8321 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8322 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8323 BWN_TGSLOW_PHYRESET); 8324 DELAY(1000); 8325 } 8326 8327 static int 8328 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8329 { 8330 struct bwn_vap *bvp = BWN_VAP(vap); 8331 struct ieee80211com *ic= vap->iv_ic; 8332 struct ifnet *ifp = ic->ic_ifp; 8333 enum ieee80211_state ostate = vap->iv_state; 8334 struct bwn_softc *sc = ifp->if_softc; 8335 struct bwn_mac *mac = sc->sc_curmac; 8336 int error; 8337 8338 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8339 ieee80211_state_name[vap->iv_state], 8340 ieee80211_state_name[nstate]); 8341 8342 error = bvp->bv_newstate(vap, nstate, arg); 8343 if (error != 0) 8344 return (error); 8345 8346 BWN_LOCK(sc); 8347 8348 bwn_led_newstate(mac, nstate); 8349 8350 /* 8351 * Clear the BSSID when we stop a STA 8352 */ 8353 if (vap->iv_opmode == IEEE80211_M_STA) { 8354 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8355 /* 8356 * Clear out the BSSID. If we reassociate to 8357 * the same AP, this will reinialize things 8358 * correctly... 8359 */ 8360 if (ic->ic_opmode == IEEE80211_M_STA && 8361 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8362 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8363 bwn_set_macaddr(mac); 8364 } 8365 } 8366 } 8367 8368 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8369 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8370 /* XXX nothing to do? */ 8371 } else if (nstate == IEEE80211_S_RUN) { 8372 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8373 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8374 bwn_set_opmode(mac); 8375 bwn_set_pretbtt(mac); 8376 bwn_spu_setdelay(mac, 0); 8377 bwn_set_macaddr(mac); 8378 } 8379 8380 BWN_UNLOCK(sc); 8381 8382 return (error); 8383 } 8384 8385 static void 8386 bwn_set_pretbtt(struct bwn_mac *mac) 8387 { 8388 struct bwn_softc *sc = mac->mac_sc; 8389 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8390 uint16_t pretbtt; 8391 8392 if (ic->ic_opmode == IEEE80211_M_IBSS) 8393 pretbtt = 2; 8394 else 8395 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8396 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8397 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8398 } 8399 8400 static int 8401 bwn_intr(void *arg) 8402 { 8403 struct bwn_mac *mac = arg; 8404 struct bwn_softc *sc = mac->mac_sc; 8405 uint32_t reason; 8406 8407 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8408 (sc->sc_flags & BWN_FLAG_INVALID)) 8409 return (FILTER_STRAY); 8410 8411 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8412 if (reason == 0xffffffff) /* shared IRQ */ 8413 return (FILTER_STRAY); 8414 reason &= mac->mac_intr_mask; 8415 if (reason == 0) 8416 return (FILTER_HANDLED); 8417 8418 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8419 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8420 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8421 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8422 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8423 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8424 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8425 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8426 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8427 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8428 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8429 8430 /* Disable interrupts. */ 8431 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8432 8433 mac->mac_reason_intr = reason; 8434 8435 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8436 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8437 8438 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8439 return (FILTER_HANDLED); 8440 } 8441 8442 static void 8443 bwn_intrtask(void *arg, int npending) 8444 { 8445 struct bwn_mac *mac = arg; 8446 struct bwn_softc *sc = mac->mac_sc; 8447 struct ifnet *ifp = sc->sc_ifp; 8448 uint32_t merged = 0; 8449 int i, tx = 0, rx = 0; 8450 8451 BWN_LOCK(sc); 8452 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8453 (sc->sc_flags & BWN_FLAG_INVALID)) { 8454 BWN_UNLOCK(sc); 8455 return; 8456 } 8457 8458 for (i = 0; i < N(mac->mac_reason); i++) 8459 merged |= mac->mac_reason[i]; 8460 8461 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8462 device_printf(sc->sc_dev, "MAC trans error\n"); 8463 8464 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8465 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8466 mac->mac_phy.txerrors--; 8467 if (mac->mac_phy.txerrors == 0) { 8468 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8469 bwn_restart(mac, "PHY TX errors"); 8470 } 8471 } 8472 8473 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8474 if (merged & BWN_DMAINTR_FATALMASK) { 8475 device_printf(sc->sc_dev, 8476 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8477 mac->mac_reason[0], mac->mac_reason[1], 8478 mac->mac_reason[2], mac->mac_reason[3], 8479 mac->mac_reason[4], mac->mac_reason[5]); 8480 bwn_restart(mac, "DMA error"); 8481 BWN_UNLOCK(sc); 8482 return; 8483 } 8484 if (merged & BWN_DMAINTR_NONFATALMASK) { 8485 device_printf(sc->sc_dev, 8486 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8487 mac->mac_reason[0], mac->mac_reason[1], 8488 mac->mac_reason[2], mac->mac_reason[3], 8489 mac->mac_reason[4], mac->mac_reason[5]); 8490 } 8491 } 8492 8493 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8494 bwn_intr_ucode_debug(mac); 8495 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8496 bwn_intr_tbtt_indication(mac); 8497 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8498 bwn_intr_atim_end(mac); 8499 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8500 bwn_intr_beacon(mac); 8501 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8502 bwn_intr_pmq(mac); 8503 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8504 bwn_intr_noise(mac); 8505 8506 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8507 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8508 bwn_dma_rx(mac->mac_method.dma.rx); 8509 rx = 1; 8510 } 8511 } else 8512 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8513 8514 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8515 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8516 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8517 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8518 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8519 8520 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8521 bwn_intr_txeof(mac); 8522 tx = 1; 8523 } 8524 8525 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8526 8527 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8528 int evt = BWN_LED_EVENT_NONE; 8529 8530 if (tx && rx) { 8531 if (sc->sc_rx_rate > sc->sc_tx_rate) 8532 evt = BWN_LED_EVENT_RX; 8533 else 8534 evt = BWN_LED_EVENT_TX; 8535 } else if (tx) { 8536 evt = BWN_LED_EVENT_TX; 8537 } else if (rx) { 8538 evt = BWN_LED_EVENT_RX; 8539 } else if (rx == 0) { 8540 evt = BWN_LED_EVENT_POLL; 8541 } 8542 8543 if (evt != BWN_LED_EVENT_NONE) 8544 bwn_led_event(mac, evt); 8545 } 8546 8547 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8548 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8549 bwn_start_locked(ifp); 8550 } 8551 8552 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8553 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8554 8555 BWN_UNLOCK(sc); 8556 } 8557 8558 static void 8559 bwn_restart(struct bwn_mac *mac, const char *msg) 8560 { 8561 struct bwn_softc *sc = mac->mac_sc; 8562 struct ifnet *ifp = sc->sc_ifp; 8563 struct ieee80211com *ic = ifp->if_l2com; 8564 8565 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8566 return; 8567 8568 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8569 ieee80211_runtask(ic, &mac->mac_hwreset); 8570 } 8571 8572 static void 8573 bwn_intr_ucode_debug(struct bwn_mac *mac) 8574 { 8575 struct bwn_softc *sc = mac->mac_sc; 8576 uint16_t reason; 8577 8578 if (mac->mac_fw.opensource == 0) 8579 return; 8580 8581 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8582 switch (reason) { 8583 case BWN_DEBUGINTR_PANIC: 8584 bwn_handle_fwpanic(mac); 8585 break; 8586 case BWN_DEBUGINTR_DUMP_SHM: 8587 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8588 break; 8589 case BWN_DEBUGINTR_DUMP_REGS: 8590 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8591 break; 8592 case BWN_DEBUGINTR_MARKER: 8593 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8594 break; 8595 default: 8596 device_printf(sc->sc_dev, 8597 "ucode debug unknown reason: %#x\n", reason); 8598 } 8599 8600 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8601 BWN_DEBUGINTR_ACK); 8602 } 8603 8604 static void 8605 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8606 { 8607 struct bwn_softc *sc = mac->mac_sc; 8608 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8609 8610 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8611 bwn_psctl(mac, 0); 8612 if (ic->ic_opmode == IEEE80211_M_IBSS) 8613 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8614 } 8615 8616 static void 8617 bwn_intr_atim_end(struct bwn_mac *mac) 8618 { 8619 8620 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8621 BWN_WRITE_4(mac, BWN_MACCMD, 8622 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8623 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8624 } 8625 } 8626 8627 static void 8628 bwn_intr_beacon(struct bwn_mac *mac) 8629 { 8630 struct bwn_softc *sc = mac->mac_sc; 8631 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8632 uint32_t cmd, beacon0, beacon1; 8633 8634 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8635 ic->ic_opmode == IEEE80211_M_MBSS) 8636 return; 8637 8638 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8639 8640 cmd = BWN_READ_4(mac, BWN_MACCMD); 8641 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8642 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8643 8644 if (beacon0 && beacon1) { 8645 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8646 mac->mac_intr_mask |= BWN_INTR_BEACON; 8647 return; 8648 } 8649 8650 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8651 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8652 bwn_load_beacon0(mac); 8653 bwn_load_beacon1(mac); 8654 cmd = BWN_READ_4(mac, BWN_MACCMD); 8655 cmd |= BWN_MACCMD_BEACON0_VALID; 8656 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8657 } else { 8658 if (!beacon0) { 8659 bwn_load_beacon0(mac); 8660 cmd = BWN_READ_4(mac, BWN_MACCMD); 8661 cmd |= BWN_MACCMD_BEACON0_VALID; 8662 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8663 } else if (!beacon1) { 8664 bwn_load_beacon1(mac); 8665 cmd = BWN_READ_4(mac, BWN_MACCMD); 8666 cmd |= BWN_MACCMD_BEACON1_VALID; 8667 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8668 } 8669 } 8670 } 8671 8672 static void 8673 bwn_intr_pmq(struct bwn_mac *mac) 8674 { 8675 uint32_t tmp; 8676 8677 while (1) { 8678 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8679 if (!(tmp & 0x00000008)) 8680 break; 8681 } 8682 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8683 } 8684 8685 static void 8686 bwn_intr_noise(struct bwn_mac *mac) 8687 { 8688 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8689 uint16_t tmp; 8690 uint8_t noise[4]; 8691 uint8_t i, j; 8692 int32_t average; 8693 8694 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8695 return; 8696 8697 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8698 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8699 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8700 noise[3] == 0x7f) 8701 goto new; 8702 8703 KASSERT(mac->mac_noise.noi_nsamples < 8, 8704 ("%s:%d: fail", __func__, __LINE__)); 8705 i = mac->mac_noise.noi_nsamples; 8706 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8707 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8708 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8709 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8710 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8711 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8712 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8713 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8714 mac->mac_noise.noi_nsamples++; 8715 if (mac->mac_noise.noi_nsamples == 8) { 8716 average = 0; 8717 for (i = 0; i < 8; i++) { 8718 for (j = 0; j < 4; j++) 8719 average += mac->mac_noise.noi_samples[i][j]; 8720 } 8721 average = (((average / 32) * 125) + 64) / 128; 8722 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8723 if (tmp >= 8) 8724 average += 2; 8725 else 8726 average -= 25; 8727 average -= (tmp == 8) ? 72 : 48; 8728 8729 mac->mac_stats.link_noise = average; 8730 mac->mac_noise.noi_running = 0; 8731 return; 8732 } 8733 new: 8734 bwn_noise_gensample(mac); 8735 } 8736 8737 static int 8738 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8739 { 8740 struct bwn_mac *mac = prq->prq_mac; 8741 struct bwn_softc *sc = mac->mac_sc; 8742 unsigned int i; 8743 8744 BWN_ASSERT_LOCKED(sc); 8745 8746 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8747 return (0); 8748 8749 for (i = 0; i < 5000; i++) { 8750 if (bwn_pio_rxeof(prq) == 0) 8751 break; 8752 } 8753 if (i >= 5000) 8754 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8755 return ((i > 0) ? 1 : 0); 8756 } 8757 8758 static void 8759 bwn_dma_rx(struct bwn_dma_ring *dr) 8760 { 8761 int slot, curslot; 8762 8763 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8764 curslot = dr->get_curslot(dr); 8765 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8766 ("%s:%d: fail", __func__, __LINE__)); 8767 8768 slot = dr->dr_curslot; 8769 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8770 bwn_dma_rxeof(dr, &slot); 8771 8772 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8773 BUS_DMASYNC_PREWRITE); 8774 8775 dr->set_curslot(dr, slot); 8776 dr->dr_curslot = slot; 8777 } 8778 8779 static void 8780 bwn_intr_txeof(struct bwn_mac *mac) 8781 { 8782 struct bwn_txstatus stat; 8783 uint32_t stat0, stat1; 8784 uint16_t tmp; 8785 8786 BWN_ASSERT_LOCKED(mac->mac_sc); 8787 8788 while (1) { 8789 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8790 if (!(stat0 & 0x00000001)) 8791 break; 8792 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8793 8794 stat.cookie = (stat0 >> 16); 8795 stat.seq = (stat1 & 0x0000ffff); 8796 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8797 tmp = (stat0 & 0x0000ffff); 8798 stat.framecnt = ((tmp & 0xf000) >> 12); 8799 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8800 stat.sreason = ((tmp & 0x001c) >> 2); 8801 stat.pm = (tmp & 0x0080) ? 1 : 0; 8802 stat.im = (tmp & 0x0040) ? 1 : 0; 8803 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8804 stat.ack = (tmp & 0x0002) ? 1 : 0; 8805 8806 bwn_handle_txeof(mac, &stat); 8807 } 8808 } 8809 8810 static void 8811 bwn_hwreset(void *arg, int npending) 8812 { 8813 struct bwn_mac *mac = arg; 8814 struct bwn_softc *sc = mac->mac_sc; 8815 int error = 0; 8816 int prev_status; 8817 8818 BWN_LOCK(sc); 8819 8820 prev_status = mac->mac_status; 8821 if (prev_status >= BWN_MAC_STATUS_STARTED) 8822 bwn_core_stop(mac); 8823 if (prev_status >= BWN_MAC_STATUS_INITED) 8824 bwn_core_exit(mac); 8825 8826 if (prev_status >= BWN_MAC_STATUS_INITED) { 8827 error = bwn_core_init(mac); 8828 if (error) 8829 goto out; 8830 } 8831 if (prev_status >= BWN_MAC_STATUS_STARTED) 8832 bwn_core_start(mac); 8833 out: 8834 if (error) { 8835 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8836 sc->sc_curmac = NULL; 8837 } 8838 BWN_UNLOCK(sc); 8839 } 8840 8841 static void 8842 bwn_handle_fwpanic(struct bwn_mac *mac) 8843 { 8844 struct bwn_softc *sc = mac->mac_sc; 8845 uint16_t reason; 8846 8847 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8848 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8849 8850 if (reason == BWN_FWPANIC_RESTART) 8851 bwn_restart(mac, "ucode panic"); 8852 } 8853 8854 static void 8855 bwn_load_beacon0(struct bwn_mac *mac) 8856 { 8857 8858 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8859 } 8860 8861 static void 8862 bwn_load_beacon1(struct bwn_mac *mac) 8863 { 8864 8865 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8866 } 8867 8868 static uint32_t 8869 bwn_jssi_read(struct bwn_mac *mac) 8870 { 8871 uint32_t val = 0; 8872 8873 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8874 val <<= 16; 8875 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8876 8877 return (val); 8878 } 8879 8880 static void 8881 bwn_noise_gensample(struct bwn_mac *mac) 8882 { 8883 uint32_t jssi = 0x7f7f7f7f; 8884 8885 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8886 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8887 BWN_WRITE_4(mac, BWN_MACCMD, 8888 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8889 } 8890 8891 static int 8892 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8893 { 8894 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8895 8896 return (dr->dr_numslots - dr->dr_usedslot); 8897 } 8898 8899 static int 8900 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8901 { 8902 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8903 8904 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8905 ("%s:%d: fail", __func__, __LINE__)); 8906 if (slot == dr->dr_numslots - 1) 8907 return (0); 8908 return (slot + 1); 8909 } 8910 8911 static void 8912 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8913 { 8914 struct bwn_mac *mac = dr->dr_mac; 8915 struct bwn_softc *sc = mac->mac_sc; 8916 struct bwn_dma *dma = &mac->mac_method.dma; 8917 struct bwn_dmadesc_generic *desc; 8918 struct bwn_dmadesc_meta *meta; 8919 struct bwn_rxhdr4 *rxhdr; 8920 struct ifnet *ifp = sc->sc_ifp; 8921 struct mbuf *m; 8922 uint32_t macstat; 8923 int32_t tmp; 8924 int cnt = 0; 8925 uint16_t len; 8926 8927 dr->getdesc(dr, *slot, &desc, &meta); 8928 8929 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8930 m = meta->mt_m; 8931 8932 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8933 ifp->if_ierrors++; 8934 return; 8935 } 8936 8937 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8938 len = le16toh(rxhdr->frame_len); 8939 if (len <= 0) { 8940 ifp->if_ierrors++; 8941 return; 8942 } 8943 if (bwn_dma_check_redzone(dr, m)) { 8944 device_printf(sc->sc_dev, "redzone error.\n"); 8945 bwn_dma_set_redzone(dr, m); 8946 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8947 BUS_DMASYNC_PREWRITE); 8948 return; 8949 } 8950 if (len > dr->dr_rx_bufsize) { 8951 tmp = len; 8952 while (1) { 8953 dr->getdesc(dr, *slot, &desc, &meta); 8954 bwn_dma_set_redzone(dr, meta->mt_m); 8955 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8956 BUS_DMASYNC_PREWRITE); 8957 *slot = bwn_dma_nextslot(dr, *slot); 8958 cnt++; 8959 tmp -= dr->dr_rx_bufsize; 8960 if (tmp <= 0) 8961 break; 8962 } 8963 device_printf(sc->sc_dev, "too small buffer " 8964 "(len %u buffer %u dropped %d)\n", 8965 len, dr->dr_rx_bufsize, cnt); 8966 return; 8967 } 8968 macstat = le32toh(rxhdr->mac_status); 8969 if (macstat & BWN_RX_MAC_FCSERR) { 8970 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8971 device_printf(sc->sc_dev, "RX drop\n"); 8972 return; 8973 } 8974 } 8975 8976 m->m_pkthdr.rcvif = ifp; 8977 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8978 m_adj(m, dr->dr_frameoffset); 8979 8980 bwn_rxeof(dr->dr_mac, m, rxhdr); 8981 } 8982 8983 static void 8984 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8985 { 8986 struct bwn_dma_ring *dr; 8987 struct bwn_dmadesc_generic *desc; 8988 struct bwn_dmadesc_meta *meta; 8989 struct bwn_pio_txqueue *tq; 8990 struct bwn_pio_txpkt *tp = NULL; 8991 struct bwn_softc *sc = mac->mac_sc; 8992 struct bwn_stats *stats = &mac->mac_stats; 8993 struct ieee80211_node *ni; 8994 struct ieee80211vap *vap; 8995 int retrycnt = 0, slot; 8996 8997 BWN_ASSERT_LOCKED(mac->mac_sc); 8998 8999 if (status->im) 9000 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9001 if (status->ampdu) 9002 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9003 if (status->rtscnt) { 9004 if (status->rtscnt == 0xf) 9005 stats->rtsfail++; 9006 else 9007 stats->rts++; 9008 } 9009 9010 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9011 if (status->ack) { 9012 dr = bwn_dma_parse_cookie(mac, status, 9013 status->cookie, &slot); 9014 if (dr == NULL) { 9015 device_printf(sc->sc_dev, 9016 "failed to parse cookie\n"); 9017 return; 9018 } 9019 while (1) { 9020 dr->getdesc(dr, slot, &desc, &meta); 9021 if (meta->mt_islast) { 9022 ni = meta->mt_ni; 9023 vap = ni->ni_vap; 9024 ieee80211_ratectl_tx_complete(vap, ni, 9025 status->ack ? 9026 IEEE80211_RATECTL_TX_SUCCESS : 9027 IEEE80211_RATECTL_TX_FAILURE, 9028 &retrycnt, 0); 9029 break; 9030 } 9031 slot = bwn_dma_nextslot(dr, slot); 9032 } 9033 } 9034 bwn_dma_handle_txeof(mac, status); 9035 } else { 9036 if (status->ack) { 9037 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9038 if (tq == NULL) { 9039 device_printf(sc->sc_dev, 9040 "failed to parse cookie\n"); 9041 return; 9042 } 9043 ni = tp->tp_ni; 9044 vap = ni->ni_vap; 9045 ieee80211_ratectl_tx_complete(vap, ni, 9046 status->ack ? 9047 IEEE80211_RATECTL_TX_SUCCESS : 9048 IEEE80211_RATECTL_TX_FAILURE, 9049 &retrycnt, 0); 9050 } 9051 bwn_pio_handle_txeof(mac, status); 9052 } 9053 9054 bwn_phy_txpower_check(mac, 0); 9055 } 9056 9057 static uint8_t 9058 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9059 { 9060 struct bwn_mac *mac = prq->prq_mac; 9061 struct bwn_softc *sc = mac->mac_sc; 9062 struct bwn_rxhdr4 rxhdr; 9063 struct ifnet *ifp = sc->sc_ifp; 9064 struct mbuf *m; 9065 uint32_t ctl32, macstat, v32; 9066 unsigned int i, padding; 9067 uint16_t ctl16, len, totlen, v16; 9068 unsigned char *mp; 9069 char *data; 9070 9071 memset(&rxhdr, 0, sizeof(rxhdr)); 9072 9073 if (prq->prq_rev >= 8) { 9074 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9075 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9076 return (0); 9077 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9078 BWN_PIO8_RXCTL_FRAMEREADY); 9079 for (i = 0; i < 10; i++) { 9080 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9081 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9082 goto ready; 9083 DELAY(10); 9084 } 9085 } else { 9086 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9087 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9088 return (0); 9089 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9090 BWN_PIO_RXCTL_FRAMEREADY); 9091 for (i = 0; i < 10; i++) { 9092 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9093 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9094 goto ready; 9095 DELAY(10); 9096 } 9097 } 9098 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9099 return (1); 9100 ready: 9101 if (prq->prq_rev >= 8) 9102 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9103 prq->prq_base + BWN_PIO8_RXDATA); 9104 else 9105 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9106 prq->prq_base + BWN_PIO_RXDATA); 9107 len = le16toh(rxhdr.frame_len); 9108 if (len > 0x700) { 9109 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9110 goto error; 9111 } 9112 if (len == 0) { 9113 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9114 goto error; 9115 } 9116 9117 macstat = le32toh(rxhdr.mac_status); 9118 if (macstat & BWN_RX_MAC_FCSERR) { 9119 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9120 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9121 goto error; 9122 } 9123 } 9124 9125 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9126 totlen = len + padding; 9127 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9128 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9129 if (m == NULL) { 9130 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9131 goto error; 9132 } 9133 mp = mtod(m, unsigned char *); 9134 if (prq->prq_rev >= 8) { 9135 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9136 prq->prq_base + BWN_PIO8_RXDATA); 9137 if (totlen & 3) { 9138 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9139 data = &(mp[totlen - 1]); 9140 switch (totlen & 3) { 9141 case 3: 9142 *data = (v32 >> 16); 9143 data--; 9144 case 2: 9145 *data = (v32 >> 8); 9146 data--; 9147 case 1: 9148 *data = v32; 9149 } 9150 } 9151 } else { 9152 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9153 prq->prq_base + BWN_PIO_RXDATA); 9154 if (totlen & 1) { 9155 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9156 mp[totlen - 1] = v16; 9157 } 9158 } 9159 9160 m->m_pkthdr.rcvif = ifp; 9161 m->m_len = m->m_pkthdr.len = totlen; 9162 9163 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9164 9165 return (1); 9166 error: 9167 if (prq->prq_rev >= 8) 9168 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9169 BWN_PIO8_RXCTL_DATAREADY); 9170 else 9171 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9172 return (1); 9173 } 9174 9175 static int 9176 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9177 struct bwn_dmadesc_meta *meta, int init) 9178 { 9179 struct bwn_mac *mac = dr->dr_mac; 9180 struct bwn_dma *dma = &mac->mac_method.dma; 9181 struct bwn_rxhdr4 *hdr; 9182 bus_dmamap_t map; 9183 bus_addr_t paddr; 9184 struct mbuf *m; 9185 int error; 9186 9187 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9188 if (m == NULL) { 9189 error = ENOBUFS; 9190 9191 /* 9192 * If the NIC is up and running, we need to: 9193 * - Clear RX buffer's header. 9194 * - Restore RX descriptor settings. 9195 */ 9196 if (init) 9197 return (error); 9198 else 9199 goto back; 9200 } 9201 m->m_len = m->m_pkthdr.len = MCLBYTES; 9202 9203 bwn_dma_set_redzone(dr, m); 9204 9205 /* 9206 * Try to load RX buf into temporary DMA map 9207 */ 9208 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9209 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9210 if (error) { 9211 m_freem(m); 9212 9213 /* 9214 * See the comment above 9215 */ 9216 if (init) 9217 return (error); 9218 else 9219 goto back; 9220 } 9221 9222 if (!init) 9223 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9224 meta->mt_m = m; 9225 meta->mt_paddr = paddr; 9226 9227 /* 9228 * Swap RX buf's DMA map with the loaded temporary one 9229 */ 9230 map = meta->mt_dmap; 9231 meta->mt_dmap = dr->dr_spare_dmap; 9232 dr->dr_spare_dmap = map; 9233 9234 back: 9235 /* 9236 * Clear RX buf header 9237 */ 9238 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9239 bzero(hdr, sizeof(*hdr)); 9240 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9241 BUS_DMASYNC_PREWRITE); 9242 9243 /* 9244 * Setup RX buf descriptor 9245 */ 9246 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9247 sizeof(*hdr), 0, 0, 0); 9248 return (error); 9249 } 9250 9251 static void 9252 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9253 bus_size_t mapsz __unused, int error) 9254 { 9255 9256 if (!error) { 9257 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9258 *((bus_addr_t *)arg) = seg->ds_addr; 9259 } 9260 } 9261 9262 static int 9263 bwn_hwrate2ieeerate(int rate) 9264 { 9265 9266 switch (rate) { 9267 case BWN_CCK_RATE_1MB: 9268 return (2); 9269 case BWN_CCK_RATE_2MB: 9270 return (4); 9271 case BWN_CCK_RATE_5MB: 9272 return (11); 9273 case BWN_CCK_RATE_11MB: 9274 return (22); 9275 case BWN_OFDM_RATE_6MB: 9276 return (12); 9277 case BWN_OFDM_RATE_9MB: 9278 return (18); 9279 case BWN_OFDM_RATE_12MB: 9280 return (24); 9281 case BWN_OFDM_RATE_18MB: 9282 return (36); 9283 case BWN_OFDM_RATE_24MB: 9284 return (48); 9285 case BWN_OFDM_RATE_36MB: 9286 return (72); 9287 case BWN_OFDM_RATE_48MB: 9288 return (96); 9289 case BWN_OFDM_RATE_54MB: 9290 return (108); 9291 default: 9292 printf("Ooops\n"); 9293 return (0); 9294 } 9295 } 9296 9297 static void 9298 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9299 { 9300 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9301 struct bwn_plcp6 *plcp; 9302 struct bwn_softc *sc = mac->mac_sc; 9303 struct ieee80211_frame_min *wh; 9304 struct ieee80211_node *ni; 9305 struct ifnet *ifp = sc->sc_ifp; 9306 struct ieee80211com *ic = ifp->if_l2com; 9307 uint32_t macstat; 9308 int padding, rate, rssi = 0, noise = 0, type; 9309 uint16_t phytype, phystat0, phystat3, chanstat; 9310 unsigned char *mp = mtod(m, unsigned char *); 9311 static int rx_mac_dec_rpt = 0; 9312 9313 BWN_ASSERT_LOCKED(sc); 9314 9315 phystat0 = le16toh(rxhdr->phy_status0); 9316 phystat3 = le16toh(rxhdr->phy_status3); 9317 macstat = le32toh(rxhdr->mac_status); 9318 chanstat = le16toh(rxhdr->channel); 9319 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9320 9321 if (macstat & BWN_RX_MAC_FCSERR) 9322 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9323 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9324 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9325 if (macstat & BWN_RX_MAC_DECERR) 9326 goto drop; 9327 9328 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9329 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9330 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9331 m->m_pkthdr.len); 9332 goto drop; 9333 } 9334 plcp = (struct bwn_plcp6 *)(mp + padding); 9335 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9336 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9337 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9338 m->m_pkthdr.len); 9339 goto drop; 9340 } 9341 wh = mtod(m, struct ieee80211_frame_min *); 9342 9343 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9344 device_printf(sc->sc_dev, 9345 "RX decryption attempted (old %d keyidx %#x)\n", 9346 BWN_ISOLDFMT(mac), 9347 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9348 9349 /* XXX calculating RSSI & noise & antenna */ 9350 9351 if (phystat0 & BWN_RX_PHYST0_OFDM) 9352 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9353 phytype == BWN_PHYTYPE_A); 9354 else 9355 rate = bwn_plcp_get_cckrate(mac, plcp); 9356 if (rate == -1) { 9357 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9358 goto drop; 9359 } 9360 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9361 9362 /* RX radio tap */ 9363 if (ieee80211_radiotap_active(ic)) 9364 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9365 m_adj(m, -IEEE80211_CRC_LEN); 9366 9367 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9368 noise = mac->mac_stats.link_noise; 9369 9370 ifp->if_ipackets++; 9371 9372 BWN_UNLOCK(sc); 9373 9374 ni = ieee80211_find_rxnode(ic, wh); 9375 if (ni != NULL) { 9376 type = ieee80211_input(ni, m, rssi, noise); 9377 ieee80211_free_node(ni); 9378 } else 9379 type = ieee80211_input_all(ic, m, rssi, noise); 9380 9381 BWN_LOCK(sc); 9382 return; 9383 drop: 9384 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9385 } 9386 9387 static void 9388 bwn_dma_handle_txeof(struct bwn_mac *mac, 9389 const struct bwn_txstatus *status) 9390 { 9391 struct bwn_dma *dma = &mac->mac_method.dma; 9392 struct bwn_dma_ring *dr; 9393 struct bwn_dmadesc_generic *desc; 9394 struct bwn_dmadesc_meta *meta; 9395 struct bwn_softc *sc = mac->mac_sc; 9396 struct ieee80211_node *ni; 9397 struct ifnet *ifp = sc->sc_ifp; 9398 struct mbuf *m; 9399 int slot; 9400 9401 BWN_ASSERT_LOCKED(sc); 9402 9403 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9404 if (dr == NULL) { 9405 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9406 return; 9407 } 9408 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9409 9410 while (1) { 9411 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9412 ("%s:%d: fail", __func__, __LINE__)); 9413 dr->getdesc(dr, slot, &desc, &meta); 9414 9415 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9416 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9417 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9418 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9419 9420 if (meta->mt_islast) { 9421 KASSERT(meta->mt_m != NULL, 9422 ("%s:%d: fail", __func__, __LINE__)); 9423 9424 ni = meta->mt_ni; 9425 m = meta->mt_m; 9426 if (ni != NULL) { 9427 /* 9428 * Do any tx complete callback. Note this must 9429 * be done before releasing the node reference. 9430 */ 9431 if (m->m_flags & M_TXCB) 9432 ieee80211_process_callback(ni, m, 0); 9433 ieee80211_free_node(ni); 9434 meta->mt_ni = NULL; 9435 } 9436 m_freem(m); 9437 meta->mt_m = NULL; 9438 } else { 9439 KASSERT(meta->mt_m == NULL, 9440 ("%s:%d: fail", __func__, __LINE__)); 9441 } 9442 9443 dr->dr_usedslot--; 9444 if (meta->mt_islast) { 9445 ifp->if_opackets++; 9446 break; 9447 } 9448 slot = bwn_dma_nextslot(dr, slot); 9449 } 9450 sc->sc_watchdog_timer = 0; 9451 if (dr->dr_stop) { 9452 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9453 ("%s:%d: fail", __func__, __LINE__)); 9454 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9455 dr->dr_stop = 0; 9456 } 9457 } 9458 9459 static void 9460 bwn_pio_handle_txeof(struct bwn_mac *mac, 9461 const struct bwn_txstatus *status) 9462 { 9463 struct bwn_pio_txqueue *tq; 9464 struct bwn_pio_txpkt *tp = NULL; 9465 struct bwn_softc *sc = mac->mac_sc; 9466 struct ifnet *ifp = sc->sc_ifp; 9467 9468 BWN_ASSERT_LOCKED(sc); 9469 9470 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9471 if (tq == NULL) 9472 return; 9473 9474 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9475 tq->tq_free++; 9476 9477 if (tp->tp_ni != NULL) { 9478 /* 9479 * Do any tx complete callback. Note this must 9480 * be done before releasing the node reference. 9481 */ 9482 if (tp->tp_m->m_flags & M_TXCB) 9483 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9484 ieee80211_free_node(tp->tp_ni); 9485 tp->tp_ni = NULL; 9486 } 9487 m_freem(tp->tp_m); 9488 tp->tp_m = NULL; 9489 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9490 9491 ifp->if_opackets++; 9492 9493 sc->sc_watchdog_timer = 0; 9494 if (tq->tq_stop) { 9495 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9496 tq->tq_stop = 0; 9497 } 9498 } 9499 9500 static void 9501 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9502 { 9503 struct bwn_softc *sc = mac->mac_sc; 9504 struct bwn_phy *phy = &mac->mac_phy; 9505 struct ifnet *ifp = sc->sc_ifp; 9506 struct ieee80211com *ic = ifp->if_l2com; 9507 unsigned long now; 9508 int result; 9509 9510 BWN_GETTIME(now); 9511 9512 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9513 return; 9514 phy->nexttime = now + 2 * 1000; 9515 9516 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9517 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9518 return; 9519 9520 if (phy->recalc_txpwr != NULL) { 9521 result = phy->recalc_txpwr(mac, 9522 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9523 if (result == BWN_TXPWR_RES_DONE) 9524 return; 9525 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9526 ("%s: fail", __func__)); 9527 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9528 9529 ieee80211_runtask(ic, &mac->mac_txpower); 9530 } 9531 } 9532 9533 static uint16_t 9534 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9535 { 9536 9537 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9538 } 9539 9540 static uint32_t 9541 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9542 { 9543 9544 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9545 } 9546 9547 static void 9548 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9549 { 9550 9551 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9552 } 9553 9554 static void 9555 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9556 { 9557 9558 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9559 } 9560 9561 static int 9562 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9563 { 9564 9565 switch (rate) { 9566 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9567 case 12: 9568 return (BWN_OFDM_RATE_6MB); 9569 case 18: 9570 return (BWN_OFDM_RATE_9MB); 9571 case 24: 9572 return (BWN_OFDM_RATE_12MB); 9573 case 36: 9574 return (BWN_OFDM_RATE_18MB); 9575 case 48: 9576 return (BWN_OFDM_RATE_24MB); 9577 case 72: 9578 return (BWN_OFDM_RATE_36MB); 9579 case 96: 9580 return (BWN_OFDM_RATE_48MB); 9581 case 108: 9582 return (BWN_OFDM_RATE_54MB); 9583 /* CCK rates (NB: not IEEE std, device-specific) */ 9584 case 2: 9585 return (BWN_CCK_RATE_1MB); 9586 case 4: 9587 return (BWN_CCK_RATE_2MB); 9588 case 11: 9589 return (BWN_CCK_RATE_5MB); 9590 case 22: 9591 return (BWN_CCK_RATE_11MB); 9592 } 9593 9594 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9595 return (BWN_CCK_RATE_1MB); 9596 } 9597 9598 static int 9599 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9600 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9601 { 9602 const struct bwn_phy *phy = &mac->mac_phy; 9603 struct bwn_softc *sc = mac->mac_sc; 9604 struct ieee80211_frame *wh; 9605 struct ieee80211_frame *protwh; 9606 struct ieee80211_frame_cts *cts; 9607 struct ieee80211_frame_rts *rts; 9608 const struct ieee80211_txparam *tp; 9609 struct ieee80211vap *vap = ni->ni_vap; 9610 struct ifnet *ifp = sc->sc_ifp; 9611 struct ieee80211com *ic = ifp->if_l2com; 9612 struct mbuf *mprot; 9613 unsigned int len; 9614 uint32_t macctl = 0; 9615 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9616 uint16_t phyctl = 0; 9617 uint8_t rate, rate_fb; 9618 9619 wh = mtod(m, struct ieee80211_frame *); 9620 memset(txhdr, 0, sizeof(*txhdr)); 9621 9622 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9623 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9624 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9625 9626 /* 9627 * Find TX rate 9628 */ 9629 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9630 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9631 rate = rate_fb = tp->mgmtrate; 9632 else if (ismcast) 9633 rate = rate_fb = tp->mcastrate; 9634 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9635 rate = rate_fb = tp->ucastrate; 9636 else { 9637 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9638 rate = ni->ni_txrate; 9639 9640 if (rix > 0) 9641 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9642 IEEE80211_RATE_VAL; 9643 else 9644 rate_fb = rate; 9645 } 9646 9647 sc->sc_tx_rate = rate; 9648 9649 rate = bwn_ieeerate2hwrate(sc, rate); 9650 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9651 9652 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9653 bwn_plcp_getcck(rate); 9654 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9655 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9656 9657 if ((rate_fb == rate) || 9658 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9659 (*(u_int16_t *)wh->i_dur == htole16(0))) 9660 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9661 else 9662 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9663 m->m_pkthdr.len, rate, isshort); 9664 9665 /* XXX TX encryption */ 9666 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9667 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9668 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9669 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9670 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9671 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9672 9673 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9674 BWN_TX_EFT_FB_CCK; 9675 txhdr->chan = phy->chan; 9676 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9677 BWN_TX_PHY_ENC_CCK; 9678 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9679 rate == BWN_CCK_RATE_11MB)) 9680 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9681 9682 /* XXX TX antenna selection */ 9683 9684 switch (bwn_antenna_sanitize(mac, 0)) { 9685 case 0: 9686 phyctl |= BWN_TX_PHY_ANT01AUTO; 9687 break; 9688 case 1: 9689 phyctl |= BWN_TX_PHY_ANT0; 9690 break; 9691 case 2: 9692 phyctl |= BWN_TX_PHY_ANT1; 9693 break; 9694 case 3: 9695 phyctl |= BWN_TX_PHY_ANT2; 9696 break; 9697 case 4: 9698 phyctl |= BWN_TX_PHY_ANT3; 9699 break; 9700 default: 9701 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9702 } 9703 9704 if (!ismcast) 9705 macctl |= BWN_TX_MAC_ACK; 9706 9707 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9708 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9709 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9710 macctl |= BWN_TX_MAC_LONGFRAME; 9711 9712 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9713 /* XXX RTS rate is always 1MB??? */ 9714 rts_rate = BWN_CCK_RATE_1MB; 9715 rts_rate_fb = bwn_get_fbrate(rts_rate); 9716 9717 protdur = ieee80211_compute_duration(ic->ic_rt, 9718 m->m_pkthdr.len, rate, isshort) + 9719 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9720 9721 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9722 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9723 (txhdr->body.old.rts_frame) : 9724 (txhdr->body.new.rts_frame)); 9725 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9726 protdur); 9727 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9728 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9729 mprot->m_pkthdr.len); 9730 m_freem(mprot); 9731 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9732 len = sizeof(struct ieee80211_frame_cts); 9733 } else { 9734 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9735 (txhdr->body.old.rts_frame) : 9736 (txhdr->body.new.rts_frame)); 9737 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9738 isshort); 9739 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9740 wh->i_addr2, protdur); 9741 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9742 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9743 mprot->m_pkthdr.len); 9744 m_freem(mprot); 9745 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9746 len = sizeof(struct ieee80211_frame_rts); 9747 } 9748 len += IEEE80211_CRC_LEN; 9749 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9750 &txhdr->body.old.rts_plcp : 9751 &txhdr->body.new.rts_plcp), len, rts_rate); 9752 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9753 rts_rate_fb); 9754 9755 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9756 (&txhdr->body.old.rts_frame) : 9757 (&txhdr->body.new.rts_frame)); 9758 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9759 9760 if (BWN_ISOFDMRATE(rts_rate)) { 9761 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9762 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9763 } else { 9764 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9765 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9766 } 9767 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9768 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9769 } 9770 9771 if (BWN_ISOLDFMT(mac)) 9772 txhdr->body.old.cookie = htole16(cookie); 9773 else 9774 txhdr->body.new.cookie = htole16(cookie); 9775 9776 txhdr->macctl = htole32(macctl); 9777 txhdr->phyctl = htole16(phyctl); 9778 9779 /* 9780 * TX radio tap 9781 */ 9782 if (ieee80211_radiotap_active_vap(vap)) { 9783 sc->sc_tx_th.wt_flags = 0; 9784 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9785 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9786 if (isshort && 9787 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9788 rate == BWN_CCK_RATE_11MB)) 9789 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9790 sc->sc_tx_th.wt_rate = rate; 9791 9792 ieee80211_radiotap_tx(vap, m); 9793 } 9794 9795 return (0); 9796 } 9797 9798 static void 9799 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9800 const uint8_t rate) 9801 { 9802 uint32_t d, plen; 9803 uint8_t *raw = plcp->o.raw; 9804 9805 if (BWN_ISOFDMRATE(rate)) { 9806 d = bwn_plcp_getofdm(rate); 9807 KASSERT(!(octets & 0xf000), 9808 ("%s:%d: fail", __func__, __LINE__)); 9809 d |= (octets << 5); 9810 plcp->o.data = htole32(d); 9811 } else { 9812 plen = octets * 16 / rate; 9813 if ((octets * 16 % rate) > 0) { 9814 plen++; 9815 if ((rate == BWN_CCK_RATE_11MB) 9816 && ((octets * 8 % 11) < 4)) { 9817 raw[1] = 0x84; 9818 } else 9819 raw[1] = 0x04; 9820 } else 9821 raw[1] = 0x04; 9822 plcp->o.data |= htole32(plen << 16); 9823 raw[0] = bwn_plcp_getcck(rate); 9824 } 9825 } 9826 9827 static uint8_t 9828 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9829 { 9830 struct bwn_softc *sc = mac->mac_sc; 9831 uint8_t mask; 9832 9833 if (n == 0) 9834 return (0); 9835 if (mac->mac_phy.gmode) 9836 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9837 else 9838 mask = siba_sprom_get_ant_a(sc->sc_dev); 9839 if (!(mask & (1 << (n - 1)))) 9840 return (0); 9841 return (n); 9842 } 9843 9844 static uint8_t 9845 bwn_get_fbrate(uint8_t bitrate) 9846 { 9847 switch (bitrate) { 9848 case BWN_CCK_RATE_1MB: 9849 return (BWN_CCK_RATE_1MB); 9850 case BWN_CCK_RATE_2MB: 9851 return (BWN_CCK_RATE_1MB); 9852 case BWN_CCK_RATE_5MB: 9853 return (BWN_CCK_RATE_2MB); 9854 case BWN_CCK_RATE_11MB: 9855 return (BWN_CCK_RATE_5MB); 9856 case BWN_OFDM_RATE_6MB: 9857 return (BWN_CCK_RATE_5MB); 9858 case BWN_OFDM_RATE_9MB: 9859 return (BWN_OFDM_RATE_6MB); 9860 case BWN_OFDM_RATE_12MB: 9861 return (BWN_OFDM_RATE_9MB); 9862 case BWN_OFDM_RATE_18MB: 9863 return (BWN_OFDM_RATE_12MB); 9864 case BWN_OFDM_RATE_24MB: 9865 return (BWN_OFDM_RATE_18MB); 9866 case BWN_OFDM_RATE_36MB: 9867 return (BWN_OFDM_RATE_24MB); 9868 case BWN_OFDM_RATE_48MB: 9869 return (BWN_OFDM_RATE_36MB); 9870 case BWN_OFDM_RATE_54MB: 9871 return (BWN_OFDM_RATE_48MB); 9872 } 9873 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9874 return (0); 9875 } 9876 9877 static uint32_t 9878 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9879 uint32_t ctl, const void *_data, int len) 9880 { 9881 struct bwn_softc *sc = mac->mac_sc; 9882 uint32_t value = 0; 9883 const uint8_t *data = _data; 9884 9885 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9886 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9887 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9888 9889 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9890 tq->tq_base + BWN_PIO8_TXDATA); 9891 if (len & 3) { 9892 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9893 BWN_PIO8_TXCTL_24_31); 9894 data = &(data[len - 1]); 9895 switch (len & 3) { 9896 case 3: 9897 ctl |= BWN_PIO8_TXCTL_16_23; 9898 value |= (uint32_t)(*data) << 16; 9899 data--; 9900 case 2: 9901 ctl |= BWN_PIO8_TXCTL_8_15; 9902 value |= (uint32_t)(*data) << 8; 9903 data--; 9904 case 1: 9905 value |= (uint32_t)(*data); 9906 } 9907 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9908 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9909 } 9910 9911 return (ctl); 9912 } 9913 9914 static void 9915 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9916 uint16_t offset, uint32_t value) 9917 { 9918 9919 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9920 } 9921 9922 static uint16_t 9923 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9924 uint16_t ctl, const void *_data, int len) 9925 { 9926 struct bwn_softc *sc = mac->mac_sc; 9927 const uint8_t *data = _data; 9928 9929 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9930 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9931 9932 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9933 tq->tq_base + BWN_PIO_TXDATA); 9934 if (len & 1) { 9935 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9936 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9937 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9938 } 9939 9940 return (ctl); 9941 } 9942 9943 static uint16_t 9944 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9945 uint16_t ctl, struct mbuf *m0) 9946 { 9947 int i, j = 0; 9948 uint16_t data = 0; 9949 const uint8_t *buf; 9950 struct mbuf *m = m0; 9951 9952 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9953 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9954 9955 for (; m != NULL; m = m->m_next) { 9956 buf = mtod(m, const uint8_t *); 9957 for (i = 0; i < m->m_len; i++) { 9958 if (!((j++) % 2)) 9959 data |= buf[i]; 9960 else { 9961 data |= (buf[i] << 8); 9962 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9963 data = 0; 9964 } 9965 } 9966 } 9967 if (m0->m_pkthdr.len % 2) { 9968 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9969 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9970 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9971 } 9972 9973 return (ctl); 9974 } 9975 9976 static void 9977 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9978 { 9979 9980 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9981 return; 9982 BWN_WRITE_2(mac, 0x684, 510 + time); 9983 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9984 } 9985 9986 static struct bwn_dma_ring * 9987 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9988 { 9989 9990 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9991 return (mac->mac_method.dma.wme[WME_AC_BE]); 9992 9993 switch (prio) { 9994 case 3: 9995 return (mac->mac_method.dma.wme[WME_AC_VO]); 9996 case 2: 9997 return (mac->mac_method.dma.wme[WME_AC_VI]); 9998 case 0: 9999 return (mac->mac_method.dma.wme[WME_AC_BE]); 10000 case 1: 10001 return (mac->mac_method.dma.wme[WME_AC_BK]); 10002 } 10003 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10004 return (NULL); 10005 } 10006 10007 static int 10008 bwn_dma_getslot(struct bwn_dma_ring *dr) 10009 { 10010 int slot; 10011 10012 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10013 10014 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10015 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10016 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10017 10018 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10019 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10020 dr->dr_curslot = slot; 10021 dr->dr_usedslot++; 10022 10023 return (slot); 10024 } 10025 10026 static int 10027 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10028 { 10029 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10030 unsigned int a, b, c, d; 10031 unsigned int avg; 10032 uint32_t tmp; 10033 10034 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10035 a = tmp & 0xff; 10036 b = (tmp >> 8) & 0xff; 10037 c = (tmp >> 16) & 0xff; 10038 d = (tmp >> 24) & 0xff; 10039 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10040 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10041 return (ENOENT); 10042 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10043 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10044 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10045 10046 if (ofdm) { 10047 a = (a + 32) & 0x3f; 10048 b = (b + 32) & 0x3f; 10049 c = (c + 32) & 0x3f; 10050 d = (d + 32) & 0x3f; 10051 } 10052 10053 avg = (a + b + c + d + 2) / 4; 10054 if (ofdm) { 10055 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10056 & BWN_HF_4DB_CCK_POWERBOOST) 10057 avg = (avg >= 13) ? (avg - 13) : 0; 10058 } 10059 return (avg); 10060 } 10061 10062 static void 10063 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10064 { 10065 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10066 int rfatt = *rfattp; 10067 int bbatt = *bbattp; 10068 10069 while (1) { 10070 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10071 break; 10072 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10073 break; 10074 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10075 break; 10076 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10077 break; 10078 if (bbatt > lo->bbatt.max) { 10079 bbatt -= 4; 10080 rfatt += 1; 10081 continue; 10082 } 10083 if (bbatt < lo->bbatt.min) { 10084 bbatt += 4; 10085 rfatt -= 1; 10086 continue; 10087 } 10088 if (rfatt > lo->rfatt.max) { 10089 rfatt -= 1; 10090 bbatt += 4; 10091 continue; 10092 } 10093 if (rfatt < lo->rfatt.min) { 10094 rfatt += 1; 10095 bbatt -= 4; 10096 continue; 10097 } 10098 break; 10099 } 10100 10101 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10102 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10103 } 10104 10105 static void 10106 bwn_phy_lock(struct bwn_mac *mac) 10107 { 10108 struct bwn_softc *sc = mac->mac_sc; 10109 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10110 10111 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10112 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10113 10114 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10115 bwn_psctl(mac, BWN_PS_AWAKE); 10116 } 10117 10118 static void 10119 bwn_phy_unlock(struct bwn_mac *mac) 10120 { 10121 struct bwn_softc *sc = mac->mac_sc; 10122 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10123 10124 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10125 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10126 10127 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10128 bwn_psctl(mac, 0); 10129 } 10130 10131 static void 10132 bwn_rf_lock(struct bwn_mac *mac) 10133 { 10134 10135 BWN_WRITE_4(mac, BWN_MACCTL, 10136 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10137 BWN_READ_4(mac, BWN_MACCTL); 10138 DELAY(10); 10139 } 10140 10141 static void 10142 bwn_rf_unlock(struct bwn_mac *mac) 10143 { 10144 10145 BWN_READ_2(mac, BWN_PHYVER); 10146 BWN_WRITE_4(mac, BWN_MACCTL, 10147 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10148 } 10149 10150 static struct bwn_pio_txqueue * 10151 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10152 struct bwn_pio_txpkt **pack) 10153 { 10154 struct bwn_pio *pio = &mac->mac_method.pio; 10155 struct bwn_pio_txqueue *tq = NULL; 10156 unsigned int index; 10157 10158 switch (cookie & 0xf000) { 10159 case 0x1000: 10160 tq = &pio->wme[WME_AC_BK]; 10161 break; 10162 case 0x2000: 10163 tq = &pio->wme[WME_AC_BE]; 10164 break; 10165 case 0x3000: 10166 tq = &pio->wme[WME_AC_VI]; 10167 break; 10168 case 0x4000: 10169 tq = &pio->wme[WME_AC_VO]; 10170 break; 10171 case 0x5000: 10172 tq = &pio->mcast; 10173 break; 10174 } 10175 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10176 if (tq == NULL) 10177 return (NULL); 10178 index = (cookie & 0x0fff); 10179 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10180 if (index >= N(tq->tq_pkts)) 10181 return (NULL); 10182 *pack = &tq->tq_pkts[index]; 10183 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10184 return (tq); 10185 } 10186 10187 static void 10188 bwn_txpwr(void *arg, int npending) 10189 { 10190 struct bwn_mac *mac = arg; 10191 struct bwn_softc *sc = mac->mac_sc; 10192 10193 BWN_LOCK(sc); 10194 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10195 mac->mac_phy.set_txpwr != NULL) 10196 mac->mac_phy.set_txpwr(mac); 10197 BWN_UNLOCK(sc); 10198 } 10199 10200 static void 10201 bwn_task_15s(struct bwn_mac *mac) 10202 { 10203 uint16_t reg; 10204 10205 if (mac->mac_fw.opensource) { 10206 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10207 if (reg) { 10208 bwn_restart(mac, "fw watchdog"); 10209 return; 10210 } 10211 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10212 } 10213 if (mac->mac_phy.task_15s) 10214 mac->mac_phy.task_15s(mac); 10215 10216 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10217 } 10218 10219 static void 10220 bwn_task_30s(struct bwn_mac *mac) 10221 { 10222 10223 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10224 return; 10225 mac->mac_noise.noi_running = 1; 10226 mac->mac_noise.noi_nsamples = 0; 10227 10228 bwn_noise_gensample(mac); 10229 } 10230 10231 static void 10232 bwn_task_60s(struct bwn_mac *mac) 10233 { 10234 10235 if (mac->mac_phy.task_60s) 10236 mac->mac_phy.task_60s(mac); 10237 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10238 } 10239 10240 static void 10241 bwn_tasks(void *arg) 10242 { 10243 struct bwn_mac *mac = arg; 10244 struct bwn_softc *sc = mac->mac_sc; 10245 10246 BWN_ASSERT_LOCKED(sc); 10247 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10248 return; 10249 10250 if (mac->mac_task_state % 4 == 0) 10251 bwn_task_60s(mac); 10252 if (mac->mac_task_state % 2 == 0) 10253 bwn_task_30s(mac); 10254 bwn_task_15s(mac); 10255 10256 mac->mac_task_state++; 10257 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10258 } 10259 10260 static int 10261 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10262 { 10263 struct bwn_softc *sc = mac->mac_sc; 10264 10265 KASSERT(a == 0, ("not support APHY\n")); 10266 10267 switch (plcp->o.raw[0] & 0xf) { 10268 case 0xb: 10269 return (BWN_OFDM_RATE_6MB); 10270 case 0xf: 10271 return (BWN_OFDM_RATE_9MB); 10272 case 0xa: 10273 return (BWN_OFDM_RATE_12MB); 10274 case 0xe: 10275 return (BWN_OFDM_RATE_18MB); 10276 case 0x9: 10277 return (BWN_OFDM_RATE_24MB); 10278 case 0xd: 10279 return (BWN_OFDM_RATE_36MB); 10280 case 0x8: 10281 return (BWN_OFDM_RATE_48MB); 10282 case 0xc: 10283 return (BWN_OFDM_RATE_54MB); 10284 } 10285 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10286 plcp->o.raw[0] & 0xf); 10287 return (-1); 10288 } 10289 10290 static int 10291 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10292 { 10293 struct bwn_softc *sc = mac->mac_sc; 10294 10295 switch (plcp->o.raw[0]) { 10296 case 0x0a: 10297 return (BWN_CCK_RATE_1MB); 10298 case 0x14: 10299 return (BWN_CCK_RATE_2MB); 10300 case 0x37: 10301 return (BWN_CCK_RATE_5MB); 10302 case 0x6e: 10303 return (BWN_CCK_RATE_11MB); 10304 } 10305 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10306 return (-1); 10307 } 10308 10309 static void 10310 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10311 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10312 int rssi, int noise) 10313 { 10314 struct bwn_softc *sc = mac->mac_sc; 10315 const struct ieee80211_frame_min *wh; 10316 uint64_t tsf; 10317 uint16_t low_mactime_now; 10318 10319 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10320 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10321 10322 wh = mtod(m, const struct ieee80211_frame_min *); 10323 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10324 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10325 10326 bwn_tsf_read(mac, &tsf); 10327 low_mactime_now = tsf; 10328 tsf = tsf & ~0xffffULL; 10329 tsf += le16toh(rxhdr->mac_time); 10330 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10331 tsf -= 0x10000; 10332 10333 sc->sc_rx_th.wr_tsf = tsf; 10334 sc->sc_rx_th.wr_rate = rate; 10335 sc->sc_rx_th.wr_antsignal = rssi; 10336 sc->sc_rx_th.wr_antnoise = noise; 10337 } 10338 10339 static void 10340 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10341 { 10342 uint32_t low, high; 10343 10344 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10345 ("%s:%d: fail", __func__, __LINE__)); 10346 10347 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10348 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10349 *tsf = high; 10350 *tsf <<= 32; 10351 *tsf |= low; 10352 } 10353 10354 static int 10355 bwn_dma_attach(struct bwn_mac *mac) 10356 { 10357 struct bwn_dma *dma = &mac->mac_method.dma; 10358 struct bwn_softc *sc = mac->mac_sc; 10359 bus_addr_t lowaddr = 0; 10360 int error; 10361 10362 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10363 return (0); 10364 10365 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10366 10367 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10368 10369 dma->dmatype = bwn_dma_gettype(mac); 10370 if (dma->dmatype == BWN_DMA_30BIT) 10371 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10372 else if (dma->dmatype == BWN_DMA_32BIT) 10373 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10374 else 10375 lowaddr = BUS_SPACE_MAXADDR; 10376 10377 /* 10378 * Create top level DMA tag 10379 */ 10380 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10381 BWN_ALIGN, 0, /* alignment, bounds */ 10382 lowaddr, /* lowaddr */ 10383 BUS_SPACE_MAXADDR, /* highaddr */ 10384 NULL, NULL, /* filter, filterarg */ 10385 MAXBSIZE, /* maxsize */ 10386 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10387 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10388 0, /* flags */ 10389 NULL, NULL, /* lockfunc, lockarg */ 10390 &dma->parent_dtag); 10391 if (error) { 10392 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10393 return (error); 10394 } 10395 10396 /* 10397 * Create TX/RX mbuf DMA tag 10398 */ 10399 error = bus_dma_tag_create(dma->parent_dtag, 10400 1, 10401 0, 10402 BUS_SPACE_MAXADDR, 10403 BUS_SPACE_MAXADDR, 10404 NULL, NULL, 10405 MCLBYTES, 10406 1, 10407 BUS_SPACE_MAXSIZE_32BIT, 10408 0, 10409 NULL, NULL, 10410 &dma->rxbuf_dtag); 10411 if (error) { 10412 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10413 goto fail0; 10414 } 10415 error = bus_dma_tag_create(dma->parent_dtag, 10416 1, 10417 0, 10418 BUS_SPACE_MAXADDR, 10419 BUS_SPACE_MAXADDR, 10420 NULL, NULL, 10421 MCLBYTES, 10422 1, 10423 BUS_SPACE_MAXSIZE_32BIT, 10424 0, 10425 NULL, NULL, 10426 &dma->txbuf_dtag); 10427 if (error) { 10428 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10429 goto fail1; 10430 } 10431 10432 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10433 if (!dma->wme[WME_AC_BK]) 10434 goto fail2; 10435 10436 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10437 if (!dma->wme[WME_AC_BE]) 10438 goto fail3; 10439 10440 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10441 if (!dma->wme[WME_AC_VI]) 10442 goto fail4; 10443 10444 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10445 if (!dma->wme[WME_AC_VO]) 10446 goto fail5; 10447 10448 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10449 if (!dma->mcast) 10450 goto fail6; 10451 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10452 if (!dma->rx) 10453 goto fail7; 10454 10455 return (error); 10456 10457 fail7: bwn_dma_ringfree(&dma->mcast); 10458 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10459 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10460 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10461 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10462 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10463 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10464 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10465 return (error); 10466 } 10467 10468 static struct bwn_dma_ring * 10469 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10470 uint16_t cookie, int *slot) 10471 { 10472 struct bwn_dma *dma = &mac->mac_method.dma; 10473 struct bwn_dma_ring *dr; 10474 struct bwn_softc *sc = mac->mac_sc; 10475 10476 BWN_ASSERT_LOCKED(mac->mac_sc); 10477 10478 switch (cookie & 0xf000) { 10479 case 0x1000: 10480 dr = dma->wme[WME_AC_BK]; 10481 break; 10482 case 0x2000: 10483 dr = dma->wme[WME_AC_BE]; 10484 break; 10485 case 0x3000: 10486 dr = dma->wme[WME_AC_VI]; 10487 break; 10488 case 0x4000: 10489 dr = dma->wme[WME_AC_VO]; 10490 break; 10491 case 0x5000: 10492 dr = dma->mcast; 10493 break; 10494 default: 10495 dr = NULL; 10496 KASSERT(0 == 1, 10497 ("invalid cookie value %d", cookie & 0xf000)); 10498 } 10499 *slot = (cookie & 0x0fff); 10500 if (*slot < 0 || *slot >= dr->dr_numslots) { 10501 /* 10502 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10503 * that it occurs events which have same H/W sequence numbers. 10504 * When it's occurred just prints a WARNING msgs and ignores. 10505 */ 10506 KASSERT(status->seq == dma->lastseq, 10507 ("%s:%d: fail", __func__, __LINE__)); 10508 device_printf(sc->sc_dev, 10509 "out of slot ranges (0 < %d < %d)\n", *slot, 10510 dr->dr_numslots); 10511 return (NULL); 10512 } 10513 dma->lastseq = status->seq; 10514 return (dr); 10515 } 10516 10517 static void 10518 bwn_dma_stop(struct bwn_mac *mac) 10519 { 10520 struct bwn_dma *dma; 10521 10522 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10523 return; 10524 dma = &mac->mac_method.dma; 10525 10526 bwn_dma_ringstop(&dma->rx); 10527 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10528 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10529 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10530 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10531 bwn_dma_ringstop(&dma->mcast); 10532 } 10533 10534 static void 10535 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10536 { 10537 10538 if (dr == NULL) 10539 return; 10540 10541 bwn_dma_cleanup(*dr); 10542 } 10543 10544 static void 10545 bwn_pio_stop(struct bwn_mac *mac) 10546 { 10547 struct bwn_pio *pio; 10548 10549 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10550 return; 10551 pio = &mac->mac_method.pio; 10552 10553 bwn_destroy_queue_tx(&pio->mcast); 10554 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10555 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10556 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10557 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10558 } 10559 10560 static void 10561 bwn_led_attach(struct bwn_mac *mac) 10562 { 10563 struct bwn_softc *sc = mac->mac_sc; 10564 const uint8_t *led_act = NULL; 10565 uint16_t val[BWN_LED_MAX]; 10566 int i; 10567 10568 sc->sc_led_idle = (2350 * hz) / 1000; 10569 sc->sc_led_blink = 1; 10570 10571 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10572 if (siba_get_pci_subvendor(sc->sc_dev) == 10573 bwn_vendor_led_act[i].vid) { 10574 led_act = bwn_vendor_led_act[i].led_act; 10575 break; 10576 } 10577 } 10578 if (led_act == NULL) 10579 led_act = bwn_default_led_act; 10580 10581 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10582 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10583 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10584 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10585 10586 for (i = 0; i < BWN_LED_MAX; ++i) { 10587 struct bwn_led *led = &sc->sc_leds[i]; 10588 10589 if (val[i] == 0xff) { 10590 led->led_act = led_act[i]; 10591 } else { 10592 if (val[i] & BWN_LED_ACT_LOW) 10593 led->led_flags |= BWN_LED_F_ACTLOW; 10594 led->led_act = val[i] & BWN_LED_ACT_MASK; 10595 } 10596 led->led_mask = (1 << i); 10597 10598 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10599 led->led_act == BWN_LED_ACT_BLINK_POLL || 10600 led->led_act == BWN_LED_ACT_BLINK) { 10601 led->led_flags |= BWN_LED_F_BLINK; 10602 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10603 led->led_flags |= BWN_LED_F_POLLABLE; 10604 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10605 led->led_flags |= BWN_LED_F_SLOW; 10606 10607 if (sc->sc_blink_led == NULL) { 10608 sc->sc_blink_led = led; 10609 if (led->led_flags & BWN_LED_F_SLOW) 10610 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10611 } 10612 } 10613 10614 DPRINTF(sc, BWN_DEBUG_LED, 10615 "%dth led, act %d, lowact %d\n", i, 10616 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10617 } 10618 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10619 } 10620 10621 static __inline uint16_t 10622 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10623 { 10624 10625 if (led->led_flags & BWN_LED_F_ACTLOW) 10626 on = !on; 10627 if (on) 10628 val |= led->led_mask; 10629 else 10630 val &= ~led->led_mask; 10631 return val; 10632 } 10633 10634 static void 10635 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10636 { 10637 struct bwn_softc *sc = mac->mac_sc; 10638 struct ifnet *ifp = sc->sc_ifp; 10639 struct ieee80211com *ic = ifp->if_l2com; 10640 uint16_t val; 10641 int i; 10642 10643 if (nstate == IEEE80211_S_INIT) { 10644 callout_stop(&sc->sc_led_blink_ch); 10645 sc->sc_led_blinking = 0; 10646 } 10647 10648 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10649 return; 10650 10651 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10652 for (i = 0; i < BWN_LED_MAX; ++i) { 10653 struct bwn_led *led = &sc->sc_leds[i]; 10654 int on; 10655 10656 if (led->led_act == BWN_LED_ACT_UNKN || 10657 led->led_act == BWN_LED_ACT_NULL) 10658 continue; 10659 10660 if ((led->led_flags & BWN_LED_F_BLINK) && 10661 nstate != IEEE80211_S_INIT) 10662 continue; 10663 10664 switch (led->led_act) { 10665 case BWN_LED_ACT_ON: /* Always on */ 10666 on = 1; 10667 break; 10668 case BWN_LED_ACT_OFF: /* Always off */ 10669 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10670 on = 0; 10671 break; 10672 default: 10673 on = 1; 10674 switch (nstate) { 10675 case IEEE80211_S_INIT: 10676 on = 0; 10677 break; 10678 case IEEE80211_S_RUN: 10679 if (led->led_act == BWN_LED_ACT_11G && 10680 ic->ic_curmode != IEEE80211_MODE_11G) 10681 on = 0; 10682 break; 10683 default: 10684 if (led->led_act == BWN_LED_ACT_ASSOC) 10685 on = 0; 10686 break; 10687 } 10688 break; 10689 } 10690 10691 val = bwn_led_onoff(led, val, on); 10692 } 10693 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10694 } 10695 10696 static void 10697 bwn_led_event(struct bwn_mac *mac, int event) 10698 { 10699 struct bwn_softc *sc = mac->mac_sc; 10700 struct bwn_led *led = sc->sc_blink_led; 10701 int rate; 10702 10703 if (event == BWN_LED_EVENT_POLL) { 10704 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10705 return; 10706 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10707 return; 10708 } 10709 10710 sc->sc_led_ticks = ticks; 10711 if (sc->sc_led_blinking) 10712 return; 10713 10714 switch (event) { 10715 case BWN_LED_EVENT_RX: 10716 rate = sc->sc_rx_rate; 10717 break; 10718 case BWN_LED_EVENT_TX: 10719 rate = sc->sc_tx_rate; 10720 break; 10721 case BWN_LED_EVENT_POLL: 10722 rate = 0; 10723 break; 10724 default: 10725 panic("unknown LED event %d\n", event); 10726 break; 10727 } 10728 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10729 bwn_led_duration[rate].off_dur); 10730 } 10731 10732 static void 10733 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10734 { 10735 struct bwn_softc *sc = mac->mac_sc; 10736 struct bwn_led *led = sc->sc_blink_led; 10737 uint16_t val; 10738 10739 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10740 val = bwn_led_onoff(led, val, 1); 10741 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10742 10743 if (led->led_flags & BWN_LED_F_SLOW) { 10744 BWN_LED_SLOWDOWN(on_dur); 10745 BWN_LED_SLOWDOWN(off_dur); 10746 } 10747 10748 sc->sc_led_blinking = 1; 10749 sc->sc_led_blink_offdur = off_dur; 10750 10751 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10752 } 10753 10754 static void 10755 bwn_led_blink_next(void *arg) 10756 { 10757 struct bwn_mac *mac = arg; 10758 struct bwn_softc *sc = mac->mac_sc; 10759 uint16_t val; 10760 10761 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10762 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10763 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10764 10765 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10766 bwn_led_blink_end, mac); 10767 } 10768 10769 static void 10770 bwn_led_blink_end(void *arg) 10771 { 10772 struct bwn_mac *mac = arg; 10773 struct bwn_softc *sc = mac->mac_sc; 10774 10775 sc->sc_led_blinking = 0; 10776 } 10777 10778 static int 10779 bwn_suspend(device_t dev) 10780 { 10781 struct bwn_softc *sc = device_get_softc(dev); 10782 10783 bwn_stop(sc, 1); 10784 return (0); 10785 } 10786 10787 static int 10788 bwn_resume(device_t dev) 10789 { 10790 struct bwn_softc *sc = device_get_softc(dev); 10791 struct ifnet *ifp = sc->sc_ifp; 10792 10793 if (ifp->if_flags & IFF_UP) 10794 bwn_init(sc); 10795 return (0); 10796 } 10797 10798 static void 10799 bwn_rfswitch(void *arg) 10800 { 10801 struct bwn_softc *sc = arg; 10802 struct bwn_mac *mac = sc->sc_curmac; 10803 int cur = 0, prev = 0; 10804 10805 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10806 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10807 10808 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10809 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10810 & BWN_RF_HWENABLED_HI_MASK)) 10811 cur = 1; 10812 } else { 10813 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10814 & BWN_RF_HWENABLED_LO_MASK) 10815 cur = 1; 10816 } 10817 10818 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10819 prev = 1; 10820 10821 if (cur != prev) { 10822 if (cur) 10823 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10824 else 10825 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10826 10827 device_printf(sc->sc_dev, 10828 "status of RF switch is changed to %s\n", 10829 cur ? "ON" : "OFF"); 10830 if (cur != mac->mac_phy.rf_on) { 10831 if (cur) 10832 bwn_rf_turnon(mac); 10833 else 10834 bwn_rf_turnoff(mac); 10835 } 10836 } 10837 10838 callout_schedule(&sc->sc_rfswitch_ch, hz); 10839 } 10840 10841 static void 10842 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10843 { 10844 struct bwn_phy *phy = &mac->mac_phy; 10845 struct bwn_phy_lp *plp = &phy->phy_lp; 10846 10847 plp->plp_antenna = BWN_ANT_DEFAULT; 10848 } 10849 10850 static int 10851 bwn_phy_lp_init(struct bwn_mac *mac) 10852 { 10853 static const struct bwn_stxtable tables[] = { 10854 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10855 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10856 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10857 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10858 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10859 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10860 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10861 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10862 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10863 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10864 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10865 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10866 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10867 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10868 { 2, 11, 0x40, 0, 0x0f } 10869 }; 10870 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10871 struct bwn_softc *sc = mac->mac_sc; 10872 const struct bwn_stxtable *st; 10873 struct ifnet *ifp = sc->sc_ifp; 10874 struct ieee80211com *ic = ifp->if_l2com; 10875 int i, error; 10876 uint16_t tmp; 10877 10878 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10879 bwn_phy_lp_bbinit(mac); 10880 10881 /* initialize RF */ 10882 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10883 DELAY(1); 10884 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10885 DELAY(1); 10886 10887 if (mac->mac_phy.rf_ver == 0x2062) 10888 bwn_phy_lp_b2062_init(mac); 10889 else { 10890 bwn_phy_lp_b2063_init(mac); 10891 10892 /* synchronize stx table. */ 10893 for (i = 0; i < N(tables); i++) { 10894 st = &tables[i]; 10895 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10896 tmp >>= st->st_rfshift; 10897 tmp <<= st->st_physhift; 10898 BWN_PHY_SETMASK(mac, 10899 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10900 ~(st->st_mask << st->st_physhift), tmp); 10901 } 10902 10903 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10904 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10905 } 10906 10907 /* calibrate RC */ 10908 if (mac->mac_phy.rev >= 2) 10909 bwn_phy_lp_rxcal_r2(mac); 10910 else if (!plp->plp_rccap) { 10911 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10912 bwn_phy_lp_rccal_r12(mac); 10913 } else 10914 bwn_phy_lp_set_rccap(mac); 10915 10916 error = bwn_phy_lp_switch_channel(mac, 7); 10917 if (error) 10918 device_printf(sc->sc_dev, 10919 "failed to change channel 7 (%d)\n", error); 10920 bwn_phy_lp_txpctl_init(mac); 10921 bwn_phy_lp_calib(mac); 10922 return (0); 10923 } 10924 10925 static uint16_t 10926 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10927 { 10928 10929 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10930 return (BWN_READ_2(mac, BWN_PHYDATA)); 10931 } 10932 10933 static void 10934 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10935 { 10936 10937 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10938 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10939 } 10940 10941 static void 10942 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10943 uint16_t set) 10944 { 10945 10946 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10947 BWN_WRITE_2(mac, BWN_PHYDATA, 10948 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10949 } 10950 10951 static uint16_t 10952 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10953 { 10954 10955 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10956 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10957 reg |= 0x100; 10958 if (mac->mac_phy.rev >= 2) 10959 reg |= 0x200; 10960 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10961 return BWN_READ_2(mac, BWN_RFDATALO); 10962 } 10963 10964 static void 10965 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10966 { 10967 10968 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10969 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10970 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10971 } 10972 10973 static void 10974 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10975 { 10976 10977 if (on) { 10978 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10979 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10980 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10981 return; 10982 } 10983 10984 if (mac->mac_phy.rev >= 2) { 10985 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10986 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10987 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10988 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10989 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10990 return; 10991 } 10992 10993 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10994 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10995 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10996 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10997 } 10998 10999 static int 11000 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11001 { 11002 struct bwn_phy *phy = &mac->mac_phy; 11003 struct bwn_phy_lp *plp = &phy->phy_lp; 11004 int error; 11005 11006 if (phy->rf_ver == 0x2063) { 11007 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11008 if (error) 11009 return (error); 11010 } else { 11011 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11012 if (error) 11013 return (error); 11014 bwn_phy_lp_set_anafilter(mac, chan); 11015 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11016 } 11017 11018 plp->plp_chan = chan; 11019 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11020 return (0); 11021 } 11022 11023 static uint32_t 11024 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11025 { 11026 struct bwn_softc *sc = mac->mac_sc; 11027 struct ifnet *ifp = sc->sc_ifp; 11028 struct ieee80211com *ic = ifp->if_l2com; 11029 11030 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11031 } 11032 11033 static void 11034 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11035 { 11036 struct bwn_phy *phy = &mac->mac_phy; 11037 struct bwn_phy_lp *plp = &phy->phy_lp; 11038 11039 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11040 return; 11041 11042 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11043 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11044 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11045 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11046 plp->plp_antenna = antenna; 11047 } 11048 11049 static void 11050 bwn_phy_lp_task_60s(struct bwn_mac *mac) 11051 { 11052 11053 bwn_phy_lp_calib(mac); 11054 } 11055 11056 static void 11057 bwn_phy_lp_readsprom(struct bwn_mac *mac) 11058 { 11059 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11060 struct bwn_softc *sc = mac->mac_sc; 11061 struct ifnet *ifp = sc->sc_ifp; 11062 struct ieee80211com *ic = ifp->if_l2com; 11063 11064 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11065 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 11066 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 11067 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 11068 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 11069 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 11070 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 11071 return; 11072 } 11073 11074 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 11075 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 11076 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 11077 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 11078 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 11079 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 11080 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 11081 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 11082 } 11083 11084 static void 11085 bwn_phy_lp_bbinit(struct bwn_mac *mac) 11086 { 11087 11088 bwn_phy_lp_tblinit(mac); 11089 if (mac->mac_phy.rev >= 2) 11090 bwn_phy_lp_bbinit_r2(mac); 11091 else 11092 bwn_phy_lp_bbinit_r01(mac); 11093 } 11094 11095 static void 11096 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11097 { 11098 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11099 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11100 struct bwn_softc *sc = mac->mac_sc; 11101 struct ifnet *ifp = sc->sc_ifp; 11102 struct ieee80211com *ic = ifp->if_l2com; 11103 11104 bwn_phy_lp_set_txgain(mac, 11105 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11106 bwn_phy_lp_set_bbmult(mac, 150); 11107 } 11108 11109 static void 11110 bwn_phy_lp_calib(struct bwn_mac *mac) 11111 { 11112 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11113 struct bwn_softc *sc = mac->mac_sc; 11114 struct ifnet *ifp = sc->sc_ifp; 11115 struct ieee80211com *ic = ifp->if_l2com; 11116 const struct bwn_rxcompco *rc = NULL; 11117 struct bwn_txgain ogain; 11118 int i, omode, oafeovr, orf, obbmult; 11119 uint8_t mode, fc = 0; 11120 11121 if (plp->plp_chanfullcal != plp->plp_chan) { 11122 plp->plp_chanfullcal = plp->plp_chan; 11123 fc = 1; 11124 } 11125 11126 bwn_mac_suspend(mac); 11127 11128 /* BlueTooth Coexistance Override */ 11129 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11130 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11131 11132 if (mac->mac_phy.rev >= 2) 11133 bwn_phy_lp_digflt_save(mac); 11134 bwn_phy_lp_get_txpctlmode(mac); 11135 mode = plp->plp_txpctlmode; 11136 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11137 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11138 bwn_phy_lp_bugfix(mac); 11139 if (mac->mac_phy.rev >= 2 && fc == 1) { 11140 bwn_phy_lp_get_txpctlmode(mac); 11141 omode = plp->plp_txpctlmode; 11142 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11143 if (oafeovr) 11144 ogain = bwn_phy_lp_get_txgain(mac); 11145 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11146 obbmult = bwn_phy_lp_get_bbmult(mac); 11147 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11148 if (oafeovr) 11149 bwn_phy_lp_set_txgain(mac, &ogain); 11150 bwn_phy_lp_set_bbmult(mac, obbmult); 11151 bwn_phy_lp_set_txpctlmode(mac, omode); 11152 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11153 } 11154 bwn_phy_lp_set_txpctlmode(mac, mode); 11155 if (mac->mac_phy.rev >= 2) 11156 bwn_phy_lp_digflt_restore(mac); 11157 11158 /* do RX IQ Calculation; assumes that noise is true. */ 11159 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11160 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11161 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11162 rc = &bwn_rxcompco_5354[i]; 11163 } 11164 } else if (mac->mac_phy.rev >= 2) 11165 rc = &bwn_rxcompco_r2; 11166 else { 11167 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11168 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11169 rc = &bwn_rxcompco_r12[i]; 11170 } 11171 } 11172 if (rc == NULL) 11173 goto fail; 11174 11175 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11176 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11177 11178 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11179 11180 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11181 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11182 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11183 } else { 11184 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11185 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11186 } 11187 11188 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11189 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11190 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11191 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11192 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11193 bwn_phy_lp_set_deaf(mac, 0); 11194 /* XXX no checking return value? */ 11195 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11196 bwn_phy_lp_clear_deaf(mac, 0); 11197 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11199 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11200 11201 /* disable RX GAIN override. */ 11202 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11203 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11204 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11205 if (mac->mac_phy.rev >= 2) { 11206 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11207 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11208 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11209 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11210 } 11211 } else { 11212 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11213 } 11214 11215 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11216 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11217 fail: 11218 bwn_mac_enable(mac); 11219 } 11220 11221 static void 11222 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11223 { 11224 11225 if (on) { 11226 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11227 return; 11228 } 11229 11230 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11231 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11232 } 11233 11234 static int 11235 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11236 { 11237 static const struct bwn_b206x_chan *bc = NULL; 11238 struct bwn_softc *sc = mac->mac_sc; 11239 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11240 tmp[6]; 11241 uint16_t old, scale, tmp16; 11242 int i, div; 11243 11244 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11245 if (bwn_b2063_chantable[i].bc_chan == chan) { 11246 bc = &bwn_b2063_chantable[i]; 11247 break; 11248 } 11249 } 11250 if (bc == NULL) 11251 return (EINVAL); 11252 11253 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11254 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11255 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11256 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11257 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11258 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11259 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11260 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11261 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11262 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11263 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11264 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11265 11266 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11267 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11268 11269 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11270 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11271 freqref = freqxtal * 3; 11272 div = (freqxtal <= 26000000 ? 1 : 2); 11273 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11274 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11275 999999) / 1000000) + 1; 11276 11277 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11278 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11279 0xfff8, timeout >> 2); 11280 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11281 0xff9f,timeout << 5); 11282 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11283 11284 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11285 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11286 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11287 11288 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11289 (timeoutref + 1)) - 1; 11290 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11291 0xf0, count >> 8); 11292 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11293 11294 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11295 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11296 while (tmp[1] >= freqref) { 11297 tmp[0]++; 11298 tmp[1] -= freqref; 11299 } 11300 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11301 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11302 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11303 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11304 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11305 11306 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11307 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11308 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11309 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11310 11311 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11312 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11313 11314 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11315 scale = 1; 11316 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11317 } else { 11318 scale = 0; 11319 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11320 } 11321 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11322 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11323 11324 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11325 (scale + 1); 11326 if (tmp[5] > 150) 11327 tmp[5] = 0; 11328 11329 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11331 11332 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11333 if (freqxtal > 26000000) 11334 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11335 else 11336 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11337 11338 if (val[0] == 45) 11339 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11340 else 11341 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11342 11343 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11344 DELAY(1); 11345 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11346 11347 /* VCO Calibration */ 11348 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11349 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11350 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11351 DELAY(1); 11352 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11353 DELAY(1); 11354 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11355 DELAY(1); 11356 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11357 DELAY(300); 11358 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11359 11360 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11361 return (0); 11362 } 11363 11364 static int 11365 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11366 { 11367 struct bwn_softc *sc = mac->mac_sc; 11368 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11369 const struct bwn_b206x_chan *bc = NULL; 11370 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11371 uint32_t tmp[9]; 11372 int i; 11373 11374 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11375 if (bwn_b2062_chantable[i].bc_chan == chan) { 11376 bc = &bwn_b2062_chantable[i]; 11377 break; 11378 } 11379 } 11380 11381 if (bc == NULL) 11382 return (EINVAL); 11383 11384 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11385 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11386 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11387 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11388 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11389 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11390 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11391 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11392 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11393 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11394 11395 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11396 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11397 bwn_phy_lp_b2062_reset_pllbias(mac); 11398 tmp[0] = freqxtal / 1000; 11399 tmp[1] = plp->plp_div * 1000; 11400 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11401 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11402 tmp[2] *= 2; 11403 tmp[3] = 48 * tmp[0]; 11404 tmp[5] = tmp[2] / tmp[3]; 11405 tmp[6] = tmp[2] % tmp[3]; 11406 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11407 tmp[4] = tmp[6] * 0x100; 11408 tmp[5] = tmp[4] / tmp[3]; 11409 tmp[6] = tmp[4] % tmp[3]; 11410 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11411 tmp[4] = tmp[6] * 0x100; 11412 tmp[5] = tmp[4] / tmp[3]; 11413 tmp[6] = tmp[4] % tmp[3]; 11414 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11415 tmp[4] = tmp[6] * 0x100; 11416 tmp[5] = tmp[4] / tmp[3]; 11417 tmp[6] = tmp[4] % tmp[3]; 11418 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11419 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11420 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11421 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11422 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11423 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11424 11425 bwn_phy_lp_b2062_vco_calib(mac); 11426 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11427 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11428 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11429 bwn_phy_lp_b2062_reset_pllbias(mac); 11430 bwn_phy_lp_b2062_vco_calib(mac); 11431 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11432 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11433 return (EIO); 11434 } 11435 } 11436 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11437 return (0); 11438 } 11439 11440 static void 11441 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11442 { 11443 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11444 uint16_t tmp = (channel == 14); 11445 11446 if (mac->mac_phy.rev < 2) { 11447 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11448 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11449 bwn_phy_lp_set_rccap(mac); 11450 return; 11451 } 11452 11453 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11454 } 11455 11456 static void 11457 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11458 { 11459 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11460 struct bwn_softc *sc = mac->mac_sc; 11461 struct ifnet *ifp = sc->sc_ifp; 11462 struct ieee80211com *ic = ifp->if_l2com; 11463 uint16_t iso, tmp[3]; 11464 11465 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11466 11467 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11468 iso = plp->plp_txisoband_m; 11469 else if (freq <= 5320) 11470 iso = plp->plp_txisoband_l; 11471 else if (freq <= 5700) 11472 iso = plp->plp_txisoband_m; 11473 else 11474 iso = plp->plp_txisoband_h; 11475 11476 tmp[0] = ((iso - 26) / 12) << 12; 11477 tmp[1] = tmp[0] + 0x1000; 11478 tmp[2] = tmp[0] + 0x2000; 11479 11480 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11481 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11482 } 11483 11484 static void 11485 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11486 { 11487 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11488 int i; 11489 static const uint16_t addr[] = { 11490 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11491 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11492 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11493 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11494 BWN_PHY_OFDM(0xcf), 11495 }; 11496 static const uint16_t val[] = { 11497 0xde5e, 0xe832, 0xe331, 0x4d26, 11498 0x0026, 0x1420, 0x0020, 0xfe08, 11499 0x0008, 11500 }; 11501 11502 for (i = 0; i < N(addr); i++) { 11503 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11504 BWN_PHY_WRITE(mac, addr[i], val[i]); 11505 } 11506 } 11507 11508 static void 11509 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11510 { 11511 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11512 struct bwn_softc *sc = mac->mac_sc; 11513 uint16_t ctl; 11514 11515 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11516 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11517 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11518 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11519 break; 11520 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11521 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11522 break; 11523 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11524 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11525 break; 11526 default: 11527 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11528 device_printf(sc->sc_dev, "unknown command mode\n"); 11529 break; 11530 } 11531 } 11532 11533 static void 11534 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11535 { 11536 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11537 uint16_t ctl; 11538 uint8_t old; 11539 11540 bwn_phy_lp_get_txpctlmode(mac); 11541 old = plp->plp_txpctlmode; 11542 if (old == mode) 11543 return; 11544 plp->plp_txpctlmode = mode; 11545 11546 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11547 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11548 plp->plp_tssiidx); 11549 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11550 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11551 11552 /* disable TX GAIN override */ 11553 if (mac->mac_phy.rev < 2) 11554 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11555 else { 11556 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11557 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11558 } 11559 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11560 11561 plp->plp_txpwridx = -1; 11562 } 11563 if (mac->mac_phy.rev >= 2) { 11564 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11565 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11566 else 11567 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11568 } 11569 11570 /* writes TX Power Control mode */ 11571 switch (plp->plp_txpctlmode) { 11572 case BWN_PHYLP_TXPCTL_OFF: 11573 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11574 break; 11575 case BWN_PHYLP_TXPCTL_ON_HW: 11576 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11577 break; 11578 case BWN_PHYLP_TXPCTL_ON_SW: 11579 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11580 break; 11581 default: 11582 ctl = 0; 11583 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11584 } 11585 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11586 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11587 } 11588 11589 static void 11590 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11591 { 11592 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11593 struct bwn_softc *sc = mac->mac_sc; 11594 const unsigned int size = 256; 11595 struct bwn_txgain tg; 11596 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11597 uint16_t tssinpt, tssiidx, value[2]; 11598 uint8_t mode; 11599 int8_t txpwridx; 11600 11601 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11602 M_NOWAIT | M_ZERO); 11603 if (tabs == NULL) { 11604 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11605 return; 11606 } 11607 11608 bwn_phy_lp_get_txpctlmode(mac); 11609 mode = plp->plp_txpctlmode; 11610 txpwridx = plp->plp_txpwridx; 11611 tssinpt = plp->plp_tssinpt; 11612 tssiidx = plp->plp_tssiidx; 11613 11614 bwn_tab_read_multi(mac, 11615 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11616 BWN_TAB_4(7, 0x140), size, tabs); 11617 11618 bwn_phy_lp_tblinit(mac); 11619 bwn_phy_lp_bbinit(mac); 11620 bwn_phy_lp_txpctl_init(mac); 11621 bwn_phy_lp_rf_onoff(mac, 1); 11622 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11623 11624 bwn_tab_write_multi(mac, 11625 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11626 BWN_TAB_4(7, 0x140), size, tabs); 11627 11628 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11629 plp->plp_tssinpt = tssinpt; 11630 plp->plp_tssiidx = tssiidx; 11631 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11632 if (txpwridx != -1) { 11633 /* set TX power by index */ 11634 plp->plp_txpwridx = txpwridx; 11635 bwn_phy_lp_get_txpctlmode(mac); 11636 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11637 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11638 if (mac->mac_phy.rev >= 2) { 11639 rxcomp = bwn_tab_read(mac, 11640 BWN_TAB_4(7, txpwridx + 320)); 11641 txgain = bwn_tab_read(mac, 11642 BWN_TAB_4(7, txpwridx + 192)); 11643 tg.tg_pad = (txgain >> 16) & 0xff; 11644 tg.tg_gm = txgain & 0xff; 11645 tg.tg_pga = (txgain >> 8) & 0xff; 11646 tg.tg_dac = (rxcomp >> 28) & 0xff; 11647 bwn_phy_lp_set_txgain(mac, &tg); 11648 } else { 11649 rxcomp = bwn_tab_read(mac, 11650 BWN_TAB_4(10, txpwridx + 320)); 11651 txgain = bwn_tab_read(mac, 11652 BWN_TAB_4(10, txpwridx + 192)); 11653 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11654 0xf800, (txgain >> 4) & 0x7fff); 11655 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11656 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11657 } 11658 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11659 11660 /* set TX IQCC */ 11661 value[0] = (rxcomp >> 10) & 0x3ff; 11662 value[1] = rxcomp & 0x3ff; 11663 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11664 11665 coeff = bwn_tab_read(mac, 11666 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11667 BWN_TAB_4(10, txpwridx + 448)); 11668 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11669 if (mac->mac_phy.rev >= 2) { 11670 rfpwr = bwn_tab_read(mac, 11671 BWN_TAB_4(7, txpwridx + 576)); 11672 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11673 rfpwr & 0xffff); 11674 } 11675 bwn_phy_lp_set_txgain_override(mac); 11676 } 11677 if (plp->plp_rccap) 11678 bwn_phy_lp_set_rccap(mac); 11679 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11680 bwn_phy_lp_set_txpctlmode(mac, mode); 11681 free(tabs, M_DEVBUF); 11682 } 11683 11684 static void 11685 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11686 { 11687 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11688 int i; 11689 static const uint16_t addr[] = { 11690 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11691 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11692 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11693 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11694 BWN_PHY_OFDM(0xcf), 11695 }; 11696 11697 for (i = 0; i < N(addr); i++) 11698 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11699 } 11700 11701 static void 11702 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11703 { 11704 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11705 11706 if (mac->mac_phy.rev < 2) { 11707 bwn_phy_lp_tblinit_r01(mac); 11708 bwn_phy_lp_tblinit_txgain(mac); 11709 bwn_phy_lp_set_gaintbl(mac, freq); 11710 return; 11711 } 11712 11713 bwn_phy_lp_tblinit_r2(mac); 11714 bwn_phy_lp_tblinit_txgain(mac); 11715 } 11716 11717 struct bwn_wpair { 11718 uint16_t reg; 11719 uint16_t value; 11720 }; 11721 11722 struct bwn_smpair { 11723 uint16_t offset; 11724 uint16_t mask; 11725 uint16_t set; 11726 }; 11727 11728 static void 11729 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11730 { 11731 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11732 struct bwn_softc *sc = mac->mac_sc; 11733 struct ifnet *ifp = sc->sc_ifp; 11734 struct ieee80211com *ic = ifp->if_l2com; 11735 static const struct bwn_wpair v1[] = { 11736 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11737 { BWN_PHY_AFE_CTL, 0x8800 }, 11738 { BWN_PHY_AFE_CTL_OVR, 0 }, 11739 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11740 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11741 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11742 { BWN_PHY_OFDM(0xf9), 0 }, 11743 { BWN_PHY_TR_LOOKUP_1, 0 } 11744 }; 11745 static const struct bwn_smpair v2[] = { 11746 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11747 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11748 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11749 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11750 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11751 }; 11752 static const struct bwn_smpair v3[] = { 11753 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11754 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11755 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11756 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11757 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11758 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11759 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11760 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11761 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11762 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11763 11764 }; 11765 int i; 11766 11767 for (i = 0; i < N(v1); i++) 11768 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11769 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11770 for (i = 0; i < N(v2); i++) 11771 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11772 11773 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11774 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11775 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11776 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11777 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11778 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11779 } else { 11780 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11781 } 11782 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11783 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11784 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11785 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11786 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11787 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11788 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11789 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11790 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11791 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11792 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11793 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11794 (siba_get_chiprev(sc->sc_dev) == 0)) { 11795 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11796 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11797 } else { 11798 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11799 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11800 } 11801 for (i = 0; i < N(v3); i++) 11802 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11803 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11804 (siba_get_chiprev(sc->sc_dev) == 0)) { 11805 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11806 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11807 } 11808 11809 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11810 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11811 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11812 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11813 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11814 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11815 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11816 } else 11817 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11818 11819 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11820 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11821 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11822 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11823 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11824 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11825 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11826 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11827 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11828 11829 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11830 (siba_get_chiprev(sc->sc_dev) == 0)) { 11831 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11832 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11833 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11834 } 11835 11836 bwn_phy_lp_digflt_save(mac); 11837 } 11838 11839 static void 11840 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11841 { 11842 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11843 struct bwn_softc *sc = mac->mac_sc; 11844 struct ifnet *ifp = sc->sc_ifp; 11845 struct ieee80211com *ic = ifp->if_l2com; 11846 static const struct bwn_smpair v1[] = { 11847 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11848 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11849 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11850 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11851 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11852 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11853 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11854 }; 11855 static const struct bwn_smpair v2[] = { 11856 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11857 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11858 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11859 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11860 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11861 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11862 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11863 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11864 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11865 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11866 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11867 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11868 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11869 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11870 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11871 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11872 }; 11873 static const struct bwn_smpair v3[] = { 11874 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11875 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11876 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11877 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11878 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11879 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11880 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11881 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11882 }; 11883 static const struct bwn_smpair v4[] = { 11884 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11885 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11886 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11887 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11888 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11889 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11890 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11891 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11892 }; 11893 static const struct bwn_smpair v5[] = { 11894 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11895 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11896 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11897 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11898 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11899 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11900 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11901 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11902 }; 11903 int i; 11904 uint16_t tmp, tmp2; 11905 11906 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11907 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11908 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11909 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11910 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11911 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11912 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11913 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11914 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11915 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11916 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11917 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11918 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11919 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11920 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11921 for (i = 0; i < N(v1); i++) 11922 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11923 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11924 0xff00, plp->plp_rxpwroffset); 11925 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11926 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11927 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11928 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11929 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11930 if (mac->mac_phy.rev == 0) 11931 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11932 0xffcf, 0x0010); 11933 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11934 } else { 11935 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11936 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11937 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11938 } 11939 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11940 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11941 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11942 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11943 else 11944 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11945 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11946 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11947 0xfff9, (plp->plp_bxarch << 1)); 11948 if (mac->mac_phy.rev == 1 && 11949 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11950 for (i = 0; i < N(v2); i++) 11951 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11952 v2[i].set); 11953 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11954 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11955 ((mac->mac_phy.rev == 0) && 11956 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11957 for (i = 0; i < N(v3); i++) 11958 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11959 v3[i].set); 11960 } else if (mac->mac_phy.rev == 1 || 11961 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11962 for (i = 0; i < N(v4); i++) 11963 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11964 v4[i].set); 11965 } else { 11966 for (i = 0; i < N(v5); i++) 11967 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11968 v5[i].set); 11969 } 11970 if (mac->mac_phy.rev == 1 && 11971 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11972 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11973 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11974 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11975 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11976 } 11977 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11978 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11979 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11980 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11981 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11982 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11983 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11984 } 11985 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11986 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11987 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11988 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11989 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11990 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11991 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11992 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11993 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11994 } else { 11995 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11996 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11997 } 11998 if (mac->mac_phy.rev == 1) { 11999 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 12000 tmp2 = (tmp & 0x03e0) >> 5; 12001 tmp2 |= tmp2 << 5; 12002 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12003 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12004 tmp2 = (tmp & 0x1f00) >> 8; 12005 tmp2 |= tmp2 << 5; 12006 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12007 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12008 tmp2 = tmp & 0x00ff; 12009 tmp2 |= tmp << 8; 12010 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12011 } 12012 } 12013 12014 struct bwn_b2062_freq { 12015 uint16_t freq; 12016 uint8_t value[6]; 12017 }; 12018 12019 static void 12020 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12021 { 12022 #define CALC_CTL7(freq, div) \ 12023 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12024 #define CALC_CTL18(freq, div) \ 12025 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12026 #define CALC_CTL19(freq, div) \ 12027 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12028 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12029 struct bwn_softc *sc = mac->mac_sc; 12030 struct ifnet *ifp = sc->sc_ifp; 12031 struct ieee80211com *ic = ifp->if_l2com; 12032 static const struct bwn_b2062_freq freqdata_tab[] = { 12033 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12034 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12035 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12036 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12037 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12038 { 19200, { 1, 1, 1, 1, 14, 9 } } 12039 }; 12040 static const struct bwn_wpair v1[] = { 12041 { BWN_B2062_N_TXCTL3, 0 }, 12042 { BWN_B2062_N_TXCTL4, 0 }, 12043 { BWN_B2062_N_TXCTL5, 0 }, 12044 { BWN_B2062_N_TXCTL6, 0 }, 12045 { BWN_B2062_N_PDNCTL0, 0x40 }, 12046 { BWN_B2062_N_PDNCTL0, 0 }, 12047 { BWN_B2062_N_CALIB_TS, 0x10 }, 12048 { BWN_B2062_N_CALIB_TS, 0 } 12049 }; 12050 const struct bwn_b2062_freq *f = NULL; 12051 uint32_t xtalfreq, ref; 12052 unsigned int i; 12053 12054 bwn_phy_lp_b2062_tblinit(mac); 12055 12056 for (i = 0; i < N(v1); i++) 12057 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12058 if (mac->mac_phy.rev > 0) 12059 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12060 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12061 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12062 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12063 else 12064 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12065 12066 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 12067 ("%s:%d: fail", __func__, __LINE__)); 12068 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12069 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12070 12071 if (xtalfreq <= 30000000) { 12072 plp->plp_div = 1; 12073 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12074 } else { 12075 plp->plp_div = 2; 12076 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12077 } 12078 12079 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12080 CALC_CTL7(xtalfreq, plp->plp_div)); 12081 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12082 CALC_CTL18(xtalfreq, plp->plp_div)); 12083 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12084 CALC_CTL19(xtalfreq, plp->plp_div)); 12085 12086 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12087 ref &= 0xffff; 12088 for (i = 0; i < N(freqdata_tab); i++) { 12089 if (ref < freqdata_tab[i].freq) { 12090 f = &freqdata_tab[i]; 12091 break; 12092 } 12093 } 12094 if (f == NULL) 12095 f = &freqdata_tab[N(freqdata_tab) - 1]; 12096 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12097 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12098 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12099 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12100 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12101 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12102 #undef CALC_CTL7 12103 #undef CALC_CTL18 12104 #undef CALC_CTL19 12105 } 12106 12107 static void 12108 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12109 { 12110 12111 bwn_phy_lp_b2063_tblinit(mac); 12112 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12113 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12114 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12115 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12116 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12117 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12118 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12119 if (mac->mac_phy.rev == 2) { 12120 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12121 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12122 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12123 } else { 12124 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12125 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12126 } 12127 } 12128 12129 static void 12130 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12131 { 12132 struct bwn_softc *sc = mac->mac_sc; 12133 static const struct bwn_wpair v1[] = { 12134 { BWN_B2063_RX_BB_SP8, 0x0 }, 12135 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12136 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12137 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12138 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12139 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12140 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12141 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12142 }; 12143 static const struct bwn_wpair v2[] = { 12144 { BWN_B2063_TX_BB_SP3, 0x0 }, 12145 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12146 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12147 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12148 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12149 }; 12150 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12151 int i; 12152 uint8_t tmp; 12153 12154 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12155 12156 for (i = 0; i < 2; i++) 12157 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12158 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12159 for (i = 2; i < N(v1); i++) 12160 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12161 for (i = 0; i < 10000; i++) { 12162 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12163 break; 12164 DELAY(1000); 12165 } 12166 12167 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12168 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12169 12170 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12171 12172 for (i = 0; i < N(v2); i++) 12173 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12174 if (freqxtal == 24000000) { 12175 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12176 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12177 } else { 12178 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12179 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12180 } 12181 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12182 for (i = 0; i < 10000; i++) { 12183 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12184 break; 12185 DELAY(1000); 12186 } 12187 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12188 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12189 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12190 } 12191 12192 static void 12193 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12194 { 12195 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12196 struct bwn_softc *sc = mac->mac_sc; 12197 struct bwn_phy_lp_iq_est ie; 12198 struct bwn_txgain tx_gains; 12199 static const uint32_t pwrtbl[21] = { 12200 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12201 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12202 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12203 0x0004c, 0x0002c, 0x0001a, 12204 }; 12205 uint32_t npwr, ipwr, sqpwr, tmp; 12206 int loopback, i, j, sum, error; 12207 uint16_t save[7]; 12208 uint8_t txo, bbmult, txpctlmode; 12209 12210 error = bwn_phy_lp_switch_channel(mac, 7); 12211 if (error) 12212 device_printf(sc->sc_dev, 12213 "failed to change channel to 7 (%d)\n", error); 12214 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12215 bbmult = bwn_phy_lp_get_bbmult(mac); 12216 if (txo) 12217 tx_gains = bwn_phy_lp_get_txgain(mac); 12218 12219 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12220 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12221 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12222 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12223 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12224 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12225 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12226 12227 bwn_phy_lp_get_txpctlmode(mac); 12228 txpctlmode = plp->plp_txpctlmode; 12229 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12230 12231 /* disable CRS */ 12232 bwn_phy_lp_set_deaf(mac, 1); 12233 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12234 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12235 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12236 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12237 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12238 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12239 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12240 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12241 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12242 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12243 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12244 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12245 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12246 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12247 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12248 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12249 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12250 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12251 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12252 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12253 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12254 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12255 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12256 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12257 12258 loopback = bwn_phy_lp_loopback(mac); 12259 if (loopback == -1) 12260 goto done; 12261 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12262 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12263 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12264 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12265 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12266 12267 tmp = 0; 12268 memset(&ie, 0, sizeof(ie)); 12269 for (i = 128; i <= 159; i++) { 12270 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12271 sum = 0; 12272 for (j = 5; j <= 25; j++) { 12273 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12274 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12275 goto done; 12276 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12277 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12278 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12279 12); 12280 sum += ((ipwr - npwr) * (ipwr - npwr)); 12281 if ((i == 128) || (sum < tmp)) { 12282 plp->plp_rccap = i; 12283 tmp = sum; 12284 } 12285 } 12286 } 12287 bwn_phy_lp_ddfs_turnoff(mac); 12288 done: 12289 /* restore CRS */ 12290 bwn_phy_lp_clear_deaf(mac, 1); 12291 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12292 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12293 12294 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12295 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12296 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12297 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12298 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12299 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12300 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12301 12302 bwn_phy_lp_set_bbmult(mac, bbmult); 12303 if (txo) 12304 bwn_phy_lp_set_txgain(mac, &tx_gains); 12305 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12306 if (plp->plp_rccap) 12307 bwn_phy_lp_set_rccap(mac); 12308 } 12309 12310 static void 12311 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12312 { 12313 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12314 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12315 12316 if (mac->mac_phy.rev == 1) 12317 rc_cap = MIN(rc_cap + 5, 15); 12318 12319 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12320 MAX(plp->plp_rccap - 4, 0x80)); 12321 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12322 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12323 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12324 } 12325 12326 static uint32_t 12327 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12328 { 12329 uint32_t i, q, r; 12330 12331 if (div == 0) 12332 return (0); 12333 12334 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12335 q <<= 1; 12336 if (r << 1 >= div) { 12337 q++; 12338 r = (r << 1) - div; 12339 } 12340 } 12341 if (r << 1 >= div) 12342 q++; 12343 return (q); 12344 } 12345 12346 static void 12347 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12348 { 12349 struct bwn_softc *sc = mac->mac_sc; 12350 12351 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12352 DELAY(20); 12353 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12354 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12355 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12356 } else { 12357 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12358 } 12359 DELAY(5); 12360 } 12361 12362 static void 12363 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12364 { 12365 12366 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12367 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12368 DELAY(200); 12369 } 12370 12371 static void 12372 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12373 { 12374 #define FLAG_A 0x01 12375 #define FLAG_G 0x02 12376 struct bwn_softc *sc = mac->mac_sc; 12377 struct ifnet *ifp = sc->sc_ifp; 12378 struct ieee80211com *ic = ifp->if_l2com; 12379 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12380 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12381 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12382 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12383 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12384 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12385 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12386 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12387 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12388 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12389 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12390 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12391 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12392 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12393 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12394 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12395 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12396 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12397 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12398 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12399 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12400 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12401 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12402 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12403 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12404 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12405 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12406 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12407 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12408 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12409 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12410 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12411 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12412 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12413 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12414 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12415 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12416 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12417 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12418 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12419 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12420 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12421 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12422 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12423 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12424 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12425 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12426 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12427 }; 12428 const struct bwn_b206x_rfinit_entry *br; 12429 unsigned int i; 12430 12431 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12432 br = &bwn_b2062_init_tab[i]; 12433 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12434 if (br->br_flags & FLAG_G) 12435 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12436 } else { 12437 if (br->br_flags & FLAG_A) 12438 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12439 } 12440 } 12441 #undef FLAG_A 12442 #undef FLAG_B 12443 } 12444 12445 static void 12446 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12447 { 12448 #define FLAG_A 0x01 12449 #define FLAG_G 0x02 12450 struct bwn_softc *sc = mac->mac_sc; 12451 struct ifnet *ifp = sc->sc_ifp; 12452 struct ieee80211com *ic = ifp->if_l2com; 12453 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12454 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12455 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12456 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12457 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12458 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12459 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12460 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12461 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12462 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12463 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12464 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12465 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12466 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12467 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12468 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12469 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12470 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12471 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12472 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12473 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12474 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12475 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12476 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12477 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12478 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12479 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12480 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12481 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12482 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12483 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12484 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12485 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12486 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12487 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12488 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12489 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12490 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12491 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12492 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12493 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12494 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12495 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12496 }; 12497 const struct bwn_b206x_rfinit_entry *br; 12498 unsigned int i; 12499 12500 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12501 br = &bwn_b2063_init_tab[i]; 12502 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12503 if (br->br_flags & FLAG_G) 12504 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12505 } else { 12506 if (br->br_flags & FLAG_A) 12507 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12508 } 12509 } 12510 #undef FLAG_A 12511 #undef FLAG_B 12512 } 12513 12514 static void 12515 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12516 int count, void *_data) 12517 { 12518 unsigned int i; 12519 uint32_t offset, type; 12520 uint8_t *data = _data; 12521 12522 type = BWN_TAB_GETTYPE(typenoffset); 12523 offset = BWN_TAB_GETOFFSET(typenoffset); 12524 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12525 12526 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12527 12528 for (i = 0; i < count; i++) { 12529 switch (type) { 12530 case BWN_TAB_8BIT: 12531 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12532 data++; 12533 break; 12534 case BWN_TAB_16BIT: 12535 *((uint16_t *)data) = BWN_PHY_READ(mac, 12536 BWN_PHY_TABLEDATALO); 12537 data += 2; 12538 break; 12539 case BWN_TAB_32BIT: 12540 *((uint32_t *)data) = BWN_PHY_READ(mac, 12541 BWN_PHY_TABLEDATAHI); 12542 *((uint32_t *)data) <<= 16; 12543 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12544 BWN_PHY_TABLEDATALO); 12545 data += 4; 12546 break; 12547 default: 12548 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12549 } 12550 } 12551 } 12552 12553 static void 12554 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12555 int count, const void *_data) 12556 { 12557 uint32_t offset, type, value; 12558 const uint8_t *data = _data; 12559 unsigned int i; 12560 12561 type = BWN_TAB_GETTYPE(typenoffset); 12562 offset = BWN_TAB_GETOFFSET(typenoffset); 12563 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12564 12565 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12566 12567 for (i = 0; i < count; i++) { 12568 switch (type) { 12569 case BWN_TAB_8BIT: 12570 value = *data; 12571 data++; 12572 KASSERT(!(value & ~0xff), 12573 ("%s:%d: fail", __func__, __LINE__)); 12574 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12575 break; 12576 case BWN_TAB_16BIT: 12577 value = *((const uint16_t *)data); 12578 data += 2; 12579 KASSERT(!(value & ~0xffff), 12580 ("%s:%d: fail", __func__, __LINE__)); 12581 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12582 break; 12583 case BWN_TAB_32BIT: 12584 value = *((const uint32_t *)data); 12585 data += 4; 12586 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12587 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12588 break; 12589 default: 12590 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12591 } 12592 } 12593 } 12594 12595 static struct bwn_txgain 12596 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12597 { 12598 struct bwn_txgain tg; 12599 uint16_t tmp; 12600 12601 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12602 if (mac->mac_phy.rev < 2) { 12603 tmp = BWN_PHY_READ(mac, 12604 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12605 tg.tg_gm = tmp & 0x0007; 12606 tg.tg_pga = (tmp & 0x0078) >> 3; 12607 tg.tg_pad = (tmp & 0x780) >> 7; 12608 return (tg); 12609 } 12610 12611 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12612 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12613 tg.tg_gm = tmp & 0xff; 12614 tg.tg_pga = (tmp >> 8) & 0xff; 12615 return (tg); 12616 } 12617 12618 static uint8_t 12619 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12620 { 12621 12622 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12623 } 12624 12625 static void 12626 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12627 { 12628 uint16_t pa; 12629 12630 if (mac->mac_phy.rev < 2) { 12631 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12632 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12633 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12634 bwn_phy_lp_set_txgain_override(mac); 12635 return; 12636 } 12637 12638 pa = bwn_phy_lp_get_pa_gain(mac); 12639 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12640 (tg->tg_pga << 8) | tg->tg_gm); 12641 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12642 tg->tg_pad | (pa << 6)); 12643 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12644 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12645 tg->tg_pad | (pa << 8)); 12646 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12647 bwn_phy_lp_set_txgain_override(mac); 12648 } 12649 12650 static void 12651 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12652 { 12653 12654 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12655 } 12656 12657 static void 12658 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12659 { 12660 uint16_t trsw = (tx << 1) | rx; 12661 12662 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12663 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12664 } 12665 12666 static void 12667 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12668 { 12669 struct bwn_softc *sc = mac->mac_sc; 12670 struct ifnet *ifp = sc->sc_ifp; 12671 struct ieee80211com *ic = ifp->if_l2com; 12672 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12673 12674 if (mac->mac_phy.rev < 2) { 12675 trsw = gain & 0x1; 12676 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12677 ext_lna = (gain & 2) >> 1; 12678 12679 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12680 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12681 0xfbff, ext_lna << 10); 12682 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12683 0xf7ff, ext_lna << 11); 12684 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12685 } else { 12686 low_gain = gain & 0xffff; 12687 high_gain = (gain >> 16) & 0xf; 12688 ext_lna = (gain >> 21) & 0x1; 12689 trsw = ~(gain >> 20) & 0x1; 12690 12691 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12692 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12693 0xfdff, ext_lna << 9); 12694 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12695 0xfbff, ext_lna << 10); 12696 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12697 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12698 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12699 tmp = (gain >> 2) & 0x3; 12700 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12701 0xe7ff, tmp<<11); 12702 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12703 tmp << 3); 12704 } 12705 } 12706 12707 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12708 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12709 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12710 if (mac->mac_phy.rev >= 2) { 12711 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12712 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12713 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12714 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12715 } 12716 return; 12717 } 12718 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12719 } 12720 12721 static void 12722 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12723 { 12724 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12725 12726 if (user) 12727 plp->plp_crsusr_off = 1; 12728 else 12729 plp->plp_crssys_off = 1; 12730 12731 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12732 } 12733 12734 static void 12735 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12736 { 12737 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12738 struct bwn_softc *sc = mac->mac_sc; 12739 struct ifnet *ifp = sc->sc_ifp; 12740 struct ieee80211com *ic = ifp->if_l2com; 12741 12742 if (user) 12743 plp->plp_crsusr_off = 0; 12744 else 12745 plp->plp_crssys_off = 0; 12746 12747 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12748 return; 12749 12750 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12751 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12752 else 12753 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12754 } 12755 12756 static unsigned int 12757 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12758 { 12759 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12760 static uint8_t sqrt_table[256] = { 12761 10, 14, 17, 20, 22, 24, 26, 28, 12762 30, 31, 33, 34, 36, 37, 38, 40, 12763 41, 42, 43, 44, 45, 46, 47, 48, 12764 50, 50, 51, 52, 53, 54, 55, 56, 12765 57, 58, 59, 60, 60, 61, 62, 63, 12766 64, 64, 65, 66, 67, 67, 68, 69, 12767 70, 70, 71, 72, 72, 73, 74, 74, 12768 75, 76, 76, 77, 78, 78, 79, 80, 12769 80, 81, 81, 82, 83, 83, 84, 84, 12770 85, 86, 86, 87, 87, 88, 88, 89, 12771 90, 90, 91, 91, 92, 92, 93, 93, 12772 94, 94, 95, 95, 96, 96, 97, 97, 12773 98, 98, 99, 100, 100, 100, 101, 101, 12774 102, 102, 103, 103, 104, 104, 105, 105, 12775 106, 106, 107, 107, 108, 108, 109, 109, 12776 110, 110, 110, 111, 111, 112, 112, 113, 12777 113, 114, 114, 114, 115, 115, 116, 116, 12778 117, 117, 117, 118, 118, 119, 119, 120, 12779 120, 120, 121, 121, 122, 122, 122, 123, 12780 123, 124, 124, 124, 125, 125, 126, 126, 12781 126, 127, 127, 128, 128, 128, 129, 129, 12782 130, 130, 130, 131, 131, 131, 132, 132, 12783 133, 133, 133, 134, 134, 134, 135, 135, 12784 136, 136, 136, 137, 137, 137, 138, 138, 12785 138, 139, 139, 140, 140, 140, 141, 141, 12786 141, 142, 142, 142, 143, 143, 143, 144, 12787 144, 144, 145, 145, 145, 146, 146, 146, 12788 147, 147, 147, 148, 148, 148, 149, 149, 12789 150, 150, 150, 150, 151, 151, 151, 152, 12790 152, 152, 153, 153, 153, 154, 154, 154, 12791 155, 155, 155, 156, 156, 156, 157, 157, 12792 157, 158, 158, 158, 159, 159, 159, 160 12793 }; 12794 12795 if (x == 0) 12796 return (0); 12797 if (x >= 256) { 12798 unsigned int tmp; 12799 12800 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12801 /* do nothing */ ; 12802 return (tmp); 12803 } 12804 return (sqrt_table[x - 1] / 10); 12805 } 12806 12807 static int 12808 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12809 { 12810 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12811 int _t; \ 12812 _t = _x - 20; \ 12813 if (_t >= 0) { \ 12814 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12815 } else { \ 12816 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12817 } \ 12818 } while (0) 12819 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12820 int _t; \ 12821 _t = _x - 11; \ 12822 if (_t >= 0) \ 12823 _v = (_y << (31 - _x)) / (_z >> _t); \ 12824 else \ 12825 _v = (_y << (31 - _x)) / (_z << -_t); \ 12826 } while (0) 12827 struct bwn_phy_lp_iq_est ie; 12828 uint16_t v0, v1; 12829 int tmp[2], ret; 12830 12831 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12832 v0 = v1 >> 8; 12833 v1 |= 0xff; 12834 12835 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12836 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12837 12838 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12839 if (ret == 0) 12840 goto done; 12841 12842 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12843 ret = 0; 12844 goto done; 12845 } 12846 12847 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12848 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12849 12850 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12851 v0 = tmp[0] >> 3; 12852 v1 = tmp[1] >> 4; 12853 done: 12854 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12855 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12856 return ret; 12857 #undef CALC_COEFF 12858 #undef CALC_COEFF2 12859 } 12860 12861 static void 12862 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12863 { 12864 static const uint16_t noisescale[] = { 12865 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12866 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12867 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12868 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12869 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12870 }; 12871 static const uint16_t crsgainnft[] = { 12872 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12873 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12874 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12875 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12876 0x013d, 12877 }; 12878 static const uint16_t filterctl[] = { 12879 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12880 0xff53, 0x0127, 12881 }; 12882 static const uint32_t psctl[] = { 12883 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12884 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12885 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12886 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12887 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12888 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12889 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12890 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12891 }; 12892 static const uint16_t ofdmcckgain_r0[] = { 12893 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12894 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12895 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12896 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12897 0x755d, 12898 }; 12899 static const uint16_t ofdmcckgain_r1[] = { 12900 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12901 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12902 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12903 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12904 0x755d, 12905 }; 12906 static const uint16_t gaindelta[] = { 12907 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12908 0x0000, 12909 }; 12910 static const uint32_t txpwrctl[] = { 12911 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12912 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12913 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12914 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12915 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12916 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12917 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12918 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12919 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12920 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12921 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12922 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12923 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12924 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12925 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12926 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12939 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12940 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12941 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12947 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12948 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12949 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12950 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12951 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12952 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12953 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12954 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12955 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12956 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12957 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12958 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12959 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12960 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12961 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12962 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12963 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12964 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12965 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12966 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12967 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12968 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12969 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12970 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12971 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12972 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12973 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12974 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12975 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12976 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12977 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12978 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12979 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12980 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12981 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12982 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12983 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12984 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12985 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12986 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12987 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12988 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12989 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12990 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12991 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12992 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12993 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12994 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12995 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12996 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12997 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12998 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12999 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13000 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13001 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13002 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13003 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13004 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13005 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13006 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13007 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13008 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13009 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13010 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13011 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13012 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13013 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13014 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13015 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13016 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13017 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13018 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13019 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13020 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13021 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13022 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13023 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13024 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13025 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13026 0x00000702, 13027 }; 13028 13029 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13030 13031 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13032 bwn_tab_sigsq_tbl); 13033 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13034 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13035 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13036 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13037 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13038 bwn_tab_pllfrac_tbl); 13039 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13040 bwn_tabl_iqlocal_tbl); 13041 if (mac->mac_phy.rev == 0) { 13042 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13043 ofdmcckgain_r0); 13044 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13045 ofdmcckgain_r0); 13046 } else { 13047 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13048 ofdmcckgain_r1); 13049 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13050 ofdmcckgain_r1); 13051 } 13052 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13053 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13054 } 13055 13056 static void 13057 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13058 { 13059 struct bwn_softc *sc = mac->mac_sc; 13060 int i; 13061 static const uint16_t noisescale[] = { 13062 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13063 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13064 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13065 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13066 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13067 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13068 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13069 }; 13070 static const uint32_t filterctl[] = { 13071 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13072 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13073 }; 13074 static const uint32_t psctl[] = { 13075 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13076 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13077 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13078 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13079 }; 13080 static const uint32_t gainidx[] = { 13081 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13083 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13084 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13085 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13086 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13087 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13088 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13089 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13090 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13091 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13092 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13093 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13094 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13095 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13096 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13097 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13098 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13099 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13100 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13101 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13102 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13103 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13104 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13105 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13106 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13107 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13108 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13109 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13110 0x0000001a, 0x64ca55ad, 0x0000001a 13111 }; 13112 static const uint16_t auxgainidx[] = { 13113 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13114 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13115 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13116 0x0004, 0x0016 13117 }; 13118 static const uint16_t swctl[] = { 13119 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13120 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13121 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13122 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13123 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13124 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13125 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13126 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13127 }; 13128 static const uint8_t hf[] = { 13129 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13130 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13131 }; 13132 static const uint32_t gainval[] = { 13133 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13134 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13135 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13136 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13137 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13138 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13139 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13141 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13142 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13143 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13144 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13145 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13146 0x000000f1, 0x00000000, 0x00000000 13147 }; 13148 static const uint16_t gain[] = { 13149 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13150 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13151 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13152 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13153 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13154 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13155 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13156 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13157 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13158 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13159 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13160 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13161 }; 13162 static const uint32_t papdeps[] = { 13163 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13164 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13165 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13166 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13167 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13168 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13169 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13170 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13171 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13172 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13173 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13174 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13175 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13176 }; 13177 static const uint32_t papdmult[] = { 13178 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13179 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13180 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13181 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13182 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13183 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13184 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13185 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13186 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13187 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13188 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13189 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13190 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13191 }; 13192 static const uint32_t gainidx_a0[] = { 13193 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13194 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13195 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13196 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13197 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13198 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13199 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13200 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13201 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13202 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13203 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13204 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13205 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13206 }; 13207 static const uint16_t auxgainidx_a0[] = { 13208 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13209 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13210 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13211 0x0002, 0x0014 13212 }; 13213 static const uint32_t gainval_a0[] = { 13214 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13215 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13216 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13217 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13218 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13219 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13220 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13222 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13224 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13225 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13226 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13227 0x000000f7, 0x00000000, 0x00000000 13228 }; 13229 static const uint16_t gain_a0[] = { 13230 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13231 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13232 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13233 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13234 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13235 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13236 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13237 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13238 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13239 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13240 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13241 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13242 }; 13243 13244 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13245 13246 for (i = 0; i < 704; i++) 13247 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13248 13249 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13250 bwn_tab_sigsq_tbl); 13251 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13252 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13253 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13254 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13255 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13256 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13257 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13258 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13259 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13260 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13261 bwn_tab_pllfrac_tbl); 13262 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13263 bwn_tabl_iqlocal_tbl); 13264 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13265 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13266 13267 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13268 (siba_get_chiprev(sc->sc_dev) == 0)) { 13269 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13270 gainidx_a0); 13271 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13272 auxgainidx_a0); 13273 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13274 gainval_a0); 13275 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13276 } 13277 } 13278 13279 static void 13280 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13281 { 13282 struct bwn_softc *sc = mac->mac_sc; 13283 struct ifnet *ifp = sc->sc_ifp; 13284 struct ieee80211com *ic = ifp->if_l2com; 13285 static struct bwn_txgain_entry txgain_r2[] = { 13286 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13287 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13288 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13289 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13290 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13291 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13292 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13293 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13294 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13295 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13296 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13297 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13298 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13299 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13300 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13301 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13302 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13303 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13304 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13305 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13306 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13307 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13308 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13309 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13310 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13311 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13312 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13313 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13314 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13315 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13316 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13317 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13318 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13319 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13320 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13321 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13322 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13323 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13324 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13325 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13326 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13327 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13328 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13329 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13330 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13331 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13332 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13333 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13334 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13335 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13336 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13337 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13338 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13339 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13340 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13341 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13342 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13343 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13344 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13345 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13346 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13347 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13348 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13349 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13350 }; 13351 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13352 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13353 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13354 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13355 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13356 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13357 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13358 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13359 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13360 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13361 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13362 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13363 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13364 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13365 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13366 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13367 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13368 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13369 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13370 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13371 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13372 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13373 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13374 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13375 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13376 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13377 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13378 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13379 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13380 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13381 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13382 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13383 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13384 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13385 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13386 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13387 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13388 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13389 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13390 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13391 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13392 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13393 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13394 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13395 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13396 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13397 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13398 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13399 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13400 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13401 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13402 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13403 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13404 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13405 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13406 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13407 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13408 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13409 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13410 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13411 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13412 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13413 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13414 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13415 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13416 }; 13417 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13418 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13419 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13420 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13421 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13422 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13423 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13424 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13425 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13426 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13427 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13428 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13429 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13430 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13431 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13432 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13433 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13434 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13435 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13436 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13437 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13438 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13439 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13440 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13441 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13442 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13443 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13444 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13445 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13446 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13447 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13448 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13449 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13450 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13451 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13452 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13453 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13454 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13455 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13456 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13457 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13458 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13459 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13460 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13461 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13462 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13463 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13464 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13465 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13466 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13467 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13468 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13469 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13470 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13471 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13472 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13473 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13474 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13475 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13476 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13477 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13478 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13479 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13480 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13481 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13482 }; 13483 static struct bwn_txgain_entry txgain_r0[] = { 13484 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13485 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13486 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13487 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13488 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13489 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13490 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13491 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13492 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13493 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13494 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13495 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13496 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13497 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13498 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13499 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13500 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13501 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13502 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13503 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13504 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13505 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13506 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13507 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13508 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13509 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13510 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13511 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13512 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13513 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13514 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13515 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13516 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13517 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13518 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13519 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13520 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13521 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13522 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13523 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13524 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13525 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13526 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13527 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13528 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13529 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13530 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13531 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13532 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13533 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13534 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13535 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13536 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13537 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13538 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13539 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13540 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13541 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13542 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13543 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13544 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13545 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13546 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13547 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13548 }; 13549 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13550 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13551 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13552 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13553 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13554 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13555 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13556 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13557 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13558 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13559 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13560 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13561 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13562 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13563 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13564 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13565 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13566 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13567 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13568 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13569 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13570 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13571 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13572 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13573 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13574 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13575 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13576 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13577 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13578 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13579 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13580 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13581 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13582 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13583 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13584 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13585 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13586 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13587 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13588 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13589 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13590 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13591 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13592 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13593 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13594 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13595 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13596 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13597 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13598 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13599 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13600 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13601 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13602 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13603 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13604 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13605 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13606 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13607 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13608 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13609 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13610 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13611 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13612 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13613 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13614 }; 13615 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13616 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13617 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13618 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13619 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13620 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13621 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13622 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13623 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13624 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13625 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13626 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13627 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13628 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13629 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13630 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13631 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13632 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13633 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13634 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13635 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13636 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13637 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13638 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13639 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13640 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13641 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13642 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13643 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13644 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13645 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13646 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13647 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13648 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13649 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13650 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13651 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13652 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13653 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13654 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13655 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13656 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13657 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13658 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13659 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13660 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13661 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13662 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13663 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13664 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13665 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13666 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13667 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13668 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13669 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13670 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13671 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13672 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13673 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13674 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13675 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13676 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13677 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13678 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13679 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13680 }; 13681 static struct bwn_txgain_entry txgain_r1[] = { 13682 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13683 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13684 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13685 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13686 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13687 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13688 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13689 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13690 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13691 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13692 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13693 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13694 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13695 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13696 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13697 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13698 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13699 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13700 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13701 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13702 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13703 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13704 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13705 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13706 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13707 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13708 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13709 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13710 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13711 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13712 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13713 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13714 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13715 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13716 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13717 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13718 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13719 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13720 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13721 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13722 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13723 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13724 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13725 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13726 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13727 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13728 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13729 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13730 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13731 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13732 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13733 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13734 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13735 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13736 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13737 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13738 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13739 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13740 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13741 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13742 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13743 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13744 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13745 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13746 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13747 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13748 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13749 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13750 { 7, 11, 6, 0, 71 } 13751 }; 13752 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13753 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13754 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13755 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13756 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13757 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13758 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13759 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13760 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13761 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13762 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13763 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13764 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13765 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13766 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13767 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13768 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13769 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13770 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13771 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13772 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13773 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13774 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13775 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13776 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13777 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13778 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13779 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13780 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13781 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13782 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13783 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13784 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13785 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13786 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13787 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13788 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13789 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13790 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13791 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13792 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13793 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13794 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13795 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13796 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13797 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13798 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13799 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13800 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13801 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13802 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13803 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13804 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13805 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13806 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13807 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13808 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13809 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13810 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13811 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13812 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13813 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13814 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13815 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13816 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13817 }; 13818 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13819 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13820 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13821 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13822 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13823 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13824 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13825 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13826 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13827 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13828 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13829 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13830 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13831 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13832 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13833 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13834 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13835 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13836 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13837 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13838 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13839 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13840 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13841 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13842 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13843 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13844 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13845 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13846 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13847 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13848 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13849 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13850 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13851 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13852 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13853 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13854 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13855 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13856 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13857 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13858 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13859 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13860 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13861 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13862 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13863 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13864 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13865 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13866 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13867 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13868 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13869 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13870 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13871 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13872 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13873 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13874 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13875 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13876 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13877 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13878 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13879 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13880 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13881 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13882 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13883 }; 13884 13885 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13886 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13887 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13888 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13889 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13890 txgain_2ghz_r2); 13891 else 13892 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13893 txgain_5ghz_r2); 13894 return; 13895 } 13896 13897 if (mac->mac_phy.rev == 0) { 13898 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13899 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13900 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13901 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13902 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13903 txgain_2ghz_r0); 13904 else 13905 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13906 txgain_5ghz_r0); 13907 return; 13908 } 13909 13910 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13911 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13912 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13913 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13914 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13915 else 13916 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13917 } 13918 13919 static void 13920 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13921 { 13922 uint32_t offset, type; 13923 13924 type = BWN_TAB_GETTYPE(typeoffset); 13925 offset = BWN_TAB_GETOFFSET(typeoffset); 13926 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13927 13928 switch (type) { 13929 case BWN_TAB_8BIT: 13930 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13931 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13932 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13933 break; 13934 case BWN_TAB_16BIT: 13935 KASSERT(!(value & ~0xffff), 13936 ("%s:%d: fail", __func__, __LINE__)); 13937 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13938 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13939 break; 13940 case BWN_TAB_32BIT: 13941 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13942 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13943 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13944 break; 13945 default: 13946 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13947 } 13948 } 13949 13950 static int 13951 bwn_phy_lp_loopback(struct bwn_mac *mac) 13952 { 13953 struct bwn_phy_lp_iq_est ie; 13954 int i, index = -1; 13955 uint32_t tmp; 13956 13957 memset(&ie, 0, sizeof(ie)); 13958 13959 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13960 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13961 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13962 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13964 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13965 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13966 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13967 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13968 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13969 for (i = 0; i < 32; i++) { 13970 bwn_phy_lp_set_rxgain_idx(mac, i); 13971 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13972 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13973 continue; 13974 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13975 if ((tmp > 4000) && (tmp < 10000)) { 13976 index = i; 13977 break; 13978 } 13979 } 13980 bwn_phy_lp_ddfs_turnoff(mac); 13981 return (index); 13982 } 13983 13984 static void 13985 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13986 { 13987 13988 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13989 } 13990 13991 static void 13992 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13993 int incr1, int incr2, int scale_idx) 13994 { 13995 13996 bwn_phy_lp_ddfs_turnoff(mac); 13997 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13998 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13999 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 14000 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14003 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14004 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14005 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14006 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14007 } 14008 14009 static uint8_t 14010 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14011 struct bwn_phy_lp_iq_est *ie) 14012 { 14013 int i; 14014 14015 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14016 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14017 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14018 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14019 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14020 14021 for (i = 0; i < 500; i++) { 14022 if (!(BWN_PHY_READ(mac, 14023 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14024 break; 14025 DELAY(1000); 14026 } 14027 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14028 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14029 return 0; 14030 } 14031 14032 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14033 ie->ie_iqprod <<= 16; 14034 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14035 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14036 ie->ie_ipwr <<= 16; 14037 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14038 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14039 ie->ie_qpwr <<= 16; 14040 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14041 14042 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14043 return 1; 14044 } 14045 14046 static uint32_t 14047 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14048 { 14049 uint32_t offset, type, value; 14050 14051 type = BWN_TAB_GETTYPE(typeoffset); 14052 offset = BWN_TAB_GETOFFSET(typeoffset); 14053 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14054 14055 switch (type) { 14056 case BWN_TAB_8BIT: 14057 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14058 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14059 break; 14060 case BWN_TAB_16BIT: 14061 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14062 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14063 break; 14064 case BWN_TAB_32BIT: 14065 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14066 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14067 value <<= 16; 14068 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14069 break; 14070 default: 14071 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14072 value = 0; 14073 } 14074 14075 return (value); 14076 } 14077 14078 static void 14079 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14080 { 14081 14082 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14083 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14084 } 14085 14086 static void 14087 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14088 { 14089 uint16_t ctl; 14090 14091 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14092 ctl |= dac << 7; 14093 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14094 } 14095 14096 static void 14097 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14098 { 14099 14100 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14101 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14102 } 14103 14104 static void 14105 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14106 { 14107 14108 if (mac->mac_phy.rev < 2) 14109 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14110 else { 14111 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14112 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14113 } 14114 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14115 } 14116 14117 static uint16_t 14118 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14119 { 14120 14121 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14122 } 14123 14124 static uint8_t 14125 bwn_nbits(int32_t val) 14126 { 14127 uint32_t tmp; 14128 uint8_t nbits = 0; 14129 14130 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14131 nbits++; 14132 return (nbits); 14133 } 14134 14135 static void 14136 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14137 struct bwn_txgain_entry *table) 14138 { 14139 int i; 14140 14141 for (i = offset; i < count; i++) 14142 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14143 } 14144 14145 static void 14146 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14147 struct bwn_txgain_entry data) 14148 { 14149 14150 if (mac->mac_phy.rev >= 2) 14151 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14152 else 14153 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14154 } 14155 14156 static void 14157 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14158 struct bwn_txgain_entry te) 14159 { 14160 struct bwn_softc *sc = mac->mac_sc; 14161 struct ifnet *ifp = sc->sc_ifp; 14162 struct ieee80211com *ic = ifp->if_l2com; 14163 uint32_t tmp; 14164 14165 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14166 14167 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14168 if (mac->mac_phy.rev >= 3) { 14169 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14170 (0x10 << 24) : (0x70 << 24)); 14171 } else { 14172 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14173 (0x14 << 24) : (0x7f << 24)); 14174 } 14175 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14176 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14177 te.te_bbmult << 20 | te.te_dac << 28); 14178 } 14179 14180 static void 14181 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14182 struct bwn_txgain_entry te) 14183 { 14184 14185 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14186 14187 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14188 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14189 te.te_dac); 14190 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14191 } 14192 14193 static void 14194 bwn_sysctl_node(struct bwn_softc *sc) 14195 { 14196 device_t dev = sc->sc_dev; 14197 struct bwn_mac *mac; 14198 struct bwn_stats *stats; 14199 14200 /* XXX assume that count of MAC is only 1. */ 14201 14202 if ((mac = sc->sc_curmac) == NULL) 14203 return; 14204 stats = &mac->mac_stats; 14205 14206 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14207 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14208 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14209 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14210 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14211 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14212 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14213 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14214 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14215 14216 #ifdef BWN_DEBUG 14217 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14218 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14219 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14220 #endif 14221 } 14222 14223 static device_method_t bwn_methods[] = { 14224 /* Device interface */ 14225 DEVMETHOD(device_probe, bwn_probe), 14226 DEVMETHOD(device_attach, bwn_attach), 14227 DEVMETHOD(device_detach, bwn_detach), 14228 DEVMETHOD(device_suspend, bwn_suspend), 14229 DEVMETHOD(device_resume, bwn_resume), 14230 DEVMETHOD_END 14231 }; 14232 static driver_t bwn_driver = { 14233 "bwn", 14234 bwn_methods, 14235 sizeof(struct bwn_softc) 14236 }; 14237 static devclass_t bwn_devclass; 14238 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14239 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14240 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14241 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14242 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14243