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 int error; 2688 2689 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || 2690 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2691 m_freem(m); 2692 return (ENETDOWN); 2693 } 2694 2695 BWN_LOCK(sc); 2696 if (bwn_tx_isfull(sc, m)) { 2697 m_freem(m); 2698 BWN_UNLOCK(sc); 2699 return (ENOBUFS); 2700 } 2701 2702 error = bwn_tx_start(sc, ni, m); 2703 if (error == 0) 2704 sc->sc_watchdog_timer = 5; 2705 BWN_UNLOCK(sc); 2706 return (error); 2707 } 2708 2709 /* 2710 * Callback from the 802.11 layer to update the slot time 2711 * based on the current setting. We use it to notify the 2712 * firmware of ERP changes and the f/w takes care of things 2713 * like slot time and preamble. 2714 */ 2715 static void 2716 bwn_updateslot(struct ieee80211com *ic) 2717 { 2718 struct bwn_softc *sc = ic->ic_softc; 2719 struct bwn_mac *mac; 2720 2721 BWN_LOCK(sc); 2722 if (sc->sc_flags & BWN_FLAG_RUNNING) { 2723 mac = (struct bwn_mac *)sc->sc_curmac; 2724 bwn_set_slot_time(mac, IEEE80211_GET_SLOTTIME(ic)); 2725 } 2726 BWN_UNLOCK(sc); 2727 } 2728 2729 /* 2730 * Callback from the 802.11 layer after a promiscuous mode change. 2731 * Note this interface does not check the operating mode as this 2732 * is an internal callback and we are expected to honor the current 2733 * state (e.g. this is used for setting the interface in promiscuous 2734 * mode when operating in hostap mode to do ACS). 2735 */ 2736 static void 2737 bwn_update_promisc(struct ieee80211com *ic) 2738 { 2739 struct bwn_softc *sc = ic->ic_softc; 2740 struct bwn_mac *mac = sc->sc_curmac; 2741 2742 BWN_LOCK(sc); 2743 mac = sc->sc_curmac; 2744 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2745 if (ic->ic_promisc > 0) 2746 sc->sc_filters |= BWN_MACCTL_PROMISC; 2747 else 2748 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2749 bwn_set_opmode(mac); 2750 } 2751 BWN_UNLOCK(sc); 2752 } 2753 2754 /* 2755 * Callback from the 802.11 layer to update WME parameters. 2756 */ 2757 static int 2758 bwn_wme_update(struct ieee80211com *ic) 2759 { 2760 struct bwn_softc *sc = ic->ic_softc; 2761 struct bwn_mac *mac = sc->sc_curmac; 2762 struct wmeParams *wmep; 2763 int i; 2764 2765 BWN_LOCK(sc); 2766 mac = sc->sc_curmac; 2767 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2768 bwn_mac_suspend(mac); 2769 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2770 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2771 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2772 } 2773 bwn_mac_enable(mac); 2774 } 2775 BWN_UNLOCK(sc); 2776 return (0); 2777 } 2778 2779 static void 2780 bwn_scan_start(struct ieee80211com *ic) 2781 { 2782 struct bwn_softc *sc = ic->ic_softc; 2783 struct bwn_mac *mac; 2784 2785 BWN_LOCK(sc); 2786 mac = sc->sc_curmac; 2787 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2788 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2789 bwn_set_opmode(mac); 2790 /* disable CFP update during scan */ 2791 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2792 } 2793 BWN_UNLOCK(sc); 2794 } 2795 2796 static void 2797 bwn_scan_end(struct ieee80211com *ic) 2798 { 2799 struct bwn_softc *sc = ic->ic_softc; 2800 struct bwn_mac *mac; 2801 2802 BWN_LOCK(sc); 2803 mac = sc->sc_curmac; 2804 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2805 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2806 bwn_set_opmode(mac); 2807 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2808 } 2809 BWN_UNLOCK(sc); 2810 } 2811 2812 static void 2813 bwn_set_channel(struct ieee80211com *ic) 2814 { 2815 struct bwn_softc *sc = ic->ic_softc; 2816 struct bwn_mac *mac = sc->sc_curmac; 2817 struct bwn_phy *phy = &mac->mac_phy; 2818 int chan, error; 2819 2820 BWN_LOCK(sc); 2821 2822 error = bwn_switch_band(sc, ic->ic_curchan); 2823 if (error) 2824 goto fail; 2825 bwn_mac_suspend(mac); 2826 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2827 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2828 if (chan != phy->chan) 2829 bwn_switch_channel(mac, chan); 2830 2831 /* TX power level */ 2832 if (ic->ic_curchan->ic_maxpower != 0 && 2833 ic->ic_curchan->ic_maxpower != phy->txpower) { 2834 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2835 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2836 BWN_TXPWR_IGNORE_TSSI); 2837 } 2838 2839 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2840 if (phy->set_antenna) 2841 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2842 2843 if (sc->sc_rf_enabled != phy->rf_on) { 2844 if (sc->sc_rf_enabled) { 2845 bwn_rf_turnon(mac); 2846 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2847 device_printf(sc->sc_dev, 2848 "please turn on the RF switch\n"); 2849 } else 2850 bwn_rf_turnoff(mac); 2851 } 2852 2853 bwn_mac_enable(mac); 2854 2855 fail: 2856 /* 2857 * Setup radio tap channel freq and flags 2858 */ 2859 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2860 htole16(ic->ic_curchan->ic_freq); 2861 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2862 htole16(ic->ic_curchan->ic_flags & 0xffff); 2863 2864 BWN_UNLOCK(sc); 2865 } 2866 2867 static struct ieee80211vap * 2868 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2869 enum ieee80211_opmode opmode, int flags, 2870 const uint8_t bssid[IEEE80211_ADDR_LEN], 2871 const uint8_t mac[IEEE80211_ADDR_LEN]) 2872 { 2873 struct ieee80211vap *vap; 2874 struct bwn_vap *bvp; 2875 2876 switch (opmode) { 2877 case IEEE80211_M_HOSTAP: 2878 case IEEE80211_M_MBSS: 2879 case IEEE80211_M_STA: 2880 case IEEE80211_M_WDS: 2881 case IEEE80211_M_MONITOR: 2882 case IEEE80211_M_IBSS: 2883 case IEEE80211_M_AHDEMO: 2884 break; 2885 default: 2886 return (NULL); 2887 } 2888 2889 bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); 2890 vap = &bvp->bv_vap; 2891 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 2892 /* override with driver methods */ 2893 bvp->bv_newstate = vap->iv_newstate; 2894 vap->iv_newstate = bwn_newstate; 2895 2896 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2897 vap->iv_max_aid = BWN_STAID_MAX; 2898 2899 ieee80211_ratectl_init(vap); 2900 2901 /* complete setup */ 2902 ieee80211_vap_attach(vap, ieee80211_media_change, 2903 ieee80211_media_status, mac); 2904 return (vap); 2905 } 2906 2907 static void 2908 bwn_vap_delete(struct ieee80211vap *vap) 2909 { 2910 struct bwn_vap *bvp = BWN_VAP(vap); 2911 2912 ieee80211_ratectl_deinit(vap); 2913 ieee80211_vap_detach(vap); 2914 free(bvp, M_80211_VAP); 2915 } 2916 2917 static int 2918 bwn_init(struct bwn_softc *sc) 2919 { 2920 struct bwn_mac *mac; 2921 int error; 2922 2923 BWN_ASSERT_LOCKED(sc); 2924 2925 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2926 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2927 sc->sc_filters = 0; 2928 bwn_wme_clear(sc); 2929 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2930 sc->sc_rf_enabled = 1; 2931 2932 mac = sc->sc_curmac; 2933 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2934 error = bwn_core_init(mac); 2935 if (error != 0) 2936 return (error); 2937 } 2938 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2939 bwn_core_start(mac); 2940 2941 bwn_set_opmode(mac); 2942 bwn_set_pretbtt(mac); 2943 bwn_spu_setdelay(mac, 0); 2944 bwn_set_macaddr(mac); 2945 2946 sc->sc_flags |= BWN_FLAG_RUNNING; 2947 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2948 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2949 2950 return (0); 2951 } 2952 2953 static void 2954 bwn_stop(struct bwn_softc *sc) 2955 { 2956 struct bwn_mac *mac = sc->sc_curmac; 2957 2958 BWN_ASSERT_LOCKED(sc); 2959 2960 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2961 /* XXX FIXME opmode not based on VAP */ 2962 bwn_set_opmode(mac); 2963 bwn_set_macaddr(mac); 2964 } 2965 2966 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 2967 bwn_core_stop(mac); 2968 2969 callout_stop(&sc->sc_led_blink_ch); 2970 sc->sc_led_blinking = 0; 2971 2972 bwn_core_exit(mac); 2973 sc->sc_rf_enabled = 0; 2974 2975 sc->sc_flags &= ~BWN_FLAG_RUNNING; 2976 } 2977 2978 static void 2979 bwn_wme_clear(struct bwn_softc *sc) 2980 { 2981 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 2982 struct wmeParams *p; 2983 unsigned int i; 2984 2985 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 2986 ("%s:%d: fail", __func__, __LINE__)); 2987 2988 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2989 p = &(sc->sc_wmeParams[i]); 2990 2991 switch (bwn_wme_shm_offsets[i]) { 2992 case BWN_WME_VOICE: 2993 p->wmep_txopLimit = 0; 2994 p->wmep_aifsn = 2; 2995 /* XXX FIXME: log2(cwmin) */ 2996 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 2997 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 2998 break; 2999 case BWN_WME_VIDEO: 3000 p->wmep_txopLimit = 0; 3001 p->wmep_aifsn = 2; 3002 /* XXX FIXME: log2(cwmin) */ 3003 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3004 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3005 break; 3006 case BWN_WME_BESTEFFORT: 3007 p->wmep_txopLimit = 0; 3008 p->wmep_aifsn = 3; 3009 /* XXX FIXME: log2(cwmin) */ 3010 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3011 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3012 break; 3013 case BWN_WME_BACKGROUND: 3014 p->wmep_txopLimit = 0; 3015 p->wmep_aifsn = 7; 3016 /* XXX FIXME: log2(cwmin) */ 3017 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3018 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3019 break; 3020 default: 3021 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3022 } 3023 } 3024 } 3025 3026 static int 3027 bwn_core_init(struct bwn_mac *mac) 3028 { 3029 struct bwn_softc *sc = mac->mac_sc; 3030 uint64_t hf; 3031 int error; 3032 3033 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3034 ("%s:%d: fail", __func__, __LINE__)); 3035 3036 siba_powerup(sc->sc_dev, 0); 3037 if (!siba_dev_isup(sc->sc_dev)) 3038 bwn_reset_core(mac, 3039 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3040 3041 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3042 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3043 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3044 BWN_GETTIME(mac->mac_phy.nexttime); 3045 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3046 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3047 mac->mac_stats.link_noise = -95; 3048 mac->mac_reason_intr = 0; 3049 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3050 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3051 #ifdef BWN_DEBUG 3052 if (sc->sc_debug & BWN_DEBUG_XMIT) 3053 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3054 #endif 3055 mac->mac_suspended = 1; 3056 mac->mac_task_state = 0; 3057 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3058 3059 mac->mac_phy.init_pre(mac); 3060 3061 siba_pcicore_intr(sc->sc_dev); 3062 3063 siba_fix_imcfglobug(sc->sc_dev); 3064 bwn_bt_disable(mac); 3065 if (mac->mac_phy.prepare_hw) { 3066 error = mac->mac_phy.prepare_hw(mac); 3067 if (error) 3068 goto fail0; 3069 } 3070 error = bwn_chip_init(mac); 3071 if (error) 3072 goto fail0; 3073 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3074 siba_get_revid(sc->sc_dev)); 3075 hf = bwn_hf_read(mac); 3076 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3077 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3078 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3079 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3080 if (mac->mac_phy.rev == 1) 3081 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3082 } 3083 if (mac->mac_phy.rf_ver == 0x2050) { 3084 if (mac->mac_phy.rf_rev < 6) 3085 hf |= BWN_HF_FORCE_VCO_RECALC; 3086 if (mac->mac_phy.rf_rev == 6) 3087 hf |= BWN_HF_4318_TSSI; 3088 } 3089 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3090 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3091 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3092 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3093 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3094 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3095 bwn_hf_write(mac, hf); 3096 3097 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3098 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3099 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3100 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3101 3102 bwn_rate_init(mac); 3103 bwn_set_phytxctl(mac); 3104 3105 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3106 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3107 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3108 3109 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3110 bwn_pio_init(mac); 3111 else 3112 bwn_dma_init(mac); 3113 bwn_wme_init(mac); 3114 bwn_spu_setdelay(mac, 1); 3115 bwn_bt_enable(mac); 3116 3117 siba_powerup(sc->sc_dev, 3118 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3119 bwn_set_macaddr(mac); 3120 bwn_crypt_init(mac); 3121 3122 /* XXX LED initializatin */ 3123 3124 mac->mac_status = BWN_MAC_STATUS_INITED; 3125 3126 return (error); 3127 3128 fail0: 3129 siba_powerdown(sc->sc_dev); 3130 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3131 ("%s:%d: fail", __func__, __LINE__)); 3132 return (error); 3133 } 3134 3135 static void 3136 bwn_core_start(struct bwn_mac *mac) 3137 { 3138 struct bwn_softc *sc = mac->mac_sc; 3139 uint32_t tmp; 3140 3141 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3142 ("%s:%d: fail", __func__, __LINE__)); 3143 3144 if (siba_get_revid(sc->sc_dev) < 5) 3145 return; 3146 3147 while (1) { 3148 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3149 if (!(tmp & 0x00000001)) 3150 break; 3151 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3152 } 3153 3154 bwn_mac_enable(mac); 3155 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3156 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3157 3158 mac->mac_status = BWN_MAC_STATUS_STARTED; 3159 } 3160 3161 static void 3162 bwn_core_exit(struct bwn_mac *mac) 3163 { 3164 struct bwn_softc *sc = mac->mac_sc; 3165 uint32_t macctl; 3166 3167 BWN_ASSERT_LOCKED(mac->mac_sc); 3168 3169 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3170 ("%s:%d: fail", __func__, __LINE__)); 3171 3172 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3173 return; 3174 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3175 3176 macctl = BWN_READ_4(mac, BWN_MACCTL); 3177 macctl &= ~BWN_MACCTL_MCODE_RUN; 3178 macctl |= BWN_MACCTL_MCODE_JMP0; 3179 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3180 3181 bwn_dma_stop(mac); 3182 bwn_pio_stop(mac); 3183 bwn_chip_exit(mac); 3184 mac->mac_phy.switch_analog(mac, 0); 3185 siba_dev_down(sc->sc_dev, 0); 3186 siba_powerdown(sc->sc_dev); 3187 } 3188 3189 static void 3190 bwn_bt_disable(struct bwn_mac *mac) 3191 { 3192 struct bwn_softc *sc = mac->mac_sc; 3193 3194 (void)sc; 3195 /* XXX do nothing yet */ 3196 } 3197 3198 static int 3199 bwn_chip_init(struct bwn_mac *mac) 3200 { 3201 struct bwn_softc *sc = mac->mac_sc; 3202 struct bwn_phy *phy = &mac->mac_phy; 3203 uint32_t macctl; 3204 int error; 3205 3206 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3207 if (phy->gmode) 3208 macctl |= BWN_MACCTL_GMODE; 3209 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3210 3211 error = bwn_fw_fillinfo(mac); 3212 if (error) 3213 return (error); 3214 error = bwn_fw_loaducode(mac); 3215 if (error) 3216 return (error); 3217 3218 error = bwn_gpio_init(mac); 3219 if (error) 3220 return (error); 3221 3222 error = bwn_fw_loadinitvals(mac); 3223 if (error) { 3224 siba_gpio_set(sc->sc_dev, 0); 3225 return (error); 3226 } 3227 phy->switch_analog(mac, 1); 3228 error = bwn_phy_init(mac); 3229 if (error) { 3230 siba_gpio_set(sc->sc_dev, 0); 3231 return (error); 3232 } 3233 if (phy->set_im) 3234 phy->set_im(mac, BWN_IMMODE_NONE); 3235 if (phy->set_antenna) 3236 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3237 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3238 3239 if (phy->type == BWN_PHYTYPE_B) 3240 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3241 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3242 if (siba_get_revid(sc->sc_dev) < 5) 3243 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3244 3245 BWN_WRITE_4(mac, BWN_MACCTL, 3246 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3247 BWN_WRITE_4(mac, BWN_MACCTL, 3248 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3249 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3250 3251 bwn_set_opmode(mac); 3252 if (siba_get_revid(sc->sc_dev) < 3) { 3253 BWN_WRITE_2(mac, 0x060e, 0x0000); 3254 BWN_WRITE_2(mac, 0x0610, 0x8000); 3255 BWN_WRITE_2(mac, 0x0604, 0x0000); 3256 BWN_WRITE_2(mac, 0x0606, 0x0200); 3257 } else { 3258 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3259 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3260 } 3261 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3262 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3263 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3264 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3265 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3266 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3267 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3268 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3269 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3270 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3271 return (error); 3272 } 3273 3274 /* read hostflags */ 3275 static uint64_t 3276 bwn_hf_read(struct bwn_mac *mac) 3277 { 3278 uint64_t ret; 3279 3280 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3281 ret <<= 16; 3282 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3283 ret <<= 16; 3284 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3285 return (ret); 3286 } 3287 3288 static void 3289 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3290 { 3291 3292 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3293 (value & 0x00000000ffffull)); 3294 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3295 (value & 0x0000ffff0000ull) >> 16); 3296 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3297 (value & 0xffff00000000ULL) >> 32); 3298 } 3299 3300 static void 3301 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3302 { 3303 3304 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3305 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3306 } 3307 3308 static void 3309 bwn_rate_init(struct bwn_mac *mac) 3310 { 3311 3312 switch (mac->mac_phy.type) { 3313 case BWN_PHYTYPE_A: 3314 case BWN_PHYTYPE_G: 3315 case BWN_PHYTYPE_LP: 3316 case BWN_PHYTYPE_N: 3317 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3318 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3319 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3320 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3321 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3322 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3323 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3324 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3325 break; 3326 /* FALLTHROUGH */ 3327 case BWN_PHYTYPE_B: 3328 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3329 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3330 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3331 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3332 break; 3333 default: 3334 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3335 } 3336 } 3337 3338 static void 3339 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3340 { 3341 uint16_t offset; 3342 3343 if (ofdm) { 3344 offset = 0x480; 3345 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3346 } else { 3347 offset = 0x4c0; 3348 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3349 } 3350 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3351 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3352 } 3353 3354 static uint8_t 3355 bwn_plcp_getcck(const uint8_t bitrate) 3356 { 3357 3358 switch (bitrate) { 3359 case BWN_CCK_RATE_1MB: 3360 return (0x0a); 3361 case BWN_CCK_RATE_2MB: 3362 return (0x14); 3363 case BWN_CCK_RATE_5MB: 3364 return (0x37); 3365 case BWN_CCK_RATE_11MB: 3366 return (0x6e); 3367 } 3368 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3369 return (0); 3370 } 3371 3372 static uint8_t 3373 bwn_plcp_getofdm(const uint8_t bitrate) 3374 { 3375 3376 switch (bitrate) { 3377 case BWN_OFDM_RATE_6MB: 3378 return (0xb); 3379 case BWN_OFDM_RATE_9MB: 3380 return (0xf); 3381 case BWN_OFDM_RATE_12MB: 3382 return (0xa); 3383 case BWN_OFDM_RATE_18MB: 3384 return (0xe); 3385 case BWN_OFDM_RATE_24MB: 3386 return (0x9); 3387 case BWN_OFDM_RATE_36MB: 3388 return (0xd); 3389 case BWN_OFDM_RATE_48MB: 3390 return (0x8); 3391 case BWN_OFDM_RATE_54MB: 3392 return (0xc); 3393 } 3394 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3395 return (0); 3396 } 3397 3398 static void 3399 bwn_set_phytxctl(struct bwn_mac *mac) 3400 { 3401 uint16_t ctl; 3402 3403 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3404 BWN_TX_PHY_TXPWR); 3405 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3406 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3407 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3408 } 3409 3410 static void 3411 bwn_pio_init(struct bwn_mac *mac) 3412 { 3413 struct bwn_pio *pio = &mac->mac_method.pio; 3414 3415 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3416 & ~BWN_MACCTL_BIGENDIAN); 3417 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3418 3419 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3420 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3421 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3422 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3423 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3424 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3425 } 3426 3427 static void 3428 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3429 int index) 3430 { 3431 struct bwn_pio_txpkt *tp; 3432 struct bwn_softc *sc = mac->mac_sc; 3433 unsigned int i; 3434 3435 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3436 tq->tq_index = index; 3437 3438 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3439 if (siba_get_revid(sc->sc_dev) >= 8) 3440 tq->tq_size = 1920; 3441 else { 3442 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3443 tq->tq_size -= 80; 3444 } 3445 3446 TAILQ_INIT(&tq->tq_pktlist); 3447 for (i = 0; i < N(tq->tq_pkts); i++) { 3448 tp = &(tq->tq_pkts[i]); 3449 tp->tp_index = i; 3450 tp->tp_queue = tq; 3451 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3452 } 3453 } 3454 3455 static uint16_t 3456 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3457 { 3458 struct bwn_softc *sc = mac->mac_sc; 3459 static const uint16_t bases[] = { 3460 BWN_PIO_BASE0, 3461 BWN_PIO_BASE1, 3462 BWN_PIO_BASE2, 3463 BWN_PIO_BASE3, 3464 BWN_PIO_BASE4, 3465 BWN_PIO_BASE5, 3466 BWN_PIO_BASE6, 3467 BWN_PIO_BASE7, 3468 }; 3469 static const uint16_t bases_rev11[] = { 3470 BWN_PIO11_BASE0, 3471 BWN_PIO11_BASE1, 3472 BWN_PIO11_BASE2, 3473 BWN_PIO11_BASE3, 3474 BWN_PIO11_BASE4, 3475 BWN_PIO11_BASE5, 3476 }; 3477 3478 if (siba_get_revid(sc->sc_dev) >= 11) { 3479 if (index >= N(bases_rev11)) 3480 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3481 return (bases_rev11[index]); 3482 } 3483 if (index >= N(bases)) 3484 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3485 return (bases[index]); 3486 } 3487 3488 static void 3489 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3490 int index) 3491 { 3492 struct bwn_softc *sc = mac->mac_sc; 3493 3494 prq->prq_mac = mac; 3495 prq->prq_rev = siba_get_revid(sc->sc_dev); 3496 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3497 bwn_dma_rxdirectfifo(mac, index, 1); 3498 } 3499 3500 static void 3501 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3502 { 3503 if (tq == NULL) 3504 return; 3505 bwn_pio_cancel_tx_packets(tq); 3506 } 3507 3508 static void 3509 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3510 { 3511 3512 bwn_destroy_pioqueue_tx(pio); 3513 } 3514 3515 static uint16_t 3516 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3517 uint16_t offset) 3518 { 3519 3520 return (BWN_READ_2(mac, tq->tq_base + offset)); 3521 } 3522 3523 static void 3524 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3525 { 3526 uint32_t ctl; 3527 int type; 3528 uint16_t base; 3529 3530 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3531 base = bwn_dma_base(type, idx); 3532 if (type == BWN_DMA_64BIT) { 3533 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3534 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3535 if (enable) 3536 ctl |= BWN_DMA64_RXDIRECTFIFO; 3537 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3538 } else { 3539 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3540 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3541 if (enable) 3542 ctl |= BWN_DMA32_RXDIRECTFIFO; 3543 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3544 } 3545 } 3546 3547 static uint64_t 3548 bwn_dma_mask(struct bwn_mac *mac) 3549 { 3550 uint32_t tmp; 3551 uint16_t base; 3552 3553 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3554 if (tmp & SIBA_TGSHIGH_DMA64) 3555 return (BWN_DMA_BIT_MASK(64)); 3556 base = bwn_dma_base(0, 0); 3557 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3558 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3559 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3560 return (BWN_DMA_BIT_MASK(32)); 3561 3562 return (BWN_DMA_BIT_MASK(30)); 3563 } 3564 3565 static int 3566 bwn_dma_mask2type(uint64_t dmamask) 3567 { 3568 3569 if (dmamask == BWN_DMA_BIT_MASK(30)) 3570 return (BWN_DMA_30BIT); 3571 if (dmamask == BWN_DMA_BIT_MASK(32)) 3572 return (BWN_DMA_32BIT); 3573 if (dmamask == BWN_DMA_BIT_MASK(64)) 3574 return (BWN_DMA_64BIT); 3575 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3576 return (BWN_DMA_30BIT); 3577 } 3578 3579 static void 3580 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3581 { 3582 struct bwn_pio_txpkt *tp; 3583 unsigned int i; 3584 3585 for (i = 0; i < N(tq->tq_pkts); i++) { 3586 tp = &(tq->tq_pkts[i]); 3587 if (tp->tp_m) { 3588 m_freem(tp->tp_m); 3589 tp->tp_m = NULL; 3590 } 3591 } 3592 } 3593 3594 static uint16_t 3595 bwn_dma_base(int type, int controller_idx) 3596 { 3597 static const uint16_t map64[] = { 3598 BWN_DMA64_BASE0, 3599 BWN_DMA64_BASE1, 3600 BWN_DMA64_BASE2, 3601 BWN_DMA64_BASE3, 3602 BWN_DMA64_BASE4, 3603 BWN_DMA64_BASE5, 3604 }; 3605 static const uint16_t map32[] = { 3606 BWN_DMA32_BASE0, 3607 BWN_DMA32_BASE1, 3608 BWN_DMA32_BASE2, 3609 BWN_DMA32_BASE3, 3610 BWN_DMA32_BASE4, 3611 BWN_DMA32_BASE5, 3612 }; 3613 3614 if (type == BWN_DMA_64BIT) { 3615 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3616 ("%s:%d: fail", __func__, __LINE__)); 3617 return (map64[controller_idx]); 3618 } 3619 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3620 ("%s:%d: fail", __func__, __LINE__)); 3621 return (map32[controller_idx]); 3622 } 3623 3624 static void 3625 bwn_dma_init(struct bwn_mac *mac) 3626 { 3627 struct bwn_dma *dma = &mac->mac_method.dma; 3628 3629 /* setup TX DMA channels. */ 3630 bwn_dma_setup(dma->wme[WME_AC_BK]); 3631 bwn_dma_setup(dma->wme[WME_AC_BE]); 3632 bwn_dma_setup(dma->wme[WME_AC_VI]); 3633 bwn_dma_setup(dma->wme[WME_AC_VO]); 3634 bwn_dma_setup(dma->mcast); 3635 /* setup RX DMA channel. */ 3636 bwn_dma_setup(dma->rx); 3637 } 3638 3639 static struct bwn_dma_ring * 3640 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3641 int for_tx, int type) 3642 { 3643 struct bwn_dma *dma = &mac->mac_method.dma; 3644 struct bwn_dma_ring *dr; 3645 struct bwn_dmadesc_generic *desc; 3646 struct bwn_dmadesc_meta *mt; 3647 struct bwn_softc *sc = mac->mac_sc; 3648 int error, i; 3649 3650 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3651 if (dr == NULL) 3652 goto out; 3653 dr->dr_numslots = BWN_RXRING_SLOTS; 3654 if (for_tx) 3655 dr->dr_numslots = BWN_TXRING_SLOTS; 3656 3657 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3658 M_DEVBUF, M_NOWAIT | M_ZERO); 3659 if (dr->dr_meta == NULL) 3660 goto fail0; 3661 3662 dr->dr_type = type; 3663 dr->dr_mac = mac; 3664 dr->dr_base = bwn_dma_base(type, controller_index); 3665 dr->dr_index = controller_index; 3666 if (type == BWN_DMA_64BIT) { 3667 dr->getdesc = bwn_dma_64_getdesc; 3668 dr->setdesc = bwn_dma_64_setdesc; 3669 dr->start_transfer = bwn_dma_64_start_transfer; 3670 dr->suspend = bwn_dma_64_suspend; 3671 dr->resume = bwn_dma_64_resume; 3672 dr->get_curslot = bwn_dma_64_get_curslot; 3673 dr->set_curslot = bwn_dma_64_set_curslot; 3674 } else { 3675 dr->getdesc = bwn_dma_32_getdesc; 3676 dr->setdesc = bwn_dma_32_setdesc; 3677 dr->start_transfer = bwn_dma_32_start_transfer; 3678 dr->suspend = bwn_dma_32_suspend; 3679 dr->resume = bwn_dma_32_resume; 3680 dr->get_curslot = bwn_dma_32_get_curslot; 3681 dr->set_curslot = bwn_dma_32_set_curslot; 3682 } 3683 if (for_tx) { 3684 dr->dr_tx = 1; 3685 dr->dr_curslot = -1; 3686 } else { 3687 if (dr->dr_index == 0) { 3688 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3689 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3690 } else 3691 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3692 } 3693 3694 error = bwn_dma_allocringmemory(dr); 3695 if (error) 3696 goto fail2; 3697 3698 if (for_tx) { 3699 /* 3700 * Assumption: BWN_TXRING_SLOTS can be divided by 3701 * BWN_TX_SLOTS_PER_FRAME 3702 */ 3703 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3704 ("%s:%d: fail", __func__, __LINE__)); 3705 3706 dr->dr_txhdr_cache = 3707 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3708 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3709 KASSERT(dr->dr_txhdr_cache != NULL, 3710 ("%s:%d: fail", __func__, __LINE__)); 3711 3712 /* 3713 * Create TX ring DMA stuffs 3714 */ 3715 error = bus_dma_tag_create(dma->parent_dtag, 3716 BWN_ALIGN, 0, 3717 BUS_SPACE_MAXADDR, 3718 BUS_SPACE_MAXADDR, 3719 NULL, NULL, 3720 BWN_HDRSIZE(mac), 3721 1, 3722 BUS_SPACE_MAXSIZE_32BIT, 3723 0, 3724 NULL, NULL, 3725 &dr->dr_txring_dtag); 3726 if (error) { 3727 device_printf(sc->sc_dev, 3728 "can't create TX ring DMA tag: TODO frees\n"); 3729 goto fail1; 3730 } 3731 3732 for (i = 0; i < dr->dr_numslots; i += 2) { 3733 dr->getdesc(dr, i, &desc, &mt); 3734 3735 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3736 mt->mt_m = NULL; 3737 mt->mt_ni = NULL; 3738 mt->mt_islast = 0; 3739 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3740 &mt->mt_dmap); 3741 if (error) { 3742 device_printf(sc->sc_dev, 3743 "can't create RX buf DMA map\n"); 3744 goto fail1; 3745 } 3746 3747 dr->getdesc(dr, i + 1, &desc, &mt); 3748 3749 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3750 mt->mt_m = NULL; 3751 mt->mt_ni = NULL; 3752 mt->mt_islast = 1; 3753 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3754 &mt->mt_dmap); 3755 if (error) { 3756 device_printf(sc->sc_dev, 3757 "can't create RX buf DMA map\n"); 3758 goto fail1; 3759 } 3760 } 3761 } else { 3762 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3763 &dr->dr_spare_dmap); 3764 if (error) { 3765 device_printf(sc->sc_dev, 3766 "can't create RX buf DMA map\n"); 3767 goto out; /* XXX wrong! */ 3768 } 3769 3770 for (i = 0; i < dr->dr_numslots; i++) { 3771 dr->getdesc(dr, i, &desc, &mt); 3772 3773 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3774 &mt->mt_dmap); 3775 if (error) { 3776 device_printf(sc->sc_dev, 3777 "can't create RX buf DMA map\n"); 3778 goto out; /* XXX wrong! */ 3779 } 3780 error = bwn_dma_newbuf(dr, desc, mt, 1); 3781 if (error) { 3782 device_printf(sc->sc_dev, 3783 "failed to allocate RX buf\n"); 3784 goto out; /* XXX wrong! */ 3785 } 3786 } 3787 3788 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3789 BUS_DMASYNC_PREWRITE); 3790 3791 dr->dr_usedslot = dr->dr_numslots; 3792 } 3793 3794 out: 3795 return (dr); 3796 3797 fail2: 3798 free(dr->dr_txhdr_cache, M_DEVBUF); 3799 fail1: 3800 free(dr->dr_meta, M_DEVBUF); 3801 fail0: 3802 free(dr, M_DEVBUF); 3803 return (NULL); 3804 } 3805 3806 static void 3807 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3808 { 3809 3810 if (dr == NULL) 3811 return; 3812 3813 bwn_dma_free_descbufs(*dr); 3814 bwn_dma_free_ringmemory(*dr); 3815 3816 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3817 free((*dr)->dr_meta, M_DEVBUF); 3818 free(*dr, M_DEVBUF); 3819 3820 *dr = NULL; 3821 } 3822 3823 static void 3824 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3825 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3826 { 3827 struct bwn_dmadesc32 *desc; 3828 3829 *meta = &(dr->dr_meta[slot]); 3830 desc = dr->dr_ring_descbase; 3831 desc = &(desc[slot]); 3832 3833 *gdesc = (struct bwn_dmadesc_generic *)desc; 3834 } 3835 3836 static void 3837 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3838 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3839 int start, int end, int irq) 3840 { 3841 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3842 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3843 uint32_t addr, addrext, ctl; 3844 int slot; 3845 3846 slot = (int)(&(desc->dma.dma32) - descbase); 3847 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3848 ("%s:%d: fail", __func__, __LINE__)); 3849 3850 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3851 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3852 addr |= siba_dma_translation(sc->sc_dev); 3853 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3854 if (slot == dr->dr_numslots - 1) 3855 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3856 if (start) 3857 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3858 if (end) 3859 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3860 if (irq) 3861 ctl |= BWN_DMA32_DCTL_IRQ; 3862 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3863 & BWN_DMA32_DCTL_ADDREXT_MASK; 3864 3865 desc->dma.dma32.control = htole32(ctl); 3866 desc->dma.dma32.address = htole32(addr); 3867 } 3868 3869 static void 3870 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3871 { 3872 3873 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3874 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3875 } 3876 3877 static void 3878 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3879 { 3880 3881 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3882 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3883 } 3884 3885 static void 3886 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3887 { 3888 3889 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3890 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3891 } 3892 3893 static int 3894 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3895 { 3896 uint32_t val; 3897 3898 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3899 val &= BWN_DMA32_RXDPTR; 3900 3901 return (val / sizeof(struct bwn_dmadesc32)); 3902 } 3903 3904 static void 3905 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3906 { 3907 3908 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3909 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3910 } 3911 3912 static void 3913 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3914 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3915 { 3916 struct bwn_dmadesc64 *desc; 3917 3918 *meta = &(dr->dr_meta[slot]); 3919 desc = dr->dr_ring_descbase; 3920 desc = &(desc[slot]); 3921 3922 *gdesc = (struct bwn_dmadesc_generic *)desc; 3923 } 3924 3925 static void 3926 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3927 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3928 int start, int end, int irq) 3929 { 3930 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3931 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3932 int slot; 3933 uint32_t ctl0 = 0, ctl1 = 0; 3934 uint32_t addrlo, addrhi; 3935 uint32_t addrext; 3936 3937 slot = (int)(&(desc->dma.dma64) - descbase); 3938 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3939 ("%s:%d: fail", __func__, __LINE__)); 3940 3941 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3942 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3943 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3944 30; 3945 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3946 if (slot == dr->dr_numslots - 1) 3947 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3948 if (start) 3949 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3950 if (end) 3951 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3952 if (irq) 3953 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3954 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3955 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3956 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3957 3958 desc->dma.dma64.control0 = htole32(ctl0); 3959 desc->dma.dma64.control1 = htole32(ctl1); 3960 desc->dma.dma64.address_low = htole32(addrlo); 3961 desc->dma.dma64.address_high = htole32(addrhi); 3962 } 3963 3964 static void 3965 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3966 { 3967 3968 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3969 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3970 } 3971 3972 static void 3973 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3974 { 3975 3976 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3977 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3978 } 3979 3980 static void 3981 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3982 { 3983 3984 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3985 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 3986 } 3987 3988 static int 3989 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 3990 { 3991 uint32_t val; 3992 3993 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 3994 val &= BWN_DMA64_RXSTATDPTR; 3995 3996 return (val / sizeof(struct bwn_dmadesc64)); 3997 } 3998 3999 static void 4000 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4001 { 4002 4003 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4004 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4005 } 4006 4007 static int 4008 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4009 { 4010 struct bwn_mac *mac = dr->dr_mac; 4011 struct bwn_dma *dma = &mac->mac_method.dma; 4012 struct bwn_softc *sc = mac->mac_sc; 4013 int error; 4014 4015 error = bus_dma_tag_create(dma->parent_dtag, 4016 BWN_ALIGN, 0, 4017 BUS_SPACE_MAXADDR, 4018 BUS_SPACE_MAXADDR, 4019 NULL, NULL, 4020 BWN_DMA_RINGMEMSIZE, 4021 1, 4022 BUS_SPACE_MAXSIZE_32BIT, 4023 0, 4024 NULL, NULL, 4025 &dr->dr_ring_dtag); 4026 if (error) { 4027 device_printf(sc->sc_dev, 4028 "can't create TX ring DMA tag: TODO frees\n"); 4029 return (-1); 4030 } 4031 4032 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4033 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4034 &dr->dr_ring_dmap); 4035 if (error) { 4036 device_printf(sc->sc_dev, 4037 "can't allocate DMA mem: TODO frees\n"); 4038 return (-1); 4039 } 4040 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4041 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4042 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4043 if (error) { 4044 device_printf(sc->sc_dev, 4045 "can't load DMA mem: TODO free\n"); 4046 return (-1); 4047 } 4048 4049 return (0); 4050 } 4051 4052 static void 4053 bwn_dma_setup(struct bwn_dma_ring *dr) 4054 { 4055 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4056 uint64_t ring64; 4057 uint32_t addrext, ring32, value; 4058 uint32_t trans = siba_dma_translation(sc->sc_dev); 4059 4060 if (dr->dr_tx) { 4061 dr->dr_curslot = -1; 4062 4063 if (dr->dr_type == BWN_DMA_64BIT) { 4064 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4065 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4066 >> 30; 4067 value = BWN_DMA64_TXENABLE; 4068 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4069 & BWN_DMA64_TXADDREXT_MASK; 4070 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4071 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4072 (ring64 & 0xffffffff)); 4073 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4074 ((ring64 >> 32) & 4075 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4076 } else { 4077 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4078 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4079 value = BWN_DMA32_TXENABLE; 4080 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4081 & BWN_DMA32_TXADDREXT_MASK; 4082 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4083 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4084 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4085 } 4086 return; 4087 } 4088 4089 /* 4090 * set for RX 4091 */ 4092 dr->dr_usedslot = dr->dr_numslots; 4093 4094 if (dr->dr_type == BWN_DMA_64BIT) { 4095 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4096 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4097 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4098 value |= BWN_DMA64_RXENABLE; 4099 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4100 & BWN_DMA64_RXADDREXT_MASK; 4101 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4102 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4103 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4104 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4105 | (trans << 1)); 4106 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4107 sizeof(struct bwn_dmadesc64)); 4108 } else { 4109 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4110 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4111 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4112 value |= BWN_DMA32_RXENABLE; 4113 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4114 & BWN_DMA32_RXADDREXT_MASK; 4115 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4116 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4117 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4118 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4119 sizeof(struct bwn_dmadesc32)); 4120 } 4121 } 4122 4123 static void 4124 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4125 { 4126 4127 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4128 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4129 dr->dr_ring_dmap); 4130 } 4131 4132 static void 4133 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4134 { 4135 4136 if (dr->dr_tx) { 4137 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4138 if (dr->dr_type == BWN_DMA_64BIT) { 4139 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4140 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4141 } else 4142 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4143 } else { 4144 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4145 if (dr->dr_type == BWN_DMA_64BIT) { 4146 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4147 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4148 } else 4149 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4150 } 4151 } 4152 4153 static void 4154 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4155 { 4156 struct bwn_dmadesc_generic *desc; 4157 struct bwn_dmadesc_meta *meta; 4158 struct bwn_mac *mac = dr->dr_mac; 4159 struct bwn_dma *dma = &mac->mac_method.dma; 4160 struct bwn_softc *sc = mac->mac_sc; 4161 int i; 4162 4163 if (!dr->dr_usedslot) 4164 return; 4165 for (i = 0; i < dr->dr_numslots; i++) { 4166 dr->getdesc(dr, i, &desc, &meta); 4167 4168 if (meta->mt_m == NULL) { 4169 if (!dr->dr_tx) 4170 device_printf(sc->sc_dev, "%s: not TX?\n", 4171 __func__); 4172 continue; 4173 } 4174 if (dr->dr_tx) { 4175 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4176 bus_dmamap_unload(dr->dr_txring_dtag, 4177 meta->mt_dmap); 4178 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4179 bus_dmamap_unload(dma->txbuf_dtag, 4180 meta->mt_dmap); 4181 } else 4182 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4183 bwn_dma_free_descbuf(dr, meta); 4184 } 4185 } 4186 4187 static int 4188 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4189 int type) 4190 { 4191 struct bwn_softc *sc = mac->mac_sc; 4192 uint32_t value; 4193 int i; 4194 uint16_t offset; 4195 4196 for (i = 0; i < 10; i++) { 4197 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4198 BWN_DMA32_TXSTATUS; 4199 value = BWN_READ_4(mac, base + offset); 4200 if (type == BWN_DMA_64BIT) { 4201 value &= BWN_DMA64_TXSTAT; 4202 if (value == BWN_DMA64_TXSTAT_DISABLED || 4203 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4204 value == BWN_DMA64_TXSTAT_STOPPED) 4205 break; 4206 } else { 4207 value &= BWN_DMA32_TXSTATE; 4208 if (value == BWN_DMA32_TXSTAT_DISABLED || 4209 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4210 value == BWN_DMA32_TXSTAT_STOPPED) 4211 break; 4212 } 4213 DELAY(1000); 4214 } 4215 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4216 BWN_WRITE_4(mac, base + offset, 0); 4217 for (i = 0; i < 10; i++) { 4218 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4219 BWN_DMA32_TXSTATUS; 4220 value = BWN_READ_4(mac, base + offset); 4221 if (type == BWN_DMA_64BIT) { 4222 value &= BWN_DMA64_TXSTAT; 4223 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4224 i = -1; 4225 break; 4226 } 4227 } else { 4228 value &= BWN_DMA32_TXSTATE; 4229 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4230 i = -1; 4231 break; 4232 } 4233 } 4234 DELAY(1000); 4235 } 4236 if (i != -1) { 4237 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4238 return (ENODEV); 4239 } 4240 DELAY(1000); 4241 4242 return (0); 4243 } 4244 4245 static int 4246 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4247 int type) 4248 { 4249 struct bwn_softc *sc = mac->mac_sc; 4250 uint32_t value; 4251 int i; 4252 uint16_t offset; 4253 4254 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4255 BWN_WRITE_4(mac, base + offset, 0); 4256 for (i = 0; i < 10; i++) { 4257 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4258 BWN_DMA32_RXSTATUS; 4259 value = BWN_READ_4(mac, base + offset); 4260 if (type == BWN_DMA_64BIT) { 4261 value &= BWN_DMA64_RXSTAT; 4262 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4263 i = -1; 4264 break; 4265 } 4266 } else { 4267 value &= BWN_DMA32_RXSTATE; 4268 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4269 i = -1; 4270 break; 4271 } 4272 } 4273 DELAY(1000); 4274 } 4275 if (i != -1) { 4276 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4277 return (ENODEV); 4278 } 4279 4280 return (0); 4281 } 4282 4283 static void 4284 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4285 struct bwn_dmadesc_meta *meta) 4286 { 4287 4288 if (meta->mt_m != NULL) { 4289 m_freem(meta->mt_m); 4290 meta->mt_m = NULL; 4291 } 4292 if (meta->mt_ni != NULL) { 4293 ieee80211_free_node(meta->mt_ni); 4294 meta->mt_ni = NULL; 4295 } 4296 } 4297 4298 static void 4299 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4300 { 4301 struct bwn_rxhdr4 *rxhdr; 4302 unsigned char *frame; 4303 4304 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4305 rxhdr->frame_len = 0; 4306 4307 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4308 sizeof(struct bwn_plcp6) + 2, 4309 ("%s:%d: fail", __func__, __LINE__)); 4310 frame = mtod(m, char *) + dr->dr_frameoffset; 4311 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4312 } 4313 4314 static uint8_t 4315 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4316 { 4317 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4318 4319 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4320 == 0xff); 4321 } 4322 4323 static void 4324 bwn_wme_init(struct bwn_mac *mac) 4325 { 4326 4327 bwn_wme_load(mac); 4328 4329 /* enable WME support. */ 4330 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4331 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4332 BWN_IFSCTL_USE_EDCF); 4333 } 4334 4335 static void 4336 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4337 { 4338 struct bwn_softc *sc = mac->mac_sc; 4339 struct ieee80211com *ic = &sc->sc_ic; 4340 uint16_t delay; /* microsec */ 4341 4342 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4343 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4344 delay = 500; 4345 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4346 delay = max(delay, (uint16_t)2400); 4347 4348 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4349 } 4350 4351 static void 4352 bwn_bt_enable(struct bwn_mac *mac) 4353 { 4354 struct bwn_softc *sc = mac->mac_sc; 4355 uint64_t hf; 4356 4357 if (bwn_bluetooth == 0) 4358 return; 4359 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4360 return; 4361 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4362 return; 4363 4364 hf = bwn_hf_read(mac); 4365 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4366 hf |= BWN_HF_BT_COEXISTALT; 4367 else 4368 hf |= BWN_HF_BT_COEXIST; 4369 bwn_hf_write(mac, hf); 4370 } 4371 4372 static void 4373 bwn_set_macaddr(struct bwn_mac *mac) 4374 { 4375 4376 bwn_mac_write_bssid(mac); 4377 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, 4378 mac->mac_sc->sc_ic.ic_macaddr); 4379 } 4380 4381 static void 4382 bwn_clear_keys(struct bwn_mac *mac) 4383 { 4384 int i; 4385 4386 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4387 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4388 ("%s:%d: fail", __func__, __LINE__)); 4389 4390 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4391 NULL, BWN_SEC_KEYSIZE, NULL); 4392 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4393 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4394 NULL, BWN_SEC_KEYSIZE, NULL); 4395 } 4396 mac->mac_key[i].keyconf = NULL; 4397 } 4398 } 4399 4400 static void 4401 bwn_crypt_init(struct bwn_mac *mac) 4402 { 4403 struct bwn_softc *sc = mac->mac_sc; 4404 4405 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4406 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4407 ("%s:%d: fail", __func__, __LINE__)); 4408 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4409 mac->mac_ktp *= 2; 4410 if (siba_get_revid(sc->sc_dev) >= 5) 4411 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4412 bwn_clear_keys(mac); 4413 } 4414 4415 static void 4416 bwn_chip_exit(struct bwn_mac *mac) 4417 { 4418 struct bwn_softc *sc = mac->mac_sc; 4419 4420 bwn_phy_exit(mac); 4421 siba_gpio_set(sc->sc_dev, 0); 4422 } 4423 4424 static int 4425 bwn_fw_fillinfo(struct bwn_mac *mac) 4426 { 4427 int error; 4428 4429 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4430 if (error == 0) 4431 return (0); 4432 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4433 if (error == 0) 4434 return (0); 4435 return (error); 4436 } 4437 4438 static int 4439 bwn_gpio_init(struct bwn_mac *mac) 4440 { 4441 struct bwn_softc *sc = mac->mac_sc; 4442 uint32_t mask = 0x1f, set = 0xf, value; 4443 4444 BWN_WRITE_4(mac, BWN_MACCTL, 4445 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4446 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4447 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4448 4449 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4450 mask |= 0x0060; 4451 set |= 0x0060; 4452 } 4453 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4454 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4455 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4456 mask |= 0x0200; 4457 set |= 0x0200; 4458 } 4459 if (siba_get_revid(sc->sc_dev) >= 2) 4460 mask |= 0x0010; 4461 4462 value = siba_gpio_get(sc->sc_dev); 4463 if (value == -1) 4464 return (0); 4465 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4466 4467 return (0); 4468 } 4469 4470 static int 4471 bwn_fw_loadinitvals(struct bwn_mac *mac) 4472 { 4473 #define GETFWOFFSET(fwp, offset) \ 4474 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4475 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4476 const struct bwn_fwhdr *hdr; 4477 struct bwn_fw *fw = &mac->mac_fw; 4478 int error; 4479 4480 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4481 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4482 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4483 if (error) 4484 return (error); 4485 if (fw->initvals_band.fw) { 4486 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4487 error = bwn_fwinitvals_write(mac, 4488 GETFWOFFSET(fw->initvals_band, hdr_len), 4489 be32toh(hdr->size), 4490 fw->initvals_band.fw->datasize - hdr_len); 4491 } 4492 return (error); 4493 #undef GETFWOFFSET 4494 } 4495 4496 static int 4497 bwn_phy_init(struct bwn_mac *mac) 4498 { 4499 struct bwn_softc *sc = mac->mac_sc; 4500 int error; 4501 4502 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4503 mac->mac_phy.rf_onoff(mac, 1); 4504 error = mac->mac_phy.init(mac); 4505 if (error) { 4506 device_printf(sc->sc_dev, "PHY init failed\n"); 4507 goto fail0; 4508 } 4509 error = bwn_switch_channel(mac, 4510 mac->mac_phy.get_default_chan(mac)); 4511 if (error) { 4512 device_printf(sc->sc_dev, 4513 "failed to switch default channel\n"); 4514 goto fail1; 4515 } 4516 return (0); 4517 fail1: 4518 if (mac->mac_phy.exit) 4519 mac->mac_phy.exit(mac); 4520 fail0: 4521 mac->mac_phy.rf_onoff(mac, 0); 4522 4523 return (error); 4524 } 4525 4526 static void 4527 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4528 { 4529 uint16_t ant; 4530 uint16_t tmp; 4531 4532 ant = bwn_ant2phy(antenna); 4533 4534 /* For ACK/CTS */ 4535 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4536 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4537 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4538 /* For Probe Resposes */ 4539 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4540 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4541 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4542 } 4543 4544 static void 4545 bwn_set_opmode(struct bwn_mac *mac) 4546 { 4547 struct bwn_softc *sc = mac->mac_sc; 4548 struct ieee80211com *ic = &sc->sc_ic; 4549 uint32_t ctl; 4550 uint16_t cfp_pretbtt; 4551 4552 ctl = BWN_READ_4(mac, BWN_MACCTL); 4553 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4554 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4555 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4556 ctl |= BWN_MACCTL_STA; 4557 4558 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4559 ic->ic_opmode == IEEE80211_M_MBSS) 4560 ctl |= BWN_MACCTL_HOSTAP; 4561 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4562 ctl &= ~BWN_MACCTL_STA; 4563 ctl |= sc->sc_filters; 4564 4565 if (siba_get_revid(sc->sc_dev) <= 4) 4566 ctl |= BWN_MACCTL_PROMISC; 4567 4568 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4569 4570 cfp_pretbtt = 2; 4571 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4572 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4573 siba_get_chiprev(sc->sc_dev) == 3) 4574 cfp_pretbtt = 100; 4575 else 4576 cfp_pretbtt = 50; 4577 } 4578 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4579 } 4580 4581 static int 4582 bwn_dma_gettype(struct bwn_mac *mac) 4583 { 4584 uint32_t tmp; 4585 uint16_t base; 4586 4587 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4588 if (tmp & SIBA_TGSHIGH_DMA64) 4589 return (BWN_DMA_64BIT); 4590 base = bwn_dma_base(0, 0); 4591 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4592 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4593 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4594 return (BWN_DMA_32BIT); 4595 4596 return (BWN_DMA_30BIT); 4597 } 4598 4599 static void 4600 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4601 { 4602 if (!error) { 4603 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4604 *((bus_addr_t *)arg) = seg->ds_addr; 4605 } 4606 } 4607 4608 static void 4609 bwn_phy_g_init_sub(struct bwn_mac *mac) 4610 { 4611 struct bwn_phy *phy = &mac->mac_phy; 4612 struct bwn_phy_g *pg = &phy->phy_g; 4613 struct bwn_softc *sc = mac->mac_sc; 4614 uint16_t i, tmp; 4615 4616 if (phy->rev == 1) 4617 bwn_phy_init_b5(mac); 4618 else 4619 bwn_phy_init_b6(mac); 4620 4621 if (phy->rev >= 2 || phy->gmode) 4622 bwn_phy_init_a(mac); 4623 4624 if (phy->rev >= 2) { 4625 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4626 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4627 } 4628 if (phy->rev == 2) { 4629 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4630 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4631 } 4632 if (phy->rev > 5) { 4633 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4634 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4635 } 4636 if (phy->gmode || phy->rev >= 2) { 4637 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4638 tmp &= BWN_PHYVER_VERSION; 4639 if (tmp == 3 || tmp == 5) { 4640 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4641 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4642 } 4643 if (tmp == 5) { 4644 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4645 0x1f00); 4646 } 4647 } 4648 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4649 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4650 if (phy->rf_rev == 8) { 4651 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4652 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4653 } 4654 if (BWN_HAS_LOOPBACK(phy)) 4655 bwn_loopback_calcgain(mac); 4656 4657 if (phy->rf_rev != 8) { 4658 if (pg->pg_initval == 0xffff) 4659 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4660 else 4661 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4662 } 4663 bwn_lo_g_init(mac); 4664 if (BWN_HAS_TXMAG(phy)) { 4665 BWN_RF_WRITE(mac, 0x52, 4666 (BWN_RF_READ(mac, 0x52) & 0xff00) 4667 | pg->pg_loctl.tx_bias | 4668 pg->pg_loctl.tx_magn); 4669 } else { 4670 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4671 } 4672 if (phy->rev >= 6) { 4673 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4674 (pg->pg_loctl.tx_bias << 12)); 4675 } 4676 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4677 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4678 else 4679 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4680 if (phy->rev < 2) 4681 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4682 else 4683 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4684 if (phy->gmode || phy->rev >= 2) { 4685 bwn_lo_g_adjust(mac); 4686 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4687 } 4688 4689 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4690 for (i = 0; i < 64; i++) { 4691 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4692 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4693 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4694 -32), 31)); 4695 } 4696 bwn_nrssi_threshold(mac); 4697 } else if (phy->gmode || phy->rev >= 2) { 4698 if (pg->pg_nrssi[0] == -1000) { 4699 KASSERT(pg->pg_nrssi[1] == -1000, 4700 ("%s:%d: fail", __func__, __LINE__)); 4701 bwn_nrssi_slope_11g(mac); 4702 } else 4703 bwn_nrssi_threshold(mac); 4704 } 4705 if (phy->rf_rev == 8) 4706 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4707 bwn_phy_hwpctl_init(mac); 4708 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4709 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4710 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4711 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4712 } 4713 } 4714 4715 static uint8_t 4716 bwn_has_hwpctl(struct bwn_mac *mac) 4717 { 4718 4719 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4720 return (0); 4721 return (mac->mac_phy.use_hwpctl(mac)); 4722 } 4723 4724 static void 4725 bwn_phy_init_b5(struct bwn_mac *mac) 4726 { 4727 struct bwn_phy *phy = &mac->mac_phy; 4728 struct bwn_phy_g *pg = &phy->phy_g; 4729 struct bwn_softc *sc = mac->mac_sc; 4730 uint16_t offset, value; 4731 uint8_t old_channel; 4732 4733 if (phy->analog == 1) 4734 BWN_RF_SET(mac, 0x007a, 0x0050); 4735 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4736 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4737 value = 0x2120; 4738 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4739 BWN_PHY_WRITE(mac, offset, value); 4740 value += 0x202; 4741 } 4742 } 4743 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4744 if (phy->rf_ver == 0x2050) 4745 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4746 4747 if (phy->gmode || phy->rev >= 2) { 4748 if (phy->rf_ver == 0x2050) { 4749 BWN_RF_SET(mac, 0x007a, 0x0020); 4750 BWN_RF_SET(mac, 0x0051, 0x0004); 4751 } 4752 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4753 4754 BWN_PHY_SET(mac, 0x0802, 0x0100); 4755 BWN_PHY_SET(mac, 0x042b, 0x2000); 4756 4757 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4758 4759 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4760 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4761 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4762 } 4763 4764 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4765 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4766 4767 if (phy->analog == 1) { 4768 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4769 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4770 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4771 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4772 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4773 } else 4774 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4775 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4776 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4777 4778 if (phy->analog == 1) 4779 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4780 else 4781 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4782 4783 if (phy->analog == 0) 4784 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4785 4786 old_channel = phy->chan; 4787 bwn_phy_g_switch_chan(mac, 7, 0); 4788 4789 if (phy->rf_ver != 0x2050) { 4790 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4791 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4792 } 4793 4794 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4795 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4796 4797 if (phy->rf_ver == 0x2050) { 4798 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4799 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4800 } 4801 4802 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4803 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4804 BWN_RF_SET(mac, 0x007a, 0x0007); 4805 4806 bwn_phy_g_switch_chan(mac, old_channel, 0); 4807 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4808 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4809 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4810 4811 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4812 pg->pg_txctl); 4813 4814 if (phy->rf_ver == 0x2050) 4815 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4816 4817 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4818 } 4819 4820 static void 4821 bwn_loopback_calcgain(struct bwn_mac *mac) 4822 { 4823 struct bwn_phy *phy = &mac->mac_phy; 4824 struct bwn_phy_g *pg = &phy->phy_g; 4825 struct bwn_softc *sc = mac->mac_sc; 4826 uint16_t backup_phy[16] = { 0 }; 4827 uint16_t backup_radio[3]; 4828 uint16_t backup_bband; 4829 uint16_t i, j, loop_i_max; 4830 uint16_t trsw_rx; 4831 uint16_t loop1_outer_done, loop1_inner_done; 4832 4833 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4834 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4835 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4836 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4837 if (phy->rev != 1) { 4838 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4839 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4840 } 4841 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4842 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4843 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4844 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4845 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4846 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4847 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4848 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4849 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4850 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4851 backup_bband = pg->pg_bbatt.att; 4852 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4853 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4854 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4855 4856 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4857 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4858 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4859 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4860 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4861 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4862 if (phy->rev != 1) { 4863 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4864 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4865 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4866 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4867 } 4868 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4869 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4870 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4871 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4872 4873 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4874 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4875 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4876 4877 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4878 if (phy->rev != 1) { 4879 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4880 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4881 } 4882 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4883 4884 if (phy->rf_rev == 8) 4885 BWN_RF_WRITE(mac, 0x43, 0x000f); 4886 else { 4887 BWN_RF_WRITE(mac, 0x52, 0); 4888 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4889 } 4890 bwn_phy_g_set_bbatt(mac, 11); 4891 4892 if (phy->rev >= 3) 4893 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4894 else 4895 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 4896 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 4897 4898 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 4899 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 4900 4901 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 4902 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 4903 4904 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 4905 if (phy->rev >= 7) { 4906 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 4907 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 4908 } 4909 } 4910 BWN_RF_MASK(mac, 0x7a, 0x00f7); 4911 4912 j = 0; 4913 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 4914 for (i = 0; i < loop_i_max; i++) { 4915 for (j = 0; j < 16; j++) { 4916 BWN_RF_WRITE(mac, 0x43, i); 4917 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 4918 (j << 8)); 4919 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4920 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4921 DELAY(20); 4922 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4923 goto done0; 4924 } 4925 } 4926 done0: 4927 loop1_outer_done = i; 4928 loop1_inner_done = j; 4929 if (j >= 8) { 4930 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 4931 trsw_rx = 0x1b; 4932 for (j = j - 8; j < 16; j++) { 4933 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 4934 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 4935 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 4936 DELAY(20); 4937 trsw_rx -= 3; 4938 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 4939 goto done1; 4940 } 4941 } else 4942 trsw_rx = 0x18; 4943 done1: 4944 4945 if (phy->rev != 1) { 4946 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 4947 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 4948 } 4949 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 4950 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 4951 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 4952 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 4953 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 4954 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 4955 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 4956 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 4957 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 4958 4959 bwn_phy_g_set_bbatt(mac, backup_bband); 4960 4961 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 4962 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 4963 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 4964 4965 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 4966 DELAY(10); 4967 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 4968 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 4969 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 4970 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 4971 4972 pg->pg_max_lb_gain = 4973 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 4974 pg->pg_trsw_rx_gain = trsw_rx * 2; 4975 } 4976 4977 static uint16_t 4978 bwn_rf_init_bcm2050(struct bwn_mac *mac) 4979 { 4980 struct bwn_phy *phy = &mac->mac_phy; 4981 uint32_t tmp1 = 0, tmp2 = 0; 4982 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 4983 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 4984 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 4985 static const uint8_t rcc_table[] = { 4986 0x02, 0x03, 0x01, 0x0f, 4987 0x06, 0x07, 0x05, 0x0f, 4988 0x0a, 0x0b, 0x09, 0x0f, 4989 0x0e, 0x0f, 0x0d, 0x0f, 4990 }; 4991 4992 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 4993 rfoverval = rfover = cck3 = 0; 4994 radio0 = BWN_RF_READ(mac, 0x43); 4995 radio1 = BWN_RF_READ(mac, 0x51); 4996 radio2 = BWN_RF_READ(mac, 0x52); 4997 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4998 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4999 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5000 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5001 5002 if (phy->type == BWN_PHYTYPE_B) { 5003 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5004 reg0 = BWN_READ_2(mac, 0x3ec); 5005 5006 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5007 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5008 } else if (phy->gmode || phy->rev >= 2) { 5009 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5010 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5011 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5012 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5013 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5014 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5015 5016 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5017 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5018 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5019 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5020 if (BWN_HAS_LOOPBACK(phy)) { 5021 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5022 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5023 if (phy->rev >= 3) 5024 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5025 else 5026 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5027 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5028 } 5029 5030 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5031 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5032 BWN_LPD(0, 1, 1))); 5033 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5034 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5035 } 5036 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5037 5038 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5039 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5040 reg1 = BWN_READ_2(mac, 0x3e6); 5041 reg2 = BWN_READ_2(mac, 0x3f4); 5042 5043 if (phy->analog == 0) 5044 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5045 else { 5046 if (phy->analog >= 2) 5047 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5048 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5049 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5050 } 5051 5052 reg = BWN_RF_READ(mac, 0x60); 5053 index = (reg & 0x001e) >> 1; 5054 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5055 5056 if (phy->type == BWN_PHYTYPE_B) 5057 BWN_RF_WRITE(mac, 0x78, 0x26); 5058 if (phy->gmode || phy->rev >= 2) { 5059 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5060 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5061 BWN_LPD(0, 1, 1))); 5062 } 5063 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5064 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5065 if (phy->gmode || phy->rev >= 2) { 5066 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5067 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5068 BWN_LPD(0, 0, 1))); 5069 } 5070 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5071 BWN_RF_SET(mac, 0x51, 0x0004); 5072 if (phy->rf_rev == 8) 5073 BWN_RF_WRITE(mac, 0x43, 0x1f); 5074 else { 5075 BWN_RF_WRITE(mac, 0x52, 0); 5076 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5077 } 5078 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5079 5080 for (i = 0; i < 16; i++) { 5081 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5082 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5083 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5084 if (phy->gmode || phy->rev >= 2) { 5085 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5086 bwn_rf_2050_rfoverval(mac, 5087 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5088 } 5089 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5090 DELAY(10); 5091 if (phy->gmode || phy->rev >= 2) { 5092 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5093 bwn_rf_2050_rfoverval(mac, 5094 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5095 } 5096 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5097 DELAY(10); 5098 if (phy->gmode || phy->rev >= 2) { 5099 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5100 bwn_rf_2050_rfoverval(mac, 5101 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5102 } 5103 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5104 DELAY(20); 5105 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5106 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5107 if (phy->gmode || phy->rev >= 2) { 5108 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5109 bwn_rf_2050_rfoverval(mac, 5110 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5111 } 5112 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5113 } 5114 DELAY(10); 5115 5116 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5117 tmp1++; 5118 tmp1 >>= 9; 5119 5120 for (i = 0; i < 16; i++) { 5121 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5122 BWN_RF_WRITE(mac, 0x78, radio78); 5123 DELAY(10); 5124 for (j = 0; j < 16; j++) { 5125 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5126 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5127 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5128 if (phy->gmode || phy->rev >= 2) { 5129 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5130 bwn_rf_2050_rfoverval(mac, 5131 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5132 } 5133 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5134 DELAY(10); 5135 if (phy->gmode || phy->rev >= 2) { 5136 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5137 bwn_rf_2050_rfoverval(mac, 5138 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5139 } 5140 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5141 DELAY(10); 5142 if (phy->gmode || phy->rev >= 2) { 5143 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5144 bwn_rf_2050_rfoverval(mac, 5145 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5146 } 5147 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5148 DELAY(10); 5149 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5150 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5151 if (phy->gmode || phy->rev >= 2) { 5152 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5153 bwn_rf_2050_rfoverval(mac, 5154 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5155 } 5156 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5157 } 5158 tmp2++; 5159 tmp2 >>= 8; 5160 if (tmp1 < tmp2) 5161 break; 5162 } 5163 5164 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5165 BWN_RF_WRITE(mac, 0x51, radio1); 5166 BWN_RF_WRITE(mac, 0x52, radio2); 5167 BWN_RF_WRITE(mac, 0x43, radio0); 5168 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5169 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5170 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5171 BWN_WRITE_2(mac, 0x3e6, reg1); 5172 if (phy->analog != 0) 5173 BWN_WRITE_2(mac, 0x3f4, reg2); 5174 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5175 bwn_spu_workaround(mac, phy->chan); 5176 if (phy->type == BWN_PHYTYPE_B) { 5177 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5178 BWN_WRITE_2(mac, 0x3ec, reg0); 5179 } else if (phy->gmode) { 5180 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5181 BWN_READ_2(mac, BWN_PHY_RADIO) 5182 & 0x7fff); 5183 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5184 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5185 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5186 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5187 analogoverval); 5188 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5189 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5190 if (BWN_HAS_LOOPBACK(phy)) { 5191 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5192 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5193 } 5194 } 5195 5196 return ((i > 15) ? radio78 : rcc); 5197 } 5198 5199 static void 5200 bwn_phy_init_b6(struct bwn_mac *mac) 5201 { 5202 struct bwn_phy *phy = &mac->mac_phy; 5203 struct bwn_phy_g *pg = &phy->phy_g; 5204 struct bwn_softc *sc = mac->mac_sc; 5205 uint16_t offset, val; 5206 uint8_t old_channel; 5207 5208 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5209 ("%s:%d: fail", __func__, __LINE__)); 5210 5211 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5212 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5213 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5214 BWN_RF_WRITE(mac, 0x51, 0x37); 5215 BWN_RF_WRITE(mac, 0x52, 0x70); 5216 BWN_RF_WRITE(mac, 0x53, 0xb3); 5217 BWN_RF_WRITE(mac, 0x54, 0x9b); 5218 BWN_RF_WRITE(mac, 0x5a, 0x88); 5219 BWN_RF_WRITE(mac, 0x5b, 0x88); 5220 BWN_RF_WRITE(mac, 0x5d, 0x88); 5221 BWN_RF_WRITE(mac, 0x5e, 0x88); 5222 BWN_RF_WRITE(mac, 0x7d, 0x88); 5223 bwn_hf_write(mac, 5224 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5225 } 5226 if (phy->rf_rev == 8) { 5227 BWN_RF_WRITE(mac, 0x51, 0); 5228 BWN_RF_WRITE(mac, 0x52, 0x40); 5229 BWN_RF_WRITE(mac, 0x53, 0xb7); 5230 BWN_RF_WRITE(mac, 0x54, 0x98); 5231 BWN_RF_WRITE(mac, 0x5a, 0x88); 5232 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5233 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5234 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5235 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5236 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5237 } else { 5238 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5239 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5240 } 5241 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5242 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5243 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5244 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5245 } 5246 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5247 BWN_PHY_WRITE(mac, offset, val); 5248 val -= 0x0202; 5249 } 5250 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5251 BWN_PHY_WRITE(mac, offset, val); 5252 val -= 0x0202; 5253 } 5254 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5255 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5256 val += 0x0202; 5257 } 5258 if (phy->type == BWN_PHYTYPE_G) { 5259 BWN_RF_SET(mac, 0x007a, 0x0020); 5260 BWN_RF_SET(mac, 0x0051, 0x0004); 5261 BWN_PHY_SET(mac, 0x0802, 0x0100); 5262 BWN_PHY_SET(mac, 0x042b, 0x2000); 5263 BWN_PHY_WRITE(mac, 0x5b, 0); 5264 BWN_PHY_WRITE(mac, 0x5c, 0); 5265 } 5266 5267 old_channel = phy->chan; 5268 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5269 5270 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5271 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5272 DELAY(40); 5273 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5274 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5275 BWN_RF_WRITE(mac, 0x50, 0x20); 5276 } 5277 if (phy->rf_rev <= 2) { 5278 BWN_RF_WRITE(mac, 0x7c, 0x20); 5279 BWN_RF_WRITE(mac, 0x5a, 0x70); 5280 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5281 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5282 } 5283 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5284 5285 bwn_phy_g_switch_chan(mac, old_channel, 0); 5286 5287 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5288 if (phy->rf_rev >= 6) 5289 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5290 else 5291 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5292 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5293 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5294 pg->pg_txctl); 5295 if (phy->rf_rev <= 5) 5296 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5297 if (phy->rf_rev <= 2) 5298 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5299 5300 if (phy->analog == 4) { 5301 BWN_WRITE_2(mac, 0x3e4, 9); 5302 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5303 } else 5304 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5305 if (phy->type == BWN_PHYTYPE_B) 5306 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5307 else if (phy->type == BWN_PHYTYPE_G) 5308 BWN_WRITE_2(mac, 0x03e6, 0x0); 5309 } 5310 5311 static void 5312 bwn_phy_init_a(struct bwn_mac *mac) 5313 { 5314 struct bwn_phy *phy = &mac->mac_phy; 5315 struct bwn_softc *sc = mac->mac_sc; 5316 5317 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5318 ("%s:%d: fail", __func__, __LINE__)); 5319 5320 if (phy->rev >= 6) { 5321 if (phy->type == BWN_PHYTYPE_A) 5322 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5323 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5324 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5325 else 5326 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5327 } 5328 5329 bwn_wa_init(mac); 5330 5331 if (phy->type == BWN_PHYTYPE_G && 5332 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5333 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5334 } 5335 5336 static void 5337 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5338 { 5339 int i; 5340 5341 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5342 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5343 } 5344 5345 static void 5346 bwn_wa_agc(struct bwn_mac *mac) 5347 { 5348 struct bwn_phy *phy = &mac->mac_phy; 5349 5350 if (phy->rev == 1) { 5351 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5352 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5353 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5354 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5355 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5356 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5357 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5358 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5359 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5360 } else { 5361 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5362 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5363 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5364 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5365 } 5366 5367 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5368 0x5700); 5369 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5370 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5371 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5372 BWN_RF_SET(mac, 0x7a, 0x0008); 5373 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5374 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5375 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5376 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5377 if (phy->rev == 1) 5378 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5379 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5380 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5381 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5382 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5383 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5384 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5385 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5386 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5387 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5388 if (phy->rev == 1) { 5389 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5390 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5391 } else { 5392 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5393 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5394 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5395 if (phy->rev >= 6) { 5396 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5397 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5398 (uint16_t)~0xf000, 0x3000); 5399 } 5400 } 5401 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5402 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5403 if (phy->rev == 1) { 5404 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5405 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5406 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5407 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5408 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5409 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5410 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5411 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5412 } else { 5413 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5414 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5415 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5416 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5417 } 5418 if (phy->rev >= 6) { 5419 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5420 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5421 } 5422 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5423 } 5424 5425 static void 5426 bwn_wa_grev1(struct bwn_mac *mac) 5427 { 5428 struct bwn_phy *phy = &mac->mac_phy; 5429 int i; 5430 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5431 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5432 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5433 5434 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5435 5436 /* init CRSTHRES and ANTDWELL */ 5437 if (phy->rev == 1) { 5438 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5439 } else if (phy->rev == 2) { 5440 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5441 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5442 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5443 } else { 5444 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5445 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5446 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5447 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5448 } 5449 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5450 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5451 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5452 5453 /* XXX support PHY-A??? */ 5454 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5455 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5456 bwn_tab_finefreqg[i]); 5457 5458 /* XXX support PHY-A??? */ 5459 if (phy->rev == 1) 5460 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5462 bwn_tab_noise_g1[i]); 5463 else 5464 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5466 bwn_tab_noise_g2[i]); 5467 5468 5469 for (i = 0; i < N(bwn_tab_rotor); i++) 5470 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5471 bwn_tab_rotor[i]); 5472 5473 /* XXX support PHY-A??? */ 5474 if (phy->rev >= 6) { 5475 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5476 BWN_PHY_ENCORE_EN) 5477 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5478 else 5479 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5480 } else 5481 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5482 5483 for (i = 0; i < N(bwn_tab_retard); i++) 5484 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5485 bwn_tab_retard[i]); 5486 5487 if (phy->rev == 1) { 5488 for (i = 0; i < 16; i++) 5489 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5490 i, 0x0020); 5491 } else { 5492 for (i = 0; i < 32; i++) 5493 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5494 } 5495 5496 bwn_wa_agc(mac); 5497 } 5498 5499 static void 5500 bwn_wa_grev26789(struct bwn_mac *mac) 5501 { 5502 struct bwn_phy *phy = &mac->mac_phy; 5503 int i; 5504 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5505 uint16_t ofdmrev; 5506 5507 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5508 5509 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5510 5511 /* init CRSTHRES and ANTDWELL */ 5512 if (phy->rev == 1) 5513 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5514 else if (phy->rev == 2) { 5515 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5516 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5517 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5518 } else { 5519 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5520 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5521 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5522 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5523 } 5524 5525 for (i = 0; i < 64; i++) 5526 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5527 5528 /* XXX support PHY-A??? */ 5529 if (phy->rev == 1) 5530 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5531 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5532 bwn_tab_noise_g1[i]); 5533 else 5534 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5535 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5536 bwn_tab_noise_g2[i]); 5537 5538 /* XXX support PHY-A??? */ 5539 if (phy->rev >= 6) { 5540 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5541 BWN_PHY_ENCORE_EN) 5542 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5543 else 5544 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5545 } else 5546 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5547 5548 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5549 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5550 bwn_tab_sigmasqr2[i]); 5551 5552 if (phy->rev == 1) { 5553 for (i = 0; i < 16; i++) 5554 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5555 0x0020); 5556 } else { 5557 for (i = 0; i < 32; i++) 5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5559 } 5560 5561 bwn_wa_agc(mac); 5562 5563 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5564 if (ofdmrev > 2) { 5565 if (phy->type == BWN_PHYTYPE_A) 5566 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5567 else 5568 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5569 } else { 5570 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5571 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5573 } 5574 5575 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5576 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5577 } 5578 5579 static void 5580 bwn_wa_init(struct bwn_mac *mac) 5581 { 5582 struct bwn_phy *phy = &mac->mac_phy; 5583 struct bwn_softc *sc = mac->mac_sc; 5584 5585 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5586 5587 switch (phy->rev) { 5588 case 1: 5589 bwn_wa_grev1(mac); 5590 break; 5591 case 2: 5592 case 6: 5593 case 7: 5594 case 8: 5595 case 9: 5596 bwn_wa_grev26789(mac); 5597 break; 5598 default: 5599 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5600 } 5601 5602 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5603 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5604 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5605 if (phy->rev < 2) { 5606 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5607 0x0002); 5608 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5609 0x0001); 5610 } else { 5611 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5612 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5613 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5614 BWN_BFL_EXTLNA) && 5615 (phy->rev >= 7)) { 5616 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5617 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5618 0x0020, 0x0001); 5619 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5620 0x0021, 0x0001); 5621 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5622 0x0022, 0x0001); 5623 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5624 0x0023, 0x0000); 5625 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5626 0x0000, 0x0000); 5627 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5628 0x0003, 0x0002); 5629 } 5630 } 5631 } 5632 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5633 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5634 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5635 } 5636 5637 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5639 } 5640 5641 static void 5642 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5643 uint16_t value) 5644 { 5645 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5646 uint16_t addr; 5647 5648 addr = table + offset; 5649 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5650 (addr - 1 != pg->pg_ofdmtab_addr)) { 5651 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5652 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5653 } 5654 pg->pg_ofdmtab_addr = addr; 5655 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5656 } 5657 5658 static void 5659 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5660 uint32_t value) 5661 { 5662 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5663 uint16_t addr; 5664 5665 addr = table + offset; 5666 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5667 (addr - 1 != pg->pg_ofdmtab_addr)) { 5668 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5669 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5670 } 5671 pg->pg_ofdmtab_addr = addr; 5672 5673 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5674 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5675 } 5676 5677 static void 5678 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5679 uint16_t value) 5680 { 5681 5682 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5683 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5684 } 5685 5686 static void 5687 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5688 { 5689 struct bwn_phy *phy = &mac->mac_phy; 5690 struct bwn_softc *sc = mac->mac_sc; 5691 unsigned int i, max_loop; 5692 uint16_t value; 5693 uint32_t buffer[5] = { 5694 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5695 }; 5696 5697 if (ofdm) { 5698 max_loop = 0x1e; 5699 buffer[0] = 0x000201cc; 5700 } else { 5701 max_loop = 0xfa; 5702 buffer[0] = 0x000b846e; 5703 } 5704 5705 BWN_ASSERT_LOCKED(mac->mac_sc); 5706 5707 for (i = 0; i < 5; i++) 5708 bwn_ram_write(mac, i * 4, buffer[i]); 5709 5710 BWN_WRITE_2(mac, 0x0568, 0x0000); 5711 BWN_WRITE_2(mac, 0x07c0, 5712 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5713 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5714 BWN_WRITE_2(mac, 0x050c, value); 5715 if (phy->type == BWN_PHYTYPE_LP) 5716 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5717 BWN_WRITE_2(mac, 0x0508, 0x0000); 5718 BWN_WRITE_2(mac, 0x050a, 0x0000); 5719 BWN_WRITE_2(mac, 0x054c, 0x0000); 5720 BWN_WRITE_2(mac, 0x056a, 0x0014); 5721 BWN_WRITE_2(mac, 0x0568, 0x0826); 5722 BWN_WRITE_2(mac, 0x0500, 0x0000); 5723 if (phy->type == BWN_PHYTYPE_LP) 5724 BWN_WRITE_2(mac, 0x0502, 0x0050); 5725 else 5726 BWN_WRITE_2(mac, 0x0502, 0x0030); 5727 5728 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5729 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5730 for (i = 0x00; i < max_loop; i++) { 5731 value = BWN_READ_2(mac, 0x050e); 5732 if (value & 0x0080) 5733 break; 5734 DELAY(10); 5735 } 5736 for (i = 0x00; i < 0x0a; i++) { 5737 value = BWN_READ_2(mac, 0x050e); 5738 if (value & 0x0400) 5739 break; 5740 DELAY(10); 5741 } 5742 for (i = 0x00; i < 0x19; i++) { 5743 value = BWN_READ_2(mac, 0x0690); 5744 if (!(value & 0x0100)) 5745 break; 5746 DELAY(10); 5747 } 5748 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5749 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5750 } 5751 5752 static void 5753 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5754 { 5755 uint32_t macctl; 5756 5757 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5758 5759 macctl = BWN_READ_4(mac, BWN_MACCTL); 5760 if (macctl & BWN_MACCTL_BIGENDIAN) 5761 printf("TODO: need swap\n"); 5762 5763 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5764 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5765 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5766 } 5767 5768 static void 5769 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5770 { 5771 uint16_t value; 5772 5773 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5774 ("%s:%d: fail", __func__, __LINE__)); 5775 5776 value = (uint8_t) (ctl->q); 5777 value |= ((uint8_t) (ctl->i)) << 8; 5778 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5779 } 5780 5781 static uint16_t 5782 bwn_lo_calcfeed(struct bwn_mac *mac, 5783 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5784 { 5785 struct bwn_phy *phy = &mac->mac_phy; 5786 struct bwn_softc *sc = mac->mac_sc; 5787 uint16_t rfover; 5788 uint16_t feedthrough; 5789 5790 if (phy->gmode) { 5791 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5792 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5793 5794 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5795 ("%s:%d: fail", __func__, __LINE__)); 5796 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5797 ("%s:%d: fail", __func__, __LINE__)); 5798 5799 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5800 5801 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5802 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5803 phy->rev > 6) 5804 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5805 5806 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5807 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5808 DELAY(10); 5809 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5810 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5811 DELAY(10); 5812 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5813 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5814 DELAY(10); 5815 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5816 } else { 5817 pga |= BWN_PHY_PGACTL_UNKNOWN; 5818 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5819 DELAY(10); 5820 pga |= BWN_PHY_PGACTL_LOWBANDW; 5821 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5822 DELAY(10); 5823 pga |= BWN_PHY_PGACTL_LPF; 5824 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5825 } 5826 DELAY(21); 5827 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5828 5829 return (feedthrough); 5830 } 5831 5832 static uint16_t 5833 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5834 uint16_t *value, uint16_t *pad_mix_gain) 5835 { 5836 struct bwn_phy *phy = &mac->mac_phy; 5837 uint16_t reg, v, padmix; 5838 5839 if (phy->type == BWN_PHYTYPE_B) { 5840 v = 0x30; 5841 if (phy->rf_rev <= 5) { 5842 reg = 0x43; 5843 padmix = 0; 5844 } else { 5845 reg = 0x52; 5846 padmix = 5; 5847 } 5848 } else { 5849 if (phy->rev >= 2 && phy->rf_rev == 8) { 5850 reg = 0x43; 5851 v = 0x10; 5852 padmix = 2; 5853 } else { 5854 reg = 0x52; 5855 v = 0x30; 5856 padmix = 5; 5857 } 5858 } 5859 if (value) 5860 *value = v; 5861 if (pad_mix_gain) 5862 *pad_mix_gain = padmix; 5863 5864 return (reg); 5865 } 5866 5867 static void 5868 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5869 { 5870 struct bwn_phy *phy = &mac->mac_phy; 5871 struct bwn_phy_g *pg = &phy->phy_g; 5872 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5873 uint16_t reg, mask; 5874 uint16_t trsw_rx, pga; 5875 uint16_t rf_pctl_reg; 5876 5877 static const uint8_t tx_bias_values[] = { 5878 0x09, 0x08, 0x0a, 0x01, 0x00, 5879 0x02, 0x05, 0x04, 0x06, 5880 }; 5881 static const uint8_t tx_magn_values[] = { 5882 0x70, 0x40, 5883 }; 5884 5885 if (!BWN_HAS_LOOPBACK(phy)) { 5886 rf_pctl_reg = 6; 5887 trsw_rx = 2; 5888 pga = 0; 5889 } else { 5890 int lb_gain; 5891 5892 trsw_rx = 0; 5893 lb_gain = pg->pg_max_lb_gain / 2; 5894 if (lb_gain > 10) { 5895 rf_pctl_reg = 0; 5896 pga = abs(10 - lb_gain) / 6; 5897 pga = MIN(MAX(pga, 0), 15); 5898 } else { 5899 int cmp_val; 5900 int tmp; 5901 5902 pga = 0; 5903 cmp_val = 0x24; 5904 if ((phy->rev >= 2) && 5905 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 5906 cmp_val = 0x3c; 5907 tmp = lb_gain; 5908 if ((10 - lb_gain) < cmp_val) 5909 tmp = (10 - lb_gain); 5910 if (tmp < 0) 5911 tmp += 6; 5912 else 5913 tmp += 3; 5914 cmp_val /= 4; 5915 tmp /= 4; 5916 if (tmp >= cmp_val) 5917 rf_pctl_reg = cmp_val; 5918 else 5919 rf_pctl_reg = tmp; 5920 } 5921 } 5922 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 5923 bwn_phy_g_set_bbatt(mac, 2); 5924 5925 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 5926 mask = ~mask; 5927 BWN_RF_MASK(mac, reg, mask); 5928 5929 if (BWN_HAS_TXMAG(phy)) { 5930 int i, j; 5931 int feedthrough; 5932 int min_feedth = 0xffff; 5933 uint8_t tx_magn, tx_bias; 5934 5935 for (i = 0; i < N(tx_magn_values); i++) { 5936 tx_magn = tx_magn_values[i]; 5937 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 5938 for (j = 0; j < N(tx_bias_values); j++) { 5939 tx_bias = tx_bias_values[j]; 5940 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 5941 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 5942 trsw_rx); 5943 if (feedthrough < min_feedth) { 5944 lo->tx_bias = tx_bias; 5945 lo->tx_magn = tx_magn; 5946 min_feedth = feedthrough; 5947 } 5948 if (lo->tx_bias == 0) 5949 break; 5950 } 5951 BWN_RF_WRITE(mac, 0x52, 5952 (BWN_RF_READ(mac, 0x52) 5953 & 0xff00) | lo->tx_bias | lo-> 5954 tx_magn); 5955 } 5956 } else { 5957 lo->tx_magn = 0; 5958 lo->tx_bias = 0; 5959 BWN_RF_MASK(mac, 0x52, 0xfff0); 5960 } 5961 5962 BWN_GETTIME(lo->txctl_measured_time); 5963 } 5964 5965 static void 5966 bwn_lo_get_powervector(struct bwn_mac *mac) 5967 { 5968 struct bwn_phy *phy = &mac->mac_phy; 5969 struct bwn_phy_g *pg = &phy->phy_g; 5970 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5971 int i; 5972 uint64_t tmp; 5973 uint64_t power_vector = 0; 5974 5975 for (i = 0; i < 8; i += 2) { 5976 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 5977 power_vector |= (tmp << (i * 8)); 5978 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 5979 } 5980 if (power_vector) 5981 lo->power_vector = power_vector; 5982 5983 BWN_GETTIME(lo->pwr_vec_read_time); 5984 } 5985 5986 static void 5987 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 5988 int use_trsw_rx) 5989 { 5990 struct bwn_phy *phy = &mac->mac_phy; 5991 struct bwn_phy_g *pg = &phy->phy_g; 5992 uint16_t tmp; 5993 5994 if (max_rx_gain < 0) 5995 max_rx_gain = 0; 5996 5997 if (BWN_HAS_LOOPBACK(phy)) { 5998 int trsw_rx = 0; 5999 int trsw_rx_gain; 6000 6001 if (use_trsw_rx) { 6002 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6003 if (max_rx_gain >= trsw_rx_gain) { 6004 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6005 trsw_rx = 0x20; 6006 } 6007 } else 6008 trsw_rx_gain = max_rx_gain; 6009 if (trsw_rx_gain < 9) { 6010 pg->pg_lna_lod_gain = 0; 6011 } else { 6012 pg->pg_lna_lod_gain = 1; 6013 trsw_rx_gain -= 8; 6014 } 6015 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6016 pg->pg_pga_gain = trsw_rx_gain / 3; 6017 if (pg->pg_pga_gain >= 5) { 6018 pg->pg_pga_gain -= 5; 6019 pg->pg_lna_gain = 2; 6020 } else 6021 pg->pg_lna_gain = 0; 6022 } else { 6023 pg->pg_lna_gain = 0; 6024 pg->pg_trsw_rx_gain = 0x20; 6025 if (max_rx_gain >= 0x14) { 6026 pg->pg_lna_lod_gain = 1; 6027 pg->pg_pga_gain = 2; 6028 } else if (max_rx_gain >= 0x12) { 6029 pg->pg_lna_lod_gain = 1; 6030 pg->pg_pga_gain = 1; 6031 } else if (max_rx_gain >= 0xf) { 6032 pg->pg_lna_lod_gain = 1; 6033 pg->pg_pga_gain = 0; 6034 } else { 6035 pg->pg_lna_lod_gain = 0; 6036 pg->pg_pga_gain = 0; 6037 } 6038 } 6039 6040 tmp = BWN_RF_READ(mac, 0x7a); 6041 if (pg->pg_lna_lod_gain == 0) 6042 tmp &= ~0x0008; 6043 else 6044 tmp |= 0x0008; 6045 BWN_RF_WRITE(mac, 0x7a, tmp); 6046 } 6047 6048 static void 6049 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6050 { 6051 struct bwn_phy *phy = &mac->mac_phy; 6052 struct bwn_phy_g *pg = &phy->phy_g; 6053 struct bwn_softc *sc = mac->mac_sc; 6054 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6055 struct timespec ts; 6056 uint16_t tmp; 6057 6058 if (bwn_has_hwpctl(mac)) { 6059 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6060 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6061 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6062 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6063 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6064 6065 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6066 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6067 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6068 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6069 } 6070 if (phy->type == BWN_PHYTYPE_B && 6071 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6072 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6073 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6074 } 6075 if (phy->rev >= 2) { 6076 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6077 sav->phy_analogoverval = 6078 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6079 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6080 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6081 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6082 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6083 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6084 6085 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6086 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6087 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6088 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6089 if (phy->type == BWN_PHYTYPE_G) { 6090 if ((phy->rev >= 7) && 6091 (siba_sprom_get_bf_lo(sc->sc_dev) & 6092 BWN_BFL_EXTLNA)) { 6093 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6094 } else { 6095 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6096 } 6097 } else { 6098 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6099 } 6100 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6101 } 6102 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6103 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6104 sav->rf0 = BWN_RF_READ(mac, 0x43); 6105 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6106 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6107 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6108 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6109 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6110 6111 if (!BWN_HAS_TXMAG(phy)) { 6112 sav->rf2 = BWN_RF_READ(mac, 0x52); 6113 sav->rf2 &= 0x00f0; 6114 } 6115 if (phy->type == BWN_PHYTYPE_B) { 6116 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6117 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6118 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6119 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6120 } else { 6121 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6122 | 0x8000); 6123 } 6124 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6125 & 0xf000); 6126 6127 tmp = 6128 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6129 BWN_PHY_WRITE(mac, tmp, 0x007f); 6130 6131 tmp = sav->phy_syncctl; 6132 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6133 tmp = sav->rf1; 6134 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6135 6136 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6137 if (phy->type == BWN_PHYTYPE_G || 6138 (phy->type == BWN_PHYTYPE_B && 6139 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6140 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6141 } else 6142 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6143 if (phy->rev >= 2) 6144 bwn_dummy_transmission(mac, 0, 1); 6145 bwn_phy_g_switch_chan(mac, 6, 0); 6146 BWN_RF_READ(mac, 0x51); 6147 if (phy->type == BWN_PHYTYPE_G) 6148 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6149 6150 nanouptime(&ts); 6151 if (time_before(lo->txctl_measured_time, 6152 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6153 bwn_lo_measure_txctl_values(mac); 6154 6155 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6156 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6157 else { 6158 if (phy->type == BWN_PHYTYPE_B) 6159 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6160 else 6161 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6162 } 6163 } 6164 6165 static void 6166 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6167 { 6168 struct bwn_phy *phy = &mac->mac_phy; 6169 struct bwn_phy_g *pg = &phy->phy_g; 6170 uint16_t tmp; 6171 6172 if (phy->rev >= 2) { 6173 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6174 tmp = (pg->pg_pga_gain << 8); 6175 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6176 DELAY(5); 6177 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6178 DELAY(2); 6179 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6180 } else { 6181 tmp = (pg->pg_pga_gain | 0xefa0); 6182 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6183 } 6184 if (phy->type == BWN_PHYTYPE_G) { 6185 if (phy->rev >= 3) 6186 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6187 else 6188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6189 if (phy->rev >= 2) 6190 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6191 else 6192 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6193 } 6194 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6195 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6196 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6197 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6198 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6199 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6200 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6201 if (!BWN_HAS_TXMAG(phy)) { 6202 tmp = sav->rf2; 6203 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6204 } 6205 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6206 if (phy->type == BWN_PHYTYPE_B && 6207 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6208 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6209 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6210 } 6211 if (phy->rev >= 2) { 6212 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6213 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6214 sav->phy_analogoverval); 6215 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6216 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6217 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6218 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6219 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6220 } 6221 if (bwn_has_hwpctl(mac)) { 6222 tmp = (sav->phy_lomask & 0xbfff); 6223 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6224 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6225 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6226 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6227 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6228 } 6229 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6230 } 6231 6232 static int 6233 bwn_lo_probe_loctl(struct bwn_mac *mac, 6234 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6235 { 6236 struct bwn_phy *phy = &mac->mac_phy; 6237 struct bwn_phy_g *pg = &phy->phy_g; 6238 struct bwn_loctl orig, test; 6239 struct bwn_loctl prev = { -100, -100 }; 6240 static const struct bwn_loctl modifiers[] = { 6241 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6242 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6243 }; 6244 int begin, end, lower = 0, i; 6245 uint16_t feedth; 6246 6247 if (d->curstate == 0) { 6248 begin = 1; 6249 end = 8; 6250 } else if (d->curstate % 2 == 0) { 6251 begin = d->curstate - 1; 6252 end = d->curstate + 1; 6253 } else { 6254 begin = d->curstate - 2; 6255 end = d->curstate + 2; 6256 } 6257 if (begin < 1) 6258 begin += 8; 6259 if (end > 8) 6260 end -= 8; 6261 6262 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6263 i = begin; 6264 d->curstate = i; 6265 while (1) { 6266 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6267 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6268 test.i += modifiers[i - 1].i * d->multipler; 6269 test.q += modifiers[i - 1].q * d->multipler; 6270 if ((test.i != prev.i || test.q != prev.q) && 6271 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6272 bwn_lo_write(mac, &test); 6273 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6274 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6275 if (feedth < d->feedth) { 6276 memcpy(probe, &test, 6277 sizeof(struct bwn_loctl)); 6278 lower = 1; 6279 d->feedth = feedth; 6280 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6281 break; 6282 } 6283 } 6284 memcpy(&prev, &test, sizeof(prev)); 6285 if (i == end) 6286 break; 6287 if (i == 8) 6288 i = 1; 6289 else 6290 i++; 6291 d->curstate = i; 6292 } 6293 6294 return (lower); 6295 } 6296 6297 static void 6298 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6299 { 6300 struct bwn_phy *phy = &mac->mac_phy; 6301 struct bwn_phy_g *pg = &phy->phy_g; 6302 struct bwn_lo_g_sm d; 6303 struct bwn_loctl probe; 6304 int lower, repeat, cnt = 0; 6305 uint16_t feedth; 6306 6307 d.nmeasure = 0; 6308 d.multipler = 1; 6309 if (BWN_HAS_LOOPBACK(phy)) 6310 d.multipler = 3; 6311 6312 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6313 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6314 6315 do { 6316 bwn_lo_write(mac, &d.loctl); 6317 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6318 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6319 if (feedth < 0x258) { 6320 if (feedth >= 0x12c) 6321 *rxgain += 6; 6322 else 6323 *rxgain += 3; 6324 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6325 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6326 } 6327 d.feedth = feedth; 6328 d.curstate = 0; 6329 do { 6330 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6331 ("%s:%d: fail", __func__, __LINE__)); 6332 memcpy(&probe, &d.loctl, 6333 sizeof(struct bwn_loctl)); 6334 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6335 if (!lower) 6336 break; 6337 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6338 break; 6339 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6340 d.nmeasure++; 6341 } while (d.nmeasure < 24); 6342 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6343 6344 if (BWN_HAS_LOOPBACK(phy)) { 6345 if (d.feedth > 0x1194) 6346 *rxgain -= 6; 6347 else if (d.feedth < 0x5dc) 6348 *rxgain += 3; 6349 if (cnt == 0) { 6350 if (d.feedth <= 0x5dc) { 6351 d.multipler = 1; 6352 cnt++; 6353 } else 6354 d.multipler = 2; 6355 } else if (cnt == 2) 6356 d.multipler = 1; 6357 } 6358 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6359 } while (++cnt < repeat); 6360 } 6361 6362 static struct bwn_lo_calib * 6363 bwn_lo_calibset(struct bwn_mac *mac, 6364 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6365 { 6366 struct bwn_phy *phy = &mac->mac_phy; 6367 struct bwn_phy_g *pg = &phy->phy_g; 6368 struct bwn_loctl loctl = { 0, 0 }; 6369 struct bwn_lo_calib *cal; 6370 struct bwn_lo_g_value sval = { 0 }; 6371 int rxgain; 6372 uint16_t pad, reg, value; 6373 6374 sval.old_channel = phy->chan; 6375 bwn_mac_suspend(mac); 6376 bwn_lo_save(mac, &sval); 6377 6378 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6379 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6380 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6381 6382 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6383 if (rfatt->padmix) 6384 rxgain -= pad; 6385 if (BWN_HAS_LOOPBACK(phy)) 6386 rxgain += pg->pg_max_lb_gain; 6387 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6388 bwn_phy_g_set_bbatt(mac, bbatt->att); 6389 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6390 6391 bwn_lo_restore(mac, &sval); 6392 bwn_mac_enable(mac); 6393 6394 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6395 if (!cal) { 6396 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6397 return (NULL); 6398 } 6399 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6400 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6401 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6402 6403 BWN_GETTIME(cal->calib_time); 6404 6405 return (cal); 6406 } 6407 6408 static struct bwn_lo_calib * 6409 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6410 const struct bwn_rfatt *rfatt) 6411 { 6412 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6413 struct bwn_lo_calib *c; 6414 6415 TAILQ_FOREACH(c, &lo->calib_list, list) { 6416 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6417 continue; 6418 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6419 continue; 6420 return (c); 6421 } 6422 6423 c = bwn_lo_calibset(mac, bbatt, rfatt); 6424 if (!c) 6425 return (NULL); 6426 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6427 6428 return (c); 6429 } 6430 6431 static void 6432 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6433 { 6434 struct bwn_phy *phy = &mac->mac_phy; 6435 struct bwn_phy_g *pg = &phy->phy_g; 6436 struct bwn_softc *sc = mac->mac_sc; 6437 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6438 const struct bwn_rfatt *rfatt; 6439 const struct bwn_bbatt *bbatt; 6440 uint64_t pvector; 6441 int i; 6442 int rf_offset, bb_offset; 6443 uint8_t changed = 0; 6444 6445 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6446 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6447 ("%s:%d: fail", __func__, __LINE__)); 6448 6449 pvector = lo->power_vector; 6450 if (!update && !pvector) 6451 return; 6452 6453 bwn_mac_suspend(mac); 6454 6455 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6456 struct bwn_lo_calib *cal; 6457 int idx; 6458 uint16_t val; 6459 6460 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6461 continue; 6462 bb_offset = i / lo->rfatt.len; 6463 rf_offset = i % lo->rfatt.len; 6464 bbatt = &(lo->bbatt.array[bb_offset]); 6465 rfatt = &(lo->rfatt.array[rf_offset]); 6466 6467 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6468 if (!cal) { 6469 device_printf(sc->sc_dev, "LO: Could not " 6470 "calibrate DC table entry\n"); 6471 continue; 6472 } 6473 val = (uint8_t)(cal->ctl.q); 6474 val |= ((uint8_t)(cal->ctl.i)) << 4; 6475 free(cal, M_DEVBUF); 6476 6477 idx = i / 2; 6478 if (i % 2) 6479 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6480 | ((val & 0x00ff) << 8); 6481 else 6482 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6483 | (val & 0x00ff); 6484 changed = 1; 6485 } 6486 if (changed) { 6487 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6488 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6489 } 6490 bwn_mac_enable(mac); 6491 } 6492 6493 static void 6494 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6495 { 6496 6497 if (!rf->padmix) 6498 return; 6499 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6500 rf->att = 4; 6501 } 6502 6503 static void 6504 bwn_lo_g_adjust(struct bwn_mac *mac) 6505 { 6506 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6507 struct bwn_lo_calib *cal; 6508 struct bwn_rfatt rf; 6509 6510 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6511 bwn_lo_fixup_rfatt(&rf); 6512 6513 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6514 if (!cal) 6515 return; 6516 bwn_lo_write(mac, &cal->ctl); 6517 } 6518 6519 static void 6520 bwn_lo_g_init(struct bwn_mac *mac) 6521 { 6522 6523 if (!bwn_has_hwpctl(mac)) 6524 return; 6525 6526 bwn_lo_get_powervector(mac); 6527 bwn_phy_g_dc_lookup_init(mac, 1); 6528 } 6529 6530 static void 6531 bwn_mac_suspend(struct bwn_mac *mac) 6532 { 6533 struct bwn_softc *sc = mac->mac_sc; 6534 int i; 6535 uint32_t tmp; 6536 6537 KASSERT(mac->mac_suspended >= 0, 6538 ("%s:%d: fail", __func__, __LINE__)); 6539 6540 if (mac->mac_suspended == 0) { 6541 bwn_psctl(mac, BWN_PS_AWAKE); 6542 BWN_WRITE_4(mac, BWN_MACCTL, 6543 BWN_READ_4(mac, BWN_MACCTL) 6544 & ~BWN_MACCTL_ON); 6545 BWN_READ_4(mac, BWN_MACCTL); 6546 for (i = 35; i; i--) { 6547 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6548 if (tmp & BWN_INTR_MAC_SUSPENDED) 6549 goto out; 6550 DELAY(10); 6551 } 6552 for (i = 40; i; i--) { 6553 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6554 if (tmp & BWN_INTR_MAC_SUSPENDED) 6555 goto out; 6556 DELAY(1000); 6557 } 6558 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6559 } 6560 out: 6561 mac->mac_suspended++; 6562 } 6563 6564 static void 6565 bwn_mac_enable(struct bwn_mac *mac) 6566 { 6567 struct bwn_softc *sc = mac->mac_sc; 6568 uint16_t state; 6569 6570 state = bwn_shm_read_2(mac, BWN_SHARED, 6571 BWN_SHARED_UCODESTAT); 6572 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6573 state != BWN_SHARED_UCODESTAT_SLEEP) 6574 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6575 6576 mac->mac_suspended--; 6577 KASSERT(mac->mac_suspended >= 0, 6578 ("%s:%d: fail", __func__, __LINE__)); 6579 if (mac->mac_suspended == 0) { 6580 BWN_WRITE_4(mac, BWN_MACCTL, 6581 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6582 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6583 BWN_READ_4(mac, BWN_MACCTL); 6584 BWN_READ_4(mac, BWN_INTR_REASON); 6585 bwn_psctl(mac, 0); 6586 } 6587 } 6588 6589 static void 6590 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6591 { 6592 struct bwn_softc *sc = mac->mac_sc; 6593 int i; 6594 uint16_t ucstat; 6595 6596 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6597 ("%s:%d: fail", __func__, __LINE__)); 6598 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6599 ("%s:%d: fail", __func__, __LINE__)); 6600 6601 /* XXX forcibly awake and hwps-off */ 6602 6603 BWN_WRITE_4(mac, BWN_MACCTL, 6604 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6605 ~BWN_MACCTL_HWPS); 6606 BWN_READ_4(mac, BWN_MACCTL); 6607 if (siba_get_revid(sc->sc_dev) >= 5) { 6608 for (i = 0; i < 100; i++) { 6609 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6610 BWN_SHARED_UCODESTAT); 6611 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6612 break; 6613 DELAY(10); 6614 } 6615 } 6616 } 6617 6618 static int16_t 6619 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6620 { 6621 6622 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6623 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6624 } 6625 6626 static void 6627 bwn_nrssi_threshold(struct bwn_mac *mac) 6628 { 6629 struct bwn_phy *phy = &mac->mac_phy; 6630 struct bwn_phy_g *pg = &phy->phy_g; 6631 struct bwn_softc *sc = mac->mac_sc; 6632 int32_t a, b; 6633 int16_t tmp16; 6634 uint16_t tmpu16; 6635 6636 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6637 6638 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6639 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6640 a = 0x13; 6641 b = 0x12; 6642 } else { 6643 a = 0xe; 6644 b = 0x11; 6645 } 6646 6647 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6648 a += (pg->pg_nrssi[0] << 6); 6649 a += (a < 32) ? 31 : 32; 6650 a = a >> 6; 6651 a = MIN(MAX(a, -31), 31); 6652 6653 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6654 b += (pg->pg_nrssi[0] << 6); 6655 if (b < 32) 6656 b += 31; 6657 else 6658 b += 32; 6659 b = b >> 6; 6660 b = MIN(MAX(b, -31), 31); 6661 6662 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6663 tmpu16 |= ((uint32_t)b & 0x0000003f); 6664 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6665 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6666 return; 6667 } 6668 6669 tmp16 = bwn_nrssi_read(mac, 0x20); 6670 if (tmp16 >= 0x20) 6671 tmp16 -= 0x40; 6672 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6673 } 6674 6675 static void 6676 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6677 { 6678 #define SAVE_RF_MAX 3 6679 #define SAVE_PHY_COMM_MAX 4 6680 #define SAVE_PHY3_MAX 8 6681 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6682 { 0x7a, 0x52, 0x43 }; 6683 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6684 { 0x15, 0x5a, 0x59, 0x58 }; 6685 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6686 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6687 0x0801, 0x0060, 0x0014, 0x0478 6688 }; 6689 struct bwn_phy *phy = &mac->mac_phy; 6690 struct bwn_phy_g *pg = &phy->phy_g; 6691 int32_t i, tmp32, phy3_idx = 0; 6692 uint16_t delta, tmp; 6693 uint16_t save_rf[SAVE_RF_MAX]; 6694 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6695 uint16_t save_phy3[SAVE_PHY3_MAX]; 6696 uint16_t ant_div, phy0, chan_ex; 6697 int16_t nrssi0, nrssi1; 6698 6699 KASSERT(phy->type == BWN_PHYTYPE_G, 6700 ("%s:%d: fail", __func__, __LINE__)); 6701 6702 if (phy->rf_rev >= 9) 6703 return; 6704 if (phy->rf_rev == 8) 6705 bwn_nrssi_offset(mac); 6706 6707 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6708 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6709 6710 /* 6711 * Save RF/PHY registers for later restoration 6712 */ 6713 ant_div = BWN_READ_2(mac, 0x03e2); 6714 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6715 for (i = 0; i < SAVE_RF_MAX; ++i) 6716 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6717 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6718 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6719 6720 phy0 = BWN_READ_2(mac, BWN_PHY0); 6721 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6722 if (phy->rev >= 3) { 6723 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6724 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6725 BWN_PHY_WRITE(mac, 0x002e, 0); 6726 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6727 switch (phy->rev) { 6728 case 4: 6729 case 6: 6730 case 7: 6731 BWN_PHY_SET(mac, 0x0478, 0x0100); 6732 BWN_PHY_SET(mac, 0x0801, 0x0040); 6733 break; 6734 case 3: 6735 case 5: 6736 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6737 break; 6738 } 6739 BWN_PHY_SET(mac, 0x0060, 0x0040); 6740 BWN_PHY_SET(mac, 0x0014, 0x0200); 6741 } 6742 /* 6743 * Calculate nrssi0 6744 */ 6745 BWN_RF_SET(mac, 0x007a, 0x0070); 6746 bwn_set_all_gains(mac, 0, 8, 0); 6747 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6748 if (phy->rev >= 2) { 6749 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6750 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6751 } 6752 BWN_RF_SET(mac, 0x007a, 0x0080); 6753 DELAY(20); 6754 6755 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6756 if (nrssi0 >= 0x0020) 6757 nrssi0 -= 0x0040; 6758 6759 /* 6760 * Calculate nrssi1 6761 */ 6762 BWN_RF_MASK(mac, 0x007a, 0x007f); 6763 if (phy->rev >= 2) 6764 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6765 6766 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6767 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6768 BWN_RF_SET(mac, 0x007a, 0x000f); 6769 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6770 if (phy->rev >= 2) { 6771 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6772 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6773 } 6774 6775 bwn_set_all_gains(mac, 3, 0, 1); 6776 if (phy->rf_rev == 8) { 6777 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6778 } else { 6779 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6780 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6781 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6782 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6783 } 6784 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6785 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6786 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6787 DELAY(20); 6788 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6789 6790 /* 6791 * Install calculated narrow RSSI values 6792 */ 6793 if (nrssi1 >= 0x0020) 6794 nrssi1 -= 0x0040; 6795 if (nrssi0 == nrssi1) 6796 pg->pg_nrssi_slope = 0x00010000; 6797 else 6798 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6799 if (nrssi0 >= -4) { 6800 pg->pg_nrssi[0] = nrssi1; 6801 pg->pg_nrssi[1] = nrssi0; 6802 } 6803 6804 /* 6805 * Restore saved RF/PHY registers 6806 */ 6807 if (phy->rev >= 3) { 6808 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6809 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6810 save_phy3[phy3_idx]); 6811 } 6812 } 6813 if (phy->rev >= 2) { 6814 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6815 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6816 } 6817 6818 for (i = 0; i < SAVE_RF_MAX; ++i) 6819 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6820 6821 BWN_WRITE_2(mac, 0x03e2, ant_div); 6822 BWN_WRITE_2(mac, 0x03e6, phy0); 6823 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6824 6825 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6826 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6827 6828 bwn_spu_workaround(mac, phy->chan); 6829 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6830 bwn_set_original_gains(mac); 6831 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6832 if (phy->rev >= 3) { 6833 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6834 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6835 save_phy3[phy3_idx]); 6836 } 6837 } 6838 6839 delta = 0x1f - pg->pg_nrssi[0]; 6840 for (i = 0; i < 64; i++) { 6841 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6842 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6843 pg->pg_nrssi_lt[i] = tmp32; 6844 } 6845 6846 bwn_nrssi_threshold(mac); 6847 #undef SAVE_RF_MAX 6848 #undef SAVE_PHY_COMM_MAX 6849 #undef SAVE_PHY3_MAX 6850 } 6851 6852 static void 6853 bwn_nrssi_offset(struct bwn_mac *mac) 6854 { 6855 #define SAVE_RF_MAX 2 6856 #define SAVE_PHY_COMM_MAX 10 6857 #define SAVE_PHY6_MAX 8 6858 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6859 { 0x7a, 0x43 }; 6860 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6861 0x0001, 0x0811, 0x0812, 0x0814, 6862 0x0815, 0x005a, 0x0059, 0x0058, 6863 0x000a, 0x0003 6864 }; 6865 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6866 0x002e, 0x002f, 0x080f, 0x0810, 6867 0x0801, 0x0060, 0x0014, 0x0478 6868 }; 6869 struct bwn_phy *phy = &mac->mac_phy; 6870 int i, phy6_idx = 0; 6871 uint16_t save_rf[SAVE_RF_MAX]; 6872 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6873 uint16_t save_phy6[SAVE_PHY6_MAX]; 6874 int16_t nrssi; 6875 uint16_t saved = 0xffff; 6876 6877 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6878 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6879 for (i = 0; i < SAVE_RF_MAX; ++i) 6880 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6881 6882 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6883 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6884 BWN_PHY_SET(mac, 0x0811, 0x000c); 6885 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6886 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6887 if (phy->rev >= 6) { 6888 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6889 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6890 6891 BWN_PHY_WRITE(mac, 0x002e, 0); 6892 BWN_PHY_WRITE(mac, 0x002f, 0); 6893 BWN_PHY_WRITE(mac, 0x080f, 0); 6894 BWN_PHY_WRITE(mac, 0x0810, 0); 6895 BWN_PHY_SET(mac, 0x0478, 0x0100); 6896 BWN_PHY_SET(mac, 0x0801, 0x0040); 6897 BWN_PHY_SET(mac, 0x0060, 0x0040); 6898 BWN_PHY_SET(mac, 0x0014, 0x0200); 6899 } 6900 BWN_RF_SET(mac, 0x007a, 0x0070); 6901 BWN_RF_SET(mac, 0x007a, 0x0080); 6902 DELAY(30); 6903 6904 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6905 if (nrssi >= 0x20) 6906 nrssi -= 0x40; 6907 if (nrssi == 31) { 6908 for (i = 7; i >= 4; i--) { 6909 BWN_RF_WRITE(mac, 0x007b, i); 6910 DELAY(20); 6911 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 6912 0x003f); 6913 if (nrssi >= 0x20) 6914 nrssi -= 0x40; 6915 if (nrssi < 31 && saved == 0xffff) 6916 saved = i; 6917 } 6918 if (saved == 0xffff) 6919 saved = 4; 6920 } else { 6921 BWN_RF_MASK(mac, 0x007a, 0x007f); 6922 if (phy->rev != 1) { 6923 BWN_PHY_SET(mac, 0x0814, 0x0001); 6924 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 6925 } 6926 BWN_PHY_SET(mac, 0x0811, 0x000c); 6927 BWN_PHY_SET(mac, 0x0812, 0x000c); 6928 BWN_PHY_SET(mac, 0x0811, 0x0030); 6929 BWN_PHY_SET(mac, 0x0812, 0x0030); 6930 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6931 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6932 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6933 if (phy->rev == 0) 6934 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 6935 else 6936 BWN_PHY_SET(mac, 0x000a, 0x2000); 6937 if (phy->rev != 1) { 6938 BWN_PHY_SET(mac, 0x0814, 0x0004); 6939 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 6940 } 6941 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6942 BWN_RF_SET(mac, 0x007a, 0x000f); 6943 bwn_set_all_gains(mac, 3, 0, 1); 6944 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 6945 DELAY(30); 6946 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6947 if (nrssi >= 0x20) 6948 nrssi -= 0x40; 6949 if (nrssi == -32) { 6950 for (i = 0; i < 4; i++) { 6951 BWN_RF_WRITE(mac, 0x007b, i); 6952 DELAY(20); 6953 nrssi = (int16_t)((BWN_PHY_READ(mac, 6954 0x047f) >> 8) & 0x003f); 6955 if (nrssi >= 0x20) 6956 nrssi -= 0x40; 6957 if (nrssi > -31 && saved == 0xffff) 6958 saved = i; 6959 } 6960 if (saved == 0xffff) 6961 saved = 3; 6962 } else 6963 saved = 0; 6964 } 6965 BWN_RF_WRITE(mac, 0x007b, saved); 6966 6967 /* 6968 * Restore saved RF/PHY registers 6969 */ 6970 if (phy->rev >= 6) { 6971 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 6972 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6973 save_phy6[phy6_idx]); 6974 } 6975 } 6976 if (phy->rev != 1) { 6977 for (i = 3; i < 5; i++) 6978 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 6979 save_phy_comm[i]); 6980 } 6981 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 6982 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6983 6984 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 6985 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6986 6987 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 6988 BWN_PHY_SET(mac, 0x0429, 0x8000); 6989 bwn_set_original_gains(mac); 6990 if (phy->rev >= 6) { 6991 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 6992 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 6993 save_phy6[phy6_idx]); 6994 } 6995 } 6996 6997 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 6998 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 6999 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7000 } 7001 7002 static void 7003 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7004 int16_t third) 7005 { 7006 struct bwn_phy *phy = &mac->mac_phy; 7007 uint16_t i; 7008 uint16_t start = 0x08, end = 0x18; 7009 uint16_t tmp; 7010 uint16_t table; 7011 7012 if (phy->rev <= 1) { 7013 start = 0x10; 7014 end = 0x20; 7015 } 7016 7017 table = BWN_OFDMTAB_GAINX; 7018 if (phy->rev <= 1) 7019 table = BWN_OFDMTAB_GAINX_R1; 7020 for (i = 0; i < 4; i++) 7021 bwn_ofdmtab_write_2(mac, table, i, first); 7022 7023 for (i = start; i < end; i++) 7024 bwn_ofdmtab_write_2(mac, table, i, second); 7025 7026 if (third != -1) { 7027 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7028 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7029 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7030 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7031 } 7032 bwn_dummy_transmission(mac, 0, 1); 7033 } 7034 7035 static void 7036 bwn_set_original_gains(struct bwn_mac *mac) 7037 { 7038 struct bwn_phy *phy = &mac->mac_phy; 7039 uint16_t i, tmp; 7040 uint16_t table; 7041 uint16_t start = 0x0008, end = 0x0018; 7042 7043 if (phy->rev <= 1) { 7044 start = 0x0010; 7045 end = 0x0020; 7046 } 7047 7048 table = BWN_OFDMTAB_GAINX; 7049 if (phy->rev <= 1) 7050 table = BWN_OFDMTAB_GAINX_R1; 7051 for (i = 0; i < 4; i++) { 7052 tmp = (i & 0xfffc); 7053 tmp |= (i & 0x0001) << 1; 7054 tmp |= (i & 0x0002) >> 1; 7055 7056 bwn_ofdmtab_write_2(mac, table, i, tmp); 7057 } 7058 7059 for (i = start; i < end; i++) 7060 bwn_ofdmtab_write_2(mac, table, i, i - start); 7061 7062 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7063 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7064 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7065 bwn_dummy_transmission(mac, 0, 1); 7066 } 7067 7068 static void 7069 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7070 { 7071 struct bwn_phy *phy = &mac->mac_phy; 7072 struct bwn_phy_g *pg = &phy->phy_g; 7073 struct bwn_rfatt old_rfatt, rfatt; 7074 struct bwn_bbatt old_bbatt, bbatt; 7075 struct bwn_softc *sc = mac->mac_sc; 7076 uint8_t old_txctl = 0; 7077 7078 KASSERT(phy->type == BWN_PHYTYPE_G, 7079 ("%s:%d: fail", __func__, __LINE__)); 7080 7081 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7082 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7083 return; 7084 7085 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7086 7087 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7088 7089 if (!phy->gmode) 7090 return; 7091 bwn_hwpctl_early_init(mac); 7092 if (pg->pg_curtssi == 0) { 7093 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7094 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7095 } else { 7096 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7097 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7098 old_txctl = pg->pg_txctl; 7099 7100 bbatt.att = 11; 7101 if (phy->rf_rev == 8) { 7102 rfatt.att = 15; 7103 rfatt.padmix = 1; 7104 } else { 7105 rfatt.att = 9; 7106 rfatt.padmix = 0; 7107 } 7108 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7109 } 7110 bwn_dummy_transmission(mac, 0, 1); 7111 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7112 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7113 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7114 else 7115 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7116 &old_rfatt, old_txctl); 7117 } 7118 bwn_hwpctl_init_gphy(mac); 7119 7120 /* clear TSSI */ 7121 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7122 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7123 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7124 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7125 } 7126 7127 static void 7128 bwn_hwpctl_early_init(struct bwn_mac *mac) 7129 { 7130 struct bwn_phy *phy = &mac->mac_phy; 7131 7132 if (!bwn_has_hwpctl(mac)) { 7133 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7134 return; 7135 } 7136 7137 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7138 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7139 BWN_PHY_SET(mac, 0x047c, 0x0002); 7140 BWN_PHY_SET(mac, 0x047a, 0xf000); 7141 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7142 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7143 BWN_PHY_SET(mac, 0x005d, 0x8000); 7144 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7145 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7146 BWN_PHY_SET(mac, 0x0036, 0x0400); 7147 } else { 7148 BWN_PHY_SET(mac, 0x0036, 0x0200); 7149 BWN_PHY_SET(mac, 0x0036, 0x0400); 7150 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7151 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7152 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7153 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7154 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7155 } 7156 } 7157 7158 static void 7159 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7160 { 7161 struct bwn_phy *phy = &mac->mac_phy; 7162 struct bwn_phy_g *pg = &phy->phy_g; 7163 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7164 int i; 7165 uint16_t nr_written = 0, tmp, value; 7166 uint8_t rf, bb; 7167 7168 if (!bwn_has_hwpctl(mac)) { 7169 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7170 return; 7171 } 7172 7173 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7174 (pg->pg_idletssi - pg->pg_curtssi)); 7175 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7176 (pg->pg_idletssi - pg->pg_curtssi)); 7177 7178 for (i = 0; i < 32; i++) 7179 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7180 for (i = 32; i < 64; i++) 7181 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7182 for (i = 0; i < 64; i += 2) { 7183 value = (uint16_t) pg->pg_tssi2dbm[i]; 7184 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7185 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7186 } 7187 7188 for (rf = 0; rf < lo->rfatt.len; rf++) { 7189 for (bb = 0; bb < lo->bbatt.len; bb++) { 7190 if (nr_written >= 0x40) 7191 return; 7192 tmp = lo->bbatt.array[bb].att; 7193 tmp <<= 8; 7194 if (phy->rf_rev == 8) 7195 tmp |= 0x50; 7196 else 7197 tmp |= 0x40; 7198 tmp |= lo->rfatt.array[rf].att; 7199 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7200 nr_written++; 7201 } 7202 } 7203 7204 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7205 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7206 7207 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7208 BWN_PHY_SET(mac, 0x0478, 0x0800); 7209 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7210 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7211 7212 bwn_phy_g_dc_lookup_init(mac, 1); 7213 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7214 } 7215 7216 static void 7217 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7218 { 7219 struct bwn_softc *sc = mac->mac_sc; 7220 7221 if (spu != 0) 7222 bwn_spu_workaround(mac, channel); 7223 7224 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7225 7226 if (channel == 14) { 7227 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7228 bwn_hf_write(mac, 7229 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7230 else 7231 bwn_hf_write(mac, 7232 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7233 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7234 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7235 return; 7236 } 7237 7238 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7239 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7240 } 7241 7242 static uint16_t 7243 bwn_phy_g_chan2freq(uint8_t channel) 7244 { 7245 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7246 7247 KASSERT(channel >= 1 && channel <= 14, 7248 ("%s:%d: fail", __func__, __LINE__)); 7249 7250 return (bwn_phy_g_rf_channels[channel - 1]); 7251 } 7252 7253 static void 7254 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7255 const struct bwn_rfatt *rfatt, uint8_t txctl) 7256 { 7257 struct bwn_phy *phy = &mac->mac_phy; 7258 struct bwn_phy_g *pg = &phy->phy_g; 7259 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7260 uint16_t bb, rf; 7261 uint16_t tx_bias, tx_magn; 7262 7263 bb = bbatt->att; 7264 rf = rfatt->att; 7265 tx_bias = lo->tx_bias; 7266 tx_magn = lo->tx_magn; 7267 if (tx_bias == 0xff) 7268 tx_bias = 0; 7269 7270 pg->pg_txctl = txctl; 7271 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7272 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7273 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7274 bwn_phy_g_set_bbatt(mac, bb); 7275 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7276 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7277 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7278 else { 7279 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7280 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7281 } 7282 if (BWN_HAS_TXMAG(phy)) 7283 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7284 else 7285 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7286 bwn_lo_g_adjust(mac); 7287 } 7288 7289 static void 7290 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7291 uint16_t bbatt) 7292 { 7293 struct bwn_phy *phy = &mac->mac_phy; 7294 7295 if (phy->analog == 0) { 7296 BWN_WRITE_2(mac, BWN_PHY0, 7297 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7298 return; 7299 } 7300 if (phy->analog > 1) { 7301 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7302 return; 7303 } 7304 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7305 } 7306 7307 static uint16_t 7308 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7309 { 7310 struct bwn_phy *phy = &mac->mac_phy; 7311 struct bwn_phy_g *pg = &phy->phy_g; 7312 struct bwn_softc *sc = mac->mac_sc; 7313 int max_lb_gain; 7314 uint16_t extlna; 7315 uint16_t i; 7316 7317 if (phy->gmode == 0) 7318 return (0); 7319 7320 if (BWN_HAS_LOOPBACK(phy)) { 7321 max_lb_gain = pg->pg_max_lb_gain; 7322 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7323 if (max_lb_gain >= 0x46) { 7324 extlna = 0x3000; 7325 max_lb_gain -= 0x46; 7326 } else if (max_lb_gain >= 0x3a) { 7327 extlna = 0x1000; 7328 max_lb_gain -= 0x3a; 7329 } else if (max_lb_gain >= 0x2e) { 7330 extlna = 0x2000; 7331 max_lb_gain -= 0x2e; 7332 } else { 7333 extlna = 0; 7334 max_lb_gain -= 0x10; 7335 } 7336 7337 for (i = 0; i < 16; i++) { 7338 max_lb_gain -= (i * 6); 7339 if (max_lb_gain < 6) 7340 break; 7341 } 7342 7343 if ((phy->rev < 7) || 7344 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7345 if (reg == BWN_PHY_RFOVER) { 7346 return (0x1b3); 7347 } else if (reg == BWN_PHY_RFOVERVAL) { 7348 extlna |= (i << 8); 7349 switch (lpd) { 7350 case BWN_LPD(0, 1, 1): 7351 return (0x0f92); 7352 case BWN_LPD(0, 0, 1): 7353 case BWN_LPD(1, 0, 1): 7354 return (0x0092 | extlna); 7355 case BWN_LPD(1, 0, 0): 7356 return (0x0093 | extlna); 7357 } 7358 KASSERT(0 == 1, 7359 ("%s:%d: fail", __func__, __LINE__)); 7360 } 7361 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7362 } else { 7363 if (reg == BWN_PHY_RFOVER) 7364 return (0x9b3); 7365 if (reg == BWN_PHY_RFOVERVAL) { 7366 if (extlna) 7367 extlna |= 0x8000; 7368 extlna |= (i << 8); 7369 switch (lpd) { 7370 case BWN_LPD(0, 1, 1): 7371 return (0x8f92); 7372 case BWN_LPD(0, 0, 1): 7373 return (0x8092 | extlna); 7374 case BWN_LPD(1, 0, 1): 7375 return (0x2092 | extlna); 7376 case BWN_LPD(1, 0, 0): 7377 return (0x2093 | extlna); 7378 } 7379 KASSERT(0 == 1, 7380 ("%s:%d: fail", __func__, __LINE__)); 7381 } 7382 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7383 } 7384 return (0); 7385 } 7386 7387 if ((phy->rev < 7) || 7388 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7389 if (reg == BWN_PHY_RFOVER) { 7390 return (0x1b3); 7391 } else if (reg == BWN_PHY_RFOVERVAL) { 7392 switch (lpd) { 7393 case BWN_LPD(0, 1, 1): 7394 return (0x0fb2); 7395 case BWN_LPD(0, 0, 1): 7396 return (0x00b2); 7397 case BWN_LPD(1, 0, 1): 7398 return (0x30b2); 7399 case BWN_LPD(1, 0, 0): 7400 return (0x30b3); 7401 } 7402 KASSERT(0 == 1, 7403 ("%s:%d: fail", __func__, __LINE__)); 7404 } 7405 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7406 } else { 7407 if (reg == BWN_PHY_RFOVER) { 7408 return (0x9b3); 7409 } else if (reg == BWN_PHY_RFOVERVAL) { 7410 switch (lpd) { 7411 case BWN_LPD(0, 1, 1): 7412 return (0x8fb2); 7413 case BWN_LPD(0, 0, 1): 7414 return (0x80b2); 7415 case BWN_LPD(1, 0, 1): 7416 return (0x20b2); 7417 case BWN_LPD(1, 0, 0): 7418 return (0x20b3); 7419 } 7420 KASSERT(0 == 1, 7421 ("%s:%d: fail", __func__, __LINE__)); 7422 } 7423 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7424 } 7425 return (0); 7426 } 7427 7428 static void 7429 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7430 { 7431 7432 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7433 return; 7434 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7435 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7436 DELAY(1000); 7437 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7438 } 7439 7440 static int 7441 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7442 { 7443 struct bwn_softc *sc = mac->mac_sc; 7444 struct bwn_fw *fw = &mac->mac_fw; 7445 const uint8_t rev = siba_get_revid(sc->sc_dev); 7446 const char *filename; 7447 uint32_t high; 7448 int error; 7449 7450 /* microcode */ 7451 if (rev >= 5 && rev <= 10) 7452 filename = "ucode5"; 7453 else if (rev >= 11 && rev <= 12) 7454 filename = "ucode11"; 7455 else if (rev == 13) 7456 filename = "ucode13"; 7457 else if (rev == 14) 7458 filename = "ucode14"; 7459 else if (rev >= 15) 7460 filename = "ucode15"; 7461 else { 7462 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7463 bwn_release_firmware(mac); 7464 return (EOPNOTSUPP); 7465 } 7466 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7467 if (error) { 7468 bwn_release_firmware(mac); 7469 return (error); 7470 } 7471 7472 /* PCM */ 7473 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7474 if (rev >= 5 && rev <= 10) { 7475 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7476 if (error == ENOENT) 7477 fw->no_pcmfile = 1; 7478 else if (error) { 7479 bwn_release_firmware(mac); 7480 return (error); 7481 } 7482 } else if (rev < 11) { 7483 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7484 return (EOPNOTSUPP); 7485 } 7486 7487 /* initvals */ 7488 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7489 switch (mac->mac_phy.type) { 7490 case BWN_PHYTYPE_A: 7491 if (rev < 5 || rev > 10) 7492 goto fail1; 7493 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7494 filename = "a0g1initvals5"; 7495 else 7496 filename = "a0g0initvals5"; 7497 break; 7498 case BWN_PHYTYPE_G: 7499 if (rev >= 5 && rev <= 10) 7500 filename = "b0g0initvals5"; 7501 else if (rev >= 13) 7502 filename = "b0g0initvals13"; 7503 else 7504 goto fail1; 7505 break; 7506 case BWN_PHYTYPE_LP: 7507 if (rev == 13) 7508 filename = "lp0initvals13"; 7509 else if (rev == 14) 7510 filename = "lp0initvals14"; 7511 else if (rev >= 15) 7512 filename = "lp0initvals15"; 7513 else 7514 goto fail1; 7515 break; 7516 case BWN_PHYTYPE_N: 7517 if (rev >= 11 && rev <= 12) 7518 filename = "n0initvals11"; 7519 else 7520 goto fail1; 7521 break; 7522 default: 7523 goto fail1; 7524 } 7525 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7526 if (error) { 7527 bwn_release_firmware(mac); 7528 return (error); 7529 } 7530 7531 /* bandswitch initvals */ 7532 switch (mac->mac_phy.type) { 7533 case BWN_PHYTYPE_A: 7534 if (rev >= 5 && rev <= 10) { 7535 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7536 filename = "a0g1bsinitvals5"; 7537 else 7538 filename = "a0g0bsinitvals5"; 7539 } else if (rev >= 11) 7540 filename = NULL; 7541 else 7542 goto fail1; 7543 break; 7544 case BWN_PHYTYPE_G: 7545 if (rev >= 5 && rev <= 10) 7546 filename = "b0g0bsinitvals5"; 7547 else if (rev >= 11) 7548 filename = NULL; 7549 else 7550 goto fail1; 7551 break; 7552 case BWN_PHYTYPE_LP: 7553 if (rev == 13) 7554 filename = "lp0bsinitvals13"; 7555 else if (rev == 14) 7556 filename = "lp0bsinitvals14"; 7557 else if (rev >= 15) 7558 filename = "lp0bsinitvals15"; 7559 else 7560 goto fail1; 7561 break; 7562 case BWN_PHYTYPE_N: 7563 if (rev >= 11 && rev <= 12) 7564 filename = "n0bsinitvals11"; 7565 else 7566 goto fail1; 7567 break; 7568 default: 7569 goto fail1; 7570 } 7571 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7572 if (error) { 7573 bwn_release_firmware(mac); 7574 return (error); 7575 } 7576 return (0); 7577 fail1: 7578 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7579 bwn_release_firmware(mac); 7580 return (EOPNOTSUPP); 7581 } 7582 7583 static int 7584 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7585 const char *name, struct bwn_fwfile *bfw) 7586 { 7587 const struct bwn_fwhdr *hdr; 7588 struct bwn_softc *sc = mac->mac_sc; 7589 const struct firmware *fw; 7590 char namebuf[64]; 7591 7592 if (name == NULL) { 7593 bwn_do_release_fw(bfw); 7594 return (0); 7595 } 7596 if (bfw->filename != NULL) { 7597 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7598 return (0); 7599 bwn_do_release_fw(bfw); 7600 } 7601 7602 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7603 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7604 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7605 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7606 fw = firmware_get(namebuf); 7607 if (fw == NULL) { 7608 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7609 namebuf); 7610 return (ENOENT); 7611 } 7612 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7613 goto fail; 7614 hdr = (const struct bwn_fwhdr *)(fw->data); 7615 switch (hdr->type) { 7616 case BWN_FWTYPE_UCODE: 7617 case BWN_FWTYPE_PCM: 7618 if (be32toh(hdr->size) != 7619 (fw->datasize - sizeof(struct bwn_fwhdr))) 7620 goto fail; 7621 /* FALLTHROUGH */ 7622 case BWN_FWTYPE_IV: 7623 if (hdr->ver != 1) 7624 goto fail; 7625 break; 7626 default: 7627 goto fail; 7628 } 7629 bfw->filename = name; 7630 bfw->fw = fw; 7631 bfw->type = type; 7632 return (0); 7633 fail: 7634 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7635 if (fw != NULL) 7636 firmware_put(fw, FIRMWARE_UNLOAD); 7637 return (EPROTO); 7638 } 7639 7640 static void 7641 bwn_release_firmware(struct bwn_mac *mac) 7642 { 7643 7644 bwn_do_release_fw(&mac->mac_fw.ucode); 7645 bwn_do_release_fw(&mac->mac_fw.pcm); 7646 bwn_do_release_fw(&mac->mac_fw.initvals); 7647 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7648 } 7649 7650 static void 7651 bwn_do_release_fw(struct bwn_fwfile *bfw) 7652 { 7653 7654 if (bfw->fw != NULL) 7655 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7656 bfw->fw = NULL; 7657 bfw->filename = NULL; 7658 } 7659 7660 static int 7661 bwn_fw_loaducode(struct bwn_mac *mac) 7662 { 7663 #define GETFWOFFSET(fwp, offset) \ 7664 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7665 #define GETFWSIZE(fwp, offset) \ 7666 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7667 struct bwn_softc *sc = mac->mac_sc; 7668 const uint32_t *data; 7669 unsigned int i; 7670 uint32_t ctl; 7671 uint16_t date, fwcaps, time; 7672 int error = 0; 7673 7674 ctl = BWN_READ_4(mac, BWN_MACCTL); 7675 ctl |= BWN_MACCTL_MCODE_JMP0; 7676 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7677 __LINE__)); 7678 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7679 for (i = 0; i < 64; i++) 7680 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7681 for (i = 0; i < 4096; i += 2) 7682 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7683 7684 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7685 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7686 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7687 i++) { 7688 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7689 DELAY(10); 7690 } 7691 7692 if (mac->mac_fw.pcm.fw) { 7693 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7694 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7695 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7696 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7697 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7698 sizeof(struct bwn_fwhdr)); i++) { 7699 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7700 DELAY(10); 7701 } 7702 } 7703 7704 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7705 BWN_WRITE_4(mac, BWN_MACCTL, 7706 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7707 BWN_MACCTL_MCODE_RUN); 7708 7709 for (i = 0; i < 21; i++) { 7710 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7711 break; 7712 if (i >= 20) { 7713 device_printf(sc->sc_dev, "ucode timeout\n"); 7714 error = ENXIO; 7715 goto error; 7716 } 7717 DELAY(50000); 7718 } 7719 BWN_READ_4(mac, BWN_INTR_REASON); 7720 7721 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7722 if (mac->mac_fw.rev <= 0x128) { 7723 device_printf(sc->sc_dev, "the firmware is too old\n"); 7724 error = EOPNOTSUPP; 7725 goto error; 7726 } 7727 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7728 BWN_SHARED_UCODE_PATCH); 7729 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7730 mac->mac_fw.opensource = (date == 0xffff); 7731 if (bwn_wme != 0) 7732 mac->mac_flags |= BWN_MAC_FLAG_WME; 7733 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7734 7735 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7736 if (mac->mac_fw.opensource == 0) { 7737 device_printf(sc->sc_dev, 7738 "firmware version (rev %u patch %u date %#x time %#x)\n", 7739 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7740 if (mac->mac_fw.no_pcmfile) 7741 device_printf(sc->sc_dev, 7742 "no HW crypto acceleration due to pcm5\n"); 7743 } else { 7744 mac->mac_fw.patch = time; 7745 fwcaps = bwn_fwcaps_read(mac); 7746 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7747 device_printf(sc->sc_dev, 7748 "disabling HW crypto acceleration\n"); 7749 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7750 } 7751 if (!(fwcaps & BWN_FWCAPS_WME)) { 7752 device_printf(sc->sc_dev, "disabling WME support\n"); 7753 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7754 } 7755 } 7756 7757 if (BWN_ISOLDFMT(mac)) 7758 device_printf(sc->sc_dev, "using old firmware image\n"); 7759 7760 return (0); 7761 7762 error: 7763 BWN_WRITE_4(mac, BWN_MACCTL, 7764 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7765 BWN_MACCTL_MCODE_JMP0); 7766 7767 return (error); 7768 #undef GETFWSIZE 7769 #undef GETFWOFFSET 7770 } 7771 7772 /* OpenFirmware only */ 7773 static uint16_t 7774 bwn_fwcaps_read(struct bwn_mac *mac) 7775 { 7776 7777 KASSERT(mac->mac_fw.opensource == 1, 7778 ("%s:%d: fail", __func__, __LINE__)); 7779 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7780 } 7781 7782 static int 7783 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7784 size_t count, size_t array_size) 7785 { 7786 #define GET_NEXTIV16(iv) \ 7787 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7788 sizeof(uint16_t) + sizeof(uint16_t))) 7789 #define GET_NEXTIV32(iv) \ 7790 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7791 sizeof(uint16_t) + sizeof(uint32_t))) 7792 struct bwn_softc *sc = mac->mac_sc; 7793 const struct bwn_fwinitvals *iv; 7794 uint16_t offset; 7795 size_t i; 7796 uint8_t bit32; 7797 7798 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7799 ("%s:%d: fail", __func__, __LINE__)); 7800 iv = ivals; 7801 for (i = 0; i < count; i++) { 7802 if (array_size < sizeof(iv->offset_size)) 7803 goto fail; 7804 array_size -= sizeof(iv->offset_size); 7805 offset = be16toh(iv->offset_size); 7806 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7807 offset &= BWN_FWINITVALS_OFFSET_MASK; 7808 if (offset >= 0x1000) 7809 goto fail; 7810 if (bit32) { 7811 if (array_size < sizeof(iv->data.d32)) 7812 goto fail; 7813 array_size -= sizeof(iv->data.d32); 7814 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7815 iv = GET_NEXTIV32(iv); 7816 } else { 7817 7818 if (array_size < sizeof(iv->data.d16)) 7819 goto fail; 7820 array_size -= sizeof(iv->data.d16); 7821 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7822 7823 iv = GET_NEXTIV16(iv); 7824 } 7825 } 7826 if (array_size != 0) 7827 goto fail; 7828 return (0); 7829 fail: 7830 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7831 return (EPROTO); 7832 #undef GET_NEXTIV16 7833 #undef GET_NEXTIV32 7834 } 7835 7836 static int 7837 bwn_switch_channel(struct bwn_mac *mac, int chan) 7838 { 7839 struct bwn_phy *phy = &(mac->mac_phy); 7840 struct bwn_softc *sc = mac->mac_sc; 7841 struct ieee80211com *ic = &sc->sc_ic; 7842 uint16_t channelcookie, savedcookie; 7843 int error; 7844 7845 if (chan == 0xffff) 7846 chan = phy->get_default_chan(mac); 7847 7848 channelcookie = chan; 7849 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7850 channelcookie |= 0x100; 7851 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7852 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7853 error = phy->switch_channel(mac, chan); 7854 if (error) 7855 goto fail; 7856 7857 mac->mac_phy.chan = chan; 7858 DELAY(8000); 7859 return (0); 7860 fail: 7861 device_printf(sc->sc_dev, "failed to switch channel\n"); 7862 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7863 return (error); 7864 } 7865 7866 static uint16_t 7867 bwn_ant2phy(int antenna) 7868 { 7869 7870 switch (antenna) { 7871 case BWN_ANT0: 7872 return (BWN_TX_PHY_ANT0); 7873 case BWN_ANT1: 7874 return (BWN_TX_PHY_ANT1); 7875 case BWN_ANT2: 7876 return (BWN_TX_PHY_ANT2); 7877 case BWN_ANT3: 7878 return (BWN_TX_PHY_ANT3); 7879 case BWN_ANTAUTO: 7880 return (BWN_TX_PHY_ANT01AUTO); 7881 } 7882 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7883 return (0); 7884 } 7885 7886 static void 7887 bwn_wme_load(struct bwn_mac *mac) 7888 { 7889 struct bwn_softc *sc = mac->mac_sc; 7890 int i; 7891 7892 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7893 ("%s:%d: fail", __func__, __LINE__)); 7894 7895 bwn_mac_suspend(mac); 7896 for (i = 0; i < N(sc->sc_wmeParams); i++) 7897 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 7898 bwn_wme_shm_offsets[i]); 7899 bwn_mac_enable(mac); 7900 } 7901 7902 static void 7903 bwn_wme_loadparams(struct bwn_mac *mac, 7904 const struct wmeParams *p, uint16_t shm_offset) 7905 { 7906 #define SM(_v, _f) (((_v) << _f##_S) & _f) 7907 struct bwn_softc *sc = mac->mac_sc; 7908 uint16_t params[BWN_NR_WMEPARAMS]; 7909 int slot, tmp; 7910 unsigned int i; 7911 7912 slot = BWN_READ_2(mac, BWN_RNG) & 7913 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7914 7915 memset(¶ms, 0, sizeof(params)); 7916 7917 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 7918 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 7919 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 7920 7921 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 7922 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7923 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 7924 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 7925 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 7926 params[BWN_WMEPARAM_BSLOTS] = slot; 7927 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 7928 7929 for (i = 0; i < N(params); i++) { 7930 if (i == BWN_WMEPARAM_STATUS) { 7931 tmp = bwn_shm_read_2(mac, BWN_SHARED, 7932 shm_offset + (i * 2)); 7933 tmp |= 0x100; 7934 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7935 tmp); 7936 } else { 7937 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 7938 params[i]); 7939 } 7940 } 7941 } 7942 7943 static void 7944 bwn_mac_write_bssid(struct bwn_mac *mac) 7945 { 7946 struct bwn_softc *sc = mac->mac_sc; 7947 uint32_t tmp; 7948 int i; 7949 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 7950 7951 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 7952 memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN); 7953 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 7954 IEEE80211_ADDR_LEN); 7955 7956 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 7957 tmp = (uint32_t) (mac_bssid[i + 0]); 7958 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 7959 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 7960 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 7961 bwn_ram_write(mac, 0x20 + i, tmp); 7962 } 7963 } 7964 7965 static void 7966 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 7967 const uint8_t *macaddr) 7968 { 7969 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 7970 uint16_t data; 7971 7972 if (!mac) 7973 macaddr = zero; 7974 7975 offset |= 0x0020; 7976 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 7977 7978 data = macaddr[0]; 7979 data |= macaddr[1] << 8; 7980 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7981 data = macaddr[2]; 7982 data |= macaddr[3] << 8; 7983 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7984 data = macaddr[4]; 7985 data |= macaddr[5] << 8; 7986 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 7987 } 7988 7989 static void 7990 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 7991 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 7992 { 7993 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 7994 uint8_t per_sta_keys_start = 8; 7995 7996 if (BWN_SEC_NEWAPI(mac)) 7997 per_sta_keys_start = 4; 7998 7999 KASSERT(index < mac->mac_max_nr_keys, 8000 ("%s:%d: fail", __func__, __LINE__)); 8001 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8002 ("%s:%d: fail", __func__, __LINE__)); 8003 8004 if (index >= per_sta_keys_start) 8005 bwn_key_macwrite(mac, index, NULL); 8006 if (key) 8007 memcpy(buf, key, key_len); 8008 bwn_key_write(mac, index, algorithm, buf); 8009 if (index >= per_sta_keys_start) 8010 bwn_key_macwrite(mac, index, mac_addr); 8011 8012 mac->mac_key[index].algorithm = algorithm; 8013 } 8014 8015 static void 8016 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8017 { 8018 struct bwn_softc *sc = mac->mac_sc; 8019 uint32_t addrtmp[2] = { 0, 0 }; 8020 uint8_t start = 8; 8021 8022 if (BWN_SEC_NEWAPI(mac)) 8023 start = 4; 8024 8025 KASSERT(index >= start, 8026 ("%s:%d: fail", __func__, __LINE__)); 8027 index -= start; 8028 8029 if (addr) { 8030 addrtmp[0] = addr[0]; 8031 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8032 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8033 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8034 addrtmp[1] = addr[4]; 8035 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8036 } 8037 8038 if (siba_get_revid(sc->sc_dev) >= 5) { 8039 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8040 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8041 } else { 8042 if (index >= 8) { 8043 bwn_shm_write_4(mac, BWN_SHARED, 8044 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8045 bwn_shm_write_2(mac, BWN_SHARED, 8046 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8047 } 8048 } 8049 } 8050 8051 static void 8052 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8053 const uint8_t *key) 8054 { 8055 unsigned int i; 8056 uint32_t offset; 8057 uint16_t kidx, value; 8058 8059 kidx = BWN_SEC_KEY2FW(mac, index); 8060 bwn_shm_write_2(mac, BWN_SHARED, 8061 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8062 8063 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8064 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8065 value = key[i]; 8066 value |= (uint16_t)(key[i + 1]) << 8; 8067 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8068 } 8069 } 8070 8071 static void 8072 bwn_phy_exit(struct bwn_mac *mac) 8073 { 8074 8075 mac->mac_phy.rf_onoff(mac, 0); 8076 if (mac->mac_phy.exit != NULL) 8077 mac->mac_phy.exit(mac); 8078 } 8079 8080 static void 8081 bwn_dma_free(struct bwn_mac *mac) 8082 { 8083 struct bwn_dma *dma; 8084 8085 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8086 return; 8087 dma = &mac->mac_method.dma; 8088 8089 bwn_dma_ringfree(&dma->rx); 8090 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8091 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8092 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8093 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8094 bwn_dma_ringfree(&dma->mcast); 8095 } 8096 8097 static void 8098 bwn_core_stop(struct bwn_mac *mac) 8099 { 8100 struct bwn_softc *sc = mac->mac_sc; 8101 8102 BWN_ASSERT_LOCKED(sc); 8103 8104 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8105 return; 8106 8107 callout_stop(&sc->sc_rfswitch_ch); 8108 callout_stop(&sc->sc_task_ch); 8109 callout_stop(&sc->sc_watchdog_ch); 8110 sc->sc_watchdog_timer = 0; 8111 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8112 BWN_READ_4(mac, BWN_INTR_MASK); 8113 bwn_mac_suspend(mac); 8114 8115 mac->mac_status = BWN_MAC_STATUS_INITED; 8116 } 8117 8118 static int 8119 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8120 { 8121 struct bwn_mac *up_dev = NULL; 8122 struct bwn_mac *down_dev; 8123 struct bwn_mac *mac; 8124 int err, status; 8125 uint8_t gmode; 8126 8127 BWN_ASSERT_LOCKED(sc); 8128 8129 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8130 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8131 mac->mac_phy.supports_2ghz) { 8132 up_dev = mac; 8133 gmode = 1; 8134 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8135 mac->mac_phy.supports_5ghz) { 8136 up_dev = mac; 8137 gmode = 0; 8138 } else { 8139 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8140 return (EINVAL); 8141 } 8142 if (up_dev != NULL) 8143 break; 8144 } 8145 if (up_dev == NULL) { 8146 device_printf(sc->sc_dev, "Could not find a device\n"); 8147 return (ENODEV); 8148 } 8149 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8150 return (0); 8151 8152 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8153 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8154 8155 down_dev = sc->sc_curmac; 8156 status = down_dev->mac_status; 8157 if (status >= BWN_MAC_STATUS_STARTED) 8158 bwn_core_stop(down_dev); 8159 if (status >= BWN_MAC_STATUS_INITED) 8160 bwn_core_exit(down_dev); 8161 8162 if (down_dev != up_dev) 8163 bwn_phy_reset(down_dev); 8164 8165 up_dev->mac_phy.gmode = gmode; 8166 if (status >= BWN_MAC_STATUS_INITED) { 8167 err = bwn_core_init(up_dev); 8168 if (err) { 8169 device_printf(sc->sc_dev, 8170 "fatal: failed to initialize for %s-GHz\n", 8171 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8172 goto fail; 8173 } 8174 } 8175 if (status >= BWN_MAC_STATUS_STARTED) 8176 bwn_core_start(up_dev); 8177 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8178 sc->sc_curmac = up_dev; 8179 8180 return (0); 8181 fail: 8182 sc->sc_curmac = NULL; 8183 return (err); 8184 } 8185 8186 static void 8187 bwn_rf_turnon(struct bwn_mac *mac) 8188 { 8189 8190 bwn_mac_suspend(mac); 8191 mac->mac_phy.rf_onoff(mac, 1); 8192 mac->mac_phy.rf_on = 1; 8193 bwn_mac_enable(mac); 8194 } 8195 8196 static void 8197 bwn_rf_turnoff(struct bwn_mac *mac) 8198 { 8199 8200 bwn_mac_suspend(mac); 8201 mac->mac_phy.rf_onoff(mac, 0); 8202 mac->mac_phy.rf_on = 0; 8203 bwn_mac_enable(mac); 8204 } 8205 8206 static void 8207 bwn_phy_reset(struct bwn_mac *mac) 8208 { 8209 struct bwn_softc *sc = mac->mac_sc; 8210 8211 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8212 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8213 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8214 DELAY(1000); 8215 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8216 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8217 BWN_TGSLOW_PHYRESET); 8218 DELAY(1000); 8219 } 8220 8221 static int 8222 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8223 { 8224 struct bwn_vap *bvp = BWN_VAP(vap); 8225 struct ieee80211com *ic= vap->iv_ic; 8226 enum ieee80211_state ostate = vap->iv_state; 8227 struct bwn_softc *sc = ic->ic_softc; 8228 struct bwn_mac *mac = sc->sc_curmac; 8229 int error; 8230 8231 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8232 ieee80211_state_name[vap->iv_state], 8233 ieee80211_state_name[nstate]); 8234 8235 error = bvp->bv_newstate(vap, nstate, arg); 8236 if (error != 0) 8237 return (error); 8238 8239 BWN_LOCK(sc); 8240 8241 bwn_led_newstate(mac, nstate); 8242 8243 /* 8244 * Clear the BSSID when we stop a STA 8245 */ 8246 if (vap->iv_opmode == IEEE80211_M_STA) { 8247 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8248 /* 8249 * Clear out the BSSID. If we reassociate to 8250 * the same AP, this will reinialize things 8251 * correctly... 8252 */ 8253 if (ic->ic_opmode == IEEE80211_M_STA && 8254 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8255 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8256 bwn_set_macaddr(mac); 8257 } 8258 } 8259 } 8260 8261 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8262 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8263 /* XXX nothing to do? */ 8264 } else if (nstate == IEEE80211_S_RUN) { 8265 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8266 bwn_set_opmode(mac); 8267 bwn_set_pretbtt(mac); 8268 bwn_spu_setdelay(mac, 0); 8269 bwn_set_macaddr(mac); 8270 } 8271 8272 BWN_UNLOCK(sc); 8273 8274 return (error); 8275 } 8276 8277 static void 8278 bwn_set_pretbtt(struct bwn_mac *mac) 8279 { 8280 struct bwn_softc *sc = mac->mac_sc; 8281 struct ieee80211com *ic = &sc->sc_ic; 8282 uint16_t pretbtt; 8283 8284 if (ic->ic_opmode == IEEE80211_M_IBSS) 8285 pretbtt = 2; 8286 else 8287 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8288 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8289 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8290 } 8291 8292 static int 8293 bwn_intr(void *arg) 8294 { 8295 struct bwn_mac *mac = arg; 8296 struct bwn_softc *sc = mac->mac_sc; 8297 uint32_t reason; 8298 8299 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8300 (sc->sc_flags & BWN_FLAG_INVALID)) 8301 return (FILTER_STRAY); 8302 8303 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8304 if (reason == 0xffffffff) /* shared IRQ */ 8305 return (FILTER_STRAY); 8306 reason &= mac->mac_intr_mask; 8307 if (reason == 0) 8308 return (FILTER_HANDLED); 8309 8310 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8311 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8312 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8313 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8314 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8315 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8316 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8317 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8318 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8319 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8320 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8321 8322 /* Disable interrupts. */ 8323 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8324 8325 mac->mac_reason_intr = reason; 8326 8327 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8328 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8329 8330 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8331 return (FILTER_HANDLED); 8332 } 8333 8334 static void 8335 bwn_intrtask(void *arg, int npending) 8336 { 8337 struct bwn_mac *mac = arg; 8338 struct bwn_softc *sc = mac->mac_sc; 8339 uint32_t merged = 0; 8340 int i, tx = 0, rx = 0; 8341 8342 BWN_LOCK(sc); 8343 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8344 (sc->sc_flags & BWN_FLAG_INVALID)) { 8345 BWN_UNLOCK(sc); 8346 return; 8347 } 8348 8349 for (i = 0; i < N(mac->mac_reason); i++) 8350 merged |= mac->mac_reason[i]; 8351 8352 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8353 device_printf(sc->sc_dev, "MAC trans error\n"); 8354 8355 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8356 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8357 mac->mac_phy.txerrors--; 8358 if (mac->mac_phy.txerrors == 0) { 8359 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8360 bwn_restart(mac, "PHY TX errors"); 8361 } 8362 } 8363 8364 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8365 if (merged & BWN_DMAINTR_FATALMASK) { 8366 device_printf(sc->sc_dev, 8367 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8368 mac->mac_reason[0], mac->mac_reason[1], 8369 mac->mac_reason[2], mac->mac_reason[3], 8370 mac->mac_reason[4], mac->mac_reason[5]); 8371 bwn_restart(mac, "DMA error"); 8372 BWN_UNLOCK(sc); 8373 return; 8374 } 8375 if (merged & BWN_DMAINTR_NONFATALMASK) { 8376 device_printf(sc->sc_dev, 8377 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8378 mac->mac_reason[0], mac->mac_reason[1], 8379 mac->mac_reason[2], mac->mac_reason[3], 8380 mac->mac_reason[4], mac->mac_reason[5]); 8381 } 8382 } 8383 8384 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8385 bwn_intr_ucode_debug(mac); 8386 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8387 bwn_intr_tbtt_indication(mac); 8388 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8389 bwn_intr_atim_end(mac); 8390 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8391 bwn_intr_beacon(mac); 8392 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8393 bwn_intr_pmq(mac); 8394 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8395 bwn_intr_noise(mac); 8396 8397 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8398 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8399 bwn_dma_rx(mac->mac_method.dma.rx); 8400 rx = 1; 8401 } 8402 } else 8403 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8404 8405 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8406 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8407 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8408 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8409 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8410 8411 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8412 bwn_intr_txeof(mac); 8413 tx = 1; 8414 } 8415 8416 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8417 8418 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8419 int evt = BWN_LED_EVENT_NONE; 8420 8421 if (tx && rx) { 8422 if (sc->sc_rx_rate > sc->sc_tx_rate) 8423 evt = BWN_LED_EVENT_RX; 8424 else 8425 evt = BWN_LED_EVENT_TX; 8426 } else if (tx) { 8427 evt = BWN_LED_EVENT_TX; 8428 } else if (rx) { 8429 evt = BWN_LED_EVENT_RX; 8430 } else if (rx == 0) { 8431 evt = BWN_LED_EVENT_POLL; 8432 } 8433 8434 if (evt != BWN_LED_EVENT_NONE) 8435 bwn_led_event(mac, evt); 8436 } 8437 8438 if (mbufq_first(&sc->sc_snd) != NULL) 8439 bwn_start(sc); 8440 8441 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8442 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8443 8444 BWN_UNLOCK(sc); 8445 } 8446 8447 static void 8448 bwn_restart(struct bwn_mac *mac, const char *msg) 8449 { 8450 struct bwn_softc *sc = mac->mac_sc; 8451 struct ieee80211com *ic = &sc->sc_ic; 8452 8453 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8454 return; 8455 8456 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8457 ieee80211_runtask(ic, &mac->mac_hwreset); 8458 } 8459 8460 static void 8461 bwn_intr_ucode_debug(struct bwn_mac *mac) 8462 { 8463 struct bwn_softc *sc = mac->mac_sc; 8464 uint16_t reason; 8465 8466 if (mac->mac_fw.opensource == 0) 8467 return; 8468 8469 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8470 switch (reason) { 8471 case BWN_DEBUGINTR_PANIC: 8472 bwn_handle_fwpanic(mac); 8473 break; 8474 case BWN_DEBUGINTR_DUMP_SHM: 8475 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8476 break; 8477 case BWN_DEBUGINTR_DUMP_REGS: 8478 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8479 break; 8480 case BWN_DEBUGINTR_MARKER: 8481 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8482 break; 8483 default: 8484 device_printf(sc->sc_dev, 8485 "ucode debug unknown reason: %#x\n", reason); 8486 } 8487 8488 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8489 BWN_DEBUGINTR_ACK); 8490 } 8491 8492 static void 8493 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8494 { 8495 struct bwn_softc *sc = mac->mac_sc; 8496 struct ieee80211com *ic = &sc->sc_ic; 8497 8498 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8499 bwn_psctl(mac, 0); 8500 if (ic->ic_opmode == IEEE80211_M_IBSS) 8501 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8502 } 8503 8504 static void 8505 bwn_intr_atim_end(struct bwn_mac *mac) 8506 { 8507 8508 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8509 BWN_WRITE_4(mac, BWN_MACCMD, 8510 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8511 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8512 } 8513 } 8514 8515 static void 8516 bwn_intr_beacon(struct bwn_mac *mac) 8517 { 8518 struct bwn_softc *sc = mac->mac_sc; 8519 struct ieee80211com *ic = &sc->sc_ic; 8520 uint32_t cmd, beacon0, beacon1; 8521 8522 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8523 ic->ic_opmode == IEEE80211_M_MBSS) 8524 return; 8525 8526 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8527 8528 cmd = BWN_READ_4(mac, BWN_MACCMD); 8529 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8530 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8531 8532 if (beacon0 && beacon1) { 8533 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8534 mac->mac_intr_mask |= BWN_INTR_BEACON; 8535 return; 8536 } 8537 8538 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8539 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8540 bwn_load_beacon0(mac); 8541 bwn_load_beacon1(mac); 8542 cmd = BWN_READ_4(mac, BWN_MACCMD); 8543 cmd |= BWN_MACCMD_BEACON0_VALID; 8544 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8545 } else { 8546 if (!beacon0) { 8547 bwn_load_beacon0(mac); 8548 cmd = BWN_READ_4(mac, BWN_MACCMD); 8549 cmd |= BWN_MACCMD_BEACON0_VALID; 8550 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8551 } else if (!beacon1) { 8552 bwn_load_beacon1(mac); 8553 cmd = BWN_READ_4(mac, BWN_MACCMD); 8554 cmd |= BWN_MACCMD_BEACON1_VALID; 8555 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8556 } 8557 } 8558 } 8559 8560 static void 8561 bwn_intr_pmq(struct bwn_mac *mac) 8562 { 8563 uint32_t tmp; 8564 8565 while (1) { 8566 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8567 if (!(tmp & 0x00000008)) 8568 break; 8569 } 8570 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8571 } 8572 8573 static void 8574 bwn_intr_noise(struct bwn_mac *mac) 8575 { 8576 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8577 uint16_t tmp; 8578 uint8_t noise[4]; 8579 uint8_t i, j; 8580 int32_t average; 8581 8582 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8583 return; 8584 8585 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8586 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8587 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8588 noise[3] == 0x7f) 8589 goto new; 8590 8591 KASSERT(mac->mac_noise.noi_nsamples < 8, 8592 ("%s:%d: fail", __func__, __LINE__)); 8593 i = mac->mac_noise.noi_nsamples; 8594 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8595 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8596 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8597 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8598 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8599 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8600 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8601 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8602 mac->mac_noise.noi_nsamples++; 8603 if (mac->mac_noise.noi_nsamples == 8) { 8604 average = 0; 8605 for (i = 0; i < 8; i++) { 8606 for (j = 0; j < 4; j++) 8607 average += mac->mac_noise.noi_samples[i][j]; 8608 } 8609 average = (((average / 32) * 125) + 64) / 128; 8610 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8611 if (tmp >= 8) 8612 average += 2; 8613 else 8614 average -= 25; 8615 average -= (tmp == 8) ? 72 : 48; 8616 8617 mac->mac_stats.link_noise = average; 8618 mac->mac_noise.noi_running = 0; 8619 return; 8620 } 8621 new: 8622 bwn_noise_gensample(mac); 8623 } 8624 8625 static int 8626 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8627 { 8628 struct bwn_mac *mac = prq->prq_mac; 8629 struct bwn_softc *sc = mac->mac_sc; 8630 unsigned int i; 8631 8632 BWN_ASSERT_LOCKED(sc); 8633 8634 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8635 return (0); 8636 8637 for (i = 0; i < 5000; i++) { 8638 if (bwn_pio_rxeof(prq) == 0) 8639 break; 8640 } 8641 if (i >= 5000) 8642 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8643 return ((i > 0) ? 1 : 0); 8644 } 8645 8646 static void 8647 bwn_dma_rx(struct bwn_dma_ring *dr) 8648 { 8649 int slot, curslot; 8650 8651 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8652 curslot = dr->get_curslot(dr); 8653 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8654 ("%s:%d: fail", __func__, __LINE__)); 8655 8656 slot = dr->dr_curslot; 8657 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8658 bwn_dma_rxeof(dr, &slot); 8659 8660 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8661 BUS_DMASYNC_PREWRITE); 8662 8663 dr->set_curslot(dr, slot); 8664 dr->dr_curslot = slot; 8665 } 8666 8667 static void 8668 bwn_intr_txeof(struct bwn_mac *mac) 8669 { 8670 struct bwn_txstatus stat; 8671 uint32_t stat0, stat1; 8672 uint16_t tmp; 8673 8674 BWN_ASSERT_LOCKED(mac->mac_sc); 8675 8676 while (1) { 8677 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8678 if (!(stat0 & 0x00000001)) 8679 break; 8680 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8681 8682 stat.cookie = (stat0 >> 16); 8683 stat.seq = (stat1 & 0x0000ffff); 8684 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8685 tmp = (stat0 & 0x0000ffff); 8686 stat.framecnt = ((tmp & 0xf000) >> 12); 8687 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8688 stat.sreason = ((tmp & 0x001c) >> 2); 8689 stat.pm = (tmp & 0x0080) ? 1 : 0; 8690 stat.im = (tmp & 0x0040) ? 1 : 0; 8691 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8692 stat.ack = (tmp & 0x0002) ? 1 : 0; 8693 8694 bwn_handle_txeof(mac, &stat); 8695 } 8696 } 8697 8698 static void 8699 bwn_hwreset(void *arg, int npending) 8700 { 8701 struct bwn_mac *mac = arg; 8702 struct bwn_softc *sc = mac->mac_sc; 8703 int error = 0; 8704 int prev_status; 8705 8706 BWN_LOCK(sc); 8707 8708 prev_status = mac->mac_status; 8709 if (prev_status >= BWN_MAC_STATUS_STARTED) 8710 bwn_core_stop(mac); 8711 if (prev_status >= BWN_MAC_STATUS_INITED) 8712 bwn_core_exit(mac); 8713 8714 if (prev_status >= BWN_MAC_STATUS_INITED) { 8715 error = bwn_core_init(mac); 8716 if (error) 8717 goto out; 8718 } 8719 if (prev_status >= BWN_MAC_STATUS_STARTED) 8720 bwn_core_start(mac); 8721 out: 8722 if (error) { 8723 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8724 sc->sc_curmac = NULL; 8725 } 8726 BWN_UNLOCK(sc); 8727 } 8728 8729 static void 8730 bwn_handle_fwpanic(struct bwn_mac *mac) 8731 { 8732 struct bwn_softc *sc = mac->mac_sc; 8733 uint16_t reason; 8734 8735 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8736 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8737 8738 if (reason == BWN_FWPANIC_RESTART) 8739 bwn_restart(mac, "ucode panic"); 8740 } 8741 8742 static void 8743 bwn_load_beacon0(struct bwn_mac *mac) 8744 { 8745 8746 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8747 } 8748 8749 static void 8750 bwn_load_beacon1(struct bwn_mac *mac) 8751 { 8752 8753 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8754 } 8755 8756 static uint32_t 8757 bwn_jssi_read(struct bwn_mac *mac) 8758 { 8759 uint32_t val = 0; 8760 8761 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8762 val <<= 16; 8763 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8764 8765 return (val); 8766 } 8767 8768 static void 8769 bwn_noise_gensample(struct bwn_mac *mac) 8770 { 8771 uint32_t jssi = 0x7f7f7f7f; 8772 8773 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8774 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8775 BWN_WRITE_4(mac, BWN_MACCMD, 8776 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8777 } 8778 8779 static int 8780 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8781 { 8782 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8783 8784 return (dr->dr_numslots - dr->dr_usedslot); 8785 } 8786 8787 static int 8788 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8789 { 8790 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8791 8792 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8793 ("%s:%d: fail", __func__, __LINE__)); 8794 if (slot == dr->dr_numslots - 1) 8795 return (0); 8796 return (slot + 1); 8797 } 8798 8799 static void 8800 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8801 { 8802 struct bwn_mac *mac = dr->dr_mac; 8803 struct bwn_softc *sc = mac->mac_sc; 8804 struct bwn_dma *dma = &mac->mac_method.dma; 8805 struct bwn_dmadesc_generic *desc; 8806 struct bwn_dmadesc_meta *meta; 8807 struct bwn_rxhdr4 *rxhdr; 8808 struct mbuf *m; 8809 uint32_t macstat; 8810 int32_t tmp; 8811 int cnt = 0; 8812 uint16_t len; 8813 8814 dr->getdesc(dr, *slot, &desc, &meta); 8815 8816 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8817 m = meta->mt_m; 8818 8819 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8820 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 8821 return; 8822 } 8823 8824 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8825 len = le16toh(rxhdr->frame_len); 8826 if (len <= 0) { 8827 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 8828 return; 8829 } 8830 if (bwn_dma_check_redzone(dr, m)) { 8831 device_printf(sc->sc_dev, "redzone error.\n"); 8832 bwn_dma_set_redzone(dr, m); 8833 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8834 BUS_DMASYNC_PREWRITE); 8835 return; 8836 } 8837 if (len > dr->dr_rx_bufsize) { 8838 tmp = len; 8839 while (1) { 8840 dr->getdesc(dr, *slot, &desc, &meta); 8841 bwn_dma_set_redzone(dr, meta->mt_m); 8842 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8843 BUS_DMASYNC_PREWRITE); 8844 *slot = bwn_dma_nextslot(dr, *slot); 8845 cnt++; 8846 tmp -= dr->dr_rx_bufsize; 8847 if (tmp <= 0) 8848 break; 8849 } 8850 device_printf(sc->sc_dev, "too small buffer " 8851 "(len %u buffer %u dropped %d)\n", 8852 len, dr->dr_rx_bufsize, cnt); 8853 return; 8854 } 8855 macstat = le32toh(rxhdr->mac_status); 8856 if (macstat & BWN_RX_MAC_FCSERR) { 8857 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8858 device_printf(sc->sc_dev, "RX drop\n"); 8859 return; 8860 } 8861 } 8862 8863 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8864 m_adj(m, dr->dr_frameoffset); 8865 8866 bwn_rxeof(dr->dr_mac, m, rxhdr); 8867 } 8868 8869 static void 8870 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8871 { 8872 struct bwn_dma_ring *dr; 8873 struct bwn_dmadesc_generic *desc; 8874 struct bwn_dmadesc_meta *meta; 8875 struct bwn_pio_txqueue *tq; 8876 struct bwn_pio_txpkt *tp = NULL; 8877 struct bwn_softc *sc = mac->mac_sc; 8878 struct bwn_stats *stats = &mac->mac_stats; 8879 struct ieee80211_node *ni; 8880 struct ieee80211vap *vap; 8881 int retrycnt = 0, slot; 8882 8883 BWN_ASSERT_LOCKED(mac->mac_sc); 8884 8885 if (status->im) 8886 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 8887 if (status->ampdu) 8888 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 8889 if (status->rtscnt) { 8890 if (status->rtscnt == 0xf) 8891 stats->rtsfail++; 8892 else 8893 stats->rts++; 8894 } 8895 8896 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8897 if (status->ack) { 8898 dr = bwn_dma_parse_cookie(mac, status, 8899 status->cookie, &slot); 8900 if (dr == NULL) { 8901 device_printf(sc->sc_dev, 8902 "failed to parse cookie\n"); 8903 return; 8904 } 8905 while (1) { 8906 dr->getdesc(dr, slot, &desc, &meta); 8907 if (meta->mt_islast) { 8908 ni = meta->mt_ni; 8909 vap = ni->ni_vap; 8910 ieee80211_ratectl_tx_complete(vap, ni, 8911 status->ack ? 8912 IEEE80211_RATECTL_TX_SUCCESS : 8913 IEEE80211_RATECTL_TX_FAILURE, 8914 &retrycnt, 0); 8915 break; 8916 } 8917 slot = bwn_dma_nextslot(dr, slot); 8918 } 8919 } 8920 bwn_dma_handle_txeof(mac, status); 8921 } else { 8922 if (status->ack) { 8923 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 8924 if (tq == NULL) { 8925 device_printf(sc->sc_dev, 8926 "failed to parse cookie\n"); 8927 return; 8928 } 8929 ni = tp->tp_ni; 8930 vap = ni->ni_vap; 8931 ieee80211_ratectl_tx_complete(vap, ni, 8932 status->ack ? 8933 IEEE80211_RATECTL_TX_SUCCESS : 8934 IEEE80211_RATECTL_TX_FAILURE, 8935 &retrycnt, 0); 8936 } 8937 bwn_pio_handle_txeof(mac, status); 8938 } 8939 8940 bwn_phy_txpower_check(mac, 0); 8941 } 8942 8943 static uint8_t 8944 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 8945 { 8946 struct bwn_mac *mac = prq->prq_mac; 8947 struct bwn_softc *sc = mac->mac_sc; 8948 struct bwn_rxhdr4 rxhdr; 8949 struct mbuf *m; 8950 uint32_t ctl32, macstat, v32; 8951 unsigned int i, padding; 8952 uint16_t ctl16, len, totlen, v16; 8953 unsigned char *mp; 8954 char *data; 8955 8956 memset(&rxhdr, 0, sizeof(rxhdr)); 8957 8958 if (prq->prq_rev >= 8) { 8959 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8960 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 8961 return (0); 8962 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 8963 BWN_PIO8_RXCTL_FRAMEREADY); 8964 for (i = 0; i < 10; i++) { 8965 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 8966 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 8967 goto ready; 8968 DELAY(10); 8969 } 8970 } else { 8971 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8972 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 8973 return (0); 8974 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 8975 BWN_PIO_RXCTL_FRAMEREADY); 8976 for (i = 0; i < 10; i++) { 8977 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 8978 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 8979 goto ready; 8980 DELAY(10); 8981 } 8982 } 8983 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 8984 return (1); 8985 ready: 8986 if (prq->prq_rev >= 8) 8987 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8988 prq->prq_base + BWN_PIO8_RXDATA); 8989 else 8990 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 8991 prq->prq_base + BWN_PIO_RXDATA); 8992 len = le16toh(rxhdr.frame_len); 8993 if (len > 0x700) { 8994 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 8995 goto error; 8996 } 8997 if (len == 0) { 8998 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 8999 goto error; 9000 } 9001 9002 macstat = le32toh(rxhdr.mac_status); 9003 if (macstat & BWN_RX_MAC_FCSERR) { 9004 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9005 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9006 goto error; 9007 } 9008 } 9009 9010 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9011 totlen = len + padding; 9012 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9013 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9014 if (m == NULL) { 9015 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9016 goto error; 9017 } 9018 mp = mtod(m, unsigned char *); 9019 if (prq->prq_rev >= 8) { 9020 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9021 prq->prq_base + BWN_PIO8_RXDATA); 9022 if (totlen & 3) { 9023 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9024 data = &(mp[totlen - 1]); 9025 switch (totlen & 3) { 9026 case 3: 9027 *data = (v32 >> 16); 9028 data--; 9029 case 2: 9030 *data = (v32 >> 8); 9031 data--; 9032 case 1: 9033 *data = v32; 9034 } 9035 } 9036 } else { 9037 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9038 prq->prq_base + BWN_PIO_RXDATA); 9039 if (totlen & 1) { 9040 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9041 mp[totlen - 1] = v16; 9042 } 9043 } 9044 9045 m->m_len = m->m_pkthdr.len = totlen; 9046 9047 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9048 9049 return (1); 9050 error: 9051 if (prq->prq_rev >= 8) 9052 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9053 BWN_PIO8_RXCTL_DATAREADY); 9054 else 9055 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9056 return (1); 9057 } 9058 9059 static int 9060 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9061 struct bwn_dmadesc_meta *meta, int init) 9062 { 9063 struct bwn_mac *mac = dr->dr_mac; 9064 struct bwn_dma *dma = &mac->mac_method.dma; 9065 struct bwn_rxhdr4 *hdr; 9066 bus_dmamap_t map; 9067 bus_addr_t paddr; 9068 struct mbuf *m; 9069 int error; 9070 9071 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9072 if (m == NULL) { 9073 error = ENOBUFS; 9074 9075 /* 9076 * If the NIC is up and running, we need to: 9077 * - Clear RX buffer's header. 9078 * - Restore RX descriptor settings. 9079 */ 9080 if (init) 9081 return (error); 9082 else 9083 goto back; 9084 } 9085 m->m_len = m->m_pkthdr.len = MCLBYTES; 9086 9087 bwn_dma_set_redzone(dr, m); 9088 9089 /* 9090 * Try to load RX buf into temporary DMA map 9091 */ 9092 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9093 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9094 if (error) { 9095 m_freem(m); 9096 9097 /* 9098 * See the comment above 9099 */ 9100 if (init) 9101 return (error); 9102 else 9103 goto back; 9104 } 9105 9106 if (!init) 9107 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9108 meta->mt_m = m; 9109 meta->mt_paddr = paddr; 9110 9111 /* 9112 * Swap RX buf's DMA map with the loaded temporary one 9113 */ 9114 map = meta->mt_dmap; 9115 meta->mt_dmap = dr->dr_spare_dmap; 9116 dr->dr_spare_dmap = map; 9117 9118 back: 9119 /* 9120 * Clear RX buf header 9121 */ 9122 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9123 bzero(hdr, sizeof(*hdr)); 9124 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9125 BUS_DMASYNC_PREWRITE); 9126 9127 /* 9128 * Setup RX buf descriptor 9129 */ 9130 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9131 sizeof(*hdr), 0, 0, 0); 9132 return (error); 9133 } 9134 9135 static void 9136 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9137 bus_size_t mapsz __unused, int error) 9138 { 9139 9140 if (!error) { 9141 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9142 *((bus_addr_t *)arg) = seg->ds_addr; 9143 } 9144 } 9145 9146 static int 9147 bwn_hwrate2ieeerate(int rate) 9148 { 9149 9150 switch (rate) { 9151 case BWN_CCK_RATE_1MB: 9152 return (2); 9153 case BWN_CCK_RATE_2MB: 9154 return (4); 9155 case BWN_CCK_RATE_5MB: 9156 return (11); 9157 case BWN_CCK_RATE_11MB: 9158 return (22); 9159 case BWN_OFDM_RATE_6MB: 9160 return (12); 9161 case BWN_OFDM_RATE_9MB: 9162 return (18); 9163 case BWN_OFDM_RATE_12MB: 9164 return (24); 9165 case BWN_OFDM_RATE_18MB: 9166 return (36); 9167 case BWN_OFDM_RATE_24MB: 9168 return (48); 9169 case BWN_OFDM_RATE_36MB: 9170 return (72); 9171 case BWN_OFDM_RATE_48MB: 9172 return (96); 9173 case BWN_OFDM_RATE_54MB: 9174 return (108); 9175 default: 9176 printf("Ooops\n"); 9177 return (0); 9178 } 9179 } 9180 9181 static void 9182 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9183 { 9184 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9185 struct bwn_plcp6 *plcp; 9186 struct bwn_softc *sc = mac->mac_sc; 9187 struct ieee80211_frame_min *wh; 9188 struct ieee80211_node *ni; 9189 struct ieee80211com *ic = &sc->sc_ic; 9190 uint32_t macstat; 9191 int padding, rate, rssi = 0, noise = 0, type; 9192 uint16_t phytype, phystat0, phystat3, chanstat; 9193 unsigned char *mp = mtod(m, unsigned char *); 9194 static int rx_mac_dec_rpt = 0; 9195 9196 BWN_ASSERT_LOCKED(sc); 9197 9198 phystat0 = le16toh(rxhdr->phy_status0); 9199 phystat3 = le16toh(rxhdr->phy_status3); 9200 macstat = le32toh(rxhdr->mac_status); 9201 chanstat = le16toh(rxhdr->channel); 9202 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9203 9204 if (macstat & BWN_RX_MAC_FCSERR) 9205 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9206 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9207 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9208 if (macstat & BWN_RX_MAC_DECERR) 9209 goto drop; 9210 9211 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9212 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9213 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9214 m->m_pkthdr.len); 9215 goto drop; 9216 } 9217 plcp = (struct bwn_plcp6 *)(mp + padding); 9218 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9219 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9220 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9221 m->m_pkthdr.len); 9222 goto drop; 9223 } 9224 wh = mtod(m, struct ieee80211_frame_min *); 9225 9226 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9227 device_printf(sc->sc_dev, 9228 "RX decryption attempted (old %d keyidx %#x)\n", 9229 BWN_ISOLDFMT(mac), 9230 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9231 9232 /* XXX calculating RSSI & noise & antenna */ 9233 9234 if (phystat0 & BWN_RX_PHYST0_OFDM) 9235 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9236 phytype == BWN_PHYTYPE_A); 9237 else 9238 rate = bwn_plcp_get_cckrate(mac, plcp); 9239 if (rate == -1) { 9240 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9241 goto drop; 9242 } 9243 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9244 9245 /* RX radio tap */ 9246 if (ieee80211_radiotap_active(ic)) 9247 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9248 m_adj(m, -IEEE80211_CRC_LEN); 9249 9250 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9251 noise = mac->mac_stats.link_noise; 9252 9253 BWN_UNLOCK(sc); 9254 9255 ni = ieee80211_find_rxnode(ic, wh); 9256 if (ni != NULL) { 9257 type = ieee80211_input(ni, m, rssi, noise); 9258 ieee80211_free_node(ni); 9259 } else 9260 type = ieee80211_input_all(ic, m, rssi, noise); 9261 9262 BWN_LOCK(sc); 9263 return; 9264 drop: 9265 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9266 } 9267 9268 static void 9269 bwn_dma_handle_txeof(struct bwn_mac *mac, 9270 const struct bwn_txstatus *status) 9271 { 9272 struct bwn_dma *dma = &mac->mac_method.dma; 9273 struct bwn_dma_ring *dr; 9274 struct bwn_dmadesc_generic *desc; 9275 struct bwn_dmadesc_meta *meta; 9276 struct bwn_softc *sc = mac->mac_sc; 9277 int slot; 9278 9279 BWN_ASSERT_LOCKED(sc); 9280 9281 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9282 if (dr == NULL) { 9283 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9284 return; 9285 } 9286 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9287 9288 while (1) { 9289 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9290 ("%s:%d: fail", __func__, __LINE__)); 9291 dr->getdesc(dr, slot, &desc, &meta); 9292 9293 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9294 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9295 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9296 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9297 9298 if (meta->mt_islast) { 9299 KASSERT(meta->mt_m != NULL, 9300 ("%s:%d: fail", __func__, __LINE__)); 9301 9302 ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0); 9303 meta->mt_ni = NULL; 9304 meta->mt_m = NULL; 9305 } else 9306 KASSERT(meta->mt_m == NULL, 9307 ("%s:%d: fail", __func__, __LINE__)); 9308 9309 dr->dr_usedslot--; 9310 if (meta->mt_islast) 9311 break; 9312 slot = bwn_dma_nextslot(dr, slot); 9313 } 9314 sc->sc_watchdog_timer = 0; 9315 if (dr->dr_stop) { 9316 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9317 ("%s:%d: fail", __func__, __LINE__)); 9318 dr->dr_stop = 0; 9319 } 9320 } 9321 9322 static void 9323 bwn_pio_handle_txeof(struct bwn_mac *mac, 9324 const struct bwn_txstatus *status) 9325 { 9326 struct bwn_pio_txqueue *tq; 9327 struct bwn_pio_txpkt *tp = NULL; 9328 struct bwn_softc *sc = mac->mac_sc; 9329 9330 BWN_ASSERT_LOCKED(sc); 9331 9332 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9333 if (tq == NULL) 9334 return; 9335 9336 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9337 tq->tq_free++; 9338 9339 if (tp->tp_ni != NULL) { 9340 /* 9341 * Do any tx complete callback. Note this must 9342 * be done before releasing the node reference. 9343 */ 9344 if (tp->tp_m->m_flags & M_TXCB) 9345 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9346 ieee80211_free_node(tp->tp_ni); 9347 tp->tp_ni = NULL; 9348 } 9349 m_freem(tp->tp_m); 9350 tp->tp_m = NULL; 9351 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9352 9353 sc->sc_watchdog_timer = 0; 9354 } 9355 9356 static void 9357 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9358 { 9359 struct bwn_softc *sc = mac->mac_sc; 9360 struct bwn_phy *phy = &mac->mac_phy; 9361 struct ieee80211com *ic = &sc->sc_ic; 9362 unsigned long now; 9363 int result; 9364 9365 BWN_GETTIME(now); 9366 9367 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9368 return; 9369 phy->nexttime = now + 2 * 1000; 9370 9371 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9372 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9373 return; 9374 9375 if (phy->recalc_txpwr != NULL) { 9376 result = phy->recalc_txpwr(mac, 9377 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9378 if (result == BWN_TXPWR_RES_DONE) 9379 return; 9380 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9381 ("%s: fail", __func__)); 9382 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9383 9384 ieee80211_runtask(ic, &mac->mac_txpower); 9385 } 9386 } 9387 9388 static uint16_t 9389 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9390 { 9391 9392 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9393 } 9394 9395 static uint32_t 9396 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9397 { 9398 9399 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9400 } 9401 9402 static void 9403 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9404 { 9405 9406 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9407 } 9408 9409 static void 9410 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9411 { 9412 9413 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9414 } 9415 9416 static int 9417 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9418 { 9419 9420 switch (rate) { 9421 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9422 case 12: 9423 return (BWN_OFDM_RATE_6MB); 9424 case 18: 9425 return (BWN_OFDM_RATE_9MB); 9426 case 24: 9427 return (BWN_OFDM_RATE_12MB); 9428 case 36: 9429 return (BWN_OFDM_RATE_18MB); 9430 case 48: 9431 return (BWN_OFDM_RATE_24MB); 9432 case 72: 9433 return (BWN_OFDM_RATE_36MB); 9434 case 96: 9435 return (BWN_OFDM_RATE_48MB); 9436 case 108: 9437 return (BWN_OFDM_RATE_54MB); 9438 /* CCK rates (NB: not IEEE std, device-specific) */ 9439 case 2: 9440 return (BWN_CCK_RATE_1MB); 9441 case 4: 9442 return (BWN_CCK_RATE_2MB); 9443 case 11: 9444 return (BWN_CCK_RATE_5MB); 9445 case 22: 9446 return (BWN_CCK_RATE_11MB); 9447 } 9448 9449 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9450 return (BWN_CCK_RATE_1MB); 9451 } 9452 9453 static int 9454 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9455 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9456 { 9457 const struct bwn_phy *phy = &mac->mac_phy; 9458 struct bwn_softc *sc = mac->mac_sc; 9459 struct ieee80211_frame *wh; 9460 struct ieee80211_frame *protwh; 9461 struct ieee80211_frame_cts *cts; 9462 struct ieee80211_frame_rts *rts; 9463 const struct ieee80211_txparam *tp; 9464 struct ieee80211vap *vap = ni->ni_vap; 9465 struct ieee80211com *ic = &sc->sc_ic; 9466 struct mbuf *mprot; 9467 unsigned int len; 9468 uint32_t macctl = 0; 9469 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9470 uint16_t phyctl = 0; 9471 uint8_t rate, rate_fb; 9472 9473 wh = mtod(m, struct ieee80211_frame *); 9474 memset(txhdr, 0, sizeof(*txhdr)); 9475 9476 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9477 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9478 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9479 9480 /* 9481 * Find TX rate 9482 */ 9483 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9484 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9485 rate = rate_fb = tp->mgmtrate; 9486 else if (ismcast) 9487 rate = rate_fb = tp->mcastrate; 9488 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9489 rate = rate_fb = tp->ucastrate; 9490 else { 9491 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9492 rate = ni->ni_txrate; 9493 9494 if (rix > 0) 9495 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9496 IEEE80211_RATE_VAL; 9497 else 9498 rate_fb = rate; 9499 } 9500 9501 sc->sc_tx_rate = rate; 9502 9503 rate = bwn_ieeerate2hwrate(sc, rate); 9504 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9505 9506 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9507 bwn_plcp_getcck(rate); 9508 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9509 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9510 9511 if ((rate_fb == rate) || 9512 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9513 (*(u_int16_t *)wh->i_dur == htole16(0))) 9514 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9515 else 9516 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9517 m->m_pkthdr.len, rate, isshort); 9518 9519 /* XXX TX encryption */ 9520 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9521 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9522 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9523 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9524 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9525 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9526 9527 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9528 BWN_TX_EFT_FB_CCK; 9529 txhdr->chan = phy->chan; 9530 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9531 BWN_TX_PHY_ENC_CCK; 9532 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9533 rate == BWN_CCK_RATE_11MB)) 9534 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9535 9536 /* XXX TX antenna selection */ 9537 9538 switch (bwn_antenna_sanitize(mac, 0)) { 9539 case 0: 9540 phyctl |= BWN_TX_PHY_ANT01AUTO; 9541 break; 9542 case 1: 9543 phyctl |= BWN_TX_PHY_ANT0; 9544 break; 9545 case 2: 9546 phyctl |= BWN_TX_PHY_ANT1; 9547 break; 9548 case 3: 9549 phyctl |= BWN_TX_PHY_ANT2; 9550 break; 9551 case 4: 9552 phyctl |= BWN_TX_PHY_ANT3; 9553 break; 9554 default: 9555 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9556 } 9557 9558 if (!ismcast) 9559 macctl |= BWN_TX_MAC_ACK; 9560 9561 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9562 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9563 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9564 macctl |= BWN_TX_MAC_LONGFRAME; 9565 9566 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9567 /* XXX RTS rate is always 1MB??? */ 9568 rts_rate = BWN_CCK_RATE_1MB; 9569 rts_rate_fb = bwn_get_fbrate(rts_rate); 9570 9571 protdur = ieee80211_compute_duration(ic->ic_rt, 9572 m->m_pkthdr.len, rate, isshort) + 9573 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9574 9575 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9576 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9577 (txhdr->body.old.rts_frame) : 9578 (txhdr->body.new.rts_frame)); 9579 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9580 protdur); 9581 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9582 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9583 mprot->m_pkthdr.len); 9584 m_freem(mprot); 9585 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9586 len = sizeof(struct ieee80211_frame_cts); 9587 } else { 9588 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9589 (txhdr->body.old.rts_frame) : 9590 (txhdr->body.new.rts_frame)); 9591 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9592 isshort); 9593 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9594 wh->i_addr2, protdur); 9595 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9596 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9597 mprot->m_pkthdr.len); 9598 m_freem(mprot); 9599 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9600 len = sizeof(struct ieee80211_frame_rts); 9601 } 9602 len += IEEE80211_CRC_LEN; 9603 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9604 &txhdr->body.old.rts_plcp : 9605 &txhdr->body.new.rts_plcp), len, rts_rate); 9606 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9607 rts_rate_fb); 9608 9609 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9610 (&txhdr->body.old.rts_frame) : 9611 (&txhdr->body.new.rts_frame)); 9612 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9613 9614 if (BWN_ISOFDMRATE(rts_rate)) { 9615 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9616 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9617 } else { 9618 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9619 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9620 } 9621 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9622 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9623 } 9624 9625 if (BWN_ISOLDFMT(mac)) 9626 txhdr->body.old.cookie = htole16(cookie); 9627 else 9628 txhdr->body.new.cookie = htole16(cookie); 9629 9630 txhdr->macctl = htole32(macctl); 9631 txhdr->phyctl = htole16(phyctl); 9632 9633 /* 9634 * TX radio tap 9635 */ 9636 if (ieee80211_radiotap_active_vap(vap)) { 9637 sc->sc_tx_th.wt_flags = 0; 9638 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9639 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9640 if (isshort && 9641 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9642 rate == BWN_CCK_RATE_11MB)) 9643 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9644 sc->sc_tx_th.wt_rate = rate; 9645 9646 ieee80211_radiotap_tx(vap, m); 9647 } 9648 9649 return (0); 9650 } 9651 9652 static void 9653 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9654 const uint8_t rate) 9655 { 9656 uint32_t d, plen; 9657 uint8_t *raw = plcp->o.raw; 9658 9659 if (BWN_ISOFDMRATE(rate)) { 9660 d = bwn_plcp_getofdm(rate); 9661 KASSERT(!(octets & 0xf000), 9662 ("%s:%d: fail", __func__, __LINE__)); 9663 d |= (octets << 5); 9664 plcp->o.data = htole32(d); 9665 } else { 9666 plen = octets * 16 / rate; 9667 if ((octets * 16 % rate) > 0) { 9668 plen++; 9669 if ((rate == BWN_CCK_RATE_11MB) 9670 && ((octets * 8 % 11) < 4)) { 9671 raw[1] = 0x84; 9672 } else 9673 raw[1] = 0x04; 9674 } else 9675 raw[1] = 0x04; 9676 plcp->o.data |= htole32(plen << 16); 9677 raw[0] = bwn_plcp_getcck(rate); 9678 } 9679 } 9680 9681 static uint8_t 9682 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9683 { 9684 struct bwn_softc *sc = mac->mac_sc; 9685 uint8_t mask; 9686 9687 if (n == 0) 9688 return (0); 9689 if (mac->mac_phy.gmode) 9690 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9691 else 9692 mask = siba_sprom_get_ant_a(sc->sc_dev); 9693 if (!(mask & (1 << (n - 1)))) 9694 return (0); 9695 return (n); 9696 } 9697 9698 static uint8_t 9699 bwn_get_fbrate(uint8_t bitrate) 9700 { 9701 switch (bitrate) { 9702 case BWN_CCK_RATE_1MB: 9703 return (BWN_CCK_RATE_1MB); 9704 case BWN_CCK_RATE_2MB: 9705 return (BWN_CCK_RATE_1MB); 9706 case BWN_CCK_RATE_5MB: 9707 return (BWN_CCK_RATE_2MB); 9708 case BWN_CCK_RATE_11MB: 9709 return (BWN_CCK_RATE_5MB); 9710 case BWN_OFDM_RATE_6MB: 9711 return (BWN_CCK_RATE_5MB); 9712 case BWN_OFDM_RATE_9MB: 9713 return (BWN_OFDM_RATE_6MB); 9714 case BWN_OFDM_RATE_12MB: 9715 return (BWN_OFDM_RATE_9MB); 9716 case BWN_OFDM_RATE_18MB: 9717 return (BWN_OFDM_RATE_12MB); 9718 case BWN_OFDM_RATE_24MB: 9719 return (BWN_OFDM_RATE_18MB); 9720 case BWN_OFDM_RATE_36MB: 9721 return (BWN_OFDM_RATE_24MB); 9722 case BWN_OFDM_RATE_48MB: 9723 return (BWN_OFDM_RATE_36MB); 9724 case BWN_OFDM_RATE_54MB: 9725 return (BWN_OFDM_RATE_48MB); 9726 } 9727 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9728 return (0); 9729 } 9730 9731 static uint32_t 9732 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9733 uint32_t ctl, const void *_data, int len) 9734 { 9735 struct bwn_softc *sc = mac->mac_sc; 9736 uint32_t value = 0; 9737 const uint8_t *data = _data; 9738 9739 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9740 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9741 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9742 9743 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9744 tq->tq_base + BWN_PIO8_TXDATA); 9745 if (len & 3) { 9746 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9747 BWN_PIO8_TXCTL_24_31); 9748 data = &(data[len - 1]); 9749 switch (len & 3) { 9750 case 3: 9751 ctl |= BWN_PIO8_TXCTL_16_23; 9752 value |= (uint32_t)(*data) << 16; 9753 data--; 9754 case 2: 9755 ctl |= BWN_PIO8_TXCTL_8_15; 9756 value |= (uint32_t)(*data) << 8; 9757 data--; 9758 case 1: 9759 value |= (uint32_t)(*data); 9760 } 9761 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9762 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9763 } 9764 9765 return (ctl); 9766 } 9767 9768 static void 9769 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9770 uint16_t offset, uint32_t value) 9771 { 9772 9773 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9774 } 9775 9776 static uint16_t 9777 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9778 uint16_t ctl, const void *_data, int len) 9779 { 9780 struct bwn_softc *sc = mac->mac_sc; 9781 const uint8_t *data = _data; 9782 9783 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9784 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9785 9786 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9787 tq->tq_base + BWN_PIO_TXDATA); 9788 if (len & 1) { 9789 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9790 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9791 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9792 } 9793 9794 return (ctl); 9795 } 9796 9797 static uint16_t 9798 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9799 uint16_t ctl, struct mbuf *m0) 9800 { 9801 int i, j = 0; 9802 uint16_t data = 0; 9803 const uint8_t *buf; 9804 struct mbuf *m = m0; 9805 9806 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9807 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9808 9809 for (; m != NULL; m = m->m_next) { 9810 buf = mtod(m, const uint8_t *); 9811 for (i = 0; i < m->m_len; i++) { 9812 if (!((j++) % 2)) 9813 data |= buf[i]; 9814 else { 9815 data |= (buf[i] << 8); 9816 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9817 data = 0; 9818 } 9819 } 9820 } 9821 if (m0->m_pkthdr.len % 2) { 9822 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9823 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9824 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9825 } 9826 9827 return (ctl); 9828 } 9829 9830 static void 9831 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9832 { 9833 9834 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9835 return; 9836 BWN_WRITE_2(mac, 0x684, 510 + time); 9837 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9838 } 9839 9840 static struct bwn_dma_ring * 9841 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9842 { 9843 9844 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9845 return (mac->mac_method.dma.wme[WME_AC_BE]); 9846 9847 switch (prio) { 9848 case 3: 9849 return (mac->mac_method.dma.wme[WME_AC_VO]); 9850 case 2: 9851 return (mac->mac_method.dma.wme[WME_AC_VI]); 9852 case 0: 9853 return (mac->mac_method.dma.wme[WME_AC_BE]); 9854 case 1: 9855 return (mac->mac_method.dma.wme[WME_AC_BK]); 9856 } 9857 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9858 return (NULL); 9859 } 9860 9861 static int 9862 bwn_dma_getslot(struct bwn_dma_ring *dr) 9863 { 9864 int slot; 9865 9866 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 9867 9868 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9869 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 9870 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 9871 9872 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 9873 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 9874 dr->dr_curslot = slot; 9875 dr->dr_usedslot++; 9876 9877 return (slot); 9878 } 9879 9880 static int 9881 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 9882 { 9883 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 9884 unsigned int a, b, c, d; 9885 unsigned int avg; 9886 uint32_t tmp; 9887 9888 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 9889 a = tmp & 0xff; 9890 b = (tmp >> 8) & 0xff; 9891 c = (tmp >> 16) & 0xff; 9892 d = (tmp >> 24) & 0xff; 9893 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 9894 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 9895 return (ENOENT); 9896 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 9897 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 9898 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 9899 9900 if (ofdm) { 9901 a = (a + 32) & 0x3f; 9902 b = (b + 32) & 0x3f; 9903 c = (c + 32) & 0x3f; 9904 d = (d + 32) & 0x3f; 9905 } 9906 9907 avg = (a + b + c + d + 2) / 4; 9908 if (ofdm) { 9909 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 9910 & BWN_HF_4DB_CCK_POWERBOOST) 9911 avg = (avg >= 13) ? (avg - 13) : 0; 9912 } 9913 return (avg); 9914 } 9915 9916 static void 9917 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 9918 { 9919 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 9920 int rfatt = *rfattp; 9921 int bbatt = *bbattp; 9922 9923 while (1) { 9924 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 9925 break; 9926 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 9927 break; 9928 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 9929 break; 9930 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 9931 break; 9932 if (bbatt > lo->bbatt.max) { 9933 bbatt -= 4; 9934 rfatt += 1; 9935 continue; 9936 } 9937 if (bbatt < lo->bbatt.min) { 9938 bbatt += 4; 9939 rfatt -= 1; 9940 continue; 9941 } 9942 if (rfatt > lo->rfatt.max) { 9943 rfatt -= 1; 9944 bbatt += 4; 9945 continue; 9946 } 9947 if (rfatt < lo->rfatt.min) { 9948 rfatt += 1; 9949 bbatt -= 4; 9950 continue; 9951 } 9952 break; 9953 } 9954 9955 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 9956 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 9957 } 9958 9959 static void 9960 bwn_phy_lock(struct bwn_mac *mac) 9961 { 9962 struct bwn_softc *sc = mac->mac_sc; 9963 struct ieee80211com *ic = &sc->sc_ic; 9964 9965 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 9966 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 9967 9968 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 9969 bwn_psctl(mac, BWN_PS_AWAKE); 9970 } 9971 9972 static void 9973 bwn_phy_unlock(struct bwn_mac *mac) 9974 { 9975 struct bwn_softc *sc = mac->mac_sc; 9976 struct ieee80211com *ic = &sc->sc_ic; 9977 9978 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 9979 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 9980 9981 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 9982 bwn_psctl(mac, 0); 9983 } 9984 9985 static void 9986 bwn_rf_lock(struct bwn_mac *mac) 9987 { 9988 9989 BWN_WRITE_4(mac, BWN_MACCTL, 9990 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 9991 BWN_READ_4(mac, BWN_MACCTL); 9992 DELAY(10); 9993 } 9994 9995 static void 9996 bwn_rf_unlock(struct bwn_mac *mac) 9997 { 9998 9999 BWN_READ_2(mac, BWN_PHYVER); 10000 BWN_WRITE_4(mac, BWN_MACCTL, 10001 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10002 } 10003 10004 static struct bwn_pio_txqueue * 10005 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10006 struct bwn_pio_txpkt **pack) 10007 { 10008 struct bwn_pio *pio = &mac->mac_method.pio; 10009 struct bwn_pio_txqueue *tq = NULL; 10010 unsigned int index; 10011 10012 switch (cookie & 0xf000) { 10013 case 0x1000: 10014 tq = &pio->wme[WME_AC_BK]; 10015 break; 10016 case 0x2000: 10017 tq = &pio->wme[WME_AC_BE]; 10018 break; 10019 case 0x3000: 10020 tq = &pio->wme[WME_AC_VI]; 10021 break; 10022 case 0x4000: 10023 tq = &pio->wme[WME_AC_VO]; 10024 break; 10025 case 0x5000: 10026 tq = &pio->mcast; 10027 break; 10028 } 10029 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10030 if (tq == NULL) 10031 return (NULL); 10032 index = (cookie & 0x0fff); 10033 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10034 if (index >= N(tq->tq_pkts)) 10035 return (NULL); 10036 *pack = &tq->tq_pkts[index]; 10037 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10038 return (tq); 10039 } 10040 10041 static void 10042 bwn_txpwr(void *arg, int npending) 10043 { 10044 struct bwn_mac *mac = arg; 10045 struct bwn_softc *sc = mac->mac_sc; 10046 10047 BWN_LOCK(sc); 10048 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10049 mac->mac_phy.set_txpwr != NULL) 10050 mac->mac_phy.set_txpwr(mac); 10051 BWN_UNLOCK(sc); 10052 } 10053 10054 static void 10055 bwn_task_15s(struct bwn_mac *mac) 10056 { 10057 uint16_t reg; 10058 10059 if (mac->mac_fw.opensource) { 10060 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10061 if (reg) { 10062 bwn_restart(mac, "fw watchdog"); 10063 return; 10064 } 10065 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10066 } 10067 if (mac->mac_phy.task_15s) 10068 mac->mac_phy.task_15s(mac); 10069 10070 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10071 } 10072 10073 static void 10074 bwn_task_30s(struct bwn_mac *mac) 10075 { 10076 10077 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10078 return; 10079 mac->mac_noise.noi_running = 1; 10080 mac->mac_noise.noi_nsamples = 0; 10081 10082 bwn_noise_gensample(mac); 10083 } 10084 10085 static void 10086 bwn_task_60s(struct bwn_mac *mac) 10087 { 10088 10089 if (mac->mac_phy.task_60s) 10090 mac->mac_phy.task_60s(mac); 10091 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10092 } 10093 10094 static void 10095 bwn_tasks(void *arg) 10096 { 10097 struct bwn_mac *mac = arg; 10098 struct bwn_softc *sc = mac->mac_sc; 10099 10100 BWN_ASSERT_LOCKED(sc); 10101 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10102 return; 10103 10104 if (mac->mac_task_state % 4 == 0) 10105 bwn_task_60s(mac); 10106 if (mac->mac_task_state % 2 == 0) 10107 bwn_task_30s(mac); 10108 bwn_task_15s(mac); 10109 10110 mac->mac_task_state++; 10111 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10112 } 10113 10114 static int 10115 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10116 { 10117 struct bwn_softc *sc = mac->mac_sc; 10118 10119 KASSERT(a == 0, ("not support APHY\n")); 10120 10121 switch (plcp->o.raw[0] & 0xf) { 10122 case 0xb: 10123 return (BWN_OFDM_RATE_6MB); 10124 case 0xf: 10125 return (BWN_OFDM_RATE_9MB); 10126 case 0xa: 10127 return (BWN_OFDM_RATE_12MB); 10128 case 0xe: 10129 return (BWN_OFDM_RATE_18MB); 10130 case 0x9: 10131 return (BWN_OFDM_RATE_24MB); 10132 case 0xd: 10133 return (BWN_OFDM_RATE_36MB); 10134 case 0x8: 10135 return (BWN_OFDM_RATE_48MB); 10136 case 0xc: 10137 return (BWN_OFDM_RATE_54MB); 10138 } 10139 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10140 plcp->o.raw[0] & 0xf); 10141 return (-1); 10142 } 10143 10144 static int 10145 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10146 { 10147 struct bwn_softc *sc = mac->mac_sc; 10148 10149 switch (plcp->o.raw[0]) { 10150 case 0x0a: 10151 return (BWN_CCK_RATE_1MB); 10152 case 0x14: 10153 return (BWN_CCK_RATE_2MB); 10154 case 0x37: 10155 return (BWN_CCK_RATE_5MB); 10156 case 0x6e: 10157 return (BWN_CCK_RATE_11MB); 10158 } 10159 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10160 return (-1); 10161 } 10162 10163 static void 10164 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10165 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10166 int rssi, int noise) 10167 { 10168 struct bwn_softc *sc = mac->mac_sc; 10169 const struct ieee80211_frame_min *wh; 10170 uint64_t tsf; 10171 uint16_t low_mactime_now; 10172 10173 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10174 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10175 10176 wh = mtod(m, const struct ieee80211_frame_min *); 10177 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10178 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10179 10180 bwn_tsf_read(mac, &tsf); 10181 low_mactime_now = tsf; 10182 tsf = tsf & ~0xffffULL; 10183 tsf += le16toh(rxhdr->mac_time); 10184 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10185 tsf -= 0x10000; 10186 10187 sc->sc_rx_th.wr_tsf = tsf; 10188 sc->sc_rx_th.wr_rate = rate; 10189 sc->sc_rx_th.wr_antsignal = rssi; 10190 sc->sc_rx_th.wr_antnoise = noise; 10191 } 10192 10193 static void 10194 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10195 { 10196 uint32_t low, high; 10197 10198 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10199 ("%s:%d: fail", __func__, __LINE__)); 10200 10201 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10202 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10203 *tsf = high; 10204 *tsf <<= 32; 10205 *tsf |= low; 10206 } 10207 10208 static int 10209 bwn_dma_attach(struct bwn_mac *mac) 10210 { 10211 struct bwn_dma *dma = &mac->mac_method.dma; 10212 struct bwn_softc *sc = mac->mac_sc; 10213 bus_addr_t lowaddr = 0; 10214 int error; 10215 10216 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10217 return (0); 10218 10219 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10220 10221 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10222 10223 dma->dmatype = bwn_dma_gettype(mac); 10224 if (dma->dmatype == BWN_DMA_30BIT) 10225 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10226 else if (dma->dmatype == BWN_DMA_32BIT) 10227 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10228 else 10229 lowaddr = BUS_SPACE_MAXADDR; 10230 10231 /* 10232 * Create top level DMA tag 10233 */ 10234 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10235 BWN_ALIGN, 0, /* alignment, bounds */ 10236 lowaddr, /* lowaddr */ 10237 BUS_SPACE_MAXADDR, /* highaddr */ 10238 NULL, NULL, /* filter, filterarg */ 10239 BUS_SPACE_MAXSIZE, /* maxsize */ 10240 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10241 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10242 0, /* flags */ 10243 NULL, NULL, /* lockfunc, lockarg */ 10244 &dma->parent_dtag); 10245 if (error) { 10246 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10247 return (error); 10248 } 10249 10250 /* 10251 * Create TX/RX mbuf DMA tag 10252 */ 10253 error = bus_dma_tag_create(dma->parent_dtag, 10254 1, 10255 0, 10256 BUS_SPACE_MAXADDR, 10257 BUS_SPACE_MAXADDR, 10258 NULL, NULL, 10259 MCLBYTES, 10260 1, 10261 BUS_SPACE_MAXSIZE_32BIT, 10262 0, 10263 NULL, NULL, 10264 &dma->rxbuf_dtag); 10265 if (error) { 10266 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10267 goto fail0; 10268 } 10269 error = bus_dma_tag_create(dma->parent_dtag, 10270 1, 10271 0, 10272 BUS_SPACE_MAXADDR, 10273 BUS_SPACE_MAXADDR, 10274 NULL, NULL, 10275 MCLBYTES, 10276 1, 10277 BUS_SPACE_MAXSIZE_32BIT, 10278 0, 10279 NULL, NULL, 10280 &dma->txbuf_dtag); 10281 if (error) { 10282 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10283 goto fail1; 10284 } 10285 10286 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10287 if (!dma->wme[WME_AC_BK]) 10288 goto fail2; 10289 10290 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10291 if (!dma->wme[WME_AC_BE]) 10292 goto fail3; 10293 10294 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10295 if (!dma->wme[WME_AC_VI]) 10296 goto fail4; 10297 10298 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10299 if (!dma->wme[WME_AC_VO]) 10300 goto fail5; 10301 10302 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10303 if (!dma->mcast) 10304 goto fail6; 10305 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10306 if (!dma->rx) 10307 goto fail7; 10308 10309 return (error); 10310 10311 fail7: bwn_dma_ringfree(&dma->mcast); 10312 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10313 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10314 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10315 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10316 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10317 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10318 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10319 return (error); 10320 } 10321 10322 static struct bwn_dma_ring * 10323 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10324 uint16_t cookie, int *slot) 10325 { 10326 struct bwn_dma *dma = &mac->mac_method.dma; 10327 struct bwn_dma_ring *dr; 10328 struct bwn_softc *sc = mac->mac_sc; 10329 10330 BWN_ASSERT_LOCKED(mac->mac_sc); 10331 10332 switch (cookie & 0xf000) { 10333 case 0x1000: 10334 dr = dma->wme[WME_AC_BK]; 10335 break; 10336 case 0x2000: 10337 dr = dma->wme[WME_AC_BE]; 10338 break; 10339 case 0x3000: 10340 dr = dma->wme[WME_AC_VI]; 10341 break; 10342 case 0x4000: 10343 dr = dma->wme[WME_AC_VO]; 10344 break; 10345 case 0x5000: 10346 dr = dma->mcast; 10347 break; 10348 default: 10349 dr = NULL; 10350 KASSERT(0 == 1, 10351 ("invalid cookie value %d", cookie & 0xf000)); 10352 } 10353 *slot = (cookie & 0x0fff); 10354 if (*slot < 0 || *slot >= dr->dr_numslots) { 10355 /* 10356 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10357 * that it occurs events which have same H/W sequence numbers. 10358 * When it's occurred just prints a WARNING msgs and ignores. 10359 */ 10360 KASSERT(status->seq == dma->lastseq, 10361 ("%s:%d: fail", __func__, __LINE__)); 10362 device_printf(sc->sc_dev, 10363 "out of slot ranges (0 < %d < %d)\n", *slot, 10364 dr->dr_numslots); 10365 return (NULL); 10366 } 10367 dma->lastseq = status->seq; 10368 return (dr); 10369 } 10370 10371 static void 10372 bwn_dma_stop(struct bwn_mac *mac) 10373 { 10374 struct bwn_dma *dma; 10375 10376 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10377 return; 10378 dma = &mac->mac_method.dma; 10379 10380 bwn_dma_ringstop(&dma->rx); 10381 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10382 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10383 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10384 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10385 bwn_dma_ringstop(&dma->mcast); 10386 } 10387 10388 static void 10389 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10390 { 10391 10392 if (dr == NULL) 10393 return; 10394 10395 bwn_dma_cleanup(*dr); 10396 } 10397 10398 static void 10399 bwn_pio_stop(struct bwn_mac *mac) 10400 { 10401 struct bwn_pio *pio; 10402 10403 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10404 return; 10405 pio = &mac->mac_method.pio; 10406 10407 bwn_destroy_queue_tx(&pio->mcast); 10408 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10409 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10410 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10411 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10412 } 10413 10414 static void 10415 bwn_led_attach(struct bwn_mac *mac) 10416 { 10417 struct bwn_softc *sc = mac->mac_sc; 10418 const uint8_t *led_act = NULL; 10419 uint16_t val[BWN_LED_MAX]; 10420 int i; 10421 10422 sc->sc_led_idle = (2350 * hz) / 1000; 10423 sc->sc_led_blink = 1; 10424 10425 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10426 if (siba_get_pci_subvendor(sc->sc_dev) == 10427 bwn_vendor_led_act[i].vid) { 10428 led_act = bwn_vendor_led_act[i].led_act; 10429 break; 10430 } 10431 } 10432 if (led_act == NULL) 10433 led_act = bwn_default_led_act; 10434 10435 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10436 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10437 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10438 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10439 10440 for (i = 0; i < BWN_LED_MAX; ++i) { 10441 struct bwn_led *led = &sc->sc_leds[i]; 10442 10443 if (val[i] == 0xff) { 10444 led->led_act = led_act[i]; 10445 } else { 10446 if (val[i] & BWN_LED_ACT_LOW) 10447 led->led_flags |= BWN_LED_F_ACTLOW; 10448 led->led_act = val[i] & BWN_LED_ACT_MASK; 10449 } 10450 led->led_mask = (1 << i); 10451 10452 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10453 led->led_act == BWN_LED_ACT_BLINK_POLL || 10454 led->led_act == BWN_LED_ACT_BLINK) { 10455 led->led_flags |= BWN_LED_F_BLINK; 10456 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10457 led->led_flags |= BWN_LED_F_POLLABLE; 10458 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10459 led->led_flags |= BWN_LED_F_SLOW; 10460 10461 if (sc->sc_blink_led == NULL) { 10462 sc->sc_blink_led = led; 10463 if (led->led_flags & BWN_LED_F_SLOW) 10464 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10465 } 10466 } 10467 10468 DPRINTF(sc, BWN_DEBUG_LED, 10469 "%dth led, act %d, lowact %d\n", i, 10470 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10471 } 10472 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10473 } 10474 10475 static __inline uint16_t 10476 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10477 { 10478 10479 if (led->led_flags & BWN_LED_F_ACTLOW) 10480 on = !on; 10481 if (on) 10482 val |= led->led_mask; 10483 else 10484 val &= ~led->led_mask; 10485 return val; 10486 } 10487 10488 static void 10489 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10490 { 10491 struct bwn_softc *sc = mac->mac_sc; 10492 struct ieee80211com *ic = &sc->sc_ic; 10493 uint16_t val; 10494 int i; 10495 10496 if (nstate == IEEE80211_S_INIT) { 10497 callout_stop(&sc->sc_led_blink_ch); 10498 sc->sc_led_blinking = 0; 10499 } 10500 10501 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) 10502 return; 10503 10504 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10505 for (i = 0; i < BWN_LED_MAX; ++i) { 10506 struct bwn_led *led = &sc->sc_leds[i]; 10507 int on; 10508 10509 if (led->led_act == BWN_LED_ACT_UNKN || 10510 led->led_act == BWN_LED_ACT_NULL) 10511 continue; 10512 10513 if ((led->led_flags & BWN_LED_F_BLINK) && 10514 nstate != IEEE80211_S_INIT) 10515 continue; 10516 10517 switch (led->led_act) { 10518 case BWN_LED_ACT_ON: /* Always on */ 10519 on = 1; 10520 break; 10521 case BWN_LED_ACT_OFF: /* Always off */ 10522 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10523 on = 0; 10524 break; 10525 default: 10526 on = 1; 10527 switch (nstate) { 10528 case IEEE80211_S_INIT: 10529 on = 0; 10530 break; 10531 case IEEE80211_S_RUN: 10532 if (led->led_act == BWN_LED_ACT_11G && 10533 ic->ic_curmode != IEEE80211_MODE_11G) 10534 on = 0; 10535 break; 10536 default: 10537 if (led->led_act == BWN_LED_ACT_ASSOC) 10538 on = 0; 10539 break; 10540 } 10541 break; 10542 } 10543 10544 val = bwn_led_onoff(led, val, on); 10545 } 10546 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10547 } 10548 10549 static void 10550 bwn_led_event(struct bwn_mac *mac, int event) 10551 { 10552 struct bwn_softc *sc = mac->mac_sc; 10553 struct bwn_led *led = sc->sc_blink_led; 10554 int rate; 10555 10556 if (event == BWN_LED_EVENT_POLL) { 10557 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10558 return; 10559 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10560 return; 10561 } 10562 10563 sc->sc_led_ticks = ticks; 10564 if (sc->sc_led_blinking) 10565 return; 10566 10567 switch (event) { 10568 case BWN_LED_EVENT_RX: 10569 rate = sc->sc_rx_rate; 10570 break; 10571 case BWN_LED_EVENT_TX: 10572 rate = sc->sc_tx_rate; 10573 break; 10574 case BWN_LED_EVENT_POLL: 10575 rate = 0; 10576 break; 10577 default: 10578 panic("unknown LED event %d\n", event); 10579 break; 10580 } 10581 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10582 bwn_led_duration[rate].off_dur); 10583 } 10584 10585 static void 10586 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10587 { 10588 struct bwn_softc *sc = mac->mac_sc; 10589 struct bwn_led *led = sc->sc_blink_led; 10590 uint16_t val; 10591 10592 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10593 val = bwn_led_onoff(led, val, 1); 10594 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10595 10596 if (led->led_flags & BWN_LED_F_SLOW) { 10597 BWN_LED_SLOWDOWN(on_dur); 10598 BWN_LED_SLOWDOWN(off_dur); 10599 } 10600 10601 sc->sc_led_blinking = 1; 10602 sc->sc_led_blink_offdur = off_dur; 10603 10604 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10605 } 10606 10607 static void 10608 bwn_led_blink_next(void *arg) 10609 { 10610 struct bwn_mac *mac = arg; 10611 struct bwn_softc *sc = mac->mac_sc; 10612 uint16_t val; 10613 10614 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10615 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10616 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10617 10618 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10619 bwn_led_blink_end, mac); 10620 } 10621 10622 static void 10623 bwn_led_blink_end(void *arg) 10624 { 10625 struct bwn_mac *mac = arg; 10626 struct bwn_softc *sc = mac->mac_sc; 10627 10628 sc->sc_led_blinking = 0; 10629 } 10630 10631 static int 10632 bwn_suspend(device_t dev) 10633 { 10634 struct bwn_softc *sc = device_get_softc(dev); 10635 10636 BWN_LOCK(sc); 10637 bwn_stop(sc); 10638 BWN_UNLOCK(sc); 10639 return (0); 10640 } 10641 10642 static int 10643 bwn_resume(device_t dev) 10644 { 10645 struct bwn_softc *sc = device_get_softc(dev); 10646 int error = EDOOFUS; 10647 10648 BWN_LOCK(sc); 10649 if (sc->sc_ic.ic_nrunning > 0) 10650 error = bwn_init(sc); 10651 BWN_UNLOCK(sc); 10652 if (error == 0) 10653 ieee80211_start_all(&sc->sc_ic); 10654 return (0); 10655 } 10656 10657 static void 10658 bwn_rfswitch(void *arg) 10659 { 10660 struct bwn_softc *sc = arg; 10661 struct bwn_mac *mac = sc->sc_curmac; 10662 int cur = 0, prev = 0; 10663 10664 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10665 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10666 10667 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10668 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10669 & BWN_RF_HWENABLED_HI_MASK)) 10670 cur = 1; 10671 } else { 10672 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10673 & BWN_RF_HWENABLED_LO_MASK) 10674 cur = 1; 10675 } 10676 10677 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10678 prev = 1; 10679 10680 if (cur != prev) { 10681 if (cur) 10682 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10683 else 10684 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10685 10686 device_printf(sc->sc_dev, 10687 "status of RF switch is changed to %s\n", 10688 cur ? "ON" : "OFF"); 10689 if (cur != mac->mac_phy.rf_on) { 10690 if (cur) 10691 bwn_rf_turnon(mac); 10692 else 10693 bwn_rf_turnoff(mac); 10694 } 10695 } 10696 10697 callout_schedule(&sc->sc_rfswitch_ch, hz); 10698 } 10699 10700 static void 10701 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10702 { 10703 struct bwn_phy *phy = &mac->mac_phy; 10704 struct bwn_phy_lp *plp = &phy->phy_lp; 10705 10706 plp->plp_antenna = BWN_ANT_DEFAULT; 10707 } 10708 10709 static int 10710 bwn_phy_lp_init(struct bwn_mac *mac) 10711 { 10712 static const struct bwn_stxtable tables[] = { 10713 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10714 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10715 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10716 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10717 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10718 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10719 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10720 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10721 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10722 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10723 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10724 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10725 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10726 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10727 { 2, 11, 0x40, 0, 0x0f } 10728 }; 10729 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10730 struct bwn_softc *sc = mac->mac_sc; 10731 const struct bwn_stxtable *st; 10732 struct ieee80211com *ic = &sc->sc_ic; 10733 int i, error; 10734 uint16_t tmp; 10735 10736 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10737 bwn_phy_lp_bbinit(mac); 10738 10739 /* initialize RF */ 10740 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10741 DELAY(1); 10742 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10743 DELAY(1); 10744 10745 if (mac->mac_phy.rf_ver == 0x2062) 10746 bwn_phy_lp_b2062_init(mac); 10747 else { 10748 bwn_phy_lp_b2063_init(mac); 10749 10750 /* synchronize stx table. */ 10751 for (i = 0; i < N(tables); i++) { 10752 st = &tables[i]; 10753 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10754 tmp >>= st->st_rfshift; 10755 tmp <<= st->st_physhift; 10756 BWN_PHY_SETMASK(mac, 10757 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10758 ~(st->st_mask << st->st_physhift), tmp); 10759 } 10760 10761 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10762 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10763 } 10764 10765 /* calibrate RC */ 10766 if (mac->mac_phy.rev >= 2) 10767 bwn_phy_lp_rxcal_r2(mac); 10768 else if (!plp->plp_rccap) { 10769 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10770 bwn_phy_lp_rccal_r12(mac); 10771 } else 10772 bwn_phy_lp_set_rccap(mac); 10773 10774 error = bwn_phy_lp_switch_channel(mac, 7); 10775 if (error) 10776 device_printf(sc->sc_dev, 10777 "failed to change channel 7 (%d)\n", error); 10778 bwn_phy_lp_txpctl_init(mac); 10779 bwn_phy_lp_calib(mac); 10780 return (0); 10781 } 10782 10783 static uint16_t 10784 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10785 { 10786 10787 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10788 return (BWN_READ_2(mac, BWN_PHYDATA)); 10789 } 10790 10791 static void 10792 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10793 { 10794 10795 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10796 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10797 } 10798 10799 static void 10800 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10801 uint16_t set) 10802 { 10803 10804 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10805 BWN_WRITE_2(mac, BWN_PHYDATA, 10806 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10807 } 10808 10809 static uint16_t 10810 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10811 { 10812 10813 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10814 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10815 reg |= 0x100; 10816 if (mac->mac_phy.rev >= 2) 10817 reg |= 0x200; 10818 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10819 return BWN_READ_2(mac, BWN_RFDATALO); 10820 } 10821 10822 static void 10823 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10824 { 10825 10826 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10827 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10828 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10829 } 10830 10831 static void 10832 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10833 { 10834 10835 if (on) { 10836 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10837 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10838 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10839 return; 10840 } 10841 10842 if (mac->mac_phy.rev >= 2) { 10843 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10844 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10845 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10846 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10847 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10848 return; 10849 } 10850 10851 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10852 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10853 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10854 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10855 } 10856 10857 static int 10858 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 10859 { 10860 struct bwn_phy *phy = &mac->mac_phy; 10861 struct bwn_phy_lp *plp = &phy->phy_lp; 10862 int error; 10863 10864 if (phy->rf_ver == 0x2063) { 10865 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 10866 if (error) 10867 return (error); 10868 } else { 10869 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 10870 if (error) 10871 return (error); 10872 bwn_phy_lp_set_anafilter(mac, chan); 10873 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 10874 } 10875 10876 plp->plp_chan = chan; 10877 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 10878 return (0); 10879 } 10880 10881 static uint32_t 10882 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 10883 { 10884 struct bwn_softc *sc = mac->mac_sc; 10885 struct ieee80211com *ic = &sc->sc_ic; 10886 10887 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 10888 } 10889 10890 static void 10891 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 10892 { 10893 struct bwn_phy *phy = &mac->mac_phy; 10894 struct bwn_phy_lp *plp = &phy->phy_lp; 10895 10896 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 10897 return; 10898 10899 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 10900 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 10901 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 10902 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 10903 plp->plp_antenna = antenna; 10904 } 10905 10906 static void 10907 bwn_phy_lp_task_60s(struct bwn_mac *mac) 10908 { 10909 10910 bwn_phy_lp_calib(mac); 10911 } 10912 10913 static void 10914 bwn_phy_lp_readsprom(struct bwn_mac *mac) 10915 { 10916 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10917 struct bwn_softc *sc = mac->mac_sc; 10918 struct ieee80211com *ic = &sc->sc_ic; 10919 10920 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 10921 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 10922 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 10923 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 10924 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 10925 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 10926 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 10927 return; 10928 } 10929 10930 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 10931 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 10932 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 10933 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 10934 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 10935 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 10936 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 10937 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 10938 } 10939 10940 static void 10941 bwn_phy_lp_bbinit(struct bwn_mac *mac) 10942 { 10943 10944 bwn_phy_lp_tblinit(mac); 10945 if (mac->mac_phy.rev >= 2) 10946 bwn_phy_lp_bbinit_r2(mac); 10947 else 10948 bwn_phy_lp_bbinit_r01(mac); 10949 } 10950 10951 static void 10952 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 10953 { 10954 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 10955 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 10956 struct bwn_softc *sc = mac->mac_sc; 10957 struct ieee80211com *ic = &sc->sc_ic; 10958 10959 bwn_phy_lp_set_txgain(mac, 10960 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 10961 bwn_phy_lp_set_bbmult(mac, 150); 10962 } 10963 10964 static void 10965 bwn_phy_lp_calib(struct bwn_mac *mac) 10966 { 10967 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10968 struct bwn_softc *sc = mac->mac_sc; 10969 struct ieee80211com *ic = &sc->sc_ic; 10970 const struct bwn_rxcompco *rc = NULL; 10971 struct bwn_txgain ogain; 10972 int i, omode, oafeovr, orf, obbmult; 10973 uint8_t mode, fc = 0; 10974 10975 if (plp->plp_chanfullcal != plp->plp_chan) { 10976 plp->plp_chanfullcal = plp->plp_chan; 10977 fc = 1; 10978 } 10979 10980 bwn_mac_suspend(mac); 10981 10982 /* BlueTooth Coexistance Override */ 10983 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 10984 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 10985 10986 if (mac->mac_phy.rev >= 2) 10987 bwn_phy_lp_digflt_save(mac); 10988 bwn_phy_lp_get_txpctlmode(mac); 10989 mode = plp->plp_txpctlmode; 10990 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 10991 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 10992 bwn_phy_lp_bugfix(mac); 10993 if (mac->mac_phy.rev >= 2 && fc == 1) { 10994 bwn_phy_lp_get_txpctlmode(mac); 10995 omode = plp->plp_txpctlmode; 10996 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 10997 if (oafeovr) 10998 ogain = bwn_phy_lp_get_txgain(mac); 10999 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11000 obbmult = bwn_phy_lp_get_bbmult(mac); 11001 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11002 if (oafeovr) 11003 bwn_phy_lp_set_txgain(mac, &ogain); 11004 bwn_phy_lp_set_bbmult(mac, obbmult); 11005 bwn_phy_lp_set_txpctlmode(mac, omode); 11006 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11007 } 11008 bwn_phy_lp_set_txpctlmode(mac, mode); 11009 if (mac->mac_phy.rev >= 2) 11010 bwn_phy_lp_digflt_restore(mac); 11011 11012 /* do RX IQ Calculation; assumes that noise is true. */ 11013 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11014 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11015 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11016 rc = &bwn_rxcompco_5354[i]; 11017 } 11018 } else if (mac->mac_phy.rev >= 2) 11019 rc = &bwn_rxcompco_r2; 11020 else { 11021 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11022 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11023 rc = &bwn_rxcompco_r12[i]; 11024 } 11025 } 11026 if (rc == NULL) 11027 goto fail; 11028 11029 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11030 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11031 11032 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11033 11034 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11035 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11036 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11037 } else { 11038 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11039 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11040 } 11041 11042 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11043 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11044 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11045 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11046 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11047 bwn_phy_lp_set_deaf(mac, 0); 11048 /* XXX no checking return value? */ 11049 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11050 bwn_phy_lp_clear_deaf(mac, 0); 11051 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11052 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11053 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11054 11055 /* disable RX GAIN override. */ 11056 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11057 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11058 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11059 if (mac->mac_phy.rev >= 2) { 11060 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11061 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11062 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11063 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11064 } 11065 } else { 11066 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11067 } 11068 11069 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11070 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11071 fail: 11072 bwn_mac_enable(mac); 11073 } 11074 11075 static void 11076 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11077 { 11078 11079 if (on) { 11080 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11081 return; 11082 } 11083 11084 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11085 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11086 } 11087 11088 static int 11089 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11090 { 11091 static const struct bwn_b206x_chan *bc = NULL; 11092 struct bwn_softc *sc = mac->mac_sc; 11093 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11094 tmp[6]; 11095 uint16_t old, scale, tmp16; 11096 int i, div; 11097 11098 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11099 if (bwn_b2063_chantable[i].bc_chan == chan) { 11100 bc = &bwn_b2063_chantable[i]; 11101 break; 11102 } 11103 } 11104 if (bc == NULL) 11105 return (EINVAL); 11106 11107 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11108 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11109 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11110 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11111 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11112 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11113 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11114 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11115 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11116 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11117 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11118 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11119 11120 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11121 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11122 11123 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11124 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11125 freqref = freqxtal * 3; 11126 div = (freqxtal <= 26000000 ? 1 : 2); 11127 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11128 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11129 999999) / 1000000) + 1; 11130 11131 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11132 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11133 0xfff8, timeout >> 2); 11134 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11135 0xff9f,timeout << 5); 11136 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11137 11138 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11139 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11140 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11141 11142 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11143 (timeoutref + 1)) - 1; 11144 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11145 0xf0, count >> 8); 11146 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11147 11148 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11149 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11150 while (tmp[1] >= freqref) { 11151 tmp[0]++; 11152 tmp[1] -= freqref; 11153 } 11154 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11155 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11156 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11157 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11158 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11159 11160 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11161 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11162 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11163 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11164 11165 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11166 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11167 11168 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11169 scale = 1; 11170 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11171 } else { 11172 scale = 0; 11173 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11174 } 11175 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11176 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11177 11178 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11179 (scale + 1); 11180 if (tmp[5] > 150) 11181 tmp[5] = 0; 11182 11183 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11184 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11185 11186 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11187 if (freqxtal > 26000000) 11188 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11189 else 11190 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11191 11192 if (val[0] == 45) 11193 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11194 else 11195 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11196 11197 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11198 DELAY(1); 11199 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11200 11201 /* VCO Calibration */ 11202 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11203 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11204 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11205 DELAY(1); 11206 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11207 DELAY(1); 11208 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11209 DELAY(1); 11210 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11211 DELAY(300); 11212 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11213 11214 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11215 return (0); 11216 } 11217 11218 static int 11219 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11220 { 11221 struct bwn_softc *sc = mac->mac_sc; 11222 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11223 const struct bwn_b206x_chan *bc = NULL; 11224 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11225 uint32_t tmp[9]; 11226 int i; 11227 11228 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11229 if (bwn_b2062_chantable[i].bc_chan == chan) { 11230 bc = &bwn_b2062_chantable[i]; 11231 break; 11232 } 11233 } 11234 11235 if (bc == NULL) 11236 return (EINVAL); 11237 11238 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11239 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11240 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11241 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11242 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11243 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11244 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11245 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11246 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11247 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11248 11249 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11250 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11251 bwn_phy_lp_b2062_reset_pllbias(mac); 11252 tmp[0] = freqxtal / 1000; 11253 tmp[1] = plp->plp_div * 1000; 11254 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11255 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11256 tmp[2] *= 2; 11257 tmp[3] = 48 * tmp[0]; 11258 tmp[5] = tmp[2] / tmp[3]; 11259 tmp[6] = tmp[2] % tmp[3]; 11260 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11261 tmp[4] = tmp[6] * 0x100; 11262 tmp[5] = tmp[4] / tmp[3]; 11263 tmp[6] = tmp[4] % tmp[3]; 11264 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, 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_RFPLLCTL28, 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_RFPLLCTL29, 11273 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11274 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11275 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11276 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11277 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11278 11279 bwn_phy_lp_b2062_vco_calib(mac); 11280 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11281 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11282 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11283 bwn_phy_lp_b2062_reset_pllbias(mac); 11284 bwn_phy_lp_b2062_vco_calib(mac); 11285 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11286 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11287 return (EIO); 11288 } 11289 } 11290 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11291 return (0); 11292 } 11293 11294 static void 11295 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11296 { 11297 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11298 uint16_t tmp = (channel == 14); 11299 11300 if (mac->mac_phy.rev < 2) { 11301 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11302 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11303 bwn_phy_lp_set_rccap(mac); 11304 return; 11305 } 11306 11307 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11308 } 11309 11310 static void 11311 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11312 { 11313 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11314 struct bwn_softc *sc = mac->mac_sc; 11315 struct ieee80211com *ic = &sc->sc_ic; 11316 uint16_t iso, tmp[3]; 11317 11318 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11319 11320 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11321 iso = plp->plp_txisoband_m; 11322 else if (freq <= 5320) 11323 iso = plp->plp_txisoband_l; 11324 else if (freq <= 5700) 11325 iso = plp->plp_txisoband_m; 11326 else 11327 iso = plp->plp_txisoband_h; 11328 11329 tmp[0] = ((iso - 26) / 12) << 12; 11330 tmp[1] = tmp[0] + 0x1000; 11331 tmp[2] = tmp[0] + 0x2000; 11332 11333 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11334 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11335 } 11336 11337 static void 11338 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11339 { 11340 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11341 int i; 11342 static const uint16_t addr[] = { 11343 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11344 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11345 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11346 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11347 BWN_PHY_OFDM(0xcf), 11348 }; 11349 static const uint16_t val[] = { 11350 0xde5e, 0xe832, 0xe331, 0x4d26, 11351 0x0026, 0x1420, 0x0020, 0xfe08, 11352 0x0008, 11353 }; 11354 11355 for (i = 0; i < N(addr); i++) { 11356 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11357 BWN_PHY_WRITE(mac, addr[i], val[i]); 11358 } 11359 } 11360 11361 static void 11362 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11363 { 11364 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11365 struct bwn_softc *sc = mac->mac_sc; 11366 uint16_t ctl; 11367 11368 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11369 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11370 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11371 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11372 break; 11373 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11374 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11375 break; 11376 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11377 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11378 break; 11379 default: 11380 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11381 device_printf(sc->sc_dev, "unknown command mode\n"); 11382 break; 11383 } 11384 } 11385 11386 static void 11387 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11388 { 11389 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11390 uint16_t ctl; 11391 uint8_t old; 11392 11393 bwn_phy_lp_get_txpctlmode(mac); 11394 old = plp->plp_txpctlmode; 11395 if (old == mode) 11396 return; 11397 plp->plp_txpctlmode = mode; 11398 11399 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11400 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11401 plp->plp_tssiidx); 11402 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11403 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11404 11405 /* disable TX GAIN override */ 11406 if (mac->mac_phy.rev < 2) 11407 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11408 else { 11409 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11410 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11411 } 11412 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11413 11414 plp->plp_txpwridx = -1; 11415 } 11416 if (mac->mac_phy.rev >= 2) { 11417 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11418 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11419 else 11420 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11421 } 11422 11423 /* writes TX Power Control mode */ 11424 switch (plp->plp_txpctlmode) { 11425 case BWN_PHYLP_TXPCTL_OFF: 11426 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11427 break; 11428 case BWN_PHYLP_TXPCTL_ON_HW: 11429 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11430 break; 11431 case BWN_PHYLP_TXPCTL_ON_SW: 11432 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11433 break; 11434 default: 11435 ctl = 0; 11436 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11437 } 11438 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11439 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11440 } 11441 11442 static void 11443 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11444 { 11445 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11446 struct bwn_softc *sc = mac->mac_sc; 11447 const unsigned int size = 256; 11448 struct bwn_txgain tg; 11449 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11450 uint16_t tssinpt, tssiidx, value[2]; 11451 uint8_t mode; 11452 int8_t txpwridx; 11453 11454 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11455 M_NOWAIT | M_ZERO); 11456 if (tabs == NULL) { 11457 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11458 return; 11459 } 11460 11461 bwn_phy_lp_get_txpctlmode(mac); 11462 mode = plp->plp_txpctlmode; 11463 txpwridx = plp->plp_txpwridx; 11464 tssinpt = plp->plp_tssinpt; 11465 tssiidx = plp->plp_tssiidx; 11466 11467 bwn_tab_read_multi(mac, 11468 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11469 BWN_TAB_4(7, 0x140), size, tabs); 11470 11471 bwn_phy_lp_tblinit(mac); 11472 bwn_phy_lp_bbinit(mac); 11473 bwn_phy_lp_txpctl_init(mac); 11474 bwn_phy_lp_rf_onoff(mac, 1); 11475 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11476 11477 bwn_tab_write_multi(mac, 11478 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11479 BWN_TAB_4(7, 0x140), size, tabs); 11480 11481 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11482 plp->plp_tssinpt = tssinpt; 11483 plp->plp_tssiidx = tssiidx; 11484 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11485 if (txpwridx != -1) { 11486 /* set TX power by index */ 11487 plp->plp_txpwridx = txpwridx; 11488 bwn_phy_lp_get_txpctlmode(mac); 11489 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11490 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11491 if (mac->mac_phy.rev >= 2) { 11492 rxcomp = bwn_tab_read(mac, 11493 BWN_TAB_4(7, txpwridx + 320)); 11494 txgain = bwn_tab_read(mac, 11495 BWN_TAB_4(7, txpwridx + 192)); 11496 tg.tg_pad = (txgain >> 16) & 0xff; 11497 tg.tg_gm = txgain & 0xff; 11498 tg.tg_pga = (txgain >> 8) & 0xff; 11499 tg.tg_dac = (rxcomp >> 28) & 0xff; 11500 bwn_phy_lp_set_txgain(mac, &tg); 11501 } else { 11502 rxcomp = bwn_tab_read(mac, 11503 BWN_TAB_4(10, txpwridx + 320)); 11504 txgain = bwn_tab_read(mac, 11505 BWN_TAB_4(10, txpwridx + 192)); 11506 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11507 0xf800, (txgain >> 4) & 0x7fff); 11508 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11509 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11510 } 11511 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11512 11513 /* set TX IQCC */ 11514 value[0] = (rxcomp >> 10) & 0x3ff; 11515 value[1] = rxcomp & 0x3ff; 11516 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11517 11518 coeff = bwn_tab_read(mac, 11519 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11520 BWN_TAB_4(10, txpwridx + 448)); 11521 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11522 if (mac->mac_phy.rev >= 2) { 11523 rfpwr = bwn_tab_read(mac, 11524 BWN_TAB_4(7, txpwridx + 576)); 11525 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11526 rfpwr & 0xffff); 11527 } 11528 bwn_phy_lp_set_txgain_override(mac); 11529 } 11530 if (plp->plp_rccap) 11531 bwn_phy_lp_set_rccap(mac); 11532 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11533 bwn_phy_lp_set_txpctlmode(mac, mode); 11534 free(tabs, M_DEVBUF); 11535 } 11536 11537 static void 11538 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11539 { 11540 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11541 int i; 11542 static const uint16_t addr[] = { 11543 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11544 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11545 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11546 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11547 BWN_PHY_OFDM(0xcf), 11548 }; 11549 11550 for (i = 0; i < N(addr); i++) 11551 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11552 } 11553 11554 static void 11555 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11556 { 11557 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11558 11559 if (mac->mac_phy.rev < 2) { 11560 bwn_phy_lp_tblinit_r01(mac); 11561 bwn_phy_lp_tblinit_txgain(mac); 11562 bwn_phy_lp_set_gaintbl(mac, freq); 11563 return; 11564 } 11565 11566 bwn_phy_lp_tblinit_r2(mac); 11567 bwn_phy_lp_tblinit_txgain(mac); 11568 } 11569 11570 struct bwn_wpair { 11571 uint16_t reg; 11572 uint16_t value; 11573 }; 11574 11575 struct bwn_smpair { 11576 uint16_t offset; 11577 uint16_t mask; 11578 uint16_t set; 11579 }; 11580 11581 static void 11582 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11583 { 11584 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11585 struct bwn_softc *sc = mac->mac_sc; 11586 struct ieee80211com *ic = &sc->sc_ic; 11587 static const struct bwn_wpair v1[] = { 11588 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11589 { BWN_PHY_AFE_CTL, 0x8800 }, 11590 { BWN_PHY_AFE_CTL_OVR, 0 }, 11591 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11592 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11593 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11594 { BWN_PHY_OFDM(0xf9), 0 }, 11595 { BWN_PHY_TR_LOOKUP_1, 0 } 11596 }; 11597 static const struct bwn_smpair v2[] = { 11598 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11599 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11600 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11601 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11602 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11603 }; 11604 static const struct bwn_smpair v3[] = { 11605 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11606 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11607 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11608 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11609 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11610 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11611 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11612 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11613 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11614 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11615 11616 }; 11617 int i; 11618 11619 for (i = 0; i < N(v1); i++) 11620 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11621 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11622 for (i = 0; i < N(v2); i++) 11623 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11624 11625 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11626 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11627 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11628 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11629 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11630 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11631 } else { 11632 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11633 } 11634 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11635 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11636 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11637 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11638 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11639 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11640 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11641 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11642 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11643 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11644 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11645 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11646 (siba_get_chiprev(sc->sc_dev) == 0)) { 11647 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11648 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11649 } else { 11650 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11651 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11652 } 11653 for (i = 0; i < N(v3); i++) 11654 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11655 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11656 (siba_get_chiprev(sc->sc_dev) == 0)) { 11657 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11658 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11659 } 11660 11661 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11662 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11663 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11664 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11665 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11666 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11667 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11668 } else 11669 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11670 11671 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11672 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11673 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11674 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11675 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11676 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11677 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11678 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11679 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11680 11681 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11682 (siba_get_chiprev(sc->sc_dev) == 0)) { 11683 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11684 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11685 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11686 } 11687 11688 bwn_phy_lp_digflt_save(mac); 11689 } 11690 11691 static void 11692 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11693 { 11694 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11695 struct bwn_softc *sc = mac->mac_sc; 11696 struct ieee80211com *ic = &sc->sc_ic; 11697 static const struct bwn_smpair v1[] = { 11698 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11699 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11700 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11701 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11702 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11703 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11704 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11705 }; 11706 static const struct bwn_smpair v2[] = { 11707 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11708 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11709 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11710 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11711 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11712 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11713 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11714 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11715 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11716 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11717 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11718 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11719 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11720 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11721 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11722 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11723 }; 11724 static const struct bwn_smpair v3[] = { 11725 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11726 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11727 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11728 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11729 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11730 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11731 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11732 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11733 }; 11734 static const struct bwn_smpair v4[] = { 11735 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11736 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11737 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11738 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11739 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11740 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11741 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11742 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11743 }; 11744 static const struct bwn_smpair v5[] = { 11745 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11746 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11747 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11748 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11749 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11750 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11751 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11752 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11753 }; 11754 int i; 11755 uint16_t tmp, tmp2; 11756 11757 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11758 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11759 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11760 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11761 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11762 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11763 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11764 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11765 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11766 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11767 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11768 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11769 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11770 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11771 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11772 for (i = 0; i < N(v1); i++) 11773 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11774 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11775 0xff00, plp->plp_rxpwroffset); 11776 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11777 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11778 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11779 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11780 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11781 if (mac->mac_phy.rev == 0) 11782 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11783 0xffcf, 0x0010); 11784 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11785 } else { 11786 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11787 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11788 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11789 } 11790 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11791 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11792 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11793 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11794 else 11795 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11796 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11797 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11798 0xfff9, (plp->plp_bxarch << 1)); 11799 if (mac->mac_phy.rev == 1 && 11800 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11801 for (i = 0; i < N(v2); i++) 11802 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11803 v2[i].set); 11804 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11805 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11806 ((mac->mac_phy.rev == 0) && 11807 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11808 for (i = 0; i < N(v3); i++) 11809 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11810 v3[i].set); 11811 } else if (mac->mac_phy.rev == 1 || 11812 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11813 for (i = 0; i < N(v4); i++) 11814 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11815 v4[i].set); 11816 } else { 11817 for (i = 0; i < N(v5); i++) 11818 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11819 v5[i].set); 11820 } 11821 if (mac->mac_phy.rev == 1 && 11822 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11823 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11824 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11825 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11826 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11827 } 11828 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11829 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11830 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11831 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11832 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11833 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11834 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11835 } 11836 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11837 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11838 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11839 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11840 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11841 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11842 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11843 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11844 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11845 } else { 11846 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11847 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11848 } 11849 if (mac->mac_phy.rev == 1) { 11850 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 11851 tmp2 = (tmp & 0x03e0) >> 5; 11852 tmp2 |= tmp2 << 5; 11853 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 11854 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 11855 tmp2 = (tmp & 0x1f00) >> 8; 11856 tmp2 |= tmp2 << 5; 11857 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 11858 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 11859 tmp2 = tmp & 0x00ff; 11860 tmp2 |= tmp << 8; 11861 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 11862 } 11863 } 11864 11865 struct bwn_b2062_freq { 11866 uint16_t freq; 11867 uint8_t value[6]; 11868 }; 11869 11870 static void 11871 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 11872 { 11873 #define CALC_CTL7(freq, div) \ 11874 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 11875 #define CALC_CTL18(freq, div) \ 11876 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 11877 #define CALC_CTL19(freq, div) \ 11878 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 11879 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11880 struct bwn_softc *sc = mac->mac_sc; 11881 struct ieee80211com *ic = &sc->sc_ic; 11882 static const struct bwn_b2062_freq freqdata_tab[] = { 11883 { 12000, { 6, 6, 6, 6, 10, 6 } }, 11884 { 13000, { 4, 4, 4, 4, 11, 7 } }, 11885 { 14400, { 3, 3, 3, 3, 12, 7 } }, 11886 { 16200, { 3, 3, 3, 3, 13, 8 } }, 11887 { 18000, { 2, 2, 2, 2, 14, 8 } }, 11888 { 19200, { 1, 1, 1, 1, 14, 9 } } 11889 }; 11890 static const struct bwn_wpair v1[] = { 11891 { BWN_B2062_N_TXCTL3, 0 }, 11892 { BWN_B2062_N_TXCTL4, 0 }, 11893 { BWN_B2062_N_TXCTL5, 0 }, 11894 { BWN_B2062_N_TXCTL6, 0 }, 11895 { BWN_B2062_N_PDNCTL0, 0x40 }, 11896 { BWN_B2062_N_PDNCTL0, 0 }, 11897 { BWN_B2062_N_CALIB_TS, 0x10 }, 11898 { BWN_B2062_N_CALIB_TS, 0 } 11899 }; 11900 const struct bwn_b2062_freq *f = NULL; 11901 uint32_t xtalfreq, ref; 11902 unsigned int i; 11903 11904 bwn_phy_lp_b2062_tblinit(mac); 11905 11906 for (i = 0; i < N(v1); i++) 11907 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 11908 if (mac->mac_phy.rev > 0) 11909 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 11910 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 11911 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11912 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 11913 else 11914 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 11915 11916 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 11917 ("%s:%d: fail", __func__, __LINE__)); 11918 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11919 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 11920 11921 if (xtalfreq <= 30000000) { 11922 plp->plp_div = 1; 11923 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 11924 } else { 11925 plp->plp_div = 2; 11926 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 11927 } 11928 11929 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 11930 CALC_CTL7(xtalfreq, plp->plp_div)); 11931 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 11932 CALC_CTL18(xtalfreq, plp->plp_div)); 11933 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 11934 CALC_CTL19(xtalfreq, plp->plp_div)); 11935 11936 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 11937 ref &= 0xffff; 11938 for (i = 0; i < N(freqdata_tab); i++) { 11939 if (ref < freqdata_tab[i].freq) { 11940 f = &freqdata_tab[i]; 11941 break; 11942 } 11943 } 11944 if (f == NULL) 11945 f = &freqdata_tab[N(freqdata_tab) - 1]; 11946 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 11947 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 11948 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 11949 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 11950 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 11951 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 11952 #undef CALC_CTL7 11953 #undef CALC_CTL18 11954 #undef CALC_CTL19 11955 } 11956 11957 static void 11958 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 11959 { 11960 11961 bwn_phy_lp_b2063_tblinit(mac); 11962 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 11963 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 11964 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 11965 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 11966 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 11967 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 11968 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 11969 if (mac->mac_phy.rev == 2) { 11970 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 11971 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 11972 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 11973 } else { 11974 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 11975 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 11976 } 11977 } 11978 11979 static void 11980 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 11981 { 11982 struct bwn_softc *sc = mac->mac_sc; 11983 static const struct bwn_wpair v1[] = { 11984 { BWN_B2063_RX_BB_SP8, 0x0 }, 11985 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 11986 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 11987 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 11988 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 11989 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 11990 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 11991 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 11992 }; 11993 static const struct bwn_wpair v2[] = { 11994 { BWN_B2063_TX_BB_SP3, 0x0 }, 11995 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 11996 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 11997 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 11998 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 11999 }; 12000 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12001 int i; 12002 uint8_t tmp; 12003 12004 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12005 12006 for (i = 0; i < 2; i++) 12007 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12008 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12009 for (i = 2; i < N(v1); i++) 12010 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12011 for (i = 0; i < 10000; i++) { 12012 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12013 break; 12014 DELAY(1000); 12015 } 12016 12017 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12018 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12019 12020 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12021 12022 for (i = 0; i < N(v2); i++) 12023 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12024 if (freqxtal == 24000000) { 12025 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12026 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12027 } else { 12028 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12029 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12030 } 12031 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12032 for (i = 0; i < 10000; i++) { 12033 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12034 break; 12035 DELAY(1000); 12036 } 12037 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12038 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12039 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12040 } 12041 12042 static void 12043 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12044 { 12045 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12046 struct bwn_softc *sc = mac->mac_sc; 12047 struct bwn_phy_lp_iq_est ie; 12048 struct bwn_txgain tx_gains; 12049 static const uint32_t pwrtbl[21] = { 12050 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12051 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12052 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12053 0x0004c, 0x0002c, 0x0001a, 12054 }; 12055 uint32_t npwr, ipwr, sqpwr, tmp; 12056 int loopback, i, j, sum, error; 12057 uint16_t save[7]; 12058 uint8_t txo, bbmult, txpctlmode; 12059 12060 error = bwn_phy_lp_switch_channel(mac, 7); 12061 if (error) 12062 device_printf(sc->sc_dev, 12063 "failed to change channel to 7 (%d)\n", error); 12064 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12065 bbmult = bwn_phy_lp_get_bbmult(mac); 12066 if (txo) 12067 tx_gains = bwn_phy_lp_get_txgain(mac); 12068 12069 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12070 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12071 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12072 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12073 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12074 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12075 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12076 12077 bwn_phy_lp_get_txpctlmode(mac); 12078 txpctlmode = plp->plp_txpctlmode; 12079 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12080 12081 /* disable CRS */ 12082 bwn_phy_lp_set_deaf(mac, 1); 12083 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12084 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12085 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12086 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12087 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12088 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12089 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12090 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12091 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12092 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12093 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12094 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12095 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12096 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12097 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12098 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12099 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12100 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12101 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12102 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12103 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12104 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12105 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12106 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12107 12108 loopback = bwn_phy_lp_loopback(mac); 12109 if (loopback == -1) 12110 goto done; 12111 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12112 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12113 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12114 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12115 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12116 12117 tmp = 0; 12118 memset(&ie, 0, sizeof(ie)); 12119 for (i = 128; i <= 159; i++) { 12120 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12121 sum = 0; 12122 for (j = 5; j <= 25; j++) { 12123 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12124 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12125 goto done; 12126 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12127 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12128 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12129 12); 12130 sum += ((ipwr - npwr) * (ipwr - npwr)); 12131 if ((i == 128) || (sum < tmp)) { 12132 plp->plp_rccap = i; 12133 tmp = sum; 12134 } 12135 } 12136 } 12137 bwn_phy_lp_ddfs_turnoff(mac); 12138 done: 12139 /* restore CRS */ 12140 bwn_phy_lp_clear_deaf(mac, 1); 12141 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12142 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12143 12144 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12145 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12146 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12147 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12148 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12149 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12150 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12151 12152 bwn_phy_lp_set_bbmult(mac, bbmult); 12153 if (txo) 12154 bwn_phy_lp_set_txgain(mac, &tx_gains); 12155 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12156 if (plp->plp_rccap) 12157 bwn_phy_lp_set_rccap(mac); 12158 } 12159 12160 static void 12161 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12162 { 12163 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12164 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12165 12166 if (mac->mac_phy.rev == 1) 12167 rc_cap = MIN(rc_cap + 5, 15); 12168 12169 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12170 MAX(plp->plp_rccap - 4, 0x80)); 12171 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12172 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12173 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12174 } 12175 12176 static uint32_t 12177 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12178 { 12179 uint32_t i, q, r; 12180 12181 if (div == 0) 12182 return (0); 12183 12184 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12185 q <<= 1; 12186 if (r << 1 >= div) { 12187 q++; 12188 r = (r << 1) - div; 12189 } 12190 } 12191 if (r << 1 >= div) 12192 q++; 12193 return (q); 12194 } 12195 12196 static void 12197 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12198 { 12199 struct bwn_softc *sc = mac->mac_sc; 12200 12201 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12202 DELAY(20); 12203 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12204 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12205 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12206 } else { 12207 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12208 } 12209 DELAY(5); 12210 } 12211 12212 static void 12213 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12214 { 12215 12216 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12217 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12218 DELAY(200); 12219 } 12220 12221 static void 12222 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12223 { 12224 #define FLAG_A 0x01 12225 #define FLAG_G 0x02 12226 struct bwn_softc *sc = mac->mac_sc; 12227 struct ieee80211com *ic = &sc->sc_ic; 12228 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12229 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12230 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12231 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12232 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12233 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12234 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12235 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12236 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12237 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12238 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12239 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12240 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12241 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12242 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12243 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12244 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12245 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12246 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12247 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12248 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12249 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12250 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12251 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12252 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12253 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12254 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12255 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12256 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12257 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12258 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12259 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12260 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12261 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12262 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12263 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12264 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12265 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12266 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12267 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12268 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12269 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12270 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12271 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12272 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12273 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12274 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12275 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12276 }; 12277 const struct bwn_b206x_rfinit_entry *br; 12278 unsigned int i; 12279 12280 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12281 br = &bwn_b2062_init_tab[i]; 12282 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12283 if (br->br_flags & FLAG_G) 12284 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12285 } else { 12286 if (br->br_flags & FLAG_A) 12287 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12288 } 12289 } 12290 #undef FLAG_A 12291 #undef FLAG_B 12292 } 12293 12294 static void 12295 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12296 { 12297 #define FLAG_A 0x01 12298 #define FLAG_G 0x02 12299 struct bwn_softc *sc = mac->mac_sc; 12300 struct ieee80211com *ic = &sc->sc_ic; 12301 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12302 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12303 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12304 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12305 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12306 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12307 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12308 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12309 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12310 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12311 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12312 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12313 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12314 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12315 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12316 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12317 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12318 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12319 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12320 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12321 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12322 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12323 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12324 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12325 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12326 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12327 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12328 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12329 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12330 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12331 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12332 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12333 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12334 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12335 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12336 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12337 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12338 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12339 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12340 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12341 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12342 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12343 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12344 }; 12345 const struct bwn_b206x_rfinit_entry *br; 12346 unsigned int i; 12347 12348 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12349 br = &bwn_b2063_init_tab[i]; 12350 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12351 if (br->br_flags & FLAG_G) 12352 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12353 } else { 12354 if (br->br_flags & FLAG_A) 12355 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12356 } 12357 } 12358 #undef FLAG_A 12359 #undef FLAG_B 12360 } 12361 12362 static void 12363 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12364 int count, void *_data) 12365 { 12366 unsigned int i; 12367 uint32_t offset, type; 12368 uint8_t *data = _data; 12369 12370 type = BWN_TAB_GETTYPE(typenoffset); 12371 offset = BWN_TAB_GETOFFSET(typenoffset); 12372 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12373 12374 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12375 12376 for (i = 0; i < count; i++) { 12377 switch (type) { 12378 case BWN_TAB_8BIT: 12379 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12380 data++; 12381 break; 12382 case BWN_TAB_16BIT: 12383 *((uint16_t *)data) = BWN_PHY_READ(mac, 12384 BWN_PHY_TABLEDATALO); 12385 data += 2; 12386 break; 12387 case BWN_TAB_32BIT: 12388 *((uint32_t *)data) = BWN_PHY_READ(mac, 12389 BWN_PHY_TABLEDATAHI); 12390 *((uint32_t *)data) <<= 16; 12391 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12392 BWN_PHY_TABLEDATALO); 12393 data += 4; 12394 break; 12395 default: 12396 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12397 } 12398 } 12399 } 12400 12401 static void 12402 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12403 int count, const void *_data) 12404 { 12405 uint32_t offset, type, value; 12406 const uint8_t *data = _data; 12407 unsigned int i; 12408 12409 type = BWN_TAB_GETTYPE(typenoffset); 12410 offset = BWN_TAB_GETOFFSET(typenoffset); 12411 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12412 12413 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12414 12415 for (i = 0; i < count; i++) { 12416 switch (type) { 12417 case BWN_TAB_8BIT: 12418 value = *data; 12419 data++; 12420 KASSERT(!(value & ~0xff), 12421 ("%s:%d: fail", __func__, __LINE__)); 12422 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12423 break; 12424 case BWN_TAB_16BIT: 12425 value = *((const uint16_t *)data); 12426 data += 2; 12427 KASSERT(!(value & ~0xffff), 12428 ("%s:%d: fail", __func__, __LINE__)); 12429 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12430 break; 12431 case BWN_TAB_32BIT: 12432 value = *((const uint32_t *)data); 12433 data += 4; 12434 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12435 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12436 break; 12437 default: 12438 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12439 } 12440 } 12441 } 12442 12443 static struct bwn_txgain 12444 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12445 { 12446 struct bwn_txgain tg; 12447 uint16_t tmp; 12448 12449 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12450 if (mac->mac_phy.rev < 2) { 12451 tmp = BWN_PHY_READ(mac, 12452 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12453 tg.tg_gm = tmp & 0x0007; 12454 tg.tg_pga = (tmp & 0x0078) >> 3; 12455 tg.tg_pad = (tmp & 0x780) >> 7; 12456 return (tg); 12457 } 12458 12459 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12460 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12461 tg.tg_gm = tmp & 0xff; 12462 tg.tg_pga = (tmp >> 8) & 0xff; 12463 return (tg); 12464 } 12465 12466 static uint8_t 12467 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12468 { 12469 12470 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12471 } 12472 12473 static void 12474 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12475 { 12476 uint16_t pa; 12477 12478 if (mac->mac_phy.rev < 2) { 12479 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12480 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12481 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12482 bwn_phy_lp_set_txgain_override(mac); 12483 return; 12484 } 12485 12486 pa = bwn_phy_lp_get_pa_gain(mac); 12487 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12488 (tg->tg_pga << 8) | tg->tg_gm); 12489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12490 tg->tg_pad | (pa << 6)); 12491 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12493 tg->tg_pad | (pa << 8)); 12494 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12495 bwn_phy_lp_set_txgain_override(mac); 12496 } 12497 12498 static void 12499 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12500 { 12501 12502 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12503 } 12504 12505 static void 12506 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12507 { 12508 uint16_t trsw = (tx << 1) | rx; 12509 12510 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12511 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12512 } 12513 12514 static void 12515 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12516 { 12517 struct bwn_softc *sc = mac->mac_sc; 12518 struct ieee80211com *ic = &sc->sc_ic; 12519 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12520 12521 if (mac->mac_phy.rev < 2) { 12522 trsw = gain & 0x1; 12523 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12524 ext_lna = (gain & 2) >> 1; 12525 12526 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12527 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12528 0xfbff, ext_lna << 10); 12529 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12530 0xf7ff, ext_lna << 11); 12531 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12532 } else { 12533 low_gain = gain & 0xffff; 12534 high_gain = (gain >> 16) & 0xf; 12535 ext_lna = (gain >> 21) & 0x1; 12536 trsw = ~(gain >> 20) & 0x1; 12537 12538 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12539 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12540 0xfdff, ext_lna << 9); 12541 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12542 0xfbff, ext_lna << 10); 12543 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12544 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12545 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12546 tmp = (gain >> 2) & 0x3; 12547 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12548 0xe7ff, tmp<<11); 12549 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12550 tmp << 3); 12551 } 12552 } 12553 12554 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12555 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12556 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12557 if (mac->mac_phy.rev >= 2) { 12558 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12559 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12560 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12561 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12562 } 12563 return; 12564 } 12565 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12566 } 12567 12568 static void 12569 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12570 { 12571 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12572 12573 if (user) 12574 plp->plp_crsusr_off = 1; 12575 else 12576 plp->plp_crssys_off = 1; 12577 12578 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12579 } 12580 12581 static void 12582 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12583 { 12584 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12585 struct bwn_softc *sc = mac->mac_sc; 12586 struct ieee80211com *ic = &sc->sc_ic; 12587 12588 if (user) 12589 plp->plp_crsusr_off = 0; 12590 else 12591 plp->plp_crssys_off = 0; 12592 12593 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12594 return; 12595 12596 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12597 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12598 else 12599 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12600 } 12601 12602 static unsigned int 12603 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12604 { 12605 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12606 static uint8_t sqrt_table[256] = { 12607 10, 14, 17, 20, 22, 24, 26, 28, 12608 30, 31, 33, 34, 36, 37, 38, 40, 12609 41, 42, 43, 44, 45, 46, 47, 48, 12610 50, 50, 51, 52, 53, 54, 55, 56, 12611 57, 58, 59, 60, 60, 61, 62, 63, 12612 64, 64, 65, 66, 67, 67, 68, 69, 12613 70, 70, 71, 72, 72, 73, 74, 74, 12614 75, 76, 76, 77, 78, 78, 79, 80, 12615 80, 81, 81, 82, 83, 83, 84, 84, 12616 85, 86, 86, 87, 87, 88, 88, 89, 12617 90, 90, 91, 91, 92, 92, 93, 93, 12618 94, 94, 95, 95, 96, 96, 97, 97, 12619 98, 98, 99, 100, 100, 100, 101, 101, 12620 102, 102, 103, 103, 104, 104, 105, 105, 12621 106, 106, 107, 107, 108, 108, 109, 109, 12622 110, 110, 110, 111, 111, 112, 112, 113, 12623 113, 114, 114, 114, 115, 115, 116, 116, 12624 117, 117, 117, 118, 118, 119, 119, 120, 12625 120, 120, 121, 121, 122, 122, 122, 123, 12626 123, 124, 124, 124, 125, 125, 126, 126, 12627 126, 127, 127, 128, 128, 128, 129, 129, 12628 130, 130, 130, 131, 131, 131, 132, 132, 12629 133, 133, 133, 134, 134, 134, 135, 135, 12630 136, 136, 136, 137, 137, 137, 138, 138, 12631 138, 139, 139, 140, 140, 140, 141, 141, 12632 141, 142, 142, 142, 143, 143, 143, 144, 12633 144, 144, 145, 145, 145, 146, 146, 146, 12634 147, 147, 147, 148, 148, 148, 149, 149, 12635 150, 150, 150, 150, 151, 151, 151, 152, 12636 152, 152, 153, 153, 153, 154, 154, 154, 12637 155, 155, 155, 156, 156, 156, 157, 157, 12638 157, 158, 158, 158, 159, 159, 159, 160 12639 }; 12640 12641 if (x == 0) 12642 return (0); 12643 if (x >= 256) { 12644 unsigned int tmp; 12645 12646 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12647 /* do nothing */ ; 12648 return (tmp); 12649 } 12650 return (sqrt_table[x - 1] / 10); 12651 } 12652 12653 static int 12654 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12655 { 12656 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12657 int _t; \ 12658 _t = _x - 20; \ 12659 if (_t >= 0) { \ 12660 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12661 } else { \ 12662 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12663 } \ 12664 } while (0) 12665 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12666 int _t; \ 12667 _t = _x - 11; \ 12668 if (_t >= 0) \ 12669 _v = (_y << (31 - _x)) / (_z >> _t); \ 12670 else \ 12671 _v = (_y << (31 - _x)) / (_z << -_t); \ 12672 } while (0) 12673 struct bwn_phy_lp_iq_est ie; 12674 uint16_t v0, v1; 12675 int tmp[2], ret; 12676 12677 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12678 v0 = v1 >> 8; 12679 v1 |= 0xff; 12680 12681 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12682 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12683 12684 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12685 if (ret == 0) 12686 goto done; 12687 12688 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12689 ret = 0; 12690 goto done; 12691 } 12692 12693 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12694 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12695 12696 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12697 v0 = tmp[0] >> 3; 12698 v1 = tmp[1] >> 4; 12699 done: 12700 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12701 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12702 return ret; 12703 #undef CALC_COEFF 12704 #undef CALC_COEFF2 12705 } 12706 12707 static void 12708 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12709 { 12710 static const uint16_t noisescale[] = { 12711 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12712 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12713 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12714 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12715 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12716 }; 12717 static const uint16_t crsgainnft[] = { 12718 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12719 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12720 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12721 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12722 0x013d, 12723 }; 12724 static const uint16_t filterctl[] = { 12725 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12726 0xff53, 0x0127, 12727 }; 12728 static const uint32_t psctl[] = { 12729 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12730 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12731 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12732 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12733 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12734 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12735 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12736 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12737 }; 12738 static const uint16_t ofdmcckgain_r0[] = { 12739 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12740 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12741 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12742 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12743 0x755d, 12744 }; 12745 static const uint16_t ofdmcckgain_r1[] = { 12746 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12747 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12748 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12749 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12750 0x755d, 12751 }; 12752 static const uint16_t gaindelta[] = { 12753 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12754 0x0000, 12755 }; 12756 static const uint32_t txpwrctl[] = { 12757 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12758 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12759 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12760 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12761 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12762 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12763 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12764 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12765 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12766 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12767 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12768 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12769 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12770 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12771 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12772 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12773 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12774 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12775 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12776 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12777 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12778 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12779 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12780 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12781 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12782 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12783 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12784 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12785 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12786 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12787 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12788 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12789 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12790 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12791 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12792 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12793 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12794 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12795 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12796 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12797 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12798 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12799 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12800 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12801 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12802 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12803 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12804 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12805 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12806 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12807 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12808 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12809 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12810 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12811 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12812 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12813 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12814 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12815 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12816 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12817 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12818 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12819 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12820 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12821 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12822 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12823 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12824 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 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, 0x000000ff, 0x000002fc, 12847 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 12848 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 12849 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 12850 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 12851 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 12852 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 12853 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 12854 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 12855 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 12856 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 12857 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 12858 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 12859 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 12860 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 12861 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 12862 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 12863 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 12864 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 12865 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 12866 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 12867 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 12868 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 12869 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 12870 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 12871 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 12872 0x00000702, 12873 }; 12874 12875 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 12876 12877 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 12878 bwn_tab_sigsq_tbl); 12879 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 12880 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 12881 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 12882 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 12883 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 12884 bwn_tab_pllfrac_tbl); 12885 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 12886 bwn_tabl_iqlocal_tbl); 12887 if (mac->mac_phy.rev == 0) { 12888 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 12889 ofdmcckgain_r0); 12890 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 12891 ofdmcckgain_r0); 12892 } else { 12893 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 12894 ofdmcckgain_r1); 12895 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 12896 ofdmcckgain_r1); 12897 } 12898 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 12899 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 12900 } 12901 12902 static void 12903 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 12904 { 12905 struct bwn_softc *sc = mac->mac_sc; 12906 int i; 12907 static const uint16_t noisescale[] = { 12908 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12909 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12910 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12911 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12912 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12913 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 12914 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 12915 }; 12916 static const uint32_t filterctl[] = { 12917 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 12918 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 12919 }; 12920 static const uint32_t psctl[] = { 12921 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 12922 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 12923 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 12924 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 12925 }; 12926 static const uint32_t gainidx[] = { 12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12930 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 12931 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 12932 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 12933 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 12934 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 12935 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 12936 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 12937 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 12938 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 12939 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 12940 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 12941 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12945 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 12946 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 12947 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 12948 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 12949 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 12950 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 12951 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 12952 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 12953 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 12954 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 12955 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 12956 0x0000001a, 0x64ca55ad, 0x0000001a 12957 }; 12958 static const uint16_t auxgainidx[] = { 12959 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12960 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 12961 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 12962 0x0004, 0x0016 12963 }; 12964 static const uint16_t swctl[] = { 12965 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12966 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 12967 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 12968 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 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 }; 12974 static const uint8_t hf[] = { 12975 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 12976 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 12977 }; 12978 static const uint32_t gainval[] = { 12979 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 12980 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 12981 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 12982 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 12983 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 12984 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 12985 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12986 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12987 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 12988 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 12989 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 12990 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 12991 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 12992 0x000000f1, 0x00000000, 0x00000000 12993 }; 12994 static const uint16_t gain[] = { 12995 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 12996 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 12997 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 12998 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 12999 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13000 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13001 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13002 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13003 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13004 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13005 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13006 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13007 }; 13008 static const uint32_t papdeps[] = { 13009 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13010 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13011 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13012 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13013 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13014 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13015 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13016 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13017 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13018 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13019 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13020 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13021 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13022 }; 13023 static const uint32_t papdmult[] = { 13024 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13025 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13026 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13027 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13028 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13029 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13030 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13031 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13032 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13033 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13034 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13035 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13036 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13037 }; 13038 static const uint32_t gainidx_a0[] = { 13039 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13040 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13041 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13042 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13043 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13044 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13045 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13046 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13047 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13048 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13049 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13050 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13051 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13052 }; 13053 static const uint16_t auxgainidx_a0[] = { 13054 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13055 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13056 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13057 0x0002, 0x0014 13058 }; 13059 static const uint32_t gainval_a0[] = { 13060 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13061 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13062 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13063 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13064 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13065 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13066 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13067 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13068 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13069 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13070 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13071 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13072 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13073 0x000000f7, 0x00000000, 0x00000000 13074 }; 13075 static const uint16_t gain_a0[] = { 13076 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13077 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13078 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13079 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13080 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13081 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13082 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13083 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13084 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13085 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13086 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13087 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13088 }; 13089 13090 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13091 13092 for (i = 0; i < 704; i++) 13093 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13094 13095 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13096 bwn_tab_sigsq_tbl); 13097 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13098 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13099 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13100 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13101 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13102 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13103 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13104 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13105 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13106 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13107 bwn_tab_pllfrac_tbl); 13108 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13109 bwn_tabl_iqlocal_tbl); 13110 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13111 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13112 13113 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13114 (siba_get_chiprev(sc->sc_dev) == 0)) { 13115 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13116 gainidx_a0); 13117 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13118 auxgainidx_a0); 13119 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13120 gainval_a0); 13121 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13122 } 13123 } 13124 13125 static void 13126 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13127 { 13128 struct bwn_softc *sc = mac->mac_sc; 13129 struct ieee80211com *ic = &sc->sc_ic; 13130 static struct bwn_txgain_entry txgain_r2[] = { 13131 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13132 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13133 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13134 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13135 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13136 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13137 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13138 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13139 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13140 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13141 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13142 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13143 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13144 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13145 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13146 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13147 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13148 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13149 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13150 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13151 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13152 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13153 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13154 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13155 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13156 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13157 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13158 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13159 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13160 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13161 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13162 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13163 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13164 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13165 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13166 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13167 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13168 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13169 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13170 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13171 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13172 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13173 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13174 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13175 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13176 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13177 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13178 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13179 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13180 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13181 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13182 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13183 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13184 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13185 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13186 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13187 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13188 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13189 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13190 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13191 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13192 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13193 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13194 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13195 }; 13196 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13197 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13198 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13199 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13200 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13201 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13202 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13203 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13204 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13205 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13206 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13207 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13208 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13209 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13210 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13211 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13212 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13213 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13214 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13215 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13216 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13217 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13218 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13219 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13220 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13221 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13222 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13223 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13224 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13225 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13226 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13227 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13228 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13229 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13230 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13231 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13232 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13233 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13234 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13235 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13236 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13237 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13238 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13239 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13240 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13241 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13242 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13243 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13244 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13245 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13246 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13247 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13248 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13249 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13250 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13251 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13252 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13253 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13254 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13255 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13256 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13257 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13258 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13259 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13260 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13261 }; 13262 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13263 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13264 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13265 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13266 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13267 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13268 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13269 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13270 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13271 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13272 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13273 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13274 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13275 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13276 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13277 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13278 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13279 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13280 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13281 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13282 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13283 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13284 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13285 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13286 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13287 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13288 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13289 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13290 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13291 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13292 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13293 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13294 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13295 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13296 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13297 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13298 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13299 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13300 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13301 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13302 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13303 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13304 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13305 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13306 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13307 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13308 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13309 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13310 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13311 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13312 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13313 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13314 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13315 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13316 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13317 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13318 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13319 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13320 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13321 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13322 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13323 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13324 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13325 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13326 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13327 }; 13328 static struct bwn_txgain_entry txgain_r0[] = { 13329 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13330 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13331 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13332 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13333 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13334 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13335 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13336 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13337 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13338 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13339 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13340 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13341 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13342 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13343 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13344 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13345 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13346 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13347 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13348 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13349 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13350 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13351 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13352 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13353 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13354 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13355 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13356 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13357 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13358 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13359 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13360 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13361 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13362 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13363 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13364 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13365 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13366 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13367 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13368 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13369 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13370 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13371 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13372 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13373 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13374 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13375 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13376 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13377 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13378 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13379 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13380 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13381 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13382 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13383 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13384 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13385 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13386 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13387 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13388 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13389 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13390 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13391 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13392 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13393 }; 13394 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13395 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13396 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13397 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13398 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13399 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13400 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13401 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13402 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13403 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13404 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13405 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13406 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13407 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13408 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13409 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13410 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13411 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13412 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13413 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13414 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13415 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13416 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13417 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13418 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13419 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13420 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13421 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13422 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13423 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13424 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13425 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13426 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13427 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13428 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13429 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13430 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13431 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13432 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13433 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13434 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13435 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13436 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13437 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13438 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13439 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13440 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13441 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13442 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13443 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13444 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13445 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13446 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13447 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13448 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13449 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13450 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13451 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13452 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13453 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13454 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13455 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13456 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13457 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13458 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13459 }; 13460 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13461 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13462 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13463 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13464 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13465 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13466 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13467 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13468 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13469 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13470 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13471 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13472 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13473 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13474 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13475 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13476 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13477 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13478 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13479 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13480 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13481 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13482 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13483 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13484 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13485 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13486 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13487 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13488 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13489 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13490 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13491 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13492 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13493 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13494 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13495 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13496 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13497 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13498 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13499 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13500 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13501 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13502 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13503 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13504 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13505 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13506 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13507 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13508 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13509 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13510 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13511 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13512 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13513 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13514 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13515 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13516 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13517 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13518 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13519 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13520 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13521 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13522 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13523 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13524 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13525 }; 13526 static struct bwn_txgain_entry txgain_r1[] = { 13527 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13528 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13529 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13530 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13531 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13532 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13533 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13534 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13535 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13536 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13537 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13538 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13539 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13540 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13541 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13542 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13543 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13544 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13545 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13546 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13547 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13548 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13549 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13550 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13551 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13552 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13553 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13554 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13555 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13556 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13557 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13558 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13559 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13560 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13561 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13562 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13563 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13564 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13565 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13566 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13567 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13568 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13569 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13570 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13571 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13572 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13573 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13574 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13575 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13576 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13577 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13578 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13579 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13580 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13581 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13582 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13583 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13584 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13585 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13586 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13587 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13588 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13589 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13590 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13591 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13592 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13593 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13594 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13595 { 7, 11, 6, 0, 71 } 13596 }; 13597 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13598 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13599 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13600 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13601 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13602 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13603 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13604 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13605 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13606 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13607 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13608 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13609 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13610 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13611 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13612 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13613 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13614 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13615 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13616 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13617 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13618 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13619 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13620 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13621 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13622 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13623 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13624 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13625 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13626 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13627 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13628 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13629 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13630 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13631 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13632 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13633 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13634 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13635 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13636 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13637 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13638 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13639 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13640 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13641 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13642 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13643 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13644 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13645 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13646 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13647 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13648 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13649 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13650 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13651 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13652 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13653 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13654 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13655 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13656 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13657 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13658 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13659 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13660 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13661 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13662 }; 13663 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13664 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13665 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13666 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13667 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13668 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13669 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13670 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13671 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13672 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13673 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13674 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13675 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13676 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13677 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13678 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13679 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13680 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13681 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13682 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13683 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13684 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13685 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13686 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13687 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13688 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13689 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13690 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13691 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13692 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13693 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13694 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13695 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13696 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13697 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13698 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13699 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13700 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13701 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13702 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13703 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13704 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13705 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13706 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13707 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13708 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13709 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13710 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13711 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13712 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13713 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13714 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13715 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13716 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13717 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13718 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13719 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13720 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13721 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13722 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13723 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13724 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13725 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13726 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13727 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13728 }; 13729 13730 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13731 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13732 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13733 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13734 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13735 txgain_2ghz_r2); 13736 else 13737 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13738 txgain_5ghz_r2); 13739 return; 13740 } 13741 13742 if (mac->mac_phy.rev == 0) { 13743 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13744 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13745 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13746 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13747 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13748 txgain_2ghz_r0); 13749 else 13750 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13751 txgain_5ghz_r0); 13752 return; 13753 } 13754 13755 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13756 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13757 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13758 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13759 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13760 else 13761 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13762 } 13763 13764 static void 13765 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13766 { 13767 uint32_t offset, type; 13768 13769 type = BWN_TAB_GETTYPE(typeoffset); 13770 offset = BWN_TAB_GETOFFSET(typeoffset); 13771 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13772 13773 switch (type) { 13774 case BWN_TAB_8BIT: 13775 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13776 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13777 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13778 break; 13779 case BWN_TAB_16BIT: 13780 KASSERT(!(value & ~0xffff), 13781 ("%s:%d: fail", __func__, __LINE__)); 13782 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13783 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13784 break; 13785 case BWN_TAB_32BIT: 13786 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13787 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13788 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13789 break; 13790 default: 13791 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13792 } 13793 } 13794 13795 static int 13796 bwn_phy_lp_loopback(struct bwn_mac *mac) 13797 { 13798 struct bwn_phy_lp_iq_est ie; 13799 int i, index = -1; 13800 uint32_t tmp; 13801 13802 memset(&ie, 0, sizeof(ie)); 13803 13804 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13805 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13806 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13807 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13808 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13809 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13810 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13811 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13812 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13813 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13814 for (i = 0; i < 32; i++) { 13815 bwn_phy_lp_set_rxgain_idx(mac, i); 13816 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13817 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13818 continue; 13819 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13820 if ((tmp > 4000) && (tmp < 10000)) { 13821 index = i; 13822 break; 13823 } 13824 } 13825 bwn_phy_lp_ddfs_turnoff(mac); 13826 return (index); 13827 } 13828 13829 static void 13830 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13831 { 13832 13833 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13834 } 13835 13836 static void 13837 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13838 int incr1, int incr2, int scale_idx) 13839 { 13840 13841 bwn_phy_lp_ddfs_turnoff(mac); 13842 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13843 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13844 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 13845 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 13846 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 13847 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 13848 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 13849 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 13850 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 13851 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 13852 } 13853 13854 static uint8_t 13855 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 13856 struct bwn_phy_lp_iq_est *ie) 13857 { 13858 int i; 13859 13860 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 13861 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 13862 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 13863 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 13864 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 13865 13866 for (i = 0; i < 500; i++) { 13867 if (!(BWN_PHY_READ(mac, 13868 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 13869 break; 13870 DELAY(1000); 13871 } 13872 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 13873 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13874 return 0; 13875 } 13876 13877 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 13878 ie->ie_iqprod <<= 16; 13879 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 13880 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 13881 ie->ie_ipwr <<= 16; 13882 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 13883 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 13884 ie->ie_qpwr <<= 16; 13885 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 13886 13887 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 13888 return 1; 13889 } 13890 13891 static uint32_t 13892 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 13893 { 13894 uint32_t offset, type, value; 13895 13896 type = BWN_TAB_GETTYPE(typeoffset); 13897 offset = BWN_TAB_GETOFFSET(typeoffset); 13898 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13899 13900 switch (type) { 13901 case BWN_TAB_8BIT: 13902 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13903 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 13904 break; 13905 case BWN_TAB_16BIT: 13906 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13907 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13908 break; 13909 case BWN_TAB_32BIT: 13910 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13911 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 13912 value <<= 16; 13913 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 13914 break; 13915 default: 13916 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13917 value = 0; 13918 } 13919 13920 return (value); 13921 } 13922 13923 static void 13924 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 13925 { 13926 13927 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 13928 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 13929 } 13930 13931 static void 13932 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 13933 { 13934 uint16_t ctl; 13935 13936 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 13937 ctl |= dac << 7; 13938 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 13939 } 13940 13941 static void 13942 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 13943 { 13944 13945 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 13946 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 13947 } 13948 13949 static void 13950 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 13951 { 13952 13953 if (mac->mac_phy.rev < 2) 13954 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 13955 else { 13956 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 13957 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 13958 } 13959 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 13960 } 13961 13962 static uint16_t 13963 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 13964 { 13965 13966 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 13967 } 13968 13969 static uint8_t 13970 bwn_nbits(int32_t val) 13971 { 13972 uint32_t tmp; 13973 uint8_t nbits = 0; 13974 13975 for (tmp = abs(val); tmp != 0; tmp >>= 1) 13976 nbits++; 13977 return (nbits); 13978 } 13979 13980 static void 13981 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 13982 struct bwn_txgain_entry *table) 13983 { 13984 int i; 13985 13986 for (i = offset; i < count; i++) 13987 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 13988 } 13989 13990 static void 13991 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 13992 struct bwn_txgain_entry data) 13993 { 13994 13995 if (mac->mac_phy.rev >= 2) 13996 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 13997 else 13998 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 13999 } 14000 14001 static void 14002 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14003 struct bwn_txgain_entry te) 14004 { 14005 struct bwn_softc *sc = mac->mac_sc; 14006 struct ieee80211com *ic = &sc->sc_ic; 14007 uint32_t tmp; 14008 14009 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14010 14011 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14012 if (mac->mac_phy.rev >= 3) { 14013 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14014 (0x10 << 24) : (0x70 << 24)); 14015 } else { 14016 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14017 (0x14 << 24) : (0x7f << 24)); 14018 } 14019 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14020 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14021 te.te_bbmult << 20 | te.te_dac << 28); 14022 } 14023 14024 static void 14025 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14026 struct bwn_txgain_entry te) 14027 { 14028 14029 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14030 14031 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14032 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14033 te.te_dac); 14034 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14035 } 14036 14037 static void 14038 bwn_sysctl_node(struct bwn_softc *sc) 14039 { 14040 device_t dev = sc->sc_dev; 14041 struct bwn_mac *mac; 14042 struct bwn_stats *stats; 14043 14044 /* XXX assume that count of MAC is only 1. */ 14045 14046 if ((mac = sc->sc_curmac) == NULL) 14047 return; 14048 stats = &mac->mac_stats; 14049 14050 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14051 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14052 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14053 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14054 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14055 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14056 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14057 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14058 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14059 14060 #ifdef BWN_DEBUG 14061 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14062 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14063 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14064 #endif 14065 } 14066 14067 static device_method_t bwn_methods[] = { 14068 /* Device interface */ 14069 DEVMETHOD(device_probe, bwn_probe), 14070 DEVMETHOD(device_attach, bwn_attach), 14071 DEVMETHOD(device_detach, bwn_detach), 14072 DEVMETHOD(device_suspend, bwn_suspend), 14073 DEVMETHOD(device_resume, bwn_resume), 14074 DEVMETHOD_END 14075 }; 14076 static driver_t bwn_driver = { 14077 "bwn", 14078 bwn_methods, 14079 sizeof(struct bwn_softc) 14080 }; 14081 static devclass_t bwn_devclass; 14082 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14083 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14084 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14085 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14086 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14087