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