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/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/module.h> 42 #include <sys/endian.h> 43 #include <sys/errno.h> 44 #include <sys/firmware.h> 45 #include <sys/lock.h> 46 #include <sys/mutex.h> 47 #include <machine/bus.h> 48 #include <machine/resource.h> 49 #include <sys/bus.h> 50 #include <sys/rman.h> 51 #include <sys/socket.h> 52 #include <sys/sockio.h> 53 54 #include <net/ethernet.h> 55 #include <net/if.h> 56 #include <net/if_var.h> 57 #include <net/if_arp.h> 58 #include <net/if_dl.h> 59 #include <net/if_llc.h> 60 #include <net/if_media.h> 61 #include <net/if_types.h> 62 63 #include <dev/pci/pcivar.h> 64 #include <dev/pci/pcireg.h> 65 #include <dev/siba/siba_ids.h> 66 #include <dev/siba/sibareg.h> 67 #include <dev/siba/sibavar.h> 68 69 #include <net80211/ieee80211_var.h> 70 #include <net80211/ieee80211_radiotap.h> 71 #include <net80211/ieee80211_regdomain.h> 72 #include <net80211/ieee80211_phy.h> 73 #include <net80211/ieee80211_ratectl.h> 74 75 #include <dev/bwn/if_bwnreg.h> 76 #include <dev/bwn/if_bwnvar.h> 77 78 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, 79 "Broadcom driver parameters"); 80 81 /* 82 * Tunable & sysctl variables. 83 */ 84 85 #ifdef BWN_DEBUG 86 static int bwn_debug = 0; 87 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0, 88 "Broadcom debugging printfs"); 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 void 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 int bwn_init(struct bwn_softc *); 141 static void bwn_parent(struct ieee80211com *); 142 static void bwn_start(struct bwn_softc *); 143 static int bwn_transmit(struct ieee80211com *, struct mbuf *); 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 ieee80211com *); 186 static void bwn_update_promisc(struct ieee80211com *); 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 *); 202 static int bwn_core_init(struct bwn_mac *); 203 static void bwn_core_start(struct bwn_mac *); 204 static void bwn_core_exit(struct bwn_mac *); 205 static void bwn_bt_disable(struct bwn_mac *); 206 static int bwn_chip_init(struct bwn_mac *); 207 static uint64_t bwn_hf_read(struct bwn_mac *); 208 static void bwn_hf_write(struct bwn_mac *, uint64_t); 209 static void bwn_set_txretry(struct bwn_mac *, int, int); 210 static void bwn_rate_init(struct bwn_mac *); 211 static void bwn_set_phytxctl(struct bwn_mac *); 212 static void bwn_spu_setdelay(struct bwn_mac *, int); 213 static void bwn_bt_enable(struct bwn_mac *); 214 static void bwn_set_macaddr(struct bwn_mac *); 215 static void bwn_crypt_init(struct bwn_mac *); 216 static void bwn_chip_exit(struct bwn_mac *); 217 static int bwn_fw_fillinfo(struct bwn_mac *); 218 static int bwn_fw_loaducode(struct bwn_mac *); 219 static int bwn_gpio_init(struct bwn_mac *); 220 static int bwn_fw_loadinitvals(struct bwn_mac *); 221 static int bwn_phy_init(struct bwn_mac *); 222 static void bwn_set_txantenna(struct bwn_mac *, int); 223 static void bwn_set_opmode(struct bwn_mac *); 224 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 225 static uint8_t bwn_plcp_getcck(const uint8_t); 226 static uint8_t bwn_plcp_getofdm(const uint8_t); 227 static void bwn_pio_init(struct bwn_mac *); 228 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 229 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 230 int); 231 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 232 struct bwn_pio_rxqueue *, int); 233 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 234 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 235 uint16_t); 236 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 237 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 238 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 239 static void bwn_pio_handle_txeof(struct bwn_mac *, 240 const struct bwn_txstatus *); 241 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 242 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 243 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 244 uint16_t); 245 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 246 uint32_t); 247 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 248 struct mbuf *); 249 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 250 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 251 struct bwn_pio_txqueue *, uint32_t, const void *, int); 252 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 253 uint16_t, uint32_t); 254 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 255 struct bwn_pio_txqueue *, uint16_t, const void *, int); 256 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 257 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 258 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 259 uint16_t, struct bwn_pio_txpkt **); 260 static void bwn_dma_init(struct bwn_mac *); 261 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 262 static int bwn_dma_mask2type(uint64_t); 263 static uint64_t bwn_dma_mask(struct bwn_mac *); 264 static uint16_t bwn_dma_base(int, int); 265 static void bwn_dma_ringfree(struct bwn_dma_ring **); 266 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 267 int, struct bwn_dmadesc_generic **, 268 struct bwn_dmadesc_meta **); 269 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 270 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 271 int, int); 272 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 273 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 274 static void bwn_dma_32_resume(struct bwn_dma_ring *); 275 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 276 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 277 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 278 int, struct bwn_dmadesc_generic **, 279 struct bwn_dmadesc_meta **); 280 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 281 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 282 int, int); 283 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 284 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 285 static void bwn_dma_64_resume(struct bwn_dma_ring *); 286 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 287 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 288 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 289 static void bwn_dma_setup(struct bwn_dma_ring *); 290 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 291 static void bwn_dma_cleanup(struct bwn_dma_ring *); 292 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 293 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 294 static void bwn_dma_rx(struct bwn_dma_ring *); 295 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 296 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 297 struct bwn_dmadesc_meta *); 298 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 299 static int bwn_dma_gettype(struct bwn_mac *); 300 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 301 static int bwn_dma_freeslot(struct bwn_dma_ring *); 302 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 303 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 304 static int bwn_dma_newbuf(struct bwn_dma_ring *, 305 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 306 int); 307 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 308 bus_size_t, int); 309 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 310 static void bwn_dma_handle_txeof(struct bwn_mac *, 311 const struct bwn_txstatus *); 312 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 313 struct mbuf *); 314 static int bwn_dma_getslot(struct bwn_dma_ring *); 315 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 316 uint8_t); 317 static int bwn_dma_attach(struct bwn_mac *); 318 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 319 int, int, int); 320 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 321 const struct bwn_txstatus *, uint16_t, int *); 322 static void bwn_dma_free(struct bwn_mac *); 323 static void bwn_phy_g_init_sub(struct bwn_mac *); 324 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 325 static void bwn_phy_init_b5(struct bwn_mac *); 326 static void bwn_phy_init_b6(struct bwn_mac *); 327 static void bwn_phy_init_a(struct bwn_mac *); 328 static void bwn_loopback_calcgain(struct bwn_mac *); 329 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 330 static void bwn_lo_g_init(struct bwn_mac *); 331 static void bwn_lo_g_adjust(struct bwn_mac *); 332 static void bwn_lo_get_powervector(struct bwn_mac *); 333 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 334 const struct bwn_bbatt *, const struct bwn_rfatt *); 335 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 336 static void bwn_phy_hwpctl_init(struct bwn_mac *); 337 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 338 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 339 const struct bwn_bbatt *, const struct bwn_rfatt *, 340 uint8_t); 341 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 342 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 343 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 344 static void bwn_wa_init(struct bwn_mac *); 345 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 346 uint16_t); 347 static void bwn_dummy_transmission(struct bwn_mac *, int, int); 348 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 349 uint32_t); 350 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 351 uint16_t); 352 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 353 static void bwn_mac_suspend(struct bwn_mac *); 354 static void bwn_mac_enable(struct bwn_mac *); 355 static void bwn_psctl(struct bwn_mac *, uint32_t); 356 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 357 static void bwn_nrssi_offset(struct bwn_mac *); 358 static void bwn_nrssi_threshold(struct bwn_mac *); 359 static void bwn_nrssi_slope_11g(struct bwn_mac *); 360 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 361 int16_t); 362 static void bwn_set_original_gains(struct bwn_mac *); 363 static void bwn_hwpctl_early_init(struct bwn_mac *); 364 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 365 static uint16_t bwn_phy_g_chan2freq(uint8_t); 366 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 367 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 368 const char *, struct bwn_fwfile *); 369 static void bwn_release_firmware(struct bwn_mac *); 370 static void bwn_do_release_fw(struct bwn_fwfile *); 371 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 372 static int bwn_fwinitvals_write(struct bwn_mac *, 373 const struct bwn_fwinitvals *, size_t, size_t); 374 static int bwn_switch_channel(struct bwn_mac *, int); 375 static uint16_t bwn_ant2phy(int); 376 static void bwn_mac_write_bssid(struct bwn_mac *); 377 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 378 const uint8_t *); 379 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 380 const uint8_t *, size_t, const uint8_t *); 381 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 382 const uint8_t *); 383 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 384 const uint8_t *); 385 static void bwn_phy_exit(struct bwn_mac *); 386 static void bwn_core_stop(struct bwn_mac *); 387 static int bwn_switch_band(struct bwn_softc *, 388 struct ieee80211_channel *); 389 static void bwn_phy_reset(struct bwn_mac *); 390 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 391 static void bwn_set_pretbtt(struct bwn_mac *); 392 static int bwn_intr(void *); 393 static void bwn_intrtask(void *, int); 394 static void bwn_restart(struct bwn_mac *, const char *); 395 static void bwn_intr_ucode_debug(struct bwn_mac *); 396 static void bwn_intr_tbtt_indication(struct bwn_mac *); 397 static void bwn_intr_atim_end(struct bwn_mac *); 398 static void bwn_intr_beacon(struct bwn_mac *); 399 static void bwn_intr_pmq(struct bwn_mac *); 400 static void bwn_intr_noise(struct bwn_mac *); 401 static void bwn_intr_txeof(struct bwn_mac *); 402 static void bwn_hwreset(void *, int); 403 static void bwn_handle_fwpanic(struct bwn_mac *); 404 static void bwn_load_beacon0(struct bwn_mac *); 405 static void bwn_load_beacon1(struct bwn_mac *); 406 static uint32_t bwn_jssi_read(struct bwn_mac *); 407 static void bwn_noise_gensample(struct bwn_mac *); 408 static void bwn_handle_txeof(struct bwn_mac *, 409 const struct bwn_txstatus *); 410 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 411 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 412 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 413 struct mbuf *); 414 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 415 static int bwn_set_txhdr(struct bwn_mac *, 416 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 417 uint16_t); 418 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 419 const uint8_t); 420 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 421 static uint8_t bwn_get_fbrate(uint8_t); 422 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 423 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 424 static void bwn_phy_lock(struct bwn_mac *); 425 static void bwn_phy_unlock(struct bwn_mac *); 426 static void bwn_rf_lock(struct bwn_mac *); 427 static void bwn_rf_unlock(struct bwn_mac *); 428 static void bwn_txpwr(void *, int); 429 static void bwn_tasks(void *); 430 static void bwn_task_15s(struct bwn_mac *); 431 static void bwn_task_30s(struct bwn_mac *); 432 static void bwn_task_60s(struct bwn_mac *); 433 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 434 uint8_t); 435 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 436 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 437 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 438 int, int); 439 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 440 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 441 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 442 static void bwn_watchdog(void *); 443 static void bwn_dma_stop(struct bwn_mac *); 444 static void bwn_pio_stop(struct bwn_mac *); 445 static void bwn_dma_ringstop(struct bwn_dma_ring **); 446 static void bwn_led_attach(struct bwn_mac *); 447 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 448 static void bwn_led_event(struct bwn_mac *, int); 449 static void bwn_led_blink_start(struct bwn_mac *, int, int); 450 static void bwn_led_blink_next(void *); 451 static void bwn_led_blink_end(void *); 452 static void bwn_rfswitch(void *); 453 static void bwn_rf_turnon(struct bwn_mac *); 454 static void bwn_rf_turnoff(struct bwn_mac *); 455 static void bwn_phy_lp_init_pre(struct bwn_mac *); 456 static int bwn_phy_lp_init(struct bwn_mac *); 457 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 458 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 459 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 460 uint16_t); 461 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 462 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 463 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 464 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 465 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 466 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 467 static void bwn_phy_lp_task_60s(struct bwn_mac *); 468 static void bwn_phy_lp_readsprom(struct bwn_mac *); 469 static void bwn_phy_lp_bbinit(struct bwn_mac *); 470 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 471 static void bwn_phy_lp_calib(struct bwn_mac *); 472 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 473 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 474 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 475 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 476 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 477 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 478 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 479 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 480 static void bwn_phy_lp_bugfix(struct bwn_mac *); 481 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 482 static void bwn_phy_lp_tblinit(struct bwn_mac *); 483 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 484 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 485 static void bwn_phy_lp_b2062_init(struct bwn_mac *); 486 static void bwn_phy_lp_b2063_init(struct bwn_mac *); 487 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 488 static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 489 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 490 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 491 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 492 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 493 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 494 const void *); 495 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 496 static struct bwn_txgain 497 bwn_phy_lp_get_txgain(struct bwn_mac *); 498 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 499 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 500 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 501 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 502 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 503 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 504 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 505 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 506 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 507 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 508 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 509 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 510 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 511 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 512 static int bwn_phy_lp_loopback(struct bwn_mac *); 513 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 514 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 515 int); 516 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 517 struct bwn_phy_lp_iq_est *); 518 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 519 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 520 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 521 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 522 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 523 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 524 static uint8_t bwn_nbits(int32_t); 525 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 526 struct bwn_txgain_entry *); 527 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 528 struct bwn_txgain_entry); 529 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 530 struct bwn_txgain_entry); 531 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 532 struct bwn_txgain_entry); 533 static void bwn_sysctl_node(struct bwn_softc *); 534 535 static struct resource_spec bwn_res_spec_legacy[] = { 536 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 537 { -1, 0, 0 } 538 }; 539 540 static struct resource_spec bwn_res_spec_msi[] = { 541 { SYS_RES_IRQ, 1, RF_ACTIVE }, 542 { -1, 0, 0 } 543 }; 544 545 static const struct bwn_channelinfo bwn_chantable_bg = { 546 .channels = { 547 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 548 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 549 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 550 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 551 { 2472, 13, 30 }, { 2484, 14, 30 } }, 552 .nchannels = 14 553 }; 554 555 static const struct bwn_channelinfo bwn_chantable_a = { 556 .channels = { 557 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 558 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 559 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 560 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 561 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 562 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 563 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 564 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 565 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 566 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 567 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 568 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 569 { 6080, 216, 30 } }, 570 .nchannels = 37 571 }; 572 573 static const struct bwn_channelinfo bwn_chantable_n = { 574 .channels = { 575 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 576 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 577 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 578 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 579 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 580 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 581 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 582 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 583 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 584 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 585 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 586 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 587 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 588 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 589 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 590 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 591 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 592 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 593 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 594 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 595 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 596 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 597 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 598 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 599 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 600 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 601 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 602 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 603 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 604 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 605 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 606 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 607 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 608 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 609 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 610 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 611 { 6130, 226, 30 }, { 6140, 228, 30 } }, 612 .nchannels = 110 613 }; 614 615 static const uint8_t bwn_b2063_chantable_data[33][12] = { 616 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 617 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 618 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 619 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 620 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 621 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 622 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 623 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 624 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 625 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 626 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 627 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 628 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 629 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 630 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 631 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 632 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 633 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 634 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 635 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 636 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 637 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 638 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 639 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 640 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 641 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 642 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 643 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 646 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 647 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 648 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 649 }; 650 651 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 652 { 1, 2412, bwn_b2063_chantable_data[0] }, 653 { 2, 2417, bwn_b2063_chantable_data[0] }, 654 { 3, 2422, bwn_b2063_chantable_data[0] }, 655 { 4, 2427, bwn_b2063_chantable_data[1] }, 656 { 5, 2432, bwn_b2063_chantable_data[1] }, 657 { 6, 2437, bwn_b2063_chantable_data[1] }, 658 { 7, 2442, bwn_b2063_chantable_data[1] }, 659 { 8, 2447, bwn_b2063_chantable_data[1] }, 660 { 9, 2452, bwn_b2063_chantable_data[2] }, 661 { 10, 2457, bwn_b2063_chantable_data[2] }, 662 { 11, 2462, bwn_b2063_chantable_data[3] }, 663 { 12, 2467, bwn_b2063_chantable_data[3] }, 664 { 13, 2472, bwn_b2063_chantable_data[3] }, 665 { 14, 2484, bwn_b2063_chantable_data[4] }, 666 { 34, 5170, bwn_b2063_chantable_data[5] }, 667 { 36, 5180, bwn_b2063_chantable_data[6] }, 668 { 38, 5190, bwn_b2063_chantable_data[7] }, 669 { 40, 5200, bwn_b2063_chantable_data[8] }, 670 { 42, 5210, bwn_b2063_chantable_data[9] }, 671 { 44, 5220, bwn_b2063_chantable_data[10] }, 672 { 46, 5230, bwn_b2063_chantable_data[11] }, 673 { 48, 5240, bwn_b2063_chantable_data[12] }, 674 { 52, 5260, bwn_b2063_chantable_data[13] }, 675 { 56, 5280, bwn_b2063_chantable_data[14] }, 676 { 60, 5300, bwn_b2063_chantable_data[14] }, 677 { 64, 5320, bwn_b2063_chantable_data[15] }, 678 { 100, 5500, bwn_b2063_chantable_data[16] }, 679 { 104, 5520, bwn_b2063_chantable_data[17] }, 680 { 108, 5540, bwn_b2063_chantable_data[18] }, 681 { 112, 5560, bwn_b2063_chantable_data[19] }, 682 { 116, 5580, bwn_b2063_chantable_data[20] }, 683 { 120, 5600, bwn_b2063_chantable_data[21] }, 684 { 124, 5620, bwn_b2063_chantable_data[21] }, 685 { 128, 5640, bwn_b2063_chantable_data[22] }, 686 { 132, 5660, bwn_b2063_chantable_data[22] }, 687 { 136, 5680, bwn_b2063_chantable_data[22] }, 688 { 140, 5700, bwn_b2063_chantable_data[23] }, 689 { 149, 5745, bwn_b2063_chantable_data[23] }, 690 { 153, 5765, bwn_b2063_chantable_data[23] }, 691 { 157, 5785, bwn_b2063_chantable_data[23] }, 692 { 161, 5805, bwn_b2063_chantable_data[23] }, 693 { 165, 5825, bwn_b2063_chantable_data[23] }, 694 { 184, 4920, bwn_b2063_chantable_data[24] }, 695 { 188, 4940, bwn_b2063_chantable_data[25] }, 696 { 192, 4960, bwn_b2063_chantable_data[26] }, 697 { 196, 4980, bwn_b2063_chantable_data[27] }, 698 { 200, 5000, bwn_b2063_chantable_data[28] }, 699 { 204, 5020, bwn_b2063_chantable_data[29] }, 700 { 208, 5040, bwn_b2063_chantable_data[30] }, 701 { 212, 5060, bwn_b2063_chantable_data[31] }, 702 { 216, 5080, bwn_b2063_chantable_data[32] } 703 }; 704 705 static const uint8_t bwn_b2062_chantable_data[22][12] = { 706 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 707 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 708 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 719 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 720 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 721 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 722 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 723 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 724 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 727 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 728 }; 729 730 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 731 { 1, 2412, bwn_b2062_chantable_data[0] }, 732 { 2, 2417, bwn_b2062_chantable_data[0] }, 733 { 3, 2422, bwn_b2062_chantable_data[0] }, 734 { 4, 2427, bwn_b2062_chantable_data[0] }, 735 { 5, 2432, bwn_b2062_chantable_data[0] }, 736 { 6, 2437, bwn_b2062_chantable_data[0] }, 737 { 7, 2442, bwn_b2062_chantable_data[0] }, 738 { 8, 2447, bwn_b2062_chantable_data[0] }, 739 { 9, 2452, bwn_b2062_chantable_data[0] }, 740 { 10, 2457, bwn_b2062_chantable_data[0] }, 741 { 11, 2462, bwn_b2062_chantable_data[0] }, 742 { 12, 2467, bwn_b2062_chantable_data[0] }, 743 { 13, 2472, bwn_b2062_chantable_data[0] }, 744 { 14, 2484, bwn_b2062_chantable_data[0] }, 745 { 34, 5170, bwn_b2062_chantable_data[1] }, 746 { 38, 5190, bwn_b2062_chantable_data[2] }, 747 { 42, 5210, bwn_b2062_chantable_data[2] }, 748 { 46, 5230, bwn_b2062_chantable_data[3] }, 749 { 36, 5180, bwn_b2062_chantable_data[4] }, 750 { 40, 5200, bwn_b2062_chantable_data[5] }, 751 { 44, 5220, bwn_b2062_chantable_data[6] }, 752 { 48, 5240, bwn_b2062_chantable_data[3] }, 753 { 52, 5260, bwn_b2062_chantable_data[3] }, 754 { 56, 5280, bwn_b2062_chantable_data[3] }, 755 { 60, 5300, bwn_b2062_chantable_data[7] }, 756 { 64, 5320, bwn_b2062_chantable_data[8] }, 757 { 100, 5500, bwn_b2062_chantable_data[9] }, 758 { 104, 5520, bwn_b2062_chantable_data[10] }, 759 { 108, 5540, bwn_b2062_chantable_data[10] }, 760 { 112, 5560, bwn_b2062_chantable_data[10] }, 761 { 116, 5580, bwn_b2062_chantable_data[11] }, 762 { 120, 5600, bwn_b2062_chantable_data[12] }, 763 { 124, 5620, bwn_b2062_chantable_data[12] }, 764 { 128, 5640, bwn_b2062_chantable_data[12] }, 765 { 132, 5660, bwn_b2062_chantable_data[12] }, 766 { 136, 5680, bwn_b2062_chantable_data[12] }, 767 { 140, 5700, bwn_b2062_chantable_data[12] }, 768 { 149, 5745, bwn_b2062_chantable_data[12] }, 769 { 153, 5765, bwn_b2062_chantable_data[12] }, 770 { 157, 5785, bwn_b2062_chantable_data[12] }, 771 { 161, 5805, bwn_b2062_chantable_data[12] }, 772 { 165, 5825, bwn_b2062_chantable_data[12] }, 773 { 184, 4920, bwn_b2062_chantable_data[13] }, 774 { 188, 4940, bwn_b2062_chantable_data[14] }, 775 { 192, 4960, bwn_b2062_chantable_data[15] }, 776 { 196, 4980, bwn_b2062_chantable_data[16] }, 777 { 200, 5000, bwn_b2062_chantable_data[17] }, 778 { 204, 5020, bwn_b2062_chantable_data[18] }, 779 { 208, 5040, bwn_b2062_chantable_data[19] }, 780 { 212, 5060, bwn_b2062_chantable_data[20] }, 781 { 216, 5080, bwn_b2062_chantable_data[21] } 782 }; 783 784 /* for LP PHY */ 785 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 786 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 787 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 788 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 789 { 13, -66, 13 }, { 14, -66, 13 }, 790 }; 791 792 /* for LP PHY */ 793 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 794 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 795 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 796 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 797 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 798 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 799 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 800 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 801 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 802 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 803 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 804 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 805 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 806 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 807 }; 808 809 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 810 811 static const uint8_t bwn_tab_sigsq_tbl[] = { 812 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 813 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 814 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 815 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 816 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 817 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 818 }; 819 820 static const uint8_t bwn_tab_pllfrac_tbl[] = { 821 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 822 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 823 }; 824 825 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 826 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 827 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 830 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 831 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 832 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 838 }; 839 840 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 841 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 842 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 843 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 844 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 845 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 846 847 #define VENDOR_LED_ACT(vendor) \ 848 { \ 849 .vid = PCI_VENDOR_##vendor, \ 850 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 851 } 852 853 static const struct { 854 uint16_t vid; 855 uint8_t led_act[BWN_LED_MAX]; 856 } bwn_vendor_led_act[] = { 857 VENDOR_LED_ACT(COMPAQ), 858 VENDOR_LED_ACT(ASUSTEK) 859 }; 860 861 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 862 { BWN_VENDOR_LED_ACT_DEFAULT }; 863 864 #undef VENDOR_LED_ACT 865 866 static const struct { 867 int on_dur; 868 int off_dur; 869 } bwn_led_duration[109] = { 870 [0] = { 400, 100 }, 871 [2] = { 150, 75 }, 872 [4] = { 90, 45 }, 873 [11] = { 66, 34 }, 874 [12] = { 53, 26 }, 875 [18] = { 42, 21 }, 876 [22] = { 35, 17 }, 877 [24] = { 32, 16 }, 878 [36] = { 21, 10 }, 879 [48] = { 16, 8 }, 880 [72] = { 11, 5 }, 881 [96] = { 9, 4 }, 882 [108] = { 7, 3 } 883 }; 884 885 static const uint16_t bwn_wme_shm_offsets[] = { 886 [0] = BWN_WME_BESTEFFORT, 887 [1] = BWN_WME_BACKGROUND, 888 [2] = BWN_WME_VOICE, 889 [3] = BWN_WME_VIDEO, 890 }; 891 892 static const struct siba_devid bwn_devs[] = { 893 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 894 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 895 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 896 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 897 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 898 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 899 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 900 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 901 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 902 }; 903 904 static int 905 bwn_probe(device_t dev) 906 { 907 int i; 908 909 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 910 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 911 siba_get_device(dev) == bwn_devs[i].sd_device && 912 siba_get_revid(dev) == bwn_devs[i].sd_rev) 913 return (BUS_PROBE_DEFAULT); 914 } 915 916 return (ENXIO); 917 } 918 919 static int 920 bwn_attach(device_t dev) 921 { 922 struct bwn_mac *mac; 923 struct bwn_softc *sc = device_get_softc(dev); 924 int error, i, msic, reg; 925 926 sc->sc_dev = dev; 927 #ifdef BWN_DEBUG 928 sc->sc_debug = bwn_debug; 929 #endif 930 931 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 932 bwn_attach_pre(sc); 933 bwn_sprom_bugfixes(dev); 934 sc->sc_flags |= BWN_FLAG_ATTACHED; 935 } 936 937 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 938 if (siba_get_pci_device(dev) != 0x4313 && 939 siba_get_pci_device(dev) != 0x431a && 940 siba_get_pci_device(dev) != 0x4321) { 941 device_printf(sc->sc_dev, 942 "skip 802.11 cores\n"); 943 return (ENODEV); 944 } 945 } 946 947 mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO); 948 mac->mac_sc = sc; 949 mac->mac_status = BWN_MAC_STATUS_UNINIT; 950 if (bwn_bfp != 0) 951 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 952 953 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 954 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 955 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 956 957 error = bwn_attach_core(mac); 958 if (error) 959 goto fail0; 960 bwn_led_attach(mac); 961 962 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 963 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 964 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 965 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 966 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 967 mac->mac_phy.rf_rev); 968 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 969 device_printf(sc->sc_dev, "DMA (%d bits)\n", 970 mac->mac_method.dma.dmatype); 971 else 972 device_printf(sc->sc_dev, "PIO\n"); 973 974 /* 975 * setup PCI resources and interrupt. 976 */ 977 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { 978 msic = pci_msi_count(dev); 979 if (bootverbose) 980 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 981 } else 982 msic = 0; 983 984 mac->mac_intr_spec = bwn_res_spec_legacy; 985 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 986 if (pci_alloc_msi(dev, &msic) == 0) { 987 device_printf(sc->sc_dev, 988 "Using %d MSI messages\n", msic); 989 mac->mac_intr_spec = bwn_res_spec_msi; 990 mac->mac_msi = 1; 991 } 992 } 993 994 error = bus_alloc_resources(dev, mac->mac_intr_spec, 995 mac->mac_res_irq); 996 if (error) { 997 device_printf(sc->sc_dev, 998 "couldn't allocate IRQ resources (%d)\n", error); 999 goto fail1; 1000 } 1001 1002 if (mac->mac_msi == 0) 1003 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1004 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1005 &mac->mac_intrhand[0]); 1006 else { 1007 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1008 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1009 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1010 &mac->mac_intrhand[i]); 1011 if (error != 0) { 1012 device_printf(sc->sc_dev, 1013 "couldn't setup interrupt (%d)\n", error); 1014 break; 1015 } 1016 } 1017 } 1018 1019 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1020 1021 /* 1022 * calls attach-post routine 1023 */ 1024 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1025 bwn_attach_post(sc); 1026 1027 return (0); 1028 fail1: 1029 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1030 pci_release_msi(dev); 1031 fail0: 1032 free(mac, M_DEVBUF); 1033 return (error); 1034 } 1035 1036 static int 1037 bwn_is_valid_ether_addr(uint8_t *addr) 1038 { 1039 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1040 1041 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1042 return (FALSE); 1043 1044 return (TRUE); 1045 } 1046 1047 static int 1048 bwn_attach_post(struct bwn_softc *sc) 1049 { 1050 struct ieee80211com *ic = &sc->sc_ic; 1051 1052 ic->ic_softc = sc; 1053 ic->ic_name = device_get_nameunit(sc->sc_dev); 1054 /* XXX not right but it's not used anywhere important */ 1055 ic->ic_phytype = IEEE80211_T_OFDM; 1056 ic->ic_opmode = IEEE80211_M_STA; 1057 ic->ic_caps = 1058 IEEE80211_C_STA /* station mode supported */ 1059 | IEEE80211_C_MONITOR /* monitor mode */ 1060 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1061 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1062 | IEEE80211_C_SHSLOT /* short slot time supported */ 1063 | IEEE80211_C_WME /* WME/WMM supported */ 1064 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1065 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1066 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1067 ; 1068 1069 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1070 1071 IEEE80211_ADDR_COPY(ic->ic_macaddr, 1072 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1073 siba_sprom_get_mac_80211a(sc->sc_dev) : 1074 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1075 1076 /* call MI attach routine. */ 1077 ieee80211_ifattach(ic); 1078 1079 ic->ic_headroom = sizeof(struct bwn_txhdr); 1080 1081 /* override default methods */ 1082 ic->ic_raw_xmit = bwn_raw_xmit; 1083 ic->ic_updateslot = bwn_updateslot; 1084 ic->ic_update_promisc = bwn_update_promisc; 1085 ic->ic_wme.wme_update = bwn_wme_update; 1086 ic->ic_scan_start = bwn_scan_start; 1087 ic->ic_scan_end = bwn_scan_end; 1088 ic->ic_set_channel = bwn_set_channel; 1089 ic->ic_vap_create = bwn_vap_create; 1090 ic->ic_vap_delete = bwn_vap_delete; 1091 ic->ic_transmit = bwn_transmit; 1092 ic->ic_parent = bwn_parent; 1093 1094 ieee80211_radiotap_attach(ic, 1095 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1096 BWN_TX_RADIOTAP_PRESENT, 1097 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1098 BWN_RX_RADIOTAP_PRESENT); 1099 1100 bwn_sysctl_node(sc); 1101 1102 if (bootverbose) 1103 ieee80211_announce(ic); 1104 return (0); 1105 } 1106 1107 static void 1108 bwn_phy_detach(struct bwn_mac *mac) 1109 { 1110 1111 if (mac->mac_phy.detach != NULL) 1112 mac->mac_phy.detach(mac); 1113 } 1114 1115 static int 1116 bwn_detach(device_t dev) 1117 { 1118 struct bwn_softc *sc = device_get_softc(dev); 1119 struct bwn_mac *mac = sc->sc_curmac; 1120 struct ieee80211com *ic = &sc->sc_ic; 1121 int i; 1122 1123 sc->sc_flags |= BWN_FLAG_INVALID; 1124 1125 if (device_is_attached(sc->sc_dev)) { 1126 BWN_LOCK(sc); 1127 bwn_stop(sc); 1128 BWN_UNLOCK(sc); 1129 bwn_dma_free(mac); 1130 callout_drain(&sc->sc_led_blink_ch); 1131 callout_drain(&sc->sc_rfswitch_ch); 1132 callout_drain(&sc->sc_task_ch); 1133 callout_drain(&sc->sc_watchdog_ch); 1134 bwn_phy_detach(mac); 1135 ieee80211_draintask(ic, &mac->mac_hwreset); 1136 ieee80211_draintask(ic, &mac->mac_txpower); 1137 ieee80211_ifdetach(ic); 1138 } 1139 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1140 taskqueue_free(sc->sc_tq); 1141 1142 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1143 if (mac->mac_intrhand[i] != NULL) { 1144 bus_teardown_intr(dev, mac->mac_res_irq[i], 1145 mac->mac_intrhand[i]); 1146 mac->mac_intrhand[i] = NULL; 1147 } 1148 } 1149 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1150 if (mac->mac_msi != 0) 1151 pci_release_msi(dev); 1152 mbufq_drain(&sc->sc_snd); 1153 BWN_LOCK_DESTROY(sc); 1154 return (0); 1155 } 1156 1157 static void 1158 bwn_attach_pre(struct bwn_softc *sc) 1159 { 1160 1161 BWN_LOCK_INIT(sc); 1162 TAILQ_INIT(&sc->sc_maclist); 1163 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1164 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1165 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1166 mbufq_init(&sc->sc_snd, ifqmaxlen); 1167 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1168 taskqueue_thread_enqueue, &sc->sc_tq); 1169 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1170 "%s taskq", device_get_nameunit(sc->sc_dev)); 1171 } 1172 1173 static void 1174 bwn_sprom_bugfixes(device_t dev) 1175 { 1176 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1177 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1178 (siba_get_pci_device(dev) == _device) && \ 1179 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1180 (siba_get_pci_subdevice(dev) == _subdevice)) 1181 1182 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1183 siba_get_pci_subdevice(dev) == 0x4e && 1184 siba_get_pci_revid(dev) > 0x40) 1185 siba_sprom_set_bf_lo(dev, 1186 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1187 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1188 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1189 siba_sprom_set_bf_lo(dev, 1190 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1191 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1192 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1193 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1194 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1195 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1196 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1197 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1198 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1199 siba_sprom_set_bf_lo(dev, 1200 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1201 } 1202 #undef BWN_ISDEV 1203 } 1204 1205 static void 1206 bwn_parent(struct ieee80211com *ic) 1207 { 1208 struct bwn_softc *sc = ic->ic_softc; 1209 int startall = 0; 1210 1211 BWN_LOCK(sc); 1212 if (ic->ic_nrunning > 0) { 1213 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { 1214 bwn_init(sc); 1215 startall = 1; 1216 } else 1217 bwn_update_promisc(ic); 1218 } else if (sc->sc_flags & BWN_FLAG_RUNNING) 1219 bwn_stop(sc); 1220 BWN_UNLOCK(sc); 1221 1222 if (startall) 1223 ieee80211_start_all(ic); 1224 } 1225 1226 static int 1227 bwn_transmit(struct ieee80211com *ic, struct mbuf *m) 1228 { 1229 struct bwn_softc *sc = ic->ic_softc; 1230 int error; 1231 1232 BWN_LOCK(sc); 1233 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { 1234 BWN_UNLOCK(sc); 1235 return (ENXIO); 1236 } 1237 error = mbufq_enqueue(&sc->sc_snd, m); 1238 if (error) { 1239 BWN_UNLOCK(sc); 1240 return (error); 1241 } 1242 bwn_start(sc); 1243 BWN_UNLOCK(sc); 1244 return (0); 1245 } 1246 1247 static void 1248 bwn_start(struct bwn_softc *sc) 1249 { 1250 struct bwn_mac *mac = sc->sc_curmac; 1251 struct ieee80211_frame *wh; 1252 struct ieee80211_node *ni; 1253 struct ieee80211_key *k; 1254 struct mbuf *m; 1255 1256 BWN_ASSERT_LOCKED(sc); 1257 1258 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL || 1259 mac->mac_status < BWN_MAC_STATUS_STARTED) 1260 return; 1261 1262 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 1263 if (bwn_tx_isfull(sc, m)) 1264 break; 1265 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1266 if (ni == NULL) { 1267 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1268 m_freem(m); 1269 counter_u64_add(sc->sc_ic.ic_oerrors, 1); 1270 continue; 1271 } 1272 wh = mtod(m, struct ieee80211_frame *); 1273 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1274 k = ieee80211_crypto_encap(ni, m); 1275 if (k == NULL) { 1276 if_inc_counter(ni->ni_vap->iv_ifp, 1277 IFCOUNTER_OERRORS, 1); 1278 ieee80211_free_node(ni); 1279 m_freem(m); 1280 continue; 1281 } 1282 } 1283 wh = NULL; /* Catch any invalid use */ 1284 if (bwn_tx_start(sc, ni, m) != 0) { 1285 if (ni != NULL) { 1286 if_inc_counter(ni->ni_vap->iv_ifp, 1287 IFCOUNTER_OERRORS, 1); 1288 ieee80211_free_node(ni); 1289 } 1290 continue; 1291 } 1292 sc->sc_watchdog_timer = 5; 1293 } 1294 } 1295 1296 static int 1297 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1298 { 1299 struct bwn_dma_ring *dr; 1300 struct bwn_mac *mac = sc->sc_curmac; 1301 struct bwn_pio_txqueue *tq; 1302 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1303 1304 BWN_ASSERT_LOCKED(sc); 1305 1306 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1307 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1308 if (dr->dr_stop == 1 || 1309 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1310 dr->dr_stop = 1; 1311 goto full; 1312 } 1313 } else { 1314 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1315 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1316 pktlen > (tq->tq_size - tq->tq_used)) 1317 goto full; 1318 } 1319 return (0); 1320 full: 1321 mbufq_prepend(&sc->sc_snd, m); 1322 return (1); 1323 } 1324 1325 static int 1326 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1327 { 1328 struct bwn_mac *mac = sc->sc_curmac; 1329 int error; 1330 1331 BWN_ASSERT_LOCKED(sc); 1332 1333 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1334 m_freem(m); 1335 return (ENXIO); 1336 } 1337 1338 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1339 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1340 if (error) { 1341 m_freem(m); 1342 return (error); 1343 } 1344 return (0); 1345 } 1346 1347 static int 1348 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1349 { 1350 struct bwn_pio_txpkt *tp; 1351 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1352 struct bwn_softc *sc = mac->mac_sc; 1353 struct bwn_txhdr txhdr; 1354 struct mbuf *m_new; 1355 uint32_t ctl32; 1356 int error; 1357 uint16_t ctl16; 1358 1359 BWN_ASSERT_LOCKED(sc); 1360 1361 /* XXX TODO send packets after DTIM */ 1362 1363 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1364 tp = TAILQ_FIRST(&tq->tq_pktlist); 1365 tp->tp_ni = ni; 1366 tp->tp_m = m; 1367 1368 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1369 if (error) { 1370 device_printf(sc->sc_dev, "tx fail\n"); 1371 return (error); 1372 } 1373 1374 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1375 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1376 tq->tq_free--; 1377 1378 if (siba_get_revid(sc->sc_dev) >= 8) { 1379 /* 1380 * XXX please removes m_defrag(9) 1381 */ 1382 m_new = m_defrag(m, M_NOWAIT); 1383 if (m_new == NULL) { 1384 device_printf(sc->sc_dev, 1385 "%s: can't defrag TX buffer\n", 1386 __func__); 1387 return (ENOBUFS); 1388 } 1389 if (m_new->m_next != NULL) 1390 device_printf(sc->sc_dev, 1391 "TODO: fragmented packets for PIO\n"); 1392 tp->tp_m = m_new; 1393 1394 /* send HEADER */ 1395 ctl32 = bwn_pio_write_multi_4(mac, tq, 1396 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1397 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1398 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1399 /* send BODY */ 1400 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1401 mtod(m_new, const void *), m_new->m_pkthdr.len); 1402 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1403 ctl32 | BWN_PIO8_TXCTL_EOF); 1404 } else { 1405 ctl16 = bwn_pio_write_multi_2(mac, tq, 1406 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1407 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1408 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1409 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1410 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1411 ctl16 | BWN_PIO_TXCTL_EOF); 1412 } 1413 1414 return (0); 1415 } 1416 1417 static struct bwn_pio_txqueue * 1418 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1419 { 1420 1421 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1422 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1423 1424 switch (prio) { 1425 case 0: 1426 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1427 case 1: 1428 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1429 case 2: 1430 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1431 case 3: 1432 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1433 } 1434 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1435 return (NULL); 1436 } 1437 1438 static int 1439 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1440 { 1441 #define BWN_GET_TXHDRCACHE(slot) \ 1442 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1443 struct bwn_dma *dma = &mac->mac_method.dma; 1444 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1445 struct bwn_dmadesc_generic *desc; 1446 struct bwn_dmadesc_meta *mt; 1447 struct bwn_softc *sc = mac->mac_sc; 1448 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1449 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1450 1451 BWN_ASSERT_LOCKED(sc); 1452 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1453 1454 /* XXX send after DTIM */ 1455 1456 slot = bwn_dma_getslot(dr); 1457 dr->getdesc(dr, slot, &desc, &mt); 1458 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1459 ("%s:%d: fail", __func__, __LINE__)); 1460 1461 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1462 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1463 BWN_DMA_COOKIE(dr, slot)); 1464 if (error) 1465 goto fail; 1466 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1467 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1468 &mt->mt_paddr, BUS_DMA_NOWAIT); 1469 if (error) { 1470 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", 1471 __func__, error); 1472 goto fail; 1473 } 1474 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1475 BUS_DMASYNC_PREWRITE); 1476 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1477 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1478 BUS_DMASYNC_PREWRITE); 1479 1480 slot = bwn_dma_getslot(dr); 1481 dr->getdesc(dr, slot, &desc, &mt); 1482 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1483 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1484 mt->mt_m = m; 1485 mt->mt_ni = ni; 1486 1487 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1488 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1489 if (error && error != EFBIG) { 1490 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", 1491 __func__, error); 1492 goto fail; 1493 } 1494 if (error) { /* error == EFBIG */ 1495 struct mbuf *m_new; 1496 1497 m_new = m_defrag(m, M_NOWAIT); 1498 if (m_new == NULL) { 1499 device_printf(sc->sc_dev, 1500 "%s: can't defrag TX buffer\n", 1501 __func__); 1502 error = ENOBUFS; 1503 goto fail; 1504 } else { 1505 m = m_new; 1506 } 1507 1508 mt->mt_m = m; 1509 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1510 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1511 if (error) { 1512 device_printf(sc->sc_dev, 1513 "%s: can't load TX buffer (2) %d\n", 1514 __func__, error); 1515 goto fail; 1516 } 1517 } 1518 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1519 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1520 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1521 BUS_DMASYNC_PREWRITE); 1522 1523 /* XXX send after DTIM */ 1524 1525 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1526 return (0); 1527 fail: 1528 dr->dr_curslot = backup[0]; 1529 dr->dr_usedslot = backup[1]; 1530 return (error); 1531 #undef BWN_GET_TXHDRCACHE 1532 } 1533 1534 static void 1535 bwn_watchdog(void *arg) 1536 { 1537 struct bwn_softc *sc = arg; 1538 1539 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1540 device_printf(sc->sc_dev, "device timeout\n"); 1541 counter_u64_add(sc->sc_ic.ic_oerrors, 1); 1542 } 1543 callout_schedule(&sc->sc_watchdog_ch, hz); 1544 } 1545 1546 static int 1547 bwn_attach_core(struct bwn_mac *mac) 1548 { 1549 struct bwn_softc *sc = mac->mac_sc; 1550 int error, have_bg = 0, have_a = 0; 1551 uint32_t high; 1552 1553 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1554 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1555 1556 siba_powerup(sc->sc_dev, 0); 1557 1558 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1559 bwn_reset_core(mac, 1560 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1561 error = bwn_phy_getinfo(mac, high); 1562 if (error) 1563 goto fail; 1564 1565 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1566 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1567 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1568 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1569 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1570 have_a = have_bg = 0; 1571 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1572 have_a = 1; 1573 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1574 mac->mac_phy.type == BWN_PHYTYPE_N || 1575 mac->mac_phy.type == BWN_PHYTYPE_LP) 1576 have_bg = 1; 1577 else 1578 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1579 mac->mac_phy.type)); 1580 } 1581 /* XXX turns off PHY A because it's not supported */ 1582 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1583 mac->mac_phy.type != BWN_PHYTYPE_N) { 1584 have_a = 0; 1585 have_bg = 1; 1586 } 1587 1588 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1589 mac->mac_phy.attach = bwn_phy_g_attach; 1590 mac->mac_phy.detach = bwn_phy_g_detach; 1591 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1592 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1593 mac->mac_phy.init = bwn_phy_g_init; 1594 mac->mac_phy.exit = bwn_phy_g_exit; 1595 mac->mac_phy.phy_read = bwn_phy_g_read; 1596 mac->mac_phy.phy_write = bwn_phy_g_write; 1597 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1598 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1599 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1600 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1601 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1602 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1603 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1604 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1605 mac->mac_phy.set_im = bwn_phy_g_im; 1606 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1607 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1608 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1609 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1610 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1611 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1612 mac->mac_phy.init = bwn_phy_lp_init; 1613 mac->mac_phy.phy_read = bwn_phy_lp_read; 1614 mac->mac_phy.phy_write = bwn_phy_lp_write; 1615 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1616 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1617 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1618 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1619 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1620 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1621 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1622 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1623 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1624 } else { 1625 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1626 mac->mac_phy.type); 1627 error = ENXIO; 1628 goto fail; 1629 } 1630 1631 mac->mac_phy.gmode = have_bg; 1632 if (mac->mac_phy.attach != NULL) { 1633 error = mac->mac_phy.attach(mac); 1634 if (error) { 1635 device_printf(sc->sc_dev, "failed\n"); 1636 goto fail; 1637 } 1638 } 1639 1640 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1641 1642 error = bwn_chiptest(mac); 1643 if (error) 1644 goto fail; 1645 error = bwn_setup_channels(mac, have_bg, have_a); 1646 if (error) { 1647 device_printf(sc->sc_dev, "failed to setup channels\n"); 1648 goto fail; 1649 } 1650 1651 if (sc->sc_curmac == NULL) 1652 sc->sc_curmac = mac; 1653 1654 error = bwn_dma_attach(mac); 1655 if (error != 0) { 1656 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1657 goto fail; 1658 } 1659 1660 mac->mac_phy.switch_analog(mac, 0); 1661 1662 siba_dev_down(sc->sc_dev, 0); 1663 fail: 1664 siba_powerdown(sc->sc_dev); 1665 return (error); 1666 } 1667 1668 static void 1669 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1670 { 1671 struct bwn_softc *sc = mac->mac_sc; 1672 uint32_t low, ctl; 1673 1674 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1675 1676 siba_dev_up(sc->sc_dev, flags); 1677 DELAY(2000); 1678 1679 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1680 ~BWN_TGSLOW_PHYRESET; 1681 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1682 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1683 DELAY(1000); 1684 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1685 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1686 DELAY(1000); 1687 1688 if (mac->mac_phy.switch_analog != NULL) 1689 mac->mac_phy.switch_analog(mac, 1); 1690 1691 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1692 if (flags & BWN_TGSLOW_SUPPORT_G) 1693 ctl |= BWN_MACCTL_GMODE; 1694 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1695 } 1696 1697 static int 1698 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1699 { 1700 struct bwn_phy *phy = &mac->mac_phy; 1701 struct bwn_softc *sc = mac->mac_sc; 1702 uint32_t tmp; 1703 1704 /* PHY */ 1705 tmp = BWN_READ_2(mac, BWN_PHYVER); 1706 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1707 phy->rf_on = 1; 1708 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1709 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1710 phy->rev = (tmp & BWN_PHYVER_VERSION); 1711 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1712 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1713 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1714 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1715 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1716 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1717 goto unsupphy; 1718 1719 /* RADIO */ 1720 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1721 if (siba_get_chiprev(sc->sc_dev) == 0) 1722 tmp = 0x3205017f; 1723 else if (siba_get_chiprev(sc->sc_dev) == 1) 1724 tmp = 0x4205017f; 1725 else 1726 tmp = 0x5205017f; 1727 } else { 1728 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1729 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1730 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1731 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1732 } 1733 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1734 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1735 phy->rf_manuf = (tmp & 0x00000fff); 1736 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1737 goto unsupradio; 1738 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1739 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1740 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1741 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1742 (phy->type == BWN_PHYTYPE_N && 1743 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1744 (phy->type == BWN_PHYTYPE_LP && 1745 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1746 goto unsupradio; 1747 1748 return (0); 1749 unsupphy: 1750 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1751 "analog %#x)\n", 1752 phy->type, phy->rev, phy->analog); 1753 return (ENXIO); 1754 unsupradio: 1755 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1756 "rev %#x)\n", 1757 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1758 return (ENXIO); 1759 } 1760 1761 static int 1762 bwn_chiptest(struct bwn_mac *mac) 1763 { 1764 #define TESTVAL0 0x55aaaa55 1765 #define TESTVAL1 0xaa5555aa 1766 struct bwn_softc *sc = mac->mac_sc; 1767 uint32_t v, backup; 1768 1769 BWN_LOCK(sc); 1770 1771 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1772 1773 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1774 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1775 goto error; 1776 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1777 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1778 goto error; 1779 1780 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1781 1782 if ((siba_get_revid(sc->sc_dev) >= 3) && 1783 (siba_get_revid(sc->sc_dev) <= 10)) { 1784 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1785 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1786 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1787 goto error; 1788 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1789 goto error; 1790 } 1791 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1792 1793 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1794 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1795 goto error; 1796 1797 BWN_UNLOCK(sc); 1798 return (0); 1799 error: 1800 BWN_UNLOCK(sc); 1801 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1802 return (ENODEV); 1803 } 1804 1805 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1806 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1807 1808 static int 1809 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1810 { 1811 struct bwn_softc *sc = mac->mac_sc; 1812 struct ieee80211com *ic = &sc->sc_ic; 1813 1814 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1815 ic->ic_nchans = 0; 1816 1817 if (have_bg) 1818 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1819 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1820 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1821 if (have_a) 1822 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1823 &ic->ic_nchans, &bwn_chantable_n, 1824 IEEE80211_CHAN_HTA); 1825 } else { 1826 if (have_a) 1827 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1828 &ic->ic_nchans, &bwn_chantable_a, 1829 IEEE80211_CHAN_A); 1830 } 1831 1832 mac->mac_phy.supports_2ghz = have_bg; 1833 mac->mac_phy.supports_5ghz = have_a; 1834 1835 return (ic->ic_nchans == 0 ? ENXIO : 0); 1836 } 1837 1838 static uint32_t 1839 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1840 { 1841 uint32_t ret; 1842 1843 BWN_ASSERT_LOCKED(mac->mac_sc); 1844 1845 if (way == BWN_SHARED) { 1846 KASSERT((offset & 0x0001) == 0, 1847 ("%s:%d warn", __func__, __LINE__)); 1848 if (offset & 0x0003) { 1849 bwn_shm_ctlword(mac, way, offset >> 2); 1850 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1851 ret <<= 16; 1852 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1853 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1854 goto out; 1855 } 1856 offset >>= 2; 1857 } 1858 bwn_shm_ctlword(mac, way, offset); 1859 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1860 out: 1861 return (ret); 1862 } 1863 1864 static uint16_t 1865 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1866 { 1867 uint16_t ret; 1868 1869 BWN_ASSERT_LOCKED(mac->mac_sc); 1870 1871 if (way == BWN_SHARED) { 1872 KASSERT((offset & 0x0001) == 0, 1873 ("%s:%d warn", __func__, __LINE__)); 1874 if (offset & 0x0003) { 1875 bwn_shm_ctlword(mac, way, offset >> 2); 1876 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1877 goto out; 1878 } 1879 offset >>= 2; 1880 } 1881 bwn_shm_ctlword(mac, way, offset); 1882 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1883 out: 1884 1885 return (ret); 1886 } 1887 1888 static void 1889 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1890 uint16_t offset) 1891 { 1892 uint32_t control; 1893 1894 control = way; 1895 control <<= 16; 1896 control |= offset; 1897 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1898 } 1899 1900 static void 1901 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1902 uint32_t value) 1903 { 1904 BWN_ASSERT_LOCKED(mac->mac_sc); 1905 1906 if (way == BWN_SHARED) { 1907 KASSERT((offset & 0x0001) == 0, 1908 ("%s:%d warn", __func__, __LINE__)); 1909 if (offset & 0x0003) { 1910 bwn_shm_ctlword(mac, way, offset >> 2); 1911 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1912 (value >> 16) & 0xffff); 1913 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1914 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1915 return; 1916 } 1917 offset >>= 2; 1918 } 1919 bwn_shm_ctlword(mac, way, offset); 1920 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1921 } 1922 1923 static void 1924 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1925 uint16_t value) 1926 { 1927 BWN_ASSERT_LOCKED(mac->mac_sc); 1928 1929 if (way == BWN_SHARED) { 1930 KASSERT((offset & 0x0001) == 0, 1931 ("%s:%d warn", __func__, __LINE__)); 1932 if (offset & 0x0003) { 1933 bwn_shm_ctlword(mac, way, offset >> 2); 1934 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1935 return; 1936 } 1937 offset >>= 2; 1938 } 1939 bwn_shm_ctlword(mac, way, offset); 1940 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1941 } 1942 1943 static void 1944 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1945 int txpow) 1946 { 1947 1948 c->ic_freq = freq; 1949 c->ic_flags = flags; 1950 c->ic_ieee = ieee; 1951 c->ic_minpower = 0; 1952 c->ic_maxpower = 2 * txpow; 1953 c->ic_maxregpower = txpow; 1954 } 1955 1956 static void 1957 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 1958 const struct bwn_channelinfo *ci, int flags) 1959 { 1960 struct ieee80211_channel *c; 1961 int i; 1962 1963 c = &chans[*nchans]; 1964 1965 for (i = 0; i < ci->nchannels; i++) { 1966 const struct bwn_channel *hc; 1967 1968 hc = &ci->channels[i]; 1969 if (*nchans >= maxchans) 1970 break; 1971 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 1972 c++, (*nchans)++; 1973 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 1974 /* g channel have a separate b-only entry */ 1975 if (*nchans >= maxchans) 1976 break; 1977 c[0] = c[-1]; 1978 c[-1].ic_flags = IEEE80211_CHAN_B; 1979 c++, (*nchans)++; 1980 } 1981 if (flags == IEEE80211_CHAN_HTG) { 1982 /* HT g channel have a separate g-only entry */ 1983 if (*nchans >= maxchans) 1984 break; 1985 c[-1].ic_flags = IEEE80211_CHAN_G; 1986 c[0] = c[-1]; 1987 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1988 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1989 c++, (*nchans)++; 1990 } 1991 if (flags == IEEE80211_CHAN_HTA) { 1992 /* HT a channel have a separate a-only entry */ 1993 if (*nchans >= maxchans) 1994 break; 1995 c[-1].ic_flags = IEEE80211_CHAN_A; 1996 c[0] = c[-1]; 1997 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1998 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1999 c++, (*nchans)++; 2000 } 2001 } 2002 } 2003 2004 static int 2005 bwn_phy_g_attach(struct bwn_mac *mac) 2006 { 2007 struct bwn_softc *sc = mac->mac_sc; 2008 struct bwn_phy *phy = &mac->mac_phy; 2009 struct bwn_phy_g *pg = &phy->phy_g; 2010 unsigned int i; 2011 int16_t pab0, pab1, pab2; 2012 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2013 int8_t bg; 2014 2015 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2016 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2017 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2018 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2019 2020 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2021 device_printf(sc->sc_dev, "not supported anymore\n"); 2022 2023 pg->pg_flags = 0; 2024 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2025 pab2 == -1) { 2026 pg->pg_idletssi = 52; 2027 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2028 return (0); 2029 } 2030 2031 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2032 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2033 if (pg->pg_tssi2dbm == NULL) { 2034 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2035 return (ENOMEM); 2036 } 2037 for (i = 0; i < 64; i++) { 2038 int32_t m1, m2, f, q, delta; 2039 int8_t j = 0; 2040 2041 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2042 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2043 f = 256; 2044 2045 do { 2046 if (j > 15) { 2047 device_printf(sc->sc_dev, 2048 "failed to generate tssi2dBm\n"); 2049 free(pg->pg_tssi2dbm, M_DEVBUF); 2050 return (ENOMEM); 2051 } 2052 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2053 f, 2048); 2054 delta = abs(q - f); 2055 f = q; 2056 j++; 2057 } while (delta >= 2); 2058 2059 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2060 128); 2061 } 2062 2063 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2064 return (0); 2065 } 2066 2067 static void 2068 bwn_phy_g_detach(struct bwn_mac *mac) 2069 { 2070 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2071 2072 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2073 free(pg->pg_tssi2dbm, M_DEVBUF); 2074 pg->pg_tssi2dbm = NULL; 2075 } 2076 pg->pg_flags = 0; 2077 } 2078 2079 static void 2080 bwn_phy_g_init_pre(struct bwn_mac *mac) 2081 { 2082 struct bwn_phy *phy = &mac->mac_phy; 2083 struct bwn_phy_g *pg = &phy->phy_g; 2084 void *tssi2dbm; 2085 int idletssi; 2086 unsigned int i; 2087 2088 tssi2dbm = pg->pg_tssi2dbm; 2089 idletssi = pg->pg_idletssi; 2090 2091 memset(pg, 0, sizeof(*pg)); 2092 2093 pg->pg_tssi2dbm = tssi2dbm; 2094 pg->pg_idletssi = idletssi; 2095 2096 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2097 2098 for (i = 0; i < N(pg->pg_nrssi); i++) 2099 pg->pg_nrssi[i] = -1000; 2100 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2101 pg->pg_nrssi_lt[i] = i; 2102 pg->pg_lofcal = 0xffff; 2103 pg->pg_initval = 0xffff; 2104 pg->pg_immode = BWN_IMMODE_NONE; 2105 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2106 pg->pg_avgtssi = 0xff; 2107 2108 pg->pg_loctl.tx_bias = 0xff; 2109 TAILQ_INIT(&pg->pg_loctl.calib_list); 2110 } 2111 2112 static int 2113 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2114 { 2115 struct bwn_phy *phy = &mac->mac_phy; 2116 struct bwn_phy_g *pg = &phy->phy_g; 2117 struct bwn_softc *sc = mac->mac_sc; 2118 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2119 static const struct bwn_rfatt rfatt0[] = { 2120 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2121 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2122 { 3, 1 }, { 4, 1 } 2123 }; 2124 static const struct bwn_rfatt rfatt1[] = { 2125 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2126 { 14, 1 } 2127 }; 2128 static const struct bwn_rfatt rfatt2[] = { 2129 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2130 { 9, 1 } 2131 }; 2132 static const struct bwn_bbatt bbatt_0[] = { 2133 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2134 }; 2135 2136 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2137 2138 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2139 pg->pg_bbatt.att = 0; 2140 else 2141 pg->pg_bbatt.att = 2; 2142 2143 /* prepare Radio Attenuation */ 2144 pg->pg_rfatt.padmix = 0; 2145 2146 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2147 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2148 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2149 pg->pg_rfatt.att = 2; 2150 goto done; 2151 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2152 pg->pg_rfatt.att = 3; 2153 goto done; 2154 } 2155 } 2156 2157 if (phy->type == BWN_PHYTYPE_A) { 2158 pg->pg_rfatt.att = 0x60; 2159 goto done; 2160 } 2161 2162 switch (phy->rf_ver) { 2163 case 0x2050: 2164 switch (phy->rf_rev) { 2165 case 0: 2166 pg->pg_rfatt.att = 5; 2167 goto done; 2168 case 1: 2169 if (phy->type == BWN_PHYTYPE_G) { 2170 if (siba_get_pci_subvendor(sc->sc_dev) == 2171 SIBA_BOARDVENDOR_BCM && 2172 siba_get_pci_subdevice(sc->sc_dev) == 2173 SIBA_BOARD_BCM4309G && 2174 siba_get_pci_revid(sc->sc_dev) >= 30) 2175 pg->pg_rfatt.att = 3; 2176 else if (siba_get_pci_subvendor(sc->sc_dev) == 2177 SIBA_BOARDVENDOR_BCM && 2178 siba_get_pci_subdevice(sc->sc_dev) == 2179 SIBA_BOARD_BU4306) 2180 pg->pg_rfatt.att = 3; 2181 else 2182 pg->pg_rfatt.att = 1; 2183 } else { 2184 if (siba_get_pci_subvendor(sc->sc_dev) == 2185 SIBA_BOARDVENDOR_BCM && 2186 siba_get_pci_subdevice(sc->sc_dev) == 2187 SIBA_BOARD_BCM4309G && 2188 siba_get_pci_revid(sc->sc_dev) >= 30) 2189 pg->pg_rfatt.att = 7; 2190 else 2191 pg->pg_rfatt.att = 6; 2192 } 2193 goto done; 2194 case 2: 2195 if (phy->type == BWN_PHYTYPE_G) { 2196 if (siba_get_pci_subvendor(sc->sc_dev) == 2197 SIBA_BOARDVENDOR_BCM && 2198 siba_get_pci_subdevice(sc->sc_dev) == 2199 SIBA_BOARD_BCM4309G && 2200 siba_get_pci_revid(sc->sc_dev) >= 30) 2201 pg->pg_rfatt.att = 3; 2202 else if (siba_get_pci_subvendor(sc->sc_dev) == 2203 SIBA_BOARDVENDOR_BCM && 2204 siba_get_pci_subdevice(sc->sc_dev) == 2205 SIBA_BOARD_BU4306) 2206 pg->pg_rfatt.att = 5; 2207 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2208 pg->pg_rfatt.att = 4; 2209 else 2210 pg->pg_rfatt.att = 3; 2211 } else 2212 pg->pg_rfatt.att = 6; 2213 goto done; 2214 case 3: 2215 pg->pg_rfatt.att = 5; 2216 goto done; 2217 case 4: 2218 case 5: 2219 pg->pg_rfatt.att = 1; 2220 goto done; 2221 case 6: 2222 case 7: 2223 pg->pg_rfatt.att = 5; 2224 goto done; 2225 case 8: 2226 pg->pg_rfatt.att = 0xa; 2227 pg->pg_rfatt.padmix = 1; 2228 goto done; 2229 case 9: 2230 default: 2231 pg->pg_rfatt.att = 5; 2232 goto done; 2233 } 2234 break; 2235 case 0x2053: 2236 switch (phy->rf_rev) { 2237 case 1: 2238 pg->pg_rfatt.att = 6; 2239 goto done; 2240 } 2241 break; 2242 } 2243 pg->pg_rfatt.att = 5; 2244 done: 2245 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2246 2247 if (!bwn_has_hwpctl(mac)) { 2248 lo->rfatt.array = rfatt0; 2249 lo->rfatt.len = N(rfatt0); 2250 lo->rfatt.min = 0; 2251 lo->rfatt.max = 9; 2252 goto genbbatt; 2253 } 2254 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2255 lo->rfatt.array = rfatt1; 2256 lo->rfatt.len = N(rfatt1); 2257 lo->rfatt.min = 0; 2258 lo->rfatt.max = 14; 2259 goto genbbatt; 2260 } 2261 lo->rfatt.array = rfatt2; 2262 lo->rfatt.len = N(rfatt2); 2263 lo->rfatt.min = 0; 2264 lo->rfatt.max = 9; 2265 genbbatt: 2266 lo->bbatt.array = bbatt_0; 2267 lo->bbatt.len = N(bbatt_0); 2268 lo->bbatt.min = 0; 2269 lo->bbatt.max = 8; 2270 2271 BWN_READ_4(mac, BWN_MACCTL); 2272 if (phy->rev == 1) { 2273 phy->gmode = 0; 2274 bwn_reset_core(mac, 0); 2275 bwn_phy_g_init_sub(mac); 2276 phy->gmode = 1; 2277 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2278 } 2279 return (0); 2280 } 2281 2282 static uint16_t 2283 bwn_phy_g_txctl(struct bwn_mac *mac) 2284 { 2285 struct bwn_phy *phy = &mac->mac_phy; 2286 2287 if (phy->rf_ver != 0x2050) 2288 return (0); 2289 if (phy->rf_rev == 1) 2290 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2291 if (phy->rf_rev < 6) 2292 return (BWN_TXCTL_PA2DB); 2293 if (phy->rf_rev == 8) 2294 return (BWN_TXCTL_TXMIX); 2295 return (0); 2296 } 2297 2298 static int 2299 bwn_phy_g_init(struct bwn_mac *mac) 2300 { 2301 2302 bwn_phy_g_init_sub(mac); 2303 return (0); 2304 } 2305 2306 static void 2307 bwn_phy_g_exit(struct bwn_mac *mac) 2308 { 2309 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2310 struct bwn_lo_calib *cal, *tmp; 2311 2312 if (lo == NULL) 2313 return; 2314 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2315 TAILQ_REMOVE(&lo->calib_list, cal, list); 2316 free(cal, M_DEVBUF); 2317 } 2318 } 2319 2320 static uint16_t 2321 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2322 { 2323 2324 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2325 return (BWN_READ_2(mac, BWN_PHYDATA)); 2326 } 2327 2328 static void 2329 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2330 { 2331 2332 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2333 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2334 } 2335 2336 static uint16_t 2337 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2338 { 2339 2340 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2341 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2342 return (BWN_READ_2(mac, BWN_RFDATALO)); 2343 } 2344 2345 static void 2346 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2347 { 2348 2349 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2350 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2351 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2352 } 2353 2354 static int 2355 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2356 { 2357 2358 return (mac->mac_phy.rev >= 6); 2359 } 2360 2361 static void 2362 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2363 { 2364 struct bwn_phy *phy = &mac->mac_phy; 2365 struct bwn_phy_g *pg = &phy->phy_g; 2366 unsigned int channel; 2367 uint16_t rfover, rfoverval; 2368 2369 if (on) { 2370 if (phy->rf_on) 2371 return; 2372 2373 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2374 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2375 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2376 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2377 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2378 pg->pg_radioctx_over); 2379 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2380 pg->pg_radioctx_overval); 2381 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2382 } 2383 channel = phy->chan; 2384 bwn_phy_g_switch_chan(mac, 6, 1); 2385 bwn_phy_g_switch_chan(mac, channel, 0); 2386 return; 2387 } 2388 2389 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2390 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2391 pg->pg_radioctx_over = rfover; 2392 pg->pg_radioctx_overval = rfoverval; 2393 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2394 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2395 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2396 } 2397 2398 static int 2399 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2400 { 2401 2402 if ((newchan < 1) || (newchan > 14)) 2403 return (EINVAL); 2404 bwn_phy_g_switch_chan(mac, newchan, 0); 2405 2406 return (0); 2407 } 2408 2409 static uint32_t 2410 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2411 { 2412 2413 return (1); 2414 } 2415 2416 static void 2417 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2418 { 2419 struct bwn_phy *phy = &mac->mac_phy; 2420 uint64_t hf; 2421 int autodiv = 0; 2422 uint16_t tmp; 2423 2424 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2425 autodiv = 1; 2426 2427 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2428 bwn_hf_write(mac, hf); 2429 2430 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2431 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2432 ((autodiv ? BWN_ANTAUTO1 : antenna) 2433 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2434 2435 if (autodiv) { 2436 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2437 if (antenna == BWN_ANTAUTO1) 2438 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2439 else 2440 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2441 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2442 } 2443 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2444 if (autodiv) 2445 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2446 else 2447 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2448 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2449 if (phy->rev >= 2) { 2450 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2451 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2452 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2453 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2454 0x15); 2455 if (phy->rev == 2) 2456 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2457 else 2458 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2459 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2460 8); 2461 } 2462 if (phy->rev >= 6) 2463 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2464 2465 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2466 bwn_hf_write(mac, hf); 2467 } 2468 2469 static int 2470 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2471 { 2472 struct bwn_phy *phy = &mac->mac_phy; 2473 struct bwn_phy_g *pg = &phy->phy_g; 2474 2475 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2476 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2477 2478 if (phy->rev == 0 || !phy->gmode) 2479 return (ENODEV); 2480 2481 pg->pg_aci_wlan_automatic = 0; 2482 return (0); 2483 } 2484 2485 static int 2486 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2487 { 2488 struct bwn_phy *phy = &mac->mac_phy; 2489 struct bwn_phy_g *pg = &phy->phy_g; 2490 struct bwn_softc *sc = mac->mac_sc; 2491 unsigned int tssi; 2492 int cck, ofdm; 2493 int power; 2494 int rfatt, bbatt; 2495 unsigned int max; 2496 2497 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2498 2499 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2500 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2501 if (cck < 0 && ofdm < 0) { 2502 if (ignore_tssi == 0) 2503 return (BWN_TXPWR_RES_DONE); 2504 cck = 0; 2505 ofdm = 0; 2506 } 2507 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2508 if (pg->pg_avgtssi != 0xff) 2509 tssi = (tssi + pg->pg_avgtssi) / 2; 2510 pg->pg_avgtssi = tssi; 2511 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2512 2513 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2514 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2515 max -= 3; 2516 if (max >= 120) { 2517 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2518 max = 80; 2519 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2520 } 2521 2522 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2523 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2524 tssi, 0x00), 0x3f)]); 2525 if (power == 0) 2526 return (BWN_TXPWR_RES_DONE); 2527 2528 rfatt = -((power + 7) / 8); 2529 bbatt = (-(power / 2)) - (4 * rfatt); 2530 if ((rfatt == 0) && (bbatt == 0)) 2531 return (BWN_TXPWR_RES_DONE); 2532 pg->pg_bbatt_delta = bbatt; 2533 pg->pg_rfatt_delta = rfatt; 2534 return (BWN_TXPWR_RES_NEED_ADJUST); 2535 } 2536 2537 static void 2538 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2539 { 2540 struct bwn_phy *phy = &mac->mac_phy; 2541 struct bwn_phy_g *pg = &phy->phy_g; 2542 struct bwn_softc *sc = mac->mac_sc; 2543 int rfatt, bbatt; 2544 uint8_t txctl; 2545 2546 bwn_mac_suspend(mac); 2547 2548 BWN_ASSERT_LOCKED(sc); 2549 2550 bbatt = pg->pg_bbatt.att; 2551 bbatt += pg->pg_bbatt_delta; 2552 rfatt = pg->pg_rfatt.att; 2553 rfatt += pg->pg_rfatt_delta; 2554 2555 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2556 txctl = pg->pg_txctl; 2557 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2558 if (rfatt <= 1) { 2559 if (txctl == 0) { 2560 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2561 rfatt += 2; 2562 bbatt += 2; 2563 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2564 BWN_BFL_PACTRL) { 2565 bbatt += 4 * (rfatt - 2); 2566 rfatt = 2; 2567 } 2568 } else if (rfatt > 4 && txctl) { 2569 txctl = 0; 2570 if (bbatt < 3) { 2571 rfatt -= 3; 2572 bbatt += 2; 2573 } else { 2574 rfatt -= 2; 2575 bbatt -= 2; 2576 } 2577 } 2578 } 2579 pg->pg_txctl = txctl; 2580 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2581 pg->pg_rfatt.att = rfatt; 2582 pg->pg_bbatt.att = bbatt; 2583 2584 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2585 2586 bwn_phy_lock(mac); 2587 bwn_rf_lock(mac); 2588 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2589 pg->pg_txctl); 2590 bwn_rf_unlock(mac); 2591 bwn_phy_unlock(mac); 2592 2593 bwn_mac_enable(mac); 2594 } 2595 2596 static void 2597 bwn_phy_g_task_15s(struct bwn_mac *mac) 2598 { 2599 struct bwn_phy *phy = &mac->mac_phy; 2600 struct bwn_phy_g *pg = &phy->phy_g; 2601 struct bwn_softc *sc = mac->mac_sc; 2602 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2603 unsigned long expire, now; 2604 struct bwn_lo_calib *cal, *tmp; 2605 uint8_t expired = 0; 2606 2607 bwn_mac_suspend(mac); 2608 2609 if (lo == NULL) 2610 goto fail; 2611 2612 BWN_GETTIME(now); 2613 if (bwn_has_hwpctl(mac)) { 2614 expire = now - BWN_LO_PWRVEC_EXPIRE; 2615 if (time_before(lo->pwr_vec_read_time, expire)) { 2616 bwn_lo_get_powervector(mac); 2617 bwn_phy_g_dc_lookup_init(mac, 0); 2618 } 2619 goto fail; 2620 } 2621 2622 expire = now - BWN_LO_CALIB_EXPIRE; 2623 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2624 if (!time_before(cal->calib_time, expire)) 2625 continue; 2626 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2627 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2628 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2629 expired = 1; 2630 } 2631 2632 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2633 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2634 cal->ctl.i, cal->ctl.q); 2635 2636 TAILQ_REMOVE(&lo->calib_list, cal, list); 2637 free(cal, M_DEVBUF); 2638 } 2639 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2640 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2641 &pg->pg_rfatt); 2642 if (cal == NULL) { 2643 device_printf(sc->sc_dev, 2644 "failed to recalibrate LO\n"); 2645 goto fail; 2646 } 2647 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2648 bwn_lo_write(mac, &cal->ctl); 2649 } 2650 2651 fail: 2652 bwn_mac_enable(mac); 2653 } 2654 2655 static void 2656 bwn_phy_g_task_60s(struct bwn_mac *mac) 2657 { 2658 struct bwn_phy *phy = &mac->mac_phy; 2659 struct bwn_softc *sc = mac->mac_sc; 2660 uint8_t old = phy->chan; 2661 2662 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2663 return; 2664 2665 bwn_mac_suspend(mac); 2666 bwn_nrssi_slope_11g(mac); 2667 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2668 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2669 bwn_switch_channel(mac, old); 2670 } 2671 bwn_mac_enable(mac); 2672 } 2673 2674 static void 2675 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2676 { 2677 2678 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2679 } 2680 2681 static int 2682 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2683 const struct ieee80211_bpf_params *params) 2684 { 2685 struct ieee80211com *ic = ni->ni_ic; 2686 struct bwn_softc *sc = ic->ic_softc; 2687 struct bwn_mac *mac = sc->sc_curmac; 2688 int error; 2689 2690 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || 2691 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2692 m_freem(m); 2693 return (ENETDOWN); 2694 } 2695 2696 BWN_LOCK(sc); 2697 if (bwn_tx_isfull(sc, m)) { 2698 m_freem(m); 2699 BWN_UNLOCK(sc); 2700 return (ENOBUFS); 2701 } 2702 2703 error = bwn_tx_start(sc, ni, m); 2704 if (error == 0) 2705 sc->sc_watchdog_timer = 5; 2706 BWN_UNLOCK(sc); 2707 return (error); 2708 } 2709 2710 /* 2711 * Callback from the 802.11 layer to update the slot time 2712 * based on the current setting. We use it to notify the 2713 * firmware of ERP changes and the f/w takes care of things 2714 * like slot time and preamble. 2715 */ 2716 static void 2717 bwn_updateslot(struct ieee80211com *ic) 2718 { 2719 struct bwn_softc *sc = ic->ic_softc; 2720 struct bwn_mac *mac; 2721 2722 BWN_LOCK(sc); 2723 if (sc->sc_flags & BWN_FLAG_RUNNING) { 2724 mac = (struct bwn_mac *)sc->sc_curmac; 2725 bwn_set_slot_time(mac, IEEE80211_GET_SLOTTIME(ic)); 2726 } 2727 BWN_UNLOCK(sc); 2728 } 2729 2730 /* 2731 * Callback from the 802.11 layer after a promiscuous mode change. 2732 * Note this interface does not check the operating mode as this 2733 * is an internal callback and we are expected to honor the current 2734 * state (e.g. this is used for setting the interface in promiscuous 2735 * mode when operating in hostap mode to do ACS). 2736 */ 2737 static void 2738 bwn_update_promisc(struct ieee80211com *ic) 2739 { 2740 struct bwn_softc *sc = ic->ic_softc; 2741 struct bwn_mac *mac = sc->sc_curmac; 2742 2743 BWN_LOCK(sc); 2744 mac = sc->sc_curmac; 2745 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2746 if (ic->ic_promisc > 0) 2747 sc->sc_filters |= BWN_MACCTL_PROMISC; 2748 else 2749 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2750 bwn_set_opmode(mac); 2751 } 2752 BWN_UNLOCK(sc); 2753 } 2754 2755 /* 2756 * Callback from the 802.11 layer to update WME parameters. 2757 */ 2758 static int 2759 bwn_wme_update(struct ieee80211com *ic) 2760 { 2761 struct bwn_softc *sc = ic->ic_softc; 2762 struct bwn_mac *mac = sc->sc_curmac; 2763 struct wmeParams *wmep; 2764 int i; 2765 2766 BWN_LOCK(sc); 2767 mac = sc->sc_curmac; 2768 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2769 bwn_mac_suspend(mac); 2770 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2771 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2772 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2773 } 2774 bwn_mac_enable(mac); 2775 } 2776 BWN_UNLOCK(sc); 2777 return (0); 2778 } 2779 2780 static void 2781 bwn_scan_start(struct ieee80211com *ic) 2782 { 2783 struct bwn_softc *sc = ic->ic_softc; 2784 struct bwn_mac *mac; 2785 2786 BWN_LOCK(sc); 2787 mac = sc->sc_curmac; 2788 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2789 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2790 bwn_set_opmode(mac); 2791 /* disable CFP update during scan */ 2792 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2793 } 2794 BWN_UNLOCK(sc); 2795 } 2796 2797 static void 2798 bwn_scan_end(struct ieee80211com *ic) 2799 { 2800 struct bwn_softc *sc = ic->ic_softc; 2801 struct bwn_mac *mac; 2802 2803 BWN_LOCK(sc); 2804 mac = sc->sc_curmac; 2805 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2806 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2807 bwn_set_opmode(mac); 2808 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2809 } 2810 BWN_UNLOCK(sc); 2811 } 2812 2813 static void 2814 bwn_set_channel(struct ieee80211com *ic) 2815 { 2816 struct bwn_softc *sc = ic->ic_softc; 2817 struct bwn_mac *mac = sc->sc_curmac; 2818 struct bwn_phy *phy = &mac->mac_phy; 2819 int chan, error; 2820 2821 BWN_LOCK(sc); 2822 2823 error = bwn_switch_band(sc, ic->ic_curchan); 2824 if (error) 2825 goto fail; 2826 bwn_mac_suspend(mac); 2827 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2828 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2829 if (chan != phy->chan) 2830 bwn_switch_channel(mac, chan); 2831 2832 /* TX power level */ 2833 if (ic->ic_curchan->ic_maxpower != 0 && 2834 ic->ic_curchan->ic_maxpower != phy->txpower) { 2835 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2836 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2837 BWN_TXPWR_IGNORE_TSSI); 2838 } 2839 2840 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2841 if (phy->set_antenna) 2842 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2843 2844 if (sc->sc_rf_enabled != phy->rf_on) { 2845 if (sc->sc_rf_enabled) { 2846 bwn_rf_turnon(mac); 2847 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2848 device_printf(sc->sc_dev, 2849 "please turn on the RF switch\n"); 2850 } else 2851 bwn_rf_turnoff(mac); 2852 } 2853 2854 bwn_mac_enable(mac); 2855 2856 fail: 2857 /* 2858 * Setup radio tap channel freq and flags 2859 */ 2860 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2861 htole16(ic->ic_curchan->ic_freq); 2862 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2863 htole16(ic->ic_curchan->ic_flags & 0xffff); 2864 2865 BWN_UNLOCK(sc); 2866 } 2867 2868 static struct ieee80211vap * 2869 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2870 enum ieee80211_opmode opmode, int flags, 2871 const uint8_t bssid[IEEE80211_ADDR_LEN], 2872 const uint8_t mac[IEEE80211_ADDR_LEN]) 2873 { 2874 struct ieee80211vap *vap; 2875 struct bwn_vap *bvp; 2876 2877 switch (opmode) { 2878 case IEEE80211_M_HOSTAP: 2879 case IEEE80211_M_MBSS: 2880 case IEEE80211_M_STA: 2881 case IEEE80211_M_WDS: 2882 case IEEE80211_M_MONITOR: 2883 case IEEE80211_M_IBSS: 2884 case IEEE80211_M_AHDEMO: 2885 break; 2886 default: 2887 return (NULL); 2888 } 2889 2890 bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); 2891 vap = &bvp->bv_vap; 2892 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 2893 /* override with driver methods */ 2894 bvp->bv_newstate = vap->iv_newstate; 2895 vap->iv_newstate = bwn_newstate; 2896 2897 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2898 vap->iv_max_aid = BWN_STAID_MAX; 2899 2900 ieee80211_ratectl_init(vap); 2901 2902 /* complete setup */ 2903 ieee80211_vap_attach(vap, ieee80211_media_change, 2904 ieee80211_media_status, mac); 2905 return (vap); 2906 } 2907 2908 static void 2909 bwn_vap_delete(struct ieee80211vap *vap) 2910 { 2911 struct bwn_vap *bvp = BWN_VAP(vap); 2912 2913 ieee80211_ratectl_deinit(vap); 2914 ieee80211_vap_detach(vap); 2915 free(bvp, M_80211_VAP); 2916 } 2917 2918 static int 2919 bwn_init(struct bwn_softc *sc) 2920 { 2921 struct bwn_mac *mac; 2922 int error; 2923 2924 BWN_ASSERT_LOCKED(sc); 2925 2926 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2927 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2928 sc->sc_filters = 0; 2929 bwn_wme_clear(sc); 2930 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2931 sc->sc_rf_enabled = 1; 2932 2933 mac = sc->sc_curmac; 2934 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2935 error = bwn_core_init(mac); 2936 if (error != 0) 2937 return (error); 2938 } 2939 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2940 bwn_core_start(mac); 2941 2942 bwn_set_opmode(mac); 2943 bwn_set_pretbtt(mac); 2944 bwn_spu_setdelay(mac, 0); 2945 bwn_set_macaddr(mac); 2946 2947 sc->sc_flags |= BWN_FLAG_RUNNING; 2948 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2949 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2950 2951 return (0); 2952 } 2953 2954 static void 2955 bwn_stop(struct bwn_softc *sc) 2956 { 2957 struct bwn_mac *mac = sc->sc_curmac; 2958 2959 BWN_ASSERT_LOCKED(sc); 2960 2961 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2962 /* XXX FIXME opmode not based on VAP */ 2963 bwn_set_opmode(mac); 2964 bwn_set_macaddr(mac); 2965 } 2966 2967 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 2968 bwn_core_stop(mac); 2969 2970 callout_stop(&sc->sc_led_blink_ch); 2971 sc->sc_led_blinking = 0; 2972 2973 bwn_core_exit(mac); 2974 sc->sc_rf_enabled = 0; 2975 2976 sc->sc_flags &= ~BWN_FLAG_RUNNING; 2977 } 2978 2979 static void 2980 bwn_wme_clear(struct bwn_softc *sc) 2981 { 2982 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 2983 struct wmeParams *p; 2984 unsigned int i; 2985 2986 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 2987 ("%s:%d: fail", __func__, __LINE__)); 2988 2989 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2990 p = &(sc->sc_wmeParams[i]); 2991 2992 switch (bwn_wme_shm_offsets[i]) { 2993 case BWN_WME_VOICE: 2994 p->wmep_txopLimit = 0; 2995 p->wmep_aifsn = 2; 2996 /* XXX FIXME: log2(cwmin) */ 2997 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 2998 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 2999 break; 3000 case BWN_WME_VIDEO: 3001 p->wmep_txopLimit = 0; 3002 p->wmep_aifsn = 2; 3003 /* XXX FIXME: log2(cwmin) */ 3004 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3005 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3006 break; 3007 case BWN_WME_BESTEFFORT: 3008 p->wmep_txopLimit = 0; 3009 p->wmep_aifsn = 3; 3010 /* XXX FIXME: log2(cwmin) */ 3011 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3012 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3013 break; 3014 case BWN_WME_BACKGROUND: 3015 p->wmep_txopLimit = 0; 3016 p->wmep_aifsn = 7; 3017 /* XXX FIXME: log2(cwmin) */ 3018 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3019 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3020 break; 3021 default: 3022 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3023 } 3024 } 3025 } 3026 3027 static int 3028 bwn_core_init(struct bwn_mac *mac) 3029 { 3030 struct bwn_softc *sc = mac->mac_sc; 3031 uint64_t hf; 3032 int error; 3033 3034 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3035 ("%s:%d: fail", __func__, __LINE__)); 3036 3037 siba_powerup(sc->sc_dev, 0); 3038 if (!siba_dev_isup(sc->sc_dev)) 3039 bwn_reset_core(mac, 3040 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3041 3042 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3043 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3044 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3045 BWN_GETTIME(mac->mac_phy.nexttime); 3046 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3047 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3048 mac->mac_stats.link_noise = -95; 3049 mac->mac_reason_intr = 0; 3050 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3051 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3052 #ifdef BWN_DEBUG 3053 if (sc->sc_debug & BWN_DEBUG_XMIT) 3054 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3055 #endif 3056 mac->mac_suspended = 1; 3057 mac->mac_task_state = 0; 3058 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3059 3060 mac->mac_phy.init_pre(mac); 3061 3062 siba_pcicore_intr(sc->sc_dev); 3063 3064 siba_fix_imcfglobug(sc->sc_dev); 3065 bwn_bt_disable(mac); 3066 if (mac->mac_phy.prepare_hw) { 3067 error = mac->mac_phy.prepare_hw(mac); 3068 if (error) 3069 goto fail0; 3070 } 3071 error = bwn_chip_init(mac); 3072 if (error) 3073 goto fail0; 3074 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3075 siba_get_revid(sc->sc_dev)); 3076 hf = bwn_hf_read(mac); 3077 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3078 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3079 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3080 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3081 if (mac->mac_phy.rev == 1) 3082 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3083 } 3084 if (mac->mac_phy.rf_ver == 0x2050) { 3085 if (mac->mac_phy.rf_rev < 6) 3086 hf |= BWN_HF_FORCE_VCO_RECALC; 3087 if (mac->mac_phy.rf_rev == 6) 3088 hf |= BWN_HF_4318_TSSI; 3089 } 3090 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3091 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3092 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3093 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3094 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3095 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3096 bwn_hf_write(mac, hf); 3097 3098 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3099 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3100 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3101 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3102 3103 bwn_rate_init(mac); 3104 bwn_set_phytxctl(mac); 3105 3106 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3107 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3108 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3109 3110 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3111 bwn_pio_init(mac); 3112 else 3113 bwn_dma_init(mac); 3114 bwn_wme_init(mac); 3115 bwn_spu_setdelay(mac, 1); 3116 bwn_bt_enable(mac); 3117 3118 siba_powerup(sc->sc_dev, 3119 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3120 bwn_set_macaddr(mac); 3121 bwn_crypt_init(mac); 3122 3123 /* XXX LED initializatin */ 3124 3125 mac->mac_status = BWN_MAC_STATUS_INITED; 3126 3127 return (error); 3128 3129 fail0: 3130 siba_powerdown(sc->sc_dev); 3131 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3132 ("%s:%d: fail", __func__, __LINE__)); 3133 return (error); 3134 } 3135 3136 static void 3137 bwn_core_start(struct bwn_mac *mac) 3138 { 3139 struct bwn_softc *sc = mac->mac_sc; 3140 uint32_t tmp; 3141 3142 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3143 ("%s:%d: fail", __func__, __LINE__)); 3144 3145 if (siba_get_revid(sc->sc_dev) < 5) 3146 return; 3147 3148 while (1) { 3149 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3150 if (!(tmp & 0x00000001)) 3151 break; 3152 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3153 } 3154 3155 bwn_mac_enable(mac); 3156 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3157 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3158 3159 mac->mac_status = BWN_MAC_STATUS_STARTED; 3160 } 3161 3162 static void 3163 bwn_core_exit(struct bwn_mac *mac) 3164 { 3165 struct bwn_softc *sc = mac->mac_sc; 3166 uint32_t macctl; 3167 3168 BWN_ASSERT_LOCKED(mac->mac_sc); 3169 3170 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3171 ("%s:%d: fail", __func__, __LINE__)); 3172 3173 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3174 return; 3175 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3176 3177 macctl = BWN_READ_4(mac, BWN_MACCTL); 3178 macctl &= ~BWN_MACCTL_MCODE_RUN; 3179 macctl |= BWN_MACCTL_MCODE_JMP0; 3180 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3181 3182 bwn_dma_stop(mac); 3183 bwn_pio_stop(mac); 3184 bwn_chip_exit(mac); 3185 mac->mac_phy.switch_analog(mac, 0); 3186 siba_dev_down(sc->sc_dev, 0); 3187 siba_powerdown(sc->sc_dev); 3188 } 3189 3190 static void 3191 bwn_bt_disable(struct bwn_mac *mac) 3192 { 3193 struct bwn_softc *sc = mac->mac_sc; 3194 3195 (void)sc; 3196 /* XXX do nothing yet */ 3197 } 3198 3199 static int 3200 bwn_chip_init(struct bwn_mac *mac) 3201 { 3202 struct bwn_softc *sc = mac->mac_sc; 3203 struct bwn_phy *phy = &mac->mac_phy; 3204 uint32_t macctl; 3205 int error; 3206 3207 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3208 if (phy->gmode) 3209 macctl |= BWN_MACCTL_GMODE; 3210 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3211 3212 error = bwn_fw_fillinfo(mac); 3213 if (error) 3214 return (error); 3215 error = bwn_fw_loaducode(mac); 3216 if (error) 3217 return (error); 3218 3219 error = bwn_gpio_init(mac); 3220 if (error) 3221 return (error); 3222 3223 error = bwn_fw_loadinitvals(mac); 3224 if (error) { 3225 siba_gpio_set(sc->sc_dev, 0); 3226 return (error); 3227 } 3228 phy->switch_analog(mac, 1); 3229 error = bwn_phy_init(mac); 3230 if (error) { 3231 siba_gpio_set(sc->sc_dev, 0); 3232 return (error); 3233 } 3234 if (phy->set_im) 3235 phy->set_im(mac, BWN_IMMODE_NONE); 3236 if (phy->set_antenna) 3237 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3238 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3239 3240 if (phy->type == BWN_PHYTYPE_B) 3241 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3242 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3243 if (siba_get_revid(sc->sc_dev) < 5) 3244 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3245 3246 BWN_WRITE_4(mac, BWN_MACCTL, 3247 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3248 BWN_WRITE_4(mac, BWN_MACCTL, 3249 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3250 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3251 3252 bwn_set_opmode(mac); 3253 if (siba_get_revid(sc->sc_dev) < 3) { 3254 BWN_WRITE_2(mac, 0x060e, 0x0000); 3255 BWN_WRITE_2(mac, 0x0610, 0x8000); 3256 BWN_WRITE_2(mac, 0x0604, 0x0000); 3257 BWN_WRITE_2(mac, 0x0606, 0x0200); 3258 } else { 3259 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3260 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3261 } 3262 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3263 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3264 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3265 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3266 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3267 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3268 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3269 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3270 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3271 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3272 return (error); 3273 } 3274 3275 /* read hostflags */ 3276 static uint64_t 3277 bwn_hf_read(struct bwn_mac *mac) 3278 { 3279 uint64_t ret; 3280 3281 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3282 ret <<= 16; 3283 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3284 ret <<= 16; 3285 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3286 return (ret); 3287 } 3288 3289 static void 3290 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3291 { 3292 3293 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3294 (value & 0x00000000ffffull)); 3295 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3296 (value & 0x0000ffff0000ull) >> 16); 3297 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3298 (value & 0xffff00000000ULL) >> 32); 3299 } 3300 3301 static void 3302 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3303 { 3304 3305 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3306 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3307 } 3308 3309 static void 3310 bwn_rate_init(struct bwn_mac *mac) 3311 { 3312 3313 switch (mac->mac_phy.type) { 3314 case BWN_PHYTYPE_A: 3315 case BWN_PHYTYPE_G: 3316 case BWN_PHYTYPE_LP: 3317 case BWN_PHYTYPE_N: 3318 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3319 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3320 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3321 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3322 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3323 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3324 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3325 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3326 break; 3327 /* FALLTHROUGH */ 3328 case BWN_PHYTYPE_B: 3329 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3330 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3331 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3332 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3333 break; 3334 default: 3335 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3336 } 3337 } 3338 3339 static void 3340 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3341 { 3342 uint16_t offset; 3343 3344 if (ofdm) { 3345 offset = 0x480; 3346 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3347 } else { 3348 offset = 0x4c0; 3349 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3350 } 3351 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3352 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3353 } 3354 3355 static uint8_t 3356 bwn_plcp_getcck(const uint8_t bitrate) 3357 { 3358 3359 switch (bitrate) { 3360 case BWN_CCK_RATE_1MB: 3361 return (0x0a); 3362 case BWN_CCK_RATE_2MB: 3363 return (0x14); 3364 case BWN_CCK_RATE_5MB: 3365 return (0x37); 3366 case BWN_CCK_RATE_11MB: 3367 return (0x6e); 3368 } 3369 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3370 return (0); 3371 } 3372 3373 static uint8_t 3374 bwn_plcp_getofdm(const uint8_t bitrate) 3375 { 3376 3377 switch (bitrate) { 3378 case BWN_OFDM_RATE_6MB: 3379 return (0xb); 3380 case BWN_OFDM_RATE_9MB: 3381 return (0xf); 3382 case BWN_OFDM_RATE_12MB: 3383 return (0xa); 3384 case BWN_OFDM_RATE_18MB: 3385 return (0xe); 3386 case BWN_OFDM_RATE_24MB: 3387 return (0x9); 3388 case BWN_OFDM_RATE_36MB: 3389 return (0xd); 3390 case BWN_OFDM_RATE_48MB: 3391 return (0x8); 3392 case BWN_OFDM_RATE_54MB: 3393 return (0xc); 3394 } 3395 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3396 return (0); 3397 } 3398 3399 static void 3400 bwn_set_phytxctl(struct bwn_mac *mac) 3401 { 3402 uint16_t ctl; 3403 3404 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3405 BWN_TX_PHY_TXPWR); 3406 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3407 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3408 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3409 } 3410 3411 static void 3412 bwn_pio_init(struct bwn_mac *mac) 3413 { 3414 struct bwn_pio *pio = &mac->mac_method.pio; 3415 3416 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3417 & ~BWN_MACCTL_BIGENDIAN); 3418 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3419 3420 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3421 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3422 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3423 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3424 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3425 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3426 } 3427 3428 static void 3429 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3430 int index) 3431 { 3432 struct bwn_pio_txpkt *tp; 3433 struct bwn_softc *sc = mac->mac_sc; 3434 unsigned int i; 3435 3436 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3437 tq->tq_index = index; 3438 3439 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3440 if (siba_get_revid(sc->sc_dev) >= 8) 3441 tq->tq_size = 1920; 3442 else { 3443 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3444 tq->tq_size -= 80; 3445 } 3446 3447 TAILQ_INIT(&tq->tq_pktlist); 3448 for (i = 0; i < N(tq->tq_pkts); i++) { 3449 tp = &(tq->tq_pkts[i]); 3450 tp->tp_index = i; 3451 tp->tp_queue = tq; 3452 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3453 } 3454 } 3455 3456 static uint16_t 3457 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3458 { 3459 struct bwn_softc *sc = mac->mac_sc; 3460 static const uint16_t bases[] = { 3461 BWN_PIO_BASE0, 3462 BWN_PIO_BASE1, 3463 BWN_PIO_BASE2, 3464 BWN_PIO_BASE3, 3465 BWN_PIO_BASE4, 3466 BWN_PIO_BASE5, 3467 BWN_PIO_BASE6, 3468 BWN_PIO_BASE7, 3469 }; 3470 static const uint16_t bases_rev11[] = { 3471 BWN_PIO11_BASE0, 3472 BWN_PIO11_BASE1, 3473 BWN_PIO11_BASE2, 3474 BWN_PIO11_BASE3, 3475 BWN_PIO11_BASE4, 3476 BWN_PIO11_BASE5, 3477 }; 3478 3479 if (siba_get_revid(sc->sc_dev) >= 11) { 3480 if (index >= N(bases_rev11)) 3481 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3482 return (bases_rev11[index]); 3483 } 3484 if (index >= N(bases)) 3485 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3486 return (bases[index]); 3487 } 3488 3489 static void 3490 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3491 int index) 3492 { 3493 struct bwn_softc *sc = mac->mac_sc; 3494 3495 prq->prq_mac = mac; 3496 prq->prq_rev = siba_get_revid(sc->sc_dev); 3497 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3498 bwn_dma_rxdirectfifo(mac, index, 1); 3499 } 3500 3501 static void 3502 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3503 { 3504 if (tq == NULL) 3505 return; 3506 bwn_pio_cancel_tx_packets(tq); 3507 } 3508 3509 static void 3510 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3511 { 3512 3513 bwn_destroy_pioqueue_tx(pio); 3514 } 3515 3516 static uint16_t 3517 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3518 uint16_t offset) 3519 { 3520 3521 return (BWN_READ_2(mac, tq->tq_base + offset)); 3522 } 3523 3524 static void 3525 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3526 { 3527 uint32_t ctl; 3528 int type; 3529 uint16_t base; 3530 3531 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3532 base = bwn_dma_base(type, idx); 3533 if (type == BWN_DMA_64BIT) { 3534 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3535 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3536 if (enable) 3537 ctl |= BWN_DMA64_RXDIRECTFIFO; 3538 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3539 } else { 3540 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3541 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3542 if (enable) 3543 ctl |= BWN_DMA32_RXDIRECTFIFO; 3544 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3545 } 3546 } 3547 3548 static uint64_t 3549 bwn_dma_mask(struct bwn_mac *mac) 3550 { 3551 uint32_t tmp; 3552 uint16_t base; 3553 3554 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3555 if (tmp & SIBA_TGSHIGH_DMA64) 3556 return (BWN_DMA_BIT_MASK(64)); 3557 base = bwn_dma_base(0, 0); 3558 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3559 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3560 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3561 return (BWN_DMA_BIT_MASK(32)); 3562 3563 return (BWN_DMA_BIT_MASK(30)); 3564 } 3565 3566 static int 3567 bwn_dma_mask2type(uint64_t dmamask) 3568 { 3569 3570 if (dmamask == BWN_DMA_BIT_MASK(30)) 3571 return (BWN_DMA_30BIT); 3572 if (dmamask == BWN_DMA_BIT_MASK(32)) 3573 return (BWN_DMA_32BIT); 3574 if (dmamask == BWN_DMA_BIT_MASK(64)) 3575 return (BWN_DMA_64BIT); 3576 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3577 return (BWN_DMA_30BIT); 3578 } 3579 3580 static void 3581 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3582 { 3583 struct bwn_pio_txpkt *tp; 3584 unsigned int i; 3585 3586 for (i = 0; i < N(tq->tq_pkts); i++) { 3587 tp = &(tq->tq_pkts[i]); 3588 if (tp->tp_m) { 3589 m_freem(tp->tp_m); 3590 tp->tp_m = NULL; 3591 } 3592 } 3593 } 3594 3595 static uint16_t 3596 bwn_dma_base(int type, int controller_idx) 3597 { 3598 static const uint16_t map64[] = { 3599 BWN_DMA64_BASE0, 3600 BWN_DMA64_BASE1, 3601 BWN_DMA64_BASE2, 3602 BWN_DMA64_BASE3, 3603 BWN_DMA64_BASE4, 3604 BWN_DMA64_BASE5, 3605 }; 3606 static const uint16_t map32[] = { 3607 BWN_DMA32_BASE0, 3608 BWN_DMA32_BASE1, 3609 BWN_DMA32_BASE2, 3610 BWN_DMA32_BASE3, 3611 BWN_DMA32_BASE4, 3612 BWN_DMA32_BASE5, 3613 }; 3614 3615 if (type == BWN_DMA_64BIT) { 3616 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3617 ("%s:%d: fail", __func__, __LINE__)); 3618 return (map64[controller_idx]); 3619 } 3620 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3621 ("%s:%d: fail", __func__, __LINE__)); 3622 return (map32[controller_idx]); 3623 } 3624 3625 static void 3626 bwn_dma_init(struct bwn_mac *mac) 3627 { 3628 struct bwn_dma *dma = &mac->mac_method.dma; 3629 3630 /* setup TX DMA channels. */ 3631 bwn_dma_setup(dma->wme[WME_AC_BK]); 3632 bwn_dma_setup(dma->wme[WME_AC_BE]); 3633 bwn_dma_setup(dma->wme[WME_AC_VI]); 3634 bwn_dma_setup(dma->wme[WME_AC_VO]); 3635 bwn_dma_setup(dma->mcast); 3636 /* setup RX DMA channel. */ 3637 bwn_dma_setup(dma->rx); 3638 } 3639 3640 static struct bwn_dma_ring * 3641 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3642 int for_tx, int type) 3643 { 3644 struct bwn_dma *dma = &mac->mac_method.dma; 3645 struct bwn_dma_ring *dr; 3646 struct bwn_dmadesc_generic *desc; 3647 struct bwn_dmadesc_meta *mt; 3648 struct bwn_softc *sc = mac->mac_sc; 3649 int error, i; 3650 3651 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3652 if (dr == NULL) 3653 goto out; 3654 dr->dr_numslots = BWN_RXRING_SLOTS; 3655 if (for_tx) 3656 dr->dr_numslots = BWN_TXRING_SLOTS; 3657 3658 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3659 M_DEVBUF, M_NOWAIT | M_ZERO); 3660 if (dr->dr_meta == NULL) 3661 goto fail0; 3662 3663 dr->dr_type = type; 3664 dr->dr_mac = mac; 3665 dr->dr_base = bwn_dma_base(type, controller_index); 3666 dr->dr_index = controller_index; 3667 if (type == BWN_DMA_64BIT) { 3668 dr->getdesc = bwn_dma_64_getdesc; 3669 dr->setdesc = bwn_dma_64_setdesc; 3670 dr->start_transfer = bwn_dma_64_start_transfer; 3671 dr->suspend = bwn_dma_64_suspend; 3672 dr->resume = bwn_dma_64_resume; 3673 dr->get_curslot = bwn_dma_64_get_curslot; 3674 dr->set_curslot = bwn_dma_64_set_curslot; 3675 } else { 3676 dr->getdesc = bwn_dma_32_getdesc; 3677 dr->setdesc = bwn_dma_32_setdesc; 3678 dr->start_transfer = bwn_dma_32_start_transfer; 3679 dr->suspend = bwn_dma_32_suspend; 3680 dr->resume = bwn_dma_32_resume; 3681 dr->get_curslot = bwn_dma_32_get_curslot; 3682 dr->set_curslot = bwn_dma_32_set_curslot; 3683 } 3684 if (for_tx) { 3685 dr->dr_tx = 1; 3686 dr->dr_curslot = -1; 3687 } else { 3688 if (dr->dr_index == 0) { 3689 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3690 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3691 } else 3692 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3693 } 3694 3695 error = bwn_dma_allocringmemory(dr); 3696 if (error) 3697 goto fail2; 3698 3699 if (for_tx) { 3700 /* 3701 * Assumption: BWN_TXRING_SLOTS can be divided by 3702 * BWN_TX_SLOTS_PER_FRAME 3703 */ 3704 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3705 ("%s:%d: fail", __func__, __LINE__)); 3706 3707 dr->dr_txhdr_cache = 3708 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3709 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3710 KASSERT(dr->dr_txhdr_cache != NULL, 3711 ("%s:%d: fail", __func__, __LINE__)); 3712 3713 /* 3714 * Create TX ring DMA stuffs 3715 */ 3716 error = bus_dma_tag_create(dma->parent_dtag, 3717 BWN_ALIGN, 0, 3718 BUS_SPACE_MAXADDR, 3719 BUS_SPACE_MAXADDR, 3720 NULL, NULL, 3721 BWN_HDRSIZE(mac), 3722 1, 3723 BUS_SPACE_MAXSIZE_32BIT, 3724 0, 3725 NULL, NULL, 3726 &dr->dr_txring_dtag); 3727 if (error) { 3728 device_printf(sc->sc_dev, 3729 "can't create TX ring DMA tag: TODO frees\n"); 3730 goto fail1; 3731 } 3732 3733 for (i = 0; i < dr->dr_numslots; i += 2) { 3734 dr->getdesc(dr, i, &desc, &mt); 3735 3736 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3737 mt->mt_m = NULL; 3738 mt->mt_ni = NULL; 3739 mt->mt_islast = 0; 3740 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3741 &mt->mt_dmap); 3742 if (error) { 3743 device_printf(sc->sc_dev, 3744 "can't create RX buf DMA map\n"); 3745 goto fail1; 3746 } 3747 3748 dr->getdesc(dr, i + 1, &desc, &mt); 3749 3750 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3751 mt->mt_m = NULL; 3752 mt->mt_ni = NULL; 3753 mt->mt_islast = 1; 3754 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3755 &mt->mt_dmap); 3756 if (error) { 3757 device_printf(sc->sc_dev, 3758 "can't create RX buf DMA map\n"); 3759 goto fail1; 3760 } 3761 } 3762 } else { 3763 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3764 &dr->dr_spare_dmap); 3765 if (error) { 3766 device_printf(sc->sc_dev, 3767 "can't create RX buf DMA map\n"); 3768 goto out; /* XXX wrong! */ 3769 } 3770 3771 for (i = 0; i < dr->dr_numslots; i++) { 3772 dr->getdesc(dr, i, &desc, &mt); 3773 3774 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3775 &mt->mt_dmap); 3776 if (error) { 3777 device_printf(sc->sc_dev, 3778 "can't create RX buf DMA map\n"); 3779 goto out; /* XXX wrong! */ 3780 } 3781 error = bwn_dma_newbuf(dr, desc, mt, 1); 3782 if (error) { 3783 device_printf(sc->sc_dev, 3784 "failed to allocate RX buf\n"); 3785 goto out; /* XXX wrong! */ 3786 } 3787 } 3788 3789 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3790 BUS_DMASYNC_PREWRITE); 3791 3792 dr->dr_usedslot = dr->dr_numslots; 3793 } 3794 3795 out: 3796 return (dr); 3797 3798 fail2: 3799 free(dr->dr_txhdr_cache, M_DEVBUF); 3800 fail1: 3801 free(dr->dr_meta, M_DEVBUF); 3802 fail0: 3803 free(dr, M_DEVBUF); 3804 return (NULL); 3805 } 3806 3807 static void 3808 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3809 { 3810 3811 if (dr == NULL) 3812 return; 3813 3814 bwn_dma_free_descbufs(*dr); 3815 bwn_dma_free_ringmemory(*dr); 3816 3817 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3818 free((*dr)->dr_meta, M_DEVBUF); 3819 free(*dr, M_DEVBUF); 3820 3821 *dr = NULL; 3822 } 3823 3824 static void 3825 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3826 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3827 { 3828 struct bwn_dmadesc32 *desc; 3829 3830 *meta = &(dr->dr_meta[slot]); 3831 desc = dr->dr_ring_descbase; 3832 desc = &(desc[slot]); 3833 3834 *gdesc = (struct bwn_dmadesc_generic *)desc; 3835 } 3836 3837 static void 3838 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3839 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3840 int start, int end, int irq) 3841 { 3842 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3843 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3844 uint32_t addr, addrext, ctl; 3845 int slot; 3846 3847 slot = (int)(&(desc->dma.dma32) - descbase); 3848 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3849 ("%s:%d: fail", __func__, __LINE__)); 3850 3851 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3852 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3853 addr |= siba_dma_translation(sc->sc_dev); 3854 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3855 if (slot == dr->dr_numslots - 1) 3856 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3857 if (start) 3858 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3859 if (end) 3860 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3861 if (irq) 3862 ctl |= BWN_DMA32_DCTL_IRQ; 3863 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3864 & BWN_DMA32_DCTL_ADDREXT_MASK; 3865 3866 desc->dma.dma32.control = htole32(ctl); 3867 desc->dma.dma32.address = htole32(addr); 3868 } 3869 3870 static void 3871 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3872 { 3873 3874 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3875 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3876 } 3877 3878 static void 3879 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3880 { 3881 3882 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3883 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3884 } 3885 3886 static void 3887 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3888 { 3889 3890 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3891 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3892 } 3893 3894 static int 3895 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3896 { 3897 uint32_t val; 3898 3899 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3900 val &= BWN_DMA32_RXDPTR; 3901 3902 return (val / sizeof(struct bwn_dmadesc32)); 3903 } 3904 3905 static void 3906 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3907 { 3908 3909 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3910 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3911 } 3912 3913 static void 3914 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3915 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3916 { 3917 struct bwn_dmadesc64 *desc; 3918 3919 *meta = &(dr->dr_meta[slot]); 3920 desc = dr->dr_ring_descbase; 3921 desc = &(desc[slot]); 3922 3923 *gdesc = (struct bwn_dmadesc_generic *)desc; 3924 } 3925 3926 static void 3927 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3928 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3929 int start, int end, int irq) 3930 { 3931 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3932 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3933 int slot; 3934 uint32_t ctl0 = 0, ctl1 = 0; 3935 uint32_t addrlo, addrhi; 3936 uint32_t addrext; 3937 3938 slot = (int)(&(desc->dma.dma64) - descbase); 3939 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3940 ("%s:%d: fail", __func__, __LINE__)); 3941 3942 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3943 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3944 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3945 30; 3946 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3947 if (slot == dr->dr_numslots - 1) 3948 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3949 if (start) 3950 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3951 if (end) 3952 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3953 if (irq) 3954 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3955 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3956 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3957 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3958 3959 desc->dma.dma64.control0 = htole32(ctl0); 3960 desc->dma.dma64.control1 = htole32(ctl1); 3961 desc->dma.dma64.address_low = htole32(addrlo); 3962 desc->dma.dma64.address_high = htole32(addrhi); 3963 } 3964 3965 static void 3966 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3967 { 3968 3969 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3970 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3971 } 3972 3973 static void 3974 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3975 { 3976 3977 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3978 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3979 } 3980 3981 static void 3982 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3983 { 3984 3985 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3986 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 3987 } 3988 3989 static int 3990 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 3991 { 3992 uint32_t val; 3993 3994 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 3995 val &= BWN_DMA64_RXSTATDPTR; 3996 3997 return (val / sizeof(struct bwn_dmadesc64)); 3998 } 3999 4000 static void 4001 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4002 { 4003 4004 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4005 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4006 } 4007 4008 static int 4009 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4010 { 4011 struct bwn_mac *mac = dr->dr_mac; 4012 struct bwn_dma *dma = &mac->mac_method.dma; 4013 struct bwn_softc *sc = mac->mac_sc; 4014 int error; 4015 4016 error = bus_dma_tag_create(dma->parent_dtag, 4017 BWN_ALIGN, 0, 4018 BUS_SPACE_MAXADDR, 4019 BUS_SPACE_MAXADDR, 4020 NULL, NULL, 4021 BWN_DMA_RINGMEMSIZE, 4022 1, 4023 BUS_SPACE_MAXSIZE_32BIT, 4024 0, 4025 NULL, NULL, 4026 &dr->dr_ring_dtag); 4027 if (error) { 4028 device_printf(sc->sc_dev, 4029 "can't create TX ring DMA tag: TODO frees\n"); 4030 return (-1); 4031 } 4032 4033 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4034 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4035 &dr->dr_ring_dmap); 4036 if (error) { 4037 device_printf(sc->sc_dev, 4038 "can't allocate DMA mem: TODO frees\n"); 4039 return (-1); 4040 } 4041 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4042 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4043 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4044 if (error) { 4045 device_printf(sc->sc_dev, 4046 "can't load DMA mem: TODO free\n"); 4047 return (-1); 4048 } 4049 4050 return (0); 4051 } 4052 4053 static void 4054 bwn_dma_setup(struct bwn_dma_ring *dr) 4055 { 4056 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4057 uint64_t ring64; 4058 uint32_t addrext, ring32, value; 4059 uint32_t trans = siba_dma_translation(sc->sc_dev); 4060 4061 if (dr->dr_tx) { 4062 dr->dr_curslot = -1; 4063 4064 if (dr->dr_type == BWN_DMA_64BIT) { 4065 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4066 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4067 >> 30; 4068 value = BWN_DMA64_TXENABLE; 4069 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4070 & BWN_DMA64_TXADDREXT_MASK; 4071 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4072 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4073 (ring64 & 0xffffffff)); 4074 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4075 ((ring64 >> 32) & 4076 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4077 } else { 4078 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4079 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4080 value = BWN_DMA32_TXENABLE; 4081 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4082 & BWN_DMA32_TXADDREXT_MASK; 4083 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4084 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4085 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4086 } 4087 return; 4088 } 4089 4090 /* 4091 * set for RX 4092 */ 4093 dr->dr_usedslot = dr->dr_numslots; 4094 4095 if (dr->dr_type == BWN_DMA_64BIT) { 4096 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4097 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4098 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4099 value |= BWN_DMA64_RXENABLE; 4100 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4101 & BWN_DMA64_RXADDREXT_MASK; 4102 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4103 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4104 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4105 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4106 | (trans << 1)); 4107 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4108 sizeof(struct bwn_dmadesc64)); 4109 } else { 4110 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4111 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4112 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4113 value |= BWN_DMA32_RXENABLE; 4114 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4115 & BWN_DMA32_RXADDREXT_MASK; 4116 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4117 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4118 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4119 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4120 sizeof(struct bwn_dmadesc32)); 4121 } 4122 } 4123 4124 static void 4125 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4126 { 4127 4128 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4129 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4130 dr->dr_ring_dmap); 4131 } 4132 4133 static void 4134 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4135 { 4136 4137 if (dr->dr_tx) { 4138 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4139 if (dr->dr_type == BWN_DMA_64BIT) { 4140 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4141 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4142 } else 4143 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4144 } else { 4145 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4146 if (dr->dr_type == BWN_DMA_64BIT) { 4147 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4148 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4149 } else 4150 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4151 } 4152 } 4153 4154 static void 4155 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4156 { 4157 struct bwn_dmadesc_generic *desc; 4158 struct bwn_dmadesc_meta *meta; 4159 struct bwn_mac *mac = dr->dr_mac; 4160 struct bwn_dma *dma = &mac->mac_method.dma; 4161 struct bwn_softc *sc = mac->mac_sc; 4162 int i; 4163 4164 if (!dr->dr_usedslot) 4165 return; 4166 for (i = 0; i < dr->dr_numslots; i++) { 4167 dr->getdesc(dr, i, &desc, &meta); 4168 4169 if (meta->mt_m == NULL) { 4170 if (!dr->dr_tx) 4171 device_printf(sc->sc_dev, "%s: not TX?\n", 4172 __func__); 4173 continue; 4174 } 4175 if (dr->dr_tx) { 4176 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4177 bus_dmamap_unload(dr->dr_txring_dtag, 4178 meta->mt_dmap); 4179 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4180 bus_dmamap_unload(dma->txbuf_dtag, 4181 meta->mt_dmap); 4182 } else 4183 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4184 bwn_dma_free_descbuf(dr, meta); 4185 } 4186 } 4187 4188 static int 4189 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4190 int type) 4191 { 4192 struct bwn_softc *sc = mac->mac_sc; 4193 uint32_t value; 4194 int i; 4195 uint16_t offset; 4196 4197 for (i = 0; i < 10; i++) { 4198 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4199 BWN_DMA32_TXSTATUS; 4200 value = BWN_READ_4(mac, base + offset); 4201 if (type == BWN_DMA_64BIT) { 4202 value &= BWN_DMA64_TXSTAT; 4203 if (value == BWN_DMA64_TXSTAT_DISABLED || 4204 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4205 value == BWN_DMA64_TXSTAT_STOPPED) 4206 break; 4207 } else { 4208 value &= BWN_DMA32_TXSTATE; 4209 if (value == BWN_DMA32_TXSTAT_DISABLED || 4210 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4211 value == BWN_DMA32_TXSTAT_STOPPED) 4212 break; 4213 } 4214 DELAY(1000); 4215 } 4216 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4217 BWN_WRITE_4(mac, base + offset, 0); 4218 for (i = 0; i < 10; i++) { 4219 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4220 BWN_DMA32_TXSTATUS; 4221 value = BWN_READ_4(mac, base + offset); 4222 if (type == BWN_DMA_64BIT) { 4223 value &= BWN_DMA64_TXSTAT; 4224 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4225 i = -1; 4226 break; 4227 } 4228 } else { 4229 value &= BWN_DMA32_TXSTATE; 4230 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4231 i = -1; 4232 break; 4233 } 4234 } 4235 DELAY(1000); 4236 } 4237 if (i != -1) { 4238 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4239 return (ENODEV); 4240 } 4241 DELAY(1000); 4242 4243 return (0); 4244 } 4245 4246 static int 4247 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4248 int type) 4249 { 4250 struct bwn_softc *sc = mac->mac_sc; 4251 uint32_t value; 4252 int i; 4253 uint16_t offset; 4254 4255 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4256 BWN_WRITE_4(mac, base + offset, 0); 4257 for (i = 0; i < 10; i++) { 4258 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4259 BWN_DMA32_RXSTATUS; 4260 value = BWN_READ_4(mac, base + offset); 4261 if (type == BWN_DMA_64BIT) { 4262 value &= BWN_DMA64_RXSTAT; 4263 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4264 i = -1; 4265 break; 4266 } 4267 } else { 4268 value &= BWN_DMA32_RXSTATE; 4269 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4270 i = -1; 4271 break; 4272 } 4273 } 4274 DELAY(1000); 4275 } 4276 if (i != -1) { 4277 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4278 return (ENODEV); 4279 } 4280 4281 return (0); 4282 } 4283 4284 static void 4285 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4286 struct bwn_dmadesc_meta *meta) 4287 { 4288 4289 if (meta->mt_m != NULL) { 4290 m_freem(meta->mt_m); 4291 meta->mt_m = NULL; 4292 } 4293 if (meta->mt_ni != NULL) { 4294 ieee80211_free_node(meta->mt_ni); 4295 meta->mt_ni = NULL; 4296 } 4297 } 4298 4299 static void 4300 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4301 { 4302 struct bwn_rxhdr4 *rxhdr; 4303 unsigned char *frame; 4304 4305 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4306 rxhdr->frame_len = 0; 4307 4308 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4309 sizeof(struct bwn_plcp6) + 2, 4310 ("%s:%d: fail", __func__, __LINE__)); 4311 frame = mtod(m, char *) + dr->dr_frameoffset; 4312 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4313 } 4314 4315 static uint8_t 4316 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4317 { 4318 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4319 4320 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4321 == 0xff); 4322 } 4323 4324 static void 4325 bwn_wme_init(struct bwn_mac *mac) 4326 { 4327 4328 bwn_wme_load(mac); 4329 4330 /* enable WME support. */ 4331 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4332 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4333 BWN_IFSCTL_USE_EDCF); 4334 } 4335 4336 static void 4337 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4338 { 4339 struct bwn_softc *sc = mac->mac_sc; 4340 struct ieee80211com *ic = &sc->sc_ic; 4341 uint16_t delay; /* microsec */ 4342 4343 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4344 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4345 delay = 500; 4346 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4347 delay = max(delay, (uint16_t)2400); 4348 4349 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4350 } 4351 4352 static void 4353 bwn_bt_enable(struct bwn_mac *mac) 4354 { 4355 struct bwn_softc *sc = mac->mac_sc; 4356 uint64_t hf; 4357 4358 if (bwn_bluetooth == 0) 4359 return; 4360 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4361 return; 4362 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4363 return; 4364 4365 hf = bwn_hf_read(mac); 4366 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4367 hf |= BWN_HF_BT_COEXISTALT; 4368 else 4369 hf |= BWN_HF_BT_COEXIST; 4370 bwn_hf_write(mac, hf); 4371 } 4372 4373 static void 4374 bwn_set_macaddr(struct bwn_mac *mac) 4375 { 4376 4377 bwn_mac_write_bssid(mac); 4378 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, 4379 mac->mac_sc->sc_ic.ic_macaddr); 4380 } 4381 4382 static void 4383 bwn_clear_keys(struct bwn_mac *mac) 4384 { 4385 int i; 4386 4387 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4388 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4389 ("%s:%d: fail", __func__, __LINE__)); 4390 4391 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4392 NULL, BWN_SEC_KEYSIZE, NULL); 4393 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4394 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4395 NULL, BWN_SEC_KEYSIZE, NULL); 4396 } 4397 mac->mac_key[i].keyconf = NULL; 4398 } 4399 } 4400 4401 static void 4402 bwn_crypt_init(struct bwn_mac *mac) 4403 { 4404 struct bwn_softc *sc = mac->mac_sc; 4405 4406 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4407 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4408 ("%s:%d: fail", __func__, __LINE__)); 4409 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4410 mac->mac_ktp *= 2; 4411 if (siba_get_revid(sc->sc_dev) >= 5) 4412 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4413 bwn_clear_keys(mac); 4414 } 4415 4416 static void 4417 bwn_chip_exit(struct bwn_mac *mac) 4418 { 4419 struct bwn_softc *sc = mac->mac_sc; 4420 4421 bwn_phy_exit(mac); 4422 siba_gpio_set(sc->sc_dev, 0); 4423 } 4424 4425 static int 4426 bwn_fw_fillinfo(struct bwn_mac *mac) 4427 { 4428 int error; 4429 4430 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4431 if (error == 0) 4432 return (0); 4433 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4434 if (error == 0) 4435 return (0); 4436 return (error); 4437 } 4438 4439 static int 4440 bwn_gpio_init(struct bwn_mac *mac) 4441 { 4442 struct bwn_softc *sc = mac->mac_sc; 4443 uint32_t mask = 0x1f, set = 0xf, value; 4444 4445 BWN_WRITE_4(mac, BWN_MACCTL, 4446 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4447 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4448 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4449 4450 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4451 mask |= 0x0060; 4452 set |= 0x0060; 4453 } 4454 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4455 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4456 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4457 mask |= 0x0200; 4458 set |= 0x0200; 4459 } 4460 if (siba_get_revid(sc->sc_dev) >= 2) 4461 mask |= 0x0010; 4462 4463 value = siba_gpio_get(sc->sc_dev); 4464 if (value == -1) 4465 return (0); 4466 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4467 4468 return (0); 4469 } 4470 4471 static int 4472 bwn_fw_loadinitvals(struct bwn_mac *mac) 4473 { 4474 #define GETFWOFFSET(fwp, offset) \ 4475 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4476 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4477 const struct bwn_fwhdr *hdr; 4478 struct bwn_fw *fw = &mac->mac_fw; 4479 int error; 4480 4481 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4482 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4483 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4484 if (error) 4485 return (error); 4486 if (fw->initvals_band.fw) { 4487 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4488 error = bwn_fwinitvals_write(mac, 4489 GETFWOFFSET(fw->initvals_band, hdr_len), 4490 be32toh(hdr->size), 4491 fw->initvals_band.fw->datasize - hdr_len); 4492 } 4493 return (error); 4494 #undef GETFWOFFSET 4495 } 4496 4497 static int 4498 bwn_phy_init(struct bwn_mac *mac) 4499 { 4500 struct bwn_softc *sc = mac->mac_sc; 4501 int error; 4502 4503 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4504 mac->mac_phy.rf_onoff(mac, 1); 4505 error = mac->mac_phy.init(mac); 4506 if (error) { 4507 device_printf(sc->sc_dev, "PHY init failed\n"); 4508 goto fail0; 4509 } 4510 error = bwn_switch_channel(mac, 4511 mac->mac_phy.get_default_chan(mac)); 4512 if (error) { 4513 device_printf(sc->sc_dev, 4514 "failed to switch default channel\n"); 4515 goto fail1; 4516 } 4517 return (0); 4518 fail1: 4519 if (mac->mac_phy.exit) 4520 mac->mac_phy.exit(mac); 4521 fail0: 4522 mac->mac_phy.rf_onoff(mac, 0); 4523 4524 return (error); 4525 } 4526 4527 static void 4528 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4529 { 4530 uint16_t ant; 4531 uint16_t tmp; 4532 4533 ant = bwn_ant2phy(antenna); 4534 4535 /* For ACK/CTS */ 4536 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4537 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4538 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4539 /* For Probe Resposes */ 4540 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4541 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4542 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4543 } 4544 4545 static void 4546 bwn_set_opmode(struct bwn_mac *mac) 4547 { 4548 struct bwn_softc *sc = mac->mac_sc; 4549 struct ieee80211com *ic = &sc->sc_ic; 4550 uint32_t ctl; 4551 uint16_t cfp_pretbtt; 4552 4553 ctl = BWN_READ_4(mac, BWN_MACCTL); 4554 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4555 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4556 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4557 ctl |= BWN_MACCTL_STA; 4558 4559 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4560 ic->ic_opmode == IEEE80211_M_MBSS) 4561 ctl |= BWN_MACCTL_HOSTAP; 4562 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4563 ctl &= ~BWN_MACCTL_STA; 4564 ctl |= sc->sc_filters; 4565 4566 if (siba_get_revid(sc->sc_dev) <= 4) 4567 ctl |= BWN_MACCTL_PROMISC; 4568 4569 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4570 4571 cfp_pretbtt = 2; 4572 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4573 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4574 siba_get_chiprev(sc->sc_dev) == 3) 4575 cfp_pretbtt = 100; 4576 else 4577 cfp_pretbtt = 50; 4578 } 4579 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4580 } 4581 4582 static int 4583 bwn_dma_gettype(struct bwn_mac *mac) 4584 { 4585 uint32_t tmp; 4586 uint16_t base; 4587 4588 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4589 if (tmp & SIBA_TGSHIGH_DMA64) 4590 return (BWN_DMA_64BIT); 4591 base = bwn_dma_base(0, 0); 4592 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4593 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4594 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4595 return (BWN_DMA_32BIT); 4596 4597 return (BWN_DMA_30BIT); 4598 } 4599 4600 static void 4601 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4602 { 4603 if (!error) { 4604 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4605 *((bus_addr_t *)arg) = seg->ds_addr; 4606 } 4607 } 4608 4609 static void 4610 bwn_phy_g_init_sub(struct bwn_mac *mac) 4611 { 4612 struct bwn_phy *phy = &mac->mac_phy; 4613 struct bwn_phy_g *pg = &phy->phy_g; 4614 struct bwn_softc *sc = mac->mac_sc; 4615 uint16_t i, tmp; 4616 4617 if (phy->rev == 1) 4618 bwn_phy_init_b5(mac); 4619 else 4620 bwn_phy_init_b6(mac); 4621 4622 if (phy->rev >= 2 || phy->gmode) 4623 bwn_phy_init_a(mac); 4624 4625 if (phy->rev >= 2) { 4626 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4627 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4628 } 4629 if (phy->rev == 2) { 4630 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4631 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4632 } 4633 if (phy->rev > 5) { 4634 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4635 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4636 } 4637 if (phy->gmode || phy->rev >= 2) { 4638 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4639 tmp &= BWN_PHYVER_VERSION; 4640 if (tmp == 3 || tmp == 5) { 4641 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4642 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4643 } 4644 if (tmp == 5) { 4645 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4646 0x1f00); 4647 } 4648 } 4649 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4650 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4651 if (phy->rf_rev == 8) { 4652 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4653 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4654 } 4655 if (BWN_HAS_LOOPBACK(phy)) 4656 bwn_loopback_calcgain(mac); 4657 4658 if (phy->rf_rev != 8) { 4659 if (pg->pg_initval == 0xffff) 4660 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4661 else 4662 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4663 } 4664 bwn_lo_g_init(mac); 4665 if (BWN_HAS_TXMAG(phy)) { 4666 BWN_RF_WRITE(mac, 0x52, 4667 (BWN_RF_READ(mac, 0x52) & 0xff00) 4668 | pg->pg_loctl.tx_bias | 4669 pg->pg_loctl.tx_magn); 4670 } else { 4671 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4672 } 4673 if (phy->rev >= 6) { 4674 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4675 (pg->pg_loctl.tx_bias << 12)); 4676 } 4677 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4678 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4679 else 4680 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4681 if (phy->rev < 2) 4682 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4683 else 4684 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4685 if (phy->gmode || phy->rev >= 2) { 4686 bwn_lo_g_adjust(mac); 4687 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4688 } 4689 4690 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4691 for (i = 0; i < 64; i++) { 4692 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4693 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4694 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4695 -32), 31)); 4696 } 4697 bwn_nrssi_threshold(mac); 4698 } else if (phy->gmode || phy->rev >= 2) { 4699 if (pg->pg_nrssi[0] == -1000) { 4700 KASSERT(pg->pg_nrssi[1] == -1000, 4701 ("%s:%d: fail", __func__, __LINE__)); 4702 bwn_nrssi_slope_11g(mac); 4703 } else 4704 bwn_nrssi_threshold(mac); 4705 } 4706 if (phy->rf_rev == 8) 4707 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4708 bwn_phy_hwpctl_init(mac); 4709 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4710 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4711 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4712 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4713 } 4714 } 4715 4716 static uint8_t 4717 bwn_has_hwpctl(struct bwn_mac *mac) 4718 { 4719 4720 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4721 return (0); 4722 return (mac->mac_phy.use_hwpctl(mac)); 4723 } 4724 4725 static void 4726 bwn_phy_init_b5(struct bwn_mac *mac) 4727 { 4728 struct bwn_phy *phy = &mac->mac_phy; 4729 struct bwn_phy_g *pg = &phy->phy_g; 4730 struct bwn_softc *sc = mac->mac_sc; 4731 uint16_t offset, value; 4732 uint8_t old_channel; 4733 4734 if (phy->analog == 1) 4735 BWN_RF_SET(mac, 0x007a, 0x0050); 4736 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4737 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4738 value = 0x2120; 4739 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4740 BWN_PHY_WRITE(mac, offset, value); 4741 value += 0x202; 4742 } 4743 } 4744 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4745 if (phy->rf_ver == 0x2050) 4746 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4747 4748 if (phy->gmode || phy->rev >= 2) { 4749 if (phy->rf_ver == 0x2050) { 4750 BWN_RF_SET(mac, 0x007a, 0x0020); 4751 BWN_RF_SET(mac, 0x0051, 0x0004); 4752 } 4753 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4754 4755 BWN_PHY_SET(mac, 0x0802, 0x0100); 4756 BWN_PHY_SET(mac, 0x042b, 0x2000); 4757 4758 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4759 4760 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4761 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4762 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4763 } 4764 4765 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4766 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4767 4768 if (phy->analog == 1) { 4769 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4770 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4771 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4772 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4773 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4774 } else 4775 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4776 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4777 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4778 4779 if (phy->analog == 1) 4780 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4781 else 4782 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4783 4784 if (phy->analog == 0) 4785 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4786 4787 old_channel = phy->chan; 4788 bwn_phy_g_switch_chan(mac, 7, 0); 4789 4790 if (phy->rf_ver != 0x2050) { 4791 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4792 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4793 } 4794 4795 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4796 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4797 4798 if (phy->rf_ver == 0x2050) { 4799 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4800 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4801 } 4802 4803 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4804 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4805 BWN_RF_SET(mac, 0x007a, 0x0007); 4806 4807 bwn_phy_g_switch_chan(mac, old_channel, 0); 4808 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4809 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4810 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4811 4812 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4813 pg->pg_txctl); 4814 4815 if (phy->rf_ver == 0x2050) 4816 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4817 4818 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4819 } 4820 4821 static void 4822 bwn_loopback_calcgain(struct bwn_mac *mac) 4823 { 4824 struct bwn_phy *phy = &mac->mac_phy; 4825 struct bwn_phy_g *pg = &phy->phy_g; 4826 struct bwn_softc *sc = mac->mac_sc; 4827 uint16_t backup_phy[16] = { 0 }; 4828 uint16_t backup_radio[3]; 4829 uint16_t backup_bband; 4830 uint16_t i, j, loop_i_max; 4831 uint16_t trsw_rx; 4832 uint16_t loop1_outer_done, loop1_inner_done; 4833 4834 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4835 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4836 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4837 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4838 if (phy->rev != 1) { 4839 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4840 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4841 } 4842 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4843 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4844 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4845 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4846 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4847 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4848 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4849 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4850 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4851 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4852 backup_bband = pg->pg_bbatt.att; 4853 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4854 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4855 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4856 4857 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4858 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4859 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4860 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4861 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4862 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4863 if (phy->rev != 1) { 4864 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4865 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4866 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4867 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4868 } 4869 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4870 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4871 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4872 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4873 4874 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4875 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4876 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4877 4878 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4879 if (phy->rev != 1) { 4880 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4881 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4882 } 4883 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4884 4885 if (phy->rf_rev == 8) 4886 BWN_RF_WRITE(mac, 0x43, 0x000f); 4887 else { 4888 BWN_RF_WRITE(mac, 0x52, 0); 4889 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4890 } 4891 bwn_phy_g_set_bbatt(mac, 11); 4892 4893 if (phy->rev >= 3) 4894 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4895 else 4896 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4897 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4898 4899 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 4900 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 4901 4902 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 4903 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 4904 4905 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 4906 if (phy->rev >= 7) { 4907 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 4908 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 4909 } 4910 } 4911 BWN_RF_MASK(mac, 0x7a, 0x00f7); 4912 4913 j = 0; 4914 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 4915 for (i = 0; i < loop_i_max; i++) { 4916 for (j = 0; j < 16; j++) { 4917 BWN_RF_WRITE(mac, 0x43, i); 4918 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 4919 (j << 8)); 4920 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4921 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4922 DELAY(20); 4923 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4924 goto done0; 4925 } 4926 } 4927 done0: 4928 loop1_outer_done = i; 4929 loop1_inner_done = j; 4930 if (j >= 8) { 4931 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 4932 trsw_rx = 0x1b; 4933 for (j = j - 8; j < 16; j++) { 4934 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 4935 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4936 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4937 DELAY(20); 4938 trsw_rx -= 3; 4939 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4940 goto done1; 4941 } 4942 } else 4943 trsw_rx = 0x18; 4944 done1: 4945 4946 if (phy->rev != 1) { 4947 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 4948 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 4949 } 4950 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 4951 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 4952 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 4953 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 4954 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 4955 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 4956 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 4957 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 4958 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 4959 4960 bwn_phy_g_set_bbatt(mac, backup_bband); 4961 4962 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 4963 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 4964 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 4965 4966 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 4967 DELAY(10); 4968 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 4969 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 4970 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 4971 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 4972 4973 pg->pg_max_lb_gain = 4974 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 4975 pg->pg_trsw_rx_gain = trsw_rx * 2; 4976 } 4977 4978 static uint16_t 4979 bwn_rf_init_bcm2050(struct bwn_mac *mac) 4980 { 4981 struct bwn_phy *phy = &mac->mac_phy; 4982 uint32_t tmp1 = 0, tmp2 = 0; 4983 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 4984 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 4985 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 4986 static const uint8_t rcc_table[] = { 4987 0x02, 0x03, 0x01, 0x0f, 4988 0x06, 0x07, 0x05, 0x0f, 4989 0x0a, 0x0b, 0x09, 0x0f, 4990 0x0e, 0x0f, 0x0d, 0x0f, 4991 }; 4992 4993 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 4994 rfoverval = rfover = cck3 = 0; 4995 radio0 = BWN_RF_READ(mac, 0x43); 4996 radio1 = BWN_RF_READ(mac, 0x51); 4997 radio2 = BWN_RF_READ(mac, 0x52); 4998 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4999 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5000 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5001 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5002 5003 if (phy->type == BWN_PHYTYPE_B) { 5004 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5005 reg0 = BWN_READ_2(mac, 0x3ec); 5006 5007 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5008 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5009 } else if (phy->gmode || phy->rev >= 2) { 5010 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5011 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5012 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5013 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5014 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5015 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5016 5017 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5018 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5019 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5020 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5021 if (BWN_HAS_LOOPBACK(phy)) { 5022 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5023 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5024 if (phy->rev >= 3) 5025 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5026 else 5027 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5028 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5029 } 5030 5031 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5032 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5033 BWN_LPD(0, 1, 1))); 5034 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5035 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5036 } 5037 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5038 5039 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5040 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5041 reg1 = BWN_READ_2(mac, 0x3e6); 5042 reg2 = BWN_READ_2(mac, 0x3f4); 5043 5044 if (phy->analog == 0) 5045 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5046 else { 5047 if (phy->analog >= 2) 5048 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5049 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5050 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5051 } 5052 5053 reg = BWN_RF_READ(mac, 0x60); 5054 index = (reg & 0x001e) >> 1; 5055 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5056 5057 if (phy->type == BWN_PHYTYPE_B) 5058 BWN_RF_WRITE(mac, 0x78, 0x26); 5059 if (phy->gmode || phy->rev >= 2) { 5060 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5061 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5062 BWN_LPD(0, 1, 1))); 5063 } 5064 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5065 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5066 if (phy->gmode || phy->rev >= 2) { 5067 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5068 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5069 BWN_LPD(0, 0, 1))); 5070 } 5071 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5072 BWN_RF_SET(mac, 0x51, 0x0004); 5073 if (phy->rf_rev == 8) 5074 BWN_RF_WRITE(mac, 0x43, 0x1f); 5075 else { 5076 BWN_RF_WRITE(mac, 0x52, 0); 5077 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5078 } 5079 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5080 5081 for (i = 0; i < 16; i++) { 5082 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5083 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5084 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5085 if (phy->gmode || phy->rev >= 2) { 5086 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5087 bwn_rf_2050_rfoverval(mac, 5088 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5089 } 5090 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5091 DELAY(10); 5092 if (phy->gmode || phy->rev >= 2) { 5093 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5094 bwn_rf_2050_rfoverval(mac, 5095 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5096 } 5097 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5098 DELAY(10); 5099 if (phy->gmode || phy->rev >= 2) { 5100 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5101 bwn_rf_2050_rfoverval(mac, 5102 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5103 } 5104 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5105 DELAY(20); 5106 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5107 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5108 if (phy->gmode || phy->rev >= 2) { 5109 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5110 bwn_rf_2050_rfoverval(mac, 5111 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5112 } 5113 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5114 } 5115 DELAY(10); 5116 5117 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5118 tmp1++; 5119 tmp1 >>= 9; 5120 5121 for (i = 0; i < 16; i++) { 5122 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5123 BWN_RF_WRITE(mac, 0x78, radio78); 5124 DELAY(10); 5125 for (j = 0; j < 16; j++) { 5126 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5127 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5128 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5129 if (phy->gmode || phy->rev >= 2) { 5130 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5131 bwn_rf_2050_rfoverval(mac, 5132 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5133 } 5134 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5135 DELAY(10); 5136 if (phy->gmode || phy->rev >= 2) { 5137 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5138 bwn_rf_2050_rfoverval(mac, 5139 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5140 } 5141 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5142 DELAY(10); 5143 if (phy->gmode || phy->rev >= 2) { 5144 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5145 bwn_rf_2050_rfoverval(mac, 5146 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5147 } 5148 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5149 DELAY(10); 5150 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5151 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5152 if (phy->gmode || phy->rev >= 2) { 5153 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5154 bwn_rf_2050_rfoverval(mac, 5155 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5156 } 5157 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5158 } 5159 tmp2++; 5160 tmp2 >>= 8; 5161 if (tmp1 < tmp2) 5162 break; 5163 } 5164 5165 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5166 BWN_RF_WRITE(mac, 0x51, radio1); 5167 BWN_RF_WRITE(mac, 0x52, radio2); 5168 BWN_RF_WRITE(mac, 0x43, radio0); 5169 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5170 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5171 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5172 BWN_WRITE_2(mac, 0x3e6, reg1); 5173 if (phy->analog != 0) 5174 BWN_WRITE_2(mac, 0x3f4, reg2); 5175 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5176 bwn_spu_workaround(mac, phy->chan); 5177 if (phy->type == BWN_PHYTYPE_B) { 5178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5179 BWN_WRITE_2(mac, 0x3ec, reg0); 5180 } else if (phy->gmode) { 5181 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5182 BWN_READ_2(mac, BWN_PHY_RADIO) 5183 & 0x7fff); 5184 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5185 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5186 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5187 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5188 analogoverval); 5189 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5190 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5191 if (BWN_HAS_LOOPBACK(phy)) { 5192 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5193 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5194 } 5195 } 5196 5197 return ((i > 15) ? radio78 : rcc); 5198 } 5199 5200 static void 5201 bwn_phy_init_b6(struct bwn_mac *mac) 5202 { 5203 struct bwn_phy *phy = &mac->mac_phy; 5204 struct bwn_phy_g *pg = &phy->phy_g; 5205 struct bwn_softc *sc = mac->mac_sc; 5206 uint16_t offset, val; 5207 uint8_t old_channel; 5208 5209 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5210 ("%s:%d: fail", __func__, __LINE__)); 5211 5212 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5213 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5214 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5215 BWN_RF_WRITE(mac, 0x51, 0x37); 5216 BWN_RF_WRITE(mac, 0x52, 0x70); 5217 BWN_RF_WRITE(mac, 0x53, 0xb3); 5218 BWN_RF_WRITE(mac, 0x54, 0x9b); 5219 BWN_RF_WRITE(mac, 0x5a, 0x88); 5220 BWN_RF_WRITE(mac, 0x5b, 0x88); 5221 BWN_RF_WRITE(mac, 0x5d, 0x88); 5222 BWN_RF_WRITE(mac, 0x5e, 0x88); 5223 BWN_RF_WRITE(mac, 0x7d, 0x88); 5224 bwn_hf_write(mac, 5225 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5226 } 5227 if (phy->rf_rev == 8) { 5228 BWN_RF_WRITE(mac, 0x51, 0); 5229 BWN_RF_WRITE(mac, 0x52, 0x40); 5230 BWN_RF_WRITE(mac, 0x53, 0xb7); 5231 BWN_RF_WRITE(mac, 0x54, 0x98); 5232 BWN_RF_WRITE(mac, 0x5a, 0x88); 5233 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5234 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5235 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5236 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5237 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5238 } else { 5239 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5240 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5241 } 5242 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5243 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5244 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5245 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5246 } 5247 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5248 BWN_PHY_WRITE(mac, offset, val); 5249 val -= 0x0202; 5250 } 5251 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5252 BWN_PHY_WRITE(mac, offset, val); 5253 val -= 0x0202; 5254 } 5255 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5256 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5257 val += 0x0202; 5258 } 5259 if (phy->type == BWN_PHYTYPE_G) { 5260 BWN_RF_SET(mac, 0x007a, 0x0020); 5261 BWN_RF_SET(mac, 0x0051, 0x0004); 5262 BWN_PHY_SET(mac, 0x0802, 0x0100); 5263 BWN_PHY_SET(mac, 0x042b, 0x2000); 5264 BWN_PHY_WRITE(mac, 0x5b, 0); 5265 BWN_PHY_WRITE(mac, 0x5c, 0); 5266 } 5267 5268 old_channel = phy->chan; 5269 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5270 5271 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5272 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5273 DELAY(40); 5274 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5275 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5276 BWN_RF_WRITE(mac, 0x50, 0x20); 5277 } 5278 if (phy->rf_rev <= 2) { 5279 BWN_RF_WRITE(mac, 0x7c, 0x20); 5280 BWN_RF_WRITE(mac, 0x5a, 0x70); 5281 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5282 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5283 } 5284 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5285 5286 bwn_phy_g_switch_chan(mac, old_channel, 0); 5287 5288 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5289 if (phy->rf_rev >= 6) 5290 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5291 else 5292 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5293 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5294 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5295 pg->pg_txctl); 5296 if (phy->rf_rev <= 5) 5297 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5298 if (phy->rf_rev <= 2) 5299 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5300 5301 if (phy->analog == 4) { 5302 BWN_WRITE_2(mac, 0x3e4, 9); 5303 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5304 } else 5305 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5306 if (phy->type == BWN_PHYTYPE_B) 5307 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5308 else if (phy->type == BWN_PHYTYPE_G) 5309 BWN_WRITE_2(mac, 0x03e6, 0x0); 5310 } 5311 5312 static void 5313 bwn_phy_init_a(struct bwn_mac *mac) 5314 { 5315 struct bwn_phy *phy = &mac->mac_phy; 5316 struct bwn_softc *sc = mac->mac_sc; 5317 5318 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5319 ("%s:%d: fail", __func__, __LINE__)); 5320 5321 if (phy->rev >= 6) { 5322 if (phy->type == BWN_PHYTYPE_A) 5323 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5324 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5325 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5326 else 5327 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5328 } 5329 5330 bwn_wa_init(mac); 5331 5332 if (phy->type == BWN_PHYTYPE_G && 5333 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5334 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5335 } 5336 5337 static void 5338 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5339 { 5340 int i; 5341 5342 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5343 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5344 } 5345 5346 static void 5347 bwn_wa_agc(struct bwn_mac *mac) 5348 { 5349 struct bwn_phy *phy = &mac->mac_phy; 5350 5351 if (phy->rev == 1) { 5352 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5353 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5354 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5355 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5356 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5357 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5358 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5359 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5360 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5361 } else { 5362 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5363 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5364 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5365 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5366 } 5367 5368 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5369 0x5700); 5370 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5371 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5372 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5373 BWN_RF_SET(mac, 0x7a, 0x0008); 5374 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5375 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5376 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5377 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5378 if (phy->rev == 1) 5379 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5380 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5381 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5382 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5383 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5384 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5385 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5386 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5387 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5388 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5389 if (phy->rev == 1) { 5390 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5391 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5392 } else { 5393 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5394 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5395 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5396 if (phy->rev >= 6) { 5397 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5398 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5399 (uint16_t)~0xf000, 0x3000); 5400 } 5401 } 5402 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5403 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5404 if (phy->rev == 1) { 5405 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5406 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5407 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5408 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5409 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5410 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5411 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5412 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5413 } else { 5414 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5415 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5416 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5417 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5418 } 5419 if (phy->rev >= 6) { 5420 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5421 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5422 } 5423 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5424 } 5425 5426 static void 5427 bwn_wa_grev1(struct bwn_mac *mac) 5428 { 5429 struct bwn_phy *phy = &mac->mac_phy; 5430 int i; 5431 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5432 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5433 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5434 5435 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5436 5437 /* init CRSTHRES and ANTDWELL */ 5438 if (phy->rev == 1) { 5439 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5440 } else if (phy->rev == 2) { 5441 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5442 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5443 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5444 } else { 5445 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5446 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5447 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5448 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5449 } 5450 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5451 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5452 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5453 5454 /* XXX support PHY-A??? */ 5455 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5456 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5457 bwn_tab_finefreqg[i]); 5458 5459 /* XXX support PHY-A??? */ 5460 if (phy->rev == 1) 5461 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5463 bwn_tab_noise_g1[i]); 5464 else 5465 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5467 bwn_tab_noise_g2[i]); 5468 5469 5470 for (i = 0; i < N(bwn_tab_rotor); i++) 5471 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5472 bwn_tab_rotor[i]); 5473 5474 /* XXX support PHY-A??? */ 5475 if (phy->rev >= 6) { 5476 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5477 BWN_PHY_ENCORE_EN) 5478 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5479 else 5480 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5481 } else 5482 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5483 5484 for (i = 0; i < N(bwn_tab_retard); i++) 5485 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5486 bwn_tab_retard[i]); 5487 5488 if (phy->rev == 1) { 5489 for (i = 0; i < 16; i++) 5490 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5491 i, 0x0020); 5492 } else { 5493 for (i = 0; i < 32; i++) 5494 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5495 } 5496 5497 bwn_wa_agc(mac); 5498 } 5499 5500 static void 5501 bwn_wa_grev26789(struct bwn_mac *mac) 5502 { 5503 struct bwn_phy *phy = &mac->mac_phy; 5504 int i; 5505 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5506 uint16_t ofdmrev; 5507 5508 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5509 5510 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5511 5512 /* init CRSTHRES and ANTDWELL */ 5513 if (phy->rev == 1) 5514 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5515 else if (phy->rev == 2) { 5516 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5517 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5518 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5519 } else { 5520 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5521 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5522 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5523 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5524 } 5525 5526 for (i = 0; i < 64; i++) 5527 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5528 5529 /* XXX support PHY-A??? */ 5530 if (phy->rev == 1) 5531 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5532 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5533 bwn_tab_noise_g1[i]); 5534 else 5535 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5536 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5537 bwn_tab_noise_g2[i]); 5538 5539 /* XXX support PHY-A??? */ 5540 if (phy->rev >= 6) { 5541 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5542 BWN_PHY_ENCORE_EN) 5543 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5544 else 5545 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5546 } else 5547 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5548 5549 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5550 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5551 bwn_tab_sigmasqr2[i]); 5552 5553 if (phy->rev == 1) { 5554 for (i = 0; i < 16; i++) 5555 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5556 0x0020); 5557 } else { 5558 for (i = 0; i < 32; i++) 5559 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5560 } 5561 5562 bwn_wa_agc(mac); 5563 5564 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5565 if (ofdmrev > 2) { 5566 if (phy->type == BWN_PHYTYPE_A) 5567 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5568 else 5569 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5570 } else { 5571 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5573 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5574 } 5575 5576 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5577 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5578 } 5579 5580 static void 5581 bwn_wa_init(struct bwn_mac *mac) 5582 { 5583 struct bwn_phy *phy = &mac->mac_phy; 5584 struct bwn_softc *sc = mac->mac_sc; 5585 5586 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5587 5588 switch (phy->rev) { 5589 case 1: 5590 bwn_wa_grev1(mac); 5591 break; 5592 case 2: 5593 case 6: 5594 case 7: 5595 case 8: 5596 case 9: 5597 bwn_wa_grev26789(mac); 5598 break; 5599 default: 5600 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5601 } 5602 5603 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5604 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5605 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5606 if (phy->rev < 2) { 5607 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5608 0x0002); 5609 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5610 0x0001); 5611 } else { 5612 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5613 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5614 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5615 BWN_BFL_EXTLNA) && 5616 (phy->rev >= 7)) { 5617 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5618 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5619 0x0020, 0x0001); 5620 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5621 0x0021, 0x0001); 5622 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5623 0x0022, 0x0001); 5624 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5625 0x0023, 0x0000); 5626 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5627 0x0000, 0x0000); 5628 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5629 0x0003, 0x0002); 5630 } 5631 } 5632 } 5633 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5634 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5635 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5636 } 5637 5638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5639 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5640 } 5641 5642 static void 5643 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5644 uint16_t value) 5645 { 5646 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5647 uint16_t addr; 5648 5649 addr = table + offset; 5650 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5651 (addr - 1 != pg->pg_ofdmtab_addr)) { 5652 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5653 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5654 } 5655 pg->pg_ofdmtab_addr = addr; 5656 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5657 } 5658 5659 static void 5660 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5661 uint32_t value) 5662 { 5663 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5664 uint16_t addr; 5665 5666 addr = table + offset; 5667 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5668 (addr - 1 != pg->pg_ofdmtab_addr)) { 5669 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5670 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5671 } 5672 pg->pg_ofdmtab_addr = addr; 5673 5674 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5675 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5676 } 5677 5678 static void 5679 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5680 uint16_t value) 5681 { 5682 5683 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5684 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5685 } 5686 5687 static void 5688 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5689 { 5690 struct bwn_phy *phy = &mac->mac_phy; 5691 struct bwn_softc *sc = mac->mac_sc; 5692 unsigned int i, max_loop; 5693 uint16_t value; 5694 uint32_t buffer[5] = { 5695 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5696 }; 5697 5698 if (ofdm) { 5699 max_loop = 0x1e; 5700 buffer[0] = 0x000201cc; 5701 } else { 5702 max_loop = 0xfa; 5703 buffer[0] = 0x000b846e; 5704 } 5705 5706 BWN_ASSERT_LOCKED(mac->mac_sc); 5707 5708 for (i = 0; i < 5; i++) 5709 bwn_ram_write(mac, i * 4, buffer[i]); 5710 5711 BWN_WRITE_2(mac, 0x0568, 0x0000); 5712 BWN_WRITE_2(mac, 0x07c0, 5713 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5714 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5715 BWN_WRITE_2(mac, 0x050c, value); 5716 if (phy->type == BWN_PHYTYPE_LP) 5717 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5718 BWN_WRITE_2(mac, 0x0508, 0x0000); 5719 BWN_WRITE_2(mac, 0x050a, 0x0000); 5720 BWN_WRITE_2(mac, 0x054c, 0x0000); 5721 BWN_WRITE_2(mac, 0x056a, 0x0014); 5722 BWN_WRITE_2(mac, 0x0568, 0x0826); 5723 BWN_WRITE_2(mac, 0x0500, 0x0000); 5724 if (phy->type == BWN_PHYTYPE_LP) 5725 BWN_WRITE_2(mac, 0x0502, 0x0050); 5726 else 5727 BWN_WRITE_2(mac, 0x0502, 0x0030); 5728 5729 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5730 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5731 for (i = 0x00; i < max_loop; i++) { 5732 value = BWN_READ_2(mac, 0x050e); 5733 if (value & 0x0080) 5734 break; 5735 DELAY(10); 5736 } 5737 for (i = 0x00; i < 0x0a; i++) { 5738 value = BWN_READ_2(mac, 0x050e); 5739 if (value & 0x0400) 5740 break; 5741 DELAY(10); 5742 } 5743 for (i = 0x00; i < 0x19; i++) { 5744 value = BWN_READ_2(mac, 0x0690); 5745 if (!(value & 0x0100)) 5746 break; 5747 DELAY(10); 5748 } 5749 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5750 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5751 } 5752 5753 static void 5754 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5755 { 5756 uint32_t macctl; 5757 5758 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5759 5760 macctl = BWN_READ_4(mac, BWN_MACCTL); 5761 if (macctl & BWN_MACCTL_BIGENDIAN) 5762 printf("TODO: need swap\n"); 5763 5764 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5765 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5766 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5767 } 5768 5769 static void 5770 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5771 { 5772 uint16_t value; 5773 5774 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5775 ("%s:%d: fail", __func__, __LINE__)); 5776 5777 value = (uint8_t) (ctl->q); 5778 value |= ((uint8_t) (ctl->i)) << 8; 5779 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5780 } 5781 5782 static uint16_t 5783 bwn_lo_calcfeed(struct bwn_mac *mac, 5784 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5785 { 5786 struct bwn_phy *phy = &mac->mac_phy; 5787 struct bwn_softc *sc = mac->mac_sc; 5788 uint16_t rfover; 5789 uint16_t feedthrough; 5790 5791 if (phy->gmode) { 5792 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5793 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5794 5795 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5796 ("%s:%d: fail", __func__, __LINE__)); 5797 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5798 ("%s:%d: fail", __func__, __LINE__)); 5799 5800 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5801 5802 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5803 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5804 phy->rev > 6) 5805 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5806 5807 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5808 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5809 DELAY(10); 5810 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5811 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5812 DELAY(10); 5813 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5814 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5815 DELAY(10); 5816 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5817 } else { 5818 pga |= BWN_PHY_PGACTL_UNKNOWN; 5819 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5820 DELAY(10); 5821 pga |= BWN_PHY_PGACTL_LOWBANDW; 5822 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5823 DELAY(10); 5824 pga |= BWN_PHY_PGACTL_LPF; 5825 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5826 } 5827 DELAY(21); 5828 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5829 5830 return (feedthrough); 5831 } 5832 5833 static uint16_t 5834 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5835 uint16_t *value, uint16_t *pad_mix_gain) 5836 { 5837 struct bwn_phy *phy = &mac->mac_phy; 5838 uint16_t reg, v, padmix; 5839 5840 if (phy->type == BWN_PHYTYPE_B) { 5841 v = 0x30; 5842 if (phy->rf_rev <= 5) { 5843 reg = 0x43; 5844 padmix = 0; 5845 } else { 5846 reg = 0x52; 5847 padmix = 5; 5848 } 5849 } else { 5850 if (phy->rev >= 2 && phy->rf_rev == 8) { 5851 reg = 0x43; 5852 v = 0x10; 5853 padmix = 2; 5854 } else { 5855 reg = 0x52; 5856 v = 0x30; 5857 padmix = 5; 5858 } 5859 } 5860 if (value) 5861 *value = v; 5862 if (pad_mix_gain) 5863 *pad_mix_gain = padmix; 5864 5865 return (reg); 5866 } 5867 5868 static void 5869 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5870 { 5871 struct bwn_phy *phy = &mac->mac_phy; 5872 struct bwn_phy_g *pg = &phy->phy_g; 5873 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5874 uint16_t reg, mask; 5875 uint16_t trsw_rx, pga; 5876 uint16_t rf_pctl_reg; 5877 5878 static const uint8_t tx_bias_values[] = { 5879 0x09, 0x08, 0x0a, 0x01, 0x00, 5880 0x02, 0x05, 0x04, 0x06, 5881 }; 5882 static const uint8_t tx_magn_values[] = { 5883 0x70, 0x40, 5884 }; 5885 5886 if (!BWN_HAS_LOOPBACK(phy)) { 5887 rf_pctl_reg = 6; 5888 trsw_rx = 2; 5889 pga = 0; 5890 } else { 5891 int lb_gain; 5892 5893 trsw_rx = 0; 5894 lb_gain = pg->pg_max_lb_gain / 2; 5895 if (lb_gain > 10) { 5896 rf_pctl_reg = 0; 5897 pga = abs(10 - lb_gain) / 6; 5898 pga = MIN(MAX(pga, 0), 15); 5899 } else { 5900 int cmp_val; 5901 int tmp; 5902 5903 pga = 0; 5904 cmp_val = 0x24; 5905 if ((phy->rev >= 2) && 5906 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 5907 cmp_val = 0x3c; 5908 tmp = lb_gain; 5909 if ((10 - lb_gain) < cmp_val) 5910 tmp = (10 - lb_gain); 5911 if (tmp < 0) 5912 tmp += 6; 5913 else 5914 tmp += 3; 5915 cmp_val /= 4; 5916 tmp /= 4; 5917 if (tmp >= cmp_val) 5918 rf_pctl_reg = cmp_val; 5919 else 5920 rf_pctl_reg = tmp; 5921 } 5922 } 5923 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 5924 bwn_phy_g_set_bbatt(mac, 2); 5925 5926 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 5927 mask = ~mask; 5928 BWN_RF_MASK(mac, reg, mask); 5929 5930 if (BWN_HAS_TXMAG(phy)) { 5931 int i, j; 5932 int feedthrough; 5933 int min_feedth = 0xffff; 5934 uint8_t tx_magn, tx_bias; 5935 5936 for (i = 0; i < N(tx_magn_values); i++) { 5937 tx_magn = tx_magn_values[i]; 5938 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 5939 for (j = 0; j < N(tx_bias_values); j++) { 5940 tx_bias = tx_bias_values[j]; 5941 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 5942 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 5943 trsw_rx); 5944 if (feedthrough < min_feedth) { 5945 lo->tx_bias = tx_bias; 5946 lo->tx_magn = tx_magn; 5947 min_feedth = feedthrough; 5948 } 5949 if (lo->tx_bias == 0) 5950 break; 5951 } 5952 BWN_RF_WRITE(mac, 0x52, 5953 (BWN_RF_READ(mac, 0x52) 5954 & 0xff00) | lo->tx_bias | lo-> 5955 tx_magn); 5956 } 5957 } else { 5958 lo->tx_magn = 0; 5959 lo->tx_bias = 0; 5960 BWN_RF_MASK(mac, 0x52, 0xfff0); 5961 } 5962 5963 BWN_GETTIME(lo->txctl_measured_time); 5964 } 5965 5966 static void 5967 bwn_lo_get_powervector(struct bwn_mac *mac) 5968 { 5969 struct bwn_phy *phy = &mac->mac_phy; 5970 struct bwn_phy_g *pg = &phy->phy_g; 5971 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5972 int i; 5973 uint64_t tmp; 5974 uint64_t power_vector = 0; 5975 5976 for (i = 0; i < 8; i += 2) { 5977 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 5978 power_vector |= (tmp << (i * 8)); 5979 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 5980 } 5981 if (power_vector) 5982 lo->power_vector = power_vector; 5983 5984 BWN_GETTIME(lo->pwr_vec_read_time); 5985 } 5986 5987 static void 5988 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 5989 int use_trsw_rx) 5990 { 5991 struct bwn_phy *phy = &mac->mac_phy; 5992 struct bwn_phy_g *pg = &phy->phy_g; 5993 uint16_t tmp; 5994 5995 if (max_rx_gain < 0) 5996 max_rx_gain = 0; 5997 5998 if (BWN_HAS_LOOPBACK(phy)) { 5999 int trsw_rx = 0; 6000 int trsw_rx_gain; 6001 6002 if (use_trsw_rx) { 6003 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6004 if (max_rx_gain >= trsw_rx_gain) { 6005 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6006 trsw_rx = 0x20; 6007 } 6008 } else 6009 trsw_rx_gain = max_rx_gain; 6010 if (trsw_rx_gain < 9) { 6011 pg->pg_lna_lod_gain = 0; 6012 } else { 6013 pg->pg_lna_lod_gain = 1; 6014 trsw_rx_gain -= 8; 6015 } 6016 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6017 pg->pg_pga_gain = trsw_rx_gain / 3; 6018 if (pg->pg_pga_gain >= 5) { 6019 pg->pg_pga_gain -= 5; 6020 pg->pg_lna_gain = 2; 6021 } else 6022 pg->pg_lna_gain = 0; 6023 } else { 6024 pg->pg_lna_gain = 0; 6025 pg->pg_trsw_rx_gain = 0x20; 6026 if (max_rx_gain >= 0x14) { 6027 pg->pg_lna_lod_gain = 1; 6028 pg->pg_pga_gain = 2; 6029 } else if (max_rx_gain >= 0x12) { 6030 pg->pg_lna_lod_gain = 1; 6031 pg->pg_pga_gain = 1; 6032 } else if (max_rx_gain >= 0xf) { 6033 pg->pg_lna_lod_gain = 1; 6034 pg->pg_pga_gain = 0; 6035 } else { 6036 pg->pg_lna_lod_gain = 0; 6037 pg->pg_pga_gain = 0; 6038 } 6039 } 6040 6041 tmp = BWN_RF_READ(mac, 0x7a); 6042 if (pg->pg_lna_lod_gain == 0) 6043 tmp &= ~0x0008; 6044 else 6045 tmp |= 0x0008; 6046 BWN_RF_WRITE(mac, 0x7a, tmp); 6047 } 6048 6049 static void 6050 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6051 { 6052 struct bwn_phy *phy = &mac->mac_phy; 6053 struct bwn_phy_g *pg = &phy->phy_g; 6054 struct bwn_softc *sc = mac->mac_sc; 6055 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6056 struct timespec ts; 6057 uint16_t tmp; 6058 6059 if (bwn_has_hwpctl(mac)) { 6060 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6061 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6062 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6063 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6064 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6065 6066 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6067 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6068 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6069 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6070 } 6071 if (phy->type == BWN_PHYTYPE_B && 6072 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6073 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6074 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6075 } 6076 if (phy->rev >= 2) { 6077 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6078 sav->phy_analogoverval = 6079 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6080 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6081 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6082 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6083 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6084 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6085 6086 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6087 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6088 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6089 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6090 if (phy->type == BWN_PHYTYPE_G) { 6091 if ((phy->rev >= 7) && 6092 (siba_sprom_get_bf_lo(sc->sc_dev) & 6093 BWN_BFL_EXTLNA)) { 6094 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6095 } else { 6096 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6097 } 6098 } else { 6099 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6100 } 6101 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6102 } 6103 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6104 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6105 sav->rf0 = BWN_RF_READ(mac, 0x43); 6106 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6107 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6108 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6109 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6110 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6111 6112 if (!BWN_HAS_TXMAG(phy)) { 6113 sav->rf2 = BWN_RF_READ(mac, 0x52); 6114 sav->rf2 &= 0x00f0; 6115 } 6116 if (phy->type == BWN_PHYTYPE_B) { 6117 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6118 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6119 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6120 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6121 } else { 6122 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6123 | 0x8000); 6124 } 6125 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6126 & 0xf000); 6127 6128 tmp = 6129 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6130 BWN_PHY_WRITE(mac, tmp, 0x007f); 6131 6132 tmp = sav->phy_syncctl; 6133 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6134 tmp = sav->rf1; 6135 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6136 6137 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6138 if (phy->type == BWN_PHYTYPE_G || 6139 (phy->type == BWN_PHYTYPE_B && 6140 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6141 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6142 } else 6143 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6144 if (phy->rev >= 2) 6145 bwn_dummy_transmission(mac, 0, 1); 6146 bwn_phy_g_switch_chan(mac, 6, 0); 6147 BWN_RF_READ(mac, 0x51); 6148 if (phy->type == BWN_PHYTYPE_G) 6149 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6150 6151 nanouptime(&ts); 6152 if (time_before(lo->txctl_measured_time, 6153 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6154 bwn_lo_measure_txctl_values(mac); 6155 6156 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6157 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6158 else { 6159 if (phy->type == BWN_PHYTYPE_B) 6160 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6161 else 6162 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6163 } 6164 } 6165 6166 static void 6167 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6168 { 6169 struct bwn_phy *phy = &mac->mac_phy; 6170 struct bwn_phy_g *pg = &phy->phy_g; 6171 uint16_t tmp; 6172 6173 if (phy->rev >= 2) { 6174 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6175 tmp = (pg->pg_pga_gain << 8); 6176 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6177 DELAY(5); 6178 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6179 DELAY(2); 6180 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6181 } else { 6182 tmp = (pg->pg_pga_gain | 0xefa0); 6183 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6184 } 6185 if (phy->type == BWN_PHYTYPE_G) { 6186 if (phy->rev >= 3) 6187 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6188 else 6189 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6190 if (phy->rev >= 2) 6191 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6192 else 6193 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6194 } 6195 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6196 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6197 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6198 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6199 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6200 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6201 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6202 if (!BWN_HAS_TXMAG(phy)) { 6203 tmp = sav->rf2; 6204 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6205 } 6206 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6207 if (phy->type == BWN_PHYTYPE_B && 6208 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6209 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6210 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6211 } 6212 if (phy->rev >= 2) { 6213 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6214 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6215 sav->phy_analogoverval); 6216 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6217 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6218 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6219 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6220 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6221 } 6222 if (bwn_has_hwpctl(mac)) { 6223 tmp = (sav->phy_lomask & 0xbfff); 6224 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6225 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6226 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6227 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6228 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6229 } 6230 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6231 } 6232 6233 static int 6234 bwn_lo_probe_loctl(struct bwn_mac *mac, 6235 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6236 { 6237 struct bwn_phy *phy = &mac->mac_phy; 6238 struct bwn_phy_g *pg = &phy->phy_g; 6239 struct bwn_loctl orig, test; 6240 struct bwn_loctl prev = { -100, -100 }; 6241 static const struct bwn_loctl modifiers[] = { 6242 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6243 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6244 }; 6245 int begin, end, lower = 0, i; 6246 uint16_t feedth; 6247 6248 if (d->curstate == 0) { 6249 begin = 1; 6250 end = 8; 6251 } else if (d->curstate % 2 == 0) { 6252 begin = d->curstate - 1; 6253 end = d->curstate + 1; 6254 } else { 6255 begin = d->curstate - 2; 6256 end = d->curstate + 2; 6257 } 6258 if (begin < 1) 6259 begin += 8; 6260 if (end > 8) 6261 end -= 8; 6262 6263 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6264 i = begin; 6265 d->curstate = i; 6266 while (1) { 6267 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6268 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6269 test.i += modifiers[i - 1].i * d->multipler; 6270 test.q += modifiers[i - 1].q * d->multipler; 6271 if ((test.i != prev.i || test.q != prev.q) && 6272 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6273 bwn_lo_write(mac, &test); 6274 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6275 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6276 if (feedth < d->feedth) { 6277 memcpy(probe, &test, 6278 sizeof(struct bwn_loctl)); 6279 lower = 1; 6280 d->feedth = feedth; 6281 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6282 break; 6283 } 6284 } 6285 memcpy(&prev, &test, sizeof(prev)); 6286 if (i == end) 6287 break; 6288 if (i == 8) 6289 i = 1; 6290 else 6291 i++; 6292 d->curstate = i; 6293 } 6294 6295 return (lower); 6296 } 6297 6298 static void 6299 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6300 { 6301 struct bwn_phy *phy = &mac->mac_phy; 6302 struct bwn_phy_g *pg = &phy->phy_g; 6303 struct bwn_lo_g_sm d; 6304 struct bwn_loctl probe; 6305 int lower, repeat, cnt = 0; 6306 uint16_t feedth; 6307 6308 d.nmeasure = 0; 6309 d.multipler = 1; 6310 if (BWN_HAS_LOOPBACK(phy)) 6311 d.multipler = 3; 6312 6313 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6314 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6315 6316 do { 6317 bwn_lo_write(mac, &d.loctl); 6318 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6319 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6320 if (feedth < 0x258) { 6321 if (feedth >= 0x12c) 6322 *rxgain += 6; 6323 else 6324 *rxgain += 3; 6325 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6326 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6327 } 6328 d.feedth = feedth; 6329 d.curstate = 0; 6330 do { 6331 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6332 ("%s:%d: fail", __func__, __LINE__)); 6333 memcpy(&probe, &d.loctl, 6334 sizeof(struct bwn_loctl)); 6335 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6336 if (!lower) 6337 break; 6338 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6339 break; 6340 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6341 d.nmeasure++; 6342 } while (d.nmeasure < 24); 6343 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6344 6345 if (BWN_HAS_LOOPBACK(phy)) { 6346 if (d.feedth > 0x1194) 6347 *rxgain -= 6; 6348 else if (d.feedth < 0x5dc) 6349 *rxgain += 3; 6350 if (cnt == 0) { 6351 if (d.feedth <= 0x5dc) { 6352 d.multipler = 1; 6353 cnt++; 6354 } else 6355 d.multipler = 2; 6356 } else if (cnt == 2) 6357 d.multipler = 1; 6358 } 6359 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6360 } while (++cnt < repeat); 6361 } 6362 6363 static struct bwn_lo_calib * 6364 bwn_lo_calibset(struct bwn_mac *mac, 6365 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6366 { 6367 struct bwn_phy *phy = &mac->mac_phy; 6368 struct bwn_phy_g *pg = &phy->phy_g; 6369 struct bwn_loctl loctl = { 0, 0 }; 6370 struct bwn_lo_calib *cal; 6371 struct bwn_lo_g_value sval = { 0 }; 6372 int rxgain; 6373 uint16_t pad, reg, value; 6374 6375 sval.old_channel = phy->chan; 6376 bwn_mac_suspend(mac); 6377 bwn_lo_save(mac, &sval); 6378 6379 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6380 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6381 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6382 6383 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6384 if (rfatt->padmix) 6385 rxgain -= pad; 6386 if (BWN_HAS_LOOPBACK(phy)) 6387 rxgain += pg->pg_max_lb_gain; 6388 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6389 bwn_phy_g_set_bbatt(mac, bbatt->att); 6390 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6391 6392 bwn_lo_restore(mac, &sval); 6393 bwn_mac_enable(mac); 6394 6395 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6396 if (!cal) { 6397 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6398 return (NULL); 6399 } 6400 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6401 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6402 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6403 6404 BWN_GETTIME(cal->calib_time); 6405 6406 return (cal); 6407 } 6408 6409 static struct bwn_lo_calib * 6410 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6411 const struct bwn_rfatt *rfatt) 6412 { 6413 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6414 struct bwn_lo_calib *c; 6415 6416 TAILQ_FOREACH(c, &lo->calib_list, list) { 6417 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6418 continue; 6419 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6420 continue; 6421 return (c); 6422 } 6423 6424 c = bwn_lo_calibset(mac, bbatt, rfatt); 6425 if (!c) 6426 return (NULL); 6427 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6428 6429 return (c); 6430 } 6431 6432 static void 6433 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6434 { 6435 struct bwn_phy *phy = &mac->mac_phy; 6436 struct bwn_phy_g *pg = &phy->phy_g; 6437 struct bwn_softc *sc = mac->mac_sc; 6438 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6439 const struct bwn_rfatt *rfatt; 6440 const struct bwn_bbatt *bbatt; 6441 uint64_t pvector; 6442 int i; 6443 int rf_offset, bb_offset; 6444 uint8_t changed = 0; 6445 6446 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6447 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6448 ("%s:%d: fail", __func__, __LINE__)); 6449 6450 pvector = lo->power_vector; 6451 if (!update && !pvector) 6452 return; 6453 6454 bwn_mac_suspend(mac); 6455 6456 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6457 struct bwn_lo_calib *cal; 6458 int idx; 6459 uint16_t val; 6460 6461 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6462 continue; 6463 bb_offset = i / lo->rfatt.len; 6464 rf_offset = i % lo->rfatt.len; 6465 bbatt = &(lo->bbatt.array[bb_offset]); 6466 rfatt = &(lo->rfatt.array[rf_offset]); 6467 6468 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6469 if (!cal) { 6470 device_printf(sc->sc_dev, "LO: Could not " 6471 "calibrate DC table entry\n"); 6472 continue; 6473 } 6474 val = (uint8_t)(cal->ctl.q); 6475 val |= ((uint8_t)(cal->ctl.i)) << 4; 6476 free(cal, M_DEVBUF); 6477 6478 idx = i / 2; 6479 if (i % 2) 6480 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6481 | ((val & 0x00ff) << 8); 6482 else 6483 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6484 | (val & 0x00ff); 6485 changed = 1; 6486 } 6487 if (changed) { 6488 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6489 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6490 } 6491 bwn_mac_enable(mac); 6492 } 6493 6494 static void 6495 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6496 { 6497 6498 if (!rf->padmix) 6499 return; 6500 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6501 rf->att = 4; 6502 } 6503 6504 static void 6505 bwn_lo_g_adjust(struct bwn_mac *mac) 6506 { 6507 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6508 struct bwn_lo_calib *cal; 6509 struct bwn_rfatt rf; 6510 6511 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6512 bwn_lo_fixup_rfatt(&rf); 6513 6514 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6515 if (!cal) 6516 return; 6517 bwn_lo_write(mac, &cal->ctl); 6518 } 6519 6520 static void 6521 bwn_lo_g_init(struct bwn_mac *mac) 6522 { 6523 6524 if (!bwn_has_hwpctl(mac)) 6525 return; 6526 6527 bwn_lo_get_powervector(mac); 6528 bwn_phy_g_dc_lookup_init(mac, 1); 6529 } 6530 6531 static void 6532 bwn_mac_suspend(struct bwn_mac *mac) 6533 { 6534 struct bwn_softc *sc = mac->mac_sc; 6535 int i; 6536 uint32_t tmp; 6537 6538 KASSERT(mac->mac_suspended >= 0, 6539 ("%s:%d: fail", __func__, __LINE__)); 6540 6541 if (mac->mac_suspended == 0) { 6542 bwn_psctl(mac, BWN_PS_AWAKE); 6543 BWN_WRITE_4(mac, BWN_MACCTL, 6544 BWN_READ_4(mac, BWN_MACCTL) 6545 & ~BWN_MACCTL_ON); 6546 BWN_READ_4(mac, BWN_MACCTL); 6547 for (i = 35; i; i--) { 6548 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6549 if (tmp & BWN_INTR_MAC_SUSPENDED) 6550 goto out; 6551 DELAY(10); 6552 } 6553 for (i = 40; i; i--) { 6554 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6555 if (tmp & BWN_INTR_MAC_SUSPENDED) 6556 goto out; 6557 DELAY(1000); 6558 } 6559 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6560 } 6561 out: 6562 mac->mac_suspended++; 6563 } 6564 6565 static void 6566 bwn_mac_enable(struct bwn_mac *mac) 6567 { 6568 struct bwn_softc *sc = mac->mac_sc; 6569 uint16_t state; 6570 6571 state = bwn_shm_read_2(mac, BWN_SHARED, 6572 BWN_SHARED_UCODESTAT); 6573 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6574 state != BWN_SHARED_UCODESTAT_SLEEP) 6575 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6576 6577 mac->mac_suspended--; 6578 KASSERT(mac->mac_suspended >= 0, 6579 ("%s:%d: fail", __func__, __LINE__)); 6580 if (mac->mac_suspended == 0) { 6581 BWN_WRITE_4(mac, BWN_MACCTL, 6582 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6583 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6584 BWN_READ_4(mac, BWN_MACCTL); 6585 BWN_READ_4(mac, BWN_INTR_REASON); 6586 bwn_psctl(mac, 0); 6587 } 6588 } 6589 6590 static void 6591 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6592 { 6593 struct bwn_softc *sc = mac->mac_sc; 6594 int i; 6595 uint16_t ucstat; 6596 6597 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6598 ("%s:%d: fail", __func__, __LINE__)); 6599 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6600 ("%s:%d: fail", __func__, __LINE__)); 6601 6602 /* XXX forcibly awake and hwps-off */ 6603 6604 BWN_WRITE_4(mac, BWN_MACCTL, 6605 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6606 ~BWN_MACCTL_HWPS); 6607 BWN_READ_4(mac, BWN_MACCTL); 6608 if (siba_get_revid(sc->sc_dev) >= 5) { 6609 for (i = 0; i < 100; i++) { 6610 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6611 BWN_SHARED_UCODESTAT); 6612 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6613 break; 6614 DELAY(10); 6615 } 6616 } 6617 } 6618 6619 static int16_t 6620 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6621 { 6622 6623 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6624 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6625 } 6626 6627 static void 6628 bwn_nrssi_threshold(struct bwn_mac *mac) 6629 { 6630 struct bwn_phy *phy = &mac->mac_phy; 6631 struct bwn_phy_g *pg = &phy->phy_g; 6632 struct bwn_softc *sc = mac->mac_sc; 6633 int32_t a, b; 6634 int16_t tmp16; 6635 uint16_t tmpu16; 6636 6637 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6638 6639 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6640 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6641 a = 0x13; 6642 b = 0x12; 6643 } else { 6644 a = 0xe; 6645 b = 0x11; 6646 } 6647 6648 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6649 a += (pg->pg_nrssi[0] << 6); 6650 a += (a < 32) ? 31 : 32; 6651 a = a >> 6; 6652 a = MIN(MAX(a, -31), 31); 6653 6654 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6655 b += (pg->pg_nrssi[0] << 6); 6656 if (b < 32) 6657 b += 31; 6658 else 6659 b += 32; 6660 b = b >> 6; 6661 b = MIN(MAX(b, -31), 31); 6662 6663 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6664 tmpu16 |= ((uint32_t)b & 0x0000003f); 6665 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6666 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6667 return; 6668 } 6669 6670 tmp16 = bwn_nrssi_read(mac, 0x20); 6671 if (tmp16 >= 0x20) 6672 tmp16 -= 0x40; 6673 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6674 } 6675 6676 static void 6677 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6678 { 6679 #define SAVE_RF_MAX 3 6680 #define SAVE_PHY_COMM_MAX 4 6681 #define SAVE_PHY3_MAX 8 6682 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6683 { 0x7a, 0x52, 0x43 }; 6684 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6685 { 0x15, 0x5a, 0x59, 0x58 }; 6686 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6687 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6688 0x0801, 0x0060, 0x0014, 0x0478 6689 }; 6690 struct bwn_phy *phy = &mac->mac_phy; 6691 struct bwn_phy_g *pg = &phy->phy_g; 6692 int32_t i, tmp32, phy3_idx = 0; 6693 uint16_t delta, tmp; 6694 uint16_t save_rf[SAVE_RF_MAX]; 6695 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6696 uint16_t save_phy3[SAVE_PHY3_MAX]; 6697 uint16_t ant_div, phy0, chan_ex; 6698 int16_t nrssi0, nrssi1; 6699 6700 KASSERT(phy->type == BWN_PHYTYPE_G, 6701 ("%s:%d: fail", __func__, __LINE__)); 6702 6703 if (phy->rf_rev >= 9) 6704 return; 6705 if (phy->rf_rev == 8) 6706 bwn_nrssi_offset(mac); 6707 6708 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6709 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6710 6711 /* 6712 * Save RF/PHY registers for later restoration 6713 */ 6714 ant_div = BWN_READ_2(mac, 0x03e2); 6715 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6716 for (i = 0; i < SAVE_RF_MAX; ++i) 6717 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6718 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6719 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6720 6721 phy0 = BWN_READ_2(mac, BWN_PHY0); 6722 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6723 if (phy->rev >= 3) { 6724 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6725 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6726 BWN_PHY_WRITE(mac, 0x002e, 0); 6727 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6728 switch (phy->rev) { 6729 case 4: 6730 case 6: 6731 case 7: 6732 BWN_PHY_SET(mac, 0x0478, 0x0100); 6733 BWN_PHY_SET(mac, 0x0801, 0x0040); 6734 break; 6735 case 3: 6736 case 5: 6737 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6738 break; 6739 } 6740 BWN_PHY_SET(mac, 0x0060, 0x0040); 6741 BWN_PHY_SET(mac, 0x0014, 0x0200); 6742 } 6743 /* 6744 * Calculate nrssi0 6745 */ 6746 BWN_RF_SET(mac, 0x007a, 0x0070); 6747 bwn_set_all_gains(mac, 0, 8, 0); 6748 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6749 if (phy->rev >= 2) { 6750 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6751 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6752 } 6753 BWN_RF_SET(mac, 0x007a, 0x0080); 6754 DELAY(20); 6755 6756 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6757 if (nrssi0 >= 0x0020) 6758 nrssi0 -= 0x0040; 6759 6760 /* 6761 * Calculate nrssi1 6762 */ 6763 BWN_RF_MASK(mac, 0x007a, 0x007f); 6764 if (phy->rev >= 2) 6765 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6766 6767 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6768 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6769 BWN_RF_SET(mac, 0x007a, 0x000f); 6770 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6771 if (phy->rev >= 2) { 6772 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6773 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6774 } 6775 6776 bwn_set_all_gains(mac, 3, 0, 1); 6777 if (phy->rf_rev == 8) { 6778 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6779 } else { 6780 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6781 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6782 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6783 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6784 } 6785 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6786 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6787 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6788 DELAY(20); 6789 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6790 6791 /* 6792 * Install calculated narrow RSSI values 6793 */ 6794 if (nrssi1 >= 0x0020) 6795 nrssi1 -= 0x0040; 6796 if (nrssi0 == nrssi1) 6797 pg->pg_nrssi_slope = 0x00010000; 6798 else 6799 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6800 if (nrssi0 >= -4) { 6801 pg->pg_nrssi[0] = nrssi1; 6802 pg->pg_nrssi[1] = nrssi0; 6803 } 6804 6805 /* 6806 * Restore saved RF/PHY registers 6807 */ 6808 if (phy->rev >= 3) { 6809 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6810 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6811 save_phy3[phy3_idx]); 6812 } 6813 } 6814 if (phy->rev >= 2) { 6815 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6816 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6817 } 6818 6819 for (i = 0; i < SAVE_RF_MAX; ++i) 6820 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6821 6822 BWN_WRITE_2(mac, 0x03e2, ant_div); 6823 BWN_WRITE_2(mac, 0x03e6, phy0); 6824 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6825 6826 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6827 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6828 6829 bwn_spu_workaround(mac, phy->chan); 6830 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6831 bwn_set_original_gains(mac); 6832 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6833 if (phy->rev >= 3) { 6834 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6835 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6836 save_phy3[phy3_idx]); 6837 } 6838 } 6839 6840 delta = 0x1f - pg->pg_nrssi[0]; 6841 for (i = 0; i < 64; i++) { 6842 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6843 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6844 pg->pg_nrssi_lt[i] = tmp32; 6845 } 6846 6847 bwn_nrssi_threshold(mac); 6848 #undef SAVE_RF_MAX 6849 #undef SAVE_PHY_COMM_MAX 6850 #undef SAVE_PHY3_MAX 6851 } 6852 6853 static void 6854 bwn_nrssi_offset(struct bwn_mac *mac) 6855 { 6856 #define SAVE_RF_MAX 2 6857 #define SAVE_PHY_COMM_MAX 10 6858 #define SAVE_PHY6_MAX 8 6859 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6860 { 0x7a, 0x43 }; 6861 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6862 0x0001, 0x0811, 0x0812, 0x0814, 6863 0x0815, 0x005a, 0x0059, 0x0058, 6864 0x000a, 0x0003 6865 }; 6866 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6867 0x002e, 0x002f, 0x080f, 0x0810, 6868 0x0801, 0x0060, 0x0014, 0x0478 6869 }; 6870 struct bwn_phy *phy = &mac->mac_phy; 6871 int i, phy6_idx = 0; 6872 uint16_t save_rf[SAVE_RF_MAX]; 6873 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6874 uint16_t save_phy6[SAVE_PHY6_MAX]; 6875 int16_t nrssi; 6876 uint16_t saved = 0xffff; 6877 6878 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6879 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6880 for (i = 0; i < SAVE_RF_MAX; ++i) 6881 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6882 6883 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6884 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6885 BWN_PHY_SET(mac, 0x0811, 0x000c); 6886 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6887 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6888 if (phy->rev >= 6) { 6889 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6890 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6891 6892 BWN_PHY_WRITE(mac, 0x002e, 0); 6893 BWN_PHY_WRITE(mac, 0x002f, 0); 6894 BWN_PHY_WRITE(mac, 0x080f, 0); 6895 BWN_PHY_WRITE(mac, 0x0810, 0); 6896 BWN_PHY_SET(mac, 0x0478, 0x0100); 6897 BWN_PHY_SET(mac, 0x0801, 0x0040); 6898 BWN_PHY_SET(mac, 0x0060, 0x0040); 6899 BWN_PHY_SET(mac, 0x0014, 0x0200); 6900 } 6901 BWN_RF_SET(mac, 0x007a, 0x0070); 6902 BWN_RF_SET(mac, 0x007a, 0x0080); 6903 DELAY(30); 6904 6905 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6906 if (nrssi >= 0x20) 6907 nrssi -= 0x40; 6908 if (nrssi == 31) { 6909 for (i = 7; i >= 4; i--) { 6910 BWN_RF_WRITE(mac, 0x007b, i); 6911 DELAY(20); 6912 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 6913 0x003f); 6914 if (nrssi >= 0x20) 6915 nrssi -= 0x40; 6916 if (nrssi < 31 && saved == 0xffff) 6917 saved = i; 6918 } 6919 if (saved == 0xffff) 6920 saved = 4; 6921 } else { 6922 BWN_RF_MASK(mac, 0x007a, 0x007f); 6923 if (phy->rev != 1) { 6924 BWN_PHY_SET(mac, 0x0814, 0x0001); 6925 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 6926 } 6927 BWN_PHY_SET(mac, 0x0811, 0x000c); 6928 BWN_PHY_SET(mac, 0x0812, 0x000c); 6929 BWN_PHY_SET(mac, 0x0811, 0x0030); 6930 BWN_PHY_SET(mac, 0x0812, 0x0030); 6931 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6932 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6933 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6934 if (phy->rev == 0) 6935 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 6936 else 6937 BWN_PHY_SET(mac, 0x000a, 0x2000); 6938 if (phy->rev != 1) { 6939 BWN_PHY_SET(mac, 0x0814, 0x0004); 6940 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 6941 } 6942 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6943 BWN_RF_SET(mac, 0x007a, 0x000f); 6944 bwn_set_all_gains(mac, 3, 0, 1); 6945 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 6946 DELAY(30); 6947 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6948 if (nrssi >= 0x20) 6949 nrssi -= 0x40; 6950 if (nrssi == -32) { 6951 for (i = 0; i < 4; i++) { 6952 BWN_RF_WRITE(mac, 0x007b, i); 6953 DELAY(20); 6954 nrssi = (int16_t)((BWN_PHY_READ(mac, 6955 0x047f) >> 8) & 0x003f); 6956 if (nrssi >= 0x20) 6957 nrssi -= 0x40; 6958 if (nrssi > -31 && saved == 0xffff) 6959 saved = i; 6960 } 6961 if (saved == 0xffff) 6962 saved = 3; 6963 } else 6964 saved = 0; 6965 } 6966 BWN_RF_WRITE(mac, 0x007b, saved); 6967 6968 /* 6969 * Restore saved RF/PHY registers 6970 */ 6971 if (phy->rev >= 6) { 6972 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 6973 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6974 save_phy6[phy6_idx]); 6975 } 6976 } 6977 if (phy->rev != 1) { 6978 for (i = 3; i < 5; i++) 6979 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 6980 save_phy_comm[i]); 6981 } 6982 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 6983 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6984 6985 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 6986 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6987 6988 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 6989 BWN_PHY_SET(mac, 0x0429, 0x8000); 6990 bwn_set_original_gains(mac); 6991 if (phy->rev >= 6) { 6992 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 6993 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6994 save_phy6[phy6_idx]); 6995 } 6996 } 6997 6998 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 6999 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7000 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7001 } 7002 7003 static void 7004 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7005 int16_t third) 7006 { 7007 struct bwn_phy *phy = &mac->mac_phy; 7008 uint16_t i; 7009 uint16_t start = 0x08, end = 0x18; 7010 uint16_t tmp; 7011 uint16_t table; 7012 7013 if (phy->rev <= 1) { 7014 start = 0x10; 7015 end = 0x20; 7016 } 7017 7018 table = BWN_OFDMTAB_GAINX; 7019 if (phy->rev <= 1) 7020 table = BWN_OFDMTAB_GAINX_R1; 7021 for (i = 0; i < 4; i++) 7022 bwn_ofdmtab_write_2(mac, table, i, first); 7023 7024 for (i = start; i < end; i++) 7025 bwn_ofdmtab_write_2(mac, table, i, second); 7026 7027 if (third != -1) { 7028 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7029 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7030 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7031 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7032 } 7033 bwn_dummy_transmission(mac, 0, 1); 7034 } 7035 7036 static void 7037 bwn_set_original_gains(struct bwn_mac *mac) 7038 { 7039 struct bwn_phy *phy = &mac->mac_phy; 7040 uint16_t i, tmp; 7041 uint16_t table; 7042 uint16_t start = 0x0008, end = 0x0018; 7043 7044 if (phy->rev <= 1) { 7045 start = 0x0010; 7046 end = 0x0020; 7047 } 7048 7049 table = BWN_OFDMTAB_GAINX; 7050 if (phy->rev <= 1) 7051 table = BWN_OFDMTAB_GAINX_R1; 7052 for (i = 0; i < 4; i++) { 7053 tmp = (i & 0xfffc); 7054 tmp |= (i & 0x0001) << 1; 7055 tmp |= (i & 0x0002) >> 1; 7056 7057 bwn_ofdmtab_write_2(mac, table, i, tmp); 7058 } 7059 7060 for (i = start; i < end; i++) 7061 bwn_ofdmtab_write_2(mac, table, i, i - start); 7062 7063 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7064 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7065 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7066 bwn_dummy_transmission(mac, 0, 1); 7067 } 7068 7069 static void 7070 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7071 { 7072 struct bwn_phy *phy = &mac->mac_phy; 7073 struct bwn_phy_g *pg = &phy->phy_g; 7074 struct bwn_rfatt old_rfatt, rfatt; 7075 struct bwn_bbatt old_bbatt, bbatt; 7076 struct bwn_softc *sc = mac->mac_sc; 7077 uint8_t old_txctl = 0; 7078 7079 KASSERT(phy->type == BWN_PHYTYPE_G, 7080 ("%s:%d: fail", __func__, __LINE__)); 7081 7082 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7083 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7084 return; 7085 7086 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7087 7088 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7089 7090 if (!phy->gmode) 7091 return; 7092 bwn_hwpctl_early_init(mac); 7093 if (pg->pg_curtssi == 0) { 7094 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7095 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7096 } else { 7097 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7098 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7099 old_txctl = pg->pg_txctl; 7100 7101 bbatt.att = 11; 7102 if (phy->rf_rev == 8) { 7103 rfatt.att = 15; 7104 rfatt.padmix = 1; 7105 } else { 7106 rfatt.att = 9; 7107 rfatt.padmix = 0; 7108 } 7109 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7110 } 7111 bwn_dummy_transmission(mac, 0, 1); 7112 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7113 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7114 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7115 else 7116 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7117 &old_rfatt, old_txctl); 7118 } 7119 bwn_hwpctl_init_gphy(mac); 7120 7121 /* clear TSSI */ 7122 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7123 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7124 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7125 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7126 } 7127 7128 static void 7129 bwn_hwpctl_early_init(struct bwn_mac *mac) 7130 { 7131 struct bwn_phy *phy = &mac->mac_phy; 7132 7133 if (!bwn_has_hwpctl(mac)) { 7134 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7135 return; 7136 } 7137 7138 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7139 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7140 BWN_PHY_SET(mac, 0x047c, 0x0002); 7141 BWN_PHY_SET(mac, 0x047a, 0xf000); 7142 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7143 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7144 BWN_PHY_SET(mac, 0x005d, 0x8000); 7145 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7146 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7147 BWN_PHY_SET(mac, 0x0036, 0x0400); 7148 } else { 7149 BWN_PHY_SET(mac, 0x0036, 0x0200); 7150 BWN_PHY_SET(mac, 0x0036, 0x0400); 7151 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7152 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7153 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7154 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7155 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7156 } 7157 } 7158 7159 static void 7160 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7161 { 7162 struct bwn_phy *phy = &mac->mac_phy; 7163 struct bwn_phy_g *pg = &phy->phy_g; 7164 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7165 int i; 7166 uint16_t nr_written = 0, tmp, value; 7167 uint8_t rf, bb; 7168 7169 if (!bwn_has_hwpctl(mac)) { 7170 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7171 return; 7172 } 7173 7174 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7175 (pg->pg_idletssi - pg->pg_curtssi)); 7176 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7177 (pg->pg_idletssi - pg->pg_curtssi)); 7178 7179 for (i = 0; i < 32; i++) 7180 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7181 for (i = 32; i < 64; i++) 7182 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7183 for (i = 0; i < 64; i += 2) { 7184 value = (uint16_t) pg->pg_tssi2dbm[i]; 7185 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7186 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7187 } 7188 7189 for (rf = 0; rf < lo->rfatt.len; rf++) { 7190 for (bb = 0; bb < lo->bbatt.len; bb++) { 7191 if (nr_written >= 0x40) 7192 return; 7193 tmp = lo->bbatt.array[bb].att; 7194 tmp <<= 8; 7195 if (phy->rf_rev == 8) 7196 tmp |= 0x50; 7197 else 7198 tmp |= 0x40; 7199 tmp |= lo->rfatt.array[rf].att; 7200 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7201 nr_written++; 7202 } 7203 } 7204 7205 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7206 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7207 7208 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7209 BWN_PHY_SET(mac, 0x0478, 0x0800); 7210 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7211 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7212 7213 bwn_phy_g_dc_lookup_init(mac, 1); 7214 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7215 } 7216 7217 static void 7218 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7219 { 7220 struct bwn_softc *sc = mac->mac_sc; 7221 7222 if (spu != 0) 7223 bwn_spu_workaround(mac, channel); 7224 7225 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7226 7227 if (channel == 14) { 7228 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7229 bwn_hf_write(mac, 7230 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7231 else 7232 bwn_hf_write(mac, 7233 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7234 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7235 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7236 return; 7237 } 7238 7239 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7240 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7241 } 7242 7243 static uint16_t 7244 bwn_phy_g_chan2freq(uint8_t channel) 7245 { 7246 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7247 7248 KASSERT(channel >= 1 && channel <= 14, 7249 ("%s:%d: fail", __func__, __LINE__)); 7250 7251 return (bwn_phy_g_rf_channels[channel - 1]); 7252 } 7253 7254 static void 7255 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7256 const struct bwn_rfatt *rfatt, uint8_t txctl) 7257 { 7258 struct bwn_phy *phy = &mac->mac_phy; 7259 struct bwn_phy_g *pg = &phy->phy_g; 7260 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7261 uint16_t bb, rf; 7262 uint16_t tx_bias, tx_magn; 7263 7264 bb = bbatt->att; 7265 rf = rfatt->att; 7266 tx_bias = lo->tx_bias; 7267 tx_magn = lo->tx_magn; 7268 if (tx_bias == 0xff) 7269 tx_bias = 0; 7270 7271 pg->pg_txctl = txctl; 7272 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7273 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7274 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7275 bwn_phy_g_set_bbatt(mac, bb); 7276 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7277 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7278 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7279 else { 7280 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7281 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7282 } 7283 if (BWN_HAS_TXMAG(phy)) 7284 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7285 else 7286 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7287 bwn_lo_g_adjust(mac); 7288 } 7289 7290 static void 7291 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7292 uint16_t bbatt) 7293 { 7294 struct bwn_phy *phy = &mac->mac_phy; 7295 7296 if (phy->analog == 0) { 7297 BWN_WRITE_2(mac, BWN_PHY0, 7298 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7299 return; 7300 } 7301 if (phy->analog > 1) { 7302 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7303 return; 7304 } 7305 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7306 } 7307 7308 static uint16_t 7309 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7310 { 7311 struct bwn_phy *phy = &mac->mac_phy; 7312 struct bwn_phy_g *pg = &phy->phy_g; 7313 struct bwn_softc *sc = mac->mac_sc; 7314 int max_lb_gain; 7315 uint16_t extlna; 7316 uint16_t i; 7317 7318 if (phy->gmode == 0) 7319 return (0); 7320 7321 if (BWN_HAS_LOOPBACK(phy)) { 7322 max_lb_gain = pg->pg_max_lb_gain; 7323 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7324 if (max_lb_gain >= 0x46) { 7325 extlna = 0x3000; 7326 max_lb_gain -= 0x46; 7327 } else if (max_lb_gain >= 0x3a) { 7328 extlna = 0x1000; 7329 max_lb_gain -= 0x3a; 7330 } else if (max_lb_gain >= 0x2e) { 7331 extlna = 0x2000; 7332 max_lb_gain -= 0x2e; 7333 } else { 7334 extlna = 0; 7335 max_lb_gain -= 0x10; 7336 } 7337 7338 for (i = 0; i < 16; i++) { 7339 max_lb_gain -= (i * 6); 7340 if (max_lb_gain < 6) 7341 break; 7342 } 7343 7344 if ((phy->rev < 7) || 7345 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7346 if (reg == BWN_PHY_RFOVER) { 7347 return (0x1b3); 7348 } else if (reg == BWN_PHY_RFOVERVAL) { 7349 extlna |= (i << 8); 7350 switch (lpd) { 7351 case BWN_LPD(0, 1, 1): 7352 return (0x0f92); 7353 case BWN_LPD(0, 0, 1): 7354 case BWN_LPD(1, 0, 1): 7355 return (0x0092 | extlna); 7356 case BWN_LPD(1, 0, 0): 7357 return (0x0093 | extlna); 7358 } 7359 KASSERT(0 == 1, 7360 ("%s:%d: fail", __func__, __LINE__)); 7361 } 7362 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7363 } else { 7364 if (reg == BWN_PHY_RFOVER) 7365 return (0x9b3); 7366 if (reg == BWN_PHY_RFOVERVAL) { 7367 if (extlna) 7368 extlna |= 0x8000; 7369 extlna |= (i << 8); 7370 switch (lpd) { 7371 case BWN_LPD(0, 1, 1): 7372 return (0x8f92); 7373 case BWN_LPD(0, 0, 1): 7374 return (0x8092 | extlna); 7375 case BWN_LPD(1, 0, 1): 7376 return (0x2092 | extlna); 7377 case BWN_LPD(1, 0, 0): 7378 return (0x2093 | extlna); 7379 } 7380 KASSERT(0 == 1, 7381 ("%s:%d: fail", __func__, __LINE__)); 7382 } 7383 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7384 } 7385 return (0); 7386 } 7387 7388 if ((phy->rev < 7) || 7389 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7390 if (reg == BWN_PHY_RFOVER) { 7391 return (0x1b3); 7392 } else if (reg == BWN_PHY_RFOVERVAL) { 7393 switch (lpd) { 7394 case BWN_LPD(0, 1, 1): 7395 return (0x0fb2); 7396 case BWN_LPD(0, 0, 1): 7397 return (0x00b2); 7398 case BWN_LPD(1, 0, 1): 7399 return (0x30b2); 7400 case BWN_LPD(1, 0, 0): 7401 return (0x30b3); 7402 } 7403 KASSERT(0 == 1, 7404 ("%s:%d: fail", __func__, __LINE__)); 7405 } 7406 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7407 } else { 7408 if (reg == BWN_PHY_RFOVER) { 7409 return (0x9b3); 7410 } else if (reg == BWN_PHY_RFOVERVAL) { 7411 switch (lpd) { 7412 case BWN_LPD(0, 1, 1): 7413 return (0x8fb2); 7414 case BWN_LPD(0, 0, 1): 7415 return (0x80b2); 7416 case BWN_LPD(1, 0, 1): 7417 return (0x20b2); 7418 case BWN_LPD(1, 0, 0): 7419 return (0x20b3); 7420 } 7421 KASSERT(0 == 1, 7422 ("%s:%d: fail", __func__, __LINE__)); 7423 } 7424 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7425 } 7426 return (0); 7427 } 7428 7429 static void 7430 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7431 { 7432 7433 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7434 return; 7435 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7436 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7437 DELAY(1000); 7438 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7439 } 7440 7441 static int 7442 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7443 { 7444 struct bwn_softc *sc = mac->mac_sc; 7445 struct bwn_fw *fw = &mac->mac_fw; 7446 const uint8_t rev = siba_get_revid(sc->sc_dev); 7447 const char *filename; 7448 uint32_t high; 7449 int error; 7450 7451 /* microcode */ 7452 if (rev >= 5 && rev <= 10) 7453 filename = "ucode5"; 7454 else if (rev >= 11 && rev <= 12) 7455 filename = "ucode11"; 7456 else if (rev == 13) 7457 filename = "ucode13"; 7458 else if (rev == 14) 7459 filename = "ucode14"; 7460 else if (rev >= 15) 7461 filename = "ucode15"; 7462 else { 7463 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7464 bwn_release_firmware(mac); 7465 return (EOPNOTSUPP); 7466 } 7467 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7468 if (error) { 7469 bwn_release_firmware(mac); 7470 return (error); 7471 } 7472 7473 /* PCM */ 7474 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7475 if (rev >= 5 && rev <= 10) { 7476 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7477 if (error == ENOENT) 7478 fw->no_pcmfile = 1; 7479 else if (error) { 7480 bwn_release_firmware(mac); 7481 return (error); 7482 } 7483 } else if (rev < 11) { 7484 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7485 return (EOPNOTSUPP); 7486 } 7487 7488 /* initvals */ 7489 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7490 switch (mac->mac_phy.type) { 7491 case BWN_PHYTYPE_A: 7492 if (rev < 5 || rev > 10) 7493 goto fail1; 7494 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7495 filename = "a0g1initvals5"; 7496 else 7497 filename = "a0g0initvals5"; 7498 break; 7499 case BWN_PHYTYPE_G: 7500 if (rev >= 5 && rev <= 10) 7501 filename = "b0g0initvals5"; 7502 else if (rev >= 13) 7503 filename = "b0g0initvals13"; 7504 else 7505 goto fail1; 7506 break; 7507 case BWN_PHYTYPE_LP: 7508 if (rev == 13) 7509 filename = "lp0initvals13"; 7510 else if (rev == 14) 7511 filename = "lp0initvals14"; 7512 else if (rev >= 15) 7513 filename = "lp0initvals15"; 7514 else 7515 goto fail1; 7516 break; 7517 case BWN_PHYTYPE_N: 7518 if (rev >= 11 && rev <= 12) 7519 filename = "n0initvals11"; 7520 else 7521 goto fail1; 7522 break; 7523 default: 7524 goto fail1; 7525 } 7526 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7527 if (error) { 7528 bwn_release_firmware(mac); 7529 return (error); 7530 } 7531 7532 /* bandswitch initvals */ 7533 switch (mac->mac_phy.type) { 7534 case BWN_PHYTYPE_A: 7535 if (rev >= 5 && rev <= 10) { 7536 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7537 filename = "a0g1bsinitvals5"; 7538 else 7539 filename = "a0g0bsinitvals5"; 7540 } else if (rev >= 11) 7541 filename = NULL; 7542 else 7543 goto fail1; 7544 break; 7545 case BWN_PHYTYPE_G: 7546 if (rev >= 5 && rev <= 10) 7547 filename = "b0g0bsinitvals5"; 7548 else if (rev >= 11) 7549 filename = NULL; 7550 else 7551 goto fail1; 7552 break; 7553 case BWN_PHYTYPE_LP: 7554 if (rev == 13) 7555 filename = "lp0bsinitvals13"; 7556 else if (rev == 14) 7557 filename = "lp0bsinitvals14"; 7558 else if (rev >= 15) 7559 filename = "lp0bsinitvals15"; 7560 else 7561 goto fail1; 7562 break; 7563 case BWN_PHYTYPE_N: 7564 if (rev >= 11 && rev <= 12) 7565 filename = "n0bsinitvals11"; 7566 else 7567 goto fail1; 7568 break; 7569 default: 7570 goto fail1; 7571 } 7572 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7573 if (error) { 7574 bwn_release_firmware(mac); 7575 return (error); 7576 } 7577 return (0); 7578 fail1: 7579 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7580 bwn_release_firmware(mac); 7581 return (EOPNOTSUPP); 7582 } 7583 7584 static int 7585 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7586 const char *name, struct bwn_fwfile *bfw) 7587 { 7588 const struct bwn_fwhdr *hdr; 7589 struct bwn_softc *sc = mac->mac_sc; 7590 const struct firmware *fw; 7591 char namebuf[64]; 7592 7593 if (name == NULL) { 7594 bwn_do_release_fw(bfw); 7595 return (0); 7596 } 7597 if (bfw->filename != NULL) { 7598 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7599 return (0); 7600 bwn_do_release_fw(bfw); 7601 } 7602 7603 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7604 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7605 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7606 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7607 fw = firmware_get(namebuf); 7608 if (fw == NULL) { 7609 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7610 namebuf); 7611 return (ENOENT); 7612 } 7613 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7614 goto fail; 7615 hdr = (const struct bwn_fwhdr *)(fw->data); 7616 switch (hdr->type) { 7617 case BWN_FWTYPE_UCODE: 7618 case BWN_FWTYPE_PCM: 7619 if (be32toh(hdr->size) != 7620 (fw->datasize - sizeof(struct bwn_fwhdr))) 7621 goto fail; 7622 /* FALLTHROUGH */ 7623 case BWN_FWTYPE_IV: 7624 if (hdr->ver != 1) 7625 goto fail; 7626 break; 7627 default: 7628 goto fail; 7629 } 7630 bfw->filename = name; 7631 bfw->fw = fw; 7632 bfw->type = type; 7633 return (0); 7634 fail: 7635 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7636 if (fw != NULL) 7637 firmware_put(fw, FIRMWARE_UNLOAD); 7638 return (EPROTO); 7639 } 7640 7641 static void 7642 bwn_release_firmware(struct bwn_mac *mac) 7643 { 7644 7645 bwn_do_release_fw(&mac->mac_fw.ucode); 7646 bwn_do_release_fw(&mac->mac_fw.pcm); 7647 bwn_do_release_fw(&mac->mac_fw.initvals); 7648 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7649 } 7650 7651 static void 7652 bwn_do_release_fw(struct bwn_fwfile *bfw) 7653 { 7654 7655 if (bfw->fw != NULL) 7656 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7657 bfw->fw = NULL; 7658 bfw->filename = NULL; 7659 } 7660 7661 static int 7662 bwn_fw_loaducode(struct bwn_mac *mac) 7663 { 7664 #define GETFWOFFSET(fwp, offset) \ 7665 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7666 #define GETFWSIZE(fwp, offset) \ 7667 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7668 struct bwn_softc *sc = mac->mac_sc; 7669 const uint32_t *data; 7670 unsigned int i; 7671 uint32_t ctl; 7672 uint16_t date, fwcaps, time; 7673 int error = 0; 7674 7675 ctl = BWN_READ_4(mac, BWN_MACCTL); 7676 ctl |= BWN_MACCTL_MCODE_JMP0; 7677 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7678 __LINE__)); 7679 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7680 for (i = 0; i < 64; i++) 7681 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7682 for (i = 0; i < 4096; i += 2) 7683 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7684 7685 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7686 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7687 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7688 i++) { 7689 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7690 DELAY(10); 7691 } 7692 7693 if (mac->mac_fw.pcm.fw) { 7694 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7695 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7696 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7697 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7698 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7699 sizeof(struct bwn_fwhdr)); i++) { 7700 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7701 DELAY(10); 7702 } 7703 } 7704 7705 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7706 BWN_WRITE_4(mac, BWN_MACCTL, 7707 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7708 BWN_MACCTL_MCODE_RUN); 7709 7710 for (i = 0; i < 21; i++) { 7711 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7712 break; 7713 if (i >= 20) { 7714 device_printf(sc->sc_dev, "ucode timeout\n"); 7715 error = ENXIO; 7716 goto error; 7717 } 7718 DELAY(50000); 7719 } 7720 BWN_READ_4(mac, BWN_INTR_REASON); 7721 7722 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7723 if (mac->mac_fw.rev <= 0x128) { 7724 device_printf(sc->sc_dev, "the firmware is too old\n"); 7725 error = EOPNOTSUPP; 7726 goto error; 7727 } 7728 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7729 BWN_SHARED_UCODE_PATCH); 7730 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7731 mac->mac_fw.opensource = (date == 0xffff); 7732 if (bwn_wme != 0) 7733 mac->mac_flags |= BWN_MAC_FLAG_WME; 7734 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7735 7736 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7737 if (mac->mac_fw.opensource == 0) { 7738 device_printf(sc->sc_dev, 7739 "firmware version (rev %u patch %u date %#x time %#x)\n", 7740 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7741 if (mac->mac_fw.no_pcmfile) 7742 device_printf(sc->sc_dev, 7743 "no HW crypto acceleration due to pcm5\n"); 7744 } else { 7745 mac->mac_fw.patch = time; 7746 fwcaps = bwn_fwcaps_read(mac); 7747 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7748 device_printf(sc->sc_dev, 7749 "disabling HW crypto acceleration\n"); 7750 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7751 } 7752 if (!(fwcaps & BWN_FWCAPS_WME)) { 7753 device_printf(sc->sc_dev, "disabling WME support\n"); 7754 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7755 } 7756 } 7757 7758 if (BWN_ISOLDFMT(mac)) 7759 device_printf(sc->sc_dev, "using old firmware image\n"); 7760 7761 return (0); 7762 7763 error: 7764 BWN_WRITE_4(mac, BWN_MACCTL, 7765 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7766 BWN_MACCTL_MCODE_JMP0); 7767 7768 return (error); 7769 #undef GETFWSIZE 7770 #undef GETFWOFFSET 7771 } 7772 7773 /* OpenFirmware only */ 7774 static uint16_t 7775 bwn_fwcaps_read(struct bwn_mac *mac) 7776 { 7777 7778 KASSERT(mac->mac_fw.opensource == 1, 7779 ("%s:%d: fail", __func__, __LINE__)); 7780 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7781 } 7782 7783 static int 7784 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7785 size_t count, size_t array_size) 7786 { 7787 #define GET_NEXTIV16(iv) \ 7788 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7789 sizeof(uint16_t) + sizeof(uint16_t))) 7790 #define GET_NEXTIV32(iv) \ 7791 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7792 sizeof(uint16_t) + sizeof(uint32_t))) 7793 struct bwn_softc *sc = mac->mac_sc; 7794 const struct bwn_fwinitvals *iv; 7795 uint16_t offset; 7796 size_t i; 7797 uint8_t bit32; 7798 7799 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7800 ("%s:%d: fail", __func__, __LINE__)); 7801 iv = ivals; 7802 for (i = 0; i < count; i++) { 7803 if (array_size < sizeof(iv->offset_size)) 7804 goto fail; 7805 array_size -= sizeof(iv->offset_size); 7806 offset = be16toh(iv->offset_size); 7807 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7808 offset &= BWN_FWINITVALS_OFFSET_MASK; 7809 if (offset >= 0x1000) 7810 goto fail; 7811 if (bit32) { 7812 if (array_size < sizeof(iv->data.d32)) 7813 goto fail; 7814 array_size -= sizeof(iv->data.d32); 7815 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7816 iv = GET_NEXTIV32(iv); 7817 } else { 7818 7819 if (array_size < sizeof(iv->data.d16)) 7820 goto fail; 7821 array_size -= sizeof(iv->data.d16); 7822 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7823 7824 iv = GET_NEXTIV16(iv); 7825 } 7826 } 7827 if (array_size != 0) 7828 goto fail; 7829 return (0); 7830 fail: 7831 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7832 return (EPROTO); 7833 #undef GET_NEXTIV16 7834 #undef GET_NEXTIV32 7835 } 7836 7837 static int 7838 bwn_switch_channel(struct bwn_mac *mac, int chan) 7839 { 7840 struct bwn_phy *phy = &(mac->mac_phy); 7841 struct bwn_softc *sc = mac->mac_sc; 7842 struct ieee80211com *ic = &sc->sc_ic; 7843 uint16_t channelcookie, savedcookie; 7844 int error; 7845 7846 if (chan == 0xffff) 7847 chan = phy->get_default_chan(mac); 7848 7849 channelcookie = chan; 7850 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7851 channelcookie |= 0x100; 7852 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7853 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7854 error = phy->switch_channel(mac, chan); 7855 if (error) 7856 goto fail; 7857 7858 mac->mac_phy.chan = chan; 7859 DELAY(8000); 7860 return (0); 7861 fail: 7862 device_printf(sc->sc_dev, "failed to switch channel\n"); 7863 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7864 return (error); 7865 } 7866 7867 static uint16_t 7868 bwn_ant2phy(int antenna) 7869 { 7870 7871 switch (antenna) { 7872 case BWN_ANT0: 7873 return (BWN_TX_PHY_ANT0); 7874 case BWN_ANT1: 7875 return (BWN_TX_PHY_ANT1); 7876 case BWN_ANT2: 7877 return (BWN_TX_PHY_ANT2); 7878 case BWN_ANT3: 7879 return (BWN_TX_PHY_ANT3); 7880 case BWN_ANTAUTO: 7881 return (BWN_TX_PHY_ANT01AUTO); 7882 } 7883 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7884 return (0); 7885 } 7886 7887 static void 7888 bwn_wme_load(struct bwn_mac *mac) 7889 { 7890 struct bwn_softc *sc = mac->mac_sc; 7891 int i; 7892 7893 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7894 ("%s:%d: fail", __func__, __LINE__)); 7895 7896 bwn_mac_suspend(mac); 7897 for (i = 0; i < N(sc->sc_wmeParams); i++) 7898 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 7899 bwn_wme_shm_offsets[i]); 7900 bwn_mac_enable(mac); 7901 } 7902 7903 static void 7904 bwn_wme_loadparams(struct bwn_mac *mac, 7905 const struct wmeParams *p, uint16_t shm_offset) 7906 { 7907 #define SM(_v, _f) (((_v) << _f##_S) & _f) 7908 struct bwn_softc *sc = mac->mac_sc; 7909 uint16_t params[BWN_NR_WMEPARAMS]; 7910 int slot, tmp; 7911 unsigned int i; 7912 7913 slot = BWN_READ_2(mac, BWN_RNG) & 7914 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7915 7916 memset(¶ms, 0, sizeof(params)); 7917 7918 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 7919 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 7920 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 7921 7922 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 7923 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7924 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 7925 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7926 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 7927 params[BWN_WMEPARAM_BSLOTS] = slot; 7928 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 7929 7930 for (i = 0; i < N(params); i++) { 7931 if (i == BWN_WMEPARAM_STATUS) { 7932 tmp = bwn_shm_read_2(mac, BWN_SHARED, 7933 shm_offset + (i * 2)); 7934 tmp |= 0x100; 7935 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7936 tmp); 7937 } else { 7938 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7939 params[i]); 7940 } 7941 } 7942 } 7943 7944 static void 7945 bwn_mac_write_bssid(struct bwn_mac *mac) 7946 { 7947 struct bwn_softc *sc = mac->mac_sc; 7948 uint32_t tmp; 7949 int i; 7950 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 7951 7952 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 7953 memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN); 7954 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 7955 IEEE80211_ADDR_LEN); 7956 7957 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 7958 tmp = (uint32_t) (mac_bssid[i + 0]); 7959 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 7960 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 7961 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 7962 bwn_ram_write(mac, 0x20 + i, tmp); 7963 } 7964 } 7965 7966 static void 7967 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 7968 const uint8_t *macaddr) 7969 { 7970 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 7971 uint16_t data; 7972 7973 if (!mac) 7974 macaddr = zero; 7975 7976 offset |= 0x0020; 7977 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 7978 7979 data = macaddr[0]; 7980 data |= macaddr[1] << 8; 7981 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7982 data = macaddr[2]; 7983 data |= macaddr[3] << 8; 7984 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7985 data = macaddr[4]; 7986 data |= macaddr[5] << 8; 7987 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7988 } 7989 7990 static void 7991 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 7992 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 7993 { 7994 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 7995 uint8_t per_sta_keys_start = 8; 7996 7997 if (BWN_SEC_NEWAPI(mac)) 7998 per_sta_keys_start = 4; 7999 8000 KASSERT(index < mac->mac_max_nr_keys, 8001 ("%s:%d: fail", __func__, __LINE__)); 8002 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8003 ("%s:%d: fail", __func__, __LINE__)); 8004 8005 if (index >= per_sta_keys_start) 8006 bwn_key_macwrite(mac, index, NULL); 8007 if (key) 8008 memcpy(buf, key, key_len); 8009 bwn_key_write(mac, index, algorithm, buf); 8010 if (index >= per_sta_keys_start) 8011 bwn_key_macwrite(mac, index, mac_addr); 8012 8013 mac->mac_key[index].algorithm = algorithm; 8014 } 8015 8016 static void 8017 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8018 { 8019 struct bwn_softc *sc = mac->mac_sc; 8020 uint32_t addrtmp[2] = { 0, 0 }; 8021 uint8_t start = 8; 8022 8023 if (BWN_SEC_NEWAPI(mac)) 8024 start = 4; 8025 8026 KASSERT(index >= start, 8027 ("%s:%d: fail", __func__, __LINE__)); 8028 index -= start; 8029 8030 if (addr) { 8031 addrtmp[0] = addr[0]; 8032 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8033 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8034 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8035 addrtmp[1] = addr[4]; 8036 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8037 } 8038 8039 if (siba_get_revid(sc->sc_dev) >= 5) { 8040 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8041 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8042 } else { 8043 if (index >= 8) { 8044 bwn_shm_write_4(mac, BWN_SHARED, 8045 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8046 bwn_shm_write_2(mac, BWN_SHARED, 8047 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8048 } 8049 } 8050 } 8051 8052 static void 8053 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8054 const uint8_t *key) 8055 { 8056 unsigned int i; 8057 uint32_t offset; 8058 uint16_t kidx, value; 8059 8060 kidx = BWN_SEC_KEY2FW(mac, index); 8061 bwn_shm_write_2(mac, BWN_SHARED, 8062 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8063 8064 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8065 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8066 value = key[i]; 8067 value |= (uint16_t)(key[i + 1]) << 8; 8068 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8069 } 8070 } 8071 8072 static void 8073 bwn_phy_exit(struct bwn_mac *mac) 8074 { 8075 8076 mac->mac_phy.rf_onoff(mac, 0); 8077 if (mac->mac_phy.exit != NULL) 8078 mac->mac_phy.exit(mac); 8079 } 8080 8081 static void 8082 bwn_dma_free(struct bwn_mac *mac) 8083 { 8084 struct bwn_dma *dma; 8085 8086 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8087 return; 8088 dma = &mac->mac_method.dma; 8089 8090 bwn_dma_ringfree(&dma->rx); 8091 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8092 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8093 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8094 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8095 bwn_dma_ringfree(&dma->mcast); 8096 } 8097 8098 static void 8099 bwn_core_stop(struct bwn_mac *mac) 8100 { 8101 struct bwn_softc *sc = mac->mac_sc; 8102 8103 BWN_ASSERT_LOCKED(sc); 8104 8105 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8106 return; 8107 8108 callout_stop(&sc->sc_rfswitch_ch); 8109 callout_stop(&sc->sc_task_ch); 8110 callout_stop(&sc->sc_watchdog_ch); 8111 sc->sc_watchdog_timer = 0; 8112 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8113 BWN_READ_4(mac, BWN_INTR_MASK); 8114 bwn_mac_suspend(mac); 8115 8116 mac->mac_status = BWN_MAC_STATUS_INITED; 8117 } 8118 8119 static int 8120 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8121 { 8122 struct bwn_mac *up_dev = NULL; 8123 struct bwn_mac *down_dev; 8124 struct bwn_mac *mac; 8125 int err, status; 8126 uint8_t gmode; 8127 8128 BWN_ASSERT_LOCKED(sc); 8129 8130 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8131 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8132 mac->mac_phy.supports_2ghz) { 8133 up_dev = mac; 8134 gmode = 1; 8135 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8136 mac->mac_phy.supports_5ghz) { 8137 up_dev = mac; 8138 gmode = 0; 8139 } else { 8140 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8141 return (EINVAL); 8142 } 8143 if (up_dev != NULL) 8144 break; 8145 } 8146 if (up_dev == NULL) { 8147 device_printf(sc->sc_dev, "Could not find a device\n"); 8148 return (ENODEV); 8149 } 8150 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8151 return (0); 8152 8153 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8154 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8155 8156 down_dev = sc->sc_curmac; 8157 status = down_dev->mac_status; 8158 if (status >= BWN_MAC_STATUS_STARTED) 8159 bwn_core_stop(down_dev); 8160 if (status >= BWN_MAC_STATUS_INITED) 8161 bwn_core_exit(down_dev); 8162 8163 if (down_dev != up_dev) 8164 bwn_phy_reset(down_dev); 8165 8166 up_dev->mac_phy.gmode = gmode; 8167 if (status >= BWN_MAC_STATUS_INITED) { 8168 err = bwn_core_init(up_dev); 8169 if (err) { 8170 device_printf(sc->sc_dev, 8171 "fatal: failed to initialize for %s-GHz\n", 8172 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8173 goto fail; 8174 } 8175 } 8176 if (status >= BWN_MAC_STATUS_STARTED) 8177 bwn_core_start(up_dev); 8178 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8179 sc->sc_curmac = up_dev; 8180 8181 return (0); 8182 fail: 8183 sc->sc_curmac = NULL; 8184 return (err); 8185 } 8186 8187 static void 8188 bwn_rf_turnon(struct bwn_mac *mac) 8189 { 8190 8191 bwn_mac_suspend(mac); 8192 mac->mac_phy.rf_onoff(mac, 1); 8193 mac->mac_phy.rf_on = 1; 8194 bwn_mac_enable(mac); 8195 } 8196 8197 static void 8198 bwn_rf_turnoff(struct bwn_mac *mac) 8199 { 8200 8201 bwn_mac_suspend(mac); 8202 mac->mac_phy.rf_onoff(mac, 0); 8203 mac->mac_phy.rf_on = 0; 8204 bwn_mac_enable(mac); 8205 } 8206 8207 static void 8208 bwn_phy_reset(struct bwn_mac *mac) 8209 { 8210 struct bwn_softc *sc = mac->mac_sc; 8211 8212 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8213 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8214 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8215 DELAY(1000); 8216 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8217 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8218 BWN_TGSLOW_PHYRESET); 8219 DELAY(1000); 8220 } 8221 8222 static int 8223 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8224 { 8225 struct bwn_vap *bvp = BWN_VAP(vap); 8226 struct ieee80211com *ic= vap->iv_ic; 8227 enum ieee80211_state ostate = vap->iv_state; 8228 struct bwn_softc *sc = ic->ic_softc; 8229 struct bwn_mac *mac = sc->sc_curmac; 8230 int error; 8231 8232 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8233 ieee80211_state_name[vap->iv_state], 8234 ieee80211_state_name[nstate]); 8235 8236 error = bvp->bv_newstate(vap, nstate, arg); 8237 if (error != 0) 8238 return (error); 8239 8240 BWN_LOCK(sc); 8241 8242 bwn_led_newstate(mac, nstate); 8243 8244 /* 8245 * Clear the BSSID when we stop a STA 8246 */ 8247 if (vap->iv_opmode == IEEE80211_M_STA) { 8248 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8249 /* 8250 * Clear out the BSSID. If we reassociate to 8251 * the same AP, this will reinialize things 8252 * correctly... 8253 */ 8254 if (ic->ic_opmode == IEEE80211_M_STA && 8255 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8256 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8257 bwn_set_macaddr(mac); 8258 } 8259 } 8260 } 8261 8262 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8263 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8264 /* XXX nothing to do? */ 8265 } else if (nstate == IEEE80211_S_RUN) { 8266 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8267 bwn_set_opmode(mac); 8268 bwn_set_pretbtt(mac); 8269 bwn_spu_setdelay(mac, 0); 8270 bwn_set_macaddr(mac); 8271 } 8272 8273 BWN_UNLOCK(sc); 8274 8275 return (error); 8276 } 8277 8278 static void 8279 bwn_set_pretbtt(struct bwn_mac *mac) 8280 { 8281 struct bwn_softc *sc = mac->mac_sc; 8282 struct ieee80211com *ic = &sc->sc_ic; 8283 uint16_t pretbtt; 8284 8285 if (ic->ic_opmode == IEEE80211_M_IBSS) 8286 pretbtt = 2; 8287 else 8288 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8289 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8290 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8291 } 8292 8293 static int 8294 bwn_intr(void *arg) 8295 { 8296 struct bwn_mac *mac = arg; 8297 struct bwn_softc *sc = mac->mac_sc; 8298 uint32_t reason; 8299 8300 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8301 (sc->sc_flags & BWN_FLAG_INVALID)) 8302 return (FILTER_STRAY); 8303 8304 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8305 if (reason == 0xffffffff) /* shared IRQ */ 8306 return (FILTER_STRAY); 8307 reason &= mac->mac_intr_mask; 8308 if (reason == 0) 8309 return (FILTER_HANDLED); 8310 8311 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8312 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8313 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8314 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8315 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8316 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8317 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8318 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8319 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8320 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8321 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8322 8323 /* Disable interrupts. */ 8324 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8325 8326 mac->mac_reason_intr = reason; 8327 8328 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8329 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8330 8331 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask); 8332 return (FILTER_HANDLED); 8333 } 8334 8335 static void 8336 bwn_intrtask(void *arg, int npending) 8337 { 8338 struct bwn_mac *mac = arg; 8339 struct bwn_softc *sc = mac->mac_sc; 8340 uint32_t merged = 0; 8341 int i, tx = 0, rx = 0; 8342 8343 BWN_LOCK(sc); 8344 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8345 (sc->sc_flags & BWN_FLAG_INVALID)) { 8346 BWN_UNLOCK(sc); 8347 return; 8348 } 8349 8350 for (i = 0; i < N(mac->mac_reason); i++) 8351 merged |= mac->mac_reason[i]; 8352 8353 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8354 device_printf(sc->sc_dev, "MAC trans error\n"); 8355 8356 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8357 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8358 mac->mac_phy.txerrors--; 8359 if (mac->mac_phy.txerrors == 0) { 8360 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8361 bwn_restart(mac, "PHY TX errors"); 8362 } 8363 } 8364 8365 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8366 if (merged & BWN_DMAINTR_FATALMASK) { 8367 device_printf(sc->sc_dev, 8368 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8369 mac->mac_reason[0], mac->mac_reason[1], 8370 mac->mac_reason[2], mac->mac_reason[3], 8371 mac->mac_reason[4], mac->mac_reason[5]); 8372 bwn_restart(mac, "DMA error"); 8373 BWN_UNLOCK(sc); 8374 return; 8375 } 8376 if (merged & BWN_DMAINTR_NONFATALMASK) { 8377 device_printf(sc->sc_dev, 8378 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8379 mac->mac_reason[0], mac->mac_reason[1], 8380 mac->mac_reason[2], mac->mac_reason[3], 8381 mac->mac_reason[4], mac->mac_reason[5]); 8382 } 8383 } 8384 8385 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8386 bwn_intr_ucode_debug(mac); 8387 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8388 bwn_intr_tbtt_indication(mac); 8389 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8390 bwn_intr_atim_end(mac); 8391 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8392 bwn_intr_beacon(mac); 8393 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8394 bwn_intr_pmq(mac); 8395 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8396 bwn_intr_noise(mac); 8397 8398 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8399 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8400 bwn_dma_rx(mac->mac_method.dma.rx); 8401 rx = 1; 8402 } 8403 } else 8404 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8405 8406 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8407 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8408 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8409 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8410 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8411 8412 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8413 bwn_intr_txeof(mac); 8414 tx = 1; 8415 } 8416 8417 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8418 8419 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8420 int evt = BWN_LED_EVENT_NONE; 8421 8422 if (tx && rx) { 8423 if (sc->sc_rx_rate > sc->sc_tx_rate) 8424 evt = BWN_LED_EVENT_RX; 8425 else 8426 evt = BWN_LED_EVENT_TX; 8427 } else if (tx) { 8428 evt = BWN_LED_EVENT_TX; 8429 } else if (rx) { 8430 evt = BWN_LED_EVENT_RX; 8431 } else if (rx == 0) { 8432 evt = BWN_LED_EVENT_POLL; 8433 } 8434 8435 if (evt != BWN_LED_EVENT_NONE) 8436 bwn_led_event(mac, evt); 8437 } 8438 8439 if (mbufq_first(&sc->sc_snd) != NULL) 8440 bwn_start(sc); 8441 8442 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8443 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8444 8445 BWN_UNLOCK(sc); 8446 } 8447 8448 static void 8449 bwn_restart(struct bwn_mac *mac, const char *msg) 8450 { 8451 struct bwn_softc *sc = mac->mac_sc; 8452 struct ieee80211com *ic = &sc->sc_ic; 8453 8454 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8455 return; 8456 8457 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8458 ieee80211_runtask(ic, &mac->mac_hwreset); 8459 } 8460 8461 static void 8462 bwn_intr_ucode_debug(struct bwn_mac *mac) 8463 { 8464 struct bwn_softc *sc = mac->mac_sc; 8465 uint16_t reason; 8466 8467 if (mac->mac_fw.opensource == 0) 8468 return; 8469 8470 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8471 switch (reason) { 8472 case BWN_DEBUGINTR_PANIC: 8473 bwn_handle_fwpanic(mac); 8474 break; 8475 case BWN_DEBUGINTR_DUMP_SHM: 8476 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8477 break; 8478 case BWN_DEBUGINTR_DUMP_REGS: 8479 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8480 break; 8481 case BWN_DEBUGINTR_MARKER: 8482 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8483 break; 8484 default: 8485 device_printf(sc->sc_dev, 8486 "ucode debug unknown reason: %#x\n", reason); 8487 } 8488 8489 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8490 BWN_DEBUGINTR_ACK); 8491 } 8492 8493 static void 8494 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8495 { 8496 struct bwn_softc *sc = mac->mac_sc; 8497 struct ieee80211com *ic = &sc->sc_ic; 8498 8499 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8500 bwn_psctl(mac, 0); 8501 if (ic->ic_opmode == IEEE80211_M_IBSS) 8502 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8503 } 8504 8505 static void 8506 bwn_intr_atim_end(struct bwn_mac *mac) 8507 { 8508 8509 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8510 BWN_WRITE_4(mac, BWN_MACCMD, 8511 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8512 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8513 } 8514 } 8515 8516 static void 8517 bwn_intr_beacon(struct bwn_mac *mac) 8518 { 8519 struct bwn_softc *sc = mac->mac_sc; 8520 struct ieee80211com *ic = &sc->sc_ic; 8521 uint32_t cmd, beacon0, beacon1; 8522 8523 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8524 ic->ic_opmode == IEEE80211_M_MBSS) 8525 return; 8526 8527 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8528 8529 cmd = BWN_READ_4(mac, BWN_MACCMD); 8530 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8531 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8532 8533 if (beacon0 && beacon1) { 8534 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8535 mac->mac_intr_mask |= BWN_INTR_BEACON; 8536 return; 8537 } 8538 8539 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8540 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8541 bwn_load_beacon0(mac); 8542 bwn_load_beacon1(mac); 8543 cmd = BWN_READ_4(mac, BWN_MACCMD); 8544 cmd |= BWN_MACCMD_BEACON0_VALID; 8545 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8546 } else { 8547 if (!beacon0) { 8548 bwn_load_beacon0(mac); 8549 cmd = BWN_READ_4(mac, BWN_MACCMD); 8550 cmd |= BWN_MACCMD_BEACON0_VALID; 8551 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8552 } else if (!beacon1) { 8553 bwn_load_beacon1(mac); 8554 cmd = BWN_READ_4(mac, BWN_MACCMD); 8555 cmd |= BWN_MACCMD_BEACON1_VALID; 8556 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8557 } 8558 } 8559 } 8560 8561 static void 8562 bwn_intr_pmq(struct bwn_mac *mac) 8563 { 8564 uint32_t tmp; 8565 8566 while (1) { 8567 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8568 if (!(tmp & 0x00000008)) 8569 break; 8570 } 8571 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8572 } 8573 8574 static void 8575 bwn_intr_noise(struct bwn_mac *mac) 8576 { 8577 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8578 uint16_t tmp; 8579 uint8_t noise[4]; 8580 uint8_t i, j; 8581 int32_t average; 8582 8583 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8584 return; 8585 8586 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8587 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8588 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8589 noise[3] == 0x7f) 8590 goto new; 8591 8592 KASSERT(mac->mac_noise.noi_nsamples < 8, 8593 ("%s:%d: fail", __func__, __LINE__)); 8594 i = mac->mac_noise.noi_nsamples; 8595 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8596 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8597 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8598 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8599 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8600 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8601 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8602 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8603 mac->mac_noise.noi_nsamples++; 8604 if (mac->mac_noise.noi_nsamples == 8) { 8605 average = 0; 8606 for (i = 0; i < 8; i++) { 8607 for (j = 0; j < 4; j++) 8608 average += mac->mac_noise.noi_samples[i][j]; 8609 } 8610 average = (((average / 32) * 125) + 64) / 128; 8611 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8612 if (tmp >= 8) 8613 average += 2; 8614 else 8615 average -= 25; 8616 average -= (tmp == 8) ? 72 : 48; 8617 8618 mac->mac_stats.link_noise = average; 8619 mac->mac_noise.noi_running = 0; 8620 return; 8621 } 8622 new: 8623 bwn_noise_gensample(mac); 8624 } 8625 8626 static int 8627 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8628 { 8629 struct bwn_mac *mac = prq->prq_mac; 8630 struct bwn_softc *sc = mac->mac_sc; 8631 unsigned int i; 8632 8633 BWN_ASSERT_LOCKED(sc); 8634 8635 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8636 return (0); 8637 8638 for (i = 0; i < 5000; i++) { 8639 if (bwn_pio_rxeof(prq) == 0) 8640 break; 8641 } 8642 if (i >= 5000) 8643 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8644 return ((i > 0) ? 1 : 0); 8645 } 8646 8647 static void 8648 bwn_dma_rx(struct bwn_dma_ring *dr) 8649 { 8650 int slot, curslot; 8651 8652 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8653 curslot = dr->get_curslot(dr); 8654 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8655 ("%s:%d: fail", __func__, __LINE__)); 8656 8657 slot = dr->dr_curslot; 8658 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8659 bwn_dma_rxeof(dr, &slot); 8660 8661 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8662 BUS_DMASYNC_PREWRITE); 8663 8664 dr->set_curslot(dr, slot); 8665 dr->dr_curslot = slot; 8666 } 8667 8668 static void 8669 bwn_intr_txeof(struct bwn_mac *mac) 8670 { 8671 struct bwn_txstatus stat; 8672 uint32_t stat0, stat1; 8673 uint16_t tmp; 8674 8675 BWN_ASSERT_LOCKED(mac->mac_sc); 8676 8677 while (1) { 8678 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8679 if (!(stat0 & 0x00000001)) 8680 break; 8681 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8682 8683 stat.cookie = (stat0 >> 16); 8684 stat.seq = (stat1 & 0x0000ffff); 8685 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8686 tmp = (stat0 & 0x0000ffff); 8687 stat.framecnt = ((tmp & 0xf000) >> 12); 8688 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8689 stat.sreason = ((tmp & 0x001c) >> 2); 8690 stat.pm = (tmp & 0x0080) ? 1 : 0; 8691 stat.im = (tmp & 0x0040) ? 1 : 0; 8692 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8693 stat.ack = (tmp & 0x0002) ? 1 : 0; 8694 8695 bwn_handle_txeof(mac, &stat); 8696 } 8697 } 8698 8699 static void 8700 bwn_hwreset(void *arg, int npending) 8701 { 8702 struct bwn_mac *mac = arg; 8703 struct bwn_softc *sc = mac->mac_sc; 8704 int error = 0; 8705 int prev_status; 8706 8707 BWN_LOCK(sc); 8708 8709 prev_status = mac->mac_status; 8710 if (prev_status >= BWN_MAC_STATUS_STARTED) 8711 bwn_core_stop(mac); 8712 if (prev_status >= BWN_MAC_STATUS_INITED) 8713 bwn_core_exit(mac); 8714 8715 if (prev_status >= BWN_MAC_STATUS_INITED) { 8716 error = bwn_core_init(mac); 8717 if (error) 8718 goto out; 8719 } 8720 if (prev_status >= BWN_MAC_STATUS_STARTED) 8721 bwn_core_start(mac); 8722 out: 8723 if (error) { 8724 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8725 sc->sc_curmac = NULL; 8726 } 8727 BWN_UNLOCK(sc); 8728 } 8729 8730 static void 8731 bwn_handle_fwpanic(struct bwn_mac *mac) 8732 { 8733 struct bwn_softc *sc = mac->mac_sc; 8734 uint16_t reason; 8735 8736 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8737 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8738 8739 if (reason == BWN_FWPANIC_RESTART) 8740 bwn_restart(mac, "ucode panic"); 8741 } 8742 8743 static void 8744 bwn_load_beacon0(struct bwn_mac *mac) 8745 { 8746 8747 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8748 } 8749 8750 static void 8751 bwn_load_beacon1(struct bwn_mac *mac) 8752 { 8753 8754 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8755 } 8756 8757 static uint32_t 8758 bwn_jssi_read(struct bwn_mac *mac) 8759 { 8760 uint32_t val = 0; 8761 8762 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8763 val <<= 16; 8764 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8765 8766 return (val); 8767 } 8768 8769 static void 8770 bwn_noise_gensample(struct bwn_mac *mac) 8771 { 8772 uint32_t jssi = 0x7f7f7f7f; 8773 8774 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8775 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8776 BWN_WRITE_4(mac, BWN_MACCMD, 8777 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8778 } 8779 8780 static int 8781 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8782 { 8783 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8784 8785 return (dr->dr_numslots - dr->dr_usedslot); 8786 } 8787 8788 static int 8789 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8790 { 8791 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8792 8793 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8794 ("%s:%d: fail", __func__, __LINE__)); 8795 if (slot == dr->dr_numslots - 1) 8796 return (0); 8797 return (slot + 1); 8798 } 8799 8800 static void 8801 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8802 { 8803 struct bwn_mac *mac = dr->dr_mac; 8804 struct bwn_softc *sc = mac->mac_sc; 8805 struct bwn_dma *dma = &mac->mac_method.dma; 8806 struct bwn_dmadesc_generic *desc; 8807 struct bwn_dmadesc_meta *meta; 8808 struct bwn_rxhdr4 *rxhdr; 8809 struct mbuf *m; 8810 uint32_t macstat; 8811 int32_t tmp; 8812 int cnt = 0; 8813 uint16_t len; 8814 8815 dr->getdesc(dr, *slot, &desc, &meta); 8816 8817 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8818 m = meta->mt_m; 8819 8820 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8821 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 8822 return; 8823 } 8824 8825 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8826 len = le16toh(rxhdr->frame_len); 8827 if (len <= 0) { 8828 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 8829 return; 8830 } 8831 if (bwn_dma_check_redzone(dr, m)) { 8832 device_printf(sc->sc_dev, "redzone error.\n"); 8833 bwn_dma_set_redzone(dr, m); 8834 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8835 BUS_DMASYNC_PREWRITE); 8836 return; 8837 } 8838 if (len > dr->dr_rx_bufsize) { 8839 tmp = len; 8840 while (1) { 8841 dr->getdesc(dr, *slot, &desc, &meta); 8842 bwn_dma_set_redzone(dr, meta->mt_m); 8843 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8844 BUS_DMASYNC_PREWRITE); 8845 *slot = bwn_dma_nextslot(dr, *slot); 8846 cnt++; 8847 tmp -= dr->dr_rx_bufsize; 8848 if (tmp <= 0) 8849 break; 8850 } 8851 device_printf(sc->sc_dev, "too small buffer " 8852 "(len %u buffer %u dropped %d)\n", 8853 len, dr->dr_rx_bufsize, cnt); 8854 return; 8855 } 8856 macstat = le32toh(rxhdr->mac_status); 8857 if (macstat & BWN_RX_MAC_FCSERR) { 8858 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8859 device_printf(sc->sc_dev, "RX drop\n"); 8860 return; 8861 } 8862 } 8863 8864 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8865 m_adj(m, dr->dr_frameoffset); 8866 8867 bwn_rxeof(dr->dr_mac, m, rxhdr); 8868 } 8869 8870 static void 8871 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8872 { 8873 struct bwn_dma_ring *dr; 8874 struct bwn_dmadesc_generic *desc; 8875 struct bwn_dmadesc_meta *meta; 8876 struct bwn_pio_txqueue *tq; 8877 struct bwn_pio_txpkt *tp = NULL; 8878 struct bwn_softc *sc = mac->mac_sc; 8879 struct bwn_stats *stats = &mac->mac_stats; 8880 struct ieee80211_node *ni; 8881 struct ieee80211vap *vap; 8882 int retrycnt = 0, slot; 8883 8884 BWN_ASSERT_LOCKED(mac->mac_sc); 8885 8886 if (status->im) 8887 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8888 if (status->ampdu) 8889 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8890 if (status->rtscnt) { 8891 if (status->rtscnt == 0xf) 8892 stats->rtsfail++; 8893 else 8894 stats->rts++; 8895 } 8896 8897 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8898 if (status->ack) { 8899 dr = bwn_dma_parse_cookie(mac, status, 8900 status->cookie, &slot); 8901 if (dr == NULL) { 8902 device_printf(sc->sc_dev, 8903 "failed to parse cookie\n"); 8904 return; 8905 } 8906 while (1) { 8907 dr->getdesc(dr, slot, &desc, &meta); 8908 if (meta->mt_islast) { 8909 ni = meta->mt_ni; 8910 vap = ni->ni_vap; 8911 ieee80211_ratectl_tx_complete(vap, ni, 8912 status->ack ? 8913 IEEE80211_RATECTL_TX_SUCCESS : 8914 IEEE80211_RATECTL_TX_FAILURE, 8915 &retrycnt, 0); 8916 break; 8917 } 8918 slot = bwn_dma_nextslot(dr, slot); 8919 } 8920 } 8921 bwn_dma_handle_txeof(mac, status); 8922 } else { 8923 if (status->ack) { 8924 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 8925 if (tq == NULL) { 8926 device_printf(sc->sc_dev, 8927 "failed to parse cookie\n"); 8928 return; 8929 } 8930 ni = tp->tp_ni; 8931 vap = ni->ni_vap; 8932 ieee80211_ratectl_tx_complete(vap, ni, 8933 status->ack ? 8934 IEEE80211_RATECTL_TX_SUCCESS : 8935 IEEE80211_RATECTL_TX_FAILURE, 8936 &retrycnt, 0); 8937 } 8938 bwn_pio_handle_txeof(mac, status); 8939 } 8940 8941 bwn_phy_txpower_check(mac, 0); 8942 } 8943 8944 static uint8_t 8945 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 8946 { 8947 struct bwn_mac *mac = prq->prq_mac; 8948 struct bwn_softc *sc = mac->mac_sc; 8949 struct bwn_rxhdr4 rxhdr; 8950 struct mbuf *m; 8951 uint32_t ctl32, macstat, v32; 8952 unsigned int i, padding; 8953 uint16_t ctl16, len, totlen, v16; 8954 unsigned char *mp; 8955 char *data; 8956 8957 memset(&rxhdr, 0, sizeof(rxhdr)); 8958 8959 if (prq->prq_rev >= 8) { 8960 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8961 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 8962 return (0); 8963 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 8964 BWN_PIO8_RXCTL_FRAMEREADY); 8965 for (i = 0; i < 10; i++) { 8966 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8967 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 8968 goto ready; 8969 DELAY(10); 8970 } 8971 } else { 8972 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8973 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 8974 return (0); 8975 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 8976 BWN_PIO_RXCTL_FRAMEREADY); 8977 for (i = 0; i < 10; i++) { 8978 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8979 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 8980 goto ready; 8981 DELAY(10); 8982 } 8983 } 8984 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 8985 return (1); 8986 ready: 8987 if (prq->prq_rev >= 8) 8988 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8989 prq->prq_base + BWN_PIO8_RXDATA); 8990 else 8991 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8992 prq->prq_base + BWN_PIO_RXDATA); 8993 len = le16toh(rxhdr.frame_len); 8994 if (len > 0x700) { 8995 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 8996 goto error; 8997 } 8998 if (len == 0) { 8999 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9000 goto error; 9001 } 9002 9003 macstat = le32toh(rxhdr.mac_status); 9004 if (macstat & BWN_RX_MAC_FCSERR) { 9005 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9006 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9007 goto error; 9008 } 9009 } 9010 9011 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9012 totlen = len + padding; 9013 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9014 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9015 if (m == NULL) { 9016 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9017 goto error; 9018 } 9019 mp = mtod(m, unsigned char *); 9020 if (prq->prq_rev >= 8) { 9021 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9022 prq->prq_base + BWN_PIO8_RXDATA); 9023 if (totlen & 3) { 9024 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9025 data = &(mp[totlen - 1]); 9026 switch (totlen & 3) { 9027 case 3: 9028 *data = (v32 >> 16); 9029 data--; 9030 case 2: 9031 *data = (v32 >> 8); 9032 data--; 9033 case 1: 9034 *data = v32; 9035 } 9036 } 9037 } else { 9038 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9039 prq->prq_base + BWN_PIO_RXDATA); 9040 if (totlen & 1) { 9041 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9042 mp[totlen - 1] = v16; 9043 } 9044 } 9045 9046 m->m_len = m->m_pkthdr.len = totlen; 9047 9048 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9049 9050 return (1); 9051 error: 9052 if (prq->prq_rev >= 8) 9053 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9054 BWN_PIO8_RXCTL_DATAREADY); 9055 else 9056 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9057 return (1); 9058 } 9059 9060 static int 9061 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9062 struct bwn_dmadesc_meta *meta, int init) 9063 { 9064 struct bwn_mac *mac = dr->dr_mac; 9065 struct bwn_dma *dma = &mac->mac_method.dma; 9066 struct bwn_rxhdr4 *hdr; 9067 bus_dmamap_t map; 9068 bus_addr_t paddr; 9069 struct mbuf *m; 9070 int error; 9071 9072 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9073 if (m == NULL) { 9074 error = ENOBUFS; 9075 9076 /* 9077 * If the NIC is up and running, we need to: 9078 * - Clear RX buffer's header. 9079 * - Restore RX descriptor settings. 9080 */ 9081 if (init) 9082 return (error); 9083 else 9084 goto back; 9085 } 9086 m->m_len = m->m_pkthdr.len = MCLBYTES; 9087 9088 bwn_dma_set_redzone(dr, m); 9089 9090 /* 9091 * Try to load RX buf into temporary DMA map 9092 */ 9093 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9094 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9095 if (error) { 9096 m_freem(m); 9097 9098 /* 9099 * See the comment above 9100 */ 9101 if (init) 9102 return (error); 9103 else 9104 goto back; 9105 } 9106 9107 if (!init) 9108 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9109 meta->mt_m = m; 9110 meta->mt_paddr = paddr; 9111 9112 /* 9113 * Swap RX buf's DMA map with the loaded temporary one 9114 */ 9115 map = meta->mt_dmap; 9116 meta->mt_dmap = dr->dr_spare_dmap; 9117 dr->dr_spare_dmap = map; 9118 9119 back: 9120 /* 9121 * Clear RX buf header 9122 */ 9123 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9124 bzero(hdr, sizeof(*hdr)); 9125 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9126 BUS_DMASYNC_PREWRITE); 9127 9128 /* 9129 * Setup RX buf descriptor 9130 */ 9131 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9132 sizeof(*hdr), 0, 0, 0); 9133 return (error); 9134 } 9135 9136 static void 9137 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9138 bus_size_t mapsz __unused, int error) 9139 { 9140 9141 if (!error) { 9142 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9143 *((bus_addr_t *)arg) = seg->ds_addr; 9144 } 9145 } 9146 9147 static int 9148 bwn_hwrate2ieeerate(int rate) 9149 { 9150 9151 switch (rate) { 9152 case BWN_CCK_RATE_1MB: 9153 return (2); 9154 case BWN_CCK_RATE_2MB: 9155 return (4); 9156 case BWN_CCK_RATE_5MB: 9157 return (11); 9158 case BWN_CCK_RATE_11MB: 9159 return (22); 9160 case BWN_OFDM_RATE_6MB: 9161 return (12); 9162 case BWN_OFDM_RATE_9MB: 9163 return (18); 9164 case BWN_OFDM_RATE_12MB: 9165 return (24); 9166 case BWN_OFDM_RATE_18MB: 9167 return (36); 9168 case BWN_OFDM_RATE_24MB: 9169 return (48); 9170 case BWN_OFDM_RATE_36MB: 9171 return (72); 9172 case BWN_OFDM_RATE_48MB: 9173 return (96); 9174 case BWN_OFDM_RATE_54MB: 9175 return (108); 9176 default: 9177 printf("Ooops\n"); 9178 return (0); 9179 } 9180 } 9181 9182 static void 9183 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9184 { 9185 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9186 struct bwn_plcp6 *plcp; 9187 struct bwn_softc *sc = mac->mac_sc; 9188 struct ieee80211_frame_min *wh; 9189 struct ieee80211_node *ni; 9190 struct ieee80211com *ic = &sc->sc_ic; 9191 uint32_t macstat; 9192 int padding, rate, rssi = 0, noise = 0, type; 9193 uint16_t phytype, phystat0, phystat3, chanstat; 9194 unsigned char *mp = mtod(m, unsigned char *); 9195 static int rx_mac_dec_rpt = 0; 9196 9197 BWN_ASSERT_LOCKED(sc); 9198 9199 phystat0 = le16toh(rxhdr->phy_status0); 9200 phystat3 = le16toh(rxhdr->phy_status3); 9201 macstat = le32toh(rxhdr->mac_status); 9202 chanstat = le16toh(rxhdr->channel); 9203 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9204 9205 if (macstat & BWN_RX_MAC_FCSERR) 9206 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9207 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9208 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9209 if (macstat & BWN_RX_MAC_DECERR) 9210 goto drop; 9211 9212 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9213 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9214 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9215 m->m_pkthdr.len); 9216 goto drop; 9217 } 9218 plcp = (struct bwn_plcp6 *)(mp + padding); 9219 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9220 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9221 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9222 m->m_pkthdr.len); 9223 goto drop; 9224 } 9225 wh = mtod(m, struct ieee80211_frame_min *); 9226 9227 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9228 device_printf(sc->sc_dev, 9229 "RX decryption attempted (old %d keyidx %#x)\n", 9230 BWN_ISOLDFMT(mac), 9231 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9232 9233 /* XXX calculating RSSI & noise & antenna */ 9234 9235 if (phystat0 & BWN_RX_PHYST0_OFDM) 9236 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9237 phytype == BWN_PHYTYPE_A); 9238 else 9239 rate = bwn_plcp_get_cckrate(mac, plcp); 9240 if (rate == -1) { 9241 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9242 goto drop; 9243 } 9244 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9245 9246 /* RX radio tap */ 9247 if (ieee80211_radiotap_active(ic)) 9248 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9249 m_adj(m, -IEEE80211_CRC_LEN); 9250 9251 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9252 noise = mac->mac_stats.link_noise; 9253 9254 BWN_UNLOCK(sc); 9255 9256 ni = ieee80211_find_rxnode(ic, wh); 9257 if (ni != NULL) { 9258 type = ieee80211_input(ni, m, rssi, noise); 9259 ieee80211_free_node(ni); 9260 } else 9261 type = ieee80211_input_all(ic, m, rssi, noise); 9262 9263 BWN_LOCK(sc); 9264 return; 9265 drop: 9266 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9267 } 9268 9269 static void 9270 bwn_dma_handle_txeof(struct bwn_mac *mac, 9271 const struct bwn_txstatus *status) 9272 { 9273 struct bwn_dma *dma = &mac->mac_method.dma; 9274 struct bwn_dma_ring *dr; 9275 struct bwn_dmadesc_generic *desc; 9276 struct bwn_dmadesc_meta *meta; 9277 struct bwn_softc *sc = mac->mac_sc; 9278 int slot; 9279 9280 BWN_ASSERT_LOCKED(sc); 9281 9282 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9283 if (dr == NULL) { 9284 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9285 return; 9286 } 9287 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9288 9289 while (1) { 9290 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9291 ("%s:%d: fail", __func__, __LINE__)); 9292 dr->getdesc(dr, slot, &desc, &meta); 9293 9294 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9295 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9296 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9297 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9298 9299 if (meta->mt_islast) { 9300 KASSERT(meta->mt_m != NULL, 9301 ("%s:%d: fail", __func__, __LINE__)); 9302 9303 ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0); 9304 meta->mt_ni = NULL; 9305 meta->mt_m = NULL; 9306 } else 9307 KASSERT(meta->mt_m == NULL, 9308 ("%s:%d: fail", __func__, __LINE__)); 9309 9310 dr->dr_usedslot--; 9311 if (meta->mt_islast) 9312 break; 9313 slot = bwn_dma_nextslot(dr, slot); 9314 } 9315 sc->sc_watchdog_timer = 0; 9316 if (dr->dr_stop) { 9317 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9318 ("%s:%d: fail", __func__, __LINE__)); 9319 dr->dr_stop = 0; 9320 } 9321 } 9322 9323 static void 9324 bwn_pio_handle_txeof(struct bwn_mac *mac, 9325 const struct bwn_txstatus *status) 9326 { 9327 struct bwn_pio_txqueue *tq; 9328 struct bwn_pio_txpkt *tp = NULL; 9329 struct bwn_softc *sc = mac->mac_sc; 9330 9331 BWN_ASSERT_LOCKED(sc); 9332 9333 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9334 if (tq == NULL) 9335 return; 9336 9337 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9338 tq->tq_free++; 9339 9340 if (tp->tp_ni != NULL) { 9341 /* 9342 * Do any tx complete callback. Note this must 9343 * be done before releasing the node reference. 9344 */ 9345 if (tp->tp_m->m_flags & M_TXCB) 9346 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9347 ieee80211_free_node(tp->tp_ni); 9348 tp->tp_ni = NULL; 9349 } 9350 m_freem(tp->tp_m); 9351 tp->tp_m = NULL; 9352 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9353 9354 sc->sc_watchdog_timer = 0; 9355 } 9356 9357 static void 9358 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9359 { 9360 struct bwn_softc *sc = mac->mac_sc; 9361 struct bwn_phy *phy = &mac->mac_phy; 9362 struct ieee80211com *ic = &sc->sc_ic; 9363 unsigned long now; 9364 int result; 9365 9366 BWN_GETTIME(now); 9367 9368 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9369 return; 9370 phy->nexttime = now + 2 * 1000; 9371 9372 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9373 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9374 return; 9375 9376 if (phy->recalc_txpwr != NULL) { 9377 result = phy->recalc_txpwr(mac, 9378 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9379 if (result == BWN_TXPWR_RES_DONE) 9380 return; 9381 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9382 ("%s: fail", __func__)); 9383 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9384 9385 ieee80211_runtask(ic, &mac->mac_txpower); 9386 } 9387 } 9388 9389 static uint16_t 9390 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9391 { 9392 9393 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9394 } 9395 9396 static uint32_t 9397 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9398 { 9399 9400 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9401 } 9402 9403 static void 9404 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9405 { 9406 9407 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9408 } 9409 9410 static void 9411 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9412 { 9413 9414 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9415 } 9416 9417 static int 9418 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9419 { 9420 9421 switch (rate) { 9422 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9423 case 12: 9424 return (BWN_OFDM_RATE_6MB); 9425 case 18: 9426 return (BWN_OFDM_RATE_9MB); 9427 case 24: 9428 return (BWN_OFDM_RATE_12MB); 9429 case 36: 9430 return (BWN_OFDM_RATE_18MB); 9431 case 48: 9432 return (BWN_OFDM_RATE_24MB); 9433 case 72: 9434 return (BWN_OFDM_RATE_36MB); 9435 case 96: 9436 return (BWN_OFDM_RATE_48MB); 9437 case 108: 9438 return (BWN_OFDM_RATE_54MB); 9439 /* CCK rates (NB: not IEEE std, device-specific) */ 9440 case 2: 9441 return (BWN_CCK_RATE_1MB); 9442 case 4: 9443 return (BWN_CCK_RATE_2MB); 9444 case 11: 9445 return (BWN_CCK_RATE_5MB); 9446 case 22: 9447 return (BWN_CCK_RATE_11MB); 9448 } 9449 9450 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9451 return (BWN_CCK_RATE_1MB); 9452 } 9453 9454 static int 9455 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9456 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9457 { 9458 const struct bwn_phy *phy = &mac->mac_phy; 9459 struct bwn_softc *sc = mac->mac_sc; 9460 struct ieee80211_frame *wh; 9461 struct ieee80211_frame *protwh; 9462 struct ieee80211_frame_cts *cts; 9463 struct ieee80211_frame_rts *rts; 9464 const struct ieee80211_txparam *tp; 9465 struct ieee80211vap *vap = ni->ni_vap; 9466 struct ieee80211com *ic = &sc->sc_ic; 9467 struct mbuf *mprot; 9468 unsigned int len; 9469 uint32_t macctl = 0; 9470 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9471 uint16_t phyctl = 0; 9472 uint8_t rate, rate_fb; 9473 9474 wh = mtod(m, struct ieee80211_frame *); 9475 memset(txhdr, 0, sizeof(*txhdr)); 9476 9477 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9478 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9479 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9480 9481 /* 9482 * Find TX rate 9483 */ 9484 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9485 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9486 rate = rate_fb = tp->mgmtrate; 9487 else if (ismcast) 9488 rate = rate_fb = tp->mcastrate; 9489 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9490 rate = rate_fb = tp->ucastrate; 9491 else { 9492 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9493 rate = ni->ni_txrate; 9494 9495 if (rix > 0) 9496 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9497 IEEE80211_RATE_VAL; 9498 else 9499 rate_fb = rate; 9500 } 9501 9502 sc->sc_tx_rate = rate; 9503 9504 rate = bwn_ieeerate2hwrate(sc, rate); 9505 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9506 9507 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9508 bwn_plcp_getcck(rate); 9509 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9510 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9511 9512 if ((rate_fb == rate) || 9513 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9514 (*(u_int16_t *)wh->i_dur == htole16(0))) 9515 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9516 else 9517 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9518 m->m_pkthdr.len, rate, isshort); 9519 9520 /* XXX TX encryption */ 9521 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9522 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9523 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9524 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9525 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9526 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9527 9528 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9529 BWN_TX_EFT_FB_CCK; 9530 txhdr->chan = phy->chan; 9531 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9532 BWN_TX_PHY_ENC_CCK; 9533 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9534 rate == BWN_CCK_RATE_11MB)) 9535 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9536 9537 /* XXX TX antenna selection */ 9538 9539 switch (bwn_antenna_sanitize(mac, 0)) { 9540 case 0: 9541 phyctl |= BWN_TX_PHY_ANT01AUTO; 9542 break; 9543 case 1: 9544 phyctl |= BWN_TX_PHY_ANT0; 9545 break; 9546 case 2: 9547 phyctl |= BWN_TX_PHY_ANT1; 9548 break; 9549 case 3: 9550 phyctl |= BWN_TX_PHY_ANT2; 9551 break; 9552 case 4: 9553 phyctl |= BWN_TX_PHY_ANT3; 9554 break; 9555 default: 9556 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9557 } 9558 9559 if (!ismcast) 9560 macctl |= BWN_TX_MAC_ACK; 9561 9562 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9563 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9564 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9565 macctl |= BWN_TX_MAC_LONGFRAME; 9566 9567 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9568 /* XXX RTS rate is always 1MB??? */ 9569 rts_rate = BWN_CCK_RATE_1MB; 9570 rts_rate_fb = bwn_get_fbrate(rts_rate); 9571 9572 protdur = ieee80211_compute_duration(ic->ic_rt, 9573 m->m_pkthdr.len, rate, isshort) + 9574 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9575 9576 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9577 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9578 (txhdr->body.old.rts_frame) : 9579 (txhdr->body.new.rts_frame)); 9580 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9581 protdur); 9582 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9583 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9584 mprot->m_pkthdr.len); 9585 m_freem(mprot); 9586 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9587 len = sizeof(struct ieee80211_frame_cts); 9588 } else { 9589 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9590 (txhdr->body.old.rts_frame) : 9591 (txhdr->body.new.rts_frame)); 9592 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9593 isshort); 9594 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9595 wh->i_addr2, protdur); 9596 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9597 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9598 mprot->m_pkthdr.len); 9599 m_freem(mprot); 9600 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9601 len = sizeof(struct ieee80211_frame_rts); 9602 } 9603 len += IEEE80211_CRC_LEN; 9604 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9605 &txhdr->body.old.rts_plcp : 9606 &txhdr->body.new.rts_plcp), len, rts_rate); 9607 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9608 rts_rate_fb); 9609 9610 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9611 (&txhdr->body.old.rts_frame) : 9612 (&txhdr->body.new.rts_frame)); 9613 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9614 9615 if (BWN_ISOFDMRATE(rts_rate)) { 9616 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9617 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9618 } else { 9619 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9620 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9621 } 9622 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9623 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9624 } 9625 9626 if (BWN_ISOLDFMT(mac)) 9627 txhdr->body.old.cookie = htole16(cookie); 9628 else 9629 txhdr->body.new.cookie = htole16(cookie); 9630 9631 txhdr->macctl = htole32(macctl); 9632 txhdr->phyctl = htole16(phyctl); 9633 9634 /* 9635 * TX radio tap 9636 */ 9637 if (ieee80211_radiotap_active_vap(vap)) { 9638 sc->sc_tx_th.wt_flags = 0; 9639 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9640 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9641 if (isshort && 9642 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9643 rate == BWN_CCK_RATE_11MB)) 9644 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9645 sc->sc_tx_th.wt_rate = rate; 9646 9647 ieee80211_radiotap_tx(vap, m); 9648 } 9649 9650 return (0); 9651 } 9652 9653 static void 9654 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9655 const uint8_t rate) 9656 { 9657 uint32_t d, plen; 9658 uint8_t *raw = plcp->o.raw; 9659 9660 if (BWN_ISOFDMRATE(rate)) { 9661 d = bwn_plcp_getofdm(rate); 9662 KASSERT(!(octets & 0xf000), 9663 ("%s:%d: fail", __func__, __LINE__)); 9664 d |= (octets << 5); 9665 plcp->o.data = htole32(d); 9666 } else { 9667 plen = octets * 16 / rate; 9668 if ((octets * 16 % rate) > 0) { 9669 plen++; 9670 if ((rate == BWN_CCK_RATE_11MB) 9671 && ((octets * 8 % 11) < 4)) { 9672 raw[1] = 0x84; 9673 } else 9674 raw[1] = 0x04; 9675 } else 9676 raw[1] = 0x04; 9677 plcp->o.data |= htole32(plen << 16); 9678 raw[0] = bwn_plcp_getcck(rate); 9679 } 9680 } 9681 9682 static uint8_t 9683 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9684 { 9685 struct bwn_softc *sc = mac->mac_sc; 9686 uint8_t mask; 9687 9688 if (n == 0) 9689 return (0); 9690 if (mac->mac_phy.gmode) 9691 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9692 else 9693 mask = siba_sprom_get_ant_a(sc->sc_dev); 9694 if (!(mask & (1 << (n - 1)))) 9695 return (0); 9696 return (n); 9697 } 9698 9699 static uint8_t 9700 bwn_get_fbrate(uint8_t bitrate) 9701 { 9702 switch (bitrate) { 9703 case BWN_CCK_RATE_1MB: 9704 return (BWN_CCK_RATE_1MB); 9705 case BWN_CCK_RATE_2MB: 9706 return (BWN_CCK_RATE_1MB); 9707 case BWN_CCK_RATE_5MB: 9708 return (BWN_CCK_RATE_2MB); 9709 case BWN_CCK_RATE_11MB: 9710 return (BWN_CCK_RATE_5MB); 9711 case BWN_OFDM_RATE_6MB: 9712 return (BWN_CCK_RATE_5MB); 9713 case BWN_OFDM_RATE_9MB: 9714 return (BWN_OFDM_RATE_6MB); 9715 case BWN_OFDM_RATE_12MB: 9716 return (BWN_OFDM_RATE_9MB); 9717 case BWN_OFDM_RATE_18MB: 9718 return (BWN_OFDM_RATE_12MB); 9719 case BWN_OFDM_RATE_24MB: 9720 return (BWN_OFDM_RATE_18MB); 9721 case BWN_OFDM_RATE_36MB: 9722 return (BWN_OFDM_RATE_24MB); 9723 case BWN_OFDM_RATE_48MB: 9724 return (BWN_OFDM_RATE_36MB); 9725 case BWN_OFDM_RATE_54MB: 9726 return (BWN_OFDM_RATE_48MB); 9727 } 9728 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9729 return (0); 9730 } 9731 9732 static uint32_t 9733 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9734 uint32_t ctl, const void *_data, int len) 9735 { 9736 struct bwn_softc *sc = mac->mac_sc; 9737 uint32_t value = 0; 9738 const uint8_t *data = _data; 9739 9740 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9741 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9742 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9743 9744 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9745 tq->tq_base + BWN_PIO8_TXDATA); 9746 if (len & 3) { 9747 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9748 BWN_PIO8_TXCTL_24_31); 9749 data = &(data[len - 1]); 9750 switch (len & 3) { 9751 case 3: 9752 ctl |= BWN_PIO8_TXCTL_16_23; 9753 value |= (uint32_t)(*data) << 16; 9754 data--; 9755 case 2: 9756 ctl |= BWN_PIO8_TXCTL_8_15; 9757 value |= (uint32_t)(*data) << 8; 9758 data--; 9759 case 1: 9760 value |= (uint32_t)(*data); 9761 } 9762 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9763 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9764 } 9765 9766 return (ctl); 9767 } 9768 9769 static void 9770 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9771 uint16_t offset, uint32_t value) 9772 { 9773 9774 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9775 } 9776 9777 static uint16_t 9778 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9779 uint16_t ctl, const void *_data, int len) 9780 { 9781 struct bwn_softc *sc = mac->mac_sc; 9782 const uint8_t *data = _data; 9783 9784 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9785 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9786 9787 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9788 tq->tq_base + BWN_PIO_TXDATA); 9789 if (len & 1) { 9790 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9791 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9792 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9793 } 9794 9795 return (ctl); 9796 } 9797 9798 static uint16_t 9799 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9800 uint16_t ctl, struct mbuf *m0) 9801 { 9802 int i, j = 0; 9803 uint16_t data = 0; 9804 const uint8_t *buf; 9805 struct mbuf *m = m0; 9806 9807 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9808 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9809 9810 for (; m != NULL; m = m->m_next) { 9811 buf = mtod(m, const uint8_t *); 9812 for (i = 0; i < m->m_len; i++) { 9813 if (!((j++) % 2)) 9814 data |= buf[i]; 9815 else { 9816 data |= (buf[i] << 8); 9817 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9818 data = 0; 9819 } 9820 } 9821 } 9822 if (m0->m_pkthdr.len % 2) { 9823 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9824 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9825 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9826 } 9827 9828 return (ctl); 9829 } 9830 9831 static void 9832 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9833 { 9834 9835 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9836 return; 9837 BWN_WRITE_2(mac, 0x684, 510 + time); 9838 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9839 } 9840 9841 static struct bwn_dma_ring * 9842 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9843 { 9844 9845 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9846 return (mac->mac_method.dma.wme[WME_AC_BE]); 9847 9848 switch (prio) { 9849 case 3: 9850 return (mac->mac_method.dma.wme[WME_AC_VO]); 9851 case 2: 9852 return (mac->mac_method.dma.wme[WME_AC_VI]); 9853 case 0: 9854 return (mac->mac_method.dma.wme[WME_AC_BE]); 9855 case 1: 9856 return (mac->mac_method.dma.wme[WME_AC_BK]); 9857 } 9858 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9859 return (NULL); 9860 } 9861 9862 static int 9863 bwn_dma_getslot(struct bwn_dma_ring *dr) 9864 { 9865 int slot; 9866 9867 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 9868 9869 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9870 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 9871 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 9872 9873 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 9874 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 9875 dr->dr_curslot = slot; 9876 dr->dr_usedslot++; 9877 9878 return (slot); 9879 } 9880 9881 static int 9882 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 9883 { 9884 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 9885 unsigned int a, b, c, d; 9886 unsigned int avg; 9887 uint32_t tmp; 9888 9889 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 9890 a = tmp & 0xff; 9891 b = (tmp >> 8) & 0xff; 9892 c = (tmp >> 16) & 0xff; 9893 d = (tmp >> 24) & 0xff; 9894 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 9895 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 9896 return (ENOENT); 9897 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 9898 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 9899 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 9900 9901 if (ofdm) { 9902 a = (a + 32) & 0x3f; 9903 b = (b + 32) & 0x3f; 9904 c = (c + 32) & 0x3f; 9905 d = (d + 32) & 0x3f; 9906 } 9907 9908 avg = (a + b + c + d + 2) / 4; 9909 if (ofdm) { 9910 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 9911 & BWN_HF_4DB_CCK_POWERBOOST) 9912 avg = (avg >= 13) ? (avg - 13) : 0; 9913 } 9914 return (avg); 9915 } 9916 9917 static void 9918 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 9919 { 9920 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 9921 int rfatt = *rfattp; 9922 int bbatt = *bbattp; 9923 9924 while (1) { 9925 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 9926 break; 9927 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 9928 break; 9929 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 9930 break; 9931 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 9932 break; 9933 if (bbatt > lo->bbatt.max) { 9934 bbatt -= 4; 9935 rfatt += 1; 9936 continue; 9937 } 9938 if (bbatt < lo->bbatt.min) { 9939 bbatt += 4; 9940 rfatt -= 1; 9941 continue; 9942 } 9943 if (rfatt > lo->rfatt.max) { 9944 rfatt -= 1; 9945 bbatt += 4; 9946 continue; 9947 } 9948 if (rfatt < lo->rfatt.min) { 9949 rfatt += 1; 9950 bbatt -= 4; 9951 continue; 9952 } 9953 break; 9954 } 9955 9956 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 9957 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 9958 } 9959 9960 static void 9961 bwn_phy_lock(struct bwn_mac *mac) 9962 { 9963 struct bwn_softc *sc = mac->mac_sc; 9964 struct ieee80211com *ic = &sc->sc_ic; 9965 9966 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 9967 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 9968 9969 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 9970 bwn_psctl(mac, BWN_PS_AWAKE); 9971 } 9972 9973 static void 9974 bwn_phy_unlock(struct bwn_mac *mac) 9975 { 9976 struct bwn_softc *sc = mac->mac_sc; 9977 struct ieee80211com *ic = &sc->sc_ic; 9978 9979 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 9980 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 9981 9982 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 9983 bwn_psctl(mac, 0); 9984 } 9985 9986 static void 9987 bwn_rf_lock(struct bwn_mac *mac) 9988 { 9989 9990 BWN_WRITE_4(mac, BWN_MACCTL, 9991 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 9992 BWN_READ_4(mac, BWN_MACCTL); 9993 DELAY(10); 9994 } 9995 9996 static void 9997 bwn_rf_unlock(struct bwn_mac *mac) 9998 { 9999 10000 BWN_READ_2(mac, BWN_PHYVER); 10001 BWN_WRITE_4(mac, BWN_MACCTL, 10002 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10003 } 10004 10005 static struct bwn_pio_txqueue * 10006 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10007 struct bwn_pio_txpkt **pack) 10008 { 10009 struct bwn_pio *pio = &mac->mac_method.pio; 10010 struct bwn_pio_txqueue *tq = NULL; 10011 unsigned int index; 10012 10013 switch (cookie & 0xf000) { 10014 case 0x1000: 10015 tq = &pio->wme[WME_AC_BK]; 10016 break; 10017 case 0x2000: 10018 tq = &pio->wme[WME_AC_BE]; 10019 break; 10020 case 0x3000: 10021 tq = &pio->wme[WME_AC_VI]; 10022 break; 10023 case 0x4000: 10024 tq = &pio->wme[WME_AC_VO]; 10025 break; 10026 case 0x5000: 10027 tq = &pio->mcast; 10028 break; 10029 } 10030 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10031 if (tq == NULL) 10032 return (NULL); 10033 index = (cookie & 0x0fff); 10034 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10035 if (index >= N(tq->tq_pkts)) 10036 return (NULL); 10037 *pack = &tq->tq_pkts[index]; 10038 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10039 return (tq); 10040 } 10041 10042 static void 10043 bwn_txpwr(void *arg, int npending) 10044 { 10045 struct bwn_mac *mac = arg; 10046 struct bwn_softc *sc = mac->mac_sc; 10047 10048 BWN_LOCK(sc); 10049 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10050 mac->mac_phy.set_txpwr != NULL) 10051 mac->mac_phy.set_txpwr(mac); 10052 BWN_UNLOCK(sc); 10053 } 10054 10055 static void 10056 bwn_task_15s(struct bwn_mac *mac) 10057 { 10058 uint16_t reg; 10059 10060 if (mac->mac_fw.opensource) { 10061 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10062 if (reg) { 10063 bwn_restart(mac, "fw watchdog"); 10064 return; 10065 } 10066 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10067 } 10068 if (mac->mac_phy.task_15s) 10069 mac->mac_phy.task_15s(mac); 10070 10071 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10072 } 10073 10074 static void 10075 bwn_task_30s(struct bwn_mac *mac) 10076 { 10077 10078 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10079 return; 10080 mac->mac_noise.noi_running = 1; 10081 mac->mac_noise.noi_nsamples = 0; 10082 10083 bwn_noise_gensample(mac); 10084 } 10085 10086 static void 10087 bwn_task_60s(struct bwn_mac *mac) 10088 { 10089 10090 if (mac->mac_phy.task_60s) 10091 mac->mac_phy.task_60s(mac); 10092 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10093 } 10094 10095 static void 10096 bwn_tasks(void *arg) 10097 { 10098 struct bwn_mac *mac = arg; 10099 struct bwn_softc *sc = mac->mac_sc; 10100 10101 BWN_ASSERT_LOCKED(sc); 10102 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10103 return; 10104 10105 if (mac->mac_task_state % 4 == 0) 10106 bwn_task_60s(mac); 10107 if (mac->mac_task_state % 2 == 0) 10108 bwn_task_30s(mac); 10109 bwn_task_15s(mac); 10110 10111 mac->mac_task_state++; 10112 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10113 } 10114 10115 static int 10116 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10117 { 10118 struct bwn_softc *sc = mac->mac_sc; 10119 10120 KASSERT(a == 0, ("not support APHY\n")); 10121 10122 switch (plcp->o.raw[0] & 0xf) { 10123 case 0xb: 10124 return (BWN_OFDM_RATE_6MB); 10125 case 0xf: 10126 return (BWN_OFDM_RATE_9MB); 10127 case 0xa: 10128 return (BWN_OFDM_RATE_12MB); 10129 case 0xe: 10130 return (BWN_OFDM_RATE_18MB); 10131 case 0x9: 10132 return (BWN_OFDM_RATE_24MB); 10133 case 0xd: 10134 return (BWN_OFDM_RATE_36MB); 10135 case 0x8: 10136 return (BWN_OFDM_RATE_48MB); 10137 case 0xc: 10138 return (BWN_OFDM_RATE_54MB); 10139 } 10140 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10141 plcp->o.raw[0] & 0xf); 10142 return (-1); 10143 } 10144 10145 static int 10146 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10147 { 10148 struct bwn_softc *sc = mac->mac_sc; 10149 10150 switch (plcp->o.raw[0]) { 10151 case 0x0a: 10152 return (BWN_CCK_RATE_1MB); 10153 case 0x14: 10154 return (BWN_CCK_RATE_2MB); 10155 case 0x37: 10156 return (BWN_CCK_RATE_5MB); 10157 case 0x6e: 10158 return (BWN_CCK_RATE_11MB); 10159 } 10160 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10161 return (-1); 10162 } 10163 10164 static void 10165 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10166 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10167 int rssi, int noise) 10168 { 10169 struct bwn_softc *sc = mac->mac_sc; 10170 const struct ieee80211_frame_min *wh; 10171 uint64_t tsf; 10172 uint16_t low_mactime_now; 10173 10174 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10175 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10176 10177 wh = mtod(m, const struct ieee80211_frame_min *); 10178 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10179 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10180 10181 bwn_tsf_read(mac, &tsf); 10182 low_mactime_now = tsf; 10183 tsf = tsf & ~0xffffULL; 10184 tsf += le16toh(rxhdr->mac_time); 10185 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10186 tsf -= 0x10000; 10187 10188 sc->sc_rx_th.wr_tsf = tsf; 10189 sc->sc_rx_th.wr_rate = rate; 10190 sc->sc_rx_th.wr_antsignal = rssi; 10191 sc->sc_rx_th.wr_antnoise = noise; 10192 } 10193 10194 static void 10195 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10196 { 10197 uint32_t low, high; 10198 10199 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10200 ("%s:%d: fail", __func__, __LINE__)); 10201 10202 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10203 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10204 *tsf = high; 10205 *tsf <<= 32; 10206 *tsf |= low; 10207 } 10208 10209 static int 10210 bwn_dma_attach(struct bwn_mac *mac) 10211 { 10212 struct bwn_dma *dma = &mac->mac_method.dma; 10213 struct bwn_softc *sc = mac->mac_sc; 10214 bus_addr_t lowaddr = 0; 10215 int error; 10216 10217 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10218 return (0); 10219 10220 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10221 10222 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10223 10224 dma->dmatype = bwn_dma_gettype(mac); 10225 if (dma->dmatype == BWN_DMA_30BIT) 10226 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10227 else if (dma->dmatype == BWN_DMA_32BIT) 10228 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10229 else 10230 lowaddr = BUS_SPACE_MAXADDR; 10231 10232 /* 10233 * Create top level DMA tag 10234 */ 10235 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10236 BWN_ALIGN, 0, /* alignment, bounds */ 10237 lowaddr, /* lowaddr */ 10238 BUS_SPACE_MAXADDR, /* highaddr */ 10239 NULL, NULL, /* filter, filterarg */ 10240 BUS_SPACE_MAXSIZE, /* maxsize */ 10241 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10242 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10243 0, /* flags */ 10244 NULL, NULL, /* lockfunc, lockarg */ 10245 &dma->parent_dtag); 10246 if (error) { 10247 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10248 return (error); 10249 } 10250 10251 /* 10252 * Create TX/RX mbuf DMA tag 10253 */ 10254 error = bus_dma_tag_create(dma->parent_dtag, 10255 1, 10256 0, 10257 BUS_SPACE_MAXADDR, 10258 BUS_SPACE_MAXADDR, 10259 NULL, NULL, 10260 MCLBYTES, 10261 1, 10262 BUS_SPACE_MAXSIZE_32BIT, 10263 0, 10264 NULL, NULL, 10265 &dma->rxbuf_dtag); 10266 if (error) { 10267 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10268 goto fail0; 10269 } 10270 error = bus_dma_tag_create(dma->parent_dtag, 10271 1, 10272 0, 10273 BUS_SPACE_MAXADDR, 10274 BUS_SPACE_MAXADDR, 10275 NULL, NULL, 10276 MCLBYTES, 10277 1, 10278 BUS_SPACE_MAXSIZE_32BIT, 10279 0, 10280 NULL, NULL, 10281 &dma->txbuf_dtag); 10282 if (error) { 10283 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10284 goto fail1; 10285 } 10286 10287 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10288 if (!dma->wme[WME_AC_BK]) 10289 goto fail2; 10290 10291 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10292 if (!dma->wme[WME_AC_BE]) 10293 goto fail3; 10294 10295 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10296 if (!dma->wme[WME_AC_VI]) 10297 goto fail4; 10298 10299 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10300 if (!dma->wme[WME_AC_VO]) 10301 goto fail5; 10302 10303 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10304 if (!dma->mcast) 10305 goto fail6; 10306 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10307 if (!dma->rx) 10308 goto fail7; 10309 10310 return (error); 10311 10312 fail7: bwn_dma_ringfree(&dma->mcast); 10313 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10314 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10315 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10316 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10317 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10318 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10319 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10320 return (error); 10321 } 10322 10323 static struct bwn_dma_ring * 10324 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10325 uint16_t cookie, int *slot) 10326 { 10327 struct bwn_dma *dma = &mac->mac_method.dma; 10328 struct bwn_dma_ring *dr; 10329 struct bwn_softc *sc = mac->mac_sc; 10330 10331 BWN_ASSERT_LOCKED(mac->mac_sc); 10332 10333 switch (cookie & 0xf000) { 10334 case 0x1000: 10335 dr = dma->wme[WME_AC_BK]; 10336 break; 10337 case 0x2000: 10338 dr = dma->wme[WME_AC_BE]; 10339 break; 10340 case 0x3000: 10341 dr = dma->wme[WME_AC_VI]; 10342 break; 10343 case 0x4000: 10344 dr = dma->wme[WME_AC_VO]; 10345 break; 10346 case 0x5000: 10347 dr = dma->mcast; 10348 break; 10349 default: 10350 dr = NULL; 10351 KASSERT(0 == 1, 10352 ("invalid cookie value %d", cookie & 0xf000)); 10353 } 10354 *slot = (cookie & 0x0fff); 10355 if (*slot < 0 || *slot >= dr->dr_numslots) { 10356 /* 10357 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10358 * that it occurs events which have same H/W sequence numbers. 10359 * When it's occurred just prints a WARNING msgs and ignores. 10360 */ 10361 KASSERT(status->seq == dma->lastseq, 10362 ("%s:%d: fail", __func__, __LINE__)); 10363 device_printf(sc->sc_dev, 10364 "out of slot ranges (0 < %d < %d)\n", *slot, 10365 dr->dr_numslots); 10366 return (NULL); 10367 } 10368 dma->lastseq = status->seq; 10369 return (dr); 10370 } 10371 10372 static void 10373 bwn_dma_stop(struct bwn_mac *mac) 10374 { 10375 struct bwn_dma *dma; 10376 10377 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10378 return; 10379 dma = &mac->mac_method.dma; 10380 10381 bwn_dma_ringstop(&dma->rx); 10382 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10383 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10384 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10385 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10386 bwn_dma_ringstop(&dma->mcast); 10387 } 10388 10389 static void 10390 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10391 { 10392 10393 if (dr == NULL) 10394 return; 10395 10396 bwn_dma_cleanup(*dr); 10397 } 10398 10399 static void 10400 bwn_pio_stop(struct bwn_mac *mac) 10401 { 10402 struct bwn_pio *pio; 10403 10404 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10405 return; 10406 pio = &mac->mac_method.pio; 10407 10408 bwn_destroy_queue_tx(&pio->mcast); 10409 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10410 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10411 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10412 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10413 } 10414 10415 static void 10416 bwn_led_attach(struct bwn_mac *mac) 10417 { 10418 struct bwn_softc *sc = mac->mac_sc; 10419 const uint8_t *led_act = NULL; 10420 uint16_t val[BWN_LED_MAX]; 10421 int i; 10422 10423 sc->sc_led_idle = (2350 * hz) / 1000; 10424 sc->sc_led_blink = 1; 10425 10426 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10427 if (siba_get_pci_subvendor(sc->sc_dev) == 10428 bwn_vendor_led_act[i].vid) { 10429 led_act = bwn_vendor_led_act[i].led_act; 10430 break; 10431 } 10432 } 10433 if (led_act == NULL) 10434 led_act = bwn_default_led_act; 10435 10436 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10437 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10438 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10439 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10440 10441 for (i = 0; i < BWN_LED_MAX; ++i) { 10442 struct bwn_led *led = &sc->sc_leds[i]; 10443 10444 if (val[i] == 0xff) { 10445 led->led_act = led_act[i]; 10446 } else { 10447 if (val[i] & BWN_LED_ACT_LOW) 10448 led->led_flags |= BWN_LED_F_ACTLOW; 10449 led->led_act = val[i] & BWN_LED_ACT_MASK; 10450 } 10451 led->led_mask = (1 << i); 10452 10453 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10454 led->led_act == BWN_LED_ACT_BLINK_POLL || 10455 led->led_act == BWN_LED_ACT_BLINK) { 10456 led->led_flags |= BWN_LED_F_BLINK; 10457 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10458 led->led_flags |= BWN_LED_F_POLLABLE; 10459 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10460 led->led_flags |= BWN_LED_F_SLOW; 10461 10462 if (sc->sc_blink_led == NULL) { 10463 sc->sc_blink_led = led; 10464 if (led->led_flags & BWN_LED_F_SLOW) 10465 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10466 } 10467 } 10468 10469 DPRINTF(sc, BWN_DEBUG_LED, 10470 "%dth led, act %d, lowact %d\n", i, 10471 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10472 } 10473 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10474 } 10475 10476 static __inline uint16_t 10477 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10478 { 10479 10480 if (led->led_flags & BWN_LED_F_ACTLOW) 10481 on = !on; 10482 if (on) 10483 val |= led->led_mask; 10484 else 10485 val &= ~led->led_mask; 10486 return val; 10487 } 10488 10489 static void 10490 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10491 { 10492 struct bwn_softc *sc = mac->mac_sc; 10493 struct ieee80211com *ic = &sc->sc_ic; 10494 uint16_t val; 10495 int i; 10496 10497 if (nstate == IEEE80211_S_INIT) { 10498 callout_stop(&sc->sc_led_blink_ch); 10499 sc->sc_led_blinking = 0; 10500 } 10501 10502 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) 10503 return; 10504 10505 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10506 for (i = 0; i < BWN_LED_MAX; ++i) { 10507 struct bwn_led *led = &sc->sc_leds[i]; 10508 int on; 10509 10510 if (led->led_act == BWN_LED_ACT_UNKN || 10511 led->led_act == BWN_LED_ACT_NULL) 10512 continue; 10513 10514 if ((led->led_flags & BWN_LED_F_BLINK) && 10515 nstate != IEEE80211_S_INIT) 10516 continue; 10517 10518 switch (led->led_act) { 10519 case BWN_LED_ACT_ON: /* Always on */ 10520 on = 1; 10521 break; 10522 case BWN_LED_ACT_OFF: /* Always off */ 10523 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10524 on = 0; 10525 break; 10526 default: 10527 on = 1; 10528 switch (nstate) { 10529 case IEEE80211_S_INIT: 10530 on = 0; 10531 break; 10532 case IEEE80211_S_RUN: 10533 if (led->led_act == BWN_LED_ACT_11G && 10534 ic->ic_curmode != IEEE80211_MODE_11G) 10535 on = 0; 10536 break; 10537 default: 10538 if (led->led_act == BWN_LED_ACT_ASSOC) 10539 on = 0; 10540 break; 10541 } 10542 break; 10543 } 10544 10545 val = bwn_led_onoff(led, val, on); 10546 } 10547 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10548 } 10549 10550 static void 10551 bwn_led_event(struct bwn_mac *mac, int event) 10552 { 10553 struct bwn_softc *sc = mac->mac_sc; 10554 struct bwn_led *led = sc->sc_blink_led; 10555 int rate; 10556 10557 if (event == BWN_LED_EVENT_POLL) { 10558 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10559 return; 10560 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10561 return; 10562 } 10563 10564 sc->sc_led_ticks = ticks; 10565 if (sc->sc_led_blinking) 10566 return; 10567 10568 switch (event) { 10569 case BWN_LED_EVENT_RX: 10570 rate = sc->sc_rx_rate; 10571 break; 10572 case BWN_LED_EVENT_TX: 10573 rate = sc->sc_tx_rate; 10574 break; 10575 case BWN_LED_EVENT_POLL: 10576 rate = 0; 10577 break; 10578 default: 10579 panic("unknown LED event %d\n", event); 10580 break; 10581 } 10582 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10583 bwn_led_duration[rate].off_dur); 10584 } 10585 10586 static void 10587 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10588 { 10589 struct bwn_softc *sc = mac->mac_sc; 10590 struct bwn_led *led = sc->sc_blink_led; 10591 uint16_t val; 10592 10593 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10594 val = bwn_led_onoff(led, val, 1); 10595 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10596 10597 if (led->led_flags & BWN_LED_F_SLOW) { 10598 BWN_LED_SLOWDOWN(on_dur); 10599 BWN_LED_SLOWDOWN(off_dur); 10600 } 10601 10602 sc->sc_led_blinking = 1; 10603 sc->sc_led_blink_offdur = off_dur; 10604 10605 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10606 } 10607 10608 static void 10609 bwn_led_blink_next(void *arg) 10610 { 10611 struct bwn_mac *mac = arg; 10612 struct bwn_softc *sc = mac->mac_sc; 10613 uint16_t val; 10614 10615 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10616 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10617 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10618 10619 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10620 bwn_led_blink_end, mac); 10621 } 10622 10623 static void 10624 bwn_led_blink_end(void *arg) 10625 { 10626 struct bwn_mac *mac = arg; 10627 struct bwn_softc *sc = mac->mac_sc; 10628 10629 sc->sc_led_blinking = 0; 10630 } 10631 10632 static int 10633 bwn_suspend(device_t dev) 10634 { 10635 struct bwn_softc *sc = device_get_softc(dev); 10636 10637 BWN_LOCK(sc); 10638 bwn_stop(sc); 10639 BWN_UNLOCK(sc); 10640 return (0); 10641 } 10642 10643 static int 10644 bwn_resume(device_t dev) 10645 { 10646 struct bwn_softc *sc = device_get_softc(dev); 10647 int error = EDOOFUS; 10648 10649 BWN_LOCK(sc); 10650 if (sc->sc_ic.ic_nrunning > 0) 10651 error = bwn_init(sc); 10652 BWN_UNLOCK(sc); 10653 if (error == 0) 10654 ieee80211_start_all(&sc->sc_ic); 10655 return (0); 10656 } 10657 10658 static void 10659 bwn_rfswitch(void *arg) 10660 { 10661 struct bwn_softc *sc = arg; 10662 struct bwn_mac *mac = sc->sc_curmac; 10663 int cur = 0, prev = 0; 10664 10665 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10666 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10667 10668 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10669 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10670 & BWN_RF_HWENABLED_HI_MASK)) 10671 cur = 1; 10672 } else { 10673 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10674 & BWN_RF_HWENABLED_LO_MASK) 10675 cur = 1; 10676 } 10677 10678 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10679 prev = 1; 10680 10681 if (cur != prev) { 10682 if (cur) 10683 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10684 else 10685 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10686 10687 device_printf(sc->sc_dev, 10688 "status of RF switch is changed to %s\n", 10689 cur ? "ON" : "OFF"); 10690 if (cur != mac->mac_phy.rf_on) { 10691 if (cur) 10692 bwn_rf_turnon(mac); 10693 else 10694 bwn_rf_turnoff(mac); 10695 } 10696 } 10697 10698 callout_schedule(&sc->sc_rfswitch_ch, hz); 10699 } 10700 10701 static void 10702 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10703 { 10704 struct bwn_phy *phy = &mac->mac_phy; 10705 struct bwn_phy_lp *plp = &phy->phy_lp; 10706 10707 plp->plp_antenna = BWN_ANT_DEFAULT; 10708 } 10709 10710 static int 10711 bwn_phy_lp_init(struct bwn_mac *mac) 10712 { 10713 static const struct bwn_stxtable tables[] = { 10714 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10715 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10716 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10717 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10718 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10719 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10720 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10721 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10722 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10723 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10724 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10725 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10726 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10727 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10728 { 2, 11, 0x40, 0, 0x0f } 10729 }; 10730 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10731 struct bwn_softc *sc = mac->mac_sc; 10732 const struct bwn_stxtable *st; 10733 struct ieee80211com *ic = &sc->sc_ic; 10734 int i, error; 10735 uint16_t tmp; 10736 10737 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10738 bwn_phy_lp_bbinit(mac); 10739 10740 /* initialize RF */ 10741 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10742 DELAY(1); 10743 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10744 DELAY(1); 10745 10746 if (mac->mac_phy.rf_ver == 0x2062) 10747 bwn_phy_lp_b2062_init(mac); 10748 else { 10749 bwn_phy_lp_b2063_init(mac); 10750 10751 /* synchronize stx table. */ 10752 for (i = 0; i < N(tables); i++) { 10753 st = &tables[i]; 10754 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10755 tmp >>= st->st_rfshift; 10756 tmp <<= st->st_physhift; 10757 BWN_PHY_SETMASK(mac, 10758 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10759 ~(st->st_mask << st->st_physhift), tmp); 10760 } 10761 10762 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10763 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10764 } 10765 10766 /* calibrate RC */ 10767 if (mac->mac_phy.rev >= 2) 10768 bwn_phy_lp_rxcal_r2(mac); 10769 else if (!plp->plp_rccap) { 10770 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10771 bwn_phy_lp_rccal_r12(mac); 10772 } else 10773 bwn_phy_lp_set_rccap(mac); 10774 10775 error = bwn_phy_lp_switch_channel(mac, 7); 10776 if (error) 10777 device_printf(sc->sc_dev, 10778 "failed to change channel 7 (%d)\n", error); 10779 bwn_phy_lp_txpctl_init(mac); 10780 bwn_phy_lp_calib(mac); 10781 return (0); 10782 } 10783 10784 static uint16_t 10785 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10786 { 10787 10788 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10789 return (BWN_READ_2(mac, BWN_PHYDATA)); 10790 } 10791 10792 static void 10793 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10794 { 10795 10796 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10797 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10798 } 10799 10800 static void 10801 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10802 uint16_t set) 10803 { 10804 10805 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10806 BWN_WRITE_2(mac, BWN_PHYDATA, 10807 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10808 } 10809 10810 static uint16_t 10811 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10812 { 10813 10814 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10815 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10816 reg |= 0x100; 10817 if (mac->mac_phy.rev >= 2) 10818 reg |= 0x200; 10819 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10820 return BWN_READ_2(mac, BWN_RFDATALO); 10821 } 10822 10823 static void 10824 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10825 { 10826 10827 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10828 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10829 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10830 } 10831 10832 static void 10833 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10834 { 10835 10836 if (on) { 10837 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10838 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10839 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10840 return; 10841 } 10842 10843 if (mac->mac_phy.rev >= 2) { 10844 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10845 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10846 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10847 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10848 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10849 return; 10850 } 10851 10852 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10853 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10854 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10855 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10856 } 10857 10858 static int 10859 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10860 { 10861 struct bwn_phy *phy = &mac->mac_phy; 10862 struct bwn_phy_lp *plp = &phy->phy_lp; 10863 int error; 10864 10865 if (phy->rf_ver == 0x2063) { 10866 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 10867 if (error) 10868 return (error); 10869 } else { 10870 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 10871 if (error) 10872 return (error); 10873 bwn_phy_lp_set_anafilter(mac, chan); 10874 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 10875 } 10876 10877 plp->plp_chan = chan; 10878 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 10879 return (0); 10880 } 10881 10882 static uint32_t 10883 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 10884 { 10885 struct bwn_softc *sc = mac->mac_sc; 10886 struct ieee80211com *ic = &sc->sc_ic; 10887 10888 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 10889 } 10890 10891 static void 10892 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 10893 { 10894 struct bwn_phy *phy = &mac->mac_phy; 10895 struct bwn_phy_lp *plp = &phy->phy_lp; 10896 10897 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 10898 return; 10899 10900 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 10901 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 10902 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 10903 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 10904 plp->plp_antenna = antenna; 10905 } 10906 10907 static void 10908 bwn_phy_lp_task_60s(struct bwn_mac *mac) 10909 { 10910 10911 bwn_phy_lp_calib(mac); 10912 } 10913 10914 static void 10915 bwn_phy_lp_readsprom(struct bwn_mac *mac) 10916 { 10917 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10918 struct bwn_softc *sc = mac->mac_sc; 10919 struct ieee80211com *ic = &sc->sc_ic; 10920 10921 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 10922 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 10923 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 10924 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 10925 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 10926 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 10927 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 10928 return; 10929 } 10930 10931 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 10932 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 10933 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 10934 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 10935 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 10936 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 10937 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 10938 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 10939 } 10940 10941 static void 10942 bwn_phy_lp_bbinit(struct bwn_mac *mac) 10943 { 10944 10945 bwn_phy_lp_tblinit(mac); 10946 if (mac->mac_phy.rev >= 2) 10947 bwn_phy_lp_bbinit_r2(mac); 10948 else 10949 bwn_phy_lp_bbinit_r01(mac); 10950 } 10951 10952 static void 10953 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 10954 { 10955 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 10956 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 10957 struct bwn_softc *sc = mac->mac_sc; 10958 struct ieee80211com *ic = &sc->sc_ic; 10959 10960 bwn_phy_lp_set_txgain(mac, 10961 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 10962 bwn_phy_lp_set_bbmult(mac, 150); 10963 } 10964 10965 static void 10966 bwn_phy_lp_calib(struct bwn_mac *mac) 10967 { 10968 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10969 struct bwn_softc *sc = mac->mac_sc; 10970 struct ieee80211com *ic = &sc->sc_ic; 10971 const struct bwn_rxcompco *rc = NULL; 10972 struct bwn_txgain ogain; 10973 int i, omode, oafeovr, orf, obbmult; 10974 uint8_t mode, fc = 0; 10975 10976 if (plp->plp_chanfullcal != plp->plp_chan) { 10977 plp->plp_chanfullcal = plp->plp_chan; 10978 fc = 1; 10979 } 10980 10981 bwn_mac_suspend(mac); 10982 10983 /* BlueTooth Coexistance Override */ 10984 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 10985 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 10986 10987 if (mac->mac_phy.rev >= 2) 10988 bwn_phy_lp_digflt_save(mac); 10989 bwn_phy_lp_get_txpctlmode(mac); 10990 mode = plp->plp_txpctlmode; 10991 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 10992 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 10993 bwn_phy_lp_bugfix(mac); 10994 if (mac->mac_phy.rev >= 2 && fc == 1) { 10995 bwn_phy_lp_get_txpctlmode(mac); 10996 omode = plp->plp_txpctlmode; 10997 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 10998 if (oafeovr) 10999 ogain = bwn_phy_lp_get_txgain(mac); 11000 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11001 obbmult = bwn_phy_lp_get_bbmult(mac); 11002 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11003 if (oafeovr) 11004 bwn_phy_lp_set_txgain(mac, &ogain); 11005 bwn_phy_lp_set_bbmult(mac, obbmult); 11006 bwn_phy_lp_set_txpctlmode(mac, omode); 11007 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11008 } 11009 bwn_phy_lp_set_txpctlmode(mac, mode); 11010 if (mac->mac_phy.rev >= 2) 11011 bwn_phy_lp_digflt_restore(mac); 11012 11013 /* do RX IQ Calculation; assumes that noise is true. */ 11014 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11015 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11016 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11017 rc = &bwn_rxcompco_5354[i]; 11018 } 11019 } else if (mac->mac_phy.rev >= 2) 11020 rc = &bwn_rxcompco_r2; 11021 else { 11022 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11023 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11024 rc = &bwn_rxcompco_r12[i]; 11025 } 11026 } 11027 if (rc == NULL) 11028 goto fail; 11029 11030 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11031 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11032 11033 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11034 11035 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11036 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11037 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11038 } else { 11039 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11040 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11041 } 11042 11043 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11044 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11045 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11046 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11047 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11048 bwn_phy_lp_set_deaf(mac, 0); 11049 /* XXX no checking return value? */ 11050 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11051 bwn_phy_lp_clear_deaf(mac, 0); 11052 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11053 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11054 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11055 11056 /* disable RX GAIN override. */ 11057 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11058 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11059 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11060 if (mac->mac_phy.rev >= 2) { 11061 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11062 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11063 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11064 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11065 } 11066 } else { 11067 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11068 } 11069 11070 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11071 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11072 fail: 11073 bwn_mac_enable(mac); 11074 } 11075 11076 static void 11077 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11078 { 11079 11080 if (on) { 11081 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11082 return; 11083 } 11084 11085 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11086 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11087 } 11088 11089 static int 11090 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11091 { 11092 static const struct bwn_b206x_chan *bc = NULL; 11093 struct bwn_softc *sc = mac->mac_sc; 11094 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11095 tmp[6]; 11096 uint16_t old, scale, tmp16; 11097 int i, div; 11098 11099 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11100 if (bwn_b2063_chantable[i].bc_chan == chan) { 11101 bc = &bwn_b2063_chantable[i]; 11102 break; 11103 } 11104 } 11105 if (bc == NULL) 11106 return (EINVAL); 11107 11108 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11109 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11110 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11111 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11112 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11113 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11114 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11115 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11116 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11117 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11118 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11119 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11120 11121 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11122 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11123 11124 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11125 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11126 freqref = freqxtal * 3; 11127 div = (freqxtal <= 26000000 ? 1 : 2); 11128 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11129 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11130 999999) / 1000000) + 1; 11131 11132 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11133 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11134 0xfff8, timeout >> 2); 11135 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11136 0xff9f,timeout << 5); 11137 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11138 11139 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11140 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11141 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11142 11143 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11144 (timeoutref + 1)) - 1; 11145 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11146 0xf0, count >> 8); 11147 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11148 11149 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11150 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11151 while (tmp[1] >= freqref) { 11152 tmp[0]++; 11153 tmp[1] -= freqref; 11154 } 11155 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11156 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11157 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11158 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11159 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11160 11161 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11162 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11163 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11164 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11165 11166 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11167 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11168 11169 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11170 scale = 1; 11171 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11172 } else { 11173 scale = 0; 11174 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11175 } 11176 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11177 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11178 11179 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11180 (scale + 1); 11181 if (tmp[5] > 150) 11182 tmp[5] = 0; 11183 11184 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11185 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11186 11187 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11188 if (freqxtal > 26000000) 11189 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11190 else 11191 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11192 11193 if (val[0] == 45) 11194 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11195 else 11196 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11197 11198 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11199 DELAY(1); 11200 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11201 11202 /* VCO Calibration */ 11203 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11204 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11205 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11206 DELAY(1); 11207 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11208 DELAY(1); 11209 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11210 DELAY(1); 11211 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11212 DELAY(300); 11213 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11214 11215 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11216 return (0); 11217 } 11218 11219 static int 11220 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11221 { 11222 struct bwn_softc *sc = mac->mac_sc; 11223 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11224 const struct bwn_b206x_chan *bc = NULL; 11225 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11226 uint32_t tmp[9]; 11227 int i; 11228 11229 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11230 if (bwn_b2062_chantable[i].bc_chan == chan) { 11231 bc = &bwn_b2062_chantable[i]; 11232 break; 11233 } 11234 } 11235 11236 if (bc == NULL) 11237 return (EINVAL); 11238 11239 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11240 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11241 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11242 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11243 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11244 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11245 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11246 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11247 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11248 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11249 11250 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11251 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11252 bwn_phy_lp_b2062_reset_pllbias(mac); 11253 tmp[0] = freqxtal / 1000; 11254 tmp[1] = plp->plp_div * 1000; 11255 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11256 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11257 tmp[2] *= 2; 11258 tmp[3] = 48 * tmp[0]; 11259 tmp[5] = tmp[2] / tmp[3]; 11260 tmp[6] = tmp[2] % tmp[3]; 11261 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11262 tmp[4] = tmp[6] * 0x100; 11263 tmp[5] = tmp[4] / tmp[3]; 11264 tmp[6] = tmp[4] % tmp[3]; 11265 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11266 tmp[4] = tmp[6] * 0x100; 11267 tmp[5] = tmp[4] / tmp[3]; 11268 tmp[6] = tmp[4] % tmp[3]; 11269 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11270 tmp[4] = tmp[6] * 0x100; 11271 tmp[5] = tmp[4] / tmp[3]; 11272 tmp[6] = tmp[4] % tmp[3]; 11273 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11274 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11275 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11276 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11277 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11278 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11279 11280 bwn_phy_lp_b2062_vco_calib(mac); 11281 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11282 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11283 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11284 bwn_phy_lp_b2062_reset_pllbias(mac); 11285 bwn_phy_lp_b2062_vco_calib(mac); 11286 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11287 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11288 return (EIO); 11289 } 11290 } 11291 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11292 return (0); 11293 } 11294 11295 static void 11296 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11297 { 11298 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11299 uint16_t tmp = (channel == 14); 11300 11301 if (mac->mac_phy.rev < 2) { 11302 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11303 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11304 bwn_phy_lp_set_rccap(mac); 11305 return; 11306 } 11307 11308 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11309 } 11310 11311 static void 11312 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11313 { 11314 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11315 struct bwn_softc *sc = mac->mac_sc; 11316 struct ieee80211com *ic = &sc->sc_ic; 11317 uint16_t iso, tmp[3]; 11318 11319 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11320 11321 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11322 iso = plp->plp_txisoband_m; 11323 else if (freq <= 5320) 11324 iso = plp->plp_txisoband_l; 11325 else if (freq <= 5700) 11326 iso = plp->plp_txisoband_m; 11327 else 11328 iso = plp->plp_txisoband_h; 11329 11330 tmp[0] = ((iso - 26) / 12) << 12; 11331 tmp[1] = tmp[0] + 0x1000; 11332 tmp[2] = tmp[0] + 0x2000; 11333 11334 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11335 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11336 } 11337 11338 static void 11339 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11340 { 11341 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11342 int i; 11343 static const uint16_t addr[] = { 11344 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11345 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11346 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11347 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11348 BWN_PHY_OFDM(0xcf), 11349 }; 11350 static const uint16_t val[] = { 11351 0xde5e, 0xe832, 0xe331, 0x4d26, 11352 0x0026, 0x1420, 0x0020, 0xfe08, 11353 0x0008, 11354 }; 11355 11356 for (i = 0; i < N(addr); i++) { 11357 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11358 BWN_PHY_WRITE(mac, addr[i], val[i]); 11359 } 11360 } 11361 11362 static void 11363 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11364 { 11365 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11366 struct bwn_softc *sc = mac->mac_sc; 11367 uint16_t ctl; 11368 11369 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11370 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11371 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11372 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11373 break; 11374 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11375 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11376 break; 11377 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11378 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11379 break; 11380 default: 11381 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11382 device_printf(sc->sc_dev, "unknown command mode\n"); 11383 break; 11384 } 11385 } 11386 11387 static void 11388 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11389 { 11390 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11391 uint16_t ctl; 11392 uint8_t old; 11393 11394 bwn_phy_lp_get_txpctlmode(mac); 11395 old = plp->plp_txpctlmode; 11396 if (old == mode) 11397 return; 11398 plp->plp_txpctlmode = mode; 11399 11400 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11401 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11402 plp->plp_tssiidx); 11403 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11404 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11405 11406 /* disable TX GAIN override */ 11407 if (mac->mac_phy.rev < 2) 11408 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11409 else { 11410 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11411 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11412 } 11413 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11414 11415 plp->plp_txpwridx = -1; 11416 } 11417 if (mac->mac_phy.rev >= 2) { 11418 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11419 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11420 else 11421 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11422 } 11423 11424 /* writes TX Power Control mode */ 11425 switch (plp->plp_txpctlmode) { 11426 case BWN_PHYLP_TXPCTL_OFF: 11427 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11428 break; 11429 case BWN_PHYLP_TXPCTL_ON_HW: 11430 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11431 break; 11432 case BWN_PHYLP_TXPCTL_ON_SW: 11433 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11434 break; 11435 default: 11436 ctl = 0; 11437 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11438 } 11439 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11440 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11441 } 11442 11443 static void 11444 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11445 { 11446 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11447 struct bwn_softc *sc = mac->mac_sc; 11448 const unsigned int size = 256; 11449 struct bwn_txgain tg; 11450 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11451 uint16_t tssinpt, tssiidx, value[2]; 11452 uint8_t mode; 11453 int8_t txpwridx; 11454 11455 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11456 M_NOWAIT | M_ZERO); 11457 if (tabs == NULL) { 11458 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11459 return; 11460 } 11461 11462 bwn_phy_lp_get_txpctlmode(mac); 11463 mode = plp->plp_txpctlmode; 11464 txpwridx = plp->plp_txpwridx; 11465 tssinpt = plp->plp_tssinpt; 11466 tssiidx = plp->plp_tssiidx; 11467 11468 bwn_tab_read_multi(mac, 11469 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11470 BWN_TAB_4(7, 0x140), size, tabs); 11471 11472 bwn_phy_lp_tblinit(mac); 11473 bwn_phy_lp_bbinit(mac); 11474 bwn_phy_lp_txpctl_init(mac); 11475 bwn_phy_lp_rf_onoff(mac, 1); 11476 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11477 11478 bwn_tab_write_multi(mac, 11479 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11480 BWN_TAB_4(7, 0x140), size, tabs); 11481 11482 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11483 plp->plp_tssinpt = tssinpt; 11484 plp->plp_tssiidx = tssiidx; 11485 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11486 if (txpwridx != -1) { 11487 /* set TX power by index */ 11488 plp->plp_txpwridx = txpwridx; 11489 bwn_phy_lp_get_txpctlmode(mac); 11490 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11491 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11492 if (mac->mac_phy.rev >= 2) { 11493 rxcomp = bwn_tab_read(mac, 11494 BWN_TAB_4(7, txpwridx + 320)); 11495 txgain = bwn_tab_read(mac, 11496 BWN_TAB_4(7, txpwridx + 192)); 11497 tg.tg_pad = (txgain >> 16) & 0xff; 11498 tg.tg_gm = txgain & 0xff; 11499 tg.tg_pga = (txgain >> 8) & 0xff; 11500 tg.tg_dac = (rxcomp >> 28) & 0xff; 11501 bwn_phy_lp_set_txgain(mac, &tg); 11502 } else { 11503 rxcomp = bwn_tab_read(mac, 11504 BWN_TAB_4(10, txpwridx + 320)); 11505 txgain = bwn_tab_read(mac, 11506 BWN_TAB_4(10, txpwridx + 192)); 11507 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11508 0xf800, (txgain >> 4) & 0x7fff); 11509 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11510 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11511 } 11512 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11513 11514 /* set TX IQCC */ 11515 value[0] = (rxcomp >> 10) & 0x3ff; 11516 value[1] = rxcomp & 0x3ff; 11517 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11518 11519 coeff = bwn_tab_read(mac, 11520 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11521 BWN_TAB_4(10, txpwridx + 448)); 11522 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11523 if (mac->mac_phy.rev >= 2) { 11524 rfpwr = bwn_tab_read(mac, 11525 BWN_TAB_4(7, txpwridx + 576)); 11526 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11527 rfpwr & 0xffff); 11528 } 11529 bwn_phy_lp_set_txgain_override(mac); 11530 } 11531 if (plp->plp_rccap) 11532 bwn_phy_lp_set_rccap(mac); 11533 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11534 bwn_phy_lp_set_txpctlmode(mac, mode); 11535 free(tabs, M_DEVBUF); 11536 } 11537 11538 static void 11539 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11540 { 11541 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11542 int i; 11543 static const uint16_t addr[] = { 11544 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11545 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11546 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11547 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11548 BWN_PHY_OFDM(0xcf), 11549 }; 11550 11551 for (i = 0; i < N(addr); i++) 11552 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11553 } 11554 11555 static void 11556 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11557 { 11558 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11559 11560 if (mac->mac_phy.rev < 2) { 11561 bwn_phy_lp_tblinit_r01(mac); 11562 bwn_phy_lp_tblinit_txgain(mac); 11563 bwn_phy_lp_set_gaintbl(mac, freq); 11564 return; 11565 } 11566 11567 bwn_phy_lp_tblinit_r2(mac); 11568 bwn_phy_lp_tblinit_txgain(mac); 11569 } 11570 11571 struct bwn_wpair { 11572 uint16_t reg; 11573 uint16_t value; 11574 }; 11575 11576 struct bwn_smpair { 11577 uint16_t offset; 11578 uint16_t mask; 11579 uint16_t set; 11580 }; 11581 11582 static void 11583 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11584 { 11585 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11586 struct bwn_softc *sc = mac->mac_sc; 11587 struct ieee80211com *ic = &sc->sc_ic; 11588 static const struct bwn_wpair v1[] = { 11589 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11590 { BWN_PHY_AFE_CTL, 0x8800 }, 11591 { BWN_PHY_AFE_CTL_OVR, 0 }, 11592 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11593 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11594 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11595 { BWN_PHY_OFDM(0xf9), 0 }, 11596 { BWN_PHY_TR_LOOKUP_1, 0 } 11597 }; 11598 static const struct bwn_smpair v2[] = { 11599 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11600 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11601 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11602 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11603 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11604 }; 11605 static const struct bwn_smpair v3[] = { 11606 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11607 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11608 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11609 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11610 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11611 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11612 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11613 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11614 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11615 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11616 11617 }; 11618 int i; 11619 11620 for (i = 0; i < N(v1); i++) 11621 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11622 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11623 for (i = 0; i < N(v2); i++) 11624 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11625 11626 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11627 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11628 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11629 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11630 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11631 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11632 } else { 11633 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11634 } 11635 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11636 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11637 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11638 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11639 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11640 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11641 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11642 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11643 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11644 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11645 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11646 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11647 (siba_get_chiprev(sc->sc_dev) == 0)) { 11648 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11649 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11650 } else { 11651 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11652 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11653 } 11654 for (i = 0; i < N(v3); i++) 11655 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11656 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11657 (siba_get_chiprev(sc->sc_dev) == 0)) { 11658 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11659 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11660 } 11661 11662 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11663 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11664 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11665 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11666 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11667 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11668 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11669 } else 11670 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11671 11672 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11673 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11674 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11675 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11676 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11677 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11678 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11679 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11680 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11681 11682 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11683 (siba_get_chiprev(sc->sc_dev) == 0)) { 11684 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11685 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11686 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11687 } 11688 11689 bwn_phy_lp_digflt_save(mac); 11690 } 11691 11692 static void 11693 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11694 { 11695 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11696 struct bwn_softc *sc = mac->mac_sc; 11697 struct ieee80211com *ic = &sc->sc_ic; 11698 static const struct bwn_smpair v1[] = { 11699 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11700 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11701 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11702 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11703 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11704 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11705 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11706 }; 11707 static const struct bwn_smpair v2[] = { 11708 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11709 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11710 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11711 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11712 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11713 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11714 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11715 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11716 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11717 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11718 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11719 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11720 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11721 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11722 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11723 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11724 }; 11725 static const struct bwn_smpair v3[] = { 11726 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11727 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11728 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11729 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11730 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11731 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11732 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11733 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11734 }; 11735 static const struct bwn_smpair v4[] = { 11736 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11737 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11738 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11739 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11740 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11741 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11742 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11743 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11744 }; 11745 static const struct bwn_smpair v5[] = { 11746 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11747 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11748 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11749 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11750 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11751 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11752 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11753 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11754 }; 11755 int i; 11756 uint16_t tmp, tmp2; 11757 11758 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11759 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11760 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11761 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11762 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11763 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11764 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11765 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11766 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11767 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11768 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11769 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11770 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11771 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11772 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11773 for (i = 0; i < N(v1); i++) 11774 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11775 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11776 0xff00, plp->plp_rxpwroffset); 11777 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11778 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11779 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11780 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11781 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11782 if (mac->mac_phy.rev == 0) 11783 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11784 0xffcf, 0x0010); 11785 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11786 } else { 11787 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11788 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11789 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11790 } 11791 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11792 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11793 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11794 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11795 else 11796 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11797 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11798 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11799 0xfff9, (plp->plp_bxarch << 1)); 11800 if (mac->mac_phy.rev == 1 && 11801 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11802 for (i = 0; i < N(v2); i++) 11803 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11804 v2[i].set); 11805 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11806 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11807 ((mac->mac_phy.rev == 0) && 11808 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11809 for (i = 0; i < N(v3); i++) 11810 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11811 v3[i].set); 11812 } else if (mac->mac_phy.rev == 1 || 11813 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11814 for (i = 0; i < N(v4); i++) 11815 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11816 v4[i].set); 11817 } else { 11818 for (i = 0; i < N(v5); i++) 11819 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11820 v5[i].set); 11821 } 11822 if (mac->mac_phy.rev == 1 && 11823 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11824 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11825 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11826 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11827 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11828 } 11829 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11830 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11831 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11832 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11833 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11834 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11835 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11836 } 11837 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11838 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11839 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11840 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11841 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11842 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11843 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11844 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11845 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11846 } else { 11847 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11848 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11849 } 11850 if (mac->mac_phy.rev == 1) { 11851 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11852 tmp2 = (tmp & 0x03e0) >> 5; 11853 tmp2 |= tmp2 << 5; 11854 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11855 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 11856 tmp2 = (tmp & 0x1f00) >> 8; 11857 tmp2 |= tmp2 << 5; 11858 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 11859 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 11860 tmp2 = tmp & 0x00ff; 11861 tmp2 |= tmp << 8; 11862 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 11863 } 11864 } 11865 11866 struct bwn_b2062_freq { 11867 uint16_t freq; 11868 uint8_t value[6]; 11869 }; 11870 11871 static void 11872 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 11873 { 11874 #define CALC_CTL7(freq, div) \ 11875 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 11876 #define CALC_CTL18(freq, div) \ 11877 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 11878 #define CALC_CTL19(freq, div) \ 11879 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 11880 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11881 struct bwn_softc *sc = mac->mac_sc; 11882 struct ieee80211com *ic = &sc->sc_ic; 11883 static const struct bwn_b2062_freq freqdata_tab[] = { 11884 { 12000, { 6, 6, 6, 6, 10, 6 } }, 11885 { 13000, { 4, 4, 4, 4, 11, 7 } }, 11886 { 14400, { 3, 3, 3, 3, 12, 7 } }, 11887 { 16200, { 3, 3, 3, 3, 13, 8 } }, 11888 { 18000, { 2, 2, 2, 2, 14, 8 } }, 11889 { 19200, { 1, 1, 1, 1, 14, 9 } } 11890 }; 11891 static const struct bwn_wpair v1[] = { 11892 { BWN_B2062_N_TXCTL3, 0 }, 11893 { BWN_B2062_N_TXCTL4, 0 }, 11894 { BWN_B2062_N_TXCTL5, 0 }, 11895 { BWN_B2062_N_TXCTL6, 0 }, 11896 { BWN_B2062_N_PDNCTL0, 0x40 }, 11897 { BWN_B2062_N_PDNCTL0, 0 }, 11898 { BWN_B2062_N_CALIB_TS, 0x10 }, 11899 { BWN_B2062_N_CALIB_TS, 0 } 11900 }; 11901 const struct bwn_b2062_freq *f = NULL; 11902 uint32_t xtalfreq, ref; 11903 unsigned int i; 11904 11905 bwn_phy_lp_b2062_tblinit(mac); 11906 11907 for (i = 0; i < N(v1); i++) 11908 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 11909 if (mac->mac_phy.rev > 0) 11910 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 11911 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 11912 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11913 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 11914 else 11915 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 11916 11917 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 11918 ("%s:%d: fail", __func__, __LINE__)); 11919 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11920 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 11921 11922 if (xtalfreq <= 30000000) { 11923 plp->plp_div = 1; 11924 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 11925 } else { 11926 plp->plp_div = 2; 11927 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 11928 } 11929 11930 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 11931 CALC_CTL7(xtalfreq, plp->plp_div)); 11932 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 11933 CALC_CTL18(xtalfreq, plp->plp_div)); 11934 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 11935 CALC_CTL19(xtalfreq, plp->plp_div)); 11936 11937 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 11938 ref &= 0xffff; 11939 for (i = 0; i < N(freqdata_tab); i++) { 11940 if (ref < freqdata_tab[i].freq) { 11941 f = &freqdata_tab[i]; 11942 break; 11943 } 11944 } 11945 if (f == NULL) 11946 f = &freqdata_tab[N(freqdata_tab) - 1]; 11947 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 11948 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 11949 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 11950 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 11951 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 11952 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 11953 #undef CALC_CTL7 11954 #undef CALC_CTL18 11955 #undef CALC_CTL19 11956 } 11957 11958 static void 11959 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 11960 { 11961 11962 bwn_phy_lp_b2063_tblinit(mac); 11963 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 11964 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 11965 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 11966 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 11967 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 11968 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 11969 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 11970 if (mac->mac_phy.rev == 2) { 11971 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 11972 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 11973 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 11974 } else { 11975 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 11976 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 11977 } 11978 } 11979 11980 static void 11981 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 11982 { 11983 struct bwn_softc *sc = mac->mac_sc; 11984 static const struct bwn_wpair v1[] = { 11985 { BWN_B2063_RX_BB_SP8, 0x0 }, 11986 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 11987 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 11988 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 11989 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 11990 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 11991 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 11992 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 11993 }; 11994 static const struct bwn_wpair v2[] = { 11995 { BWN_B2063_TX_BB_SP3, 0x0 }, 11996 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 11997 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 11998 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 11999 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12000 }; 12001 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12002 int i; 12003 uint8_t tmp; 12004 12005 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12006 12007 for (i = 0; i < 2; i++) 12008 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12009 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12010 for (i = 2; i < N(v1); i++) 12011 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12012 for (i = 0; i < 10000; i++) { 12013 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12014 break; 12015 DELAY(1000); 12016 } 12017 12018 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12019 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12020 12021 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12022 12023 for (i = 0; i < N(v2); i++) 12024 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12025 if (freqxtal == 24000000) { 12026 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12027 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12028 } else { 12029 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12030 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12031 } 12032 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12033 for (i = 0; i < 10000; i++) { 12034 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12035 break; 12036 DELAY(1000); 12037 } 12038 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12039 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12040 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12041 } 12042 12043 static void 12044 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12045 { 12046 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12047 struct bwn_softc *sc = mac->mac_sc; 12048 struct bwn_phy_lp_iq_est ie; 12049 struct bwn_txgain tx_gains; 12050 static const uint32_t pwrtbl[21] = { 12051 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12052 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12053 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12054 0x0004c, 0x0002c, 0x0001a, 12055 }; 12056 uint32_t npwr, ipwr, sqpwr, tmp; 12057 int loopback, i, j, sum, error; 12058 uint16_t save[7]; 12059 uint8_t txo, bbmult, txpctlmode; 12060 12061 error = bwn_phy_lp_switch_channel(mac, 7); 12062 if (error) 12063 device_printf(sc->sc_dev, 12064 "failed to change channel to 7 (%d)\n", error); 12065 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12066 bbmult = bwn_phy_lp_get_bbmult(mac); 12067 if (txo) 12068 tx_gains = bwn_phy_lp_get_txgain(mac); 12069 12070 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12071 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12072 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12073 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12074 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12075 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12076 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12077 12078 bwn_phy_lp_get_txpctlmode(mac); 12079 txpctlmode = plp->plp_txpctlmode; 12080 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12081 12082 /* disable CRS */ 12083 bwn_phy_lp_set_deaf(mac, 1); 12084 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12085 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12086 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12087 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12088 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12089 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12090 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12091 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12092 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12093 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12094 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12095 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12096 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12097 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12098 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12099 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12100 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12101 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12102 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12103 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12104 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12105 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12106 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12107 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12108 12109 loopback = bwn_phy_lp_loopback(mac); 12110 if (loopback == -1) 12111 goto done; 12112 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12113 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12114 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12115 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12116 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12117 12118 tmp = 0; 12119 memset(&ie, 0, sizeof(ie)); 12120 for (i = 128; i <= 159; i++) { 12121 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12122 sum = 0; 12123 for (j = 5; j <= 25; j++) { 12124 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12125 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12126 goto done; 12127 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12128 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12129 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12130 12); 12131 sum += ((ipwr - npwr) * (ipwr - npwr)); 12132 if ((i == 128) || (sum < tmp)) { 12133 plp->plp_rccap = i; 12134 tmp = sum; 12135 } 12136 } 12137 } 12138 bwn_phy_lp_ddfs_turnoff(mac); 12139 done: 12140 /* restore CRS */ 12141 bwn_phy_lp_clear_deaf(mac, 1); 12142 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12143 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12144 12145 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12146 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12147 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12148 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12149 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12150 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12151 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12152 12153 bwn_phy_lp_set_bbmult(mac, bbmult); 12154 if (txo) 12155 bwn_phy_lp_set_txgain(mac, &tx_gains); 12156 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12157 if (plp->plp_rccap) 12158 bwn_phy_lp_set_rccap(mac); 12159 } 12160 12161 static void 12162 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12163 { 12164 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12165 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12166 12167 if (mac->mac_phy.rev == 1) 12168 rc_cap = MIN(rc_cap + 5, 15); 12169 12170 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12171 MAX(plp->plp_rccap - 4, 0x80)); 12172 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12173 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12174 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12175 } 12176 12177 static uint32_t 12178 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12179 { 12180 uint32_t i, q, r; 12181 12182 if (div == 0) 12183 return (0); 12184 12185 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12186 q <<= 1; 12187 if (r << 1 >= div) { 12188 q++; 12189 r = (r << 1) - div; 12190 } 12191 } 12192 if (r << 1 >= div) 12193 q++; 12194 return (q); 12195 } 12196 12197 static void 12198 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12199 { 12200 struct bwn_softc *sc = mac->mac_sc; 12201 12202 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12203 DELAY(20); 12204 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12205 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12206 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12207 } else { 12208 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12209 } 12210 DELAY(5); 12211 } 12212 12213 static void 12214 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12215 { 12216 12217 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12218 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12219 DELAY(200); 12220 } 12221 12222 static void 12223 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12224 { 12225 #define FLAG_A 0x01 12226 #define FLAG_G 0x02 12227 struct bwn_softc *sc = mac->mac_sc; 12228 struct ieee80211com *ic = &sc->sc_ic; 12229 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12230 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12231 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12232 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12233 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12234 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12235 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12236 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12237 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12238 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12239 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12240 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12241 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12242 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12243 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12244 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12245 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12246 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12247 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12248 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12249 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12250 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12251 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12252 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12253 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12254 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12255 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12256 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12257 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12258 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12259 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12260 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12261 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12262 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12263 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12264 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12265 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12266 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12267 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12268 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12269 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12270 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12271 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12272 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12273 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12274 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12275 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12276 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12277 }; 12278 const struct bwn_b206x_rfinit_entry *br; 12279 unsigned int i; 12280 12281 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12282 br = &bwn_b2062_init_tab[i]; 12283 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12284 if (br->br_flags & FLAG_G) 12285 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12286 } else { 12287 if (br->br_flags & FLAG_A) 12288 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12289 } 12290 } 12291 #undef FLAG_A 12292 #undef FLAG_B 12293 } 12294 12295 static void 12296 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12297 { 12298 #define FLAG_A 0x01 12299 #define FLAG_G 0x02 12300 struct bwn_softc *sc = mac->mac_sc; 12301 struct ieee80211com *ic = &sc->sc_ic; 12302 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12303 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12304 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12305 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12306 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12307 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12308 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12309 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12310 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12311 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12312 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12313 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12314 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12315 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12316 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12317 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12318 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12319 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12320 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12321 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12322 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12323 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12324 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12325 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12326 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12327 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12328 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12329 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12330 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12331 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12332 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12333 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12334 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12335 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12336 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12337 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12338 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12339 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12340 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12341 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12342 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12343 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12344 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12345 }; 12346 const struct bwn_b206x_rfinit_entry *br; 12347 unsigned int i; 12348 12349 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12350 br = &bwn_b2063_init_tab[i]; 12351 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12352 if (br->br_flags & FLAG_G) 12353 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12354 } else { 12355 if (br->br_flags & FLAG_A) 12356 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12357 } 12358 } 12359 #undef FLAG_A 12360 #undef FLAG_B 12361 } 12362 12363 static void 12364 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12365 int count, void *_data) 12366 { 12367 unsigned int i; 12368 uint32_t offset, type; 12369 uint8_t *data = _data; 12370 12371 type = BWN_TAB_GETTYPE(typenoffset); 12372 offset = BWN_TAB_GETOFFSET(typenoffset); 12373 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12374 12375 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12376 12377 for (i = 0; i < count; i++) { 12378 switch (type) { 12379 case BWN_TAB_8BIT: 12380 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12381 data++; 12382 break; 12383 case BWN_TAB_16BIT: 12384 *((uint16_t *)data) = BWN_PHY_READ(mac, 12385 BWN_PHY_TABLEDATALO); 12386 data += 2; 12387 break; 12388 case BWN_TAB_32BIT: 12389 *((uint32_t *)data) = BWN_PHY_READ(mac, 12390 BWN_PHY_TABLEDATAHI); 12391 *((uint32_t *)data) <<= 16; 12392 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12393 BWN_PHY_TABLEDATALO); 12394 data += 4; 12395 break; 12396 default: 12397 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12398 } 12399 } 12400 } 12401 12402 static void 12403 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12404 int count, const void *_data) 12405 { 12406 uint32_t offset, type, value; 12407 const uint8_t *data = _data; 12408 unsigned int i; 12409 12410 type = BWN_TAB_GETTYPE(typenoffset); 12411 offset = BWN_TAB_GETOFFSET(typenoffset); 12412 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12413 12414 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12415 12416 for (i = 0; i < count; i++) { 12417 switch (type) { 12418 case BWN_TAB_8BIT: 12419 value = *data; 12420 data++; 12421 KASSERT(!(value & ~0xff), 12422 ("%s:%d: fail", __func__, __LINE__)); 12423 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12424 break; 12425 case BWN_TAB_16BIT: 12426 value = *((const uint16_t *)data); 12427 data += 2; 12428 KASSERT(!(value & ~0xffff), 12429 ("%s:%d: fail", __func__, __LINE__)); 12430 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12431 break; 12432 case BWN_TAB_32BIT: 12433 value = *((const uint32_t *)data); 12434 data += 4; 12435 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12436 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12437 break; 12438 default: 12439 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12440 } 12441 } 12442 } 12443 12444 static struct bwn_txgain 12445 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12446 { 12447 struct bwn_txgain tg; 12448 uint16_t tmp; 12449 12450 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12451 if (mac->mac_phy.rev < 2) { 12452 tmp = BWN_PHY_READ(mac, 12453 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12454 tg.tg_gm = tmp & 0x0007; 12455 tg.tg_pga = (tmp & 0x0078) >> 3; 12456 tg.tg_pad = (tmp & 0x780) >> 7; 12457 return (tg); 12458 } 12459 12460 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12461 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12462 tg.tg_gm = tmp & 0xff; 12463 tg.tg_pga = (tmp >> 8) & 0xff; 12464 return (tg); 12465 } 12466 12467 static uint8_t 12468 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12469 { 12470 12471 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12472 } 12473 12474 static void 12475 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12476 { 12477 uint16_t pa; 12478 12479 if (mac->mac_phy.rev < 2) { 12480 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12481 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12482 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12483 bwn_phy_lp_set_txgain_override(mac); 12484 return; 12485 } 12486 12487 pa = bwn_phy_lp_get_pa_gain(mac); 12488 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12489 (tg->tg_pga << 8) | tg->tg_gm); 12490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12491 tg->tg_pad | (pa << 6)); 12492 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12494 tg->tg_pad | (pa << 8)); 12495 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12496 bwn_phy_lp_set_txgain_override(mac); 12497 } 12498 12499 static void 12500 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12501 { 12502 12503 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12504 } 12505 12506 static void 12507 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12508 { 12509 uint16_t trsw = (tx << 1) | rx; 12510 12511 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12512 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12513 } 12514 12515 static void 12516 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12517 { 12518 struct bwn_softc *sc = mac->mac_sc; 12519 struct ieee80211com *ic = &sc->sc_ic; 12520 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12521 12522 if (mac->mac_phy.rev < 2) { 12523 trsw = gain & 0x1; 12524 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12525 ext_lna = (gain & 2) >> 1; 12526 12527 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12528 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12529 0xfbff, ext_lna << 10); 12530 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12531 0xf7ff, ext_lna << 11); 12532 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12533 } else { 12534 low_gain = gain & 0xffff; 12535 high_gain = (gain >> 16) & 0xf; 12536 ext_lna = (gain >> 21) & 0x1; 12537 trsw = ~(gain >> 20) & 0x1; 12538 12539 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12540 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12541 0xfdff, ext_lna << 9); 12542 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12543 0xfbff, ext_lna << 10); 12544 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12545 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12546 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12547 tmp = (gain >> 2) & 0x3; 12548 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12549 0xe7ff, tmp<<11); 12550 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12551 tmp << 3); 12552 } 12553 } 12554 12555 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12556 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12557 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12558 if (mac->mac_phy.rev >= 2) { 12559 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12560 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12561 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12562 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12563 } 12564 return; 12565 } 12566 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12567 } 12568 12569 static void 12570 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12571 { 12572 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12573 12574 if (user) 12575 plp->plp_crsusr_off = 1; 12576 else 12577 plp->plp_crssys_off = 1; 12578 12579 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12580 } 12581 12582 static void 12583 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12584 { 12585 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12586 struct bwn_softc *sc = mac->mac_sc; 12587 struct ieee80211com *ic = &sc->sc_ic; 12588 12589 if (user) 12590 plp->plp_crsusr_off = 0; 12591 else 12592 plp->plp_crssys_off = 0; 12593 12594 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12595 return; 12596 12597 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12598 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12599 else 12600 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12601 } 12602 12603 static unsigned int 12604 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12605 { 12606 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12607 static uint8_t sqrt_table[256] = { 12608 10, 14, 17, 20, 22, 24, 26, 28, 12609 30, 31, 33, 34, 36, 37, 38, 40, 12610 41, 42, 43, 44, 45, 46, 47, 48, 12611 50, 50, 51, 52, 53, 54, 55, 56, 12612 57, 58, 59, 60, 60, 61, 62, 63, 12613 64, 64, 65, 66, 67, 67, 68, 69, 12614 70, 70, 71, 72, 72, 73, 74, 74, 12615 75, 76, 76, 77, 78, 78, 79, 80, 12616 80, 81, 81, 82, 83, 83, 84, 84, 12617 85, 86, 86, 87, 87, 88, 88, 89, 12618 90, 90, 91, 91, 92, 92, 93, 93, 12619 94, 94, 95, 95, 96, 96, 97, 97, 12620 98, 98, 99, 100, 100, 100, 101, 101, 12621 102, 102, 103, 103, 104, 104, 105, 105, 12622 106, 106, 107, 107, 108, 108, 109, 109, 12623 110, 110, 110, 111, 111, 112, 112, 113, 12624 113, 114, 114, 114, 115, 115, 116, 116, 12625 117, 117, 117, 118, 118, 119, 119, 120, 12626 120, 120, 121, 121, 122, 122, 122, 123, 12627 123, 124, 124, 124, 125, 125, 126, 126, 12628 126, 127, 127, 128, 128, 128, 129, 129, 12629 130, 130, 130, 131, 131, 131, 132, 132, 12630 133, 133, 133, 134, 134, 134, 135, 135, 12631 136, 136, 136, 137, 137, 137, 138, 138, 12632 138, 139, 139, 140, 140, 140, 141, 141, 12633 141, 142, 142, 142, 143, 143, 143, 144, 12634 144, 144, 145, 145, 145, 146, 146, 146, 12635 147, 147, 147, 148, 148, 148, 149, 149, 12636 150, 150, 150, 150, 151, 151, 151, 152, 12637 152, 152, 153, 153, 153, 154, 154, 154, 12638 155, 155, 155, 156, 156, 156, 157, 157, 12639 157, 158, 158, 158, 159, 159, 159, 160 12640 }; 12641 12642 if (x == 0) 12643 return (0); 12644 if (x >= 256) { 12645 unsigned int tmp; 12646 12647 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12648 /* do nothing */ ; 12649 return (tmp); 12650 } 12651 return (sqrt_table[x - 1] / 10); 12652 } 12653 12654 static int 12655 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12656 { 12657 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12658 int _t; \ 12659 _t = _x - 20; \ 12660 if (_t >= 0) { \ 12661 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12662 } else { \ 12663 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12664 } \ 12665 } while (0) 12666 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12667 int _t; \ 12668 _t = _x - 11; \ 12669 if (_t >= 0) \ 12670 _v = (_y << (31 - _x)) / (_z >> _t); \ 12671 else \ 12672 _v = (_y << (31 - _x)) / (_z << -_t); \ 12673 } while (0) 12674 struct bwn_phy_lp_iq_est ie; 12675 uint16_t v0, v1; 12676 int tmp[2], ret; 12677 12678 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12679 v0 = v1 >> 8; 12680 v1 |= 0xff; 12681 12682 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12683 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12684 12685 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12686 if (ret == 0) 12687 goto done; 12688 12689 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12690 ret = 0; 12691 goto done; 12692 } 12693 12694 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12695 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12696 12697 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12698 v0 = tmp[0] >> 3; 12699 v1 = tmp[1] >> 4; 12700 done: 12701 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12702 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12703 return ret; 12704 #undef CALC_COEFF 12705 #undef CALC_COEFF2 12706 } 12707 12708 static void 12709 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12710 { 12711 static const uint16_t noisescale[] = { 12712 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12713 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12714 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12715 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12716 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12717 }; 12718 static const uint16_t crsgainnft[] = { 12719 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12720 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12721 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12722 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12723 0x013d, 12724 }; 12725 static const uint16_t filterctl[] = { 12726 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12727 0xff53, 0x0127, 12728 }; 12729 static const uint32_t psctl[] = { 12730 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12731 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12732 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12733 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12734 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12735 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12736 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12737 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12738 }; 12739 static const uint16_t ofdmcckgain_r0[] = { 12740 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12741 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12742 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12743 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12744 0x755d, 12745 }; 12746 static const uint16_t ofdmcckgain_r1[] = { 12747 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12748 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12749 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12750 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12751 0x755d, 12752 }; 12753 static const uint16_t gaindelta[] = { 12754 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12755 0x0000, 12756 }; 12757 static const uint32_t txpwrctl[] = { 12758 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12759 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12760 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12761 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12762 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12763 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12764 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12765 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12766 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12767 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12768 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12769 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12770 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12771 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12772 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12773 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12774 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12775 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12776 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12777 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12778 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12779 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12780 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12781 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12782 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12783 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12784 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12785 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12786 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12787 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12788 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12789 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12790 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12791 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12792 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12793 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12794 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12795 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12796 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12797 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12798 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12799 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12800 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12801 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12802 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12803 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12804 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12805 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12806 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12807 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12808 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12809 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12810 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12811 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12812 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12813 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12814 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12815 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12816 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12817 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12818 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12819 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12820 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12821 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12822 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12823 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12824 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12825 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12826 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12827 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12828 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12829 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12830 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12831 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12832 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12833 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12834 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12835 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12836 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12837 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12838 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12839 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12840 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12841 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12842 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12843 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12844 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12845 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12846 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12847 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12848 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12849 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12850 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 12851 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 12852 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 12853 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 12854 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 12855 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 12856 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 12857 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 12858 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 12859 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 12860 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 12861 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 12862 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 12863 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 12864 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 12865 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 12866 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 12867 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 12868 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 12869 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 12870 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 12871 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 12872 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 12873 0x00000702, 12874 }; 12875 12876 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 12877 12878 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 12879 bwn_tab_sigsq_tbl); 12880 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 12881 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 12882 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 12883 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 12884 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 12885 bwn_tab_pllfrac_tbl); 12886 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 12887 bwn_tabl_iqlocal_tbl); 12888 if (mac->mac_phy.rev == 0) { 12889 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 12890 ofdmcckgain_r0); 12891 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 12892 ofdmcckgain_r0); 12893 } else { 12894 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 12895 ofdmcckgain_r1); 12896 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 12897 ofdmcckgain_r1); 12898 } 12899 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 12900 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 12901 } 12902 12903 static void 12904 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 12905 { 12906 struct bwn_softc *sc = mac->mac_sc; 12907 int i; 12908 static const uint16_t noisescale[] = { 12909 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12910 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12911 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12912 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12913 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12914 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12915 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 12916 }; 12917 static const uint32_t filterctl[] = { 12918 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 12919 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 12920 }; 12921 static const uint32_t psctl[] = { 12922 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 12923 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 12924 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 12925 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 12926 }; 12927 static const uint32_t gainidx[] = { 12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12931 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 12932 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 12933 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 12934 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 12935 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 12936 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 12937 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 12938 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 12939 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 12940 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 12941 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 12942 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12946 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 12947 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 12948 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 12949 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 12950 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 12951 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 12952 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 12953 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 12954 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 12955 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 12956 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 12957 0x0000001a, 0x64ca55ad, 0x0000001a 12958 }; 12959 static const uint16_t auxgainidx[] = { 12960 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12961 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 12962 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 12963 0x0004, 0x0016 12964 }; 12965 static const uint16_t swctl[] = { 12966 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12967 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12968 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 12969 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 12970 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12971 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12972 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 12973 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 12974 }; 12975 static const uint8_t hf[] = { 12976 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 12977 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 12978 }; 12979 static const uint32_t gainval[] = { 12980 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 12981 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 12982 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 12983 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 12984 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 12985 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 12986 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12987 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12988 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 12989 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 12990 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 12991 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 12992 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 12993 0x000000f1, 0x00000000, 0x00000000 12994 }; 12995 static const uint16_t gain[] = { 12996 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 12997 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 12998 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 12999 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13000 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13001 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13002 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13003 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13004 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13005 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13006 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13007 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13008 }; 13009 static const uint32_t papdeps[] = { 13010 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13011 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13012 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13013 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13014 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13015 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13016 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13017 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13018 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13019 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13020 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13021 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13022 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13023 }; 13024 static const uint32_t papdmult[] = { 13025 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13026 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13027 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13028 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13029 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13030 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13031 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13032 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13033 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13034 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13035 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13036 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13037 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13038 }; 13039 static const uint32_t gainidx_a0[] = { 13040 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13041 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13042 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13043 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13044 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13045 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13046 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13047 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13048 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13049 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13050 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13051 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13052 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13053 }; 13054 static const uint16_t auxgainidx_a0[] = { 13055 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13056 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13057 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13058 0x0002, 0x0014 13059 }; 13060 static const uint32_t gainval_a0[] = { 13061 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13062 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13063 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13064 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13065 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13066 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13067 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13068 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13069 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13070 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13071 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13072 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13073 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13074 0x000000f7, 0x00000000, 0x00000000 13075 }; 13076 static const uint16_t gain_a0[] = { 13077 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13078 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13079 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13080 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13081 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13082 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13083 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13084 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13085 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13086 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13087 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13088 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13089 }; 13090 13091 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13092 13093 for (i = 0; i < 704; i++) 13094 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13095 13096 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13097 bwn_tab_sigsq_tbl); 13098 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13099 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13100 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13101 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13102 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13103 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13104 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13105 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13106 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13107 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13108 bwn_tab_pllfrac_tbl); 13109 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13110 bwn_tabl_iqlocal_tbl); 13111 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13112 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13113 13114 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13115 (siba_get_chiprev(sc->sc_dev) == 0)) { 13116 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13117 gainidx_a0); 13118 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13119 auxgainidx_a0); 13120 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13121 gainval_a0); 13122 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13123 } 13124 } 13125 13126 static void 13127 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13128 { 13129 struct bwn_softc *sc = mac->mac_sc; 13130 struct ieee80211com *ic = &sc->sc_ic; 13131 static struct bwn_txgain_entry txgain_r2[] = { 13132 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13133 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13134 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13135 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13136 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13137 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13138 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13139 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13140 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13141 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13142 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13143 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13144 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13145 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13146 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13147 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13148 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13149 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13150 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13151 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13152 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13153 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13154 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13155 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13156 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13157 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13158 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13159 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13160 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13161 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13162 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13163 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13164 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13165 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13166 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13167 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13168 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13169 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13170 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13171 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13172 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13173 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13174 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13175 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13176 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13177 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13178 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13179 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13180 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13181 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13182 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13183 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13184 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13185 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13186 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13187 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13188 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13189 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13190 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13191 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13192 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13193 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13194 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13195 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13196 }; 13197 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13198 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13199 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13200 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13201 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13202 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13203 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13204 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13205 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13206 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13207 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13208 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13209 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13210 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13211 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13212 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13213 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13214 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13215 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13216 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13217 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13218 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13219 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13220 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13221 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13222 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13223 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13224 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13225 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13226 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13227 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13228 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13229 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13230 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13231 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13232 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13233 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13234 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13235 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13236 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13237 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13238 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13239 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13240 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13241 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13242 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13243 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13244 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13245 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13246 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13247 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13248 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13249 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13250 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13251 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13252 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13253 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13254 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13255 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13256 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13257 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13258 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13259 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13260 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13261 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13262 }; 13263 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13264 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13265 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13266 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13267 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13268 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13269 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13270 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13271 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13272 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13273 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13274 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13275 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13276 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13277 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13278 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13279 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13280 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13281 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13282 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13283 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13284 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13285 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13286 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13287 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13288 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13289 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13290 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13291 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13292 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13293 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13294 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13295 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13296 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13297 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13298 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13299 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13300 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13301 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13302 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13303 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13304 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13305 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13306 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13307 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13308 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13309 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13310 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13311 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13312 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13313 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13314 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13315 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13316 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13317 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13318 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13319 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13320 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13321 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13322 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13323 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13324 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13325 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13326 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13327 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13328 }; 13329 static struct bwn_txgain_entry txgain_r0[] = { 13330 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13331 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13332 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13333 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13334 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13335 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13336 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13337 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13338 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13339 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13340 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13341 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13342 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13343 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13344 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13345 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13346 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13347 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13348 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13349 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13350 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13351 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13352 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13353 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13354 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13355 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13356 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13357 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13358 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13359 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13360 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13361 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13362 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13363 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13364 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13365 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13366 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13367 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13368 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13369 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13370 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13371 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13372 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13373 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13374 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13375 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13376 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13377 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13378 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13379 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13380 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13381 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13382 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13383 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13384 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13385 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13386 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13387 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13388 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13389 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13390 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13391 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13392 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13393 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13394 }; 13395 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13396 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13397 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13398 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13399 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13400 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13401 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13402 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13403 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13404 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13405 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13406 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13407 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13408 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13409 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13410 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13411 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13412 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13413 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13414 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13415 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13416 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13417 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13418 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13419 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13420 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13421 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13422 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13423 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13424 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13425 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13426 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13427 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13428 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13429 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13430 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13431 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13432 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13433 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13434 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13435 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13436 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13437 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13438 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13439 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13440 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13441 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13442 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13443 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13444 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13445 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13446 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13447 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13448 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13449 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13450 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13451 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13452 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13453 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13454 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13455 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13456 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13457 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13458 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13459 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13460 }; 13461 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13462 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13463 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13464 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13465 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13466 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13467 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13468 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13469 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13470 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13471 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13472 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13473 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13474 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13475 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13476 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13477 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13478 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13479 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13480 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13481 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13482 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13483 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13484 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13485 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13486 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13487 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13488 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13489 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13490 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13491 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13492 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13493 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13494 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13495 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13496 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13497 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13498 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13499 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13500 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13501 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13502 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13503 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13504 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13505 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13506 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13507 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13508 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13509 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13510 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13511 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13512 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13513 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13514 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13515 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13516 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13517 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13518 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13519 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13520 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13521 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13522 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13523 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13524 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13525 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13526 }; 13527 static struct bwn_txgain_entry txgain_r1[] = { 13528 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13529 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13530 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13531 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13532 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13533 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13534 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13535 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13536 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13537 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13538 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13539 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13540 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13541 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13542 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13543 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13544 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13545 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13546 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13547 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13548 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13549 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13550 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13551 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13552 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13553 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13554 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13555 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13556 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13557 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13558 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13559 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13560 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13561 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13562 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13563 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13564 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13565 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13566 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13567 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13568 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13569 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13570 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13571 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13572 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13573 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13574 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13575 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13576 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13577 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13578 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13579 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13580 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13581 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13582 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13583 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13584 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13585 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13586 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13587 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13588 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13589 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13590 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13591 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13592 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13593 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13594 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13595 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13596 { 7, 11, 6, 0, 71 } 13597 }; 13598 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13599 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13600 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13601 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13602 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13603 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13604 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13605 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13606 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13607 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13608 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13609 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13610 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13611 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13612 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13613 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13614 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13615 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13616 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13617 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13618 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13619 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13620 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13621 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13622 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13623 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13624 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13625 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13626 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13627 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13628 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13629 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13630 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13631 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13632 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13633 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13634 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13635 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13636 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13637 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13638 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13639 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13640 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13641 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13642 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13643 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13644 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13645 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13646 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13647 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13648 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13649 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13650 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13651 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13652 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13653 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13654 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13655 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13656 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13657 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13658 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13659 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13660 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13661 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13662 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13663 }; 13664 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13665 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13666 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13667 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13668 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13669 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13670 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13671 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13672 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13673 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13674 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13675 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13676 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13677 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13678 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13679 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13680 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13681 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13682 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13683 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13684 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13685 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13686 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13687 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13688 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13689 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13690 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13691 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13692 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13693 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13694 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13695 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13696 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13697 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13698 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13699 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13700 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13701 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13702 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13703 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13704 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13705 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13706 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13707 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13708 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13709 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13710 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13711 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13712 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13713 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13714 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13715 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13716 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13717 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13718 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13719 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13720 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13721 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13722 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13723 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13724 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13725 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13726 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13727 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13728 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13729 }; 13730 13731 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13732 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13733 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13734 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13735 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13736 txgain_2ghz_r2); 13737 else 13738 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13739 txgain_5ghz_r2); 13740 return; 13741 } 13742 13743 if (mac->mac_phy.rev == 0) { 13744 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13745 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13746 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13747 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13748 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13749 txgain_2ghz_r0); 13750 else 13751 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13752 txgain_5ghz_r0); 13753 return; 13754 } 13755 13756 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13757 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13758 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13759 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13760 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13761 else 13762 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13763 } 13764 13765 static void 13766 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13767 { 13768 uint32_t offset, type; 13769 13770 type = BWN_TAB_GETTYPE(typeoffset); 13771 offset = BWN_TAB_GETOFFSET(typeoffset); 13772 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13773 13774 switch (type) { 13775 case BWN_TAB_8BIT: 13776 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13777 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13778 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13779 break; 13780 case BWN_TAB_16BIT: 13781 KASSERT(!(value & ~0xffff), 13782 ("%s:%d: fail", __func__, __LINE__)); 13783 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13784 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13785 break; 13786 case BWN_TAB_32BIT: 13787 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13788 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13789 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13790 break; 13791 default: 13792 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13793 } 13794 } 13795 13796 static int 13797 bwn_phy_lp_loopback(struct bwn_mac *mac) 13798 { 13799 struct bwn_phy_lp_iq_est ie; 13800 int i, index = -1; 13801 uint32_t tmp; 13802 13803 memset(&ie, 0, sizeof(ie)); 13804 13805 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13806 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13807 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13808 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13809 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13810 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13811 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13812 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13813 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13814 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13815 for (i = 0; i < 32; i++) { 13816 bwn_phy_lp_set_rxgain_idx(mac, i); 13817 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13818 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13819 continue; 13820 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13821 if ((tmp > 4000) && (tmp < 10000)) { 13822 index = i; 13823 break; 13824 } 13825 } 13826 bwn_phy_lp_ddfs_turnoff(mac); 13827 return (index); 13828 } 13829 13830 static void 13831 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13832 { 13833 13834 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13835 } 13836 13837 static void 13838 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13839 int incr1, int incr2, int scale_idx) 13840 { 13841 13842 bwn_phy_lp_ddfs_turnoff(mac); 13843 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13844 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13845 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13846 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13847 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13848 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13849 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 13850 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 13851 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 13852 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 13853 } 13854 13855 static uint8_t 13856 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 13857 struct bwn_phy_lp_iq_est *ie) 13858 { 13859 int i; 13860 13861 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 13862 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 13863 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 13864 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 13865 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 13866 13867 for (i = 0; i < 500; i++) { 13868 if (!(BWN_PHY_READ(mac, 13869 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 13870 break; 13871 DELAY(1000); 13872 } 13873 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 13874 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13875 return 0; 13876 } 13877 13878 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 13879 ie->ie_iqprod <<= 16; 13880 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 13881 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 13882 ie->ie_ipwr <<= 16; 13883 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 13884 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 13885 ie->ie_qpwr <<= 16; 13886 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 13887 13888 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13889 return 1; 13890 } 13891 13892 static uint32_t 13893 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 13894 { 13895 uint32_t offset, type, value; 13896 13897 type = BWN_TAB_GETTYPE(typeoffset); 13898 offset = BWN_TAB_GETOFFSET(typeoffset); 13899 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13900 13901 switch (type) { 13902 case BWN_TAB_8BIT: 13903 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13904 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 13905 break; 13906 case BWN_TAB_16BIT: 13907 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13908 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13909 break; 13910 case BWN_TAB_32BIT: 13911 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13912 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 13913 value <<= 16; 13914 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13915 break; 13916 default: 13917 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13918 value = 0; 13919 } 13920 13921 return (value); 13922 } 13923 13924 static void 13925 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 13926 { 13927 13928 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 13929 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 13930 } 13931 13932 static void 13933 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 13934 { 13935 uint16_t ctl; 13936 13937 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 13938 ctl |= dac << 7; 13939 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 13940 } 13941 13942 static void 13943 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 13944 { 13945 13946 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 13947 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 13948 } 13949 13950 static void 13951 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 13952 { 13953 13954 if (mac->mac_phy.rev < 2) 13955 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 13956 else { 13957 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 13958 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 13959 } 13960 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 13961 } 13962 13963 static uint16_t 13964 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 13965 { 13966 13967 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 13968 } 13969 13970 static uint8_t 13971 bwn_nbits(int32_t val) 13972 { 13973 uint32_t tmp; 13974 uint8_t nbits = 0; 13975 13976 for (tmp = abs(val); tmp != 0; tmp >>= 1) 13977 nbits++; 13978 return (nbits); 13979 } 13980 13981 static void 13982 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 13983 struct bwn_txgain_entry *table) 13984 { 13985 int i; 13986 13987 for (i = offset; i < count; i++) 13988 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 13989 } 13990 13991 static void 13992 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 13993 struct bwn_txgain_entry data) 13994 { 13995 13996 if (mac->mac_phy.rev >= 2) 13997 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 13998 else 13999 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14000 } 14001 14002 static void 14003 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14004 struct bwn_txgain_entry te) 14005 { 14006 struct bwn_softc *sc = mac->mac_sc; 14007 struct ieee80211com *ic = &sc->sc_ic; 14008 uint32_t tmp; 14009 14010 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14011 14012 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14013 if (mac->mac_phy.rev >= 3) { 14014 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14015 (0x10 << 24) : (0x70 << 24)); 14016 } else { 14017 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14018 (0x14 << 24) : (0x7f << 24)); 14019 } 14020 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14021 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14022 te.te_bbmult << 20 | te.te_dac << 28); 14023 } 14024 14025 static void 14026 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14027 struct bwn_txgain_entry te) 14028 { 14029 14030 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14031 14032 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14033 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14034 te.te_dac); 14035 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14036 } 14037 14038 static void 14039 bwn_sysctl_node(struct bwn_softc *sc) 14040 { 14041 device_t dev = sc->sc_dev; 14042 struct bwn_mac *mac; 14043 struct bwn_stats *stats; 14044 14045 /* XXX assume that count of MAC is only 1. */ 14046 14047 if ((mac = sc->sc_curmac) == NULL) 14048 return; 14049 stats = &mac->mac_stats; 14050 14051 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14052 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14053 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14054 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14055 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14056 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14057 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14058 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14059 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14060 14061 #ifdef BWN_DEBUG 14062 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14063 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14064 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14065 #endif 14066 } 14067 14068 static device_method_t bwn_methods[] = { 14069 /* Device interface */ 14070 DEVMETHOD(device_probe, bwn_probe), 14071 DEVMETHOD(device_attach, bwn_attach), 14072 DEVMETHOD(device_detach, bwn_detach), 14073 DEVMETHOD(device_suspend, bwn_suspend), 14074 DEVMETHOD(device_resume, bwn_resume), 14075 DEVMETHOD_END 14076 }; 14077 static driver_t bwn_driver = { 14078 "bwn", 14079 bwn_methods, 14080 sizeof(struct bwn_softc) 14081 }; 14082 static devclass_t bwn_devclass; 14083 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14084 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14085 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14086 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14087 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14088