1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 5 * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org> 6 * Copyright (c) 2017 The FreeBSD Foundation 7 * All rights reserved. 8 * 9 * Portions of this software were developed by Landon Fuller 10 * under sponsorship from the FreeBSD Foundation. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 20 * redistribution must be conditioned upon including a substantially 21 * similar Disclaimer requirement for further binary redistribution. 22 * 23 * NO WARRANTY 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 28 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 29 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 34 * THE POSSIBILITY OF SUCH DAMAGES. 35 */ 36 37 #include <sys/cdefs.h> 38 __FBSDID("$FreeBSD$"); 39 40 /* 41 * The Broadcom Wireless LAN controller driver. 42 */ 43 44 #include "opt_bwn.h" 45 #include "opt_wlan.h" 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/gpio.h> 51 #include <sys/malloc.h> 52 #include <sys/module.h> 53 #include <sys/endian.h> 54 #include <sys/errno.h> 55 #include <sys/firmware.h> 56 #include <sys/lock.h> 57 #include <sys/mutex.h> 58 #include <machine/bus.h> 59 #include <machine/resource.h> 60 #include <sys/bus.h> 61 #include <sys/rman.h> 62 #include <sys/socket.h> 63 #include <sys/sockio.h> 64 65 #include <net/ethernet.h> 66 #include <net/if.h> 67 #include <net/if_var.h> 68 #include <net/if_arp.h> 69 #include <net/if_dl.h> 70 #include <net/if_llc.h> 71 #include <net/if_media.h> 72 #include <net/if_types.h> 73 74 #include <net80211/ieee80211_var.h> 75 #include <net80211/ieee80211_radiotap.h> 76 #include <net80211/ieee80211_regdomain.h> 77 #include <net80211/ieee80211_phy.h> 78 #include <net80211/ieee80211_ratectl.h> 79 80 #include <dev/bhnd/bhnd.h> 81 #include <dev/bhnd/bhnd_ids.h> 82 83 #include <dev/bhnd/cores/chipc/chipc.h> 84 #include <dev/bhnd/cores/pmu/bhnd_pmu.h> 85 86 #include <dev/bwn/if_bwnreg.h> 87 #include <dev/bwn/if_bwnvar.h> 88 89 #include <dev/bwn/if_bwn_debug.h> 90 #include <dev/bwn/if_bwn_misc.h> 91 #include <dev/bwn/if_bwn_util.h> 92 #include <dev/bwn/if_bwn_phy_common.h> 93 #include <dev/bwn/if_bwn_phy_g.h> 94 #include <dev/bwn/if_bwn_phy_lp.h> 95 #include <dev/bwn/if_bwn_phy_n.h> 96 97 #include "bhnd_nvram_map.h" 98 99 #include "gpio_if.h" 100 101 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, 102 "Broadcom driver parameters"); 103 104 /* 105 * Tunable & sysctl variables. 106 */ 107 108 #ifdef BWN_DEBUG 109 static int bwn_debug = 0; 110 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0, 111 "Broadcom debugging printfs"); 112 #endif 113 114 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */ 115 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0, 116 "uses Bad Frames Preemption"); 117 static int bwn_bluetooth = 1; 118 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0, 119 "turns on Bluetooth Coexistence"); 120 static int bwn_hwpctl = 0; 121 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, 122 "uses H/W power control"); 123 static int bwn_usedma = 1; 124 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, 125 "uses DMA"); 126 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma); 127 static int bwn_wme = 1; 128 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, 129 "uses WME support"); 130 131 static void bwn_attach_pre(struct bwn_softc *); 132 static int bwn_attach_post(struct bwn_softc *); 133 static int bwn_retain_bus_providers(struct bwn_softc *sc); 134 static void bwn_release_bus_providers(struct bwn_softc *sc); 135 static void bwn_sprom_bugfixes(device_t); 136 static int bwn_init(struct bwn_softc *); 137 static void bwn_parent(struct ieee80211com *); 138 static void bwn_start(struct bwn_softc *); 139 static int bwn_transmit(struct ieee80211com *, struct mbuf *); 140 static int bwn_attach_core(struct bwn_mac *); 141 static int bwn_phy_getinfo(struct bwn_mac *, int); 142 static int bwn_chiptest(struct bwn_mac *); 143 static int bwn_setup_channels(struct bwn_mac *, int, int); 144 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t, 145 uint16_t); 146 static void bwn_addchannels(struct ieee80211_channel [], int, int *, 147 const struct bwn_channelinfo *, const uint8_t []); 148 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 149 const struct ieee80211_bpf_params *); 150 static void bwn_updateslot(struct ieee80211com *); 151 static void bwn_update_promisc(struct ieee80211com *); 152 static void bwn_wme_init(struct bwn_mac *); 153 static int bwn_wme_update(struct ieee80211com *); 154 static void bwn_wme_clear(struct bwn_softc *); 155 static void bwn_wme_load(struct bwn_mac *); 156 static void bwn_wme_loadparams(struct bwn_mac *, 157 const struct wmeParams *, uint16_t); 158 static void bwn_scan_start(struct ieee80211com *); 159 static void bwn_scan_end(struct ieee80211com *); 160 static void bwn_set_channel(struct ieee80211com *); 161 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, 162 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 163 const uint8_t [IEEE80211_ADDR_LEN], 164 const uint8_t [IEEE80211_ADDR_LEN]); 165 static void bwn_vap_delete(struct ieee80211vap *); 166 static void bwn_stop(struct bwn_softc *); 167 static int bwn_core_forceclk(struct bwn_mac *, bool); 168 static int bwn_core_init(struct bwn_mac *); 169 static void bwn_core_start(struct bwn_mac *); 170 static void bwn_core_exit(struct bwn_mac *); 171 static void bwn_bt_disable(struct bwn_mac *); 172 static int bwn_chip_init(struct bwn_mac *); 173 static void bwn_set_txretry(struct bwn_mac *, int, int); 174 static void bwn_rate_init(struct bwn_mac *); 175 static void bwn_set_phytxctl(struct bwn_mac *); 176 static void bwn_spu_setdelay(struct bwn_mac *, int); 177 static void bwn_bt_enable(struct bwn_mac *); 178 static void bwn_set_macaddr(struct bwn_mac *); 179 static void bwn_crypt_init(struct bwn_mac *); 180 static void bwn_chip_exit(struct bwn_mac *); 181 static int bwn_fw_fillinfo(struct bwn_mac *); 182 static int bwn_fw_loaducode(struct bwn_mac *); 183 static int bwn_gpio_init(struct bwn_mac *); 184 static int bwn_fw_loadinitvals(struct bwn_mac *); 185 static int bwn_phy_init(struct bwn_mac *); 186 static void bwn_set_txantenna(struct bwn_mac *, int); 187 static void bwn_set_opmode(struct bwn_mac *); 188 static void bwn_rate_write(struct bwn_mac *, uint16_t, int); 189 static uint8_t bwn_plcp_getcck(const uint8_t); 190 static uint8_t bwn_plcp_getofdm(const uint8_t); 191 static void bwn_pio_init(struct bwn_mac *); 192 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int); 193 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *, 194 int); 195 static void bwn_pio_setupqueue_rx(struct bwn_mac *, 196 struct bwn_pio_rxqueue *, int); 197 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *); 198 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *, 199 uint16_t); 200 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *); 201 static int bwn_pio_rx(struct bwn_pio_rxqueue *); 202 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *); 203 static void bwn_pio_handle_txeof(struct bwn_mac *, 204 const struct bwn_txstatus *); 205 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t); 206 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t); 207 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t, 208 uint16_t); 209 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t, 210 uint32_t); 211 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *, 212 struct mbuf *); 213 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t); 214 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *, 215 struct bwn_pio_txqueue *, uint32_t, const void *, int); 216 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *, 217 uint16_t, uint32_t); 218 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *, 219 struct bwn_pio_txqueue *, uint16_t, const void *, int); 220 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *, 221 struct bwn_pio_txqueue *, uint16_t, struct mbuf *); 222 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *, 223 uint16_t, struct bwn_pio_txpkt **); 224 static void bwn_dma_init(struct bwn_mac *); 225 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); 226 static uint16_t bwn_dma_base(int, int); 227 static void bwn_dma_ringfree(struct bwn_dma_ring **); 228 static void bwn_dma_32_getdesc(struct bwn_dma_ring *, 229 int, struct bwn_dmadesc_generic **, 230 struct bwn_dmadesc_meta **); 231 static void bwn_dma_32_setdesc(struct bwn_dma_ring *, 232 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 233 int, int); 234 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int); 235 static void bwn_dma_32_suspend(struct bwn_dma_ring *); 236 static void bwn_dma_32_resume(struct bwn_dma_ring *); 237 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *); 238 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int); 239 static void bwn_dma_64_getdesc(struct bwn_dma_ring *, 240 int, struct bwn_dmadesc_generic **, 241 struct bwn_dmadesc_meta **); 242 static void bwn_dma_64_setdesc(struct bwn_dma_ring *, 243 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, 244 int, int); 245 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int); 246 static void bwn_dma_64_suspend(struct bwn_dma_ring *); 247 static void bwn_dma_64_resume(struct bwn_dma_ring *); 248 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *); 249 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int); 250 static int bwn_dma_allocringmemory(struct bwn_dma_ring *); 251 static void bwn_dma_setup(struct bwn_dma_ring *); 252 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *); 253 static void bwn_dma_cleanup(struct bwn_dma_ring *); 254 static void bwn_dma_free_descbufs(struct bwn_dma_ring *); 255 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int); 256 static void bwn_dma_rx(struct bwn_dma_ring *); 257 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int); 258 static void bwn_dma_free_descbuf(struct bwn_dma_ring *, 259 struct bwn_dmadesc_meta *); 260 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); 261 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); 262 static int bwn_dma_freeslot(struct bwn_dma_ring *); 263 static int bwn_dma_nextslot(struct bwn_dma_ring *, int); 264 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *); 265 static int bwn_dma_newbuf(struct bwn_dma_ring *, 266 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *, 267 int); 268 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int, 269 bus_size_t, int); 270 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *); 271 static void bwn_ratectl_tx_complete(const struct ieee80211_node *, 272 const struct bwn_txstatus *); 273 static void bwn_dma_handle_txeof(struct bwn_mac *, 274 const struct bwn_txstatus *); 275 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *, 276 struct mbuf *); 277 static int bwn_dma_getslot(struct bwn_dma_ring *); 278 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *, 279 uint8_t); 280 static int bwn_dma_attach(struct bwn_mac *); 281 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, 282 int, int); 283 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, 284 const struct bwn_txstatus *, uint16_t, int *); 285 static void bwn_dma_free(struct bwn_mac *); 286 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype); 287 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype, 288 const char *, struct bwn_fwfile *); 289 static void bwn_release_firmware(struct bwn_mac *); 290 static void bwn_do_release_fw(struct bwn_fwfile *); 291 static uint16_t bwn_fwcaps_read(struct bwn_mac *); 292 static int bwn_fwinitvals_write(struct bwn_mac *, 293 const struct bwn_fwinitvals *, size_t, size_t); 294 static uint16_t bwn_ant2phy(int); 295 static void bwn_mac_write_bssid(struct bwn_mac *); 296 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t, 297 const uint8_t *); 298 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t, 299 const uint8_t *, size_t, const uint8_t *); 300 static void bwn_key_macwrite(struct bwn_mac *, uint8_t, 301 const uint8_t *); 302 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t, 303 const uint8_t *); 304 static void bwn_phy_exit(struct bwn_mac *); 305 static void bwn_core_stop(struct bwn_mac *); 306 static int bwn_switch_band(struct bwn_softc *, 307 struct ieee80211_channel *); 308 static int bwn_phy_reset(struct bwn_mac *); 309 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 310 static void bwn_set_pretbtt(struct bwn_mac *); 311 static int bwn_intr(void *); 312 static void bwn_intrtask(void *, int); 313 static void bwn_restart(struct bwn_mac *, const char *); 314 static void bwn_intr_ucode_debug(struct bwn_mac *); 315 static void bwn_intr_tbtt_indication(struct bwn_mac *); 316 static void bwn_intr_atim_end(struct bwn_mac *); 317 static void bwn_intr_beacon(struct bwn_mac *); 318 static void bwn_intr_pmq(struct bwn_mac *); 319 static void bwn_intr_noise(struct bwn_mac *); 320 static void bwn_intr_txeof(struct bwn_mac *); 321 static void bwn_hwreset(void *, int); 322 static void bwn_handle_fwpanic(struct bwn_mac *); 323 static void bwn_load_beacon0(struct bwn_mac *); 324 static void bwn_load_beacon1(struct bwn_mac *); 325 static uint32_t bwn_jssi_read(struct bwn_mac *); 326 static void bwn_noise_gensample(struct bwn_mac *); 327 static void bwn_handle_txeof(struct bwn_mac *, 328 const struct bwn_txstatus *); 329 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); 330 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); 331 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, 332 struct mbuf *); 333 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); 334 static int bwn_set_txhdr(struct bwn_mac *, 335 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *, 336 uint16_t); 337 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t, 338 const uint8_t); 339 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t); 340 static uint8_t bwn_get_fbrate(uint8_t); 341 static void bwn_txpwr(void *, int); 342 static void bwn_tasks(void *); 343 static void bwn_task_15s(struct bwn_mac *); 344 static void bwn_task_30s(struct bwn_mac *); 345 static void bwn_task_60s(struct bwn_mac *); 346 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *, 347 uint8_t); 348 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *); 349 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *, 350 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int, 351 int, int); 352 static void bwn_tsf_read(struct bwn_mac *, uint64_t *); 353 static void bwn_set_slot_time(struct bwn_mac *, uint16_t); 354 static void bwn_watchdog(void *); 355 static void bwn_dma_stop(struct bwn_mac *); 356 static void bwn_pio_stop(struct bwn_mac *); 357 static void bwn_dma_ringstop(struct bwn_dma_ring **); 358 static int bwn_led_attach(struct bwn_mac *); 359 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); 360 static void bwn_led_event(struct bwn_mac *, int); 361 static void bwn_led_blink_start(struct bwn_mac *, int, int); 362 static void bwn_led_blink_next(void *); 363 static void bwn_led_blink_end(void *); 364 static void bwn_rfswitch(void *); 365 static void bwn_rf_turnon(struct bwn_mac *); 366 static void bwn_rf_turnoff(struct bwn_mac *); 367 static void bwn_sysctl_node(struct bwn_softc *); 368 369 static const struct bwn_channelinfo bwn_chantable_bg = { 370 .channels = { 371 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, 372 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 }, 373 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 }, 374 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 }, 375 { 2472, 13, 30 }, { 2484, 14, 30 } }, 376 .nchannels = 14 377 }; 378 379 static const struct bwn_channelinfo bwn_chantable_a = { 380 .channels = { 381 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 }, 382 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 }, 383 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 }, 384 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 }, 385 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 }, 386 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 }, 387 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 }, 388 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 }, 389 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 }, 390 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 }, 391 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 }, 392 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 }, 393 { 6080, 216, 30 } }, 394 .nchannels = 37 395 }; 396 397 #if 0 398 static const struct bwn_channelinfo bwn_chantable_n = { 399 .channels = { 400 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 }, 401 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 }, 402 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 }, 403 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 }, 404 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 }, 405 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 }, 406 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 }, 407 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 }, 408 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 }, 409 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 }, 410 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 }, 411 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 }, 412 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 }, 413 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 }, 414 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 }, 415 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 }, 416 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 }, 417 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 }, 418 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 }, 419 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 }, 420 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 }, 421 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 }, 422 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 }, 423 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 }, 424 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 }, 425 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 }, 426 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 }, 427 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 }, 428 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 }, 429 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 }, 430 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 }, 431 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 }, 432 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 }, 433 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 }, 434 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 }, 435 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 }, 436 { 6130, 226, 30 }, { 6140, 228, 30 } }, 437 .nchannels = 110 438 }; 439 #endif 440 441 #define VENDOR_LED_ACT(vendor) \ 442 { \ 443 .vid = PCI_VENDOR_##vendor, \ 444 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \ 445 } 446 447 static const struct { 448 uint16_t vid; 449 uint8_t led_act[BWN_LED_MAX]; 450 } bwn_vendor_led_act[] = { 451 VENDOR_LED_ACT(HP_COMPAQ), 452 VENDOR_LED_ACT(ASUSTEK) 453 }; 454 455 static const uint8_t bwn_default_led_act[BWN_LED_MAX] = 456 { BWN_VENDOR_LED_ACT_DEFAULT }; 457 458 #undef VENDOR_LED_ACT 459 460 static const char *bwn_led_vars[] = { 461 BHND_NVAR_LEDBH0, 462 BHND_NVAR_LEDBH1, 463 BHND_NVAR_LEDBH2, 464 BHND_NVAR_LEDBH3 465 }; 466 467 static const struct { 468 int on_dur; 469 int off_dur; 470 } bwn_led_duration[109] = { 471 [0] = { 400, 100 }, 472 [2] = { 150, 75 }, 473 [4] = { 90, 45 }, 474 [11] = { 66, 34 }, 475 [12] = { 53, 26 }, 476 [18] = { 42, 21 }, 477 [22] = { 35, 17 }, 478 [24] = { 32, 16 }, 479 [36] = { 21, 10 }, 480 [48] = { 16, 8 }, 481 [72] = { 11, 5 }, 482 [96] = { 9, 4 }, 483 [108] = { 7, 3 } 484 }; 485 486 static const uint16_t bwn_wme_shm_offsets[] = { 487 [0] = BWN_WME_BESTEFFORT, 488 [1] = BWN_WME_BACKGROUND, 489 [2] = BWN_WME_VOICE, 490 [3] = BWN_WME_VIDEO, 491 }; 492 493 /* Supported D11 core revisions */ 494 #define BWN_DEV(_hwrev) {{ \ 495 BHND_MATCH_CORE(BHND_MFGID_BCM, BHND_COREID_D11), \ 496 BHND_MATCH_CORE_REV(_hwrev), \ 497 }} 498 static const struct bhnd_device bwn_devices[] = { 499 BWN_DEV(HWREV_RANGE(5, 16)), 500 BWN_DEV(HWREV_EQ(23)), 501 BHND_DEVICE_END 502 }; 503 504 /* D11 quirks when bridged via a PCI host bridge core */ 505 static const struct bhnd_device_quirk pci_bridge_quirks[] = { 506 BHND_CORE_QUIRK (HWREV_LTE(10), BWN_QUIRK_UCODE_SLOWCLOCK_WAR), 507 BHND_DEVICE_QUIRK_END 508 }; 509 510 /* D11 quirks when bridged via a PCMCIA host bridge core */ 511 static const struct bhnd_device_quirk pcmcia_bridge_quirks[] = { 512 BHND_CORE_QUIRK (HWREV_ANY, BWN_QUIRK_NODMA), 513 BHND_DEVICE_QUIRK_END 514 }; 515 516 /* Host bridge cores for which D11 quirk flags should be applied */ 517 static const struct bhnd_device bridge_devices[] = { 518 BHND_DEVICE(BCM, PCI, NULL, pci_bridge_quirks), 519 BHND_DEVICE(BCM, PCMCIA, NULL, pcmcia_bridge_quirks), 520 BHND_DEVICE_END 521 }; 522 523 static int 524 bwn_probe(device_t dev) 525 { 526 const struct bhnd_device *id; 527 528 id = bhnd_device_lookup(dev, bwn_devices, sizeof(bwn_devices[0])); 529 if (id == NULL) 530 return (ENXIO); 531 532 bhnd_set_default_core_desc(dev); 533 return (BUS_PROBE_DEFAULT); 534 } 535 536 static int 537 bwn_attach(device_t dev) 538 { 539 struct bwn_mac *mac; 540 struct bwn_softc *sc; 541 device_t parent, hostb; 542 char chip_name[BHND_CHIPID_MAX_NAMELEN]; 543 int error; 544 545 sc = device_get_softc(dev); 546 sc->sc_dev = dev; 547 #ifdef BWN_DEBUG 548 sc->sc_debug = bwn_debug; 549 #endif 550 551 mac = NULL; 552 553 /* Determine the driver quirks applicable to this device, including any 554 * quirks specific to the bus host bridge core (if any) */ 555 sc->sc_quirks = bhnd_device_quirks(dev, bwn_devices, 556 sizeof(bwn_devices[0])); 557 558 parent = device_get_parent(dev); 559 if ((hostb = bhnd_bus_find_hostb_device(parent)) != NULL) { 560 sc->sc_quirks |= bhnd_device_quirks(hostb, bridge_devices, 561 sizeof(bridge_devices[0])); 562 } 563 564 /* DMA explicitly disabled? */ 565 if (!bwn_usedma) 566 sc->sc_quirks |= BWN_QUIRK_NODMA; 567 568 /* Fetch our chip identification and board info */ 569 sc->sc_cid = *bhnd_get_chipid(dev); 570 if ((error = bhnd_read_board_info(dev, &sc->sc_board_info))) { 571 device_printf(sc->sc_dev, "couldn't read board info\n"); 572 return (error); 573 } 574 575 /* Allocate our D11 register block and PMU state */ 576 sc->sc_mem_rid = 0; 577 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 578 &sc->sc_mem_rid, RF_ACTIVE); 579 if (sc->sc_mem_res == NULL) { 580 device_printf(sc->sc_dev, "couldn't allocate registers\n"); 581 return (error); 582 } 583 584 if ((error = bhnd_alloc_pmu(sc->sc_dev))) { 585 bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, 586 sc->sc_mem_rid, sc->sc_mem_res); 587 return (error); 588 } 589 590 /* Retain references to all required bus service providers */ 591 if ((error = bwn_retain_bus_providers(sc))) 592 goto fail; 593 594 /* Fetch mask of available antennas */ 595 error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA2G, 596 &sc->sc_ant2g); 597 if (error) { 598 device_printf(sc->sc_dev, "error determining 2GHz antenna " 599 "availability from NVRAM: %d\n", error); 600 goto fail; 601 } 602 603 error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA5G, 604 &sc->sc_ant5g); 605 if (error) { 606 device_printf(sc->sc_dev, "error determining 5GHz antenna " 607 "availability from NVRAM: %d\n", error); 608 goto fail; 609 } 610 611 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { 612 bwn_attach_pre(sc); 613 bwn_sprom_bugfixes(dev); 614 sc->sc_flags |= BWN_FLAG_ATTACHED; 615 } 616 617 mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO); 618 mac->mac_sc = sc; 619 mac->mac_status = BWN_MAC_STATUS_UNINIT; 620 if (bwn_bfp != 0) 621 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP; 622 623 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac); 624 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac); 625 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac); 626 627 error = bwn_attach_core(mac); 628 if (error) 629 goto fail; 630 error = bwn_led_attach(mac); 631 if (error) 632 goto fail; 633 634 bhnd_format_chip_id(chip_name, sizeof(chip_name), sc->sc_cid.chip_id); 635 device_printf(sc->sc_dev, "WLAN (%s rev %u) " 636 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", 637 chip_name, bhnd_get_hwrev(sc->sc_dev), mac->mac_phy.analog, 638 mac->mac_phy.type, mac->mac_phy.rev, mac->mac_phy.rf_manuf, 639 mac->mac_phy.rf_ver, mac->mac_phy.rf_rev); 640 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 641 device_printf(sc->sc_dev, "DMA (%d bits)\n", mac->mac_dmatype); 642 else 643 device_printf(sc->sc_dev, "PIO\n"); 644 645 #ifdef BWN_GPL_PHY 646 device_printf(sc->sc_dev, 647 "Note: compiled with BWN_GPL_PHY; includes GPLv2 code\n"); 648 #endif 649 650 mac->mac_rid_irq = 0; 651 mac->mac_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 652 &mac->mac_rid_irq, RF_ACTIVE | RF_SHAREABLE); 653 654 if (mac->mac_res_irq == NULL) { 655 device_printf(sc->sc_dev, "couldn't allocate IRQ resource\n"); 656 error = ENXIO; 657 goto fail; 658 } 659 660 error = bus_setup_intr(dev, mac->mac_res_irq, 661 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, 662 &mac->mac_intrhand); 663 if (error != 0) { 664 device_printf(sc->sc_dev, "couldn't setup interrupt (%d)\n", 665 error); 666 goto fail; 667 } 668 669 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); 670 671 /* 672 * calls attach-post routine 673 */ 674 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0) 675 bwn_attach_post(sc); 676 677 return (0); 678 fail: 679 if (mac != NULL && mac->mac_res_irq != NULL) { 680 bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq, 681 mac->mac_res_irq); 682 } 683 684 free(mac, M_DEVBUF); 685 bhnd_release_pmu(dev); 686 bwn_release_bus_providers(sc); 687 688 if (sc->sc_mem_res != NULL) { 689 bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, 690 sc->sc_mem_rid, sc->sc_mem_res); 691 } 692 693 return (error); 694 } 695 696 static int 697 bwn_retain_bus_providers(struct bwn_softc *sc) 698 { 699 struct chipc_caps *ccaps; 700 701 sc->sc_chipc = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_CHIPC); 702 if (sc->sc_chipc == NULL) { 703 device_printf(sc->sc_dev, "ChipCommon device not found\n"); 704 goto failed; 705 } 706 707 ccaps = BHND_CHIPC_GET_CAPS(sc->sc_chipc); 708 709 sc->sc_gpio = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_GPIO); 710 if (sc->sc_gpio == NULL) { 711 device_printf(sc->sc_dev, "GPIO device not found\n"); 712 goto failed; 713 } 714 715 if (ccaps->pmu) { 716 sc->sc_pmu = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_PMU); 717 if (sc->sc_pmu == NULL) { 718 device_printf(sc->sc_dev, "PMU device not found\n"); 719 goto failed; 720 } 721 } 722 723 return (0); 724 725 failed: 726 bwn_release_bus_providers(sc); 727 return (ENXIO); 728 } 729 730 static void 731 bwn_release_bus_providers(struct bwn_softc *sc) 732 { 733 #define BWN_RELEASE_PROV(_sc, _prov, _service) do { \ 734 if ((_sc)-> _prov != NULL) { \ 735 bhnd_release_provider((_sc)->sc_dev, (_sc)-> _prov, \ 736 (_service)); \ 737 (_sc)-> _prov = NULL; \ 738 } \ 739 } while (0) 740 741 BWN_RELEASE_PROV(sc, sc_chipc, BHND_SERVICE_CHIPC); 742 BWN_RELEASE_PROV(sc, sc_gpio, BHND_SERVICE_GPIO); 743 BWN_RELEASE_PROV(sc, sc_pmu, BHND_SERVICE_PMU); 744 745 #undef BWN_RELEASE_PROV 746 } 747 748 static int 749 bwn_attach_post(struct bwn_softc *sc) 750 { 751 struct ieee80211com *ic; 752 const char *mac_varname; 753 u_int core_unit; 754 int error; 755 756 ic = &sc->sc_ic; 757 758 ic->ic_softc = sc; 759 ic->ic_name = device_get_nameunit(sc->sc_dev); 760 /* XXX not right but it's not used anywhere important */ 761 ic->ic_phytype = IEEE80211_T_OFDM; 762 ic->ic_opmode = IEEE80211_M_STA; 763 ic->ic_caps = 764 IEEE80211_C_STA /* station mode supported */ 765 | IEEE80211_C_MONITOR /* monitor mode */ 766 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 767 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 768 | IEEE80211_C_SHSLOT /* short slot time supported */ 769 | IEEE80211_C_WME /* WME/WMM supported */ 770 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 771 #if 0 772 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 773 #endif 774 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 775 ; 776 777 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ 778 779 /* Determine the NVRAM variable containing our MAC address */ 780 core_unit = bhnd_get_core_unit(sc->sc_dev); 781 mac_varname = NULL; 782 if (sc->sc_board_info.board_srom_rev <= 2) { 783 if (core_unit == 0) { 784 mac_varname = BHND_NVAR_IL0MACADDR; 785 } else if (core_unit == 1) { 786 mac_varname = BHND_NVAR_ET1MACADDR; 787 } 788 } else { 789 if (core_unit == 0) { 790 mac_varname = BHND_NVAR_MACADDR; 791 } 792 } 793 794 if (mac_varname == NULL) { 795 device_printf(sc->sc_dev, "missing MAC address variable for " 796 "D11 core %u", core_unit); 797 return (ENXIO); 798 } 799 800 /* Read the MAC address from NVRAM */ 801 error = bhnd_nvram_getvar_array(sc->sc_dev, mac_varname, ic->ic_macaddr, 802 sizeof(ic->ic_macaddr), BHND_NVRAM_TYPE_UINT8_ARRAY); 803 if (error) { 804 device_printf(sc->sc_dev, "error reading %s: %d\n", mac_varname, 805 error); 806 return (error); 807 } 808 809 /* call MI attach routine. */ 810 ieee80211_ifattach(ic); 811 812 ic->ic_headroom = sizeof(struct bwn_txhdr); 813 814 /* override default methods */ 815 ic->ic_raw_xmit = bwn_raw_xmit; 816 ic->ic_updateslot = bwn_updateslot; 817 ic->ic_update_promisc = bwn_update_promisc; 818 ic->ic_wme.wme_update = bwn_wme_update; 819 ic->ic_scan_start = bwn_scan_start; 820 ic->ic_scan_end = bwn_scan_end; 821 ic->ic_set_channel = bwn_set_channel; 822 ic->ic_vap_create = bwn_vap_create; 823 ic->ic_vap_delete = bwn_vap_delete; 824 ic->ic_transmit = bwn_transmit; 825 ic->ic_parent = bwn_parent; 826 827 ieee80211_radiotap_attach(ic, 828 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 829 BWN_TX_RADIOTAP_PRESENT, 830 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 831 BWN_RX_RADIOTAP_PRESENT); 832 833 bwn_sysctl_node(sc); 834 835 if (bootverbose) 836 ieee80211_announce(ic); 837 return (0); 838 } 839 840 static void 841 bwn_phy_detach(struct bwn_mac *mac) 842 { 843 844 if (mac->mac_phy.detach != NULL) 845 mac->mac_phy.detach(mac); 846 } 847 848 static int 849 bwn_detach(device_t dev) 850 { 851 struct bwn_softc *sc = device_get_softc(dev); 852 struct bwn_mac *mac = sc->sc_curmac; 853 struct ieee80211com *ic = &sc->sc_ic; 854 855 sc->sc_flags |= BWN_FLAG_INVALID; 856 857 if (device_is_attached(sc->sc_dev)) { 858 BWN_LOCK(sc); 859 bwn_stop(sc); 860 BWN_UNLOCK(sc); 861 bwn_dma_free(mac); 862 callout_drain(&sc->sc_led_blink_ch); 863 callout_drain(&sc->sc_rfswitch_ch); 864 callout_drain(&sc->sc_task_ch); 865 callout_drain(&sc->sc_watchdog_ch); 866 bwn_phy_detach(mac); 867 ieee80211_draintask(ic, &mac->mac_hwreset); 868 ieee80211_draintask(ic, &mac->mac_txpower); 869 ieee80211_ifdetach(ic); 870 } 871 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); 872 taskqueue_free(sc->sc_tq); 873 874 if (mac->mac_intrhand != NULL) { 875 bus_teardown_intr(dev, mac->mac_res_irq, mac->mac_intrhand); 876 mac->mac_intrhand = NULL; 877 } 878 879 bhnd_release_pmu(dev); 880 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, 881 sc->sc_mem_res); 882 bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq, 883 mac->mac_res_irq); 884 mbufq_drain(&sc->sc_snd); 885 bwn_release_firmware(mac); 886 BWN_LOCK_DESTROY(sc); 887 888 bwn_release_bus_providers(sc); 889 890 return (0); 891 } 892 893 static void 894 bwn_attach_pre(struct bwn_softc *sc) 895 { 896 897 BWN_LOCK_INIT(sc); 898 TAILQ_INIT(&sc->sc_maclist); 899 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); 900 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); 901 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); 902 mbufq_init(&sc->sc_snd, ifqmaxlen); 903 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, 904 taskqueue_thread_enqueue, &sc->sc_tq); 905 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 906 "%s taskq", device_get_nameunit(sc->sc_dev)); 907 } 908 909 static void 910 bwn_sprom_bugfixes(device_t dev) 911 { 912 struct bwn_softc *sc = device_get_softc(dev); 913 914 #define BWN_ISDEV(_device, _subvendor, _subdevice) \ 915 ((sc->sc_board_info.board_devid == PCI_DEVID_##_device) && \ 916 (sc->sc_board_info.board_vendor == PCI_VENDOR_##_subvendor) && \ 917 (sc->sc_board_info.board_type == _subdevice)) 918 919 /* A subset of Apple Airport Extreme (BCM4306 rev 2) devices 920 * were programmed with a missing PACTRL boardflag */ 921 if (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE && 922 sc->sc_board_info.board_type == 0x4e && 923 sc->sc_board_info.board_rev > 0x40) 924 sc->sc_board_info.board_flags |= BHND_BFL_PACTRL; 925 926 if (BWN_ISDEV(BCM4318_D11G, ASUSTEK, 0x100f) || 927 BWN_ISDEV(BCM4306_D11G, DELL, 0x0003) || 928 BWN_ISDEV(BCM4306_D11G, HP, 0x12f8) || 929 BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0013) || 930 BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0014) || 931 BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0015) || 932 BWN_ISDEV(BCM4306_D11G, MOTOROLA, 0x7010)) 933 sc->sc_board_info.board_flags &= ~BHND_BFL_BTCOEX; 934 #undef BWN_ISDEV 935 } 936 937 static void 938 bwn_parent(struct ieee80211com *ic) 939 { 940 struct bwn_softc *sc = ic->ic_softc; 941 int startall = 0; 942 943 BWN_LOCK(sc); 944 if (ic->ic_nrunning > 0) { 945 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { 946 bwn_init(sc); 947 startall = 1; 948 } else 949 bwn_update_promisc(ic); 950 } else if (sc->sc_flags & BWN_FLAG_RUNNING) 951 bwn_stop(sc); 952 BWN_UNLOCK(sc); 953 954 if (startall) 955 ieee80211_start_all(ic); 956 } 957 958 static int 959 bwn_transmit(struct ieee80211com *ic, struct mbuf *m) 960 { 961 struct bwn_softc *sc = ic->ic_softc; 962 int error; 963 964 BWN_LOCK(sc); 965 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { 966 BWN_UNLOCK(sc); 967 return (ENXIO); 968 } 969 error = mbufq_enqueue(&sc->sc_snd, m); 970 if (error) { 971 BWN_UNLOCK(sc); 972 return (error); 973 } 974 bwn_start(sc); 975 BWN_UNLOCK(sc); 976 return (0); 977 } 978 979 static void 980 bwn_start(struct bwn_softc *sc) 981 { 982 struct bwn_mac *mac = sc->sc_curmac; 983 struct ieee80211_frame *wh; 984 struct ieee80211_node *ni; 985 struct ieee80211_key *k; 986 struct mbuf *m; 987 988 BWN_ASSERT_LOCKED(sc); 989 990 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL || 991 mac->mac_status < BWN_MAC_STATUS_STARTED) 992 return; 993 994 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 995 if (bwn_tx_isfull(sc, m)) 996 break; 997 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 998 if (ni == NULL) { 999 device_printf(sc->sc_dev, "unexpected NULL ni\n"); 1000 m_freem(m); 1001 counter_u64_add(sc->sc_ic.ic_oerrors, 1); 1002 continue; 1003 } 1004 wh = mtod(m, struct ieee80211_frame *); 1005 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1006 k = ieee80211_crypto_encap(ni, m); 1007 if (k == NULL) { 1008 if_inc_counter(ni->ni_vap->iv_ifp, 1009 IFCOUNTER_OERRORS, 1); 1010 ieee80211_free_node(ni); 1011 m_freem(m); 1012 continue; 1013 } 1014 } 1015 wh = NULL; /* Catch any invalid use */ 1016 if (bwn_tx_start(sc, ni, m) != 0) { 1017 if (ni != NULL) { 1018 if_inc_counter(ni->ni_vap->iv_ifp, 1019 IFCOUNTER_OERRORS, 1); 1020 ieee80211_free_node(ni); 1021 } 1022 continue; 1023 } 1024 sc->sc_watchdog_timer = 5; 1025 } 1026 } 1027 1028 static int 1029 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) 1030 { 1031 struct bwn_dma_ring *dr; 1032 struct bwn_mac *mac = sc->sc_curmac; 1033 struct bwn_pio_txqueue *tq; 1034 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1035 1036 BWN_ASSERT_LOCKED(sc); 1037 1038 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 1039 dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1040 if (dr->dr_stop == 1 || 1041 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) { 1042 dr->dr_stop = 1; 1043 goto full; 1044 } 1045 } else { 1046 tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1047 if (tq->tq_free == 0 || pktlen > tq->tq_size || 1048 pktlen > (tq->tq_size - tq->tq_used)) 1049 goto full; 1050 } 1051 return (0); 1052 full: 1053 mbufq_prepend(&sc->sc_snd, m); 1054 return (1); 1055 } 1056 1057 static int 1058 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) 1059 { 1060 struct bwn_mac *mac = sc->sc_curmac; 1061 int error; 1062 1063 BWN_ASSERT_LOCKED(sc); 1064 1065 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) { 1066 m_freem(m); 1067 return (ENXIO); 1068 } 1069 1070 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? 1071 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m); 1072 if (error) { 1073 m_freem(m); 1074 return (error); 1075 } 1076 return (0); 1077 } 1078 1079 static int 1080 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1081 { 1082 struct bwn_pio_txpkt *tp; 1083 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m)); 1084 struct bwn_softc *sc = mac->mac_sc; 1085 struct bwn_txhdr txhdr; 1086 struct mbuf *m_new; 1087 uint32_t ctl32; 1088 int error; 1089 uint16_t ctl16; 1090 1091 BWN_ASSERT_LOCKED(sc); 1092 1093 /* XXX TODO send packets after DTIM */ 1094 1095 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__)); 1096 tp = TAILQ_FIRST(&tq->tq_pktlist); 1097 tp->tp_ni = ni; 1098 tp->tp_m = m; 1099 1100 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp)); 1101 if (error) { 1102 device_printf(sc->sc_dev, "tx fail\n"); 1103 return (error); 1104 } 1105 1106 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list); 1107 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 1108 tq->tq_free--; 1109 1110 if (bhnd_get_hwrev(sc->sc_dev) >= 8) { 1111 /* 1112 * XXX please removes m_defrag(9) 1113 */ 1114 m_new = m_defrag(m, M_NOWAIT); 1115 if (m_new == NULL) { 1116 device_printf(sc->sc_dev, 1117 "%s: can't defrag TX buffer\n", 1118 __func__); 1119 return (ENOBUFS); 1120 } 1121 if (m_new->m_next != NULL) 1122 device_printf(sc->sc_dev, 1123 "TODO: fragmented packets for PIO\n"); 1124 tp->tp_m = m_new; 1125 1126 /* send HEADER */ 1127 ctl32 = bwn_pio_write_multi_4(mac, tq, 1128 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) | 1129 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF, 1130 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1131 /* send BODY */ 1132 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32, 1133 mtod(m_new, const void *), m_new->m_pkthdr.len); 1134 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL, 1135 ctl32 | BWN_PIO8_TXCTL_EOF); 1136 } else { 1137 ctl16 = bwn_pio_write_multi_2(mac, tq, 1138 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) | 1139 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF, 1140 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac)); 1141 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m); 1142 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, 1143 ctl16 | BWN_PIO_TXCTL_EOF); 1144 } 1145 1146 return (0); 1147 } 1148 1149 static struct bwn_pio_txqueue * 1150 bwn_pio_select(struct bwn_mac *mac, uint8_t prio) 1151 { 1152 1153 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 1154 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1155 1156 switch (prio) { 1157 case 0: 1158 return (&mac->mac_method.pio.wme[WME_AC_BE]); 1159 case 1: 1160 return (&mac->mac_method.pio.wme[WME_AC_BK]); 1161 case 2: 1162 return (&mac->mac_method.pio.wme[WME_AC_VI]); 1163 case 3: 1164 return (&mac->mac_method.pio.wme[WME_AC_VO]); 1165 } 1166 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1167 return (NULL); 1168 } 1169 1170 static int 1171 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) 1172 { 1173 #define BWN_GET_TXHDRCACHE(slot) \ 1174 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)]) 1175 struct bwn_dma *dma = &mac->mac_method.dma; 1176 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m)); 1177 struct bwn_dmadesc_generic *desc; 1178 struct bwn_dmadesc_meta *mt; 1179 struct bwn_softc *sc = mac->mac_sc; 1180 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; 1181 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; 1182 1183 BWN_ASSERT_LOCKED(sc); 1184 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__)); 1185 1186 /* XXX send after DTIM */ 1187 1188 slot = bwn_dma_getslot(dr); 1189 dr->getdesc(dr, slot, &desc, &mt); 1190 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER, 1191 ("%s:%d: fail", __func__, __LINE__)); 1192 1193 error = bwn_set_txhdr(dr->dr_mac, ni, m, 1194 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot), 1195 BWN_DMA_COOKIE(dr, slot)); 1196 if (error) 1197 goto fail; 1198 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap, 1199 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, 1200 &mt->mt_paddr, BUS_DMA_NOWAIT); 1201 if (error) { 1202 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", 1203 __func__, error); 1204 goto fail; 1205 } 1206 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap, 1207 BUS_DMASYNC_PREWRITE); 1208 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0); 1209 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1210 BUS_DMASYNC_PREWRITE); 1211 1212 slot = bwn_dma_getslot(dr); 1213 dr->getdesc(dr, slot, &desc, &mt); 1214 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY && 1215 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__)); 1216 mt->mt_m = m; 1217 mt->mt_ni = ni; 1218 1219 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, 1220 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1221 if (error && error != EFBIG) { 1222 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", 1223 __func__, error); 1224 goto fail; 1225 } 1226 if (error) { /* error == EFBIG */ 1227 struct mbuf *m_new; 1228 1229 m_new = m_defrag(m, M_NOWAIT); 1230 if (m_new == NULL) { 1231 device_printf(sc->sc_dev, 1232 "%s: can't defrag TX buffer\n", 1233 __func__); 1234 error = ENOBUFS; 1235 goto fail; 1236 } else { 1237 m = m_new; 1238 } 1239 1240 mt->mt_m = m; 1241 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, 1242 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); 1243 if (error) { 1244 device_printf(sc->sc_dev, 1245 "%s: can't load TX buffer (2) %d\n", 1246 __func__, error); 1247 goto fail; 1248 } 1249 } 1250 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE); 1251 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1); 1252 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 1253 BUS_DMASYNC_PREWRITE); 1254 1255 /* XXX send after DTIM */ 1256 1257 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot)); 1258 return (0); 1259 fail: 1260 dr->dr_curslot = backup[0]; 1261 dr->dr_usedslot = backup[1]; 1262 return (error); 1263 #undef BWN_GET_TXHDRCACHE 1264 } 1265 1266 static void 1267 bwn_watchdog(void *arg) 1268 { 1269 struct bwn_softc *sc = arg; 1270 1271 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { 1272 device_printf(sc->sc_dev, "device timeout\n"); 1273 counter_u64_add(sc->sc_ic.ic_oerrors, 1); 1274 } 1275 callout_schedule(&sc->sc_watchdog_ch, hz); 1276 } 1277 1278 static int 1279 bwn_attach_core(struct bwn_mac *mac) 1280 { 1281 struct bwn_softc *sc = mac->mac_sc; 1282 int error, have_bg = 0, have_a = 0; 1283 uint16_t iost; 1284 1285 KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 5, 1286 ("unsupported revision %d", bhnd_get_hwrev(sc->sc_dev))); 1287 1288 if ((error = bwn_core_forceclk(mac, true))) 1289 return (error); 1290 1291 if ((error = bhnd_read_iost(sc->sc_dev, &iost))) { 1292 device_printf(sc->sc_dev, "error reading I/O status flags: " 1293 "%d\n", error); 1294 return (error); 1295 } 1296 1297 have_a = (iost & BWN_IOST_HAVE_5GHZ) ? 1 : 0; 1298 have_bg = (iost & BWN_IOST_HAVE_2GHZ) ? 1 : 0; 1299 if (iost & BWN_IOST_DUALPHY) { 1300 have_bg = 1; 1301 have_a = 1; 1302 } 1303 1304 1305 #if 0 1306 device_printf(sc->sc_dev, "%s: iost=0x%04hx, have_a=%d, have_bg=%d," 1307 " deviceid=0x%04x, siba_deviceid=0x%04x\n", 1308 __func__, 1309 iost, 1310 have_a, 1311 have_bg, 1312 sc->sc_board_info.board_devid, 1313 sc->sc_cid.chip_id); 1314 #endif 1315 1316 /* 1317 * Guess at whether it has A-PHY or G-PHY. 1318 * This is just used for resetting the core to probe things; 1319 * we will re-guess once it's all up and working. 1320 */ 1321 error = bwn_reset_core(mac, have_bg); 1322 if (error) 1323 goto fail; 1324 1325 /* 1326 * Determine the DMA engine type 1327 */ 1328 if (iost & BHND_IOST_DMA64) { 1329 mac->mac_dmatype = BHND_DMA_ADDR_64BIT; 1330 } else { 1331 uint32_t tmp; 1332 uint16_t base; 1333 1334 base = bwn_dma_base(0, 0); 1335 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, 1336 BWN_DMA32_TXADDREXT_MASK); 1337 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 1338 if (tmp & BWN_DMA32_TXADDREXT_MASK) { 1339 mac->mac_dmatype = BHND_DMA_ADDR_32BIT; 1340 } else { 1341 mac->mac_dmatype = BHND_DMA_ADDR_30BIT; 1342 } 1343 } 1344 1345 /* 1346 * Get the PHY version. 1347 */ 1348 error = bwn_phy_getinfo(mac, have_bg); 1349 if (error) 1350 goto fail; 1351 1352 /* 1353 * This is the whitelist of devices which we "believe" 1354 * the SPROM PHY config from. The rest are "guessed". 1355 */ 1356 if (sc->sc_board_info.board_devid != PCI_DEVID_BCM4311_D11DUAL && 1357 sc->sc_board_info.board_devid != PCI_DEVID_BCM4328_D11G && 1358 sc->sc_board_info.board_devid != PCI_DEVID_BCM4318_D11DUAL && 1359 sc->sc_board_info.board_devid != PCI_DEVID_BCM4306_D11DUAL && 1360 sc->sc_board_info.board_devid != PCI_DEVID_BCM4321_D11N && 1361 sc->sc_board_info.board_devid != PCI_DEVID_BCM4322_D11N) { 1362 have_a = have_bg = 0; 1363 if (mac->mac_phy.type == BWN_PHYTYPE_A) 1364 have_a = 1; 1365 else if (mac->mac_phy.type == BWN_PHYTYPE_G || 1366 mac->mac_phy.type == BWN_PHYTYPE_N || 1367 mac->mac_phy.type == BWN_PHYTYPE_LP) 1368 have_bg = 1; 1369 else 1370 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__, 1371 mac->mac_phy.type)); 1372 } 1373 1374 /* 1375 * XXX The PHY-G support doesn't do 5GHz operation. 1376 */ 1377 if (mac->mac_phy.type != BWN_PHYTYPE_LP && 1378 mac->mac_phy.type != BWN_PHYTYPE_N) { 1379 device_printf(sc->sc_dev, 1380 "%s: forcing 2GHz only; no dual-band support for PHY\n", 1381 __func__); 1382 have_a = 0; 1383 have_bg = 1; 1384 } 1385 1386 mac->mac_phy.phy_n = NULL; 1387 1388 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 1389 mac->mac_phy.attach = bwn_phy_g_attach; 1390 mac->mac_phy.detach = bwn_phy_g_detach; 1391 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw; 1392 mac->mac_phy.init_pre = bwn_phy_g_init_pre; 1393 mac->mac_phy.init = bwn_phy_g_init; 1394 mac->mac_phy.exit = bwn_phy_g_exit; 1395 mac->mac_phy.phy_read = bwn_phy_g_read; 1396 mac->mac_phy.phy_write = bwn_phy_g_write; 1397 mac->mac_phy.rf_read = bwn_phy_g_rf_read; 1398 mac->mac_phy.rf_write = bwn_phy_g_rf_write; 1399 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl; 1400 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff; 1401 mac->mac_phy.switch_analog = bwn_phy_switch_analog; 1402 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel; 1403 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan; 1404 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna; 1405 mac->mac_phy.set_im = bwn_phy_g_im; 1406 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr; 1407 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr; 1408 mac->mac_phy.task_15s = bwn_phy_g_task_15s; 1409 mac->mac_phy.task_60s = bwn_phy_g_task_60s; 1410 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) { 1411 mac->mac_phy.init_pre = bwn_phy_lp_init_pre; 1412 mac->mac_phy.init = bwn_phy_lp_init; 1413 mac->mac_phy.phy_read = bwn_phy_lp_read; 1414 mac->mac_phy.phy_write = bwn_phy_lp_write; 1415 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset; 1416 mac->mac_phy.rf_read = bwn_phy_lp_rf_read; 1417 mac->mac_phy.rf_write = bwn_phy_lp_rf_write; 1418 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff; 1419 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog; 1420 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel; 1421 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan; 1422 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna; 1423 mac->mac_phy.task_60s = bwn_phy_lp_task_60s; 1424 } else if (mac->mac_phy.type == BWN_PHYTYPE_N) { 1425 mac->mac_phy.attach = bwn_phy_n_attach; 1426 mac->mac_phy.detach = bwn_phy_n_detach; 1427 mac->mac_phy.prepare_hw = bwn_phy_n_prepare_hw; 1428 mac->mac_phy.init_pre = bwn_phy_n_init_pre; 1429 mac->mac_phy.init = bwn_phy_n_init; 1430 mac->mac_phy.exit = bwn_phy_n_exit; 1431 mac->mac_phy.phy_read = bwn_phy_n_read; 1432 mac->mac_phy.phy_write = bwn_phy_n_write; 1433 mac->mac_phy.rf_read = bwn_phy_n_rf_read; 1434 mac->mac_phy.rf_write = bwn_phy_n_rf_write; 1435 mac->mac_phy.use_hwpctl = bwn_phy_n_hwpctl; 1436 mac->mac_phy.rf_onoff = bwn_phy_n_rf_onoff; 1437 mac->mac_phy.switch_analog = bwn_phy_n_switch_analog; 1438 mac->mac_phy.switch_channel = bwn_phy_n_switch_channel; 1439 mac->mac_phy.get_default_chan = bwn_phy_n_get_default_chan; 1440 mac->mac_phy.set_antenna = bwn_phy_n_set_antenna; 1441 mac->mac_phy.set_im = bwn_phy_n_im; 1442 mac->mac_phy.recalc_txpwr = bwn_phy_n_recalc_txpwr; 1443 mac->mac_phy.set_txpwr = bwn_phy_n_set_txpwr; 1444 mac->mac_phy.task_15s = bwn_phy_n_task_15s; 1445 mac->mac_phy.task_60s = bwn_phy_n_task_60s; 1446 } else { 1447 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n", 1448 mac->mac_phy.type); 1449 error = ENXIO; 1450 goto fail; 1451 } 1452 1453 mac->mac_phy.gmode = have_bg; 1454 if (mac->mac_phy.attach != NULL) { 1455 error = mac->mac_phy.attach(mac); 1456 if (error) { 1457 device_printf(sc->sc_dev, "failed\n"); 1458 goto fail; 1459 } 1460 } 1461 1462 error = bwn_reset_core(mac, have_bg); 1463 if (error) 1464 goto fail; 1465 1466 error = bwn_chiptest(mac); 1467 if (error) 1468 goto fail; 1469 error = bwn_setup_channels(mac, have_bg, have_a); 1470 if (error) { 1471 device_printf(sc->sc_dev, "failed to setup channels\n"); 1472 goto fail; 1473 } 1474 1475 if (sc->sc_curmac == NULL) 1476 sc->sc_curmac = mac; 1477 1478 error = bwn_dma_attach(mac); 1479 if (error != 0) { 1480 device_printf(sc->sc_dev, "failed to initialize DMA\n"); 1481 goto fail; 1482 } 1483 1484 mac->mac_phy.switch_analog(mac, 0); 1485 1486 fail: 1487 bhnd_suspend_hw(sc->sc_dev, 0); 1488 bwn_release_firmware(mac); 1489 return (error); 1490 } 1491 1492 /* 1493 * Reset 1494 */ 1495 int 1496 bwn_reset_core(struct bwn_mac *mac, int g_mode) 1497 { 1498 struct bwn_softc *sc; 1499 uint32_t ctl; 1500 uint16_t ioctl, ioctl_mask; 1501 int error; 1502 1503 sc = mac->mac_sc; 1504 1505 DPRINTF(sc, BWN_DEBUG_RESET, "%s: g_mode=%d\n", __func__, g_mode); 1506 1507 /* Reset core */ 1508 ioctl = (BWN_IOCTL_PHYCLOCK_ENABLE | BWN_IOCTL_PHYRESET); 1509 if (g_mode) 1510 ioctl |= BWN_IOCTL_SUPPORT_G; 1511 1512 /* XXX N-PHY only; and hard-code to 20MHz for now */ 1513 if (mac->mac_phy.type == BWN_PHYTYPE_N) 1514 ioctl |= BWN_IOCTL_PHY_BANDWIDTH_20MHZ; 1515 1516 if ((error = bhnd_reset_hw(sc->sc_dev, ioctl, ioctl))) { 1517 device_printf(sc->sc_dev, "core reset failed: %d", error); 1518 return (error); 1519 } 1520 1521 DELAY(2000); 1522 1523 /* Take PHY out of reset */ 1524 ioctl = BHND_IOCTL_CLK_FORCE; 1525 ioctl_mask = BHND_IOCTL_CLK_FORCE | 1526 BWN_IOCTL_PHYRESET | 1527 BWN_IOCTL_PHYCLOCK_ENABLE; 1528 1529 if ((error = bhnd_write_ioctl(sc->sc_dev, ioctl, ioctl_mask))) { 1530 device_printf(sc->sc_dev, "failed to set core ioctl flags: " 1531 "%d\n", error); 1532 return (error); 1533 } 1534 1535 DELAY(2000); 1536 1537 ioctl = BWN_IOCTL_PHYCLOCK_ENABLE; 1538 if ((error = bhnd_write_ioctl(sc->sc_dev, ioctl, ioctl_mask))) { 1539 device_printf(sc->sc_dev, "failed to set core ioctl flags: " 1540 "%d\n", error); 1541 return (error); 1542 } 1543 1544 DELAY(2000); 1545 1546 if (mac->mac_phy.switch_analog != NULL) 1547 mac->mac_phy.switch_analog(mac, 1); 1548 1549 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE; 1550 if (g_mode) 1551 ctl |= BWN_MACCTL_GMODE; 1552 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON); 1553 1554 return (0); 1555 } 1556 1557 static int 1558 bwn_phy_getinfo(struct bwn_mac *mac, int gmode) 1559 { 1560 struct bwn_phy *phy = &mac->mac_phy; 1561 struct bwn_softc *sc = mac->mac_sc; 1562 uint32_t tmp; 1563 1564 /* PHY */ 1565 tmp = BWN_READ_2(mac, BWN_PHYVER); 1566 phy->gmode = gmode; 1567 phy->rf_on = 1; 1568 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12; 1569 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8; 1570 phy->rev = (tmp & BWN_PHYVER_VERSION); 1571 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) || 1572 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 && 1573 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) || 1574 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) || 1575 (phy->type == BWN_PHYTYPE_N && phy->rev > 6) || 1576 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2)) 1577 goto unsupphy; 1578 1579 /* RADIO */ 1580 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1581 tmp = BWN_READ_2(mac, BWN_RFDATALO); 1582 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID); 1583 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16; 1584 1585 phy->rf_rev = (tmp & 0xf0000000) >> 28; 1586 phy->rf_ver = (tmp & 0x0ffff000) >> 12; 1587 phy->rf_manuf = (tmp & 0x00000fff); 1588 1589 /* 1590 * For now, just always do full init (ie, what bwn has traditionally 1591 * done) 1592 */ 1593 phy->phy_do_full_init = 1; 1594 1595 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */ 1596 goto unsupradio; 1597 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 || 1598 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) || 1599 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) || 1600 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) || 1601 (phy->type == BWN_PHYTYPE_N && 1602 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) || 1603 (phy->type == BWN_PHYTYPE_LP && 1604 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063)) 1605 goto unsupradio; 1606 1607 return (0); 1608 unsupphy: 1609 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, " 1610 "analog %#x)\n", 1611 phy->type, phy->rev, phy->analog); 1612 return (ENXIO); 1613 unsupradio: 1614 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, " 1615 "rev %#x)\n", 1616 phy->rf_manuf, phy->rf_ver, phy->rf_rev); 1617 return (ENXIO); 1618 } 1619 1620 static int 1621 bwn_chiptest(struct bwn_mac *mac) 1622 { 1623 #define TESTVAL0 0x55aaaa55 1624 #define TESTVAL1 0xaa5555aa 1625 struct bwn_softc *sc = mac->mac_sc; 1626 uint32_t v, backup; 1627 1628 BWN_LOCK(sc); 1629 1630 backup = bwn_shm_read_4(mac, BWN_SHARED, 0); 1631 1632 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0); 1633 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0) 1634 goto error; 1635 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1); 1636 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1) 1637 goto error; 1638 1639 bwn_shm_write_4(mac, BWN_SHARED, 0, backup); 1640 1641 if ((bhnd_get_hwrev(sc->sc_dev) >= 3) && 1642 (bhnd_get_hwrev(sc->sc_dev) <= 10)) { 1643 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa); 1644 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb); 1645 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb) 1646 goto error; 1647 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc) 1648 goto error; 1649 } 1650 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0); 1651 1652 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE; 1653 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON)) 1654 goto error; 1655 1656 BWN_UNLOCK(sc); 1657 return (0); 1658 error: 1659 BWN_UNLOCK(sc); 1660 device_printf(sc->sc_dev, "failed to validate the chipaccess\n"); 1661 return (ENODEV); 1662 } 1663 1664 static int 1665 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) 1666 { 1667 struct bwn_softc *sc = mac->mac_sc; 1668 struct ieee80211com *ic = &sc->sc_ic; 1669 uint8_t bands[IEEE80211_MODE_BYTES]; 1670 1671 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 1672 ic->ic_nchans = 0; 1673 1674 DPRINTF(sc, BWN_DEBUG_EEPROM, "%s: called; bg=%d, a=%d\n", 1675 __func__, 1676 have_bg, 1677 have_a); 1678 1679 if (have_bg) { 1680 memset(bands, 0, sizeof(bands)); 1681 setbit(bands, IEEE80211_MODE_11B); 1682 setbit(bands, IEEE80211_MODE_11G); 1683 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1684 &ic->ic_nchans, &bwn_chantable_bg, bands); 1685 } 1686 1687 if (have_a) { 1688 memset(bands, 0, sizeof(bands)); 1689 setbit(bands, IEEE80211_MODE_11A); 1690 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX, 1691 &ic->ic_nchans, &bwn_chantable_a, bands); 1692 } 1693 1694 mac->mac_phy.supports_2ghz = have_bg; 1695 mac->mac_phy.supports_5ghz = have_a; 1696 1697 return (ic->ic_nchans == 0 ? ENXIO : 0); 1698 } 1699 1700 uint32_t 1701 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1702 { 1703 uint32_t ret; 1704 1705 BWN_ASSERT_LOCKED(mac->mac_sc); 1706 1707 if (way == BWN_SHARED) { 1708 KASSERT((offset & 0x0001) == 0, 1709 ("%s:%d warn", __func__, __LINE__)); 1710 if (offset & 0x0003) { 1711 bwn_shm_ctlword(mac, way, offset >> 2); 1712 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1713 ret <<= 16; 1714 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1715 ret |= BWN_READ_2(mac, BWN_SHM_DATA); 1716 goto out; 1717 } 1718 offset >>= 2; 1719 } 1720 bwn_shm_ctlword(mac, way, offset); 1721 ret = BWN_READ_4(mac, BWN_SHM_DATA); 1722 out: 1723 return (ret); 1724 } 1725 1726 uint16_t 1727 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset) 1728 { 1729 uint16_t ret; 1730 1731 BWN_ASSERT_LOCKED(mac->mac_sc); 1732 1733 if (way == BWN_SHARED) { 1734 KASSERT((offset & 0x0001) == 0, 1735 ("%s:%d warn", __func__, __LINE__)); 1736 if (offset & 0x0003) { 1737 bwn_shm_ctlword(mac, way, offset >> 2); 1738 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED); 1739 goto out; 1740 } 1741 offset >>= 2; 1742 } 1743 bwn_shm_ctlword(mac, way, offset); 1744 ret = BWN_READ_2(mac, BWN_SHM_DATA); 1745 out: 1746 1747 return (ret); 1748 } 1749 1750 static void 1751 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way, 1752 uint16_t offset) 1753 { 1754 uint32_t control; 1755 1756 control = way; 1757 control <<= 16; 1758 control |= offset; 1759 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control); 1760 } 1761 1762 void 1763 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1764 uint32_t value) 1765 { 1766 BWN_ASSERT_LOCKED(mac->mac_sc); 1767 1768 if (way == BWN_SHARED) { 1769 KASSERT((offset & 0x0001) == 0, 1770 ("%s:%d warn", __func__, __LINE__)); 1771 if (offset & 0x0003) { 1772 bwn_shm_ctlword(mac, way, offset >> 2); 1773 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, 1774 (value >> 16) & 0xffff); 1775 bwn_shm_ctlword(mac, way, (offset >> 2) + 1); 1776 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff); 1777 return; 1778 } 1779 offset >>= 2; 1780 } 1781 bwn_shm_ctlword(mac, way, offset); 1782 BWN_WRITE_4(mac, BWN_SHM_DATA, value); 1783 } 1784 1785 void 1786 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset, 1787 uint16_t value) 1788 { 1789 BWN_ASSERT_LOCKED(mac->mac_sc); 1790 1791 if (way == BWN_SHARED) { 1792 KASSERT((offset & 0x0001) == 0, 1793 ("%s:%d warn", __func__, __LINE__)); 1794 if (offset & 0x0003) { 1795 bwn_shm_ctlword(mac, way, offset >> 2); 1796 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value); 1797 return; 1798 } 1799 offset >>= 2; 1800 } 1801 bwn_shm_ctlword(mac, way, offset); 1802 BWN_WRITE_2(mac, BWN_SHM_DATA, value); 1803 } 1804 1805 static void 1806 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 1807 const struct bwn_channelinfo *ci, const uint8_t bands[]) 1808 { 1809 int i, error; 1810 1811 for (i = 0, error = 0; i < ci->nchannels && error == 0; i++) { 1812 const struct bwn_channel *hc = &ci->channels[i]; 1813 1814 error = ieee80211_add_channel(chans, maxchans, nchans, 1815 hc->ieee, hc->freq, hc->maxTxPow, 0, bands); 1816 } 1817 } 1818 1819 static int 1820 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 1821 const struct ieee80211_bpf_params *params) 1822 { 1823 struct ieee80211com *ic = ni->ni_ic; 1824 struct bwn_softc *sc = ic->ic_softc; 1825 struct bwn_mac *mac = sc->sc_curmac; 1826 int error; 1827 1828 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || 1829 mac->mac_status < BWN_MAC_STATUS_STARTED) { 1830 m_freem(m); 1831 return (ENETDOWN); 1832 } 1833 1834 BWN_LOCK(sc); 1835 if (bwn_tx_isfull(sc, m)) { 1836 m_freem(m); 1837 BWN_UNLOCK(sc); 1838 return (ENOBUFS); 1839 } 1840 1841 error = bwn_tx_start(sc, ni, m); 1842 if (error == 0) 1843 sc->sc_watchdog_timer = 5; 1844 BWN_UNLOCK(sc); 1845 return (error); 1846 } 1847 1848 /* 1849 * Callback from the 802.11 layer to update the slot time 1850 * based on the current setting. We use it to notify the 1851 * firmware of ERP changes and the f/w takes care of things 1852 * like slot time and preamble. 1853 */ 1854 static void 1855 bwn_updateslot(struct ieee80211com *ic) 1856 { 1857 struct bwn_softc *sc = ic->ic_softc; 1858 struct bwn_mac *mac; 1859 1860 BWN_LOCK(sc); 1861 if (sc->sc_flags & BWN_FLAG_RUNNING) { 1862 mac = (struct bwn_mac *)sc->sc_curmac; 1863 bwn_set_slot_time(mac, IEEE80211_GET_SLOTTIME(ic)); 1864 } 1865 BWN_UNLOCK(sc); 1866 } 1867 1868 /* 1869 * Callback from the 802.11 layer after a promiscuous mode change. 1870 * Note this interface does not check the operating mode as this 1871 * is an internal callback and we are expected to honor the current 1872 * state (e.g. this is used for setting the interface in promiscuous 1873 * mode when operating in hostap mode to do ACS). 1874 */ 1875 static void 1876 bwn_update_promisc(struct ieee80211com *ic) 1877 { 1878 struct bwn_softc *sc = ic->ic_softc; 1879 struct bwn_mac *mac = sc->sc_curmac; 1880 1881 BWN_LOCK(sc); 1882 mac = sc->sc_curmac; 1883 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 1884 if (ic->ic_promisc > 0) 1885 sc->sc_filters |= BWN_MACCTL_PROMISC; 1886 else 1887 sc->sc_filters &= ~BWN_MACCTL_PROMISC; 1888 bwn_set_opmode(mac); 1889 } 1890 BWN_UNLOCK(sc); 1891 } 1892 1893 /* 1894 * Callback from the 802.11 layer to update WME parameters. 1895 */ 1896 static int 1897 bwn_wme_update(struct ieee80211com *ic) 1898 { 1899 struct bwn_softc *sc = ic->ic_softc; 1900 struct bwn_mac *mac = sc->sc_curmac; 1901 struct chanAccParams chp; 1902 struct wmeParams *wmep; 1903 int i; 1904 1905 ieee80211_wme_ic_getparams(ic, &chp); 1906 1907 BWN_LOCK(sc); 1908 mac = sc->sc_curmac; 1909 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 1910 bwn_mac_suspend(mac); 1911 for (i = 0; i < N(sc->sc_wmeParams); i++) { 1912 wmep = &chp.cap_wmeParams[i]; 1913 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]); 1914 } 1915 bwn_mac_enable(mac); 1916 } 1917 BWN_UNLOCK(sc); 1918 return (0); 1919 } 1920 1921 static void 1922 bwn_scan_start(struct ieee80211com *ic) 1923 { 1924 struct bwn_softc *sc = ic->ic_softc; 1925 struct bwn_mac *mac; 1926 1927 BWN_LOCK(sc); 1928 mac = sc->sc_curmac; 1929 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 1930 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC; 1931 bwn_set_opmode(mac); 1932 /* disable CFP update during scan */ 1933 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE); 1934 } 1935 BWN_UNLOCK(sc); 1936 } 1937 1938 static void 1939 bwn_scan_end(struct ieee80211com *ic) 1940 { 1941 struct bwn_softc *sc = ic->ic_softc; 1942 struct bwn_mac *mac; 1943 1944 BWN_LOCK(sc); 1945 mac = sc->sc_curmac; 1946 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { 1947 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC; 1948 bwn_set_opmode(mac); 1949 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE); 1950 } 1951 BWN_UNLOCK(sc); 1952 } 1953 1954 static void 1955 bwn_set_channel(struct ieee80211com *ic) 1956 { 1957 struct bwn_softc *sc = ic->ic_softc; 1958 struct bwn_mac *mac = sc->sc_curmac; 1959 struct bwn_phy *phy = &mac->mac_phy; 1960 int chan, error; 1961 1962 BWN_LOCK(sc); 1963 1964 error = bwn_switch_band(sc, ic->ic_curchan); 1965 if (error) 1966 goto fail; 1967 bwn_mac_suspend(mac); 1968 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 1969 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 1970 if (chan != phy->chan) 1971 bwn_switch_channel(mac, chan); 1972 1973 /* TX power level */ 1974 if (ic->ic_curchan->ic_maxpower != 0 && 1975 ic->ic_curchan->ic_maxpower != phy->txpower) { 1976 phy->txpower = ic->ic_curchan->ic_maxpower / 2; 1977 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME | 1978 BWN_TXPWR_IGNORE_TSSI); 1979 } 1980 1981 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 1982 if (phy->set_antenna) 1983 phy->set_antenna(mac, BWN_ANT_DEFAULT); 1984 1985 if (sc->sc_rf_enabled != phy->rf_on) { 1986 if (sc->sc_rf_enabled) { 1987 bwn_rf_turnon(mac); 1988 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)) 1989 device_printf(sc->sc_dev, 1990 "please turn on the RF switch\n"); 1991 } else 1992 bwn_rf_turnoff(mac); 1993 } 1994 1995 bwn_mac_enable(mac); 1996 1997 fail: 1998 /* 1999 * Setup radio tap channel freq and flags 2000 */ 2001 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = 2002 htole16(ic->ic_curchan->ic_freq); 2003 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = 2004 htole16(ic->ic_curchan->ic_flags & 0xffff); 2005 2006 BWN_UNLOCK(sc); 2007 } 2008 2009 static struct ieee80211vap * 2010 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2011 enum ieee80211_opmode opmode, int flags, 2012 const uint8_t bssid[IEEE80211_ADDR_LEN], 2013 const uint8_t mac[IEEE80211_ADDR_LEN]) 2014 { 2015 struct ieee80211vap *vap; 2016 struct bwn_vap *bvp; 2017 2018 switch (opmode) { 2019 case IEEE80211_M_HOSTAP: 2020 case IEEE80211_M_MBSS: 2021 case IEEE80211_M_STA: 2022 case IEEE80211_M_WDS: 2023 case IEEE80211_M_MONITOR: 2024 case IEEE80211_M_IBSS: 2025 case IEEE80211_M_AHDEMO: 2026 break; 2027 default: 2028 return (NULL); 2029 } 2030 2031 bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); 2032 vap = &bvp->bv_vap; 2033 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 2034 /* override with driver methods */ 2035 bvp->bv_newstate = vap->iv_newstate; 2036 vap->iv_newstate = bwn_newstate; 2037 2038 /* override max aid so sta's cannot assoc when we're out of sta id's */ 2039 vap->iv_max_aid = BWN_STAID_MAX; 2040 2041 ieee80211_ratectl_init(vap); 2042 2043 /* complete setup */ 2044 ieee80211_vap_attach(vap, ieee80211_media_change, 2045 ieee80211_media_status, mac); 2046 return (vap); 2047 } 2048 2049 static void 2050 bwn_vap_delete(struct ieee80211vap *vap) 2051 { 2052 struct bwn_vap *bvp = BWN_VAP(vap); 2053 2054 ieee80211_ratectl_deinit(vap); 2055 ieee80211_vap_detach(vap); 2056 free(bvp, M_80211_VAP); 2057 } 2058 2059 static int 2060 bwn_init(struct bwn_softc *sc) 2061 { 2062 struct bwn_mac *mac; 2063 int error; 2064 2065 BWN_ASSERT_LOCKED(sc); 2066 2067 DPRINTF(sc, BWN_DEBUG_RESET, "%s: called\n", __func__); 2068 2069 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN); 2070 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP; 2071 sc->sc_filters = 0; 2072 bwn_wme_clear(sc); 2073 sc->sc_beacons[0] = sc->sc_beacons[1] = 0; 2074 sc->sc_rf_enabled = 1; 2075 2076 mac = sc->sc_curmac; 2077 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) { 2078 error = bwn_core_init(mac); 2079 if (error != 0) 2080 return (error); 2081 } 2082 if (mac->mac_status == BWN_MAC_STATUS_INITED) 2083 bwn_core_start(mac); 2084 2085 bwn_set_opmode(mac); 2086 bwn_set_pretbtt(mac); 2087 bwn_spu_setdelay(mac, 0); 2088 bwn_set_macaddr(mac); 2089 2090 sc->sc_flags |= BWN_FLAG_RUNNING; 2091 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 2092 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); 2093 2094 return (0); 2095 } 2096 2097 static void 2098 bwn_stop(struct bwn_softc *sc) 2099 { 2100 struct bwn_mac *mac = sc->sc_curmac; 2101 2102 BWN_ASSERT_LOCKED(sc); 2103 2104 DPRINTF(sc, BWN_DEBUG_RESET, "%s: called\n", __func__); 2105 2106 if (mac->mac_status >= BWN_MAC_STATUS_INITED) { 2107 /* XXX FIXME opmode not based on VAP */ 2108 bwn_set_opmode(mac); 2109 bwn_set_macaddr(mac); 2110 } 2111 2112 if (mac->mac_status >= BWN_MAC_STATUS_STARTED) 2113 bwn_core_stop(mac); 2114 2115 callout_stop(&sc->sc_led_blink_ch); 2116 sc->sc_led_blinking = 0; 2117 2118 bwn_core_exit(mac); 2119 sc->sc_rf_enabled = 0; 2120 2121 sc->sc_flags &= ~BWN_FLAG_RUNNING; 2122 } 2123 2124 static void 2125 bwn_wme_clear(struct bwn_softc *sc) 2126 { 2127 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 2128 struct wmeParams *p; 2129 unsigned int i; 2130 2131 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 2132 ("%s:%d: fail", __func__, __LINE__)); 2133 2134 for (i = 0; i < N(sc->sc_wmeParams); i++) { 2135 p = &(sc->sc_wmeParams[i]); 2136 2137 switch (bwn_wme_shm_offsets[i]) { 2138 case BWN_WME_VOICE: 2139 p->wmep_txopLimit = 0; 2140 p->wmep_aifsn = 2; 2141 /* XXX FIXME: log2(cwmin) */ 2142 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 2143 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 2144 break; 2145 case BWN_WME_VIDEO: 2146 p->wmep_txopLimit = 0; 2147 p->wmep_aifsn = 2; 2148 /* XXX FIXME: log2(cwmin) */ 2149 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 2150 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX); 2151 break; 2152 case BWN_WME_BESTEFFORT: 2153 p->wmep_txopLimit = 0; 2154 p->wmep_aifsn = 3; 2155 /* XXX FIXME: log2(cwmin) */ 2156 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 2157 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 2158 break; 2159 case BWN_WME_BACKGROUND: 2160 p->wmep_txopLimit = 0; 2161 p->wmep_aifsn = 7; 2162 /* XXX FIXME: log2(cwmin) */ 2163 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN); 2164 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX); 2165 break; 2166 default: 2167 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 2168 } 2169 } 2170 } 2171 2172 static int 2173 bwn_core_forceclk(struct bwn_mac *mac, bool force) 2174 { 2175 struct bwn_softc *sc; 2176 bhnd_clock clock; 2177 int error; 2178 2179 sc = mac->mac_sc; 2180 2181 /* On PMU equipped devices, we do not need to force the HT clock */ 2182 if (sc->sc_pmu != NULL) 2183 return (0); 2184 2185 /* Issue a PMU clock request */ 2186 if (force) 2187 clock = BHND_CLOCK_HT; 2188 else 2189 clock = BHND_CLOCK_DYN; 2190 2191 if ((error = bhnd_request_clock(sc->sc_dev, clock))) { 2192 device_printf(sc->sc_dev, "%d clock request failed: %d\n", 2193 clock, error); 2194 return (error); 2195 } 2196 2197 return (0); 2198 } 2199 2200 static int 2201 bwn_core_init(struct bwn_mac *mac) 2202 { 2203 struct bwn_softc *sc = mac->mac_sc; 2204 uint64_t hf; 2205 int error; 2206 2207 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 2208 ("%s:%d: fail", __func__, __LINE__)); 2209 2210 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__); 2211 2212 if ((error = bwn_core_forceclk(mac, true))) 2213 return (error); 2214 2215 if (bhnd_is_hw_suspended(sc->sc_dev)) { 2216 if ((error = bwn_reset_core(mac, mac->mac_phy.gmode))) 2217 goto fail0; 2218 } 2219 2220 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 2221 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 2222 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0; 2223 BWN_GETTIME(mac->mac_phy.nexttime); 2224 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 2225 bzero(&mac->mac_stats, sizeof(mac->mac_stats)); 2226 mac->mac_stats.link_noise = -95; 2227 mac->mac_reason_intr = 0; 2228 bzero(mac->mac_reason, sizeof(mac->mac_reason)); 2229 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE; 2230 #ifdef BWN_DEBUG 2231 if (sc->sc_debug & BWN_DEBUG_XMIT) 2232 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR; 2233 #endif 2234 mac->mac_suspended = 1; 2235 mac->mac_task_state = 0; 2236 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise)); 2237 2238 mac->mac_phy.init_pre(mac); 2239 2240 bwn_bt_disable(mac); 2241 if (mac->mac_phy.prepare_hw) { 2242 error = mac->mac_phy.prepare_hw(mac); 2243 if (error) 2244 goto fail0; 2245 } 2246 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: chip_init\n", __func__); 2247 error = bwn_chip_init(mac); 2248 if (error) 2249 goto fail0; 2250 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV, 2251 bhnd_get_hwrev(sc->sc_dev)); 2252 hf = bwn_hf_read(mac); 2253 if (mac->mac_phy.type == BWN_PHYTYPE_G) { 2254 hf |= BWN_HF_GPHY_SYM_WORKAROUND; 2255 if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL) 2256 hf |= BWN_HF_PAGAINBOOST_OFDM_ON; 2257 if (mac->mac_phy.rev == 1) 2258 hf |= BWN_HF_GPHY_DC_CANCELFILTER; 2259 } 2260 if (mac->mac_phy.rf_ver == 0x2050) { 2261 if (mac->mac_phy.rf_rev < 6) 2262 hf |= BWN_HF_FORCE_VCO_RECALC; 2263 if (mac->mac_phy.rf_rev == 6) 2264 hf |= BWN_HF_4318_TSSI; 2265 } 2266 if (sc->sc_board_info.board_flags & BHND_BFL_NOPLLDOWN) 2267 hf |= BWN_HF_SLOWCLOCK_REQ_OFF; 2268 if (sc->sc_quirks & BWN_QUIRK_UCODE_SLOWCLOCK_WAR) 2269 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND; 2270 hf &= ~BWN_HF_SKIP_CFP_UPDATE; 2271 bwn_hf_write(mac, hf); 2272 2273 /* Tell the firmware about the MAC capabilities */ 2274 if (bhnd_get_hwrev(sc->sc_dev) >= 13) { 2275 uint32_t cap; 2276 cap = BWN_READ_4(mac, BWN_MAC_HW_CAP); 2277 DPRINTF(sc, BWN_DEBUG_RESET, 2278 "%s: hw capabilities: 0x%08x\n", 2279 __func__, cap); 2280 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_MACHW_L, 2281 cap & 0xffff); 2282 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_MACHW_H, 2283 (cap >> 16) & 0xffff); 2284 } 2285 2286 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG); 2287 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3); 2288 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2); 2289 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1); 2290 2291 bwn_rate_init(mac); 2292 bwn_set_phytxctl(mac); 2293 2294 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN, 2295 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf); 2296 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff); 2297 2298 if (sc->sc_quirks & BWN_QUIRK_NODMA) 2299 bwn_pio_init(mac); 2300 else 2301 bwn_dma_init(mac); 2302 bwn_wme_init(mac); 2303 bwn_spu_setdelay(mac, 1); 2304 bwn_bt_enable(mac); 2305 2306 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: powerup\n", __func__); 2307 if (sc->sc_board_info.board_flags & BHND_BFL_NOPLLDOWN) 2308 bwn_core_forceclk(mac, true); 2309 else 2310 bwn_core_forceclk(mac, false); 2311 2312 bwn_set_macaddr(mac); 2313 bwn_crypt_init(mac); 2314 2315 /* XXX LED initializatin */ 2316 2317 mac->mac_status = BWN_MAC_STATUS_INITED; 2318 2319 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: done\n", __func__); 2320 return (error); 2321 2322 fail0: 2323 bhnd_suspend_hw(sc->sc_dev, 0); 2324 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT, 2325 ("%s:%d: fail", __func__, __LINE__)); 2326 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: fail\n", __func__); 2327 return (error); 2328 } 2329 2330 static void 2331 bwn_core_start(struct bwn_mac *mac) 2332 { 2333 struct bwn_softc *sc = mac->mac_sc; 2334 uint32_t tmp; 2335 2336 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED, 2337 ("%s:%d: fail", __func__, __LINE__)); 2338 2339 if (bhnd_get_hwrev(sc->sc_dev) < 5) 2340 return; 2341 2342 while (1) { 2343 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0); 2344 if (!(tmp & 0x00000001)) 2345 break; 2346 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1); 2347 } 2348 2349 bwn_mac_enable(mac); 2350 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 2351 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 2352 2353 mac->mac_status = BWN_MAC_STATUS_STARTED; 2354 } 2355 2356 static void 2357 bwn_core_exit(struct bwn_mac *mac) 2358 { 2359 struct bwn_softc *sc = mac->mac_sc; 2360 uint32_t macctl; 2361 2362 BWN_ASSERT_LOCKED(mac->mac_sc); 2363 2364 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED, 2365 ("%s:%d: fail", __func__, __LINE__)); 2366 2367 if (mac->mac_status != BWN_MAC_STATUS_INITED) 2368 return; 2369 mac->mac_status = BWN_MAC_STATUS_UNINIT; 2370 2371 macctl = BWN_READ_4(mac, BWN_MACCTL); 2372 macctl &= ~BWN_MACCTL_MCODE_RUN; 2373 macctl |= BWN_MACCTL_MCODE_JMP0; 2374 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 2375 2376 bwn_dma_stop(mac); 2377 bwn_pio_stop(mac); 2378 bwn_chip_exit(mac); 2379 mac->mac_phy.switch_analog(mac, 0); 2380 bhnd_suspend_hw(sc->sc_dev, 0); 2381 } 2382 2383 static void 2384 bwn_bt_disable(struct bwn_mac *mac) 2385 { 2386 struct bwn_softc *sc = mac->mac_sc; 2387 2388 (void)sc; 2389 /* XXX do nothing yet */ 2390 } 2391 2392 static int 2393 bwn_chip_init(struct bwn_mac *mac) 2394 { 2395 struct bwn_softc *sc = mac->mac_sc; 2396 struct bwn_phy *phy = &mac->mac_phy; 2397 uint32_t macctl; 2398 u_int delay; 2399 int error; 2400 2401 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA; 2402 if (phy->gmode) 2403 macctl |= BWN_MACCTL_GMODE; 2404 BWN_WRITE_4(mac, BWN_MACCTL, macctl); 2405 2406 error = bwn_fw_fillinfo(mac); 2407 if (error) 2408 return (error); 2409 error = bwn_fw_loaducode(mac); 2410 if (error) 2411 return (error); 2412 2413 error = bwn_gpio_init(mac); 2414 if (error) 2415 return (error); 2416 2417 error = bwn_fw_loadinitvals(mac); 2418 if (error) 2419 return (error); 2420 2421 phy->switch_analog(mac, 1); 2422 error = bwn_phy_init(mac); 2423 if (error) 2424 return (error); 2425 2426 if (phy->set_im) 2427 phy->set_im(mac, BWN_IMMODE_NONE); 2428 if (phy->set_antenna) 2429 phy->set_antenna(mac, BWN_ANT_DEFAULT); 2430 bwn_set_txantenna(mac, BWN_ANT_DEFAULT); 2431 2432 if (phy->type == BWN_PHYTYPE_B) 2433 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004); 2434 BWN_WRITE_4(mac, 0x0100, 0x01000000); 2435 if (bhnd_get_hwrev(sc->sc_dev) < 5) 2436 BWN_WRITE_4(mac, 0x010c, 0x01000000); 2437 2438 BWN_WRITE_4(mac, BWN_MACCTL, 2439 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA); 2440 BWN_WRITE_4(mac, BWN_MACCTL, 2441 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA); 2442 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000); 2443 2444 bwn_set_opmode(mac); 2445 if (bhnd_get_hwrev(sc->sc_dev) < 3) { 2446 BWN_WRITE_2(mac, 0x060e, 0x0000); 2447 BWN_WRITE_2(mac, 0x0610, 0x8000); 2448 BWN_WRITE_2(mac, 0x0604, 0x0000); 2449 BWN_WRITE_2(mac, 0x0606, 0x0200); 2450 } else { 2451 BWN_WRITE_4(mac, 0x0188, 0x80000000); 2452 BWN_WRITE_4(mac, 0x018c, 0x02000000); 2453 } 2454 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000); 2455 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00); 2456 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00); 2457 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00); 2458 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00); 2459 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00); 2460 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00); 2461 2462 bwn_mac_phy_clock_set(mac, true); 2463 2464 /* Provide the HT clock transition latency to the MAC core */ 2465 error = bhnd_get_clock_latency(sc->sc_dev, BHND_CLOCK_HT, &delay); 2466 if (error) { 2467 device_printf(sc->sc_dev, "failed to fetch HT clock latency: " 2468 "%d\n", error); 2469 return (error); 2470 } 2471 2472 if (delay > UINT16_MAX) { 2473 device_printf(sc->sc_dev, "invalid HT clock latency: %u\n", 2474 delay); 2475 return (ENXIO); 2476 } 2477 2478 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, delay); 2479 return (0); 2480 } 2481 2482 /* read hostflags */ 2483 uint64_t 2484 bwn_hf_read(struct bwn_mac *mac) 2485 { 2486 uint64_t ret; 2487 2488 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI); 2489 ret <<= 16; 2490 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI); 2491 ret <<= 16; 2492 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO); 2493 return (ret); 2494 } 2495 2496 void 2497 bwn_hf_write(struct bwn_mac *mac, uint64_t value) 2498 { 2499 2500 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO, 2501 (value & 0x00000000ffffull)); 2502 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI, 2503 (value & 0x0000ffff0000ull) >> 16); 2504 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI, 2505 (value & 0xffff00000000ULL) >> 32); 2506 } 2507 2508 static void 2509 bwn_set_txretry(struct bwn_mac *mac, int s, int l) 2510 { 2511 2512 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf)); 2513 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf)); 2514 } 2515 2516 static void 2517 bwn_rate_init(struct bwn_mac *mac) 2518 { 2519 2520 switch (mac->mac_phy.type) { 2521 case BWN_PHYTYPE_A: 2522 case BWN_PHYTYPE_G: 2523 case BWN_PHYTYPE_LP: 2524 case BWN_PHYTYPE_N: 2525 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1); 2526 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1); 2527 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1); 2528 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1); 2529 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1); 2530 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1); 2531 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1); 2532 if (mac->mac_phy.type == BWN_PHYTYPE_A) 2533 break; 2534 /* FALLTHROUGH */ 2535 case BWN_PHYTYPE_B: 2536 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0); 2537 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0); 2538 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0); 2539 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0); 2540 break; 2541 default: 2542 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 2543 } 2544 } 2545 2546 static void 2547 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm) 2548 { 2549 uint16_t offset; 2550 2551 if (ofdm) { 2552 offset = 0x480; 2553 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2; 2554 } else { 2555 offset = 0x4c0; 2556 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2; 2557 } 2558 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20, 2559 bwn_shm_read_2(mac, BWN_SHARED, offset)); 2560 } 2561 2562 static uint8_t 2563 bwn_plcp_getcck(const uint8_t bitrate) 2564 { 2565 2566 switch (bitrate) { 2567 case BWN_CCK_RATE_1MB: 2568 return (0x0a); 2569 case BWN_CCK_RATE_2MB: 2570 return (0x14); 2571 case BWN_CCK_RATE_5MB: 2572 return (0x37); 2573 case BWN_CCK_RATE_11MB: 2574 return (0x6e); 2575 } 2576 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 2577 return (0); 2578 } 2579 2580 static uint8_t 2581 bwn_plcp_getofdm(const uint8_t bitrate) 2582 { 2583 2584 switch (bitrate) { 2585 case BWN_OFDM_RATE_6MB: 2586 return (0xb); 2587 case BWN_OFDM_RATE_9MB: 2588 return (0xf); 2589 case BWN_OFDM_RATE_12MB: 2590 return (0xa); 2591 case BWN_OFDM_RATE_18MB: 2592 return (0xe); 2593 case BWN_OFDM_RATE_24MB: 2594 return (0x9); 2595 case BWN_OFDM_RATE_36MB: 2596 return (0xd); 2597 case BWN_OFDM_RATE_48MB: 2598 return (0x8); 2599 case BWN_OFDM_RATE_54MB: 2600 return (0xc); 2601 } 2602 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 2603 return (0); 2604 } 2605 2606 static void 2607 bwn_set_phytxctl(struct bwn_mac *mac) 2608 { 2609 uint16_t ctl; 2610 2611 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO | 2612 BWN_TX_PHY_TXPWR); 2613 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl); 2614 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl); 2615 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl); 2616 } 2617 2618 static void 2619 bwn_pio_init(struct bwn_mac *mac) 2620 { 2621 struct bwn_pio *pio = &mac->mac_method.pio; 2622 2623 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL) 2624 & ~BWN_MACCTL_BIGENDIAN); 2625 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0); 2626 2627 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0); 2628 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1); 2629 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2); 2630 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3); 2631 bwn_pio_set_txqueue(mac, &pio->mcast, 4); 2632 bwn_pio_setupqueue_rx(mac, &pio->rx, 0); 2633 } 2634 2635 static void 2636 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 2637 int index) 2638 { 2639 struct bwn_pio_txpkt *tp; 2640 struct bwn_softc *sc = mac->mac_sc; 2641 unsigned int i; 2642 2643 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac); 2644 tq->tq_index = index; 2645 2646 tq->tq_free = BWN_PIO_MAX_TXPACKETS; 2647 if (bhnd_get_hwrev(sc->sc_dev) >= 8) 2648 tq->tq_size = 1920; 2649 else { 2650 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE); 2651 tq->tq_size -= 80; 2652 } 2653 2654 TAILQ_INIT(&tq->tq_pktlist); 2655 for (i = 0; i < N(tq->tq_pkts); i++) { 2656 tp = &(tq->tq_pkts[i]); 2657 tp->tp_index = i; 2658 tp->tp_queue = tq; 2659 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 2660 } 2661 } 2662 2663 static uint16_t 2664 bwn_pio_idx2base(struct bwn_mac *mac, int index) 2665 { 2666 struct bwn_softc *sc = mac->mac_sc; 2667 static const uint16_t bases[] = { 2668 BWN_PIO_BASE0, 2669 BWN_PIO_BASE1, 2670 BWN_PIO_BASE2, 2671 BWN_PIO_BASE3, 2672 BWN_PIO_BASE4, 2673 BWN_PIO_BASE5, 2674 BWN_PIO_BASE6, 2675 BWN_PIO_BASE7, 2676 }; 2677 static const uint16_t bases_rev11[] = { 2678 BWN_PIO11_BASE0, 2679 BWN_PIO11_BASE1, 2680 BWN_PIO11_BASE2, 2681 BWN_PIO11_BASE3, 2682 BWN_PIO11_BASE4, 2683 BWN_PIO11_BASE5, 2684 }; 2685 2686 if (bhnd_get_hwrev(sc->sc_dev) >= 11) { 2687 if (index >= N(bases_rev11)) 2688 device_printf(sc->sc_dev, "%s: warning\n", __func__); 2689 return (bases_rev11[index]); 2690 } 2691 if (index >= N(bases)) 2692 device_printf(sc->sc_dev, "%s: warning\n", __func__); 2693 return (bases[index]); 2694 } 2695 2696 static void 2697 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq, 2698 int index) 2699 { 2700 struct bwn_softc *sc = mac->mac_sc; 2701 2702 prq->prq_mac = mac; 2703 prq->prq_rev = bhnd_get_hwrev(sc->sc_dev); 2704 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac); 2705 bwn_dma_rxdirectfifo(mac, index, 1); 2706 } 2707 2708 static void 2709 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq) 2710 { 2711 if (tq == NULL) 2712 return; 2713 bwn_pio_cancel_tx_packets(tq); 2714 } 2715 2716 static void 2717 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio) 2718 { 2719 2720 bwn_destroy_pioqueue_tx(pio); 2721 } 2722 2723 static uint16_t 2724 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 2725 uint16_t offset) 2726 { 2727 2728 return (BWN_READ_2(mac, tq->tq_base + offset)); 2729 } 2730 2731 static void 2732 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable) 2733 { 2734 uint32_t ctl; 2735 uint16_t base; 2736 2737 base = bwn_dma_base(mac->mac_dmatype, idx); 2738 if (mac->mac_dmatype == BHND_DMA_ADDR_64BIT) { 2739 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL); 2740 ctl &= ~BWN_DMA64_RXDIRECTFIFO; 2741 if (enable) 2742 ctl |= BWN_DMA64_RXDIRECTFIFO; 2743 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl); 2744 } else { 2745 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL); 2746 ctl &= ~BWN_DMA32_RXDIRECTFIFO; 2747 if (enable) 2748 ctl |= BWN_DMA32_RXDIRECTFIFO; 2749 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl); 2750 } 2751 } 2752 2753 static void 2754 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq) 2755 { 2756 struct bwn_pio_txpkt *tp; 2757 unsigned int i; 2758 2759 for (i = 0; i < N(tq->tq_pkts); i++) { 2760 tp = &(tq->tq_pkts[i]); 2761 if (tp->tp_m) { 2762 m_freem(tp->tp_m); 2763 tp->tp_m = NULL; 2764 } 2765 } 2766 } 2767 2768 static uint16_t 2769 bwn_dma_base(int type, int controller_idx) 2770 { 2771 static const uint16_t map64[] = { 2772 BWN_DMA64_BASE0, 2773 BWN_DMA64_BASE1, 2774 BWN_DMA64_BASE2, 2775 BWN_DMA64_BASE3, 2776 BWN_DMA64_BASE4, 2777 BWN_DMA64_BASE5, 2778 }; 2779 static const uint16_t map32[] = { 2780 BWN_DMA32_BASE0, 2781 BWN_DMA32_BASE1, 2782 BWN_DMA32_BASE2, 2783 BWN_DMA32_BASE3, 2784 BWN_DMA32_BASE4, 2785 BWN_DMA32_BASE5, 2786 }; 2787 2788 if (type == BHND_DMA_ADDR_64BIT) { 2789 KASSERT(controller_idx >= 0 && controller_idx < N(map64), 2790 ("%s:%d: fail", __func__, __LINE__)); 2791 return (map64[controller_idx]); 2792 } 2793 KASSERT(controller_idx >= 0 && controller_idx < N(map32), 2794 ("%s:%d: fail", __func__, __LINE__)); 2795 return (map32[controller_idx]); 2796 } 2797 2798 static void 2799 bwn_dma_init(struct bwn_mac *mac) 2800 { 2801 struct bwn_dma *dma = &mac->mac_method.dma; 2802 2803 /* setup TX DMA channels. */ 2804 bwn_dma_setup(dma->wme[WME_AC_BK]); 2805 bwn_dma_setup(dma->wme[WME_AC_BE]); 2806 bwn_dma_setup(dma->wme[WME_AC_VI]); 2807 bwn_dma_setup(dma->wme[WME_AC_VO]); 2808 bwn_dma_setup(dma->mcast); 2809 /* setup RX DMA channel. */ 2810 bwn_dma_setup(dma->rx); 2811 } 2812 2813 static struct bwn_dma_ring * 2814 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index, 2815 int for_tx) 2816 { 2817 struct bwn_dma *dma = &mac->mac_method.dma; 2818 struct bwn_dma_ring *dr; 2819 struct bwn_dmadesc_generic *desc; 2820 struct bwn_dmadesc_meta *mt; 2821 struct bwn_softc *sc = mac->mac_sc; 2822 int error, i; 2823 2824 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO); 2825 if (dr == NULL) 2826 goto out; 2827 dr->dr_numslots = BWN_RXRING_SLOTS; 2828 if (for_tx) 2829 dr->dr_numslots = BWN_TXRING_SLOTS; 2830 2831 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta), 2832 M_DEVBUF, M_NOWAIT | M_ZERO); 2833 if (dr->dr_meta == NULL) 2834 goto fail0; 2835 2836 dr->dr_type = mac->mac_dmatype; 2837 dr->dr_mac = mac; 2838 dr->dr_base = bwn_dma_base(dr->dr_type, controller_index); 2839 dr->dr_index = controller_index; 2840 if (dr->dr_type == BHND_DMA_ADDR_64BIT) { 2841 dr->getdesc = bwn_dma_64_getdesc; 2842 dr->setdesc = bwn_dma_64_setdesc; 2843 dr->start_transfer = bwn_dma_64_start_transfer; 2844 dr->suspend = bwn_dma_64_suspend; 2845 dr->resume = bwn_dma_64_resume; 2846 dr->get_curslot = bwn_dma_64_get_curslot; 2847 dr->set_curslot = bwn_dma_64_set_curslot; 2848 } else { 2849 dr->getdesc = bwn_dma_32_getdesc; 2850 dr->setdesc = bwn_dma_32_setdesc; 2851 dr->start_transfer = bwn_dma_32_start_transfer; 2852 dr->suspend = bwn_dma_32_suspend; 2853 dr->resume = bwn_dma_32_resume; 2854 dr->get_curslot = bwn_dma_32_get_curslot; 2855 dr->set_curslot = bwn_dma_32_set_curslot; 2856 } 2857 if (for_tx) { 2858 dr->dr_tx = 1; 2859 dr->dr_curslot = -1; 2860 } else { 2861 if (dr->dr_index == 0) { 2862 switch (mac->mac_fw.fw_hdr_format) { 2863 case BWN_FW_HDR_351: 2864 case BWN_FW_HDR_410: 2865 dr->dr_rx_bufsize = 2866 BWN_DMA0_RX_BUFFERSIZE_FW351; 2867 dr->dr_frameoffset = 2868 BWN_DMA0_RX_FRAMEOFFSET_FW351; 2869 break; 2870 case BWN_FW_HDR_598: 2871 dr->dr_rx_bufsize = 2872 BWN_DMA0_RX_BUFFERSIZE_FW598; 2873 dr->dr_frameoffset = 2874 BWN_DMA0_RX_FRAMEOFFSET_FW598; 2875 break; 2876 } 2877 } else 2878 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 2879 } 2880 2881 error = bwn_dma_allocringmemory(dr); 2882 if (error) 2883 goto fail2; 2884 2885 if (for_tx) { 2886 /* 2887 * Assumption: BWN_TXRING_SLOTS can be divided by 2888 * BWN_TX_SLOTS_PER_FRAME 2889 */ 2890 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0, 2891 ("%s:%d: fail", __func__, __LINE__)); 2892 2893 dr->dr_txhdr_cache = contigmalloc( 2894 (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 2895 BWN_MAXTXHDRSIZE, M_DEVBUF, M_ZERO, 2896 0, BUS_SPACE_MAXADDR, 8, 0); 2897 if (dr->dr_txhdr_cache == NULL) { 2898 device_printf(sc->sc_dev, 2899 "can't allocate TX header DMA memory\n"); 2900 goto fail1; 2901 } 2902 2903 /* 2904 * Create TX ring DMA stuffs 2905 */ 2906 error = bus_dma_tag_create(dma->parent_dtag, 2907 BWN_ALIGN, 0, 2908 BUS_SPACE_MAXADDR, 2909 BUS_SPACE_MAXADDR, 2910 NULL, NULL, 2911 BWN_HDRSIZE(mac), 2912 1, 2913 BUS_SPACE_MAXSIZE_32BIT, 2914 0, 2915 NULL, NULL, 2916 &dr->dr_txring_dtag); 2917 if (error) { 2918 device_printf(sc->sc_dev, 2919 "can't create TX ring DMA tag: TODO frees\n"); 2920 goto fail2; 2921 } 2922 2923 for (i = 0; i < dr->dr_numslots; i += 2) { 2924 dr->getdesc(dr, i, &desc, &mt); 2925 2926 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 2927 mt->mt_m = NULL; 2928 mt->mt_ni = NULL; 2929 mt->mt_islast = 0; 2930 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 2931 &mt->mt_dmap); 2932 if (error) { 2933 device_printf(sc->sc_dev, 2934 "can't create RX buf DMA map\n"); 2935 goto fail2; 2936 } 2937 2938 dr->getdesc(dr, i + 1, &desc, &mt); 2939 2940 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 2941 mt->mt_m = NULL; 2942 mt->mt_ni = NULL; 2943 mt->mt_islast = 1; 2944 error = bus_dmamap_create(dma->txbuf_dtag, 0, 2945 &mt->mt_dmap); 2946 if (error) { 2947 device_printf(sc->sc_dev, 2948 "can't create RX buf DMA map\n"); 2949 goto fail2; 2950 } 2951 } 2952 } else { 2953 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 2954 &dr->dr_spare_dmap); 2955 if (error) { 2956 device_printf(sc->sc_dev, 2957 "can't create RX buf DMA map\n"); 2958 goto out; /* XXX wrong! */ 2959 } 2960 2961 for (i = 0; i < dr->dr_numslots; i++) { 2962 dr->getdesc(dr, i, &desc, &mt); 2963 2964 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 2965 &mt->mt_dmap); 2966 if (error) { 2967 device_printf(sc->sc_dev, 2968 "can't create RX buf DMA map\n"); 2969 goto out; /* XXX wrong! */ 2970 } 2971 error = bwn_dma_newbuf(dr, desc, mt, 1); 2972 if (error) { 2973 device_printf(sc->sc_dev, 2974 "failed to allocate RX buf\n"); 2975 goto out; /* XXX wrong! */ 2976 } 2977 } 2978 2979 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 2980 BUS_DMASYNC_PREWRITE); 2981 2982 dr->dr_usedslot = dr->dr_numslots; 2983 } 2984 2985 out: 2986 return (dr); 2987 2988 fail2: 2989 if (dr->dr_txhdr_cache != NULL) { 2990 contigfree(dr->dr_txhdr_cache, 2991 (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 2992 BWN_MAXTXHDRSIZE, M_DEVBUF); 2993 } 2994 fail1: 2995 free(dr->dr_meta, M_DEVBUF); 2996 fail0: 2997 free(dr, M_DEVBUF); 2998 return (NULL); 2999 } 3000 3001 static void 3002 bwn_dma_ringfree(struct bwn_dma_ring **dr) 3003 { 3004 3005 if (dr == NULL) 3006 return; 3007 3008 bwn_dma_free_descbufs(*dr); 3009 bwn_dma_free_ringmemory(*dr); 3010 3011 if ((*dr)->dr_txhdr_cache != NULL) { 3012 contigfree((*dr)->dr_txhdr_cache, 3013 ((*dr)->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 3014 BWN_MAXTXHDRSIZE, M_DEVBUF); 3015 } 3016 free((*dr)->dr_meta, M_DEVBUF); 3017 free(*dr, M_DEVBUF); 3018 3019 *dr = NULL; 3020 } 3021 3022 static void 3023 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 3024 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3025 { 3026 struct bwn_dmadesc32 *desc; 3027 3028 *meta = &(dr->dr_meta[slot]); 3029 desc = dr->dr_ring_descbase; 3030 desc = &(desc[slot]); 3031 3032 *gdesc = (struct bwn_dmadesc_generic *)desc; 3033 } 3034 3035 static void 3036 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 3037 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3038 int start, int end, int irq) 3039 { 3040 struct bwn_dmadesc32 *descbase; 3041 struct bwn_dma *dma; 3042 struct bhnd_dma_translation *dt; 3043 uint32_t addr, addrext, ctl; 3044 int slot; 3045 3046 descbase = dr->dr_ring_descbase; 3047 dma = &dr->dr_mac->mac_method.dma; 3048 dt = &dma->translation; 3049 3050 slot = (int)(&(desc->dma.dma32) - descbase); 3051 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3052 ("%s:%d: fail", __func__, __LINE__)); 3053 3054 addr = (dmaaddr & dt->addr_mask) | dt->base_addr; 3055 addrext = ((dmaaddr & dt->addrext_mask) >> dma->addrext_shift); 3056 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 3057 if (slot == dr->dr_numslots - 1) 3058 ctl |= BWN_DMA32_DCTL_DTABLEEND; 3059 if (start) 3060 ctl |= BWN_DMA32_DCTL_FRAMESTART; 3061 if (end) 3062 ctl |= BWN_DMA32_DCTL_FRAMEEND; 3063 if (irq) 3064 ctl |= BWN_DMA32_DCTL_IRQ; 3065 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 3066 & BWN_DMA32_DCTL_ADDREXT_MASK; 3067 3068 desc->dma.dma32.control = htole32(ctl); 3069 desc->dma.dma32.address = htole32(addr); 3070 } 3071 3072 static void 3073 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 3074 { 3075 3076 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 3077 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 3078 } 3079 3080 static void 3081 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 3082 { 3083 3084 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3085 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 3086 } 3087 3088 static void 3089 bwn_dma_32_resume(struct bwn_dma_ring *dr) 3090 { 3091 3092 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 3093 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 3094 } 3095 3096 static int 3097 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3098 { 3099 uint32_t val; 3100 3101 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3102 val &= BWN_DMA32_RXDPTR; 3103 3104 return (val / sizeof(struct bwn_dmadesc32)); 3105 } 3106 3107 static void 3108 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3109 { 3110 3111 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3112 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3113 } 3114 3115 static void 3116 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3117 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3118 { 3119 struct bwn_dmadesc64 *desc; 3120 3121 *meta = &(dr->dr_meta[slot]); 3122 desc = dr->dr_ring_descbase; 3123 desc = &(desc[slot]); 3124 3125 *gdesc = (struct bwn_dmadesc_generic *)desc; 3126 } 3127 3128 static void 3129 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3130 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3131 int start, int end, int irq) 3132 { 3133 struct bwn_dmadesc64 *descbase; 3134 struct bwn_dma *dma; 3135 struct bhnd_dma_translation *dt; 3136 bhnd_addr_t addr; 3137 uint32_t addrhi, addrlo; 3138 uint32_t addrext; 3139 uint32_t ctl0, ctl1; 3140 int slot; 3141 3142 3143 descbase = dr->dr_ring_descbase; 3144 dma = &dr->dr_mac->mac_method.dma; 3145 dt = &dma->translation; 3146 3147 slot = (int)(&(desc->dma.dma64) - descbase); 3148 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3149 ("%s:%d: fail", __func__, __LINE__)); 3150 3151 addr = (dmaaddr & dt->addr_mask) | dt->base_addr; 3152 addrhi = (addr >> 32); 3153 addrlo = (addr & UINT32_MAX); 3154 addrext = ((dmaaddr & dt->addrext_mask) >> dma->addrext_shift); 3155 3156 ctl0 = 0; 3157 if (slot == dr->dr_numslots - 1) 3158 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3159 if (start) 3160 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3161 if (end) 3162 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3163 if (irq) 3164 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3165 3166 ctl1 = 0; 3167 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3168 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3169 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3170 3171 desc->dma.dma64.control0 = htole32(ctl0); 3172 desc->dma.dma64.control1 = htole32(ctl1); 3173 desc->dma.dma64.address_low = htole32(addrlo); 3174 desc->dma.dma64.address_high = htole32(addrhi); 3175 } 3176 3177 static void 3178 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3179 { 3180 3181 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3182 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3183 } 3184 3185 static void 3186 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3187 { 3188 3189 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3190 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3191 } 3192 3193 static void 3194 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3195 { 3196 3197 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3198 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 3199 } 3200 3201 static int 3202 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 3203 { 3204 uint32_t val; 3205 3206 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 3207 val &= BWN_DMA64_RXSTATDPTR; 3208 3209 return (val / sizeof(struct bwn_dmadesc64)); 3210 } 3211 3212 static void 3213 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 3214 { 3215 3216 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 3217 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3218 } 3219 3220 static int 3221 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 3222 { 3223 struct bwn_mac *mac = dr->dr_mac; 3224 struct bwn_dma *dma = &mac->mac_method.dma; 3225 struct bwn_softc *sc = mac->mac_sc; 3226 int error; 3227 3228 error = bus_dma_tag_create(dma->parent_dtag, 3229 BWN_ALIGN, 0, 3230 BUS_SPACE_MAXADDR, 3231 BUS_SPACE_MAXADDR, 3232 NULL, NULL, 3233 BWN_DMA_RINGMEMSIZE, 3234 1, 3235 BUS_SPACE_MAXSIZE_32BIT, 3236 0, 3237 NULL, NULL, 3238 &dr->dr_ring_dtag); 3239 if (error) { 3240 device_printf(sc->sc_dev, 3241 "can't create TX ring DMA tag: TODO frees\n"); 3242 return (-1); 3243 } 3244 3245 error = bus_dmamem_alloc(dr->dr_ring_dtag, 3246 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 3247 &dr->dr_ring_dmap); 3248 if (error) { 3249 device_printf(sc->sc_dev, 3250 "can't allocate DMA mem: TODO frees\n"); 3251 return (-1); 3252 } 3253 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 3254 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 3255 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 3256 if (error) { 3257 device_printf(sc->sc_dev, 3258 "can't load DMA mem: TODO free\n"); 3259 return (-1); 3260 } 3261 3262 return (0); 3263 } 3264 3265 static void 3266 bwn_dma_setup(struct bwn_dma_ring *dr) 3267 { 3268 struct bwn_mac *mac; 3269 struct bwn_dma *dma; 3270 struct bhnd_dma_translation *dt; 3271 bhnd_addr_t addr, paddr; 3272 uint32_t addrhi, addrlo, addrext, value; 3273 3274 mac = dr->dr_mac; 3275 dma = &mac->mac_method.dma; 3276 dt = &dma->translation; 3277 3278 paddr = dr->dr_ring_dmabase; 3279 addr = (paddr & dt->addr_mask) | dt->base_addr; 3280 addrhi = (addr >> 32); 3281 addrlo = (addr & UINT32_MAX); 3282 addrext = ((paddr & dt->addrext_mask) >> dma->addrext_shift); 3283 3284 if (dr->dr_tx) { 3285 dr->dr_curslot = -1; 3286 3287 if (dr->dr_type == BHND_DMA_ADDR_64BIT) { 3288 value = BWN_DMA64_TXENABLE; 3289 value |= BWN_DMA64_TXPARITY_DISABLE; 3290 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 3291 & BWN_DMA64_TXADDREXT_MASK; 3292 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 3293 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, addrlo); 3294 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, addrhi); 3295 } else { 3296 value = BWN_DMA32_TXENABLE; 3297 value |= BWN_DMA32_TXPARITY_DISABLE; 3298 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 3299 & BWN_DMA32_TXADDREXT_MASK; 3300 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 3301 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, addrlo); 3302 } 3303 return; 3304 } 3305 3306 /* 3307 * set for RX 3308 */ 3309 dr->dr_usedslot = dr->dr_numslots; 3310 3311 if (dr->dr_type == BHND_DMA_ADDR_64BIT) { 3312 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 3313 value |= BWN_DMA64_RXENABLE; 3314 value |= BWN_DMA64_RXPARITY_DISABLE; 3315 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 3316 & BWN_DMA64_RXADDREXT_MASK; 3317 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 3318 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, addrlo); 3319 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, addrhi); 3320 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 3321 sizeof(struct bwn_dmadesc64)); 3322 } else { 3323 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 3324 value |= BWN_DMA32_RXENABLE; 3325 value |= BWN_DMA32_RXPARITY_DISABLE; 3326 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 3327 & BWN_DMA32_RXADDREXT_MASK; 3328 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 3329 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, addrlo); 3330 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 3331 sizeof(struct bwn_dmadesc32)); 3332 } 3333 } 3334 3335 static void 3336 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 3337 { 3338 3339 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 3340 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 3341 dr->dr_ring_dmap); 3342 } 3343 3344 static void 3345 bwn_dma_cleanup(struct bwn_dma_ring *dr) 3346 { 3347 3348 if (dr->dr_tx) { 3349 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 3350 if (dr->dr_type == BHND_DMA_ADDR_64BIT) { 3351 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 3352 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 3353 } else 3354 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 3355 } else { 3356 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 3357 if (dr->dr_type == BHND_DMA_ADDR_64BIT) { 3358 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 3359 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 3360 } else 3361 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 3362 } 3363 } 3364 3365 static void 3366 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 3367 { 3368 struct bwn_dmadesc_generic *desc; 3369 struct bwn_dmadesc_meta *meta; 3370 struct bwn_mac *mac = dr->dr_mac; 3371 struct bwn_dma *dma = &mac->mac_method.dma; 3372 struct bwn_softc *sc = mac->mac_sc; 3373 int i; 3374 3375 if (!dr->dr_usedslot) 3376 return; 3377 for (i = 0; i < dr->dr_numslots; i++) { 3378 dr->getdesc(dr, i, &desc, &meta); 3379 3380 if (meta->mt_m == NULL) { 3381 if (!dr->dr_tx) 3382 device_printf(sc->sc_dev, "%s: not TX?\n", 3383 __func__); 3384 continue; 3385 } 3386 if (dr->dr_tx) { 3387 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 3388 bus_dmamap_unload(dr->dr_txring_dtag, 3389 meta->mt_dmap); 3390 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 3391 bus_dmamap_unload(dma->txbuf_dtag, 3392 meta->mt_dmap); 3393 } else 3394 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 3395 bwn_dma_free_descbuf(dr, meta); 3396 } 3397 } 3398 3399 static int 3400 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 3401 int type) 3402 { 3403 struct bwn_softc *sc = mac->mac_sc; 3404 uint32_t value; 3405 int i; 3406 uint16_t offset; 3407 3408 for (i = 0; i < 10; i++) { 3409 offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_TXSTATUS : 3410 BWN_DMA32_TXSTATUS; 3411 value = BWN_READ_4(mac, base + offset); 3412 if (type == BHND_DMA_ADDR_64BIT) { 3413 value &= BWN_DMA64_TXSTAT; 3414 if (value == BWN_DMA64_TXSTAT_DISABLED || 3415 value == BWN_DMA64_TXSTAT_IDLEWAIT || 3416 value == BWN_DMA64_TXSTAT_STOPPED) 3417 break; 3418 } else { 3419 value &= BWN_DMA32_TXSTATE; 3420 if (value == BWN_DMA32_TXSTAT_DISABLED || 3421 value == BWN_DMA32_TXSTAT_IDLEWAIT || 3422 value == BWN_DMA32_TXSTAT_STOPPED) 3423 break; 3424 } 3425 DELAY(1000); 3426 } 3427 offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_TXCTL : 3428 BWN_DMA32_TXCTL; 3429 BWN_WRITE_4(mac, base + offset, 0); 3430 for (i = 0; i < 10; i++) { 3431 offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_TXSTATUS : 3432 BWN_DMA32_TXSTATUS; 3433 value = BWN_READ_4(mac, base + offset); 3434 if (type == BHND_DMA_ADDR_64BIT) { 3435 value &= BWN_DMA64_TXSTAT; 3436 if (value == BWN_DMA64_TXSTAT_DISABLED) { 3437 i = -1; 3438 break; 3439 } 3440 } else { 3441 value &= BWN_DMA32_TXSTATE; 3442 if (value == BWN_DMA32_TXSTAT_DISABLED) { 3443 i = -1; 3444 break; 3445 } 3446 } 3447 DELAY(1000); 3448 } 3449 if (i != -1) { 3450 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 3451 return (ENODEV); 3452 } 3453 DELAY(1000); 3454 3455 return (0); 3456 } 3457 3458 static int 3459 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 3460 int type) 3461 { 3462 struct bwn_softc *sc = mac->mac_sc; 3463 uint32_t value; 3464 int i; 3465 uint16_t offset; 3466 3467 offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_RXCTL : 3468 BWN_DMA32_RXCTL; 3469 BWN_WRITE_4(mac, base + offset, 0); 3470 for (i = 0; i < 10; i++) { 3471 offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_RXSTATUS : 3472 BWN_DMA32_RXSTATUS; 3473 value = BWN_READ_4(mac, base + offset); 3474 if (type == BHND_DMA_ADDR_64BIT) { 3475 value &= BWN_DMA64_RXSTAT; 3476 if (value == BWN_DMA64_RXSTAT_DISABLED) { 3477 i = -1; 3478 break; 3479 } 3480 } else { 3481 value &= BWN_DMA32_RXSTATE; 3482 if (value == BWN_DMA32_RXSTAT_DISABLED) { 3483 i = -1; 3484 break; 3485 } 3486 } 3487 DELAY(1000); 3488 } 3489 if (i != -1) { 3490 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 3491 return (ENODEV); 3492 } 3493 3494 return (0); 3495 } 3496 3497 static void 3498 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 3499 struct bwn_dmadesc_meta *meta) 3500 { 3501 3502 if (meta->mt_m != NULL) { 3503 m_freem(meta->mt_m); 3504 meta->mt_m = NULL; 3505 } 3506 if (meta->mt_ni != NULL) { 3507 ieee80211_free_node(meta->mt_ni); 3508 meta->mt_ni = NULL; 3509 } 3510 } 3511 3512 static void 3513 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 3514 { 3515 struct bwn_rxhdr4 *rxhdr; 3516 unsigned char *frame; 3517 3518 rxhdr = mtod(m, struct bwn_rxhdr4 *); 3519 rxhdr->frame_len = 0; 3520 3521 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 3522 sizeof(struct bwn_plcp6) + 2, 3523 ("%s:%d: fail", __func__, __LINE__)); 3524 frame = mtod(m, char *) + dr->dr_frameoffset; 3525 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 3526 } 3527 3528 static uint8_t 3529 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 3530 { 3531 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 3532 3533 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 3534 == 0xff); 3535 } 3536 3537 static void 3538 bwn_wme_init(struct bwn_mac *mac) 3539 { 3540 3541 bwn_wme_load(mac); 3542 3543 /* enable WME support. */ 3544 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 3545 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 3546 BWN_IFSCTL_USE_EDCF); 3547 } 3548 3549 static void 3550 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 3551 { 3552 struct bwn_softc *sc = mac->mac_sc; 3553 struct ieee80211com *ic = &sc->sc_ic; 3554 uint16_t delay; /* microsec */ 3555 3556 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 3557 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 3558 delay = 500; 3559 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 3560 delay = max(delay, (uint16_t)2400); 3561 3562 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 3563 } 3564 3565 static void 3566 bwn_bt_enable(struct bwn_mac *mac) 3567 { 3568 struct bwn_softc *sc = mac->mac_sc; 3569 uint64_t hf; 3570 3571 if (bwn_bluetooth == 0) 3572 return; 3573 if ((sc->sc_board_info.board_flags & BHND_BFL_BTCOEX) == 0) 3574 return; 3575 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 3576 return; 3577 3578 hf = bwn_hf_read(mac); 3579 if (sc->sc_board_info.board_flags & BHND_BFL_BTC2WIRE_ALTGPIO) 3580 hf |= BWN_HF_BT_COEXISTALT; 3581 else 3582 hf |= BWN_HF_BT_COEXIST; 3583 bwn_hf_write(mac, hf); 3584 } 3585 3586 static void 3587 bwn_set_macaddr(struct bwn_mac *mac) 3588 { 3589 3590 bwn_mac_write_bssid(mac); 3591 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, 3592 mac->mac_sc->sc_ic.ic_macaddr); 3593 } 3594 3595 static void 3596 bwn_clear_keys(struct bwn_mac *mac) 3597 { 3598 int i; 3599 3600 for (i = 0; i < mac->mac_max_nr_keys; i++) { 3601 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 3602 ("%s:%d: fail", __func__, __LINE__)); 3603 3604 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 3605 NULL, BWN_SEC_KEYSIZE, NULL); 3606 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 3607 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 3608 NULL, BWN_SEC_KEYSIZE, NULL); 3609 } 3610 mac->mac_key[i].keyconf = NULL; 3611 } 3612 } 3613 3614 static void 3615 bwn_crypt_init(struct bwn_mac *mac) 3616 { 3617 struct bwn_softc *sc = mac->mac_sc; 3618 3619 mac->mac_max_nr_keys = (bhnd_get_hwrev(sc->sc_dev) >= 5) ? 58 : 20; 3620 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 3621 ("%s:%d: fail", __func__, __LINE__)); 3622 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 3623 mac->mac_ktp *= 2; 3624 if (bhnd_get_hwrev(sc->sc_dev) >= 5) 3625 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 3626 bwn_clear_keys(mac); 3627 } 3628 3629 static void 3630 bwn_chip_exit(struct bwn_mac *mac) 3631 { 3632 bwn_phy_exit(mac); 3633 } 3634 3635 static int 3636 bwn_fw_fillinfo(struct bwn_mac *mac) 3637 { 3638 int error; 3639 3640 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 3641 if (error == 0) 3642 return (0); 3643 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 3644 if (error == 0) 3645 return (0); 3646 return (error); 3647 } 3648 3649 /** 3650 * Request that the GPIO controller tristate all pins set in @p mask, granting 3651 * the MAC core control over the pins. 3652 * 3653 * @param mac bwn MAC state. 3654 * @param pins If the bit position for a pin number is set to one, tristate the 3655 * pin. 3656 */ 3657 int 3658 bwn_gpio_control(struct bwn_mac *mac, uint32_t pins) 3659 { 3660 struct bwn_softc *sc; 3661 uint32_t flags[32]; 3662 int error; 3663 3664 sc = mac->mac_sc; 3665 3666 /* Determine desired pin flags */ 3667 for (size_t pin = 0; pin < nitems(flags); pin++) { 3668 uint32_t pinbit = (1 << pin); 3669 3670 if (pins & pinbit) { 3671 /* Tristate output */ 3672 flags[pin] = GPIO_PIN_OUTPUT|GPIO_PIN_TRISTATE; 3673 } else { 3674 /* Leave unmodified */ 3675 flags[pin] = 0; 3676 } 3677 } 3678 3679 /* Configure all pins */ 3680 error = GPIO_PIN_CONFIG_32(sc->sc_gpio, 0, nitems(flags), flags); 3681 if (error) { 3682 device_printf(sc->sc_dev, "error configuring %s pin flags: " 3683 "%d\n", device_get_nameunit(sc->sc_gpio), error); 3684 return (error); 3685 } 3686 3687 return (0); 3688 } 3689 3690 3691 static int 3692 bwn_gpio_init(struct bwn_mac *mac) 3693 { 3694 struct bwn_softc *sc; 3695 uint32_t pins; 3696 3697 sc = mac->mac_sc; 3698 3699 pins = 0xF; 3700 3701 BWN_WRITE_4(mac, BWN_MACCTL, 3702 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 3703 BWN_WRITE_2(mac, BWN_GPIO_MASK, 3704 BWN_READ_2(mac, BWN_GPIO_MASK) | pins); 3705 3706 if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL) { 3707 /* MAC core is responsible for toggling PAREF via gpio9 */ 3708 BWN_WRITE_2(mac, BWN_GPIO_MASK, 3709 BWN_READ_2(mac, BWN_GPIO_MASK) | BHND_GPIO_BOARD_PACTRL); 3710 3711 pins |= BHND_GPIO_BOARD_PACTRL; 3712 } 3713 3714 return (bwn_gpio_control(mac, pins)); 3715 } 3716 3717 static int 3718 bwn_fw_loadinitvals(struct bwn_mac *mac) 3719 { 3720 #define GETFWOFFSET(fwp, offset) \ 3721 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 3722 const size_t hdr_len = sizeof(struct bwn_fwhdr); 3723 const struct bwn_fwhdr *hdr; 3724 struct bwn_fw *fw = &mac->mac_fw; 3725 int error; 3726 3727 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 3728 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 3729 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 3730 if (error) 3731 return (error); 3732 if (fw->initvals_band.fw) { 3733 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 3734 error = bwn_fwinitvals_write(mac, 3735 GETFWOFFSET(fw->initvals_band, hdr_len), 3736 be32toh(hdr->size), 3737 fw->initvals_band.fw->datasize - hdr_len); 3738 } 3739 return (error); 3740 #undef GETFWOFFSET 3741 } 3742 3743 static int 3744 bwn_phy_init(struct bwn_mac *mac) 3745 { 3746 struct bwn_softc *sc = mac->mac_sc; 3747 int error; 3748 3749 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 3750 mac->mac_phy.rf_onoff(mac, 1); 3751 error = mac->mac_phy.init(mac); 3752 if (error) { 3753 device_printf(sc->sc_dev, "PHY init failed\n"); 3754 goto fail0; 3755 } 3756 error = bwn_switch_channel(mac, 3757 mac->mac_phy.get_default_chan(mac)); 3758 if (error) { 3759 device_printf(sc->sc_dev, 3760 "failed to switch default channel\n"); 3761 goto fail1; 3762 } 3763 return (0); 3764 fail1: 3765 if (mac->mac_phy.exit) 3766 mac->mac_phy.exit(mac); 3767 fail0: 3768 mac->mac_phy.rf_onoff(mac, 0); 3769 3770 return (error); 3771 } 3772 3773 static void 3774 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 3775 { 3776 uint16_t ant; 3777 uint16_t tmp; 3778 3779 ant = bwn_ant2phy(antenna); 3780 3781 /* For ACK/CTS */ 3782 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 3783 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 3784 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 3785 /* For Probe Resposes */ 3786 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 3787 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 3788 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 3789 } 3790 3791 static void 3792 bwn_set_opmode(struct bwn_mac *mac) 3793 { 3794 struct bwn_softc *sc = mac->mac_sc; 3795 struct ieee80211com *ic = &sc->sc_ic; 3796 uint32_t ctl; 3797 uint16_t cfp_pretbtt; 3798 3799 ctl = BWN_READ_4(mac, BWN_MACCTL); 3800 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 3801 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 3802 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 3803 ctl |= BWN_MACCTL_STA; 3804 3805 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 3806 ic->ic_opmode == IEEE80211_M_MBSS) 3807 ctl |= BWN_MACCTL_HOSTAP; 3808 else if (ic->ic_opmode == IEEE80211_M_IBSS) 3809 ctl &= ~BWN_MACCTL_STA; 3810 ctl |= sc->sc_filters; 3811 3812 if (bhnd_get_hwrev(sc->sc_dev) <= 4) 3813 ctl |= BWN_MACCTL_PROMISC; 3814 3815 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 3816 3817 cfp_pretbtt = 2; 3818 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 3819 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4306 && 3820 sc->sc_cid.chip_rev == 3) 3821 cfp_pretbtt = 100; 3822 else 3823 cfp_pretbtt = 50; 3824 } 3825 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 3826 } 3827 3828 static void 3829 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 3830 { 3831 if (!error) { 3832 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 3833 *((bus_addr_t *)arg) = seg->ds_addr; 3834 } 3835 } 3836 3837 void 3838 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 3839 { 3840 struct bwn_phy *phy = &mac->mac_phy; 3841 struct bwn_softc *sc = mac->mac_sc; 3842 unsigned int i, max_loop; 3843 uint16_t value; 3844 uint32_t buffer[5] = { 3845 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 3846 }; 3847 3848 if (ofdm) { 3849 max_loop = 0x1e; 3850 buffer[0] = 0x000201cc; 3851 } else { 3852 max_loop = 0xfa; 3853 buffer[0] = 0x000b846e; 3854 } 3855 3856 BWN_ASSERT_LOCKED(mac->mac_sc); 3857 3858 for (i = 0; i < 5; i++) 3859 bwn_ram_write(mac, i * 4, buffer[i]); 3860 3861 BWN_WRITE_2(mac, 0x0568, 0x0000); 3862 BWN_WRITE_2(mac, 0x07c0, 3863 (bhnd_get_hwrev(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 3864 3865 value = (ofdm ? 0x41 : 0x40); 3866 BWN_WRITE_2(mac, 0x050c, value); 3867 3868 if (phy->type == BWN_PHYTYPE_N || phy->type == BWN_PHYTYPE_LP || 3869 phy->type == BWN_PHYTYPE_LCN) 3870 BWN_WRITE_2(mac, 0x0514, 0x1a02); 3871 BWN_WRITE_2(mac, 0x0508, 0x0000); 3872 BWN_WRITE_2(mac, 0x050a, 0x0000); 3873 BWN_WRITE_2(mac, 0x054c, 0x0000); 3874 BWN_WRITE_2(mac, 0x056a, 0x0014); 3875 BWN_WRITE_2(mac, 0x0568, 0x0826); 3876 BWN_WRITE_2(mac, 0x0500, 0x0000); 3877 3878 /* XXX TODO: n phy pa override? */ 3879 3880 switch (phy->type) { 3881 case BWN_PHYTYPE_N: 3882 case BWN_PHYTYPE_LCN: 3883 BWN_WRITE_2(mac, 0x0502, 0x00d0); 3884 break; 3885 case BWN_PHYTYPE_LP: 3886 BWN_WRITE_2(mac, 0x0502, 0x0050); 3887 break; 3888 default: 3889 BWN_WRITE_2(mac, 0x0502, 0x0030); 3890 break; 3891 } 3892 3893 /* flush */ 3894 BWN_READ_2(mac, 0x0502); 3895 3896 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 3897 BWN_RF_WRITE(mac, 0x0051, 0x0017); 3898 for (i = 0x00; i < max_loop; i++) { 3899 value = BWN_READ_2(mac, 0x050e); 3900 if (value & 0x0080) 3901 break; 3902 DELAY(10); 3903 } 3904 for (i = 0x00; i < 0x0a; i++) { 3905 value = BWN_READ_2(mac, 0x050e); 3906 if (value & 0x0400) 3907 break; 3908 DELAY(10); 3909 } 3910 for (i = 0x00; i < 0x19; i++) { 3911 value = BWN_READ_2(mac, 0x0690); 3912 if (!(value & 0x0100)) 3913 break; 3914 DELAY(10); 3915 } 3916 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 3917 BWN_RF_WRITE(mac, 0x0051, 0x0037); 3918 } 3919 3920 void 3921 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 3922 { 3923 uint32_t macctl; 3924 3925 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 3926 3927 macctl = BWN_READ_4(mac, BWN_MACCTL); 3928 if (macctl & BWN_MACCTL_BIGENDIAN) 3929 printf("TODO: need swap\n"); 3930 3931 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 3932 BWN_BARRIER(mac, BWN_RAM_CONTROL, 4, BUS_SPACE_BARRIER_WRITE); 3933 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 3934 } 3935 3936 void 3937 bwn_mac_suspend(struct bwn_mac *mac) 3938 { 3939 struct bwn_softc *sc = mac->mac_sc; 3940 int i; 3941 uint32_t tmp; 3942 3943 KASSERT(mac->mac_suspended >= 0, 3944 ("%s:%d: fail", __func__, __LINE__)); 3945 3946 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: suspended=%d\n", 3947 __func__, mac->mac_suspended); 3948 3949 if (mac->mac_suspended == 0) { 3950 bwn_psctl(mac, BWN_PS_AWAKE); 3951 BWN_WRITE_4(mac, BWN_MACCTL, 3952 BWN_READ_4(mac, BWN_MACCTL) 3953 & ~BWN_MACCTL_ON); 3954 BWN_READ_4(mac, BWN_MACCTL); 3955 for (i = 35; i; i--) { 3956 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 3957 if (tmp & BWN_INTR_MAC_SUSPENDED) 3958 goto out; 3959 DELAY(10); 3960 } 3961 for (i = 40; i; i--) { 3962 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 3963 if (tmp & BWN_INTR_MAC_SUSPENDED) 3964 goto out; 3965 DELAY(1000); 3966 } 3967 device_printf(sc->sc_dev, "MAC suspend failed\n"); 3968 } 3969 out: 3970 mac->mac_suspended++; 3971 } 3972 3973 void 3974 bwn_mac_enable(struct bwn_mac *mac) 3975 { 3976 struct bwn_softc *sc = mac->mac_sc; 3977 uint16_t state; 3978 3979 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: suspended=%d\n", 3980 __func__, mac->mac_suspended); 3981 3982 state = bwn_shm_read_2(mac, BWN_SHARED, 3983 BWN_SHARED_UCODESTAT); 3984 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 3985 state != BWN_SHARED_UCODESTAT_SLEEP) { 3986 DPRINTF(sc, BWN_DEBUG_FW, 3987 "%s: warn: firmware state (%d)\n", 3988 __func__, state); 3989 } 3990 3991 mac->mac_suspended--; 3992 KASSERT(mac->mac_suspended >= 0, 3993 ("%s:%d: fail", __func__, __LINE__)); 3994 if (mac->mac_suspended == 0) { 3995 BWN_WRITE_4(mac, BWN_MACCTL, 3996 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 3997 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 3998 BWN_READ_4(mac, BWN_MACCTL); 3999 BWN_READ_4(mac, BWN_INTR_REASON); 4000 bwn_psctl(mac, 0); 4001 } 4002 } 4003 4004 void 4005 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 4006 { 4007 struct bwn_softc *sc = mac->mac_sc; 4008 int i; 4009 uint16_t ucstat; 4010 4011 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 4012 ("%s:%d: fail", __func__, __LINE__)); 4013 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 4014 ("%s:%d: fail", __func__, __LINE__)); 4015 4016 /* XXX forcibly awake and hwps-off */ 4017 4018 BWN_WRITE_4(mac, BWN_MACCTL, 4019 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 4020 ~BWN_MACCTL_HWPS); 4021 BWN_READ_4(mac, BWN_MACCTL); 4022 if (bhnd_get_hwrev(sc->sc_dev) >= 5) { 4023 for (i = 0; i < 100; i++) { 4024 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 4025 BWN_SHARED_UCODESTAT); 4026 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 4027 break; 4028 DELAY(10); 4029 } 4030 } 4031 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: ucstat=%d\n", __func__, 4032 ucstat); 4033 } 4034 4035 static int 4036 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 4037 { 4038 struct bwn_softc *sc = mac->mac_sc; 4039 struct bwn_fw *fw = &mac->mac_fw; 4040 const uint8_t rev = bhnd_get_hwrev(sc->sc_dev); 4041 const char *filename; 4042 uint16_t iost; 4043 int error; 4044 4045 /* microcode */ 4046 filename = NULL; 4047 switch (rev) { 4048 case 42: 4049 if (mac->mac_phy.type == BWN_PHYTYPE_AC) 4050 filename = "ucode42"; 4051 break; 4052 case 40: 4053 if (mac->mac_phy.type == BWN_PHYTYPE_AC) 4054 filename = "ucode40"; 4055 break; 4056 case 33: 4057 if (mac->mac_phy.type == BWN_PHYTYPE_LCN40) 4058 filename = "ucode33_lcn40"; 4059 break; 4060 case 30: 4061 if (mac->mac_phy.type == BWN_PHYTYPE_N) 4062 filename = "ucode30_mimo"; 4063 break; 4064 case 29: 4065 if (mac->mac_phy.type == BWN_PHYTYPE_HT) 4066 filename = "ucode29_mimo"; 4067 break; 4068 case 26: 4069 if (mac->mac_phy.type == BWN_PHYTYPE_HT) 4070 filename = "ucode26_mimo"; 4071 break; 4072 case 28: 4073 case 25: 4074 if (mac->mac_phy.type == BWN_PHYTYPE_N) 4075 filename = "ucode25_mimo"; 4076 else if (mac->mac_phy.type == BWN_PHYTYPE_LCN) 4077 filename = "ucode25_lcn"; 4078 break; 4079 case 24: 4080 if (mac->mac_phy.type == BWN_PHYTYPE_LCN) 4081 filename = "ucode24_lcn"; 4082 break; 4083 case 23: 4084 if (mac->mac_phy.type == BWN_PHYTYPE_N) 4085 filename = "ucode16_mimo"; 4086 break; 4087 case 16: 4088 case 17: 4089 case 18: 4090 case 19: 4091 if (mac->mac_phy.type == BWN_PHYTYPE_N) 4092 filename = "ucode16_mimo"; 4093 else if (mac->mac_phy.type == BWN_PHYTYPE_LP) 4094 filename = "ucode16_lp"; 4095 break; 4096 case 15: 4097 filename = "ucode15"; 4098 break; 4099 case 14: 4100 filename = "ucode14"; 4101 break; 4102 case 13: 4103 filename = "ucode13"; 4104 break; 4105 case 12: 4106 case 11: 4107 filename = "ucode11"; 4108 break; 4109 case 10: 4110 case 9: 4111 case 8: 4112 case 7: 4113 case 6: 4114 case 5: 4115 filename = "ucode5"; 4116 break; 4117 default: 4118 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 4119 bwn_release_firmware(mac); 4120 return (EOPNOTSUPP); 4121 } 4122 4123 device_printf(sc->sc_dev, "ucode fw: %s\n", filename); 4124 error = bwn_fw_get(mac, type, filename, &fw->ucode); 4125 if (error) { 4126 bwn_release_firmware(mac); 4127 return (error); 4128 } 4129 4130 /* PCM */ 4131 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 4132 if (rev >= 5 && rev <= 10) { 4133 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 4134 if (error == ENOENT) 4135 fw->no_pcmfile = 1; 4136 else if (error) { 4137 bwn_release_firmware(mac); 4138 return (error); 4139 } 4140 } else if (rev < 11) { 4141 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 4142 bwn_release_firmware(mac); 4143 return (EOPNOTSUPP); 4144 } 4145 4146 /* initvals */ 4147 error = bhnd_read_iost(sc->sc_dev, &iost); 4148 if (error) 4149 goto fail1; 4150 4151 switch (mac->mac_phy.type) { 4152 case BWN_PHYTYPE_A: 4153 if (rev < 5 || rev > 10) 4154 goto fail1; 4155 if (iost & BWN_IOST_HAVE_2GHZ) 4156 filename = "a0g1initvals5"; 4157 else 4158 filename = "a0g0initvals5"; 4159 break; 4160 case BWN_PHYTYPE_G: 4161 if (rev >= 5 && rev <= 10) 4162 filename = "b0g0initvals5"; 4163 else if (rev >= 13) 4164 filename = "b0g0initvals13"; 4165 else 4166 goto fail1; 4167 break; 4168 case BWN_PHYTYPE_LP: 4169 if (rev == 13) 4170 filename = "lp0initvals13"; 4171 else if (rev == 14) 4172 filename = "lp0initvals14"; 4173 else if (rev >= 15) 4174 filename = "lp0initvals15"; 4175 else 4176 goto fail1; 4177 break; 4178 case BWN_PHYTYPE_N: 4179 if (rev == 30) 4180 filename = "n16initvals30"; 4181 else if (rev == 28 || rev == 25) 4182 filename = "n0initvals25"; 4183 else if (rev == 24) 4184 filename = "n0initvals24"; 4185 else if (rev == 23) 4186 filename = "n0initvals16"; 4187 else if (rev >= 16 && rev <= 18) 4188 filename = "n0initvals16"; 4189 else if (rev >= 11 && rev <= 12) 4190 filename = "n0initvals11"; 4191 else 4192 goto fail1; 4193 break; 4194 default: 4195 goto fail1; 4196 } 4197 error = bwn_fw_get(mac, type, filename, &fw->initvals); 4198 if (error) { 4199 bwn_release_firmware(mac); 4200 return (error); 4201 } 4202 4203 /* bandswitch initvals */ 4204 switch (mac->mac_phy.type) { 4205 case BWN_PHYTYPE_A: 4206 if (rev >= 5 && rev <= 10) { 4207 if (iost & BWN_IOST_HAVE_2GHZ) 4208 filename = "a0g1bsinitvals5"; 4209 else 4210 filename = "a0g0bsinitvals5"; 4211 } else if (rev >= 11) 4212 filename = NULL; 4213 else 4214 goto fail1; 4215 break; 4216 case BWN_PHYTYPE_G: 4217 if (rev >= 5 && rev <= 10) 4218 filename = "b0g0bsinitvals5"; 4219 else if (rev >= 11) 4220 filename = NULL; 4221 else 4222 goto fail1; 4223 break; 4224 case BWN_PHYTYPE_LP: 4225 if (rev == 13) 4226 filename = "lp0bsinitvals13"; 4227 else if (rev == 14) 4228 filename = "lp0bsinitvals14"; 4229 else if (rev >= 15) 4230 filename = "lp0bsinitvals15"; 4231 else 4232 goto fail1; 4233 break; 4234 case BWN_PHYTYPE_N: 4235 if (rev == 30) 4236 filename = "n16bsinitvals30"; 4237 else if (rev == 28 || rev == 25) 4238 filename = "n0bsinitvals25"; 4239 else if (rev == 24) 4240 filename = "n0bsinitvals24"; 4241 else if (rev == 23) 4242 filename = "n0bsinitvals16"; 4243 else if (rev >= 16 && rev <= 18) 4244 filename = "n0bsinitvals16"; 4245 else if (rev >= 11 && rev <= 12) 4246 filename = "n0bsinitvals11"; 4247 else 4248 goto fail1; 4249 break; 4250 default: 4251 device_printf(sc->sc_dev, "unknown phy (%d)\n", 4252 mac->mac_phy.type); 4253 goto fail1; 4254 } 4255 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 4256 if (error) { 4257 bwn_release_firmware(mac); 4258 return (error); 4259 } 4260 return (0); 4261 fail1: 4262 device_printf(sc->sc_dev, "no INITVALS for rev %d, phy.type %d\n", 4263 rev, mac->mac_phy.type); 4264 bwn_release_firmware(mac); 4265 return (EOPNOTSUPP); 4266 } 4267 4268 static int 4269 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 4270 const char *name, struct bwn_fwfile *bfw) 4271 { 4272 const struct bwn_fwhdr *hdr; 4273 struct bwn_softc *sc = mac->mac_sc; 4274 const struct firmware *fw; 4275 char namebuf[64]; 4276 4277 if (name == NULL) { 4278 bwn_do_release_fw(bfw); 4279 return (0); 4280 } 4281 if (bfw->filename != NULL) { 4282 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 4283 return (0); 4284 bwn_do_release_fw(bfw); 4285 } 4286 4287 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 4288 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 4289 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 4290 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 4291 fw = firmware_get(namebuf); 4292 if (fw == NULL) { 4293 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 4294 namebuf); 4295 return (ENOENT); 4296 } 4297 if (fw->datasize < sizeof(struct bwn_fwhdr)) 4298 goto fail; 4299 hdr = (const struct bwn_fwhdr *)(fw->data); 4300 switch (hdr->type) { 4301 case BWN_FWTYPE_UCODE: 4302 case BWN_FWTYPE_PCM: 4303 if (be32toh(hdr->size) != 4304 (fw->datasize - sizeof(struct bwn_fwhdr))) 4305 goto fail; 4306 /* FALLTHROUGH */ 4307 case BWN_FWTYPE_IV: 4308 if (hdr->ver != 1) 4309 goto fail; 4310 break; 4311 default: 4312 goto fail; 4313 } 4314 bfw->filename = name; 4315 bfw->fw = fw; 4316 bfw->type = type; 4317 return (0); 4318 fail: 4319 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 4320 if (fw != NULL) 4321 firmware_put(fw, FIRMWARE_UNLOAD); 4322 return (EPROTO); 4323 } 4324 4325 static void 4326 bwn_release_firmware(struct bwn_mac *mac) 4327 { 4328 4329 bwn_do_release_fw(&mac->mac_fw.ucode); 4330 bwn_do_release_fw(&mac->mac_fw.pcm); 4331 bwn_do_release_fw(&mac->mac_fw.initvals); 4332 bwn_do_release_fw(&mac->mac_fw.initvals_band); 4333 } 4334 4335 static void 4336 bwn_do_release_fw(struct bwn_fwfile *bfw) 4337 { 4338 4339 if (bfw->fw != NULL) 4340 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 4341 bfw->fw = NULL; 4342 bfw->filename = NULL; 4343 } 4344 4345 static int 4346 bwn_fw_loaducode(struct bwn_mac *mac) 4347 { 4348 #define GETFWOFFSET(fwp, offset) \ 4349 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 4350 #define GETFWSIZE(fwp, offset) \ 4351 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 4352 struct bwn_softc *sc = mac->mac_sc; 4353 const uint32_t *data; 4354 unsigned int i; 4355 uint32_t ctl; 4356 uint16_t date, fwcaps, time; 4357 int error = 0; 4358 4359 ctl = BWN_READ_4(mac, BWN_MACCTL); 4360 ctl |= BWN_MACCTL_MCODE_JMP0; 4361 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 4362 __LINE__)); 4363 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4364 for (i = 0; i < 64; i++) 4365 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 4366 for (i = 0; i < 4096; i += 2) 4367 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 4368 4369 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 4370 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 4371 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 4372 i++) { 4373 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 4374 DELAY(10); 4375 } 4376 4377 if (mac->mac_fw.pcm.fw) { 4378 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 4379 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 4380 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 4381 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 4382 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 4383 sizeof(struct bwn_fwhdr)); i++) { 4384 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 4385 DELAY(10); 4386 } 4387 } 4388 4389 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 4390 BWN_WRITE_4(mac, BWN_MACCTL, 4391 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 4392 BWN_MACCTL_MCODE_RUN); 4393 4394 for (i = 0; i < 21; i++) { 4395 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 4396 break; 4397 if (i >= 20) { 4398 device_printf(sc->sc_dev, "ucode timeout\n"); 4399 error = ENXIO; 4400 goto error; 4401 } 4402 DELAY(50000); 4403 } 4404 BWN_READ_4(mac, BWN_INTR_REASON); 4405 4406 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 4407 if (mac->mac_fw.rev <= 0x128) { 4408 device_printf(sc->sc_dev, "the firmware is too old\n"); 4409 error = EOPNOTSUPP; 4410 goto error; 4411 } 4412 4413 /* 4414 * Determine firmware header version; needed for TX/RX packet 4415 * handling. 4416 */ 4417 if (mac->mac_fw.rev >= 598) 4418 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_598; 4419 else if (mac->mac_fw.rev >= 410) 4420 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_410; 4421 else 4422 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_351; 4423 4424 /* 4425 * We don't support rev 598 or later; that requires 4426 * another round of changes to the TX/RX descriptor 4427 * and status layout. 4428 * 4429 * So, complain this is the case and exit out, rather 4430 * than attaching and then failing. 4431 */ 4432 #if 0 4433 if (mac->mac_fw.fw_hdr_format == BWN_FW_HDR_598) { 4434 device_printf(sc->sc_dev, 4435 "firmware is too new (>=598); not supported\n"); 4436 error = EOPNOTSUPP; 4437 goto error; 4438 } 4439 #endif 4440 4441 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 4442 BWN_SHARED_UCODE_PATCH); 4443 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 4444 mac->mac_fw.opensource = (date == 0xffff); 4445 if (bwn_wme != 0) 4446 mac->mac_flags |= BWN_MAC_FLAG_WME; 4447 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 4448 4449 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 4450 if (mac->mac_fw.opensource == 0) { 4451 device_printf(sc->sc_dev, 4452 "firmware version (rev %u patch %u date %#x time %#x)\n", 4453 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 4454 if (mac->mac_fw.no_pcmfile) 4455 device_printf(sc->sc_dev, 4456 "no HW crypto acceleration due to pcm5\n"); 4457 } else { 4458 mac->mac_fw.patch = time; 4459 fwcaps = bwn_fwcaps_read(mac); 4460 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 4461 device_printf(sc->sc_dev, 4462 "disabling HW crypto acceleration\n"); 4463 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 4464 } 4465 if (!(fwcaps & BWN_FWCAPS_WME)) { 4466 device_printf(sc->sc_dev, "disabling WME support\n"); 4467 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 4468 } 4469 } 4470 4471 if (BWN_ISOLDFMT(mac)) 4472 device_printf(sc->sc_dev, "using old firmware image\n"); 4473 4474 return (0); 4475 4476 error: 4477 BWN_WRITE_4(mac, BWN_MACCTL, 4478 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 4479 BWN_MACCTL_MCODE_JMP0); 4480 4481 return (error); 4482 #undef GETFWSIZE 4483 #undef GETFWOFFSET 4484 } 4485 4486 /* OpenFirmware only */ 4487 static uint16_t 4488 bwn_fwcaps_read(struct bwn_mac *mac) 4489 { 4490 4491 KASSERT(mac->mac_fw.opensource == 1, 4492 ("%s:%d: fail", __func__, __LINE__)); 4493 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 4494 } 4495 4496 static int 4497 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 4498 size_t count, size_t array_size) 4499 { 4500 #define GET_NEXTIV16(iv) \ 4501 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 4502 sizeof(uint16_t) + sizeof(uint16_t))) 4503 #define GET_NEXTIV32(iv) \ 4504 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 4505 sizeof(uint16_t) + sizeof(uint32_t))) 4506 struct bwn_softc *sc = mac->mac_sc; 4507 const struct bwn_fwinitvals *iv; 4508 uint16_t offset; 4509 size_t i; 4510 uint8_t bit32; 4511 4512 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 4513 ("%s:%d: fail", __func__, __LINE__)); 4514 iv = ivals; 4515 for (i = 0; i < count; i++) { 4516 if (array_size < sizeof(iv->offset_size)) 4517 goto fail; 4518 array_size -= sizeof(iv->offset_size); 4519 offset = be16toh(iv->offset_size); 4520 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 4521 offset &= BWN_FWINITVALS_OFFSET_MASK; 4522 if (offset >= 0x1000) 4523 goto fail; 4524 if (bit32) { 4525 if (array_size < sizeof(iv->data.d32)) 4526 goto fail; 4527 array_size -= sizeof(iv->data.d32); 4528 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 4529 iv = GET_NEXTIV32(iv); 4530 } else { 4531 4532 if (array_size < sizeof(iv->data.d16)) 4533 goto fail; 4534 array_size -= sizeof(iv->data.d16); 4535 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 4536 4537 iv = GET_NEXTIV16(iv); 4538 } 4539 } 4540 if (array_size != 0) 4541 goto fail; 4542 return (0); 4543 fail: 4544 device_printf(sc->sc_dev, "initvals: invalid format\n"); 4545 return (EPROTO); 4546 #undef GET_NEXTIV16 4547 #undef GET_NEXTIV32 4548 } 4549 4550 int 4551 bwn_switch_channel(struct bwn_mac *mac, int chan) 4552 { 4553 struct bwn_phy *phy = &(mac->mac_phy); 4554 struct bwn_softc *sc = mac->mac_sc; 4555 struct ieee80211com *ic = &sc->sc_ic; 4556 uint16_t channelcookie, savedcookie; 4557 int error; 4558 4559 if (chan == 0xffff) 4560 chan = phy->get_default_chan(mac); 4561 4562 channelcookie = chan; 4563 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 4564 channelcookie |= 0x100; 4565 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 4566 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 4567 error = phy->switch_channel(mac, chan); 4568 if (error) 4569 goto fail; 4570 4571 mac->mac_phy.chan = chan; 4572 DELAY(8000); 4573 return (0); 4574 fail: 4575 device_printf(sc->sc_dev, "failed to switch channel\n"); 4576 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 4577 return (error); 4578 } 4579 4580 static uint16_t 4581 bwn_ant2phy(int antenna) 4582 { 4583 4584 switch (antenna) { 4585 case BWN_ANT0: 4586 return (BWN_TX_PHY_ANT0); 4587 case BWN_ANT1: 4588 return (BWN_TX_PHY_ANT1); 4589 case BWN_ANT2: 4590 return (BWN_TX_PHY_ANT2); 4591 case BWN_ANT3: 4592 return (BWN_TX_PHY_ANT3); 4593 case BWN_ANTAUTO: 4594 return (BWN_TX_PHY_ANT01AUTO); 4595 } 4596 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 4597 return (0); 4598 } 4599 4600 static void 4601 bwn_wme_load(struct bwn_mac *mac) 4602 { 4603 struct bwn_softc *sc = mac->mac_sc; 4604 int i; 4605 4606 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 4607 ("%s:%d: fail", __func__, __LINE__)); 4608 4609 bwn_mac_suspend(mac); 4610 for (i = 0; i < N(sc->sc_wmeParams); i++) 4611 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 4612 bwn_wme_shm_offsets[i]); 4613 bwn_mac_enable(mac); 4614 } 4615 4616 static void 4617 bwn_wme_loadparams(struct bwn_mac *mac, 4618 const struct wmeParams *p, uint16_t shm_offset) 4619 { 4620 #define SM(_v, _f) (((_v) << _f##_S) & _f) 4621 struct bwn_softc *sc = mac->mac_sc; 4622 uint16_t params[BWN_NR_WMEPARAMS]; 4623 int slot, tmp; 4624 unsigned int i; 4625 4626 slot = BWN_READ_2(mac, BWN_RNG) & 4627 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 4628 4629 memset(¶ms, 0, sizeof(params)); 4630 4631 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 4632 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 4633 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 4634 4635 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 4636 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 4637 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 4638 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 4639 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 4640 params[BWN_WMEPARAM_BSLOTS] = slot; 4641 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 4642 4643 for (i = 0; i < N(params); i++) { 4644 if (i == BWN_WMEPARAM_STATUS) { 4645 tmp = bwn_shm_read_2(mac, BWN_SHARED, 4646 shm_offset + (i * 2)); 4647 tmp |= 0x100; 4648 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 4649 tmp); 4650 } else { 4651 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 4652 params[i]); 4653 } 4654 } 4655 } 4656 4657 static void 4658 bwn_mac_write_bssid(struct bwn_mac *mac) 4659 { 4660 struct bwn_softc *sc = mac->mac_sc; 4661 uint32_t tmp; 4662 int i; 4663 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 4664 4665 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 4666 memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN); 4667 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 4668 IEEE80211_ADDR_LEN); 4669 4670 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 4671 tmp = (uint32_t) (mac_bssid[i + 0]); 4672 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 4673 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 4674 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 4675 bwn_ram_write(mac, 0x20 + i, tmp); 4676 } 4677 } 4678 4679 static void 4680 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 4681 const uint8_t *macaddr) 4682 { 4683 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 4684 uint16_t data; 4685 4686 if (!mac) 4687 macaddr = zero; 4688 4689 offset |= 0x0020; 4690 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 4691 4692 data = macaddr[0]; 4693 data |= macaddr[1] << 8; 4694 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 4695 data = macaddr[2]; 4696 data |= macaddr[3] << 8; 4697 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 4698 data = macaddr[4]; 4699 data |= macaddr[5] << 8; 4700 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 4701 } 4702 4703 static void 4704 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 4705 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 4706 { 4707 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 4708 uint8_t per_sta_keys_start = 8; 4709 4710 if (BWN_SEC_NEWAPI(mac)) 4711 per_sta_keys_start = 4; 4712 4713 KASSERT(index < mac->mac_max_nr_keys, 4714 ("%s:%d: fail", __func__, __LINE__)); 4715 KASSERT(key_len <= BWN_SEC_KEYSIZE, 4716 ("%s:%d: fail", __func__, __LINE__)); 4717 4718 if (index >= per_sta_keys_start) 4719 bwn_key_macwrite(mac, index, NULL); 4720 if (key) 4721 memcpy(buf, key, key_len); 4722 bwn_key_write(mac, index, algorithm, buf); 4723 if (index >= per_sta_keys_start) 4724 bwn_key_macwrite(mac, index, mac_addr); 4725 4726 mac->mac_key[index].algorithm = algorithm; 4727 } 4728 4729 static void 4730 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 4731 { 4732 struct bwn_softc *sc = mac->mac_sc; 4733 uint32_t addrtmp[2] = { 0, 0 }; 4734 uint8_t start = 8; 4735 4736 if (BWN_SEC_NEWAPI(mac)) 4737 start = 4; 4738 4739 KASSERT(index >= start, 4740 ("%s:%d: fail", __func__, __LINE__)); 4741 index -= start; 4742 4743 if (addr) { 4744 addrtmp[0] = addr[0]; 4745 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 4746 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 4747 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 4748 addrtmp[1] = addr[4]; 4749 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 4750 } 4751 4752 if (bhnd_get_hwrev(sc->sc_dev) >= 5) { 4753 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 4754 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 4755 } else { 4756 if (index >= 8) { 4757 bwn_shm_write_4(mac, BWN_SHARED, 4758 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 4759 bwn_shm_write_2(mac, BWN_SHARED, 4760 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 4761 } 4762 } 4763 } 4764 4765 static void 4766 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 4767 const uint8_t *key) 4768 { 4769 unsigned int i; 4770 uint32_t offset; 4771 uint16_t kidx, value; 4772 4773 kidx = BWN_SEC_KEY2FW(mac, index); 4774 bwn_shm_write_2(mac, BWN_SHARED, 4775 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 4776 4777 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 4778 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 4779 value = key[i]; 4780 value |= (uint16_t)(key[i + 1]) << 8; 4781 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 4782 } 4783 } 4784 4785 static void 4786 bwn_phy_exit(struct bwn_mac *mac) 4787 { 4788 4789 mac->mac_phy.rf_onoff(mac, 0); 4790 if (mac->mac_phy.exit != NULL) 4791 mac->mac_phy.exit(mac); 4792 } 4793 4794 static void 4795 bwn_dma_free(struct bwn_mac *mac) 4796 { 4797 struct bwn_dma *dma; 4798 4799 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 4800 return; 4801 dma = &mac->mac_method.dma; 4802 4803 bwn_dma_ringfree(&dma->rx); 4804 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 4805 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 4806 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 4807 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 4808 bwn_dma_ringfree(&dma->mcast); 4809 } 4810 4811 static void 4812 bwn_core_stop(struct bwn_mac *mac) 4813 { 4814 struct bwn_softc *sc = mac->mac_sc; 4815 4816 BWN_ASSERT_LOCKED(sc); 4817 4818 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 4819 return; 4820 4821 callout_stop(&sc->sc_rfswitch_ch); 4822 callout_stop(&sc->sc_task_ch); 4823 callout_stop(&sc->sc_watchdog_ch); 4824 sc->sc_watchdog_timer = 0; 4825 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 4826 BWN_READ_4(mac, BWN_INTR_MASK); 4827 bwn_mac_suspend(mac); 4828 4829 mac->mac_status = BWN_MAC_STATUS_INITED; 4830 } 4831 4832 static int 4833 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 4834 { 4835 struct bwn_mac *up_dev = NULL; 4836 struct bwn_mac *down_dev; 4837 struct bwn_mac *mac; 4838 int err, status; 4839 uint8_t gmode; 4840 4841 BWN_ASSERT_LOCKED(sc); 4842 4843 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 4844 if (IEEE80211_IS_CHAN_2GHZ(chan) && 4845 mac->mac_phy.supports_2ghz) { 4846 up_dev = mac; 4847 gmode = 1; 4848 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 4849 mac->mac_phy.supports_5ghz) { 4850 up_dev = mac; 4851 gmode = 0; 4852 } else { 4853 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 4854 return (EINVAL); 4855 } 4856 if (up_dev != NULL) 4857 break; 4858 } 4859 if (up_dev == NULL) { 4860 device_printf(sc->sc_dev, "Could not find a device\n"); 4861 return (ENODEV); 4862 } 4863 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 4864 return (0); 4865 4866 DPRINTF(sc, BWN_DEBUG_RF | BWN_DEBUG_PHY | BWN_DEBUG_RESET, 4867 "switching to %s-GHz band\n", 4868 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 4869 4870 down_dev = sc->sc_curmac; 4871 status = down_dev->mac_status; 4872 if (status >= BWN_MAC_STATUS_STARTED) 4873 bwn_core_stop(down_dev); 4874 if (status >= BWN_MAC_STATUS_INITED) 4875 bwn_core_exit(down_dev); 4876 4877 if (down_dev != up_dev) { 4878 err = bwn_phy_reset(down_dev); 4879 if (err) 4880 goto fail; 4881 } 4882 4883 up_dev->mac_phy.gmode = gmode; 4884 if (status >= BWN_MAC_STATUS_INITED) { 4885 err = bwn_core_init(up_dev); 4886 if (err) { 4887 device_printf(sc->sc_dev, 4888 "fatal: failed to initialize for %s-GHz\n", 4889 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 4890 goto fail; 4891 } 4892 } 4893 if (status >= BWN_MAC_STATUS_STARTED) 4894 bwn_core_start(up_dev); 4895 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 4896 sc->sc_curmac = up_dev; 4897 4898 return (0); 4899 fail: 4900 sc->sc_curmac = NULL; 4901 return (err); 4902 } 4903 4904 static void 4905 bwn_rf_turnon(struct bwn_mac *mac) 4906 { 4907 4908 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__); 4909 4910 bwn_mac_suspend(mac); 4911 mac->mac_phy.rf_onoff(mac, 1); 4912 mac->mac_phy.rf_on = 1; 4913 bwn_mac_enable(mac); 4914 } 4915 4916 static void 4917 bwn_rf_turnoff(struct bwn_mac *mac) 4918 { 4919 4920 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__); 4921 4922 bwn_mac_suspend(mac); 4923 mac->mac_phy.rf_onoff(mac, 0); 4924 mac->mac_phy.rf_on = 0; 4925 bwn_mac_enable(mac); 4926 } 4927 4928 /* 4929 * PHY reset. 4930 */ 4931 static int 4932 bwn_phy_reset(struct bwn_mac *mac) 4933 { 4934 struct bwn_softc *sc; 4935 uint16_t iost, mask; 4936 int error; 4937 4938 sc = mac->mac_sc; 4939 4940 iost = BWN_IOCTL_PHYRESET | BHND_IOCTL_CLK_FORCE; 4941 mask = iost | BWN_IOCTL_SUPPORT_G; 4942 4943 if ((error = bhnd_write_ioctl(sc->sc_dev, iost, mask))) 4944 return (error); 4945 4946 DELAY(1000); 4947 4948 iost &= ~BHND_IOCTL_CLK_FORCE; 4949 4950 if ((error = bhnd_write_ioctl(sc->sc_dev, iost, mask))) 4951 return (error); 4952 4953 DELAY(1000); 4954 4955 return (0); 4956 } 4957 4958 static int 4959 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 4960 { 4961 struct bwn_vap *bvp = BWN_VAP(vap); 4962 struct ieee80211com *ic= vap->iv_ic; 4963 enum ieee80211_state ostate = vap->iv_state; 4964 struct bwn_softc *sc = ic->ic_softc; 4965 struct bwn_mac *mac = sc->sc_curmac; 4966 int error; 4967 4968 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 4969 ieee80211_state_name[vap->iv_state], 4970 ieee80211_state_name[nstate]); 4971 4972 error = bvp->bv_newstate(vap, nstate, arg); 4973 if (error != 0) 4974 return (error); 4975 4976 BWN_LOCK(sc); 4977 4978 bwn_led_newstate(mac, nstate); 4979 4980 /* 4981 * Clear the BSSID when we stop a STA 4982 */ 4983 if (vap->iv_opmode == IEEE80211_M_STA) { 4984 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 4985 /* 4986 * Clear out the BSSID. If we reassociate to 4987 * the same AP, this will reinialize things 4988 * correctly... 4989 */ 4990 if (ic->ic_opmode == IEEE80211_M_STA && 4991 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 4992 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 4993 bwn_set_macaddr(mac); 4994 } 4995 } 4996 } 4997 4998 if (vap->iv_opmode == IEEE80211_M_MONITOR || 4999 vap->iv_opmode == IEEE80211_M_AHDEMO) { 5000 /* XXX nothing to do? */ 5001 } else if (nstate == IEEE80211_S_RUN) { 5002 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 5003 bwn_set_opmode(mac); 5004 bwn_set_pretbtt(mac); 5005 bwn_spu_setdelay(mac, 0); 5006 bwn_set_macaddr(mac); 5007 } 5008 5009 BWN_UNLOCK(sc); 5010 5011 return (error); 5012 } 5013 5014 static void 5015 bwn_set_pretbtt(struct bwn_mac *mac) 5016 { 5017 struct bwn_softc *sc = mac->mac_sc; 5018 struct ieee80211com *ic = &sc->sc_ic; 5019 uint16_t pretbtt; 5020 5021 if (ic->ic_opmode == IEEE80211_M_IBSS) 5022 pretbtt = 2; 5023 else 5024 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 5025 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 5026 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 5027 } 5028 5029 static int 5030 bwn_intr(void *arg) 5031 { 5032 struct bwn_mac *mac = arg; 5033 struct bwn_softc *sc = mac->mac_sc; 5034 uint32_t reason; 5035 5036 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 5037 (sc->sc_flags & BWN_FLAG_INVALID)) 5038 return (FILTER_STRAY); 5039 5040 DPRINTF(sc, BWN_DEBUG_INTR, "%s: called\n", __func__); 5041 5042 reason = BWN_READ_4(mac, BWN_INTR_REASON); 5043 if (reason == 0xffffffff) /* shared IRQ */ 5044 return (FILTER_STRAY); 5045 reason &= mac->mac_intr_mask; 5046 if (reason == 0) 5047 return (FILTER_HANDLED); 5048 DPRINTF(sc, BWN_DEBUG_INTR, "%s: reason=0x%08x\n", __func__, reason); 5049 5050 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00; 5051 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 5052 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 5053 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 5054 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 5055 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 5056 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 5057 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 5058 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 5059 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 5060 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 5061 5062 /* Disable interrupts. */ 5063 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 5064 5065 mac->mac_reason_intr = reason; 5066 5067 BWN_BARRIER(mac, 0, 0, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); 5068 5069 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask); 5070 return (FILTER_HANDLED); 5071 } 5072 5073 static void 5074 bwn_intrtask(void *arg, int npending) 5075 { 5076 struct bwn_mac *mac = arg; 5077 struct bwn_softc *sc = mac->mac_sc; 5078 uint32_t merged = 0; 5079 int i, tx = 0, rx = 0; 5080 5081 BWN_LOCK(sc); 5082 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 5083 (sc->sc_flags & BWN_FLAG_INVALID)) { 5084 BWN_UNLOCK(sc); 5085 return; 5086 } 5087 5088 for (i = 0; i < N(mac->mac_reason); i++) 5089 merged |= mac->mac_reason[i]; 5090 5091 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 5092 device_printf(sc->sc_dev, "MAC trans error\n"); 5093 5094 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 5095 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 5096 mac->mac_phy.txerrors--; 5097 if (mac->mac_phy.txerrors == 0) { 5098 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 5099 bwn_restart(mac, "PHY TX errors"); 5100 } 5101 } 5102 5103 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) { 5104 if (merged & BWN_DMAINTR_FATALMASK) { 5105 device_printf(sc->sc_dev, 5106 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 5107 mac->mac_reason[0], mac->mac_reason[1], 5108 mac->mac_reason[2], mac->mac_reason[3], 5109 mac->mac_reason[4], mac->mac_reason[5]); 5110 bwn_restart(mac, "DMA error"); 5111 BWN_UNLOCK(sc); 5112 return; 5113 } 5114 if (merged & BWN_DMAINTR_NONFATALMASK) { 5115 device_printf(sc->sc_dev, 5116 "DMA error: %#x %#x %#x %#x %#x %#x\n", 5117 mac->mac_reason[0], mac->mac_reason[1], 5118 mac->mac_reason[2], mac->mac_reason[3], 5119 mac->mac_reason[4], mac->mac_reason[5]); 5120 } 5121 } 5122 5123 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 5124 bwn_intr_ucode_debug(mac); 5125 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 5126 bwn_intr_tbtt_indication(mac); 5127 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 5128 bwn_intr_atim_end(mac); 5129 if (mac->mac_reason_intr & BWN_INTR_BEACON) 5130 bwn_intr_beacon(mac); 5131 if (mac->mac_reason_intr & BWN_INTR_PMQ) 5132 bwn_intr_pmq(mac); 5133 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 5134 bwn_intr_noise(mac); 5135 5136 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 5137 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 5138 bwn_dma_rx(mac->mac_method.dma.rx); 5139 rx = 1; 5140 } 5141 } else 5142 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 5143 5144 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5145 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5146 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5147 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5148 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5149 5150 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 5151 bwn_intr_txeof(mac); 5152 tx = 1; 5153 } 5154 5155 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 5156 5157 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 5158 int evt = BWN_LED_EVENT_NONE; 5159 5160 if (tx && rx) { 5161 if (sc->sc_rx_rate > sc->sc_tx_rate) 5162 evt = BWN_LED_EVENT_RX; 5163 else 5164 evt = BWN_LED_EVENT_TX; 5165 } else if (tx) { 5166 evt = BWN_LED_EVENT_TX; 5167 } else if (rx) { 5168 evt = BWN_LED_EVENT_RX; 5169 } else if (rx == 0) { 5170 evt = BWN_LED_EVENT_POLL; 5171 } 5172 5173 if (evt != BWN_LED_EVENT_NONE) 5174 bwn_led_event(mac, evt); 5175 } 5176 5177 if (mbufq_first(&sc->sc_snd) != NULL) 5178 bwn_start(sc); 5179 5180 BWN_BARRIER(mac, 0, 0, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); 5181 5182 BWN_UNLOCK(sc); 5183 } 5184 5185 static void 5186 bwn_restart(struct bwn_mac *mac, const char *msg) 5187 { 5188 struct bwn_softc *sc = mac->mac_sc; 5189 struct ieee80211com *ic = &sc->sc_ic; 5190 5191 if (mac->mac_status < BWN_MAC_STATUS_INITED) 5192 return; 5193 5194 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 5195 ieee80211_runtask(ic, &mac->mac_hwreset); 5196 } 5197 5198 static void 5199 bwn_intr_ucode_debug(struct bwn_mac *mac) 5200 { 5201 struct bwn_softc *sc = mac->mac_sc; 5202 uint16_t reason; 5203 5204 if (mac->mac_fw.opensource == 0) 5205 return; 5206 5207 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 5208 switch (reason) { 5209 case BWN_DEBUGINTR_PANIC: 5210 bwn_handle_fwpanic(mac); 5211 break; 5212 case BWN_DEBUGINTR_DUMP_SHM: 5213 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 5214 break; 5215 case BWN_DEBUGINTR_DUMP_REGS: 5216 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 5217 break; 5218 case BWN_DEBUGINTR_MARKER: 5219 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 5220 break; 5221 default: 5222 device_printf(sc->sc_dev, 5223 "ucode debug unknown reason: %#x\n", reason); 5224 } 5225 5226 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 5227 BWN_DEBUGINTR_ACK); 5228 } 5229 5230 static void 5231 bwn_intr_tbtt_indication(struct bwn_mac *mac) 5232 { 5233 struct bwn_softc *sc = mac->mac_sc; 5234 struct ieee80211com *ic = &sc->sc_ic; 5235 5236 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 5237 bwn_psctl(mac, 0); 5238 if (ic->ic_opmode == IEEE80211_M_IBSS) 5239 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 5240 } 5241 5242 static void 5243 bwn_intr_atim_end(struct bwn_mac *mac) 5244 { 5245 5246 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 5247 BWN_WRITE_4(mac, BWN_MACCMD, 5248 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 5249 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 5250 } 5251 } 5252 5253 static void 5254 bwn_intr_beacon(struct bwn_mac *mac) 5255 { 5256 struct bwn_softc *sc = mac->mac_sc; 5257 struct ieee80211com *ic = &sc->sc_ic; 5258 uint32_t cmd, beacon0, beacon1; 5259 5260 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 5261 ic->ic_opmode == IEEE80211_M_MBSS) 5262 return; 5263 5264 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 5265 5266 cmd = BWN_READ_4(mac, BWN_MACCMD); 5267 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 5268 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 5269 5270 if (beacon0 && beacon1) { 5271 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 5272 mac->mac_intr_mask |= BWN_INTR_BEACON; 5273 return; 5274 } 5275 5276 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 5277 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 5278 bwn_load_beacon0(mac); 5279 bwn_load_beacon1(mac); 5280 cmd = BWN_READ_4(mac, BWN_MACCMD); 5281 cmd |= BWN_MACCMD_BEACON0_VALID; 5282 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 5283 } else { 5284 if (!beacon0) { 5285 bwn_load_beacon0(mac); 5286 cmd = BWN_READ_4(mac, BWN_MACCMD); 5287 cmd |= BWN_MACCMD_BEACON0_VALID; 5288 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 5289 } else if (!beacon1) { 5290 bwn_load_beacon1(mac); 5291 cmd = BWN_READ_4(mac, BWN_MACCMD); 5292 cmd |= BWN_MACCMD_BEACON1_VALID; 5293 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 5294 } 5295 } 5296 } 5297 5298 static void 5299 bwn_intr_pmq(struct bwn_mac *mac) 5300 { 5301 uint32_t tmp; 5302 5303 while (1) { 5304 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 5305 if (!(tmp & 0x00000008)) 5306 break; 5307 } 5308 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 5309 } 5310 5311 static void 5312 bwn_intr_noise(struct bwn_mac *mac) 5313 { 5314 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5315 uint16_t tmp; 5316 uint8_t noise[4]; 5317 uint8_t i, j; 5318 int32_t average; 5319 5320 if (mac->mac_phy.type != BWN_PHYTYPE_G) 5321 return; 5322 5323 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 5324 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 5325 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 5326 noise[3] == 0x7f) 5327 goto new; 5328 5329 KASSERT(mac->mac_noise.noi_nsamples < 8, 5330 ("%s:%d: fail", __func__, __LINE__)); 5331 i = mac->mac_noise.noi_nsamples; 5332 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 5333 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 5334 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 5335 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 5336 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 5337 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 5338 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 5339 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 5340 mac->mac_noise.noi_nsamples++; 5341 if (mac->mac_noise.noi_nsamples == 8) { 5342 average = 0; 5343 for (i = 0; i < 8; i++) { 5344 for (j = 0; j < 4; j++) 5345 average += mac->mac_noise.noi_samples[i][j]; 5346 } 5347 average = (((average / 32) * 125) + 64) / 128; 5348 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 5349 if (tmp >= 8) 5350 average += 2; 5351 else 5352 average -= 25; 5353 average -= (tmp == 8) ? 72 : 48; 5354 5355 mac->mac_stats.link_noise = average; 5356 mac->mac_noise.noi_running = 0; 5357 return; 5358 } 5359 new: 5360 bwn_noise_gensample(mac); 5361 } 5362 5363 static int 5364 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 5365 { 5366 struct bwn_mac *mac = prq->prq_mac; 5367 struct bwn_softc *sc = mac->mac_sc; 5368 unsigned int i; 5369 5370 BWN_ASSERT_LOCKED(sc); 5371 5372 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 5373 return (0); 5374 5375 for (i = 0; i < 5000; i++) { 5376 if (bwn_pio_rxeof(prq) == 0) 5377 break; 5378 } 5379 if (i >= 5000) 5380 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 5381 return ((i > 0) ? 1 : 0); 5382 } 5383 5384 static void 5385 bwn_dma_rx(struct bwn_dma_ring *dr) 5386 { 5387 int slot, curslot; 5388 5389 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 5390 curslot = dr->get_curslot(dr); 5391 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 5392 ("%s:%d: fail", __func__, __LINE__)); 5393 5394 slot = dr->dr_curslot; 5395 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 5396 bwn_dma_rxeof(dr, &slot); 5397 5398 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 5399 BUS_DMASYNC_PREWRITE); 5400 5401 dr->set_curslot(dr, slot); 5402 dr->dr_curslot = slot; 5403 } 5404 5405 static void 5406 bwn_intr_txeof(struct bwn_mac *mac) 5407 { 5408 struct bwn_txstatus stat; 5409 uint32_t stat0, stat1; 5410 uint16_t tmp; 5411 5412 BWN_ASSERT_LOCKED(mac->mac_sc); 5413 5414 while (1) { 5415 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 5416 if (!(stat0 & 0x00000001)) 5417 break; 5418 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 5419 5420 DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT, 5421 "%s: stat0=0x%08x, stat1=0x%08x\n", 5422 __func__, 5423 stat0, 5424 stat1); 5425 5426 stat.cookie = (stat0 >> 16); 5427 stat.seq = (stat1 & 0x0000ffff); 5428 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 5429 tmp = (stat0 & 0x0000ffff); 5430 stat.framecnt = ((tmp & 0xf000) >> 12); 5431 stat.rtscnt = ((tmp & 0x0f00) >> 8); 5432 stat.sreason = ((tmp & 0x001c) >> 2); 5433 stat.pm = (tmp & 0x0080) ? 1 : 0; 5434 stat.im = (tmp & 0x0040) ? 1 : 0; 5435 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 5436 stat.ack = (tmp & 0x0002) ? 1 : 0; 5437 5438 DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT, 5439 "%s: cookie=%d, seq=%d, phystat=0x%02x, framecnt=%d, " 5440 "rtscnt=%d, sreason=%d, pm=%d, im=%d, ampdu=%d, ack=%d\n", 5441 __func__, 5442 stat.cookie, 5443 stat.seq, 5444 stat.phy_stat, 5445 stat.framecnt, 5446 stat.rtscnt, 5447 stat.sreason, 5448 stat.pm, 5449 stat.im, 5450 stat.ampdu, 5451 stat.ack); 5452 5453 bwn_handle_txeof(mac, &stat); 5454 } 5455 } 5456 5457 static void 5458 bwn_hwreset(void *arg, int npending) 5459 { 5460 struct bwn_mac *mac = arg; 5461 struct bwn_softc *sc = mac->mac_sc; 5462 int error = 0; 5463 int prev_status; 5464 5465 BWN_LOCK(sc); 5466 5467 prev_status = mac->mac_status; 5468 if (prev_status >= BWN_MAC_STATUS_STARTED) 5469 bwn_core_stop(mac); 5470 if (prev_status >= BWN_MAC_STATUS_INITED) 5471 bwn_core_exit(mac); 5472 5473 if (prev_status >= BWN_MAC_STATUS_INITED) { 5474 error = bwn_core_init(mac); 5475 if (error) 5476 goto out; 5477 } 5478 if (prev_status >= BWN_MAC_STATUS_STARTED) 5479 bwn_core_start(mac); 5480 out: 5481 if (error) { 5482 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 5483 sc->sc_curmac = NULL; 5484 } 5485 BWN_UNLOCK(sc); 5486 } 5487 5488 static void 5489 bwn_handle_fwpanic(struct bwn_mac *mac) 5490 { 5491 struct bwn_softc *sc = mac->mac_sc; 5492 uint16_t reason; 5493 5494 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 5495 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 5496 5497 if (reason == BWN_FWPANIC_RESTART) 5498 bwn_restart(mac, "ucode panic"); 5499 } 5500 5501 static void 5502 bwn_load_beacon0(struct bwn_mac *mac) 5503 { 5504 5505 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5506 } 5507 5508 static void 5509 bwn_load_beacon1(struct bwn_mac *mac) 5510 { 5511 5512 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5513 } 5514 5515 static uint32_t 5516 bwn_jssi_read(struct bwn_mac *mac) 5517 { 5518 uint32_t val = 0; 5519 5520 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 5521 val <<= 16; 5522 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 5523 5524 return (val); 5525 } 5526 5527 static void 5528 bwn_noise_gensample(struct bwn_mac *mac) 5529 { 5530 uint32_t jssi = 0x7f7f7f7f; 5531 5532 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 5533 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 5534 BWN_WRITE_4(mac, BWN_MACCMD, 5535 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 5536 } 5537 5538 static int 5539 bwn_dma_freeslot(struct bwn_dma_ring *dr) 5540 { 5541 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 5542 5543 return (dr->dr_numslots - dr->dr_usedslot); 5544 } 5545 5546 static int 5547 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 5548 { 5549 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 5550 5551 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 5552 ("%s:%d: fail", __func__, __LINE__)); 5553 if (slot == dr->dr_numslots - 1) 5554 return (0); 5555 return (slot + 1); 5556 } 5557 5558 static void 5559 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 5560 { 5561 struct bwn_mac *mac = dr->dr_mac; 5562 struct bwn_softc *sc = mac->mac_sc; 5563 struct bwn_dma *dma = &mac->mac_method.dma; 5564 struct bwn_dmadesc_generic *desc; 5565 struct bwn_dmadesc_meta *meta; 5566 struct bwn_rxhdr4 *rxhdr; 5567 struct mbuf *m; 5568 uint32_t macstat; 5569 int32_t tmp; 5570 int cnt = 0; 5571 uint16_t len; 5572 5573 dr->getdesc(dr, *slot, &desc, &meta); 5574 5575 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 5576 m = meta->mt_m; 5577 5578 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 5579 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 5580 return; 5581 } 5582 5583 rxhdr = mtod(m, struct bwn_rxhdr4 *); 5584 len = le16toh(rxhdr->frame_len); 5585 if (len <= 0) { 5586 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 5587 return; 5588 } 5589 if (bwn_dma_check_redzone(dr, m)) { 5590 device_printf(sc->sc_dev, "redzone error.\n"); 5591 bwn_dma_set_redzone(dr, m); 5592 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 5593 BUS_DMASYNC_PREWRITE); 5594 return; 5595 } 5596 if (len > dr->dr_rx_bufsize) { 5597 tmp = len; 5598 while (1) { 5599 dr->getdesc(dr, *slot, &desc, &meta); 5600 bwn_dma_set_redzone(dr, meta->mt_m); 5601 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 5602 BUS_DMASYNC_PREWRITE); 5603 *slot = bwn_dma_nextslot(dr, *slot); 5604 cnt++; 5605 tmp -= dr->dr_rx_bufsize; 5606 if (tmp <= 0) 5607 break; 5608 } 5609 device_printf(sc->sc_dev, "too small buffer " 5610 "(len %u buffer %u dropped %d)\n", 5611 len, dr->dr_rx_bufsize, cnt); 5612 return; 5613 } 5614 5615 switch (mac->mac_fw.fw_hdr_format) { 5616 case BWN_FW_HDR_351: 5617 case BWN_FW_HDR_410: 5618 macstat = le32toh(rxhdr->ps4.r351.mac_status); 5619 break; 5620 case BWN_FW_HDR_598: 5621 macstat = le32toh(rxhdr->ps4.r598.mac_status); 5622 break; 5623 } 5624 5625 if (macstat & BWN_RX_MAC_FCSERR) { 5626 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 5627 device_printf(sc->sc_dev, "RX drop\n"); 5628 return; 5629 } 5630 } 5631 5632 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 5633 m_adj(m, dr->dr_frameoffset); 5634 5635 bwn_rxeof(dr->dr_mac, m, rxhdr); 5636 } 5637 5638 static void 5639 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 5640 { 5641 struct bwn_softc *sc = mac->mac_sc; 5642 struct bwn_stats *stats = &mac->mac_stats; 5643 5644 BWN_ASSERT_LOCKED(mac->mac_sc); 5645 5646 if (status->im) 5647 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 5648 if (status->ampdu) 5649 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 5650 if (status->rtscnt) { 5651 if (status->rtscnt == 0xf) 5652 stats->rtsfail++; 5653 else 5654 stats->rts++; 5655 } 5656 5657 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 5658 bwn_dma_handle_txeof(mac, status); 5659 } else { 5660 bwn_pio_handle_txeof(mac, status); 5661 } 5662 5663 bwn_phy_txpower_check(mac, 0); 5664 } 5665 5666 static uint8_t 5667 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 5668 { 5669 struct bwn_mac *mac = prq->prq_mac; 5670 struct bwn_softc *sc = mac->mac_sc; 5671 struct bwn_rxhdr4 rxhdr; 5672 struct mbuf *m; 5673 uint32_t ctl32, macstat, v32; 5674 unsigned int i, padding; 5675 uint16_t ctl16, len, totlen, v16; 5676 unsigned char *mp; 5677 char *data; 5678 5679 memset(&rxhdr, 0, sizeof(rxhdr)); 5680 5681 if (prq->prq_rev >= 8) { 5682 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 5683 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 5684 return (0); 5685 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 5686 BWN_PIO8_RXCTL_FRAMEREADY); 5687 for (i = 0; i < 10; i++) { 5688 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 5689 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 5690 goto ready; 5691 DELAY(10); 5692 } 5693 } else { 5694 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 5695 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 5696 return (0); 5697 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 5698 BWN_PIO_RXCTL_FRAMEREADY); 5699 for (i = 0; i < 10; i++) { 5700 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 5701 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 5702 goto ready; 5703 DELAY(10); 5704 } 5705 } 5706 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 5707 return (1); 5708 ready: 5709 if (prq->prq_rev >= 8) { 5710 bus_read_multi_4(sc->sc_mem_res, 5711 prq->prq_base + BWN_PIO8_RXDATA, (void *)&rxhdr, 5712 sizeof(rxhdr)); 5713 } else { 5714 bus_read_multi_2(sc->sc_mem_res, 5715 prq->prq_base + BWN_PIO_RXDATA, (void *)&rxhdr, 5716 sizeof(rxhdr)); 5717 } 5718 len = le16toh(rxhdr.frame_len); 5719 if (len > 0x700) { 5720 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 5721 goto error; 5722 } 5723 if (len == 0) { 5724 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 5725 goto error; 5726 } 5727 5728 switch (mac->mac_fw.fw_hdr_format) { 5729 case BWN_FW_HDR_351: 5730 case BWN_FW_HDR_410: 5731 macstat = le32toh(rxhdr.ps4.r351.mac_status); 5732 break; 5733 case BWN_FW_HDR_598: 5734 macstat = le32toh(rxhdr.ps4.r598.mac_status); 5735 break; 5736 } 5737 5738 if (macstat & BWN_RX_MAC_FCSERR) { 5739 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 5740 device_printf(sc->sc_dev, "%s: FCS error", __func__); 5741 goto error; 5742 } 5743 } 5744 5745 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 5746 totlen = len + padding; 5747 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 5748 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 5749 if (m == NULL) { 5750 device_printf(sc->sc_dev, "%s: out of memory", __func__); 5751 goto error; 5752 } 5753 mp = mtod(m, unsigned char *); 5754 if (prq->prq_rev >= 8) { 5755 bus_read_multi_4(sc->sc_mem_res, 5756 prq->prq_base + BWN_PIO8_RXDATA, (void *)mp, (totlen & ~3)); 5757 if (totlen & 3) { 5758 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 5759 data = &(mp[totlen - 1]); 5760 switch (totlen & 3) { 5761 case 3: 5762 *data = (v32 >> 16); 5763 data--; 5764 case 2: 5765 *data = (v32 >> 8); 5766 data--; 5767 case 1: 5768 *data = v32; 5769 } 5770 } 5771 } else { 5772 bus_read_multi_2(sc->sc_mem_res, 5773 prq->prq_base + BWN_PIO_RXDATA, (void *)mp, (totlen & ~1)); 5774 if (totlen & 1) { 5775 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 5776 mp[totlen - 1] = v16; 5777 } 5778 } 5779 5780 m->m_len = m->m_pkthdr.len = totlen; 5781 5782 bwn_rxeof(prq->prq_mac, m, &rxhdr); 5783 5784 return (1); 5785 error: 5786 if (prq->prq_rev >= 8) 5787 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 5788 BWN_PIO8_RXCTL_DATAREADY); 5789 else 5790 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 5791 return (1); 5792 } 5793 5794 static int 5795 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 5796 struct bwn_dmadesc_meta *meta, int init) 5797 { 5798 struct bwn_mac *mac = dr->dr_mac; 5799 struct bwn_dma *dma = &mac->mac_method.dma; 5800 struct bwn_rxhdr4 *hdr; 5801 bus_dmamap_t map; 5802 bus_addr_t paddr; 5803 struct mbuf *m; 5804 int error; 5805 5806 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 5807 if (m == NULL) { 5808 error = ENOBUFS; 5809 5810 /* 5811 * If the NIC is up and running, we need to: 5812 * - Clear RX buffer's header. 5813 * - Restore RX descriptor settings. 5814 */ 5815 if (init) 5816 return (error); 5817 else 5818 goto back; 5819 } 5820 m->m_len = m->m_pkthdr.len = MCLBYTES; 5821 5822 bwn_dma_set_redzone(dr, m); 5823 5824 /* 5825 * Try to load RX buf into temporary DMA map 5826 */ 5827 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 5828 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 5829 if (error) { 5830 m_freem(m); 5831 5832 /* 5833 * See the comment above 5834 */ 5835 if (init) 5836 return (error); 5837 else 5838 goto back; 5839 } 5840 5841 if (!init) 5842 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 5843 meta->mt_m = m; 5844 meta->mt_paddr = paddr; 5845 5846 /* 5847 * Swap RX buf's DMA map with the loaded temporary one 5848 */ 5849 map = meta->mt_dmap; 5850 meta->mt_dmap = dr->dr_spare_dmap; 5851 dr->dr_spare_dmap = map; 5852 5853 back: 5854 /* 5855 * Clear RX buf header 5856 */ 5857 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 5858 bzero(hdr, sizeof(*hdr)); 5859 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 5860 BUS_DMASYNC_PREWRITE); 5861 5862 /* 5863 * Setup RX buf descriptor 5864 */ 5865 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 5866 sizeof(*hdr), 0, 0, 0); 5867 return (error); 5868 } 5869 5870 static void 5871 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 5872 bus_size_t mapsz __unused, int error) 5873 { 5874 5875 if (!error) { 5876 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 5877 *((bus_addr_t *)arg) = seg->ds_addr; 5878 } 5879 } 5880 5881 static int 5882 bwn_hwrate2ieeerate(int rate) 5883 { 5884 5885 switch (rate) { 5886 case BWN_CCK_RATE_1MB: 5887 return (2); 5888 case BWN_CCK_RATE_2MB: 5889 return (4); 5890 case BWN_CCK_RATE_5MB: 5891 return (11); 5892 case BWN_CCK_RATE_11MB: 5893 return (22); 5894 case BWN_OFDM_RATE_6MB: 5895 return (12); 5896 case BWN_OFDM_RATE_9MB: 5897 return (18); 5898 case BWN_OFDM_RATE_12MB: 5899 return (24); 5900 case BWN_OFDM_RATE_18MB: 5901 return (36); 5902 case BWN_OFDM_RATE_24MB: 5903 return (48); 5904 case BWN_OFDM_RATE_36MB: 5905 return (72); 5906 case BWN_OFDM_RATE_48MB: 5907 return (96); 5908 case BWN_OFDM_RATE_54MB: 5909 return (108); 5910 default: 5911 printf("Ooops\n"); 5912 return (0); 5913 } 5914 } 5915 5916 /* 5917 * Post process the RX provided RSSI. 5918 * 5919 * Valid for A, B, G, LP PHYs. 5920 */ 5921 static int8_t 5922 bwn_rx_rssi_calc(struct bwn_mac *mac, uint8_t in_rssi, 5923 int ofdm, int adjust_2053, int adjust_2050) 5924 { 5925 struct bwn_phy *phy = &mac->mac_phy; 5926 struct bwn_phy_g *gphy = &phy->phy_g; 5927 int tmp; 5928 5929 switch (phy->rf_ver) { 5930 case 0x2050: 5931 if (ofdm) { 5932 tmp = in_rssi; 5933 if (tmp > 127) 5934 tmp -= 256; 5935 tmp = tmp * 73 / 64; 5936 if (adjust_2050) 5937 tmp += 25; 5938 else 5939 tmp -= 3; 5940 } else { 5941 if (mac->mac_sc->sc_board_info.board_flags 5942 & BHND_BFL_ADCDIV) { 5943 if (in_rssi > 63) 5944 in_rssi = 63; 5945 tmp = gphy->pg_nrssi_lt[in_rssi]; 5946 tmp = (31 - tmp) * -131 / 128 - 57; 5947 } else { 5948 tmp = in_rssi; 5949 tmp = (31 - tmp) * -149 / 128 - 68; 5950 } 5951 if (phy->type == BWN_PHYTYPE_G && adjust_2050) 5952 tmp += 25; 5953 } 5954 break; 5955 case 0x2060: 5956 if (in_rssi > 127) 5957 tmp = in_rssi - 256; 5958 else 5959 tmp = in_rssi; 5960 break; 5961 default: 5962 tmp = in_rssi; 5963 tmp = (tmp - 11) * 103 / 64; 5964 if (adjust_2053) 5965 tmp -= 109; 5966 else 5967 tmp -= 83; 5968 } 5969 5970 return (tmp); 5971 } 5972 5973 static void 5974 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 5975 { 5976 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 5977 struct bwn_plcp6 *plcp; 5978 struct bwn_softc *sc = mac->mac_sc; 5979 struct ieee80211_frame_min *wh; 5980 struct ieee80211_node *ni; 5981 struct ieee80211com *ic = &sc->sc_ic; 5982 uint32_t macstat; 5983 int padding, rate, rssi = 0, noise = 0, type; 5984 uint16_t phytype, phystat0, phystat3, chanstat; 5985 unsigned char *mp = mtod(m, unsigned char *); 5986 5987 BWN_ASSERT_LOCKED(sc); 5988 5989 phystat0 = le16toh(rxhdr->phy_status0); 5990 5991 /* 5992 * XXX Note: phy_status3 doesn't exist for HT-PHY; it's only 5993 * used for LP-PHY. 5994 */ 5995 phystat3 = le16toh(rxhdr->ps3.lp.phy_status3); 5996 5997 switch (mac->mac_fw.fw_hdr_format) { 5998 case BWN_FW_HDR_351: 5999 case BWN_FW_HDR_410: 6000 macstat = le32toh(rxhdr->ps4.r351.mac_status); 6001 chanstat = le16toh(rxhdr->ps4.r351.channel); 6002 break; 6003 case BWN_FW_HDR_598: 6004 macstat = le32toh(rxhdr->ps4.r598.mac_status); 6005 chanstat = le16toh(rxhdr->ps4.r598.channel); 6006 break; 6007 } 6008 6009 6010 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 6011 6012 if (macstat & BWN_RX_MAC_FCSERR) 6013 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 6014 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 6015 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 6016 if (macstat & BWN_RX_MAC_DECERR) 6017 goto drop; 6018 6019 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 6020 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 6021 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 6022 m->m_pkthdr.len); 6023 goto drop; 6024 } 6025 plcp = (struct bwn_plcp6 *)(mp + padding); 6026 m_adj(m, sizeof(struct bwn_plcp6) + padding); 6027 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 6028 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 6029 m->m_pkthdr.len); 6030 goto drop; 6031 } 6032 wh = mtod(m, struct ieee80211_frame_min *); 6033 6034 if (macstat & BWN_RX_MAC_DEC) { 6035 DPRINTF(sc, BWN_DEBUG_HWCRYPTO, 6036 "RX decryption attempted (old %d keyidx %#x)\n", 6037 BWN_ISOLDFMT(mac), 6038 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 6039 } 6040 6041 if (phystat0 & BWN_RX_PHYST0_OFDM) 6042 rate = bwn_plcp_get_ofdmrate(mac, plcp, 6043 phytype == BWN_PHYTYPE_A); 6044 else 6045 rate = bwn_plcp_get_cckrate(mac, plcp); 6046 if (rate == -1) { 6047 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 6048 goto drop; 6049 } 6050 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 6051 6052 /* rssi/noise */ 6053 switch (phytype) { 6054 case BWN_PHYTYPE_A: 6055 case BWN_PHYTYPE_B: 6056 case BWN_PHYTYPE_G: 6057 case BWN_PHYTYPE_LP: 6058 rssi = bwn_rx_rssi_calc(mac, rxhdr->phy.abg.rssi, 6059 !! (phystat0 & BWN_RX_PHYST0_OFDM), 6060 !! (phystat0 & BWN_RX_PHYST0_GAINCTL), 6061 !! (phystat3 & BWN_RX_PHYST3_TRSTATE)); 6062 break; 6063 case BWN_PHYTYPE_N: 6064 /* Broadcom has code for min/avg, but always used max */ 6065 if (rxhdr->phy.n.power0 == 16 || rxhdr->phy.n.power0 == 32) 6066 rssi = max(rxhdr->phy.n.power1, rxhdr->ps2.n.power2); 6067 else 6068 rssi = max(rxhdr->phy.n.power0, rxhdr->phy.n.power1); 6069 #if 0 6070 DPRINTF(mac->mac_sc, BWN_DEBUG_RECV, 6071 "%s: power0=%d, power1=%d, power2=%d\n", 6072 __func__, 6073 rxhdr->phy.n.power0, 6074 rxhdr->phy.n.power1, 6075 rxhdr->ps2.n.power2); 6076 #endif 6077 break; 6078 default: 6079 /* XXX TODO: implement rssi for other PHYs */ 6080 break; 6081 } 6082 6083 /* 6084 * RSSI here is absolute, not relative to the noise floor. 6085 */ 6086 noise = mac->mac_stats.link_noise; 6087 rssi = rssi - noise; 6088 6089 /* RX radio tap */ 6090 if (ieee80211_radiotap_active(ic)) 6091 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 6092 m_adj(m, -IEEE80211_CRC_LEN); 6093 6094 BWN_UNLOCK(sc); 6095 6096 ni = ieee80211_find_rxnode(ic, wh); 6097 if (ni != NULL) { 6098 type = ieee80211_input(ni, m, rssi, noise); 6099 ieee80211_free_node(ni); 6100 } else 6101 type = ieee80211_input_all(ic, m, rssi, noise); 6102 6103 BWN_LOCK(sc); 6104 return; 6105 drop: 6106 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 6107 } 6108 6109 static void 6110 bwn_ratectl_tx_complete(const struct ieee80211_node *ni, 6111 const struct bwn_txstatus *status) 6112 { 6113 struct ieee80211_ratectl_tx_status txs; 6114 int retrycnt = 0; 6115 6116 /* 6117 * If we don't get an ACK, then we should log the 6118 * full framecnt. That may be 0 if it's a PHY 6119 * failure, so ensure that gets logged as some 6120 * retry attempt. 6121 */ 6122 txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY; 6123 if (status->ack) { 6124 txs.status = IEEE80211_RATECTL_TX_SUCCESS; 6125 retrycnt = status->framecnt - 1; 6126 } else { 6127 txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED; 6128 retrycnt = status->framecnt; 6129 if (retrycnt == 0) 6130 retrycnt = 1; 6131 } 6132 txs.long_retries = retrycnt; 6133 ieee80211_ratectl_tx_complete(ni, &txs); 6134 } 6135 6136 static void 6137 bwn_dma_handle_txeof(struct bwn_mac *mac, 6138 const struct bwn_txstatus *status) 6139 { 6140 struct bwn_dma *dma = &mac->mac_method.dma; 6141 struct bwn_dma_ring *dr; 6142 struct bwn_dmadesc_generic *desc; 6143 struct bwn_dmadesc_meta *meta; 6144 struct bwn_softc *sc = mac->mac_sc; 6145 int slot; 6146 6147 BWN_ASSERT_LOCKED(sc); 6148 6149 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 6150 if (dr == NULL) { 6151 device_printf(sc->sc_dev, "failed to parse cookie\n"); 6152 return; 6153 } 6154 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 6155 6156 while (1) { 6157 KASSERT(slot >= 0 && slot < dr->dr_numslots, 6158 ("%s:%d: fail", __func__, __LINE__)); 6159 dr->getdesc(dr, slot, &desc, &meta); 6160 6161 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) 6162 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 6163 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) 6164 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 6165 6166 if (meta->mt_islast) { 6167 KASSERT(meta->mt_m != NULL, 6168 ("%s:%d: fail", __func__, __LINE__)); 6169 6170 bwn_ratectl_tx_complete(meta->mt_ni, status); 6171 ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0); 6172 meta->mt_ni = NULL; 6173 meta->mt_m = NULL; 6174 } else 6175 KASSERT(meta->mt_m == NULL, 6176 ("%s:%d: fail", __func__, __LINE__)); 6177 6178 dr->dr_usedslot--; 6179 if (meta->mt_islast) 6180 break; 6181 slot = bwn_dma_nextslot(dr, slot); 6182 } 6183 sc->sc_watchdog_timer = 0; 6184 if (dr->dr_stop) { 6185 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 6186 ("%s:%d: fail", __func__, __LINE__)); 6187 dr->dr_stop = 0; 6188 } 6189 } 6190 6191 static void 6192 bwn_pio_handle_txeof(struct bwn_mac *mac, 6193 const struct bwn_txstatus *status) 6194 { 6195 struct bwn_pio_txqueue *tq; 6196 struct bwn_pio_txpkt *tp = NULL; 6197 struct bwn_softc *sc = mac->mac_sc; 6198 6199 BWN_ASSERT_LOCKED(sc); 6200 6201 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 6202 if (tq == NULL) 6203 return; 6204 6205 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 6206 tq->tq_free++; 6207 6208 /* XXX ieee80211_tx_complete()? */ 6209 if (tp->tp_ni != NULL) { 6210 /* 6211 * Do any tx complete callback. Note this must 6212 * be done before releasing the node reference. 6213 */ 6214 6215 bwn_ratectl_tx_complete(tp->tp_ni, status); 6216 if (tp->tp_m->m_flags & M_TXCB) 6217 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 6218 ieee80211_free_node(tp->tp_ni); 6219 tp->tp_ni = NULL; 6220 } 6221 m_freem(tp->tp_m); 6222 tp->tp_m = NULL; 6223 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 6224 6225 sc->sc_watchdog_timer = 0; 6226 } 6227 6228 static void 6229 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 6230 { 6231 struct bwn_softc *sc = mac->mac_sc; 6232 struct bwn_phy *phy = &mac->mac_phy; 6233 struct ieee80211com *ic = &sc->sc_ic; 6234 unsigned long now; 6235 bwn_txpwr_result_t result; 6236 6237 BWN_GETTIME(now); 6238 6239 if (!(flags & BWN_TXPWR_IGNORE_TIME) && ieee80211_time_before(now, phy->nexttime)) 6240 return; 6241 phy->nexttime = now + 2 * 1000; 6242 6243 if (sc->sc_board_info.board_vendor == PCI_VENDOR_BROADCOM && 6244 sc->sc_board_info.board_type == BHND_BOARD_BU4306) 6245 return; 6246 6247 if (phy->recalc_txpwr != NULL) { 6248 result = phy->recalc_txpwr(mac, 6249 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 6250 if (result == BWN_TXPWR_RES_DONE) 6251 return; 6252 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 6253 ("%s: fail", __func__)); 6254 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 6255 6256 ieee80211_runtask(ic, &mac->mac_txpower); 6257 } 6258 } 6259 6260 static uint16_t 6261 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 6262 { 6263 6264 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 6265 } 6266 6267 static uint32_t 6268 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 6269 { 6270 6271 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 6272 } 6273 6274 static void 6275 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 6276 { 6277 6278 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 6279 } 6280 6281 static void 6282 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 6283 { 6284 6285 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 6286 } 6287 6288 static int 6289 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 6290 { 6291 6292 switch (rate) { 6293 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 6294 case 12: 6295 return (BWN_OFDM_RATE_6MB); 6296 case 18: 6297 return (BWN_OFDM_RATE_9MB); 6298 case 24: 6299 return (BWN_OFDM_RATE_12MB); 6300 case 36: 6301 return (BWN_OFDM_RATE_18MB); 6302 case 48: 6303 return (BWN_OFDM_RATE_24MB); 6304 case 72: 6305 return (BWN_OFDM_RATE_36MB); 6306 case 96: 6307 return (BWN_OFDM_RATE_48MB); 6308 case 108: 6309 return (BWN_OFDM_RATE_54MB); 6310 /* CCK rates (NB: not IEEE std, device-specific) */ 6311 case 2: 6312 return (BWN_CCK_RATE_1MB); 6313 case 4: 6314 return (BWN_CCK_RATE_2MB); 6315 case 11: 6316 return (BWN_CCK_RATE_5MB); 6317 case 22: 6318 return (BWN_CCK_RATE_11MB); 6319 } 6320 6321 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 6322 return (BWN_CCK_RATE_1MB); 6323 } 6324 6325 static uint16_t 6326 bwn_set_txhdr_phyctl1(struct bwn_mac *mac, uint8_t bitrate) 6327 { 6328 struct bwn_phy *phy = &mac->mac_phy; 6329 uint16_t control = 0; 6330 uint16_t bw; 6331 6332 /* XXX TODO: this is for LP phy, what about N-PHY, etc? */ 6333 bw = BWN_TXH_PHY1_BW_20; 6334 6335 if (BWN_ISCCKRATE(bitrate) && phy->type != BWN_PHYTYPE_LP) { 6336 control = bw; 6337 } else { 6338 control = bw; 6339 /* Figure out coding rate and modulation */ 6340 /* XXX TODO: table-ize, for MCS transmit */ 6341 /* Note: this is BWN_*_RATE values */ 6342 switch (bitrate) { 6343 case BWN_CCK_RATE_1MB: 6344 control |= 0; 6345 break; 6346 case BWN_CCK_RATE_2MB: 6347 control |= 1; 6348 break; 6349 case BWN_CCK_RATE_5MB: 6350 control |= 2; 6351 break; 6352 case BWN_CCK_RATE_11MB: 6353 control |= 3; 6354 break; 6355 case BWN_OFDM_RATE_6MB: 6356 control |= BWN_TXH_PHY1_CRATE_1_2; 6357 control |= BWN_TXH_PHY1_MODUL_BPSK; 6358 break; 6359 case BWN_OFDM_RATE_9MB: 6360 control |= BWN_TXH_PHY1_CRATE_3_4; 6361 control |= BWN_TXH_PHY1_MODUL_BPSK; 6362 break; 6363 case BWN_OFDM_RATE_12MB: 6364 control |= BWN_TXH_PHY1_CRATE_1_2; 6365 control |= BWN_TXH_PHY1_MODUL_QPSK; 6366 break; 6367 case BWN_OFDM_RATE_18MB: 6368 control |= BWN_TXH_PHY1_CRATE_3_4; 6369 control |= BWN_TXH_PHY1_MODUL_QPSK; 6370 break; 6371 case BWN_OFDM_RATE_24MB: 6372 control |= BWN_TXH_PHY1_CRATE_1_2; 6373 control |= BWN_TXH_PHY1_MODUL_QAM16; 6374 break; 6375 case BWN_OFDM_RATE_36MB: 6376 control |= BWN_TXH_PHY1_CRATE_3_4; 6377 control |= BWN_TXH_PHY1_MODUL_QAM16; 6378 break; 6379 case BWN_OFDM_RATE_48MB: 6380 control |= BWN_TXH_PHY1_CRATE_1_2; 6381 control |= BWN_TXH_PHY1_MODUL_QAM64; 6382 break; 6383 case BWN_OFDM_RATE_54MB: 6384 control |= BWN_TXH_PHY1_CRATE_3_4; 6385 control |= BWN_TXH_PHY1_MODUL_QAM64; 6386 break; 6387 default: 6388 break; 6389 } 6390 control |= BWN_TXH_PHY1_MODE_SISO; 6391 } 6392 6393 return control; 6394 } 6395 6396 static int 6397 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 6398 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 6399 { 6400 const struct bwn_phy *phy = &mac->mac_phy; 6401 struct bwn_softc *sc = mac->mac_sc; 6402 struct ieee80211_frame *wh; 6403 struct ieee80211_frame *protwh; 6404 const struct ieee80211_txparam *tp = ni->ni_txparms; 6405 struct ieee80211vap *vap = ni->ni_vap; 6406 struct ieee80211com *ic = &sc->sc_ic; 6407 struct mbuf *mprot; 6408 uint8_t *prot_ptr; 6409 unsigned int len; 6410 uint32_t macctl = 0; 6411 int rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 6412 uint16_t phyctl = 0; 6413 uint8_t rate, rate_fb; 6414 int fill_phy_ctl1 = 0; 6415 6416 wh = mtod(m, struct ieee80211_frame *); 6417 memset(txhdr, 0, sizeof(*txhdr)); 6418 6419 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 6420 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 6421 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 6422 6423 if ((phy->type == BWN_PHYTYPE_N) || (phy->type == BWN_PHYTYPE_LP) 6424 || (phy->type == BWN_PHYTYPE_HT)) 6425 fill_phy_ctl1 = 1; 6426 6427 /* 6428 * Find TX rate 6429 */ 6430 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 6431 rate = rate_fb = tp->mgmtrate; 6432 else if (ismcast) 6433 rate = rate_fb = tp->mcastrate; 6434 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 6435 rate = rate_fb = tp->ucastrate; 6436 else { 6437 rix = ieee80211_ratectl_rate(ni, NULL, 0); 6438 rate = ni->ni_txrate; 6439 6440 if (rix > 0) 6441 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 6442 IEEE80211_RATE_VAL; 6443 else 6444 rate_fb = rate; 6445 } 6446 6447 sc->sc_tx_rate = rate; 6448 6449 /* Note: this maps the select ieee80211 rate to hardware rate */ 6450 rate = bwn_ieeerate2hwrate(sc, rate); 6451 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 6452 6453 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 6454 bwn_plcp_getcck(rate); 6455 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 6456 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 6457 6458 /* XXX rate/rate_fb is the hardware rate */ 6459 if ((rate_fb == rate) || 6460 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 6461 (*(u_int16_t *)wh->i_dur == htole16(0))) 6462 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 6463 else 6464 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 6465 m->m_pkthdr.len, rate, isshort); 6466 6467 /* XXX TX encryption */ 6468 6469 switch (mac->mac_fw.fw_hdr_format) { 6470 case BWN_FW_HDR_351: 6471 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r351.plcp), 6472 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 6473 break; 6474 case BWN_FW_HDR_410: 6475 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r410.plcp), 6476 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 6477 break; 6478 case BWN_FW_HDR_598: 6479 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r598.plcp), 6480 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 6481 break; 6482 } 6483 6484 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 6485 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 6486 6487 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 6488 BWN_TX_EFT_FB_CCK; 6489 txhdr->chan = phy->chan; 6490 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 6491 BWN_TX_PHY_ENC_CCK; 6492 /* XXX preamble? obey net80211 */ 6493 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 6494 rate == BWN_CCK_RATE_11MB)) 6495 phyctl |= BWN_TX_PHY_SHORTPRMBL; 6496 6497 if (! phy->gmode) 6498 macctl |= BWN_TX_MAC_5GHZ; 6499 6500 /* XXX TX antenna selection */ 6501 6502 switch (bwn_antenna_sanitize(mac, 0)) { 6503 case 0: 6504 phyctl |= BWN_TX_PHY_ANT01AUTO; 6505 break; 6506 case 1: 6507 phyctl |= BWN_TX_PHY_ANT0; 6508 break; 6509 case 2: 6510 phyctl |= BWN_TX_PHY_ANT1; 6511 break; 6512 case 3: 6513 phyctl |= BWN_TX_PHY_ANT2; 6514 break; 6515 case 4: 6516 phyctl |= BWN_TX_PHY_ANT3; 6517 break; 6518 default: 6519 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 6520 } 6521 6522 if (!ismcast) 6523 macctl |= BWN_TX_MAC_ACK; 6524 6525 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 6526 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 6527 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 6528 macctl |= BWN_TX_MAC_LONGFRAME; 6529 6530 if ((ic->ic_flags & IEEE80211_F_USEPROT) && 6531 ic->ic_protmode != IEEE80211_PROT_NONE) { 6532 /* Note: don't fall back to CCK rates for 5G */ 6533 if (phy->gmode) 6534 rts_rate = BWN_CCK_RATE_1MB; 6535 else 6536 rts_rate = BWN_OFDM_RATE_6MB; 6537 rts_rate_fb = bwn_get_fbrate(rts_rate); 6538 6539 /* XXX 'rate' here is hardware rate now, not the net80211 rate */ 6540 mprot = ieee80211_alloc_prot(ni, m, rate, ic->ic_protmode); 6541 if (mprot == NULL) { 6542 if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, 1); 6543 device_printf(sc->sc_dev, 6544 "could not allocate mbuf for protection mode %d\n", 6545 ic->ic_protmode); 6546 return (ENOBUFS); 6547 } 6548 6549 switch (mac->mac_fw.fw_hdr_format) { 6550 case BWN_FW_HDR_351: 6551 prot_ptr = txhdr->body.r351.rts_frame; 6552 break; 6553 case BWN_FW_HDR_410: 6554 prot_ptr = txhdr->body.r410.rts_frame; 6555 break; 6556 case BWN_FW_HDR_598: 6557 prot_ptr = txhdr->body.r598.rts_frame; 6558 break; 6559 } 6560 6561 bcopy(mtod(mprot, uint8_t *), prot_ptr, mprot->m_pkthdr.len); 6562 m_freem(mprot); 6563 6564 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 6565 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 6566 len = sizeof(struct ieee80211_frame_cts); 6567 } else { 6568 macctl |= BWN_TX_MAC_SEND_RTSCTS; 6569 len = sizeof(struct ieee80211_frame_rts); 6570 } 6571 len += IEEE80211_CRC_LEN; 6572 6573 switch (mac->mac_fw.fw_hdr_format) { 6574 case BWN_FW_HDR_351: 6575 bwn_plcp_genhdr((struct bwn_plcp4 *) 6576 &txhdr->body.r351.rts_plcp, len, rts_rate); 6577 break; 6578 case BWN_FW_HDR_410: 6579 bwn_plcp_genhdr((struct bwn_plcp4 *) 6580 &txhdr->body.r410.rts_plcp, len, rts_rate); 6581 break; 6582 case BWN_FW_HDR_598: 6583 bwn_plcp_genhdr((struct bwn_plcp4 *) 6584 &txhdr->body.r598.rts_plcp, len, rts_rate); 6585 break; 6586 } 6587 6588 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 6589 rts_rate_fb); 6590 6591 switch (mac->mac_fw.fw_hdr_format) { 6592 case BWN_FW_HDR_351: 6593 protwh = (struct ieee80211_frame *) 6594 &txhdr->body.r351.rts_frame; 6595 break; 6596 case BWN_FW_HDR_410: 6597 protwh = (struct ieee80211_frame *) 6598 &txhdr->body.r410.rts_frame; 6599 break; 6600 case BWN_FW_HDR_598: 6601 protwh = (struct ieee80211_frame *) 6602 &txhdr->body.r598.rts_frame; 6603 break; 6604 } 6605 6606 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 6607 6608 if (BWN_ISOFDMRATE(rts_rate)) { 6609 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 6610 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 6611 } else { 6612 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 6613 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 6614 } 6615 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 6616 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 6617 6618 if (fill_phy_ctl1) { 6619 txhdr->phyctl_1rts = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate)); 6620 txhdr->phyctl_1rtsfb = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate_fb)); 6621 } 6622 } 6623 6624 if (fill_phy_ctl1) { 6625 txhdr->phyctl_1 = htole16(bwn_set_txhdr_phyctl1(mac, rate)); 6626 txhdr->phyctl_1fb = htole16(bwn_set_txhdr_phyctl1(mac, rate_fb)); 6627 } 6628 6629 switch (mac->mac_fw.fw_hdr_format) { 6630 case BWN_FW_HDR_351: 6631 txhdr->body.r351.cookie = htole16(cookie); 6632 break; 6633 case BWN_FW_HDR_410: 6634 txhdr->body.r410.cookie = htole16(cookie); 6635 break; 6636 case BWN_FW_HDR_598: 6637 txhdr->body.r598.cookie = htole16(cookie); 6638 break; 6639 } 6640 6641 txhdr->macctl = htole32(macctl); 6642 txhdr->phyctl = htole16(phyctl); 6643 6644 /* 6645 * TX radio tap 6646 */ 6647 if (ieee80211_radiotap_active_vap(vap)) { 6648 sc->sc_tx_th.wt_flags = 0; 6649 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 6650 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 6651 if (isshort && 6652 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 6653 rate == BWN_CCK_RATE_11MB)) 6654 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 6655 sc->sc_tx_th.wt_rate = rate; 6656 6657 ieee80211_radiotap_tx(vap, m); 6658 } 6659 6660 return (0); 6661 } 6662 6663 static void 6664 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 6665 const uint8_t rate) 6666 { 6667 uint32_t d, plen; 6668 uint8_t *raw = plcp->o.raw; 6669 6670 if (BWN_ISOFDMRATE(rate)) { 6671 d = bwn_plcp_getofdm(rate); 6672 KASSERT(!(octets & 0xf000), 6673 ("%s:%d: fail", __func__, __LINE__)); 6674 d |= (octets << 5); 6675 plcp->o.data = htole32(d); 6676 } else { 6677 plen = octets * 16 / rate; 6678 if ((octets * 16 % rate) > 0) { 6679 plen++; 6680 if ((rate == BWN_CCK_RATE_11MB) 6681 && ((octets * 8 % 11) < 4)) { 6682 raw[1] = 0x84; 6683 } else 6684 raw[1] = 0x04; 6685 } else 6686 raw[1] = 0x04; 6687 plcp->o.data |= htole32(plen << 16); 6688 raw[0] = bwn_plcp_getcck(rate); 6689 } 6690 } 6691 6692 static uint8_t 6693 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 6694 { 6695 struct bwn_softc *sc = mac->mac_sc; 6696 uint8_t mask; 6697 6698 if (n == 0) 6699 return (0); 6700 if (mac->mac_phy.gmode) 6701 mask = sc->sc_ant2g; 6702 else 6703 mask = sc->sc_ant5g; 6704 if (!(mask & (1 << (n - 1)))) 6705 return (0); 6706 return (n); 6707 } 6708 6709 /* 6710 * Return a fallback rate for the given rate. 6711 * 6712 * Note: Don't fall back from OFDM to CCK. 6713 */ 6714 static uint8_t 6715 bwn_get_fbrate(uint8_t bitrate) 6716 { 6717 switch (bitrate) { 6718 /* CCK */ 6719 case BWN_CCK_RATE_1MB: 6720 return (BWN_CCK_RATE_1MB); 6721 case BWN_CCK_RATE_2MB: 6722 return (BWN_CCK_RATE_1MB); 6723 case BWN_CCK_RATE_5MB: 6724 return (BWN_CCK_RATE_2MB); 6725 case BWN_CCK_RATE_11MB: 6726 return (BWN_CCK_RATE_5MB); 6727 6728 /* OFDM */ 6729 case BWN_OFDM_RATE_6MB: 6730 return (BWN_OFDM_RATE_6MB); 6731 case BWN_OFDM_RATE_9MB: 6732 return (BWN_OFDM_RATE_6MB); 6733 case BWN_OFDM_RATE_12MB: 6734 return (BWN_OFDM_RATE_9MB); 6735 case BWN_OFDM_RATE_18MB: 6736 return (BWN_OFDM_RATE_12MB); 6737 case BWN_OFDM_RATE_24MB: 6738 return (BWN_OFDM_RATE_18MB); 6739 case BWN_OFDM_RATE_36MB: 6740 return (BWN_OFDM_RATE_24MB); 6741 case BWN_OFDM_RATE_48MB: 6742 return (BWN_OFDM_RATE_36MB); 6743 case BWN_OFDM_RATE_54MB: 6744 return (BWN_OFDM_RATE_48MB); 6745 } 6746 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 6747 return (0); 6748 } 6749 6750 static uint32_t 6751 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6752 uint32_t ctl, const void *_data, int len) 6753 { 6754 struct bwn_softc *sc = mac->mac_sc; 6755 uint32_t value = 0; 6756 const uint8_t *data = _data; 6757 6758 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 6759 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 6760 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 6761 6762 bus_write_multi_4(sc->sc_mem_res, tq->tq_base + BWN_PIO8_TXDATA, 6763 __DECONST(void *, data), (len & ~3)); 6764 if (len & 3) { 6765 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 6766 BWN_PIO8_TXCTL_24_31); 6767 data = &(data[len - 1]); 6768 switch (len & 3) { 6769 case 3: 6770 ctl |= BWN_PIO8_TXCTL_16_23; 6771 value |= (uint32_t)(*data) << 16; 6772 data--; 6773 case 2: 6774 ctl |= BWN_PIO8_TXCTL_8_15; 6775 value |= (uint32_t)(*data) << 8; 6776 data--; 6777 case 1: 6778 value |= (uint32_t)(*data); 6779 } 6780 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 6781 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 6782 } 6783 6784 return (ctl); 6785 } 6786 6787 static void 6788 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6789 uint16_t offset, uint32_t value) 6790 { 6791 6792 BWN_WRITE_4(mac, tq->tq_base + offset, value); 6793 } 6794 6795 static uint16_t 6796 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6797 uint16_t ctl, const void *_data, int len) 6798 { 6799 struct bwn_softc *sc = mac->mac_sc; 6800 const uint8_t *data = _data; 6801 6802 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 6803 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6804 6805 bus_write_multi_2(sc->sc_mem_res, tq->tq_base + BWN_PIO_TXDATA, 6806 __DECONST(void *, data), (len & ~1)); 6807 if (len & 1) { 6808 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 6809 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6810 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 6811 } 6812 6813 return (ctl); 6814 } 6815 6816 static uint16_t 6817 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6818 uint16_t ctl, struct mbuf *m0) 6819 { 6820 int i, j = 0; 6821 uint16_t data = 0; 6822 const uint8_t *buf; 6823 struct mbuf *m = m0; 6824 6825 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 6826 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6827 6828 for (; m != NULL; m = m->m_next) { 6829 buf = mtod(m, const uint8_t *); 6830 for (i = 0; i < m->m_len; i++) { 6831 if (!((j++) % 2)) 6832 data |= buf[i]; 6833 else { 6834 data |= (buf[i] << 8); 6835 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 6836 data = 0; 6837 } 6838 } 6839 } 6840 if (m0->m_pkthdr.len % 2) { 6841 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 6842 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6843 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 6844 } 6845 6846 return (ctl); 6847 } 6848 6849 static void 6850 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 6851 { 6852 6853 /* XXX should exit if 5GHz band .. */ 6854 if (mac->mac_phy.type != BWN_PHYTYPE_G) 6855 return; 6856 6857 BWN_WRITE_2(mac, 0x684, 510 + time); 6858 /* Disabled in Linux b43, can adversely effect performance */ 6859 #if 0 6860 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 6861 #endif 6862 } 6863 6864 static struct bwn_dma_ring * 6865 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 6866 { 6867 6868 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 6869 return (mac->mac_method.dma.wme[WME_AC_BE]); 6870 6871 switch (prio) { 6872 case 3: 6873 return (mac->mac_method.dma.wme[WME_AC_VO]); 6874 case 2: 6875 return (mac->mac_method.dma.wme[WME_AC_VI]); 6876 case 0: 6877 return (mac->mac_method.dma.wme[WME_AC_BE]); 6878 case 1: 6879 return (mac->mac_method.dma.wme[WME_AC_BK]); 6880 } 6881 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 6882 return (NULL); 6883 } 6884 6885 static int 6886 bwn_dma_getslot(struct bwn_dma_ring *dr) 6887 { 6888 int slot; 6889 6890 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 6891 6892 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 6893 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 6894 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 6895 6896 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 6897 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 6898 dr->dr_curslot = slot; 6899 dr->dr_usedslot++; 6900 6901 return (slot); 6902 } 6903 6904 static struct bwn_pio_txqueue * 6905 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 6906 struct bwn_pio_txpkt **pack) 6907 { 6908 struct bwn_pio *pio = &mac->mac_method.pio; 6909 struct bwn_pio_txqueue *tq = NULL; 6910 unsigned int index; 6911 6912 switch (cookie & 0xf000) { 6913 case 0x1000: 6914 tq = &pio->wme[WME_AC_BK]; 6915 break; 6916 case 0x2000: 6917 tq = &pio->wme[WME_AC_BE]; 6918 break; 6919 case 0x3000: 6920 tq = &pio->wme[WME_AC_VI]; 6921 break; 6922 case 0x4000: 6923 tq = &pio->wme[WME_AC_VO]; 6924 break; 6925 case 0x5000: 6926 tq = &pio->mcast; 6927 break; 6928 } 6929 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 6930 if (tq == NULL) 6931 return (NULL); 6932 index = (cookie & 0x0fff); 6933 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 6934 if (index >= N(tq->tq_pkts)) 6935 return (NULL); 6936 *pack = &tq->tq_pkts[index]; 6937 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 6938 return (tq); 6939 } 6940 6941 static void 6942 bwn_txpwr(void *arg, int npending) 6943 { 6944 struct bwn_mac *mac = arg; 6945 struct bwn_softc *sc; 6946 6947 if (mac == NULL) 6948 return; 6949 6950 sc = mac->mac_sc; 6951 6952 BWN_LOCK(sc); 6953 if (mac->mac_status >= BWN_MAC_STATUS_STARTED && 6954 mac->mac_phy.set_txpwr != NULL) 6955 mac->mac_phy.set_txpwr(mac); 6956 BWN_UNLOCK(sc); 6957 } 6958 6959 static void 6960 bwn_task_15s(struct bwn_mac *mac) 6961 { 6962 uint16_t reg; 6963 6964 if (mac->mac_fw.opensource) { 6965 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 6966 if (reg) { 6967 bwn_restart(mac, "fw watchdog"); 6968 return; 6969 } 6970 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 6971 } 6972 if (mac->mac_phy.task_15s) 6973 mac->mac_phy.task_15s(mac); 6974 6975 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 6976 } 6977 6978 static void 6979 bwn_task_30s(struct bwn_mac *mac) 6980 { 6981 6982 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 6983 return; 6984 mac->mac_noise.noi_running = 1; 6985 mac->mac_noise.noi_nsamples = 0; 6986 6987 bwn_noise_gensample(mac); 6988 } 6989 6990 static void 6991 bwn_task_60s(struct bwn_mac *mac) 6992 { 6993 6994 if (mac->mac_phy.task_60s) 6995 mac->mac_phy.task_60s(mac); 6996 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 6997 } 6998 6999 static void 7000 bwn_tasks(void *arg) 7001 { 7002 struct bwn_mac *mac = arg; 7003 struct bwn_softc *sc = mac->mac_sc; 7004 7005 BWN_ASSERT_LOCKED(sc); 7006 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 7007 return; 7008 7009 if (mac->mac_task_state % 4 == 0) 7010 bwn_task_60s(mac); 7011 if (mac->mac_task_state % 2 == 0) 7012 bwn_task_30s(mac); 7013 bwn_task_15s(mac); 7014 7015 mac->mac_task_state++; 7016 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 7017 } 7018 7019 static int 7020 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 7021 { 7022 struct bwn_softc *sc = mac->mac_sc; 7023 7024 KASSERT(a == 0, ("not support APHY\n")); 7025 7026 switch (plcp->o.raw[0] & 0xf) { 7027 case 0xb: 7028 return (BWN_OFDM_RATE_6MB); 7029 case 0xf: 7030 return (BWN_OFDM_RATE_9MB); 7031 case 0xa: 7032 return (BWN_OFDM_RATE_12MB); 7033 case 0xe: 7034 return (BWN_OFDM_RATE_18MB); 7035 case 0x9: 7036 return (BWN_OFDM_RATE_24MB); 7037 case 0xd: 7038 return (BWN_OFDM_RATE_36MB); 7039 case 0x8: 7040 return (BWN_OFDM_RATE_48MB); 7041 case 0xc: 7042 return (BWN_OFDM_RATE_54MB); 7043 } 7044 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 7045 plcp->o.raw[0] & 0xf); 7046 return (-1); 7047 } 7048 7049 static int 7050 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 7051 { 7052 struct bwn_softc *sc = mac->mac_sc; 7053 7054 switch (plcp->o.raw[0]) { 7055 case 0x0a: 7056 return (BWN_CCK_RATE_1MB); 7057 case 0x14: 7058 return (BWN_CCK_RATE_2MB); 7059 case 0x37: 7060 return (BWN_CCK_RATE_5MB); 7061 case 0x6e: 7062 return (BWN_CCK_RATE_11MB); 7063 } 7064 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 7065 return (-1); 7066 } 7067 7068 static void 7069 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 7070 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 7071 int rssi, int noise) 7072 { 7073 struct bwn_softc *sc = mac->mac_sc; 7074 const struct ieee80211_frame_min *wh; 7075 uint64_t tsf; 7076 uint16_t low_mactime_now; 7077 uint16_t mt; 7078 7079 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 7080 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 7081 7082 wh = mtod(m, const struct ieee80211_frame_min *); 7083 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 7084 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 7085 7086 bwn_tsf_read(mac, &tsf); 7087 low_mactime_now = tsf; 7088 tsf = tsf & ~0xffffULL; 7089 7090 switch (mac->mac_fw.fw_hdr_format) { 7091 case BWN_FW_HDR_351: 7092 case BWN_FW_HDR_410: 7093 mt = le16toh(rxhdr->ps4.r351.mac_time); 7094 break; 7095 case BWN_FW_HDR_598: 7096 mt = le16toh(rxhdr->ps4.r598.mac_time); 7097 break; 7098 } 7099 7100 tsf += mt; 7101 if (low_mactime_now < mt) 7102 tsf -= 0x10000; 7103 7104 sc->sc_rx_th.wr_tsf = tsf; 7105 sc->sc_rx_th.wr_rate = rate; 7106 sc->sc_rx_th.wr_antsignal = rssi; 7107 sc->sc_rx_th.wr_antnoise = noise; 7108 } 7109 7110 static void 7111 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 7112 { 7113 uint32_t low, high; 7114 7115 KASSERT(bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 3, 7116 ("%s:%d: fail", __func__, __LINE__)); 7117 7118 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 7119 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 7120 *tsf = high; 7121 *tsf <<= 32; 7122 *tsf |= low; 7123 } 7124 7125 static int 7126 bwn_dma_attach(struct bwn_mac *mac) 7127 { 7128 struct bwn_dma *dma; 7129 struct bwn_softc *sc; 7130 struct bhnd_dma_translation *dt, dma_translation; 7131 bhnd_addr_t addrext_req; 7132 bus_dma_tag_t dmat; 7133 bus_addr_t lowaddr; 7134 u_int addrext_shift, addr_width; 7135 int error; 7136 7137 dma = &mac->mac_method.dma; 7138 sc = mac->mac_sc; 7139 dt = NULL; 7140 7141 if (sc->sc_quirks & BWN_QUIRK_NODMA) 7142 return (0); 7143 7144 KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 5, ("%s: fail", __func__)); 7145 7146 /* Use the DMA engine's maximum host address width to determine the 7147 * addrext constraints, and supported device address width. */ 7148 switch (mac->mac_dmatype) { 7149 case BHND_DMA_ADDR_30BIT: 7150 /* 32-bit engine without addrext support */ 7151 addrext_req = 0x0; 7152 addrext_shift = 0; 7153 7154 /* We can address the full 32-bit device address space */ 7155 addr_width = BHND_DMA_ADDR_32BIT; 7156 break; 7157 7158 case BHND_DMA_ADDR_32BIT: 7159 /* 32-bit engine with addrext support */ 7160 addrext_req = BWN_DMA32_ADDREXT_MASK; 7161 addrext_shift = BWN_DMA32_ADDREXT_SHIFT; 7162 addr_width = BHND_DMA_ADDR_32BIT; 7163 break; 7164 7165 case BHND_DMA_ADDR_64BIT: 7166 /* 64-bit engine with addrext support */ 7167 addrext_req = BWN_DMA64_ADDREXT_MASK; 7168 addrext_shift = BWN_DMA64_ADDREXT_SHIFT; 7169 addr_width = BHND_DMA_ADDR_64BIT; 7170 break; 7171 7172 default: 7173 device_printf(sc->sc_dev, "unsupported DMA address width: %d\n", 7174 mac->mac_dmatype); 7175 return (ENXIO); 7176 } 7177 7178 7179 /* Fetch our device->host DMA translation and tag */ 7180 error = bhnd_get_dma_translation(sc->sc_dev, addr_width, 0, &dmat, 7181 &dma_translation); 7182 if (error) { 7183 device_printf(sc->sc_dev, "error fetching DMA translation: " 7184 "%d\n", error); 7185 return (error); 7186 } 7187 7188 /* Verify that our DMA engine's addrext constraints are compatible with 7189 * our DMA translation */ 7190 if (addrext_req != 0x0 && 7191 (dma_translation.addrext_mask & addrext_req) != addrext_req) 7192 { 7193 device_printf(sc->sc_dev, "bus addrext mask %#jx incompatible " 7194 "with device addrext mask %#jx, disabling extended address " 7195 "support\n", (uintmax_t)dma_translation.addrext_mask, 7196 (uintmax_t)addrext_req); 7197 7198 addrext_req = 0x0; 7199 addrext_shift = 0; 7200 } 7201 7202 /* Apply our addrext translation constraint */ 7203 dma_translation.addrext_mask = addrext_req; 7204 7205 /* Initialize our DMA engine configuration */ 7206 mac->mac_flags |= BWN_MAC_FLAG_DMA; 7207 7208 dma->addrext_shift = addrext_shift; 7209 dma->translation = dma_translation; 7210 7211 dt = &dma->translation; 7212 7213 /* Dermine our translation's maximum supported address */ 7214 lowaddr = MIN((dt->addr_mask | dt->addrext_mask), BUS_SPACE_MAXADDR); 7215 7216 /* 7217 * Create top level DMA tag 7218 */ 7219 error = bus_dma_tag_create(dmat, /* parent */ 7220 BWN_ALIGN, 0, /* alignment, bounds */ 7221 lowaddr, /* lowaddr */ 7222 BUS_SPACE_MAXADDR, /* highaddr */ 7223 NULL, NULL, /* filter, filterarg */ 7224 BUS_SPACE_MAXSIZE, /* maxsize */ 7225 BUS_SPACE_UNRESTRICTED, /* nsegments */ 7226 BUS_SPACE_MAXSIZE, /* maxsegsize */ 7227 0, /* flags */ 7228 NULL, NULL, /* lockfunc, lockarg */ 7229 &dma->parent_dtag); 7230 if (error) { 7231 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 7232 return (error); 7233 } 7234 7235 /* 7236 * Create TX/RX mbuf DMA tag 7237 */ 7238 error = bus_dma_tag_create(dma->parent_dtag, 7239 1, 7240 0, 7241 BUS_SPACE_MAXADDR, 7242 BUS_SPACE_MAXADDR, 7243 NULL, NULL, 7244 MCLBYTES, 7245 1, 7246 BUS_SPACE_MAXSIZE_32BIT, 7247 0, 7248 NULL, NULL, 7249 &dma->rxbuf_dtag); 7250 if (error) { 7251 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 7252 goto fail0; 7253 } 7254 error = bus_dma_tag_create(dma->parent_dtag, 7255 1, 7256 0, 7257 BUS_SPACE_MAXADDR, 7258 BUS_SPACE_MAXADDR, 7259 NULL, NULL, 7260 MCLBYTES, 7261 1, 7262 BUS_SPACE_MAXSIZE_32BIT, 7263 0, 7264 NULL, NULL, 7265 &dma->txbuf_dtag); 7266 if (error) { 7267 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 7268 goto fail1; 7269 } 7270 7271 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1); 7272 if (!dma->wme[WME_AC_BK]) 7273 goto fail2; 7274 7275 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1); 7276 if (!dma->wme[WME_AC_BE]) 7277 goto fail3; 7278 7279 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1); 7280 if (!dma->wme[WME_AC_VI]) 7281 goto fail4; 7282 7283 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1); 7284 if (!dma->wme[WME_AC_VO]) 7285 goto fail5; 7286 7287 dma->mcast = bwn_dma_ringsetup(mac, 4, 1); 7288 if (!dma->mcast) 7289 goto fail6; 7290 dma->rx = bwn_dma_ringsetup(mac, 0, 0); 7291 if (!dma->rx) 7292 goto fail7; 7293 7294 return (error); 7295 7296 fail7: bwn_dma_ringfree(&dma->mcast); 7297 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 7298 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 7299 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 7300 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 7301 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 7302 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 7303 fail0: bus_dma_tag_destroy(dma->parent_dtag); 7304 return (error); 7305 } 7306 7307 static struct bwn_dma_ring * 7308 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 7309 uint16_t cookie, int *slot) 7310 { 7311 struct bwn_dma *dma = &mac->mac_method.dma; 7312 struct bwn_dma_ring *dr; 7313 struct bwn_softc *sc = mac->mac_sc; 7314 7315 BWN_ASSERT_LOCKED(mac->mac_sc); 7316 7317 switch (cookie & 0xf000) { 7318 case 0x1000: 7319 dr = dma->wme[WME_AC_BK]; 7320 break; 7321 case 0x2000: 7322 dr = dma->wme[WME_AC_BE]; 7323 break; 7324 case 0x3000: 7325 dr = dma->wme[WME_AC_VI]; 7326 break; 7327 case 0x4000: 7328 dr = dma->wme[WME_AC_VO]; 7329 break; 7330 case 0x5000: 7331 dr = dma->mcast; 7332 break; 7333 default: 7334 dr = NULL; 7335 KASSERT(0 == 1, 7336 ("invalid cookie value %d", cookie & 0xf000)); 7337 } 7338 *slot = (cookie & 0x0fff); 7339 if (*slot < 0 || *slot >= dr->dr_numslots) { 7340 /* 7341 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 7342 * that it occurs events which have same H/W sequence numbers. 7343 * When it's occurred just prints a WARNING msgs and ignores. 7344 */ 7345 KASSERT(status->seq == dma->lastseq, 7346 ("%s:%d: fail", __func__, __LINE__)); 7347 device_printf(sc->sc_dev, 7348 "out of slot ranges (0 < %d < %d)\n", *slot, 7349 dr->dr_numslots); 7350 return (NULL); 7351 } 7352 dma->lastseq = status->seq; 7353 return (dr); 7354 } 7355 7356 static void 7357 bwn_dma_stop(struct bwn_mac *mac) 7358 { 7359 struct bwn_dma *dma; 7360 7361 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 7362 return; 7363 dma = &mac->mac_method.dma; 7364 7365 bwn_dma_ringstop(&dma->rx); 7366 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 7367 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 7368 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 7369 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 7370 bwn_dma_ringstop(&dma->mcast); 7371 } 7372 7373 static void 7374 bwn_dma_ringstop(struct bwn_dma_ring **dr) 7375 { 7376 7377 if (dr == NULL) 7378 return; 7379 7380 bwn_dma_cleanup(*dr); 7381 } 7382 7383 static void 7384 bwn_pio_stop(struct bwn_mac *mac) 7385 { 7386 struct bwn_pio *pio; 7387 7388 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 7389 return; 7390 pio = &mac->mac_method.pio; 7391 7392 bwn_destroy_queue_tx(&pio->mcast); 7393 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 7394 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 7395 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 7396 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 7397 } 7398 7399 static int 7400 bwn_led_attach(struct bwn_mac *mac) 7401 { 7402 struct bwn_softc *sc = mac->mac_sc; 7403 const uint8_t *led_act = NULL; 7404 int error; 7405 int i; 7406 7407 sc->sc_led_idle = (2350 * hz) / 1000; 7408 sc->sc_led_blink = 1; 7409 7410 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 7411 if (sc->sc_board_info.board_vendor == 7412 bwn_vendor_led_act[i].vid) { 7413 led_act = bwn_vendor_led_act[i].led_act; 7414 break; 7415 } 7416 } 7417 if (led_act == NULL) 7418 led_act = bwn_default_led_act; 7419 7420 _Static_assert(nitems(bwn_led_vars) == BWN_LED_MAX, 7421 "invalid NVRAM variable name array"); 7422 7423 for (i = 0; i < BWN_LED_MAX; ++i) { 7424 struct bwn_led *led; 7425 uint8_t val; 7426 7427 led = &sc->sc_leds[i]; 7428 7429 KASSERT(i < nitems(bwn_led_vars), ("unknown LED index")); 7430 error = bhnd_nvram_getvar_uint8(sc->sc_dev, bwn_led_vars[i], 7431 &val); 7432 if (error) { 7433 if (error != ENOENT) { 7434 device_printf(sc->sc_dev, "NVRAM variable %s " 7435 "unreadable: %d", bwn_led_vars[i], error); 7436 return (error); 7437 } 7438 7439 /* Not found; use default */ 7440 led->led_act = led_act[i]; 7441 } else { 7442 if (val & BWN_LED_ACT_LOW) 7443 led->led_flags |= BWN_LED_F_ACTLOW; 7444 led->led_act = val & BWN_LED_ACT_MASK; 7445 } 7446 led->led_mask = (1 << i); 7447 7448 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 7449 led->led_act == BWN_LED_ACT_BLINK_POLL || 7450 led->led_act == BWN_LED_ACT_BLINK) { 7451 led->led_flags |= BWN_LED_F_BLINK; 7452 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 7453 led->led_flags |= BWN_LED_F_POLLABLE; 7454 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 7455 led->led_flags |= BWN_LED_F_SLOW; 7456 7457 if (sc->sc_blink_led == NULL) { 7458 sc->sc_blink_led = led; 7459 if (led->led_flags & BWN_LED_F_SLOW) 7460 BWN_LED_SLOWDOWN(sc->sc_led_idle); 7461 } 7462 } 7463 7464 DPRINTF(sc, BWN_DEBUG_LED, 7465 "%dth led, act %d, lowact %d\n", i, 7466 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 7467 } 7468 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 7469 7470 return (0); 7471 } 7472 7473 static __inline uint16_t 7474 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 7475 { 7476 7477 if (led->led_flags & BWN_LED_F_ACTLOW) 7478 on = !on; 7479 if (on) 7480 val |= led->led_mask; 7481 else 7482 val &= ~led->led_mask; 7483 return val; 7484 } 7485 7486 static void 7487 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 7488 { 7489 struct bwn_softc *sc = mac->mac_sc; 7490 struct ieee80211com *ic = &sc->sc_ic; 7491 uint16_t val; 7492 int i; 7493 7494 if (nstate == IEEE80211_S_INIT) { 7495 callout_stop(&sc->sc_led_blink_ch); 7496 sc->sc_led_blinking = 0; 7497 } 7498 7499 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) 7500 return; 7501 7502 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 7503 for (i = 0; i < BWN_LED_MAX; ++i) { 7504 struct bwn_led *led = &sc->sc_leds[i]; 7505 int on; 7506 7507 if (led->led_act == BWN_LED_ACT_UNKN || 7508 led->led_act == BWN_LED_ACT_NULL) 7509 continue; 7510 7511 if ((led->led_flags & BWN_LED_F_BLINK) && 7512 nstate != IEEE80211_S_INIT) 7513 continue; 7514 7515 switch (led->led_act) { 7516 case BWN_LED_ACT_ON: /* Always on */ 7517 on = 1; 7518 break; 7519 case BWN_LED_ACT_OFF: /* Always off */ 7520 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 7521 on = 0; 7522 break; 7523 default: 7524 on = 1; 7525 switch (nstate) { 7526 case IEEE80211_S_INIT: 7527 on = 0; 7528 break; 7529 case IEEE80211_S_RUN: 7530 if (led->led_act == BWN_LED_ACT_11G && 7531 ic->ic_curmode != IEEE80211_MODE_11G) 7532 on = 0; 7533 break; 7534 default: 7535 if (led->led_act == BWN_LED_ACT_ASSOC) 7536 on = 0; 7537 break; 7538 } 7539 break; 7540 } 7541 7542 val = bwn_led_onoff(led, val, on); 7543 } 7544 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 7545 } 7546 7547 static void 7548 bwn_led_event(struct bwn_mac *mac, int event) 7549 { 7550 struct bwn_softc *sc = mac->mac_sc; 7551 struct bwn_led *led = sc->sc_blink_led; 7552 int rate; 7553 7554 if (event == BWN_LED_EVENT_POLL) { 7555 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 7556 return; 7557 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 7558 return; 7559 } 7560 7561 sc->sc_led_ticks = ticks; 7562 if (sc->sc_led_blinking) 7563 return; 7564 7565 switch (event) { 7566 case BWN_LED_EVENT_RX: 7567 rate = sc->sc_rx_rate; 7568 break; 7569 case BWN_LED_EVENT_TX: 7570 rate = sc->sc_tx_rate; 7571 break; 7572 case BWN_LED_EVENT_POLL: 7573 rate = 0; 7574 break; 7575 default: 7576 panic("unknown LED event %d\n", event); 7577 break; 7578 } 7579 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 7580 bwn_led_duration[rate].off_dur); 7581 } 7582 7583 static void 7584 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 7585 { 7586 struct bwn_softc *sc = mac->mac_sc; 7587 struct bwn_led *led = sc->sc_blink_led; 7588 uint16_t val; 7589 7590 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 7591 val = bwn_led_onoff(led, val, 1); 7592 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 7593 7594 if (led->led_flags & BWN_LED_F_SLOW) { 7595 BWN_LED_SLOWDOWN(on_dur); 7596 BWN_LED_SLOWDOWN(off_dur); 7597 } 7598 7599 sc->sc_led_blinking = 1; 7600 sc->sc_led_blink_offdur = off_dur; 7601 7602 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 7603 } 7604 7605 static void 7606 bwn_led_blink_next(void *arg) 7607 { 7608 struct bwn_mac *mac = arg; 7609 struct bwn_softc *sc = mac->mac_sc; 7610 uint16_t val; 7611 7612 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 7613 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 7614 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 7615 7616 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 7617 bwn_led_blink_end, mac); 7618 } 7619 7620 static void 7621 bwn_led_blink_end(void *arg) 7622 { 7623 struct bwn_mac *mac = arg; 7624 struct bwn_softc *sc = mac->mac_sc; 7625 7626 sc->sc_led_blinking = 0; 7627 } 7628 7629 static int 7630 bwn_suspend(device_t dev) 7631 { 7632 struct bwn_softc *sc = device_get_softc(dev); 7633 7634 BWN_LOCK(sc); 7635 bwn_stop(sc); 7636 BWN_UNLOCK(sc); 7637 return (0); 7638 } 7639 7640 static int 7641 bwn_resume(device_t dev) 7642 { 7643 struct bwn_softc *sc = device_get_softc(dev); 7644 int error = EDOOFUS; 7645 7646 BWN_LOCK(sc); 7647 if (sc->sc_ic.ic_nrunning > 0) 7648 error = bwn_init(sc); 7649 BWN_UNLOCK(sc); 7650 if (error == 0) 7651 ieee80211_start_all(&sc->sc_ic); 7652 return (0); 7653 } 7654 7655 static void 7656 bwn_rfswitch(void *arg) 7657 { 7658 struct bwn_softc *sc = arg; 7659 struct bwn_mac *mac = sc->sc_curmac; 7660 int cur = 0, prev = 0; 7661 7662 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 7663 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 7664 7665 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP 7666 || mac->mac_phy.type == BWN_PHYTYPE_N) { 7667 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 7668 & BWN_RF_HWENABLED_HI_MASK)) 7669 cur = 1; 7670 } else { 7671 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 7672 & BWN_RF_HWENABLED_LO_MASK) 7673 cur = 1; 7674 } 7675 7676 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 7677 prev = 1; 7678 7679 DPRINTF(sc, BWN_DEBUG_RESET, "%s: called; cur=%d, prev=%d\n", 7680 __func__, cur, prev); 7681 7682 if (cur != prev) { 7683 if (cur) 7684 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 7685 else 7686 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 7687 7688 device_printf(sc->sc_dev, 7689 "status of RF switch is changed to %s\n", 7690 cur ? "ON" : "OFF"); 7691 if (cur != mac->mac_phy.rf_on) { 7692 if (cur) 7693 bwn_rf_turnon(mac); 7694 else 7695 bwn_rf_turnoff(mac); 7696 } 7697 } 7698 7699 callout_schedule(&sc->sc_rfswitch_ch, hz); 7700 } 7701 7702 static void 7703 bwn_sysctl_node(struct bwn_softc *sc) 7704 { 7705 device_t dev = sc->sc_dev; 7706 struct bwn_mac *mac; 7707 struct bwn_stats *stats; 7708 7709 /* XXX assume that count of MAC is only 1. */ 7710 7711 if ((mac = sc->sc_curmac) == NULL) 7712 return; 7713 stats = &mac->mac_stats; 7714 7715 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 7716 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7717 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 7718 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 7719 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7720 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 7721 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 7722 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7723 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 7724 7725 #ifdef BWN_DEBUG 7726 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 7727 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7728 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 7729 #endif 7730 } 7731 7732 static device_method_t bwn_methods[] = { 7733 /* Device interface */ 7734 DEVMETHOD(device_probe, bwn_probe), 7735 DEVMETHOD(device_attach, bwn_attach), 7736 DEVMETHOD(device_detach, bwn_detach), 7737 DEVMETHOD(device_suspend, bwn_suspend), 7738 DEVMETHOD(device_resume, bwn_resume), 7739 DEVMETHOD_END 7740 }; 7741 static driver_t bwn_driver = { 7742 "bwn", 7743 bwn_methods, 7744 sizeof(struct bwn_softc) 7745 }; 7746 static devclass_t bwn_devclass; 7747 DRIVER_MODULE(bwn, bhnd, bwn_driver, bwn_devclass, 0, 0); 7748 MODULE_DEPEND(bwn, bhnd, 1, 1, 1); 7749 MODULE_DEPEND(bwn, gpiobus, 1, 1, 1); 7750 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 7751 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 7752 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 7753 MODULE_VERSION(bwn, 1); 7754