1 /*- 2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * The Broadcom Wireless LAN controller driver. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/module.h> 40 #include <sys/kernel.h> 41 #include <sys/endian.h> 42 #include <sys/errno.h> 43 #include <sys/firmware.h> 44 #include <sys/lock.h> 45 #include <sys/mutex.h> 46 #include <machine/bus.h> 47 #include <machine/resource.h> 48 #include <sys/bus.h> 49 #include <sys/rman.h> 50 #include <sys/socket.h> 51 #include <sys/sockio.h> 52 53 #include <net/ethernet.h> 54 #include <net/if.h> 55 #include <net/if_var.h> 56 #include <net/if_arp.h> 57 #include <net/if_dl.h> 58 #include <net/if_llc.h> 59 #include <net/if_media.h> 60 #include <net/if_types.h> 61 62 #include <dev/pci/pcivar.h> 63 #include <dev/pci/pcireg.h> 64 #include <dev/siba/siba_ids.h> 65 #include <dev/siba/sibareg.h> 66 #include <dev/siba/sibavar.h> 67 68 #include <net80211/ieee80211_var.h> 69 #include <net80211/ieee80211_radiotap.h> 70 #include <net80211/ieee80211_regdomain.h> 71 #include <net80211/ieee80211_phy.h> 72 #include <net80211/ieee80211_ratectl.h> 73 74 #include <dev/bwn/if_bwnreg.h> 75 #include <dev/bwn/if_bwnvar.h> 76 77 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, 78 "Broadcom driver parameters"); 79 80 /* 81 * Tunable & sysctl variables. 82 */ 83 84 #ifdef BWN_DEBUG 85 static int bwn_debug = 0; 86 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0, 87 "Broadcom debugging printfs"); 88 enum { 89 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 90 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ 91 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */ 92 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */ 93 BWN_DEBUG_RESET = 0x00000010, /* reset processing */ 94 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */ 95 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */ 96 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */ 97 BWN_DEBUG_INTR = 0x00000100, /* ISR */ 98 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */ 99 BWN_DEBUG_NODE = 0x00000400, /* node management */ 100 BWN_DEBUG_LED = 0x00000800, /* led management */ 101 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */ 102 BWN_DEBUG_LO = 0x00002000, /* LO */ 103 BWN_DEBUG_FW = 0x00004000, /* firmware */ 104 BWN_DEBUG_WME = 0x00008000, /* WME */ 105 BWN_DEBUG_RF = 0x00010000, /* RF */ 106 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ 107 BWN_DEBUG_ANY = 0xffffffff 108 }; 109 #define DPRINTF(sc, m, fmt, ...) do { \ 110 if (sc->sc_debug & (m)) \ 111 printf(fmt, __VA_ARGS__); \ 112 } while (0) 113 #else 114 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 115 #endif 116 117 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 118 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 119 "uses Bad Frames Preemption"); 120 static int bwn_bluetooth = 1; 121 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 122 "turns on Bluetooth Coexistence"); 123 static int bwn_hwpctl = 0; 124 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 125 "uses H/W power control"); 126 static int bwn_msi_disable = 0; /* MSI disabled */ 127 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable); 128 static int bwn_usedma = 1; 129 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 130 "uses DMA"); 131 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 132 static int bwn_wme = 1; 133 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 134 "uses WME support"); 135 136 static void bwn_attach_pre(struct bwn_softc *); 137 static int bwn_attach_post(struct bwn_softc *); 138 static void bwn_sprom_bugfixes(device_t); 139 static int bwn_init(struct bwn_softc *); 140 static void bwn_parent(struct ieee80211com *); 141 static void bwn_start(struct bwn_softc *); 142 static int bwn_transmit(struct ieee80211com *, struct mbuf *); 143 static int bwn_attach_core(struct bwn_mac *); 144 static void bwn_reset_core(struct bwn_mac *, uint32_t); 145 static int bwn_phy_getinfo(struct bwn_mac *, int); 146 static int bwn_chiptest(struct bwn_mac *); 147 static int bwn_setup_channels(struct bwn_mac *, int, int); 148 static int bwn_phy_g_attach(struct bwn_mac *); 149 static void bwn_phy_g_detach(struct bwn_mac *); 150 static void bwn_phy_g_init_pre(struct bwn_mac *); 151 static int bwn_phy_g_prepare_hw(struct bwn_mac *); 152 static int bwn_phy_g_init(struct bwn_mac *); 153 static void bwn_phy_g_exit(struct bwn_mac *); 154 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t); 155 static void bwn_phy_g_write(struct bwn_mac *, uint16_t, 156 uint16_t); 157 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t); 158 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t, 159 uint16_t); 160 static int bwn_phy_g_hwpctl(struct bwn_mac *); 161 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int); 162 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t); 163 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *); 164 static void bwn_phy_g_set_antenna(struct bwn_mac *, int); 165 static int bwn_phy_g_im(struct bwn_mac *, int); 166 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int); 167 static void bwn_phy_g_set_txpwr(struct bwn_mac *); 168 static void bwn_phy_g_task_15s(struct bwn_mac *); 169 static void bwn_phy_g_task_60s(struct bwn_mac *); 170 static uint16_t bwn_phy_g_txctl(struct bwn_mac *); 171 static void bwn_phy_switch_analog(struct bwn_mac *, int); 172 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t); 173 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t, 174 uint16_t); 175 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t); 176 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t, 177 uint32_t); 178 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 179 uint16_t); 180 static void bwn_addchannels(struct ieee80211_channel [], int, int *, 181 const struct bwn_channelinfo *, int); 182 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 183 const struct ieee80211_bpf_params *); 184 static void bwn_updateslot(struct ieee80211com *); 185 static void bwn_update_promisc(struct ieee80211com *); 186 static void bwn_wme_init(struct bwn_mac *); 187 static int bwn_wme_update(struct ieee80211com *); 188 static void bwn_wme_clear(struct bwn_softc *); 189 static void bwn_wme_load(struct bwn_mac *); 190 static void bwn_wme_loadparams(struct bwn_mac *, 191 const struct wmeParams *, uint16_t); 192 static void bwn_scan_start(struct ieee80211com *); 193 static void bwn_scan_end(struct ieee80211com *); 194 static void bwn_set_channel(struct ieee80211com *); 195 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 196 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 197 const uint8_t [IEEE80211_ADDR_LEN], 198 const uint8_t [IEEE80211_ADDR_LEN]); 199 static void bwn_vap_delete(struct ieee80211vap *); 200 static void bwn_stop(struct bwn_softc *); 201 static int bwn_core_init(struct bwn_mac *); 202 static void bwn_core_start(struct bwn_mac *); 203 static void bwn_core_exit(struct bwn_mac *); 204 static void bwn_bt_disable(struct bwn_mac *); 205 static int bwn_chip_init(struct bwn_mac *); 206 static uint64_t bwn_hf_read(struct bwn_mac *); 207 static void bwn_hf_write(struct bwn_mac *, uint64_t); 208 static void bwn_set_txretry(struct bwn_mac *, int, int); 209 static void bwn_rate_init(struct bwn_mac *); 210 static void bwn_set_phytxctl(struct bwn_mac *); 211 static void bwn_spu_setdelay(struct bwn_mac *, int); 212 static void bwn_bt_enable(struct bwn_mac *); 213 static void bwn_set_macaddr(struct bwn_mac *); 214 static void bwn_crypt_init(struct bwn_mac *); 215 static void bwn_chip_exit(struct bwn_mac *); 216 static int bwn_fw_fillinfo(struct bwn_mac *); 217 static int bwn_fw_loaducode(struct bwn_mac *); 218 static int bwn_gpio_init(struct bwn_mac *); 219 static int bwn_fw_loadinitvals(struct bwn_mac *); 220 static int bwn_phy_init(struct bwn_mac *); 221 static void bwn_set_txantenna(struct bwn_mac *, int); 222 static void bwn_set_opmode(struct bwn_mac *); 223 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 224 static uint8_t bwn_plcp_getcck(const uint8_t); 225 static uint8_t bwn_plcp_getofdm(const uint8_t); 226 static void bwn_pio_init(struct bwn_mac *); 227 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 228 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 229 int); 230 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 231 struct bwn_pio_rxqueue *, int); 232 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 233 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 234 uint16_t); 235 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 236 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 237 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 238 static void bwn_pio_handle_txeof(struct bwn_mac *, 239 const struct bwn_txstatus *); 240 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 241 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 242 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 243 uint16_t); 244 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 245 uint32_t); 246 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 247 struct mbuf *); 248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 249 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 250 struct bwn_pio_txqueue *, uint32_t, const void *, int); 251 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 252 uint16_t, uint32_t); 253 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 254 struct bwn_pio_txqueue *, uint16_t, const void *, int); 255 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 256 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 258 uint16_t, struct bwn_pio_txpkt **); 259 static void bwn_dma_init(struct bwn_mac *); 260 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 261 static int bwn_dma_mask2type(uint64_t); 262 static uint64_t bwn_dma_mask(struct bwn_mac *); 263 static uint16_t bwn_dma_base(int, int); 264 static void bwn_dma_ringfree(struct bwn_dma_ring **); 265 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 266 int, struct bwn_dmadesc_generic **, 267 struct bwn_dmadesc_meta **); 268 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 269 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 270 int, int); 271 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 272 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 273 static void bwn_dma_32_resume(struct bwn_dma_ring *); 274 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 275 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 276 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 277 int, struct bwn_dmadesc_generic **, 278 struct bwn_dmadesc_meta **); 279 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 280 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 281 int, int); 282 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 283 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 284 static void bwn_dma_64_resume(struct bwn_dma_ring *); 285 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 286 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 287 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 288 static void bwn_dma_setup(struct bwn_dma_ring *); 289 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 290 static void bwn_dma_cleanup(struct bwn_dma_ring *); 291 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 292 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 293 static void bwn_dma_rx(struct bwn_dma_ring *); 294 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 295 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 296 struct bwn_dmadesc_meta *); 297 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 298 static int bwn_dma_gettype(struct bwn_mac *); 299 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 300 static int bwn_dma_freeslot(struct bwn_dma_ring *); 301 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 302 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 303 static int bwn_dma_newbuf(struct bwn_dma_ring *, 304 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 305 int); 306 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 307 bus_size_t, int); 308 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 309 static void bwn_dma_handle_txeof(struct bwn_mac *, 310 const struct bwn_txstatus *); 311 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 312 struct mbuf *); 313 static int bwn_dma_getslot(struct bwn_dma_ring *); 314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 315 uint8_t); 316 static int bwn_dma_attach(struct bwn_mac *); 317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 318 int, int, int); 319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 320 const struct bwn_txstatus *, uint16_t, int *); 321 static void bwn_dma_free(struct bwn_mac *); 322 static void bwn_phy_g_init_sub(struct bwn_mac *); 323 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 324 static void bwn_phy_init_b5(struct bwn_mac *); 325 static void bwn_phy_init_b6(struct bwn_mac *); 326 static void bwn_phy_init_a(struct bwn_mac *); 327 static void bwn_loopback_calcgain(struct bwn_mac *); 328 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 329 static void bwn_lo_g_init(struct bwn_mac *); 330 static void bwn_lo_g_adjust(struct bwn_mac *); 331 static void bwn_lo_get_powervector(struct bwn_mac *); 332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 333 const struct bwn_bbatt *, const struct bwn_rfatt *); 334 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 335 static void bwn_phy_hwpctl_init(struct bwn_mac *); 336 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 337 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 338 const struct bwn_bbatt *, const struct bwn_rfatt *, 339 uint8_t); 340 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 341 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 342 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 343 static void bwn_wa_init(struct bwn_mac *); 344 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 345 uint16_t); 346 static void bwn_dummy_transmission(struct bwn_mac *, int, int); 347 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 348 uint32_t); 349 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 350 uint16_t); 351 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 352 static void bwn_mac_suspend(struct bwn_mac *); 353 static void bwn_mac_enable(struct bwn_mac *); 354 static void bwn_psctl(struct bwn_mac *, uint32_t); 355 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 356 static void bwn_nrssi_offset(struct bwn_mac *); 357 static void bwn_nrssi_threshold(struct bwn_mac *); 358 static void bwn_nrssi_slope_11g(struct bwn_mac *); 359 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 360 int16_t); 361 static void bwn_set_original_gains(struct bwn_mac *); 362 static void bwn_hwpctl_early_init(struct bwn_mac *); 363 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 364 static uint16_t bwn_phy_g_chan2freq(uint8_t); 365 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 366 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 367 const char *, struct bwn_fwfile *); 368 static void bwn_release_firmware(struct bwn_mac *); 369 static void bwn_do_release_fw(struct bwn_fwfile *); 370 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 371 static int bwn_fwinitvals_write(struct bwn_mac *, 372 const struct bwn_fwinitvals *, size_t, size_t); 373 static int bwn_switch_channel(struct bwn_mac *, int); 374 static uint16_t bwn_ant2phy(int); 375 static void bwn_mac_write_bssid(struct bwn_mac *); 376 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 377 const uint8_t *); 378 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 379 const uint8_t *, size_t, const uint8_t *); 380 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 381 const uint8_t *); 382 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 383 const uint8_t *); 384 static void bwn_phy_exit(struct bwn_mac *); 385 static void bwn_core_stop(struct bwn_mac *); 386 static int bwn_switch_band(struct bwn_softc *, 387 struct ieee80211_channel *); 388 static void bwn_phy_reset(struct bwn_mac *); 389 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 390 static void bwn_set_pretbtt(struct bwn_mac *); 391 static int bwn_intr(void *); 392 static void bwn_intrtask(void *, int); 393 static void bwn_restart(struct bwn_mac *, const char *); 394 static void bwn_intr_ucode_debug(struct bwn_mac *); 395 static void bwn_intr_tbtt_indication(struct bwn_mac *); 396 static void bwn_intr_atim_end(struct bwn_mac *); 397 static void bwn_intr_beacon(struct bwn_mac *); 398 static void bwn_intr_pmq(struct bwn_mac *); 399 static void bwn_intr_noise(struct bwn_mac *); 400 static void bwn_intr_txeof(struct bwn_mac *); 401 static void bwn_hwreset(void *, int); 402 static void bwn_handle_fwpanic(struct bwn_mac *); 403 static void bwn_load_beacon0(struct bwn_mac *); 404 static void bwn_load_beacon1(struct bwn_mac *); 405 static uint32_t bwn_jssi_read(struct bwn_mac *); 406 static void bwn_noise_gensample(struct bwn_mac *); 407 static void bwn_handle_txeof(struct bwn_mac *, 408 const struct bwn_txstatus *); 409 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 410 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 411 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 412 struct mbuf *); 413 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 414 static int bwn_set_txhdr(struct bwn_mac *, 415 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 416 uint16_t); 417 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 418 const uint8_t); 419 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 420 static uint8_t bwn_get_fbrate(uint8_t); 421 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 422 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 423 static void bwn_phy_lock(struct bwn_mac *); 424 static void bwn_phy_unlock(struct bwn_mac *); 425 static void bwn_rf_lock(struct bwn_mac *); 426 static void bwn_rf_unlock(struct bwn_mac *); 427 static void bwn_txpwr(void *, int); 428 static void bwn_tasks(void *); 429 static void bwn_task_15s(struct bwn_mac *); 430 static void bwn_task_30s(struct bwn_mac *); 431 static void bwn_task_60s(struct bwn_mac *); 432 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 433 uint8_t); 434 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 435 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 436 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 437 int, int); 438 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 439 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 440 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 441 static void bwn_watchdog(void *); 442 static void bwn_dma_stop(struct bwn_mac *); 443 static void bwn_pio_stop(struct bwn_mac *); 444 static void bwn_dma_ringstop(struct bwn_dma_ring **); 445 static void bwn_led_attach(struct bwn_mac *); 446 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 447 static void bwn_led_event(struct bwn_mac *, int); 448 static void bwn_led_blink_start(struct bwn_mac *, int, int); 449 static void bwn_led_blink_next(void *); 450 static void bwn_led_blink_end(void *); 451 static void bwn_rfswitch(void *); 452 static void bwn_rf_turnon(struct bwn_mac *); 453 static void bwn_rf_turnoff(struct bwn_mac *); 454 static void bwn_phy_lp_init_pre(struct bwn_mac *); 455 static int bwn_phy_lp_init(struct bwn_mac *); 456 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 457 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 458 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 459 uint16_t); 460 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 461 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 462 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 463 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 464 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 465 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 466 static void bwn_phy_lp_task_60s(struct bwn_mac *); 467 static void bwn_phy_lp_readsprom(struct bwn_mac *); 468 static void bwn_phy_lp_bbinit(struct bwn_mac *); 469 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 470 static void bwn_phy_lp_calib(struct bwn_mac *); 471 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 472 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 473 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 474 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 475 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 476 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 477 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 478 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 479 static void bwn_phy_lp_bugfix(struct bwn_mac *); 480 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 481 static void bwn_phy_lp_tblinit(struct bwn_mac *); 482 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 483 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 484 static void bwn_phy_lp_b2062_init(struct bwn_mac *); 485 static void bwn_phy_lp_b2063_init(struct bwn_mac *); 486 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 487 static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 488 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 489 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 490 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 491 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 492 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 493 const void *); 494 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 495 static struct bwn_txgain 496 bwn_phy_lp_get_txgain(struct bwn_mac *); 497 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 498 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 499 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 500 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 501 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 502 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 503 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 504 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 505 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 506 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 507 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 508 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 509 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 510 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 511 static int bwn_phy_lp_loopback(struct bwn_mac *); 512 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 513 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 514 int); 515 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 516 struct bwn_phy_lp_iq_est *); 517 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 518 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 519 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 520 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 521 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 522 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 523 static uint8_t bwn_nbits(int32_t); 524 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 525 struct bwn_txgain_entry *); 526 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 527 struct bwn_txgain_entry); 528 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 529 struct bwn_txgain_entry); 530 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 531 struct bwn_txgain_entry); 532 static void bwn_sysctl_node(struct bwn_softc *); 533 534 static struct resource_spec bwn_res_spec_legacy[] = { 535 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 536 { -1, 0, 0 } 537 }; 538 539 static struct resource_spec bwn_res_spec_msi[] = { 540 { SYS_RES_IRQ, 1, RF_ACTIVE }, 541 { -1, 0, 0 } 542 }; 543 544 static const struct bwn_channelinfo bwn_chantable_bg = { 545 .channels = { 546 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 547 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 548 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 549 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 550 { 2472, 13, 30 }, { 2484, 14, 30 } }, 551 .nchannels = 14 552 }; 553 554 static const struct bwn_channelinfo bwn_chantable_a = { 555 .channels = { 556 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 557 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 558 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 559 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 560 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 561 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 562 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 563 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 564 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 565 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 566 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 567 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 568 { 6080, 216, 30 } }, 569 .nchannels = 37 570 }; 571 572 static const struct bwn_channelinfo bwn_chantable_n = { 573 .channels = { 574 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 575 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 576 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 577 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 578 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 579 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 580 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 581 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 582 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 583 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 584 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 585 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 586 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 587 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 588 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 589 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 590 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 591 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 592 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 593 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 594 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 595 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 596 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 597 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 598 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 599 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 600 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 601 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 602 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 603 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 604 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 605 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 606 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 607 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 608 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 609 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 610 { 6130, 226, 30 }, { 6140, 228, 30 } }, 611 .nchannels = 110 612 }; 613 614 static const uint8_t bwn_b2063_chantable_data[33][12] = { 615 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 616 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 617 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 618 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 619 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 620 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 621 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 622 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 623 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 624 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 625 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 626 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 627 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 628 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 629 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 630 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 631 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 632 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 633 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 634 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 635 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 636 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 637 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 638 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 639 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 640 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 641 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 642 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 643 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 645 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 646 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 647 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 648 }; 649 650 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 651 { 1, 2412, bwn_b2063_chantable_data[0] }, 652 { 2, 2417, bwn_b2063_chantable_data[0] }, 653 { 3, 2422, bwn_b2063_chantable_data[0] }, 654 { 4, 2427, bwn_b2063_chantable_data[1] }, 655 { 5, 2432, bwn_b2063_chantable_data[1] }, 656 { 6, 2437, bwn_b2063_chantable_data[1] }, 657 { 7, 2442, bwn_b2063_chantable_data[1] }, 658 { 8, 2447, bwn_b2063_chantable_data[1] }, 659 { 9, 2452, bwn_b2063_chantable_data[2] }, 660 { 10, 2457, bwn_b2063_chantable_data[2] }, 661 { 11, 2462, bwn_b2063_chantable_data[3] }, 662 { 12, 2467, bwn_b2063_chantable_data[3] }, 663 { 13, 2472, bwn_b2063_chantable_data[3] }, 664 { 14, 2484, bwn_b2063_chantable_data[4] }, 665 { 34, 5170, bwn_b2063_chantable_data[5] }, 666 { 36, 5180, bwn_b2063_chantable_data[6] }, 667 { 38, 5190, bwn_b2063_chantable_data[7] }, 668 { 40, 5200, bwn_b2063_chantable_data[8] }, 669 { 42, 5210, bwn_b2063_chantable_data[9] }, 670 { 44, 5220, bwn_b2063_chantable_data[10] }, 671 { 46, 5230, bwn_b2063_chantable_data[11] }, 672 { 48, 5240, bwn_b2063_chantable_data[12] }, 673 { 52, 5260, bwn_b2063_chantable_data[13] }, 674 { 56, 5280, bwn_b2063_chantable_data[14] }, 675 { 60, 5300, bwn_b2063_chantable_data[14] }, 676 { 64, 5320, bwn_b2063_chantable_data[15] }, 677 { 100, 5500, bwn_b2063_chantable_data[16] }, 678 { 104, 5520, bwn_b2063_chantable_data[17] }, 679 { 108, 5540, bwn_b2063_chantable_data[18] }, 680 { 112, 5560, bwn_b2063_chantable_data[19] }, 681 { 116, 5580, bwn_b2063_chantable_data[20] }, 682 { 120, 5600, bwn_b2063_chantable_data[21] }, 683 { 124, 5620, bwn_b2063_chantable_data[21] }, 684 { 128, 5640, bwn_b2063_chantable_data[22] }, 685 { 132, 5660, bwn_b2063_chantable_data[22] }, 686 { 136, 5680, bwn_b2063_chantable_data[22] }, 687 { 140, 5700, bwn_b2063_chantable_data[23] }, 688 { 149, 5745, bwn_b2063_chantable_data[23] }, 689 { 153, 5765, bwn_b2063_chantable_data[23] }, 690 { 157, 5785, bwn_b2063_chantable_data[23] }, 691 { 161, 5805, bwn_b2063_chantable_data[23] }, 692 { 165, 5825, bwn_b2063_chantable_data[23] }, 693 { 184, 4920, bwn_b2063_chantable_data[24] }, 694 { 188, 4940, bwn_b2063_chantable_data[25] }, 695 { 192, 4960, bwn_b2063_chantable_data[26] }, 696 { 196, 4980, bwn_b2063_chantable_data[27] }, 697 { 200, 5000, bwn_b2063_chantable_data[28] }, 698 { 204, 5020, bwn_b2063_chantable_data[29] }, 699 { 208, 5040, bwn_b2063_chantable_data[30] }, 700 { 212, 5060, bwn_b2063_chantable_data[31] }, 701 { 216, 5080, bwn_b2063_chantable_data[32] } 702 }; 703 704 static const uint8_t bwn_b2062_chantable_data[22][12] = { 705 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 706 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 707 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 708 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 718 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 719 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 720 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 721 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 722 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 723 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 724 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 726 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 727 }; 728 729 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 730 { 1, 2412, bwn_b2062_chantable_data[0] }, 731 { 2, 2417, bwn_b2062_chantable_data[0] }, 732 { 3, 2422, bwn_b2062_chantable_data[0] }, 733 { 4, 2427, bwn_b2062_chantable_data[0] }, 734 { 5, 2432, bwn_b2062_chantable_data[0] }, 735 { 6, 2437, bwn_b2062_chantable_data[0] }, 736 { 7, 2442, bwn_b2062_chantable_data[0] }, 737 { 8, 2447, bwn_b2062_chantable_data[0] }, 738 { 9, 2452, bwn_b2062_chantable_data[0] }, 739 { 10, 2457, bwn_b2062_chantable_data[0] }, 740 { 11, 2462, bwn_b2062_chantable_data[0] }, 741 { 12, 2467, bwn_b2062_chantable_data[0] }, 742 { 13, 2472, bwn_b2062_chantable_data[0] }, 743 { 14, 2484, bwn_b2062_chantable_data[0] }, 744 { 34, 5170, bwn_b2062_chantable_data[1] }, 745 { 38, 5190, bwn_b2062_chantable_data[2] }, 746 { 42, 5210, bwn_b2062_chantable_data[2] }, 747 { 46, 5230, bwn_b2062_chantable_data[3] }, 748 { 36, 5180, bwn_b2062_chantable_data[4] }, 749 { 40, 5200, bwn_b2062_chantable_data[5] }, 750 { 44, 5220, bwn_b2062_chantable_data[6] }, 751 { 48, 5240, bwn_b2062_chantable_data[3] }, 752 { 52, 5260, bwn_b2062_chantable_data[3] }, 753 { 56, 5280, bwn_b2062_chantable_data[3] }, 754 { 60, 5300, bwn_b2062_chantable_data[7] }, 755 { 64, 5320, bwn_b2062_chantable_data[8] }, 756 { 100, 5500, bwn_b2062_chantable_data[9] }, 757 { 104, 5520, bwn_b2062_chantable_data[10] }, 758 { 108, 5540, bwn_b2062_chantable_data[10] }, 759 { 112, 5560, bwn_b2062_chantable_data[10] }, 760 { 116, 5580, bwn_b2062_chantable_data[11] }, 761 { 120, 5600, bwn_b2062_chantable_data[12] }, 762 { 124, 5620, bwn_b2062_chantable_data[12] }, 763 { 128, 5640, bwn_b2062_chantable_data[12] }, 764 { 132, 5660, bwn_b2062_chantable_data[12] }, 765 { 136, 5680, bwn_b2062_chantable_data[12] }, 766 { 140, 5700, bwn_b2062_chantable_data[12] }, 767 { 149, 5745, bwn_b2062_chantable_data[12] }, 768 { 153, 5765, bwn_b2062_chantable_data[12] }, 769 { 157, 5785, bwn_b2062_chantable_data[12] }, 770 { 161, 5805, bwn_b2062_chantable_data[12] }, 771 { 165, 5825, bwn_b2062_chantable_data[12] }, 772 { 184, 4920, bwn_b2062_chantable_data[13] }, 773 { 188, 4940, bwn_b2062_chantable_data[14] }, 774 { 192, 4960, bwn_b2062_chantable_data[15] }, 775 { 196, 4980, bwn_b2062_chantable_data[16] }, 776 { 200, 5000, bwn_b2062_chantable_data[17] }, 777 { 204, 5020, bwn_b2062_chantable_data[18] }, 778 { 208, 5040, bwn_b2062_chantable_data[19] }, 779 { 212, 5060, bwn_b2062_chantable_data[20] }, 780 { 216, 5080, bwn_b2062_chantable_data[21] } 781 }; 782 783 /* for LP PHY */ 784 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 785 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 786 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 787 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 788 { 13, -66, 13 }, { 14, -66, 13 }, 789 }; 790 791 /* for LP PHY */ 792 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 793 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 794 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 795 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 796 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 797 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 798 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 799 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 800 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 801 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 802 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 803 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 804 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 805 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 806 }; 807 808 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 809 810 static const uint8_t bwn_tab_sigsq_tbl[] = { 811 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 812 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 813 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 814 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 815 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 816 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 817 }; 818 819 static const uint8_t bwn_tab_pllfrac_tbl[] = { 820 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 821 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 822 }; 823 824 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 825 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 826 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 827 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 829 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 830 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 831 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 0x4000, 0x0000, 0x0000, 835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 837 }; 838 839 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 840 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 841 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 842 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 843 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 844 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 845 846 #define VENDOR_LED_ACT(vendor) \ 847 { \ 848 .vid = PCI_VENDOR_##vendor, \ 849 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 850 } 851 852 static const struct { 853 uint16_t vid; 854 uint8_t led_act[BWN_LED_MAX]; 855 } bwn_vendor_led_act[] = { 856 VENDOR_LED_ACT(COMPAQ), 857 VENDOR_LED_ACT(ASUSTEK) 858 }; 859 860 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 861 { BWN_VENDOR_LED_ACT_DEFAULT }; 862 863 #undef VENDOR_LED_ACT 864 865 static const struct { 866 int on_dur; 867 int off_dur; 868 } bwn_led_duration[109] = { 869 [0] = { 400, 100 }, 870 [2] = { 150, 75 }, 871 [4] = { 90, 45 }, 872 [11] = { 66, 34 }, 873 [12] = { 53, 26 }, 874 [18] = { 42, 21 }, 875 [22] = { 35, 17 }, 876 [24] = { 32, 16 }, 877 [36] = { 21, 10 }, 878 [48] = { 16, 8 }, 879 [72] = { 11, 5 }, 880 [96] = { 9, 4 }, 881 [108] = { 7, 3 } 882 }; 883 884 static const uint16_t bwn_wme_shm_offsets[] = { 885 [0] = BWN_WME_BESTEFFORT, 886 [1] = BWN_WME_BACKGROUND, 887 [2] = BWN_WME_VOICE, 888 [3] = BWN_WME_VIDEO, 889 }; 890 891 static const struct siba_devid bwn_devs[] = { 892 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 893 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 894 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 895 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 896 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 897 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 898 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 899 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 900 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 901 }; 902 903 static int 904 bwn_probe(device_t dev) 905 { 906 int i; 907 908 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 909 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 910 siba_get_device(dev) == bwn_devs[i].sd_device && 911 siba_get_revid(dev) == bwn_devs[i].sd_rev) 912 return (BUS_PROBE_DEFAULT); 913 } 914 915 return (ENXIO); 916 } 917 918 static int 919 bwn_attach(device_t dev) 920 { 921 struct bwn_mac *mac; 922 struct bwn_softc *sc = device_get_softc(dev); 923 int error, i, msic, reg; 924 925 sc->sc_dev = dev; 926 #ifdef BWN_DEBUG 927 sc->sc_debug = bwn_debug; 928 #endif 929 930 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 931 bwn_attach_pre(sc); 932 bwn_sprom_bugfixes(dev); 933 sc->sc_flags |= BWN_FLAG_ATTACHED; 934 } 935 936 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 937 if (siba_get_pci_device(dev) != 0x4313 && 938 siba_get_pci_device(dev) != 0x431a && 939 siba_get_pci_device(dev) != 0x4321) { 940 device_printf(sc->sc_dev, 941 "skip 802.11 cores\n"); 942 return (ENODEV); 943 } 944 } 945 946 mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO); 947 mac->mac_sc = sc; 948 mac->mac_status = BWN_MAC_STATUS_UNINIT; 949 if (bwn_bfp != 0) 950 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 951 952 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 953 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 954 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 955 956 error = bwn_attach_core(mac); 957 if (error) 958 goto fail0; 959 bwn_led_attach(mac); 960 961 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 962 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 963 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 964 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 965 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 966 mac->mac_phy.rf_rev); 967 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 968 device_printf(sc->sc_dev, "DMA (%d bits)\n", 969 mac->mac_method.dma.dmatype); 970 else 971 device_printf(sc->sc_dev, "PIO\n"); 972 973 /* 974 * setup PCI resources and interrupt. 975 */ 976 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { 977 msic = pci_msi_count(dev); 978 if (bootverbose) 979 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 980 } else 981 msic = 0; 982 983 mac->mac_intr_spec = bwn_res_spec_legacy; 984 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 985 if (pci_alloc_msi(dev, &msic) == 0) { 986 device_printf(sc->sc_dev, 987 "Using %d MSI messages\n", msic); 988 mac->mac_intr_spec = bwn_res_spec_msi; 989 mac->mac_msi = 1; 990 } 991 } 992 993 error = bus_alloc_resources(dev, mac->mac_intr_spec, 994 mac->mac_res_irq); 995 if (error) { 996 device_printf(sc->sc_dev, 997 "couldn't allocate IRQ resources (%d)\n", error); 998 goto fail1; 999 } 1000 1001 if (mac->mac_msi == 0) 1002 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1003 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1004 &mac->mac_intrhand[0]); 1005 else { 1006 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1007 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1008 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1009 &mac->mac_intrhand[i]); 1010 if (error != 0) { 1011 device_printf(sc->sc_dev, 1012 "couldn't setup interrupt (%d)\n", error); 1013 break; 1014 } 1015 } 1016 } 1017 1018 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1019 1020 /* 1021 * calls attach-post routine 1022 */ 1023 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1024 bwn_attach_post(sc); 1025 1026 return (0); 1027 fail1: 1028 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1029 pci_release_msi(dev); 1030 fail0: 1031 free(mac, M_DEVBUF); 1032 return (error); 1033 } 1034 1035 static int 1036 bwn_is_valid_ether_addr(uint8_t *addr) 1037 { 1038 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1039 1040 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1041 return (FALSE); 1042 1043 return (TRUE); 1044 } 1045 1046 static int 1047 bwn_attach_post(struct bwn_softc *sc) 1048 { 1049 struct ieee80211com *ic = &sc->sc_ic; 1050 1051 ic->ic_softc = sc; 1052 ic->ic_name = device_get_nameunit(sc->sc_dev); 1053 /* XXX not right but it's not used anywhere important */ 1054 ic->ic_phytype = IEEE80211_T_OFDM; 1055 ic->ic_opmode = IEEE80211_M_STA; 1056 ic->ic_caps = 1057 IEEE80211_C_STA /* station mode supported */ 1058 | IEEE80211_C_MONITOR /* monitor mode */ 1059 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1060 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1061 | IEEE80211_C_SHSLOT /* short slot time supported */ 1062 | IEEE80211_C_WME /* WME/WMM supported */ 1063 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1064 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1065 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1066 ; 1067 1068 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1069 1070 IEEE80211_ADDR_COPY(ic->ic_macaddr, 1071 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1072 siba_sprom_get_mac_80211a(sc->sc_dev) : 1073 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1074 1075 /* call MI attach routine. */ 1076 ieee80211_ifattach(ic); 1077 1078 ic->ic_headroom = sizeof(struct bwn_txhdr); 1079 1080 /* override default methods */ 1081 ic->ic_raw_xmit = bwn_raw_xmit; 1082 ic->ic_updateslot = bwn_updateslot; 1083 ic->ic_update_promisc = bwn_update_promisc; 1084 ic->ic_wme.wme_update = bwn_wme_update; 1085 ic->ic_scan_start = bwn_scan_start; 1086 ic->ic_scan_end = bwn_scan_end; 1087 ic->ic_set_channel = bwn_set_channel; 1088 ic->ic_vap_create = bwn_vap_create; 1089 ic->ic_vap_delete = bwn_vap_delete; 1090 ic->ic_transmit = bwn_transmit; 1091 ic->ic_parent = bwn_parent; 1092 1093 ieee80211_radiotap_attach(ic, 1094 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1095 BWN_TX_RADIOTAP_PRESENT, 1096 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1097 BWN_RX_RADIOTAP_PRESENT); 1098 1099 bwn_sysctl_node(sc); 1100 1101 if (bootverbose) 1102 ieee80211_announce(ic); 1103 return (0); 1104 } 1105 1106 static void 1107 bwn_phy_detach(struct bwn_mac *mac) 1108 { 1109 1110 if (mac->mac_phy.detach != NULL) 1111 mac->mac_phy.detach(mac); 1112 } 1113 1114 static int 1115 bwn_detach(device_t dev) 1116 { 1117 struct bwn_softc *sc = device_get_softc(dev); 1118 struct bwn_mac *mac = sc->sc_curmac; 1119 struct ieee80211com *ic = &sc->sc_ic; 1120 int i; 1121 1122 sc->sc_flags |= BWN_FLAG_INVALID; 1123 1124 if (device_is_attached(sc->sc_dev)) { 1125 BWN_LOCK(sc); 1126 bwn_stop(sc); 1127 BWN_UNLOCK(sc); 1128 bwn_dma_free(mac); 1129 callout_drain(&sc->sc_led_blink_ch); 1130 callout_drain(&sc->sc_rfswitch_ch); 1131 callout_drain(&sc->sc_task_ch); 1132 callout_drain(&sc->sc_watchdog_ch); 1133 bwn_phy_detach(mac); 1134 ieee80211_draintask(ic, &mac->mac_hwreset); 1135 ieee80211_draintask(ic, &mac->mac_txpower); 1136 ieee80211_ifdetach(ic); 1137 } 1138 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1139 taskqueue_free(sc->sc_tq); 1140 1141 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1142 if (mac->mac_intrhand[i] != NULL) { 1143 bus_teardown_intr(dev, mac->mac_res_irq[i], 1144 mac->mac_intrhand[i]); 1145 mac->mac_intrhand[i] = NULL; 1146 } 1147 } 1148 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1149 if (mac->mac_msi != 0) 1150 pci_release_msi(dev); 1151 mbufq_drain(&sc->sc_snd); 1152 BWN_LOCK_DESTROY(sc); 1153 return (0); 1154 } 1155 1156 static void 1157 bwn_attach_pre(struct bwn_softc *sc) 1158 { 1159 1160 BWN_LOCK_INIT(sc); 1161 TAILQ_INIT(&sc->sc_maclist); 1162 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1163 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1164 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1165 mbufq_init(&sc->sc_snd, ifqmaxlen); 1166 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1167 taskqueue_thread_enqueue, &sc->sc_tq); 1168 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1169 "%s taskq", device_get_nameunit(sc->sc_dev)); 1170 } 1171 1172 static void 1173 bwn_sprom_bugfixes(device_t dev) 1174 { 1175 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1176 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1177 (siba_get_pci_device(dev) == _device) && \ 1178 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1179 (siba_get_pci_subdevice(dev) == _subdevice)) 1180 1181 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1182 siba_get_pci_subdevice(dev) == 0x4e && 1183 siba_get_pci_revid(dev) > 0x40) 1184 siba_sprom_set_bf_lo(dev, 1185 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1186 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1187 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1188 siba_sprom_set_bf_lo(dev, 1189 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1190 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1191 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1192 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1193 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1194 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1195 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1196 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1197 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1198 siba_sprom_set_bf_lo(dev, 1199 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1200 } 1201 #undef BWN_ISDEV 1202 } 1203 1204 static void 1205 bwn_parent(struct ieee80211com *ic) 1206 { 1207 struct bwn_softc *sc = ic->ic_softc; 1208 int startall = 0; 1209 1210 BWN_LOCK(sc); 1211 if (ic->ic_nrunning > 0) { 1212 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { 1213 bwn_init(sc); 1214 startall = 1; 1215 } else 1216 bwn_update_promisc(ic); 1217 } else if (sc->sc_flags & BWN_FLAG_RUNNING) 1218 bwn_stop(sc); 1219 BWN_UNLOCK(sc); 1220 1221 if (startall) 1222 ieee80211_start_all(ic); 1223 } 1224 1225 static int 1226 bwn_transmit(struct ieee80211com *ic, struct mbuf *m) 1227 { 1228 struct bwn_softc *sc = ic->ic_softc; 1229 int error; 1230 1231 BWN_LOCK(sc); 1232 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { 1233 BWN_UNLOCK(sc); 1234 return (ENXIO); 1235 } 1236 error = mbufq_enqueue(&sc->sc_snd, m); 1237 if (error) { 1238 BWN_UNLOCK(sc); 1239 return (error); 1240 } 1241 bwn_start(sc); 1242 BWN_UNLOCK(sc); 1243 return (0); 1244 } 1245 1246 static void 1247 bwn_start(struct bwn_softc *sc) 1248 { 1249 struct bwn_mac *mac = sc->sc_curmac; 1250 struct ieee80211_frame *wh; 1251 struct ieee80211_node *ni; 1252 struct ieee80211_key *k; 1253 struct mbuf *m; 1254 1255 BWN_ASSERT_LOCKED(sc); 1256 1257 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL || 1258 mac->mac_status < BWN_MAC_STATUS_STARTED) 1259 return; 1260 1261 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 1262 if (bwn_tx_isfull(sc, m)) 1263 break; 1264 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1265 if (ni == NULL) { 1266 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1267 m_freem(m); 1268 counter_u64_add(sc->sc_ic.ic_oerrors, 1); 1269 continue; 1270 } 1271 wh = mtod(m, struct ieee80211_frame *); 1272 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1273 k = ieee80211_crypto_encap(ni, m); 1274 if (k == NULL) { 1275 if_inc_counter(ni->ni_vap->iv_ifp, 1276 IFCOUNTER_OERRORS, 1); 1277 ieee80211_free_node(ni); 1278 m_freem(m); 1279 continue; 1280 } 1281 } 1282 wh = NULL; /* Catch any invalid use */ 1283 if (bwn_tx_start(sc, ni, m) != 0) { 1284 if (ni != NULL) { 1285 if_inc_counter(ni->ni_vap->iv_ifp, 1286 IFCOUNTER_OERRORS, 1); 1287 ieee80211_free_node(ni); 1288 } 1289 continue; 1290 } 1291 sc->sc_watchdog_timer = 5; 1292 } 1293 } 1294 1295 static int 1296 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1297 { 1298 struct bwn_dma_ring *dr; 1299 struct bwn_mac *mac = sc->sc_curmac; 1300 struct bwn_pio_txqueue *tq; 1301 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1302 1303 BWN_ASSERT_LOCKED(sc); 1304 1305 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1306 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1307 if (dr->dr_stop == 1 || 1308 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1309 dr->dr_stop = 1; 1310 goto full; 1311 } 1312 } else { 1313 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1314 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1315 pktlen > (tq->tq_size - tq->tq_used)) 1316 goto full; 1317 } 1318 return (0); 1319 full: 1320 mbufq_prepend(&sc->sc_snd, m); 1321 return (1); 1322 } 1323 1324 static int 1325 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1326 { 1327 struct bwn_mac *mac = sc->sc_curmac; 1328 int error; 1329 1330 BWN_ASSERT_LOCKED(sc); 1331 1332 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1333 m_freem(m); 1334 return (ENXIO); 1335 } 1336 1337 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1338 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1339 if (error) { 1340 m_freem(m); 1341 return (error); 1342 } 1343 return (0); 1344 } 1345 1346 static int 1347 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1348 { 1349 struct bwn_pio_txpkt *tp; 1350 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1351 struct bwn_softc *sc = mac->mac_sc; 1352 struct bwn_txhdr txhdr; 1353 struct mbuf *m_new; 1354 uint32_t ctl32; 1355 int error; 1356 uint16_t ctl16; 1357 1358 BWN_ASSERT_LOCKED(sc); 1359 1360 /* XXX TODO send packets after DTIM */ 1361 1362 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1363 tp = TAILQ_FIRST(&tq->tq_pktlist); 1364 tp->tp_ni = ni; 1365 tp->tp_m = m; 1366 1367 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1368 if (error) { 1369 device_printf(sc->sc_dev, "tx fail\n"); 1370 return (error); 1371 } 1372 1373 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1374 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1375 tq->tq_free--; 1376 1377 if (siba_get_revid(sc->sc_dev) >= 8) { 1378 /* 1379 * XXX please removes m_defrag(9) 1380 */ 1381 m_new = m_defrag(m, M_NOWAIT); 1382 if (m_new == NULL) { 1383 device_printf(sc->sc_dev, 1384 "%s: can't defrag TX buffer\n", 1385 __func__); 1386 return (ENOBUFS); 1387 } 1388 if (m_new->m_next != NULL) 1389 device_printf(sc->sc_dev, 1390 "TODO: fragmented packets for PIO\n"); 1391 tp->tp_m = m_new; 1392 1393 /* send HEADER */ 1394 ctl32 = bwn_pio_write_multi_4(mac, tq, 1395 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1396 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1397 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1398 /* send BODY */ 1399 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1400 mtod(m_new, const void *), m_new->m_pkthdr.len); 1401 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1402 ctl32 | BWN_PIO8_TXCTL_EOF); 1403 } else { 1404 ctl16 = bwn_pio_write_multi_2(mac, tq, 1405 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1406 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1407 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1408 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1409 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1410 ctl16 | BWN_PIO_TXCTL_EOF); 1411 } 1412 1413 return (0); 1414 } 1415 1416 static struct bwn_pio_txqueue * 1417 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1418 { 1419 1420 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1421 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1422 1423 switch (prio) { 1424 case 0: 1425 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1426 case 1: 1427 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1428 case 2: 1429 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1430 case 3: 1431 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1432 } 1433 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1434 return (NULL); 1435 } 1436 1437 static int 1438 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1439 { 1440 #define BWN_GET_TXHDRCACHE(slot) \ 1441 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1442 struct bwn_dma *dma = &mac->mac_method.dma; 1443 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1444 struct bwn_dmadesc_generic *desc; 1445 struct bwn_dmadesc_meta *mt; 1446 struct bwn_softc *sc = mac->mac_sc; 1447 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1448 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1449 1450 BWN_ASSERT_LOCKED(sc); 1451 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1452 1453 /* XXX send after DTIM */ 1454 1455 slot = bwn_dma_getslot(dr); 1456 dr->getdesc(dr, slot, &desc, &mt); 1457 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1458 ("%s:%d: fail", __func__, __LINE__)); 1459 1460 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1461 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1462 BWN_DMA_COOKIE(dr, slot)); 1463 if (error) 1464 goto fail; 1465 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1466 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1467 &mt->mt_paddr, BUS_DMA_NOWAIT); 1468 if (error) { 1469 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", 1470 __func__, error); 1471 goto fail; 1472 } 1473 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1474 BUS_DMASYNC_PREWRITE); 1475 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1476 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1477 BUS_DMASYNC_PREWRITE); 1478 1479 slot = bwn_dma_getslot(dr); 1480 dr->getdesc(dr, slot, &desc, &mt); 1481 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1482 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1483 mt->mt_m = m; 1484 mt->mt_ni = ni; 1485 1486 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1487 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1488 if (error && error != EFBIG) { 1489 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", 1490 __func__, error); 1491 goto fail; 1492 } 1493 if (error) { /* error == EFBIG */ 1494 struct mbuf *m_new; 1495 1496 m_new = m_defrag(m, M_NOWAIT); 1497 if (m_new == NULL) { 1498 device_printf(sc->sc_dev, 1499 "%s: can't defrag TX buffer\n", 1500 __func__); 1501 error = ENOBUFS; 1502 goto fail; 1503 } else { 1504 m = m_new; 1505 } 1506 1507 mt->mt_m = m; 1508 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1509 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1510 if (error) { 1511 device_printf(sc->sc_dev, 1512 "%s: can't load TX buffer (2) %d\n", 1513 __func__, error); 1514 goto fail; 1515 } 1516 } 1517 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1518 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1519 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1520 BUS_DMASYNC_PREWRITE); 1521 1522 /* XXX send after DTIM */ 1523 1524 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1525 return (0); 1526 fail: 1527 dr->dr_curslot = backup[0]; 1528 dr->dr_usedslot = backup[1]; 1529 return (error); 1530 #undef BWN_GET_TXHDRCACHE 1531 } 1532 1533 static void 1534 bwn_watchdog(void *arg) 1535 { 1536 struct bwn_softc *sc = arg; 1537 1538 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1539 device_printf(sc->sc_dev, "device timeout\n"); 1540 counter_u64_add(sc->sc_ic.ic_oerrors, 1); 1541 } 1542 callout_schedule(&sc->sc_watchdog_ch, hz); 1543 } 1544 1545 static int 1546 bwn_attach_core(struct bwn_mac *mac) 1547 { 1548 struct bwn_softc *sc = mac->mac_sc; 1549 int error, have_bg = 0, have_a = 0; 1550 uint32_t high; 1551 1552 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1553 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1554 1555 siba_powerup(sc->sc_dev, 0); 1556 1557 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1558 bwn_reset_core(mac, 1559 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1560 error = bwn_phy_getinfo(mac, high); 1561 if (error) 1562 goto fail; 1563 1564 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1565 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1566 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1567 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1568 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1569 have_a = have_bg = 0; 1570 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1571 have_a = 1; 1572 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1573 mac->mac_phy.type == BWN_PHYTYPE_N || 1574 mac->mac_phy.type == BWN_PHYTYPE_LP) 1575 have_bg = 1; 1576 else 1577 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1578 mac->mac_phy.type)); 1579 } 1580 /* XXX turns off PHY A because it's not supported */ 1581 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1582 mac->mac_phy.type != BWN_PHYTYPE_N) { 1583 have_a = 0; 1584 have_bg = 1; 1585 } 1586 1587 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1588 mac->mac_phy.attach = bwn_phy_g_attach; 1589 mac->mac_phy.detach = bwn_phy_g_detach; 1590 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1591 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1592 mac->mac_phy.init = bwn_phy_g_init; 1593 mac->mac_phy.exit = bwn_phy_g_exit; 1594 mac->mac_phy.phy_read = bwn_phy_g_read; 1595 mac->mac_phy.phy_write = bwn_phy_g_write; 1596 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1597 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1598 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1599 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1600 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1601 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1602 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1603 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1604 mac->mac_phy.set_im = bwn_phy_g_im; 1605 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1606 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1607 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1608 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1609 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1610 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1611 mac->mac_phy.init = bwn_phy_lp_init; 1612 mac->mac_phy.phy_read = bwn_phy_lp_read; 1613 mac->mac_phy.phy_write = bwn_phy_lp_write; 1614 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1615 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1616 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1617 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1618 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1619 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1620 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1621 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1622 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1623 } else { 1624 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1625 mac->mac_phy.type); 1626 error = ENXIO; 1627 goto fail; 1628 } 1629 1630 mac->mac_phy.gmode = have_bg; 1631 if (mac->mac_phy.attach != NULL) { 1632 error = mac->mac_phy.attach(mac); 1633 if (error) { 1634 device_printf(sc->sc_dev, "failed\n"); 1635 goto fail; 1636 } 1637 } 1638 1639 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1640 1641 error = bwn_chiptest(mac); 1642 if (error) 1643 goto fail; 1644 error = bwn_setup_channels(mac, have_bg, have_a); 1645 if (error) { 1646 device_printf(sc->sc_dev, "failed to setup channels\n"); 1647 goto fail; 1648 } 1649 1650 if (sc->sc_curmac == NULL) 1651 sc->sc_curmac = mac; 1652 1653 error = bwn_dma_attach(mac); 1654 if (error != 0) { 1655 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1656 goto fail; 1657 } 1658 1659 mac->mac_phy.switch_analog(mac, 0); 1660 1661 siba_dev_down(sc->sc_dev, 0); 1662 fail: 1663 siba_powerdown(sc->sc_dev); 1664 return (error); 1665 } 1666 1667 static void 1668 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1669 { 1670 struct bwn_softc *sc = mac->mac_sc; 1671 uint32_t low, ctl; 1672 1673 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1674 1675 siba_dev_up(sc->sc_dev, flags); 1676 DELAY(2000); 1677 1678 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1679 ~BWN_TGSLOW_PHYRESET; 1680 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1681 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1682 DELAY(1000); 1683 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1684 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1685 DELAY(1000); 1686 1687 if (mac->mac_phy.switch_analog != NULL) 1688 mac->mac_phy.switch_analog(mac, 1); 1689 1690 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1691 if (flags & BWN_TGSLOW_SUPPORT_G) 1692 ctl |= BWN_MACCTL_GMODE; 1693 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1694 } 1695 1696 static int 1697 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1698 { 1699 struct bwn_phy *phy = &mac->mac_phy; 1700 struct bwn_softc *sc = mac->mac_sc; 1701 uint32_t tmp; 1702 1703 /* PHY */ 1704 tmp = BWN_READ_2(mac, BWN_PHYVER); 1705 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1706 phy->rf_on = 1; 1707 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1708 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1709 phy->rev = (tmp & BWN_PHYVER_VERSION); 1710 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1711 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1712 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1713 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1714 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1715 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1716 goto unsupphy; 1717 1718 /* RADIO */ 1719 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1720 if (siba_get_chiprev(sc->sc_dev) == 0) 1721 tmp = 0x3205017f; 1722 else if (siba_get_chiprev(sc->sc_dev) == 1) 1723 tmp = 0x4205017f; 1724 else 1725 tmp = 0x5205017f; 1726 } else { 1727 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1728 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1729 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1730 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1731 } 1732 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1733 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1734 phy->rf_manuf = (tmp & 0x00000fff); 1735 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1736 goto unsupradio; 1737 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1738 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1739 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1740 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1741 (phy->type == BWN_PHYTYPE_N && 1742 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1743 (phy->type == BWN_PHYTYPE_LP && 1744 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1745 goto unsupradio; 1746 1747 return (0); 1748 unsupphy: 1749 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1750 "analog %#x)\n", 1751 phy->type, phy->rev, phy->analog); 1752 return (ENXIO); 1753 unsupradio: 1754 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1755 "rev %#x)\n", 1756 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1757 return (ENXIO); 1758 } 1759 1760 static int 1761 bwn_chiptest(struct bwn_mac *mac) 1762 { 1763 #define TESTVAL0 0x55aaaa55 1764 #define TESTVAL1 0xaa5555aa 1765 struct bwn_softc *sc = mac->mac_sc; 1766 uint32_t v, backup; 1767 1768 BWN_LOCK(sc); 1769 1770 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1771 1772 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1773 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1774 goto error; 1775 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1776 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1777 goto error; 1778 1779 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1780 1781 if ((siba_get_revid(sc->sc_dev) >= 3) && 1782 (siba_get_revid(sc->sc_dev) <= 10)) { 1783 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1784 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1785 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1786 goto error; 1787 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1788 goto error; 1789 } 1790 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1791 1792 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1793 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1794 goto error; 1795 1796 BWN_UNLOCK(sc); 1797 return (0); 1798 error: 1799 BWN_UNLOCK(sc); 1800 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1801 return (ENODEV); 1802 } 1803 1804 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1805 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1806 1807 static int 1808 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1809 { 1810 struct bwn_softc *sc = mac->mac_sc; 1811 struct ieee80211com *ic = &sc->sc_ic; 1812 1813 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1814 ic->ic_nchans = 0; 1815 1816 if (have_bg) 1817 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1818 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1819 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1820 if (have_a) 1821 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1822 &ic->ic_nchans, &bwn_chantable_n, 1823 IEEE80211_CHAN_HTA); 1824 } else { 1825 if (have_a) 1826 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1827 &ic->ic_nchans, &bwn_chantable_a, 1828 IEEE80211_CHAN_A); 1829 } 1830 1831 mac->mac_phy.supports_2ghz = have_bg; 1832 mac->mac_phy.supports_5ghz = have_a; 1833 1834 return (ic->ic_nchans == 0 ? ENXIO : 0); 1835 } 1836 1837 static uint32_t 1838 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1839 { 1840 uint32_t ret; 1841 1842 BWN_ASSERT_LOCKED(mac->mac_sc); 1843 1844 if (way == BWN_SHARED) { 1845 KASSERT((offset & 0x0001) == 0, 1846 ("%s:%d warn", __func__, __LINE__)); 1847 if (offset & 0x0003) { 1848 bwn_shm_ctlword(mac, way, offset >> 2); 1849 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1850 ret <<= 16; 1851 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1852 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1853 goto out; 1854 } 1855 offset >>= 2; 1856 } 1857 bwn_shm_ctlword(mac, way, offset); 1858 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1859 out: 1860 return (ret); 1861 } 1862 1863 static uint16_t 1864 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1865 { 1866 uint16_t ret; 1867 1868 BWN_ASSERT_LOCKED(mac->mac_sc); 1869 1870 if (way == BWN_SHARED) { 1871 KASSERT((offset & 0x0001) == 0, 1872 ("%s:%d warn", __func__, __LINE__)); 1873 if (offset & 0x0003) { 1874 bwn_shm_ctlword(mac, way, offset >> 2); 1875 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1876 goto out; 1877 } 1878 offset >>= 2; 1879 } 1880 bwn_shm_ctlword(mac, way, offset); 1881 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1882 out: 1883 1884 return (ret); 1885 } 1886 1887 static void 1888 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1889 uint16_t offset) 1890 { 1891 uint32_t control; 1892 1893 control = way; 1894 control <<= 16; 1895 control |= offset; 1896 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1897 } 1898 1899 static void 1900 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1901 uint32_t value) 1902 { 1903 BWN_ASSERT_LOCKED(mac->mac_sc); 1904 1905 if (way == BWN_SHARED) { 1906 KASSERT((offset & 0x0001) == 0, 1907 ("%s:%d warn", __func__, __LINE__)); 1908 if (offset & 0x0003) { 1909 bwn_shm_ctlword(mac, way, offset >> 2); 1910 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1911 (value >> 16) & 0xffff); 1912 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1913 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1914 return; 1915 } 1916 offset >>= 2; 1917 } 1918 bwn_shm_ctlword(mac, way, offset); 1919 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1920 } 1921 1922 static void 1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1924 uint16_t value) 1925 { 1926 BWN_ASSERT_LOCKED(mac->mac_sc); 1927 1928 if (way == BWN_SHARED) { 1929 KASSERT((offset & 0x0001) == 0, 1930 ("%s:%d warn", __func__, __LINE__)); 1931 if (offset & 0x0003) { 1932 bwn_shm_ctlword(mac, way, offset >> 2); 1933 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1934 return; 1935 } 1936 offset >>= 2; 1937 } 1938 bwn_shm_ctlword(mac, way, offset); 1939 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1940 } 1941 1942 static void 1943 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1944 int txpow) 1945 { 1946 1947 c->ic_freq = freq; 1948 c->ic_flags = flags; 1949 c->ic_ieee = ieee; 1950 c->ic_minpower = 0; 1951 c->ic_maxpower = 2 * txpow; 1952 c->ic_maxregpower = txpow; 1953 } 1954 1955 static void 1956 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 1957 const struct bwn_channelinfo *ci, int flags) 1958 { 1959 struct ieee80211_channel *c; 1960 int i; 1961 1962 c = &chans[*nchans]; 1963 1964 for (i = 0; i < ci->nchannels; i++) { 1965 const struct bwn_channel *hc; 1966 1967 hc = &ci->channels[i]; 1968 if (*nchans >= maxchans) 1969 break; 1970 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 1971 c++, (*nchans)++; 1972 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 1973 /* g channel have a separate b-only entry */ 1974 if (*nchans >= maxchans) 1975 break; 1976 c[0] = c[-1]; 1977 c[-1].ic_flags = IEEE80211_CHAN_B; 1978 c++, (*nchans)++; 1979 } 1980 if (flags == IEEE80211_CHAN_HTG) { 1981 /* HT g channel have a separate g-only entry */ 1982 if (*nchans >= maxchans) 1983 break; 1984 c[-1].ic_flags = IEEE80211_CHAN_G; 1985 c[0] = c[-1]; 1986 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1987 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1988 c++, (*nchans)++; 1989 } 1990 if (flags == IEEE80211_CHAN_HTA) { 1991 /* HT a channel have a separate a-only entry */ 1992 if (*nchans >= maxchans) 1993 break; 1994 c[-1].ic_flags = IEEE80211_CHAN_A; 1995 c[0] = c[-1]; 1996 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1997 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1998 c++, (*nchans)++; 1999 } 2000 } 2001 } 2002 2003 static int 2004 bwn_phy_g_attach(struct bwn_mac *mac) 2005 { 2006 struct bwn_softc *sc = mac->mac_sc; 2007 struct bwn_phy *phy = &mac->mac_phy; 2008 struct bwn_phy_g *pg = &phy->phy_g; 2009 unsigned int i; 2010 int16_t pab0, pab1, pab2; 2011 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2012 int8_t bg; 2013 2014 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2015 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2016 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2017 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2018 2019 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2020 device_printf(sc->sc_dev, "not supported anymore\n"); 2021 2022 pg->pg_flags = 0; 2023 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2024 pab2 == -1) { 2025 pg->pg_idletssi = 52; 2026 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2027 return (0); 2028 } 2029 2030 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2031 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2032 if (pg->pg_tssi2dbm == NULL) { 2033 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2034 return (ENOMEM); 2035 } 2036 for (i = 0; i < 64; i++) { 2037 int32_t m1, m2, f, q, delta; 2038 int8_t j = 0; 2039 2040 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2041 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2042 f = 256; 2043 2044 do { 2045 if (j > 15) { 2046 device_printf(sc->sc_dev, 2047 "failed to generate tssi2dBm\n"); 2048 free(pg->pg_tssi2dbm, M_DEVBUF); 2049 return (ENOMEM); 2050 } 2051 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2052 f, 2048); 2053 delta = abs(q - f); 2054 f = q; 2055 j++; 2056 } while (delta >= 2); 2057 2058 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2059 128); 2060 } 2061 2062 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2063 return (0); 2064 } 2065 2066 static void 2067 bwn_phy_g_detach(struct bwn_mac *mac) 2068 { 2069 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2070 2071 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2072 free(pg->pg_tssi2dbm, M_DEVBUF); 2073 pg->pg_tssi2dbm = NULL; 2074 } 2075 pg->pg_flags = 0; 2076 } 2077 2078 static void 2079 bwn_phy_g_init_pre(struct bwn_mac *mac) 2080 { 2081 struct bwn_phy *phy = &mac->mac_phy; 2082 struct bwn_phy_g *pg = &phy->phy_g; 2083 void *tssi2dbm; 2084 int idletssi; 2085 unsigned int i; 2086 2087 tssi2dbm = pg->pg_tssi2dbm; 2088 idletssi = pg->pg_idletssi; 2089 2090 memset(pg, 0, sizeof(*pg)); 2091 2092 pg->pg_tssi2dbm = tssi2dbm; 2093 pg->pg_idletssi = idletssi; 2094 2095 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2096 2097 for (i = 0; i < N(pg->pg_nrssi); i++) 2098 pg->pg_nrssi[i] = -1000; 2099 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2100 pg->pg_nrssi_lt[i] = i; 2101 pg->pg_lofcal = 0xffff; 2102 pg->pg_initval = 0xffff; 2103 pg->pg_immode = BWN_IMMODE_NONE; 2104 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2105 pg->pg_avgtssi = 0xff; 2106 2107 pg->pg_loctl.tx_bias = 0xff; 2108 TAILQ_INIT(&pg->pg_loctl.calib_list); 2109 } 2110 2111 static int 2112 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2113 { 2114 struct bwn_phy *phy = &mac->mac_phy; 2115 struct bwn_phy_g *pg = &phy->phy_g; 2116 struct bwn_softc *sc = mac->mac_sc; 2117 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2118 static const struct bwn_rfatt rfatt0[] = { 2119 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2120 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2121 { 3, 1 }, { 4, 1 } 2122 }; 2123 static const struct bwn_rfatt rfatt1[] = { 2124 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2125 { 14, 1 } 2126 }; 2127 static const struct bwn_rfatt rfatt2[] = { 2128 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2129 { 9, 1 } 2130 }; 2131 static const struct bwn_bbatt bbatt_0[] = { 2132 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2133 }; 2134 2135 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2136 2137 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2138 pg->pg_bbatt.att = 0; 2139 else 2140 pg->pg_bbatt.att = 2; 2141 2142 /* prepare Radio Attenuation */ 2143 pg->pg_rfatt.padmix = 0; 2144 2145 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2146 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2147 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2148 pg->pg_rfatt.att = 2; 2149 goto done; 2150 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2151 pg->pg_rfatt.att = 3; 2152 goto done; 2153 } 2154 } 2155 2156 if (phy->type == BWN_PHYTYPE_A) { 2157 pg->pg_rfatt.att = 0x60; 2158 goto done; 2159 } 2160 2161 switch (phy->rf_ver) { 2162 case 0x2050: 2163 switch (phy->rf_rev) { 2164 case 0: 2165 pg->pg_rfatt.att = 5; 2166 goto done; 2167 case 1: 2168 if (phy->type == BWN_PHYTYPE_G) { 2169 if (siba_get_pci_subvendor(sc->sc_dev) == 2170 SIBA_BOARDVENDOR_BCM && 2171 siba_get_pci_subdevice(sc->sc_dev) == 2172 SIBA_BOARD_BCM4309G && 2173 siba_get_pci_revid(sc->sc_dev) >= 30) 2174 pg->pg_rfatt.att = 3; 2175 else if (siba_get_pci_subvendor(sc->sc_dev) == 2176 SIBA_BOARDVENDOR_BCM && 2177 siba_get_pci_subdevice(sc->sc_dev) == 2178 SIBA_BOARD_BU4306) 2179 pg->pg_rfatt.att = 3; 2180 else 2181 pg->pg_rfatt.att = 1; 2182 } else { 2183 if (siba_get_pci_subvendor(sc->sc_dev) == 2184 SIBA_BOARDVENDOR_BCM && 2185 siba_get_pci_subdevice(sc->sc_dev) == 2186 SIBA_BOARD_BCM4309G && 2187 siba_get_pci_revid(sc->sc_dev) >= 30) 2188 pg->pg_rfatt.att = 7; 2189 else 2190 pg->pg_rfatt.att = 6; 2191 } 2192 goto done; 2193 case 2: 2194 if (phy->type == BWN_PHYTYPE_G) { 2195 if (siba_get_pci_subvendor(sc->sc_dev) == 2196 SIBA_BOARDVENDOR_BCM && 2197 siba_get_pci_subdevice(sc->sc_dev) == 2198 SIBA_BOARD_BCM4309G && 2199 siba_get_pci_revid(sc->sc_dev) >= 30) 2200 pg->pg_rfatt.att = 3; 2201 else if (siba_get_pci_subvendor(sc->sc_dev) == 2202 SIBA_BOARDVENDOR_BCM && 2203 siba_get_pci_subdevice(sc->sc_dev) == 2204 SIBA_BOARD_BU4306) 2205 pg->pg_rfatt.att = 5; 2206 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2207 pg->pg_rfatt.att = 4; 2208 else 2209 pg->pg_rfatt.att = 3; 2210 } else 2211 pg->pg_rfatt.att = 6; 2212 goto done; 2213 case 3: 2214 pg->pg_rfatt.att = 5; 2215 goto done; 2216 case 4: 2217 case 5: 2218 pg->pg_rfatt.att = 1; 2219 goto done; 2220 case 6: 2221 case 7: 2222 pg->pg_rfatt.att = 5; 2223 goto done; 2224 case 8: 2225 pg->pg_rfatt.att = 0xa; 2226 pg->pg_rfatt.padmix = 1; 2227 goto done; 2228 case 9: 2229 default: 2230 pg->pg_rfatt.att = 5; 2231 goto done; 2232 } 2233 break; 2234 case 0x2053: 2235 switch (phy->rf_rev) { 2236 case 1: 2237 pg->pg_rfatt.att = 6; 2238 goto done; 2239 } 2240 break; 2241 } 2242 pg->pg_rfatt.att = 5; 2243 done: 2244 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2245 2246 if (!bwn_has_hwpctl(mac)) { 2247 lo->rfatt.array = rfatt0; 2248 lo->rfatt.len = N(rfatt0); 2249 lo->rfatt.min = 0; 2250 lo->rfatt.max = 9; 2251 goto genbbatt; 2252 } 2253 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2254 lo->rfatt.array = rfatt1; 2255 lo->rfatt.len = N(rfatt1); 2256 lo->rfatt.min = 0; 2257 lo->rfatt.max = 14; 2258 goto genbbatt; 2259 } 2260 lo->rfatt.array = rfatt2; 2261 lo->rfatt.len = N(rfatt2); 2262 lo->rfatt.min = 0; 2263 lo->rfatt.max = 9; 2264 genbbatt: 2265 lo->bbatt.array = bbatt_0; 2266 lo->bbatt.len = N(bbatt_0); 2267 lo->bbatt.min = 0; 2268 lo->bbatt.max = 8; 2269 2270 BWN_READ_4(mac, BWN_MACCTL); 2271 if (phy->rev == 1) { 2272 phy->gmode = 0; 2273 bwn_reset_core(mac, 0); 2274 bwn_phy_g_init_sub(mac); 2275 phy->gmode = 1; 2276 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2277 } 2278 return (0); 2279 } 2280 2281 static uint16_t 2282 bwn_phy_g_txctl(struct bwn_mac *mac) 2283 { 2284 struct bwn_phy *phy = &mac->mac_phy; 2285 2286 if (phy->rf_ver != 0x2050) 2287 return (0); 2288 if (phy->rf_rev == 1) 2289 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2290 if (phy->rf_rev < 6) 2291 return (BWN_TXCTL_PA2DB); 2292 if (phy->rf_rev == 8) 2293 return (BWN_TXCTL_TXMIX); 2294 return (0); 2295 } 2296 2297 static int 2298 bwn_phy_g_init(struct bwn_mac *mac) 2299 { 2300 2301 bwn_phy_g_init_sub(mac); 2302 return (0); 2303 } 2304 2305 static void 2306 bwn_phy_g_exit(struct bwn_mac *mac) 2307 { 2308 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2309 struct bwn_lo_calib *cal, *tmp; 2310 2311 if (lo == NULL) 2312 return; 2313 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2314 TAILQ_REMOVE(&lo->calib_list, cal, list); 2315 free(cal, M_DEVBUF); 2316 } 2317 } 2318 2319 static uint16_t 2320 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2321 { 2322 2323 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2324 return (BWN_READ_2(mac, BWN_PHYDATA)); 2325 } 2326 2327 static void 2328 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2329 { 2330 2331 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2332 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2333 } 2334 2335 static uint16_t 2336 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2337 { 2338 2339 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2340 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2341 return (BWN_READ_2(mac, BWN_RFDATALO)); 2342 } 2343 2344 static void 2345 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2346 { 2347 2348 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2349 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2350 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2351 } 2352 2353 static int 2354 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2355 { 2356 2357 return (mac->mac_phy.rev >= 6); 2358 } 2359 2360 static void 2361 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2362 { 2363 struct bwn_phy *phy = &mac->mac_phy; 2364 struct bwn_phy_g *pg = &phy->phy_g; 2365 unsigned int channel; 2366 uint16_t rfover, rfoverval; 2367 2368 if (on) { 2369 if (phy->rf_on) 2370 return; 2371 2372 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2373 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2374 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2375 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2376 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2377 pg->pg_radioctx_over); 2378 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2379 pg->pg_radioctx_overval); 2380 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2381 } 2382 channel = phy->chan; 2383 bwn_phy_g_switch_chan(mac, 6, 1); 2384 bwn_phy_g_switch_chan(mac, channel, 0); 2385 return; 2386 } 2387 2388 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2389 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2390 pg->pg_radioctx_over = rfover; 2391 pg->pg_radioctx_overval = rfoverval; 2392 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2393 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2394 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2395 } 2396 2397 static int 2398 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2399 { 2400 2401 if ((newchan < 1) || (newchan > 14)) 2402 return (EINVAL); 2403 bwn_phy_g_switch_chan(mac, newchan, 0); 2404 2405 return (0); 2406 } 2407 2408 static uint32_t 2409 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2410 { 2411 2412 return (1); 2413 } 2414 2415 static void 2416 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2417 { 2418 struct bwn_phy *phy = &mac->mac_phy; 2419 uint64_t hf; 2420 int autodiv = 0; 2421 uint16_t tmp; 2422 2423 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2424 autodiv = 1; 2425 2426 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2427 bwn_hf_write(mac, hf); 2428 2429 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2430 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2431 ((autodiv ? BWN_ANTAUTO1 : antenna) 2432 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2433 2434 if (autodiv) { 2435 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2436 if (antenna == BWN_ANTAUTO1) 2437 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2438 else 2439 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2440 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2441 } 2442 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2443 if (autodiv) 2444 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2445 else 2446 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2447 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2448 if (phy->rev >= 2) { 2449 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2450 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2451 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2452 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2453 0x15); 2454 if (phy->rev == 2) 2455 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2456 else 2457 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2458 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2459 8); 2460 } 2461 if (phy->rev >= 6) 2462 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2463 2464 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2465 bwn_hf_write(mac, hf); 2466 } 2467 2468 static int 2469 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2470 { 2471 struct bwn_phy *phy = &mac->mac_phy; 2472 struct bwn_phy_g *pg = &phy->phy_g; 2473 2474 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2475 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2476 2477 if (phy->rev == 0 || !phy->gmode) 2478 return (ENODEV); 2479 2480 pg->pg_aci_wlan_automatic = 0; 2481 return (0); 2482 } 2483 2484 static int 2485 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2486 { 2487 struct bwn_phy *phy = &mac->mac_phy; 2488 struct bwn_phy_g *pg = &phy->phy_g; 2489 struct bwn_softc *sc = mac->mac_sc; 2490 unsigned int tssi; 2491 int cck, ofdm; 2492 int power; 2493 int rfatt, bbatt; 2494 unsigned int max; 2495 2496 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2497 2498 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2499 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2500 if (cck < 0 && ofdm < 0) { 2501 if (ignore_tssi == 0) 2502 return (BWN_TXPWR_RES_DONE); 2503 cck = 0; 2504 ofdm = 0; 2505 } 2506 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2507 if (pg->pg_avgtssi != 0xff) 2508 tssi = (tssi + pg->pg_avgtssi) / 2; 2509 pg->pg_avgtssi = tssi; 2510 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2511 2512 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2513 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2514 max -= 3; 2515 if (max >= 120) { 2516 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2517 max = 80; 2518 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2519 } 2520 2521 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2522 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2523 tssi, 0x00), 0x3f)]); 2524 if (power == 0) 2525 return (BWN_TXPWR_RES_DONE); 2526 2527 rfatt = -((power + 7) / 8); 2528 bbatt = (-(power / 2)) - (4 * rfatt); 2529 if ((rfatt == 0) && (bbatt == 0)) 2530 return (BWN_TXPWR_RES_DONE); 2531 pg->pg_bbatt_delta = bbatt; 2532 pg->pg_rfatt_delta = rfatt; 2533 return (BWN_TXPWR_RES_NEED_ADJUST); 2534 } 2535 2536 static void 2537 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2538 { 2539 struct bwn_phy *phy = &mac->mac_phy; 2540 struct bwn_phy_g *pg = &phy->phy_g; 2541 struct bwn_softc *sc = mac->mac_sc; 2542 int rfatt, bbatt; 2543 uint8_t txctl; 2544 2545 bwn_mac_suspend(mac); 2546 2547 BWN_ASSERT_LOCKED(sc); 2548 2549 bbatt = pg->pg_bbatt.att; 2550 bbatt += pg->pg_bbatt_delta; 2551 rfatt = pg->pg_rfatt.att; 2552 rfatt += pg->pg_rfatt_delta; 2553 2554 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2555 txctl = pg->pg_txctl; 2556 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2557 if (rfatt <= 1) { 2558 if (txctl == 0) { 2559 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2560 rfatt += 2; 2561 bbatt += 2; 2562 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2563 BWN_BFL_PACTRL) { 2564 bbatt += 4 * (rfatt - 2); 2565 rfatt = 2; 2566 } 2567 } else if (rfatt > 4 && txctl) { 2568 txctl = 0; 2569 if (bbatt < 3) { 2570 rfatt -= 3; 2571 bbatt += 2; 2572 } else { 2573 rfatt -= 2; 2574 bbatt -= 2; 2575 } 2576 } 2577 } 2578 pg->pg_txctl = txctl; 2579 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2580 pg->pg_rfatt.att = rfatt; 2581 pg->pg_bbatt.att = bbatt; 2582 2583 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2584 2585 bwn_phy_lock(mac); 2586 bwn_rf_lock(mac); 2587 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2588 pg->pg_txctl); 2589 bwn_rf_unlock(mac); 2590 bwn_phy_unlock(mac); 2591 2592 bwn_mac_enable(mac); 2593 } 2594 2595 static void 2596 bwn_phy_g_task_15s(struct bwn_mac *mac) 2597 { 2598 struct bwn_phy *phy = &mac->mac_phy; 2599 struct bwn_phy_g *pg = &phy->phy_g; 2600 struct bwn_softc *sc = mac->mac_sc; 2601 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2602 unsigned long expire, now; 2603 struct bwn_lo_calib *cal, *tmp; 2604 uint8_t expired = 0; 2605 2606 bwn_mac_suspend(mac); 2607 2608 if (lo == NULL) 2609 goto fail; 2610 2611 BWN_GETTIME(now); 2612 if (bwn_has_hwpctl(mac)) { 2613 expire = now - BWN_LO_PWRVEC_EXPIRE; 2614 if (time_before(lo->pwr_vec_read_time, expire)) { 2615 bwn_lo_get_powervector(mac); 2616 bwn_phy_g_dc_lookup_init(mac, 0); 2617 } 2618 goto fail; 2619 } 2620 2621 expire = now - BWN_LO_CALIB_EXPIRE; 2622 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2623 if (!time_before(cal->calib_time, expire)) 2624 continue; 2625 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2626 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2627 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2628 expired = 1; 2629 } 2630 2631 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2632 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2633 cal->ctl.i, cal->ctl.q); 2634 2635 TAILQ_REMOVE(&lo->calib_list, cal, list); 2636 free(cal, M_DEVBUF); 2637 } 2638 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2639 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2640 &pg->pg_rfatt); 2641 if (cal == NULL) { 2642 device_printf(sc->sc_dev, 2643 "failed to recalibrate LO\n"); 2644 goto fail; 2645 } 2646 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2647 bwn_lo_write(mac, &cal->ctl); 2648 } 2649 2650 fail: 2651 bwn_mac_enable(mac); 2652 } 2653 2654 static void 2655 bwn_phy_g_task_60s(struct bwn_mac *mac) 2656 { 2657 struct bwn_phy *phy = &mac->mac_phy; 2658 struct bwn_softc *sc = mac->mac_sc; 2659 uint8_t old = phy->chan; 2660 2661 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2662 return; 2663 2664 bwn_mac_suspend(mac); 2665 bwn_nrssi_slope_11g(mac); 2666 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2667 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2668 bwn_switch_channel(mac, old); 2669 } 2670 bwn_mac_enable(mac); 2671 } 2672 2673 static void 2674 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2675 { 2676 2677 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2678 } 2679 2680 static int 2681 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2682 const struct ieee80211_bpf_params *params) 2683 { 2684 struct ieee80211com *ic = ni->ni_ic; 2685 struct bwn_softc *sc = ic->ic_softc; 2686 struct bwn_mac *mac = sc->sc_curmac; 2687 2688 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || 2689 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2690 ieee80211_free_node(ni); 2691 m_freem(m); 2692 return (ENETDOWN); 2693 } 2694 2695 BWN_LOCK(sc); 2696 if (bwn_tx_isfull(sc, m)) { 2697 ieee80211_free_node(ni); 2698 m_freem(m); 2699 BWN_UNLOCK(sc); 2700 return (ENOBUFS); 2701 } 2702 2703 if (bwn_tx_start(sc, ni, m) != 0) { 2704 if (ni != NULL) 2705 ieee80211_free_node(ni); 2706 } 2707 sc->sc_watchdog_timer = 5; 2708 BWN_UNLOCK(sc); 2709 return (0); 2710 } 2711 2712 /* 2713 * Callback from the 802.11 layer to update the slot time 2714 * based on the current setting. We use it to notify the 2715 * firmware of ERP changes and the f/w takes care of things 2716 * like slot time and preamble. 2717 */ 2718 static void 2719 bwn_updateslot(struct ieee80211com *ic) 2720 { 2721 struct bwn_softc *sc = ic->ic_softc; 2722 struct bwn_mac *mac; 2723 2724 BWN_LOCK(sc); 2725 if (sc->sc_flags & BWN_FLAG_RUNNING) { 2726 mac = (struct bwn_mac *)sc->sc_curmac; 2727 bwn_set_slot_time(mac, 2728 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2729 } 2730 BWN_UNLOCK(sc); 2731 } 2732 2733 /* 2734 * Callback from the 802.11 layer after a promiscuous mode change. 2735 * Note this interface does not check the operating mode as this 2736 * is an internal callback and we are expected to honor the current 2737 * state (e.g. this is used for setting the interface in promiscuous 2738 * mode when operating in hostap mode to do ACS). 2739 */ 2740 static void 2741 bwn_update_promisc(struct ieee80211com *ic) 2742 { 2743 struct bwn_softc *sc = ic->ic_softc; 2744 struct bwn_mac *mac = sc->sc_curmac; 2745 2746 BWN_LOCK(sc); 2747 mac = sc->sc_curmac; 2748 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2749 if (ic->ic_promisc > 0) 2750 sc->sc_filters |= BWN_MACCTL_PROMISC; 2751 else 2752 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2753 bwn_set_opmode(mac); 2754 } 2755 BWN_UNLOCK(sc); 2756 } 2757 2758 /* 2759 * Callback from the 802.11 layer to update WME parameters. 2760 */ 2761 static int 2762 bwn_wme_update(struct ieee80211com *ic) 2763 { 2764 struct bwn_softc *sc = ic->ic_softc; 2765 struct bwn_mac *mac = sc->sc_curmac; 2766 struct wmeParams *wmep; 2767 int i; 2768 2769 BWN_LOCK(sc); 2770 mac = sc->sc_curmac; 2771 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2772 bwn_mac_suspend(mac); 2773 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2774 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2775 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2776 } 2777 bwn_mac_enable(mac); 2778 } 2779 BWN_UNLOCK(sc); 2780 return (0); 2781 } 2782 2783 static void 2784 bwn_scan_start(struct ieee80211com *ic) 2785 { 2786 struct bwn_softc *sc = ic->ic_softc; 2787 struct bwn_mac *mac; 2788 2789 BWN_LOCK(sc); 2790 mac = sc->sc_curmac; 2791 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2792 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2793 bwn_set_opmode(mac); 2794 /* disable CFP update during scan */ 2795 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2796 } 2797 BWN_UNLOCK(sc); 2798 } 2799 2800 static void 2801 bwn_scan_end(struct ieee80211com *ic) 2802 { 2803 struct bwn_softc *sc = ic->ic_softc; 2804 struct bwn_mac *mac; 2805 2806 BWN_LOCK(sc); 2807 mac = sc->sc_curmac; 2808 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2809 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2810 bwn_set_opmode(mac); 2811 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2812 } 2813 BWN_UNLOCK(sc); 2814 } 2815 2816 static void 2817 bwn_set_channel(struct ieee80211com *ic) 2818 { 2819 struct bwn_softc *sc = ic->ic_softc; 2820 struct bwn_mac *mac = sc->sc_curmac; 2821 struct bwn_phy *phy = &mac->mac_phy; 2822 int chan, error; 2823 2824 BWN_LOCK(sc); 2825 2826 error = bwn_switch_band(sc, ic->ic_curchan); 2827 if (error) 2828 goto fail; 2829 bwn_mac_suspend(mac); 2830 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2831 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2832 if (chan != phy->chan) 2833 bwn_switch_channel(mac, chan); 2834 2835 /* TX power level */ 2836 if (ic->ic_curchan->ic_maxpower != 0 && 2837 ic->ic_curchan->ic_maxpower != phy->txpower) { 2838 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2839 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2840 BWN_TXPWR_IGNORE_TSSI); 2841 } 2842 2843 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2844 if (phy->set_antenna) 2845 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2846 2847 if (sc->sc_rf_enabled != phy->rf_on) { 2848 if (sc->sc_rf_enabled) { 2849 bwn_rf_turnon(mac); 2850 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2851 device_printf(sc->sc_dev, 2852 "please turn on the RF switch\n"); 2853 } else 2854 bwn_rf_turnoff(mac); 2855 } 2856 2857 bwn_mac_enable(mac); 2858 2859 fail: 2860 /* 2861 * Setup radio tap channel freq and flags 2862 */ 2863 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2864 htole16(ic->ic_curchan->ic_freq); 2865 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2866 htole16(ic->ic_curchan->ic_flags & 0xffff); 2867 2868 BWN_UNLOCK(sc); 2869 } 2870 2871 static struct ieee80211vap * 2872 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2873 enum ieee80211_opmode opmode, int flags, 2874 const uint8_t bssid[IEEE80211_ADDR_LEN], 2875 const uint8_t mac[IEEE80211_ADDR_LEN]) 2876 { 2877 struct ieee80211vap *vap; 2878 struct bwn_vap *bvp; 2879 2880 switch (opmode) { 2881 case IEEE80211_M_HOSTAP: 2882 case IEEE80211_M_MBSS: 2883 case IEEE80211_M_STA: 2884 case IEEE80211_M_WDS: 2885 case IEEE80211_M_MONITOR: 2886 case IEEE80211_M_IBSS: 2887 case IEEE80211_M_AHDEMO: 2888 break; 2889 default: 2890 return (NULL); 2891 } 2892 2893 bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); 2894 vap = &bvp->bv_vap; 2895 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 2896 /* override with driver methods */ 2897 bvp->bv_newstate = vap->iv_newstate; 2898 vap->iv_newstate = bwn_newstate; 2899 2900 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2901 vap->iv_max_aid = BWN_STAID_MAX; 2902 2903 ieee80211_ratectl_init(vap); 2904 2905 /* complete setup */ 2906 ieee80211_vap_attach(vap, ieee80211_media_change, 2907 ieee80211_media_status, mac); 2908 return (vap); 2909 } 2910 2911 static void 2912 bwn_vap_delete(struct ieee80211vap *vap) 2913 { 2914 struct bwn_vap *bvp = BWN_VAP(vap); 2915 2916 ieee80211_ratectl_deinit(vap); 2917 ieee80211_vap_detach(vap); 2918 free(bvp, M_80211_VAP); 2919 } 2920 2921 static int 2922 bwn_init(struct bwn_softc *sc) 2923 { 2924 struct bwn_mac *mac; 2925 int error; 2926 2927 BWN_ASSERT_LOCKED(sc); 2928 2929 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2930 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2931 sc->sc_filters = 0; 2932 bwn_wme_clear(sc); 2933 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2934 sc->sc_rf_enabled = 1; 2935 2936 mac = sc->sc_curmac; 2937 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2938 error = bwn_core_init(mac); 2939 if (error != 0) 2940 return (error); 2941 } 2942 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2943 bwn_core_start(mac); 2944 2945 bwn_set_opmode(mac); 2946 bwn_set_pretbtt(mac); 2947 bwn_spu_setdelay(mac, 0); 2948 bwn_set_macaddr(mac); 2949 2950 sc->sc_flags |= BWN_FLAG_RUNNING; 2951 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2952 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2953 2954 return (0); 2955 } 2956 2957 static void 2958 bwn_stop(struct bwn_softc *sc) 2959 { 2960 struct bwn_mac *mac = sc->sc_curmac; 2961 2962 BWN_ASSERT_LOCKED(sc); 2963 2964 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2965 /* XXX FIXME opmode not based on VAP */ 2966 bwn_set_opmode(mac); 2967 bwn_set_macaddr(mac); 2968 } 2969 2970 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 2971 bwn_core_stop(mac); 2972 2973 callout_stop(&sc->sc_led_blink_ch); 2974 sc->sc_led_blinking = 0; 2975 2976 bwn_core_exit(mac); 2977 sc->sc_rf_enabled = 0; 2978 2979 sc->sc_flags &= ~BWN_FLAG_RUNNING; 2980 } 2981 2982 static void 2983 bwn_wme_clear(struct bwn_softc *sc) 2984 { 2985 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 2986 struct wmeParams *p; 2987 unsigned int i; 2988 2989 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 2990 ("%s:%d: fail", __func__, __LINE__)); 2991 2992 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2993 p = &(sc->sc_wmeParams[i]); 2994 2995 switch (bwn_wme_shm_offsets[i]) { 2996 case BWN_WME_VOICE: 2997 p->wmep_txopLimit = 0; 2998 p->wmep_aifsn = 2; 2999 /* XXX FIXME: log2(cwmin) */ 3000 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3001 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3002 break; 3003 case BWN_WME_VIDEO: 3004 p->wmep_txopLimit = 0; 3005 p->wmep_aifsn = 2; 3006 /* XXX FIXME: log2(cwmin) */ 3007 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3008 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3009 break; 3010 case BWN_WME_BESTEFFORT: 3011 p->wmep_txopLimit = 0; 3012 p->wmep_aifsn = 3; 3013 /* XXX FIXME: log2(cwmin) */ 3014 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3015 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3016 break; 3017 case BWN_WME_BACKGROUND: 3018 p->wmep_txopLimit = 0; 3019 p->wmep_aifsn = 7; 3020 /* XXX FIXME: log2(cwmin) */ 3021 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3022 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3023 break; 3024 default: 3025 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3026 } 3027 } 3028 } 3029 3030 static int 3031 bwn_core_init(struct bwn_mac *mac) 3032 { 3033 struct bwn_softc *sc = mac->mac_sc; 3034 uint64_t hf; 3035 int error; 3036 3037 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3038 ("%s:%d: fail", __func__, __LINE__)); 3039 3040 siba_powerup(sc->sc_dev, 0); 3041 if (!siba_dev_isup(sc->sc_dev)) 3042 bwn_reset_core(mac, 3043 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3044 3045 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3046 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3047 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3048 BWN_GETTIME(mac->mac_phy.nexttime); 3049 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3050 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3051 mac->mac_stats.link_noise = -95; 3052 mac->mac_reason_intr = 0; 3053 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3054 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3055 #ifdef BWN_DEBUG 3056 if (sc->sc_debug & BWN_DEBUG_XMIT) 3057 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3058 #endif 3059 mac->mac_suspended = 1; 3060 mac->mac_task_state = 0; 3061 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3062 3063 mac->mac_phy.init_pre(mac); 3064 3065 siba_pcicore_intr(sc->sc_dev); 3066 3067 siba_fix_imcfglobug(sc->sc_dev); 3068 bwn_bt_disable(mac); 3069 if (mac->mac_phy.prepare_hw) { 3070 error = mac->mac_phy.prepare_hw(mac); 3071 if (error) 3072 goto fail0; 3073 } 3074 error = bwn_chip_init(mac); 3075 if (error) 3076 goto fail0; 3077 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3078 siba_get_revid(sc->sc_dev)); 3079 hf = bwn_hf_read(mac); 3080 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3081 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3082 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3083 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3084 if (mac->mac_phy.rev == 1) 3085 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3086 } 3087 if (mac->mac_phy.rf_ver == 0x2050) { 3088 if (mac->mac_phy.rf_rev < 6) 3089 hf |= BWN_HF_FORCE_VCO_RECALC; 3090 if (mac->mac_phy.rf_rev == 6) 3091 hf |= BWN_HF_4318_TSSI; 3092 } 3093 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3094 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3095 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3096 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3097 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3098 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3099 bwn_hf_write(mac, hf); 3100 3101 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3102 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3103 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3104 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3105 3106 bwn_rate_init(mac); 3107 bwn_set_phytxctl(mac); 3108 3109 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3110 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3111 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3112 3113 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3114 bwn_pio_init(mac); 3115 else 3116 bwn_dma_init(mac); 3117 bwn_wme_init(mac); 3118 bwn_spu_setdelay(mac, 1); 3119 bwn_bt_enable(mac); 3120 3121 siba_powerup(sc->sc_dev, 3122 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3123 bwn_set_macaddr(mac); 3124 bwn_crypt_init(mac); 3125 3126 /* XXX LED initializatin */ 3127 3128 mac->mac_status = BWN_MAC_STATUS_INITED; 3129 3130 return (error); 3131 3132 fail0: 3133 siba_powerdown(sc->sc_dev); 3134 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3135 ("%s:%d: fail", __func__, __LINE__)); 3136 return (error); 3137 } 3138 3139 static void 3140 bwn_core_start(struct bwn_mac *mac) 3141 { 3142 struct bwn_softc *sc = mac->mac_sc; 3143 uint32_t tmp; 3144 3145 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3146 ("%s:%d: fail", __func__, __LINE__)); 3147 3148 if (siba_get_revid(sc->sc_dev) < 5) 3149 return; 3150 3151 while (1) { 3152 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3153 if (!(tmp & 0x00000001)) 3154 break; 3155 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3156 } 3157 3158 bwn_mac_enable(mac); 3159 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3160 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3161 3162 mac->mac_status = BWN_MAC_STATUS_STARTED; 3163 } 3164 3165 static void 3166 bwn_core_exit(struct bwn_mac *mac) 3167 { 3168 struct bwn_softc *sc = mac->mac_sc; 3169 uint32_t macctl; 3170 3171 BWN_ASSERT_LOCKED(mac->mac_sc); 3172 3173 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3174 ("%s:%d: fail", __func__, __LINE__)); 3175 3176 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3177 return; 3178 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3179 3180 macctl = BWN_READ_4(mac, BWN_MACCTL); 3181 macctl &= ~BWN_MACCTL_MCODE_RUN; 3182 macctl |= BWN_MACCTL_MCODE_JMP0; 3183 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3184 3185 bwn_dma_stop(mac); 3186 bwn_pio_stop(mac); 3187 bwn_chip_exit(mac); 3188 mac->mac_phy.switch_analog(mac, 0); 3189 siba_dev_down(sc->sc_dev, 0); 3190 siba_powerdown(sc->sc_dev); 3191 } 3192 3193 static void 3194 bwn_bt_disable(struct bwn_mac *mac) 3195 { 3196 struct bwn_softc *sc = mac->mac_sc; 3197 3198 (void)sc; 3199 /* XXX do nothing yet */ 3200 } 3201 3202 static int 3203 bwn_chip_init(struct bwn_mac *mac) 3204 { 3205 struct bwn_softc *sc = mac->mac_sc; 3206 struct bwn_phy *phy = &mac->mac_phy; 3207 uint32_t macctl; 3208 int error; 3209 3210 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3211 if (phy->gmode) 3212 macctl |= BWN_MACCTL_GMODE; 3213 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3214 3215 error = bwn_fw_fillinfo(mac); 3216 if (error) 3217 return (error); 3218 error = bwn_fw_loaducode(mac); 3219 if (error) 3220 return (error); 3221 3222 error = bwn_gpio_init(mac); 3223 if (error) 3224 return (error); 3225 3226 error = bwn_fw_loadinitvals(mac); 3227 if (error) { 3228 siba_gpio_set(sc->sc_dev, 0); 3229 return (error); 3230 } 3231 phy->switch_analog(mac, 1); 3232 error = bwn_phy_init(mac); 3233 if (error) { 3234 siba_gpio_set(sc->sc_dev, 0); 3235 return (error); 3236 } 3237 if (phy->set_im) 3238 phy->set_im(mac, BWN_IMMODE_NONE); 3239 if (phy->set_antenna) 3240 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3241 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3242 3243 if (phy->type == BWN_PHYTYPE_B) 3244 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3245 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3246 if (siba_get_revid(sc->sc_dev) < 5) 3247 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3248 3249 BWN_WRITE_4(mac, BWN_MACCTL, 3250 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3251 BWN_WRITE_4(mac, BWN_MACCTL, 3252 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3253 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3254 3255 bwn_set_opmode(mac); 3256 if (siba_get_revid(sc->sc_dev) < 3) { 3257 BWN_WRITE_2(mac, 0x060e, 0x0000); 3258 BWN_WRITE_2(mac, 0x0610, 0x8000); 3259 BWN_WRITE_2(mac, 0x0604, 0x0000); 3260 BWN_WRITE_2(mac, 0x0606, 0x0200); 3261 } else { 3262 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3263 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3264 } 3265 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3266 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3267 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3268 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3269 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3270 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3271 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3272 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3273 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3274 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3275 return (error); 3276 } 3277 3278 /* read hostflags */ 3279 static uint64_t 3280 bwn_hf_read(struct bwn_mac *mac) 3281 { 3282 uint64_t ret; 3283 3284 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3285 ret <<= 16; 3286 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3287 ret <<= 16; 3288 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3289 return (ret); 3290 } 3291 3292 static void 3293 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3294 { 3295 3296 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3297 (value & 0x00000000ffffull)); 3298 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3299 (value & 0x0000ffff0000ull) >> 16); 3300 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3301 (value & 0xffff00000000ULL) >> 32); 3302 } 3303 3304 static void 3305 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3306 { 3307 3308 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3309 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3310 } 3311 3312 static void 3313 bwn_rate_init(struct bwn_mac *mac) 3314 { 3315 3316 switch (mac->mac_phy.type) { 3317 case BWN_PHYTYPE_A: 3318 case BWN_PHYTYPE_G: 3319 case BWN_PHYTYPE_LP: 3320 case BWN_PHYTYPE_N: 3321 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3322 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3323 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3324 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3325 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3326 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3327 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3328 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3329 break; 3330 /* FALLTHROUGH */ 3331 case BWN_PHYTYPE_B: 3332 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3333 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3334 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3335 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3336 break; 3337 default: 3338 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3339 } 3340 } 3341 3342 static void 3343 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3344 { 3345 uint16_t offset; 3346 3347 if (ofdm) { 3348 offset = 0x480; 3349 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3350 } else { 3351 offset = 0x4c0; 3352 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3353 } 3354 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3355 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3356 } 3357 3358 static uint8_t 3359 bwn_plcp_getcck(const uint8_t bitrate) 3360 { 3361 3362 switch (bitrate) { 3363 case BWN_CCK_RATE_1MB: 3364 return (0x0a); 3365 case BWN_CCK_RATE_2MB: 3366 return (0x14); 3367 case BWN_CCK_RATE_5MB: 3368 return (0x37); 3369 case BWN_CCK_RATE_11MB: 3370 return (0x6e); 3371 } 3372 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3373 return (0); 3374 } 3375 3376 static uint8_t 3377 bwn_plcp_getofdm(const uint8_t bitrate) 3378 { 3379 3380 switch (bitrate) { 3381 case BWN_OFDM_RATE_6MB: 3382 return (0xb); 3383 case BWN_OFDM_RATE_9MB: 3384 return (0xf); 3385 case BWN_OFDM_RATE_12MB: 3386 return (0xa); 3387 case BWN_OFDM_RATE_18MB: 3388 return (0xe); 3389 case BWN_OFDM_RATE_24MB: 3390 return (0x9); 3391 case BWN_OFDM_RATE_36MB: 3392 return (0xd); 3393 case BWN_OFDM_RATE_48MB: 3394 return (0x8); 3395 case BWN_OFDM_RATE_54MB: 3396 return (0xc); 3397 } 3398 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3399 return (0); 3400 } 3401 3402 static void 3403 bwn_set_phytxctl(struct bwn_mac *mac) 3404 { 3405 uint16_t ctl; 3406 3407 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3408 BWN_TX_PHY_TXPWR); 3409 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3410 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3411 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3412 } 3413 3414 static void 3415 bwn_pio_init(struct bwn_mac *mac) 3416 { 3417 struct bwn_pio *pio = &mac->mac_method.pio; 3418 3419 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3420 & ~BWN_MACCTL_BIGENDIAN); 3421 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3422 3423 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3424 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3425 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3426 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3427 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3428 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3429 } 3430 3431 static void 3432 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3433 int index) 3434 { 3435 struct bwn_pio_txpkt *tp; 3436 struct bwn_softc *sc = mac->mac_sc; 3437 unsigned int i; 3438 3439 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3440 tq->tq_index = index; 3441 3442 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3443 if (siba_get_revid(sc->sc_dev) >= 8) 3444 tq->tq_size = 1920; 3445 else { 3446 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3447 tq->tq_size -= 80; 3448 } 3449 3450 TAILQ_INIT(&tq->tq_pktlist); 3451 for (i = 0; i < N(tq->tq_pkts); i++) { 3452 tp = &(tq->tq_pkts[i]); 3453 tp->tp_index = i; 3454 tp->tp_queue = tq; 3455 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3456 } 3457 } 3458 3459 static uint16_t 3460 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3461 { 3462 struct bwn_softc *sc = mac->mac_sc; 3463 static const uint16_t bases[] = { 3464 BWN_PIO_BASE0, 3465 BWN_PIO_BASE1, 3466 BWN_PIO_BASE2, 3467 BWN_PIO_BASE3, 3468 BWN_PIO_BASE4, 3469 BWN_PIO_BASE5, 3470 BWN_PIO_BASE6, 3471 BWN_PIO_BASE7, 3472 }; 3473 static const uint16_t bases_rev11[] = { 3474 BWN_PIO11_BASE0, 3475 BWN_PIO11_BASE1, 3476 BWN_PIO11_BASE2, 3477 BWN_PIO11_BASE3, 3478 BWN_PIO11_BASE4, 3479 BWN_PIO11_BASE5, 3480 }; 3481 3482 if (siba_get_revid(sc->sc_dev) >= 11) { 3483 if (index >= N(bases_rev11)) 3484 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3485 return (bases_rev11[index]); 3486 } 3487 if (index >= N(bases)) 3488 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3489 return (bases[index]); 3490 } 3491 3492 static void 3493 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3494 int index) 3495 { 3496 struct bwn_softc *sc = mac->mac_sc; 3497 3498 prq->prq_mac = mac; 3499 prq->prq_rev = siba_get_revid(sc->sc_dev); 3500 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3501 bwn_dma_rxdirectfifo(mac, index, 1); 3502 } 3503 3504 static void 3505 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3506 { 3507 if (tq == NULL) 3508 return; 3509 bwn_pio_cancel_tx_packets(tq); 3510 } 3511 3512 static void 3513 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3514 { 3515 3516 bwn_destroy_pioqueue_tx(pio); 3517 } 3518 3519 static uint16_t 3520 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3521 uint16_t offset) 3522 { 3523 3524 return (BWN_READ_2(mac, tq->tq_base + offset)); 3525 } 3526 3527 static void 3528 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3529 { 3530 uint32_t ctl; 3531 int type; 3532 uint16_t base; 3533 3534 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3535 base = bwn_dma_base(type, idx); 3536 if (type == BWN_DMA_64BIT) { 3537 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3538 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3539 if (enable) 3540 ctl |= BWN_DMA64_RXDIRECTFIFO; 3541 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3542 } else { 3543 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3544 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3545 if (enable) 3546 ctl |= BWN_DMA32_RXDIRECTFIFO; 3547 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3548 } 3549 } 3550 3551 static uint64_t 3552 bwn_dma_mask(struct bwn_mac *mac) 3553 { 3554 uint32_t tmp; 3555 uint16_t base; 3556 3557 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3558 if (tmp & SIBA_TGSHIGH_DMA64) 3559 return (BWN_DMA_BIT_MASK(64)); 3560 base = bwn_dma_base(0, 0); 3561 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3562 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3563 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3564 return (BWN_DMA_BIT_MASK(32)); 3565 3566 return (BWN_DMA_BIT_MASK(30)); 3567 } 3568 3569 static int 3570 bwn_dma_mask2type(uint64_t dmamask) 3571 { 3572 3573 if (dmamask == BWN_DMA_BIT_MASK(30)) 3574 return (BWN_DMA_30BIT); 3575 if (dmamask == BWN_DMA_BIT_MASK(32)) 3576 return (BWN_DMA_32BIT); 3577 if (dmamask == BWN_DMA_BIT_MASK(64)) 3578 return (BWN_DMA_64BIT); 3579 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3580 return (BWN_DMA_30BIT); 3581 } 3582 3583 static void 3584 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3585 { 3586 struct bwn_pio_txpkt *tp; 3587 unsigned int i; 3588 3589 for (i = 0; i < N(tq->tq_pkts); i++) { 3590 tp = &(tq->tq_pkts[i]); 3591 if (tp->tp_m) { 3592 m_freem(tp->tp_m); 3593 tp->tp_m = NULL; 3594 } 3595 } 3596 } 3597 3598 static uint16_t 3599 bwn_dma_base(int type, int controller_idx) 3600 { 3601 static const uint16_t map64[] = { 3602 BWN_DMA64_BASE0, 3603 BWN_DMA64_BASE1, 3604 BWN_DMA64_BASE2, 3605 BWN_DMA64_BASE3, 3606 BWN_DMA64_BASE4, 3607 BWN_DMA64_BASE5, 3608 }; 3609 static const uint16_t map32[] = { 3610 BWN_DMA32_BASE0, 3611 BWN_DMA32_BASE1, 3612 BWN_DMA32_BASE2, 3613 BWN_DMA32_BASE3, 3614 BWN_DMA32_BASE4, 3615 BWN_DMA32_BASE5, 3616 }; 3617 3618 if (type == BWN_DMA_64BIT) { 3619 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3620 ("%s:%d: fail", __func__, __LINE__)); 3621 return (map64[controller_idx]); 3622 } 3623 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3624 ("%s:%d: fail", __func__, __LINE__)); 3625 return (map32[controller_idx]); 3626 } 3627 3628 static void 3629 bwn_dma_init(struct bwn_mac *mac) 3630 { 3631 struct bwn_dma *dma = &mac->mac_method.dma; 3632 3633 /* setup TX DMA channels. */ 3634 bwn_dma_setup(dma->wme[WME_AC_BK]); 3635 bwn_dma_setup(dma->wme[WME_AC_BE]); 3636 bwn_dma_setup(dma->wme[WME_AC_VI]); 3637 bwn_dma_setup(dma->wme[WME_AC_VO]); 3638 bwn_dma_setup(dma->mcast); 3639 /* setup RX DMA channel. */ 3640 bwn_dma_setup(dma->rx); 3641 } 3642 3643 static struct bwn_dma_ring * 3644 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3645 int for_tx, int type) 3646 { 3647 struct bwn_dma *dma = &mac->mac_method.dma; 3648 struct bwn_dma_ring *dr; 3649 struct bwn_dmadesc_generic *desc; 3650 struct bwn_dmadesc_meta *mt; 3651 struct bwn_softc *sc = mac->mac_sc; 3652 int error, i; 3653 3654 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3655 if (dr == NULL) 3656 goto out; 3657 dr->dr_numslots = BWN_RXRING_SLOTS; 3658 if (for_tx) 3659 dr->dr_numslots = BWN_TXRING_SLOTS; 3660 3661 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3662 M_DEVBUF, M_NOWAIT | M_ZERO); 3663 if (dr->dr_meta == NULL) 3664 goto fail0; 3665 3666 dr->dr_type = type; 3667 dr->dr_mac = mac; 3668 dr->dr_base = bwn_dma_base(type, controller_index); 3669 dr->dr_index = controller_index; 3670 if (type == BWN_DMA_64BIT) { 3671 dr->getdesc = bwn_dma_64_getdesc; 3672 dr->setdesc = bwn_dma_64_setdesc; 3673 dr->start_transfer = bwn_dma_64_start_transfer; 3674 dr->suspend = bwn_dma_64_suspend; 3675 dr->resume = bwn_dma_64_resume; 3676 dr->get_curslot = bwn_dma_64_get_curslot; 3677 dr->set_curslot = bwn_dma_64_set_curslot; 3678 } else { 3679 dr->getdesc = bwn_dma_32_getdesc; 3680 dr->setdesc = bwn_dma_32_setdesc; 3681 dr->start_transfer = bwn_dma_32_start_transfer; 3682 dr->suspend = bwn_dma_32_suspend; 3683 dr->resume = bwn_dma_32_resume; 3684 dr->get_curslot = bwn_dma_32_get_curslot; 3685 dr->set_curslot = bwn_dma_32_set_curslot; 3686 } 3687 if (for_tx) { 3688 dr->dr_tx = 1; 3689 dr->dr_curslot = -1; 3690 } else { 3691 if (dr->dr_index == 0) { 3692 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3693 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3694 } else 3695 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3696 } 3697 3698 error = bwn_dma_allocringmemory(dr); 3699 if (error) 3700 goto fail2; 3701 3702 if (for_tx) { 3703 /* 3704 * Assumption: BWN_TXRING_SLOTS can be divided by 3705 * BWN_TX_SLOTS_PER_FRAME 3706 */ 3707 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3708 ("%s:%d: fail", __func__, __LINE__)); 3709 3710 dr->dr_txhdr_cache = 3711 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3712 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3713 KASSERT(dr->dr_txhdr_cache != NULL, 3714 ("%s:%d: fail", __func__, __LINE__)); 3715 3716 /* 3717 * Create TX ring DMA stuffs 3718 */ 3719 error = bus_dma_tag_create(dma->parent_dtag, 3720 BWN_ALIGN, 0, 3721 BUS_SPACE_MAXADDR, 3722 BUS_SPACE_MAXADDR, 3723 NULL, NULL, 3724 BWN_HDRSIZE(mac), 3725 1, 3726 BUS_SPACE_MAXSIZE_32BIT, 3727 0, 3728 NULL, NULL, 3729 &dr->dr_txring_dtag); 3730 if (error) { 3731 device_printf(sc->sc_dev, 3732 "can't create TX ring DMA tag: TODO frees\n"); 3733 goto fail1; 3734 } 3735 3736 for (i = 0; i < dr->dr_numslots; i += 2) { 3737 dr->getdesc(dr, i, &desc, &mt); 3738 3739 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3740 mt->mt_m = NULL; 3741 mt->mt_ni = NULL; 3742 mt->mt_islast = 0; 3743 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3744 &mt->mt_dmap); 3745 if (error) { 3746 device_printf(sc->sc_dev, 3747 "can't create RX buf DMA map\n"); 3748 goto fail1; 3749 } 3750 3751 dr->getdesc(dr, i + 1, &desc, &mt); 3752 3753 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3754 mt->mt_m = NULL; 3755 mt->mt_ni = NULL; 3756 mt->mt_islast = 1; 3757 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3758 &mt->mt_dmap); 3759 if (error) { 3760 device_printf(sc->sc_dev, 3761 "can't create RX buf DMA map\n"); 3762 goto fail1; 3763 } 3764 } 3765 } else { 3766 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3767 &dr->dr_spare_dmap); 3768 if (error) { 3769 device_printf(sc->sc_dev, 3770 "can't create RX buf DMA map\n"); 3771 goto out; /* XXX wrong! */ 3772 } 3773 3774 for (i = 0; i < dr->dr_numslots; i++) { 3775 dr->getdesc(dr, i, &desc, &mt); 3776 3777 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3778 &mt->mt_dmap); 3779 if (error) { 3780 device_printf(sc->sc_dev, 3781 "can't create RX buf DMA map\n"); 3782 goto out; /* XXX wrong! */ 3783 } 3784 error = bwn_dma_newbuf(dr, desc, mt, 1); 3785 if (error) { 3786 device_printf(sc->sc_dev, 3787 "failed to allocate RX buf\n"); 3788 goto out; /* XXX wrong! */ 3789 } 3790 } 3791 3792 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3793 BUS_DMASYNC_PREWRITE); 3794 3795 dr->dr_usedslot = dr->dr_numslots; 3796 } 3797 3798 out: 3799 return (dr); 3800 3801 fail2: 3802 free(dr->dr_txhdr_cache, M_DEVBUF); 3803 fail1: 3804 free(dr->dr_meta, M_DEVBUF); 3805 fail0: 3806 free(dr, M_DEVBUF); 3807 return (NULL); 3808 } 3809 3810 static void 3811 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3812 { 3813 3814 if (dr == NULL) 3815 return; 3816 3817 bwn_dma_free_descbufs(*dr); 3818 bwn_dma_free_ringmemory(*dr); 3819 3820 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3821 free((*dr)->dr_meta, M_DEVBUF); 3822 free(*dr, M_DEVBUF); 3823 3824 *dr = NULL; 3825 } 3826 3827 static void 3828 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3829 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3830 { 3831 struct bwn_dmadesc32 *desc; 3832 3833 *meta = &(dr->dr_meta[slot]); 3834 desc = dr->dr_ring_descbase; 3835 desc = &(desc[slot]); 3836 3837 *gdesc = (struct bwn_dmadesc_generic *)desc; 3838 } 3839 3840 static void 3841 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3842 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3843 int start, int end, int irq) 3844 { 3845 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3846 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3847 uint32_t addr, addrext, ctl; 3848 int slot; 3849 3850 slot = (int)(&(desc->dma.dma32) - descbase); 3851 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3852 ("%s:%d: fail", __func__, __LINE__)); 3853 3854 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3855 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3856 addr |= siba_dma_translation(sc->sc_dev); 3857 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3858 if (slot == dr->dr_numslots - 1) 3859 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3860 if (start) 3861 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3862 if (end) 3863 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3864 if (irq) 3865 ctl |= BWN_DMA32_DCTL_IRQ; 3866 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3867 & BWN_DMA32_DCTL_ADDREXT_MASK; 3868 3869 desc->dma.dma32.control = htole32(ctl); 3870 desc->dma.dma32.address = htole32(addr); 3871 } 3872 3873 static void 3874 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3875 { 3876 3877 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3878 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3879 } 3880 3881 static void 3882 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3883 { 3884 3885 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3886 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3887 } 3888 3889 static void 3890 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3891 { 3892 3893 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3894 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3895 } 3896 3897 static int 3898 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3899 { 3900 uint32_t val; 3901 3902 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3903 val &= BWN_DMA32_RXDPTR; 3904 3905 return (val / sizeof(struct bwn_dmadesc32)); 3906 } 3907 3908 static void 3909 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3910 { 3911 3912 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3913 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3914 } 3915 3916 static void 3917 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3918 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3919 { 3920 struct bwn_dmadesc64 *desc; 3921 3922 *meta = &(dr->dr_meta[slot]); 3923 desc = dr->dr_ring_descbase; 3924 desc = &(desc[slot]); 3925 3926 *gdesc = (struct bwn_dmadesc_generic *)desc; 3927 } 3928 3929 static void 3930 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3931 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3932 int start, int end, int irq) 3933 { 3934 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3935 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3936 int slot; 3937 uint32_t ctl0 = 0, ctl1 = 0; 3938 uint32_t addrlo, addrhi; 3939 uint32_t addrext; 3940 3941 slot = (int)(&(desc->dma.dma64) - descbase); 3942 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3943 ("%s:%d: fail", __func__, __LINE__)); 3944 3945 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3946 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3947 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3948 30; 3949 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3950 if (slot == dr->dr_numslots - 1) 3951 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3952 if (start) 3953 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3954 if (end) 3955 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3956 if (irq) 3957 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3958 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3959 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3960 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3961 3962 desc->dma.dma64.control0 = htole32(ctl0); 3963 desc->dma.dma64.control1 = htole32(ctl1); 3964 desc->dma.dma64.address_low = htole32(addrlo); 3965 desc->dma.dma64.address_high = htole32(addrhi); 3966 } 3967 3968 static void 3969 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3970 { 3971 3972 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3973 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3974 } 3975 3976 static void 3977 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3978 { 3979 3980 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3981 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3982 } 3983 3984 static void 3985 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3986 { 3987 3988 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3989 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 3990 } 3991 3992 static int 3993 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 3994 { 3995 uint32_t val; 3996 3997 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 3998 val &= BWN_DMA64_RXSTATDPTR; 3999 4000 return (val / sizeof(struct bwn_dmadesc64)); 4001 } 4002 4003 static void 4004 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4005 { 4006 4007 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4008 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4009 } 4010 4011 static int 4012 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4013 { 4014 struct bwn_mac *mac = dr->dr_mac; 4015 struct bwn_dma *dma = &mac->mac_method.dma; 4016 struct bwn_softc *sc = mac->mac_sc; 4017 int error; 4018 4019 error = bus_dma_tag_create(dma->parent_dtag, 4020 BWN_ALIGN, 0, 4021 BUS_SPACE_MAXADDR, 4022 BUS_SPACE_MAXADDR, 4023 NULL, NULL, 4024 BWN_DMA_RINGMEMSIZE, 4025 1, 4026 BUS_SPACE_MAXSIZE_32BIT, 4027 0, 4028 NULL, NULL, 4029 &dr->dr_ring_dtag); 4030 if (error) { 4031 device_printf(sc->sc_dev, 4032 "can't create TX ring DMA tag: TODO frees\n"); 4033 return (-1); 4034 } 4035 4036 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4037 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4038 &dr->dr_ring_dmap); 4039 if (error) { 4040 device_printf(sc->sc_dev, 4041 "can't allocate DMA mem: TODO frees\n"); 4042 return (-1); 4043 } 4044 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4045 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4046 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4047 if (error) { 4048 device_printf(sc->sc_dev, 4049 "can't load DMA mem: TODO free\n"); 4050 return (-1); 4051 } 4052 4053 return (0); 4054 } 4055 4056 static void 4057 bwn_dma_setup(struct bwn_dma_ring *dr) 4058 { 4059 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4060 uint64_t ring64; 4061 uint32_t addrext, ring32, value; 4062 uint32_t trans = siba_dma_translation(sc->sc_dev); 4063 4064 if (dr->dr_tx) { 4065 dr->dr_curslot = -1; 4066 4067 if (dr->dr_type == BWN_DMA_64BIT) { 4068 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4069 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4070 >> 30; 4071 value = BWN_DMA64_TXENABLE; 4072 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4073 & BWN_DMA64_TXADDREXT_MASK; 4074 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4075 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4076 (ring64 & 0xffffffff)); 4077 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4078 ((ring64 >> 32) & 4079 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4080 } else { 4081 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4082 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4083 value = BWN_DMA32_TXENABLE; 4084 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4085 & BWN_DMA32_TXADDREXT_MASK; 4086 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4087 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4088 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4089 } 4090 return; 4091 } 4092 4093 /* 4094 * set for RX 4095 */ 4096 dr->dr_usedslot = dr->dr_numslots; 4097 4098 if (dr->dr_type == BWN_DMA_64BIT) { 4099 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4100 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4101 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4102 value |= BWN_DMA64_RXENABLE; 4103 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4104 & BWN_DMA64_RXADDREXT_MASK; 4105 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4106 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4107 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4108 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4109 | (trans << 1)); 4110 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4111 sizeof(struct bwn_dmadesc64)); 4112 } else { 4113 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4114 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4115 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4116 value |= BWN_DMA32_RXENABLE; 4117 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4118 & BWN_DMA32_RXADDREXT_MASK; 4119 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4120 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4121 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4122 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4123 sizeof(struct bwn_dmadesc32)); 4124 } 4125 } 4126 4127 static void 4128 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4129 { 4130 4131 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4132 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4133 dr->dr_ring_dmap); 4134 } 4135 4136 static void 4137 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4138 { 4139 4140 if (dr->dr_tx) { 4141 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4142 if (dr->dr_type == BWN_DMA_64BIT) { 4143 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4144 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4145 } else 4146 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4147 } else { 4148 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4149 if (dr->dr_type == BWN_DMA_64BIT) { 4150 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4151 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4152 } else 4153 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4154 } 4155 } 4156 4157 static void 4158 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4159 { 4160 struct bwn_dmadesc_generic *desc; 4161 struct bwn_dmadesc_meta *meta; 4162 struct bwn_mac *mac = dr->dr_mac; 4163 struct bwn_dma *dma = &mac->mac_method.dma; 4164 struct bwn_softc *sc = mac->mac_sc; 4165 int i; 4166 4167 if (!dr->dr_usedslot) 4168 return; 4169 for (i = 0; i < dr->dr_numslots; i++) { 4170 dr->getdesc(dr, i, &desc, &meta); 4171 4172 if (meta->mt_m == NULL) { 4173 if (!dr->dr_tx) 4174 device_printf(sc->sc_dev, "%s: not TX?\n", 4175 __func__); 4176 continue; 4177 } 4178 if (dr->dr_tx) { 4179 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4180 bus_dmamap_unload(dr->dr_txring_dtag, 4181 meta->mt_dmap); 4182 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4183 bus_dmamap_unload(dma->txbuf_dtag, 4184 meta->mt_dmap); 4185 } else 4186 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4187 bwn_dma_free_descbuf(dr, meta); 4188 } 4189 } 4190 4191 static int 4192 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4193 int type) 4194 { 4195 struct bwn_softc *sc = mac->mac_sc; 4196 uint32_t value; 4197 int i; 4198 uint16_t offset; 4199 4200 for (i = 0; i < 10; i++) { 4201 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4202 BWN_DMA32_TXSTATUS; 4203 value = BWN_READ_4(mac, base + offset); 4204 if (type == BWN_DMA_64BIT) { 4205 value &= BWN_DMA64_TXSTAT; 4206 if (value == BWN_DMA64_TXSTAT_DISABLED || 4207 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4208 value == BWN_DMA64_TXSTAT_STOPPED) 4209 break; 4210 } else { 4211 value &= BWN_DMA32_TXSTATE; 4212 if (value == BWN_DMA32_TXSTAT_DISABLED || 4213 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4214 value == BWN_DMA32_TXSTAT_STOPPED) 4215 break; 4216 } 4217 DELAY(1000); 4218 } 4219 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4220 BWN_WRITE_4(mac, base + offset, 0); 4221 for (i = 0; i < 10; i++) { 4222 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4223 BWN_DMA32_TXSTATUS; 4224 value = BWN_READ_4(mac, base + offset); 4225 if (type == BWN_DMA_64BIT) { 4226 value &= BWN_DMA64_TXSTAT; 4227 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4228 i = -1; 4229 break; 4230 } 4231 } else { 4232 value &= BWN_DMA32_TXSTATE; 4233 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4234 i = -1; 4235 break; 4236 } 4237 } 4238 DELAY(1000); 4239 } 4240 if (i != -1) { 4241 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4242 return (ENODEV); 4243 } 4244 DELAY(1000); 4245 4246 return (0); 4247 } 4248 4249 static int 4250 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4251 int type) 4252 { 4253 struct bwn_softc *sc = mac->mac_sc; 4254 uint32_t value; 4255 int i; 4256 uint16_t offset; 4257 4258 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4259 BWN_WRITE_4(mac, base + offset, 0); 4260 for (i = 0; i < 10; i++) { 4261 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4262 BWN_DMA32_RXSTATUS; 4263 value = BWN_READ_4(mac, base + offset); 4264 if (type == BWN_DMA_64BIT) { 4265 value &= BWN_DMA64_RXSTAT; 4266 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4267 i = -1; 4268 break; 4269 } 4270 } else { 4271 value &= BWN_DMA32_RXSTATE; 4272 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4273 i = -1; 4274 break; 4275 } 4276 } 4277 DELAY(1000); 4278 } 4279 if (i != -1) { 4280 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4281 return (ENODEV); 4282 } 4283 4284 return (0); 4285 } 4286 4287 static void 4288 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4289 struct bwn_dmadesc_meta *meta) 4290 { 4291 4292 if (meta->mt_m != NULL) { 4293 m_freem(meta->mt_m); 4294 meta->mt_m = NULL; 4295 } 4296 if (meta->mt_ni != NULL) { 4297 ieee80211_free_node(meta->mt_ni); 4298 meta->mt_ni = NULL; 4299 } 4300 } 4301 4302 static void 4303 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4304 { 4305 struct bwn_rxhdr4 *rxhdr; 4306 unsigned char *frame; 4307 4308 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4309 rxhdr->frame_len = 0; 4310 4311 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4312 sizeof(struct bwn_plcp6) + 2, 4313 ("%s:%d: fail", __func__, __LINE__)); 4314 frame = mtod(m, char *) + dr->dr_frameoffset; 4315 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4316 } 4317 4318 static uint8_t 4319 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4320 { 4321 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4322 4323 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4324 == 0xff); 4325 } 4326 4327 static void 4328 bwn_wme_init(struct bwn_mac *mac) 4329 { 4330 4331 bwn_wme_load(mac); 4332 4333 /* enable WME support. */ 4334 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4335 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4336 BWN_IFSCTL_USE_EDCF); 4337 } 4338 4339 static void 4340 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4341 { 4342 struct bwn_softc *sc = mac->mac_sc; 4343 struct ieee80211com *ic = &sc->sc_ic; 4344 uint16_t delay; /* microsec */ 4345 4346 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4347 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4348 delay = 500; 4349 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4350 delay = max(delay, (uint16_t)2400); 4351 4352 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4353 } 4354 4355 static void 4356 bwn_bt_enable(struct bwn_mac *mac) 4357 { 4358 struct bwn_softc *sc = mac->mac_sc; 4359 uint64_t hf; 4360 4361 if (bwn_bluetooth == 0) 4362 return; 4363 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4364 return; 4365 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4366 return; 4367 4368 hf = bwn_hf_read(mac); 4369 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4370 hf |= BWN_HF_BT_COEXISTALT; 4371 else 4372 hf |= BWN_HF_BT_COEXIST; 4373 bwn_hf_write(mac, hf); 4374 } 4375 4376 static void 4377 bwn_set_macaddr(struct bwn_mac *mac) 4378 { 4379 4380 bwn_mac_write_bssid(mac); 4381 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, 4382 mac->mac_sc->sc_ic.ic_macaddr); 4383 } 4384 4385 static void 4386 bwn_clear_keys(struct bwn_mac *mac) 4387 { 4388 int i; 4389 4390 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4391 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4392 ("%s:%d: fail", __func__, __LINE__)); 4393 4394 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4395 NULL, BWN_SEC_KEYSIZE, NULL); 4396 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4397 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4398 NULL, BWN_SEC_KEYSIZE, NULL); 4399 } 4400 mac->mac_key[i].keyconf = NULL; 4401 } 4402 } 4403 4404 static void 4405 bwn_crypt_init(struct bwn_mac *mac) 4406 { 4407 struct bwn_softc *sc = mac->mac_sc; 4408 4409 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4410 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4411 ("%s:%d: fail", __func__, __LINE__)); 4412 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4413 mac->mac_ktp *= 2; 4414 if (siba_get_revid(sc->sc_dev) >= 5) 4415 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4416 bwn_clear_keys(mac); 4417 } 4418 4419 static void 4420 bwn_chip_exit(struct bwn_mac *mac) 4421 { 4422 struct bwn_softc *sc = mac->mac_sc; 4423 4424 bwn_phy_exit(mac); 4425 siba_gpio_set(sc->sc_dev, 0); 4426 } 4427 4428 static int 4429 bwn_fw_fillinfo(struct bwn_mac *mac) 4430 { 4431 int error; 4432 4433 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4434 if (error == 0) 4435 return (0); 4436 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4437 if (error == 0) 4438 return (0); 4439 return (error); 4440 } 4441 4442 static int 4443 bwn_gpio_init(struct bwn_mac *mac) 4444 { 4445 struct bwn_softc *sc = mac->mac_sc; 4446 uint32_t mask = 0x1f, set = 0xf, value; 4447 4448 BWN_WRITE_4(mac, BWN_MACCTL, 4449 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4450 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4451 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4452 4453 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4454 mask |= 0x0060; 4455 set |= 0x0060; 4456 } 4457 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4458 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4459 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4460 mask |= 0x0200; 4461 set |= 0x0200; 4462 } 4463 if (siba_get_revid(sc->sc_dev) >= 2) 4464 mask |= 0x0010; 4465 4466 value = siba_gpio_get(sc->sc_dev); 4467 if (value == -1) 4468 return (0); 4469 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4470 4471 return (0); 4472 } 4473 4474 static int 4475 bwn_fw_loadinitvals(struct bwn_mac *mac) 4476 { 4477 #define GETFWOFFSET(fwp, offset) \ 4478 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4479 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4480 const struct bwn_fwhdr *hdr; 4481 struct bwn_fw *fw = &mac->mac_fw; 4482 int error; 4483 4484 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4485 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4486 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4487 if (error) 4488 return (error); 4489 if (fw->initvals_band.fw) { 4490 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4491 error = bwn_fwinitvals_write(mac, 4492 GETFWOFFSET(fw->initvals_band, hdr_len), 4493 be32toh(hdr->size), 4494 fw->initvals_band.fw->datasize - hdr_len); 4495 } 4496 return (error); 4497 #undef GETFWOFFSET 4498 } 4499 4500 static int 4501 bwn_phy_init(struct bwn_mac *mac) 4502 { 4503 struct bwn_softc *sc = mac->mac_sc; 4504 int error; 4505 4506 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4507 mac->mac_phy.rf_onoff(mac, 1); 4508 error = mac->mac_phy.init(mac); 4509 if (error) { 4510 device_printf(sc->sc_dev, "PHY init failed\n"); 4511 goto fail0; 4512 } 4513 error = bwn_switch_channel(mac, 4514 mac->mac_phy.get_default_chan(mac)); 4515 if (error) { 4516 device_printf(sc->sc_dev, 4517 "failed to switch default channel\n"); 4518 goto fail1; 4519 } 4520 return (0); 4521 fail1: 4522 if (mac->mac_phy.exit) 4523 mac->mac_phy.exit(mac); 4524 fail0: 4525 mac->mac_phy.rf_onoff(mac, 0); 4526 4527 return (error); 4528 } 4529 4530 static void 4531 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4532 { 4533 uint16_t ant; 4534 uint16_t tmp; 4535 4536 ant = bwn_ant2phy(antenna); 4537 4538 /* For ACK/CTS */ 4539 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4540 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4541 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4542 /* For Probe Resposes */ 4543 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4544 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4545 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4546 } 4547 4548 static void 4549 bwn_set_opmode(struct bwn_mac *mac) 4550 { 4551 struct bwn_softc *sc = mac->mac_sc; 4552 struct ieee80211com *ic = &sc->sc_ic; 4553 uint32_t ctl; 4554 uint16_t cfp_pretbtt; 4555 4556 ctl = BWN_READ_4(mac, BWN_MACCTL); 4557 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4558 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4559 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4560 ctl |= BWN_MACCTL_STA; 4561 4562 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4563 ic->ic_opmode == IEEE80211_M_MBSS) 4564 ctl |= BWN_MACCTL_HOSTAP; 4565 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4566 ctl &= ~BWN_MACCTL_STA; 4567 ctl |= sc->sc_filters; 4568 4569 if (siba_get_revid(sc->sc_dev) <= 4) 4570 ctl |= BWN_MACCTL_PROMISC; 4571 4572 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4573 4574 cfp_pretbtt = 2; 4575 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4576 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4577 siba_get_chiprev(sc->sc_dev) == 3) 4578 cfp_pretbtt = 100; 4579 else 4580 cfp_pretbtt = 50; 4581 } 4582 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4583 } 4584 4585 static int 4586 bwn_dma_gettype(struct bwn_mac *mac) 4587 { 4588 uint32_t tmp; 4589 uint16_t base; 4590 4591 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4592 if (tmp & SIBA_TGSHIGH_DMA64) 4593 return (BWN_DMA_64BIT); 4594 base = bwn_dma_base(0, 0); 4595 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4596 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4597 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4598 return (BWN_DMA_32BIT); 4599 4600 return (BWN_DMA_30BIT); 4601 } 4602 4603 static void 4604 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4605 { 4606 if (!error) { 4607 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4608 *((bus_addr_t *)arg) = seg->ds_addr; 4609 } 4610 } 4611 4612 static void 4613 bwn_phy_g_init_sub(struct bwn_mac *mac) 4614 { 4615 struct bwn_phy *phy = &mac->mac_phy; 4616 struct bwn_phy_g *pg = &phy->phy_g; 4617 struct bwn_softc *sc = mac->mac_sc; 4618 uint16_t i, tmp; 4619 4620 if (phy->rev == 1) 4621 bwn_phy_init_b5(mac); 4622 else 4623 bwn_phy_init_b6(mac); 4624 4625 if (phy->rev >= 2 || phy->gmode) 4626 bwn_phy_init_a(mac); 4627 4628 if (phy->rev >= 2) { 4629 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4630 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4631 } 4632 if (phy->rev == 2) { 4633 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4634 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4635 } 4636 if (phy->rev > 5) { 4637 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4638 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4639 } 4640 if (phy->gmode || phy->rev >= 2) { 4641 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4642 tmp &= BWN_PHYVER_VERSION; 4643 if (tmp == 3 || tmp == 5) { 4644 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4645 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4646 } 4647 if (tmp == 5) { 4648 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4649 0x1f00); 4650 } 4651 } 4652 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4653 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4654 if (phy->rf_rev == 8) { 4655 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4656 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4657 } 4658 if (BWN_HAS_LOOPBACK(phy)) 4659 bwn_loopback_calcgain(mac); 4660 4661 if (phy->rf_rev != 8) { 4662 if (pg->pg_initval == 0xffff) 4663 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4664 else 4665 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4666 } 4667 bwn_lo_g_init(mac); 4668 if (BWN_HAS_TXMAG(phy)) { 4669 BWN_RF_WRITE(mac, 0x52, 4670 (BWN_RF_READ(mac, 0x52) & 0xff00) 4671 | pg->pg_loctl.tx_bias | 4672 pg->pg_loctl.tx_magn); 4673 } else { 4674 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4675 } 4676 if (phy->rev >= 6) { 4677 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4678 (pg->pg_loctl.tx_bias << 12)); 4679 } 4680 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4681 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4682 else 4683 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4684 if (phy->rev < 2) 4685 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4686 else 4687 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4688 if (phy->gmode || phy->rev >= 2) { 4689 bwn_lo_g_adjust(mac); 4690 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4691 } 4692 4693 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4694 for (i = 0; i < 64; i++) { 4695 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4696 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4697 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4698 -32), 31)); 4699 } 4700 bwn_nrssi_threshold(mac); 4701 } else if (phy->gmode || phy->rev >= 2) { 4702 if (pg->pg_nrssi[0] == -1000) { 4703 KASSERT(pg->pg_nrssi[1] == -1000, 4704 ("%s:%d: fail", __func__, __LINE__)); 4705 bwn_nrssi_slope_11g(mac); 4706 } else 4707 bwn_nrssi_threshold(mac); 4708 } 4709 if (phy->rf_rev == 8) 4710 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4711 bwn_phy_hwpctl_init(mac); 4712 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4713 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4714 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4715 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4716 } 4717 } 4718 4719 static uint8_t 4720 bwn_has_hwpctl(struct bwn_mac *mac) 4721 { 4722 4723 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4724 return (0); 4725 return (mac->mac_phy.use_hwpctl(mac)); 4726 } 4727 4728 static void 4729 bwn_phy_init_b5(struct bwn_mac *mac) 4730 { 4731 struct bwn_phy *phy = &mac->mac_phy; 4732 struct bwn_phy_g *pg = &phy->phy_g; 4733 struct bwn_softc *sc = mac->mac_sc; 4734 uint16_t offset, value; 4735 uint8_t old_channel; 4736 4737 if (phy->analog == 1) 4738 BWN_RF_SET(mac, 0x007a, 0x0050); 4739 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4740 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4741 value = 0x2120; 4742 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4743 BWN_PHY_WRITE(mac, offset, value); 4744 value += 0x202; 4745 } 4746 } 4747 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4748 if (phy->rf_ver == 0x2050) 4749 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4750 4751 if (phy->gmode || phy->rev >= 2) { 4752 if (phy->rf_ver == 0x2050) { 4753 BWN_RF_SET(mac, 0x007a, 0x0020); 4754 BWN_RF_SET(mac, 0x0051, 0x0004); 4755 } 4756 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4757 4758 BWN_PHY_SET(mac, 0x0802, 0x0100); 4759 BWN_PHY_SET(mac, 0x042b, 0x2000); 4760 4761 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4762 4763 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4764 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4765 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4766 } 4767 4768 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4769 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4770 4771 if (phy->analog == 1) { 4772 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4773 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4774 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4775 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4776 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4777 } else 4778 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4779 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4780 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4781 4782 if (phy->analog == 1) 4783 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4784 else 4785 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4786 4787 if (phy->analog == 0) 4788 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4789 4790 old_channel = phy->chan; 4791 bwn_phy_g_switch_chan(mac, 7, 0); 4792 4793 if (phy->rf_ver != 0x2050) { 4794 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4795 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4796 } 4797 4798 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4799 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4800 4801 if (phy->rf_ver == 0x2050) { 4802 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4803 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4804 } 4805 4806 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4807 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4808 BWN_RF_SET(mac, 0x007a, 0x0007); 4809 4810 bwn_phy_g_switch_chan(mac, old_channel, 0); 4811 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4812 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4813 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4814 4815 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4816 pg->pg_txctl); 4817 4818 if (phy->rf_ver == 0x2050) 4819 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4820 4821 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4822 } 4823 4824 static void 4825 bwn_loopback_calcgain(struct bwn_mac *mac) 4826 { 4827 struct bwn_phy *phy = &mac->mac_phy; 4828 struct bwn_phy_g *pg = &phy->phy_g; 4829 struct bwn_softc *sc = mac->mac_sc; 4830 uint16_t backup_phy[16] = { 0 }; 4831 uint16_t backup_radio[3]; 4832 uint16_t backup_bband; 4833 uint16_t i, j, loop_i_max; 4834 uint16_t trsw_rx; 4835 uint16_t loop1_outer_done, loop1_inner_done; 4836 4837 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4838 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4839 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4840 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4841 if (phy->rev != 1) { 4842 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4843 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4844 } 4845 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4846 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4847 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4848 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4849 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4850 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4851 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4852 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4853 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4854 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4855 backup_bband = pg->pg_bbatt.att; 4856 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4857 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4858 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4859 4860 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4861 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4862 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4863 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4864 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4865 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4866 if (phy->rev != 1) { 4867 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4868 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4869 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4870 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4871 } 4872 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4873 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4874 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4875 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4876 4877 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4878 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4879 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4880 4881 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4882 if (phy->rev != 1) { 4883 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4884 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4885 } 4886 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4887 4888 if (phy->rf_rev == 8) 4889 BWN_RF_WRITE(mac, 0x43, 0x000f); 4890 else { 4891 BWN_RF_WRITE(mac, 0x52, 0); 4892 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4893 } 4894 bwn_phy_g_set_bbatt(mac, 11); 4895 4896 if (phy->rev >= 3) 4897 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4898 else 4899 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4900 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4901 4902 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 4903 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 4904 4905 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 4906 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 4907 4908 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 4909 if (phy->rev >= 7) { 4910 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 4911 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 4912 } 4913 } 4914 BWN_RF_MASK(mac, 0x7a, 0x00f7); 4915 4916 j = 0; 4917 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 4918 for (i = 0; i < loop_i_max; i++) { 4919 for (j = 0; j < 16; j++) { 4920 BWN_RF_WRITE(mac, 0x43, i); 4921 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 4922 (j << 8)); 4923 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4924 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4925 DELAY(20); 4926 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4927 goto done0; 4928 } 4929 } 4930 done0: 4931 loop1_outer_done = i; 4932 loop1_inner_done = j; 4933 if (j >= 8) { 4934 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 4935 trsw_rx = 0x1b; 4936 for (j = j - 8; j < 16; j++) { 4937 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 4938 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4939 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4940 DELAY(20); 4941 trsw_rx -= 3; 4942 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4943 goto done1; 4944 } 4945 } else 4946 trsw_rx = 0x18; 4947 done1: 4948 4949 if (phy->rev != 1) { 4950 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 4951 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 4952 } 4953 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 4954 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 4955 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 4956 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 4957 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 4958 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 4959 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 4960 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 4961 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 4962 4963 bwn_phy_g_set_bbatt(mac, backup_bband); 4964 4965 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 4966 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 4967 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 4968 4969 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 4970 DELAY(10); 4971 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 4972 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 4973 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 4974 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 4975 4976 pg->pg_max_lb_gain = 4977 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 4978 pg->pg_trsw_rx_gain = trsw_rx * 2; 4979 } 4980 4981 static uint16_t 4982 bwn_rf_init_bcm2050(struct bwn_mac *mac) 4983 { 4984 struct bwn_phy *phy = &mac->mac_phy; 4985 uint32_t tmp1 = 0, tmp2 = 0; 4986 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 4987 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 4988 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 4989 static const uint8_t rcc_table[] = { 4990 0x02, 0x03, 0x01, 0x0f, 4991 0x06, 0x07, 0x05, 0x0f, 4992 0x0a, 0x0b, 0x09, 0x0f, 4993 0x0e, 0x0f, 0x0d, 0x0f, 4994 }; 4995 4996 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 4997 rfoverval = rfover = cck3 = 0; 4998 radio0 = BWN_RF_READ(mac, 0x43); 4999 radio1 = BWN_RF_READ(mac, 0x51); 5000 radio2 = BWN_RF_READ(mac, 0x52); 5001 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5002 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5003 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5004 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5005 5006 if (phy->type == BWN_PHYTYPE_B) { 5007 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5008 reg0 = BWN_READ_2(mac, 0x3ec); 5009 5010 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5011 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5012 } else if (phy->gmode || phy->rev >= 2) { 5013 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5014 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5015 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5016 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5017 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5018 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5019 5020 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5021 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5022 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5023 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5024 if (BWN_HAS_LOOPBACK(phy)) { 5025 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5026 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5027 if (phy->rev >= 3) 5028 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5029 else 5030 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5031 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5032 } 5033 5034 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5035 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5036 BWN_LPD(0, 1, 1))); 5037 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5038 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5039 } 5040 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5041 5042 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5043 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5044 reg1 = BWN_READ_2(mac, 0x3e6); 5045 reg2 = BWN_READ_2(mac, 0x3f4); 5046 5047 if (phy->analog == 0) 5048 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5049 else { 5050 if (phy->analog >= 2) 5051 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5052 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5053 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5054 } 5055 5056 reg = BWN_RF_READ(mac, 0x60); 5057 index = (reg & 0x001e) >> 1; 5058 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5059 5060 if (phy->type == BWN_PHYTYPE_B) 5061 BWN_RF_WRITE(mac, 0x78, 0x26); 5062 if (phy->gmode || phy->rev >= 2) { 5063 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5064 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5065 BWN_LPD(0, 1, 1))); 5066 } 5067 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5068 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5069 if (phy->gmode || phy->rev >= 2) { 5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5071 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5072 BWN_LPD(0, 0, 1))); 5073 } 5074 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5075 BWN_RF_SET(mac, 0x51, 0x0004); 5076 if (phy->rf_rev == 8) 5077 BWN_RF_WRITE(mac, 0x43, 0x1f); 5078 else { 5079 BWN_RF_WRITE(mac, 0x52, 0); 5080 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5081 } 5082 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5083 5084 for (i = 0; i < 16; i++) { 5085 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5086 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5087 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5088 if (phy->gmode || phy->rev >= 2) { 5089 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5090 bwn_rf_2050_rfoverval(mac, 5091 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5092 } 5093 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5094 DELAY(10); 5095 if (phy->gmode || phy->rev >= 2) { 5096 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5097 bwn_rf_2050_rfoverval(mac, 5098 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5099 } 5100 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5101 DELAY(10); 5102 if (phy->gmode || phy->rev >= 2) { 5103 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5104 bwn_rf_2050_rfoverval(mac, 5105 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5106 } 5107 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5108 DELAY(20); 5109 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5110 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5111 if (phy->gmode || phy->rev >= 2) { 5112 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5113 bwn_rf_2050_rfoverval(mac, 5114 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5115 } 5116 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5117 } 5118 DELAY(10); 5119 5120 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5121 tmp1++; 5122 tmp1 >>= 9; 5123 5124 for (i = 0; i < 16; i++) { 5125 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5126 BWN_RF_WRITE(mac, 0x78, radio78); 5127 DELAY(10); 5128 for (j = 0; j < 16; j++) { 5129 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5130 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5131 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5132 if (phy->gmode || phy->rev >= 2) { 5133 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5134 bwn_rf_2050_rfoverval(mac, 5135 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5136 } 5137 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5138 DELAY(10); 5139 if (phy->gmode || phy->rev >= 2) { 5140 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5141 bwn_rf_2050_rfoverval(mac, 5142 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5143 } 5144 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5145 DELAY(10); 5146 if (phy->gmode || phy->rev >= 2) { 5147 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5148 bwn_rf_2050_rfoverval(mac, 5149 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5150 } 5151 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5152 DELAY(10); 5153 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5154 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5155 if (phy->gmode || phy->rev >= 2) { 5156 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5157 bwn_rf_2050_rfoverval(mac, 5158 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5159 } 5160 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5161 } 5162 tmp2++; 5163 tmp2 >>= 8; 5164 if (tmp1 < tmp2) 5165 break; 5166 } 5167 5168 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5169 BWN_RF_WRITE(mac, 0x51, radio1); 5170 BWN_RF_WRITE(mac, 0x52, radio2); 5171 BWN_RF_WRITE(mac, 0x43, radio0); 5172 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5173 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5174 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5175 BWN_WRITE_2(mac, 0x3e6, reg1); 5176 if (phy->analog != 0) 5177 BWN_WRITE_2(mac, 0x3f4, reg2); 5178 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5179 bwn_spu_workaround(mac, phy->chan); 5180 if (phy->type == BWN_PHYTYPE_B) { 5181 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5182 BWN_WRITE_2(mac, 0x3ec, reg0); 5183 } else if (phy->gmode) { 5184 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5185 BWN_READ_2(mac, BWN_PHY_RADIO) 5186 & 0x7fff); 5187 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5188 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5189 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5190 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5191 analogoverval); 5192 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5193 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5194 if (BWN_HAS_LOOPBACK(phy)) { 5195 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5196 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5197 } 5198 } 5199 5200 return ((i > 15) ? radio78 : rcc); 5201 } 5202 5203 static void 5204 bwn_phy_init_b6(struct bwn_mac *mac) 5205 { 5206 struct bwn_phy *phy = &mac->mac_phy; 5207 struct bwn_phy_g *pg = &phy->phy_g; 5208 struct bwn_softc *sc = mac->mac_sc; 5209 uint16_t offset, val; 5210 uint8_t old_channel; 5211 5212 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5213 ("%s:%d: fail", __func__, __LINE__)); 5214 5215 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5216 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5217 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5218 BWN_RF_WRITE(mac, 0x51, 0x37); 5219 BWN_RF_WRITE(mac, 0x52, 0x70); 5220 BWN_RF_WRITE(mac, 0x53, 0xb3); 5221 BWN_RF_WRITE(mac, 0x54, 0x9b); 5222 BWN_RF_WRITE(mac, 0x5a, 0x88); 5223 BWN_RF_WRITE(mac, 0x5b, 0x88); 5224 BWN_RF_WRITE(mac, 0x5d, 0x88); 5225 BWN_RF_WRITE(mac, 0x5e, 0x88); 5226 BWN_RF_WRITE(mac, 0x7d, 0x88); 5227 bwn_hf_write(mac, 5228 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5229 } 5230 if (phy->rf_rev == 8) { 5231 BWN_RF_WRITE(mac, 0x51, 0); 5232 BWN_RF_WRITE(mac, 0x52, 0x40); 5233 BWN_RF_WRITE(mac, 0x53, 0xb7); 5234 BWN_RF_WRITE(mac, 0x54, 0x98); 5235 BWN_RF_WRITE(mac, 0x5a, 0x88); 5236 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5237 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5238 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5239 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5240 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5241 } else { 5242 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5243 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5244 } 5245 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5246 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5247 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5248 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5249 } 5250 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5251 BWN_PHY_WRITE(mac, offset, val); 5252 val -= 0x0202; 5253 } 5254 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5255 BWN_PHY_WRITE(mac, offset, val); 5256 val -= 0x0202; 5257 } 5258 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5259 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5260 val += 0x0202; 5261 } 5262 if (phy->type == BWN_PHYTYPE_G) { 5263 BWN_RF_SET(mac, 0x007a, 0x0020); 5264 BWN_RF_SET(mac, 0x0051, 0x0004); 5265 BWN_PHY_SET(mac, 0x0802, 0x0100); 5266 BWN_PHY_SET(mac, 0x042b, 0x2000); 5267 BWN_PHY_WRITE(mac, 0x5b, 0); 5268 BWN_PHY_WRITE(mac, 0x5c, 0); 5269 } 5270 5271 old_channel = phy->chan; 5272 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5273 5274 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5275 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5276 DELAY(40); 5277 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5278 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5279 BWN_RF_WRITE(mac, 0x50, 0x20); 5280 } 5281 if (phy->rf_rev <= 2) { 5282 BWN_RF_WRITE(mac, 0x7c, 0x20); 5283 BWN_RF_WRITE(mac, 0x5a, 0x70); 5284 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5285 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5286 } 5287 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5288 5289 bwn_phy_g_switch_chan(mac, old_channel, 0); 5290 5291 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5292 if (phy->rf_rev >= 6) 5293 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5294 else 5295 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5296 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5297 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5298 pg->pg_txctl); 5299 if (phy->rf_rev <= 5) 5300 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5301 if (phy->rf_rev <= 2) 5302 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5303 5304 if (phy->analog == 4) { 5305 BWN_WRITE_2(mac, 0x3e4, 9); 5306 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5307 } else 5308 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5309 if (phy->type == BWN_PHYTYPE_B) 5310 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5311 else if (phy->type == BWN_PHYTYPE_G) 5312 BWN_WRITE_2(mac, 0x03e6, 0x0); 5313 } 5314 5315 static void 5316 bwn_phy_init_a(struct bwn_mac *mac) 5317 { 5318 struct bwn_phy *phy = &mac->mac_phy; 5319 struct bwn_softc *sc = mac->mac_sc; 5320 5321 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5322 ("%s:%d: fail", __func__, __LINE__)); 5323 5324 if (phy->rev >= 6) { 5325 if (phy->type == BWN_PHYTYPE_A) 5326 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5327 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5328 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5329 else 5330 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5331 } 5332 5333 bwn_wa_init(mac); 5334 5335 if (phy->type == BWN_PHYTYPE_G && 5336 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5337 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5338 } 5339 5340 static void 5341 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5342 { 5343 int i; 5344 5345 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5346 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5347 } 5348 5349 static void 5350 bwn_wa_agc(struct bwn_mac *mac) 5351 { 5352 struct bwn_phy *phy = &mac->mac_phy; 5353 5354 if (phy->rev == 1) { 5355 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5356 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5357 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5358 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5359 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5360 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5361 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5362 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5363 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5364 } else { 5365 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5366 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5367 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5368 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5369 } 5370 5371 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5372 0x5700); 5373 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5374 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5375 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5376 BWN_RF_SET(mac, 0x7a, 0x0008); 5377 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5378 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5379 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5380 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5381 if (phy->rev == 1) 5382 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5383 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5384 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5385 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5386 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5387 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5388 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5389 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5390 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5391 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5392 if (phy->rev == 1) { 5393 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5394 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5395 } else { 5396 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5397 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5398 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5399 if (phy->rev >= 6) { 5400 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5401 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5402 (uint16_t)~0xf000, 0x3000); 5403 } 5404 } 5405 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5406 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5407 if (phy->rev == 1) { 5408 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5409 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5410 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5411 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5412 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5413 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5414 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5415 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5416 } else { 5417 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5418 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5419 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5420 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5421 } 5422 if (phy->rev >= 6) { 5423 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5424 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5425 } 5426 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5427 } 5428 5429 static void 5430 bwn_wa_grev1(struct bwn_mac *mac) 5431 { 5432 struct bwn_phy *phy = &mac->mac_phy; 5433 int i; 5434 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5435 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5436 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5437 5438 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5439 5440 /* init CRSTHRES and ANTDWELL */ 5441 if (phy->rev == 1) { 5442 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5443 } else if (phy->rev == 2) { 5444 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5445 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5446 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5447 } else { 5448 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5449 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5450 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5451 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5452 } 5453 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5454 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5455 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5456 5457 /* XXX support PHY-A??? */ 5458 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5460 bwn_tab_finefreqg[i]); 5461 5462 /* XXX support PHY-A??? */ 5463 if (phy->rev == 1) 5464 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5466 bwn_tab_noise_g1[i]); 5467 else 5468 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5470 bwn_tab_noise_g2[i]); 5471 5472 5473 for (i = 0; i < N(bwn_tab_rotor); i++) 5474 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5475 bwn_tab_rotor[i]); 5476 5477 /* XXX support PHY-A??? */ 5478 if (phy->rev >= 6) { 5479 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5480 BWN_PHY_ENCORE_EN) 5481 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5482 else 5483 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5484 } else 5485 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5486 5487 for (i = 0; i < N(bwn_tab_retard); i++) 5488 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5489 bwn_tab_retard[i]); 5490 5491 if (phy->rev == 1) { 5492 for (i = 0; i < 16; i++) 5493 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5494 i, 0x0020); 5495 } else { 5496 for (i = 0; i < 32; i++) 5497 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5498 } 5499 5500 bwn_wa_agc(mac); 5501 } 5502 5503 static void 5504 bwn_wa_grev26789(struct bwn_mac *mac) 5505 { 5506 struct bwn_phy *phy = &mac->mac_phy; 5507 int i; 5508 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5509 uint16_t ofdmrev; 5510 5511 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5512 5513 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5514 5515 /* init CRSTHRES and ANTDWELL */ 5516 if (phy->rev == 1) 5517 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5518 else if (phy->rev == 2) { 5519 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5520 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5521 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5522 } else { 5523 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5524 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5525 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5526 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5527 } 5528 5529 for (i = 0; i < 64; i++) 5530 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5531 5532 /* XXX support PHY-A??? */ 5533 if (phy->rev == 1) 5534 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5535 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5536 bwn_tab_noise_g1[i]); 5537 else 5538 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5539 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5540 bwn_tab_noise_g2[i]); 5541 5542 /* XXX support PHY-A??? */ 5543 if (phy->rev >= 6) { 5544 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5545 BWN_PHY_ENCORE_EN) 5546 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5547 else 5548 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5549 } else 5550 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5551 5552 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5553 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5554 bwn_tab_sigmasqr2[i]); 5555 5556 if (phy->rev == 1) { 5557 for (i = 0; i < 16; i++) 5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5559 0x0020); 5560 } else { 5561 for (i = 0; i < 32; i++) 5562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5563 } 5564 5565 bwn_wa_agc(mac); 5566 5567 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5568 if (ofdmrev > 2) { 5569 if (phy->type == BWN_PHYTYPE_A) 5570 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5571 else 5572 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5573 } else { 5574 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5575 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5576 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5577 } 5578 5579 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5580 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5581 } 5582 5583 static void 5584 bwn_wa_init(struct bwn_mac *mac) 5585 { 5586 struct bwn_phy *phy = &mac->mac_phy; 5587 struct bwn_softc *sc = mac->mac_sc; 5588 5589 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5590 5591 switch (phy->rev) { 5592 case 1: 5593 bwn_wa_grev1(mac); 5594 break; 5595 case 2: 5596 case 6: 5597 case 7: 5598 case 8: 5599 case 9: 5600 bwn_wa_grev26789(mac); 5601 break; 5602 default: 5603 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5604 } 5605 5606 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5607 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5608 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5609 if (phy->rev < 2) { 5610 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5611 0x0002); 5612 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5613 0x0001); 5614 } else { 5615 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5616 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5617 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5618 BWN_BFL_EXTLNA) && 5619 (phy->rev >= 7)) { 5620 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5621 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5622 0x0020, 0x0001); 5623 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5624 0x0021, 0x0001); 5625 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5626 0x0022, 0x0001); 5627 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5628 0x0023, 0x0000); 5629 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5630 0x0000, 0x0000); 5631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5632 0x0003, 0x0002); 5633 } 5634 } 5635 } 5636 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5637 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5638 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5639 } 5640 5641 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5642 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5643 } 5644 5645 static void 5646 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5647 uint16_t value) 5648 { 5649 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5650 uint16_t addr; 5651 5652 addr = table + offset; 5653 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5654 (addr - 1 != pg->pg_ofdmtab_addr)) { 5655 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5656 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5657 } 5658 pg->pg_ofdmtab_addr = addr; 5659 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5660 } 5661 5662 static void 5663 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5664 uint32_t value) 5665 { 5666 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5667 uint16_t addr; 5668 5669 addr = table + offset; 5670 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5671 (addr - 1 != pg->pg_ofdmtab_addr)) { 5672 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5673 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5674 } 5675 pg->pg_ofdmtab_addr = addr; 5676 5677 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5678 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5679 } 5680 5681 static void 5682 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5683 uint16_t value) 5684 { 5685 5686 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5687 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5688 } 5689 5690 static void 5691 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5692 { 5693 struct bwn_phy *phy = &mac->mac_phy; 5694 struct bwn_softc *sc = mac->mac_sc; 5695 unsigned int i, max_loop; 5696 uint16_t value; 5697 uint32_t buffer[5] = { 5698 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5699 }; 5700 5701 if (ofdm) { 5702 max_loop = 0x1e; 5703 buffer[0] = 0x000201cc; 5704 } else { 5705 max_loop = 0xfa; 5706 buffer[0] = 0x000b846e; 5707 } 5708 5709 BWN_ASSERT_LOCKED(mac->mac_sc); 5710 5711 for (i = 0; i < 5; i++) 5712 bwn_ram_write(mac, i * 4, buffer[i]); 5713 5714 BWN_WRITE_2(mac, 0x0568, 0x0000); 5715 BWN_WRITE_2(mac, 0x07c0, 5716 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5717 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5718 BWN_WRITE_2(mac, 0x050c, value); 5719 if (phy->type == BWN_PHYTYPE_LP) 5720 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5721 BWN_WRITE_2(mac, 0x0508, 0x0000); 5722 BWN_WRITE_2(mac, 0x050a, 0x0000); 5723 BWN_WRITE_2(mac, 0x054c, 0x0000); 5724 BWN_WRITE_2(mac, 0x056a, 0x0014); 5725 BWN_WRITE_2(mac, 0x0568, 0x0826); 5726 BWN_WRITE_2(mac, 0x0500, 0x0000); 5727 if (phy->type == BWN_PHYTYPE_LP) 5728 BWN_WRITE_2(mac, 0x0502, 0x0050); 5729 else 5730 BWN_WRITE_2(mac, 0x0502, 0x0030); 5731 5732 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5733 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5734 for (i = 0x00; i < max_loop; i++) { 5735 value = BWN_READ_2(mac, 0x050e); 5736 if (value & 0x0080) 5737 break; 5738 DELAY(10); 5739 } 5740 for (i = 0x00; i < 0x0a; i++) { 5741 value = BWN_READ_2(mac, 0x050e); 5742 if (value & 0x0400) 5743 break; 5744 DELAY(10); 5745 } 5746 for (i = 0x00; i < 0x19; i++) { 5747 value = BWN_READ_2(mac, 0x0690); 5748 if (!(value & 0x0100)) 5749 break; 5750 DELAY(10); 5751 } 5752 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5753 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5754 } 5755 5756 static void 5757 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5758 { 5759 uint32_t macctl; 5760 5761 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5762 5763 macctl = BWN_READ_4(mac, BWN_MACCTL); 5764 if (macctl & BWN_MACCTL_BIGENDIAN) 5765 printf("TODO: need swap\n"); 5766 5767 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5768 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5769 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5770 } 5771 5772 static void 5773 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5774 { 5775 uint16_t value; 5776 5777 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5778 ("%s:%d: fail", __func__, __LINE__)); 5779 5780 value = (uint8_t) (ctl->q); 5781 value |= ((uint8_t) (ctl->i)) << 8; 5782 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5783 } 5784 5785 static uint16_t 5786 bwn_lo_calcfeed(struct bwn_mac *mac, 5787 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5788 { 5789 struct bwn_phy *phy = &mac->mac_phy; 5790 struct bwn_softc *sc = mac->mac_sc; 5791 uint16_t rfover; 5792 uint16_t feedthrough; 5793 5794 if (phy->gmode) { 5795 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5796 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5797 5798 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5799 ("%s:%d: fail", __func__, __LINE__)); 5800 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5801 ("%s:%d: fail", __func__, __LINE__)); 5802 5803 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5804 5805 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5806 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5807 phy->rev > 6) 5808 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5809 5810 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5811 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5812 DELAY(10); 5813 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5814 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5815 DELAY(10); 5816 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5817 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5818 DELAY(10); 5819 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5820 } else { 5821 pga |= BWN_PHY_PGACTL_UNKNOWN; 5822 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5823 DELAY(10); 5824 pga |= BWN_PHY_PGACTL_LOWBANDW; 5825 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5826 DELAY(10); 5827 pga |= BWN_PHY_PGACTL_LPF; 5828 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5829 } 5830 DELAY(21); 5831 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5832 5833 return (feedthrough); 5834 } 5835 5836 static uint16_t 5837 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5838 uint16_t *value, uint16_t *pad_mix_gain) 5839 { 5840 struct bwn_phy *phy = &mac->mac_phy; 5841 uint16_t reg, v, padmix; 5842 5843 if (phy->type == BWN_PHYTYPE_B) { 5844 v = 0x30; 5845 if (phy->rf_rev <= 5) { 5846 reg = 0x43; 5847 padmix = 0; 5848 } else { 5849 reg = 0x52; 5850 padmix = 5; 5851 } 5852 } else { 5853 if (phy->rev >= 2 && phy->rf_rev == 8) { 5854 reg = 0x43; 5855 v = 0x10; 5856 padmix = 2; 5857 } else { 5858 reg = 0x52; 5859 v = 0x30; 5860 padmix = 5; 5861 } 5862 } 5863 if (value) 5864 *value = v; 5865 if (pad_mix_gain) 5866 *pad_mix_gain = padmix; 5867 5868 return (reg); 5869 } 5870 5871 static void 5872 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5873 { 5874 struct bwn_phy *phy = &mac->mac_phy; 5875 struct bwn_phy_g *pg = &phy->phy_g; 5876 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5877 uint16_t reg, mask; 5878 uint16_t trsw_rx, pga; 5879 uint16_t rf_pctl_reg; 5880 5881 static const uint8_t tx_bias_values[] = { 5882 0x09, 0x08, 0x0a, 0x01, 0x00, 5883 0x02, 0x05, 0x04, 0x06, 5884 }; 5885 static const uint8_t tx_magn_values[] = { 5886 0x70, 0x40, 5887 }; 5888 5889 if (!BWN_HAS_LOOPBACK(phy)) { 5890 rf_pctl_reg = 6; 5891 trsw_rx = 2; 5892 pga = 0; 5893 } else { 5894 int lb_gain; 5895 5896 trsw_rx = 0; 5897 lb_gain = pg->pg_max_lb_gain / 2; 5898 if (lb_gain > 10) { 5899 rf_pctl_reg = 0; 5900 pga = abs(10 - lb_gain) / 6; 5901 pga = MIN(MAX(pga, 0), 15); 5902 } else { 5903 int cmp_val; 5904 int tmp; 5905 5906 pga = 0; 5907 cmp_val = 0x24; 5908 if ((phy->rev >= 2) && 5909 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 5910 cmp_val = 0x3c; 5911 tmp = lb_gain; 5912 if ((10 - lb_gain) < cmp_val) 5913 tmp = (10 - lb_gain); 5914 if (tmp < 0) 5915 tmp += 6; 5916 else 5917 tmp += 3; 5918 cmp_val /= 4; 5919 tmp /= 4; 5920 if (tmp >= cmp_val) 5921 rf_pctl_reg = cmp_val; 5922 else 5923 rf_pctl_reg = tmp; 5924 } 5925 } 5926 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 5927 bwn_phy_g_set_bbatt(mac, 2); 5928 5929 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 5930 mask = ~mask; 5931 BWN_RF_MASK(mac, reg, mask); 5932 5933 if (BWN_HAS_TXMAG(phy)) { 5934 int i, j; 5935 int feedthrough; 5936 int min_feedth = 0xffff; 5937 uint8_t tx_magn, tx_bias; 5938 5939 for (i = 0; i < N(tx_magn_values); i++) { 5940 tx_magn = tx_magn_values[i]; 5941 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 5942 for (j = 0; j < N(tx_bias_values); j++) { 5943 tx_bias = tx_bias_values[j]; 5944 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 5945 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 5946 trsw_rx); 5947 if (feedthrough < min_feedth) { 5948 lo->tx_bias = tx_bias; 5949 lo->tx_magn = tx_magn; 5950 min_feedth = feedthrough; 5951 } 5952 if (lo->tx_bias == 0) 5953 break; 5954 } 5955 BWN_RF_WRITE(mac, 0x52, 5956 (BWN_RF_READ(mac, 0x52) 5957 & 0xff00) | lo->tx_bias | lo-> 5958 tx_magn); 5959 } 5960 } else { 5961 lo->tx_magn = 0; 5962 lo->tx_bias = 0; 5963 BWN_RF_MASK(mac, 0x52, 0xfff0); 5964 } 5965 5966 BWN_GETTIME(lo->txctl_measured_time); 5967 } 5968 5969 static void 5970 bwn_lo_get_powervector(struct bwn_mac *mac) 5971 { 5972 struct bwn_phy *phy = &mac->mac_phy; 5973 struct bwn_phy_g *pg = &phy->phy_g; 5974 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5975 int i; 5976 uint64_t tmp; 5977 uint64_t power_vector = 0; 5978 5979 for (i = 0; i < 8; i += 2) { 5980 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 5981 power_vector |= (tmp << (i * 8)); 5982 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 5983 } 5984 if (power_vector) 5985 lo->power_vector = power_vector; 5986 5987 BWN_GETTIME(lo->pwr_vec_read_time); 5988 } 5989 5990 static void 5991 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 5992 int use_trsw_rx) 5993 { 5994 struct bwn_phy *phy = &mac->mac_phy; 5995 struct bwn_phy_g *pg = &phy->phy_g; 5996 uint16_t tmp; 5997 5998 if (max_rx_gain < 0) 5999 max_rx_gain = 0; 6000 6001 if (BWN_HAS_LOOPBACK(phy)) { 6002 int trsw_rx = 0; 6003 int trsw_rx_gain; 6004 6005 if (use_trsw_rx) { 6006 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6007 if (max_rx_gain >= trsw_rx_gain) { 6008 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6009 trsw_rx = 0x20; 6010 } 6011 } else 6012 trsw_rx_gain = max_rx_gain; 6013 if (trsw_rx_gain < 9) { 6014 pg->pg_lna_lod_gain = 0; 6015 } else { 6016 pg->pg_lna_lod_gain = 1; 6017 trsw_rx_gain -= 8; 6018 } 6019 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6020 pg->pg_pga_gain = trsw_rx_gain / 3; 6021 if (pg->pg_pga_gain >= 5) { 6022 pg->pg_pga_gain -= 5; 6023 pg->pg_lna_gain = 2; 6024 } else 6025 pg->pg_lna_gain = 0; 6026 } else { 6027 pg->pg_lna_gain = 0; 6028 pg->pg_trsw_rx_gain = 0x20; 6029 if (max_rx_gain >= 0x14) { 6030 pg->pg_lna_lod_gain = 1; 6031 pg->pg_pga_gain = 2; 6032 } else if (max_rx_gain >= 0x12) { 6033 pg->pg_lna_lod_gain = 1; 6034 pg->pg_pga_gain = 1; 6035 } else if (max_rx_gain >= 0xf) { 6036 pg->pg_lna_lod_gain = 1; 6037 pg->pg_pga_gain = 0; 6038 } else { 6039 pg->pg_lna_lod_gain = 0; 6040 pg->pg_pga_gain = 0; 6041 } 6042 } 6043 6044 tmp = BWN_RF_READ(mac, 0x7a); 6045 if (pg->pg_lna_lod_gain == 0) 6046 tmp &= ~0x0008; 6047 else 6048 tmp |= 0x0008; 6049 BWN_RF_WRITE(mac, 0x7a, tmp); 6050 } 6051 6052 static void 6053 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6054 { 6055 struct bwn_phy *phy = &mac->mac_phy; 6056 struct bwn_phy_g *pg = &phy->phy_g; 6057 struct bwn_softc *sc = mac->mac_sc; 6058 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6059 struct timespec ts; 6060 uint16_t tmp; 6061 6062 if (bwn_has_hwpctl(mac)) { 6063 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6064 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6065 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6066 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6067 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6068 6069 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6070 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6071 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6072 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6073 } 6074 if (phy->type == BWN_PHYTYPE_B && 6075 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6076 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6077 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6078 } 6079 if (phy->rev >= 2) { 6080 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6081 sav->phy_analogoverval = 6082 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6083 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6084 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6085 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6086 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6087 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6088 6089 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6090 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6091 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6092 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6093 if (phy->type == BWN_PHYTYPE_G) { 6094 if ((phy->rev >= 7) && 6095 (siba_sprom_get_bf_lo(sc->sc_dev) & 6096 BWN_BFL_EXTLNA)) { 6097 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6098 } else { 6099 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6100 } 6101 } else { 6102 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6103 } 6104 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6105 } 6106 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6107 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6108 sav->rf0 = BWN_RF_READ(mac, 0x43); 6109 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6110 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6111 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6112 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6113 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6114 6115 if (!BWN_HAS_TXMAG(phy)) { 6116 sav->rf2 = BWN_RF_READ(mac, 0x52); 6117 sav->rf2 &= 0x00f0; 6118 } 6119 if (phy->type == BWN_PHYTYPE_B) { 6120 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6121 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6122 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6123 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6124 } else { 6125 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6126 | 0x8000); 6127 } 6128 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6129 & 0xf000); 6130 6131 tmp = 6132 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6133 BWN_PHY_WRITE(mac, tmp, 0x007f); 6134 6135 tmp = sav->phy_syncctl; 6136 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6137 tmp = sav->rf1; 6138 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6139 6140 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6141 if (phy->type == BWN_PHYTYPE_G || 6142 (phy->type == BWN_PHYTYPE_B && 6143 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6144 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6145 } else 6146 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6147 if (phy->rev >= 2) 6148 bwn_dummy_transmission(mac, 0, 1); 6149 bwn_phy_g_switch_chan(mac, 6, 0); 6150 BWN_RF_READ(mac, 0x51); 6151 if (phy->type == BWN_PHYTYPE_G) 6152 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6153 6154 nanouptime(&ts); 6155 if (time_before(lo->txctl_measured_time, 6156 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6157 bwn_lo_measure_txctl_values(mac); 6158 6159 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6160 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6161 else { 6162 if (phy->type == BWN_PHYTYPE_B) 6163 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6164 else 6165 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6166 } 6167 } 6168 6169 static void 6170 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6171 { 6172 struct bwn_phy *phy = &mac->mac_phy; 6173 struct bwn_phy_g *pg = &phy->phy_g; 6174 uint16_t tmp; 6175 6176 if (phy->rev >= 2) { 6177 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6178 tmp = (pg->pg_pga_gain << 8); 6179 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6180 DELAY(5); 6181 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6182 DELAY(2); 6183 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6184 } else { 6185 tmp = (pg->pg_pga_gain | 0xefa0); 6186 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6187 } 6188 if (phy->type == BWN_PHYTYPE_G) { 6189 if (phy->rev >= 3) 6190 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6191 else 6192 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6193 if (phy->rev >= 2) 6194 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6195 else 6196 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6197 } 6198 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6199 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6200 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6201 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6202 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6203 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6204 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6205 if (!BWN_HAS_TXMAG(phy)) { 6206 tmp = sav->rf2; 6207 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6208 } 6209 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6210 if (phy->type == BWN_PHYTYPE_B && 6211 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6212 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6213 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6214 } 6215 if (phy->rev >= 2) { 6216 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6217 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6218 sav->phy_analogoverval); 6219 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6220 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6221 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6222 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6223 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6224 } 6225 if (bwn_has_hwpctl(mac)) { 6226 tmp = (sav->phy_lomask & 0xbfff); 6227 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6228 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6229 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6231 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6232 } 6233 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6234 } 6235 6236 static int 6237 bwn_lo_probe_loctl(struct bwn_mac *mac, 6238 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6239 { 6240 struct bwn_phy *phy = &mac->mac_phy; 6241 struct bwn_phy_g *pg = &phy->phy_g; 6242 struct bwn_loctl orig, test; 6243 struct bwn_loctl prev = { -100, -100 }; 6244 static const struct bwn_loctl modifiers[] = { 6245 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6246 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6247 }; 6248 int begin, end, lower = 0, i; 6249 uint16_t feedth; 6250 6251 if (d->curstate == 0) { 6252 begin = 1; 6253 end = 8; 6254 } else if (d->curstate % 2 == 0) { 6255 begin = d->curstate - 1; 6256 end = d->curstate + 1; 6257 } else { 6258 begin = d->curstate - 2; 6259 end = d->curstate + 2; 6260 } 6261 if (begin < 1) 6262 begin += 8; 6263 if (end > 8) 6264 end -= 8; 6265 6266 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6267 i = begin; 6268 d->curstate = i; 6269 while (1) { 6270 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6271 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6272 test.i += modifiers[i - 1].i * d->multipler; 6273 test.q += modifiers[i - 1].q * d->multipler; 6274 if ((test.i != prev.i || test.q != prev.q) && 6275 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6276 bwn_lo_write(mac, &test); 6277 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6278 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6279 if (feedth < d->feedth) { 6280 memcpy(probe, &test, 6281 sizeof(struct bwn_loctl)); 6282 lower = 1; 6283 d->feedth = feedth; 6284 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6285 break; 6286 } 6287 } 6288 memcpy(&prev, &test, sizeof(prev)); 6289 if (i == end) 6290 break; 6291 if (i == 8) 6292 i = 1; 6293 else 6294 i++; 6295 d->curstate = i; 6296 } 6297 6298 return (lower); 6299 } 6300 6301 static void 6302 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6303 { 6304 struct bwn_phy *phy = &mac->mac_phy; 6305 struct bwn_phy_g *pg = &phy->phy_g; 6306 struct bwn_lo_g_sm d; 6307 struct bwn_loctl probe; 6308 int lower, repeat, cnt = 0; 6309 uint16_t feedth; 6310 6311 d.nmeasure = 0; 6312 d.multipler = 1; 6313 if (BWN_HAS_LOOPBACK(phy)) 6314 d.multipler = 3; 6315 6316 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6317 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6318 6319 do { 6320 bwn_lo_write(mac, &d.loctl); 6321 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6322 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6323 if (feedth < 0x258) { 6324 if (feedth >= 0x12c) 6325 *rxgain += 6; 6326 else 6327 *rxgain += 3; 6328 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6329 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6330 } 6331 d.feedth = feedth; 6332 d.curstate = 0; 6333 do { 6334 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6335 ("%s:%d: fail", __func__, __LINE__)); 6336 memcpy(&probe, &d.loctl, 6337 sizeof(struct bwn_loctl)); 6338 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6339 if (!lower) 6340 break; 6341 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6342 break; 6343 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6344 d.nmeasure++; 6345 } while (d.nmeasure < 24); 6346 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6347 6348 if (BWN_HAS_LOOPBACK(phy)) { 6349 if (d.feedth > 0x1194) 6350 *rxgain -= 6; 6351 else if (d.feedth < 0x5dc) 6352 *rxgain += 3; 6353 if (cnt == 0) { 6354 if (d.feedth <= 0x5dc) { 6355 d.multipler = 1; 6356 cnt++; 6357 } else 6358 d.multipler = 2; 6359 } else if (cnt == 2) 6360 d.multipler = 1; 6361 } 6362 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6363 } while (++cnt < repeat); 6364 } 6365 6366 static struct bwn_lo_calib * 6367 bwn_lo_calibset(struct bwn_mac *mac, 6368 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6369 { 6370 struct bwn_phy *phy = &mac->mac_phy; 6371 struct bwn_phy_g *pg = &phy->phy_g; 6372 struct bwn_loctl loctl = { 0, 0 }; 6373 struct bwn_lo_calib *cal; 6374 struct bwn_lo_g_value sval = { 0 }; 6375 int rxgain; 6376 uint16_t pad, reg, value; 6377 6378 sval.old_channel = phy->chan; 6379 bwn_mac_suspend(mac); 6380 bwn_lo_save(mac, &sval); 6381 6382 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6383 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6384 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6385 6386 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6387 if (rfatt->padmix) 6388 rxgain -= pad; 6389 if (BWN_HAS_LOOPBACK(phy)) 6390 rxgain += pg->pg_max_lb_gain; 6391 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6392 bwn_phy_g_set_bbatt(mac, bbatt->att); 6393 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6394 6395 bwn_lo_restore(mac, &sval); 6396 bwn_mac_enable(mac); 6397 6398 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6399 if (!cal) { 6400 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6401 return (NULL); 6402 } 6403 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6404 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6405 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6406 6407 BWN_GETTIME(cal->calib_time); 6408 6409 return (cal); 6410 } 6411 6412 static struct bwn_lo_calib * 6413 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6414 const struct bwn_rfatt *rfatt) 6415 { 6416 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6417 struct bwn_lo_calib *c; 6418 6419 TAILQ_FOREACH(c, &lo->calib_list, list) { 6420 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6421 continue; 6422 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6423 continue; 6424 return (c); 6425 } 6426 6427 c = bwn_lo_calibset(mac, bbatt, rfatt); 6428 if (!c) 6429 return (NULL); 6430 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6431 6432 return (c); 6433 } 6434 6435 static void 6436 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6437 { 6438 struct bwn_phy *phy = &mac->mac_phy; 6439 struct bwn_phy_g *pg = &phy->phy_g; 6440 struct bwn_softc *sc = mac->mac_sc; 6441 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6442 const struct bwn_rfatt *rfatt; 6443 const struct bwn_bbatt *bbatt; 6444 uint64_t pvector; 6445 int i; 6446 int rf_offset, bb_offset; 6447 uint8_t changed = 0; 6448 6449 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6450 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6451 ("%s:%d: fail", __func__, __LINE__)); 6452 6453 pvector = lo->power_vector; 6454 if (!update && !pvector) 6455 return; 6456 6457 bwn_mac_suspend(mac); 6458 6459 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6460 struct bwn_lo_calib *cal; 6461 int idx; 6462 uint16_t val; 6463 6464 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6465 continue; 6466 bb_offset = i / lo->rfatt.len; 6467 rf_offset = i % lo->rfatt.len; 6468 bbatt = &(lo->bbatt.array[bb_offset]); 6469 rfatt = &(lo->rfatt.array[rf_offset]); 6470 6471 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6472 if (!cal) { 6473 device_printf(sc->sc_dev, "LO: Could not " 6474 "calibrate DC table entry\n"); 6475 continue; 6476 } 6477 val = (uint8_t)(cal->ctl.q); 6478 val |= ((uint8_t)(cal->ctl.i)) << 4; 6479 free(cal, M_DEVBUF); 6480 6481 idx = i / 2; 6482 if (i % 2) 6483 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6484 | ((val & 0x00ff) << 8); 6485 else 6486 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6487 | (val & 0x00ff); 6488 changed = 1; 6489 } 6490 if (changed) { 6491 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6492 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6493 } 6494 bwn_mac_enable(mac); 6495 } 6496 6497 static void 6498 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6499 { 6500 6501 if (!rf->padmix) 6502 return; 6503 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6504 rf->att = 4; 6505 } 6506 6507 static void 6508 bwn_lo_g_adjust(struct bwn_mac *mac) 6509 { 6510 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6511 struct bwn_lo_calib *cal; 6512 struct bwn_rfatt rf; 6513 6514 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6515 bwn_lo_fixup_rfatt(&rf); 6516 6517 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6518 if (!cal) 6519 return; 6520 bwn_lo_write(mac, &cal->ctl); 6521 } 6522 6523 static void 6524 bwn_lo_g_init(struct bwn_mac *mac) 6525 { 6526 6527 if (!bwn_has_hwpctl(mac)) 6528 return; 6529 6530 bwn_lo_get_powervector(mac); 6531 bwn_phy_g_dc_lookup_init(mac, 1); 6532 } 6533 6534 static void 6535 bwn_mac_suspend(struct bwn_mac *mac) 6536 { 6537 struct bwn_softc *sc = mac->mac_sc; 6538 int i; 6539 uint32_t tmp; 6540 6541 KASSERT(mac->mac_suspended >= 0, 6542 ("%s:%d: fail", __func__, __LINE__)); 6543 6544 if (mac->mac_suspended == 0) { 6545 bwn_psctl(mac, BWN_PS_AWAKE); 6546 BWN_WRITE_4(mac, BWN_MACCTL, 6547 BWN_READ_4(mac, BWN_MACCTL) 6548 & ~BWN_MACCTL_ON); 6549 BWN_READ_4(mac, BWN_MACCTL); 6550 for (i = 35; i; i--) { 6551 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6552 if (tmp & BWN_INTR_MAC_SUSPENDED) 6553 goto out; 6554 DELAY(10); 6555 } 6556 for (i = 40; i; i--) { 6557 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6558 if (tmp & BWN_INTR_MAC_SUSPENDED) 6559 goto out; 6560 DELAY(1000); 6561 } 6562 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6563 } 6564 out: 6565 mac->mac_suspended++; 6566 } 6567 6568 static void 6569 bwn_mac_enable(struct bwn_mac *mac) 6570 { 6571 struct bwn_softc *sc = mac->mac_sc; 6572 uint16_t state; 6573 6574 state = bwn_shm_read_2(mac, BWN_SHARED, 6575 BWN_SHARED_UCODESTAT); 6576 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6577 state != BWN_SHARED_UCODESTAT_SLEEP) 6578 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6579 6580 mac->mac_suspended--; 6581 KASSERT(mac->mac_suspended >= 0, 6582 ("%s:%d: fail", __func__, __LINE__)); 6583 if (mac->mac_suspended == 0) { 6584 BWN_WRITE_4(mac, BWN_MACCTL, 6585 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6586 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6587 BWN_READ_4(mac, BWN_MACCTL); 6588 BWN_READ_4(mac, BWN_INTR_REASON); 6589 bwn_psctl(mac, 0); 6590 } 6591 } 6592 6593 static void 6594 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6595 { 6596 struct bwn_softc *sc = mac->mac_sc; 6597 int i; 6598 uint16_t ucstat; 6599 6600 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6601 ("%s:%d: fail", __func__, __LINE__)); 6602 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6603 ("%s:%d: fail", __func__, __LINE__)); 6604 6605 /* XXX forcibly awake and hwps-off */ 6606 6607 BWN_WRITE_4(mac, BWN_MACCTL, 6608 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6609 ~BWN_MACCTL_HWPS); 6610 BWN_READ_4(mac, BWN_MACCTL); 6611 if (siba_get_revid(sc->sc_dev) >= 5) { 6612 for (i = 0; i < 100; i++) { 6613 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6614 BWN_SHARED_UCODESTAT); 6615 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6616 break; 6617 DELAY(10); 6618 } 6619 } 6620 } 6621 6622 static int16_t 6623 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6624 { 6625 6626 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6627 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6628 } 6629 6630 static void 6631 bwn_nrssi_threshold(struct bwn_mac *mac) 6632 { 6633 struct bwn_phy *phy = &mac->mac_phy; 6634 struct bwn_phy_g *pg = &phy->phy_g; 6635 struct bwn_softc *sc = mac->mac_sc; 6636 int32_t a, b; 6637 int16_t tmp16; 6638 uint16_t tmpu16; 6639 6640 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6641 6642 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6643 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6644 a = 0x13; 6645 b = 0x12; 6646 } else { 6647 a = 0xe; 6648 b = 0x11; 6649 } 6650 6651 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6652 a += (pg->pg_nrssi[0] << 6); 6653 a += (a < 32) ? 31 : 32; 6654 a = a >> 6; 6655 a = MIN(MAX(a, -31), 31); 6656 6657 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6658 b += (pg->pg_nrssi[0] << 6); 6659 if (b < 32) 6660 b += 31; 6661 else 6662 b += 32; 6663 b = b >> 6; 6664 b = MIN(MAX(b, -31), 31); 6665 6666 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6667 tmpu16 |= ((uint32_t)b & 0x0000003f); 6668 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6669 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6670 return; 6671 } 6672 6673 tmp16 = bwn_nrssi_read(mac, 0x20); 6674 if (tmp16 >= 0x20) 6675 tmp16 -= 0x40; 6676 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6677 } 6678 6679 static void 6680 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6681 { 6682 #define SAVE_RF_MAX 3 6683 #define SAVE_PHY_COMM_MAX 4 6684 #define SAVE_PHY3_MAX 8 6685 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6686 { 0x7a, 0x52, 0x43 }; 6687 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6688 { 0x15, 0x5a, 0x59, 0x58 }; 6689 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6690 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6691 0x0801, 0x0060, 0x0014, 0x0478 6692 }; 6693 struct bwn_phy *phy = &mac->mac_phy; 6694 struct bwn_phy_g *pg = &phy->phy_g; 6695 int32_t i, tmp32, phy3_idx = 0; 6696 uint16_t delta, tmp; 6697 uint16_t save_rf[SAVE_RF_MAX]; 6698 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6699 uint16_t save_phy3[SAVE_PHY3_MAX]; 6700 uint16_t ant_div, phy0, chan_ex; 6701 int16_t nrssi0, nrssi1; 6702 6703 KASSERT(phy->type == BWN_PHYTYPE_G, 6704 ("%s:%d: fail", __func__, __LINE__)); 6705 6706 if (phy->rf_rev >= 9) 6707 return; 6708 if (phy->rf_rev == 8) 6709 bwn_nrssi_offset(mac); 6710 6711 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6712 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6713 6714 /* 6715 * Save RF/PHY registers for later restoration 6716 */ 6717 ant_div = BWN_READ_2(mac, 0x03e2); 6718 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6719 for (i = 0; i < SAVE_RF_MAX; ++i) 6720 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6721 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6722 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6723 6724 phy0 = BWN_READ_2(mac, BWN_PHY0); 6725 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6726 if (phy->rev >= 3) { 6727 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6728 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6729 BWN_PHY_WRITE(mac, 0x002e, 0); 6730 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6731 switch (phy->rev) { 6732 case 4: 6733 case 6: 6734 case 7: 6735 BWN_PHY_SET(mac, 0x0478, 0x0100); 6736 BWN_PHY_SET(mac, 0x0801, 0x0040); 6737 break; 6738 case 3: 6739 case 5: 6740 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6741 break; 6742 } 6743 BWN_PHY_SET(mac, 0x0060, 0x0040); 6744 BWN_PHY_SET(mac, 0x0014, 0x0200); 6745 } 6746 /* 6747 * Calculate nrssi0 6748 */ 6749 BWN_RF_SET(mac, 0x007a, 0x0070); 6750 bwn_set_all_gains(mac, 0, 8, 0); 6751 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6752 if (phy->rev >= 2) { 6753 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6754 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6755 } 6756 BWN_RF_SET(mac, 0x007a, 0x0080); 6757 DELAY(20); 6758 6759 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6760 if (nrssi0 >= 0x0020) 6761 nrssi0 -= 0x0040; 6762 6763 /* 6764 * Calculate nrssi1 6765 */ 6766 BWN_RF_MASK(mac, 0x007a, 0x007f); 6767 if (phy->rev >= 2) 6768 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6769 6770 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6771 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6772 BWN_RF_SET(mac, 0x007a, 0x000f); 6773 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6774 if (phy->rev >= 2) { 6775 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6776 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6777 } 6778 6779 bwn_set_all_gains(mac, 3, 0, 1); 6780 if (phy->rf_rev == 8) { 6781 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6782 } else { 6783 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6784 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6785 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6786 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6787 } 6788 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6789 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6790 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6791 DELAY(20); 6792 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6793 6794 /* 6795 * Install calculated narrow RSSI values 6796 */ 6797 if (nrssi1 >= 0x0020) 6798 nrssi1 -= 0x0040; 6799 if (nrssi0 == nrssi1) 6800 pg->pg_nrssi_slope = 0x00010000; 6801 else 6802 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6803 if (nrssi0 >= -4) { 6804 pg->pg_nrssi[0] = nrssi1; 6805 pg->pg_nrssi[1] = nrssi0; 6806 } 6807 6808 /* 6809 * Restore saved RF/PHY registers 6810 */ 6811 if (phy->rev >= 3) { 6812 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6813 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6814 save_phy3[phy3_idx]); 6815 } 6816 } 6817 if (phy->rev >= 2) { 6818 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6819 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6820 } 6821 6822 for (i = 0; i < SAVE_RF_MAX; ++i) 6823 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6824 6825 BWN_WRITE_2(mac, 0x03e2, ant_div); 6826 BWN_WRITE_2(mac, 0x03e6, phy0); 6827 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6828 6829 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6830 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6831 6832 bwn_spu_workaround(mac, phy->chan); 6833 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6834 bwn_set_original_gains(mac); 6835 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6836 if (phy->rev >= 3) { 6837 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6838 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6839 save_phy3[phy3_idx]); 6840 } 6841 } 6842 6843 delta = 0x1f - pg->pg_nrssi[0]; 6844 for (i = 0; i < 64; i++) { 6845 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6846 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6847 pg->pg_nrssi_lt[i] = tmp32; 6848 } 6849 6850 bwn_nrssi_threshold(mac); 6851 #undef SAVE_RF_MAX 6852 #undef SAVE_PHY_COMM_MAX 6853 #undef SAVE_PHY3_MAX 6854 } 6855 6856 static void 6857 bwn_nrssi_offset(struct bwn_mac *mac) 6858 { 6859 #define SAVE_RF_MAX 2 6860 #define SAVE_PHY_COMM_MAX 10 6861 #define SAVE_PHY6_MAX 8 6862 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6863 { 0x7a, 0x43 }; 6864 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6865 0x0001, 0x0811, 0x0812, 0x0814, 6866 0x0815, 0x005a, 0x0059, 0x0058, 6867 0x000a, 0x0003 6868 }; 6869 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6870 0x002e, 0x002f, 0x080f, 0x0810, 6871 0x0801, 0x0060, 0x0014, 0x0478 6872 }; 6873 struct bwn_phy *phy = &mac->mac_phy; 6874 int i, phy6_idx = 0; 6875 uint16_t save_rf[SAVE_RF_MAX]; 6876 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6877 uint16_t save_phy6[SAVE_PHY6_MAX]; 6878 int16_t nrssi; 6879 uint16_t saved = 0xffff; 6880 6881 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6882 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6883 for (i = 0; i < SAVE_RF_MAX; ++i) 6884 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6885 6886 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6887 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6888 BWN_PHY_SET(mac, 0x0811, 0x000c); 6889 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6890 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6891 if (phy->rev >= 6) { 6892 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6893 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6894 6895 BWN_PHY_WRITE(mac, 0x002e, 0); 6896 BWN_PHY_WRITE(mac, 0x002f, 0); 6897 BWN_PHY_WRITE(mac, 0x080f, 0); 6898 BWN_PHY_WRITE(mac, 0x0810, 0); 6899 BWN_PHY_SET(mac, 0x0478, 0x0100); 6900 BWN_PHY_SET(mac, 0x0801, 0x0040); 6901 BWN_PHY_SET(mac, 0x0060, 0x0040); 6902 BWN_PHY_SET(mac, 0x0014, 0x0200); 6903 } 6904 BWN_RF_SET(mac, 0x007a, 0x0070); 6905 BWN_RF_SET(mac, 0x007a, 0x0080); 6906 DELAY(30); 6907 6908 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6909 if (nrssi >= 0x20) 6910 nrssi -= 0x40; 6911 if (nrssi == 31) { 6912 for (i = 7; i >= 4; i--) { 6913 BWN_RF_WRITE(mac, 0x007b, i); 6914 DELAY(20); 6915 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 6916 0x003f); 6917 if (nrssi >= 0x20) 6918 nrssi -= 0x40; 6919 if (nrssi < 31 && saved == 0xffff) 6920 saved = i; 6921 } 6922 if (saved == 0xffff) 6923 saved = 4; 6924 } else { 6925 BWN_RF_MASK(mac, 0x007a, 0x007f); 6926 if (phy->rev != 1) { 6927 BWN_PHY_SET(mac, 0x0814, 0x0001); 6928 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 6929 } 6930 BWN_PHY_SET(mac, 0x0811, 0x000c); 6931 BWN_PHY_SET(mac, 0x0812, 0x000c); 6932 BWN_PHY_SET(mac, 0x0811, 0x0030); 6933 BWN_PHY_SET(mac, 0x0812, 0x0030); 6934 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6935 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6936 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6937 if (phy->rev == 0) 6938 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 6939 else 6940 BWN_PHY_SET(mac, 0x000a, 0x2000); 6941 if (phy->rev != 1) { 6942 BWN_PHY_SET(mac, 0x0814, 0x0004); 6943 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 6944 } 6945 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6946 BWN_RF_SET(mac, 0x007a, 0x000f); 6947 bwn_set_all_gains(mac, 3, 0, 1); 6948 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 6949 DELAY(30); 6950 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6951 if (nrssi >= 0x20) 6952 nrssi -= 0x40; 6953 if (nrssi == -32) { 6954 for (i = 0; i < 4; i++) { 6955 BWN_RF_WRITE(mac, 0x007b, i); 6956 DELAY(20); 6957 nrssi = (int16_t)((BWN_PHY_READ(mac, 6958 0x047f) >> 8) & 0x003f); 6959 if (nrssi >= 0x20) 6960 nrssi -= 0x40; 6961 if (nrssi > -31 && saved == 0xffff) 6962 saved = i; 6963 } 6964 if (saved == 0xffff) 6965 saved = 3; 6966 } else 6967 saved = 0; 6968 } 6969 BWN_RF_WRITE(mac, 0x007b, saved); 6970 6971 /* 6972 * Restore saved RF/PHY registers 6973 */ 6974 if (phy->rev >= 6) { 6975 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 6976 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6977 save_phy6[phy6_idx]); 6978 } 6979 } 6980 if (phy->rev != 1) { 6981 for (i = 3; i < 5; i++) 6982 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 6983 save_phy_comm[i]); 6984 } 6985 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 6986 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6987 6988 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 6989 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6990 6991 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 6992 BWN_PHY_SET(mac, 0x0429, 0x8000); 6993 bwn_set_original_gains(mac); 6994 if (phy->rev >= 6) { 6995 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 6996 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6997 save_phy6[phy6_idx]); 6998 } 6999 } 7000 7001 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7002 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7003 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7004 } 7005 7006 static void 7007 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7008 int16_t third) 7009 { 7010 struct bwn_phy *phy = &mac->mac_phy; 7011 uint16_t i; 7012 uint16_t start = 0x08, end = 0x18; 7013 uint16_t tmp; 7014 uint16_t table; 7015 7016 if (phy->rev <= 1) { 7017 start = 0x10; 7018 end = 0x20; 7019 } 7020 7021 table = BWN_OFDMTAB_GAINX; 7022 if (phy->rev <= 1) 7023 table = BWN_OFDMTAB_GAINX_R1; 7024 for (i = 0; i < 4; i++) 7025 bwn_ofdmtab_write_2(mac, table, i, first); 7026 7027 for (i = start; i < end; i++) 7028 bwn_ofdmtab_write_2(mac, table, i, second); 7029 7030 if (third != -1) { 7031 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7032 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7033 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7034 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7035 } 7036 bwn_dummy_transmission(mac, 0, 1); 7037 } 7038 7039 static void 7040 bwn_set_original_gains(struct bwn_mac *mac) 7041 { 7042 struct bwn_phy *phy = &mac->mac_phy; 7043 uint16_t i, tmp; 7044 uint16_t table; 7045 uint16_t start = 0x0008, end = 0x0018; 7046 7047 if (phy->rev <= 1) { 7048 start = 0x0010; 7049 end = 0x0020; 7050 } 7051 7052 table = BWN_OFDMTAB_GAINX; 7053 if (phy->rev <= 1) 7054 table = BWN_OFDMTAB_GAINX_R1; 7055 for (i = 0; i < 4; i++) { 7056 tmp = (i & 0xfffc); 7057 tmp |= (i & 0x0001) << 1; 7058 tmp |= (i & 0x0002) >> 1; 7059 7060 bwn_ofdmtab_write_2(mac, table, i, tmp); 7061 } 7062 7063 for (i = start; i < end; i++) 7064 bwn_ofdmtab_write_2(mac, table, i, i - start); 7065 7066 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7067 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7068 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7069 bwn_dummy_transmission(mac, 0, 1); 7070 } 7071 7072 static void 7073 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7074 { 7075 struct bwn_phy *phy = &mac->mac_phy; 7076 struct bwn_phy_g *pg = &phy->phy_g; 7077 struct bwn_rfatt old_rfatt, rfatt; 7078 struct bwn_bbatt old_bbatt, bbatt; 7079 struct bwn_softc *sc = mac->mac_sc; 7080 uint8_t old_txctl = 0; 7081 7082 KASSERT(phy->type == BWN_PHYTYPE_G, 7083 ("%s:%d: fail", __func__, __LINE__)); 7084 7085 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7086 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7087 return; 7088 7089 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7090 7091 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7092 7093 if (!phy->gmode) 7094 return; 7095 bwn_hwpctl_early_init(mac); 7096 if (pg->pg_curtssi == 0) { 7097 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7098 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7099 } else { 7100 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7101 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7102 old_txctl = pg->pg_txctl; 7103 7104 bbatt.att = 11; 7105 if (phy->rf_rev == 8) { 7106 rfatt.att = 15; 7107 rfatt.padmix = 1; 7108 } else { 7109 rfatt.att = 9; 7110 rfatt.padmix = 0; 7111 } 7112 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7113 } 7114 bwn_dummy_transmission(mac, 0, 1); 7115 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7116 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7117 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7118 else 7119 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7120 &old_rfatt, old_txctl); 7121 } 7122 bwn_hwpctl_init_gphy(mac); 7123 7124 /* clear TSSI */ 7125 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7126 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7127 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7128 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7129 } 7130 7131 static void 7132 bwn_hwpctl_early_init(struct bwn_mac *mac) 7133 { 7134 struct bwn_phy *phy = &mac->mac_phy; 7135 7136 if (!bwn_has_hwpctl(mac)) { 7137 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7138 return; 7139 } 7140 7141 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7142 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7143 BWN_PHY_SET(mac, 0x047c, 0x0002); 7144 BWN_PHY_SET(mac, 0x047a, 0xf000); 7145 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7146 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7147 BWN_PHY_SET(mac, 0x005d, 0x8000); 7148 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7149 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7150 BWN_PHY_SET(mac, 0x0036, 0x0400); 7151 } else { 7152 BWN_PHY_SET(mac, 0x0036, 0x0200); 7153 BWN_PHY_SET(mac, 0x0036, 0x0400); 7154 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7155 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7156 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7157 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7158 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7159 } 7160 } 7161 7162 static void 7163 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7164 { 7165 struct bwn_phy *phy = &mac->mac_phy; 7166 struct bwn_phy_g *pg = &phy->phy_g; 7167 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7168 int i; 7169 uint16_t nr_written = 0, tmp, value; 7170 uint8_t rf, bb; 7171 7172 if (!bwn_has_hwpctl(mac)) { 7173 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7174 return; 7175 } 7176 7177 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7178 (pg->pg_idletssi - pg->pg_curtssi)); 7179 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7180 (pg->pg_idletssi - pg->pg_curtssi)); 7181 7182 for (i = 0; i < 32; i++) 7183 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7184 for (i = 32; i < 64; i++) 7185 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7186 for (i = 0; i < 64; i += 2) { 7187 value = (uint16_t) pg->pg_tssi2dbm[i]; 7188 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7189 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7190 } 7191 7192 for (rf = 0; rf < lo->rfatt.len; rf++) { 7193 for (bb = 0; bb < lo->bbatt.len; bb++) { 7194 if (nr_written >= 0x40) 7195 return; 7196 tmp = lo->bbatt.array[bb].att; 7197 tmp <<= 8; 7198 if (phy->rf_rev == 8) 7199 tmp |= 0x50; 7200 else 7201 tmp |= 0x40; 7202 tmp |= lo->rfatt.array[rf].att; 7203 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7204 nr_written++; 7205 } 7206 } 7207 7208 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7209 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7210 7211 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7212 BWN_PHY_SET(mac, 0x0478, 0x0800); 7213 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7214 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7215 7216 bwn_phy_g_dc_lookup_init(mac, 1); 7217 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7218 } 7219 7220 static void 7221 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7222 { 7223 struct bwn_softc *sc = mac->mac_sc; 7224 7225 if (spu != 0) 7226 bwn_spu_workaround(mac, channel); 7227 7228 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7229 7230 if (channel == 14) { 7231 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7232 bwn_hf_write(mac, 7233 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7234 else 7235 bwn_hf_write(mac, 7236 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7237 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7238 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7239 return; 7240 } 7241 7242 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7243 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7244 } 7245 7246 static uint16_t 7247 bwn_phy_g_chan2freq(uint8_t channel) 7248 { 7249 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7250 7251 KASSERT(channel >= 1 && channel <= 14, 7252 ("%s:%d: fail", __func__, __LINE__)); 7253 7254 return (bwn_phy_g_rf_channels[channel - 1]); 7255 } 7256 7257 static void 7258 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7259 const struct bwn_rfatt *rfatt, uint8_t txctl) 7260 { 7261 struct bwn_phy *phy = &mac->mac_phy; 7262 struct bwn_phy_g *pg = &phy->phy_g; 7263 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7264 uint16_t bb, rf; 7265 uint16_t tx_bias, tx_magn; 7266 7267 bb = bbatt->att; 7268 rf = rfatt->att; 7269 tx_bias = lo->tx_bias; 7270 tx_magn = lo->tx_magn; 7271 if (tx_bias == 0xff) 7272 tx_bias = 0; 7273 7274 pg->pg_txctl = txctl; 7275 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7276 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7277 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7278 bwn_phy_g_set_bbatt(mac, bb); 7279 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7280 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7281 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7282 else { 7283 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7284 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7285 } 7286 if (BWN_HAS_TXMAG(phy)) 7287 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7288 else 7289 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7290 bwn_lo_g_adjust(mac); 7291 } 7292 7293 static void 7294 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7295 uint16_t bbatt) 7296 { 7297 struct bwn_phy *phy = &mac->mac_phy; 7298 7299 if (phy->analog == 0) { 7300 BWN_WRITE_2(mac, BWN_PHY0, 7301 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7302 return; 7303 } 7304 if (phy->analog > 1) { 7305 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7306 return; 7307 } 7308 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7309 } 7310 7311 static uint16_t 7312 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7313 { 7314 struct bwn_phy *phy = &mac->mac_phy; 7315 struct bwn_phy_g *pg = &phy->phy_g; 7316 struct bwn_softc *sc = mac->mac_sc; 7317 int max_lb_gain; 7318 uint16_t extlna; 7319 uint16_t i; 7320 7321 if (phy->gmode == 0) 7322 return (0); 7323 7324 if (BWN_HAS_LOOPBACK(phy)) { 7325 max_lb_gain = pg->pg_max_lb_gain; 7326 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7327 if (max_lb_gain >= 0x46) { 7328 extlna = 0x3000; 7329 max_lb_gain -= 0x46; 7330 } else if (max_lb_gain >= 0x3a) { 7331 extlna = 0x1000; 7332 max_lb_gain -= 0x3a; 7333 } else if (max_lb_gain >= 0x2e) { 7334 extlna = 0x2000; 7335 max_lb_gain -= 0x2e; 7336 } else { 7337 extlna = 0; 7338 max_lb_gain -= 0x10; 7339 } 7340 7341 for (i = 0; i < 16; i++) { 7342 max_lb_gain -= (i * 6); 7343 if (max_lb_gain < 6) 7344 break; 7345 } 7346 7347 if ((phy->rev < 7) || 7348 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7349 if (reg == BWN_PHY_RFOVER) { 7350 return (0x1b3); 7351 } else if (reg == BWN_PHY_RFOVERVAL) { 7352 extlna |= (i << 8); 7353 switch (lpd) { 7354 case BWN_LPD(0, 1, 1): 7355 return (0x0f92); 7356 case BWN_LPD(0, 0, 1): 7357 case BWN_LPD(1, 0, 1): 7358 return (0x0092 | extlna); 7359 case BWN_LPD(1, 0, 0): 7360 return (0x0093 | extlna); 7361 } 7362 KASSERT(0 == 1, 7363 ("%s:%d: fail", __func__, __LINE__)); 7364 } 7365 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7366 } else { 7367 if (reg == BWN_PHY_RFOVER) 7368 return (0x9b3); 7369 if (reg == BWN_PHY_RFOVERVAL) { 7370 if (extlna) 7371 extlna |= 0x8000; 7372 extlna |= (i << 8); 7373 switch (lpd) { 7374 case BWN_LPD(0, 1, 1): 7375 return (0x8f92); 7376 case BWN_LPD(0, 0, 1): 7377 return (0x8092 | extlna); 7378 case BWN_LPD(1, 0, 1): 7379 return (0x2092 | extlna); 7380 case BWN_LPD(1, 0, 0): 7381 return (0x2093 | extlna); 7382 } 7383 KASSERT(0 == 1, 7384 ("%s:%d: fail", __func__, __LINE__)); 7385 } 7386 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7387 } 7388 return (0); 7389 } 7390 7391 if ((phy->rev < 7) || 7392 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7393 if (reg == BWN_PHY_RFOVER) { 7394 return (0x1b3); 7395 } else if (reg == BWN_PHY_RFOVERVAL) { 7396 switch (lpd) { 7397 case BWN_LPD(0, 1, 1): 7398 return (0x0fb2); 7399 case BWN_LPD(0, 0, 1): 7400 return (0x00b2); 7401 case BWN_LPD(1, 0, 1): 7402 return (0x30b2); 7403 case BWN_LPD(1, 0, 0): 7404 return (0x30b3); 7405 } 7406 KASSERT(0 == 1, 7407 ("%s:%d: fail", __func__, __LINE__)); 7408 } 7409 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7410 } else { 7411 if (reg == BWN_PHY_RFOVER) { 7412 return (0x9b3); 7413 } else if (reg == BWN_PHY_RFOVERVAL) { 7414 switch (lpd) { 7415 case BWN_LPD(0, 1, 1): 7416 return (0x8fb2); 7417 case BWN_LPD(0, 0, 1): 7418 return (0x80b2); 7419 case BWN_LPD(1, 0, 1): 7420 return (0x20b2); 7421 case BWN_LPD(1, 0, 0): 7422 return (0x20b3); 7423 } 7424 KASSERT(0 == 1, 7425 ("%s:%d: fail", __func__, __LINE__)); 7426 } 7427 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7428 } 7429 return (0); 7430 } 7431 7432 static void 7433 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7434 { 7435 7436 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7437 return; 7438 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7439 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7440 DELAY(1000); 7441 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7442 } 7443 7444 static int 7445 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7446 { 7447 struct bwn_softc *sc = mac->mac_sc; 7448 struct bwn_fw *fw = &mac->mac_fw; 7449 const uint8_t rev = siba_get_revid(sc->sc_dev); 7450 const char *filename; 7451 uint32_t high; 7452 int error; 7453 7454 /* microcode */ 7455 if (rev >= 5 && rev <= 10) 7456 filename = "ucode5"; 7457 else if (rev >= 11 && rev <= 12) 7458 filename = "ucode11"; 7459 else if (rev == 13) 7460 filename = "ucode13"; 7461 else if (rev == 14) 7462 filename = "ucode14"; 7463 else if (rev >= 15) 7464 filename = "ucode15"; 7465 else { 7466 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7467 bwn_release_firmware(mac); 7468 return (EOPNOTSUPP); 7469 } 7470 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7471 if (error) { 7472 bwn_release_firmware(mac); 7473 return (error); 7474 } 7475 7476 /* PCM */ 7477 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7478 if (rev >= 5 && rev <= 10) { 7479 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7480 if (error == ENOENT) 7481 fw->no_pcmfile = 1; 7482 else if (error) { 7483 bwn_release_firmware(mac); 7484 return (error); 7485 } 7486 } else if (rev < 11) { 7487 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7488 return (EOPNOTSUPP); 7489 } 7490 7491 /* initvals */ 7492 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7493 switch (mac->mac_phy.type) { 7494 case BWN_PHYTYPE_A: 7495 if (rev < 5 || rev > 10) 7496 goto fail1; 7497 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7498 filename = "a0g1initvals5"; 7499 else 7500 filename = "a0g0initvals5"; 7501 break; 7502 case BWN_PHYTYPE_G: 7503 if (rev >= 5 && rev <= 10) 7504 filename = "b0g0initvals5"; 7505 else if (rev >= 13) 7506 filename = "b0g0initvals13"; 7507 else 7508 goto fail1; 7509 break; 7510 case BWN_PHYTYPE_LP: 7511 if (rev == 13) 7512 filename = "lp0initvals13"; 7513 else if (rev == 14) 7514 filename = "lp0initvals14"; 7515 else if (rev >= 15) 7516 filename = "lp0initvals15"; 7517 else 7518 goto fail1; 7519 break; 7520 case BWN_PHYTYPE_N: 7521 if (rev >= 11 && rev <= 12) 7522 filename = "n0initvals11"; 7523 else 7524 goto fail1; 7525 break; 7526 default: 7527 goto fail1; 7528 } 7529 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7530 if (error) { 7531 bwn_release_firmware(mac); 7532 return (error); 7533 } 7534 7535 /* bandswitch initvals */ 7536 switch (mac->mac_phy.type) { 7537 case BWN_PHYTYPE_A: 7538 if (rev >= 5 && rev <= 10) { 7539 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7540 filename = "a0g1bsinitvals5"; 7541 else 7542 filename = "a0g0bsinitvals5"; 7543 } else if (rev >= 11) 7544 filename = NULL; 7545 else 7546 goto fail1; 7547 break; 7548 case BWN_PHYTYPE_G: 7549 if (rev >= 5 && rev <= 10) 7550 filename = "b0g0bsinitvals5"; 7551 else if (rev >= 11) 7552 filename = NULL; 7553 else 7554 goto fail1; 7555 break; 7556 case BWN_PHYTYPE_LP: 7557 if (rev == 13) 7558 filename = "lp0bsinitvals13"; 7559 else if (rev == 14) 7560 filename = "lp0bsinitvals14"; 7561 else if (rev >= 15) 7562 filename = "lp0bsinitvals15"; 7563 else 7564 goto fail1; 7565 break; 7566 case BWN_PHYTYPE_N: 7567 if (rev >= 11 && rev <= 12) 7568 filename = "n0bsinitvals11"; 7569 else 7570 goto fail1; 7571 break; 7572 default: 7573 goto fail1; 7574 } 7575 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7576 if (error) { 7577 bwn_release_firmware(mac); 7578 return (error); 7579 } 7580 return (0); 7581 fail1: 7582 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7583 bwn_release_firmware(mac); 7584 return (EOPNOTSUPP); 7585 } 7586 7587 static int 7588 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7589 const char *name, struct bwn_fwfile *bfw) 7590 { 7591 const struct bwn_fwhdr *hdr; 7592 struct bwn_softc *sc = mac->mac_sc; 7593 const struct firmware *fw; 7594 char namebuf[64]; 7595 7596 if (name == NULL) { 7597 bwn_do_release_fw(bfw); 7598 return (0); 7599 } 7600 if (bfw->filename != NULL) { 7601 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7602 return (0); 7603 bwn_do_release_fw(bfw); 7604 } 7605 7606 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7607 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7608 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7609 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7610 fw = firmware_get(namebuf); 7611 if (fw == NULL) { 7612 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7613 namebuf); 7614 return (ENOENT); 7615 } 7616 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7617 goto fail; 7618 hdr = (const struct bwn_fwhdr *)(fw->data); 7619 switch (hdr->type) { 7620 case BWN_FWTYPE_UCODE: 7621 case BWN_FWTYPE_PCM: 7622 if (be32toh(hdr->size) != 7623 (fw->datasize - sizeof(struct bwn_fwhdr))) 7624 goto fail; 7625 /* FALLTHROUGH */ 7626 case BWN_FWTYPE_IV: 7627 if (hdr->ver != 1) 7628 goto fail; 7629 break; 7630 default: 7631 goto fail; 7632 } 7633 bfw->filename = name; 7634 bfw->fw = fw; 7635 bfw->type = type; 7636 return (0); 7637 fail: 7638 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7639 if (fw != NULL) 7640 firmware_put(fw, FIRMWARE_UNLOAD); 7641 return (EPROTO); 7642 } 7643 7644 static void 7645 bwn_release_firmware(struct bwn_mac *mac) 7646 { 7647 7648 bwn_do_release_fw(&mac->mac_fw.ucode); 7649 bwn_do_release_fw(&mac->mac_fw.pcm); 7650 bwn_do_release_fw(&mac->mac_fw.initvals); 7651 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7652 } 7653 7654 static void 7655 bwn_do_release_fw(struct bwn_fwfile *bfw) 7656 { 7657 7658 if (bfw->fw != NULL) 7659 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7660 bfw->fw = NULL; 7661 bfw->filename = NULL; 7662 } 7663 7664 static int 7665 bwn_fw_loaducode(struct bwn_mac *mac) 7666 { 7667 #define GETFWOFFSET(fwp, offset) \ 7668 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7669 #define GETFWSIZE(fwp, offset) \ 7670 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7671 struct bwn_softc *sc = mac->mac_sc; 7672 const uint32_t *data; 7673 unsigned int i; 7674 uint32_t ctl; 7675 uint16_t date, fwcaps, time; 7676 int error = 0; 7677 7678 ctl = BWN_READ_4(mac, BWN_MACCTL); 7679 ctl |= BWN_MACCTL_MCODE_JMP0; 7680 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7681 __LINE__)); 7682 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7683 for (i = 0; i < 64; i++) 7684 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7685 for (i = 0; i < 4096; i += 2) 7686 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7687 7688 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7689 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7690 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7691 i++) { 7692 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7693 DELAY(10); 7694 } 7695 7696 if (mac->mac_fw.pcm.fw) { 7697 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7698 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7699 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7700 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7701 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7702 sizeof(struct bwn_fwhdr)); i++) { 7703 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7704 DELAY(10); 7705 } 7706 } 7707 7708 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7709 BWN_WRITE_4(mac, BWN_MACCTL, 7710 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7711 BWN_MACCTL_MCODE_RUN); 7712 7713 for (i = 0; i < 21; i++) { 7714 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7715 break; 7716 if (i >= 20) { 7717 device_printf(sc->sc_dev, "ucode timeout\n"); 7718 error = ENXIO; 7719 goto error; 7720 } 7721 DELAY(50000); 7722 } 7723 BWN_READ_4(mac, BWN_INTR_REASON); 7724 7725 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7726 if (mac->mac_fw.rev <= 0x128) { 7727 device_printf(sc->sc_dev, "the firmware is too old\n"); 7728 error = EOPNOTSUPP; 7729 goto error; 7730 } 7731 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7732 BWN_SHARED_UCODE_PATCH); 7733 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7734 mac->mac_fw.opensource = (date == 0xffff); 7735 if (bwn_wme != 0) 7736 mac->mac_flags |= BWN_MAC_FLAG_WME; 7737 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7738 7739 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7740 if (mac->mac_fw.opensource == 0) { 7741 device_printf(sc->sc_dev, 7742 "firmware version (rev %u patch %u date %#x time %#x)\n", 7743 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7744 if (mac->mac_fw.no_pcmfile) 7745 device_printf(sc->sc_dev, 7746 "no HW crypto acceleration due to pcm5\n"); 7747 } else { 7748 mac->mac_fw.patch = time; 7749 fwcaps = bwn_fwcaps_read(mac); 7750 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7751 device_printf(sc->sc_dev, 7752 "disabling HW crypto acceleration\n"); 7753 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7754 } 7755 if (!(fwcaps & BWN_FWCAPS_WME)) { 7756 device_printf(sc->sc_dev, "disabling WME support\n"); 7757 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7758 } 7759 } 7760 7761 if (BWN_ISOLDFMT(mac)) 7762 device_printf(sc->sc_dev, "using old firmware image\n"); 7763 7764 return (0); 7765 7766 error: 7767 BWN_WRITE_4(mac, BWN_MACCTL, 7768 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7769 BWN_MACCTL_MCODE_JMP0); 7770 7771 return (error); 7772 #undef GETFWSIZE 7773 #undef GETFWOFFSET 7774 } 7775 7776 /* OpenFirmware only */ 7777 static uint16_t 7778 bwn_fwcaps_read(struct bwn_mac *mac) 7779 { 7780 7781 KASSERT(mac->mac_fw.opensource == 1, 7782 ("%s:%d: fail", __func__, __LINE__)); 7783 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7784 } 7785 7786 static int 7787 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7788 size_t count, size_t array_size) 7789 { 7790 #define GET_NEXTIV16(iv) \ 7791 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7792 sizeof(uint16_t) + sizeof(uint16_t))) 7793 #define GET_NEXTIV32(iv) \ 7794 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7795 sizeof(uint16_t) + sizeof(uint32_t))) 7796 struct bwn_softc *sc = mac->mac_sc; 7797 const struct bwn_fwinitvals *iv; 7798 uint16_t offset; 7799 size_t i; 7800 uint8_t bit32; 7801 7802 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7803 ("%s:%d: fail", __func__, __LINE__)); 7804 iv = ivals; 7805 for (i = 0; i < count; i++) { 7806 if (array_size < sizeof(iv->offset_size)) 7807 goto fail; 7808 array_size -= sizeof(iv->offset_size); 7809 offset = be16toh(iv->offset_size); 7810 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7811 offset &= BWN_FWINITVALS_OFFSET_MASK; 7812 if (offset >= 0x1000) 7813 goto fail; 7814 if (bit32) { 7815 if (array_size < sizeof(iv->data.d32)) 7816 goto fail; 7817 array_size -= sizeof(iv->data.d32); 7818 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7819 iv = GET_NEXTIV32(iv); 7820 } else { 7821 7822 if (array_size < sizeof(iv->data.d16)) 7823 goto fail; 7824 array_size -= sizeof(iv->data.d16); 7825 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7826 7827 iv = GET_NEXTIV16(iv); 7828 } 7829 } 7830 if (array_size != 0) 7831 goto fail; 7832 return (0); 7833 fail: 7834 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7835 return (EPROTO); 7836 #undef GET_NEXTIV16 7837 #undef GET_NEXTIV32 7838 } 7839 7840 static int 7841 bwn_switch_channel(struct bwn_mac *mac, int chan) 7842 { 7843 struct bwn_phy *phy = &(mac->mac_phy); 7844 struct bwn_softc *sc = mac->mac_sc; 7845 struct ieee80211com *ic = &sc->sc_ic; 7846 uint16_t channelcookie, savedcookie; 7847 int error; 7848 7849 if (chan == 0xffff) 7850 chan = phy->get_default_chan(mac); 7851 7852 channelcookie = chan; 7853 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7854 channelcookie |= 0x100; 7855 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7856 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7857 error = phy->switch_channel(mac, chan); 7858 if (error) 7859 goto fail; 7860 7861 mac->mac_phy.chan = chan; 7862 DELAY(8000); 7863 return (0); 7864 fail: 7865 device_printf(sc->sc_dev, "failed to switch channel\n"); 7866 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7867 return (error); 7868 } 7869 7870 static uint16_t 7871 bwn_ant2phy(int antenna) 7872 { 7873 7874 switch (antenna) { 7875 case BWN_ANT0: 7876 return (BWN_TX_PHY_ANT0); 7877 case BWN_ANT1: 7878 return (BWN_TX_PHY_ANT1); 7879 case BWN_ANT2: 7880 return (BWN_TX_PHY_ANT2); 7881 case BWN_ANT3: 7882 return (BWN_TX_PHY_ANT3); 7883 case BWN_ANTAUTO: 7884 return (BWN_TX_PHY_ANT01AUTO); 7885 } 7886 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7887 return (0); 7888 } 7889 7890 static void 7891 bwn_wme_load(struct bwn_mac *mac) 7892 { 7893 struct bwn_softc *sc = mac->mac_sc; 7894 int i; 7895 7896 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7897 ("%s:%d: fail", __func__, __LINE__)); 7898 7899 bwn_mac_suspend(mac); 7900 for (i = 0; i < N(sc->sc_wmeParams); i++) 7901 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 7902 bwn_wme_shm_offsets[i]); 7903 bwn_mac_enable(mac); 7904 } 7905 7906 static void 7907 bwn_wme_loadparams(struct bwn_mac *mac, 7908 const struct wmeParams *p, uint16_t shm_offset) 7909 { 7910 #define SM(_v, _f) (((_v) << _f##_S) & _f) 7911 struct bwn_softc *sc = mac->mac_sc; 7912 uint16_t params[BWN_NR_WMEPARAMS]; 7913 int slot, tmp; 7914 unsigned int i; 7915 7916 slot = BWN_READ_2(mac, BWN_RNG) & 7917 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7918 7919 memset(¶ms, 0, sizeof(params)); 7920 7921 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 7922 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 7923 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 7924 7925 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 7926 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7927 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 7928 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7929 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 7930 params[BWN_WMEPARAM_BSLOTS] = slot; 7931 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 7932 7933 for (i = 0; i < N(params); i++) { 7934 if (i == BWN_WMEPARAM_STATUS) { 7935 tmp = bwn_shm_read_2(mac, BWN_SHARED, 7936 shm_offset + (i * 2)); 7937 tmp |= 0x100; 7938 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7939 tmp); 7940 } else { 7941 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7942 params[i]); 7943 } 7944 } 7945 } 7946 7947 static void 7948 bwn_mac_write_bssid(struct bwn_mac *mac) 7949 { 7950 struct bwn_softc *sc = mac->mac_sc; 7951 uint32_t tmp; 7952 int i; 7953 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 7954 7955 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 7956 memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN); 7957 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 7958 IEEE80211_ADDR_LEN); 7959 7960 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 7961 tmp = (uint32_t) (mac_bssid[i + 0]); 7962 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 7963 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 7964 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 7965 bwn_ram_write(mac, 0x20 + i, tmp); 7966 } 7967 } 7968 7969 static void 7970 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 7971 const uint8_t *macaddr) 7972 { 7973 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 7974 uint16_t data; 7975 7976 if (!mac) 7977 macaddr = zero; 7978 7979 offset |= 0x0020; 7980 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 7981 7982 data = macaddr[0]; 7983 data |= macaddr[1] << 8; 7984 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7985 data = macaddr[2]; 7986 data |= macaddr[3] << 8; 7987 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7988 data = macaddr[4]; 7989 data |= macaddr[5] << 8; 7990 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7991 } 7992 7993 static void 7994 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 7995 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 7996 { 7997 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 7998 uint8_t per_sta_keys_start = 8; 7999 8000 if (BWN_SEC_NEWAPI(mac)) 8001 per_sta_keys_start = 4; 8002 8003 KASSERT(index < mac->mac_max_nr_keys, 8004 ("%s:%d: fail", __func__, __LINE__)); 8005 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8006 ("%s:%d: fail", __func__, __LINE__)); 8007 8008 if (index >= per_sta_keys_start) 8009 bwn_key_macwrite(mac, index, NULL); 8010 if (key) 8011 memcpy(buf, key, key_len); 8012 bwn_key_write(mac, index, algorithm, buf); 8013 if (index >= per_sta_keys_start) 8014 bwn_key_macwrite(mac, index, mac_addr); 8015 8016 mac->mac_key[index].algorithm = algorithm; 8017 } 8018 8019 static void 8020 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8021 { 8022 struct bwn_softc *sc = mac->mac_sc; 8023 uint32_t addrtmp[2] = { 0, 0 }; 8024 uint8_t start = 8; 8025 8026 if (BWN_SEC_NEWAPI(mac)) 8027 start = 4; 8028 8029 KASSERT(index >= start, 8030 ("%s:%d: fail", __func__, __LINE__)); 8031 index -= start; 8032 8033 if (addr) { 8034 addrtmp[0] = addr[0]; 8035 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8036 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8037 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8038 addrtmp[1] = addr[4]; 8039 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8040 } 8041 8042 if (siba_get_revid(sc->sc_dev) >= 5) { 8043 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8044 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8045 } else { 8046 if (index >= 8) { 8047 bwn_shm_write_4(mac, BWN_SHARED, 8048 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8049 bwn_shm_write_2(mac, BWN_SHARED, 8050 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8051 } 8052 } 8053 } 8054 8055 static void 8056 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8057 const uint8_t *key) 8058 { 8059 unsigned int i; 8060 uint32_t offset; 8061 uint16_t kidx, value; 8062 8063 kidx = BWN_SEC_KEY2FW(mac, index); 8064 bwn_shm_write_2(mac, BWN_SHARED, 8065 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8066 8067 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8068 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8069 value = key[i]; 8070 value |= (uint16_t)(key[i + 1]) << 8; 8071 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8072 } 8073 } 8074 8075 static void 8076 bwn_phy_exit(struct bwn_mac *mac) 8077 { 8078 8079 mac->mac_phy.rf_onoff(mac, 0); 8080 if (mac->mac_phy.exit != NULL) 8081 mac->mac_phy.exit(mac); 8082 } 8083 8084 static void 8085 bwn_dma_free(struct bwn_mac *mac) 8086 { 8087 struct bwn_dma *dma; 8088 8089 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8090 return; 8091 dma = &mac->mac_method.dma; 8092 8093 bwn_dma_ringfree(&dma->rx); 8094 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8095 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8096 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8097 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8098 bwn_dma_ringfree(&dma->mcast); 8099 } 8100 8101 static void 8102 bwn_core_stop(struct bwn_mac *mac) 8103 { 8104 struct bwn_softc *sc = mac->mac_sc; 8105 8106 BWN_ASSERT_LOCKED(sc); 8107 8108 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8109 return; 8110 8111 callout_stop(&sc->sc_rfswitch_ch); 8112 callout_stop(&sc->sc_task_ch); 8113 callout_stop(&sc->sc_watchdog_ch); 8114 sc->sc_watchdog_timer = 0; 8115 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8116 BWN_READ_4(mac, BWN_INTR_MASK); 8117 bwn_mac_suspend(mac); 8118 8119 mac->mac_status = BWN_MAC_STATUS_INITED; 8120 } 8121 8122 static int 8123 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8124 { 8125 struct bwn_mac *up_dev = NULL; 8126 struct bwn_mac *down_dev; 8127 struct bwn_mac *mac; 8128 int err, status; 8129 uint8_t gmode; 8130 8131 BWN_ASSERT_LOCKED(sc); 8132 8133 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8134 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8135 mac->mac_phy.supports_2ghz) { 8136 up_dev = mac; 8137 gmode = 1; 8138 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8139 mac->mac_phy.supports_5ghz) { 8140 up_dev = mac; 8141 gmode = 0; 8142 } else { 8143 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8144 return (EINVAL); 8145 } 8146 if (up_dev != NULL) 8147 break; 8148 } 8149 if (up_dev == NULL) { 8150 device_printf(sc->sc_dev, "Could not find a device\n"); 8151 return (ENODEV); 8152 } 8153 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8154 return (0); 8155 8156 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8157 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8158 8159 down_dev = sc->sc_curmac; 8160 status = down_dev->mac_status; 8161 if (status >= BWN_MAC_STATUS_STARTED) 8162 bwn_core_stop(down_dev); 8163 if (status >= BWN_MAC_STATUS_INITED) 8164 bwn_core_exit(down_dev); 8165 8166 if (down_dev != up_dev) 8167 bwn_phy_reset(down_dev); 8168 8169 up_dev->mac_phy.gmode = gmode; 8170 if (status >= BWN_MAC_STATUS_INITED) { 8171 err = bwn_core_init(up_dev); 8172 if (err) { 8173 device_printf(sc->sc_dev, 8174 "fatal: failed to initialize for %s-GHz\n", 8175 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8176 goto fail; 8177 } 8178 } 8179 if (status >= BWN_MAC_STATUS_STARTED) 8180 bwn_core_start(up_dev); 8181 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8182 sc->sc_curmac = up_dev; 8183 8184 return (0); 8185 fail: 8186 sc->sc_curmac = NULL; 8187 return (err); 8188 } 8189 8190 static void 8191 bwn_rf_turnon(struct bwn_mac *mac) 8192 { 8193 8194 bwn_mac_suspend(mac); 8195 mac->mac_phy.rf_onoff(mac, 1); 8196 mac->mac_phy.rf_on = 1; 8197 bwn_mac_enable(mac); 8198 } 8199 8200 static void 8201 bwn_rf_turnoff(struct bwn_mac *mac) 8202 { 8203 8204 bwn_mac_suspend(mac); 8205 mac->mac_phy.rf_onoff(mac, 0); 8206 mac->mac_phy.rf_on = 0; 8207 bwn_mac_enable(mac); 8208 } 8209 8210 static void 8211 bwn_phy_reset(struct bwn_mac *mac) 8212 { 8213 struct bwn_softc *sc = mac->mac_sc; 8214 8215 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8216 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8217 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8218 DELAY(1000); 8219 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8220 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8221 BWN_TGSLOW_PHYRESET); 8222 DELAY(1000); 8223 } 8224 8225 static int 8226 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8227 { 8228 struct bwn_vap *bvp = BWN_VAP(vap); 8229 struct ieee80211com *ic= vap->iv_ic; 8230 enum ieee80211_state ostate = vap->iv_state; 8231 struct bwn_softc *sc = ic->ic_softc; 8232 struct bwn_mac *mac = sc->sc_curmac; 8233 int error; 8234 8235 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8236 ieee80211_state_name[vap->iv_state], 8237 ieee80211_state_name[nstate]); 8238 8239 error = bvp->bv_newstate(vap, nstate, arg); 8240 if (error != 0) 8241 return (error); 8242 8243 BWN_LOCK(sc); 8244 8245 bwn_led_newstate(mac, nstate); 8246 8247 /* 8248 * Clear the BSSID when we stop a STA 8249 */ 8250 if (vap->iv_opmode == IEEE80211_M_STA) { 8251 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8252 /* 8253 * Clear out the BSSID. If we reassociate to 8254 * the same AP, this will reinialize things 8255 * correctly... 8256 */ 8257 if (ic->ic_opmode == IEEE80211_M_STA && 8258 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8259 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8260 bwn_set_macaddr(mac); 8261 } 8262 } 8263 } 8264 8265 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8266 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8267 /* XXX nothing to do? */ 8268 } else if (nstate == IEEE80211_S_RUN) { 8269 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8270 bwn_set_opmode(mac); 8271 bwn_set_pretbtt(mac); 8272 bwn_spu_setdelay(mac, 0); 8273 bwn_set_macaddr(mac); 8274 } 8275 8276 BWN_UNLOCK(sc); 8277 8278 return (error); 8279 } 8280 8281 static void 8282 bwn_set_pretbtt(struct bwn_mac *mac) 8283 { 8284 struct bwn_softc *sc = mac->mac_sc; 8285 struct ieee80211com *ic = &sc->sc_ic; 8286 uint16_t pretbtt; 8287 8288 if (ic->ic_opmode == IEEE80211_M_IBSS) 8289 pretbtt = 2; 8290 else 8291 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8292 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8293 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8294 } 8295 8296 static int 8297 bwn_intr(void *arg) 8298 { 8299 struct bwn_mac *mac = arg; 8300 struct bwn_softc *sc = mac->mac_sc; 8301 uint32_t reason; 8302 8303 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8304 (sc->sc_flags & BWN_FLAG_INVALID)) 8305 return (FILTER_STRAY); 8306 8307 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8308 if (reason == 0xffffffff) /* shared IRQ */ 8309 return (FILTER_STRAY); 8310 reason &= mac->mac_intr_mask; 8311 if (reason == 0) 8312 return (FILTER_HANDLED); 8313 8314 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8315 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8316 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8317 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8318 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8319 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8320 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8321 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8322 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8323 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8324 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8325 8326 /* Disable interrupts. */ 8327 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8328 8329 mac->mac_reason_intr = reason; 8330 8331 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8332 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8333 8334 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8335 return (FILTER_HANDLED); 8336 } 8337 8338 static void 8339 bwn_intrtask(void *arg, int npending) 8340 { 8341 struct bwn_mac *mac = arg; 8342 struct bwn_softc *sc = mac->mac_sc; 8343 uint32_t merged = 0; 8344 int i, tx = 0, rx = 0; 8345 8346 BWN_LOCK(sc); 8347 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8348 (sc->sc_flags & BWN_FLAG_INVALID)) { 8349 BWN_UNLOCK(sc); 8350 return; 8351 } 8352 8353 for (i = 0; i < N(mac->mac_reason); i++) 8354 merged |= mac->mac_reason[i]; 8355 8356 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8357 device_printf(sc->sc_dev, "MAC trans error\n"); 8358 8359 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8360 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8361 mac->mac_phy.txerrors--; 8362 if (mac->mac_phy.txerrors == 0) { 8363 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8364 bwn_restart(mac, "PHY TX errors"); 8365 } 8366 } 8367 8368 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8369 if (merged & BWN_DMAINTR_FATALMASK) { 8370 device_printf(sc->sc_dev, 8371 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8372 mac->mac_reason[0], mac->mac_reason[1], 8373 mac->mac_reason[2], mac->mac_reason[3], 8374 mac->mac_reason[4], mac->mac_reason[5]); 8375 bwn_restart(mac, "DMA error"); 8376 BWN_UNLOCK(sc); 8377 return; 8378 } 8379 if (merged & BWN_DMAINTR_NONFATALMASK) { 8380 device_printf(sc->sc_dev, 8381 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8382 mac->mac_reason[0], mac->mac_reason[1], 8383 mac->mac_reason[2], mac->mac_reason[3], 8384 mac->mac_reason[4], mac->mac_reason[5]); 8385 } 8386 } 8387 8388 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8389 bwn_intr_ucode_debug(mac); 8390 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8391 bwn_intr_tbtt_indication(mac); 8392 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8393 bwn_intr_atim_end(mac); 8394 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8395 bwn_intr_beacon(mac); 8396 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8397 bwn_intr_pmq(mac); 8398 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8399 bwn_intr_noise(mac); 8400 8401 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8402 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8403 bwn_dma_rx(mac->mac_method.dma.rx); 8404 rx = 1; 8405 } 8406 } else 8407 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8408 8409 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8410 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8411 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8412 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8413 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8414 8415 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8416 bwn_intr_txeof(mac); 8417 tx = 1; 8418 } 8419 8420 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8421 8422 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8423 int evt = BWN_LED_EVENT_NONE; 8424 8425 if (tx && rx) { 8426 if (sc->sc_rx_rate > sc->sc_tx_rate) 8427 evt = BWN_LED_EVENT_RX; 8428 else 8429 evt = BWN_LED_EVENT_TX; 8430 } else if (tx) { 8431 evt = BWN_LED_EVENT_TX; 8432 } else if (rx) { 8433 evt = BWN_LED_EVENT_RX; 8434 } else if (rx == 0) { 8435 evt = BWN_LED_EVENT_POLL; 8436 } 8437 8438 if (evt != BWN_LED_EVENT_NONE) 8439 bwn_led_event(mac, evt); 8440 } 8441 8442 if (mbufq_first(&sc->sc_snd) != NULL) 8443 bwn_start(sc); 8444 8445 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8446 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8447 8448 BWN_UNLOCK(sc); 8449 } 8450 8451 static void 8452 bwn_restart(struct bwn_mac *mac, const char *msg) 8453 { 8454 struct bwn_softc *sc = mac->mac_sc; 8455 struct ieee80211com *ic = &sc->sc_ic; 8456 8457 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8458 return; 8459 8460 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8461 ieee80211_runtask(ic, &mac->mac_hwreset); 8462 } 8463 8464 static void 8465 bwn_intr_ucode_debug(struct bwn_mac *mac) 8466 { 8467 struct bwn_softc *sc = mac->mac_sc; 8468 uint16_t reason; 8469 8470 if (mac->mac_fw.opensource == 0) 8471 return; 8472 8473 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8474 switch (reason) { 8475 case BWN_DEBUGINTR_PANIC: 8476 bwn_handle_fwpanic(mac); 8477 break; 8478 case BWN_DEBUGINTR_DUMP_SHM: 8479 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8480 break; 8481 case BWN_DEBUGINTR_DUMP_REGS: 8482 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8483 break; 8484 case BWN_DEBUGINTR_MARKER: 8485 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8486 break; 8487 default: 8488 device_printf(sc->sc_dev, 8489 "ucode debug unknown reason: %#x\n", reason); 8490 } 8491 8492 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8493 BWN_DEBUGINTR_ACK); 8494 } 8495 8496 static void 8497 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8498 { 8499 struct bwn_softc *sc = mac->mac_sc; 8500 struct ieee80211com *ic = &sc->sc_ic; 8501 8502 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8503 bwn_psctl(mac, 0); 8504 if (ic->ic_opmode == IEEE80211_M_IBSS) 8505 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8506 } 8507 8508 static void 8509 bwn_intr_atim_end(struct bwn_mac *mac) 8510 { 8511 8512 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8513 BWN_WRITE_4(mac, BWN_MACCMD, 8514 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8515 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8516 } 8517 } 8518 8519 static void 8520 bwn_intr_beacon(struct bwn_mac *mac) 8521 { 8522 struct bwn_softc *sc = mac->mac_sc; 8523 struct ieee80211com *ic = &sc->sc_ic; 8524 uint32_t cmd, beacon0, beacon1; 8525 8526 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8527 ic->ic_opmode == IEEE80211_M_MBSS) 8528 return; 8529 8530 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8531 8532 cmd = BWN_READ_4(mac, BWN_MACCMD); 8533 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8534 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8535 8536 if (beacon0 && beacon1) { 8537 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8538 mac->mac_intr_mask |= BWN_INTR_BEACON; 8539 return; 8540 } 8541 8542 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8543 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8544 bwn_load_beacon0(mac); 8545 bwn_load_beacon1(mac); 8546 cmd = BWN_READ_4(mac, BWN_MACCMD); 8547 cmd |= BWN_MACCMD_BEACON0_VALID; 8548 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8549 } else { 8550 if (!beacon0) { 8551 bwn_load_beacon0(mac); 8552 cmd = BWN_READ_4(mac, BWN_MACCMD); 8553 cmd |= BWN_MACCMD_BEACON0_VALID; 8554 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8555 } else if (!beacon1) { 8556 bwn_load_beacon1(mac); 8557 cmd = BWN_READ_4(mac, BWN_MACCMD); 8558 cmd |= BWN_MACCMD_BEACON1_VALID; 8559 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8560 } 8561 } 8562 } 8563 8564 static void 8565 bwn_intr_pmq(struct bwn_mac *mac) 8566 { 8567 uint32_t tmp; 8568 8569 while (1) { 8570 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8571 if (!(tmp & 0x00000008)) 8572 break; 8573 } 8574 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8575 } 8576 8577 static void 8578 bwn_intr_noise(struct bwn_mac *mac) 8579 { 8580 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8581 uint16_t tmp; 8582 uint8_t noise[4]; 8583 uint8_t i, j; 8584 int32_t average; 8585 8586 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8587 return; 8588 8589 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8590 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8591 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8592 noise[3] == 0x7f) 8593 goto new; 8594 8595 KASSERT(mac->mac_noise.noi_nsamples < 8, 8596 ("%s:%d: fail", __func__, __LINE__)); 8597 i = mac->mac_noise.noi_nsamples; 8598 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8599 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8600 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8601 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8602 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8603 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8604 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8605 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8606 mac->mac_noise.noi_nsamples++; 8607 if (mac->mac_noise.noi_nsamples == 8) { 8608 average = 0; 8609 for (i = 0; i < 8; i++) { 8610 for (j = 0; j < 4; j++) 8611 average += mac->mac_noise.noi_samples[i][j]; 8612 } 8613 average = (((average / 32) * 125) + 64) / 128; 8614 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8615 if (tmp >= 8) 8616 average += 2; 8617 else 8618 average -= 25; 8619 average -= (tmp == 8) ? 72 : 48; 8620 8621 mac->mac_stats.link_noise = average; 8622 mac->mac_noise.noi_running = 0; 8623 return; 8624 } 8625 new: 8626 bwn_noise_gensample(mac); 8627 } 8628 8629 static int 8630 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8631 { 8632 struct bwn_mac *mac = prq->prq_mac; 8633 struct bwn_softc *sc = mac->mac_sc; 8634 unsigned int i; 8635 8636 BWN_ASSERT_LOCKED(sc); 8637 8638 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8639 return (0); 8640 8641 for (i = 0; i < 5000; i++) { 8642 if (bwn_pio_rxeof(prq) == 0) 8643 break; 8644 } 8645 if (i >= 5000) 8646 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8647 return ((i > 0) ? 1 : 0); 8648 } 8649 8650 static void 8651 bwn_dma_rx(struct bwn_dma_ring *dr) 8652 { 8653 int slot, curslot; 8654 8655 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8656 curslot = dr->get_curslot(dr); 8657 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8658 ("%s:%d: fail", __func__, __LINE__)); 8659 8660 slot = dr->dr_curslot; 8661 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8662 bwn_dma_rxeof(dr, &slot); 8663 8664 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8665 BUS_DMASYNC_PREWRITE); 8666 8667 dr->set_curslot(dr, slot); 8668 dr->dr_curslot = slot; 8669 } 8670 8671 static void 8672 bwn_intr_txeof(struct bwn_mac *mac) 8673 { 8674 struct bwn_txstatus stat; 8675 uint32_t stat0, stat1; 8676 uint16_t tmp; 8677 8678 BWN_ASSERT_LOCKED(mac->mac_sc); 8679 8680 while (1) { 8681 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8682 if (!(stat0 & 0x00000001)) 8683 break; 8684 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8685 8686 stat.cookie = (stat0 >> 16); 8687 stat.seq = (stat1 & 0x0000ffff); 8688 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8689 tmp = (stat0 & 0x0000ffff); 8690 stat.framecnt = ((tmp & 0xf000) >> 12); 8691 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8692 stat.sreason = ((tmp & 0x001c) >> 2); 8693 stat.pm = (tmp & 0x0080) ? 1 : 0; 8694 stat.im = (tmp & 0x0040) ? 1 : 0; 8695 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8696 stat.ack = (tmp & 0x0002) ? 1 : 0; 8697 8698 bwn_handle_txeof(mac, &stat); 8699 } 8700 } 8701 8702 static void 8703 bwn_hwreset(void *arg, int npending) 8704 { 8705 struct bwn_mac *mac = arg; 8706 struct bwn_softc *sc = mac->mac_sc; 8707 int error = 0; 8708 int prev_status; 8709 8710 BWN_LOCK(sc); 8711 8712 prev_status = mac->mac_status; 8713 if (prev_status >= BWN_MAC_STATUS_STARTED) 8714 bwn_core_stop(mac); 8715 if (prev_status >= BWN_MAC_STATUS_INITED) 8716 bwn_core_exit(mac); 8717 8718 if (prev_status >= BWN_MAC_STATUS_INITED) { 8719 error = bwn_core_init(mac); 8720 if (error) 8721 goto out; 8722 } 8723 if (prev_status >= BWN_MAC_STATUS_STARTED) 8724 bwn_core_start(mac); 8725 out: 8726 if (error) { 8727 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8728 sc->sc_curmac = NULL; 8729 } 8730 BWN_UNLOCK(sc); 8731 } 8732 8733 static void 8734 bwn_handle_fwpanic(struct bwn_mac *mac) 8735 { 8736 struct bwn_softc *sc = mac->mac_sc; 8737 uint16_t reason; 8738 8739 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8740 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8741 8742 if (reason == BWN_FWPANIC_RESTART) 8743 bwn_restart(mac, "ucode panic"); 8744 } 8745 8746 static void 8747 bwn_load_beacon0(struct bwn_mac *mac) 8748 { 8749 8750 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8751 } 8752 8753 static void 8754 bwn_load_beacon1(struct bwn_mac *mac) 8755 { 8756 8757 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8758 } 8759 8760 static uint32_t 8761 bwn_jssi_read(struct bwn_mac *mac) 8762 { 8763 uint32_t val = 0; 8764 8765 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8766 val <<= 16; 8767 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8768 8769 return (val); 8770 } 8771 8772 static void 8773 bwn_noise_gensample(struct bwn_mac *mac) 8774 { 8775 uint32_t jssi = 0x7f7f7f7f; 8776 8777 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8778 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8779 BWN_WRITE_4(mac, BWN_MACCMD, 8780 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8781 } 8782 8783 static int 8784 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8785 { 8786 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8787 8788 return (dr->dr_numslots - dr->dr_usedslot); 8789 } 8790 8791 static int 8792 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8793 { 8794 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8795 8796 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8797 ("%s:%d: fail", __func__, __LINE__)); 8798 if (slot == dr->dr_numslots - 1) 8799 return (0); 8800 return (slot + 1); 8801 } 8802 8803 static void 8804 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8805 { 8806 struct bwn_mac *mac = dr->dr_mac; 8807 struct bwn_softc *sc = mac->mac_sc; 8808 struct bwn_dma *dma = &mac->mac_method.dma; 8809 struct bwn_dmadesc_generic *desc; 8810 struct bwn_dmadesc_meta *meta; 8811 struct bwn_rxhdr4 *rxhdr; 8812 struct mbuf *m; 8813 uint32_t macstat; 8814 int32_t tmp; 8815 int cnt = 0; 8816 uint16_t len; 8817 8818 dr->getdesc(dr, *slot, &desc, &meta); 8819 8820 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8821 m = meta->mt_m; 8822 8823 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8824 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 8825 return; 8826 } 8827 8828 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8829 len = le16toh(rxhdr->frame_len); 8830 if (len <= 0) { 8831 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 8832 return; 8833 } 8834 if (bwn_dma_check_redzone(dr, m)) { 8835 device_printf(sc->sc_dev, "redzone error.\n"); 8836 bwn_dma_set_redzone(dr, m); 8837 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8838 BUS_DMASYNC_PREWRITE); 8839 return; 8840 } 8841 if (len > dr->dr_rx_bufsize) { 8842 tmp = len; 8843 while (1) { 8844 dr->getdesc(dr, *slot, &desc, &meta); 8845 bwn_dma_set_redzone(dr, meta->mt_m); 8846 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8847 BUS_DMASYNC_PREWRITE); 8848 *slot = bwn_dma_nextslot(dr, *slot); 8849 cnt++; 8850 tmp -= dr->dr_rx_bufsize; 8851 if (tmp <= 0) 8852 break; 8853 } 8854 device_printf(sc->sc_dev, "too small buffer " 8855 "(len %u buffer %u dropped %d)\n", 8856 len, dr->dr_rx_bufsize, cnt); 8857 return; 8858 } 8859 macstat = le32toh(rxhdr->mac_status); 8860 if (macstat & BWN_RX_MAC_FCSERR) { 8861 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8862 device_printf(sc->sc_dev, "RX drop\n"); 8863 return; 8864 } 8865 } 8866 8867 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8868 m_adj(m, dr->dr_frameoffset); 8869 8870 bwn_rxeof(dr->dr_mac, m, rxhdr); 8871 } 8872 8873 static void 8874 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8875 { 8876 struct bwn_dma_ring *dr; 8877 struct bwn_dmadesc_generic *desc; 8878 struct bwn_dmadesc_meta *meta; 8879 struct bwn_pio_txqueue *tq; 8880 struct bwn_pio_txpkt *tp = NULL; 8881 struct bwn_softc *sc = mac->mac_sc; 8882 struct bwn_stats *stats = &mac->mac_stats; 8883 struct ieee80211_node *ni; 8884 struct ieee80211vap *vap; 8885 int retrycnt = 0, slot; 8886 8887 BWN_ASSERT_LOCKED(mac->mac_sc); 8888 8889 if (status->im) 8890 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8891 if (status->ampdu) 8892 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8893 if (status->rtscnt) { 8894 if (status->rtscnt == 0xf) 8895 stats->rtsfail++; 8896 else 8897 stats->rts++; 8898 } 8899 8900 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8901 if (status->ack) { 8902 dr = bwn_dma_parse_cookie(mac, status, 8903 status->cookie, &slot); 8904 if (dr == NULL) { 8905 device_printf(sc->sc_dev, 8906 "failed to parse cookie\n"); 8907 return; 8908 } 8909 while (1) { 8910 dr->getdesc(dr, slot, &desc, &meta); 8911 if (meta->mt_islast) { 8912 ni = meta->mt_ni; 8913 vap = ni->ni_vap; 8914 ieee80211_ratectl_tx_complete(vap, ni, 8915 status->ack ? 8916 IEEE80211_RATECTL_TX_SUCCESS : 8917 IEEE80211_RATECTL_TX_FAILURE, 8918 &retrycnt, 0); 8919 break; 8920 } 8921 slot = bwn_dma_nextslot(dr, slot); 8922 } 8923 } 8924 bwn_dma_handle_txeof(mac, status); 8925 } else { 8926 if (status->ack) { 8927 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 8928 if (tq == NULL) { 8929 device_printf(sc->sc_dev, 8930 "failed to parse cookie\n"); 8931 return; 8932 } 8933 ni = tp->tp_ni; 8934 vap = ni->ni_vap; 8935 ieee80211_ratectl_tx_complete(vap, ni, 8936 status->ack ? 8937 IEEE80211_RATECTL_TX_SUCCESS : 8938 IEEE80211_RATECTL_TX_FAILURE, 8939 &retrycnt, 0); 8940 } 8941 bwn_pio_handle_txeof(mac, status); 8942 } 8943 8944 bwn_phy_txpower_check(mac, 0); 8945 } 8946 8947 static uint8_t 8948 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 8949 { 8950 struct bwn_mac *mac = prq->prq_mac; 8951 struct bwn_softc *sc = mac->mac_sc; 8952 struct bwn_rxhdr4 rxhdr; 8953 struct mbuf *m; 8954 uint32_t ctl32, macstat, v32; 8955 unsigned int i, padding; 8956 uint16_t ctl16, len, totlen, v16; 8957 unsigned char *mp; 8958 char *data; 8959 8960 memset(&rxhdr, 0, sizeof(rxhdr)); 8961 8962 if (prq->prq_rev >= 8) { 8963 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8964 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 8965 return (0); 8966 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 8967 BWN_PIO8_RXCTL_FRAMEREADY); 8968 for (i = 0; i < 10; i++) { 8969 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8970 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 8971 goto ready; 8972 DELAY(10); 8973 } 8974 } else { 8975 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8976 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 8977 return (0); 8978 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 8979 BWN_PIO_RXCTL_FRAMEREADY); 8980 for (i = 0; i < 10; i++) { 8981 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8982 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 8983 goto ready; 8984 DELAY(10); 8985 } 8986 } 8987 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 8988 return (1); 8989 ready: 8990 if (prq->prq_rev >= 8) 8991 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8992 prq->prq_base + BWN_PIO8_RXDATA); 8993 else 8994 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8995 prq->prq_base + BWN_PIO_RXDATA); 8996 len = le16toh(rxhdr.frame_len); 8997 if (len > 0x700) { 8998 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 8999 goto error; 9000 } 9001 if (len == 0) { 9002 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9003 goto error; 9004 } 9005 9006 macstat = le32toh(rxhdr.mac_status); 9007 if (macstat & BWN_RX_MAC_FCSERR) { 9008 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9009 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9010 goto error; 9011 } 9012 } 9013 9014 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9015 totlen = len + padding; 9016 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9017 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9018 if (m == NULL) { 9019 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9020 goto error; 9021 } 9022 mp = mtod(m, unsigned char *); 9023 if (prq->prq_rev >= 8) { 9024 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9025 prq->prq_base + BWN_PIO8_RXDATA); 9026 if (totlen & 3) { 9027 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9028 data = &(mp[totlen - 1]); 9029 switch (totlen & 3) { 9030 case 3: 9031 *data = (v32 >> 16); 9032 data--; 9033 case 2: 9034 *data = (v32 >> 8); 9035 data--; 9036 case 1: 9037 *data = v32; 9038 } 9039 } 9040 } else { 9041 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9042 prq->prq_base + BWN_PIO_RXDATA); 9043 if (totlen & 1) { 9044 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9045 mp[totlen - 1] = v16; 9046 } 9047 } 9048 9049 m->m_len = m->m_pkthdr.len = totlen; 9050 9051 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9052 9053 return (1); 9054 error: 9055 if (prq->prq_rev >= 8) 9056 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9057 BWN_PIO8_RXCTL_DATAREADY); 9058 else 9059 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9060 return (1); 9061 } 9062 9063 static int 9064 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9065 struct bwn_dmadesc_meta *meta, int init) 9066 { 9067 struct bwn_mac *mac = dr->dr_mac; 9068 struct bwn_dma *dma = &mac->mac_method.dma; 9069 struct bwn_rxhdr4 *hdr; 9070 bus_dmamap_t map; 9071 bus_addr_t paddr; 9072 struct mbuf *m; 9073 int error; 9074 9075 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9076 if (m == NULL) { 9077 error = ENOBUFS; 9078 9079 /* 9080 * If the NIC is up and running, we need to: 9081 * - Clear RX buffer's header. 9082 * - Restore RX descriptor settings. 9083 */ 9084 if (init) 9085 return (error); 9086 else 9087 goto back; 9088 } 9089 m->m_len = m->m_pkthdr.len = MCLBYTES; 9090 9091 bwn_dma_set_redzone(dr, m); 9092 9093 /* 9094 * Try to load RX buf into temporary DMA map 9095 */ 9096 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9097 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9098 if (error) { 9099 m_freem(m); 9100 9101 /* 9102 * See the comment above 9103 */ 9104 if (init) 9105 return (error); 9106 else 9107 goto back; 9108 } 9109 9110 if (!init) 9111 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9112 meta->mt_m = m; 9113 meta->mt_paddr = paddr; 9114 9115 /* 9116 * Swap RX buf's DMA map with the loaded temporary one 9117 */ 9118 map = meta->mt_dmap; 9119 meta->mt_dmap = dr->dr_spare_dmap; 9120 dr->dr_spare_dmap = map; 9121 9122 back: 9123 /* 9124 * Clear RX buf header 9125 */ 9126 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9127 bzero(hdr, sizeof(*hdr)); 9128 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9129 BUS_DMASYNC_PREWRITE); 9130 9131 /* 9132 * Setup RX buf descriptor 9133 */ 9134 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9135 sizeof(*hdr), 0, 0, 0); 9136 return (error); 9137 } 9138 9139 static void 9140 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9141 bus_size_t mapsz __unused, int error) 9142 { 9143 9144 if (!error) { 9145 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9146 *((bus_addr_t *)arg) = seg->ds_addr; 9147 } 9148 } 9149 9150 static int 9151 bwn_hwrate2ieeerate(int rate) 9152 { 9153 9154 switch (rate) { 9155 case BWN_CCK_RATE_1MB: 9156 return (2); 9157 case BWN_CCK_RATE_2MB: 9158 return (4); 9159 case BWN_CCK_RATE_5MB: 9160 return (11); 9161 case BWN_CCK_RATE_11MB: 9162 return (22); 9163 case BWN_OFDM_RATE_6MB: 9164 return (12); 9165 case BWN_OFDM_RATE_9MB: 9166 return (18); 9167 case BWN_OFDM_RATE_12MB: 9168 return (24); 9169 case BWN_OFDM_RATE_18MB: 9170 return (36); 9171 case BWN_OFDM_RATE_24MB: 9172 return (48); 9173 case BWN_OFDM_RATE_36MB: 9174 return (72); 9175 case BWN_OFDM_RATE_48MB: 9176 return (96); 9177 case BWN_OFDM_RATE_54MB: 9178 return (108); 9179 default: 9180 printf("Ooops\n"); 9181 return (0); 9182 } 9183 } 9184 9185 static void 9186 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9187 { 9188 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9189 struct bwn_plcp6 *plcp; 9190 struct bwn_softc *sc = mac->mac_sc; 9191 struct ieee80211_frame_min *wh; 9192 struct ieee80211_node *ni; 9193 struct ieee80211com *ic = &sc->sc_ic; 9194 uint32_t macstat; 9195 int padding, rate, rssi = 0, noise = 0, type; 9196 uint16_t phytype, phystat0, phystat3, chanstat; 9197 unsigned char *mp = mtod(m, unsigned char *); 9198 static int rx_mac_dec_rpt = 0; 9199 9200 BWN_ASSERT_LOCKED(sc); 9201 9202 phystat0 = le16toh(rxhdr->phy_status0); 9203 phystat3 = le16toh(rxhdr->phy_status3); 9204 macstat = le32toh(rxhdr->mac_status); 9205 chanstat = le16toh(rxhdr->channel); 9206 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9207 9208 if (macstat & BWN_RX_MAC_FCSERR) 9209 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9210 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9211 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9212 if (macstat & BWN_RX_MAC_DECERR) 9213 goto drop; 9214 9215 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9216 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9217 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9218 m->m_pkthdr.len); 9219 goto drop; 9220 } 9221 plcp = (struct bwn_plcp6 *)(mp + padding); 9222 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9223 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9224 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9225 m->m_pkthdr.len); 9226 goto drop; 9227 } 9228 wh = mtod(m, struct ieee80211_frame_min *); 9229 9230 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9231 device_printf(sc->sc_dev, 9232 "RX decryption attempted (old %d keyidx %#x)\n", 9233 BWN_ISOLDFMT(mac), 9234 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9235 9236 /* XXX calculating RSSI & noise & antenna */ 9237 9238 if (phystat0 & BWN_RX_PHYST0_OFDM) 9239 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9240 phytype == BWN_PHYTYPE_A); 9241 else 9242 rate = bwn_plcp_get_cckrate(mac, plcp); 9243 if (rate == -1) { 9244 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9245 goto drop; 9246 } 9247 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9248 9249 /* RX radio tap */ 9250 if (ieee80211_radiotap_active(ic)) 9251 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9252 m_adj(m, -IEEE80211_CRC_LEN); 9253 9254 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9255 noise = mac->mac_stats.link_noise; 9256 9257 BWN_UNLOCK(sc); 9258 9259 ni = ieee80211_find_rxnode(ic, wh); 9260 if (ni != NULL) { 9261 type = ieee80211_input(ni, m, rssi, noise); 9262 ieee80211_free_node(ni); 9263 } else 9264 type = ieee80211_input_all(ic, m, rssi, noise); 9265 9266 BWN_LOCK(sc); 9267 return; 9268 drop: 9269 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9270 } 9271 9272 static void 9273 bwn_dma_handle_txeof(struct bwn_mac *mac, 9274 const struct bwn_txstatus *status) 9275 { 9276 struct bwn_dma *dma = &mac->mac_method.dma; 9277 struct bwn_dma_ring *dr; 9278 struct bwn_dmadesc_generic *desc; 9279 struct bwn_dmadesc_meta *meta; 9280 struct bwn_softc *sc = mac->mac_sc; 9281 int slot; 9282 9283 BWN_ASSERT_LOCKED(sc); 9284 9285 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9286 if (dr == NULL) { 9287 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9288 return; 9289 } 9290 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9291 9292 while (1) { 9293 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9294 ("%s:%d: fail", __func__, __LINE__)); 9295 dr->getdesc(dr, slot, &desc, &meta); 9296 9297 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9298 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9299 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9300 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9301 9302 if (meta->mt_islast) { 9303 KASSERT(meta->mt_m != NULL, 9304 ("%s:%d: fail", __func__, __LINE__)); 9305 9306 ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0); 9307 meta->mt_ni = NULL; 9308 meta->mt_m = NULL; 9309 } else 9310 KASSERT(meta->mt_m == NULL, 9311 ("%s:%d: fail", __func__, __LINE__)); 9312 9313 dr->dr_usedslot--; 9314 if (meta->mt_islast) 9315 break; 9316 slot = bwn_dma_nextslot(dr, slot); 9317 } 9318 sc->sc_watchdog_timer = 0; 9319 if (dr->dr_stop) { 9320 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9321 ("%s:%d: fail", __func__, __LINE__)); 9322 dr->dr_stop = 0; 9323 } 9324 } 9325 9326 static void 9327 bwn_pio_handle_txeof(struct bwn_mac *mac, 9328 const struct bwn_txstatus *status) 9329 { 9330 struct bwn_pio_txqueue *tq; 9331 struct bwn_pio_txpkt *tp = NULL; 9332 struct bwn_softc *sc = mac->mac_sc; 9333 9334 BWN_ASSERT_LOCKED(sc); 9335 9336 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9337 if (tq == NULL) 9338 return; 9339 9340 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9341 tq->tq_free++; 9342 9343 if (tp->tp_ni != NULL) { 9344 /* 9345 * Do any tx complete callback. Note this must 9346 * be done before releasing the node reference. 9347 */ 9348 if (tp->tp_m->m_flags & M_TXCB) 9349 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9350 ieee80211_free_node(tp->tp_ni); 9351 tp->tp_ni = NULL; 9352 } 9353 m_freem(tp->tp_m); 9354 tp->tp_m = NULL; 9355 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9356 9357 sc->sc_watchdog_timer = 0; 9358 } 9359 9360 static void 9361 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9362 { 9363 struct bwn_softc *sc = mac->mac_sc; 9364 struct bwn_phy *phy = &mac->mac_phy; 9365 struct ieee80211com *ic = &sc->sc_ic; 9366 unsigned long now; 9367 int result; 9368 9369 BWN_GETTIME(now); 9370 9371 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9372 return; 9373 phy->nexttime = now + 2 * 1000; 9374 9375 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9376 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9377 return; 9378 9379 if (phy->recalc_txpwr != NULL) { 9380 result = phy->recalc_txpwr(mac, 9381 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9382 if (result == BWN_TXPWR_RES_DONE) 9383 return; 9384 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9385 ("%s: fail", __func__)); 9386 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9387 9388 ieee80211_runtask(ic, &mac->mac_txpower); 9389 } 9390 } 9391 9392 static uint16_t 9393 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9394 { 9395 9396 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9397 } 9398 9399 static uint32_t 9400 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9401 { 9402 9403 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9404 } 9405 9406 static void 9407 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9408 { 9409 9410 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9411 } 9412 9413 static void 9414 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9415 { 9416 9417 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9418 } 9419 9420 static int 9421 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9422 { 9423 9424 switch (rate) { 9425 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9426 case 12: 9427 return (BWN_OFDM_RATE_6MB); 9428 case 18: 9429 return (BWN_OFDM_RATE_9MB); 9430 case 24: 9431 return (BWN_OFDM_RATE_12MB); 9432 case 36: 9433 return (BWN_OFDM_RATE_18MB); 9434 case 48: 9435 return (BWN_OFDM_RATE_24MB); 9436 case 72: 9437 return (BWN_OFDM_RATE_36MB); 9438 case 96: 9439 return (BWN_OFDM_RATE_48MB); 9440 case 108: 9441 return (BWN_OFDM_RATE_54MB); 9442 /* CCK rates (NB: not IEEE std, device-specific) */ 9443 case 2: 9444 return (BWN_CCK_RATE_1MB); 9445 case 4: 9446 return (BWN_CCK_RATE_2MB); 9447 case 11: 9448 return (BWN_CCK_RATE_5MB); 9449 case 22: 9450 return (BWN_CCK_RATE_11MB); 9451 } 9452 9453 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9454 return (BWN_CCK_RATE_1MB); 9455 } 9456 9457 static int 9458 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9459 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9460 { 9461 const struct bwn_phy *phy = &mac->mac_phy; 9462 struct bwn_softc *sc = mac->mac_sc; 9463 struct ieee80211_frame *wh; 9464 struct ieee80211_frame *protwh; 9465 struct ieee80211_frame_cts *cts; 9466 struct ieee80211_frame_rts *rts; 9467 const struct ieee80211_txparam *tp; 9468 struct ieee80211vap *vap = ni->ni_vap; 9469 struct ieee80211com *ic = &sc->sc_ic; 9470 struct mbuf *mprot; 9471 unsigned int len; 9472 uint32_t macctl = 0; 9473 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9474 uint16_t phyctl = 0; 9475 uint8_t rate, rate_fb; 9476 9477 wh = mtod(m, struct ieee80211_frame *); 9478 memset(txhdr, 0, sizeof(*txhdr)); 9479 9480 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9481 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9482 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9483 9484 /* 9485 * Find TX rate 9486 */ 9487 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9488 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9489 rate = rate_fb = tp->mgmtrate; 9490 else if (ismcast) 9491 rate = rate_fb = tp->mcastrate; 9492 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9493 rate = rate_fb = tp->ucastrate; 9494 else { 9495 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9496 rate = ni->ni_txrate; 9497 9498 if (rix > 0) 9499 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9500 IEEE80211_RATE_VAL; 9501 else 9502 rate_fb = rate; 9503 } 9504 9505 sc->sc_tx_rate = rate; 9506 9507 rate = bwn_ieeerate2hwrate(sc, rate); 9508 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9509 9510 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9511 bwn_plcp_getcck(rate); 9512 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9513 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9514 9515 if ((rate_fb == rate) || 9516 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9517 (*(u_int16_t *)wh->i_dur == htole16(0))) 9518 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9519 else 9520 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9521 m->m_pkthdr.len, rate, isshort); 9522 9523 /* XXX TX encryption */ 9524 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9525 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9526 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9527 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9528 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9529 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9530 9531 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9532 BWN_TX_EFT_FB_CCK; 9533 txhdr->chan = phy->chan; 9534 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9535 BWN_TX_PHY_ENC_CCK; 9536 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9537 rate == BWN_CCK_RATE_11MB)) 9538 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9539 9540 /* XXX TX antenna selection */ 9541 9542 switch (bwn_antenna_sanitize(mac, 0)) { 9543 case 0: 9544 phyctl |= BWN_TX_PHY_ANT01AUTO; 9545 break; 9546 case 1: 9547 phyctl |= BWN_TX_PHY_ANT0; 9548 break; 9549 case 2: 9550 phyctl |= BWN_TX_PHY_ANT1; 9551 break; 9552 case 3: 9553 phyctl |= BWN_TX_PHY_ANT2; 9554 break; 9555 case 4: 9556 phyctl |= BWN_TX_PHY_ANT3; 9557 break; 9558 default: 9559 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9560 } 9561 9562 if (!ismcast) 9563 macctl |= BWN_TX_MAC_ACK; 9564 9565 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9566 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9567 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9568 macctl |= BWN_TX_MAC_LONGFRAME; 9569 9570 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9571 /* XXX RTS rate is always 1MB??? */ 9572 rts_rate = BWN_CCK_RATE_1MB; 9573 rts_rate_fb = bwn_get_fbrate(rts_rate); 9574 9575 protdur = ieee80211_compute_duration(ic->ic_rt, 9576 m->m_pkthdr.len, rate, isshort) + 9577 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9578 9579 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9580 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9581 (txhdr->body.old.rts_frame) : 9582 (txhdr->body.new.rts_frame)); 9583 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9584 protdur); 9585 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9586 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9587 mprot->m_pkthdr.len); 9588 m_freem(mprot); 9589 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9590 len = sizeof(struct ieee80211_frame_cts); 9591 } else { 9592 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9593 (txhdr->body.old.rts_frame) : 9594 (txhdr->body.new.rts_frame)); 9595 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9596 isshort); 9597 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9598 wh->i_addr2, protdur); 9599 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9600 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9601 mprot->m_pkthdr.len); 9602 m_freem(mprot); 9603 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9604 len = sizeof(struct ieee80211_frame_rts); 9605 } 9606 len += IEEE80211_CRC_LEN; 9607 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9608 &txhdr->body.old.rts_plcp : 9609 &txhdr->body.new.rts_plcp), len, rts_rate); 9610 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9611 rts_rate_fb); 9612 9613 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9614 (&txhdr->body.old.rts_frame) : 9615 (&txhdr->body.new.rts_frame)); 9616 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9617 9618 if (BWN_ISOFDMRATE(rts_rate)) { 9619 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9620 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9621 } else { 9622 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9623 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9624 } 9625 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9626 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9627 } 9628 9629 if (BWN_ISOLDFMT(mac)) 9630 txhdr->body.old.cookie = htole16(cookie); 9631 else 9632 txhdr->body.new.cookie = htole16(cookie); 9633 9634 txhdr->macctl = htole32(macctl); 9635 txhdr->phyctl = htole16(phyctl); 9636 9637 /* 9638 * TX radio tap 9639 */ 9640 if (ieee80211_radiotap_active_vap(vap)) { 9641 sc->sc_tx_th.wt_flags = 0; 9642 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9643 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9644 if (isshort && 9645 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9646 rate == BWN_CCK_RATE_11MB)) 9647 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9648 sc->sc_tx_th.wt_rate = rate; 9649 9650 ieee80211_radiotap_tx(vap, m); 9651 } 9652 9653 return (0); 9654 } 9655 9656 static void 9657 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9658 const uint8_t rate) 9659 { 9660 uint32_t d, plen; 9661 uint8_t *raw = plcp->o.raw; 9662 9663 if (BWN_ISOFDMRATE(rate)) { 9664 d = bwn_plcp_getofdm(rate); 9665 KASSERT(!(octets & 0xf000), 9666 ("%s:%d: fail", __func__, __LINE__)); 9667 d |= (octets << 5); 9668 plcp->o.data = htole32(d); 9669 } else { 9670 plen = octets * 16 / rate; 9671 if ((octets * 16 % rate) > 0) { 9672 plen++; 9673 if ((rate == BWN_CCK_RATE_11MB) 9674 && ((octets * 8 % 11) < 4)) { 9675 raw[1] = 0x84; 9676 } else 9677 raw[1] = 0x04; 9678 } else 9679 raw[1] = 0x04; 9680 plcp->o.data |= htole32(plen << 16); 9681 raw[0] = bwn_plcp_getcck(rate); 9682 } 9683 } 9684 9685 static uint8_t 9686 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9687 { 9688 struct bwn_softc *sc = mac->mac_sc; 9689 uint8_t mask; 9690 9691 if (n == 0) 9692 return (0); 9693 if (mac->mac_phy.gmode) 9694 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9695 else 9696 mask = siba_sprom_get_ant_a(sc->sc_dev); 9697 if (!(mask & (1 << (n - 1)))) 9698 return (0); 9699 return (n); 9700 } 9701 9702 static uint8_t 9703 bwn_get_fbrate(uint8_t bitrate) 9704 { 9705 switch (bitrate) { 9706 case BWN_CCK_RATE_1MB: 9707 return (BWN_CCK_RATE_1MB); 9708 case BWN_CCK_RATE_2MB: 9709 return (BWN_CCK_RATE_1MB); 9710 case BWN_CCK_RATE_5MB: 9711 return (BWN_CCK_RATE_2MB); 9712 case BWN_CCK_RATE_11MB: 9713 return (BWN_CCK_RATE_5MB); 9714 case BWN_OFDM_RATE_6MB: 9715 return (BWN_CCK_RATE_5MB); 9716 case BWN_OFDM_RATE_9MB: 9717 return (BWN_OFDM_RATE_6MB); 9718 case BWN_OFDM_RATE_12MB: 9719 return (BWN_OFDM_RATE_9MB); 9720 case BWN_OFDM_RATE_18MB: 9721 return (BWN_OFDM_RATE_12MB); 9722 case BWN_OFDM_RATE_24MB: 9723 return (BWN_OFDM_RATE_18MB); 9724 case BWN_OFDM_RATE_36MB: 9725 return (BWN_OFDM_RATE_24MB); 9726 case BWN_OFDM_RATE_48MB: 9727 return (BWN_OFDM_RATE_36MB); 9728 case BWN_OFDM_RATE_54MB: 9729 return (BWN_OFDM_RATE_48MB); 9730 } 9731 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9732 return (0); 9733 } 9734 9735 static uint32_t 9736 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9737 uint32_t ctl, const void *_data, int len) 9738 { 9739 struct bwn_softc *sc = mac->mac_sc; 9740 uint32_t value = 0; 9741 const uint8_t *data = _data; 9742 9743 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9744 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9745 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9746 9747 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9748 tq->tq_base + BWN_PIO8_TXDATA); 9749 if (len & 3) { 9750 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9751 BWN_PIO8_TXCTL_24_31); 9752 data = &(data[len - 1]); 9753 switch (len & 3) { 9754 case 3: 9755 ctl |= BWN_PIO8_TXCTL_16_23; 9756 value |= (uint32_t)(*data) << 16; 9757 data--; 9758 case 2: 9759 ctl |= BWN_PIO8_TXCTL_8_15; 9760 value |= (uint32_t)(*data) << 8; 9761 data--; 9762 case 1: 9763 value |= (uint32_t)(*data); 9764 } 9765 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9766 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9767 } 9768 9769 return (ctl); 9770 } 9771 9772 static void 9773 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9774 uint16_t offset, uint32_t value) 9775 { 9776 9777 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9778 } 9779 9780 static uint16_t 9781 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9782 uint16_t ctl, const void *_data, int len) 9783 { 9784 struct bwn_softc *sc = mac->mac_sc; 9785 const uint8_t *data = _data; 9786 9787 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9788 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9789 9790 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9791 tq->tq_base + BWN_PIO_TXDATA); 9792 if (len & 1) { 9793 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9794 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9795 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9796 } 9797 9798 return (ctl); 9799 } 9800 9801 static uint16_t 9802 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9803 uint16_t ctl, struct mbuf *m0) 9804 { 9805 int i, j = 0; 9806 uint16_t data = 0; 9807 const uint8_t *buf; 9808 struct mbuf *m = m0; 9809 9810 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9811 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9812 9813 for (; m != NULL; m = m->m_next) { 9814 buf = mtod(m, const uint8_t *); 9815 for (i = 0; i < m->m_len; i++) { 9816 if (!((j++) % 2)) 9817 data |= buf[i]; 9818 else { 9819 data |= (buf[i] << 8); 9820 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9821 data = 0; 9822 } 9823 } 9824 } 9825 if (m0->m_pkthdr.len % 2) { 9826 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9827 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9828 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9829 } 9830 9831 return (ctl); 9832 } 9833 9834 static void 9835 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9836 { 9837 9838 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9839 return; 9840 BWN_WRITE_2(mac, 0x684, 510 + time); 9841 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9842 } 9843 9844 static struct bwn_dma_ring * 9845 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9846 { 9847 9848 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9849 return (mac->mac_method.dma.wme[WME_AC_BE]); 9850 9851 switch (prio) { 9852 case 3: 9853 return (mac->mac_method.dma.wme[WME_AC_VO]); 9854 case 2: 9855 return (mac->mac_method.dma.wme[WME_AC_VI]); 9856 case 0: 9857 return (mac->mac_method.dma.wme[WME_AC_BE]); 9858 case 1: 9859 return (mac->mac_method.dma.wme[WME_AC_BK]); 9860 } 9861 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9862 return (NULL); 9863 } 9864 9865 static int 9866 bwn_dma_getslot(struct bwn_dma_ring *dr) 9867 { 9868 int slot; 9869 9870 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 9871 9872 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9873 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 9874 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 9875 9876 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 9877 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 9878 dr->dr_curslot = slot; 9879 dr->dr_usedslot++; 9880 9881 return (slot); 9882 } 9883 9884 static int 9885 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 9886 { 9887 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 9888 unsigned int a, b, c, d; 9889 unsigned int avg; 9890 uint32_t tmp; 9891 9892 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 9893 a = tmp & 0xff; 9894 b = (tmp >> 8) & 0xff; 9895 c = (tmp >> 16) & 0xff; 9896 d = (tmp >> 24) & 0xff; 9897 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 9898 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 9899 return (ENOENT); 9900 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 9901 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 9902 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 9903 9904 if (ofdm) { 9905 a = (a + 32) & 0x3f; 9906 b = (b + 32) & 0x3f; 9907 c = (c + 32) & 0x3f; 9908 d = (d + 32) & 0x3f; 9909 } 9910 9911 avg = (a + b + c + d + 2) / 4; 9912 if (ofdm) { 9913 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 9914 & BWN_HF_4DB_CCK_POWERBOOST) 9915 avg = (avg >= 13) ? (avg - 13) : 0; 9916 } 9917 return (avg); 9918 } 9919 9920 static void 9921 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 9922 { 9923 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 9924 int rfatt = *rfattp; 9925 int bbatt = *bbattp; 9926 9927 while (1) { 9928 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 9929 break; 9930 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 9931 break; 9932 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 9933 break; 9934 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 9935 break; 9936 if (bbatt > lo->bbatt.max) { 9937 bbatt -= 4; 9938 rfatt += 1; 9939 continue; 9940 } 9941 if (bbatt < lo->bbatt.min) { 9942 bbatt += 4; 9943 rfatt -= 1; 9944 continue; 9945 } 9946 if (rfatt > lo->rfatt.max) { 9947 rfatt -= 1; 9948 bbatt += 4; 9949 continue; 9950 } 9951 if (rfatt < lo->rfatt.min) { 9952 rfatt += 1; 9953 bbatt -= 4; 9954 continue; 9955 } 9956 break; 9957 } 9958 9959 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 9960 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 9961 } 9962 9963 static void 9964 bwn_phy_lock(struct bwn_mac *mac) 9965 { 9966 struct bwn_softc *sc = mac->mac_sc; 9967 struct ieee80211com *ic = &sc->sc_ic; 9968 9969 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 9970 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 9971 9972 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 9973 bwn_psctl(mac, BWN_PS_AWAKE); 9974 } 9975 9976 static void 9977 bwn_phy_unlock(struct bwn_mac *mac) 9978 { 9979 struct bwn_softc *sc = mac->mac_sc; 9980 struct ieee80211com *ic = &sc->sc_ic; 9981 9982 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 9983 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 9984 9985 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 9986 bwn_psctl(mac, 0); 9987 } 9988 9989 static void 9990 bwn_rf_lock(struct bwn_mac *mac) 9991 { 9992 9993 BWN_WRITE_4(mac, BWN_MACCTL, 9994 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 9995 BWN_READ_4(mac, BWN_MACCTL); 9996 DELAY(10); 9997 } 9998 9999 static void 10000 bwn_rf_unlock(struct bwn_mac *mac) 10001 { 10002 10003 BWN_READ_2(mac, BWN_PHYVER); 10004 BWN_WRITE_4(mac, BWN_MACCTL, 10005 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10006 } 10007 10008 static struct bwn_pio_txqueue * 10009 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10010 struct bwn_pio_txpkt **pack) 10011 { 10012 struct bwn_pio *pio = &mac->mac_method.pio; 10013 struct bwn_pio_txqueue *tq = NULL; 10014 unsigned int index; 10015 10016 switch (cookie & 0xf000) { 10017 case 0x1000: 10018 tq = &pio->wme[WME_AC_BK]; 10019 break; 10020 case 0x2000: 10021 tq = &pio->wme[WME_AC_BE]; 10022 break; 10023 case 0x3000: 10024 tq = &pio->wme[WME_AC_VI]; 10025 break; 10026 case 0x4000: 10027 tq = &pio->wme[WME_AC_VO]; 10028 break; 10029 case 0x5000: 10030 tq = &pio->mcast; 10031 break; 10032 } 10033 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10034 if (tq == NULL) 10035 return (NULL); 10036 index = (cookie & 0x0fff); 10037 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10038 if (index >= N(tq->tq_pkts)) 10039 return (NULL); 10040 *pack = &tq->tq_pkts[index]; 10041 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10042 return (tq); 10043 } 10044 10045 static void 10046 bwn_txpwr(void *arg, int npending) 10047 { 10048 struct bwn_mac *mac = arg; 10049 struct bwn_softc *sc = mac->mac_sc; 10050 10051 BWN_LOCK(sc); 10052 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10053 mac->mac_phy.set_txpwr != NULL) 10054 mac->mac_phy.set_txpwr(mac); 10055 BWN_UNLOCK(sc); 10056 } 10057 10058 static void 10059 bwn_task_15s(struct bwn_mac *mac) 10060 { 10061 uint16_t reg; 10062 10063 if (mac->mac_fw.opensource) { 10064 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10065 if (reg) { 10066 bwn_restart(mac, "fw watchdog"); 10067 return; 10068 } 10069 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10070 } 10071 if (mac->mac_phy.task_15s) 10072 mac->mac_phy.task_15s(mac); 10073 10074 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10075 } 10076 10077 static void 10078 bwn_task_30s(struct bwn_mac *mac) 10079 { 10080 10081 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10082 return; 10083 mac->mac_noise.noi_running = 1; 10084 mac->mac_noise.noi_nsamples = 0; 10085 10086 bwn_noise_gensample(mac); 10087 } 10088 10089 static void 10090 bwn_task_60s(struct bwn_mac *mac) 10091 { 10092 10093 if (mac->mac_phy.task_60s) 10094 mac->mac_phy.task_60s(mac); 10095 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10096 } 10097 10098 static void 10099 bwn_tasks(void *arg) 10100 { 10101 struct bwn_mac *mac = arg; 10102 struct bwn_softc *sc = mac->mac_sc; 10103 10104 BWN_ASSERT_LOCKED(sc); 10105 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10106 return; 10107 10108 if (mac->mac_task_state % 4 == 0) 10109 bwn_task_60s(mac); 10110 if (mac->mac_task_state % 2 == 0) 10111 bwn_task_30s(mac); 10112 bwn_task_15s(mac); 10113 10114 mac->mac_task_state++; 10115 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10116 } 10117 10118 static int 10119 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10120 { 10121 struct bwn_softc *sc = mac->mac_sc; 10122 10123 KASSERT(a == 0, ("not support APHY\n")); 10124 10125 switch (plcp->o.raw[0] & 0xf) { 10126 case 0xb: 10127 return (BWN_OFDM_RATE_6MB); 10128 case 0xf: 10129 return (BWN_OFDM_RATE_9MB); 10130 case 0xa: 10131 return (BWN_OFDM_RATE_12MB); 10132 case 0xe: 10133 return (BWN_OFDM_RATE_18MB); 10134 case 0x9: 10135 return (BWN_OFDM_RATE_24MB); 10136 case 0xd: 10137 return (BWN_OFDM_RATE_36MB); 10138 case 0x8: 10139 return (BWN_OFDM_RATE_48MB); 10140 case 0xc: 10141 return (BWN_OFDM_RATE_54MB); 10142 } 10143 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10144 plcp->o.raw[0] & 0xf); 10145 return (-1); 10146 } 10147 10148 static int 10149 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10150 { 10151 struct bwn_softc *sc = mac->mac_sc; 10152 10153 switch (plcp->o.raw[0]) { 10154 case 0x0a: 10155 return (BWN_CCK_RATE_1MB); 10156 case 0x14: 10157 return (BWN_CCK_RATE_2MB); 10158 case 0x37: 10159 return (BWN_CCK_RATE_5MB); 10160 case 0x6e: 10161 return (BWN_CCK_RATE_11MB); 10162 } 10163 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10164 return (-1); 10165 } 10166 10167 static void 10168 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10169 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10170 int rssi, int noise) 10171 { 10172 struct bwn_softc *sc = mac->mac_sc; 10173 const struct ieee80211_frame_min *wh; 10174 uint64_t tsf; 10175 uint16_t low_mactime_now; 10176 10177 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10178 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10179 10180 wh = mtod(m, const struct ieee80211_frame_min *); 10181 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10182 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10183 10184 bwn_tsf_read(mac, &tsf); 10185 low_mactime_now = tsf; 10186 tsf = tsf & ~0xffffULL; 10187 tsf += le16toh(rxhdr->mac_time); 10188 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10189 tsf -= 0x10000; 10190 10191 sc->sc_rx_th.wr_tsf = tsf; 10192 sc->sc_rx_th.wr_rate = rate; 10193 sc->sc_rx_th.wr_antsignal = rssi; 10194 sc->sc_rx_th.wr_antnoise = noise; 10195 } 10196 10197 static void 10198 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10199 { 10200 uint32_t low, high; 10201 10202 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10203 ("%s:%d: fail", __func__, __LINE__)); 10204 10205 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10206 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10207 *tsf = high; 10208 *tsf <<= 32; 10209 *tsf |= low; 10210 } 10211 10212 static int 10213 bwn_dma_attach(struct bwn_mac *mac) 10214 { 10215 struct bwn_dma *dma = &mac->mac_method.dma; 10216 struct bwn_softc *sc = mac->mac_sc; 10217 bus_addr_t lowaddr = 0; 10218 int error; 10219 10220 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10221 return (0); 10222 10223 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10224 10225 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10226 10227 dma->dmatype = bwn_dma_gettype(mac); 10228 if (dma->dmatype == BWN_DMA_30BIT) 10229 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10230 else if (dma->dmatype == BWN_DMA_32BIT) 10231 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10232 else 10233 lowaddr = BUS_SPACE_MAXADDR; 10234 10235 /* 10236 * Create top level DMA tag 10237 */ 10238 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10239 BWN_ALIGN, 0, /* alignment, bounds */ 10240 lowaddr, /* lowaddr */ 10241 BUS_SPACE_MAXADDR, /* highaddr */ 10242 NULL, NULL, /* filter, filterarg */ 10243 BUS_SPACE_MAXSIZE, /* maxsize */ 10244 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10245 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10246 0, /* flags */ 10247 NULL, NULL, /* lockfunc, lockarg */ 10248 &dma->parent_dtag); 10249 if (error) { 10250 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10251 return (error); 10252 } 10253 10254 /* 10255 * Create TX/RX mbuf DMA tag 10256 */ 10257 error = bus_dma_tag_create(dma->parent_dtag, 10258 1, 10259 0, 10260 BUS_SPACE_MAXADDR, 10261 BUS_SPACE_MAXADDR, 10262 NULL, NULL, 10263 MCLBYTES, 10264 1, 10265 BUS_SPACE_MAXSIZE_32BIT, 10266 0, 10267 NULL, NULL, 10268 &dma->rxbuf_dtag); 10269 if (error) { 10270 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10271 goto fail0; 10272 } 10273 error = bus_dma_tag_create(dma->parent_dtag, 10274 1, 10275 0, 10276 BUS_SPACE_MAXADDR, 10277 BUS_SPACE_MAXADDR, 10278 NULL, NULL, 10279 MCLBYTES, 10280 1, 10281 BUS_SPACE_MAXSIZE_32BIT, 10282 0, 10283 NULL, NULL, 10284 &dma->txbuf_dtag); 10285 if (error) { 10286 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10287 goto fail1; 10288 } 10289 10290 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10291 if (!dma->wme[WME_AC_BK]) 10292 goto fail2; 10293 10294 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10295 if (!dma->wme[WME_AC_BE]) 10296 goto fail3; 10297 10298 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10299 if (!dma->wme[WME_AC_VI]) 10300 goto fail4; 10301 10302 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10303 if (!dma->wme[WME_AC_VO]) 10304 goto fail5; 10305 10306 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10307 if (!dma->mcast) 10308 goto fail6; 10309 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10310 if (!dma->rx) 10311 goto fail7; 10312 10313 return (error); 10314 10315 fail7: bwn_dma_ringfree(&dma->mcast); 10316 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10317 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10318 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10319 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10320 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10321 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10322 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10323 return (error); 10324 } 10325 10326 static struct bwn_dma_ring * 10327 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10328 uint16_t cookie, int *slot) 10329 { 10330 struct bwn_dma *dma = &mac->mac_method.dma; 10331 struct bwn_dma_ring *dr; 10332 struct bwn_softc *sc = mac->mac_sc; 10333 10334 BWN_ASSERT_LOCKED(mac->mac_sc); 10335 10336 switch (cookie & 0xf000) { 10337 case 0x1000: 10338 dr = dma->wme[WME_AC_BK]; 10339 break; 10340 case 0x2000: 10341 dr = dma->wme[WME_AC_BE]; 10342 break; 10343 case 0x3000: 10344 dr = dma->wme[WME_AC_VI]; 10345 break; 10346 case 0x4000: 10347 dr = dma->wme[WME_AC_VO]; 10348 break; 10349 case 0x5000: 10350 dr = dma->mcast; 10351 break; 10352 default: 10353 dr = NULL; 10354 KASSERT(0 == 1, 10355 ("invalid cookie value %d", cookie & 0xf000)); 10356 } 10357 *slot = (cookie & 0x0fff); 10358 if (*slot < 0 || *slot >= dr->dr_numslots) { 10359 /* 10360 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10361 * that it occurs events which have same H/W sequence numbers. 10362 * When it's occurred just prints a WARNING msgs and ignores. 10363 */ 10364 KASSERT(status->seq == dma->lastseq, 10365 ("%s:%d: fail", __func__, __LINE__)); 10366 device_printf(sc->sc_dev, 10367 "out of slot ranges (0 < %d < %d)\n", *slot, 10368 dr->dr_numslots); 10369 return (NULL); 10370 } 10371 dma->lastseq = status->seq; 10372 return (dr); 10373 } 10374 10375 static void 10376 bwn_dma_stop(struct bwn_mac *mac) 10377 { 10378 struct bwn_dma *dma; 10379 10380 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10381 return; 10382 dma = &mac->mac_method.dma; 10383 10384 bwn_dma_ringstop(&dma->rx); 10385 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10386 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10387 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10388 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10389 bwn_dma_ringstop(&dma->mcast); 10390 } 10391 10392 static void 10393 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10394 { 10395 10396 if (dr == NULL) 10397 return; 10398 10399 bwn_dma_cleanup(*dr); 10400 } 10401 10402 static void 10403 bwn_pio_stop(struct bwn_mac *mac) 10404 { 10405 struct bwn_pio *pio; 10406 10407 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10408 return; 10409 pio = &mac->mac_method.pio; 10410 10411 bwn_destroy_queue_tx(&pio->mcast); 10412 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10413 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10414 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10415 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10416 } 10417 10418 static void 10419 bwn_led_attach(struct bwn_mac *mac) 10420 { 10421 struct bwn_softc *sc = mac->mac_sc; 10422 const uint8_t *led_act = NULL; 10423 uint16_t val[BWN_LED_MAX]; 10424 int i; 10425 10426 sc->sc_led_idle = (2350 * hz) / 1000; 10427 sc->sc_led_blink = 1; 10428 10429 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10430 if (siba_get_pci_subvendor(sc->sc_dev) == 10431 bwn_vendor_led_act[i].vid) { 10432 led_act = bwn_vendor_led_act[i].led_act; 10433 break; 10434 } 10435 } 10436 if (led_act == NULL) 10437 led_act = bwn_default_led_act; 10438 10439 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10440 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10441 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10442 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10443 10444 for (i = 0; i < BWN_LED_MAX; ++i) { 10445 struct bwn_led *led = &sc->sc_leds[i]; 10446 10447 if (val[i] == 0xff) { 10448 led->led_act = led_act[i]; 10449 } else { 10450 if (val[i] & BWN_LED_ACT_LOW) 10451 led->led_flags |= BWN_LED_F_ACTLOW; 10452 led->led_act = val[i] & BWN_LED_ACT_MASK; 10453 } 10454 led->led_mask = (1 << i); 10455 10456 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10457 led->led_act == BWN_LED_ACT_BLINK_POLL || 10458 led->led_act == BWN_LED_ACT_BLINK) { 10459 led->led_flags |= BWN_LED_F_BLINK; 10460 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10461 led->led_flags |= BWN_LED_F_POLLABLE; 10462 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10463 led->led_flags |= BWN_LED_F_SLOW; 10464 10465 if (sc->sc_blink_led == NULL) { 10466 sc->sc_blink_led = led; 10467 if (led->led_flags & BWN_LED_F_SLOW) 10468 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10469 } 10470 } 10471 10472 DPRINTF(sc, BWN_DEBUG_LED, 10473 "%dth led, act %d, lowact %d\n", i, 10474 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10475 } 10476 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10477 } 10478 10479 static __inline uint16_t 10480 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10481 { 10482 10483 if (led->led_flags & BWN_LED_F_ACTLOW) 10484 on = !on; 10485 if (on) 10486 val |= led->led_mask; 10487 else 10488 val &= ~led->led_mask; 10489 return val; 10490 } 10491 10492 static void 10493 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10494 { 10495 struct bwn_softc *sc = mac->mac_sc; 10496 struct ieee80211com *ic = &sc->sc_ic; 10497 uint16_t val; 10498 int i; 10499 10500 if (nstate == IEEE80211_S_INIT) { 10501 callout_stop(&sc->sc_led_blink_ch); 10502 sc->sc_led_blinking = 0; 10503 } 10504 10505 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) 10506 return; 10507 10508 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10509 for (i = 0; i < BWN_LED_MAX; ++i) { 10510 struct bwn_led *led = &sc->sc_leds[i]; 10511 int on; 10512 10513 if (led->led_act == BWN_LED_ACT_UNKN || 10514 led->led_act == BWN_LED_ACT_NULL) 10515 continue; 10516 10517 if ((led->led_flags & BWN_LED_F_BLINK) && 10518 nstate != IEEE80211_S_INIT) 10519 continue; 10520 10521 switch (led->led_act) { 10522 case BWN_LED_ACT_ON: /* Always on */ 10523 on = 1; 10524 break; 10525 case BWN_LED_ACT_OFF: /* Always off */ 10526 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10527 on = 0; 10528 break; 10529 default: 10530 on = 1; 10531 switch (nstate) { 10532 case IEEE80211_S_INIT: 10533 on = 0; 10534 break; 10535 case IEEE80211_S_RUN: 10536 if (led->led_act == BWN_LED_ACT_11G && 10537 ic->ic_curmode != IEEE80211_MODE_11G) 10538 on = 0; 10539 break; 10540 default: 10541 if (led->led_act == BWN_LED_ACT_ASSOC) 10542 on = 0; 10543 break; 10544 } 10545 break; 10546 } 10547 10548 val = bwn_led_onoff(led, val, on); 10549 } 10550 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10551 } 10552 10553 static void 10554 bwn_led_event(struct bwn_mac *mac, int event) 10555 { 10556 struct bwn_softc *sc = mac->mac_sc; 10557 struct bwn_led *led = sc->sc_blink_led; 10558 int rate; 10559 10560 if (event == BWN_LED_EVENT_POLL) { 10561 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10562 return; 10563 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10564 return; 10565 } 10566 10567 sc->sc_led_ticks = ticks; 10568 if (sc->sc_led_blinking) 10569 return; 10570 10571 switch (event) { 10572 case BWN_LED_EVENT_RX: 10573 rate = sc->sc_rx_rate; 10574 break; 10575 case BWN_LED_EVENT_TX: 10576 rate = sc->sc_tx_rate; 10577 break; 10578 case BWN_LED_EVENT_POLL: 10579 rate = 0; 10580 break; 10581 default: 10582 panic("unknown LED event %d\n", event); 10583 break; 10584 } 10585 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10586 bwn_led_duration[rate].off_dur); 10587 } 10588 10589 static void 10590 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10591 { 10592 struct bwn_softc *sc = mac->mac_sc; 10593 struct bwn_led *led = sc->sc_blink_led; 10594 uint16_t val; 10595 10596 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10597 val = bwn_led_onoff(led, val, 1); 10598 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10599 10600 if (led->led_flags & BWN_LED_F_SLOW) { 10601 BWN_LED_SLOWDOWN(on_dur); 10602 BWN_LED_SLOWDOWN(off_dur); 10603 } 10604 10605 sc->sc_led_blinking = 1; 10606 sc->sc_led_blink_offdur = off_dur; 10607 10608 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10609 } 10610 10611 static void 10612 bwn_led_blink_next(void *arg) 10613 { 10614 struct bwn_mac *mac = arg; 10615 struct bwn_softc *sc = mac->mac_sc; 10616 uint16_t val; 10617 10618 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10619 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10620 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10621 10622 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10623 bwn_led_blink_end, mac); 10624 } 10625 10626 static void 10627 bwn_led_blink_end(void *arg) 10628 { 10629 struct bwn_mac *mac = arg; 10630 struct bwn_softc *sc = mac->mac_sc; 10631 10632 sc->sc_led_blinking = 0; 10633 } 10634 10635 static int 10636 bwn_suspend(device_t dev) 10637 { 10638 struct bwn_softc *sc = device_get_softc(dev); 10639 10640 BWN_LOCK(sc); 10641 bwn_stop(sc); 10642 BWN_UNLOCK(sc); 10643 return (0); 10644 } 10645 10646 static int 10647 bwn_resume(device_t dev) 10648 { 10649 struct bwn_softc *sc = device_get_softc(dev); 10650 int error = EDOOFUS; 10651 10652 BWN_LOCK(sc); 10653 if (sc->sc_ic.ic_nrunning > 0) 10654 error = bwn_init(sc); 10655 BWN_UNLOCK(sc); 10656 if (error == 0) 10657 ieee80211_start_all(&sc->sc_ic); 10658 return (0); 10659 } 10660 10661 static void 10662 bwn_rfswitch(void *arg) 10663 { 10664 struct bwn_softc *sc = arg; 10665 struct bwn_mac *mac = sc->sc_curmac; 10666 int cur = 0, prev = 0; 10667 10668 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10669 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10670 10671 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10672 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10673 & BWN_RF_HWENABLED_HI_MASK)) 10674 cur = 1; 10675 } else { 10676 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10677 & BWN_RF_HWENABLED_LO_MASK) 10678 cur = 1; 10679 } 10680 10681 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10682 prev = 1; 10683 10684 if (cur != prev) { 10685 if (cur) 10686 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10687 else 10688 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10689 10690 device_printf(sc->sc_dev, 10691 "status of RF switch is changed to %s\n", 10692 cur ? "ON" : "OFF"); 10693 if (cur != mac->mac_phy.rf_on) { 10694 if (cur) 10695 bwn_rf_turnon(mac); 10696 else 10697 bwn_rf_turnoff(mac); 10698 } 10699 } 10700 10701 callout_schedule(&sc->sc_rfswitch_ch, hz); 10702 } 10703 10704 static void 10705 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10706 { 10707 struct bwn_phy *phy = &mac->mac_phy; 10708 struct bwn_phy_lp *plp = &phy->phy_lp; 10709 10710 plp->plp_antenna = BWN_ANT_DEFAULT; 10711 } 10712 10713 static int 10714 bwn_phy_lp_init(struct bwn_mac *mac) 10715 { 10716 static const struct bwn_stxtable tables[] = { 10717 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10718 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10719 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10720 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10721 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10722 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10723 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10724 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10725 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10726 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10727 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10728 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10729 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10730 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10731 { 2, 11, 0x40, 0, 0x0f } 10732 }; 10733 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10734 struct bwn_softc *sc = mac->mac_sc; 10735 const struct bwn_stxtable *st; 10736 struct ieee80211com *ic = &sc->sc_ic; 10737 int i, error; 10738 uint16_t tmp; 10739 10740 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10741 bwn_phy_lp_bbinit(mac); 10742 10743 /* initialize RF */ 10744 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10745 DELAY(1); 10746 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10747 DELAY(1); 10748 10749 if (mac->mac_phy.rf_ver == 0x2062) 10750 bwn_phy_lp_b2062_init(mac); 10751 else { 10752 bwn_phy_lp_b2063_init(mac); 10753 10754 /* synchronize stx table. */ 10755 for (i = 0; i < N(tables); i++) { 10756 st = &tables[i]; 10757 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10758 tmp >>= st->st_rfshift; 10759 tmp <<= st->st_physhift; 10760 BWN_PHY_SETMASK(mac, 10761 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10762 ~(st->st_mask << st->st_physhift), tmp); 10763 } 10764 10765 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10766 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10767 } 10768 10769 /* calibrate RC */ 10770 if (mac->mac_phy.rev >= 2) 10771 bwn_phy_lp_rxcal_r2(mac); 10772 else if (!plp->plp_rccap) { 10773 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10774 bwn_phy_lp_rccal_r12(mac); 10775 } else 10776 bwn_phy_lp_set_rccap(mac); 10777 10778 error = bwn_phy_lp_switch_channel(mac, 7); 10779 if (error) 10780 device_printf(sc->sc_dev, 10781 "failed to change channel 7 (%d)\n", error); 10782 bwn_phy_lp_txpctl_init(mac); 10783 bwn_phy_lp_calib(mac); 10784 return (0); 10785 } 10786 10787 static uint16_t 10788 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10789 { 10790 10791 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10792 return (BWN_READ_2(mac, BWN_PHYDATA)); 10793 } 10794 10795 static void 10796 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10797 { 10798 10799 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10800 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10801 } 10802 10803 static void 10804 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10805 uint16_t set) 10806 { 10807 10808 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10809 BWN_WRITE_2(mac, BWN_PHYDATA, 10810 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10811 } 10812 10813 static uint16_t 10814 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10815 { 10816 10817 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10818 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10819 reg |= 0x100; 10820 if (mac->mac_phy.rev >= 2) 10821 reg |= 0x200; 10822 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10823 return BWN_READ_2(mac, BWN_RFDATALO); 10824 } 10825 10826 static void 10827 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10828 { 10829 10830 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10831 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10832 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10833 } 10834 10835 static void 10836 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10837 { 10838 10839 if (on) { 10840 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10841 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10842 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10843 return; 10844 } 10845 10846 if (mac->mac_phy.rev >= 2) { 10847 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10848 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10849 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10850 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10851 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10852 return; 10853 } 10854 10855 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10856 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10857 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10858 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10859 } 10860 10861 static int 10862 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10863 { 10864 struct bwn_phy *phy = &mac->mac_phy; 10865 struct bwn_phy_lp *plp = &phy->phy_lp; 10866 int error; 10867 10868 if (phy->rf_ver == 0x2063) { 10869 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 10870 if (error) 10871 return (error); 10872 } else { 10873 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 10874 if (error) 10875 return (error); 10876 bwn_phy_lp_set_anafilter(mac, chan); 10877 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 10878 } 10879 10880 plp->plp_chan = chan; 10881 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 10882 return (0); 10883 } 10884 10885 static uint32_t 10886 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 10887 { 10888 struct bwn_softc *sc = mac->mac_sc; 10889 struct ieee80211com *ic = &sc->sc_ic; 10890 10891 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 10892 } 10893 10894 static void 10895 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 10896 { 10897 struct bwn_phy *phy = &mac->mac_phy; 10898 struct bwn_phy_lp *plp = &phy->phy_lp; 10899 10900 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 10901 return; 10902 10903 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 10904 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 10905 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 10906 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 10907 plp->plp_antenna = antenna; 10908 } 10909 10910 static void 10911 bwn_phy_lp_task_60s(struct bwn_mac *mac) 10912 { 10913 10914 bwn_phy_lp_calib(mac); 10915 } 10916 10917 static void 10918 bwn_phy_lp_readsprom(struct bwn_mac *mac) 10919 { 10920 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10921 struct bwn_softc *sc = mac->mac_sc; 10922 struct ieee80211com *ic = &sc->sc_ic; 10923 10924 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 10925 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 10926 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 10927 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 10928 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 10929 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 10930 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 10931 return; 10932 } 10933 10934 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 10935 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 10936 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 10937 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 10938 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 10939 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 10940 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 10941 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 10942 } 10943 10944 static void 10945 bwn_phy_lp_bbinit(struct bwn_mac *mac) 10946 { 10947 10948 bwn_phy_lp_tblinit(mac); 10949 if (mac->mac_phy.rev >= 2) 10950 bwn_phy_lp_bbinit_r2(mac); 10951 else 10952 bwn_phy_lp_bbinit_r01(mac); 10953 } 10954 10955 static void 10956 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 10957 { 10958 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 10959 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 10960 struct bwn_softc *sc = mac->mac_sc; 10961 struct ieee80211com *ic = &sc->sc_ic; 10962 10963 bwn_phy_lp_set_txgain(mac, 10964 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 10965 bwn_phy_lp_set_bbmult(mac, 150); 10966 } 10967 10968 static void 10969 bwn_phy_lp_calib(struct bwn_mac *mac) 10970 { 10971 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10972 struct bwn_softc *sc = mac->mac_sc; 10973 struct ieee80211com *ic = &sc->sc_ic; 10974 const struct bwn_rxcompco *rc = NULL; 10975 struct bwn_txgain ogain; 10976 int i, omode, oafeovr, orf, obbmult; 10977 uint8_t mode, fc = 0; 10978 10979 if (plp->plp_chanfullcal != plp->plp_chan) { 10980 plp->plp_chanfullcal = plp->plp_chan; 10981 fc = 1; 10982 } 10983 10984 bwn_mac_suspend(mac); 10985 10986 /* BlueTooth Coexistance Override */ 10987 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 10988 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 10989 10990 if (mac->mac_phy.rev >= 2) 10991 bwn_phy_lp_digflt_save(mac); 10992 bwn_phy_lp_get_txpctlmode(mac); 10993 mode = plp->plp_txpctlmode; 10994 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 10995 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 10996 bwn_phy_lp_bugfix(mac); 10997 if (mac->mac_phy.rev >= 2 && fc == 1) { 10998 bwn_phy_lp_get_txpctlmode(mac); 10999 omode = plp->plp_txpctlmode; 11000 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11001 if (oafeovr) 11002 ogain = bwn_phy_lp_get_txgain(mac); 11003 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11004 obbmult = bwn_phy_lp_get_bbmult(mac); 11005 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11006 if (oafeovr) 11007 bwn_phy_lp_set_txgain(mac, &ogain); 11008 bwn_phy_lp_set_bbmult(mac, obbmult); 11009 bwn_phy_lp_set_txpctlmode(mac, omode); 11010 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11011 } 11012 bwn_phy_lp_set_txpctlmode(mac, mode); 11013 if (mac->mac_phy.rev >= 2) 11014 bwn_phy_lp_digflt_restore(mac); 11015 11016 /* do RX IQ Calculation; assumes that noise is true. */ 11017 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11018 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11019 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11020 rc = &bwn_rxcompco_5354[i]; 11021 } 11022 } else if (mac->mac_phy.rev >= 2) 11023 rc = &bwn_rxcompco_r2; 11024 else { 11025 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11026 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11027 rc = &bwn_rxcompco_r12[i]; 11028 } 11029 } 11030 if (rc == NULL) 11031 goto fail; 11032 11033 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11034 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11035 11036 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11037 11038 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11039 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11040 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11041 } else { 11042 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11043 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11044 } 11045 11046 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11047 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11048 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11049 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11050 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11051 bwn_phy_lp_set_deaf(mac, 0); 11052 /* XXX no checking return value? */ 11053 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11054 bwn_phy_lp_clear_deaf(mac, 0); 11055 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11056 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11057 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11058 11059 /* disable RX GAIN override. */ 11060 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11061 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11062 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11063 if (mac->mac_phy.rev >= 2) { 11064 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11065 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11066 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11067 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11068 } 11069 } else { 11070 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11071 } 11072 11073 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11074 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11075 fail: 11076 bwn_mac_enable(mac); 11077 } 11078 11079 static void 11080 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11081 { 11082 11083 if (on) { 11084 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11085 return; 11086 } 11087 11088 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11089 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11090 } 11091 11092 static int 11093 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11094 { 11095 static const struct bwn_b206x_chan *bc = NULL; 11096 struct bwn_softc *sc = mac->mac_sc; 11097 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11098 tmp[6]; 11099 uint16_t old, scale, tmp16; 11100 int i, div; 11101 11102 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11103 if (bwn_b2063_chantable[i].bc_chan == chan) { 11104 bc = &bwn_b2063_chantable[i]; 11105 break; 11106 } 11107 } 11108 if (bc == NULL) 11109 return (EINVAL); 11110 11111 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11112 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11113 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11114 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11115 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11116 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11117 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11118 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11119 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11120 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11121 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11122 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11123 11124 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11125 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11126 11127 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11128 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11129 freqref = freqxtal * 3; 11130 div = (freqxtal <= 26000000 ? 1 : 2); 11131 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11132 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11133 999999) / 1000000) + 1; 11134 11135 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11136 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11137 0xfff8, timeout >> 2); 11138 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11139 0xff9f,timeout << 5); 11140 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11141 11142 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11143 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11144 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11145 11146 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11147 (timeoutref + 1)) - 1; 11148 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11149 0xf0, count >> 8); 11150 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11151 11152 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11153 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11154 while (tmp[1] >= freqref) { 11155 tmp[0]++; 11156 tmp[1] -= freqref; 11157 } 11158 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11159 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11160 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11161 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11162 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11163 11164 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11165 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11166 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11167 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11168 11169 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11170 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11171 11172 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11173 scale = 1; 11174 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11175 } else { 11176 scale = 0; 11177 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11178 } 11179 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11180 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11181 11182 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11183 (scale + 1); 11184 if (tmp[5] > 150) 11185 tmp[5] = 0; 11186 11187 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11188 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11189 11190 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11191 if (freqxtal > 26000000) 11192 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11193 else 11194 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11195 11196 if (val[0] == 45) 11197 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11198 else 11199 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11200 11201 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11202 DELAY(1); 11203 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11204 11205 /* VCO Calibration */ 11206 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11207 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11208 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11209 DELAY(1); 11210 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11211 DELAY(1); 11212 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11213 DELAY(1); 11214 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11215 DELAY(300); 11216 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11217 11218 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11219 return (0); 11220 } 11221 11222 static int 11223 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11224 { 11225 struct bwn_softc *sc = mac->mac_sc; 11226 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11227 const struct bwn_b206x_chan *bc = NULL; 11228 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11229 uint32_t tmp[9]; 11230 int i; 11231 11232 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11233 if (bwn_b2062_chantable[i].bc_chan == chan) { 11234 bc = &bwn_b2062_chantable[i]; 11235 break; 11236 } 11237 } 11238 11239 if (bc == NULL) 11240 return (EINVAL); 11241 11242 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11243 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11244 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11245 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11246 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11247 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11248 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11249 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11250 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11251 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11252 11253 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11254 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11255 bwn_phy_lp_b2062_reset_pllbias(mac); 11256 tmp[0] = freqxtal / 1000; 11257 tmp[1] = plp->plp_div * 1000; 11258 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11259 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11260 tmp[2] *= 2; 11261 tmp[3] = 48 * tmp[0]; 11262 tmp[5] = tmp[2] / tmp[3]; 11263 tmp[6] = tmp[2] % tmp[3]; 11264 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11265 tmp[4] = tmp[6] * 0x100; 11266 tmp[5] = tmp[4] / tmp[3]; 11267 tmp[6] = tmp[4] % tmp[3]; 11268 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11269 tmp[4] = tmp[6] * 0x100; 11270 tmp[5] = tmp[4] / tmp[3]; 11271 tmp[6] = tmp[4] % tmp[3]; 11272 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11273 tmp[4] = tmp[6] * 0x100; 11274 tmp[5] = tmp[4] / tmp[3]; 11275 tmp[6] = tmp[4] % tmp[3]; 11276 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11277 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11278 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11279 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11280 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11281 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11282 11283 bwn_phy_lp_b2062_vco_calib(mac); 11284 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11285 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11286 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11287 bwn_phy_lp_b2062_reset_pllbias(mac); 11288 bwn_phy_lp_b2062_vco_calib(mac); 11289 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11290 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11291 return (EIO); 11292 } 11293 } 11294 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11295 return (0); 11296 } 11297 11298 static void 11299 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11300 { 11301 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11302 uint16_t tmp = (channel == 14); 11303 11304 if (mac->mac_phy.rev < 2) { 11305 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11306 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11307 bwn_phy_lp_set_rccap(mac); 11308 return; 11309 } 11310 11311 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11312 } 11313 11314 static void 11315 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11316 { 11317 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11318 struct bwn_softc *sc = mac->mac_sc; 11319 struct ieee80211com *ic = &sc->sc_ic; 11320 uint16_t iso, tmp[3]; 11321 11322 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11323 11324 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11325 iso = plp->plp_txisoband_m; 11326 else if (freq <= 5320) 11327 iso = plp->plp_txisoband_l; 11328 else if (freq <= 5700) 11329 iso = plp->plp_txisoband_m; 11330 else 11331 iso = plp->plp_txisoband_h; 11332 11333 tmp[0] = ((iso - 26) / 12) << 12; 11334 tmp[1] = tmp[0] + 0x1000; 11335 tmp[2] = tmp[0] + 0x2000; 11336 11337 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11338 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11339 } 11340 11341 static void 11342 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11343 { 11344 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11345 int i; 11346 static const uint16_t addr[] = { 11347 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11348 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11349 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11350 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11351 BWN_PHY_OFDM(0xcf), 11352 }; 11353 static const uint16_t val[] = { 11354 0xde5e, 0xe832, 0xe331, 0x4d26, 11355 0x0026, 0x1420, 0x0020, 0xfe08, 11356 0x0008, 11357 }; 11358 11359 for (i = 0; i < N(addr); i++) { 11360 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11361 BWN_PHY_WRITE(mac, addr[i], val[i]); 11362 } 11363 } 11364 11365 static void 11366 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11367 { 11368 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11369 struct bwn_softc *sc = mac->mac_sc; 11370 uint16_t ctl; 11371 11372 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11373 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11374 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11375 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11376 break; 11377 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11378 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11379 break; 11380 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11381 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11382 break; 11383 default: 11384 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11385 device_printf(sc->sc_dev, "unknown command mode\n"); 11386 break; 11387 } 11388 } 11389 11390 static void 11391 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11392 { 11393 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11394 uint16_t ctl; 11395 uint8_t old; 11396 11397 bwn_phy_lp_get_txpctlmode(mac); 11398 old = plp->plp_txpctlmode; 11399 if (old == mode) 11400 return; 11401 plp->plp_txpctlmode = mode; 11402 11403 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11404 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11405 plp->plp_tssiidx); 11406 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11407 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11408 11409 /* disable TX GAIN override */ 11410 if (mac->mac_phy.rev < 2) 11411 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11412 else { 11413 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11414 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11415 } 11416 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11417 11418 plp->plp_txpwridx = -1; 11419 } 11420 if (mac->mac_phy.rev >= 2) { 11421 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11422 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11423 else 11424 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11425 } 11426 11427 /* writes TX Power Control mode */ 11428 switch (plp->plp_txpctlmode) { 11429 case BWN_PHYLP_TXPCTL_OFF: 11430 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11431 break; 11432 case BWN_PHYLP_TXPCTL_ON_HW: 11433 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11434 break; 11435 case BWN_PHYLP_TXPCTL_ON_SW: 11436 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11437 break; 11438 default: 11439 ctl = 0; 11440 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11441 } 11442 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11443 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11444 } 11445 11446 static void 11447 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11448 { 11449 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11450 struct bwn_softc *sc = mac->mac_sc; 11451 const unsigned int size = 256; 11452 struct bwn_txgain tg; 11453 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11454 uint16_t tssinpt, tssiidx, value[2]; 11455 uint8_t mode; 11456 int8_t txpwridx; 11457 11458 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11459 M_NOWAIT | M_ZERO); 11460 if (tabs == NULL) { 11461 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11462 return; 11463 } 11464 11465 bwn_phy_lp_get_txpctlmode(mac); 11466 mode = plp->plp_txpctlmode; 11467 txpwridx = plp->plp_txpwridx; 11468 tssinpt = plp->plp_tssinpt; 11469 tssiidx = plp->plp_tssiidx; 11470 11471 bwn_tab_read_multi(mac, 11472 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11473 BWN_TAB_4(7, 0x140), size, tabs); 11474 11475 bwn_phy_lp_tblinit(mac); 11476 bwn_phy_lp_bbinit(mac); 11477 bwn_phy_lp_txpctl_init(mac); 11478 bwn_phy_lp_rf_onoff(mac, 1); 11479 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11480 11481 bwn_tab_write_multi(mac, 11482 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11483 BWN_TAB_4(7, 0x140), size, tabs); 11484 11485 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11486 plp->plp_tssinpt = tssinpt; 11487 plp->plp_tssiidx = tssiidx; 11488 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11489 if (txpwridx != -1) { 11490 /* set TX power by index */ 11491 plp->plp_txpwridx = txpwridx; 11492 bwn_phy_lp_get_txpctlmode(mac); 11493 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11494 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11495 if (mac->mac_phy.rev >= 2) { 11496 rxcomp = bwn_tab_read(mac, 11497 BWN_TAB_4(7, txpwridx + 320)); 11498 txgain = bwn_tab_read(mac, 11499 BWN_TAB_4(7, txpwridx + 192)); 11500 tg.tg_pad = (txgain >> 16) & 0xff; 11501 tg.tg_gm = txgain & 0xff; 11502 tg.tg_pga = (txgain >> 8) & 0xff; 11503 tg.tg_dac = (rxcomp >> 28) & 0xff; 11504 bwn_phy_lp_set_txgain(mac, &tg); 11505 } else { 11506 rxcomp = bwn_tab_read(mac, 11507 BWN_TAB_4(10, txpwridx + 320)); 11508 txgain = bwn_tab_read(mac, 11509 BWN_TAB_4(10, txpwridx + 192)); 11510 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11511 0xf800, (txgain >> 4) & 0x7fff); 11512 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11513 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11514 } 11515 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11516 11517 /* set TX IQCC */ 11518 value[0] = (rxcomp >> 10) & 0x3ff; 11519 value[1] = rxcomp & 0x3ff; 11520 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11521 11522 coeff = bwn_tab_read(mac, 11523 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11524 BWN_TAB_4(10, txpwridx + 448)); 11525 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11526 if (mac->mac_phy.rev >= 2) { 11527 rfpwr = bwn_tab_read(mac, 11528 BWN_TAB_4(7, txpwridx + 576)); 11529 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11530 rfpwr & 0xffff); 11531 } 11532 bwn_phy_lp_set_txgain_override(mac); 11533 } 11534 if (plp->plp_rccap) 11535 bwn_phy_lp_set_rccap(mac); 11536 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11537 bwn_phy_lp_set_txpctlmode(mac, mode); 11538 free(tabs, M_DEVBUF); 11539 } 11540 11541 static void 11542 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11543 { 11544 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11545 int i; 11546 static const uint16_t addr[] = { 11547 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11548 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11549 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11550 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11551 BWN_PHY_OFDM(0xcf), 11552 }; 11553 11554 for (i = 0; i < N(addr); i++) 11555 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11556 } 11557 11558 static void 11559 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11560 { 11561 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11562 11563 if (mac->mac_phy.rev < 2) { 11564 bwn_phy_lp_tblinit_r01(mac); 11565 bwn_phy_lp_tblinit_txgain(mac); 11566 bwn_phy_lp_set_gaintbl(mac, freq); 11567 return; 11568 } 11569 11570 bwn_phy_lp_tblinit_r2(mac); 11571 bwn_phy_lp_tblinit_txgain(mac); 11572 } 11573 11574 struct bwn_wpair { 11575 uint16_t reg; 11576 uint16_t value; 11577 }; 11578 11579 struct bwn_smpair { 11580 uint16_t offset; 11581 uint16_t mask; 11582 uint16_t set; 11583 }; 11584 11585 static void 11586 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11587 { 11588 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11589 struct bwn_softc *sc = mac->mac_sc; 11590 struct ieee80211com *ic = &sc->sc_ic; 11591 static const struct bwn_wpair v1[] = { 11592 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11593 { BWN_PHY_AFE_CTL, 0x8800 }, 11594 { BWN_PHY_AFE_CTL_OVR, 0 }, 11595 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11596 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11597 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11598 { BWN_PHY_OFDM(0xf9), 0 }, 11599 { BWN_PHY_TR_LOOKUP_1, 0 } 11600 }; 11601 static const struct bwn_smpair v2[] = { 11602 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11603 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11604 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11605 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11606 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11607 }; 11608 static const struct bwn_smpair v3[] = { 11609 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11610 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11611 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11612 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11613 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11614 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11615 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11616 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11617 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11618 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11619 11620 }; 11621 int i; 11622 11623 for (i = 0; i < N(v1); i++) 11624 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11625 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11626 for (i = 0; i < N(v2); i++) 11627 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11628 11629 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11630 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11631 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11632 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11633 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11634 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11635 } else { 11636 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11637 } 11638 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11639 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11640 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11641 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11642 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11643 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11644 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11645 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11646 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11647 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11648 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11649 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11650 (siba_get_chiprev(sc->sc_dev) == 0)) { 11651 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11652 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11653 } else { 11654 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11655 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11656 } 11657 for (i = 0; i < N(v3); i++) 11658 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11659 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11660 (siba_get_chiprev(sc->sc_dev) == 0)) { 11661 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11662 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11663 } 11664 11665 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11666 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11667 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11668 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11669 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11670 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11671 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11672 } else 11673 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11674 11675 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11676 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11677 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11678 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11679 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11680 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11681 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11682 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11683 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11684 11685 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11686 (siba_get_chiprev(sc->sc_dev) == 0)) { 11687 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11688 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11689 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11690 } 11691 11692 bwn_phy_lp_digflt_save(mac); 11693 } 11694 11695 static void 11696 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11697 { 11698 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11699 struct bwn_softc *sc = mac->mac_sc; 11700 struct ieee80211com *ic = &sc->sc_ic; 11701 static const struct bwn_smpair v1[] = { 11702 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11703 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11704 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11705 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11706 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11707 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11708 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11709 }; 11710 static const struct bwn_smpair v2[] = { 11711 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11712 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11713 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11714 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11715 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11716 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11717 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11718 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11719 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11720 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11721 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11722 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11723 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11724 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11725 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11726 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11727 }; 11728 static const struct bwn_smpair v3[] = { 11729 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11730 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11731 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11732 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11733 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11734 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11735 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11736 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11737 }; 11738 static const struct bwn_smpair v4[] = { 11739 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11740 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11741 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11742 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11743 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11744 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11745 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11746 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11747 }; 11748 static const struct bwn_smpair v5[] = { 11749 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11750 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11751 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11752 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11753 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11754 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11755 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11756 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11757 }; 11758 int i; 11759 uint16_t tmp, tmp2; 11760 11761 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11762 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11763 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11764 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11765 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11766 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11767 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11768 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11769 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11770 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11771 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11772 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11773 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11774 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11775 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11776 for (i = 0; i < N(v1); i++) 11777 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11778 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11779 0xff00, plp->plp_rxpwroffset); 11780 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11781 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11782 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11783 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11784 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11785 if (mac->mac_phy.rev == 0) 11786 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11787 0xffcf, 0x0010); 11788 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11789 } else { 11790 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11791 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11792 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11793 } 11794 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11795 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11796 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11797 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11798 else 11799 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11800 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11801 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11802 0xfff9, (plp->plp_bxarch << 1)); 11803 if (mac->mac_phy.rev == 1 && 11804 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11805 for (i = 0; i < N(v2); i++) 11806 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11807 v2[i].set); 11808 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11809 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11810 ((mac->mac_phy.rev == 0) && 11811 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11812 for (i = 0; i < N(v3); i++) 11813 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11814 v3[i].set); 11815 } else if (mac->mac_phy.rev == 1 || 11816 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11817 for (i = 0; i < N(v4); i++) 11818 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11819 v4[i].set); 11820 } else { 11821 for (i = 0; i < N(v5); i++) 11822 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11823 v5[i].set); 11824 } 11825 if (mac->mac_phy.rev == 1 && 11826 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11827 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11828 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11829 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11830 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11831 } 11832 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11833 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11834 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11835 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11836 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11837 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11838 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11839 } 11840 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11841 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11842 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11843 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11844 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11845 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11846 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11847 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11848 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11849 } else { 11850 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11851 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11852 } 11853 if (mac->mac_phy.rev == 1) { 11854 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11855 tmp2 = (tmp & 0x03e0) >> 5; 11856 tmp2 |= tmp2 << 5; 11857 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11858 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 11859 tmp2 = (tmp & 0x1f00) >> 8; 11860 tmp2 |= tmp2 << 5; 11861 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 11862 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 11863 tmp2 = tmp & 0x00ff; 11864 tmp2 |= tmp << 8; 11865 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 11866 } 11867 } 11868 11869 struct bwn_b2062_freq { 11870 uint16_t freq; 11871 uint8_t value[6]; 11872 }; 11873 11874 static void 11875 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 11876 { 11877 #define CALC_CTL7(freq, div) \ 11878 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 11879 #define CALC_CTL18(freq, div) \ 11880 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 11881 #define CALC_CTL19(freq, div) \ 11882 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 11883 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11884 struct bwn_softc *sc = mac->mac_sc; 11885 struct ieee80211com *ic = &sc->sc_ic; 11886 static const struct bwn_b2062_freq freqdata_tab[] = { 11887 { 12000, { 6, 6, 6, 6, 10, 6 } }, 11888 { 13000, { 4, 4, 4, 4, 11, 7 } }, 11889 { 14400, { 3, 3, 3, 3, 12, 7 } }, 11890 { 16200, { 3, 3, 3, 3, 13, 8 } }, 11891 { 18000, { 2, 2, 2, 2, 14, 8 } }, 11892 { 19200, { 1, 1, 1, 1, 14, 9 } } 11893 }; 11894 static const struct bwn_wpair v1[] = { 11895 { BWN_B2062_N_TXCTL3, 0 }, 11896 { BWN_B2062_N_TXCTL4, 0 }, 11897 { BWN_B2062_N_TXCTL5, 0 }, 11898 { BWN_B2062_N_TXCTL6, 0 }, 11899 { BWN_B2062_N_PDNCTL0, 0x40 }, 11900 { BWN_B2062_N_PDNCTL0, 0 }, 11901 { BWN_B2062_N_CALIB_TS, 0x10 }, 11902 { BWN_B2062_N_CALIB_TS, 0 } 11903 }; 11904 const struct bwn_b2062_freq *f = NULL; 11905 uint32_t xtalfreq, ref; 11906 unsigned int i; 11907 11908 bwn_phy_lp_b2062_tblinit(mac); 11909 11910 for (i = 0; i < N(v1); i++) 11911 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 11912 if (mac->mac_phy.rev > 0) 11913 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 11914 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 11915 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11916 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 11917 else 11918 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 11919 11920 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 11921 ("%s:%d: fail", __func__, __LINE__)); 11922 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11923 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 11924 11925 if (xtalfreq <= 30000000) { 11926 plp->plp_div = 1; 11927 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 11928 } else { 11929 plp->plp_div = 2; 11930 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 11931 } 11932 11933 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 11934 CALC_CTL7(xtalfreq, plp->plp_div)); 11935 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 11936 CALC_CTL18(xtalfreq, plp->plp_div)); 11937 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 11938 CALC_CTL19(xtalfreq, plp->plp_div)); 11939 11940 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 11941 ref &= 0xffff; 11942 for (i = 0; i < N(freqdata_tab); i++) { 11943 if (ref < freqdata_tab[i].freq) { 11944 f = &freqdata_tab[i]; 11945 break; 11946 } 11947 } 11948 if (f == NULL) 11949 f = &freqdata_tab[N(freqdata_tab) - 1]; 11950 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 11951 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 11952 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 11953 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 11954 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 11955 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 11956 #undef CALC_CTL7 11957 #undef CALC_CTL18 11958 #undef CALC_CTL19 11959 } 11960 11961 static void 11962 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 11963 { 11964 11965 bwn_phy_lp_b2063_tblinit(mac); 11966 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 11967 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 11968 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 11969 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 11970 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 11971 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 11972 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 11973 if (mac->mac_phy.rev == 2) { 11974 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 11975 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 11976 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 11977 } else { 11978 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 11979 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 11980 } 11981 } 11982 11983 static void 11984 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 11985 { 11986 struct bwn_softc *sc = mac->mac_sc; 11987 static const struct bwn_wpair v1[] = { 11988 { BWN_B2063_RX_BB_SP8, 0x0 }, 11989 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 11990 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 11991 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 11992 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 11993 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 11994 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 11995 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 11996 }; 11997 static const struct bwn_wpair v2[] = { 11998 { BWN_B2063_TX_BB_SP3, 0x0 }, 11999 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12000 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12001 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12002 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12003 }; 12004 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12005 int i; 12006 uint8_t tmp; 12007 12008 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12009 12010 for (i = 0; i < 2; i++) 12011 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12012 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12013 for (i = 2; i < N(v1); i++) 12014 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12015 for (i = 0; i < 10000; i++) { 12016 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12017 break; 12018 DELAY(1000); 12019 } 12020 12021 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12022 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12023 12024 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12025 12026 for (i = 0; i < N(v2); i++) 12027 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12028 if (freqxtal == 24000000) { 12029 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12030 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12031 } else { 12032 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12033 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12034 } 12035 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12036 for (i = 0; i < 10000; i++) { 12037 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12038 break; 12039 DELAY(1000); 12040 } 12041 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12042 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12043 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12044 } 12045 12046 static void 12047 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12048 { 12049 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12050 struct bwn_softc *sc = mac->mac_sc; 12051 struct bwn_phy_lp_iq_est ie; 12052 struct bwn_txgain tx_gains; 12053 static const uint32_t pwrtbl[21] = { 12054 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12055 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12056 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12057 0x0004c, 0x0002c, 0x0001a, 12058 }; 12059 uint32_t npwr, ipwr, sqpwr, tmp; 12060 int loopback, i, j, sum, error; 12061 uint16_t save[7]; 12062 uint8_t txo, bbmult, txpctlmode; 12063 12064 error = bwn_phy_lp_switch_channel(mac, 7); 12065 if (error) 12066 device_printf(sc->sc_dev, 12067 "failed to change channel to 7 (%d)\n", error); 12068 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12069 bbmult = bwn_phy_lp_get_bbmult(mac); 12070 if (txo) 12071 tx_gains = bwn_phy_lp_get_txgain(mac); 12072 12073 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12074 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12075 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12076 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12077 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12078 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12079 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12080 12081 bwn_phy_lp_get_txpctlmode(mac); 12082 txpctlmode = plp->plp_txpctlmode; 12083 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12084 12085 /* disable CRS */ 12086 bwn_phy_lp_set_deaf(mac, 1); 12087 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12088 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12089 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12090 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12091 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12092 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12093 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12094 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12095 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12096 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12097 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12098 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12099 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12100 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12101 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12102 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12103 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12104 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12105 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12106 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12107 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12108 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12109 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12110 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12111 12112 loopback = bwn_phy_lp_loopback(mac); 12113 if (loopback == -1) 12114 goto done; 12115 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12116 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12117 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12118 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12119 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12120 12121 tmp = 0; 12122 memset(&ie, 0, sizeof(ie)); 12123 for (i = 128; i <= 159; i++) { 12124 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12125 sum = 0; 12126 for (j = 5; j <= 25; j++) { 12127 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12128 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12129 goto done; 12130 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12131 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12132 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12133 12); 12134 sum += ((ipwr - npwr) * (ipwr - npwr)); 12135 if ((i == 128) || (sum < tmp)) { 12136 plp->plp_rccap = i; 12137 tmp = sum; 12138 } 12139 } 12140 } 12141 bwn_phy_lp_ddfs_turnoff(mac); 12142 done: 12143 /* restore CRS */ 12144 bwn_phy_lp_clear_deaf(mac, 1); 12145 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12146 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12147 12148 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12149 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12150 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12151 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12152 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12153 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12154 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12155 12156 bwn_phy_lp_set_bbmult(mac, bbmult); 12157 if (txo) 12158 bwn_phy_lp_set_txgain(mac, &tx_gains); 12159 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12160 if (plp->plp_rccap) 12161 bwn_phy_lp_set_rccap(mac); 12162 } 12163 12164 static void 12165 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12166 { 12167 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12168 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12169 12170 if (mac->mac_phy.rev == 1) 12171 rc_cap = MIN(rc_cap + 5, 15); 12172 12173 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12174 MAX(plp->plp_rccap - 4, 0x80)); 12175 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12176 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12177 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12178 } 12179 12180 static uint32_t 12181 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12182 { 12183 uint32_t i, q, r; 12184 12185 if (div == 0) 12186 return (0); 12187 12188 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12189 q <<= 1; 12190 if (r << 1 >= div) { 12191 q++; 12192 r = (r << 1) - div; 12193 } 12194 } 12195 if (r << 1 >= div) 12196 q++; 12197 return (q); 12198 } 12199 12200 static void 12201 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12202 { 12203 struct bwn_softc *sc = mac->mac_sc; 12204 12205 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12206 DELAY(20); 12207 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12208 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12209 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12210 } else { 12211 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12212 } 12213 DELAY(5); 12214 } 12215 12216 static void 12217 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12218 { 12219 12220 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12221 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12222 DELAY(200); 12223 } 12224 12225 static void 12226 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12227 { 12228 #define FLAG_A 0x01 12229 #define FLAG_G 0x02 12230 struct bwn_softc *sc = mac->mac_sc; 12231 struct ieee80211com *ic = &sc->sc_ic; 12232 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12233 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12234 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12235 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12236 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12237 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12238 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12239 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12240 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12241 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12242 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12243 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12244 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12245 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12246 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12247 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12248 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12249 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12250 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12251 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12252 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12253 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12254 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12255 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12256 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12257 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12258 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12259 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12260 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12261 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12262 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12263 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12264 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12265 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12266 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12267 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12268 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12269 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12270 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12271 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12272 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12273 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12274 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12275 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12276 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12277 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12278 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12279 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12280 }; 12281 const struct bwn_b206x_rfinit_entry *br; 12282 unsigned int i; 12283 12284 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12285 br = &bwn_b2062_init_tab[i]; 12286 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12287 if (br->br_flags & FLAG_G) 12288 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12289 } else { 12290 if (br->br_flags & FLAG_A) 12291 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12292 } 12293 } 12294 #undef FLAG_A 12295 #undef FLAG_B 12296 } 12297 12298 static void 12299 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12300 { 12301 #define FLAG_A 0x01 12302 #define FLAG_G 0x02 12303 struct bwn_softc *sc = mac->mac_sc; 12304 struct ieee80211com *ic = &sc->sc_ic; 12305 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12306 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12307 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12308 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12309 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12310 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12311 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12312 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12313 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12314 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12315 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12316 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12317 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12318 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12319 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12320 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12321 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12322 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12323 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12324 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12325 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12326 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12327 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12328 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12329 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12330 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12331 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12332 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12333 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12334 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12335 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12336 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12337 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12338 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12339 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12340 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12341 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12342 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12343 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12344 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12345 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12346 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12347 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12348 }; 12349 const struct bwn_b206x_rfinit_entry *br; 12350 unsigned int i; 12351 12352 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12353 br = &bwn_b2063_init_tab[i]; 12354 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12355 if (br->br_flags & FLAG_G) 12356 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12357 } else { 12358 if (br->br_flags & FLAG_A) 12359 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12360 } 12361 } 12362 #undef FLAG_A 12363 #undef FLAG_B 12364 } 12365 12366 static void 12367 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12368 int count, void *_data) 12369 { 12370 unsigned int i; 12371 uint32_t offset, type; 12372 uint8_t *data = _data; 12373 12374 type = BWN_TAB_GETTYPE(typenoffset); 12375 offset = BWN_TAB_GETOFFSET(typenoffset); 12376 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12377 12378 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12379 12380 for (i = 0; i < count; i++) { 12381 switch (type) { 12382 case BWN_TAB_8BIT: 12383 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12384 data++; 12385 break; 12386 case BWN_TAB_16BIT: 12387 *((uint16_t *)data) = BWN_PHY_READ(mac, 12388 BWN_PHY_TABLEDATALO); 12389 data += 2; 12390 break; 12391 case BWN_TAB_32BIT: 12392 *((uint32_t *)data) = BWN_PHY_READ(mac, 12393 BWN_PHY_TABLEDATAHI); 12394 *((uint32_t *)data) <<= 16; 12395 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12396 BWN_PHY_TABLEDATALO); 12397 data += 4; 12398 break; 12399 default: 12400 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12401 } 12402 } 12403 } 12404 12405 static void 12406 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12407 int count, const void *_data) 12408 { 12409 uint32_t offset, type, value; 12410 const uint8_t *data = _data; 12411 unsigned int i; 12412 12413 type = BWN_TAB_GETTYPE(typenoffset); 12414 offset = BWN_TAB_GETOFFSET(typenoffset); 12415 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12416 12417 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12418 12419 for (i = 0; i < count; i++) { 12420 switch (type) { 12421 case BWN_TAB_8BIT: 12422 value = *data; 12423 data++; 12424 KASSERT(!(value & ~0xff), 12425 ("%s:%d: fail", __func__, __LINE__)); 12426 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12427 break; 12428 case BWN_TAB_16BIT: 12429 value = *((const uint16_t *)data); 12430 data += 2; 12431 KASSERT(!(value & ~0xffff), 12432 ("%s:%d: fail", __func__, __LINE__)); 12433 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12434 break; 12435 case BWN_TAB_32BIT: 12436 value = *((const uint32_t *)data); 12437 data += 4; 12438 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12439 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12440 break; 12441 default: 12442 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12443 } 12444 } 12445 } 12446 12447 static struct bwn_txgain 12448 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12449 { 12450 struct bwn_txgain tg; 12451 uint16_t tmp; 12452 12453 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12454 if (mac->mac_phy.rev < 2) { 12455 tmp = BWN_PHY_READ(mac, 12456 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12457 tg.tg_gm = tmp & 0x0007; 12458 tg.tg_pga = (tmp & 0x0078) >> 3; 12459 tg.tg_pad = (tmp & 0x780) >> 7; 12460 return (tg); 12461 } 12462 12463 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12464 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12465 tg.tg_gm = tmp & 0xff; 12466 tg.tg_pga = (tmp >> 8) & 0xff; 12467 return (tg); 12468 } 12469 12470 static uint8_t 12471 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12472 { 12473 12474 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12475 } 12476 12477 static void 12478 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12479 { 12480 uint16_t pa; 12481 12482 if (mac->mac_phy.rev < 2) { 12483 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12484 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12485 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12486 bwn_phy_lp_set_txgain_override(mac); 12487 return; 12488 } 12489 12490 pa = bwn_phy_lp_get_pa_gain(mac); 12491 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12492 (tg->tg_pga << 8) | tg->tg_gm); 12493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12494 tg->tg_pad | (pa << 6)); 12495 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12496 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12497 tg->tg_pad | (pa << 8)); 12498 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12499 bwn_phy_lp_set_txgain_override(mac); 12500 } 12501 12502 static void 12503 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12504 { 12505 12506 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12507 } 12508 12509 static void 12510 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12511 { 12512 uint16_t trsw = (tx << 1) | rx; 12513 12514 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12515 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12516 } 12517 12518 static void 12519 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12520 { 12521 struct bwn_softc *sc = mac->mac_sc; 12522 struct ieee80211com *ic = &sc->sc_ic; 12523 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12524 12525 if (mac->mac_phy.rev < 2) { 12526 trsw = gain & 0x1; 12527 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12528 ext_lna = (gain & 2) >> 1; 12529 12530 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12531 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12532 0xfbff, ext_lna << 10); 12533 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12534 0xf7ff, ext_lna << 11); 12535 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12536 } else { 12537 low_gain = gain & 0xffff; 12538 high_gain = (gain >> 16) & 0xf; 12539 ext_lna = (gain >> 21) & 0x1; 12540 trsw = ~(gain >> 20) & 0x1; 12541 12542 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12543 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12544 0xfdff, ext_lna << 9); 12545 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12546 0xfbff, ext_lna << 10); 12547 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12548 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12549 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12550 tmp = (gain >> 2) & 0x3; 12551 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12552 0xe7ff, tmp<<11); 12553 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12554 tmp << 3); 12555 } 12556 } 12557 12558 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12559 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12560 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12561 if (mac->mac_phy.rev >= 2) { 12562 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12563 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12564 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12565 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12566 } 12567 return; 12568 } 12569 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12570 } 12571 12572 static void 12573 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12574 { 12575 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12576 12577 if (user) 12578 plp->plp_crsusr_off = 1; 12579 else 12580 plp->plp_crssys_off = 1; 12581 12582 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12583 } 12584 12585 static void 12586 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12587 { 12588 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12589 struct bwn_softc *sc = mac->mac_sc; 12590 struct ieee80211com *ic = &sc->sc_ic; 12591 12592 if (user) 12593 plp->plp_crsusr_off = 0; 12594 else 12595 plp->plp_crssys_off = 0; 12596 12597 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12598 return; 12599 12600 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12601 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12602 else 12603 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12604 } 12605 12606 static unsigned int 12607 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12608 { 12609 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12610 static uint8_t sqrt_table[256] = { 12611 10, 14, 17, 20, 22, 24, 26, 28, 12612 30, 31, 33, 34, 36, 37, 38, 40, 12613 41, 42, 43, 44, 45, 46, 47, 48, 12614 50, 50, 51, 52, 53, 54, 55, 56, 12615 57, 58, 59, 60, 60, 61, 62, 63, 12616 64, 64, 65, 66, 67, 67, 68, 69, 12617 70, 70, 71, 72, 72, 73, 74, 74, 12618 75, 76, 76, 77, 78, 78, 79, 80, 12619 80, 81, 81, 82, 83, 83, 84, 84, 12620 85, 86, 86, 87, 87, 88, 88, 89, 12621 90, 90, 91, 91, 92, 92, 93, 93, 12622 94, 94, 95, 95, 96, 96, 97, 97, 12623 98, 98, 99, 100, 100, 100, 101, 101, 12624 102, 102, 103, 103, 104, 104, 105, 105, 12625 106, 106, 107, 107, 108, 108, 109, 109, 12626 110, 110, 110, 111, 111, 112, 112, 113, 12627 113, 114, 114, 114, 115, 115, 116, 116, 12628 117, 117, 117, 118, 118, 119, 119, 120, 12629 120, 120, 121, 121, 122, 122, 122, 123, 12630 123, 124, 124, 124, 125, 125, 126, 126, 12631 126, 127, 127, 128, 128, 128, 129, 129, 12632 130, 130, 130, 131, 131, 131, 132, 132, 12633 133, 133, 133, 134, 134, 134, 135, 135, 12634 136, 136, 136, 137, 137, 137, 138, 138, 12635 138, 139, 139, 140, 140, 140, 141, 141, 12636 141, 142, 142, 142, 143, 143, 143, 144, 12637 144, 144, 145, 145, 145, 146, 146, 146, 12638 147, 147, 147, 148, 148, 148, 149, 149, 12639 150, 150, 150, 150, 151, 151, 151, 152, 12640 152, 152, 153, 153, 153, 154, 154, 154, 12641 155, 155, 155, 156, 156, 156, 157, 157, 12642 157, 158, 158, 158, 159, 159, 159, 160 12643 }; 12644 12645 if (x == 0) 12646 return (0); 12647 if (x >= 256) { 12648 unsigned int tmp; 12649 12650 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12651 /* do nothing */ ; 12652 return (tmp); 12653 } 12654 return (sqrt_table[x - 1] / 10); 12655 } 12656 12657 static int 12658 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12659 { 12660 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12661 int _t; \ 12662 _t = _x - 20; \ 12663 if (_t >= 0) { \ 12664 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12665 } else { \ 12666 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12667 } \ 12668 } while (0) 12669 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12670 int _t; \ 12671 _t = _x - 11; \ 12672 if (_t >= 0) \ 12673 _v = (_y << (31 - _x)) / (_z >> _t); \ 12674 else \ 12675 _v = (_y << (31 - _x)) / (_z << -_t); \ 12676 } while (0) 12677 struct bwn_phy_lp_iq_est ie; 12678 uint16_t v0, v1; 12679 int tmp[2], ret; 12680 12681 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12682 v0 = v1 >> 8; 12683 v1 |= 0xff; 12684 12685 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12686 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12687 12688 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12689 if (ret == 0) 12690 goto done; 12691 12692 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12693 ret = 0; 12694 goto done; 12695 } 12696 12697 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12698 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12699 12700 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12701 v0 = tmp[0] >> 3; 12702 v1 = tmp[1] >> 4; 12703 done: 12704 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12705 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12706 return ret; 12707 #undef CALC_COEFF 12708 #undef CALC_COEFF2 12709 } 12710 12711 static void 12712 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12713 { 12714 static const uint16_t noisescale[] = { 12715 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12716 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12717 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12718 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12719 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12720 }; 12721 static const uint16_t crsgainnft[] = { 12722 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12723 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12724 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12725 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12726 0x013d, 12727 }; 12728 static const uint16_t filterctl[] = { 12729 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12730 0xff53, 0x0127, 12731 }; 12732 static const uint32_t psctl[] = { 12733 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12734 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12735 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12736 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12737 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12738 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12739 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12740 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12741 }; 12742 static const uint16_t ofdmcckgain_r0[] = { 12743 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12744 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12745 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12746 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12747 0x755d, 12748 }; 12749 static const uint16_t ofdmcckgain_r1[] = { 12750 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12751 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12752 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12753 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12754 0x755d, 12755 }; 12756 static const uint16_t gaindelta[] = { 12757 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12758 0x0000, 12759 }; 12760 static const uint32_t txpwrctl[] = { 12761 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12762 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12763 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12764 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12765 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12766 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12767 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12768 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12769 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12770 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12771 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12772 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12773 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000, 12797 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12798 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12799 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12800 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12801 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12802 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12803 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12804 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12805 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12806 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12807 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12808 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12809 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12810 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12811 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12812 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12813 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12814 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12815 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12816 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12817 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12818 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12819 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12820 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12821 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12822 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12823 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12824 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12825 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12826 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12827 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12828 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12829 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12830 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12831 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12832 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12833 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12834 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12835 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12836 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12837 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12838 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12839 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12840 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12841 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12842 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12843 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12844 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12845 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12846 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12847 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12848 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12849 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12850 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 12851 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12852 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12853 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 12854 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 12855 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 12856 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 12857 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 12858 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 12859 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 12860 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 12861 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 12862 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 12863 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 12864 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 12865 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 12866 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 12867 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 12868 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 12869 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 12870 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 12871 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 12872 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 12873 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 12874 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 12875 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 12876 0x00000702, 12877 }; 12878 12879 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 12880 12881 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 12882 bwn_tab_sigsq_tbl); 12883 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 12884 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 12885 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 12886 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 12887 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 12888 bwn_tab_pllfrac_tbl); 12889 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 12890 bwn_tabl_iqlocal_tbl); 12891 if (mac->mac_phy.rev == 0) { 12892 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 12893 ofdmcckgain_r0); 12894 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 12895 ofdmcckgain_r0); 12896 } else { 12897 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 12898 ofdmcckgain_r1); 12899 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 12900 ofdmcckgain_r1); 12901 } 12902 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 12903 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 12904 } 12905 12906 static void 12907 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 12908 { 12909 struct bwn_softc *sc = mac->mac_sc; 12910 int i; 12911 static const uint16_t noisescale[] = { 12912 0x00a4, 0x00a4, 0x00a4, 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, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12916 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12917 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12918 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 12919 }; 12920 static const uint32_t filterctl[] = { 12921 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 12922 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 12923 }; 12924 static const uint32_t psctl[] = { 12925 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 12926 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 12927 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 12928 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 12929 }; 12930 static const uint32_t gainidx[] = { 12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12934 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 12935 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 12936 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 12937 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 12938 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 12939 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 12940 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 12941 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 12942 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 12943 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 12944 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 12945 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12947 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12948 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12949 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 12950 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 12951 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 12952 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 12953 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 12954 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 12955 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 12956 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 12957 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 12958 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 12959 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 12960 0x0000001a, 0x64ca55ad, 0x0000001a 12961 }; 12962 static const uint16_t auxgainidx[] = { 12963 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12964 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 12965 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 12966 0x0004, 0x0016 12967 }; 12968 static const uint16_t swctl[] = { 12969 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12970 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12971 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 12972 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 12973 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12974 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12975 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 12976 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 12977 }; 12978 static const uint8_t hf[] = { 12979 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 12980 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 12981 }; 12982 static const uint32_t gainval[] = { 12983 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 12984 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 12985 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 12986 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 12987 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 12988 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 12989 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12990 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12991 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 12992 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 12993 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 12994 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 12995 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 12996 0x000000f1, 0x00000000, 0x00000000 12997 }; 12998 static const uint16_t gain[] = { 12999 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13000 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13001 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13002 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13003 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13004 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 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 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13009 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13010 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13011 }; 13012 static const uint32_t papdeps[] = { 13013 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13014 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13015 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13016 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13017 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13018 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13019 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13020 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13021 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13022 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13023 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13024 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13025 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13026 }; 13027 static const uint32_t papdmult[] = { 13028 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13029 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13030 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13031 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13032 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13033 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13034 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13035 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13036 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13037 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13038 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13039 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13040 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13041 }; 13042 static const uint32_t gainidx_a0[] = { 13043 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13044 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13045 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13046 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13047 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13048 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13049 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13050 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13051 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13052 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13053 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13054 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13055 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13056 }; 13057 static const uint16_t auxgainidx_a0[] = { 13058 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13059 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13060 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13061 0x0002, 0x0014 13062 }; 13063 static const uint32_t gainval_a0[] = { 13064 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13065 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13066 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13067 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13068 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13069 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13070 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13071 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13072 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13073 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13074 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13075 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13076 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13077 0x000000f7, 0x00000000, 0x00000000 13078 }; 13079 static const uint16_t gain_a0[] = { 13080 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13081 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13082 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13083 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13084 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13085 0x035f, 0x075f, 0x0b5f, 0x0f5f, 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 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13090 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13091 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13092 }; 13093 13094 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13095 13096 for (i = 0; i < 704; i++) 13097 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13098 13099 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13100 bwn_tab_sigsq_tbl); 13101 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13102 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13103 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13104 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13105 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13106 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13107 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13108 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13109 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13110 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13111 bwn_tab_pllfrac_tbl); 13112 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13113 bwn_tabl_iqlocal_tbl); 13114 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13115 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13116 13117 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13118 (siba_get_chiprev(sc->sc_dev) == 0)) { 13119 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13120 gainidx_a0); 13121 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13122 auxgainidx_a0); 13123 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13124 gainval_a0); 13125 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13126 } 13127 } 13128 13129 static void 13130 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13131 { 13132 struct bwn_softc *sc = mac->mac_sc; 13133 struct ieee80211com *ic = &sc->sc_ic; 13134 static struct bwn_txgain_entry txgain_r2[] = { 13135 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13136 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13137 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13138 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13139 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13140 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13141 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13142 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13143 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13144 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13145 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13146 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13147 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13148 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13149 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13150 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13151 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13152 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13153 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13154 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13155 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13156 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13157 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13158 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13159 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13160 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13161 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13162 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13163 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13164 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13165 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13166 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13167 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13168 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13169 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13170 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13171 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13172 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13173 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13174 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13175 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13176 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13177 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13178 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13179 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13180 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13181 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13182 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13183 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13184 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13185 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13186 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13187 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13188 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13189 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13190 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13191 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13192 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13193 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13194 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13195 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13196 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13197 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13198 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13199 }; 13200 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13201 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13202 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13203 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13204 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13205 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13206 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13207 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13208 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13209 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13210 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13211 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13212 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13213 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13214 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13215 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13216 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13217 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13218 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13219 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13220 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13221 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13222 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13223 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13224 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13225 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13226 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13227 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13228 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13229 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13230 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13231 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13232 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13233 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13234 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13235 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13236 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13237 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13238 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13239 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13240 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13241 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13242 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13243 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13244 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13245 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13246 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13247 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13248 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13249 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13250 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13251 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13252 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13253 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13254 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13255 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13256 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13257 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13258 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13259 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13260 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13261 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13262 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13263 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13264 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13265 }; 13266 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13267 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13268 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13269 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13270 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13271 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13272 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13273 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13274 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13275 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13276 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13277 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13278 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13279 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13280 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13281 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13282 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13283 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13284 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13285 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13286 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13287 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13288 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13289 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13290 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13291 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13292 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13293 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13294 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13295 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13296 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13297 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13298 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13299 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13300 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13301 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13302 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13303 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13304 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13305 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13306 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13307 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13308 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13309 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13310 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13311 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13312 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13313 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13314 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13315 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13316 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13317 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13318 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13319 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13320 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13321 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13322 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13323 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13324 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13325 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13326 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13327 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13328 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13329 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13330 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13331 }; 13332 static struct bwn_txgain_entry txgain_r0[] = { 13333 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13334 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13335 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13336 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13337 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13338 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13339 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13340 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13341 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13342 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13343 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13344 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13345 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13346 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13347 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13348 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13349 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13350 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13351 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13352 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13353 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13354 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13355 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13356 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13357 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13358 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13359 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13360 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13361 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13362 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13363 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13364 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13365 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13366 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13367 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13368 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13369 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13370 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13371 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13372 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13373 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13374 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13375 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13376 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13377 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13378 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13379 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13380 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13381 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13382 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13383 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13384 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13385 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13386 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13387 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13388 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13389 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13390 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13391 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13392 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13393 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13394 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13395 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13396 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13397 }; 13398 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13399 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13400 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13401 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13402 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13403 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13404 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13405 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13406 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13407 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13408 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13409 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13410 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13411 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13412 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13413 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13414 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13415 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13416 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13417 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13418 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13419 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13420 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13421 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13422 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13423 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13424 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13425 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13426 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13427 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13428 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13429 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13430 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13431 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13432 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13433 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13434 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13435 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13436 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13437 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13438 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13439 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13440 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13441 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13442 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13443 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13444 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13445 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13446 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13447 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13448 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13449 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13450 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13451 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13452 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13453 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13454 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13455 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13456 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13457 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13458 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13459 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13460 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13461 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13462 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13463 }; 13464 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13465 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13466 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13467 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13468 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13469 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13470 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13471 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13472 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13473 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13474 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13475 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13476 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13477 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13478 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13479 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13480 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13481 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13482 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13483 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13484 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13485 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13486 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13487 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13488 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13489 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13490 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13491 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13492 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13493 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13494 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13495 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13496 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13497 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13498 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13499 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13500 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13501 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13502 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13503 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13504 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13505 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13506 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13507 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13508 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13509 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13510 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13511 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13512 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13513 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13514 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13515 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13516 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13517 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13518 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13519 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13520 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13521 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13522 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13523 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13524 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13525 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13526 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13527 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13528 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13529 }; 13530 static struct bwn_txgain_entry txgain_r1[] = { 13531 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13532 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13533 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13534 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13535 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13536 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13537 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13538 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13539 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13540 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13541 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13542 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13543 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13544 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13545 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13546 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13547 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13548 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13549 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13550 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13551 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13552 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13553 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13554 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13555 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13556 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13557 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13558 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13559 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13560 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13561 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13562 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13563 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13564 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13565 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13566 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13567 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13568 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13569 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13570 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13571 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13572 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13573 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13574 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13575 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13576 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13577 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13578 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13579 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13580 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13581 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13582 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13583 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13584 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13585 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13586 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13587 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13588 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13589 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13590 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13591 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13592 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13593 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13594 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13595 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13596 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13597 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13598 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13599 { 7, 11, 6, 0, 71 } 13600 }; 13601 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13602 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13603 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13604 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13605 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13606 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13607 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13608 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13609 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13610 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13611 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13612 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13613 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13614 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13615 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13616 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13617 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13618 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13619 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13620 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13621 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13622 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13623 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13624 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13625 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13626 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13627 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13628 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13629 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13630 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13631 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13632 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13633 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13634 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13635 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13636 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13637 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13638 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13639 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13640 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13641 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13642 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13643 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13644 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13645 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13646 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13647 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13648 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13649 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13650 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13651 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13652 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13653 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13654 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13655 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13656 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13657 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13658 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13659 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13660 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13661 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13662 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13663 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13664 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13665 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13666 }; 13667 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13668 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13669 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13670 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13671 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13672 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13673 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13674 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13675 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13676 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13677 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13678 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13679 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13680 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13681 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13682 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13683 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13684 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13685 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13686 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13687 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13688 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13689 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13690 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13691 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13692 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13693 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13694 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13695 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13696 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13697 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13698 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13699 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13700 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13701 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13702 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13703 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13704 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13705 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13706 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13707 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13708 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13709 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13710 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13711 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13712 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13713 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13714 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13715 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13716 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13717 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13718 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13719 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13720 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13721 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13722 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13723 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13724 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13725 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13726 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13727 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13728 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13729 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13730 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13731 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13732 }; 13733 13734 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13735 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13736 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13737 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13738 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13739 txgain_2ghz_r2); 13740 else 13741 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13742 txgain_5ghz_r2); 13743 return; 13744 } 13745 13746 if (mac->mac_phy.rev == 0) { 13747 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13748 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13749 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13750 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13751 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13752 txgain_2ghz_r0); 13753 else 13754 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13755 txgain_5ghz_r0); 13756 return; 13757 } 13758 13759 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13760 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13761 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13762 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13763 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13764 else 13765 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13766 } 13767 13768 static void 13769 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13770 { 13771 uint32_t offset, type; 13772 13773 type = BWN_TAB_GETTYPE(typeoffset); 13774 offset = BWN_TAB_GETOFFSET(typeoffset); 13775 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13776 13777 switch (type) { 13778 case BWN_TAB_8BIT: 13779 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13780 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13781 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13782 break; 13783 case BWN_TAB_16BIT: 13784 KASSERT(!(value & ~0xffff), 13785 ("%s:%d: fail", __func__, __LINE__)); 13786 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13787 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13788 break; 13789 case BWN_TAB_32BIT: 13790 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13791 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13792 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13793 break; 13794 default: 13795 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13796 } 13797 } 13798 13799 static int 13800 bwn_phy_lp_loopback(struct bwn_mac *mac) 13801 { 13802 struct bwn_phy_lp_iq_est ie; 13803 int i, index = -1; 13804 uint32_t tmp; 13805 13806 memset(&ie, 0, sizeof(ie)); 13807 13808 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13809 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13810 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13811 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13812 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13813 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13814 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13815 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13816 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13817 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13818 for (i = 0; i < 32; i++) { 13819 bwn_phy_lp_set_rxgain_idx(mac, i); 13820 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13821 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13822 continue; 13823 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13824 if ((tmp > 4000) && (tmp < 10000)) { 13825 index = i; 13826 break; 13827 } 13828 } 13829 bwn_phy_lp_ddfs_turnoff(mac); 13830 return (index); 13831 } 13832 13833 static void 13834 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13835 { 13836 13837 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13838 } 13839 13840 static void 13841 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13842 int incr1, int incr2, int scale_idx) 13843 { 13844 13845 bwn_phy_lp_ddfs_turnoff(mac); 13846 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13847 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13848 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13849 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13850 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13851 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13852 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 13853 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 13854 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 13855 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 13856 } 13857 13858 static uint8_t 13859 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 13860 struct bwn_phy_lp_iq_est *ie) 13861 { 13862 int i; 13863 13864 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 13865 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 13866 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 13867 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 13868 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 13869 13870 for (i = 0; i < 500; i++) { 13871 if (!(BWN_PHY_READ(mac, 13872 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 13873 break; 13874 DELAY(1000); 13875 } 13876 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 13877 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13878 return 0; 13879 } 13880 13881 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 13882 ie->ie_iqprod <<= 16; 13883 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 13884 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 13885 ie->ie_ipwr <<= 16; 13886 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 13887 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 13888 ie->ie_qpwr <<= 16; 13889 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 13890 13891 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13892 return 1; 13893 } 13894 13895 static uint32_t 13896 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 13897 { 13898 uint32_t offset, type, value; 13899 13900 type = BWN_TAB_GETTYPE(typeoffset); 13901 offset = BWN_TAB_GETOFFSET(typeoffset); 13902 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13903 13904 switch (type) { 13905 case BWN_TAB_8BIT: 13906 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13907 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 13908 break; 13909 case BWN_TAB_16BIT: 13910 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13911 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13912 break; 13913 case BWN_TAB_32BIT: 13914 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13915 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 13916 value <<= 16; 13917 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13918 break; 13919 default: 13920 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13921 value = 0; 13922 } 13923 13924 return (value); 13925 } 13926 13927 static void 13928 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 13929 { 13930 13931 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 13932 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 13933 } 13934 13935 static void 13936 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 13937 { 13938 uint16_t ctl; 13939 13940 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 13941 ctl |= dac << 7; 13942 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 13943 } 13944 13945 static void 13946 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 13947 { 13948 13949 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 13950 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 13951 } 13952 13953 static void 13954 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 13955 { 13956 13957 if (mac->mac_phy.rev < 2) 13958 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 13959 else { 13960 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 13961 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 13962 } 13963 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 13964 } 13965 13966 static uint16_t 13967 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 13968 { 13969 13970 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 13971 } 13972 13973 static uint8_t 13974 bwn_nbits(int32_t val) 13975 { 13976 uint32_t tmp; 13977 uint8_t nbits = 0; 13978 13979 for (tmp = abs(val); tmp != 0; tmp >>= 1) 13980 nbits++; 13981 return (nbits); 13982 } 13983 13984 static void 13985 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 13986 struct bwn_txgain_entry *table) 13987 { 13988 int i; 13989 13990 for (i = offset; i < count; i++) 13991 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 13992 } 13993 13994 static void 13995 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 13996 struct bwn_txgain_entry data) 13997 { 13998 13999 if (mac->mac_phy.rev >= 2) 14000 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14001 else 14002 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14003 } 14004 14005 static void 14006 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14007 struct bwn_txgain_entry te) 14008 { 14009 struct bwn_softc *sc = mac->mac_sc; 14010 struct ieee80211com *ic = &sc->sc_ic; 14011 uint32_t tmp; 14012 14013 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14014 14015 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14016 if (mac->mac_phy.rev >= 3) { 14017 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14018 (0x10 << 24) : (0x70 << 24)); 14019 } else { 14020 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14021 (0x14 << 24) : (0x7f << 24)); 14022 } 14023 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14024 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14025 te.te_bbmult << 20 | te.te_dac << 28); 14026 } 14027 14028 static void 14029 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14030 struct bwn_txgain_entry te) 14031 { 14032 14033 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14034 14035 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14036 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14037 te.te_dac); 14038 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14039 } 14040 14041 static void 14042 bwn_sysctl_node(struct bwn_softc *sc) 14043 { 14044 device_t dev = sc->sc_dev; 14045 struct bwn_mac *mac; 14046 struct bwn_stats *stats; 14047 14048 /* XXX assume that count of MAC is only 1. */ 14049 14050 if ((mac = sc->sc_curmac) == NULL) 14051 return; 14052 stats = &mac->mac_stats; 14053 14054 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14055 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14056 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14057 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14058 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14059 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14060 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14061 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14062 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14063 14064 #ifdef BWN_DEBUG 14065 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14066 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14067 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14068 #endif 14069 } 14070 14071 static device_method_t bwn_methods[] = { 14072 /* Device interface */ 14073 DEVMETHOD(device_probe, bwn_probe), 14074 DEVMETHOD(device_attach, bwn_attach), 14075 DEVMETHOD(device_detach, bwn_detach), 14076 DEVMETHOD(device_suspend, bwn_suspend), 14077 DEVMETHOD(device_resume, bwn_resume), 14078 DEVMETHOD_END 14079 }; 14080 static driver_t bwn_driver = { 14081 "bwn", 14082 bwn_methods, 14083 sizeof(struct bwn_softc) 14084 }; 14085 static devclass_t bwn_devclass; 14086 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14087 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14088 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14089 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14090 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14091