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 int 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 void bwn_init(void *); 140 static int bwn_init_locked(struct bwn_softc *); 141 static int bwn_ioctl(struct ifnet *, u_long, caddr_t); 142 static void bwn_start(struct ifnet *); 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 *, int); 201 static void bwn_stop_locked(struct bwn_softc *, int); 202 static int bwn_core_init(struct bwn_mac *); 203 static void bwn_core_start(struct bwn_mac *); 204 static void bwn_core_exit(struct bwn_mac *); 205 static void bwn_bt_disable(struct bwn_mac *); 206 static int bwn_chip_init(struct bwn_mac *); 207 static uint64_t bwn_hf_read(struct bwn_mac *); 208 static void bwn_hf_write(struct bwn_mac *, uint64_t); 209 static void bwn_set_txretry(struct bwn_mac *, int, int); 210 static void bwn_rate_init(struct bwn_mac *); 211 static void bwn_set_phytxctl(struct bwn_mac *); 212 static void bwn_spu_setdelay(struct bwn_mac *, int); 213 static void bwn_bt_enable(struct bwn_mac *); 214 static void bwn_set_macaddr(struct bwn_mac *); 215 static void bwn_crypt_init(struct bwn_mac *); 216 static void bwn_chip_exit(struct bwn_mac *); 217 static int bwn_fw_fillinfo(struct bwn_mac *); 218 static int bwn_fw_loaducode(struct bwn_mac *); 219 static int bwn_gpio_init(struct bwn_mac *); 220 static int bwn_fw_loadinitvals(struct bwn_mac *); 221 static int bwn_phy_init(struct bwn_mac *); 222 static void bwn_set_txantenna(struct bwn_mac *, int); 223 static void bwn_set_opmode(struct bwn_mac *); 224 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 225 static uint8_t bwn_plcp_getcck(const uint8_t); 226 static uint8_t bwn_plcp_getofdm(const uint8_t); 227 static void bwn_pio_init(struct bwn_mac *); 228 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 229 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 230 int); 231 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 232 struct bwn_pio_rxqueue *, int); 233 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 234 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 235 uint16_t); 236 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 237 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 238 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 239 static void bwn_pio_handle_txeof(struct bwn_mac *, 240 const struct bwn_txstatus *); 241 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 242 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 243 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 244 uint16_t); 245 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 246 uint32_t); 247 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 248 struct mbuf *); 249 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 250 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 251 struct bwn_pio_txqueue *, uint32_t, const void *, int); 252 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 253 uint16_t, uint32_t); 254 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 255 struct bwn_pio_txqueue *, uint16_t, const void *, int); 256 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 257 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 258 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 259 uint16_t, struct bwn_pio_txpkt **); 260 static void bwn_dma_init(struct bwn_mac *); 261 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 262 static int bwn_dma_mask2type(uint64_t); 263 static uint64_t bwn_dma_mask(struct bwn_mac *); 264 static uint16_t bwn_dma_base(int, int); 265 static void bwn_dma_ringfree(struct bwn_dma_ring **); 266 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 267 int, struct bwn_dmadesc_generic **, 268 struct bwn_dmadesc_meta **); 269 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 270 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 271 int, int); 272 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 273 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 274 static void bwn_dma_32_resume(struct bwn_dma_ring *); 275 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 276 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 277 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 278 int, struct bwn_dmadesc_generic **, 279 struct bwn_dmadesc_meta **); 280 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 281 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 282 int, int); 283 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 284 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 285 static void bwn_dma_64_resume(struct bwn_dma_ring *); 286 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 287 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 288 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 289 static void bwn_dma_setup(struct bwn_dma_ring *); 290 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 291 static void bwn_dma_cleanup(struct bwn_dma_ring *); 292 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 293 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 294 static void bwn_dma_rx(struct bwn_dma_ring *); 295 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 296 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 297 struct bwn_dmadesc_meta *); 298 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 299 static int bwn_dma_gettype(struct bwn_mac *); 300 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 301 static int bwn_dma_freeslot(struct bwn_dma_ring *); 302 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 303 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 304 static int bwn_dma_newbuf(struct bwn_dma_ring *, 305 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 306 int); 307 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 308 bus_size_t, int); 309 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 310 static void bwn_dma_handle_txeof(struct bwn_mac *, 311 const struct bwn_txstatus *); 312 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 313 struct mbuf *); 314 static int bwn_dma_getslot(struct bwn_dma_ring *); 315 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 316 uint8_t); 317 static int bwn_dma_attach(struct bwn_mac *); 318 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 319 int, int, int); 320 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 321 const struct bwn_txstatus *, uint16_t, int *); 322 static void bwn_dma_free(struct bwn_mac *); 323 static void bwn_phy_g_init_sub(struct bwn_mac *); 324 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 325 static void bwn_phy_init_b5(struct bwn_mac *); 326 static void bwn_phy_init_b6(struct bwn_mac *); 327 static void bwn_phy_init_a(struct bwn_mac *); 328 static void bwn_loopback_calcgain(struct bwn_mac *); 329 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 330 static void bwn_lo_g_init(struct bwn_mac *); 331 static void bwn_lo_g_adjust(struct bwn_mac *); 332 static void bwn_lo_get_powervector(struct bwn_mac *); 333 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 334 const struct bwn_bbatt *, const struct bwn_rfatt *); 335 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 336 static void bwn_phy_hwpctl_init(struct bwn_mac *); 337 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 338 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 339 const struct bwn_bbatt *, const struct bwn_rfatt *, 340 uint8_t); 341 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 342 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 343 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 344 static void bwn_wa_init(struct bwn_mac *); 345 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 346 uint16_t); 347 static void bwn_dummy_transmission(struct bwn_mac *, int, int); 348 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 349 uint32_t); 350 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 351 uint16_t); 352 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t); 353 static void bwn_mac_suspend(struct bwn_mac *); 354 static void bwn_mac_enable(struct bwn_mac *); 355 static void bwn_psctl(struct bwn_mac *, uint32_t); 356 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 357 static void bwn_nrssi_offset(struct bwn_mac *); 358 static void bwn_nrssi_threshold(struct bwn_mac *); 359 static void bwn_nrssi_slope_11g(struct bwn_mac *); 360 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 361 int16_t); 362 static void bwn_set_original_gains(struct bwn_mac *); 363 static void bwn_hwpctl_early_init(struct bwn_mac *); 364 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 365 static uint16_t bwn_phy_g_chan2freq(uint8_t); 366 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 367 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 368 const char *, struct bwn_fwfile *); 369 static void bwn_release_firmware(struct bwn_mac *); 370 static void bwn_do_release_fw(struct bwn_fwfile *); 371 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 372 static int bwn_fwinitvals_write(struct bwn_mac *, 373 const struct bwn_fwinitvals *, size_t, size_t); 374 static int bwn_switch_channel(struct bwn_mac *, int); 375 static uint16_t bwn_ant2phy(int); 376 static void bwn_mac_write_bssid(struct bwn_mac *); 377 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 378 const uint8_t *); 379 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 380 const uint8_t *, size_t, const uint8_t *); 381 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 382 const uint8_t *); 383 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 384 const uint8_t *); 385 static void bwn_phy_exit(struct bwn_mac *); 386 static void bwn_core_stop(struct bwn_mac *); 387 static int bwn_switch_band(struct bwn_softc *, 388 struct ieee80211_channel *); 389 static void bwn_phy_reset(struct bwn_mac *); 390 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 391 static void bwn_set_pretbtt(struct bwn_mac *); 392 static int bwn_intr(void *); 393 static void bwn_intrtask(void *, int); 394 static void bwn_restart(struct bwn_mac *, const char *); 395 static void bwn_intr_ucode_debug(struct bwn_mac *); 396 static void bwn_intr_tbtt_indication(struct bwn_mac *); 397 static void bwn_intr_atim_end(struct bwn_mac *); 398 static void bwn_intr_beacon(struct bwn_mac *); 399 static void bwn_intr_pmq(struct bwn_mac *); 400 static void bwn_intr_noise(struct bwn_mac *); 401 static void bwn_intr_txeof(struct bwn_mac *); 402 static void bwn_hwreset(void *, int); 403 static void bwn_handle_fwpanic(struct bwn_mac *); 404 static void bwn_load_beacon0(struct bwn_mac *); 405 static void bwn_load_beacon1(struct bwn_mac *); 406 static uint32_t bwn_jssi_read(struct bwn_mac *); 407 static void bwn_noise_gensample(struct bwn_mac *); 408 static void bwn_handle_txeof(struct bwn_mac *, 409 const struct bwn_txstatus *); 410 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 411 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 412 static void bwn_start_locked(struct ifnet *); 413 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 414 struct mbuf *); 415 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 416 static int bwn_set_txhdr(struct bwn_mac *, 417 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 418 uint16_t); 419 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 420 const uint8_t); 421 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 422 static uint8_t bwn_get_fbrate(uint8_t); 423 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t); 424 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *); 425 static void bwn_phy_lock(struct bwn_mac *); 426 static void bwn_phy_unlock(struct bwn_mac *); 427 static void bwn_rf_lock(struct bwn_mac *); 428 static void bwn_rf_unlock(struct bwn_mac *); 429 static void bwn_txpwr(void *, int); 430 static void bwn_tasks(void *); 431 static void bwn_task_15s(struct bwn_mac *); 432 static void bwn_task_30s(struct bwn_mac *); 433 static void bwn_task_60s(struct bwn_mac *); 434 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 435 uint8_t); 436 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 437 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 438 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 439 int, int); 440 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 441 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 442 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 443 static void bwn_watchdog(void *); 444 static void bwn_dma_stop(struct bwn_mac *); 445 static void bwn_pio_stop(struct bwn_mac *); 446 static void bwn_dma_ringstop(struct bwn_dma_ring **); 447 static void bwn_led_attach(struct bwn_mac *); 448 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 449 static void bwn_led_event(struct bwn_mac *, int); 450 static void bwn_led_blink_start(struct bwn_mac *, int, int); 451 static void bwn_led_blink_next(void *); 452 static void bwn_led_blink_end(void *); 453 static void bwn_rfswitch(void *); 454 static void bwn_rf_turnon(struct bwn_mac *); 455 static void bwn_rf_turnoff(struct bwn_mac *); 456 static void bwn_phy_lp_init_pre(struct bwn_mac *); 457 static int bwn_phy_lp_init(struct bwn_mac *); 458 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t); 459 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t); 460 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t, 461 uint16_t); 462 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t); 463 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t); 464 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int); 465 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t); 466 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *); 467 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int); 468 static void bwn_phy_lp_task_60s(struct bwn_mac *); 469 static void bwn_phy_lp_readsprom(struct bwn_mac *); 470 static void bwn_phy_lp_bbinit(struct bwn_mac *); 471 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 472 static void bwn_phy_lp_calib(struct bwn_mac *); 473 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int); 474 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 475 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 476 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 477 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 478 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 479 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 480 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 481 static void bwn_phy_lp_bugfix(struct bwn_mac *); 482 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 483 static void bwn_phy_lp_tblinit(struct bwn_mac *); 484 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 485 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 486 static void bwn_phy_lp_b2062_init(struct bwn_mac *); 487 static void bwn_phy_lp_b2063_init(struct bwn_mac *); 488 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *); 489 static void bwn_phy_lp_rccal_r12(struct bwn_mac *); 490 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 491 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 492 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 493 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 494 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 495 const void *); 496 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 497 static struct bwn_txgain 498 bwn_phy_lp_get_txgain(struct bwn_mac *); 499 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 500 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 501 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 502 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 503 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 504 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 505 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 506 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 507 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 508 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 509 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 510 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 511 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 512 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 513 static int bwn_phy_lp_loopback(struct bwn_mac *); 514 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 515 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 516 int); 517 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 518 struct bwn_phy_lp_iq_est *); 519 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 520 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 521 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 522 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 523 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 524 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 525 static uint8_t bwn_nbits(int32_t); 526 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 527 struct bwn_txgain_entry *); 528 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 529 struct bwn_txgain_entry); 530 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 531 struct bwn_txgain_entry); 532 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 533 struct bwn_txgain_entry); 534 static void bwn_sysctl_node(struct bwn_softc *); 535 536 static struct resource_spec bwn_res_spec_legacy[] = { 537 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 538 { -1, 0, 0 } 539 }; 540 541 static struct resource_spec bwn_res_spec_msi[] = { 542 { SYS_RES_IRQ, 1, RF_ACTIVE }, 543 { -1, 0, 0 } 544 }; 545 546 static const struct bwn_channelinfo bwn_chantable_bg = { 547 .channels = { 548 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 549 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 550 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 551 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 552 { 2472, 13, 30 }, { 2484, 14, 30 } }, 553 .nchannels = 14 554 }; 555 556 static const struct bwn_channelinfo bwn_chantable_a = { 557 .channels = { 558 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 559 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 560 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 561 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 562 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 563 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 564 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 565 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 566 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 567 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 568 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 569 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 570 { 6080, 216, 30 } }, 571 .nchannels = 37 572 }; 573 574 static const struct bwn_channelinfo bwn_chantable_n = { 575 .channels = { 576 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 577 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 578 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 579 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 580 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 581 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 582 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 583 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 584 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 585 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 586 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 587 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 588 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 589 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 590 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 591 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 592 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 593 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 594 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 595 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 596 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 597 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 598 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 599 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 600 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 601 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 602 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 603 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 604 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 605 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 606 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 607 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 608 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 609 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 610 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 611 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 612 { 6130, 226, 30 }, { 6140, 228, 30 } }, 613 .nchannels = 110 614 }; 615 616 static const uint8_t bwn_b2063_chantable_data[33][12] = { 617 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 618 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 619 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 620 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 621 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 622 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 623 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 624 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 625 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 626 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 627 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 628 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 629 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 630 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 631 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 632 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 633 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 634 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 635 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 636 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 637 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 638 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 639 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 640 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 641 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 642 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 643 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 646 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 647 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 648 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 649 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 650 }; 651 652 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 653 { 1, 2412, bwn_b2063_chantable_data[0] }, 654 { 2, 2417, bwn_b2063_chantable_data[0] }, 655 { 3, 2422, bwn_b2063_chantable_data[0] }, 656 { 4, 2427, bwn_b2063_chantable_data[1] }, 657 { 5, 2432, bwn_b2063_chantable_data[1] }, 658 { 6, 2437, bwn_b2063_chantable_data[1] }, 659 { 7, 2442, bwn_b2063_chantable_data[1] }, 660 { 8, 2447, bwn_b2063_chantable_data[1] }, 661 { 9, 2452, bwn_b2063_chantable_data[2] }, 662 { 10, 2457, bwn_b2063_chantable_data[2] }, 663 { 11, 2462, bwn_b2063_chantable_data[3] }, 664 { 12, 2467, bwn_b2063_chantable_data[3] }, 665 { 13, 2472, bwn_b2063_chantable_data[3] }, 666 { 14, 2484, bwn_b2063_chantable_data[4] }, 667 { 34, 5170, bwn_b2063_chantable_data[5] }, 668 { 36, 5180, bwn_b2063_chantable_data[6] }, 669 { 38, 5190, bwn_b2063_chantable_data[7] }, 670 { 40, 5200, bwn_b2063_chantable_data[8] }, 671 { 42, 5210, bwn_b2063_chantable_data[9] }, 672 { 44, 5220, bwn_b2063_chantable_data[10] }, 673 { 46, 5230, bwn_b2063_chantable_data[11] }, 674 { 48, 5240, bwn_b2063_chantable_data[12] }, 675 { 52, 5260, bwn_b2063_chantable_data[13] }, 676 { 56, 5280, bwn_b2063_chantable_data[14] }, 677 { 60, 5300, bwn_b2063_chantable_data[14] }, 678 { 64, 5320, bwn_b2063_chantable_data[15] }, 679 { 100, 5500, bwn_b2063_chantable_data[16] }, 680 { 104, 5520, bwn_b2063_chantable_data[17] }, 681 { 108, 5540, bwn_b2063_chantable_data[18] }, 682 { 112, 5560, bwn_b2063_chantable_data[19] }, 683 { 116, 5580, bwn_b2063_chantable_data[20] }, 684 { 120, 5600, bwn_b2063_chantable_data[21] }, 685 { 124, 5620, bwn_b2063_chantable_data[21] }, 686 { 128, 5640, bwn_b2063_chantable_data[22] }, 687 { 132, 5660, bwn_b2063_chantable_data[22] }, 688 { 136, 5680, bwn_b2063_chantable_data[22] }, 689 { 140, 5700, bwn_b2063_chantable_data[23] }, 690 { 149, 5745, bwn_b2063_chantable_data[23] }, 691 { 153, 5765, bwn_b2063_chantable_data[23] }, 692 { 157, 5785, bwn_b2063_chantable_data[23] }, 693 { 161, 5805, bwn_b2063_chantable_data[23] }, 694 { 165, 5825, bwn_b2063_chantable_data[23] }, 695 { 184, 4920, bwn_b2063_chantable_data[24] }, 696 { 188, 4940, bwn_b2063_chantable_data[25] }, 697 { 192, 4960, bwn_b2063_chantable_data[26] }, 698 { 196, 4980, bwn_b2063_chantable_data[27] }, 699 { 200, 5000, bwn_b2063_chantable_data[28] }, 700 { 204, 5020, bwn_b2063_chantable_data[29] }, 701 { 208, 5040, bwn_b2063_chantable_data[30] }, 702 { 212, 5060, bwn_b2063_chantable_data[31] }, 703 { 216, 5080, bwn_b2063_chantable_data[32] } 704 }; 705 706 static const uint8_t bwn_b2062_chantable_data[22][12] = { 707 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 708 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 709 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 710 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 711 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 712 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 713 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 714 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 715 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 716 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 717 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 718 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 719 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 720 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 721 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 722 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 723 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 724 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 725 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 726 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 727 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 728 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 729 }; 730 731 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 732 { 1, 2412, bwn_b2062_chantable_data[0] }, 733 { 2, 2417, bwn_b2062_chantable_data[0] }, 734 { 3, 2422, bwn_b2062_chantable_data[0] }, 735 { 4, 2427, bwn_b2062_chantable_data[0] }, 736 { 5, 2432, bwn_b2062_chantable_data[0] }, 737 { 6, 2437, bwn_b2062_chantable_data[0] }, 738 { 7, 2442, bwn_b2062_chantable_data[0] }, 739 { 8, 2447, bwn_b2062_chantable_data[0] }, 740 { 9, 2452, bwn_b2062_chantable_data[0] }, 741 { 10, 2457, bwn_b2062_chantable_data[0] }, 742 { 11, 2462, bwn_b2062_chantable_data[0] }, 743 { 12, 2467, bwn_b2062_chantable_data[0] }, 744 { 13, 2472, bwn_b2062_chantable_data[0] }, 745 { 14, 2484, bwn_b2062_chantable_data[0] }, 746 { 34, 5170, bwn_b2062_chantable_data[1] }, 747 { 38, 5190, bwn_b2062_chantable_data[2] }, 748 { 42, 5210, bwn_b2062_chantable_data[2] }, 749 { 46, 5230, bwn_b2062_chantable_data[3] }, 750 { 36, 5180, bwn_b2062_chantable_data[4] }, 751 { 40, 5200, bwn_b2062_chantable_data[5] }, 752 { 44, 5220, bwn_b2062_chantable_data[6] }, 753 { 48, 5240, bwn_b2062_chantable_data[3] }, 754 { 52, 5260, bwn_b2062_chantable_data[3] }, 755 { 56, 5280, bwn_b2062_chantable_data[3] }, 756 { 60, 5300, bwn_b2062_chantable_data[7] }, 757 { 64, 5320, bwn_b2062_chantable_data[8] }, 758 { 100, 5500, bwn_b2062_chantable_data[9] }, 759 { 104, 5520, bwn_b2062_chantable_data[10] }, 760 { 108, 5540, bwn_b2062_chantable_data[10] }, 761 { 112, 5560, bwn_b2062_chantable_data[10] }, 762 { 116, 5580, bwn_b2062_chantable_data[11] }, 763 { 120, 5600, bwn_b2062_chantable_data[12] }, 764 { 124, 5620, bwn_b2062_chantable_data[12] }, 765 { 128, 5640, bwn_b2062_chantable_data[12] }, 766 { 132, 5660, bwn_b2062_chantable_data[12] }, 767 { 136, 5680, bwn_b2062_chantable_data[12] }, 768 { 140, 5700, bwn_b2062_chantable_data[12] }, 769 { 149, 5745, bwn_b2062_chantable_data[12] }, 770 { 153, 5765, bwn_b2062_chantable_data[12] }, 771 { 157, 5785, bwn_b2062_chantable_data[12] }, 772 { 161, 5805, bwn_b2062_chantable_data[12] }, 773 { 165, 5825, bwn_b2062_chantable_data[12] }, 774 { 184, 4920, bwn_b2062_chantable_data[13] }, 775 { 188, 4940, bwn_b2062_chantable_data[14] }, 776 { 192, 4960, bwn_b2062_chantable_data[15] }, 777 { 196, 4980, bwn_b2062_chantable_data[16] }, 778 { 200, 5000, bwn_b2062_chantable_data[17] }, 779 { 204, 5020, bwn_b2062_chantable_data[18] }, 780 { 208, 5040, bwn_b2062_chantable_data[19] }, 781 { 212, 5060, bwn_b2062_chantable_data[20] }, 782 { 216, 5080, bwn_b2062_chantable_data[21] } 783 }; 784 785 /* for LP PHY */ 786 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 787 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 788 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 789 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 790 { 13, -66, 13 }, { 14, -66, 13 }, 791 }; 792 793 /* for LP PHY */ 794 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 795 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 796 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 797 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 798 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 799 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 800 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 801 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 802 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 803 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 804 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 805 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 806 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 807 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 808 }; 809 810 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 811 812 static const uint8_t bwn_tab_sigsq_tbl[] = { 813 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 814 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 815 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 816 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 817 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 818 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 819 }; 820 821 static const uint8_t bwn_tab_pllfrac_tbl[] = { 822 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 823 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 824 }; 825 826 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 827 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 828 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 831 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 832 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 838 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 839 }; 840 841 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 842 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 843 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 844 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 845 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 846 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 847 848 #define VENDOR_LED_ACT(vendor) \ 849 { \ 850 .vid = PCI_VENDOR_##vendor, \ 851 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 852 } 853 854 static const struct { 855 uint16_t vid; 856 uint8_t led_act[BWN_LED_MAX]; 857 } bwn_vendor_led_act[] = { 858 VENDOR_LED_ACT(COMPAQ), 859 VENDOR_LED_ACT(ASUSTEK) 860 }; 861 862 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 863 { BWN_VENDOR_LED_ACT_DEFAULT }; 864 865 #undef VENDOR_LED_ACT 866 867 static const struct { 868 int on_dur; 869 int off_dur; 870 } bwn_led_duration[109] = { 871 [0] = { 400, 100 }, 872 [2] = { 150, 75 }, 873 [4] = { 90, 45 }, 874 [11] = { 66, 34 }, 875 [12] = { 53, 26 }, 876 [18] = { 42, 21 }, 877 [22] = { 35, 17 }, 878 [24] = { 32, 16 }, 879 [36] = { 21, 10 }, 880 [48] = { 16, 8 }, 881 [72] = { 11, 5 }, 882 [96] = { 9, 4 }, 883 [108] = { 7, 3 } 884 }; 885 886 static const uint16_t bwn_wme_shm_offsets[] = { 887 [0] = BWN_WME_BESTEFFORT, 888 [1] = BWN_WME_BACKGROUND, 889 [2] = BWN_WME_VOICE, 890 [3] = BWN_WME_VIDEO, 891 }; 892 893 static const struct siba_devid bwn_devs[] = { 894 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), 895 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), 896 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), 897 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), 898 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), 899 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), 900 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), 901 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), 902 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") 903 }; 904 905 static int 906 bwn_probe(device_t dev) 907 { 908 int i; 909 910 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) { 911 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && 912 siba_get_device(dev) == bwn_devs[i].sd_device && 913 siba_get_revid(dev) == bwn_devs[i].sd_rev) 914 return (BUS_PROBE_DEFAULT); 915 } 916 917 return (ENXIO); 918 } 919 920 static int 921 bwn_attach(device_t dev) 922 { 923 struct bwn_mac *mac; 924 struct bwn_softc *sc = device_get_softc(dev); 925 int error, i, msic, reg; 926 927 sc->sc_dev = dev; 928 #ifdef BWN_DEBUG 929 sc->sc_debug = bwn_debug; 930 #endif 931 932 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 933 error = bwn_attach_pre(sc); 934 if (error != 0) 935 return (error); 936 bwn_sprom_bugfixes(dev); 937 sc->sc_flags |= BWN_FLAG_ATTACHED; 938 } 939 940 if (!TAILQ_EMPTY(&sc->sc_maclist)) { 941 if (siba_get_pci_device(dev) != 0x4313 && 942 siba_get_pci_device(dev) != 0x431a && 943 siba_get_pci_device(dev) != 0x4321) { 944 device_printf(sc->sc_dev, 945 "skip 802.11 cores\n"); 946 return (ENODEV); 947 } 948 } 949 950 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, 951 M_NOWAIT | M_ZERO); 952 if (mac == NULL) 953 return (ENOMEM); 954 mac->mac_sc = sc; 955 mac->mac_status = BWN_MAC_STATUS_UNINIT; 956 if (bwn_bfp != 0) 957 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 958 959 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 960 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 961 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 962 963 error = bwn_attach_core(mac); 964 if (error) 965 goto fail0; 966 bwn_led_attach(mac); 967 968 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " 969 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 970 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), 971 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, 972 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, 973 mac->mac_phy.rf_rev); 974 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 975 device_printf(sc->sc_dev, "DMA (%d bits)\n", 976 mac->mac_method.dma.dmatype); 977 else 978 device_printf(sc->sc_dev, "PIO\n"); 979 980 /* 981 * setup PCI resources and interrupt. 982 */ 983 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { 984 msic = pci_msi_count(dev); 985 if (bootverbose) 986 device_printf(sc->sc_dev, "MSI count : %d\n", msic); 987 } else 988 msic = 0; 989 990 mac->mac_intr_spec = bwn_res_spec_legacy; 991 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { 992 if (pci_alloc_msi(dev, &msic) == 0) { 993 device_printf(sc->sc_dev, 994 "Using %d MSI messages\n", msic); 995 mac->mac_intr_spec = bwn_res_spec_msi; 996 mac->mac_msi = 1; 997 } 998 } 999 1000 error = bus_alloc_resources(dev, mac->mac_intr_spec, 1001 mac->mac_res_irq); 1002 if (error) { 1003 device_printf(sc->sc_dev, 1004 "couldn't allocate IRQ resources (%d)\n", error); 1005 goto fail1; 1006 } 1007 1008 if (mac->mac_msi == 0) 1009 error = bus_setup_intr(dev, mac->mac_res_irq[0], 1010 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1011 &mac->mac_intrhand[0]); 1012 else { 1013 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1014 error = bus_setup_intr(dev, mac->mac_res_irq[i], 1015 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 1016 &mac->mac_intrhand[i]); 1017 if (error != 0) { 1018 device_printf(sc->sc_dev, 1019 "couldn't setup interrupt (%d)\n", error); 1020 break; 1021 } 1022 } 1023 } 1024 1025 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 1026 1027 /* 1028 * calls attach-post routine 1029 */ 1030 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 1031 bwn_attach_post(sc); 1032 1033 return (0); 1034 fail1: 1035 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) 1036 pci_release_msi(dev); 1037 fail0: 1038 free(mac, M_DEVBUF); 1039 return (error); 1040 } 1041 1042 static int 1043 bwn_is_valid_ether_addr(uint8_t *addr) 1044 { 1045 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1046 1047 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1048 return (FALSE); 1049 1050 return (TRUE); 1051 } 1052 1053 static int 1054 bwn_attach_post(struct bwn_softc *sc) 1055 { 1056 struct ieee80211com *ic; 1057 struct ifnet *ifp = sc->sc_ifp; 1058 1059 ic = ifp->if_l2com; 1060 ic->ic_ifp = ifp; 1061 ic->ic_softc = sc; 1062 ic->ic_name = device_get_nameunit(sc->sc_dev); 1063 /* XXX not right but it's not used anywhere important */ 1064 ic->ic_phytype = IEEE80211_T_OFDM; 1065 ic->ic_opmode = IEEE80211_M_STA; 1066 ic->ic_caps = 1067 IEEE80211_C_STA /* station mode supported */ 1068 | IEEE80211_C_MONITOR /* monitor mode */ 1069 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 1070 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 1071 | IEEE80211_C_SHSLOT /* short slot time supported */ 1072 | IEEE80211_C_WME /* WME/WMM supported */ 1073 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 1074 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 1075 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 1076 ; 1077 1078 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 1079 1080 /* call MI attach routine. */ 1081 ieee80211_ifattach(ic, 1082 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? 1083 siba_sprom_get_mac_80211a(sc->sc_dev) : 1084 siba_sprom_get_mac_80211bg(sc->sc_dev)); 1085 1086 ic->ic_headroom = sizeof(struct bwn_txhdr); 1087 1088 /* override default methods */ 1089 ic->ic_raw_xmit = bwn_raw_xmit; 1090 ic->ic_updateslot = bwn_updateslot; 1091 ic->ic_update_promisc = bwn_update_promisc; 1092 ic->ic_wme.wme_update = bwn_wme_update; 1093 1094 ic->ic_scan_start = bwn_scan_start; 1095 ic->ic_scan_end = bwn_scan_end; 1096 ic->ic_set_channel = bwn_set_channel; 1097 1098 ic->ic_vap_create = bwn_vap_create; 1099 ic->ic_vap_delete = bwn_vap_delete; 1100 1101 ieee80211_radiotap_attach(ic, 1102 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 1103 BWN_TX_RADIOTAP_PRESENT, 1104 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 1105 BWN_RX_RADIOTAP_PRESENT); 1106 1107 bwn_sysctl_node(sc); 1108 1109 if (bootverbose) 1110 ieee80211_announce(ic); 1111 return (0); 1112 } 1113 1114 static void 1115 bwn_phy_detach(struct bwn_mac *mac) 1116 { 1117 1118 if (mac->mac_phy.detach != NULL) 1119 mac->mac_phy.detach(mac); 1120 } 1121 1122 static int 1123 bwn_detach(device_t dev) 1124 { 1125 struct bwn_softc *sc = device_get_softc(dev); 1126 struct bwn_mac *mac = sc->sc_curmac; 1127 struct ifnet *ifp = sc->sc_ifp; 1128 struct ieee80211com *ic = ifp->if_l2com; 1129 int i; 1130 1131 sc->sc_flags |= BWN_FLAG_INVALID; 1132 1133 if (device_is_attached(sc->sc_dev)) { 1134 bwn_stop(sc, 1); 1135 bwn_dma_free(mac); 1136 callout_drain(&sc->sc_led_blink_ch); 1137 callout_drain(&sc->sc_rfswitch_ch); 1138 callout_drain(&sc->sc_task_ch); 1139 callout_drain(&sc->sc_watchdog_ch); 1140 bwn_phy_detach(mac); 1141 if (ifp != NULL) { 1142 ieee80211_draintask(ic, &mac->mac_hwreset); 1143 ieee80211_draintask(ic, &mac->mac_txpower); 1144 ieee80211_ifdetach(ic); 1145 if_free(ifp); 1146 } 1147 } 1148 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 1149 taskqueue_free(sc->sc_tq); 1150 1151 for (i = 0; i < BWN_MSI_MESSAGES; i++) { 1152 if (mac->mac_intrhand[i] != NULL) { 1153 bus_teardown_intr(dev, mac->mac_res_irq[i], 1154 mac->mac_intrhand[i]); 1155 mac->mac_intrhand[i] = NULL; 1156 } 1157 } 1158 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); 1159 if (mac->mac_msi != 0) 1160 pci_release_msi(dev); 1161 1162 BWN_LOCK_DESTROY(sc); 1163 return (0); 1164 } 1165 1166 static int 1167 bwn_attach_pre(struct bwn_softc *sc) 1168 { 1169 struct ifnet *ifp; 1170 int error = 0; 1171 1172 BWN_LOCK_INIT(sc); 1173 TAILQ_INIT(&sc->sc_maclist); 1174 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 1175 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 1176 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 1177 1178 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 1179 taskqueue_thread_enqueue, &sc->sc_tq); 1180 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 1181 "%s taskq", device_get_nameunit(sc->sc_dev)); 1182 1183 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 1184 if (ifp == NULL) { 1185 device_printf(sc->sc_dev, "can not if_alloc()\n"); 1186 error = ENOSPC; 1187 goto fail; 1188 } 1189 1190 /* set these up early for if_printf use */ 1191 if_initname(ifp, device_get_name(sc->sc_dev), 1192 device_get_unit(sc->sc_dev)); 1193 1194 ifp->if_softc = sc; 1195 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1196 ifp->if_init = bwn_init; 1197 ifp->if_ioctl = bwn_ioctl; 1198 ifp->if_start = bwn_start; 1199 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 1200 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 1201 IFQ_SET_READY(&ifp->if_snd); 1202 1203 return (0); 1204 1205 fail: BWN_LOCK_DESTROY(sc); 1206 return (error); 1207 } 1208 1209 static void 1210 bwn_sprom_bugfixes(device_t dev) 1211 { 1212 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ 1213 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ 1214 (siba_get_pci_device(dev) == _device) && \ 1215 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ 1216 (siba_get_pci_subdevice(dev) == _subdevice)) 1217 1218 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && 1219 siba_get_pci_subdevice(dev) == 0x4e && 1220 siba_get_pci_revid(dev) > 0x40) 1221 siba_sprom_set_bf_lo(dev, 1222 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); 1223 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && 1224 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) 1225 siba_sprom_set_bf_lo(dev, 1226 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); 1227 if (siba_get_type(dev) == SIBA_TYPE_PCI) { 1228 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || 1229 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || 1230 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || 1231 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || 1232 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || 1233 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || 1234 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) 1235 siba_sprom_set_bf_lo(dev, 1236 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); 1237 } 1238 #undef BWN_ISDEV 1239 } 1240 1241 static int 1242 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1243 { 1244 #define IS_RUNNING(ifp) \ 1245 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1246 struct bwn_softc *sc = ifp->if_softc; 1247 struct ieee80211com *ic = ifp->if_l2com; 1248 struct ifreq *ifr = (struct ifreq *)data; 1249 int error = 0, startall; 1250 1251 switch (cmd) { 1252 case SIOCSIFFLAGS: 1253 startall = 0; 1254 if (IS_RUNNING(ifp)) { 1255 bwn_update_promisc(ic); 1256 } else if (ifp->if_flags & IFF_UP) { 1257 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { 1258 bwn_init(sc); 1259 startall = 1; 1260 } 1261 } else 1262 bwn_stop(sc, 1); 1263 if (startall) 1264 ieee80211_start_all(ic); 1265 break; 1266 case SIOCGIFMEDIA: 1267 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1268 break; 1269 case SIOCGIFADDR: 1270 error = ether_ioctl(ifp, cmd, data); 1271 break; 1272 default: 1273 error = EINVAL; 1274 break; 1275 } 1276 return (error); 1277 } 1278 1279 static void 1280 bwn_start(struct ifnet *ifp) 1281 { 1282 struct bwn_softc *sc = ifp->if_softc; 1283 1284 BWN_LOCK(sc); 1285 bwn_start_locked(ifp); 1286 BWN_UNLOCK(sc); 1287 } 1288 1289 static void 1290 bwn_start_locked(struct ifnet *ifp) 1291 { 1292 struct bwn_softc *sc = ifp->if_softc; 1293 struct bwn_mac *mac = sc->sc_curmac; 1294 struct ieee80211_frame *wh; 1295 struct ieee80211_node *ni; 1296 struct ieee80211_key *k; 1297 struct mbuf *m; 1298 1299 BWN_ASSERT_LOCKED(sc); 1300 1301 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || 1302 mac->mac_status < BWN_MAC_STATUS_STARTED) 1303 return; 1304 1305 for (;;) { 1306 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ 1307 if (m == NULL) 1308 break; 1309 1310 if (bwn_tx_isfull(sc, m)) 1311 break; 1312 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1313 if (ni == NULL) { 1314 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1315 m_freem(m); 1316 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1317 continue; 1318 } 1319 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); 1320 wh = mtod(m, struct ieee80211_frame *); 1321 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1322 k = ieee80211_crypto_encap(ni, m); 1323 if (k == NULL) { 1324 ieee80211_free_node(ni); 1325 m_freem(m); 1326 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1327 continue; 1328 } 1329 } 1330 wh = NULL; /* Catch any invalid use */ 1331 1332 if (bwn_tx_start(sc, ni, m) != 0) { 1333 if (ni != NULL) 1334 ieee80211_free_node(ni); 1335 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1336 continue; 1337 } 1338 1339 sc->sc_watchdog_timer = 5; 1340 } 1341 } 1342 1343 static int 1344 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1345 { 1346 struct bwn_dma_ring *dr; 1347 struct bwn_mac *mac = sc->sc_curmac; 1348 struct bwn_pio_txqueue *tq; 1349 struct ifnet *ifp = sc->sc_ifp; 1350 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1351 1352 BWN_ASSERT_LOCKED(sc); 1353 1354 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1355 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1356 if (dr->dr_stop == 1 || 1357 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1358 dr->dr_stop = 1; 1359 goto full; 1360 } 1361 } else { 1362 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1363 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1364 pktlen > (tq->tq_size - tq->tq_used)) { 1365 tq->tq_stop = 1; 1366 goto full; 1367 } 1368 } 1369 return (0); 1370 full: 1371 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1372 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1373 return (1); 1374 } 1375 1376 static int 1377 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1378 { 1379 struct bwn_mac *mac = sc->sc_curmac; 1380 int error; 1381 1382 BWN_ASSERT_LOCKED(sc); 1383 1384 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1385 m_freem(m); 1386 return (ENXIO); 1387 } 1388 1389 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1390 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1391 if (error) { 1392 m_freem(m); 1393 return (error); 1394 } 1395 return (0); 1396 } 1397 1398 static int 1399 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1400 { 1401 struct bwn_pio_txpkt *tp; 1402 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1403 struct bwn_softc *sc = mac->mac_sc; 1404 struct bwn_txhdr txhdr; 1405 struct mbuf *m_new; 1406 uint32_t ctl32; 1407 int error; 1408 uint16_t ctl16; 1409 1410 BWN_ASSERT_LOCKED(sc); 1411 1412 /* XXX TODO send packets after DTIM */ 1413 1414 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1415 tp = TAILQ_FIRST(&tq->tq_pktlist); 1416 tp->tp_ni = ni; 1417 tp->tp_m = m; 1418 1419 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1420 if (error) { 1421 device_printf(sc->sc_dev, "tx fail\n"); 1422 return (error); 1423 } 1424 1425 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1426 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1427 tq->tq_free--; 1428 1429 if (siba_get_revid(sc->sc_dev) >= 8) { 1430 /* 1431 * XXX please removes m_defrag(9) 1432 */ 1433 m_new = m_defrag(m, M_NOWAIT); 1434 if (m_new == NULL) { 1435 device_printf(sc->sc_dev, 1436 "%s: can't defrag TX buffer\n", 1437 __func__); 1438 return (ENOBUFS); 1439 } 1440 if (m_new->m_next != NULL) 1441 device_printf(sc->sc_dev, 1442 "TODO: fragmented packets for PIO\n"); 1443 tp->tp_m = m_new; 1444 1445 /* send HEADER */ 1446 ctl32 = bwn_pio_write_multi_4(mac, tq, 1447 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1448 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1449 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1450 /* send BODY */ 1451 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1452 mtod(m_new, const void *), m_new->m_pkthdr.len); 1453 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1454 ctl32 | BWN_PIO8_TXCTL_EOF); 1455 } else { 1456 ctl16 = bwn_pio_write_multi_2(mac, tq, 1457 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1458 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1459 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1460 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1461 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1462 ctl16 | BWN_PIO_TXCTL_EOF); 1463 } 1464 1465 return (0); 1466 } 1467 1468 static struct bwn_pio_txqueue * 1469 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1470 { 1471 1472 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1473 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1474 1475 switch (prio) { 1476 case 0: 1477 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1478 case 1: 1479 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1480 case 2: 1481 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1482 case 3: 1483 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1484 } 1485 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1486 return (NULL); 1487 } 1488 1489 static int 1490 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1491 { 1492 #define BWN_GET_TXHDRCACHE(slot) \ 1493 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1494 struct bwn_dma *dma = &mac->mac_method.dma; 1495 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1496 struct bwn_dmadesc_generic *desc; 1497 struct bwn_dmadesc_meta *mt; 1498 struct bwn_softc *sc = mac->mac_sc; 1499 struct ifnet *ifp = sc->sc_ifp; 1500 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1501 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1502 1503 BWN_ASSERT_LOCKED(sc); 1504 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1505 1506 /* XXX send after DTIM */ 1507 1508 slot = bwn_dma_getslot(dr); 1509 dr->getdesc(dr, slot, &desc, &mt); 1510 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1511 ("%s:%d: fail", __func__, __LINE__)); 1512 1513 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1514 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1515 BWN_DMA_COOKIE(dr, slot)); 1516 if (error) 1517 goto fail; 1518 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1519 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1520 &mt->mt_paddr, BUS_DMA_NOWAIT); 1521 if (error) { 1522 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1523 __func__, error); 1524 goto fail; 1525 } 1526 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1527 BUS_DMASYNC_PREWRITE); 1528 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1529 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1530 BUS_DMASYNC_PREWRITE); 1531 1532 slot = bwn_dma_getslot(dr); 1533 dr->getdesc(dr, slot, &desc, &mt); 1534 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1535 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1536 mt->mt_m = m; 1537 mt->mt_ni = ni; 1538 1539 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1540 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1541 if (error && error != EFBIG) { 1542 if_printf(ifp, "%s: can't load TX buffer (1) %d\n", 1543 __func__, error); 1544 goto fail; 1545 } 1546 if (error) { /* error == EFBIG */ 1547 struct mbuf *m_new; 1548 1549 m_new = m_defrag(m, M_NOWAIT); 1550 if (m_new == NULL) { 1551 if_printf(ifp, "%s: can't defrag TX buffer\n", 1552 __func__); 1553 error = ENOBUFS; 1554 goto fail; 1555 } else { 1556 m = m_new; 1557 } 1558 1559 mt->mt_m = m; 1560 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1561 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1562 if (error) { 1563 if_printf(ifp, "%s: can't load TX buffer (2) %d\n", 1564 __func__, error); 1565 goto fail; 1566 } 1567 } 1568 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1569 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1570 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1571 BUS_DMASYNC_PREWRITE); 1572 1573 /* XXX send after DTIM */ 1574 1575 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1576 return (0); 1577 fail: 1578 dr->dr_curslot = backup[0]; 1579 dr->dr_usedslot = backup[1]; 1580 return (error); 1581 #undef BWN_GET_TXHDRCACHE 1582 } 1583 1584 static void 1585 bwn_watchdog(void *arg) 1586 { 1587 struct bwn_softc *sc = arg; 1588 struct ifnet *ifp = sc->sc_ifp; 1589 1590 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1591 if_printf(ifp, "device timeout\n"); 1592 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1593 } 1594 callout_schedule(&sc->sc_watchdog_ch, hz); 1595 } 1596 1597 static int 1598 bwn_attach_core(struct bwn_mac *mac) 1599 { 1600 struct bwn_softc *sc = mac->mac_sc; 1601 int error, have_bg = 0, have_a = 0; 1602 uint32_t high; 1603 1604 KASSERT(siba_get_revid(sc->sc_dev) >= 5, 1605 ("unsupported revision %d", siba_get_revid(sc->sc_dev))); 1606 1607 siba_powerup(sc->sc_dev, 0); 1608 1609 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 1610 bwn_reset_core(mac, 1611 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0); 1612 error = bwn_phy_getinfo(mac, high); 1613 if (error) 1614 goto fail; 1615 1616 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; 1617 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1618 if (siba_get_pci_device(sc->sc_dev) != 0x4312 && 1619 siba_get_pci_device(sc->sc_dev) != 0x4319 && 1620 siba_get_pci_device(sc->sc_dev) != 0x4324) { 1621 have_a = have_bg = 0; 1622 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1623 have_a = 1; 1624 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1625 mac->mac_phy.type == BWN_PHYTYPE_N || 1626 mac->mac_phy.type == BWN_PHYTYPE_LP) 1627 have_bg = 1; 1628 else 1629 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1630 mac->mac_phy.type)); 1631 } 1632 /* XXX turns off PHY A because it's not supported */ 1633 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1634 mac->mac_phy.type != BWN_PHYTYPE_N) { 1635 have_a = 0; 1636 have_bg = 1; 1637 } 1638 1639 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1640 mac->mac_phy.attach = bwn_phy_g_attach; 1641 mac->mac_phy.detach = bwn_phy_g_detach; 1642 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1643 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1644 mac->mac_phy.init = bwn_phy_g_init; 1645 mac->mac_phy.exit = bwn_phy_g_exit; 1646 mac->mac_phy.phy_read = bwn_phy_g_read; 1647 mac->mac_phy.phy_write = bwn_phy_g_write; 1648 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1649 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1650 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1651 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1652 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1653 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1654 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1655 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1656 mac->mac_phy.set_im = bwn_phy_g_im; 1657 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1658 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1659 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1660 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1661 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1662 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1663 mac->mac_phy.init = bwn_phy_lp_init; 1664 mac->mac_phy.phy_read = bwn_phy_lp_read; 1665 mac->mac_phy.phy_write = bwn_phy_lp_write; 1666 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1667 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1668 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1669 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1670 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1671 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1672 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1673 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1674 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1675 } else { 1676 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1677 mac->mac_phy.type); 1678 error = ENXIO; 1679 goto fail; 1680 } 1681 1682 mac->mac_phy.gmode = have_bg; 1683 if (mac->mac_phy.attach != NULL) { 1684 error = mac->mac_phy.attach(mac); 1685 if (error) { 1686 device_printf(sc->sc_dev, "failed\n"); 1687 goto fail; 1688 } 1689 } 1690 1691 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0); 1692 1693 error = bwn_chiptest(mac); 1694 if (error) 1695 goto fail; 1696 error = bwn_setup_channels(mac, have_bg, have_a); 1697 if (error) { 1698 device_printf(sc->sc_dev, "failed to setup channels\n"); 1699 goto fail; 1700 } 1701 1702 if (sc->sc_curmac == NULL) 1703 sc->sc_curmac = mac; 1704 1705 error = bwn_dma_attach(mac); 1706 if (error != 0) { 1707 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1708 goto fail; 1709 } 1710 1711 mac->mac_phy.switch_analog(mac, 0); 1712 1713 siba_dev_down(sc->sc_dev, 0); 1714 fail: 1715 siba_powerdown(sc->sc_dev); 1716 return (error); 1717 } 1718 1719 static void 1720 bwn_reset_core(struct bwn_mac *mac, uint32_t flags) 1721 { 1722 struct bwn_softc *sc = mac->mac_sc; 1723 uint32_t low, ctl; 1724 1725 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET); 1726 1727 siba_dev_up(sc->sc_dev, flags); 1728 DELAY(2000); 1729 1730 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) & 1731 ~BWN_TGSLOW_PHYRESET; 1732 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low); 1733 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1734 DELAY(1000); 1735 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC); 1736 siba_read_4(sc->sc_dev, SIBA_TGSLOW); 1737 DELAY(1000); 1738 1739 if (mac->mac_phy.switch_analog != NULL) 1740 mac->mac_phy.switch_analog(mac, 1); 1741 1742 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1743 if (flags & BWN_TGSLOW_SUPPORT_G) 1744 ctl |= BWN_MACCTL_GMODE; 1745 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1746 } 1747 1748 static int 1749 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh) 1750 { 1751 struct bwn_phy *phy = &mac->mac_phy; 1752 struct bwn_softc *sc = mac->mac_sc; 1753 uint32_t tmp; 1754 1755 /* PHY */ 1756 tmp = BWN_READ_2(mac, BWN_PHYVER); 1757 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; 1758 phy->rf_on = 1; 1759 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1760 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1761 phy->rev = (tmp & BWN_PHYVER_VERSION); 1762 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1763 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1764 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1765 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1766 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) || 1767 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1768 goto unsupphy; 1769 1770 /* RADIO */ 1771 if (siba_get_chipid(sc->sc_dev) == 0x4317) { 1772 if (siba_get_chiprev(sc->sc_dev) == 0) 1773 tmp = 0x3205017f; 1774 else if (siba_get_chiprev(sc->sc_dev) == 1) 1775 tmp = 0x4205017f; 1776 else 1777 tmp = 0x5205017f; 1778 } else { 1779 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1780 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1781 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1782 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1783 } 1784 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1785 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1786 phy->rf_manuf = (tmp & 0x00000fff); 1787 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1788 goto unsupradio; 1789 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1790 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1791 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1792 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1793 (phy->type == BWN_PHYTYPE_N && 1794 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1795 (phy->type == BWN_PHYTYPE_LP && 1796 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1797 goto unsupradio; 1798 1799 return (0); 1800 unsupphy: 1801 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1802 "analog %#x)\n", 1803 phy->type, phy->rev, phy->analog); 1804 return (ENXIO); 1805 unsupradio: 1806 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1807 "rev %#x)\n", 1808 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1809 return (ENXIO); 1810 } 1811 1812 static int 1813 bwn_chiptest(struct bwn_mac *mac) 1814 { 1815 #define TESTVAL0 0x55aaaa55 1816 #define TESTVAL1 0xaa5555aa 1817 struct bwn_softc *sc = mac->mac_sc; 1818 uint32_t v, backup; 1819 1820 BWN_LOCK(sc); 1821 1822 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1823 1824 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1825 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1826 goto error; 1827 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1828 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1829 goto error; 1830 1831 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1832 1833 if ((siba_get_revid(sc->sc_dev) >= 3) && 1834 (siba_get_revid(sc->sc_dev) <= 10)) { 1835 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1836 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1837 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1838 goto error; 1839 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1840 goto error; 1841 } 1842 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1843 1844 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1845 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1846 goto error; 1847 1848 BWN_UNLOCK(sc); 1849 return (0); 1850 error: 1851 BWN_UNLOCK(sc); 1852 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1853 return (ENODEV); 1854 } 1855 1856 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G) 1857 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A) 1858 1859 static int 1860 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1861 { 1862 struct bwn_softc *sc = mac->mac_sc; 1863 struct ifnet *ifp = sc->sc_ifp; 1864 struct ieee80211com *ic = ifp->if_l2com; 1865 1866 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1867 ic->ic_nchans = 0; 1868 1869 if (have_bg) 1870 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1871 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G); 1872 if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1873 if (have_a) 1874 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1875 &ic->ic_nchans, &bwn_chantable_n, 1876 IEEE80211_CHAN_HTA); 1877 } else { 1878 if (have_a) 1879 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1880 &ic->ic_nchans, &bwn_chantable_a, 1881 IEEE80211_CHAN_A); 1882 } 1883 1884 mac->mac_phy.supports_2ghz = have_bg; 1885 mac->mac_phy.supports_5ghz = have_a; 1886 1887 return (ic->ic_nchans == 0 ? ENXIO : 0); 1888 } 1889 1890 static uint32_t 1891 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1892 { 1893 uint32_t ret; 1894 1895 BWN_ASSERT_LOCKED(mac->mac_sc); 1896 1897 if (way == BWN_SHARED) { 1898 KASSERT((offset & 0x0001) == 0, 1899 ("%s:%d warn", __func__, __LINE__)); 1900 if (offset & 0x0003) { 1901 bwn_shm_ctlword(mac, way, offset >> 2); 1902 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1903 ret <<= 16; 1904 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1905 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1906 goto out; 1907 } 1908 offset >>= 2; 1909 } 1910 bwn_shm_ctlword(mac, way, offset); 1911 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1912 out: 1913 return (ret); 1914 } 1915 1916 static uint16_t 1917 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1918 { 1919 uint16_t ret; 1920 1921 BWN_ASSERT_LOCKED(mac->mac_sc); 1922 1923 if (way == BWN_SHARED) { 1924 KASSERT((offset & 0x0001) == 0, 1925 ("%s:%d warn", __func__, __LINE__)); 1926 if (offset & 0x0003) { 1927 bwn_shm_ctlword(mac, way, offset >> 2); 1928 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1929 goto out; 1930 } 1931 offset >>= 2; 1932 } 1933 bwn_shm_ctlword(mac, way, offset); 1934 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1935 out: 1936 1937 return (ret); 1938 } 1939 1940 static void 1941 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1942 uint16_t offset) 1943 { 1944 uint32_t control; 1945 1946 control = way; 1947 control <<= 16; 1948 control |= offset; 1949 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1950 } 1951 1952 static void 1953 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1954 uint32_t value) 1955 { 1956 BWN_ASSERT_LOCKED(mac->mac_sc); 1957 1958 if (way == BWN_SHARED) { 1959 KASSERT((offset & 0x0001) == 0, 1960 ("%s:%d warn", __func__, __LINE__)); 1961 if (offset & 0x0003) { 1962 bwn_shm_ctlword(mac, way, offset >> 2); 1963 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1964 (value >> 16) & 0xffff); 1965 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1966 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1967 return; 1968 } 1969 offset >>= 2; 1970 } 1971 bwn_shm_ctlword(mac, way, offset); 1972 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1973 } 1974 1975 static void 1976 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1977 uint16_t value) 1978 { 1979 BWN_ASSERT_LOCKED(mac->mac_sc); 1980 1981 if (way == BWN_SHARED) { 1982 KASSERT((offset & 0x0001) == 0, 1983 ("%s:%d warn", __func__, __LINE__)); 1984 if (offset & 0x0003) { 1985 bwn_shm_ctlword(mac, way, offset >> 2); 1986 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1987 return; 1988 } 1989 offset >>= 2; 1990 } 1991 bwn_shm_ctlword(mac, way, offset); 1992 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1993 } 1994 1995 static void 1996 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, 1997 int txpow) 1998 { 1999 2000 c->ic_freq = freq; 2001 c->ic_flags = flags; 2002 c->ic_ieee = ieee; 2003 c->ic_minpower = 0; 2004 c->ic_maxpower = 2 * txpow; 2005 c->ic_maxregpower = txpow; 2006 } 2007 2008 static void 2009 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 2010 const struct bwn_channelinfo *ci, int flags) 2011 { 2012 struct ieee80211_channel *c; 2013 int i; 2014 2015 c = &chans[*nchans]; 2016 2017 for (i = 0; i < ci->nchannels; i++) { 2018 const struct bwn_channel *hc; 2019 2020 hc = &ci->channels[i]; 2021 if (*nchans >= maxchans) 2022 break; 2023 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 2024 c++, (*nchans)++; 2025 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 2026 /* g channel have a separate b-only entry */ 2027 if (*nchans >= maxchans) 2028 break; 2029 c[0] = c[-1]; 2030 c[-1].ic_flags = IEEE80211_CHAN_B; 2031 c++, (*nchans)++; 2032 } 2033 if (flags == IEEE80211_CHAN_HTG) { 2034 /* HT g channel have a separate g-only entry */ 2035 if (*nchans >= maxchans) 2036 break; 2037 c[-1].ic_flags = IEEE80211_CHAN_G; 2038 c[0] = c[-1]; 2039 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2040 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2041 c++, (*nchans)++; 2042 } 2043 if (flags == IEEE80211_CHAN_HTA) { 2044 /* HT a channel have a separate a-only entry */ 2045 if (*nchans >= maxchans) 2046 break; 2047 c[-1].ic_flags = IEEE80211_CHAN_A; 2048 c[0] = c[-1]; 2049 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 2050 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 2051 c++, (*nchans)++; 2052 } 2053 } 2054 } 2055 2056 static int 2057 bwn_phy_g_attach(struct bwn_mac *mac) 2058 { 2059 struct bwn_softc *sc = mac->mac_sc; 2060 struct bwn_phy *phy = &mac->mac_phy; 2061 struct bwn_phy_g *pg = &phy->phy_g; 2062 unsigned int i; 2063 int16_t pab0, pab1, pab2; 2064 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 2065 int8_t bg; 2066 2067 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev); 2068 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev); 2069 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev); 2070 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev); 2071 2072 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050)) 2073 device_printf(sc->sc_dev, "not supported anymore\n"); 2074 2075 pg->pg_flags = 0; 2076 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 2077 pab2 == -1) { 2078 pg->pg_idletssi = 52; 2079 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 2080 return (0); 2081 } 2082 2083 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 2084 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 2085 if (pg->pg_tssi2dbm == NULL) { 2086 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 2087 return (ENOMEM); 2088 } 2089 for (i = 0; i < 64; i++) { 2090 int32_t m1, m2, f, q, delta; 2091 int8_t j = 0; 2092 2093 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 2094 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 2095 f = 256; 2096 2097 do { 2098 if (j > 15) { 2099 device_printf(sc->sc_dev, 2100 "failed to generate tssi2dBm\n"); 2101 free(pg->pg_tssi2dbm, M_DEVBUF); 2102 return (ENOMEM); 2103 } 2104 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 2105 f, 2048); 2106 delta = abs(q - f); 2107 f = q; 2108 j++; 2109 } while (delta >= 2); 2110 2111 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 2112 128); 2113 } 2114 2115 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 2116 return (0); 2117 } 2118 2119 static void 2120 bwn_phy_g_detach(struct bwn_mac *mac) 2121 { 2122 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2123 2124 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 2125 free(pg->pg_tssi2dbm, M_DEVBUF); 2126 pg->pg_tssi2dbm = NULL; 2127 } 2128 pg->pg_flags = 0; 2129 } 2130 2131 static void 2132 bwn_phy_g_init_pre(struct bwn_mac *mac) 2133 { 2134 struct bwn_phy *phy = &mac->mac_phy; 2135 struct bwn_phy_g *pg = &phy->phy_g; 2136 void *tssi2dbm; 2137 int idletssi; 2138 unsigned int i; 2139 2140 tssi2dbm = pg->pg_tssi2dbm; 2141 idletssi = pg->pg_idletssi; 2142 2143 memset(pg, 0, sizeof(*pg)); 2144 2145 pg->pg_tssi2dbm = tssi2dbm; 2146 pg->pg_idletssi = idletssi; 2147 2148 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 2149 2150 for (i = 0; i < N(pg->pg_nrssi); i++) 2151 pg->pg_nrssi[i] = -1000; 2152 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 2153 pg->pg_nrssi_lt[i] = i; 2154 pg->pg_lofcal = 0xffff; 2155 pg->pg_initval = 0xffff; 2156 pg->pg_immode = BWN_IMMODE_NONE; 2157 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 2158 pg->pg_avgtssi = 0xff; 2159 2160 pg->pg_loctl.tx_bias = 0xff; 2161 TAILQ_INIT(&pg->pg_loctl.calib_list); 2162 } 2163 2164 static int 2165 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 2166 { 2167 struct bwn_phy *phy = &mac->mac_phy; 2168 struct bwn_phy_g *pg = &phy->phy_g; 2169 struct bwn_softc *sc = mac->mac_sc; 2170 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2171 static const struct bwn_rfatt rfatt0[] = { 2172 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 2173 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 2174 { 3, 1 }, { 4, 1 } 2175 }; 2176 static const struct bwn_rfatt rfatt1[] = { 2177 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 2178 { 14, 1 } 2179 }; 2180 static const struct bwn_rfatt rfatt2[] = { 2181 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 2182 { 9, 1 } 2183 }; 2184 static const struct bwn_bbatt bbatt_0[] = { 2185 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 2186 }; 2187 2188 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 2189 2190 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 2191 pg->pg_bbatt.att = 0; 2192 else 2193 pg->pg_bbatt.att = 2; 2194 2195 /* prepare Radio Attenuation */ 2196 pg->pg_rfatt.padmix = 0; 2197 2198 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 2199 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) { 2200 if (siba_get_pci_revid(sc->sc_dev) < 0x43) { 2201 pg->pg_rfatt.att = 2; 2202 goto done; 2203 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) { 2204 pg->pg_rfatt.att = 3; 2205 goto done; 2206 } 2207 } 2208 2209 if (phy->type == BWN_PHYTYPE_A) { 2210 pg->pg_rfatt.att = 0x60; 2211 goto done; 2212 } 2213 2214 switch (phy->rf_ver) { 2215 case 0x2050: 2216 switch (phy->rf_rev) { 2217 case 0: 2218 pg->pg_rfatt.att = 5; 2219 goto done; 2220 case 1: 2221 if (phy->type == BWN_PHYTYPE_G) { 2222 if (siba_get_pci_subvendor(sc->sc_dev) == 2223 SIBA_BOARDVENDOR_BCM && 2224 siba_get_pci_subdevice(sc->sc_dev) == 2225 SIBA_BOARD_BCM4309G && 2226 siba_get_pci_revid(sc->sc_dev) >= 30) 2227 pg->pg_rfatt.att = 3; 2228 else if (siba_get_pci_subvendor(sc->sc_dev) == 2229 SIBA_BOARDVENDOR_BCM && 2230 siba_get_pci_subdevice(sc->sc_dev) == 2231 SIBA_BOARD_BU4306) 2232 pg->pg_rfatt.att = 3; 2233 else 2234 pg->pg_rfatt.att = 1; 2235 } else { 2236 if (siba_get_pci_subvendor(sc->sc_dev) == 2237 SIBA_BOARDVENDOR_BCM && 2238 siba_get_pci_subdevice(sc->sc_dev) == 2239 SIBA_BOARD_BCM4309G && 2240 siba_get_pci_revid(sc->sc_dev) >= 30) 2241 pg->pg_rfatt.att = 7; 2242 else 2243 pg->pg_rfatt.att = 6; 2244 } 2245 goto done; 2246 case 2: 2247 if (phy->type == BWN_PHYTYPE_G) { 2248 if (siba_get_pci_subvendor(sc->sc_dev) == 2249 SIBA_BOARDVENDOR_BCM && 2250 siba_get_pci_subdevice(sc->sc_dev) == 2251 SIBA_BOARD_BCM4309G && 2252 siba_get_pci_revid(sc->sc_dev) >= 30) 2253 pg->pg_rfatt.att = 3; 2254 else if (siba_get_pci_subvendor(sc->sc_dev) == 2255 SIBA_BOARDVENDOR_BCM && 2256 siba_get_pci_subdevice(sc->sc_dev) == 2257 SIBA_BOARD_BU4306) 2258 pg->pg_rfatt.att = 5; 2259 else if (siba_get_chipid(sc->sc_dev) == 0x4320) 2260 pg->pg_rfatt.att = 4; 2261 else 2262 pg->pg_rfatt.att = 3; 2263 } else 2264 pg->pg_rfatt.att = 6; 2265 goto done; 2266 case 3: 2267 pg->pg_rfatt.att = 5; 2268 goto done; 2269 case 4: 2270 case 5: 2271 pg->pg_rfatt.att = 1; 2272 goto done; 2273 case 6: 2274 case 7: 2275 pg->pg_rfatt.att = 5; 2276 goto done; 2277 case 8: 2278 pg->pg_rfatt.att = 0xa; 2279 pg->pg_rfatt.padmix = 1; 2280 goto done; 2281 case 9: 2282 default: 2283 pg->pg_rfatt.att = 5; 2284 goto done; 2285 } 2286 break; 2287 case 0x2053: 2288 switch (phy->rf_rev) { 2289 case 1: 2290 pg->pg_rfatt.att = 6; 2291 goto done; 2292 } 2293 break; 2294 } 2295 pg->pg_rfatt.att = 5; 2296 done: 2297 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 2298 2299 if (!bwn_has_hwpctl(mac)) { 2300 lo->rfatt.array = rfatt0; 2301 lo->rfatt.len = N(rfatt0); 2302 lo->rfatt.min = 0; 2303 lo->rfatt.max = 9; 2304 goto genbbatt; 2305 } 2306 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 2307 lo->rfatt.array = rfatt1; 2308 lo->rfatt.len = N(rfatt1); 2309 lo->rfatt.min = 0; 2310 lo->rfatt.max = 14; 2311 goto genbbatt; 2312 } 2313 lo->rfatt.array = rfatt2; 2314 lo->rfatt.len = N(rfatt2); 2315 lo->rfatt.min = 0; 2316 lo->rfatt.max = 9; 2317 genbbatt: 2318 lo->bbatt.array = bbatt_0; 2319 lo->bbatt.len = N(bbatt_0); 2320 lo->bbatt.min = 0; 2321 lo->bbatt.max = 8; 2322 2323 BWN_READ_4(mac, BWN_MACCTL); 2324 if (phy->rev == 1) { 2325 phy->gmode = 0; 2326 bwn_reset_core(mac, 0); 2327 bwn_phy_g_init_sub(mac); 2328 phy->gmode = 1; 2329 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G); 2330 } 2331 return (0); 2332 } 2333 2334 static uint16_t 2335 bwn_phy_g_txctl(struct bwn_mac *mac) 2336 { 2337 struct bwn_phy *phy = &mac->mac_phy; 2338 2339 if (phy->rf_ver != 0x2050) 2340 return (0); 2341 if (phy->rf_rev == 1) 2342 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 2343 if (phy->rf_rev < 6) 2344 return (BWN_TXCTL_PA2DB); 2345 if (phy->rf_rev == 8) 2346 return (BWN_TXCTL_TXMIX); 2347 return (0); 2348 } 2349 2350 static int 2351 bwn_phy_g_init(struct bwn_mac *mac) 2352 { 2353 2354 bwn_phy_g_init_sub(mac); 2355 return (0); 2356 } 2357 2358 static void 2359 bwn_phy_g_exit(struct bwn_mac *mac) 2360 { 2361 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2362 struct bwn_lo_calib *cal, *tmp; 2363 2364 if (lo == NULL) 2365 return; 2366 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2367 TAILQ_REMOVE(&lo->calib_list, cal, list); 2368 free(cal, M_DEVBUF); 2369 } 2370 } 2371 2372 static uint16_t 2373 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 2374 { 2375 2376 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2377 return (BWN_READ_2(mac, BWN_PHYDATA)); 2378 } 2379 2380 static void 2381 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2382 { 2383 2384 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 2385 BWN_WRITE_2(mac, BWN_PHYDATA, value); 2386 } 2387 2388 static uint16_t 2389 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 2390 { 2391 2392 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2393 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 2394 return (BWN_READ_2(mac, BWN_RFDATALO)); 2395 } 2396 2397 static void 2398 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 2399 { 2400 2401 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 2402 BWN_WRITE_2(mac, BWN_RFCTL, reg); 2403 BWN_WRITE_2(mac, BWN_RFDATALO, value); 2404 } 2405 2406 static int 2407 bwn_phy_g_hwpctl(struct bwn_mac *mac) 2408 { 2409 2410 return (mac->mac_phy.rev >= 6); 2411 } 2412 2413 static void 2414 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 2415 { 2416 struct bwn_phy *phy = &mac->mac_phy; 2417 struct bwn_phy_g *pg = &phy->phy_g; 2418 unsigned int channel; 2419 uint16_t rfover, rfoverval; 2420 2421 if (on) { 2422 if (phy->rf_on) 2423 return; 2424 2425 BWN_PHY_WRITE(mac, 0x15, 0x8000); 2426 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 2427 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 2428 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 2429 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 2430 pg->pg_radioctx_over); 2431 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 2432 pg->pg_radioctx_overval); 2433 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 2434 } 2435 channel = phy->chan; 2436 bwn_phy_g_switch_chan(mac, 6, 1); 2437 bwn_phy_g_switch_chan(mac, channel, 0); 2438 return; 2439 } 2440 2441 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2442 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2443 pg->pg_radioctx_over = rfover; 2444 pg->pg_radioctx_overval = rfoverval; 2445 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 2446 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 2447 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 2448 } 2449 2450 static int 2451 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 2452 { 2453 2454 if ((newchan < 1) || (newchan > 14)) 2455 return (EINVAL); 2456 bwn_phy_g_switch_chan(mac, newchan, 0); 2457 2458 return (0); 2459 } 2460 2461 static uint32_t 2462 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 2463 { 2464 2465 return (1); 2466 } 2467 2468 static void 2469 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 2470 { 2471 struct bwn_phy *phy = &mac->mac_phy; 2472 uint64_t hf; 2473 int autodiv = 0; 2474 uint16_t tmp; 2475 2476 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 2477 autodiv = 1; 2478 2479 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 2480 bwn_hf_write(mac, hf); 2481 2482 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 2483 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 2484 ((autodiv ? BWN_ANTAUTO1 : antenna) 2485 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 2486 2487 if (autodiv) { 2488 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 2489 if (antenna == BWN_ANTAUTO1) 2490 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 2491 else 2492 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 2493 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 2494 } 2495 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 2496 if (autodiv) 2497 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 2498 else 2499 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 2500 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 2501 if (phy->rev >= 2) { 2502 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 2503 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 2504 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 2505 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 2506 0x15); 2507 if (phy->rev == 2) 2508 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 2509 else 2510 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 2511 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 2512 8); 2513 } 2514 if (phy->rev >= 6) 2515 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 2516 2517 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 2518 bwn_hf_write(mac, hf); 2519 } 2520 2521 static int 2522 bwn_phy_g_im(struct bwn_mac *mac, int mode) 2523 { 2524 struct bwn_phy *phy = &mac->mac_phy; 2525 struct bwn_phy_g *pg = &phy->phy_g; 2526 2527 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2528 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 2529 2530 if (phy->rev == 0 || !phy->gmode) 2531 return (ENODEV); 2532 2533 pg->pg_aci_wlan_automatic = 0; 2534 return (0); 2535 } 2536 2537 static int 2538 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 2539 { 2540 struct bwn_phy *phy = &mac->mac_phy; 2541 struct bwn_phy_g *pg = &phy->phy_g; 2542 struct bwn_softc *sc = mac->mac_sc; 2543 unsigned int tssi; 2544 int cck, ofdm; 2545 int power; 2546 int rfatt, bbatt; 2547 unsigned int max; 2548 2549 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2550 2551 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 2552 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 2553 if (cck < 0 && ofdm < 0) { 2554 if (ignore_tssi == 0) 2555 return (BWN_TXPWR_RES_DONE); 2556 cck = 0; 2557 ofdm = 0; 2558 } 2559 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 2560 if (pg->pg_avgtssi != 0xff) 2561 tssi = (tssi + pg->pg_avgtssi) / 2; 2562 pg->pg_avgtssi = tssi; 2563 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 2564 2565 max = siba_sprom_get_maxpwr_bg(sc->sc_dev); 2566 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 2567 max -= 3; 2568 if (max >= 120) { 2569 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 2570 max = 80; 2571 siba_sprom_set_maxpwr_bg(sc->sc_dev, max); 2572 } 2573 2574 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 2575 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 2576 tssi, 0x00), 0x3f)]); 2577 if (power == 0) 2578 return (BWN_TXPWR_RES_DONE); 2579 2580 rfatt = -((power + 7) / 8); 2581 bbatt = (-(power / 2)) - (4 * rfatt); 2582 if ((rfatt == 0) && (bbatt == 0)) 2583 return (BWN_TXPWR_RES_DONE); 2584 pg->pg_bbatt_delta = bbatt; 2585 pg->pg_rfatt_delta = rfatt; 2586 return (BWN_TXPWR_RES_NEED_ADJUST); 2587 } 2588 2589 static void 2590 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 2591 { 2592 struct bwn_phy *phy = &mac->mac_phy; 2593 struct bwn_phy_g *pg = &phy->phy_g; 2594 struct bwn_softc *sc = mac->mac_sc; 2595 int rfatt, bbatt; 2596 uint8_t txctl; 2597 2598 bwn_mac_suspend(mac); 2599 2600 BWN_ASSERT_LOCKED(sc); 2601 2602 bbatt = pg->pg_bbatt.att; 2603 bbatt += pg->pg_bbatt_delta; 2604 rfatt = pg->pg_rfatt.att; 2605 rfatt += pg->pg_rfatt_delta; 2606 2607 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2608 txctl = pg->pg_txctl; 2609 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 2610 if (rfatt <= 1) { 2611 if (txctl == 0) { 2612 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 2613 rfatt += 2; 2614 bbatt += 2; 2615 } else if (siba_sprom_get_bf_lo(sc->sc_dev) & 2616 BWN_BFL_PACTRL) { 2617 bbatt += 4 * (rfatt - 2); 2618 rfatt = 2; 2619 } 2620 } else if (rfatt > 4 && txctl) { 2621 txctl = 0; 2622 if (bbatt < 3) { 2623 rfatt -= 3; 2624 bbatt += 2; 2625 } else { 2626 rfatt -= 2; 2627 bbatt -= 2; 2628 } 2629 } 2630 } 2631 pg->pg_txctl = txctl; 2632 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 2633 pg->pg_rfatt.att = rfatt; 2634 pg->pg_bbatt.att = bbatt; 2635 2636 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 2637 2638 bwn_phy_lock(mac); 2639 bwn_rf_lock(mac); 2640 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 2641 pg->pg_txctl); 2642 bwn_rf_unlock(mac); 2643 bwn_phy_unlock(mac); 2644 2645 bwn_mac_enable(mac); 2646 } 2647 2648 static void 2649 bwn_phy_g_task_15s(struct bwn_mac *mac) 2650 { 2651 struct bwn_phy *phy = &mac->mac_phy; 2652 struct bwn_phy_g *pg = &phy->phy_g; 2653 struct bwn_softc *sc = mac->mac_sc; 2654 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2655 unsigned long expire, now; 2656 struct bwn_lo_calib *cal, *tmp; 2657 uint8_t expired = 0; 2658 2659 bwn_mac_suspend(mac); 2660 2661 if (lo == NULL) 2662 goto fail; 2663 2664 BWN_GETTIME(now); 2665 if (bwn_has_hwpctl(mac)) { 2666 expire = now - BWN_LO_PWRVEC_EXPIRE; 2667 if (time_before(lo->pwr_vec_read_time, expire)) { 2668 bwn_lo_get_powervector(mac); 2669 bwn_phy_g_dc_lookup_init(mac, 0); 2670 } 2671 goto fail; 2672 } 2673 2674 expire = now - BWN_LO_CALIB_EXPIRE; 2675 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 2676 if (!time_before(cal->calib_time, expire)) 2677 continue; 2678 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 2679 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 2680 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 2681 expired = 1; 2682 } 2683 2684 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 2685 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 2686 cal->ctl.i, cal->ctl.q); 2687 2688 TAILQ_REMOVE(&lo->calib_list, cal, list); 2689 free(cal, M_DEVBUF); 2690 } 2691 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 2692 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 2693 &pg->pg_rfatt); 2694 if (cal == NULL) { 2695 device_printf(sc->sc_dev, 2696 "failed to recalibrate LO\n"); 2697 goto fail; 2698 } 2699 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 2700 bwn_lo_write(mac, &cal->ctl); 2701 } 2702 2703 fail: 2704 bwn_mac_enable(mac); 2705 } 2706 2707 static void 2708 bwn_phy_g_task_60s(struct bwn_mac *mac) 2709 { 2710 struct bwn_phy *phy = &mac->mac_phy; 2711 struct bwn_softc *sc = mac->mac_sc; 2712 uint8_t old = phy->chan; 2713 2714 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) 2715 return; 2716 2717 bwn_mac_suspend(mac); 2718 bwn_nrssi_slope_11g(mac); 2719 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 2720 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 2721 bwn_switch_channel(mac, old); 2722 } 2723 bwn_mac_enable(mac); 2724 } 2725 2726 static void 2727 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 2728 { 2729 2730 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 2731 } 2732 2733 static int 2734 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2735 const struct ieee80211_bpf_params *params) 2736 { 2737 struct ieee80211com *ic = ni->ni_ic; 2738 struct ifnet *ifp = ic->ic_ifp; 2739 struct bwn_softc *sc = ifp->if_softc; 2740 struct bwn_mac *mac = sc->sc_curmac; 2741 2742 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 2743 mac->mac_status < BWN_MAC_STATUS_STARTED) { 2744 ieee80211_free_node(ni); 2745 m_freem(m); 2746 return (ENETDOWN); 2747 } 2748 2749 BWN_LOCK(sc); 2750 if (bwn_tx_isfull(sc, m)) { 2751 ieee80211_free_node(ni); 2752 m_freem(m); 2753 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 2754 BWN_UNLOCK(sc); 2755 return (ENOBUFS); 2756 } 2757 2758 if (bwn_tx_start(sc, ni, m) != 0) { 2759 if (ni != NULL) 2760 ieee80211_free_node(ni); 2761 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 2762 } 2763 sc->sc_watchdog_timer = 5; 2764 BWN_UNLOCK(sc); 2765 return (0); 2766 } 2767 2768 /* 2769 * Callback from the 802.11 layer to update the slot time 2770 * based on the current setting. We use it to notify the 2771 * firmware of ERP changes and the f/w takes care of things 2772 * like slot time and preamble. 2773 */ 2774 static void 2775 bwn_updateslot(struct ieee80211com *ic) 2776 { 2777 struct bwn_softc *sc = ic->ic_softc; 2778 struct bwn_mac *mac; 2779 2780 BWN_LOCK(sc); 2781 if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) { 2782 mac = (struct bwn_mac *)sc->sc_curmac; 2783 bwn_set_slot_time(mac, 2784 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); 2785 } 2786 BWN_UNLOCK(sc); 2787 } 2788 2789 /* 2790 * Callback from the 802.11 layer after a promiscuous mode change. 2791 * Note this interface does not check the operating mode as this 2792 * is an internal callback and we are expected to honor the current 2793 * state (e.g. this is used for setting the interface in promiscuous 2794 * mode when operating in hostap mode to do ACS). 2795 */ 2796 static void 2797 bwn_update_promisc(struct ieee80211com *ic) 2798 { 2799 struct bwn_softc *sc = ic->ic_softc; 2800 struct bwn_mac *mac = sc->sc_curmac; 2801 2802 BWN_LOCK(sc); 2803 mac = sc->sc_curmac; 2804 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2805 if (ic->ic_ifp->if_flags & IFF_PROMISC) 2806 sc->sc_filters |= BWN_MACCTL_PROMISC; 2807 else 2808 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 2809 bwn_set_opmode(mac); 2810 } 2811 BWN_UNLOCK(sc); 2812 } 2813 2814 /* 2815 * Callback from the 802.11 layer to update WME parameters. 2816 */ 2817 static int 2818 bwn_wme_update(struct ieee80211com *ic) 2819 { 2820 struct bwn_softc *sc = ic->ic_ifp->if_softc; 2821 struct bwn_mac *mac = sc->sc_curmac; 2822 struct wmeParams *wmep; 2823 int i; 2824 2825 BWN_LOCK(sc); 2826 mac = sc->sc_curmac; 2827 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2828 bwn_mac_suspend(mac); 2829 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2830 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i]; 2831 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 2832 } 2833 bwn_mac_enable(mac); 2834 } 2835 BWN_UNLOCK(sc); 2836 return (0); 2837 } 2838 2839 static void 2840 bwn_scan_start(struct ieee80211com *ic) 2841 { 2842 struct ifnet *ifp = ic->ic_ifp; 2843 struct bwn_softc *sc = ifp->if_softc; 2844 struct bwn_mac *mac; 2845 2846 BWN_LOCK(sc); 2847 mac = sc->sc_curmac; 2848 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2849 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 2850 bwn_set_opmode(mac); 2851 /* disable CFP update during scan */ 2852 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 2853 } 2854 BWN_UNLOCK(sc); 2855 } 2856 2857 static void 2858 bwn_scan_end(struct ieee80211com *ic) 2859 { 2860 struct ifnet *ifp = ic->ic_ifp; 2861 struct bwn_softc *sc = ifp->if_softc; 2862 struct bwn_mac *mac; 2863 2864 BWN_LOCK(sc); 2865 mac = sc->sc_curmac; 2866 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 2867 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 2868 bwn_set_opmode(mac); 2869 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 2870 } 2871 BWN_UNLOCK(sc); 2872 } 2873 2874 static void 2875 bwn_set_channel(struct ieee80211com *ic) 2876 { 2877 struct ifnet *ifp = ic->ic_ifp; 2878 struct bwn_softc *sc = ifp->if_softc; 2879 struct bwn_mac *mac = sc->sc_curmac; 2880 struct bwn_phy *phy = &mac->mac_phy; 2881 int chan, error; 2882 2883 BWN_LOCK(sc); 2884 2885 error = bwn_switch_band(sc, ic->ic_curchan); 2886 if (error) 2887 goto fail; 2888 bwn_mac_suspend(mac); 2889 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2890 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2891 if (chan != phy->chan) 2892 bwn_switch_channel(mac, chan); 2893 2894 /* TX power level */ 2895 if (ic->ic_curchan->ic_maxpower != 0 && 2896 ic->ic_curchan->ic_maxpower != phy->txpower) { 2897 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 2898 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 2899 BWN_TXPWR_IGNORE_TSSI); 2900 } 2901 2902 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2903 if (phy->set_antenna) 2904 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2905 2906 if (sc->sc_rf_enabled != phy->rf_on) { 2907 if (sc->sc_rf_enabled) { 2908 bwn_rf_turnon(mac); 2909 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 2910 device_printf(sc->sc_dev, 2911 "please turn on the RF switch\n"); 2912 } else 2913 bwn_rf_turnoff(mac); 2914 } 2915 2916 bwn_mac_enable(mac); 2917 2918 fail: 2919 /* 2920 * Setup radio tap channel freq and flags 2921 */ 2922 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2923 htole16(ic->ic_curchan->ic_freq); 2924 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2925 htole16(ic->ic_curchan->ic_flags & 0xffff); 2926 2927 BWN_UNLOCK(sc); 2928 } 2929 2930 static struct ieee80211vap * 2931 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2932 enum ieee80211_opmode opmode, int flags, 2933 const uint8_t bssid[IEEE80211_ADDR_LEN], 2934 const uint8_t mac0[IEEE80211_ADDR_LEN]) 2935 { 2936 struct ifnet *ifp = ic->ic_ifp; 2937 struct bwn_softc *sc = ifp->if_softc; 2938 struct ieee80211vap *vap; 2939 struct bwn_vap *bvp; 2940 uint8_t mac[IEEE80211_ADDR_LEN]; 2941 2942 IEEE80211_ADDR_COPY(mac, mac0); 2943 switch (opmode) { 2944 case IEEE80211_M_HOSTAP: 2945 case IEEE80211_M_MBSS: 2946 case IEEE80211_M_STA: 2947 case IEEE80211_M_WDS: 2948 case IEEE80211_M_MONITOR: 2949 case IEEE80211_M_IBSS: 2950 case IEEE80211_M_AHDEMO: 2951 break; 2952 default: 2953 return (NULL); 2954 } 2955 2956 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); 2957 2958 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), 2959 M_80211_VAP, M_NOWAIT | M_ZERO); 2960 if (bvp == NULL) { 2961 device_printf(sc->sc_dev, "failed to allocate a buffer\n"); 2962 return (NULL); 2963 } 2964 vap = &bvp->bv_vap; 2965 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 2966 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 2967 /* override with driver methods */ 2968 bvp->bv_newstate = vap->iv_newstate; 2969 vap->iv_newstate = bwn_newstate; 2970 2971 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2972 vap->iv_max_aid = BWN_STAID_MAX; 2973 2974 ieee80211_ratectl_init(vap); 2975 2976 /* complete setup */ 2977 ieee80211_vap_attach(vap, ieee80211_media_change, 2978 ieee80211_media_status); 2979 return (vap); 2980 } 2981 2982 static void 2983 bwn_vap_delete(struct ieee80211vap *vap) 2984 { 2985 struct bwn_vap *bvp = BWN_VAP(vap); 2986 2987 ieee80211_ratectl_deinit(vap); 2988 ieee80211_vap_detach(vap); 2989 free(bvp, M_80211_VAP); 2990 } 2991 2992 static void 2993 bwn_init(void *arg) 2994 { 2995 struct bwn_softc *sc = arg; 2996 struct ifnet *ifp = sc->sc_ifp; 2997 struct ieee80211com *ic = ifp->if_l2com; 2998 int error = 0; 2999 3000 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", 3001 __func__, ifp->if_flags); 3002 3003 BWN_LOCK(sc); 3004 error = bwn_init_locked(sc); 3005 BWN_UNLOCK(sc); 3006 3007 if (error == 0) 3008 ieee80211_start_all(ic); /* start all vap's */ 3009 } 3010 3011 static int 3012 bwn_init_locked(struct bwn_softc *sc) 3013 { 3014 struct bwn_mac *mac; 3015 struct ifnet *ifp = sc->sc_ifp; 3016 int error; 3017 3018 BWN_ASSERT_LOCKED(sc); 3019 3020 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 3021 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 3022 sc->sc_filters = 0; 3023 bwn_wme_clear(sc); 3024 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 3025 sc->sc_rf_enabled = 1; 3026 3027 mac = sc->sc_curmac; 3028 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 3029 error = bwn_core_init(mac); 3030 if (error != 0) 3031 return (error); 3032 } 3033 if (mac->mac_status == BWN_MAC_STATUS_INITED) 3034 bwn_core_start(mac); 3035 3036 bwn_set_opmode(mac); 3037 bwn_set_pretbtt(mac); 3038 bwn_spu_setdelay(mac, 0); 3039 bwn_set_macaddr(mac); 3040 3041 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3042 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 3043 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 3044 3045 return (0); 3046 } 3047 3048 static void 3049 bwn_stop(struct bwn_softc *sc, int statechg) 3050 { 3051 3052 BWN_LOCK(sc); 3053 bwn_stop_locked(sc, statechg); 3054 BWN_UNLOCK(sc); 3055 } 3056 3057 static void 3058 bwn_stop_locked(struct bwn_softc *sc, int statechg) 3059 { 3060 struct bwn_mac *mac = sc->sc_curmac; 3061 struct ifnet *ifp = sc->sc_ifp; 3062 3063 BWN_ASSERT_LOCKED(sc); 3064 3065 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 3066 /* XXX FIXME opmode not based on VAP */ 3067 bwn_set_opmode(mac); 3068 bwn_set_macaddr(mac); 3069 } 3070 3071 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 3072 bwn_core_stop(mac); 3073 3074 callout_stop(&sc->sc_led_blink_ch); 3075 sc->sc_led_blinking = 0; 3076 3077 bwn_core_exit(mac); 3078 sc->sc_rf_enabled = 0; 3079 3080 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 3081 } 3082 3083 static void 3084 bwn_wme_clear(struct bwn_softc *sc) 3085 { 3086 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 3087 struct wmeParams *p; 3088 unsigned int i; 3089 3090 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 3091 ("%s:%d: fail", __func__, __LINE__)); 3092 3093 for (i = 0; i < N(sc->sc_wmeParams); i++) { 3094 p = &(sc->sc_wmeParams[i]); 3095 3096 switch (bwn_wme_shm_offsets[i]) { 3097 case BWN_WME_VOICE: 3098 p->wmep_txopLimit = 0; 3099 p->wmep_aifsn = 2; 3100 /* XXX FIXME: log2(cwmin) */ 3101 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3102 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3103 break; 3104 case BWN_WME_VIDEO: 3105 p->wmep_txopLimit = 0; 3106 p->wmep_aifsn = 2; 3107 /* XXX FIXME: log2(cwmin) */ 3108 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3109 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 3110 break; 3111 case BWN_WME_BESTEFFORT: 3112 p->wmep_txopLimit = 0; 3113 p->wmep_aifsn = 3; 3114 /* XXX FIXME: log2(cwmin) */ 3115 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3116 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3117 break; 3118 case BWN_WME_BACKGROUND: 3119 p->wmep_txopLimit = 0; 3120 p->wmep_aifsn = 7; 3121 /* XXX FIXME: log2(cwmin) */ 3122 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 3123 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 3124 break; 3125 default: 3126 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3127 } 3128 } 3129 } 3130 3131 static int 3132 bwn_core_init(struct bwn_mac *mac) 3133 { 3134 struct bwn_softc *sc = mac->mac_sc; 3135 uint64_t hf; 3136 int error; 3137 3138 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3139 ("%s:%d: fail", __func__, __LINE__)); 3140 3141 siba_powerup(sc->sc_dev, 0); 3142 if (!siba_dev_isup(sc->sc_dev)) 3143 bwn_reset_core(mac, 3144 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0); 3145 3146 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 3147 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 3148 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 3149 BWN_GETTIME(mac->mac_phy.nexttime); 3150 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 3151 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 3152 mac->mac_stats.link_noise = -95; 3153 mac->mac_reason_intr = 0; 3154 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 3155 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 3156 #ifdef BWN_DEBUG 3157 if (sc->sc_debug & BWN_DEBUG_XMIT) 3158 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 3159 #endif 3160 mac->mac_suspended = 1; 3161 mac->mac_task_state = 0; 3162 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 3163 3164 mac->mac_phy.init_pre(mac); 3165 3166 siba_pcicore_intr(sc->sc_dev); 3167 3168 siba_fix_imcfglobug(sc->sc_dev); 3169 bwn_bt_disable(mac); 3170 if (mac->mac_phy.prepare_hw) { 3171 error = mac->mac_phy.prepare_hw(mac); 3172 if (error) 3173 goto fail0; 3174 } 3175 error = bwn_chip_init(mac); 3176 if (error) 3177 goto fail0; 3178 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 3179 siba_get_revid(sc->sc_dev)); 3180 hf = bwn_hf_read(mac); 3181 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 3182 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 3183 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 3184 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 3185 if (mac->mac_phy.rev == 1) 3186 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 3187 } 3188 if (mac->mac_phy.rf_ver == 0x2050) { 3189 if (mac->mac_phy.rf_rev < 6) 3190 hf |= BWN_HF_FORCE_VCO_RECALC; 3191 if (mac->mac_phy.rf_rev == 6) 3192 hf |= BWN_HF_4318_TSSI; 3193 } 3194 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW) 3195 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 3196 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) && 3197 (siba_get_pcicore_revid(sc->sc_dev) <= 10)) 3198 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 3199 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 3200 bwn_hf_write(mac, hf); 3201 3202 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 3204 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 3205 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 3206 3207 bwn_rate_init(mac); 3208 bwn_set_phytxctl(mac); 3209 3210 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 3211 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 3212 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 3213 3214 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 3215 bwn_pio_init(mac); 3216 else 3217 bwn_dma_init(mac); 3218 bwn_wme_init(mac); 3219 bwn_spu_setdelay(mac, 1); 3220 bwn_bt_enable(mac); 3221 3222 siba_powerup(sc->sc_dev, 3223 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)); 3224 bwn_set_macaddr(mac); 3225 bwn_crypt_init(mac); 3226 3227 /* XXX LED initializatin */ 3228 3229 mac->mac_status = BWN_MAC_STATUS_INITED; 3230 3231 return (error); 3232 3233 fail0: 3234 siba_powerdown(sc->sc_dev); 3235 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 3236 ("%s:%d: fail", __func__, __LINE__)); 3237 return (error); 3238 } 3239 3240 static void 3241 bwn_core_start(struct bwn_mac *mac) 3242 { 3243 struct bwn_softc *sc = mac->mac_sc; 3244 uint32_t tmp; 3245 3246 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 3247 ("%s:%d: fail", __func__, __LINE__)); 3248 3249 if (siba_get_revid(sc->sc_dev) < 5) 3250 return; 3251 3252 while (1) { 3253 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 3254 if (!(tmp & 0x00000001)) 3255 break; 3256 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 3257 } 3258 3259 bwn_mac_enable(mac); 3260 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 3261 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 3262 3263 mac->mac_status = BWN_MAC_STATUS_STARTED; 3264 } 3265 3266 static void 3267 bwn_core_exit(struct bwn_mac *mac) 3268 { 3269 struct bwn_softc *sc = mac->mac_sc; 3270 uint32_t macctl; 3271 3272 BWN_ASSERT_LOCKED(mac->mac_sc); 3273 3274 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 3275 ("%s:%d: fail", __func__, __LINE__)); 3276 3277 if (mac->mac_status != BWN_MAC_STATUS_INITED) 3278 return; 3279 mac->mac_status = BWN_MAC_STATUS_UNINIT; 3280 3281 macctl = BWN_READ_4(mac, BWN_MACCTL); 3282 macctl &= ~BWN_MACCTL_MCODE_RUN; 3283 macctl |= BWN_MACCTL_MCODE_JMP0; 3284 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3285 3286 bwn_dma_stop(mac); 3287 bwn_pio_stop(mac); 3288 bwn_chip_exit(mac); 3289 mac->mac_phy.switch_analog(mac, 0); 3290 siba_dev_down(sc->sc_dev, 0); 3291 siba_powerdown(sc->sc_dev); 3292 } 3293 3294 static void 3295 bwn_bt_disable(struct bwn_mac *mac) 3296 { 3297 struct bwn_softc *sc = mac->mac_sc; 3298 3299 (void)sc; 3300 /* XXX do nothing yet */ 3301 } 3302 3303 static int 3304 bwn_chip_init(struct bwn_mac *mac) 3305 { 3306 struct bwn_softc *sc = mac->mac_sc; 3307 struct bwn_phy *phy = &mac->mac_phy; 3308 uint32_t macctl; 3309 int error; 3310 3311 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 3312 if (phy->gmode) 3313 macctl |= BWN_MACCTL_GMODE; 3314 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 3315 3316 error = bwn_fw_fillinfo(mac); 3317 if (error) 3318 return (error); 3319 error = bwn_fw_loaducode(mac); 3320 if (error) 3321 return (error); 3322 3323 error = bwn_gpio_init(mac); 3324 if (error) 3325 return (error); 3326 3327 error = bwn_fw_loadinitvals(mac); 3328 if (error) { 3329 siba_gpio_set(sc->sc_dev, 0); 3330 return (error); 3331 } 3332 phy->switch_analog(mac, 1); 3333 error = bwn_phy_init(mac); 3334 if (error) { 3335 siba_gpio_set(sc->sc_dev, 0); 3336 return (error); 3337 } 3338 if (phy->set_im) 3339 phy->set_im(mac, BWN_IMMODE_NONE); 3340 if (phy->set_antenna) 3341 phy->set_antenna(mac, BWN_ANT_DEFAULT); 3342 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 3343 3344 if (phy->type == BWN_PHYTYPE_B) 3345 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 3346 BWN_WRITE_4(mac, 0x0100, 0x01000000); 3347 if (siba_get_revid(sc->sc_dev) < 5) 3348 BWN_WRITE_4(mac, 0x010c, 0x01000000); 3349 3350 BWN_WRITE_4(mac, BWN_MACCTL, 3351 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 3352 BWN_WRITE_4(mac, BWN_MACCTL, 3353 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 3354 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 3355 3356 bwn_set_opmode(mac); 3357 if (siba_get_revid(sc->sc_dev) < 3) { 3358 BWN_WRITE_2(mac, 0x060e, 0x0000); 3359 BWN_WRITE_2(mac, 0x0610, 0x8000); 3360 BWN_WRITE_2(mac, 0x0604, 0x0000); 3361 BWN_WRITE_2(mac, 0x0606, 0x0200); 3362 } else { 3363 BWN_WRITE_4(mac, 0x0188, 0x80000000); 3364 BWN_WRITE_4(mac, 0x018c, 0x02000000); 3365 } 3366 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 3367 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 3368 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 3369 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 3370 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 3371 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 3372 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 3373 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 3374 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000); 3375 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); 3376 return (error); 3377 } 3378 3379 /* read hostflags */ 3380 static uint64_t 3381 bwn_hf_read(struct bwn_mac *mac) 3382 { 3383 uint64_t ret; 3384 3385 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 3386 ret <<= 16; 3387 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 3388 ret <<= 16; 3389 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 3390 return (ret); 3391 } 3392 3393 static void 3394 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 3395 { 3396 3397 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 3398 (value & 0x00000000ffffull)); 3399 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 3400 (value & 0x0000ffff0000ull) >> 16); 3401 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 3402 (value & 0xffff00000000ULL) >> 32); 3403 } 3404 3405 static void 3406 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 3407 { 3408 3409 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 3410 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 3411 } 3412 3413 static void 3414 bwn_rate_init(struct bwn_mac *mac) 3415 { 3416 3417 switch (mac->mac_phy.type) { 3418 case BWN_PHYTYPE_A: 3419 case BWN_PHYTYPE_G: 3420 case BWN_PHYTYPE_LP: 3421 case BWN_PHYTYPE_N: 3422 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 3423 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 3424 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 3425 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 3426 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 3427 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 3428 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 3429 if (mac->mac_phy.type == BWN_PHYTYPE_A) 3430 break; 3431 /* FALLTHROUGH */ 3432 case BWN_PHYTYPE_B: 3433 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 3434 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 3435 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 3436 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 3437 break; 3438 default: 3439 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3440 } 3441 } 3442 3443 static void 3444 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 3445 { 3446 uint16_t offset; 3447 3448 if (ofdm) { 3449 offset = 0x480; 3450 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 3451 } else { 3452 offset = 0x4c0; 3453 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 3454 } 3455 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 3456 bwn_shm_read_2(mac, BWN_SHARED, offset)); 3457 } 3458 3459 static uint8_t 3460 bwn_plcp_getcck(const uint8_t bitrate) 3461 { 3462 3463 switch (bitrate) { 3464 case BWN_CCK_RATE_1MB: 3465 return (0x0a); 3466 case BWN_CCK_RATE_2MB: 3467 return (0x14); 3468 case BWN_CCK_RATE_5MB: 3469 return (0x37); 3470 case BWN_CCK_RATE_11MB: 3471 return (0x6e); 3472 } 3473 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3474 return (0); 3475 } 3476 3477 static uint8_t 3478 bwn_plcp_getofdm(const uint8_t bitrate) 3479 { 3480 3481 switch (bitrate) { 3482 case BWN_OFDM_RATE_6MB: 3483 return (0xb); 3484 case BWN_OFDM_RATE_9MB: 3485 return (0xf); 3486 case BWN_OFDM_RATE_12MB: 3487 return (0xa); 3488 case BWN_OFDM_RATE_18MB: 3489 return (0xe); 3490 case BWN_OFDM_RATE_24MB: 3491 return (0x9); 3492 case BWN_OFDM_RATE_36MB: 3493 return (0xd); 3494 case BWN_OFDM_RATE_48MB: 3495 return (0x8); 3496 case BWN_OFDM_RATE_54MB: 3497 return (0xc); 3498 } 3499 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3500 return (0); 3501 } 3502 3503 static void 3504 bwn_set_phytxctl(struct bwn_mac *mac) 3505 { 3506 uint16_t ctl; 3507 3508 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 3509 BWN_TX_PHY_TXPWR); 3510 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 3511 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 3512 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 3513 } 3514 3515 static void 3516 bwn_pio_init(struct bwn_mac *mac) 3517 { 3518 struct bwn_pio *pio = &mac->mac_method.pio; 3519 3520 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 3521 & ~BWN_MACCTL_BIGENDIAN); 3522 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 3523 3524 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 3525 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 3528 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 3529 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 3530 } 3531 3532 static void 3533 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3534 int index) 3535 { 3536 struct bwn_pio_txpkt *tp; 3537 struct bwn_softc *sc = mac->mac_sc; 3538 unsigned int i; 3539 3540 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 3541 tq->tq_index = index; 3542 3543 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 3544 if (siba_get_revid(sc->sc_dev) >= 8) 3545 tq->tq_size = 1920; 3546 else { 3547 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 3548 tq->tq_size -= 80; 3549 } 3550 3551 TAILQ_INIT(&tq->tq_pktlist); 3552 for (i = 0; i < N(tq->tq_pkts); i++) { 3553 tp = &(tq->tq_pkts[i]); 3554 tp->tp_index = i; 3555 tp->tp_queue = tq; 3556 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 3557 } 3558 } 3559 3560 static uint16_t 3561 bwn_pio_idx2base(struct bwn_mac *mac, int index) 3562 { 3563 struct bwn_softc *sc = mac->mac_sc; 3564 static const uint16_t bases[] = { 3565 BWN_PIO_BASE0, 3566 BWN_PIO_BASE1, 3567 BWN_PIO_BASE2, 3568 BWN_PIO_BASE3, 3569 BWN_PIO_BASE4, 3570 BWN_PIO_BASE5, 3571 BWN_PIO_BASE6, 3572 BWN_PIO_BASE7, 3573 }; 3574 static const uint16_t bases_rev11[] = { 3575 BWN_PIO11_BASE0, 3576 BWN_PIO11_BASE1, 3577 BWN_PIO11_BASE2, 3578 BWN_PIO11_BASE3, 3579 BWN_PIO11_BASE4, 3580 BWN_PIO11_BASE5, 3581 }; 3582 3583 if (siba_get_revid(sc->sc_dev) >= 11) { 3584 if (index >= N(bases_rev11)) 3585 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3586 return (bases_rev11[index]); 3587 } 3588 if (index >= N(bases)) 3589 device_printf(sc->sc_dev, "%s: warning\n", __func__); 3590 return (bases[index]); 3591 } 3592 3593 static void 3594 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 3595 int index) 3596 { 3597 struct bwn_softc *sc = mac->mac_sc; 3598 3599 prq->prq_mac = mac; 3600 prq->prq_rev = siba_get_revid(sc->sc_dev); 3601 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 3602 bwn_dma_rxdirectfifo(mac, index, 1); 3603 } 3604 3605 static void 3606 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 3607 { 3608 if (tq == NULL) 3609 return; 3610 bwn_pio_cancel_tx_packets(tq); 3611 } 3612 3613 static void 3614 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 3615 { 3616 3617 bwn_destroy_pioqueue_tx(pio); 3618 } 3619 3620 static uint16_t 3621 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 3622 uint16_t offset) 3623 { 3624 3625 return (BWN_READ_2(mac, tq->tq_base + offset)); 3626 } 3627 3628 static void 3629 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 3630 { 3631 uint32_t ctl; 3632 int type; 3633 uint16_t base; 3634 3635 type = bwn_dma_mask2type(bwn_dma_mask(mac)); 3636 base = bwn_dma_base(type, idx); 3637 if (type == BWN_DMA_64BIT) { 3638 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 3639 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 3640 if (enable) 3641 ctl |= BWN_DMA64_RXDIRECTFIFO; 3642 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 3643 } else { 3644 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 3645 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 3646 if (enable) 3647 ctl |= BWN_DMA32_RXDIRECTFIFO; 3648 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 3649 } 3650 } 3651 3652 static uint64_t 3653 bwn_dma_mask(struct bwn_mac *mac) 3654 { 3655 uint32_t tmp; 3656 uint16_t base; 3657 3658 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3659 if (tmp & SIBA_TGSHIGH_DMA64) 3660 return (BWN_DMA_BIT_MASK(64)); 3661 base = bwn_dma_base(0, 0); 3662 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3663 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3664 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3665 return (BWN_DMA_BIT_MASK(32)); 3666 3667 return (BWN_DMA_BIT_MASK(30)); 3668 } 3669 3670 static int 3671 bwn_dma_mask2type(uint64_t dmamask) 3672 { 3673 3674 if (dmamask == BWN_DMA_BIT_MASK(30)) 3675 return (BWN_DMA_30BIT); 3676 if (dmamask == BWN_DMA_BIT_MASK(32)) 3677 return (BWN_DMA_32BIT); 3678 if (dmamask == BWN_DMA_BIT_MASK(64)) 3679 return (BWN_DMA_64BIT); 3680 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3681 return (BWN_DMA_30BIT); 3682 } 3683 3684 static void 3685 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 3686 { 3687 struct bwn_pio_txpkt *tp; 3688 unsigned int i; 3689 3690 for (i = 0; i < N(tq->tq_pkts); i++) { 3691 tp = &(tq->tq_pkts[i]); 3692 if (tp->tp_m) { 3693 m_freem(tp->tp_m); 3694 tp->tp_m = NULL; 3695 } 3696 } 3697 } 3698 3699 static uint16_t 3700 bwn_dma_base(int type, int controller_idx) 3701 { 3702 static const uint16_t map64[] = { 3703 BWN_DMA64_BASE0, 3704 BWN_DMA64_BASE1, 3705 BWN_DMA64_BASE2, 3706 BWN_DMA64_BASE3, 3707 BWN_DMA64_BASE4, 3708 BWN_DMA64_BASE5, 3709 }; 3710 static const uint16_t map32[] = { 3711 BWN_DMA32_BASE0, 3712 BWN_DMA32_BASE1, 3713 BWN_DMA32_BASE2, 3714 BWN_DMA32_BASE3, 3715 BWN_DMA32_BASE4, 3716 BWN_DMA32_BASE5, 3717 }; 3718 3719 if (type == BWN_DMA_64BIT) { 3720 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 3721 ("%s:%d: fail", __func__, __LINE__)); 3722 return (map64[controller_idx]); 3723 } 3724 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 3725 ("%s:%d: fail", __func__, __LINE__)); 3726 return (map32[controller_idx]); 3727 } 3728 3729 static void 3730 bwn_dma_init(struct bwn_mac *mac) 3731 { 3732 struct bwn_dma *dma = &mac->mac_method.dma; 3733 3734 /* setup TX DMA channels. */ 3735 bwn_dma_setup(dma->wme[WME_AC_BK]); 3736 bwn_dma_setup(dma->wme[WME_AC_BE]); 3737 bwn_dma_setup(dma->wme[WME_AC_VI]); 3738 bwn_dma_setup(dma->wme[WME_AC_VO]); 3739 bwn_dma_setup(dma->mcast); 3740 /* setup RX DMA channel. */ 3741 bwn_dma_setup(dma->rx); 3742 } 3743 3744 static struct bwn_dma_ring * 3745 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 3746 int for_tx, int type) 3747 { 3748 struct bwn_dma *dma = &mac->mac_method.dma; 3749 struct bwn_dma_ring *dr; 3750 struct bwn_dmadesc_generic *desc; 3751 struct bwn_dmadesc_meta *mt; 3752 struct bwn_softc *sc = mac->mac_sc; 3753 int error, i; 3754 3755 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 3756 if (dr == NULL) 3757 goto out; 3758 dr->dr_numslots = BWN_RXRING_SLOTS; 3759 if (for_tx) 3760 dr->dr_numslots = BWN_TXRING_SLOTS; 3761 3762 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 3763 M_DEVBUF, M_NOWAIT | M_ZERO); 3764 if (dr->dr_meta == NULL) 3765 goto fail0; 3766 3767 dr->dr_type = type; 3768 dr->dr_mac = mac; 3769 dr->dr_base = bwn_dma_base(type, controller_index); 3770 dr->dr_index = controller_index; 3771 if (type == BWN_DMA_64BIT) { 3772 dr->getdesc = bwn_dma_64_getdesc; 3773 dr->setdesc = bwn_dma_64_setdesc; 3774 dr->start_transfer = bwn_dma_64_start_transfer; 3775 dr->suspend = bwn_dma_64_suspend; 3776 dr->resume = bwn_dma_64_resume; 3777 dr->get_curslot = bwn_dma_64_get_curslot; 3778 dr->set_curslot = bwn_dma_64_set_curslot; 3779 } else { 3780 dr->getdesc = bwn_dma_32_getdesc; 3781 dr->setdesc = bwn_dma_32_setdesc; 3782 dr->start_transfer = bwn_dma_32_start_transfer; 3783 dr->suspend = bwn_dma_32_suspend; 3784 dr->resume = bwn_dma_32_resume; 3785 dr->get_curslot = bwn_dma_32_get_curslot; 3786 dr->set_curslot = bwn_dma_32_set_curslot; 3787 } 3788 if (for_tx) { 3789 dr->dr_tx = 1; 3790 dr->dr_curslot = -1; 3791 } else { 3792 if (dr->dr_index == 0) { 3793 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE; 3794 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET; 3795 } else 3796 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3797 } 3798 3799 error = bwn_dma_allocringmemory(dr); 3800 if (error) 3801 goto fail2; 3802 3803 if (for_tx) { 3804 /* 3805 * Assumption: BWN_TXRING_SLOTS can be divided by 3806 * BWN_TX_SLOTS_PER_FRAME 3807 */ 3808 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 3809 ("%s:%d: fail", __func__, __LINE__)); 3810 3811 dr->dr_txhdr_cache = 3812 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3813 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO); 3814 KASSERT(dr->dr_txhdr_cache != NULL, 3815 ("%s:%d: fail", __func__, __LINE__)); 3816 3817 /* 3818 * Create TX ring DMA stuffs 3819 */ 3820 error = bus_dma_tag_create(dma->parent_dtag, 3821 BWN_ALIGN, 0, 3822 BUS_SPACE_MAXADDR, 3823 BUS_SPACE_MAXADDR, 3824 NULL, NULL, 3825 BWN_HDRSIZE(mac), 3826 1, 3827 BUS_SPACE_MAXSIZE_32BIT, 3828 0, 3829 NULL, NULL, 3830 &dr->dr_txring_dtag); 3831 if (error) { 3832 device_printf(sc->sc_dev, 3833 "can't create TX ring DMA tag: TODO frees\n"); 3834 goto fail1; 3835 } 3836 3837 for (i = 0; i < dr->dr_numslots; i += 2) { 3838 dr->getdesc(dr, i, &desc, &mt); 3839 3840 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 3841 mt->mt_m = NULL; 3842 mt->mt_ni = NULL; 3843 mt->mt_islast = 0; 3844 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 3845 &mt->mt_dmap); 3846 if (error) { 3847 device_printf(sc->sc_dev, 3848 "can't create RX buf DMA map\n"); 3849 goto fail1; 3850 } 3851 3852 dr->getdesc(dr, i + 1, &desc, &mt); 3853 3854 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 3855 mt->mt_m = NULL; 3856 mt->mt_ni = NULL; 3857 mt->mt_islast = 1; 3858 error = bus_dmamap_create(dma->txbuf_dtag, 0, 3859 &mt->mt_dmap); 3860 if (error) { 3861 device_printf(sc->sc_dev, 3862 "can't create RX buf DMA map\n"); 3863 goto fail1; 3864 } 3865 } 3866 } else { 3867 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3868 &dr->dr_spare_dmap); 3869 if (error) { 3870 device_printf(sc->sc_dev, 3871 "can't create RX buf DMA map\n"); 3872 goto out; /* XXX wrong! */ 3873 } 3874 3875 for (i = 0; i < dr->dr_numslots; i++) { 3876 dr->getdesc(dr, i, &desc, &mt); 3877 3878 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 3879 &mt->mt_dmap); 3880 if (error) { 3881 device_printf(sc->sc_dev, 3882 "can't create RX buf DMA map\n"); 3883 goto out; /* XXX wrong! */ 3884 } 3885 error = bwn_dma_newbuf(dr, desc, mt, 1); 3886 if (error) { 3887 device_printf(sc->sc_dev, 3888 "failed to allocate RX buf\n"); 3889 goto out; /* XXX wrong! */ 3890 } 3891 } 3892 3893 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 3894 BUS_DMASYNC_PREWRITE); 3895 3896 dr->dr_usedslot = dr->dr_numslots; 3897 } 3898 3899 out: 3900 return (dr); 3901 3902 fail2: 3903 free(dr->dr_txhdr_cache, M_DEVBUF); 3904 fail1: 3905 free(dr->dr_meta, M_DEVBUF); 3906 fail0: 3907 free(dr, M_DEVBUF); 3908 return (NULL); 3909 } 3910 3911 static void 3912 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3913 { 3914 3915 if (dr == NULL) 3916 return; 3917 3918 bwn_dma_free_descbufs(*dr); 3919 bwn_dma_free_ringmemory(*dr); 3920 3921 free((*dr)->dr_txhdr_cache, M_DEVBUF); 3922 free((*dr)->dr_meta, M_DEVBUF); 3923 free(*dr, M_DEVBUF); 3924 3925 *dr = NULL; 3926 } 3927 3928 static void 3929 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3930 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3931 { 3932 struct bwn_dmadesc32 *desc; 3933 3934 *meta = &(dr->dr_meta[slot]); 3935 desc = dr->dr_ring_descbase; 3936 desc = &(desc[slot]); 3937 3938 *gdesc = (struct bwn_dmadesc_generic *)desc; 3939 } 3940 3941 static void 3942 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3943 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3944 int start, int end, int irq) 3945 { 3946 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 3947 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3948 uint32_t addr, addrext, ctl; 3949 int slot; 3950 3951 slot = (int)(&(desc->dma.dma32) - descbase); 3952 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3953 ("%s:%d: fail", __func__, __LINE__)); 3954 3955 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 3956 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 3957 addr |= siba_dma_translation(sc->sc_dev); 3958 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3959 if (slot == dr->dr_numslots - 1) 3960 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3961 if (start) 3962 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3963 if (end) 3964 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3965 if (irq) 3966 ctl |= BWN_DMA32_DCTL_IRQ; 3967 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3968 & BWN_DMA32_DCTL_ADDREXT_MASK; 3969 3970 desc->dma.dma32.control = htole32(ctl); 3971 desc->dma.dma32.address = htole32(addr); 3972 } 3973 3974 static void 3975 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3976 { 3977 3978 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3979 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3980 } 3981 3982 static void 3983 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3984 { 3985 3986 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3987 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3988 } 3989 3990 static void 3991 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3992 { 3993 3994 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3995 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3996 } 3997 3998 static int 3999 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 4000 { 4001 uint32_t val; 4002 4003 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 4004 val &= BWN_DMA32_RXDPTR; 4005 4006 return (val / sizeof(struct bwn_dmadesc32)); 4007 } 4008 4009 static void 4010 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 4011 { 4012 4013 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 4014 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 4015 } 4016 4017 static void 4018 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 4019 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 4020 { 4021 struct bwn_dmadesc64 *desc; 4022 4023 *meta = &(dr->dr_meta[slot]); 4024 desc = dr->dr_ring_descbase; 4025 desc = &(desc[slot]); 4026 4027 *gdesc = (struct bwn_dmadesc_generic *)desc; 4028 } 4029 4030 static void 4031 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 4032 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 4033 int start, int end, int irq) 4034 { 4035 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 4036 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4037 int slot; 4038 uint32_t ctl0 = 0, ctl1 = 0; 4039 uint32_t addrlo, addrhi; 4040 uint32_t addrext; 4041 4042 slot = (int)(&(desc->dma.dma64) - descbase); 4043 KASSERT(slot >= 0 && slot < dr->dr_numslots, 4044 ("%s:%d: fail", __func__, __LINE__)); 4045 4046 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 4047 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 4048 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 4049 30; 4050 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 4051 if (slot == dr->dr_numslots - 1) 4052 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 4053 if (start) 4054 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 4055 if (end) 4056 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 4057 if (irq) 4058 ctl0 |= BWN_DMA64_DCTL0_IRQ; 4059 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 4060 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 4061 & BWN_DMA64_DCTL1_ADDREXT_MASK; 4062 4063 desc->dma.dma64.control0 = htole32(ctl0); 4064 desc->dma.dma64.control1 = htole32(ctl1); 4065 desc->dma.dma64.address_low = htole32(addrlo); 4066 desc->dma.dma64.address_high = htole32(addrhi); 4067 } 4068 4069 static void 4070 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 4071 { 4072 4073 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 4074 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4075 } 4076 4077 static void 4078 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 4079 { 4080 4081 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4082 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 4083 } 4084 4085 static void 4086 bwn_dma_64_resume(struct bwn_dma_ring *dr) 4087 { 4088 4089 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 4090 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 4091 } 4092 4093 static int 4094 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 4095 { 4096 uint32_t val; 4097 4098 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 4099 val &= BWN_DMA64_RXSTATDPTR; 4100 4101 return (val / sizeof(struct bwn_dmadesc64)); 4102 } 4103 4104 static void 4105 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 4106 { 4107 4108 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 4109 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 4110 } 4111 4112 static int 4113 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 4114 { 4115 struct bwn_mac *mac = dr->dr_mac; 4116 struct bwn_dma *dma = &mac->mac_method.dma; 4117 struct bwn_softc *sc = mac->mac_sc; 4118 int error; 4119 4120 error = bus_dma_tag_create(dma->parent_dtag, 4121 BWN_ALIGN, 0, 4122 BUS_SPACE_MAXADDR, 4123 BUS_SPACE_MAXADDR, 4124 NULL, NULL, 4125 BWN_DMA_RINGMEMSIZE, 4126 1, 4127 BUS_SPACE_MAXSIZE_32BIT, 4128 0, 4129 NULL, NULL, 4130 &dr->dr_ring_dtag); 4131 if (error) { 4132 device_printf(sc->sc_dev, 4133 "can't create TX ring DMA tag: TODO frees\n"); 4134 return (-1); 4135 } 4136 4137 error = bus_dmamem_alloc(dr->dr_ring_dtag, 4138 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 4139 &dr->dr_ring_dmap); 4140 if (error) { 4141 device_printf(sc->sc_dev, 4142 "can't allocate DMA mem: TODO frees\n"); 4143 return (-1); 4144 } 4145 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 4146 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 4147 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 4148 if (error) { 4149 device_printf(sc->sc_dev, 4150 "can't load DMA mem: TODO free\n"); 4151 return (-1); 4152 } 4153 4154 return (0); 4155 } 4156 4157 static void 4158 bwn_dma_setup(struct bwn_dma_ring *dr) 4159 { 4160 struct bwn_softc *sc = dr->dr_mac->mac_sc; 4161 uint64_t ring64; 4162 uint32_t addrext, ring32, value; 4163 uint32_t trans = siba_dma_translation(sc->sc_dev); 4164 4165 if (dr->dr_tx) { 4166 dr->dr_curslot = -1; 4167 4168 if (dr->dr_type == BWN_DMA_64BIT) { 4169 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4170 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 4171 >> 30; 4172 value = BWN_DMA64_TXENABLE; 4173 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 4174 & BWN_DMA64_TXADDREXT_MASK; 4175 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 4176 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 4177 (ring64 & 0xffffffff)); 4178 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 4179 ((ring64 >> 32) & 4180 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 4181 } else { 4182 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4183 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4184 value = BWN_DMA32_TXENABLE; 4185 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 4186 & BWN_DMA32_TXADDREXT_MASK; 4187 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 4188 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 4189 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4190 } 4191 return; 4192 } 4193 4194 /* 4195 * set for RX 4196 */ 4197 dr->dr_usedslot = dr->dr_numslots; 4198 4199 if (dr->dr_type == BWN_DMA_64BIT) { 4200 ring64 = (uint64_t)(dr->dr_ring_dmabase); 4201 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 4202 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 4203 value |= BWN_DMA64_RXENABLE; 4204 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 4205 & BWN_DMA64_RXADDREXT_MASK; 4206 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 4207 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 4208 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 4209 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 4210 | (trans << 1)); 4211 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 4212 sizeof(struct bwn_dmadesc64)); 4213 } else { 4214 ring32 = (uint32_t)(dr->dr_ring_dmabase); 4215 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 4216 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 4217 value |= BWN_DMA32_RXENABLE; 4218 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 4219 & BWN_DMA32_RXADDREXT_MASK; 4220 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 4221 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 4222 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 4223 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 4224 sizeof(struct bwn_dmadesc32)); 4225 } 4226 } 4227 4228 static void 4229 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 4230 { 4231 4232 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 4233 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 4234 dr->dr_ring_dmap); 4235 } 4236 4237 static void 4238 bwn_dma_cleanup(struct bwn_dma_ring *dr) 4239 { 4240 4241 if (dr->dr_tx) { 4242 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4243 if (dr->dr_type == BWN_DMA_64BIT) { 4244 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 4245 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 4246 } else 4247 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 4248 } else { 4249 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 4250 if (dr->dr_type == BWN_DMA_64BIT) { 4251 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 4252 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 4253 } else 4254 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 4255 } 4256 } 4257 4258 static void 4259 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 4260 { 4261 struct bwn_dmadesc_generic *desc; 4262 struct bwn_dmadesc_meta *meta; 4263 struct bwn_mac *mac = dr->dr_mac; 4264 struct bwn_dma *dma = &mac->mac_method.dma; 4265 struct bwn_softc *sc = mac->mac_sc; 4266 int i; 4267 4268 if (!dr->dr_usedslot) 4269 return; 4270 for (i = 0; i < dr->dr_numslots; i++) { 4271 dr->getdesc(dr, i, &desc, &meta); 4272 4273 if (meta->mt_m == NULL) { 4274 if (!dr->dr_tx) 4275 device_printf(sc->sc_dev, "%s: not TX?\n", 4276 __func__); 4277 continue; 4278 } 4279 if (dr->dr_tx) { 4280 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 4281 bus_dmamap_unload(dr->dr_txring_dtag, 4282 meta->mt_dmap); 4283 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 4284 bus_dmamap_unload(dma->txbuf_dtag, 4285 meta->mt_dmap); 4286 } else 4287 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 4288 bwn_dma_free_descbuf(dr, meta); 4289 } 4290 } 4291 4292 static int 4293 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 4294 int type) 4295 { 4296 struct bwn_softc *sc = mac->mac_sc; 4297 uint32_t value; 4298 int i; 4299 uint16_t offset; 4300 4301 for (i = 0; i < 10; i++) { 4302 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4303 BWN_DMA32_TXSTATUS; 4304 value = BWN_READ_4(mac, base + offset); 4305 if (type == BWN_DMA_64BIT) { 4306 value &= BWN_DMA64_TXSTAT; 4307 if (value == BWN_DMA64_TXSTAT_DISABLED || 4308 value == BWN_DMA64_TXSTAT_IDLEWAIT || 4309 value == BWN_DMA64_TXSTAT_STOPPED) 4310 break; 4311 } else { 4312 value &= BWN_DMA32_TXSTATE; 4313 if (value == BWN_DMA32_TXSTAT_DISABLED || 4314 value == BWN_DMA32_TXSTAT_IDLEWAIT || 4315 value == BWN_DMA32_TXSTAT_STOPPED) 4316 break; 4317 } 4318 DELAY(1000); 4319 } 4320 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 4321 BWN_WRITE_4(mac, base + offset, 0); 4322 for (i = 0; i < 10; i++) { 4323 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 4324 BWN_DMA32_TXSTATUS; 4325 value = BWN_READ_4(mac, base + offset); 4326 if (type == BWN_DMA_64BIT) { 4327 value &= BWN_DMA64_TXSTAT; 4328 if (value == BWN_DMA64_TXSTAT_DISABLED) { 4329 i = -1; 4330 break; 4331 } 4332 } else { 4333 value &= BWN_DMA32_TXSTATE; 4334 if (value == BWN_DMA32_TXSTAT_DISABLED) { 4335 i = -1; 4336 break; 4337 } 4338 } 4339 DELAY(1000); 4340 } 4341 if (i != -1) { 4342 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4343 return (ENODEV); 4344 } 4345 DELAY(1000); 4346 4347 return (0); 4348 } 4349 4350 static int 4351 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 4352 int type) 4353 { 4354 struct bwn_softc *sc = mac->mac_sc; 4355 uint32_t value; 4356 int i; 4357 uint16_t offset; 4358 4359 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 4360 BWN_WRITE_4(mac, base + offset, 0); 4361 for (i = 0; i < 10; i++) { 4362 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 4363 BWN_DMA32_RXSTATUS; 4364 value = BWN_READ_4(mac, base + offset); 4365 if (type == BWN_DMA_64BIT) { 4366 value &= BWN_DMA64_RXSTAT; 4367 if (value == BWN_DMA64_RXSTAT_DISABLED) { 4368 i = -1; 4369 break; 4370 } 4371 } else { 4372 value &= BWN_DMA32_RXSTATE; 4373 if (value == BWN_DMA32_RXSTAT_DISABLED) { 4374 i = -1; 4375 break; 4376 } 4377 } 4378 DELAY(1000); 4379 } 4380 if (i != -1) { 4381 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 4382 return (ENODEV); 4383 } 4384 4385 return (0); 4386 } 4387 4388 static void 4389 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 4390 struct bwn_dmadesc_meta *meta) 4391 { 4392 4393 if (meta->mt_m != NULL) { 4394 m_freem(meta->mt_m); 4395 meta->mt_m = NULL; 4396 } 4397 if (meta->mt_ni != NULL) { 4398 ieee80211_free_node(meta->mt_ni); 4399 meta->mt_ni = NULL; 4400 } 4401 } 4402 4403 static void 4404 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4405 { 4406 struct bwn_rxhdr4 *rxhdr; 4407 unsigned char *frame; 4408 4409 rxhdr = mtod(m, struct bwn_rxhdr4 *); 4410 rxhdr->frame_len = 0; 4411 4412 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 4413 sizeof(struct bwn_plcp6) + 2, 4414 ("%s:%d: fail", __func__, __LINE__)); 4415 frame = mtod(m, char *) + dr->dr_frameoffset; 4416 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 4417 } 4418 4419 static uint8_t 4420 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 4421 { 4422 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 4423 4424 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 4425 == 0xff); 4426 } 4427 4428 static void 4429 bwn_wme_init(struct bwn_mac *mac) 4430 { 4431 4432 bwn_wme_load(mac); 4433 4434 /* enable WME support. */ 4435 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 4436 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 4437 BWN_IFSCTL_USE_EDCF); 4438 } 4439 4440 static void 4441 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 4442 { 4443 struct bwn_softc *sc = mac->mac_sc; 4444 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4445 uint16_t delay; /* microsec */ 4446 4447 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 4448 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 4449 delay = 500; 4450 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 4451 delay = max(delay, (uint16_t)2400); 4452 4453 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 4454 } 4455 4456 static void 4457 bwn_bt_enable(struct bwn_mac *mac) 4458 { 4459 struct bwn_softc *sc = mac->mac_sc; 4460 uint64_t hf; 4461 4462 if (bwn_bluetooth == 0) 4463 return; 4464 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 4465 return; 4466 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 4467 return; 4468 4469 hf = bwn_hf_read(mac); 4470 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 4471 hf |= BWN_HF_BT_COEXISTALT; 4472 else 4473 hf |= BWN_HF_BT_COEXIST; 4474 bwn_hf_write(mac, hf); 4475 } 4476 4477 static void 4478 bwn_set_macaddr(struct bwn_mac *mac) 4479 { 4480 4481 bwn_mac_write_bssid(mac); 4482 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); 4483 } 4484 4485 static void 4486 bwn_clear_keys(struct bwn_mac *mac) 4487 { 4488 int i; 4489 4490 for (i = 0; i < mac->mac_max_nr_keys; i++) { 4491 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 4492 ("%s:%d: fail", __func__, __LINE__)); 4493 4494 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 4495 NULL, BWN_SEC_KEYSIZE, NULL); 4496 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 4497 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 4498 NULL, BWN_SEC_KEYSIZE, NULL); 4499 } 4500 mac->mac_key[i].keyconf = NULL; 4501 } 4502 } 4503 4504 static void 4505 bwn_crypt_init(struct bwn_mac *mac) 4506 { 4507 struct bwn_softc *sc = mac->mac_sc; 4508 4509 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 4510 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 4511 ("%s:%d: fail", __func__, __LINE__)); 4512 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 4513 mac->mac_ktp *= 2; 4514 if (siba_get_revid(sc->sc_dev) >= 5) 4515 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 4516 bwn_clear_keys(mac); 4517 } 4518 4519 static void 4520 bwn_chip_exit(struct bwn_mac *mac) 4521 { 4522 struct bwn_softc *sc = mac->mac_sc; 4523 4524 bwn_phy_exit(mac); 4525 siba_gpio_set(sc->sc_dev, 0); 4526 } 4527 4528 static int 4529 bwn_fw_fillinfo(struct bwn_mac *mac) 4530 { 4531 int error; 4532 4533 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 4534 if (error == 0) 4535 return (0); 4536 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 4537 if (error == 0) 4538 return (0); 4539 return (error); 4540 } 4541 4542 static int 4543 bwn_gpio_init(struct bwn_mac *mac) 4544 { 4545 struct bwn_softc *sc = mac->mac_sc; 4546 uint32_t mask = 0x1f, set = 0xf, value; 4547 4548 BWN_WRITE_4(mac, BWN_MACCTL, 4549 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 4550 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4551 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 4552 4553 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 4554 mask |= 0x0060; 4555 set |= 0x0060; 4556 } 4557 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 4558 BWN_WRITE_2(mac, BWN_GPIO_MASK, 4559 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 4560 mask |= 0x0200; 4561 set |= 0x0200; 4562 } 4563 if (siba_get_revid(sc->sc_dev) >= 2) 4564 mask |= 0x0010; 4565 4566 value = siba_gpio_get(sc->sc_dev); 4567 if (value == -1) 4568 return (0); 4569 siba_gpio_set(sc->sc_dev, (value & mask) | set); 4570 4571 return (0); 4572 } 4573 4574 static int 4575 bwn_fw_loadinitvals(struct bwn_mac *mac) 4576 { 4577 #define GETFWOFFSET(fwp, offset) \ 4578 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 4579 const size_t hdr_len = sizeof(struct bwn_fwhdr); 4580 const struct bwn_fwhdr *hdr; 4581 struct bwn_fw *fw = &mac->mac_fw; 4582 int error; 4583 4584 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 4585 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 4586 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 4587 if (error) 4588 return (error); 4589 if (fw->initvals_band.fw) { 4590 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 4591 error = bwn_fwinitvals_write(mac, 4592 GETFWOFFSET(fw->initvals_band, hdr_len), 4593 be32toh(hdr->size), 4594 fw->initvals_band.fw->datasize - hdr_len); 4595 } 4596 return (error); 4597 #undef GETFWOFFSET 4598 } 4599 4600 static int 4601 bwn_phy_init(struct bwn_mac *mac) 4602 { 4603 struct bwn_softc *sc = mac->mac_sc; 4604 int error; 4605 4606 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 4607 mac->mac_phy.rf_onoff(mac, 1); 4608 error = mac->mac_phy.init(mac); 4609 if (error) { 4610 device_printf(sc->sc_dev, "PHY init failed\n"); 4611 goto fail0; 4612 } 4613 error = bwn_switch_channel(mac, 4614 mac->mac_phy.get_default_chan(mac)); 4615 if (error) { 4616 device_printf(sc->sc_dev, 4617 "failed to switch default channel\n"); 4618 goto fail1; 4619 } 4620 return (0); 4621 fail1: 4622 if (mac->mac_phy.exit) 4623 mac->mac_phy.exit(mac); 4624 fail0: 4625 mac->mac_phy.rf_onoff(mac, 0); 4626 4627 return (error); 4628 } 4629 4630 static void 4631 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 4632 { 4633 uint16_t ant; 4634 uint16_t tmp; 4635 4636 ant = bwn_ant2phy(antenna); 4637 4638 /* For ACK/CTS */ 4639 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 4640 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4641 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 4642 /* For Probe Resposes */ 4643 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 4644 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 4645 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 4646 } 4647 4648 static void 4649 bwn_set_opmode(struct bwn_mac *mac) 4650 { 4651 struct bwn_softc *sc = mac->mac_sc; 4652 struct ifnet *ifp = sc->sc_ifp; 4653 struct ieee80211com *ic = ifp->if_l2com; 4654 uint32_t ctl; 4655 uint16_t cfp_pretbtt; 4656 4657 ctl = BWN_READ_4(mac, BWN_MACCTL); 4658 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 4659 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 4660 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 4661 ctl |= BWN_MACCTL_STA; 4662 4663 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4664 ic->ic_opmode == IEEE80211_M_MBSS) 4665 ctl |= BWN_MACCTL_HOSTAP; 4666 else if (ic->ic_opmode == IEEE80211_M_IBSS) 4667 ctl &= ~BWN_MACCTL_STA; 4668 ctl |= sc->sc_filters; 4669 4670 if (siba_get_revid(sc->sc_dev) <= 4) 4671 ctl |= BWN_MACCTL_PROMISC; 4672 4673 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4674 4675 cfp_pretbtt = 2; 4676 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 4677 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 4678 siba_get_chiprev(sc->sc_dev) == 3) 4679 cfp_pretbtt = 100; 4680 else 4681 cfp_pretbtt = 50; 4682 } 4683 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 4684 } 4685 4686 static int 4687 bwn_dma_gettype(struct bwn_mac *mac) 4688 { 4689 uint32_t tmp; 4690 uint16_t base; 4691 4692 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 4693 if (tmp & SIBA_TGSHIGH_DMA64) 4694 return (BWN_DMA_64BIT); 4695 base = bwn_dma_base(0, 0); 4696 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 4697 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 4698 if (tmp & BWN_DMA32_TXADDREXT_MASK) 4699 return (BWN_DMA_32BIT); 4700 4701 return (BWN_DMA_30BIT); 4702 } 4703 4704 static void 4705 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 4706 { 4707 if (!error) { 4708 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 4709 *((bus_addr_t *)arg) = seg->ds_addr; 4710 } 4711 } 4712 4713 static void 4714 bwn_phy_g_init_sub(struct bwn_mac *mac) 4715 { 4716 struct bwn_phy *phy = &mac->mac_phy; 4717 struct bwn_phy_g *pg = &phy->phy_g; 4718 struct bwn_softc *sc = mac->mac_sc; 4719 uint16_t i, tmp; 4720 4721 if (phy->rev == 1) 4722 bwn_phy_init_b5(mac); 4723 else 4724 bwn_phy_init_b6(mac); 4725 4726 if (phy->rev >= 2 || phy->gmode) 4727 bwn_phy_init_a(mac); 4728 4729 if (phy->rev >= 2) { 4730 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 4731 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 4732 } 4733 if (phy->rev == 2) { 4734 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 4735 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4736 } 4737 if (phy->rev > 5) { 4738 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 4739 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 4740 } 4741 if (phy->gmode || phy->rev >= 2) { 4742 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 4743 tmp &= BWN_PHYVER_VERSION; 4744 if (tmp == 3 || tmp == 5) { 4745 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 4746 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 4747 } 4748 if (tmp == 5) { 4749 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 4750 0x1f00); 4751 } 4752 } 4753 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 4754 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 4755 if (phy->rf_rev == 8) { 4756 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 4757 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 4758 } 4759 if (BWN_HAS_LOOPBACK(phy)) 4760 bwn_loopback_calcgain(mac); 4761 4762 if (phy->rf_rev != 8) { 4763 if (pg->pg_initval == 0xffff) 4764 pg->pg_initval = bwn_rf_init_bcm2050(mac); 4765 else 4766 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 4767 } 4768 bwn_lo_g_init(mac); 4769 if (BWN_HAS_TXMAG(phy)) { 4770 BWN_RF_WRITE(mac, 0x52, 4771 (BWN_RF_READ(mac, 0x52) & 0xff00) 4772 | pg->pg_loctl.tx_bias | 4773 pg->pg_loctl.tx_magn); 4774 } else { 4775 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 4776 } 4777 if (phy->rev >= 6) { 4778 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 4779 (pg->pg_loctl.tx_bias << 12)); 4780 } 4781 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) 4782 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 4783 else 4784 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 4785 if (phy->rev < 2) 4786 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 4787 else 4788 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 4789 if (phy->gmode || phy->rev >= 2) { 4790 bwn_lo_g_adjust(mac); 4791 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 4792 } 4793 4794 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 4795 for (i = 0; i < 64; i++) { 4796 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 4797 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 4798 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 4799 -32), 31)); 4800 } 4801 bwn_nrssi_threshold(mac); 4802 } else if (phy->gmode || phy->rev >= 2) { 4803 if (pg->pg_nrssi[0] == -1000) { 4804 KASSERT(pg->pg_nrssi[1] == -1000, 4805 ("%s:%d: fail", __func__, __LINE__)); 4806 bwn_nrssi_slope_11g(mac); 4807 } else 4808 bwn_nrssi_threshold(mac); 4809 } 4810 if (phy->rf_rev == 8) 4811 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 4812 bwn_phy_hwpctl_init(mac); 4813 if ((siba_get_chipid(sc->sc_dev) == 0x4306 4814 && siba_get_chippkg(sc->sc_dev) == 2) || 0) { 4815 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 4816 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 4817 } 4818 } 4819 4820 static uint8_t 4821 bwn_has_hwpctl(struct bwn_mac *mac) 4822 { 4823 4824 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 4825 return (0); 4826 return (mac->mac_phy.use_hwpctl(mac)); 4827 } 4828 4829 static void 4830 bwn_phy_init_b5(struct bwn_mac *mac) 4831 { 4832 struct bwn_phy *phy = &mac->mac_phy; 4833 struct bwn_phy_g *pg = &phy->phy_g; 4834 struct bwn_softc *sc = mac->mac_sc; 4835 uint16_t offset, value; 4836 uint8_t old_channel; 4837 4838 if (phy->analog == 1) 4839 BWN_RF_SET(mac, 0x007a, 0x0050); 4840 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) && 4841 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) { 4842 value = 0x2120; 4843 for (offset = 0x00a8; offset < 0x00c7; offset++) { 4844 BWN_PHY_WRITE(mac, offset, value); 4845 value += 0x202; 4846 } 4847 } 4848 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 4849 if (phy->rf_ver == 0x2050) 4850 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 4851 4852 if (phy->gmode || phy->rev >= 2) { 4853 if (phy->rf_ver == 0x2050) { 4854 BWN_RF_SET(mac, 0x007a, 0x0020); 4855 BWN_RF_SET(mac, 0x0051, 0x0004); 4856 } 4857 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 4858 4859 BWN_PHY_SET(mac, 0x0802, 0x0100); 4860 BWN_PHY_SET(mac, 0x042b, 0x2000); 4861 4862 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 4863 4864 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 4865 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 4866 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 4867 } 4868 4869 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 4870 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 4871 4872 if (phy->analog == 1) { 4873 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 4874 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 4875 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 4876 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 4877 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 4878 } else 4879 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 4880 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 4881 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 4882 4883 if (phy->analog == 1) 4884 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 4885 else 4886 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 4887 4888 if (phy->analog == 0) 4889 BWN_WRITE_2(mac, 0x03e4, 0x3000); 4890 4891 old_channel = phy->chan; 4892 bwn_phy_g_switch_chan(mac, 7, 0); 4893 4894 if (phy->rf_ver != 0x2050) { 4895 BWN_RF_WRITE(mac, 0x0075, 0x0080); 4896 BWN_RF_WRITE(mac, 0x0079, 0x0081); 4897 } 4898 4899 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4900 BWN_RF_WRITE(mac, 0x0050, 0x0023); 4901 4902 if (phy->rf_ver == 0x2050) { 4903 BWN_RF_WRITE(mac, 0x0050, 0x0020); 4904 BWN_RF_WRITE(mac, 0x005a, 0x0070); 4905 } 4906 4907 BWN_RF_WRITE(mac, 0x005b, 0x007b); 4908 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 4909 BWN_RF_SET(mac, 0x007a, 0x0007); 4910 4911 bwn_phy_g_switch_chan(mac, old_channel, 0); 4912 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 4913 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 4914 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 4915 4916 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 4917 pg->pg_txctl); 4918 4919 if (phy->rf_ver == 0x2050) 4920 BWN_RF_WRITE(mac, 0x005d, 0x000d); 4921 4922 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 4923 } 4924 4925 static void 4926 bwn_loopback_calcgain(struct bwn_mac *mac) 4927 { 4928 struct bwn_phy *phy = &mac->mac_phy; 4929 struct bwn_phy_g *pg = &phy->phy_g; 4930 struct bwn_softc *sc = mac->mac_sc; 4931 uint16_t backup_phy[16] = { 0 }; 4932 uint16_t backup_radio[3]; 4933 uint16_t backup_bband; 4934 uint16_t i, j, loop_i_max; 4935 uint16_t trsw_rx; 4936 uint16_t loop1_outer_done, loop1_inner_done; 4937 4938 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 4939 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 4940 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 4941 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 4942 if (phy->rev != 1) { 4943 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 4944 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 4945 } 4946 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 4947 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 4948 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 4949 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 4950 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 4951 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 4952 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 4953 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 4954 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 4955 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 4956 backup_bband = pg->pg_bbatt.att; 4957 backup_radio[0] = BWN_RF_READ(mac, 0x52); 4958 backup_radio[1] = BWN_RF_READ(mac, 0x43); 4959 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 4960 4961 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 4962 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 4963 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 4964 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 4965 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 4966 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 4967 if (phy->rev != 1) { 4968 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 4969 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 4970 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 4971 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 4972 } 4973 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 4974 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 4975 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 4976 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 4977 4978 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 4979 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 4981 4982 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 4983 if (phy->rev != 1) { 4984 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 4985 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 4986 } 4987 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 4988 4989 if (phy->rf_rev == 8) 4990 BWN_RF_WRITE(mac, 0x43, 0x000f); 4991 else { 4992 BWN_RF_WRITE(mac, 0x52, 0); 4993 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 4994 } 4995 bwn_phy_g_set_bbatt(mac, 11); 4996 4997 if (phy->rev >= 3) 4998 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 4999 else 5000 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5001 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5002 5003 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 5004 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 5005 5006 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 5007 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 5008 5009 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) { 5010 if (phy->rev >= 7) { 5011 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 5012 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 5013 } 5014 } 5015 BWN_RF_MASK(mac, 0x7a, 0x00f7); 5016 5017 j = 0; 5018 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 5019 for (i = 0; i < loop_i_max; i++) { 5020 for (j = 0; j < 16; j++) { 5021 BWN_RF_WRITE(mac, 0x43, i); 5022 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 5023 (j << 8)); 5024 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5025 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5026 DELAY(20); 5027 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5028 goto done0; 5029 } 5030 } 5031 done0: 5032 loop1_outer_done = i; 5033 loop1_inner_done = j; 5034 if (j >= 8) { 5035 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 5036 trsw_rx = 0x1b; 5037 for (j = j - 8; j < 16; j++) { 5038 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 5039 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 5040 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 5041 DELAY(20); 5042 trsw_rx -= 3; 5043 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 5044 goto done1; 5045 } 5046 } else 5047 trsw_rx = 0x18; 5048 done1: 5049 5050 if (phy->rev != 1) { 5051 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 5052 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 5053 } 5054 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 5055 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 5059 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 5060 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 5061 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 5062 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 5063 5064 bwn_phy_g_set_bbatt(mac, backup_bband); 5065 5066 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 5067 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 5068 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 5069 5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 5071 DELAY(10); 5072 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 5073 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 5074 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 5075 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 5076 5077 pg->pg_max_lb_gain = 5078 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 5079 pg->pg_trsw_rx_gain = trsw_rx * 2; 5080 } 5081 5082 static uint16_t 5083 bwn_rf_init_bcm2050(struct bwn_mac *mac) 5084 { 5085 struct bwn_phy *phy = &mac->mac_phy; 5086 uint32_t tmp1 = 0, tmp2 = 0; 5087 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 5088 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 5089 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 5090 static const uint8_t rcc_table[] = { 5091 0x02, 0x03, 0x01, 0x0f, 5092 0x06, 0x07, 0x05, 0x0f, 5093 0x0a, 0x0b, 0x09, 0x0f, 5094 0x0e, 0x0f, 0x0d, 0x0f, 5095 }; 5096 5097 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 5098 rfoverval = rfover = cck3 = 0; 5099 radio0 = BWN_RF_READ(mac, 0x43); 5100 radio1 = BWN_RF_READ(mac, 0x51); 5101 radio2 = BWN_RF_READ(mac, 0x52); 5102 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 5103 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 5104 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 5105 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 5106 5107 if (phy->type == BWN_PHYTYPE_B) { 5108 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 5109 reg0 = BWN_READ_2(mac, 0x3ec); 5110 5111 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 5112 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 5113 } else if (phy->gmode || phy->rev >= 2) { 5114 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 5115 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 5116 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 5117 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 5118 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 5119 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 5120 5121 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 5122 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 5123 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 5124 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 5125 if (BWN_HAS_LOOPBACK(phy)) { 5126 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 5127 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 5128 if (phy->rev >= 3) 5129 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 5130 else 5131 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 5132 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 5133 } 5134 5135 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5136 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5137 BWN_LPD(0, 1, 1))); 5138 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 5139 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 5140 } 5141 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 5142 5143 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 5144 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 5145 reg1 = BWN_READ_2(mac, 0x3e6); 5146 reg2 = BWN_READ_2(mac, 0x3f4); 5147 5148 if (phy->analog == 0) 5149 BWN_WRITE_2(mac, 0x03e6, 0x0122); 5150 else { 5151 if (phy->analog >= 2) 5152 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 5153 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 5154 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 5155 } 5156 5157 reg = BWN_RF_READ(mac, 0x60); 5158 index = (reg & 0x001e) >> 1; 5159 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 5160 5161 if (phy->type == BWN_PHYTYPE_B) 5162 BWN_RF_WRITE(mac, 0x78, 0x26); 5163 if (phy->gmode || phy->rev >= 2) { 5164 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5165 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5166 BWN_LPD(0, 1, 1))); 5167 } 5168 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 5169 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 5170 if (phy->gmode || phy->rev >= 2) { 5171 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5172 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 5173 BWN_LPD(0, 0, 1))); 5174 } 5175 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 5176 BWN_RF_SET(mac, 0x51, 0x0004); 5177 if (phy->rf_rev == 8) 5178 BWN_RF_WRITE(mac, 0x43, 0x1f); 5179 else { 5180 BWN_RF_WRITE(mac, 0x52, 0); 5181 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 5182 } 5183 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5184 5185 for (i = 0; i < 16; i++) { 5186 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 5187 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5189 if (phy->gmode || phy->rev >= 2) { 5190 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5191 bwn_rf_2050_rfoverval(mac, 5192 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5193 } 5194 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5195 DELAY(10); 5196 if (phy->gmode || phy->rev >= 2) { 5197 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5198 bwn_rf_2050_rfoverval(mac, 5199 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5200 } 5201 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5202 DELAY(10); 5203 if (phy->gmode || phy->rev >= 2) { 5204 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5205 bwn_rf_2050_rfoverval(mac, 5206 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5207 } 5208 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5209 DELAY(20); 5210 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5211 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5212 if (phy->gmode || phy->rev >= 2) { 5213 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5214 bwn_rf_2050_rfoverval(mac, 5215 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5216 } 5217 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5218 } 5219 DELAY(10); 5220 5221 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5222 tmp1++; 5223 tmp1 >>= 9; 5224 5225 for (i = 0; i < 16; i++) { 5226 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 5227 BWN_RF_WRITE(mac, 0x78, radio78); 5228 DELAY(10); 5229 for (j = 0; j < 16; j++) { 5230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 5231 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 5232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 5233 if (phy->gmode || phy->rev >= 2) { 5234 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5235 bwn_rf_2050_rfoverval(mac, 5236 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5237 } 5238 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5239 DELAY(10); 5240 if (phy->gmode || phy->rev >= 2) { 5241 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5242 bwn_rf_2050_rfoverval(mac, 5243 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5244 } 5245 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 5246 DELAY(10); 5247 if (phy->gmode || phy->rev >= 2) { 5248 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5249 bwn_rf_2050_rfoverval(mac, 5250 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 5251 } 5252 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 5253 DELAY(10); 5254 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5255 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 5256 if (phy->gmode || phy->rev >= 2) { 5257 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 5258 bwn_rf_2050_rfoverval(mac, 5259 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 5260 } 5261 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 5262 } 5263 tmp2++; 5264 tmp2 >>= 8; 5265 if (tmp1 < tmp2) 5266 break; 5267 } 5268 5269 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 5270 BWN_RF_WRITE(mac, 0x51, radio1); 5271 BWN_RF_WRITE(mac, 0x52, radio2); 5272 BWN_RF_WRITE(mac, 0x43, radio0); 5273 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 5274 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 5276 BWN_WRITE_2(mac, 0x3e6, reg1); 5277 if (phy->analog != 0) 5278 BWN_WRITE_2(mac, 0x3f4, reg2); 5279 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 5280 bwn_spu_workaround(mac, phy->chan); 5281 if (phy->type == BWN_PHYTYPE_B) { 5282 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 5283 BWN_WRITE_2(mac, 0x3ec, reg0); 5284 } else if (phy->gmode) { 5285 BWN_WRITE_2(mac, BWN_PHY_RADIO, 5286 BWN_READ_2(mac, BWN_PHY_RADIO) 5287 & 0x7fff); 5288 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 5289 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 5290 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 5291 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 5292 analogoverval); 5293 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 5294 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 5295 if (BWN_HAS_LOOPBACK(phy)) { 5296 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 5297 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 5298 } 5299 } 5300 5301 return ((i > 15) ? radio78 : rcc); 5302 } 5303 5304 static void 5305 bwn_phy_init_b6(struct bwn_mac *mac) 5306 { 5307 struct bwn_phy *phy = &mac->mac_phy; 5308 struct bwn_phy_g *pg = &phy->phy_g; 5309 struct bwn_softc *sc = mac->mac_sc; 5310 uint16_t offset, val; 5311 uint8_t old_channel; 5312 5313 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 5314 ("%s:%d: fail", __func__, __LINE__)); 5315 5316 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 5317 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 5318 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 5319 BWN_RF_WRITE(mac, 0x51, 0x37); 5320 BWN_RF_WRITE(mac, 0x52, 0x70); 5321 BWN_RF_WRITE(mac, 0x53, 0xb3); 5322 BWN_RF_WRITE(mac, 0x54, 0x9b); 5323 BWN_RF_WRITE(mac, 0x5a, 0x88); 5324 BWN_RF_WRITE(mac, 0x5b, 0x88); 5325 BWN_RF_WRITE(mac, 0x5d, 0x88); 5326 BWN_RF_WRITE(mac, 0x5e, 0x88); 5327 BWN_RF_WRITE(mac, 0x7d, 0x88); 5328 bwn_hf_write(mac, 5329 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 5330 } 5331 if (phy->rf_rev == 8) { 5332 BWN_RF_WRITE(mac, 0x51, 0); 5333 BWN_RF_WRITE(mac, 0x52, 0x40); 5334 BWN_RF_WRITE(mac, 0x53, 0xb7); 5335 BWN_RF_WRITE(mac, 0x54, 0x98); 5336 BWN_RF_WRITE(mac, 0x5a, 0x88); 5337 BWN_RF_WRITE(mac, 0x5b, 0x6b); 5338 BWN_RF_WRITE(mac, 0x5c, 0x0f); 5339 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) { 5340 BWN_RF_WRITE(mac, 0x5d, 0xfa); 5341 BWN_RF_WRITE(mac, 0x5e, 0xd8); 5342 } else { 5343 BWN_RF_WRITE(mac, 0x5d, 0xf5); 5344 BWN_RF_WRITE(mac, 0x5e, 0xb8); 5345 } 5346 BWN_RF_WRITE(mac, 0x0073, 0x0003); 5347 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 5348 BWN_RF_WRITE(mac, 0x007c, 0x0001); 5349 BWN_RF_WRITE(mac, 0x007e, 0x0008); 5350 } 5351 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 5352 BWN_PHY_WRITE(mac, offset, val); 5353 val -= 0x0202; 5354 } 5355 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 5356 BWN_PHY_WRITE(mac, offset, val); 5357 val -= 0x0202; 5358 } 5359 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 5360 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 5361 val += 0x0202; 5362 } 5363 if (phy->type == BWN_PHYTYPE_G) { 5364 BWN_RF_SET(mac, 0x007a, 0x0020); 5365 BWN_RF_SET(mac, 0x0051, 0x0004); 5366 BWN_PHY_SET(mac, 0x0802, 0x0100); 5367 BWN_PHY_SET(mac, 0x042b, 0x2000); 5368 BWN_PHY_WRITE(mac, 0x5b, 0); 5369 BWN_PHY_WRITE(mac, 0x5c, 0); 5370 } 5371 5372 old_channel = phy->chan; 5373 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 5374 5375 BWN_RF_WRITE(mac, 0x0050, 0x0020); 5376 BWN_RF_WRITE(mac, 0x0050, 0x0023); 5377 DELAY(40); 5378 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 5379 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 5380 BWN_RF_WRITE(mac, 0x50, 0x20); 5381 } 5382 if (phy->rf_rev <= 2) { 5383 BWN_RF_WRITE(mac, 0x7c, 0x20); 5384 BWN_RF_WRITE(mac, 0x5a, 0x70); 5385 BWN_RF_WRITE(mac, 0x5b, 0x7b); 5386 BWN_RF_WRITE(mac, 0x5c, 0xb0); 5387 } 5388 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 5389 5390 bwn_phy_g_switch_chan(mac, old_channel, 0); 5391 5392 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 5393 if (phy->rf_rev >= 6) 5394 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 5395 else 5396 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 5397 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 5398 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 5399 pg->pg_txctl); 5400 if (phy->rf_rev <= 5) 5401 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 5402 if (phy->rf_rev <= 2) 5403 BWN_RF_WRITE(mac, 0x005d, 0x000d); 5404 5405 if (phy->analog == 4) { 5406 BWN_WRITE_2(mac, 0x3e4, 9); 5407 BWN_PHY_MASK(mac, 0x61, 0x0fff); 5408 } else 5409 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 5410 if (phy->type == BWN_PHYTYPE_B) 5411 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5412 else if (phy->type == BWN_PHYTYPE_G) 5413 BWN_WRITE_2(mac, 0x03e6, 0x0); 5414 } 5415 5416 static void 5417 bwn_phy_init_a(struct bwn_mac *mac) 5418 { 5419 struct bwn_phy *phy = &mac->mac_phy; 5420 struct bwn_softc *sc = mac->mac_sc; 5421 5422 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 5423 ("%s:%d: fail", __func__, __LINE__)); 5424 5425 if (phy->rev >= 6) { 5426 if (phy->type == BWN_PHYTYPE_A) 5427 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 5428 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 5429 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 5430 else 5431 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 5432 } 5433 5434 bwn_wa_init(mac); 5435 5436 if (phy->type == BWN_PHYTYPE_G && 5437 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)) 5438 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 5439 } 5440 5441 static void 5442 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 5443 { 5444 int i; 5445 5446 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 5447 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 5448 } 5449 5450 static void 5451 bwn_wa_agc(struct bwn_mac *mac) 5452 { 5453 struct bwn_phy *phy = &mac->mac_phy; 5454 5455 if (phy->rev == 1) { 5456 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 5464 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 5465 } else { 5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 5467 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 5470 } 5471 5472 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 5473 0x5700); 5474 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 5475 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 5476 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 5477 BWN_RF_SET(mac, 0x7a, 0x0008); 5478 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 5479 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 5480 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 5481 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 5482 if (phy->rev == 1) 5483 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 5484 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 5493 if (phy->rev == 1) { 5494 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 5495 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 5496 } else { 5497 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 5498 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 5499 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 5500 if (phy->rev >= 6) { 5501 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 5502 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 5503 (uint16_t)~0xf000, 0x3000); 5504 } 5505 } 5506 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 5507 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 5508 if (phy->rev == 1) { 5509 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 5510 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 5511 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 5512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 5513 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 5517 } else { 5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 5522 } 5523 if (phy->rev >= 6) { 5524 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 5525 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 5526 } 5527 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 5528 } 5529 5530 static void 5531 bwn_wa_grev1(struct bwn_mac *mac) 5532 { 5533 struct bwn_phy *phy = &mac->mac_phy; 5534 int i; 5535 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 5536 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 5537 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 5538 5539 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5540 5541 /* init CRSTHRES and ANTDWELL */ 5542 if (phy->rev == 1) { 5543 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5544 } else if (phy->rev == 2) { 5545 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5546 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5547 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5548 } else { 5549 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5550 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5551 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5552 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5553 } 5554 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 5555 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 5556 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 5557 5558 /* XXX support PHY-A??? */ 5559 for (i = 0; i < N(bwn_tab_finefreqg); i++) 5560 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 5561 bwn_tab_finefreqg[i]); 5562 5563 /* XXX support PHY-A??? */ 5564 if (phy->rev == 1) 5565 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5567 bwn_tab_noise_g1[i]); 5568 else 5569 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5570 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5571 bwn_tab_noise_g2[i]); 5572 5573 5574 for (i = 0; i < N(bwn_tab_rotor); i++) 5575 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 5576 bwn_tab_rotor[i]); 5577 5578 /* XXX support PHY-A??? */ 5579 if (phy->rev >= 6) { 5580 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5581 BWN_PHY_ENCORE_EN) 5582 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5583 else 5584 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5585 } else 5586 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5587 5588 for (i = 0; i < N(bwn_tab_retard); i++) 5589 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 5590 bwn_tab_retard[i]); 5591 5592 if (phy->rev == 1) { 5593 for (i = 0; i < 16; i++) 5594 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 5595 i, 0x0020); 5596 } else { 5597 for (i = 0; i < 32; i++) 5598 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5599 } 5600 5601 bwn_wa_agc(mac); 5602 } 5603 5604 static void 5605 bwn_wa_grev26789(struct bwn_mac *mac) 5606 { 5607 struct bwn_phy *phy = &mac->mac_phy; 5608 int i; 5609 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 5610 uint16_t ofdmrev; 5611 5612 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5613 5614 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 5615 5616 /* init CRSTHRES and ANTDWELL */ 5617 if (phy->rev == 1) 5618 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 5619 else if (phy->rev == 2) { 5620 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 5621 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 5622 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5623 } else { 5624 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 5625 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 5626 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 5627 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 5628 } 5629 5630 for (i = 0; i < 64; i++) 5631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 5632 5633 /* XXX support PHY-A??? */ 5634 if (phy->rev == 1) 5635 for (i = 0; i < N(bwn_tab_noise_g1); i++) 5636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5637 bwn_tab_noise_g1[i]); 5638 else 5639 for (i = 0; i < N(bwn_tab_noise_g2); i++) 5640 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 5641 bwn_tab_noise_g2[i]); 5642 5643 /* XXX support PHY-A??? */ 5644 if (phy->rev >= 6) { 5645 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 5646 BWN_PHY_ENCORE_EN) 5647 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 5648 else 5649 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 5650 } else 5651 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 5652 5653 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 5654 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 5655 bwn_tab_sigmasqr2[i]); 5656 5657 if (phy->rev == 1) { 5658 for (i = 0; i < 16; i++) 5659 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 5660 0x0020); 5661 } else { 5662 for (i = 0; i < 32; i++) 5663 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 5664 } 5665 5666 bwn_wa_agc(mac); 5667 5668 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 5669 if (ofdmrev > 2) { 5670 if (phy->type == BWN_PHYTYPE_A) 5671 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 5672 else 5673 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 5674 } else { 5675 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 5676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 5678 } 5679 5680 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 5681 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 5682 } 5683 5684 static void 5685 bwn_wa_init(struct bwn_mac *mac) 5686 { 5687 struct bwn_phy *phy = &mac->mac_phy; 5688 struct bwn_softc *sc = mac->mac_sc; 5689 5690 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 5691 5692 switch (phy->rev) { 5693 case 1: 5694 bwn_wa_grev1(mac); 5695 break; 5696 case 2: 5697 case 6: 5698 case 7: 5699 case 8: 5700 case 9: 5701 bwn_wa_grev26789(mac); 5702 break; 5703 default: 5704 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5705 } 5706 5707 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM || 5708 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 || 5709 siba_get_pci_revid(sc->sc_dev) != 0x17) { 5710 if (phy->rev < 2) { 5711 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 5712 0x0002); 5713 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 5714 0x0001); 5715 } else { 5716 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 5717 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 5718 if ((siba_sprom_get_bf_lo(sc->sc_dev) & 5719 BWN_BFL_EXTLNA) && 5720 (phy->rev >= 7)) { 5721 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 5722 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5723 0x0020, 0x0001); 5724 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5725 0x0021, 0x0001); 5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5727 0x0022, 0x0001); 5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5729 0x0023, 0x0000); 5730 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5731 0x0000, 0x0000); 5732 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 5733 0x0003, 0x0002); 5734 } 5735 } 5736 } 5737 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) { 5738 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 5739 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 5740 } 5741 5742 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 5743 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 5744 } 5745 5746 static void 5747 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5748 uint16_t value) 5749 { 5750 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5751 uint16_t addr; 5752 5753 addr = table + offset; 5754 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5755 (addr - 1 != pg->pg_ofdmtab_addr)) { 5756 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5757 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5758 } 5759 pg->pg_ofdmtab_addr = addr; 5760 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5761 } 5762 5763 static void 5764 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5765 uint32_t value) 5766 { 5767 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5768 uint16_t addr; 5769 5770 addr = table + offset; 5771 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 5772 (addr - 1 != pg->pg_ofdmtab_addr)) { 5773 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 5774 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 5775 } 5776 pg->pg_ofdmtab_addr = addr; 5777 5778 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 5779 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 5780 } 5781 5782 static void 5783 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 5784 uint16_t value) 5785 { 5786 5787 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 5788 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 5789 } 5790 5791 static void 5792 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 5793 { 5794 struct bwn_phy *phy = &mac->mac_phy; 5795 struct bwn_softc *sc = mac->mac_sc; 5796 unsigned int i, max_loop; 5797 uint16_t value; 5798 uint32_t buffer[5] = { 5799 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 5800 }; 5801 5802 if (ofdm) { 5803 max_loop = 0x1e; 5804 buffer[0] = 0x000201cc; 5805 } else { 5806 max_loop = 0xfa; 5807 buffer[0] = 0x000b846e; 5808 } 5809 5810 BWN_ASSERT_LOCKED(mac->mac_sc); 5811 5812 for (i = 0; i < 5; i++) 5813 bwn_ram_write(mac, i * 4, buffer[i]); 5814 5815 BWN_WRITE_2(mac, 0x0568, 0x0000); 5816 BWN_WRITE_2(mac, 0x07c0, 5817 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 5818 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40); 5819 BWN_WRITE_2(mac, 0x050c, value); 5820 if (phy->type == BWN_PHYTYPE_LP) 5821 BWN_WRITE_2(mac, 0x0514, 0x1a02); 5822 BWN_WRITE_2(mac, 0x0508, 0x0000); 5823 BWN_WRITE_2(mac, 0x050a, 0x0000); 5824 BWN_WRITE_2(mac, 0x054c, 0x0000); 5825 BWN_WRITE_2(mac, 0x056a, 0x0014); 5826 BWN_WRITE_2(mac, 0x0568, 0x0826); 5827 BWN_WRITE_2(mac, 0x0500, 0x0000); 5828 if (phy->type == BWN_PHYTYPE_LP) 5829 BWN_WRITE_2(mac, 0x0502, 0x0050); 5830 else 5831 BWN_WRITE_2(mac, 0x0502, 0x0030); 5832 5833 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5834 BWN_RF_WRITE(mac, 0x0051, 0x0017); 5835 for (i = 0x00; i < max_loop; i++) { 5836 value = BWN_READ_2(mac, 0x050e); 5837 if (value & 0x0080) 5838 break; 5839 DELAY(10); 5840 } 5841 for (i = 0x00; i < 0x0a; i++) { 5842 value = BWN_READ_2(mac, 0x050e); 5843 if (value & 0x0400) 5844 break; 5845 DELAY(10); 5846 } 5847 for (i = 0x00; i < 0x19; i++) { 5848 value = BWN_READ_2(mac, 0x0690); 5849 if (!(value & 0x0100)) 5850 break; 5851 DELAY(10); 5852 } 5853 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 5854 BWN_RF_WRITE(mac, 0x0051, 0x0037); 5855 } 5856 5857 static void 5858 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 5859 { 5860 uint32_t macctl; 5861 5862 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 5863 5864 macctl = BWN_READ_4(mac, BWN_MACCTL); 5865 if (macctl & BWN_MACCTL_BIGENDIAN) 5866 printf("TODO: need swap\n"); 5867 5868 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 5869 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5870 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 5871 } 5872 5873 static void 5874 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 5875 { 5876 uint16_t value; 5877 5878 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 5879 ("%s:%d: fail", __func__, __LINE__)); 5880 5881 value = (uint8_t) (ctl->q); 5882 value |= ((uint8_t) (ctl->i)) << 8; 5883 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 5884 } 5885 5886 static uint16_t 5887 bwn_lo_calcfeed(struct bwn_mac *mac, 5888 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 5889 { 5890 struct bwn_phy *phy = &mac->mac_phy; 5891 struct bwn_softc *sc = mac->mac_sc; 5892 uint16_t rfover; 5893 uint16_t feedthrough; 5894 5895 if (phy->gmode) { 5896 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 5897 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 5898 5899 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 5900 ("%s:%d: fail", __func__, __LINE__)); 5901 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 5902 ("%s:%d: fail", __func__, __LINE__)); 5903 5904 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 5905 5906 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 5907 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && 5908 phy->rev > 6) 5909 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 5910 5911 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 5912 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5913 DELAY(10); 5914 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 5915 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5916 DELAY(10); 5917 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 5918 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 5919 DELAY(10); 5920 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 5921 } else { 5922 pga |= BWN_PHY_PGACTL_UNKNOWN; 5923 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5924 DELAY(10); 5925 pga |= BWN_PHY_PGACTL_LOWBANDW; 5926 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5927 DELAY(10); 5928 pga |= BWN_PHY_PGACTL_LPF; 5929 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 5930 } 5931 DELAY(21); 5932 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 5933 5934 return (feedthrough); 5935 } 5936 5937 static uint16_t 5938 bwn_lo_txctl_regtable(struct bwn_mac *mac, 5939 uint16_t *value, uint16_t *pad_mix_gain) 5940 { 5941 struct bwn_phy *phy = &mac->mac_phy; 5942 uint16_t reg, v, padmix; 5943 5944 if (phy->type == BWN_PHYTYPE_B) { 5945 v = 0x30; 5946 if (phy->rf_rev <= 5) { 5947 reg = 0x43; 5948 padmix = 0; 5949 } else { 5950 reg = 0x52; 5951 padmix = 5; 5952 } 5953 } else { 5954 if (phy->rev >= 2 && phy->rf_rev == 8) { 5955 reg = 0x43; 5956 v = 0x10; 5957 padmix = 2; 5958 } else { 5959 reg = 0x52; 5960 v = 0x30; 5961 padmix = 5; 5962 } 5963 } 5964 if (value) 5965 *value = v; 5966 if (pad_mix_gain) 5967 *pad_mix_gain = padmix; 5968 5969 return (reg); 5970 } 5971 5972 static void 5973 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 5974 { 5975 struct bwn_phy *phy = &mac->mac_phy; 5976 struct bwn_phy_g *pg = &phy->phy_g; 5977 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 5978 uint16_t reg, mask; 5979 uint16_t trsw_rx, pga; 5980 uint16_t rf_pctl_reg; 5981 5982 static const uint8_t tx_bias_values[] = { 5983 0x09, 0x08, 0x0a, 0x01, 0x00, 5984 0x02, 0x05, 0x04, 0x06, 5985 }; 5986 static const uint8_t tx_magn_values[] = { 5987 0x70, 0x40, 5988 }; 5989 5990 if (!BWN_HAS_LOOPBACK(phy)) { 5991 rf_pctl_reg = 6; 5992 trsw_rx = 2; 5993 pga = 0; 5994 } else { 5995 int lb_gain; 5996 5997 trsw_rx = 0; 5998 lb_gain = pg->pg_max_lb_gain / 2; 5999 if (lb_gain > 10) { 6000 rf_pctl_reg = 0; 6001 pga = abs(10 - lb_gain) / 6; 6002 pga = MIN(MAX(pga, 0), 15); 6003 } else { 6004 int cmp_val; 6005 int tmp; 6006 6007 pga = 0; 6008 cmp_val = 0x24; 6009 if ((phy->rev >= 2) && 6010 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 6011 cmp_val = 0x3c; 6012 tmp = lb_gain; 6013 if ((10 - lb_gain) < cmp_val) 6014 tmp = (10 - lb_gain); 6015 if (tmp < 0) 6016 tmp += 6; 6017 else 6018 tmp += 3; 6019 cmp_val /= 4; 6020 tmp /= 4; 6021 if (tmp >= cmp_val) 6022 rf_pctl_reg = cmp_val; 6023 else 6024 rf_pctl_reg = tmp; 6025 } 6026 } 6027 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 6028 bwn_phy_g_set_bbatt(mac, 2); 6029 6030 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 6031 mask = ~mask; 6032 BWN_RF_MASK(mac, reg, mask); 6033 6034 if (BWN_HAS_TXMAG(phy)) { 6035 int i, j; 6036 int feedthrough; 6037 int min_feedth = 0xffff; 6038 uint8_t tx_magn, tx_bias; 6039 6040 for (i = 0; i < N(tx_magn_values); i++) { 6041 tx_magn = tx_magn_values[i]; 6042 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 6043 for (j = 0; j < N(tx_bias_values); j++) { 6044 tx_bias = tx_bias_values[j]; 6045 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 6046 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 6047 trsw_rx); 6048 if (feedthrough < min_feedth) { 6049 lo->tx_bias = tx_bias; 6050 lo->tx_magn = tx_magn; 6051 min_feedth = feedthrough; 6052 } 6053 if (lo->tx_bias == 0) 6054 break; 6055 } 6056 BWN_RF_WRITE(mac, 0x52, 6057 (BWN_RF_READ(mac, 0x52) 6058 & 0xff00) | lo->tx_bias | lo-> 6059 tx_magn); 6060 } 6061 } else { 6062 lo->tx_magn = 0; 6063 lo->tx_bias = 0; 6064 BWN_RF_MASK(mac, 0x52, 0xfff0); 6065 } 6066 6067 BWN_GETTIME(lo->txctl_measured_time); 6068 } 6069 6070 static void 6071 bwn_lo_get_powervector(struct bwn_mac *mac) 6072 { 6073 struct bwn_phy *phy = &mac->mac_phy; 6074 struct bwn_phy_g *pg = &phy->phy_g; 6075 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6076 int i; 6077 uint64_t tmp; 6078 uint64_t power_vector = 0; 6079 6080 for (i = 0; i < 8; i += 2) { 6081 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 6082 power_vector |= (tmp << (i * 8)); 6083 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 6084 } 6085 if (power_vector) 6086 lo->power_vector = power_vector; 6087 6088 BWN_GETTIME(lo->pwr_vec_read_time); 6089 } 6090 6091 static void 6092 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 6093 int use_trsw_rx) 6094 { 6095 struct bwn_phy *phy = &mac->mac_phy; 6096 struct bwn_phy_g *pg = &phy->phy_g; 6097 uint16_t tmp; 6098 6099 if (max_rx_gain < 0) 6100 max_rx_gain = 0; 6101 6102 if (BWN_HAS_LOOPBACK(phy)) { 6103 int trsw_rx = 0; 6104 int trsw_rx_gain; 6105 6106 if (use_trsw_rx) { 6107 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 6108 if (max_rx_gain >= trsw_rx_gain) { 6109 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 6110 trsw_rx = 0x20; 6111 } 6112 } else 6113 trsw_rx_gain = max_rx_gain; 6114 if (trsw_rx_gain < 9) { 6115 pg->pg_lna_lod_gain = 0; 6116 } else { 6117 pg->pg_lna_lod_gain = 1; 6118 trsw_rx_gain -= 8; 6119 } 6120 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 6121 pg->pg_pga_gain = trsw_rx_gain / 3; 6122 if (pg->pg_pga_gain >= 5) { 6123 pg->pg_pga_gain -= 5; 6124 pg->pg_lna_gain = 2; 6125 } else 6126 pg->pg_lna_gain = 0; 6127 } else { 6128 pg->pg_lna_gain = 0; 6129 pg->pg_trsw_rx_gain = 0x20; 6130 if (max_rx_gain >= 0x14) { 6131 pg->pg_lna_lod_gain = 1; 6132 pg->pg_pga_gain = 2; 6133 } else if (max_rx_gain >= 0x12) { 6134 pg->pg_lna_lod_gain = 1; 6135 pg->pg_pga_gain = 1; 6136 } else if (max_rx_gain >= 0xf) { 6137 pg->pg_lna_lod_gain = 1; 6138 pg->pg_pga_gain = 0; 6139 } else { 6140 pg->pg_lna_lod_gain = 0; 6141 pg->pg_pga_gain = 0; 6142 } 6143 } 6144 6145 tmp = BWN_RF_READ(mac, 0x7a); 6146 if (pg->pg_lna_lod_gain == 0) 6147 tmp &= ~0x0008; 6148 else 6149 tmp |= 0x0008; 6150 BWN_RF_WRITE(mac, 0x7a, tmp); 6151 } 6152 6153 static void 6154 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6155 { 6156 struct bwn_phy *phy = &mac->mac_phy; 6157 struct bwn_phy_g *pg = &phy->phy_g; 6158 struct bwn_softc *sc = mac->mac_sc; 6159 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6160 struct timespec ts; 6161 uint16_t tmp; 6162 6163 if (bwn_has_hwpctl(mac)) { 6164 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 6165 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 6166 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6167 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 6168 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 6169 6170 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 6171 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 6172 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 6173 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 6174 } 6175 if (phy->type == BWN_PHYTYPE_B && 6176 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 6177 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 6178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 6179 } 6180 if (phy->rev >= 2) { 6181 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 6182 sav->phy_analogoverval = 6183 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 6184 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 6185 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 6186 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 6187 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 6188 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 6189 6190 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 6191 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 6192 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 6193 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 6194 if (phy->type == BWN_PHYTYPE_G) { 6195 if ((phy->rev >= 7) && 6196 (siba_sprom_get_bf_lo(sc->sc_dev) & 6197 BWN_BFL_EXTLNA)) { 6198 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 6199 } else { 6200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 6201 } 6202 } else { 6203 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 6204 } 6205 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 6206 } 6207 sav->reg0 = BWN_READ_2(mac, 0x3f4); 6208 sav->reg1 = BWN_READ_2(mac, 0x3e2); 6209 sav->rf0 = BWN_RF_READ(mac, 0x43); 6210 sav->rf1 = BWN_RF_READ(mac, 0x7a); 6211 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 6212 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 6213 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 6214 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 6215 6216 if (!BWN_HAS_TXMAG(phy)) { 6217 sav->rf2 = BWN_RF_READ(mac, 0x52); 6218 sav->rf2 &= 0x00f0; 6219 } 6220 if (phy->type == BWN_PHYTYPE_B) { 6221 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 6222 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 6223 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 6224 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 6225 } else { 6226 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 6227 | 0x8000); 6228 } 6229 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 6230 & 0xf000); 6231 6232 tmp = 6233 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 6234 BWN_PHY_WRITE(mac, tmp, 0x007f); 6235 6236 tmp = sav->phy_syncctl; 6237 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 6238 tmp = sav->rf1; 6239 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 6240 6241 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 6242 if (phy->type == BWN_PHYTYPE_G || 6243 (phy->type == BWN_PHYTYPE_B && 6244 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 6245 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 6246 } else 6247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 6248 if (phy->rev >= 2) 6249 bwn_dummy_transmission(mac, 0, 1); 6250 bwn_phy_g_switch_chan(mac, 6, 0); 6251 BWN_RF_READ(mac, 0x51); 6252 if (phy->type == BWN_PHYTYPE_G) 6253 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 6254 6255 nanouptime(&ts); 6256 if (time_before(lo->txctl_measured_time, 6257 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 6258 bwn_lo_measure_txctl_values(mac); 6259 6260 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 6261 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 6262 else { 6263 if (phy->type == BWN_PHYTYPE_B) 6264 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6265 else 6266 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 6267 } 6268 } 6269 6270 static void 6271 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 6272 { 6273 struct bwn_phy *phy = &mac->mac_phy; 6274 struct bwn_phy_g *pg = &phy->phy_g; 6275 uint16_t tmp; 6276 6277 if (phy->rev >= 2) { 6278 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 6279 tmp = (pg->pg_pga_gain << 8); 6280 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 6281 DELAY(5); 6282 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 6283 DELAY(2); 6284 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 6285 } else { 6286 tmp = (pg->pg_pga_gain | 0xefa0); 6287 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 6288 } 6289 if (phy->type == BWN_PHYTYPE_G) { 6290 if (phy->rev >= 3) 6291 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 6292 else 6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 6294 if (phy->rev >= 2) 6295 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 6296 else 6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 6298 } 6299 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 6300 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 6301 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 6302 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 6303 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 6304 BWN_RF_WRITE(mac, 0x43, sav->rf0); 6305 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 6306 if (!BWN_HAS_TXMAG(phy)) { 6307 tmp = sav->rf2; 6308 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 6309 } 6310 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 6311 if (phy->type == BWN_PHYTYPE_B && 6312 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 6313 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 6314 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 6315 } 6316 if (phy->rev >= 2) { 6317 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 6318 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 6319 sav->phy_analogoverval); 6320 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 6321 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 6322 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 6323 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 6324 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 6325 } 6326 if (bwn_has_hwpctl(mac)) { 6327 tmp = (sav->phy_lomask & 0xbfff); 6328 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 6329 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 6330 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 6331 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 6332 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 6333 } 6334 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 6335 } 6336 6337 static int 6338 bwn_lo_probe_loctl(struct bwn_mac *mac, 6339 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 6340 { 6341 struct bwn_phy *phy = &mac->mac_phy; 6342 struct bwn_phy_g *pg = &phy->phy_g; 6343 struct bwn_loctl orig, test; 6344 struct bwn_loctl prev = { -100, -100 }; 6345 static const struct bwn_loctl modifiers[] = { 6346 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 6347 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 6348 }; 6349 int begin, end, lower = 0, i; 6350 uint16_t feedth; 6351 6352 if (d->curstate == 0) { 6353 begin = 1; 6354 end = 8; 6355 } else if (d->curstate % 2 == 0) { 6356 begin = d->curstate - 1; 6357 end = d->curstate + 1; 6358 } else { 6359 begin = d->curstate - 2; 6360 end = d->curstate + 2; 6361 } 6362 if (begin < 1) 6363 begin += 8; 6364 if (end > 8) 6365 end -= 8; 6366 6367 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 6368 i = begin; 6369 d->curstate = i; 6370 while (1) { 6371 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 6372 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 6373 test.i += modifiers[i - 1].i * d->multipler; 6374 test.q += modifiers[i - 1].q * d->multipler; 6375 if ((test.i != prev.i || test.q != prev.q) && 6376 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 6377 bwn_lo_write(mac, &test); 6378 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6379 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6380 if (feedth < d->feedth) { 6381 memcpy(probe, &test, 6382 sizeof(struct bwn_loctl)); 6383 lower = 1; 6384 d->feedth = feedth; 6385 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 6386 break; 6387 } 6388 } 6389 memcpy(&prev, &test, sizeof(prev)); 6390 if (i == end) 6391 break; 6392 if (i == 8) 6393 i = 1; 6394 else 6395 i++; 6396 d->curstate = i; 6397 } 6398 6399 return (lower); 6400 } 6401 6402 static void 6403 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 6404 { 6405 struct bwn_phy *phy = &mac->mac_phy; 6406 struct bwn_phy_g *pg = &phy->phy_g; 6407 struct bwn_lo_g_sm d; 6408 struct bwn_loctl probe; 6409 int lower, repeat, cnt = 0; 6410 uint16_t feedth; 6411 6412 d.nmeasure = 0; 6413 d.multipler = 1; 6414 if (BWN_HAS_LOOPBACK(phy)) 6415 d.multipler = 3; 6416 6417 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 6418 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 6419 6420 do { 6421 bwn_lo_write(mac, &d.loctl); 6422 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6423 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6424 if (feedth < 0x258) { 6425 if (feedth >= 0x12c) 6426 *rxgain += 6; 6427 else 6428 *rxgain += 3; 6429 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 6430 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 6431 } 6432 d.feedth = feedth; 6433 d.curstate = 0; 6434 do { 6435 KASSERT(d.curstate >= 0 && d.curstate <= 8, 6436 ("%s:%d: fail", __func__, __LINE__)); 6437 memcpy(&probe, &d.loctl, 6438 sizeof(struct bwn_loctl)); 6439 lower = bwn_lo_probe_loctl(mac, &probe, &d); 6440 if (!lower) 6441 break; 6442 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 6443 break; 6444 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 6445 d.nmeasure++; 6446 } while (d.nmeasure < 24); 6447 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 6448 6449 if (BWN_HAS_LOOPBACK(phy)) { 6450 if (d.feedth > 0x1194) 6451 *rxgain -= 6; 6452 else if (d.feedth < 0x5dc) 6453 *rxgain += 3; 6454 if (cnt == 0) { 6455 if (d.feedth <= 0x5dc) { 6456 d.multipler = 1; 6457 cnt++; 6458 } else 6459 d.multipler = 2; 6460 } else if (cnt == 2) 6461 d.multipler = 1; 6462 } 6463 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 6464 } while (++cnt < repeat); 6465 } 6466 6467 static struct bwn_lo_calib * 6468 bwn_lo_calibset(struct bwn_mac *mac, 6469 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 6470 { 6471 struct bwn_phy *phy = &mac->mac_phy; 6472 struct bwn_phy_g *pg = &phy->phy_g; 6473 struct bwn_loctl loctl = { 0, 0 }; 6474 struct bwn_lo_calib *cal; 6475 struct bwn_lo_g_value sval = { 0 }; 6476 int rxgain; 6477 uint16_t pad, reg, value; 6478 6479 sval.old_channel = phy->chan; 6480 bwn_mac_suspend(mac); 6481 bwn_lo_save(mac, &sval); 6482 6483 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 6484 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 6485 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 6486 6487 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 6488 if (rfatt->padmix) 6489 rxgain -= pad; 6490 if (BWN_HAS_LOOPBACK(phy)) 6491 rxgain += pg->pg_max_lb_gain; 6492 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 6493 bwn_phy_g_set_bbatt(mac, bbatt->att); 6494 bwn_lo_probe_sm(mac, &loctl, &rxgain); 6495 6496 bwn_lo_restore(mac, &sval); 6497 bwn_mac_enable(mac); 6498 6499 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 6500 if (!cal) { 6501 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 6502 return (NULL); 6503 } 6504 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 6505 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 6506 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 6507 6508 BWN_GETTIME(cal->calib_time); 6509 6510 return (cal); 6511 } 6512 6513 static struct bwn_lo_calib * 6514 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 6515 const struct bwn_rfatt *rfatt) 6516 { 6517 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 6518 struct bwn_lo_calib *c; 6519 6520 TAILQ_FOREACH(c, &lo->calib_list, list) { 6521 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 6522 continue; 6523 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 6524 continue; 6525 return (c); 6526 } 6527 6528 c = bwn_lo_calibset(mac, bbatt, rfatt); 6529 if (!c) 6530 return (NULL); 6531 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 6532 6533 return (c); 6534 } 6535 6536 static void 6537 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 6538 { 6539 struct bwn_phy *phy = &mac->mac_phy; 6540 struct bwn_phy_g *pg = &phy->phy_g; 6541 struct bwn_softc *sc = mac->mac_sc; 6542 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 6543 const struct bwn_rfatt *rfatt; 6544 const struct bwn_bbatt *bbatt; 6545 uint64_t pvector; 6546 int i; 6547 int rf_offset, bb_offset; 6548 uint8_t changed = 0; 6549 6550 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 6551 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 6552 ("%s:%d: fail", __func__, __LINE__)); 6553 6554 pvector = lo->power_vector; 6555 if (!update && !pvector) 6556 return; 6557 6558 bwn_mac_suspend(mac); 6559 6560 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 6561 struct bwn_lo_calib *cal; 6562 int idx; 6563 uint16_t val; 6564 6565 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 6566 continue; 6567 bb_offset = i / lo->rfatt.len; 6568 rf_offset = i % lo->rfatt.len; 6569 bbatt = &(lo->bbatt.array[bb_offset]); 6570 rfatt = &(lo->rfatt.array[rf_offset]); 6571 6572 cal = bwn_lo_calibset(mac, bbatt, rfatt); 6573 if (!cal) { 6574 device_printf(sc->sc_dev, "LO: Could not " 6575 "calibrate DC table entry\n"); 6576 continue; 6577 } 6578 val = (uint8_t)(cal->ctl.q); 6579 val |= ((uint8_t)(cal->ctl.i)) << 4; 6580 free(cal, M_DEVBUF); 6581 6582 idx = i / 2; 6583 if (i % 2) 6584 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 6585 | ((val & 0x00ff) << 8); 6586 else 6587 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 6588 | (val & 0x00ff); 6589 changed = 1; 6590 } 6591 if (changed) { 6592 for (i = 0; i < BWN_DC_LT_SIZE; i++) 6593 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 6594 } 6595 bwn_mac_enable(mac); 6596 } 6597 6598 static void 6599 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 6600 { 6601 6602 if (!rf->padmix) 6603 return; 6604 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 6605 rf->att = 4; 6606 } 6607 6608 static void 6609 bwn_lo_g_adjust(struct bwn_mac *mac) 6610 { 6611 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 6612 struct bwn_lo_calib *cal; 6613 struct bwn_rfatt rf; 6614 6615 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 6616 bwn_lo_fixup_rfatt(&rf); 6617 6618 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 6619 if (!cal) 6620 return; 6621 bwn_lo_write(mac, &cal->ctl); 6622 } 6623 6624 static void 6625 bwn_lo_g_init(struct bwn_mac *mac) 6626 { 6627 6628 if (!bwn_has_hwpctl(mac)) 6629 return; 6630 6631 bwn_lo_get_powervector(mac); 6632 bwn_phy_g_dc_lookup_init(mac, 1); 6633 } 6634 6635 static void 6636 bwn_mac_suspend(struct bwn_mac *mac) 6637 { 6638 struct bwn_softc *sc = mac->mac_sc; 6639 int i; 6640 uint32_t tmp; 6641 6642 KASSERT(mac->mac_suspended >= 0, 6643 ("%s:%d: fail", __func__, __LINE__)); 6644 6645 if (mac->mac_suspended == 0) { 6646 bwn_psctl(mac, BWN_PS_AWAKE); 6647 BWN_WRITE_4(mac, BWN_MACCTL, 6648 BWN_READ_4(mac, BWN_MACCTL) 6649 & ~BWN_MACCTL_ON); 6650 BWN_READ_4(mac, BWN_MACCTL); 6651 for (i = 35; i; i--) { 6652 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6653 if (tmp & BWN_INTR_MAC_SUSPENDED) 6654 goto out; 6655 DELAY(10); 6656 } 6657 for (i = 40; i; i--) { 6658 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 6659 if (tmp & BWN_INTR_MAC_SUSPENDED) 6660 goto out; 6661 DELAY(1000); 6662 } 6663 device_printf(sc->sc_dev, "MAC suspend failed\n"); 6664 } 6665 out: 6666 mac->mac_suspended++; 6667 } 6668 6669 static void 6670 bwn_mac_enable(struct bwn_mac *mac) 6671 { 6672 struct bwn_softc *sc = mac->mac_sc; 6673 uint16_t state; 6674 6675 state = bwn_shm_read_2(mac, BWN_SHARED, 6676 BWN_SHARED_UCODESTAT); 6677 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 6678 state != BWN_SHARED_UCODESTAT_SLEEP) 6679 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 6680 6681 mac->mac_suspended--; 6682 KASSERT(mac->mac_suspended >= 0, 6683 ("%s:%d: fail", __func__, __LINE__)); 6684 if (mac->mac_suspended == 0) { 6685 BWN_WRITE_4(mac, BWN_MACCTL, 6686 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 6687 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 6688 BWN_READ_4(mac, BWN_MACCTL); 6689 BWN_READ_4(mac, BWN_INTR_REASON); 6690 bwn_psctl(mac, 0); 6691 } 6692 } 6693 6694 static void 6695 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 6696 { 6697 struct bwn_softc *sc = mac->mac_sc; 6698 int i; 6699 uint16_t ucstat; 6700 6701 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 6702 ("%s:%d: fail", __func__, __LINE__)); 6703 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 6704 ("%s:%d: fail", __func__, __LINE__)); 6705 6706 /* XXX forcibly awake and hwps-off */ 6707 6708 BWN_WRITE_4(mac, BWN_MACCTL, 6709 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 6710 ~BWN_MACCTL_HWPS); 6711 BWN_READ_4(mac, BWN_MACCTL); 6712 if (siba_get_revid(sc->sc_dev) >= 5) { 6713 for (i = 0; i < 100; i++) { 6714 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 6715 BWN_SHARED_UCODESTAT); 6716 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 6717 break; 6718 DELAY(10); 6719 } 6720 } 6721 } 6722 6723 static int16_t 6724 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 6725 { 6726 6727 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 6728 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 6729 } 6730 6731 static void 6732 bwn_nrssi_threshold(struct bwn_mac *mac) 6733 { 6734 struct bwn_phy *phy = &mac->mac_phy; 6735 struct bwn_phy_g *pg = &phy->phy_g; 6736 struct bwn_softc *sc = mac->mac_sc; 6737 int32_t a, b; 6738 int16_t tmp16; 6739 uint16_t tmpu16; 6740 6741 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 6742 6743 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) { 6744 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 6745 a = 0x13; 6746 b = 0x12; 6747 } else { 6748 a = 0xe; 6749 b = 0x11; 6750 } 6751 6752 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6753 a += (pg->pg_nrssi[0] << 6); 6754 a += (a < 32) ? 31 : 32; 6755 a = a >> 6; 6756 a = MIN(MAX(a, -31), 31); 6757 6758 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 6759 b += (pg->pg_nrssi[0] << 6); 6760 if (b < 32) 6761 b += 31; 6762 else 6763 b += 32; 6764 b = b >> 6; 6765 b = MIN(MAX(b, -31), 31); 6766 6767 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 6768 tmpu16 |= ((uint32_t)b & 0x0000003f); 6769 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 6770 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 6771 return; 6772 } 6773 6774 tmp16 = bwn_nrssi_read(mac, 0x20); 6775 if (tmp16 >= 0x20) 6776 tmp16 -= 0x40; 6777 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 6778 } 6779 6780 static void 6781 bwn_nrssi_slope_11g(struct bwn_mac *mac) 6782 { 6783 #define SAVE_RF_MAX 3 6784 #define SAVE_PHY_COMM_MAX 4 6785 #define SAVE_PHY3_MAX 8 6786 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6787 { 0x7a, 0x52, 0x43 }; 6788 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 6789 { 0x15, 0x5a, 0x59, 0x58 }; 6790 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 6791 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 6792 0x0801, 0x0060, 0x0014, 0x0478 6793 }; 6794 struct bwn_phy *phy = &mac->mac_phy; 6795 struct bwn_phy_g *pg = &phy->phy_g; 6796 int32_t i, tmp32, phy3_idx = 0; 6797 uint16_t delta, tmp; 6798 uint16_t save_rf[SAVE_RF_MAX]; 6799 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6800 uint16_t save_phy3[SAVE_PHY3_MAX]; 6801 uint16_t ant_div, phy0, chan_ex; 6802 int16_t nrssi0, nrssi1; 6803 6804 KASSERT(phy->type == BWN_PHYTYPE_G, 6805 ("%s:%d: fail", __func__, __LINE__)); 6806 6807 if (phy->rf_rev >= 9) 6808 return; 6809 if (phy->rf_rev == 8) 6810 bwn_nrssi_offset(mac); 6811 6812 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 6813 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 6814 6815 /* 6816 * Save RF/PHY registers for later restoration 6817 */ 6818 ant_div = BWN_READ_2(mac, 0x03e2); 6819 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 6820 for (i = 0; i < SAVE_RF_MAX; ++i) 6821 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6822 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6823 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6824 6825 phy0 = BWN_READ_2(mac, BWN_PHY0); 6826 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 6827 if (phy->rev >= 3) { 6828 for (i = 0; i < SAVE_PHY3_MAX; ++i) 6829 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 6830 BWN_PHY_WRITE(mac, 0x002e, 0); 6831 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 6832 switch (phy->rev) { 6833 case 4: 6834 case 6: 6835 case 7: 6836 BWN_PHY_SET(mac, 0x0478, 0x0100); 6837 BWN_PHY_SET(mac, 0x0801, 0x0040); 6838 break; 6839 case 3: 6840 case 5: 6841 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 6842 break; 6843 } 6844 BWN_PHY_SET(mac, 0x0060, 0x0040); 6845 BWN_PHY_SET(mac, 0x0014, 0x0200); 6846 } 6847 /* 6848 * Calculate nrssi0 6849 */ 6850 BWN_RF_SET(mac, 0x007a, 0x0070); 6851 bwn_set_all_gains(mac, 0, 8, 0); 6852 BWN_RF_MASK(mac, 0x007a, 0x00f7); 6853 if (phy->rev >= 2) { 6854 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 6855 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 6856 } 6857 BWN_RF_SET(mac, 0x007a, 0x0080); 6858 DELAY(20); 6859 6860 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6861 if (nrssi0 >= 0x0020) 6862 nrssi0 -= 0x0040; 6863 6864 /* 6865 * Calculate nrssi1 6866 */ 6867 BWN_RF_MASK(mac, 0x007a, 0x007f); 6868 if (phy->rev >= 2) 6869 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 6870 6871 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 6872 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 6873 BWN_RF_SET(mac, 0x007a, 0x000f); 6874 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 6875 if (phy->rev >= 2) { 6876 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 6877 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 6878 } 6879 6880 bwn_set_all_gains(mac, 3, 0, 1); 6881 if (phy->rf_rev == 8) { 6882 BWN_RF_WRITE(mac, 0x0043, 0x001f); 6883 } else { 6884 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 6885 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 6886 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 6887 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 6888 } 6889 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 6890 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 6891 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 6892 DELAY(20); 6893 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 6894 6895 /* 6896 * Install calculated narrow RSSI values 6897 */ 6898 if (nrssi1 >= 0x0020) 6899 nrssi1 -= 0x0040; 6900 if (nrssi0 == nrssi1) 6901 pg->pg_nrssi_slope = 0x00010000; 6902 else 6903 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 6904 if (nrssi0 >= -4) { 6905 pg->pg_nrssi[0] = nrssi1; 6906 pg->pg_nrssi[1] = nrssi0; 6907 } 6908 6909 /* 6910 * Restore saved RF/PHY registers 6911 */ 6912 if (phy->rev >= 3) { 6913 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 6914 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6915 save_phy3[phy3_idx]); 6916 } 6917 } 6918 if (phy->rev >= 2) { 6919 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 6920 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 6921 } 6922 6923 for (i = 0; i < SAVE_RF_MAX; ++i) 6924 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 6925 6926 BWN_WRITE_2(mac, 0x03e2, ant_div); 6927 BWN_WRITE_2(mac, 0x03e6, phy0); 6928 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 6929 6930 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6931 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 6932 6933 bwn_spu_workaround(mac, phy->chan); 6934 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 6935 bwn_set_original_gains(mac); 6936 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 6937 if (phy->rev >= 3) { 6938 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 6939 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 6940 save_phy3[phy3_idx]); 6941 } 6942 } 6943 6944 delta = 0x1f - pg->pg_nrssi[0]; 6945 for (i = 0; i < 64; i++) { 6946 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 6947 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 6948 pg->pg_nrssi_lt[i] = tmp32; 6949 } 6950 6951 bwn_nrssi_threshold(mac); 6952 #undef SAVE_RF_MAX 6953 #undef SAVE_PHY_COMM_MAX 6954 #undef SAVE_PHY3_MAX 6955 } 6956 6957 static void 6958 bwn_nrssi_offset(struct bwn_mac *mac) 6959 { 6960 #define SAVE_RF_MAX 2 6961 #define SAVE_PHY_COMM_MAX 10 6962 #define SAVE_PHY6_MAX 8 6963 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 6964 { 0x7a, 0x43 }; 6965 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 6966 0x0001, 0x0811, 0x0812, 0x0814, 6967 0x0815, 0x005a, 0x0059, 0x0058, 6968 0x000a, 0x0003 6969 }; 6970 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 6971 0x002e, 0x002f, 0x080f, 0x0810, 6972 0x0801, 0x0060, 0x0014, 0x0478 6973 }; 6974 struct bwn_phy *phy = &mac->mac_phy; 6975 int i, phy6_idx = 0; 6976 uint16_t save_rf[SAVE_RF_MAX]; 6977 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 6978 uint16_t save_phy6[SAVE_PHY6_MAX]; 6979 int16_t nrssi; 6980 uint16_t saved = 0xffff; 6981 6982 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 6983 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 6984 for (i = 0; i < SAVE_RF_MAX; ++i) 6985 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 6986 6987 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 6988 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 6989 BWN_PHY_SET(mac, 0x0811, 0x000c); 6990 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 6991 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 6992 if (phy->rev >= 6) { 6993 for (i = 0; i < SAVE_PHY6_MAX; ++i) 6994 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 6995 6996 BWN_PHY_WRITE(mac, 0x002e, 0); 6997 BWN_PHY_WRITE(mac, 0x002f, 0); 6998 BWN_PHY_WRITE(mac, 0x080f, 0); 6999 BWN_PHY_WRITE(mac, 0x0810, 0); 7000 BWN_PHY_SET(mac, 0x0478, 0x0100); 7001 BWN_PHY_SET(mac, 0x0801, 0x0040); 7002 BWN_PHY_SET(mac, 0x0060, 0x0040); 7003 BWN_PHY_SET(mac, 0x0014, 0x0200); 7004 } 7005 BWN_RF_SET(mac, 0x007a, 0x0070); 7006 BWN_RF_SET(mac, 0x007a, 0x0080); 7007 DELAY(30); 7008 7009 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7010 if (nrssi >= 0x20) 7011 nrssi -= 0x40; 7012 if (nrssi == 31) { 7013 for (i = 7; i >= 4; i--) { 7014 BWN_RF_WRITE(mac, 0x007b, i); 7015 DELAY(20); 7016 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 7017 0x003f); 7018 if (nrssi >= 0x20) 7019 nrssi -= 0x40; 7020 if (nrssi < 31 && saved == 0xffff) 7021 saved = i; 7022 } 7023 if (saved == 0xffff) 7024 saved = 4; 7025 } else { 7026 BWN_RF_MASK(mac, 0x007a, 0x007f); 7027 if (phy->rev != 1) { 7028 BWN_PHY_SET(mac, 0x0814, 0x0001); 7029 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 7030 } 7031 BWN_PHY_SET(mac, 0x0811, 0x000c); 7032 BWN_PHY_SET(mac, 0x0812, 0x000c); 7033 BWN_PHY_SET(mac, 0x0811, 0x0030); 7034 BWN_PHY_SET(mac, 0x0812, 0x0030); 7035 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 7036 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 7037 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 7038 if (phy->rev == 0) 7039 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 7040 else 7041 BWN_PHY_SET(mac, 0x000a, 0x2000); 7042 if (phy->rev != 1) { 7043 BWN_PHY_SET(mac, 0x0814, 0x0004); 7044 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 7045 } 7046 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 7047 BWN_RF_SET(mac, 0x007a, 0x000f); 7048 bwn_set_all_gains(mac, 3, 0, 1); 7049 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 7050 DELAY(30); 7051 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 7052 if (nrssi >= 0x20) 7053 nrssi -= 0x40; 7054 if (nrssi == -32) { 7055 for (i = 0; i < 4; i++) { 7056 BWN_RF_WRITE(mac, 0x007b, i); 7057 DELAY(20); 7058 nrssi = (int16_t)((BWN_PHY_READ(mac, 7059 0x047f) >> 8) & 0x003f); 7060 if (nrssi >= 0x20) 7061 nrssi -= 0x40; 7062 if (nrssi > -31 && saved == 0xffff) 7063 saved = i; 7064 } 7065 if (saved == 0xffff) 7066 saved = 3; 7067 } else 7068 saved = 0; 7069 } 7070 BWN_RF_WRITE(mac, 0x007b, saved); 7071 7072 /* 7073 * Restore saved RF/PHY registers 7074 */ 7075 if (phy->rev >= 6) { 7076 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 7077 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7078 save_phy6[phy6_idx]); 7079 } 7080 } 7081 if (phy->rev != 1) { 7082 for (i = 3; i < 5; i++) 7083 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 7084 save_phy_comm[i]); 7085 } 7086 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 7087 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 7088 7089 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 7090 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 7091 7092 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 7093 BWN_PHY_SET(mac, 0x0429, 0x8000); 7094 bwn_set_original_gains(mac); 7095 if (phy->rev >= 6) { 7096 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 7097 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 7098 save_phy6[phy6_idx]); 7099 } 7100 } 7101 7102 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 7103 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 7104 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 7105 } 7106 7107 static void 7108 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 7109 int16_t third) 7110 { 7111 struct bwn_phy *phy = &mac->mac_phy; 7112 uint16_t i; 7113 uint16_t start = 0x08, end = 0x18; 7114 uint16_t tmp; 7115 uint16_t table; 7116 7117 if (phy->rev <= 1) { 7118 start = 0x10; 7119 end = 0x20; 7120 } 7121 7122 table = BWN_OFDMTAB_GAINX; 7123 if (phy->rev <= 1) 7124 table = BWN_OFDMTAB_GAINX_R1; 7125 for (i = 0; i < 4; i++) 7126 bwn_ofdmtab_write_2(mac, table, i, first); 7127 7128 for (i = start; i < end; i++) 7129 bwn_ofdmtab_write_2(mac, table, i, second); 7130 7131 if (third != -1) { 7132 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 7133 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 7134 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 7135 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 7136 } 7137 bwn_dummy_transmission(mac, 0, 1); 7138 } 7139 7140 static void 7141 bwn_set_original_gains(struct bwn_mac *mac) 7142 { 7143 struct bwn_phy *phy = &mac->mac_phy; 7144 uint16_t i, tmp; 7145 uint16_t table; 7146 uint16_t start = 0x0008, end = 0x0018; 7147 7148 if (phy->rev <= 1) { 7149 start = 0x0010; 7150 end = 0x0020; 7151 } 7152 7153 table = BWN_OFDMTAB_GAINX; 7154 if (phy->rev <= 1) 7155 table = BWN_OFDMTAB_GAINX_R1; 7156 for (i = 0; i < 4; i++) { 7157 tmp = (i & 0xfffc); 7158 tmp |= (i & 0x0001) << 1; 7159 tmp |= (i & 0x0002) >> 1; 7160 7161 bwn_ofdmtab_write_2(mac, table, i, tmp); 7162 } 7163 7164 for (i = start; i < end; i++) 7165 bwn_ofdmtab_write_2(mac, table, i, i - start); 7166 7167 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 7168 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 7169 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 7170 bwn_dummy_transmission(mac, 0, 1); 7171 } 7172 7173 static void 7174 bwn_phy_hwpctl_init(struct bwn_mac *mac) 7175 { 7176 struct bwn_phy *phy = &mac->mac_phy; 7177 struct bwn_phy_g *pg = &phy->phy_g; 7178 struct bwn_rfatt old_rfatt, rfatt; 7179 struct bwn_bbatt old_bbatt, bbatt; 7180 struct bwn_softc *sc = mac->mac_sc; 7181 uint8_t old_txctl = 0; 7182 7183 KASSERT(phy->type == BWN_PHYTYPE_G, 7184 ("%s:%d: fail", __func__, __LINE__)); 7185 7186 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) && 7187 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)) 7188 return; 7189 7190 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 7191 7192 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 7193 7194 if (!phy->gmode) 7195 return; 7196 bwn_hwpctl_early_init(mac); 7197 if (pg->pg_curtssi == 0) { 7198 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 7199 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 7200 } else { 7201 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 7202 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 7203 old_txctl = pg->pg_txctl; 7204 7205 bbatt.att = 11; 7206 if (phy->rf_rev == 8) { 7207 rfatt.att = 15; 7208 rfatt.padmix = 1; 7209 } else { 7210 rfatt.att = 9; 7211 rfatt.padmix = 0; 7212 } 7213 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 7214 } 7215 bwn_dummy_transmission(mac, 0, 1); 7216 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 7217 if (phy->rf_ver == 0x2050 && phy->analog == 0) 7218 BWN_RF_MASK(mac, 0x0076, 0xff7b); 7219 else 7220 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 7221 &old_rfatt, old_txctl); 7222 } 7223 bwn_hwpctl_init_gphy(mac); 7224 7225 /* clear TSSI */ 7226 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 7227 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 7228 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 7229 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 7230 } 7231 7232 static void 7233 bwn_hwpctl_early_init(struct bwn_mac *mac) 7234 { 7235 struct bwn_phy *phy = &mac->mac_phy; 7236 7237 if (!bwn_has_hwpctl(mac)) { 7238 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 7239 return; 7240 } 7241 7242 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 7243 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 7244 BWN_PHY_SET(mac, 0x047c, 0x0002); 7245 BWN_PHY_SET(mac, 0x047a, 0xf000); 7246 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 7247 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7248 BWN_PHY_SET(mac, 0x005d, 0x8000); 7249 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7250 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7251 BWN_PHY_SET(mac, 0x0036, 0x0400); 7252 } else { 7253 BWN_PHY_SET(mac, 0x0036, 0x0200); 7254 BWN_PHY_SET(mac, 0x0036, 0x0400); 7255 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 7256 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 7257 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 7258 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 7259 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 7260 } 7261 } 7262 7263 static void 7264 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 7265 { 7266 struct bwn_phy *phy = &mac->mac_phy; 7267 struct bwn_phy_g *pg = &phy->phy_g; 7268 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7269 int i; 7270 uint16_t nr_written = 0, tmp, value; 7271 uint8_t rf, bb; 7272 7273 if (!bwn_has_hwpctl(mac)) { 7274 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 7275 return; 7276 } 7277 7278 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 7279 (pg->pg_idletssi - pg->pg_curtssi)); 7280 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 7281 (pg->pg_idletssi - pg->pg_curtssi)); 7282 7283 for (i = 0; i < 32; i++) 7284 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 7285 for (i = 32; i < 64; i++) 7286 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 7287 for (i = 0; i < 64; i += 2) { 7288 value = (uint16_t) pg->pg_tssi2dbm[i]; 7289 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 7290 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 7291 } 7292 7293 for (rf = 0; rf < lo->rfatt.len; rf++) { 7294 for (bb = 0; bb < lo->bbatt.len; bb++) { 7295 if (nr_written >= 0x40) 7296 return; 7297 tmp = lo->bbatt.array[bb].att; 7298 tmp <<= 8; 7299 if (phy->rf_rev == 8) 7300 tmp |= 0x50; 7301 else 7302 tmp |= 0x40; 7303 tmp |= lo->rfatt.array[rf].att; 7304 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 7305 nr_written++; 7306 } 7307 } 7308 7309 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 7310 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 7311 7312 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 7313 BWN_PHY_SET(mac, 0x0478, 0x0800); 7314 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 7315 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 7316 7317 bwn_phy_g_dc_lookup_init(mac, 1); 7318 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 7319 } 7320 7321 static void 7322 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 7323 { 7324 struct bwn_softc *sc = mac->mac_sc; 7325 7326 if (spu != 0) 7327 bwn_spu_workaround(mac, channel); 7328 7329 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7330 7331 if (channel == 14) { 7332 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN) 7333 bwn_hf_write(mac, 7334 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 7335 else 7336 bwn_hf_write(mac, 7337 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 7338 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7339 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 7340 return; 7341 } 7342 7343 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 7344 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 7345 } 7346 7347 static uint16_t 7348 bwn_phy_g_chan2freq(uint8_t channel) 7349 { 7350 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 7351 7352 KASSERT(channel >= 1 && channel <= 14, 7353 ("%s:%d: fail", __func__, __LINE__)); 7354 7355 return (bwn_phy_g_rf_channels[channel - 1]); 7356 } 7357 7358 static void 7359 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 7360 const struct bwn_rfatt *rfatt, uint8_t txctl) 7361 { 7362 struct bwn_phy *phy = &mac->mac_phy; 7363 struct bwn_phy_g *pg = &phy->phy_g; 7364 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 7365 uint16_t bb, rf; 7366 uint16_t tx_bias, tx_magn; 7367 7368 bb = bbatt->att; 7369 rf = rfatt->att; 7370 tx_bias = lo->tx_bias; 7371 tx_magn = lo->tx_magn; 7372 if (tx_bias == 0xff) 7373 tx_bias = 0; 7374 7375 pg->pg_txctl = txctl; 7376 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 7377 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 7378 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 7379 bwn_phy_g_set_bbatt(mac, bb); 7380 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 7381 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 7382 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 7383 else { 7384 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 7385 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 7386 } 7387 if (BWN_HAS_TXMAG(phy)) 7388 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 7389 else 7390 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 7391 bwn_lo_g_adjust(mac); 7392 } 7393 7394 static void 7395 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 7396 uint16_t bbatt) 7397 { 7398 struct bwn_phy *phy = &mac->mac_phy; 7399 7400 if (phy->analog == 0) { 7401 BWN_WRITE_2(mac, BWN_PHY0, 7402 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 7403 return; 7404 } 7405 if (phy->analog > 1) { 7406 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 7407 return; 7408 } 7409 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 7410 } 7411 7412 static uint16_t 7413 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 7414 { 7415 struct bwn_phy *phy = &mac->mac_phy; 7416 struct bwn_phy_g *pg = &phy->phy_g; 7417 struct bwn_softc *sc = mac->mac_sc; 7418 int max_lb_gain; 7419 uint16_t extlna; 7420 uint16_t i; 7421 7422 if (phy->gmode == 0) 7423 return (0); 7424 7425 if (BWN_HAS_LOOPBACK(phy)) { 7426 max_lb_gain = pg->pg_max_lb_gain; 7427 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 7428 if (max_lb_gain >= 0x46) { 7429 extlna = 0x3000; 7430 max_lb_gain -= 0x46; 7431 } else if (max_lb_gain >= 0x3a) { 7432 extlna = 0x1000; 7433 max_lb_gain -= 0x3a; 7434 } else if (max_lb_gain >= 0x2e) { 7435 extlna = 0x2000; 7436 max_lb_gain -= 0x2e; 7437 } else { 7438 extlna = 0; 7439 max_lb_gain -= 0x10; 7440 } 7441 7442 for (i = 0; i < 16; i++) { 7443 max_lb_gain -= (i * 6); 7444 if (max_lb_gain < 6) 7445 break; 7446 } 7447 7448 if ((phy->rev < 7) || 7449 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7450 if (reg == BWN_PHY_RFOVER) { 7451 return (0x1b3); 7452 } else if (reg == BWN_PHY_RFOVERVAL) { 7453 extlna |= (i << 8); 7454 switch (lpd) { 7455 case BWN_LPD(0, 1, 1): 7456 return (0x0f92); 7457 case BWN_LPD(0, 0, 1): 7458 case BWN_LPD(1, 0, 1): 7459 return (0x0092 | extlna); 7460 case BWN_LPD(1, 0, 0): 7461 return (0x0093 | extlna); 7462 } 7463 KASSERT(0 == 1, 7464 ("%s:%d: fail", __func__, __LINE__)); 7465 } 7466 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7467 } else { 7468 if (reg == BWN_PHY_RFOVER) 7469 return (0x9b3); 7470 if (reg == BWN_PHY_RFOVERVAL) { 7471 if (extlna) 7472 extlna |= 0x8000; 7473 extlna |= (i << 8); 7474 switch (lpd) { 7475 case BWN_LPD(0, 1, 1): 7476 return (0x8f92); 7477 case BWN_LPD(0, 0, 1): 7478 return (0x8092 | extlna); 7479 case BWN_LPD(1, 0, 1): 7480 return (0x2092 | extlna); 7481 case BWN_LPD(1, 0, 0): 7482 return (0x2093 | extlna); 7483 } 7484 KASSERT(0 == 1, 7485 ("%s:%d: fail", __func__, __LINE__)); 7486 } 7487 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7488 } 7489 return (0); 7490 } 7491 7492 if ((phy->rev < 7) || 7493 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) { 7494 if (reg == BWN_PHY_RFOVER) { 7495 return (0x1b3); 7496 } else if (reg == BWN_PHY_RFOVERVAL) { 7497 switch (lpd) { 7498 case BWN_LPD(0, 1, 1): 7499 return (0x0fb2); 7500 case BWN_LPD(0, 0, 1): 7501 return (0x00b2); 7502 case BWN_LPD(1, 0, 1): 7503 return (0x30b2); 7504 case BWN_LPD(1, 0, 0): 7505 return (0x30b3); 7506 } 7507 KASSERT(0 == 1, 7508 ("%s:%d: fail", __func__, __LINE__)); 7509 } 7510 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7511 } else { 7512 if (reg == BWN_PHY_RFOVER) { 7513 return (0x9b3); 7514 } else if (reg == BWN_PHY_RFOVERVAL) { 7515 switch (lpd) { 7516 case BWN_LPD(0, 1, 1): 7517 return (0x8fb2); 7518 case BWN_LPD(0, 0, 1): 7519 return (0x80b2); 7520 case BWN_LPD(1, 0, 1): 7521 return (0x20b2); 7522 case BWN_LPD(1, 0, 0): 7523 return (0x20b3); 7524 } 7525 KASSERT(0 == 1, 7526 ("%s:%d: fail", __func__, __LINE__)); 7527 } 7528 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7529 } 7530 return (0); 7531 } 7532 7533 static void 7534 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 7535 { 7536 7537 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 7538 return; 7539 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 7540 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 7541 DELAY(1000); 7542 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 7543 } 7544 7545 static int 7546 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 7547 { 7548 struct bwn_softc *sc = mac->mac_sc; 7549 struct bwn_fw *fw = &mac->mac_fw; 7550 const uint8_t rev = siba_get_revid(sc->sc_dev); 7551 const char *filename; 7552 uint32_t high; 7553 int error; 7554 7555 /* microcode */ 7556 if (rev >= 5 && rev <= 10) 7557 filename = "ucode5"; 7558 else if (rev >= 11 && rev <= 12) 7559 filename = "ucode11"; 7560 else if (rev == 13) 7561 filename = "ucode13"; 7562 else if (rev == 14) 7563 filename = "ucode14"; 7564 else if (rev >= 15) 7565 filename = "ucode15"; 7566 else { 7567 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 7568 bwn_release_firmware(mac); 7569 return (EOPNOTSUPP); 7570 } 7571 error = bwn_fw_get(mac, type, filename, &fw->ucode); 7572 if (error) { 7573 bwn_release_firmware(mac); 7574 return (error); 7575 } 7576 7577 /* PCM */ 7578 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 7579 if (rev >= 5 && rev <= 10) { 7580 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 7581 if (error == ENOENT) 7582 fw->no_pcmfile = 1; 7583 else if (error) { 7584 bwn_release_firmware(mac); 7585 return (error); 7586 } 7587 } else if (rev < 11) { 7588 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 7589 return (EOPNOTSUPP); 7590 } 7591 7592 /* initvals */ 7593 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 7594 switch (mac->mac_phy.type) { 7595 case BWN_PHYTYPE_A: 7596 if (rev < 5 || rev > 10) 7597 goto fail1; 7598 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7599 filename = "a0g1initvals5"; 7600 else 7601 filename = "a0g0initvals5"; 7602 break; 7603 case BWN_PHYTYPE_G: 7604 if (rev >= 5 && rev <= 10) 7605 filename = "b0g0initvals5"; 7606 else if (rev >= 13) 7607 filename = "b0g0initvals13"; 7608 else 7609 goto fail1; 7610 break; 7611 case BWN_PHYTYPE_LP: 7612 if (rev == 13) 7613 filename = "lp0initvals13"; 7614 else if (rev == 14) 7615 filename = "lp0initvals14"; 7616 else if (rev >= 15) 7617 filename = "lp0initvals15"; 7618 else 7619 goto fail1; 7620 break; 7621 case BWN_PHYTYPE_N: 7622 if (rev >= 11 && rev <= 12) 7623 filename = "n0initvals11"; 7624 else 7625 goto fail1; 7626 break; 7627 default: 7628 goto fail1; 7629 } 7630 error = bwn_fw_get(mac, type, filename, &fw->initvals); 7631 if (error) { 7632 bwn_release_firmware(mac); 7633 return (error); 7634 } 7635 7636 /* bandswitch initvals */ 7637 switch (mac->mac_phy.type) { 7638 case BWN_PHYTYPE_A: 7639 if (rev >= 5 && rev <= 10) { 7640 if (high & BWN_TGSHIGH_HAVE_2GHZ) 7641 filename = "a0g1bsinitvals5"; 7642 else 7643 filename = "a0g0bsinitvals5"; 7644 } else if (rev >= 11) 7645 filename = NULL; 7646 else 7647 goto fail1; 7648 break; 7649 case BWN_PHYTYPE_G: 7650 if (rev >= 5 && rev <= 10) 7651 filename = "b0g0bsinitvals5"; 7652 else if (rev >= 11) 7653 filename = NULL; 7654 else 7655 goto fail1; 7656 break; 7657 case BWN_PHYTYPE_LP: 7658 if (rev == 13) 7659 filename = "lp0bsinitvals13"; 7660 else if (rev == 14) 7661 filename = "lp0bsinitvals14"; 7662 else if (rev >= 15) 7663 filename = "lp0bsinitvals15"; 7664 else 7665 goto fail1; 7666 break; 7667 case BWN_PHYTYPE_N: 7668 if (rev >= 11 && rev <= 12) 7669 filename = "n0bsinitvals11"; 7670 else 7671 goto fail1; 7672 break; 7673 default: 7674 goto fail1; 7675 } 7676 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 7677 if (error) { 7678 bwn_release_firmware(mac); 7679 return (error); 7680 } 7681 return (0); 7682 fail1: 7683 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev); 7684 bwn_release_firmware(mac); 7685 return (EOPNOTSUPP); 7686 } 7687 7688 static int 7689 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 7690 const char *name, struct bwn_fwfile *bfw) 7691 { 7692 const struct bwn_fwhdr *hdr; 7693 struct bwn_softc *sc = mac->mac_sc; 7694 const struct firmware *fw; 7695 char namebuf[64]; 7696 7697 if (name == NULL) { 7698 bwn_do_release_fw(bfw); 7699 return (0); 7700 } 7701 if (bfw->filename != NULL) { 7702 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 7703 return (0); 7704 bwn_do_release_fw(bfw); 7705 } 7706 7707 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 7708 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 7709 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 7710 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 7711 fw = firmware_get(namebuf); 7712 if (fw == NULL) { 7713 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 7714 namebuf); 7715 return (ENOENT); 7716 } 7717 if (fw->datasize < sizeof(struct bwn_fwhdr)) 7718 goto fail; 7719 hdr = (const struct bwn_fwhdr *)(fw->data); 7720 switch (hdr->type) { 7721 case BWN_FWTYPE_UCODE: 7722 case BWN_FWTYPE_PCM: 7723 if (be32toh(hdr->size) != 7724 (fw->datasize - sizeof(struct bwn_fwhdr))) 7725 goto fail; 7726 /* FALLTHROUGH */ 7727 case BWN_FWTYPE_IV: 7728 if (hdr->ver != 1) 7729 goto fail; 7730 break; 7731 default: 7732 goto fail; 7733 } 7734 bfw->filename = name; 7735 bfw->fw = fw; 7736 bfw->type = type; 7737 return (0); 7738 fail: 7739 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 7740 if (fw != NULL) 7741 firmware_put(fw, FIRMWARE_UNLOAD); 7742 return (EPROTO); 7743 } 7744 7745 static void 7746 bwn_release_firmware(struct bwn_mac *mac) 7747 { 7748 7749 bwn_do_release_fw(&mac->mac_fw.ucode); 7750 bwn_do_release_fw(&mac->mac_fw.pcm); 7751 bwn_do_release_fw(&mac->mac_fw.initvals); 7752 bwn_do_release_fw(&mac->mac_fw.initvals_band); 7753 } 7754 7755 static void 7756 bwn_do_release_fw(struct bwn_fwfile *bfw) 7757 { 7758 7759 if (bfw->fw != NULL) 7760 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 7761 bfw->fw = NULL; 7762 bfw->filename = NULL; 7763 } 7764 7765 static int 7766 bwn_fw_loaducode(struct bwn_mac *mac) 7767 { 7768 #define GETFWOFFSET(fwp, offset) \ 7769 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 7770 #define GETFWSIZE(fwp, offset) \ 7771 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 7772 struct bwn_softc *sc = mac->mac_sc; 7773 const uint32_t *data; 7774 unsigned int i; 7775 uint32_t ctl; 7776 uint16_t date, fwcaps, time; 7777 int error = 0; 7778 7779 ctl = BWN_READ_4(mac, BWN_MACCTL); 7780 ctl |= BWN_MACCTL_MCODE_JMP0; 7781 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 7782 __LINE__)); 7783 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 7784 for (i = 0; i < 64; i++) 7785 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 7786 for (i = 0; i < 4096; i += 2) 7787 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 7788 7789 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7790 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 7791 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 7792 i++) { 7793 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7794 DELAY(10); 7795 } 7796 7797 if (mac->mac_fw.pcm.fw) { 7798 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 7799 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 7800 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 7801 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 7802 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 7803 sizeof(struct bwn_fwhdr)); i++) { 7804 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 7805 DELAY(10); 7806 } 7807 } 7808 7809 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 7810 BWN_WRITE_4(mac, BWN_MACCTL, 7811 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 7812 BWN_MACCTL_MCODE_RUN); 7813 7814 for (i = 0; i < 21; i++) { 7815 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 7816 break; 7817 if (i >= 20) { 7818 device_printf(sc->sc_dev, "ucode timeout\n"); 7819 error = ENXIO; 7820 goto error; 7821 } 7822 DELAY(50000); 7823 } 7824 BWN_READ_4(mac, BWN_INTR_REASON); 7825 7826 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 7827 if (mac->mac_fw.rev <= 0x128) { 7828 device_printf(sc->sc_dev, "the firmware is too old\n"); 7829 error = EOPNOTSUPP; 7830 goto error; 7831 } 7832 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 7833 BWN_SHARED_UCODE_PATCH); 7834 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 7835 mac->mac_fw.opensource = (date == 0xffff); 7836 if (bwn_wme != 0) 7837 mac->mac_flags |= BWN_MAC_FLAG_WME; 7838 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 7839 7840 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 7841 if (mac->mac_fw.opensource == 0) { 7842 device_printf(sc->sc_dev, 7843 "firmware version (rev %u patch %u date %#x time %#x)\n", 7844 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 7845 if (mac->mac_fw.no_pcmfile) 7846 device_printf(sc->sc_dev, 7847 "no HW crypto acceleration due to pcm5\n"); 7848 } else { 7849 mac->mac_fw.patch = time; 7850 fwcaps = bwn_fwcaps_read(mac); 7851 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 7852 device_printf(sc->sc_dev, 7853 "disabling HW crypto acceleration\n"); 7854 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 7855 } 7856 if (!(fwcaps & BWN_FWCAPS_WME)) { 7857 device_printf(sc->sc_dev, "disabling WME support\n"); 7858 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 7859 } 7860 } 7861 7862 if (BWN_ISOLDFMT(mac)) 7863 device_printf(sc->sc_dev, "using old firmware image\n"); 7864 7865 return (0); 7866 7867 error: 7868 BWN_WRITE_4(mac, BWN_MACCTL, 7869 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 7870 BWN_MACCTL_MCODE_JMP0); 7871 7872 return (error); 7873 #undef GETFWSIZE 7874 #undef GETFWOFFSET 7875 } 7876 7877 /* OpenFirmware only */ 7878 static uint16_t 7879 bwn_fwcaps_read(struct bwn_mac *mac) 7880 { 7881 7882 KASSERT(mac->mac_fw.opensource == 1, 7883 ("%s:%d: fail", __func__, __LINE__)); 7884 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 7885 } 7886 7887 static int 7888 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 7889 size_t count, size_t array_size) 7890 { 7891 #define GET_NEXTIV16(iv) \ 7892 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7893 sizeof(uint16_t) + sizeof(uint16_t))) 7894 #define GET_NEXTIV32(iv) \ 7895 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 7896 sizeof(uint16_t) + sizeof(uint32_t))) 7897 struct bwn_softc *sc = mac->mac_sc; 7898 const struct bwn_fwinitvals *iv; 7899 uint16_t offset; 7900 size_t i; 7901 uint8_t bit32; 7902 7903 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 7904 ("%s:%d: fail", __func__, __LINE__)); 7905 iv = ivals; 7906 for (i = 0; i < count; i++) { 7907 if (array_size < sizeof(iv->offset_size)) 7908 goto fail; 7909 array_size -= sizeof(iv->offset_size); 7910 offset = be16toh(iv->offset_size); 7911 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 7912 offset &= BWN_FWINITVALS_OFFSET_MASK; 7913 if (offset >= 0x1000) 7914 goto fail; 7915 if (bit32) { 7916 if (array_size < sizeof(iv->data.d32)) 7917 goto fail; 7918 array_size -= sizeof(iv->data.d32); 7919 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 7920 iv = GET_NEXTIV32(iv); 7921 } else { 7922 7923 if (array_size < sizeof(iv->data.d16)) 7924 goto fail; 7925 array_size -= sizeof(iv->data.d16); 7926 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 7927 7928 iv = GET_NEXTIV16(iv); 7929 } 7930 } 7931 if (array_size != 0) 7932 goto fail; 7933 return (0); 7934 fail: 7935 device_printf(sc->sc_dev, "initvals: invalid format\n"); 7936 return (EPROTO); 7937 #undef GET_NEXTIV16 7938 #undef GET_NEXTIV32 7939 } 7940 7941 static int 7942 bwn_switch_channel(struct bwn_mac *mac, int chan) 7943 { 7944 struct bwn_phy *phy = &(mac->mac_phy); 7945 struct bwn_softc *sc = mac->mac_sc; 7946 struct ifnet *ifp = sc->sc_ifp; 7947 struct ieee80211com *ic = ifp->if_l2com; 7948 uint16_t channelcookie, savedcookie; 7949 int error; 7950 7951 if (chan == 0xffff) 7952 chan = phy->get_default_chan(mac); 7953 7954 channelcookie = chan; 7955 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 7956 channelcookie |= 0x100; 7957 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 7958 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 7959 error = phy->switch_channel(mac, chan); 7960 if (error) 7961 goto fail; 7962 7963 mac->mac_phy.chan = chan; 7964 DELAY(8000); 7965 return (0); 7966 fail: 7967 device_printf(sc->sc_dev, "failed to switch channel\n"); 7968 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 7969 return (error); 7970 } 7971 7972 static uint16_t 7973 bwn_ant2phy(int antenna) 7974 { 7975 7976 switch (antenna) { 7977 case BWN_ANT0: 7978 return (BWN_TX_PHY_ANT0); 7979 case BWN_ANT1: 7980 return (BWN_TX_PHY_ANT1); 7981 case BWN_ANT2: 7982 return (BWN_TX_PHY_ANT2); 7983 case BWN_ANT3: 7984 return (BWN_TX_PHY_ANT3); 7985 case BWN_ANTAUTO: 7986 return (BWN_TX_PHY_ANT01AUTO); 7987 } 7988 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 7989 return (0); 7990 } 7991 7992 static void 7993 bwn_wme_load(struct bwn_mac *mac) 7994 { 7995 struct bwn_softc *sc = mac->mac_sc; 7996 int i; 7997 7998 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 7999 ("%s:%d: fail", __func__, __LINE__)); 8000 8001 bwn_mac_suspend(mac); 8002 for (i = 0; i < N(sc->sc_wmeParams); i++) 8003 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 8004 bwn_wme_shm_offsets[i]); 8005 bwn_mac_enable(mac); 8006 } 8007 8008 static void 8009 bwn_wme_loadparams(struct bwn_mac *mac, 8010 const struct wmeParams *p, uint16_t shm_offset) 8011 { 8012 #define SM(_v, _f) (((_v) << _f##_S) & _f) 8013 struct bwn_softc *sc = mac->mac_sc; 8014 uint16_t params[BWN_NR_WMEPARAMS]; 8015 int slot, tmp; 8016 unsigned int i; 8017 8018 slot = BWN_READ_2(mac, BWN_RNG) & 8019 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8020 8021 memset(¶ms, 0, sizeof(params)); 8022 8023 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 8024 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 8025 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 8026 8027 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 8028 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8029 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 8030 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 8031 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 8032 params[BWN_WMEPARAM_BSLOTS] = slot; 8033 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 8034 8035 for (i = 0; i < N(params); i++) { 8036 if (i == BWN_WMEPARAM_STATUS) { 8037 tmp = bwn_shm_read_2(mac, BWN_SHARED, 8038 shm_offset + (i * 2)); 8039 tmp |= 0x100; 8040 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8041 tmp); 8042 } else { 8043 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 8044 params[i]); 8045 } 8046 } 8047 } 8048 8049 static void 8050 bwn_mac_write_bssid(struct bwn_mac *mac) 8051 { 8052 struct bwn_softc *sc = mac->mac_sc; 8053 uint32_t tmp; 8054 int i; 8055 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 8056 8057 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 8058 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); 8059 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 8060 IEEE80211_ADDR_LEN); 8061 8062 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 8063 tmp = (uint32_t) (mac_bssid[i + 0]); 8064 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 8065 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 8066 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 8067 bwn_ram_write(mac, 0x20 + i, tmp); 8068 } 8069 } 8070 8071 static void 8072 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 8073 const uint8_t *macaddr) 8074 { 8075 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 8076 uint16_t data; 8077 8078 if (!mac) 8079 macaddr = zero; 8080 8081 offset |= 0x0020; 8082 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 8083 8084 data = macaddr[0]; 8085 data |= macaddr[1] << 8; 8086 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8087 data = macaddr[2]; 8088 data |= macaddr[3] << 8; 8089 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8090 data = macaddr[4]; 8091 data |= macaddr[5] << 8; 8092 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 8093 } 8094 8095 static void 8096 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8097 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 8098 { 8099 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 8100 uint8_t per_sta_keys_start = 8; 8101 8102 if (BWN_SEC_NEWAPI(mac)) 8103 per_sta_keys_start = 4; 8104 8105 KASSERT(index < mac->mac_max_nr_keys, 8106 ("%s:%d: fail", __func__, __LINE__)); 8107 KASSERT(key_len <= BWN_SEC_KEYSIZE, 8108 ("%s:%d: fail", __func__, __LINE__)); 8109 8110 if (index >= per_sta_keys_start) 8111 bwn_key_macwrite(mac, index, NULL); 8112 if (key) 8113 memcpy(buf, key, key_len); 8114 bwn_key_write(mac, index, algorithm, buf); 8115 if (index >= per_sta_keys_start) 8116 bwn_key_macwrite(mac, index, mac_addr); 8117 8118 mac->mac_key[index].algorithm = algorithm; 8119 } 8120 8121 static void 8122 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 8123 { 8124 struct bwn_softc *sc = mac->mac_sc; 8125 uint32_t addrtmp[2] = { 0, 0 }; 8126 uint8_t start = 8; 8127 8128 if (BWN_SEC_NEWAPI(mac)) 8129 start = 4; 8130 8131 KASSERT(index >= start, 8132 ("%s:%d: fail", __func__, __LINE__)); 8133 index -= start; 8134 8135 if (addr) { 8136 addrtmp[0] = addr[0]; 8137 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 8138 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 8139 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 8140 addrtmp[1] = addr[4]; 8141 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 8142 } 8143 8144 if (siba_get_revid(sc->sc_dev) >= 5) { 8145 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 8146 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 8147 } else { 8148 if (index >= 8) { 8149 bwn_shm_write_4(mac, BWN_SHARED, 8150 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 8151 bwn_shm_write_2(mac, BWN_SHARED, 8152 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 8153 } 8154 } 8155 } 8156 8157 static void 8158 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 8159 const uint8_t *key) 8160 { 8161 unsigned int i; 8162 uint32_t offset; 8163 uint16_t kidx, value; 8164 8165 kidx = BWN_SEC_KEY2FW(mac, index); 8166 bwn_shm_write_2(mac, BWN_SHARED, 8167 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 8168 8169 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 8170 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 8171 value = key[i]; 8172 value |= (uint16_t)(key[i + 1]) << 8; 8173 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 8174 } 8175 } 8176 8177 static void 8178 bwn_phy_exit(struct bwn_mac *mac) 8179 { 8180 8181 mac->mac_phy.rf_onoff(mac, 0); 8182 if (mac->mac_phy.exit != NULL) 8183 mac->mac_phy.exit(mac); 8184 } 8185 8186 static void 8187 bwn_dma_free(struct bwn_mac *mac) 8188 { 8189 struct bwn_dma *dma; 8190 8191 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 8192 return; 8193 dma = &mac->mac_method.dma; 8194 8195 bwn_dma_ringfree(&dma->rx); 8196 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 8197 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 8198 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 8199 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 8200 bwn_dma_ringfree(&dma->mcast); 8201 } 8202 8203 static void 8204 bwn_core_stop(struct bwn_mac *mac) 8205 { 8206 struct bwn_softc *sc = mac->mac_sc; 8207 8208 BWN_ASSERT_LOCKED(sc); 8209 8210 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8211 return; 8212 8213 callout_stop(&sc->sc_rfswitch_ch); 8214 callout_stop(&sc->sc_task_ch); 8215 callout_stop(&sc->sc_watchdog_ch); 8216 sc->sc_watchdog_timer = 0; 8217 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8218 BWN_READ_4(mac, BWN_INTR_MASK); 8219 bwn_mac_suspend(mac); 8220 8221 mac->mac_status = BWN_MAC_STATUS_INITED; 8222 } 8223 8224 static int 8225 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 8226 { 8227 struct bwn_mac *up_dev = NULL; 8228 struct bwn_mac *down_dev; 8229 struct bwn_mac *mac; 8230 int err, status; 8231 uint8_t gmode; 8232 8233 BWN_ASSERT_LOCKED(sc); 8234 8235 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 8236 if (IEEE80211_IS_CHAN_2GHZ(chan) && 8237 mac->mac_phy.supports_2ghz) { 8238 up_dev = mac; 8239 gmode = 1; 8240 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 8241 mac->mac_phy.supports_5ghz) { 8242 up_dev = mac; 8243 gmode = 0; 8244 } else { 8245 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8246 return (EINVAL); 8247 } 8248 if (up_dev != NULL) 8249 break; 8250 } 8251 if (up_dev == NULL) { 8252 device_printf(sc->sc_dev, "Could not find a device\n"); 8253 return (ENODEV); 8254 } 8255 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 8256 return (0); 8257 8258 device_printf(sc->sc_dev, "switching to %s-GHz band\n", 8259 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8260 8261 down_dev = sc->sc_curmac; 8262 status = down_dev->mac_status; 8263 if (status >= BWN_MAC_STATUS_STARTED) 8264 bwn_core_stop(down_dev); 8265 if (status >= BWN_MAC_STATUS_INITED) 8266 bwn_core_exit(down_dev); 8267 8268 if (down_dev != up_dev) 8269 bwn_phy_reset(down_dev); 8270 8271 up_dev->mac_phy.gmode = gmode; 8272 if (status >= BWN_MAC_STATUS_INITED) { 8273 err = bwn_core_init(up_dev); 8274 if (err) { 8275 device_printf(sc->sc_dev, 8276 "fatal: failed to initialize for %s-GHz\n", 8277 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 8278 goto fail; 8279 } 8280 } 8281 if (status >= BWN_MAC_STATUS_STARTED) 8282 bwn_core_start(up_dev); 8283 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 8284 sc->sc_curmac = up_dev; 8285 8286 return (0); 8287 fail: 8288 sc->sc_curmac = NULL; 8289 return (err); 8290 } 8291 8292 static void 8293 bwn_rf_turnon(struct bwn_mac *mac) 8294 { 8295 8296 bwn_mac_suspend(mac); 8297 mac->mac_phy.rf_onoff(mac, 1); 8298 mac->mac_phy.rf_on = 1; 8299 bwn_mac_enable(mac); 8300 } 8301 8302 static void 8303 bwn_rf_turnoff(struct bwn_mac *mac) 8304 { 8305 8306 bwn_mac_suspend(mac); 8307 mac->mac_phy.rf_onoff(mac, 0); 8308 mac->mac_phy.rf_on = 0; 8309 bwn_mac_enable(mac); 8310 } 8311 8312 static void 8313 bwn_phy_reset(struct bwn_mac *mac) 8314 { 8315 struct bwn_softc *sc = mac->mac_sc; 8316 8317 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8318 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 8319 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 8320 DELAY(1000); 8321 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 8322 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) | 8323 BWN_TGSLOW_PHYRESET); 8324 DELAY(1000); 8325 } 8326 8327 static int 8328 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8329 { 8330 struct bwn_vap *bvp = BWN_VAP(vap); 8331 struct ieee80211com *ic= vap->iv_ic; 8332 struct ifnet *ifp = ic->ic_ifp; 8333 enum ieee80211_state ostate = vap->iv_state; 8334 struct bwn_softc *sc = ifp->if_softc; 8335 struct bwn_mac *mac = sc->sc_curmac; 8336 int error; 8337 8338 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 8339 ieee80211_state_name[vap->iv_state], 8340 ieee80211_state_name[nstate]); 8341 8342 error = bvp->bv_newstate(vap, nstate, arg); 8343 if (error != 0) 8344 return (error); 8345 8346 BWN_LOCK(sc); 8347 8348 bwn_led_newstate(mac, nstate); 8349 8350 /* 8351 * Clear the BSSID when we stop a STA 8352 */ 8353 if (vap->iv_opmode == IEEE80211_M_STA) { 8354 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 8355 /* 8356 * Clear out the BSSID. If we reassociate to 8357 * the same AP, this will reinialize things 8358 * correctly... 8359 */ 8360 if (ic->ic_opmode == IEEE80211_M_STA && 8361 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 8362 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 8363 bwn_set_macaddr(mac); 8364 } 8365 } 8366 } 8367 8368 if (vap->iv_opmode == IEEE80211_M_MONITOR || 8369 vap->iv_opmode == IEEE80211_M_AHDEMO) { 8370 /* XXX nothing to do? */ 8371 } else if (nstate == IEEE80211_S_RUN) { 8372 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 8373 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); 8374 bwn_set_opmode(mac); 8375 bwn_set_pretbtt(mac); 8376 bwn_spu_setdelay(mac, 0); 8377 bwn_set_macaddr(mac); 8378 } 8379 8380 BWN_UNLOCK(sc); 8381 8382 return (error); 8383 } 8384 8385 static void 8386 bwn_set_pretbtt(struct bwn_mac *mac) 8387 { 8388 struct bwn_softc *sc = mac->mac_sc; 8389 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8390 uint16_t pretbtt; 8391 8392 if (ic->ic_opmode == IEEE80211_M_IBSS) 8393 pretbtt = 2; 8394 else 8395 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 8396 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 8397 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 8398 } 8399 8400 static int 8401 bwn_intr(void *arg) 8402 { 8403 struct bwn_mac *mac = arg; 8404 struct bwn_softc *sc = mac->mac_sc; 8405 uint32_t reason; 8406 8407 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8408 (sc->sc_flags & BWN_FLAG_INVALID)) 8409 return (FILTER_STRAY); 8410 8411 reason = BWN_READ_4(mac, BWN_INTR_REASON); 8412 if (reason == 0xffffffff) /* shared IRQ */ 8413 return (FILTER_STRAY); 8414 reason &= mac->mac_intr_mask; 8415 if (reason == 0) 8416 return (FILTER_HANDLED); 8417 8418 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 8419 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 8420 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 8421 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 8422 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 8423 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 8424 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 8425 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 8426 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 8427 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 8428 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 8429 8430 /* Disable interrupts. */ 8431 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 8432 8433 mac->mac_reason_intr = reason; 8434 8435 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8436 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8437 8438 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask); 8439 return (FILTER_HANDLED); 8440 } 8441 8442 static void 8443 bwn_intrtask(void *arg, int npending) 8444 { 8445 struct bwn_mac *mac = arg; 8446 struct bwn_softc *sc = mac->mac_sc; 8447 struct ifnet *ifp = sc->sc_ifp; 8448 uint32_t merged = 0; 8449 int i, tx = 0, rx = 0; 8450 8451 BWN_LOCK(sc); 8452 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 8453 (sc->sc_flags & BWN_FLAG_INVALID)) { 8454 BWN_UNLOCK(sc); 8455 return; 8456 } 8457 8458 for (i = 0; i < N(mac->mac_reason); i++) 8459 merged |= mac->mac_reason[i]; 8460 8461 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 8462 device_printf(sc->sc_dev, "MAC trans error\n"); 8463 8464 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 8465 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 8466 mac->mac_phy.txerrors--; 8467 if (mac->mac_phy.txerrors == 0) { 8468 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 8469 bwn_restart(mac, "PHY TX errors"); 8470 } 8471 } 8472 8473 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 8474 if (merged & BWN_DMAINTR_FATALMASK) { 8475 device_printf(sc->sc_dev, 8476 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 8477 mac->mac_reason[0], mac->mac_reason[1], 8478 mac->mac_reason[2], mac->mac_reason[3], 8479 mac->mac_reason[4], mac->mac_reason[5]); 8480 bwn_restart(mac, "DMA error"); 8481 BWN_UNLOCK(sc); 8482 return; 8483 } 8484 if (merged & BWN_DMAINTR_NONFATALMASK) { 8485 device_printf(sc->sc_dev, 8486 "DMA error: %#x %#x %#x %#x %#x %#x\n", 8487 mac->mac_reason[0], mac->mac_reason[1], 8488 mac->mac_reason[2], mac->mac_reason[3], 8489 mac->mac_reason[4], mac->mac_reason[5]); 8490 } 8491 } 8492 8493 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 8494 bwn_intr_ucode_debug(mac); 8495 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 8496 bwn_intr_tbtt_indication(mac); 8497 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 8498 bwn_intr_atim_end(mac); 8499 if (mac->mac_reason_intr & BWN_INTR_BEACON) 8500 bwn_intr_beacon(mac); 8501 if (mac->mac_reason_intr & BWN_INTR_PMQ) 8502 bwn_intr_pmq(mac); 8503 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 8504 bwn_intr_noise(mac); 8505 8506 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 8507 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 8508 bwn_dma_rx(mac->mac_method.dma.rx); 8509 rx = 1; 8510 } 8511 } else 8512 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 8513 8514 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8515 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8516 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8517 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8518 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 8519 8520 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 8521 bwn_intr_txeof(mac); 8522 tx = 1; 8523 } 8524 8525 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 8526 8527 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 8528 int evt = BWN_LED_EVENT_NONE; 8529 8530 if (tx && rx) { 8531 if (sc->sc_rx_rate > sc->sc_tx_rate) 8532 evt = BWN_LED_EVENT_RX; 8533 else 8534 evt = BWN_LED_EVENT_TX; 8535 } else if (tx) { 8536 evt = BWN_LED_EVENT_TX; 8537 } else if (rx) { 8538 evt = BWN_LED_EVENT_RX; 8539 } else if (rx == 0) { 8540 evt = BWN_LED_EVENT_POLL; 8541 } 8542 8543 if (evt != BWN_LED_EVENT_NONE) 8544 bwn_led_event(mac, evt); 8545 } 8546 8547 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 8548 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 8549 bwn_start_locked(ifp); 8550 } 8551 8552 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 8553 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 8554 8555 BWN_UNLOCK(sc); 8556 } 8557 8558 static void 8559 bwn_restart(struct bwn_mac *mac, const char *msg) 8560 { 8561 struct bwn_softc *sc = mac->mac_sc; 8562 struct ifnet *ifp = sc->sc_ifp; 8563 struct ieee80211com *ic = ifp->if_l2com; 8564 8565 if (mac->mac_status < BWN_MAC_STATUS_INITED) 8566 return; 8567 8568 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 8569 ieee80211_runtask(ic, &mac->mac_hwreset); 8570 } 8571 8572 static void 8573 bwn_intr_ucode_debug(struct bwn_mac *mac) 8574 { 8575 struct bwn_softc *sc = mac->mac_sc; 8576 uint16_t reason; 8577 8578 if (mac->mac_fw.opensource == 0) 8579 return; 8580 8581 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 8582 switch (reason) { 8583 case BWN_DEBUGINTR_PANIC: 8584 bwn_handle_fwpanic(mac); 8585 break; 8586 case BWN_DEBUGINTR_DUMP_SHM: 8587 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 8588 break; 8589 case BWN_DEBUGINTR_DUMP_REGS: 8590 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 8591 break; 8592 case BWN_DEBUGINTR_MARKER: 8593 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 8594 break; 8595 default: 8596 device_printf(sc->sc_dev, 8597 "ucode debug unknown reason: %#x\n", reason); 8598 } 8599 8600 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 8601 BWN_DEBUGINTR_ACK); 8602 } 8603 8604 static void 8605 bwn_intr_tbtt_indication(struct bwn_mac *mac) 8606 { 8607 struct bwn_softc *sc = mac->mac_sc; 8608 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8609 8610 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 8611 bwn_psctl(mac, 0); 8612 if (ic->ic_opmode == IEEE80211_M_IBSS) 8613 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 8614 } 8615 8616 static void 8617 bwn_intr_atim_end(struct bwn_mac *mac) 8618 { 8619 8620 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 8621 BWN_WRITE_4(mac, BWN_MACCMD, 8622 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 8623 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 8624 } 8625 } 8626 8627 static void 8628 bwn_intr_beacon(struct bwn_mac *mac) 8629 { 8630 struct bwn_softc *sc = mac->mac_sc; 8631 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 8632 uint32_t cmd, beacon0, beacon1; 8633 8634 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 8635 ic->ic_opmode == IEEE80211_M_MBSS) 8636 return; 8637 8638 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 8639 8640 cmd = BWN_READ_4(mac, BWN_MACCMD); 8641 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 8642 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 8643 8644 if (beacon0 && beacon1) { 8645 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 8646 mac->mac_intr_mask |= BWN_INTR_BEACON; 8647 return; 8648 } 8649 8650 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 8651 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 8652 bwn_load_beacon0(mac); 8653 bwn_load_beacon1(mac); 8654 cmd = BWN_READ_4(mac, BWN_MACCMD); 8655 cmd |= BWN_MACCMD_BEACON0_VALID; 8656 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8657 } else { 8658 if (!beacon0) { 8659 bwn_load_beacon0(mac); 8660 cmd = BWN_READ_4(mac, BWN_MACCMD); 8661 cmd |= BWN_MACCMD_BEACON0_VALID; 8662 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8663 } else if (!beacon1) { 8664 bwn_load_beacon1(mac); 8665 cmd = BWN_READ_4(mac, BWN_MACCMD); 8666 cmd |= BWN_MACCMD_BEACON1_VALID; 8667 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 8668 } 8669 } 8670 } 8671 8672 static void 8673 bwn_intr_pmq(struct bwn_mac *mac) 8674 { 8675 uint32_t tmp; 8676 8677 while (1) { 8678 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 8679 if (!(tmp & 0x00000008)) 8680 break; 8681 } 8682 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 8683 } 8684 8685 static void 8686 bwn_intr_noise(struct bwn_mac *mac) 8687 { 8688 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 8689 uint16_t tmp; 8690 uint8_t noise[4]; 8691 uint8_t i, j; 8692 int32_t average; 8693 8694 if (mac->mac_phy.type != BWN_PHYTYPE_G) 8695 return; 8696 8697 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 8698 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 8699 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 8700 noise[3] == 0x7f) 8701 goto new; 8702 8703 KASSERT(mac->mac_noise.noi_nsamples < 8, 8704 ("%s:%d: fail", __func__, __LINE__)); 8705 i = mac->mac_noise.noi_nsamples; 8706 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 8707 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 8708 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 8709 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 8710 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 8711 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 8712 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 8713 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 8714 mac->mac_noise.noi_nsamples++; 8715 if (mac->mac_noise.noi_nsamples == 8) { 8716 average = 0; 8717 for (i = 0; i < 8; i++) { 8718 for (j = 0; j < 4; j++) 8719 average += mac->mac_noise.noi_samples[i][j]; 8720 } 8721 average = (((average / 32) * 125) + 64) / 128; 8722 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 8723 if (tmp >= 8) 8724 average += 2; 8725 else 8726 average -= 25; 8727 average -= (tmp == 8) ? 72 : 48; 8728 8729 mac->mac_stats.link_noise = average; 8730 mac->mac_noise.noi_running = 0; 8731 return; 8732 } 8733 new: 8734 bwn_noise_gensample(mac); 8735 } 8736 8737 static int 8738 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 8739 { 8740 struct bwn_mac *mac = prq->prq_mac; 8741 struct bwn_softc *sc = mac->mac_sc; 8742 unsigned int i; 8743 8744 BWN_ASSERT_LOCKED(sc); 8745 8746 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 8747 return (0); 8748 8749 for (i = 0; i < 5000; i++) { 8750 if (bwn_pio_rxeof(prq) == 0) 8751 break; 8752 } 8753 if (i >= 5000) 8754 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 8755 return ((i > 0) ? 1 : 0); 8756 } 8757 8758 static void 8759 bwn_dma_rx(struct bwn_dma_ring *dr) 8760 { 8761 int slot, curslot; 8762 8763 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 8764 curslot = dr->get_curslot(dr); 8765 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 8766 ("%s:%d: fail", __func__, __LINE__)); 8767 8768 slot = dr->dr_curslot; 8769 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 8770 bwn_dma_rxeof(dr, &slot); 8771 8772 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 8773 BUS_DMASYNC_PREWRITE); 8774 8775 dr->set_curslot(dr, slot); 8776 dr->dr_curslot = slot; 8777 } 8778 8779 static void 8780 bwn_intr_txeof(struct bwn_mac *mac) 8781 { 8782 struct bwn_txstatus stat; 8783 uint32_t stat0, stat1; 8784 uint16_t tmp; 8785 8786 BWN_ASSERT_LOCKED(mac->mac_sc); 8787 8788 while (1) { 8789 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 8790 if (!(stat0 & 0x00000001)) 8791 break; 8792 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 8793 8794 stat.cookie = (stat0 >> 16); 8795 stat.seq = (stat1 & 0x0000ffff); 8796 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 8797 tmp = (stat0 & 0x0000ffff); 8798 stat.framecnt = ((tmp & 0xf000) >> 12); 8799 stat.rtscnt = ((tmp & 0x0f00) >> 8); 8800 stat.sreason = ((tmp & 0x001c) >> 2); 8801 stat.pm = (tmp & 0x0080) ? 1 : 0; 8802 stat.im = (tmp & 0x0040) ? 1 : 0; 8803 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 8804 stat.ack = (tmp & 0x0002) ? 1 : 0; 8805 8806 bwn_handle_txeof(mac, &stat); 8807 } 8808 } 8809 8810 static void 8811 bwn_hwreset(void *arg, int npending) 8812 { 8813 struct bwn_mac *mac = arg; 8814 struct bwn_softc *sc = mac->mac_sc; 8815 int error = 0; 8816 int prev_status; 8817 8818 BWN_LOCK(sc); 8819 8820 prev_status = mac->mac_status; 8821 if (prev_status >= BWN_MAC_STATUS_STARTED) 8822 bwn_core_stop(mac); 8823 if (prev_status >= BWN_MAC_STATUS_INITED) 8824 bwn_core_exit(mac); 8825 8826 if (prev_status >= BWN_MAC_STATUS_INITED) { 8827 error = bwn_core_init(mac); 8828 if (error) 8829 goto out; 8830 } 8831 if (prev_status >= BWN_MAC_STATUS_STARTED) 8832 bwn_core_start(mac); 8833 out: 8834 if (error) { 8835 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 8836 sc->sc_curmac = NULL; 8837 } 8838 BWN_UNLOCK(sc); 8839 } 8840 8841 static void 8842 bwn_handle_fwpanic(struct bwn_mac *mac) 8843 { 8844 struct bwn_softc *sc = mac->mac_sc; 8845 uint16_t reason; 8846 8847 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 8848 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 8849 8850 if (reason == BWN_FWPANIC_RESTART) 8851 bwn_restart(mac, "ucode panic"); 8852 } 8853 8854 static void 8855 bwn_load_beacon0(struct bwn_mac *mac) 8856 { 8857 8858 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8859 } 8860 8861 static void 8862 bwn_load_beacon1(struct bwn_mac *mac) 8863 { 8864 8865 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 8866 } 8867 8868 static uint32_t 8869 bwn_jssi_read(struct bwn_mac *mac) 8870 { 8871 uint32_t val = 0; 8872 8873 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 8874 val <<= 16; 8875 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 8876 8877 return (val); 8878 } 8879 8880 static void 8881 bwn_noise_gensample(struct bwn_mac *mac) 8882 { 8883 uint32_t jssi = 0x7f7f7f7f; 8884 8885 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 8886 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 8887 BWN_WRITE_4(mac, BWN_MACCMD, 8888 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 8889 } 8890 8891 static int 8892 bwn_dma_freeslot(struct bwn_dma_ring *dr) 8893 { 8894 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8895 8896 return (dr->dr_numslots - dr->dr_usedslot); 8897 } 8898 8899 static int 8900 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 8901 { 8902 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 8903 8904 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 8905 ("%s:%d: fail", __func__, __LINE__)); 8906 if (slot == dr->dr_numslots - 1) 8907 return (0); 8908 return (slot + 1); 8909 } 8910 8911 static void 8912 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 8913 { 8914 struct bwn_mac *mac = dr->dr_mac; 8915 struct bwn_softc *sc = mac->mac_sc; 8916 struct bwn_dma *dma = &mac->mac_method.dma; 8917 struct bwn_dmadesc_generic *desc; 8918 struct bwn_dmadesc_meta *meta; 8919 struct bwn_rxhdr4 *rxhdr; 8920 struct ifnet *ifp = sc->sc_ifp; 8921 struct mbuf *m; 8922 uint32_t macstat; 8923 int32_t tmp; 8924 int cnt = 0; 8925 uint16_t len; 8926 8927 dr->getdesc(dr, *slot, &desc, &meta); 8928 8929 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 8930 m = meta->mt_m; 8931 8932 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 8933 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 8934 return; 8935 } 8936 8937 rxhdr = mtod(m, struct bwn_rxhdr4 *); 8938 len = le16toh(rxhdr->frame_len); 8939 if (len <= 0) { 8940 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 8941 return; 8942 } 8943 if (bwn_dma_check_redzone(dr, m)) { 8944 device_printf(sc->sc_dev, "redzone error.\n"); 8945 bwn_dma_set_redzone(dr, m); 8946 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8947 BUS_DMASYNC_PREWRITE); 8948 return; 8949 } 8950 if (len > dr->dr_rx_bufsize) { 8951 tmp = len; 8952 while (1) { 8953 dr->getdesc(dr, *slot, &desc, &meta); 8954 bwn_dma_set_redzone(dr, meta->mt_m); 8955 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 8956 BUS_DMASYNC_PREWRITE); 8957 *slot = bwn_dma_nextslot(dr, *slot); 8958 cnt++; 8959 tmp -= dr->dr_rx_bufsize; 8960 if (tmp <= 0) 8961 break; 8962 } 8963 device_printf(sc->sc_dev, "too small buffer " 8964 "(len %u buffer %u dropped %d)\n", 8965 len, dr->dr_rx_bufsize, cnt); 8966 return; 8967 } 8968 macstat = le32toh(rxhdr->mac_status); 8969 if (macstat & BWN_RX_MAC_FCSERR) { 8970 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 8971 device_printf(sc->sc_dev, "RX drop\n"); 8972 return; 8973 } 8974 } 8975 8976 m->m_pkthdr.rcvif = ifp; 8977 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 8978 m_adj(m, dr->dr_frameoffset); 8979 8980 bwn_rxeof(dr->dr_mac, m, rxhdr); 8981 } 8982 8983 static void 8984 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 8985 { 8986 struct bwn_dma_ring *dr; 8987 struct bwn_dmadesc_generic *desc; 8988 struct bwn_dmadesc_meta *meta; 8989 struct bwn_pio_txqueue *tq; 8990 struct bwn_pio_txpkt *tp = NULL; 8991 struct bwn_softc *sc = mac->mac_sc; 8992 struct bwn_stats *stats = &mac->mac_stats; 8993 struct ieee80211_node *ni; 8994 struct ieee80211vap *vap; 8995 int retrycnt = 0, slot; 8996 8997 BWN_ASSERT_LOCKED(mac->mac_sc); 8998 8999 if (status->im) 9000 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 9001 if (status->ampdu) 9002 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 9003 if (status->rtscnt) { 9004 if (status->rtscnt == 0xf) 9005 stats->rtsfail++; 9006 else 9007 stats->rts++; 9008 } 9009 9010 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 9011 if (status->ack) { 9012 dr = bwn_dma_parse_cookie(mac, status, 9013 status->cookie, &slot); 9014 if (dr == NULL) { 9015 device_printf(sc->sc_dev, 9016 "failed to parse cookie\n"); 9017 return; 9018 } 9019 while (1) { 9020 dr->getdesc(dr, slot, &desc, &meta); 9021 if (meta->mt_islast) { 9022 ni = meta->mt_ni; 9023 vap = ni->ni_vap; 9024 ieee80211_ratectl_tx_complete(vap, ni, 9025 status->ack ? 9026 IEEE80211_RATECTL_TX_SUCCESS : 9027 IEEE80211_RATECTL_TX_FAILURE, 9028 &retrycnt, 0); 9029 break; 9030 } 9031 slot = bwn_dma_nextslot(dr, slot); 9032 } 9033 } 9034 bwn_dma_handle_txeof(mac, status); 9035 } else { 9036 if (status->ack) { 9037 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9038 if (tq == NULL) { 9039 device_printf(sc->sc_dev, 9040 "failed to parse cookie\n"); 9041 return; 9042 } 9043 ni = tp->tp_ni; 9044 vap = ni->ni_vap; 9045 ieee80211_ratectl_tx_complete(vap, ni, 9046 status->ack ? 9047 IEEE80211_RATECTL_TX_SUCCESS : 9048 IEEE80211_RATECTL_TX_FAILURE, 9049 &retrycnt, 0); 9050 } 9051 bwn_pio_handle_txeof(mac, status); 9052 } 9053 9054 bwn_phy_txpower_check(mac, 0); 9055 } 9056 9057 static uint8_t 9058 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 9059 { 9060 struct bwn_mac *mac = prq->prq_mac; 9061 struct bwn_softc *sc = mac->mac_sc; 9062 struct bwn_rxhdr4 rxhdr; 9063 struct ifnet *ifp = sc->sc_ifp; 9064 struct mbuf *m; 9065 uint32_t ctl32, macstat, v32; 9066 unsigned int i, padding; 9067 uint16_t ctl16, len, totlen, v16; 9068 unsigned char *mp; 9069 char *data; 9070 9071 memset(&rxhdr, 0, sizeof(rxhdr)); 9072 9073 if (prq->prq_rev >= 8) { 9074 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9075 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 9076 return (0); 9077 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9078 BWN_PIO8_RXCTL_FRAMEREADY); 9079 for (i = 0; i < 10; i++) { 9080 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 9081 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 9082 goto ready; 9083 DELAY(10); 9084 } 9085 } else { 9086 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9087 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 9088 return (0); 9089 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 9090 BWN_PIO_RXCTL_FRAMEREADY); 9091 for (i = 0; i < 10; i++) { 9092 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 9093 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 9094 goto ready; 9095 DELAY(10); 9096 } 9097 } 9098 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 9099 return (1); 9100 ready: 9101 if (prq->prq_rev >= 8) 9102 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9103 prq->prq_base + BWN_PIO8_RXDATA); 9104 else 9105 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 9106 prq->prq_base + BWN_PIO_RXDATA); 9107 len = le16toh(rxhdr.frame_len); 9108 if (len > 0x700) { 9109 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 9110 goto error; 9111 } 9112 if (len == 0) { 9113 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 9114 goto error; 9115 } 9116 9117 macstat = le32toh(rxhdr.mac_status); 9118 if (macstat & BWN_RX_MAC_FCSERR) { 9119 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 9120 device_printf(sc->sc_dev, "%s: FCS error", __func__); 9121 goto error; 9122 } 9123 } 9124 9125 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9126 totlen = len + padding; 9127 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 9128 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9129 if (m == NULL) { 9130 device_printf(sc->sc_dev, "%s: out of memory", __func__); 9131 goto error; 9132 } 9133 mp = mtod(m, unsigned char *); 9134 if (prq->prq_rev >= 8) { 9135 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 9136 prq->prq_base + BWN_PIO8_RXDATA); 9137 if (totlen & 3) { 9138 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 9139 data = &(mp[totlen - 1]); 9140 switch (totlen & 3) { 9141 case 3: 9142 *data = (v32 >> 16); 9143 data--; 9144 case 2: 9145 *data = (v32 >> 8); 9146 data--; 9147 case 1: 9148 *data = v32; 9149 } 9150 } 9151 } else { 9152 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 9153 prq->prq_base + BWN_PIO_RXDATA); 9154 if (totlen & 1) { 9155 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 9156 mp[totlen - 1] = v16; 9157 } 9158 } 9159 9160 m->m_pkthdr.rcvif = ifp; 9161 m->m_len = m->m_pkthdr.len = totlen; 9162 9163 bwn_rxeof(prq->prq_mac, m, &rxhdr); 9164 9165 return (1); 9166 error: 9167 if (prq->prq_rev >= 8) 9168 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 9169 BWN_PIO8_RXCTL_DATAREADY); 9170 else 9171 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 9172 return (1); 9173 } 9174 9175 static int 9176 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 9177 struct bwn_dmadesc_meta *meta, int init) 9178 { 9179 struct bwn_mac *mac = dr->dr_mac; 9180 struct bwn_dma *dma = &mac->mac_method.dma; 9181 struct bwn_rxhdr4 *hdr; 9182 bus_dmamap_t map; 9183 bus_addr_t paddr; 9184 struct mbuf *m; 9185 int error; 9186 9187 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 9188 if (m == NULL) { 9189 error = ENOBUFS; 9190 9191 /* 9192 * If the NIC is up and running, we need to: 9193 * - Clear RX buffer's header. 9194 * - Restore RX descriptor settings. 9195 */ 9196 if (init) 9197 return (error); 9198 else 9199 goto back; 9200 } 9201 m->m_len = m->m_pkthdr.len = MCLBYTES; 9202 9203 bwn_dma_set_redzone(dr, m); 9204 9205 /* 9206 * Try to load RX buf into temporary DMA map 9207 */ 9208 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 9209 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 9210 if (error) { 9211 m_freem(m); 9212 9213 /* 9214 * See the comment above 9215 */ 9216 if (init) 9217 return (error); 9218 else 9219 goto back; 9220 } 9221 9222 if (!init) 9223 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 9224 meta->mt_m = m; 9225 meta->mt_paddr = paddr; 9226 9227 /* 9228 * Swap RX buf's DMA map with the loaded temporary one 9229 */ 9230 map = meta->mt_dmap; 9231 meta->mt_dmap = dr->dr_spare_dmap; 9232 dr->dr_spare_dmap = map; 9233 9234 back: 9235 /* 9236 * Clear RX buf header 9237 */ 9238 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 9239 bzero(hdr, sizeof(*hdr)); 9240 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 9241 BUS_DMASYNC_PREWRITE); 9242 9243 /* 9244 * Setup RX buf descriptor 9245 */ 9246 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 9247 sizeof(*hdr), 0, 0, 0); 9248 return (error); 9249 } 9250 9251 static void 9252 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 9253 bus_size_t mapsz __unused, int error) 9254 { 9255 9256 if (!error) { 9257 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 9258 *((bus_addr_t *)arg) = seg->ds_addr; 9259 } 9260 } 9261 9262 static int 9263 bwn_hwrate2ieeerate(int rate) 9264 { 9265 9266 switch (rate) { 9267 case BWN_CCK_RATE_1MB: 9268 return (2); 9269 case BWN_CCK_RATE_2MB: 9270 return (4); 9271 case BWN_CCK_RATE_5MB: 9272 return (11); 9273 case BWN_CCK_RATE_11MB: 9274 return (22); 9275 case BWN_OFDM_RATE_6MB: 9276 return (12); 9277 case BWN_OFDM_RATE_9MB: 9278 return (18); 9279 case BWN_OFDM_RATE_12MB: 9280 return (24); 9281 case BWN_OFDM_RATE_18MB: 9282 return (36); 9283 case BWN_OFDM_RATE_24MB: 9284 return (48); 9285 case BWN_OFDM_RATE_36MB: 9286 return (72); 9287 case BWN_OFDM_RATE_48MB: 9288 return (96); 9289 case BWN_OFDM_RATE_54MB: 9290 return (108); 9291 default: 9292 printf("Ooops\n"); 9293 return (0); 9294 } 9295 } 9296 9297 static void 9298 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 9299 { 9300 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 9301 struct bwn_plcp6 *plcp; 9302 struct bwn_softc *sc = mac->mac_sc; 9303 struct ieee80211_frame_min *wh; 9304 struct ieee80211_node *ni; 9305 struct ifnet *ifp = sc->sc_ifp; 9306 struct ieee80211com *ic = ifp->if_l2com; 9307 uint32_t macstat; 9308 int padding, rate, rssi = 0, noise = 0, type; 9309 uint16_t phytype, phystat0, phystat3, chanstat; 9310 unsigned char *mp = mtod(m, unsigned char *); 9311 static int rx_mac_dec_rpt = 0; 9312 9313 BWN_ASSERT_LOCKED(sc); 9314 9315 phystat0 = le16toh(rxhdr->phy_status0); 9316 phystat3 = le16toh(rxhdr->phy_status3); 9317 macstat = le32toh(rxhdr->mac_status); 9318 chanstat = le16toh(rxhdr->channel); 9319 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 9320 9321 if (macstat & BWN_RX_MAC_FCSERR) 9322 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 9323 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 9324 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 9325 if (macstat & BWN_RX_MAC_DECERR) 9326 goto drop; 9327 9328 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 9329 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 9330 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9331 m->m_pkthdr.len); 9332 goto drop; 9333 } 9334 plcp = (struct bwn_plcp6 *)(mp + padding); 9335 m_adj(m, sizeof(struct bwn_plcp6) + padding); 9336 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 9337 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 9338 m->m_pkthdr.len); 9339 goto drop; 9340 } 9341 wh = mtod(m, struct ieee80211_frame_min *); 9342 9343 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 9344 device_printf(sc->sc_dev, 9345 "RX decryption attempted (old %d keyidx %#x)\n", 9346 BWN_ISOLDFMT(mac), 9347 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 9348 9349 /* XXX calculating RSSI & noise & antenna */ 9350 9351 if (phystat0 & BWN_RX_PHYST0_OFDM) 9352 rate = bwn_plcp_get_ofdmrate(mac, plcp, 9353 phytype == BWN_PHYTYPE_A); 9354 else 9355 rate = bwn_plcp_get_cckrate(mac, plcp); 9356 if (rate == -1) { 9357 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 9358 goto drop; 9359 } 9360 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 9361 9362 /* RX radio tap */ 9363 if (ieee80211_radiotap_active(ic)) 9364 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 9365 m_adj(m, -IEEE80211_CRC_LEN); 9366 9367 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ 9368 noise = mac->mac_stats.link_noise; 9369 9370 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 9371 9372 BWN_UNLOCK(sc); 9373 9374 ni = ieee80211_find_rxnode(ic, wh); 9375 if (ni != NULL) { 9376 type = ieee80211_input(ni, m, rssi, noise); 9377 ieee80211_free_node(ni); 9378 } else 9379 type = ieee80211_input_all(ic, m, rssi, noise); 9380 9381 BWN_LOCK(sc); 9382 return; 9383 drop: 9384 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 9385 } 9386 9387 static void 9388 bwn_dma_handle_txeof(struct bwn_mac *mac, 9389 const struct bwn_txstatus *status) 9390 { 9391 struct bwn_dma *dma = &mac->mac_method.dma; 9392 struct bwn_dma_ring *dr; 9393 struct bwn_dmadesc_generic *desc; 9394 struct bwn_dmadesc_meta *meta; 9395 struct bwn_softc *sc = mac->mac_sc; 9396 struct ieee80211_node *ni; 9397 struct ifnet *ifp = sc->sc_ifp; 9398 struct mbuf *m; 9399 int slot; 9400 9401 BWN_ASSERT_LOCKED(sc); 9402 9403 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 9404 if (dr == NULL) { 9405 device_printf(sc->sc_dev, "failed to parse cookie\n"); 9406 return; 9407 } 9408 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 9409 9410 while (1) { 9411 KASSERT(slot >= 0 && slot < dr->dr_numslots, 9412 ("%s:%d: fail", __func__, __LINE__)); 9413 dr->getdesc(dr, slot, &desc, &meta); 9414 9415 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 9416 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 9417 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 9418 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 9419 9420 if (meta->mt_islast) { 9421 KASSERT(meta->mt_m != NULL, 9422 ("%s:%d: fail", __func__, __LINE__)); 9423 9424 ni = meta->mt_ni; 9425 m = meta->mt_m; 9426 if (ni != NULL) { 9427 /* 9428 * Do any tx complete callback. Note this must 9429 * be done before releasing the node reference. 9430 */ 9431 if (m->m_flags & M_TXCB) 9432 ieee80211_process_callback(ni, m, 0); 9433 ieee80211_free_node(ni); 9434 meta->mt_ni = NULL; 9435 } 9436 m_freem(m); 9437 meta->mt_m = NULL; 9438 } else { 9439 KASSERT(meta->mt_m == NULL, 9440 ("%s:%d: fail", __func__, __LINE__)); 9441 } 9442 9443 dr->dr_usedslot--; 9444 if (meta->mt_islast) { 9445 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 9446 break; 9447 } 9448 slot = bwn_dma_nextslot(dr, slot); 9449 } 9450 sc->sc_watchdog_timer = 0; 9451 if (dr->dr_stop) { 9452 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 9453 ("%s:%d: fail", __func__, __LINE__)); 9454 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9455 dr->dr_stop = 0; 9456 } 9457 } 9458 9459 static void 9460 bwn_pio_handle_txeof(struct bwn_mac *mac, 9461 const struct bwn_txstatus *status) 9462 { 9463 struct bwn_pio_txqueue *tq; 9464 struct bwn_pio_txpkt *tp = NULL; 9465 struct bwn_softc *sc = mac->mac_sc; 9466 struct ifnet *ifp = sc->sc_ifp; 9467 9468 BWN_ASSERT_LOCKED(sc); 9469 9470 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 9471 if (tq == NULL) 9472 return; 9473 9474 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 9475 tq->tq_free++; 9476 9477 if (tp->tp_ni != NULL) { 9478 /* 9479 * Do any tx complete callback. Note this must 9480 * be done before releasing the node reference. 9481 */ 9482 if (tp->tp_m->m_flags & M_TXCB) 9483 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 9484 ieee80211_free_node(tp->tp_ni); 9485 tp->tp_ni = NULL; 9486 } 9487 m_freem(tp->tp_m); 9488 tp->tp_m = NULL; 9489 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 9490 9491 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 9492 9493 sc->sc_watchdog_timer = 0; 9494 if (tq->tq_stop) { 9495 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 9496 tq->tq_stop = 0; 9497 } 9498 } 9499 9500 static void 9501 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 9502 { 9503 struct bwn_softc *sc = mac->mac_sc; 9504 struct bwn_phy *phy = &mac->mac_phy; 9505 struct ifnet *ifp = sc->sc_ifp; 9506 struct ieee80211com *ic = ifp->if_l2com; 9507 unsigned long now; 9508 int result; 9509 9510 BWN_GETTIME(now); 9511 9512 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime)) 9513 return; 9514 phy->nexttime = now + 2 * 1000; 9515 9516 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 9517 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 9518 return; 9519 9520 if (phy->recalc_txpwr != NULL) { 9521 result = phy->recalc_txpwr(mac, 9522 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 9523 if (result == BWN_TXPWR_RES_DONE) 9524 return; 9525 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 9526 ("%s: fail", __func__)); 9527 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 9528 9529 ieee80211_runtask(ic, &mac->mac_txpower); 9530 } 9531 } 9532 9533 static uint16_t 9534 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 9535 { 9536 9537 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 9538 } 9539 9540 static uint32_t 9541 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 9542 { 9543 9544 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 9545 } 9546 9547 static void 9548 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 9549 { 9550 9551 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 9552 } 9553 9554 static void 9555 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 9556 { 9557 9558 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 9559 } 9560 9561 static int 9562 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 9563 { 9564 9565 switch (rate) { 9566 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 9567 case 12: 9568 return (BWN_OFDM_RATE_6MB); 9569 case 18: 9570 return (BWN_OFDM_RATE_9MB); 9571 case 24: 9572 return (BWN_OFDM_RATE_12MB); 9573 case 36: 9574 return (BWN_OFDM_RATE_18MB); 9575 case 48: 9576 return (BWN_OFDM_RATE_24MB); 9577 case 72: 9578 return (BWN_OFDM_RATE_36MB); 9579 case 96: 9580 return (BWN_OFDM_RATE_48MB); 9581 case 108: 9582 return (BWN_OFDM_RATE_54MB); 9583 /* CCK rates (NB: not IEEE std, device-specific) */ 9584 case 2: 9585 return (BWN_CCK_RATE_1MB); 9586 case 4: 9587 return (BWN_CCK_RATE_2MB); 9588 case 11: 9589 return (BWN_CCK_RATE_5MB); 9590 case 22: 9591 return (BWN_CCK_RATE_11MB); 9592 } 9593 9594 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 9595 return (BWN_CCK_RATE_1MB); 9596 } 9597 9598 static int 9599 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 9600 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 9601 { 9602 const struct bwn_phy *phy = &mac->mac_phy; 9603 struct bwn_softc *sc = mac->mac_sc; 9604 struct ieee80211_frame *wh; 9605 struct ieee80211_frame *protwh; 9606 struct ieee80211_frame_cts *cts; 9607 struct ieee80211_frame_rts *rts; 9608 const struct ieee80211_txparam *tp; 9609 struct ieee80211vap *vap = ni->ni_vap; 9610 struct ifnet *ifp = sc->sc_ifp; 9611 struct ieee80211com *ic = ifp->if_l2com; 9612 struct mbuf *mprot; 9613 unsigned int len; 9614 uint32_t macctl = 0; 9615 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 9616 uint16_t phyctl = 0; 9617 uint8_t rate, rate_fb; 9618 9619 wh = mtod(m, struct ieee80211_frame *); 9620 memset(txhdr, 0, sizeof(*txhdr)); 9621 9622 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9623 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 9624 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 9625 9626 /* 9627 * Find TX rate 9628 */ 9629 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 9630 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 9631 rate = rate_fb = tp->mgmtrate; 9632 else if (ismcast) 9633 rate = rate_fb = tp->mcastrate; 9634 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 9635 rate = rate_fb = tp->ucastrate; 9636 else { 9637 rix = ieee80211_ratectl_rate(ni, NULL, 0); 9638 rate = ni->ni_txrate; 9639 9640 if (rix > 0) 9641 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 9642 IEEE80211_RATE_VAL; 9643 else 9644 rate_fb = rate; 9645 } 9646 9647 sc->sc_tx_rate = rate; 9648 9649 rate = bwn_ieeerate2hwrate(sc, rate); 9650 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 9651 9652 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 9653 bwn_plcp_getcck(rate); 9654 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 9655 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 9656 9657 if ((rate_fb == rate) || 9658 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 9659 (*(u_int16_t *)wh->i_dur == htole16(0))) 9660 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 9661 else 9662 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 9663 m->m_pkthdr.len, rate, isshort); 9664 9665 /* XXX TX encryption */ 9666 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 9667 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 9668 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 9669 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 9670 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 9671 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 9672 9673 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 9674 BWN_TX_EFT_FB_CCK; 9675 txhdr->chan = phy->chan; 9676 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 9677 BWN_TX_PHY_ENC_CCK; 9678 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9679 rate == BWN_CCK_RATE_11MB)) 9680 phyctl |= BWN_TX_PHY_SHORTPRMBL; 9681 9682 /* XXX TX antenna selection */ 9683 9684 switch (bwn_antenna_sanitize(mac, 0)) { 9685 case 0: 9686 phyctl |= BWN_TX_PHY_ANT01AUTO; 9687 break; 9688 case 1: 9689 phyctl |= BWN_TX_PHY_ANT0; 9690 break; 9691 case 2: 9692 phyctl |= BWN_TX_PHY_ANT1; 9693 break; 9694 case 3: 9695 phyctl |= BWN_TX_PHY_ANT2; 9696 break; 9697 case 4: 9698 phyctl |= BWN_TX_PHY_ANT3; 9699 break; 9700 default: 9701 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9702 } 9703 9704 if (!ismcast) 9705 macctl |= BWN_TX_MAC_ACK; 9706 9707 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 9708 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 9709 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 9710 macctl |= BWN_TX_MAC_LONGFRAME; 9711 9712 if (ic->ic_flags & IEEE80211_F_USEPROT) { 9713 /* XXX RTS rate is always 1MB??? */ 9714 rts_rate = BWN_CCK_RATE_1MB; 9715 rts_rate_fb = bwn_get_fbrate(rts_rate); 9716 9717 protdur = ieee80211_compute_duration(ic->ic_rt, 9718 m->m_pkthdr.len, rate, isshort) + 9719 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 9720 9721 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 9722 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 9723 (txhdr->body.old.rts_frame) : 9724 (txhdr->body.new.rts_frame)); 9725 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 9726 protdur); 9727 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9728 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 9729 mprot->m_pkthdr.len); 9730 m_freem(mprot); 9731 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 9732 len = sizeof(struct ieee80211_frame_cts); 9733 } else { 9734 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 9735 (txhdr->body.old.rts_frame) : 9736 (txhdr->body.new.rts_frame)); 9737 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 9738 isshort); 9739 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 9740 wh->i_addr2, protdur); 9741 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 9742 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 9743 mprot->m_pkthdr.len); 9744 m_freem(mprot); 9745 macctl |= BWN_TX_MAC_SEND_RTSCTS; 9746 len = sizeof(struct ieee80211_frame_rts); 9747 } 9748 len += IEEE80211_CRC_LEN; 9749 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 9750 &txhdr->body.old.rts_plcp : 9751 &txhdr->body.new.rts_plcp), len, rts_rate); 9752 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 9753 rts_rate_fb); 9754 9755 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 9756 (&txhdr->body.old.rts_frame) : 9757 (&txhdr->body.new.rts_frame)); 9758 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 9759 9760 if (BWN_ISOFDMRATE(rts_rate)) { 9761 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 9762 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 9763 } else { 9764 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 9765 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 9766 } 9767 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 9768 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 9769 } 9770 9771 if (BWN_ISOLDFMT(mac)) 9772 txhdr->body.old.cookie = htole16(cookie); 9773 else 9774 txhdr->body.new.cookie = htole16(cookie); 9775 9776 txhdr->macctl = htole32(macctl); 9777 txhdr->phyctl = htole16(phyctl); 9778 9779 /* 9780 * TX radio tap 9781 */ 9782 if (ieee80211_radiotap_active_vap(vap)) { 9783 sc->sc_tx_th.wt_flags = 0; 9784 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 9785 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 9786 if (isshort && 9787 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 9788 rate == BWN_CCK_RATE_11MB)) 9789 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 9790 sc->sc_tx_th.wt_rate = rate; 9791 9792 ieee80211_radiotap_tx(vap, m); 9793 } 9794 9795 return (0); 9796 } 9797 9798 static void 9799 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 9800 const uint8_t rate) 9801 { 9802 uint32_t d, plen; 9803 uint8_t *raw = plcp->o.raw; 9804 9805 if (BWN_ISOFDMRATE(rate)) { 9806 d = bwn_plcp_getofdm(rate); 9807 KASSERT(!(octets & 0xf000), 9808 ("%s:%d: fail", __func__, __LINE__)); 9809 d |= (octets << 5); 9810 plcp->o.data = htole32(d); 9811 } else { 9812 plen = octets * 16 / rate; 9813 if ((octets * 16 % rate) > 0) { 9814 plen++; 9815 if ((rate == BWN_CCK_RATE_11MB) 9816 && ((octets * 8 % 11) < 4)) { 9817 raw[1] = 0x84; 9818 } else 9819 raw[1] = 0x04; 9820 } else 9821 raw[1] = 0x04; 9822 plcp->o.data |= htole32(plen << 16); 9823 raw[0] = bwn_plcp_getcck(rate); 9824 } 9825 } 9826 9827 static uint8_t 9828 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 9829 { 9830 struct bwn_softc *sc = mac->mac_sc; 9831 uint8_t mask; 9832 9833 if (n == 0) 9834 return (0); 9835 if (mac->mac_phy.gmode) 9836 mask = siba_sprom_get_ant_bg(sc->sc_dev); 9837 else 9838 mask = siba_sprom_get_ant_a(sc->sc_dev); 9839 if (!(mask & (1 << (n - 1)))) 9840 return (0); 9841 return (n); 9842 } 9843 9844 static uint8_t 9845 bwn_get_fbrate(uint8_t bitrate) 9846 { 9847 switch (bitrate) { 9848 case BWN_CCK_RATE_1MB: 9849 return (BWN_CCK_RATE_1MB); 9850 case BWN_CCK_RATE_2MB: 9851 return (BWN_CCK_RATE_1MB); 9852 case BWN_CCK_RATE_5MB: 9853 return (BWN_CCK_RATE_2MB); 9854 case BWN_CCK_RATE_11MB: 9855 return (BWN_CCK_RATE_5MB); 9856 case BWN_OFDM_RATE_6MB: 9857 return (BWN_CCK_RATE_5MB); 9858 case BWN_OFDM_RATE_9MB: 9859 return (BWN_OFDM_RATE_6MB); 9860 case BWN_OFDM_RATE_12MB: 9861 return (BWN_OFDM_RATE_9MB); 9862 case BWN_OFDM_RATE_18MB: 9863 return (BWN_OFDM_RATE_12MB); 9864 case BWN_OFDM_RATE_24MB: 9865 return (BWN_OFDM_RATE_18MB); 9866 case BWN_OFDM_RATE_36MB: 9867 return (BWN_OFDM_RATE_24MB); 9868 case BWN_OFDM_RATE_48MB: 9869 return (BWN_OFDM_RATE_36MB); 9870 case BWN_OFDM_RATE_54MB: 9871 return (BWN_OFDM_RATE_48MB); 9872 } 9873 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 9874 return (0); 9875 } 9876 9877 static uint32_t 9878 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9879 uint32_t ctl, const void *_data, int len) 9880 { 9881 struct bwn_softc *sc = mac->mac_sc; 9882 uint32_t value = 0; 9883 const uint8_t *data = _data; 9884 9885 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 9886 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 9887 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9888 9889 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 9890 tq->tq_base + BWN_PIO8_TXDATA); 9891 if (len & 3) { 9892 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 9893 BWN_PIO8_TXCTL_24_31); 9894 data = &(data[len - 1]); 9895 switch (len & 3) { 9896 case 3: 9897 ctl |= BWN_PIO8_TXCTL_16_23; 9898 value |= (uint32_t)(*data) << 16; 9899 data--; 9900 case 2: 9901 ctl |= BWN_PIO8_TXCTL_8_15; 9902 value |= (uint32_t)(*data) << 8; 9903 data--; 9904 case 1: 9905 value |= (uint32_t)(*data); 9906 } 9907 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 9908 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 9909 } 9910 9911 return (ctl); 9912 } 9913 9914 static void 9915 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9916 uint16_t offset, uint32_t value) 9917 { 9918 9919 BWN_WRITE_4(mac, tq->tq_base + offset, value); 9920 } 9921 9922 static uint16_t 9923 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9924 uint16_t ctl, const void *_data, int len) 9925 { 9926 struct bwn_softc *sc = mac->mac_sc; 9927 const uint8_t *data = _data; 9928 9929 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9930 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9931 9932 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 9933 tq->tq_base + BWN_PIO_TXDATA); 9934 if (len & 1) { 9935 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9936 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9937 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 9938 } 9939 9940 return (ctl); 9941 } 9942 9943 static uint16_t 9944 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 9945 uint16_t ctl, struct mbuf *m0) 9946 { 9947 int i, j = 0; 9948 uint16_t data = 0; 9949 const uint8_t *buf; 9950 struct mbuf *m = m0; 9951 9952 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 9953 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9954 9955 for (; m != NULL; m = m->m_next) { 9956 buf = mtod(m, const uint8_t *); 9957 for (i = 0; i < m->m_len; i++) { 9958 if (!((j++) % 2)) 9959 data |= buf[i]; 9960 else { 9961 data |= (buf[i] << 8); 9962 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9963 data = 0; 9964 } 9965 } 9966 } 9967 if (m0->m_pkthdr.len % 2) { 9968 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 9969 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 9970 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 9971 } 9972 9973 return (ctl); 9974 } 9975 9976 static void 9977 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 9978 { 9979 9980 if (mac->mac_phy.type != BWN_PHYTYPE_G) 9981 return; 9982 BWN_WRITE_2(mac, 0x684, 510 + time); 9983 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 9984 } 9985 9986 static struct bwn_dma_ring * 9987 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 9988 { 9989 9990 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 9991 return (mac->mac_method.dma.wme[WME_AC_BE]); 9992 9993 switch (prio) { 9994 case 3: 9995 return (mac->mac_method.dma.wme[WME_AC_VO]); 9996 case 2: 9997 return (mac->mac_method.dma.wme[WME_AC_VI]); 9998 case 0: 9999 return (mac->mac_method.dma.wme[WME_AC_BE]); 10000 case 1: 10001 return (mac->mac_method.dma.wme[WME_AC_BK]); 10002 } 10003 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 10004 return (NULL); 10005 } 10006 10007 static int 10008 bwn_dma_getslot(struct bwn_dma_ring *dr) 10009 { 10010 int slot; 10011 10012 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 10013 10014 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 10015 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 10016 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 10017 10018 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 10019 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 10020 dr->dr_curslot = slot; 10021 dr->dr_usedslot++; 10022 10023 return (slot); 10024 } 10025 10026 static int 10027 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 10028 { 10029 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 10030 unsigned int a, b, c, d; 10031 unsigned int avg; 10032 uint32_t tmp; 10033 10034 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 10035 a = tmp & 0xff; 10036 b = (tmp >> 8) & 0xff; 10037 c = (tmp >> 16) & 0xff; 10038 d = (tmp >> 24) & 0xff; 10039 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 10040 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 10041 return (ENOENT); 10042 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 10043 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 10044 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 10045 10046 if (ofdm) { 10047 a = (a + 32) & 0x3f; 10048 b = (b + 32) & 0x3f; 10049 c = (c + 32) & 0x3f; 10050 d = (d + 32) & 0x3f; 10051 } 10052 10053 avg = (a + b + c + d + 2) / 4; 10054 if (ofdm) { 10055 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 10056 & BWN_HF_4DB_CCK_POWERBOOST) 10057 avg = (avg >= 13) ? (avg - 13) : 0; 10058 } 10059 return (avg); 10060 } 10061 10062 static void 10063 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 10064 { 10065 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 10066 int rfatt = *rfattp; 10067 int bbatt = *bbattp; 10068 10069 while (1) { 10070 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 10071 break; 10072 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 10073 break; 10074 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 10075 break; 10076 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 10077 break; 10078 if (bbatt > lo->bbatt.max) { 10079 bbatt -= 4; 10080 rfatt += 1; 10081 continue; 10082 } 10083 if (bbatt < lo->bbatt.min) { 10084 bbatt += 4; 10085 rfatt -= 1; 10086 continue; 10087 } 10088 if (rfatt > lo->rfatt.max) { 10089 rfatt -= 1; 10090 bbatt += 4; 10091 continue; 10092 } 10093 if (rfatt < lo->rfatt.min) { 10094 rfatt += 1; 10095 bbatt -= 4; 10096 continue; 10097 } 10098 break; 10099 } 10100 10101 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 10102 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 10103 } 10104 10105 static void 10106 bwn_phy_lock(struct bwn_mac *mac) 10107 { 10108 struct bwn_softc *sc = mac->mac_sc; 10109 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10110 10111 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10112 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10113 10114 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10115 bwn_psctl(mac, BWN_PS_AWAKE); 10116 } 10117 10118 static void 10119 bwn_phy_unlock(struct bwn_mac *mac) 10120 { 10121 struct bwn_softc *sc = mac->mac_sc; 10122 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 10123 10124 KASSERT(siba_get_revid(sc->sc_dev) >= 3, 10125 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); 10126 10127 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 10128 bwn_psctl(mac, 0); 10129 } 10130 10131 static void 10132 bwn_rf_lock(struct bwn_mac *mac) 10133 { 10134 10135 BWN_WRITE_4(mac, BWN_MACCTL, 10136 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 10137 BWN_READ_4(mac, BWN_MACCTL); 10138 DELAY(10); 10139 } 10140 10141 static void 10142 bwn_rf_unlock(struct bwn_mac *mac) 10143 { 10144 10145 BWN_READ_2(mac, BWN_PHYVER); 10146 BWN_WRITE_4(mac, BWN_MACCTL, 10147 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 10148 } 10149 10150 static struct bwn_pio_txqueue * 10151 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 10152 struct bwn_pio_txpkt **pack) 10153 { 10154 struct bwn_pio *pio = &mac->mac_method.pio; 10155 struct bwn_pio_txqueue *tq = NULL; 10156 unsigned int index; 10157 10158 switch (cookie & 0xf000) { 10159 case 0x1000: 10160 tq = &pio->wme[WME_AC_BK]; 10161 break; 10162 case 0x2000: 10163 tq = &pio->wme[WME_AC_BE]; 10164 break; 10165 case 0x3000: 10166 tq = &pio->wme[WME_AC_VI]; 10167 break; 10168 case 0x4000: 10169 tq = &pio->wme[WME_AC_VO]; 10170 break; 10171 case 0x5000: 10172 tq = &pio->mcast; 10173 break; 10174 } 10175 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 10176 if (tq == NULL) 10177 return (NULL); 10178 index = (cookie & 0x0fff); 10179 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 10180 if (index >= N(tq->tq_pkts)) 10181 return (NULL); 10182 *pack = &tq->tq_pkts[index]; 10183 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 10184 return (tq); 10185 } 10186 10187 static void 10188 bwn_txpwr(void *arg, int npending) 10189 { 10190 struct bwn_mac *mac = arg; 10191 struct bwn_softc *sc = mac->mac_sc; 10192 10193 BWN_LOCK(sc); 10194 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 10195 mac->mac_phy.set_txpwr != NULL) 10196 mac->mac_phy.set_txpwr(mac); 10197 BWN_UNLOCK(sc); 10198 } 10199 10200 static void 10201 bwn_task_15s(struct bwn_mac *mac) 10202 { 10203 uint16_t reg; 10204 10205 if (mac->mac_fw.opensource) { 10206 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 10207 if (reg) { 10208 bwn_restart(mac, "fw watchdog"); 10209 return; 10210 } 10211 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 10212 } 10213 if (mac->mac_phy.task_15s) 10214 mac->mac_phy.task_15s(mac); 10215 10216 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 10217 } 10218 10219 static void 10220 bwn_task_30s(struct bwn_mac *mac) 10221 { 10222 10223 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 10224 return; 10225 mac->mac_noise.noi_running = 1; 10226 mac->mac_noise.noi_nsamples = 0; 10227 10228 bwn_noise_gensample(mac); 10229 } 10230 10231 static void 10232 bwn_task_60s(struct bwn_mac *mac) 10233 { 10234 10235 if (mac->mac_phy.task_60s) 10236 mac->mac_phy.task_60s(mac); 10237 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 10238 } 10239 10240 static void 10241 bwn_tasks(void *arg) 10242 { 10243 struct bwn_mac *mac = arg; 10244 struct bwn_softc *sc = mac->mac_sc; 10245 10246 BWN_ASSERT_LOCKED(sc); 10247 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 10248 return; 10249 10250 if (mac->mac_task_state % 4 == 0) 10251 bwn_task_60s(mac); 10252 if (mac->mac_task_state % 2 == 0) 10253 bwn_task_30s(mac); 10254 bwn_task_15s(mac); 10255 10256 mac->mac_task_state++; 10257 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 10258 } 10259 10260 static int 10261 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 10262 { 10263 struct bwn_softc *sc = mac->mac_sc; 10264 10265 KASSERT(a == 0, ("not support APHY\n")); 10266 10267 switch (plcp->o.raw[0] & 0xf) { 10268 case 0xb: 10269 return (BWN_OFDM_RATE_6MB); 10270 case 0xf: 10271 return (BWN_OFDM_RATE_9MB); 10272 case 0xa: 10273 return (BWN_OFDM_RATE_12MB); 10274 case 0xe: 10275 return (BWN_OFDM_RATE_18MB); 10276 case 0x9: 10277 return (BWN_OFDM_RATE_24MB); 10278 case 0xd: 10279 return (BWN_OFDM_RATE_36MB); 10280 case 0x8: 10281 return (BWN_OFDM_RATE_48MB); 10282 case 0xc: 10283 return (BWN_OFDM_RATE_54MB); 10284 } 10285 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 10286 plcp->o.raw[0] & 0xf); 10287 return (-1); 10288 } 10289 10290 static int 10291 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 10292 { 10293 struct bwn_softc *sc = mac->mac_sc; 10294 10295 switch (plcp->o.raw[0]) { 10296 case 0x0a: 10297 return (BWN_CCK_RATE_1MB); 10298 case 0x14: 10299 return (BWN_CCK_RATE_2MB); 10300 case 0x37: 10301 return (BWN_CCK_RATE_5MB); 10302 case 0x6e: 10303 return (BWN_CCK_RATE_11MB); 10304 } 10305 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 10306 return (-1); 10307 } 10308 10309 static void 10310 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 10311 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 10312 int rssi, int noise) 10313 { 10314 struct bwn_softc *sc = mac->mac_sc; 10315 const struct ieee80211_frame_min *wh; 10316 uint64_t tsf; 10317 uint16_t low_mactime_now; 10318 10319 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 10320 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 10321 10322 wh = mtod(m, const struct ieee80211_frame_min *); 10323 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 10324 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 10325 10326 bwn_tsf_read(mac, &tsf); 10327 low_mactime_now = tsf; 10328 tsf = tsf & ~0xffffULL; 10329 tsf += le16toh(rxhdr->mac_time); 10330 if (low_mactime_now < le16toh(rxhdr->mac_time)) 10331 tsf -= 0x10000; 10332 10333 sc->sc_rx_th.wr_tsf = tsf; 10334 sc->sc_rx_th.wr_rate = rate; 10335 sc->sc_rx_th.wr_antsignal = rssi; 10336 sc->sc_rx_th.wr_antnoise = noise; 10337 } 10338 10339 static void 10340 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 10341 { 10342 uint32_t low, high; 10343 10344 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 10345 ("%s:%d: fail", __func__, __LINE__)); 10346 10347 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 10348 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 10349 *tsf = high; 10350 *tsf <<= 32; 10351 *tsf |= low; 10352 } 10353 10354 static int 10355 bwn_dma_attach(struct bwn_mac *mac) 10356 { 10357 struct bwn_dma *dma = &mac->mac_method.dma; 10358 struct bwn_softc *sc = mac->mac_sc; 10359 bus_addr_t lowaddr = 0; 10360 int error; 10361 10362 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 10363 return (0); 10364 10365 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 10366 10367 mac->mac_flags |= BWN_MAC_FLAG_DMA; 10368 10369 dma->dmatype = bwn_dma_gettype(mac); 10370 if (dma->dmatype == BWN_DMA_30BIT) 10371 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 10372 else if (dma->dmatype == BWN_DMA_32BIT) 10373 lowaddr = BUS_SPACE_MAXADDR_32BIT; 10374 else 10375 lowaddr = BUS_SPACE_MAXADDR; 10376 10377 /* 10378 * Create top level DMA tag 10379 */ 10380 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 10381 BWN_ALIGN, 0, /* alignment, bounds */ 10382 lowaddr, /* lowaddr */ 10383 BUS_SPACE_MAXADDR, /* highaddr */ 10384 NULL, NULL, /* filter, filterarg */ 10385 BUS_SPACE_MAXSIZE, /* maxsize */ 10386 BUS_SPACE_UNRESTRICTED, /* nsegments */ 10387 BUS_SPACE_MAXSIZE, /* maxsegsize */ 10388 0, /* flags */ 10389 NULL, NULL, /* lockfunc, lockarg */ 10390 &dma->parent_dtag); 10391 if (error) { 10392 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 10393 return (error); 10394 } 10395 10396 /* 10397 * Create TX/RX mbuf DMA tag 10398 */ 10399 error = bus_dma_tag_create(dma->parent_dtag, 10400 1, 10401 0, 10402 BUS_SPACE_MAXADDR, 10403 BUS_SPACE_MAXADDR, 10404 NULL, NULL, 10405 MCLBYTES, 10406 1, 10407 BUS_SPACE_MAXSIZE_32BIT, 10408 0, 10409 NULL, NULL, 10410 &dma->rxbuf_dtag); 10411 if (error) { 10412 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10413 goto fail0; 10414 } 10415 error = bus_dma_tag_create(dma->parent_dtag, 10416 1, 10417 0, 10418 BUS_SPACE_MAXADDR, 10419 BUS_SPACE_MAXADDR, 10420 NULL, NULL, 10421 MCLBYTES, 10422 1, 10423 BUS_SPACE_MAXSIZE_32BIT, 10424 0, 10425 NULL, NULL, 10426 &dma->txbuf_dtag); 10427 if (error) { 10428 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 10429 goto fail1; 10430 } 10431 10432 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 10433 if (!dma->wme[WME_AC_BK]) 10434 goto fail2; 10435 10436 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 10437 if (!dma->wme[WME_AC_BE]) 10438 goto fail3; 10439 10440 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 10441 if (!dma->wme[WME_AC_VI]) 10442 goto fail4; 10443 10444 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 10445 if (!dma->wme[WME_AC_VO]) 10446 goto fail5; 10447 10448 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 10449 if (!dma->mcast) 10450 goto fail6; 10451 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 10452 if (!dma->rx) 10453 goto fail7; 10454 10455 return (error); 10456 10457 fail7: bwn_dma_ringfree(&dma->mcast); 10458 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 10459 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 10460 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 10461 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 10462 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 10463 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 10464 fail0: bus_dma_tag_destroy(dma->parent_dtag); 10465 return (error); 10466 } 10467 10468 static struct bwn_dma_ring * 10469 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 10470 uint16_t cookie, int *slot) 10471 { 10472 struct bwn_dma *dma = &mac->mac_method.dma; 10473 struct bwn_dma_ring *dr; 10474 struct bwn_softc *sc = mac->mac_sc; 10475 10476 BWN_ASSERT_LOCKED(mac->mac_sc); 10477 10478 switch (cookie & 0xf000) { 10479 case 0x1000: 10480 dr = dma->wme[WME_AC_BK]; 10481 break; 10482 case 0x2000: 10483 dr = dma->wme[WME_AC_BE]; 10484 break; 10485 case 0x3000: 10486 dr = dma->wme[WME_AC_VI]; 10487 break; 10488 case 0x4000: 10489 dr = dma->wme[WME_AC_VO]; 10490 break; 10491 case 0x5000: 10492 dr = dma->mcast; 10493 break; 10494 default: 10495 dr = NULL; 10496 KASSERT(0 == 1, 10497 ("invalid cookie value %d", cookie & 0xf000)); 10498 } 10499 *slot = (cookie & 0x0fff); 10500 if (*slot < 0 || *slot >= dr->dr_numslots) { 10501 /* 10502 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 10503 * that it occurs events which have same H/W sequence numbers. 10504 * When it's occurred just prints a WARNING msgs and ignores. 10505 */ 10506 KASSERT(status->seq == dma->lastseq, 10507 ("%s:%d: fail", __func__, __LINE__)); 10508 device_printf(sc->sc_dev, 10509 "out of slot ranges (0 < %d < %d)\n", *slot, 10510 dr->dr_numslots); 10511 return (NULL); 10512 } 10513 dma->lastseq = status->seq; 10514 return (dr); 10515 } 10516 10517 static void 10518 bwn_dma_stop(struct bwn_mac *mac) 10519 { 10520 struct bwn_dma *dma; 10521 10522 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 10523 return; 10524 dma = &mac->mac_method.dma; 10525 10526 bwn_dma_ringstop(&dma->rx); 10527 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 10528 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 10529 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 10530 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 10531 bwn_dma_ringstop(&dma->mcast); 10532 } 10533 10534 static void 10535 bwn_dma_ringstop(struct bwn_dma_ring **dr) 10536 { 10537 10538 if (dr == NULL) 10539 return; 10540 10541 bwn_dma_cleanup(*dr); 10542 } 10543 10544 static void 10545 bwn_pio_stop(struct bwn_mac *mac) 10546 { 10547 struct bwn_pio *pio; 10548 10549 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 10550 return; 10551 pio = &mac->mac_method.pio; 10552 10553 bwn_destroy_queue_tx(&pio->mcast); 10554 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 10555 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 10556 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 10557 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 10558 } 10559 10560 static void 10561 bwn_led_attach(struct bwn_mac *mac) 10562 { 10563 struct bwn_softc *sc = mac->mac_sc; 10564 const uint8_t *led_act = NULL; 10565 uint16_t val[BWN_LED_MAX]; 10566 int i; 10567 10568 sc->sc_led_idle = (2350 * hz) / 1000; 10569 sc->sc_led_blink = 1; 10570 10571 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 10572 if (siba_get_pci_subvendor(sc->sc_dev) == 10573 bwn_vendor_led_act[i].vid) { 10574 led_act = bwn_vendor_led_act[i].led_act; 10575 break; 10576 } 10577 } 10578 if (led_act == NULL) 10579 led_act = bwn_default_led_act; 10580 10581 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 10582 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 10583 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 10584 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 10585 10586 for (i = 0; i < BWN_LED_MAX; ++i) { 10587 struct bwn_led *led = &sc->sc_leds[i]; 10588 10589 if (val[i] == 0xff) { 10590 led->led_act = led_act[i]; 10591 } else { 10592 if (val[i] & BWN_LED_ACT_LOW) 10593 led->led_flags |= BWN_LED_F_ACTLOW; 10594 led->led_act = val[i] & BWN_LED_ACT_MASK; 10595 } 10596 led->led_mask = (1 << i); 10597 10598 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 10599 led->led_act == BWN_LED_ACT_BLINK_POLL || 10600 led->led_act == BWN_LED_ACT_BLINK) { 10601 led->led_flags |= BWN_LED_F_BLINK; 10602 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 10603 led->led_flags |= BWN_LED_F_POLLABLE; 10604 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 10605 led->led_flags |= BWN_LED_F_SLOW; 10606 10607 if (sc->sc_blink_led == NULL) { 10608 sc->sc_blink_led = led; 10609 if (led->led_flags & BWN_LED_F_SLOW) 10610 BWN_LED_SLOWDOWN(sc->sc_led_idle); 10611 } 10612 } 10613 10614 DPRINTF(sc, BWN_DEBUG_LED, 10615 "%dth led, act %d, lowact %d\n", i, 10616 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 10617 } 10618 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 10619 } 10620 10621 static __inline uint16_t 10622 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 10623 { 10624 10625 if (led->led_flags & BWN_LED_F_ACTLOW) 10626 on = !on; 10627 if (on) 10628 val |= led->led_mask; 10629 else 10630 val &= ~led->led_mask; 10631 return val; 10632 } 10633 10634 static void 10635 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 10636 { 10637 struct bwn_softc *sc = mac->mac_sc; 10638 struct ifnet *ifp = sc->sc_ifp; 10639 struct ieee80211com *ic = ifp->if_l2com; 10640 uint16_t val; 10641 int i; 10642 10643 if (nstate == IEEE80211_S_INIT) { 10644 callout_stop(&sc->sc_led_blink_ch); 10645 sc->sc_led_blinking = 0; 10646 } 10647 10648 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 10649 return; 10650 10651 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10652 for (i = 0; i < BWN_LED_MAX; ++i) { 10653 struct bwn_led *led = &sc->sc_leds[i]; 10654 int on; 10655 10656 if (led->led_act == BWN_LED_ACT_UNKN || 10657 led->led_act == BWN_LED_ACT_NULL) 10658 continue; 10659 10660 if ((led->led_flags & BWN_LED_F_BLINK) && 10661 nstate != IEEE80211_S_INIT) 10662 continue; 10663 10664 switch (led->led_act) { 10665 case BWN_LED_ACT_ON: /* Always on */ 10666 on = 1; 10667 break; 10668 case BWN_LED_ACT_OFF: /* Always off */ 10669 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 10670 on = 0; 10671 break; 10672 default: 10673 on = 1; 10674 switch (nstate) { 10675 case IEEE80211_S_INIT: 10676 on = 0; 10677 break; 10678 case IEEE80211_S_RUN: 10679 if (led->led_act == BWN_LED_ACT_11G && 10680 ic->ic_curmode != IEEE80211_MODE_11G) 10681 on = 0; 10682 break; 10683 default: 10684 if (led->led_act == BWN_LED_ACT_ASSOC) 10685 on = 0; 10686 break; 10687 } 10688 break; 10689 } 10690 10691 val = bwn_led_onoff(led, val, on); 10692 } 10693 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10694 } 10695 10696 static void 10697 bwn_led_event(struct bwn_mac *mac, int event) 10698 { 10699 struct bwn_softc *sc = mac->mac_sc; 10700 struct bwn_led *led = sc->sc_blink_led; 10701 int rate; 10702 10703 if (event == BWN_LED_EVENT_POLL) { 10704 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 10705 return; 10706 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 10707 return; 10708 } 10709 10710 sc->sc_led_ticks = ticks; 10711 if (sc->sc_led_blinking) 10712 return; 10713 10714 switch (event) { 10715 case BWN_LED_EVENT_RX: 10716 rate = sc->sc_rx_rate; 10717 break; 10718 case BWN_LED_EVENT_TX: 10719 rate = sc->sc_tx_rate; 10720 break; 10721 case BWN_LED_EVENT_POLL: 10722 rate = 0; 10723 break; 10724 default: 10725 panic("unknown LED event %d\n", event); 10726 break; 10727 } 10728 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 10729 bwn_led_duration[rate].off_dur); 10730 } 10731 10732 static void 10733 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 10734 { 10735 struct bwn_softc *sc = mac->mac_sc; 10736 struct bwn_led *led = sc->sc_blink_led; 10737 uint16_t val; 10738 10739 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10740 val = bwn_led_onoff(led, val, 1); 10741 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10742 10743 if (led->led_flags & BWN_LED_F_SLOW) { 10744 BWN_LED_SLOWDOWN(on_dur); 10745 BWN_LED_SLOWDOWN(off_dur); 10746 } 10747 10748 sc->sc_led_blinking = 1; 10749 sc->sc_led_blink_offdur = off_dur; 10750 10751 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 10752 } 10753 10754 static void 10755 bwn_led_blink_next(void *arg) 10756 { 10757 struct bwn_mac *mac = arg; 10758 struct bwn_softc *sc = mac->mac_sc; 10759 uint16_t val; 10760 10761 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 10762 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 10763 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 10764 10765 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 10766 bwn_led_blink_end, mac); 10767 } 10768 10769 static void 10770 bwn_led_blink_end(void *arg) 10771 { 10772 struct bwn_mac *mac = arg; 10773 struct bwn_softc *sc = mac->mac_sc; 10774 10775 sc->sc_led_blinking = 0; 10776 } 10777 10778 static int 10779 bwn_suspend(device_t dev) 10780 { 10781 struct bwn_softc *sc = device_get_softc(dev); 10782 10783 bwn_stop(sc, 1); 10784 return (0); 10785 } 10786 10787 static int 10788 bwn_resume(device_t dev) 10789 { 10790 struct bwn_softc *sc = device_get_softc(dev); 10791 struct ifnet *ifp = sc->sc_ifp; 10792 10793 if (ifp->if_flags & IFF_UP) 10794 bwn_init(sc); 10795 return (0); 10796 } 10797 10798 static void 10799 bwn_rfswitch(void *arg) 10800 { 10801 struct bwn_softc *sc = arg; 10802 struct bwn_mac *mac = sc->sc_curmac; 10803 int cur = 0, prev = 0; 10804 10805 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 10806 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 10807 10808 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) { 10809 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 10810 & BWN_RF_HWENABLED_HI_MASK)) 10811 cur = 1; 10812 } else { 10813 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 10814 & BWN_RF_HWENABLED_LO_MASK) 10815 cur = 1; 10816 } 10817 10818 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 10819 prev = 1; 10820 10821 if (cur != prev) { 10822 if (cur) 10823 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 10824 else 10825 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 10826 10827 device_printf(sc->sc_dev, 10828 "status of RF switch is changed to %s\n", 10829 cur ? "ON" : "OFF"); 10830 if (cur != mac->mac_phy.rf_on) { 10831 if (cur) 10832 bwn_rf_turnon(mac); 10833 else 10834 bwn_rf_turnoff(mac); 10835 } 10836 } 10837 10838 callout_schedule(&sc->sc_rfswitch_ch, hz); 10839 } 10840 10841 static void 10842 bwn_phy_lp_init_pre(struct bwn_mac *mac) 10843 { 10844 struct bwn_phy *phy = &mac->mac_phy; 10845 struct bwn_phy_lp *plp = &phy->phy_lp; 10846 10847 plp->plp_antenna = BWN_ANT_DEFAULT; 10848 } 10849 10850 static int 10851 bwn_phy_lp_init(struct bwn_mac *mac) 10852 { 10853 static const struct bwn_stxtable tables[] = { 10854 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 10855 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 10856 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 10857 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 10858 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 10859 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 10860 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 10861 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 10862 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 10863 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 10864 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 10865 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 10866 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 10867 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 10868 { 2, 11, 0x40, 0, 0x0f } 10869 }; 10870 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 10871 struct bwn_softc *sc = mac->mac_sc; 10872 const struct bwn_stxtable *st; 10873 struct ifnet *ifp = sc->sc_ifp; 10874 struct ieee80211com *ic = ifp->if_l2com; 10875 int i, error; 10876 uint16_t tmp; 10877 10878 bwn_phy_lp_readsprom(mac); /* XXX bad place */ 10879 bwn_phy_lp_bbinit(mac); 10880 10881 /* initialize RF */ 10882 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 10883 DELAY(1); 10884 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 10885 DELAY(1); 10886 10887 if (mac->mac_phy.rf_ver == 0x2062) 10888 bwn_phy_lp_b2062_init(mac); 10889 else { 10890 bwn_phy_lp_b2063_init(mac); 10891 10892 /* synchronize stx table. */ 10893 for (i = 0; i < N(tables); i++) { 10894 st = &tables[i]; 10895 tmp = BWN_RF_READ(mac, st->st_rfaddr); 10896 tmp >>= st->st_rfshift; 10897 tmp <<= st->st_physhift; 10898 BWN_PHY_SETMASK(mac, 10899 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 10900 ~(st->st_mask << st->st_physhift), tmp); 10901 } 10902 10903 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 10904 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 10905 } 10906 10907 /* calibrate RC */ 10908 if (mac->mac_phy.rev >= 2) 10909 bwn_phy_lp_rxcal_r2(mac); 10910 else if (!plp->plp_rccap) { 10911 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 10912 bwn_phy_lp_rccal_r12(mac); 10913 } else 10914 bwn_phy_lp_set_rccap(mac); 10915 10916 error = bwn_phy_lp_switch_channel(mac, 7); 10917 if (error) 10918 device_printf(sc->sc_dev, 10919 "failed to change channel 7 (%d)\n", error); 10920 bwn_phy_lp_txpctl_init(mac); 10921 bwn_phy_lp_calib(mac); 10922 return (0); 10923 } 10924 10925 static uint16_t 10926 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 10927 { 10928 10929 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10930 return (BWN_READ_2(mac, BWN_PHYDATA)); 10931 } 10932 10933 static void 10934 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10935 { 10936 10937 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10938 BWN_WRITE_2(mac, BWN_PHYDATA, value); 10939 } 10940 10941 static void 10942 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 10943 uint16_t set) 10944 { 10945 10946 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 10947 BWN_WRITE_2(mac, BWN_PHYDATA, 10948 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 10949 } 10950 10951 static uint16_t 10952 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 10953 { 10954 10955 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10956 if (mac->mac_phy.rev < 2 && reg != 0x4001) 10957 reg |= 0x100; 10958 if (mac->mac_phy.rev >= 2) 10959 reg |= 0x200; 10960 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10961 return BWN_READ_2(mac, BWN_RFDATALO); 10962 } 10963 10964 static void 10965 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 10966 { 10967 10968 KASSERT(reg != 1, ("unaccessible register %d", reg)); 10969 BWN_WRITE_2(mac, BWN_RFCTL, reg); 10970 BWN_WRITE_2(mac, BWN_RFDATALO, value); 10971 } 10972 10973 static void 10974 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 10975 { 10976 10977 if (on) { 10978 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 10979 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 10980 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 10981 return; 10982 } 10983 10984 if (mac->mac_phy.rev >= 2) { 10985 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 10986 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10987 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 10988 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 10989 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 10990 return; 10991 } 10992 10993 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 10994 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 10995 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 10996 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 10997 } 10998 10999 static int 11000 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 11001 { 11002 struct bwn_phy *phy = &mac->mac_phy; 11003 struct bwn_phy_lp *plp = &phy->phy_lp; 11004 int error; 11005 11006 if (phy->rf_ver == 0x2063) { 11007 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 11008 if (error) 11009 return (error); 11010 } else { 11011 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 11012 if (error) 11013 return (error); 11014 bwn_phy_lp_set_anafilter(mac, chan); 11015 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 11016 } 11017 11018 plp->plp_chan = chan; 11019 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 11020 return (0); 11021 } 11022 11023 static uint32_t 11024 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 11025 { 11026 struct bwn_softc *sc = mac->mac_sc; 11027 struct ifnet *ifp = sc->sc_ifp; 11028 struct ieee80211com *ic = ifp->if_l2com; 11029 11030 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 11031 } 11032 11033 static void 11034 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 11035 { 11036 struct bwn_phy *phy = &mac->mac_phy; 11037 struct bwn_phy_lp *plp = &phy->phy_lp; 11038 11039 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 11040 return; 11041 11042 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 11043 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 11044 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 11045 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 11046 plp->plp_antenna = antenna; 11047 } 11048 11049 static void 11050 bwn_phy_lp_task_60s(struct bwn_mac *mac) 11051 { 11052 11053 bwn_phy_lp_calib(mac); 11054 } 11055 11056 static void 11057 bwn_phy_lp_readsprom(struct bwn_mac *mac) 11058 { 11059 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11060 struct bwn_softc *sc = mac->mac_sc; 11061 struct ifnet *ifp = sc->sc_ifp; 11062 struct ieee80211com *ic = ifp->if_l2com; 11063 11064 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11065 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); 11066 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev); 11067 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev); 11068 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev); 11069 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev); 11070 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev); 11071 return; 11072 } 11073 11074 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev); 11075 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev); 11076 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev); 11077 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev); 11078 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev); 11079 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev); 11080 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev); 11081 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev); 11082 } 11083 11084 static void 11085 bwn_phy_lp_bbinit(struct bwn_mac *mac) 11086 { 11087 11088 bwn_phy_lp_tblinit(mac); 11089 if (mac->mac_phy.rev >= 2) 11090 bwn_phy_lp_bbinit_r2(mac); 11091 else 11092 bwn_phy_lp_bbinit_r01(mac); 11093 } 11094 11095 static void 11096 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 11097 { 11098 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 11099 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 11100 struct bwn_softc *sc = mac->mac_sc; 11101 struct ifnet *ifp = sc->sc_ifp; 11102 struct ieee80211com *ic = ifp->if_l2com; 11103 11104 bwn_phy_lp_set_txgain(mac, 11105 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 11106 bwn_phy_lp_set_bbmult(mac, 150); 11107 } 11108 11109 static void 11110 bwn_phy_lp_calib(struct bwn_mac *mac) 11111 { 11112 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11113 struct bwn_softc *sc = mac->mac_sc; 11114 struct ifnet *ifp = sc->sc_ifp; 11115 struct ieee80211com *ic = ifp->if_l2com; 11116 const struct bwn_rxcompco *rc = NULL; 11117 struct bwn_txgain ogain; 11118 int i, omode, oafeovr, orf, obbmult; 11119 uint8_t mode, fc = 0; 11120 11121 if (plp->plp_chanfullcal != plp->plp_chan) { 11122 plp->plp_chanfullcal = plp->plp_chan; 11123 fc = 1; 11124 } 11125 11126 bwn_mac_suspend(mac); 11127 11128 /* BlueTooth Coexistance Override */ 11129 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 11130 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 11131 11132 if (mac->mac_phy.rev >= 2) 11133 bwn_phy_lp_digflt_save(mac); 11134 bwn_phy_lp_get_txpctlmode(mac); 11135 mode = plp->plp_txpctlmode; 11136 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11137 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 11138 bwn_phy_lp_bugfix(mac); 11139 if (mac->mac_phy.rev >= 2 && fc == 1) { 11140 bwn_phy_lp_get_txpctlmode(mac); 11141 omode = plp->plp_txpctlmode; 11142 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 11143 if (oafeovr) 11144 ogain = bwn_phy_lp_get_txgain(mac); 11145 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 11146 obbmult = bwn_phy_lp_get_bbmult(mac); 11147 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11148 if (oafeovr) 11149 bwn_phy_lp_set_txgain(mac, &ogain); 11150 bwn_phy_lp_set_bbmult(mac, obbmult); 11151 bwn_phy_lp_set_txpctlmode(mac, omode); 11152 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 11153 } 11154 bwn_phy_lp_set_txpctlmode(mac, mode); 11155 if (mac->mac_phy.rev >= 2) 11156 bwn_phy_lp_digflt_restore(mac); 11157 11158 /* do RX IQ Calculation; assumes that noise is true. */ 11159 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 11160 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 11161 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 11162 rc = &bwn_rxcompco_5354[i]; 11163 } 11164 } else if (mac->mac_phy.rev >= 2) 11165 rc = &bwn_rxcompco_r2; 11166 else { 11167 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 11168 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 11169 rc = &bwn_rxcompco_r12[i]; 11170 } 11171 } 11172 if (rc == NULL) 11173 goto fail; 11174 11175 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 11176 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 11177 11178 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 11179 11180 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11181 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 11182 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 11183 } else { 11184 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 11185 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 11186 } 11187 11188 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 11189 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11190 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 11191 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 11192 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 11193 bwn_phy_lp_set_deaf(mac, 0); 11194 /* XXX no checking return value? */ 11195 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 11196 bwn_phy_lp_clear_deaf(mac, 0); 11197 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 11199 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 11200 11201 /* disable RX GAIN override. */ 11202 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 11203 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 11204 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 11205 if (mac->mac_phy.rev >= 2) { 11206 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11207 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11208 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 11209 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 11210 } 11211 } else { 11212 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 11213 } 11214 11215 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 11216 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 11217 fail: 11218 bwn_mac_enable(mac); 11219 } 11220 11221 static void 11222 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 11223 { 11224 11225 if (on) { 11226 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 11227 return; 11228 } 11229 11230 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 11231 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 11232 } 11233 11234 static int 11235 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 11236 { 11237 static const struct bwn_b206x_chan *bc = NULL; 11238 struct bwn_softc *sc = mac->mac_sc; 11239 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref, 11240 tmp[6]; 11241 uint16_t old, scale, tmp16; 11242 int i, div; 11243 11244 for (i = 0; i < N(bwn_b2063_chantable); i++) { 11245 if (bwn_b2063_chantable[i].bc_chan == chan) { 11246 bc = &bwn_b2063_chantable[i]; 11247 break; 11248 } 11249 } 11250 if (bc == NULL) 11251 return (EINVAL); 11252 11253 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 11254 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 11255 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 11256 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 11257 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 11258 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 11259 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 11260 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 11261 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 11262 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 11263 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 11264 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 11265 11266 old = BWN_RF_READ(mac, BWN_B2063_COM15); 11267 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 11268 11269 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11270 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 11271 freqref = freqxtal * 3; 11272 div = (freqxtal <= 26000000 ? 1 : 2); 11273 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 11274 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 11275 999999) / 1000000) + 1; 11276 11277 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 11278 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 11279 0xfff8, timeout >> 2); 11280 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11281 0xff9f,timeout << 5); 11282 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 11283 11284 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 11285 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 11286 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 11287 11288 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 11289 (timeoutref + 1)) - 1; 11290 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 11291 0xf0, count >> 8); 11292 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 11293 11294 tmp[0] = ((val[2] * 62500) / freqref) << 4; 11295 tmp[1] = ((val[2] * 62500) % freqref) << 4; 11296 while (tmp[1] >= freqref) { 11297 tmp[0]++; 11298 tmp[1] -= freqref; 11299 } 11300 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 11301 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 11302 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 11303 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 11304 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 11305 11306 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 11307 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 11308 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 11309 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 11310 11311 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 11312 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 11313 11314 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) { 11315 scale = 1; 11316 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 11317 } else { 11318 scale = 0; 11319 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 11320 } 11321 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 11322 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 11323 11324 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 11325 (scale + 1); 11326 if (tmp[5] > 150) 11327 tmp[5] = 0; 11328 11329 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 11331 11332 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 11333 if (freqxtal > 26000000) 11334 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 11335 else 11336 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 11337 11338 if (val[0] == 45) 11339 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 11340 else 11341 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 11342 11343 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 11344 DELAY(1); 11345 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 11346 11347 /* VCO Calibration */ 11348 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 11349 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 11350 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 11351 DELAY(1); 11352 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 11353 DELAY(1); 11354 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 11355 DELAY(1); 11356 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 11357 DELAY(300); 11358 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 11359 11360 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 11361 return (0); 11362 } 11363 11364 static int 11365 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 11366 { 11367 struct bwn_softc *sc = mac->mac_sc; 11368 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11369 const struct bwn_b206x_chan *bc = NULL; 11370 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 11371 uint32_t tmp[9]; 11372 int i; 11373 11374 for (i = 0; i < N(bwn_b2062_chantable); i++) { 11375 if (bwn_b2062_chantable[i].bc_chan == chan) { 11376 bc = &bwn_b2062_chantable[i]; 11377 break; 11378 } 11379 } 11380 11381 if (bc == NULL) 11382 return (EINVAL); 11383 11384 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 11385 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 11386 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 11387 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 11388 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 11389 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 11390 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 11391 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 11392 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 11393 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 11394 11395 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 11396 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 11397 bwn_phy_lp_b2062_reset_pllbias(mac); 11398 tmp[0] = freqxtal / 1000; 11399 tmp[1] = plp->plp_div * 1000; 11400 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 11401 if (ieee80211_ieee2mhz(chan, 0) < 4000) 11402 tmp[2] *= 2; 11403 tmp[3] = 48 * tmp[0]; 11404 tmp[5] = tmp[2] / tmp[3]; 11405 tmp[6] = tmp[2] % tmp[3]; 11406 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 11407 tmp[4] = tmp[6] * 0x100; 11408 tmp[5] = tmp[4] / tmp[3]; 11409 tmp[6] = tmp[4] % tmp[3]; 11410 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 11411 tmp[4] = tmp[6] * 0x100; 11412 tmp[5] = tmp[4] / tmp[3]; 11413 tmp[6] = tmp[4] % tmp[3]; 11414 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 11415 tmp[4] = tmp[6] * 0x100; 11416 tmp[5] = tmp[4] / tmp[3]; 11417 tmp[6] = tmp[4] % tmp[3]; 11418 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 11419 tmp[5] + ((2 * tmp[6]) / tmp[3])); 11420 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 11421 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 11422 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 11423 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 11424 11425 bwn_phy_lp_b2062_vco_calib(mac); 11426 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11427 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 11428 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 11429 bwn_phy_lp_b2062_reset_pllbias(mac); 11430 bwn_phy_lp_b2062_vco_calib(mac); 11431 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 11432 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11433 return (EIO); 11434 } 11435 } 11436 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 11437 return (0); 11438 } 11439 11440 static void 11441 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 11442 { 11443 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11444 uint16_t tmp = (channel == 14); 11445 11446 if (mac->mac_phy.rev < 2) { 11447 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 11448 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 11449 bwn_phy_lp_set_rccap(mac); 11450 return; 11451 } 11452 11453 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 11454 } 11455 11456 static void 11457 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 11458 { 11459 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11460 struct bwn_softc *sc = mac->mac_sc; 11461 struct ifnet *ifp = sc->sc_ifp; 11462 struct ieee80211com *ic = ifp->if_l2com; 11463 uint16_t iso, tmp[3]; 11464 11465 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 11466 11467 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 11468 iso = plp->plp_txisoband_m; 11469 else if (freq <= 5320) 11470 iso = plp->plp_txisoband_l; 11471 else if (freq <= 5700) 11472 iso = plp->plp_txisoband_m; 11473 else 11474 iso = plp->plp_txisoband_h; 11475 11476 tmp[0] = ((iso - 26) / 12) << 12; 11477 tmp[1] = tmp[0] + 0x1000; 11478 tmp[2] = tmp[0] + 0x2000; 11479 11480 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 11481 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 11482 } 11483 11484 static void 11485 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 11486 { 11487 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11488 int i; 11489 static const uint16_t addr[] = { 11490 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11491 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11492 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11493 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11494 BWN_PHY_OFDM(0xcf), 11495 }; 11496 static const uint16_t val[] = { 11497 0xde5e, 0xe832, 0xe331, 0x4d26, 11498 0x0026, 0x1420, 0x0020, 0xfe08, 11499 0x0008, 11500 }; 11501 11502 for (i = 0; i < N(addr); i++) { 11503 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 11504 BWN_PHY_WRITE(mac, addr[i], val[i]); 11505 } 11506 } 11507 11508 static void 11509 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 11510 { 11511 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11512 struct bwn_softc *sc = mac->mac_sc; 11513 uint16_t ctl; 11514 11515 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 11516 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 11517 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 11518 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 11519 break; 11520 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 11521 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 11522 break; 11523 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 11524 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 11525 break; 11526 default: 11527 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 11528 device_printf(sc->sc_dev, "unknown command mode\n"); 11529 break; 11530 } 11531 } 11532 11533 static void 11534 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 11535 { 11536 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11537 uint16_t ctl; 11538 uint8_t old; 11539 11540 bwn_phy_lp_get_txpctlmode(mac); 11541 old = plp->plp_txpctlmode; 11542 if (old == mode) 11543 return; 11544 plp->plp_txpctlmode = mode; 11545 11546 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 11547 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 11548 plp->plp_tssiidx); 11549 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 11550 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 11551 11552 /* disable TX GAIN override */ 11553 if (mac->mac_phy.rev < 2) 11554 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 11555 else { 11556 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 11557 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 11558 } 11559 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 11560 11561 plp->plp_txpwridx = -1; 11562 } 11563 if (mac->mac_phy.rev >= 2) { 11564 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 11565 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 11566 else 11567 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 11568 } 11569 11570 /* writes TX Power Control mode */ 11571 switch (plp->plp_txpctlmode) { 11572 case BWN_PHYLP_TXPCTL_OFF: 11573 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 11574 break; 11575 case BWN_PHYLP_TXPCTL_ON_HW: 11576 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 11577 break; 11578 case BWN_PHYLP_TXPCTL_ON_SW: 11579 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 11580 break; 11581 default: 11582 ctl = 0; 11583 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 11584 } 11585 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 11586 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 11587 } 11588 11589 static void 11590 bwn_phy_lp_bugfix(struct bwn_mac *mac) 11591 { 11592 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11593 struct bwn_softc *sc = mac->mac_sc; 11594 const unsigned int size = 256; 11595 struct bwn_txgain tg; 11596 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 11597 uint16_t tssinpt, tssiidx, value[2]; 11598 uint8_t mode; 11599 int8_t txpwridx; 11600 11601 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 11602 M_NOWAIT | M_ZERO); 11603 if (tabs == NULL) { 11604 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 11605 return; 11606 } 11607 11608 bwn_phy_lp_get_txpctlmode(mac); 11609 mode = plp->plp_txpctlmode; 11610 txpwridx = plp->plp_txpwridx; 11611 tssinpt = plp->plp_tssinpt; 11612 tssiidx = plp->plp_tssiidx; 11613 11614 bwn_tab_read_multi(mac, 11615 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11616 BWN_TAB_4(7, 0x140), size, tabs); 11617 11618 bwn_phy_lp_tblinit(mac); 11619 bwn_phy_lp_bbinit(mac); 11620 bwn_phy_lp_txpctl_init(mac); 11621 bwn_phy_lp_rf_onoff(mac, 1); 11622 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 11623 11624 bwn_tab_write_multi(mac, 11625 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 11626 BWN_TAB_4(7, 0x140), size, tabs); 11627 11628 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 11629 plp->plp_tssinpt = tssinpt; 11630 plp->plp_tssiidx = tssiidx; 11631 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 11632 if (txpwridx != -1) { 11633 /* set TX power by index */ 11634 plp->plp_txpwridx = txpwridx; 11635 bwn_phy_lp_get_txpctlmode(mac); 11636 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 11637 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 11638 if (mac->mac_phy.rev >= 2) { 11639 rxcomp = bwn_tab_read(mac, 11640 BWN_TAB_4(7, txpwridx + 320)); 11641 txgain = bwn_tab_read(mac, 11642 BWN_TAB_4(7, txpwridx + 192)); 11643 tg.tg_pad = (txgain >> 16) & 0xff; 11644 tg.tg_gm = txgain & 0xff; 11645 tg.tg_pga = (txgain >> 8) & 0xff; 11646 tg.tg_dac = (rxcomp >> 28) & 0xff; 11647 bwn_phy_lp_set_txgain(mac, &tg); 11648 } else { 11649 rxcomp = bwn_tab_read(mac, 11650 BWN_TAB_4(10, txpwridx + 320)); 11651 txgain = bwn_tab_read(mac, 11652 BWN_TAB_4(10, txpwridx + 192)); 11653 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 11654 0xf800, (txgain >> 4) & 0x7fff); 11655 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 11656 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 11657 } 11658 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 11659 11660 /* set TX IQCC */ 11661 value[0] = (rxcomp >> 10) & 0x3ff; 11662 value[1] = rxcomp & 0x3ff; 11663 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 11664 11665 coeff = bwn_tab_read(mac, 11666 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 11667 BWN_TAB_4(10, txpwridx + 448)); 11668 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 11669 if (mac->mac_phy.rev >= 2) { 11670 rfpwr = bwn_tab_read(mac, 11671 BWN_TAB_4(7, txpwridx + 576)); 11672 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 11673 rfpwr & 0xffff); 11674 } 11675 bwn_phy_lp_set_txgain_override(mac); 11676 } 11677 if (plp->plp_rccap) 11678 bwn_phy_lp_set_rccap(mac); 11679 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 11680 bwn_phy_lp_set_txpctlmode(mac, mode); 11681 free(tabs, M_DEVBUF); 11682 } 11683 11684 static void 11685 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 11686 { 11687 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11688 int i; 11689 static const uint16_t addr[] = { 11690 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 11691 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 11692 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 11693 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 11694 BWN_PHY_OFDM(0xcf), 11695 }; 11696 11697 for (i = 0; i < N(addr); i++) 11698 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 11699 } 11700 11701 static void 11702 bwn_phy_lp_tblinit(struct bwn_mac *mac) 11703 { 11704 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 11705 11706 if (mac->mac_phy.rev < 2) { 11707 bwn_phy_lp_tblinit_r01(mac); 11708 bwn_phy_lp_tblinit_txgain(mac); 11709 bwn_phy_lp_set_gaintbl(mac, freq); 11710 return; 11711 } 11712 11713 bwn_phy_lp_tblinit_r2(mac); 11714 bwn_phy_lp_tblinit_txgain(mac); 11715 } 11716 11717 struct bwn_wpair { 11718 uint16_t reg; 11719 uint16_t value; 11720 }; 11721 11722 struct bwn_smpair { 11723 uint16_t offset; 11724 uint16_t mask; 11725 uint16_t set; 11726 }; 11727 11728 static void 11729 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 11730 { 11731 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11732 struct bwn_softc *sc = mac->mac_sc; 11733 struct ifnet *ifp = sc->sc_ifp; 11734 struct ieee80211com *ic = ifp->if_l2com; 11735 static const struct bwn_wpair v1[] = { 11736 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 11737 { BWN_PHY_AFE_CTL, 0x8800 }, 11738 { BWN_PHY_AFE_CTL_OVR, 0 }, 11739 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 11740 { BWN_PHY_RF_OVERRIDE_0, 0 }, 11741 { BWN_PHY_RF_OVERRIDE_2, 0 }, 11742 { BWN_PHY_OFDM(0xf9), 0 }, 11743 { BWN_PHY_TR_LOOKUP_1, 0 } 11744 }; 11745 static const struct bwn_smpair v2[] = { 11746 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 11747 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 11748 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 11749 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 11750 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 11751 }; 11752 static const struct bwn_smpair v3[] = { 11753 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 11754 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11755 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 11756 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 11757 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 11758 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 11759 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 11760 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 11761 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 11762 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 11763 11764 }; 11765 int i; 11766 11767 for (i = 0; i < N(v1); i++) 11768 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 11769 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 11770 for (i = 0; i < N(v2); i++) 11771 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 11772 11773 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 11774 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 11775 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 11776 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) { 11777 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 11778 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 11779 } else { 11780 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 11781 } 11782 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 11783 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 11784 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 11785 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 11786 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 11787 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 11788 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 11789 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 11790 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 11791 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 11792 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 11793 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11794 (siba_get_chiprev(sc->sc_dev) == 0)) { 11795 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11796 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 11797 } else { 11798 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 11799 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 11800 } 11801 for (i = 0; i < N(v3); i++) 11802 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 11803 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11804 (siba_get_chiprev(sc->sc_dev) == 0)) { 11805 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 11806 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 11807 } 11808 11809 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11810 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 11811 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 11812 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 11813 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 11814 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 11815 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11816 } else 11817 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 11818 11819 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 11820 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 11821 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 11822 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 11823 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 11824 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 11825 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 11826 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 11827 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 11828 11829 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 11830 (siba_get_chiprev(sc->sc_dev) == 0)) { 11831 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 11832 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 11833 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 11834 } 11835 11836 bwn_phy_lp_digflt_save(mac); 11837 } 11838 11839 static void 11840 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 11841 { 11842 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 11843 struct bwn_softc *sc = mac->mac_sc; 11844 struct ifnet *ifp = sc->sc_ifp; 11845 struct ieee80211com *ic = ifp->if_l2com; 11846 static const struct bwn_smpair v1[] = { 11847 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 11848 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 11849 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 11850 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 11851 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 11852 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 11853 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 11854 }; 11855 static const struct bwn_smpair v2[] = { 11856 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11857 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 11858 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11859 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11860 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 11861 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 11862 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 11863 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 11864 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 11865 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 11866 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 11867 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 11868 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 11869 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 11870 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 11871 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 11872 }; 11873 static const struct bwn_smpair v3[] = { 11874 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 11875 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 11876 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 11877 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 11878 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11879 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 11880 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11881 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 11882 }; 11883 static const struct bwn_smpair v4[] = { 11884 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 11885 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 11886 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 11887 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 11888 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 11889 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 11890 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 11891 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 11892 }; 11893 static const struct bwn_smpair v5[] = { 11894 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 11895 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 11896 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 11897 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 11898 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 11899 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 11900 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 11901 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 11902 }; 11903 int i; 11904 uint16_t tmp, tmp2; 11905 11906 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 11907 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 11908 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 11909 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 11910 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 11911 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 11912 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 11913 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 11914 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 11915 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 11916 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 11917 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 11918 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 11919 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 11920 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 11921 for (i = 0; i < N(v1); i++) 11922 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 11923 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 11924 0xff00, plp->plp_rxpwroffset); 11925 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) && 11926 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 11927 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) { 11928 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28); 11929 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1); 11930 if (mac->mac_phy.rev == 0) 11931 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 11932 0xffcf, 0x0010); 11933 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 11934 } else { 11935 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0); 11936 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 11937 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 11938 } 11939 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 11940 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 11941 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV) 11942 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 11943 else 11944 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 11945 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 11946 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 11947 0xfff9, (plp->plp_bxarch << 1)); 11948 if (mac->mac_phy.rev == 1 && 11949 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) { 11950 for (i = 0; i < N(v2); i++) 11951 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 11952 v2[i].set); 11953 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 11954 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) || 11955 ((mac->mac_phy.rev == 0) && 11956 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) { 11957 for (i = 0; i < N(v3); i++) 11958 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 11959 v3[i].set); 11960 } else if (mac->mac_phy.rev == 1 || 11961 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) { 11962 for (i = 0; i < N(v4); i++) 11963 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 11964 v4[i].set); 11965 } else { 11966 for (i = 0; i < N(v5); i++) 11967 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 11968 v5[i].set); 11969 } 11970 if (mac->mac_phy.rev == 1 && 11971 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) { 11972 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 11973 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 11974 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 11975 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 11976 } 11977 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) && 11978 (siba_get_chipid(sc->sc_dev) == 0x5354) && 11979 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) { 11980 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 11981 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 11982 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 11983 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 11984 } 11985 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 11986 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 11987 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 11988 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 11989 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 11990 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 11991 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 11992 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 11993 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 11994 } else { 11995 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 11996 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 11997 } 11998 if (mac->mac_phy.rev == 1) { 11999 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 12000 tmp2 = (tmp & 0x03e0) >> 5; 12001 tmp2 |= tmp2 << 5; 12002 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 12003 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 12004 tmp2 = (tmp & 0x1f00) >> 8; 12005 tmp2 |= tmp2 << 5; 12006 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 12007 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 12008 tmp2 = tmp & 0x00ff; 12009 tmp2 |= tmp << 8; 12010 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 12011 } 12012 } 12013 12014 struct bwn_b2062_freq { 12015 uint16_t freq; 12016 uint8_t value[6]; 12017 }; 12018 12019 static void 12020 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 12021 { 12022 #define CALC_CTL7(freq, div) \ 12023 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 12024 #define CALC_CTL18(freq, div) \ 12025 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 12026 #define CALC_CTL19(freq, div) \ 12027 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 12028 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12029 struct bwn_softc *sc = mac->mac_sc; 12030 struct ifnet *ifp = sc->sc_ifp; 12031 struct ieee80211com *ic = ifp->if_l2com; 12032 static const struct bwn_b2062_freq freqdata_tab[] = { 12033 { 12000, { 6, 6, 6, 6, 10, 6 } }, 12034 { 13000, { 4, 4, 4, 4, 11, 7 } }, 12035 { 14400, { 3, 3, 3, 3, 12, 7 } }, 12036 { 16200, { 3, 3, 3, 3, 13, 8 } }, 12037 { 18000, { 2, 2, 2, 2, 14, 8 } }, 12038 { 19200, { 1, 1, 1, 1, 14, 9 } } 12039 }; 12040 static const struct bwn_wpair v1[] = { 12041 { BWN_B2062_N_TXCTL3, 0 }, 12042 { BWN_B2062_N_TXCTL4, 0 }, 12043 { BWN_B2062_N_TXCTL5, 0 }, 12044 { BWN_B2062_N_TXCTL6, 0 }, 12045 { BWN_B2062_N_PDNCTL0, 0x40 }, 12046 { BWN_B2062_N_PDNCTL0, 0 }, 12047 { BWN_B2062_N_CALIB_TS, 0x10 }, 12048 { BWN_B2062_N_CALIB_TS, 0 } 12049 }; 12050 const struct bwn_b2062_freq *f = NULL; 12051 uint32_t xtalfreq, ref; 12052 unsigned int i; 12053 12054 bwn_phy_lp_b2062_tblinit(mac); 12055 12056 for (i = 0; i < N(v1); i++) 12057 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12058 if (mac->mac_phy.rev > 0) 12059 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 12060 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 12061 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12062 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 12063 else 12064 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 12065 12066 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU, 12067 ("%s:%d: fail", __func__, __LINE__)); 12068 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12069 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__)); 12070 12071 if (xtalfreq <= 30000000) { 12072 plp->plp_div = 1; 12073 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 12074 } else { 12075 plp->plp_div = 2; 12076 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 12077 } 12078 12079 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 12080 CALC_CTL7(xtalfreq, plp->plp_div)); 12081 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 12082 CALC_CTL18(xtalfreq, plp->plp_div)); 12083 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 12084 CALC_CTL19(xtalfreq, plp->plp_div)); 12085 12086 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 12087 ref &= 0xffff; 12088 for (i = 0; i < N(freqdata_tab); i++) { 12089 if (ref < freqdata_tab[i].freq) { 12090 f = &freqdata_tab[i]; 12091 break; 12092 } 12093 } 12094 if (f == NULL) 12095 f = &freqdata_tab[N(freqdata_tab) - 1]; 12096 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 12097 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 12098 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 12099 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 12100 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 12101 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 12102 #undef CALC_CTL7 12103 #undef CALC_CTL18 12104 #undef CALC_CTL19 12105 } 12106 12107 static void 12108 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 12109 { 12110 12111 bwn_phy_lp_b2063_tblinit(mac); 12112 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 12113 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 12114 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 12115 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 12116 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 12117 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 12118 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 12119 if (mac->mac_phy.rev == 2) { 12120 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 12121 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 12122 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 12123 } else { 12124 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 12125 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 12126 } 12127 } 12128 12129 static void 12130 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 12131 { 12132 struct bwn_softc *sc = mac->mac_sc; 12133 static const struct bwn_wpair v1[] = { 12134 { BWN_B2063_RX_BB_SP8, 0x0 }, 12135 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12136 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12137 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 12138 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 12139 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 12140 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 12141 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 12142 }; 12143 static const struct bwn_wpair v2[] = { 12144 { BWN_B2063_TX_BB_SP3, 0x0 }, 12145 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 12146 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 12147 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 12148 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 12149 }; 12150 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000; 12151 int i; 12152 uint8_t tmp; 12153 12154 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 12155 12156 for (i = 0; i < 2; i++) 12157 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12158 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 12159 for (i = 2; i < N(v1); i++) 12160 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 12161 for (i = 0; i < 10000; i++) { 12162 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12163 break; 12164 DELAY(1000); 12165 } 12166 12167 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12168 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 12169 12170 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 12171 12172 for (i = 0; i < N(v2); i++) 12173 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 12174 if (freqxtal == 24000000) { 12175 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 12176 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 12177 } else { 12178 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 12179 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 12180 } 12181 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 12182 for (i = 0; i < 10000; i++) { 12183 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 12184 break; 12185 DELAY(1000); 12186 } 12187 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 12188 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 12189 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 12190 } 12191 12192 static void 12193 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 12194 { 12195 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12196 struct bwn_softc *sc = mac->mac_sc; 12197 struct bwn_phy_lp_iq_est ie; 12198 struct bwn_txgain tx_gains; 12199 static const uint32_t pwrtbl[21] = { 12200 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 12201 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 12202 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 12203 0x0004c, 0x0002c, 0x0001a, 12204 }; 12205 uint32_t npwr, ipwr, sqpwr, tmp; 12206 int loopback, i, j, sum, error; 12207 uint16_t save[7]; 12208 uint8_t txo, bbmult, txpctlmode; 12209 12210 error = bwn_phy_lp_switch_channel(mac, 7); 12211 if (error) 12212 device_printf(sc->sc_dev, 12213 "failed to change channel to 7 (%d)\n", error); 12214 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 12215 bbmult = bwn_phy_lp_get_bbmult(mac); 12216 if (txo) 12217 tx_gains = bwn_phy_lp_get_txgain(mac); 12218 12219 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 12220 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 12221 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 12222 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 12223 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 12224 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 12225 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 12226 12227 bwn_phy_lp_get_txpctlmode(mac); 12228 txpctlmode = plp->plp_txpctlmode; 12229 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 12230 12231 /* disable CRS */ 12232 bwn_phy_lp_set_deaf(mac, 1); 12233 bwn_phy_lp_set_trsw_over(mac, 0, 1); 12234 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 12235 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 12236 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 12237 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 12238 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 12239 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12240 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 12241 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 12242 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 12243 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12244 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 12245 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 12246 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 12247 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 12248 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 12249 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 12250 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 12251 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 12252 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 12253 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 12254 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 12255 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 12256 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 12257 12258 loopback = bwn_phy_lp_loopback(mac); 12259 if (loopback == -1) 12260 goto done; 12261 bwn_phy_lp_set_rxgain_idx(mac, loopback); 12262 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 12263 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 12264 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 12265 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 12266 12267 tmp = 0; 12268 memset(&ie, 0, sizeof(ie)); 12269 for (i = 128; i <= 159; i++) { 12270 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 12271 sum = 0; 12272 for (j = 5; j <= 25; j++) { 12273 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 12274 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 12275 goto done; 12276 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 12277 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 12278 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 12279 12); 12280 sum += ((ipwr - npwr) * (ipwr - npwr)); 12281 if ((i == 128) || (sum < tmp)) { 12282 plp->plp_rccap = i; 12283 tmp = sum; 12284 } 12285 } 12286 } 12287 bwn_phy_lp_ddfs_turnoff(mac); 12288 done: 12289 /* restore CRS */ 12290 bwn_phy_lp_clear_deaf(mac, 1); 12291 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 12292 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 12293 12294 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 12295 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 12296 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 12297 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 12298 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 12299 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 12300 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 12301 12302 bwn_phy_lp_set_bbmult(mac, bbmult); 12303 if (txo) 12304 bwn_phy_lp_set_txgain(mac, &tx_gains); 12305 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 12306 if (plp->plp_rccap) 12307 bwn_phy_lp_set_rccap(mac); 12308 } 12309 12310 static void 12311 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 12312 { 12313 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12314 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 12315 12316 if (mac->mac_phy.rev == 1) 12317 rc_cap = MIN(rc_cap + 5, 15); 12318 12319 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 12320 MAX(plp->plp_rccap - 4, 0x80)); 12321 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 12322 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 12323 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 12324 } 12325 12326 static uint32_t 12327 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 12328 { 12329 uint32_t i, q, r; 12330 12331 if (div == 0) 12332 return (0); 12333 12334 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 12335 q <<= 1; 12336 if (r << 1 >= div) { 12337 q++; 12338 r = (r << 1) - div; 12339 } 12340 } 12341 if (r << 1 >= div) 12342 q++; 12343 return (q); 12344 } 12345 12346 static void 12347 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 12348 { 12349 struct bwn_softc *sc = mac->mac_sc; 12350 12351 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 12352 DELAY(20); 12353 if (siba_get_chipid(sc->sc_dev) == 0x5354) { 12354 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 12355 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 12356 } else { 12357 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 12358 } 12359 DELAY(5); 12360 } 12361 12362 static void 12363 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 12364 { 12365 12366 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 12367 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 12368 DELAY(200); 12369 } 12370 12371 static void 12372 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 12373 { 12374 #define FLAG_A 0x01 12375 #define FLAG_G 0x02 12376 struct bwn_softc *sc = mac->mac_sc; 12377 struct ifnet *ifp = sc->sc_ifp; 12378 struct ieee80211com *ic = ifp->if_l2com; 12379 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 12380 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12381 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 12382 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 12383 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 12384 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 12385 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12386 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 12387 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 12388 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 12389 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 12390 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 12391 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 12392 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 12393 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 12394 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12395 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 12396 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 12397 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 12398 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 12399 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 12400 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 12401 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 12402 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 12403 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 12404 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 12405 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 12406 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 12407 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 12408 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 12409 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 12410 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 12411 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 12412 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 12413 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 12414 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 12415 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 12416 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 12417 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 12418 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 12419 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 12420 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 12421 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 12422 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 12423 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 12424 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 12425 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 12426 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 12427 }; 12428 const struct bwn_b206x_rfinit_entry *br; 12429 unsigned int i; 12430 12431 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 12432 br = &bwn_b2062_init_tab[i]; 12433 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12434 if (br->br_flags & FLAG_G) 12435 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12436 } else { 12437 if (br->br_flags & FLAG_A) 12438 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12439 } 12440 } 12441 #undef FLAG_A 12442 #undef FLAG_B 12443 } 12444 12445 static void 12446 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 12447 { 12448 #define FLAG_A 0x01 12449 #define FLAG_G 0x02 12450 struct bwn_softc *sc = mac->mac_sc; 12451 struct ifnet *ifp = sc->sc_ifp; 12452 struct ieee80211com *ic = ifp->if_l2com; 12453 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 12454 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 12455 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 12456 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 12457 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 12458 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 12459 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 12460 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 12461 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 12462 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 12463 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 12464 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 12465 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 12466 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 12467 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 12468 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 12469 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 12470 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 12471 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 12472 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 12473 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 12474 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 12475 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 12476 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 12477 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 12478 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 12479 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 12480 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 12481 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 12482 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 12483 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 12484 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 12485 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 12486 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 12487 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 12488 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 12489 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 12490 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 12491 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 12492 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 12493 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 12494 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 12495 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 12496 }; 12497 const struct bwn_b206x_rfinit_entry *br; 12498 unsigned int i; 12499 12500 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 12501 br = &bwn_b2063_init_tab[i]; 12502 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12503 if (br->br_flags & FLAG_G) 12504 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 12505 } else { 12506 if (br->br_flags & FLAG_A) 12507 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 12508 } 12509 } 12510 #undef FLAG_A 12511 #undef FLAG_B 12512 } 12513 12514 static void 12515 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 12516 int count, void *_data) 12517 { 12518 unsigned int i; 12519 uint32_t offset, type; 12520 uint8_t *data = _data; 12521 12522 type = BWN_TAB_GETTYPE(typenoffset); 12523 offset = BWN_TAB_GETOFFSET(typenoffset); 12524 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12525 12526 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12527 12528 for (i = 0; i < count; i++) { 12529 switch (type) { 12530 case BWN_TAB_8BIT: 12531 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 12532 data++; 12533 break; 12534 case BWN_TAB_16BIT: 12535 *((uint16_t *)data) = BWN_PHY_READ(mac, 12536 BWN_PHY_TABLEDATALO); 12537 data += 2; 12538 break; 12539 case BWN_TAB_32BIT: 12540 *((uint32_t *)data) = BWN_PHY_READ(mac, 12541 BWN_PHY_TABLEDATAHI); 12542 *((uint32_t *)data) <<= 16; 12543 *((uint32_t *)data) |= BWN_PHY_READ(mac, 12544 BWN_PHY_TABLEDATALO); 12545 data += 4; 12546 break; 12547 default: 12548 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12549 } 12550 } 12551 } 12552 12553 static void 12554 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 12555 int count, const void *_data) 12556 { 12557 uint32_t offset, type, value; 12558 const uint8_t *data = _data; 12559 unsigned int i; 12560 12561 type = BWN_TAB_GETTYPE(typenoffset); 12562 offset = BWN_TAB_GETOFFSET(typenoffset); 12563 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 12564 12565 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 12566 12567 for (i = 0; i < count; i++) { 12568 switch (type) { 12569 case BWN_TAB_8BIT: 12570 value = *data; 12571 data++; 12572 KASSERT(!(value & ~0xff), 12573 ("%s:%d: fail", __func__, __LINE__)); 12574 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12575 break; 12576 case BWN_TAB_16BIT: 12577 value = *((const uint16_t *)data); 12578 data += 2; 12579 KASSERT(!(value & ~0xffff), 12580 ("%s:%d: fail", __func__, __LINE__)); 12581 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12582 break; 12583 case BWN_TAB_32BIT: 12584 value = *((const uint32_t *)data); 12585 data += 4; 12586 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 12587 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 12588 break; 12589 default: 12590 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 12591 } 12592 } 12593 } 12594 12595 static struct bwn_txgain 12596 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 12597 { 12598 struct bwn_txgain tg; 12599 uint16_t tmp; 12600 12601 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 12602 if (mac->mac_phy.rev < 2) { 12603 tmp = BWN_PHY_READ(mac, 12604 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 12605 tg.tg_gm = tmp & 0x0007; 12606 tg.tg_pga = (tmp & 0x0078) >> 3; 12607 tg.tg_pad = (tmp & 0x780) >> 7; 12608 return (tg); 12609 } 12610 12611 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 12612 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 12613 tg.tg_gm = tmp & 0xff; 12614 tg.tg_pga = (tmp >> 8) & 0xff; 12615 return (tg); 12616 } 12617 12618 static uint8_t 12619 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 12620 { 12621 12622 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 12623 } 12624 12625 static void 12626 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 12627 { 12628 uint16_t pa; 12629 12630 if (mac->mac_phy.rev < 2) { 12631 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 12632 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 12633 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12634 bwn_phy_lp_set_txgain_override(mac); 12635 return; 12636 } 12637 12638 pa = bwn_phy_lp_get_pa_gain(mac); 12639 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 12640 (tg->tg_pga << 8) | tg->tg_gm); 12641 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 12642 tg->tg_pad | (pa << 6)); 12643 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 12644 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 12645 tg->tg_pad | (pa << 8)); 12646 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 12647 bwn_phy_lp_set_txgain_override(mac); 12648 } 12649 12650 static void 12651 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 12652 { 12653 12654 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 12655 } 12656 12657 static void 12658 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 12659 { 12660 uint16_t trsw = (tx << 1) | rx; 12661 12662 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 12663 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 12664 } 12665 12666 static void 12667 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 12668 { 12669 struct bwn_softc *sc = mac->mac_sc; 12670 struct ifnet *ifp = sc->sc_ifp; 12671 struct ieee80211com *ic = ifp->if_l2com; 12672 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 12673 12674 if (mac->mac_phy.rev < 2) { 12675 trsw = gain & 0x1; 12676 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 12677 ext_lna = (gain & 2) >> 1; 12678 12679 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12680 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12681 0xfbff, ext_lna << 10); 12682 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12683 0xf7ff, ext_lna << 11); 12684 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 12685 } else { 12686 low_gain = gain & 0xffff; 12687 high_gain = (gain >> 16) & 0xf; 12688 ext_lna = (gain >> 21) & 0x1; 12689 trsw = ~(gain >> 20) & 0x1; 12690 12691 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 12692 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12693 0xfdff, ext_lna << 9); 12694 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12695 0xfbff, ext_lna << 10); 12696 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 12697 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 12698 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12699 tmp = (gain >> 2) & 0x3; 12700 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 12701 0xe7ff, tmp<<11); 12702 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 12703 tmp << 3); 12704 } 12705 } 12706 12707 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 12708 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 12709 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 12710 if (mac->mac_phy.rev >= 2) { 12711 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 12712 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 12713 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 12714 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 12715 } 12716 return; 12717 } 12718 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 12719 } 12720 12721 static void 12722 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 12723 { 12724 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12725 12726 if (user) 12727 plp->plp_crsusr_off = 1; 12728 else 12729 plp->plp_crssys_off = 1; 12730 12731 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 12732 } 12733 12734 static void 12735 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 12736 { 12737 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 12738 struct bwn_softc *sc = mac->mac_sc; 12739 struct ifnet *ifp = sc->sc_ifp; 12740 struct ieee80211com *ic = ifp->if_l2com; 12741 12742 if (user) 12743 plp->plp_crsusr_off = 0; 12744 else 12745 plp->plp_crssys_off = 0; 12746 12747 if (plp->plp_crsusr_off || plp->plp_crssys_off) 12748 return; 12749 12750 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 12751 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 12752 else 12753 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 12754 } 12755 12756 static unsigned int 12757 bwn_sqrt(struct bwn_mac *mac, unsigned int x) 12758 { 12759 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ 12760 static uint8_t sqrt_table[256] = { 12761 10, 14, 17, 20, 22, 24, 26, 28, 12762 30, 31, 33, 34, 36, 37, 38, 40, 12763 41, 42, 43, 44, 45, 46, 47, 48, 12764 50, 50, 51, 52, 53, 54, 55, 56, 12765 57, 58, 59, 60, 60, 61, 62, 63, 12766 64, 64, 65, 66, 67, 67, 68, 69, 12767 70, 70, 71, 72, 72, 73, 74, 74, 12768 75, 76, 76, 77, 78, 78, 79, 80, 12769 80, 81, 81, 82, 83, 83, 84, 84, 12770 85, 86, 86, 87, 87, 88, 88, 89, 12771 90, 90, 91, 91, 92, 92, 93, 93, 12772 94, 94, 95, 95, 96, 96, 97, 97, 12773 98, 98, 99, 100, 100, 100, 101, 101, 12774 102, 102, 103, 103, 104, 104, 105, 105, 12775 106, 106, 107, 107, 108, 108, 109, 109, 12776 110, 110, 110, 111, 111, 112, 112, 113, 12777 113, 114, 114, 114, 115, 115, 116, 116, 12778 117, 117, 117, 118, 118, 119, 119, 120, 12779 120, 120, 121, 121, 122, 122, 122, 123, 12780 123, 124, 124, 124, 125, 125, 126, 126, 12781 126, 127, 127, 128, 128, 128, 129, 129, 12782 130, 130, 130, 131, 131, 131, 132, 132, 12783 133, 133, 133, 134, 134, 134, 135, 135, 12784 136, 136, 136, 137, 137, 137, 138, 138, 12785 138, 139, 139, 140, 140, 140, 141, 141, 12786 141, 142, 142, 142, 143, 143, 143, 144, 12787 144, 144, 145, 145, 145, 146, 146, 146, 12788 147, 147, 147, 148, 148, 148, 149, 149, 12789 150, 150, 150, 150, 151, 151, 151, 152, 12790 152, 152, 153, 153, 153, 154, 154, 154, 12791 155, 155, 155, 156, 156, 156, 157, 157, 12792 157, 158, 158, 158, 159, 159, 159, 160 12793 }; 12794 12795 if (x == 0) 12796 return (0); 12797 if (x >= 256) { 12798 unsigned int tmp; 12799 12800 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1) 12801 /* do nothing */ ; 12802 return (tmp); 12803 } 12804 return (sqrt_table[x - 1] / 10); 12805 } 12806 12807 static int 12808 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 12809 { 12810 #define CALC_COEFF(_v, _x, _y, _z) do { \ 12811 int _t; \ 12812 _t = _x - 20; \ 12813 if (_t >= 0) { \ 12814 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 12815 } else { \ 12816 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 12817 } \ 12818 } while (0) 12819 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 12820 int _t; \ 12821 _t = _x - 11; \ 12822 if (_t >= 0) \ 12823 _v = (_y << (31 - _x)) / (_z >> _t); \ 12824 else \ 12825 _v = (_y << (31 - _x)) / (_z << -_t); \ 12826 } while (0) 12827 struct bwn_phy_lp_iq_est ie; 12828 uint16_t v0, v1; 12829 int tmp[2], ret; 12830 12831 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 12832 v0 = v1 >> 8; 12833 v1 |= 0xff; 12834 12835 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 12836 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 12837 12838 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 12839 if (ret == 0) 12840 goto done; 12841 12842 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 12843 ret = 0; 12844 goto done; 12845 } 12846 12847 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 12848 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 12849 12850 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 12851 v0 = tmp[0] >> 3; 12852 v1 = tmp[1] >> 4; 12853 done: 12854 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 12855 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 12856 return ret; 12857 #undef CALC_COEFF 12858 #undef CALC_COEFF2 12859 } 12860 12861 static void 12862 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 12863 { 12864 static const uint16_t noisescale[] = { 12865 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12866 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 12867 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 12868 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12869 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 12870 }; 12871 static const uint16_t crsgainnft[] = { 12872 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 12873 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 12874 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 12875 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 12876 0x013d, 12877 }; 12878 static const uint16_t filterctl[] = { 12879 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 12880 0xff53, 0x0127, 12881 }; 12882 static const uint32_t psctl[] = { 12883 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 12884 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 12885 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 12886 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 12887 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 12888 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 12889 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 12890 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 12891 }; 12892 static const uint16_t ofdmcckgain_r0[] = { 12893 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12894 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12895 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12896 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12897 0x755d, 12898 }; 12899 static const uint16_t ofdmcckgain_r1[] = { 12900 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 12901 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 12902 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 12903 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 12904 0x755d, 12905 }; 12906 static const uint16_t gaindelta[] = { 12907 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 12908 0x0000, 12909 }; 12910 static const uint32_t txpwrctl[] = { 12911 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 12912 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 12913 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 12914 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 12915 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 12916 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 12917 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 12918 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 12919 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 12920 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 12921 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 12922 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 12923 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 12924 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12925 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12926 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12939 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12940 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12941 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12947 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12948 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 12949 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 12950 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 12951 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 12952 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 12953 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 12954 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 12955 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 12956 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 12957 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 12958 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 12959 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 12960 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 12961 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 12962 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 12963 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 12964 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 12965 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 12966 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 12967 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 12968 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 12969 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 12970 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 12971 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 12972 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 12973 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 12974 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 12975 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12976 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12977 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12978 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12979 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12980 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12981 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12982 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12983 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12984 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12985 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12986 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12987 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12988 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12989 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12990 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12991 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12992 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12993 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12994 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12995 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12996 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12997 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 12998 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 12999 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 13000 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 13001 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 13002 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 13003 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 13004 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 13005 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 13006 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 13007 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 13008 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 13009 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 13010 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 13011 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 13012 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 13013 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 13014 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 13015 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 13016 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 13017 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 13018 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 13019 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 13020 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 13021 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 13022 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 13023 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 13024 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 13025 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 13026 0x00000702, 13027 }; 13028 13029 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13030 13031 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13032 bwn_tab_sigsq_tbl); 13033 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13034 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 13035 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 13036 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 13037 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13038 bwn_tab_pllfrac_tbl); 13039 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13040 bwn_tabl_iqlocal_tbl); 13041 if (mac->mac_phy.rev == 0) { 13042 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 13043 ofdmcckgain_r0); 13044 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 13045 ofdmcckgain_r0); 13046 } else { 13047 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 13048 ofdmcckgain_r1); 13049 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 13050 ofdmcckgain_r1); 13051 } 13052 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 13053 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 13054 } 13055 13056 static void 13057 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 13058 { 13059 struct bwn_softc *sc = mac->mac_sc; 13060 int i; 13061 static const uint16_t noisescale[] = { 13062 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13063 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13064 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13065 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13066 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13067 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 13068 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 13069 }; 13070 static const uint32_t filterctl[] = { 13071 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 13072 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 13073 }; 13074 static const uint32_t psctl[] = { 13075 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 13076 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 13077 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 13078 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 13079 }; 13080 static const uint32_t gainidx[] = { 13081 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13083 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13084 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 13085 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 13086 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 13087 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 13088 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 13089 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 13090 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 13091 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 13092 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 13093 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 13094 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 13095 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 13096 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13097 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13098 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13099 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 13100 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 13101 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 13102 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 13103 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 13104 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 13105 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 13106 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 13107 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 13108 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 13109 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 13110 0x0000001a, 0x64ca55ad, 0x0000001a 13111 }; 13112 static const uint16_t auxgainidx[] = { 13113 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13114 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 13115 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 13116 0x0004, 0x0016 13117 }; 13118 static const uint16_t swctl[] = { 13119 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13120 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13121 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13122 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 13123 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13124 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 13125 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 13126 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 13127 }; 13128 static const uint8_t hf[] = { 13129 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 13130 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 13131 }; 13132 static const uint32_t gainval[] = { 13133 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13134 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13135 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13136 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13137 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13138 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13139 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13141 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13142 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13143 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13144 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13145 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 13146 0x000000f1, 0x00000000, 0x00000000 13147 }; 13148 static const uint16_t gain[] = { 13149 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 13150 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 13151 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 13152 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 13153 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 13154 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 13155 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13156 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13157 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13158 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13159 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13160 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13161 }; 13162 static const uint32_t papdeps[] = { 13163 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 13164 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 13165 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 13166 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 13167 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 13168 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 13169 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 13170 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 13171 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 13172 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 13173 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 13174 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 13175 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 13176 }; 13177 static const uint32_t papdmult[] = { 13178 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13179 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13180 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13181 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13182 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13183 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13184 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13185 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13186 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13187 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13188 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13189 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13190 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13191 }; 13192 static const uint32_t gainidx_a0[] = { 13193 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 13194 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 13195 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 13196 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 13197 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 13198 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 13199 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 13200 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 13201 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 13202 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 13203 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 13204 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 13205 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 13206 }; 13207 static const uint16_t auxgainidx_a0[] = { 13208 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13209 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 13210 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13211 0x0002, 0x0014 13212 }; 13213 static const uint32_t gainval_a0[] = { 13214 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 13215 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 13216 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 13217 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 13218 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 13219 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 13220 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 13222 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 13223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 13224 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 13225 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 13226 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 13227 0x000000f7, 0x00000000, 0x00000000 13228 }; 13229 static const uint16_t gain_a0[] = { 13230 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 13231 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 13232 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 13233 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 13234 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 13235 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 13236 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13237 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13238 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13239 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13240 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 13241 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 13242 }; 13243 13244 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 13245 13246 for (i = 0; i < 704; i++) 13247 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 13248 13249 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 13250 bwn_tab_sigsq_tbl); 13251 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 13252 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 13253 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 13254 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 13255 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 13256 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 13257 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 13258 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 13259 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 13260 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 13261 bwn_tab_pllfrac_tbl); 13262 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 13263 bwn_tabl_iqlocal_tbl); 13264 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 13265 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 13266 13267 if ((siba_get_chipid(sc->sc_dev) == 0x4325) && 13268 (siba_get_chiprev(sc->sc_dev) == 0)) { 13269 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 13270 gainidx_a0); 13271 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 13272 auxgainidx_a0); 13273 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 13274 gainval_a0); 13275 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 13276 } 13277 } 13278 13279 static void 13280 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 13281 { 13282 struct bwn_softc *sc = mac->mac_sc; 13283 struct ifnet *ifp = sc->sc_ifp; 13284 struct ieee80211com *ic = ifp->if_l2com; 13285 static struct bwn_txgain_entry txgain_r2[] = { 13286 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 13287 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 13288 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 13289 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 13290 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 13291 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 13292 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 13293 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 13294 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 13295 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 13296 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 13297 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 13298 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 13299 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 13300 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 13301 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13302 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 13303 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 13304 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 13305 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 13306 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13307 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 13308 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 13309 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13310 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13311 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13312 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 13313 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13314 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13315 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 13316 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 13317 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 13318 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13319 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13320 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13321 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 13322 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 13323 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 13324 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 13325 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 13326 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 13327 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 13328 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 13329 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 13330 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 13331 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 13332 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 13333 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 13334 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 13335 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 13336 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 13337 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 13338 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 13339 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 13340 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 13341 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 13342 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 13343 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 13344 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 13345 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 13346 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 13347 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 13348 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 13349 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 13350 }; 13351 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 13352 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 13353 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 13354 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 13355 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 13356 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 13357 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 13358 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 13359 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 13360 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 13361 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 13362 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 13363 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 13364 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 13365 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 13366 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 13367 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 13368 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 13369 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 13370 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 13371 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 13372 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 13373 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 13374 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 13375 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 13376 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 13377 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 13378 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 13379 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 13380 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 13381 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 13382 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 13383 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 13384 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 13385 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 13386 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 13387 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 13388 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 13389 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 13390 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 13391 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 13392 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 13393 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 13394 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 13395 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 13396 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 13397 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 13398 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 13399 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 13400 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 13401 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 13402 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 13403 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 13404 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 13405 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 13406 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 13407 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 13408 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 13409 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 13410 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 13411 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 13412 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 13413 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 13414 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 13415 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 13416 }; 13417 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 13418 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 13419 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 13420 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 13421 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 13422 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 13423 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 13424 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 13425 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 13426 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 13427 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 13428 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 13429 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 13430 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 13431 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 13432 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 13433 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 13434 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 13435 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 13436 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 13437 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 13438 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 13439 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 13440 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 13441 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 13442 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 13443 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 13444 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 13445 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 13446 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 13447 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 13448 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 13449 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 13450 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 13451 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 13452 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 13453 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 13454 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 13455 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 13456 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 13457 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 13458 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 13459 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 13460 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 13461 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 13462 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 13463 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 13464 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 13465 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 13466 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 13467 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 13468 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 13469 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 13470 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 13471 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 13472 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 13473 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 13474 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 13475 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 13476 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 13477 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 13478 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 13479 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 13480 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 13481 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 13482 }; 13483 static struct bwn_txgain_entry txgain_r0[] = { 13484 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13485 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13486 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13487 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13488 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13489 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13490 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13491 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13492 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13493 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13494 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13495 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13496 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13497 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13498 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13499 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13500 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13501 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13502 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 13503 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 13504 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13505 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 13506 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 13507 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 13508 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 13509 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 13510 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 13511 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 13512 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 13513 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 13514 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 13515 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 13516 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 13517 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 13518 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 13519 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13520 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13521 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 13522 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 13523 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 13524 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 13525 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 13526 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 13527 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13528 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13529 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13530 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13531 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 13532 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 13533 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 13534 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 13535 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 13536 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 13537 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 13538 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 13539 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 13540 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 13541 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 13542 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 13543 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 13544 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 13545 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 13546 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 13547 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 13548 }; 13549 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 13550 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13551 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13552 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13553 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13554 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13555 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13556 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13557 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13558 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13559 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13560 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13561 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13562 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13563 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13564 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13565 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13566 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13567 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13568 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13569 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13570 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13571 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13572 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13573 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13574 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13575 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13576 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13577 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13578 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13579 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13580 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13581 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13582 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13583 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 13584 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 13585 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 13586 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 13587 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 13588 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 13589 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 13590 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 13591 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 13592 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 13593 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 13594 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 13595 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 13596 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 13597 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 13598 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 13599 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 13600 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 13601 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 13602 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 13603 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 13604 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 13605 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 13606 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 13607 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 13608 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 13609 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 13610 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 13611 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 13612 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 13613 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 13614 }; 13615 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 13616 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13617 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13618 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13619 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13620 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13621 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13622 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13623 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13624 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13625 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13626 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13627 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13628 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13629 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13630 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13631 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13632 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13633 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13634 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13635 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13636 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13637 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13638 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13639 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13640 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13641 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13642 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13643 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13644 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13645 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13646 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13647 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13648 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13649 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13650 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13651 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13652 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13653 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13654 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13655 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13656 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13657 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13658 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13659 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13660 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13661 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13662 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13663 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13664 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13665 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13666 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13667 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13668 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13669 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13670 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13671 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13672 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13673 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13674 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13675 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13676 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13677 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13678 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13679 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13680 }; 13681 static struct bwn_txgain_entry txgain_r1[] = { 13682 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 13683 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 13684 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 13685 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 13686 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 13687 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 13688 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 13689 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 13690 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 13691 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 13692 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 13693 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 13694 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 13695 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 13696 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 13697 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 13698 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 13699 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 13700 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 13701 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13702 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13703 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 13704 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 13705 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 13706 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 13707 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 13708 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 13709 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 13710 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 13711 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 13712 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 13713 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 13714 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 13715 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13716 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 13717 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13718 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13719 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13720 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13721 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 13722 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 13723 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 13724 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 13725 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 13726 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 13727 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 13728 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 13729 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 13730 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 13731 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 13732 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 13733 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 13734 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13735 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13736 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13737 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 13738 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13739 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13740 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13741 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 13742 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 13743 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 13744 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 13745 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 13746 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13747 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 13748 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 13749 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 13750 { 7, 11, 6, 0, 71 } 13751 }; 13752 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 13753 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 13754 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 13755 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 13756 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 13757 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 13758 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 13759 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 13760 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 13761 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 13762 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 13763 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 13764 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 13765 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 13766 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 13767 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 13768 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 13769 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 13770 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 13771 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 13772 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 13773 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 13774 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 13775 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 13776 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 13777 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 13778 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 13779 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 13780 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 13781 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 13782 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 13783 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 13784 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 13785 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 13786 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 13787 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 13788 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 13789 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 13790 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 13791 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 13792 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 13793 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 13794 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 13795 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 13796 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 13797 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 13798 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 13799 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 13800 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 13801 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 13802 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 13803 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 13804 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 13805 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 13806 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 13807 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 13808 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 13809 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 13810 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 13811 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 13812 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 13813 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 13814 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 13815 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 13816 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 13817 }; 13818 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 13819 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 13820 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 13821 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 13822 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 13823 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 13824 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 13825 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 13826 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 13827 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 13828 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 13829 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 13830 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 13831 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 13832 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 13833 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 13834 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 13835 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 13836 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 13837 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 13838 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 13839 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 13840 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 13841 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 13842 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 13843 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 13844 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 13845 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 13846 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 13847 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 13848 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 13849 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 13850 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 13851 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 13852 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 13853 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 13854 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 13855 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 13856 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 13857 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 13858 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 13859 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 13860 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 13861 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 13862 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 13863 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 13864 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 13865 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 13866 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 13867 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 13868 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 13869 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 13870 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 13871 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 13872 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 13873 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 13874 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 13875 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 13876 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 13877 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 13878 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 13879 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 13880 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 13881 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 13882 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 13883 }; 13884 13885 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 13886 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) 13887 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 13888 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13889 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13890 txgain_2ghz_r2); 13891 else 13892 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13893 txgain_5ghz_r2); 13894 return; 13895 } 13896 13897 if (mac->mac_phy.rev == 0) { 13898 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13899 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13900 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 13901 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13902 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13903 txgain_2ghz_r0); 13904 else 13905 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 13906 txgain_5ghz_r0); 13907 return; 13908 } 13909 13910 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) || 13911 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA)) 13912 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 13913 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 13914 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 13915 else 13916 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 13917 } 13918 13919 static void 13920 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 13921 { 13922 uint32_t offset, type; 13923 13924 type = BWN_TAB_GETTYPE(typeoffset); 13925 offset = BWN_TAB_GETOFFSET(typeoffset); 13926 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 13927 13928 switch (type) { 13929 case BWN_TAB_8BIT: 13930 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 13931 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13932 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13933 break; 13934 case BWN_TAB_16BIT: 13935 KASSERT(!(value & ~0xffff), 13936 ("%s:%d: fail", __func__, __LINE__)); 13937 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13938 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13939 break; 13940 case BWN_TAB_32BIT: 13941 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 13942 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 13943 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 13944 break; 13945 default: 13946 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 13947 } 13948 } 13949 13950 static int 13951 bwn_phy_lp_loopback(struct bwn_mac *mac) 13952 { 13953 struct bwn_phy_lp_iq_est ie; 13954 int i, index = -1; 13955 uint32_t tmp; 13956 13957 memset(&ie, 0, sizeof(ie)); 13958 13959 bwn_phy_lp_set_trsw_over(mac, 1, 1); 13960 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 13961 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 13962 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 13964 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 13965 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 13966 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 13967 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 13968 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 13969 for (i = 0; i < 32; i++) { 13970 bwn_phy_lp_set_rxgain_idx(mac, i); 13971 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 13972 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 13973 continue; 13974 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 13975 if ((tmp > 4000) && (tmp < 10000)) { 13976 index = i; 13977 break; 13978 } 13979 } 13980 bwn_phy_lp_ddfs_turnoff(mac); 13981 return (index); 13982 } 13983 13984 static void 13985 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 13986 { 13987 13988 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 13989 } 13990 13991 static void 13992 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 13993 int incr1, int incr2, int scale_idx) 13994 { 13995 13996 bwn_phy_lp_ddfs_turnoff(mac); 13997 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 13998 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 13999 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 14000 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 14002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 14003 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 14004 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 14005 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 14006 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 14007 } 14008 14009 static uint8_t 14010 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 14011 struct bwn_phy_lp_iq_est *ie) 14012 { 14013 int i; 14014 14015 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 14016 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 14017 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 14018 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 14019 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 14020 14021 for (i = 0; i < 500; i++) { 14022 if (!(BWN_PHY_READ(mac, 14023 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 14024 break; 14025 DELAY(1000); 14026 } 14027 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 14028 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14029 return 0; 14030 } 14031 14032 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 14033 ie->ie_iqprod <<= 16; 14034 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 14035 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 14036 ie->ie_ipwr <<= 16; 14037 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 14038 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 14039 ie->ie_qpwr <<= 16; 14040 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 14041 14042 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 14043 return 1; 14044 } 14045 14046 static uint32_t 14047 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 14048 { 14049 uint32_t offset, type, value; 14050 14051 type = BWN_TAB_GETTYPE(typeoffset); 14052 offset = BWN_TAB_GETOFFSET(typeoffset); 14053 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 14054 14055 switch (type) { 14056 case BWN_TAB_8BIT: 14057 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14058 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 14059 break; 14060 case BWN_TAB_16BIT: 14061 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14062 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14063 break; 14064 case BWN_TAB_32BIT: 14065 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 14066 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 14067 value <<= 16; 14068 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 14069 break; 14070 default: 14071 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 14072 value = 0; 14073 } 14074 14075 return (value); 14076 } 14077 14078 static void 14079 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 14080 { 14081 14082 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 14083 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 14084 } 14085 14086 static void 14087 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 14088 { 14089 uint16_t ctl; 14090 14091 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 14092 ctl |= dac << 7; 14093 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 14094 } 14095 14096 static void 14097 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 14098 { 14099 14100 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 14101 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 14102 } 14103 14104 static void 14105 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 14106 { 14107 14108 if (mac->mac_phy.rev < 2) 14109 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 14110 else { 14111 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 14112 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 14113 } 14114 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 14115 } 14116 14117 static uint16_t 14118 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 14119 { 14120 14121 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 14122 } 14123 14124 static uint8_t 14125 bwn_nbits(int32_t val) 14126 { 14127 uint32_t tmp; 14128 uint8_t nbits = 0; 14129 14130 for (tmp = abs(val); tmp != 0; tmp >>= 1) 14131 nbits++; 14132 return (nbits); 14133 } 14134 14135 static void 14136 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 14137 struct bwn_txgain_entry *table) 14138 { 14139 int i; 14140 14141 for (i = offset; i < count; i++) 14142 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 14143 } 14144 14145 static void 14146 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 14147 struct bwn_txgain_entry data) 14148 { 14149 14150 if (mac->mac_phy.rev >= 2) 14151 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 14152 else 14153 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 14154 } 14155 14156 static void 14157 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 14158 struct bwn_txgain_entry te) 14159 { 14160 struct bwn_softc *sc = mac->mac_sc; 14161 struct ifnet *ifp = sc->sc_ifp; 14162 struct ieee80211com *ic = ifp->if_l2com; 14163 uint32_t tmp; 14164 14165 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 14166 14167 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 14168 if (mac->mac_phy.rev >= 3) { 14169 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14170 (0x10 << 24) : (0x70 << 24)); 14171 } else { 14172 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 14173 (0x14 << 24) : (0x7f << 24)); 14174 } 14175 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 14176 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 14177 te.te_bbmult << 20 | te.te_dac << 28); 14178 } 14179 14180 static void 14181 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 14182 struct bwn_txgain_entry te) 14183 { 14184 14185 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 14186 14187 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 14188 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 14189 te.te_dac); 14190 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 14191 } 14192 14193 static void 14194 bwn_sysctl_node(struct bwn_softc *sc) 14195 { 14196 device_t dev = sc->sc_dev; 14197 struct bwn_mac *mac; 14198 struct bwn_stats *stats; 14199 14200 /* XXX assume that count of MAC is only 1. */ 14201 14202 if ((mac = sc->sc_curmac) == NULL) 14203 return; 14204 stats = &mac->mac_stats; 14205 14206 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14207 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14208 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 14209 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14210 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14211 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 14212 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 14213 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14214 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 14215 14216 #ifdef BWN_DEBUG 14217 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 14218 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 14219 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 14220 #endif 14221 } 14222 14223 static device_method_t bwn_methods[] = { 14224 /* Device interface */ 14225 DEVMETHOD(device_probe, bwn_probe), 14226 DEVMETHOD(device_attach, bwn_attach), 14227 DEVMETHOD(device_detach, bwn_detach), 14228 DEVMETHOD(device_suspend, bwn_suspend), 14229 DEVMETHOD(device_resume, bwn_resume), 14230 DEVMETHOD_END 14231 }; 14232 static driver_t bwn_driver = { 14233 "bwn", 14234 bwn_methods, 14235 sizeof(struct bwn_softc) 14236 }; 14237 static devclass_t bwn_devclass; 14238 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); 14239 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 14240 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 14241 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 14242 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 14243