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