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, MERCHANTABILITY 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 #if !defined(__DragonFly__) 2814 NULL, NULL, 2815 #endif 2816 BWN_HDRSIZE(mac), 2817 1, 2818 BUS_SPACE_MAXSIZE_32BIT, 2819 0, 2820 #if !defined(__DragonFly__) 2821 NULL, NULL, 2822 #endif 2823 &dr->dr_txring_dtag); 2824 if (error) { 2825 device_printf(sc->sc_dev, 2826 "can't create TX ring DMA tag: TODO frees\n"); 2827 goto fail2; 2828 } 2829 2830 for (i = 0; i < dr->dr_numslots; i += 2) { 2831 dr->getdesc(dr, i, &desc, &mt); 2832 2833 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER; 2834 mt->mt_m = NULL; 2835 mt->mt_ni = NULL; 2836 mt->mt_islast = 0; 2837 error = bus_dmamap_create(dr->dr_txring_dtag, 0, 2838 &mt->mt_dmap); 2839 if (error) { 2840 device_printf(sc->sc_dev, 2841 "can't create RX buf DMA map\n"); 2842 goto fail2; 2843 } 2844 2845 dr->getdesc(dr, i + 1, &desc, &mt); 2846 2847 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY; 2848 mt->mt_m = NULL; 2849 mt->mt_ni = NULL; 2850 mt->mt_islast = 1; 2851 error = bus_dmamap_create(dma->txbuf_dtag, 0, 2852 &mt->mt_dmap); 2853 if (error) { 2854 device_printf(sc->sc_dev, 2855 "can't create RX buf DMA map\n"); 2856 goto fail2; 2857 } 2858 } 2859 } else { 2860 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 2861 &dr->dr_spare_dmap); 2862 if (error) { 2863 device_printf(sc->sc_dev, 2864 "can't create RX buf DMA map\n"); 2865 goto out; /* XXX wrong! */ 2866 } 2867 2868 for (i = 0; i < dr->dr_numslots; i++) { 2869 dr->getdesc(dr, i, &desc, &mt); 2870 2871 error = bus_dmamap_create(dma->rxbuf_dtag, 0, 2872 &mt->mt_dmap); 2873 if (error) { 2874 device_printf(sc->sc_dev, 2875 "can't create RX buf DMA map\n"); 2876 goto out; /* XXX wrong! */ 2877 } 2878 error = bwn_dma_newbuf(dr, desc, mt, 1); 2879 if (error) { 2880 device_printf(sc->sc_dev, 2881 "failed to allocate RX buf\n"); 2882 goto out; /* XXX wrong! */ 2883 } 2884 } 2885 2886 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 2887 BUS_DMASYNC_PREWRITE); 2888 2889 dr->dr_usedslot = dr->dr_numslots; 2890 } 2891 2892 out: 2893 return (dr); 2894 2895 fail2: 2896 if (dr->dr_txhdr_cache != NULL) { 2897 contigfree(dr->dr_txhdr_cache, 2898 (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 2899 BWN_MAXTXHDRSIZE, M_DEVBUF); 2900 } 2901 fail1: 2902 kfree(dr->dr_meta, M_DEVBUF); 2903 fail0: 2904 kfree(dr, M_DEVBUF); 2905 return (NULL); 2906 } 2907 2908 static void 2909 bwn_dma_ringfree(struct bwn_dma_ring **dr) 2910 { 2911 2912 if (dr == NULL) 2913 return; 2914 2915 bwn_dma_free_descbufs(*dr); 2916 bwn_dma_free_ringmemory(*dr); 2917 2918 if ((*dr)->dr_txhdr_cache != NULL) { 2919 contigfree((*dr)->dr_txhdr_cache, 2920 ((*dr)->dr_numslots / BWN_TX_SLOTS_PER_FRAME) * 2921 BWN_MAXTXHDRSIZE, M_DEVBUF); 2922 } 2923 kfree((*dr)->dr_meta, M_DEVBUF); 2924 kfree(*dr, M_DEVBUF); 2925 2926 *dr = NULL; 2927 } 2928 2929 static void 2930 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot, 2931 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 2932 { 2933 struct bwn_dmadesc32 *desc; 2934 2935 *meta = &(dr->dr_meta[slot]); 2936 desc = dr->dr_ring_descbase; 2937 desc = &(desc[slot]); 2938 2939 *gdesc = (struct bwn_dmadesc_generic *)desc; 2940 } 2941 2942 static void 2943 bwn_dma_32_setdesc(struct bwn_dma_ring *dr, 2944 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 2945 int start, int end, int irq) 2946 { 2947 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase; 2948 struct bwn_softc *sc = dr->dr_mac->mac_sc; 2949 uint32_t addr, addrext, ctl; 2950 int slot; 2951 2952 slot = (int)(&(desc->dma.dma32) - descbase); 2953 KASSERT(slot >= 0 && slot < dr->dr_numslots, 2954 ("%s:%d: fail", __func__, __LINE__)); 2955 2956 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK); 2957 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30; 2958 addr |= siba_dma_translation(sc->sc_dev); 2959 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT; 2960 if (slot == dr->dr_numslots - 1) 2961 ctl |= BWN_DMA32_DCTL_DTABLEEND; 2962 if (start) 2963 ctl |= BWN_DMA32_DCTL_FRAMESTART; 2964 if (end) 2965 ctl |= BWN_DMA32_DCTL_FRAMEEND; 2966 if (irq) 2967 ctl |= BWN_DMA32_DCTL_IRQ; 2968 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT) 2969 & BWN_DMA32_DCTL_ADDREXT_MASK; 2970 2971 desc->dma.dma32.control = htole32(ctl); 2972 desc->dma.dma32.address = htole32(addr); 2973 } 2974 2975 static void 2976 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot) 2977 { 2978 2979 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX, 2980 (uint32_t)(slot * sizeof(struct bwn_dmadesc32))); 2981 } 2982 2983 static void 2984 bwn_dma_32_suspend(struct bwn_dma_ring *dr) 2985 { 2986 2987 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 2988 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND); 2989 } 2990 2991 static void 2992 bwn_dma_32_resume(struct bwn_dma_ring *dr) 2993 { 2994 2995 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, 2996 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND); 2997 } 2998 2999 static int 3000 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr) 3001 { 3002 uint32_t val; 3003 3004 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS); 3005 val &= BWN_DMA32_RXDPTR; 3006 3007 return (val / sizeof(struct bwn_dmadesc32)); 3008 } 3009 3010 static void 3011 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot) 3012 { 3013 3014 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, 3015 (uint32_t) (slot * sizeof(struct bwn_dmadesc32))); 3016 } 3017 3018 static void 3019 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot, 3020 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta) 3021 { 3022 struct bwn_dmadesc64 *desc; 3023 3024 *meta = &(dr->dr_meta[slot]); 3025 desc = dr->dr_ring_descbase; 3026 desc = &(desc[slot]); 3027 3028 *gdesc = (struct bwn_dmadesc_generic *)desc; 3029 } 3030 3031 static void 3032 bwn_dma_64_setdesc(struct bwn_dma_ring *dr, 3033 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize, 3034 int start, int end, int irq) 3035 { 3036 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase; 3037 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3038 int slot; 3039 uint32_t ctl0 = 0, ctl1 = 0; 3040 uint32_t addrlo, addrhi; 3041 uint32_t addrext; 3042 3043 slot = (int)(&(desc->dma.dma64) - descbase); 3044 KASSERT(slot >= 0 && slot < dr->dr_numslots, 3045 ("%s:%d: fail", __func__, __LINE__)); 3046 3047 addrlo = (uint32_t) (dmaaddr & 0xffffffff); 3048 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK); 3049 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 3050 30; 3051 addrhi |= (siba_dma_translation(sc->sc_dev) << 1); 3052 if (slot == dr->dr_numslots - 1) 3053 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND; 3054 if (start) 3055 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART; 3056 if (end) 3057 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND; 3058 if (irq) 3059 ctl0 |= BWN_DMA64_DCTL0_IRQ; 3060 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT; 3061 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT) 3062 & BWN_DMA64_DCTL1_ADDREXT_MASK; 3063 3064 desc->dma.dma64.control0 = htole32(ctl0); 3065 desc->dma.dma64.control1 = htole32(ctl1); 3066 desc->dma.dma64.address_low = htole32(addrlo); 3067 desc->dma.dma64.address_high = htole32(addrhi); 3068 } 3069 3070 static void 3071 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot) 3072 { 3073 3074 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX, 3075 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3076 } 3077 3078 static void 3079 bwn_dma_64_suspend(struct bwn_dma_ring *dr) 3080 { 3081 3082 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3083 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND); 3084 } 3085 3086 static void 3087 bwn_dma_64_resume(struct bwn_dma_ring *dr) 3088 { 3089 3090 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, 3091 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND); 3092 } 3093 3094 static int 3095 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr) 3096 { 3097 uint32_t val; 3098 3099 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS); 3100 val &= BWN_DMA64_RXSTATDPTR; 3101 3102 return (val / sizeof(struct bwn_dmadesc64)); 3103 } 3104 3105 static void 3106 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot) 3107 { 3108 3109 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, 3110 (uint32_t)(slot * sizeof(struct bwn_dmadesc64))); 3111 } 3112 3113 static int 3114 bwn_dma_allocringmemory(struct bwn_dma_ring *dr) 3115 { 3116 struct bwn_mac *mac = dr->dr_mac; 3117 struct bwn_dma *dma = &mac->mac_method.dma; 3118 struct bwn_softc *sc = mac->mac_sc; 3119 int error; 3120 3121 error = bus_dma_tag_create(dma->parent_dtag, 3122 BWN_ALIGN, 0, 3123 BUS_SPACE_MAXADDR, 3124 BUS_SPACE_MAXADDR, 3125 #if !defined(__DragonFly__) 3126 NULL, NULL, 3127 #endif 3128 BWN_DMA_RINGMEMSIZE, 3129 1, 3130 BUS_SPACE_MAXSIZE_32BIT, 3131 0, 3132 #if !defined(__DragonFly__) 3133 NULL, NULL, 3134 #endif 3135 &dr->dr_ring_dtag); 3136 if (error) { 3137 device_printf(sc->sc_dev, 3138 "can't create TX ring DMA tag: TODO frees\n"); 3139 return (-1); 3140 } 3141 3142 error = bus_dmamem_alloc(dr->dr_ring_dtag, 3143 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO, 3144 &dr->dr_ring_dmap); 3145 if (error) { 3146 device_printf(sc->sc_dev, 3147 "can't allocate DMA mem: TODO frees\n"); 3148 return (-1); 3149 } 3150 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap, 3151 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE, 3152 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT); 3153 if (error || dr->dr_ring_dmabase == 0) { 3154 device_printf(sc->sc_dev, 3155 "can't load DMA mem: TODO free\n"); 3156 return (-1); 3157 } 3158 3159 return (0); 3160 } 3161 3162 static void 3163 bwn_dma_setup(struct bwn_dma_ring *dr) 3164 { 3165 struct bwn_softc *sc = dr->dr_mac->mac_sc; 3166 uint64_t ring64; 3167 uint32_t addrext, ring32, value; 3168 uint32_t trans = siba_dma_translation(sc->sc_dev); 3169 3170 if (dr->dr_tx) { 3171 dr->dr_curslot = -1; 3172 3173 if (dr->dr_type == BWN_DMA_64BIT) { 3174 ring64 = (uint64_t)(dr->dr_ring_dmabase); 3175 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) 3176 >> 30; 3177 value = BWN_DMA64_TXENABLE; 3178 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT) 3179 & BWN_DMA64_TXADDREXT_MASK; 3180 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value); 3181 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 3182 (ring64 & 0xffffffff)); 3183 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 3184 ((ring64 >> 32) & 3185 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1)); 3186 } else { 3187 ring32 = (uint32_t)(dr->dr_ring_dmabase); 3188 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 3189 value = BWN_DMA32_TXENABLE; 3190 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT) 3191 & BWN_DMA32_TXADDREXT_MASK; 3192 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value); 3193 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 3194 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 3195 } 3196 return; 3197 } 3198 3199 /* 3200 * set for RX 3201 */ 3202 dr->dr_usedslot = dr->dr_numslots; 3203 3204 if (dr->dr_type == BWN_DMA_64BIT) { 3205 ring64 = (uint64_t)(dr->dr_ring_dmabase); 3206 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30; 3207 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT); 3208 value |= BWN_DMA64_RXENABLE; 3209 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT) 3210 & BWN_DMA64_RXADDREXT_MASK; 3211 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value); 3212 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff)); 3213 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 3214 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK) 3215 | (trans << 1)); 3216 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots * 3217 sizeof(struct bwn_dmadesc64)); 3218 } else { 3219 ring32 = (uint32_t)(dr->dr_ring_dmabase); 3220 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30; 3221 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT); 3222 value |= BWN_DMA32_RXENABLE; 3223 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT) 3224 & BWN_DMA32_RXADDREXT_MASK; 3225 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value); 3226 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 3227 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans); 3228 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots * 3229 sizeof(struct bwn_dmadesc32)); 3230 } 3231 } 3232 3233 static void 3234 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr) 3235 { 3236 3237 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap); 3238 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase, 3239 dr->dr_ring_dmap); 3240 } 3241 3242 static void 3243 bwn_dma_cleanup(struct bwn_dma_ring *dr) 3244 { 3245 3246 if (dr->dr_tx) { 3247 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 3248 if (dr->dr_type == BWN_DMA_64BIT) { 3249 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0); 3250 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0); 3251 } else 3252 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0); 3253 } else { 3254 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type); 3255 if (dr->dr_type == BWN_DMA_64BIT) { 3256 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0); 3257 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0); 3258 } else 3259 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0); 3260 } 3261 } 3262 3263 static void 3264 bwn_dma_free_descbufs(struct bwn_dma_ring *dr) 3265 { 3266 struct bwn_dmadesc_generic *desc; 3267 struct bwn_dmadesc_meta *meta; 3268 struct bwn_mac *mac = dr->dr_mac; 3269 struct bwn_dma *dma = &mac->mac_method.dma; 3270 struct bwn_softc *sc = mac->mac_sc; 3271 int i; 3272 3273 if (!dr->dr_usedslot) 3274 return; 3275 for (i = 0; i < dr->dr_numslots; i++) { 3276 dr->getdesc(dr, i, &desc, &meta); 3277 3278 if (meta->mt_m == NULL) { 3279 if (!dr->dr_tx) 3280 device_printf(sc->sc_dev, "%s: not TX?\n", 3281 __func__); 3282 continue; 3283 } 3284 if (dr->dr_tx) { 3285 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 3286 bus_dmamap_unload(dr->dr_txring_dtag, 3287 meta->mt_dmap); 3288 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 3289 bus_dmamap_unload(dma->txbuf_dtag, 3290 meta->mt_dmap); 3291 } 3292 } else 3293 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 3294 bwn_dma_free_descbuf(dr, meta); 3295 } 3296 } 3297 3298 static int 3299 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base, 3300 int type) 3301 { 3302 struct bwn_softc *sc = mac->mac_sc; 3303 uint32_t value; 3304 int i; 3305 uint16_t offset; 3306 3307 for (i = 0; i < 10; i++) { 3308 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 3309 BWN_DMA32_TXSTATUS; 3310 value = BWN_READ_4(mac, base + offset); 3311 if (type == BWN_DMA_64BIT) { 3312 value &= BWN_DMA64_TXSTAT; 3313 if (value == BWN_DMA64_TXSTAT_DISABLED || 3314 value == BWN_DMA64_TXSTAT_IDLEWAIT || 3315 value == BWN_DMA64_TXSTAT_STOPPED) 3316 break; 3317 } else { 3318 value &= BWN_DMA32_TXSTATE; 3319 if (value == BWN_DMA32_TXSTAT_DISABLED || 3320 value == BWN_DMA32_TXSTAT_IDLEWAIT || 3321 value == BWN_DMA32_TXSTAT_STOPPED) 3322 break; 3323 } 3324 DELAY(1000); 3325 } 3326 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL; 3327 BWN_WRITE_4(mac, base + offset, 0); 3328 for (i = 0; i < 10; i++) { 3329 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS : 3330 BWN_DMA32_TXSTATUS; 3331 value = BWN_READ_4(mac, base + offset); 3332 if (type == BWN_DMA_64BIT) { 3333 value &= BWN_DMA64_TXSTAT; 3334 if (value == BWN_DMA64_TXSTAT_DISABLED) { 3335 i = -1; 3336 break; 3337 } 3338 } else { 3339 value &= BWN_DMA32_TXSTATE; 3340 if (value == BWN_DMA32_TXSTAT_DISABLED) { 3341 i = -1; 3342 break; 3343 } 3344 } 3345 DELAY(1000); 3346 } 3347 if (i != -1) { 3348 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 3349 return (ENODEV); 3350 } 3351 DELAY(1000); 3352 3353 return (0); 3354 } 3355 3356 static int 3357 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base, 3358 int type) 3359 { 3360 struct bwn_softc *sc = mac->mac_sc; 3361 uint32_t value; 3362 int i; 3363 uint16_t offset; 3364 3365 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL; 3366 BWN_WRITE_4(mac, base + offset, 0); 3367 for (i = 0; i < 10; i++) { 3368 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS : 3369 BWN_DMA32_RXSTATUS; 3370 value = BWN_READ_4(mac, base + offset); 3371 if (type == BWN_DMA_64BIT) { 3372 value &= BWN_DMA64_RXSTAT; 3373 if (value == BWN_DMA64_RXSTAT_DISABLED) { 3374 i = -1; 3375 break; 3376 } 3377 } else { 3378 value &= BWN_DMA32_RXSTATE; 3379 if (value == BWN_DMA32_RXSTAT_DISABLED) { 3380 i = -1; 3381 break; 3382 } 3383 } 3384 DELAY(1000); 3385 } 3386 if (i != -1) { 3387 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 3388 return (ENODEV); 3389 } 3390 3391 return (0); 3392 } 3393 3394 static void 3395 bwn_dma_free_descbuf(struct bwn_dma_ring *dr, 3396 struct bwn_dmadesc_meta *meta) 3397 { 3398 3399 if (meta->mt_m != NULL) { 3400 m_freem(meta->mt_m); 3401 meta->mt_m = NULL; 3402 } 3403 if (meta->mt_ni != NULL) { 3404 ieee80211_free_node(meta->mt_ni); 3405 meta->mt_ni = NULL; 3406 } 3407 } 3408 3409 static void 3410 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 3411 { 3412 struct bwn_rxhdr4 *rxhdr; 3413 unsigned char *frame; 3414 3415 rxhdr = mtod(m, struct bwn_rxhdr4 *); 3416 rxhdr->frame_len = 0; 3417 3418 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset + 3419 sizeof(struct bwn_plcp6) + 2, 3420 ("%s:%d: fail", __func__, __LINE__)); 3421 frame = mtod(m, char *) + dr->dr_frameoffset; 3422 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */); 3423 } 3424 3425 static uint8_t 3426 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m) 3427 { 3428 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset; 3429 3430 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) 3431 == 0xff); 3432 } 3433 3434 static void 3435 bwn_wme_init(struct bwn_mac *mac) 3436 { 3437 3438 bwn_wme_load(mac); 3439 3440 /* enable WME support. */ 3441 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF); 3442 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) | 3443 BWN_IFSCTL_USE_EDCF); 3444 } 3445 3446 static void 3447 bwn_spu_setdelay(struct bwn_mac *mac, int idle) 3448 { 3449 struct bwn_softc *sc = mac->mac_sc; 3450 struct ieee80211com *ic = &sc->sc_ic; 3451 uint16_t delay; /* microsec */ 3452 3453 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; 3454 if (ic->ic_opmode == IEEE80211_M_IBSS || idle) 3455 delay = 500; 3456 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8)) 3457 delay = max(delay, (uint16_t)2400); 3458 3459 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay); 3460 } 3461 3462 static void 3463 bwn_bt_enable(struct bwn_mac *mac) 3464 { 3465 struct bwn_softc *sc = mac->mac_sc; 3466 uint64_t hf; 3467 3468 if (bwn_bluetooth == 0) 3469 return; 3470 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0) 3471 return; 3472 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode) 3473 return; 3474 3475 hf = bwn_hf_read(mac); 3476 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD) 3477 hf |= BWN_HF_BT_COEXISTALT; 3478 else 3479 hf |= BWN_HF_BT_COEXIST; 3480 bwn_hf_write(mac, hf); 3481 } 3482 3483 static void 3484 bwn_set_macaddr(struct bwn_mac *mac) 3485 { 3486 3487 bwn_mac_write_bssid(mac); 3488 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, 3489 mac->mac_sc->sc_ic.ic_macaddr); 3490 } 3491 3492 static void 3493 bwn_clear_keys(struct bwn_mac *mac) 3494 { 3495 int i; 3496 3497 for (i = 0; i < mac->mac_max_nr_keys; i++) { 3498 KASSERT(i >= 0 && i < mac->mac_max_nr_keys, 3499 ("%s:%d: fail", __func__, __LINE__)); 3500 3501 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE, 3502 NULL, BWN_SEC_KEYSIZE, NULL); 3503 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) { 3504 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE, 3505 NULL, BWN_SEC_KEYSIZE, NULL); 3506 } 3507 mac->mac_key[i].keyconf = NULL; 3508 } 3509 } 3510 3511 static void 3512 bwn_crypt_init(struct bwn_mac *mac) 3513 { 3514 struct bwn_softc *sc = mac->mac_sc; 3515 3516 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20; 3517 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key), 3518 ("%s:%d: fail", __func__, __LINE__)); 3519 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP); 3520 mac->mac_ktp *= 2; 3521 if (siba_get_revid(sc->sc_dev) >= 5) 3522 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8); 3523 bwn_clear_keys(mac); 3524 } 3525 3526 static void 3527 bwn_chip_exit(struct bwn_mac *mac) 3528 { 3529 struct bwn_softc *sc = mac->mac_sc; 3530 3531 bwn_phy_exit(mac); 3532 siba_gpio_set(sc->sc_dev, 0); 3533 } 3534 3535 static int 3536 bwn_fw_fillinfo(struct bwn_mac *mac) 3537 { 3538 int error; 3539 3540 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT); 3541 if (error == 0) 3542 return (0); 3543 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE); 3544 if (error == 0) 3545 return (0); 3546 return (error); 3547 } 3548 3549 static int 3550 bwn_gpio_init(struct bwn_mac *mac) 3551 { 3552 struct bwn_softc *sc = mac->mac_sc; 3553 uint32_t mask = 0x1f, set = 0xf, value; 3554 3555 BWN_WRITE_4(mac, BWN_MACCTL, 3556 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK); 3557 BWN_WRITE_2(mac, BWN_GPIO_MASK, 3558 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f); 3559 3560 if (siba_get_chipid(sc->sc_dev) == 0x4301) { 3561 mask |= 0x0060; 3562 set |= 0x0060; 3563 } 3564 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) { 3565 BWN_WRITE_2(mac, BWN_GPIO_MASK, 3566 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200); 3567 mask |= 0x0200; 3568 set |= 0x0200; 3569 } 3570 if (siba_get_revid(sc->sc_dev) >= 2) 3571 mask |= 0x0010; 3572 3573 value = siba_gpio_get(sc->sc_dev); 3574 if (value == -1) 3575 return (0); 3576 siba_gpio_set(sc->sc_dev, (value & mask) | set); 3577 3578 return (0); 3579 } 3580 3581 static int 3582 bwn_fw_loadinitvals(struct bwn_mac *mac) 3583 { 3584 #define GETFWOFFSET(fwp, offset) \ 3585 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset)) 3586 const size_t hdr_len = sizeof(struct bwn_fwhdr); 3587 const struct bwn_fwhdr *hdr; 3588 struct bwn_fw *fw = &mac->mac_fw; 3589 int error; 3590 3591 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data); 3592 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len), 3593 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len); 3594 if (error) 3595 return (error); 3596 if (fw->initvals_band.fw) { 3597 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data); 3598 error = bwn_fwinitvals_write(mac, 3599 GETFWOFFSET(fw->initvals_band, hdr_len), 3600 be32toh(hdr->size), 3601 fw->initvals_band.fw->datasize - hdr_len); 3602 } 3603 return (error); 3604 #undef GETFWOFFSET 3605 } 3606 3607 static int 3608 bwn_phy_init(struct bwn_mac *mac) 3609 { 3610 struct bwn_softc *sc = mac->mac_sc; 3611 int error; 3612 3613 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac); 3614 mac->mac_phy.rf_onoff(mac, 1); 3615 error = mac->mac_phy.init(mac); 3616 if (error) { 3617 device_printf(sc->sc_dev, "PHY init failed\n"); 3618 goto fail0; 3619 } 3620 error = bwn_switch_channel(mac, 3621 mac->mac_phy.get_default_chan(mac)); 3622 if (error) { 3623 device_printf(sc->sc_dev, 3624 "failed to switch default channel\n"); 3625 goto fail1; 3626 } 3627 return (0); 3628 fail1: 3629 if (mac->mac_phy.exit) 3630 mac->mac_phy.exit(mac); 3631 fail0: 3632 mac->mac_phy.rf_onoff(mac, 0); 3633 3634 return (error); 3635 } 3636 3637 static void 3638 bwn_set_txantenna(struct bwn_mac *mac, int antenna) 3639 { 3640 uint16_t ant; 3641 uint16_t tmp; 3642 3643 ant = bwn_ant2phy(antenna); 3644 3645 /* For ACK/CTS */ 3646 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL); 3647 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 3648 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp); 3649 /* For Probe Resposes */ 3650 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL); 3651 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant; 3652 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp); 3653 } 3654 3655 static void 3656 bwn_set_opmode(struct bwn_mac *mac) 3657 { 3658 struct bwn_softc *sc = mac->mac_sc; 3659 struct ieee80211com *ic = &sc->sc_ic; 3660 uint32_t ctl; 3661 uint16_t cfp_pretbtt; 3662 3663 ctl = BWN_READ_4(mac, BWN_MACCTL); 3664 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL | 3665 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS | 3666 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC); 3667 ctl |= BWN_MACCTL_STA; 3668 3669 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 3670 ic->ic_opmode == IEEE80211_M_MBSS) 3671 ctl |= BWN_MACCTL_HOSTAP; 3672 else if (ic->ic_opmode == IEEE80211_M_IBSS) 3673 ctl &= ~BWN_MACCTL_STA; 3674 ctl |= sc->sc_filters; 3675 3676 if (siba_get_revid(sc->sc_dev) <= 4) 3677 ctl |= BWN_MACCTL_PROMISC; 3678 3679 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 3680 3681 cfp_pretbtt = 2; 3682 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) { 3683 if (siba_get_chipid(sc->sc_dev) == 0x4306 && 3684 siba_get_chiprev(sc->sc_dev) == 3) 3685 cfp_pretbtt = 100; 3686 else 3687 cfp_pretbtt = 50; 3688 } 3689 BWN_WRITE_2(mac, 0x612, cfp_pretbtt); 3690 } 3691 3692 static int 3693 bwn_dma_gettype(struct bwn_mac *mac) 3694 { 3695 uint32_t tmp; 3696 uint16_t base; 3697 3698 tmp = BWN_READ_4(mac, SIBA_TGSHIGH); 3699 if (tmp & SIBA_TGSHIGH_DMA64) 3700 return (BWN_DMA_64BIT); 3701 base = bwn_dma_base(0, 0); 3702 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK); 3703 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); 3704 if (tmp & BWN_DMA32_TXADDREXT_MASK) 3705 return (BWN_DMA_32BIT); 3706 3707 return (BWN_DMA_30BIT); 3708 } 3709 3710 static void 3711 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) 3712 { 3713 if (error) { 3714 *((bus_addr_t *)arg) = 0; 3715 } else { 3716 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 3717 *((bus_addr_t *)arg) = seg->ds_addr; 3718 } 3719 } 3720 3721 void 3722 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon) 3723 { 3724 struct bwn_phy *phy = &mac->mac_phy; 3725 struct bwn_softc *sc = mac->mac_sc; 3726 unsigned int i, max_loop; 3727 uint16_t value; 3728 uint32_t buffer[5] = { 3729 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 3730 }; 3731 3732 if (ofdm) { 3733 max_loop = 0x1e; 3734 buffer[0] = 0x000201cc; 3735 } else { 3736 max_loop = 0xfa; 3737 buffer[0] = 0x000b846e; 3738 } 3739 3740 BWN_ASSERT_LOCKED(mac->mac_sc); 3741 3742 for (i = 0; i < 5; i++) 3743 bwn_ram_write(mac, i * 4, buffer[i]); 3744 3745 BWN_WRITE_2(mac, 0x0568, 0x0000); 3746 BWN_WRITE_2(mac, 0x07c0, 3747 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100); 3748 3749 value = (ofdm ? 0x41 : 0x40); 3750 BWN_WRITE_2(mac, 0x050c, value); 3751 3752 if (phy->type == BWN_PHYTYPE_N || phy->type == BWN_PHYTYPE_LP || 3753 phy->type == BWN_PHYTYPE_LCN) 3754 BWN_WRITE_2(mac, 0x0514, 0x1a02); 3755 BWN_WRITE_2(mac, 0x0508, 0x0000); 3756 BWN_WRITE_2(mac, 0x050a, 0x0000); 3757 BWN_WRITE_2(mac, 0x054c, 0x0000); 3758 BWN_WRITE_2(mac, 0x056a, 0x0014); 3759 BWN_WRITE_2(mac, 0x0568, 0x0826); 3760 BWN_WRITE_2(mac, 0x0500, 0x0000); 3761 3762 /* XXX TODO: n phy pa override? */ 3763 3764 switch (phy->type) { 3765 case BWN_PHYTYPE_N: 3766 case BWN_PHYTYPE_LCN: 3767 BWN_WRITE_2(mac, 0x0502, 0x00d0); 3768 break; 3769 case BWN_PHYTYPE_LP: 3770 BWN_WRITE_2(mac, 0x0502, 0x0050); 3771 break; 3772 default: 3773 BWN_WRITE_2(mac, 0x0502, 0x0030); 3774 break; 3775 } 3776 3777 /* flush */ 3778 BWN_READ_2(mac, 0x0502); 3779 3780 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 3781 BWN_RF_WRITE(mac, 0x0051, 0x0017); 3782 for (i = 0x00; i < max_loop; i++) { 3783 value = BWN_READ_2(mac, 0x050e); 3784 if (value & 0x0080) 3785 break; 3786 DELAY(10); 3787 } 3788 for (i = 0x00; i < 0x0a; i++) { 3789 value = BWN_READ_2(mac, 0x050e); 3790 if (value & 0x0400) 3791 break; 3792 DELAY(10); 3793 } 3794 for (i = 0x00; i < 0x19; i++) { 3795 value = BWN_READ_2(mac, 0x0690); 3796 if (!(value & 0x0100)) 3797 break; 3798 DELAY(10); 3799 } 3800 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5) 3801 BWN_RF_WRITE(mac, 0x0051, 0x0037); 3802 } 3803 3804 void 3805 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val) 3806 { 3807 uint32_t macctl; 3808 3809 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__)); 3810 3811 macctl = BWN_READ_4(mac, BWN_MACCTL); 3812 if (macctl & BWN_MACCTL_BIGENDIAN) 3813 kprintf("TODO: need swap\n"); 3814 3815 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset); 3816 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 3817 BWN_WRITE_4(mac, BWN_RAM_DATA, val); 3818 } 3819 3820 void 3821 bwn_mac_suspend(struct bwn_mac *mac) 3822 { 3823 struct bwn_softc *sc = mac->mac_sc; 3824 int i; 3825 uint32_t tmp; 3826 3827 KASSERT(mac->mac_suspended >= 0, 3828 ("%s:%d: fail", __func__, __LINE__)); 3829 3830 if (mac->mac_suspended == 0) { 3831 bwn_psctl(mac, BWN_PS_AWAKE); 3832 BWN_WRITE_4(mac, BWN_MACCTL, 3833 BWN_READ_4(mac, BWN_MACCTL) 3834 & ~BWN_MACCTL_ON); 3835 BWN_READ_4(mac, BWN_MACCTL); 3836 for (i = 35; i; i--) { 3837 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 3838 if (tmp & BWN_INTR_MAC_SUSPENDED) 3839 goto out; 3840 DELAY(10); 3841 } 3842 for (i = 40; i; i--) { 3843 tmp = BWN_READ_4(mac, BWN_INTR_REASON); 3844 if (tmp & BWN_INTR_MAC_SUSPENDED) 3845 goto out; 3846 DELAY(1000); 3847 } 3848 device_printf(sc->sc_dev, "MAC suspend failed\n"); 3849 } 3850 out: 3851 mac->mac_suspended++; 3852 } 3853 3854 void 3855 bwn_mac_enable(struct bwn_mac *mac) 3856 { 3857 struct bwn_softc *sc = mac->mac_sc; 3858 uint16_t state; 3859 3860 state = bwn_shm_read_2(mac, BWN_SHARED, 3861 BWN_SHARED_UCODESTAT); 3862 if (state != BWN_SHARED_UCODESTAT_SUSPEND && 3863 state != BWN_SHARED_UCODESTAT_SLEEP) 3864 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state); 3865 3866 mac->mac_suspended--; 3867 KASSERT(mac->mac_suspended >= 0, 3868 ("%s:%d: fail", __func__, __LINE__)); 3869 if (mac->mac_suspended == 0) { 3870 BWN_WRITE_4(mac, BWN_MACCTL, 3871 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON); 3872 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED); 3873 BWN_READ_4(mac, BWN_MACCTL); 3874 BWN_READ_4(mac, BWN_INTR_REASON); 3875 bwn_psctl(mac, 0); 3876 } 3877 } 3878 3879 void 3880 bwn_psctl(struct bwn_mac *mac, uint32_t flags) 3881 { 3882 struct bwn_softc *sc = mac->mac_sc; 3883 int i; 3884 uint16_t ucstat; 3885 3886 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)), 3887 ("%s:%d: fail", __func__, __LINE__)); 3888 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)), 3889 ("%s:%d: fail", __func__, __LINE__)); 3890 3891 /* XXX forcibly awake and hwps-off */ 3892 3893 BWN_WRITE_4(mac, BWN_MACCTL, 3894 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) & 3895 ~BWN_MACCTL_HWPS); 3896 BWN_READ_4(mac, BWN_MACCTL); 3897 if (siba_get_revid(sc->sc_dev) >= 5) { 3898 for (i = 0; i < 100; i++) { 3899 ucstat = bwn_shm_read_2(mac, BWN_SHARED, 3900 BWN_SHARED_UCODESTAT); 3901 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP) 3902 break; 3903 DELAY(10); 3904 } 3905 } 3906 } 3907 3908 static int 3909 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type) 3910 { 3911 struct bwn_softc *sc = mac->mac_sc; 3912 struct bwn_fw *fw = &mac->mac_fw; 3913 const uint8_t rev = siba_get_revid(sc->sc_dev); 3914 const char *filename; 3915 uint32_t high; 3916 int error; 3917 3918 /* microcode */ 3919 filename = NULL; 3920 switch (rev) { 3921 case 42: 3922 if (mac->mac_phy.type == BWN_PHYTYPE_AC) 3923 filename = "ucode42"; 3924 break; 3925 case 40: 3926 if (mac->mac_phy.type == BWN_PHYTYPE_AC) 3927 filename = "ucode40"; 3928 break; 3929 case 33: 3930 if (mac->mac_phy.type == BWN_PHYTYPE_LCN40) 3931 filename = "ucode33_lcn40"; 3932 break; 3933 case 30: 3934 if (mac->mac_phy.type == BWN_PHYTYPE_N) 3935 filename = "ucode30_mimo"; 3936 break; 3937 case 29: 3938 if (mac->mac_phy.type == BWN_PHYTYPE_HT) 3939 filename = "ucode29_mimo"; 3940 break; 3941 case 26: 3942 if (mac->mac_phy.type == BWN_PHYTYPE_HT) 3943 filename = "ucode26_mimo"; 3944 break; 3945 case 28: 3946 case 25: 3947 if (mac->mac_phy.type == BWN_PHYTYPE_N) 3948 filename = "ucode25_mimo"; 3949 else if (mac->mac_phy.type == BWN_PHYTYPE_LCN) 3950 filename = "ucode25_lcn"; 3951 break; 3952 case 24: 3953 if (mac->mac_phy.type == BWN_PHYTYPE_LCN) 3954 filename = "ucode24_lcn"; 3955 break; 3956 case 23: 3957 if (mac->mac_phy.type == BWN_PHYTYPE_N) 3958 filename = "ucode16_mimo"; 3959 break; 3960 case 16: 3961 case 17: 3962 case 18: 3963 case 19: 3964 if (mac->mac_phy.type == BWN_PHYTYPE_N) 3965 filename = "ucode16_mimo"; 3966 else if (mac->mac_phy.type == BWN_PHYTYPE_LP) 3967 filename = "ucode16_lp"; 3968 break; 3969 case 15: 3970 filename = "ucode15"; 3971 break; 3972 case 14: 3973 filename = "ucode14"; 3974 break; 3975 case 13: 3976 filename = "ucode13"; 3977 break; 3978 case 12: 3979 case 11: 3980 filename = "ucode11"; 3981 break; 3982 case 10: 3983 case 9: 3984 case 8: 3985 case 7: 3986 case 6: 3987 case 5: 3988 filename = "ucode5"; 3989 break; 3990 default: 3991 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev); 3992 bwn_release_firmware(mac); 3993 return (EOPNOTSUPP); 3994 } 3995 3996 device_printf(sc->sc_dev, "ucode fw: %s\n", filename); 3997 error = bwn_fw_get(mac, type, filename, &fw->ucode); 3998 if (error) { 3999 bwn_release_firmware(mac); 4000 return (error); 4001 } 4002 4003 /* PCM */ 4004 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__)); 4005 if (rev >= 5 && rev <= 10) { 4006 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm); 4007 if (error == ENOENT) 4008 fw->no_pcmfile = 1; 4009 else if (error) { 4010 bwn_release_firmware(mac); 4011 return (error); 4012 } 4013 } else if (rev < 11) { 4014 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev); 4015 return (EOPNOTSUPP); 4016 } 4017 4018 /* initvals */ 4019 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); 4020 switch (mac->mac_phy.type) { 4021 case BWN_PHYTYPE_A: 4022 if (rev < 5 || rev > 10) 4023 goto fail1; 4024 if (high & BWN_TGSHIGH_HAVE_2GHZ) 4025 filename = "a0g1initvals5"; 4026 else 4027 filename = "a0g0initvals5"; 4028 break; 4029 case BWN_PHYTYPE_G: 4030 if (rev >= 5 && rev <= 10) 4031 filename = "b0g0initvals5"; 4032 else if (rev >= 13) 4033 filename = "b0g0initvals13"; 4034 else 4035 goto fail1; 4036 break; 4037 case BWN_PHYTYPE_LP: 4038 if (rev == 13) 4039 filename = "lp0initvals13"; 4040 else if (rev == 14) 4041 filename = "lp0initvals14"; 4042 else if (rev >= 15) 4043 filename = "lp0initvals15"; 4044 else 4045 goto fail1; 4046 break; 4047 case BWN_PHYTYPE_N: 4048 if (rev == 30) 4049 filename = "n16initvals30"; 4050 else if (rev == 28 || rev == 25) 4051 filename = "n0initvals25"; 4052 else if (rev == 24) 4053 filename = "n0initvals24"; 4054 else if (rev == 23) 4055 filename = "n0initvals16"; 4056 else if (rev >= 16 && rev <= 18) 4057 filename = "n0initvals16"; 4058 else if (rev >= 11 && rev <= 12) 4059 filename = "n0initvals11"; 4060 else 4061 goto fail1; 4062 break; 4063 default: 4064 goto fail1; 4065 } 4066 error = bwn_fw_get(mac, type, filename, &fw->initvals); 4067 if (error) { 4068 bwn_release_firmware(mac); 4069 return (error); 4070 } 4071 4072 /* bandswitch initvals */ 4073 switch (mac->mac_phy.type) { 4074 case BWN_PHYTYPE_A: 4075 if (rev >= 5 && rev <= 10) { 4076 if (high & BWN_TGSHIGH_HAVE_2GHZ) 4077 filename = "a0g1bsinitvals5"; 4078 else 4079 filename = "a0g0bsinitvals5"; 4080 } else if (rev >= 11) 4081 filename = NULL; 4082 else 4083 goto fail1; 4084 break; 4085 case BWN_PHYTYPE_G: 4086 if (rev >= 5 && rev <= 10) 4087 filename = "b0g0bsinitvals5"; 4088 else if (rev >= 11) 4089 filename = NULL; 4090 else 4091 goto fail1; 4092 break; 4093 case BWN_PHYTYPE_LP: 4094 if (rev == 13) 4095 filename = "lp0bsinitvals13"; 4096 else if (rev == 14) 4097 filename = "lp0bsinitvals14"; 4098 else if (rev >= 15) 4099 filename = "lp0bsinitvals15"; 4100 else 4101 goto fail1; 4102 break; 4103 case BWN_PHYTYPE_N: 4104 if (rev == 30) 4105 filename = "n16bsinitvals30"; 4106 else if (rev == 28 || rev == 25) 4107 filename = "n0bsinitvals25"; 4108 else if (rev == 24) 4109 filename = "n0bsinitvals24"; 4110 else if (rev == 23) 4111 filename = "n0bsinitvals16"; 4112 else if (rev >= 16 && rev <= 18) 4113 filename = "n0bsinitvals16"; 4114 else if (rev >= 11 && rev <= 12) 4115 filename = "n0bsinitvals11"; 4116 else 4117 goto fail1; 4118 break; 4119 default: 4120 device_printf(sc->sc_dev, "unknown phy (%d)\n", 4121 mac->mac_phy.type); 4122 goto fail1; 4123 } 4124 error = bwn_fw_get(mac, type, filename, &fw->initvals_band); 4125 if (error) { 4126 bwn_release_firmware(mac); 4127 return (error); 4128 } 4129 return (0); 4130 fail1: 4131 device_printf(sc->sc_dev, "no INITVALS for rev %d, phy.type %d\n", 4132 rev, mac->mac_phy.type); 4133 bwn_release_firmware(mac); 4134 return (EOPNOTSUPP); 4135 } 4136 4137 static int 4138 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type, 4139 const char *name, struct bwn_fwfile *bfw) 4140 { 4141 const struct bwn_fwhdr *hdr; 4142 struct bwn_softc *sc = mac->mac_sc; 4143 const struct firmware *fw; 4144 char namebuf[64]; 4145 4146 if (name == NULL) { 4147 bwn_do_release_fw(bfw); 4148 return (0); 4149 } 4150 if (bfw->filename != NULL) { 4151 if (bfw->type == type && (strcmp(bfw->filename, name) == 0)) 4152 return (0); 4153 bwn_do_release_fw(bfw); 4154 } 4155 4156 ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s", 4157 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", 4158 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name); 4159 /* XXX Sleeping on "fwload" with the non-sleepable locks held */ 4160 fw = firmware_get(namebuf); 4161 if (fw == NULL) { 4162 device_printf(sc->sc_dev, "the fw file(%s) not found\n", 4163 namebuf); 4164 return (ENOENT); 4165 } 4166 if (fw->datasize < sizeof(struct bwn_fwhdr)) 4167 goto fail; 4168 hdr = (const struct bwn_fwhdr *)(fw->data); 4169 switch (hdr->type) { 4170 case BWN_FWTYPE_UCODE: 4171 case BWN_FWTYPE_PCM: 4172 if (be32toh(hdr->size) != 4173 (fw->datasize - sizeof(struct bwn_fwhdr))) 4174 goto fail; 4175 /* FALLTHROUGH */ 4176 case BWN_FWTYPE_IV: 4177 if (hdr->ver != 1) 4178 goto fail; 4179 break; 4180 default: 4181 goto fail; 4182 } 4183 bfw->filename = name; 4184 bfw->fw = fw; 4185 bfw->type = type; 4186 return (0); 4187 fail: 4188 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf); 4189 if (fw != NULL) 4190 firmware_put(fw, FIRMWARE_UNLOAD); 4191 return (EPROTO); 4192 } 4193 4194 static void 4195 bwn_release_firmware(struct bwn_mac *mac) 4196 { 4197 4198 bwn_do_release_fw(&mac->mac_fw.ucode); 4199 bwn_do_release_fw(&mac->mac_fw.pcm); 4200 bwn_do_release_fw(&mac->mac_fw.initvals); 4201 bwn_do_release_fw(&mac->mac_fw.initvals_band); 4202 } 4203 4204 static void 4205 bwn_do_release_fw(struct bwn_fwfile *bfw) 4206 { 4207 4208 if (bfw->fw != NULL) 4209 firmware_put(bfw->fw, FIRMWARE_UNLOAD); 4210 bfw->fw = NULL; 4211 bfw->filename = NULL; 4212 } 4213 4214 static int 4215 bwn_fw_loaducode(struct bwn_mac *mac) 4216 { 4217 #define GETFWOFFSET(fwp, offset) \ 4218 ((const uint32_t *)((const char *)fwp.fw->data + offset)) 4219 #define GETFWSIZE(fwp, offset) \ 4220 ((fwp.fw->datasize - offset) / sizeof(uint32_t)) 4221 struct bwn_softc *sc = mac->mac_sc; 4222 const uint32_t *data; 4223 unsigned int i; 4224 uint32_t ctl; 4225 uint16_t date, fwcaps, time; 4226 int error = 0; 4227 4228 ctl = BWN_READ_4(mac, BWN_MACCTL); 4229 ctl |= BWN_MACCTL_MCODE_JMP0; 4230 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__, 4231 __LINE__)); 4232 BWN_WRITE_4(mac, BWN_MACCTL, ctl); 4233 for (i = 0; i < 64; i++) 4234 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0); 4235 for (i = 0; i < 4096; i += 2) 4236 bwn_shm_write_2(mac, BWN_SHARED, i, 0); 4237 4238 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 4239 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000); 4240 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr)); 4241 i++) { 4242 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 4243 DELAY(10); 4244 } 4245 4246 if (mac->mac_fw.pcm.fw) { 4247 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr)); 4248 bwn_shm_ctlword(mac, BWN_HW, 0x01ea); 4249 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000); 4250 bwn_shm_ctlword(mac, BWN_HW, 0x01eb); 4251 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm, 4252 sizeof(struct bwn_fwhdr)); i++) { 4253 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i])); 4254 DELAY(10); 4255 } 4256 } 4257 4258 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL); 4259 BWN_WRITE_4(mac, BWN_MACCTL, 4260 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) | 4261 BWN_MACCTL_MCODE_RUN); 4262 4263 for (i = 0; i < 21; i++) { 4264 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED) 4265 break; 4266 if (i >= 20) { 4267 device_printf(sc->sc_dev, "ucode timeout\n"); 4268 error = ENXIO; 4269 goto error; 4270 } 4271 DELAY(50000); 4272 } 4273 BWN_READ_4(mac, BWN_INTR_REASON); 4274 4275 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV); 4276 if (mac->mac_fw.rev <= 0x128) { 4277 device_printf(sc->sc_dev, "the firmware is too old\n"); 4278 error = EOPNOTSUPP; 4279 goto error; 4280 } 4281 4282 /* 4283 * Determine firmware header version; needed for TX/RX packet 4284 * handling. 4285 */ 4286 if (mac->mac_fw.rev >= 598) 4287 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_598; 4288 else if (mac->mac_fw.rev >= 410) 4289 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_410; 4290 else 4291 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_351; 4292 4293 /* 4294 * We don't support rev 598 or later; that requires 4295 * another round of changes to the TX/RX descriptor 4296 * and status layout. 4297 * 4298 * So, complain this is the case and exit out, rather 4299 * than attaching and then failing. 4300 */ 4301 if (mac->mac_fw.fw_hdr_format == BWN_FW_HDR_598) { 4302 device_printf(sc->sc_dev, 4303 "firmware is too new (>=598); not supported\n"); 4304 error = EOPNOTSUPP; 4305 goto error; 4306 } 4307 4308 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED, 4309 BWN_SHARED_UCODE_PATCH); 4310 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE); 4311 mac->mac_fw.opensource = (date == 0xffff); 4312 if (bwn_wme != 0) 4313 mac->mac_flags |= BWN_MAC_FLAG_WME; 4314 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO; 4315 4316 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME); 4317 if (mac->mac_fw.opensource == 0) { 4318 device_printf(sc->sc_dev, 4319 "firmware version (rev %u patch %u date %#x time %#x)\n", 4320 mac->mac_fw.rev, mac->mac_fw.patch, date, time); 4321 if (mac->mac_fw.no_pcmfile) 4322 device_printf(sc->sc_dev, 4323 "no HW crypto acceleration due to pcm5\n"); 4324 } else { 4325 mac->mac_fw.patch = time; 4326 fwcaps = bwn_fwcaps_read(mac); 4327 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) { 4328 device_printf(sc->sc_dev, 4329 "disabling HW crypto acceleration\n"); 4330 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO; 4331 } 4332 if (!(fwcaps & BWN_FWCAPS_WME)) { 4333 device_printf(sc->sc_dev, "disabling WME support\n"); 4334 mac->mac_flags &= ~BWN_MAC_FLAG_WME; 4335 } 4336 } 4337 4338 if (BWN_ISOLDFMT(mac)) 4339 device_printf(sc->sc_dev, "using old firmware image\n"); 4340 4341 return (0); 4342 4343 error: 4344 BWN_WRITE_4(mac, BWN_MACCTL, 4345 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) | 4346 BWN_MACCTL_MCODE_JMP0); 4347 4348 return (error); 4349 #undef GETFWSIZE 4350 #undef GETFWOFFSET 4351 } 4352 4353 /* OpenFirmware only */ 4354 static uint16_t 4355 bwn_fwcaps_read(struct bwn_mac *mac) 4356 { 4357 4358 KASSERT(mac->mac_fw.opensource == 1, 4359 ("%s:%d: fail", __func__, __LINE__)); 4360 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS)); 4361 } 4362 4363 static int 4364 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals, 4365 size_t count, size_t array_size) 4366 { 4367 #define GET_NEXTIV16(iv) \ 4368 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 4369 sizeof(uint16_t) + sizeof(uint16_t))) 4370 #define GET_NEXTIV32(iv) \ 4371 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \ 4372 sizeof(uint16_t) + sizeof(uint32_t))) 4373 struct bwn_softc *sc = mac->mac_sc; 4374 const struct bwn_fwinitvals *iv; 4375 uint16_t offset; 4376 size_t i; 4377 uint8_t bit32; 4378 4379 KASSERT(sizeof(struct bwn_fwinitvals) == 6, 4380 ("%s:%d: fail", __func__, __LINE__)); 4381 iv = ivals; 4382 for (i = 0; i < count; i++) { 4383 if (array_size < sizeof(iv->offset_size)) 4384 goto fail; 4385 array_size -= sizeof(iv->offset_size); 4386 offset = be16toh(iv->offset_size); 4387 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0; 4388 offset &= BWN_FWINITVALS_OFFSET_MASK; 4389 if (offset >= 0x1000) 4390 goto fail; 4391 if (bit32) { 4392 if (array_size < sizeof(iv->data.d32)) 4393 goto fail; 4394 array_size -= sizeof(iv->data.d32); 4395 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32)); 4396 iv = GET_NEXTIV32(iv); 4397 } else { 4398 4399 if (array_size < sizeof(iv->data.d16)) 4400 goto fail; 4401 array_size -= sizeof(iv->data.d16); 4402 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16)); 4403 4404 iv = GET_NEXTIV16(iv); 4405 } 4406 } 4407 if (array_size != 0) 4408 goto fail; 4409 return (0); 4410 fail: 4411 device_printf(sc->sc_dev, "initvals: invalid format\n"); 4412 return (EPROTO); 4413 #undef GET_NEXTIV16 4414 #undef GET_NEXTIV32 4415 } 4416 4417 int 4418 bwn_switch_channel(struct bwn_mac *mac, int chan) 4419 { 4420 struct bwn_phy *phy = &(mac->mac_phy); 4421 struct bwn_softc *sc = mac->mac_sc; 4422 struct ieee80211com *ic = &sc->sc_ic; 4423 uint16_t channelcookie, savedcookie; 4424 int error; 4425 4426 if (chan == 0xffff) 4427 chan = phy->get_default_chan(mac); 4428 4429 channelcookie = chan; 4430 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 4431 channelcookie |= 0x100; 4432 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN); 4433 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie); 4434 error = phy->switch_channel(mac, chan); 4435 if (error) 4436 goto fail; 4437 4438 mac->mac_phy.chan = chan; 4439 DELAY(8000); 4440 return (0); 4441 fail: 4442 device_printf(sc->sc_dev, "failed to switch channel\n"); 4443 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie); 4444 return (error); 4445 } 4446 4447 static uint16_t 4448 bwn_ant2phy(int antenna) 4449 { 4450 4451 switch (antenna) { 4452 case BWN_ANT0: 4453 return (BWN_TX_PHY_ANT0); 4454 case BWN_ANT1: 4455 return (BWN_TX_PHY_ANT1); 4456 case BWN_ANT2: 4457 return (BWN_TX_PHY_ANT2); 4458 case BWN_ANT3: 4459 return (BWN_TX_PHY_ANT3); 4460 case BWN_ANTAUTO: 4461 return (BWN_TX_PHY_ANT01AUTO); 4462 } 4463 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 4464 return (0); 4465 } 4466 4467 static void 4468 bwn_wme_load(struct bwn_mac *mac) 4469 { 4470 struct bwn_softc *sc = mac->mac_sc; 4471 int i; 4472 4473 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams), 4474 ("%s:%d: fail", __func__, __LINE__)); 4475 4476 bwn_mac_suspend(mac); 4477 for (i = 0; i < N(sc->sc_wmeParams); i++) 4478 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]), 4479 bwn_wme_shm_offsets[i]); 4480 bwn_mac_enable(mac); 4481 } 4482 4483 static void 4484 bwn_wme_loadparams(struct bwn_mac *mac, 4485 const struct wmeParams *p, uint16_t shm_offset) 4486 { 4487 #define SM(_v, _f) (((_v) << _f##_S) & _f) 4488 struct bwn_softc *sc = mac->mac_sc; 4489 uint16_t params[BWN_NR_WMEPARAMS]; 4490 int slot, tmp; 4491 unsigned int i; 4492 4493 slot = BWN_READ_2(mac, BWN_RNG) & 4494 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 4495 4496 memset(¶ms, 0, sizeof(params)); 4497 4498 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d " 4499 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit, 4500 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn); 4501 4502 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32; 4503 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 4504 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX); 4505 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN); 4506 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn; 4507 params[BWN_WMEPARAM_BSLOTS] = slot; 4508 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn; 4509 4510 for (i = 0; i < N(params); i++) { 4511 if (i == BWN_WMEPARAM_STATUS) { 4512 tmp = bwn_shm_read_2(mac, BWN_SHARED, 4513 shm_offset + (i * 2)); 4514 tmp |= 0x100; 4515 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 4516 tmp); 4517 } else { 4518 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2), 4519 params[i]); 4520 } 4521 } 4522 } 4523 4524 static void 4525 bwn_mac_write_bssid(struct bwn_mac *mac) 4526 { 4527 struct bwn_softc *sc = mac->mac_sc; 4528 uint32_t tmp; 4529 int i; 4530 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; 4531 4532 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); 4533 memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN); 4534 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, 4535 IEEE80211_ADDR_LEN); 4536 4537 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) { 4538 tmp = (uint32_t) (mac_bssid[i + 0]); 4539 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8; 4540 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16; 4541 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24; 4542 bwn_ram_write(mac, 0x20 + i, tmp); 4543 } 4544 } 4545 4546 static void 4547 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset, 4548 const uint8_t *macaddr) 4549 { 4550 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 }; 4551 uint16_t data; 4552 4553 if (!mac) 4554 macaddr = zero; 4555 4556 offset |= 0x0020; 4557 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset); 4558 4559 data = macaddr[0]; 4560 data |= macaddr[1] << 8; 4561 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 4562 data = macaddr[2]; 4563 data |= macaddr[3] << 8; 4564 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 4565 data = macaddr[4]; 4566 data |= macaddr[5] << 8; 4567 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data); 4568 } 4569 4570 static void 4571 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 4572 const uint8_t *key, size_t key_len, const uint8_t *mac_addr) 4573 { 4574 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, }; 4575 uint8_t per_sta_keys_start = 8; 4576 4577 if (BWN_SEC_NEWAPI(mac)) 4578 per_sta_keys_start = 4; 4579 4580 KASSERT(index < mac->mac_max_nr_keys, 4581 ("%s:%d: fail", __func__, __LINE__)); 4582 KASSERT(key_len <= BWN_SEC_KEYSIZE, 4583 ("%s:%d: fail", __func__, __LINE__)); 4584 4585 if (index >= per_sta_keys_start) 4586 bwn_key_macwrite(mac, index, NULL); 4587 if (key) 4588 memcpy(buf, key, key_len); 4589 bwn_key_write(mac, index, algorithm, buf); 4590 if (index >= per_sta_keys_start) 4591 bwn_key_macwrite(mac, index, mac_addr); 4592 4593 mac->mac_key[index].algorithm = algorithm; 4594 } 4595 4596 static void 4597 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr) 4598 { 4599 struct bwn_softc *sc = mac->mac_sc; 4600 uint32_t addrtmp[2] = { 0, 0 }; 4601 uint8_t start = 8; 4602 4603 if (BWN_SEC_NEWAPI(mac)) 4604 start = 4; 4605 4606 KASSERT(index >= start, 4607 ("%s:%d: fail", __func__, __LINE__)); 4608 index -= start; 4609 4610 if (addr) { 4611 addrtmp[0] = addr[0]; 4612 addrtmp[0] |= ((uint32_t) (addr[1]) << 8); 4613 addrtmp[0] |= ((uint32_t) (addr[2]) << 16); 4614 addrtmp[0] |= ((uint32_t) (addr[3]) << 24); 4615 addrtmp[1] = addr[4]; 4616 addrtmp[1] |= ((uint32_t) (addr[5]) << 8); 4617 } 4618 4619 if (siba_get_revid(sc->sc_dev) >= 5) { 4620 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]); 4621 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]); 4622 } else { 4623 if (index >= 8) { 4624 bwn_shm_write_4(mac, BWN_SHARED, 4625 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]); 4626 bwn_shm_write_2(mac, BWN_SHARED, 4627 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]); 4628 } 4629 } 4630 } 4631 4632 static void 4633 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm, 4634 const uint8_t *key) 4635 { 4636 unsigned int i; 4637 uint32_t offset; 4638 uint16_t kidx, value; 4639 4640 kidx = BWN_SEC_KEY2FW(mac, index); 4641 bwn_shm_write_2(mac, BWN_SHARED, 4642 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm); 4643 4644 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE); 4645 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) { 4646 value = key[i]; 4647 value |= (uint16_t)(key[i + 1]) << 8; 4648 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value); 4649 } 4650 } 4651 4652 static void 4653 bwn_phy_exit(struct bwn_mac *mac) 4654 { 4655 4656 mac->mac_phy.rf_onoff(mac, 0); 4657 if (mac->mac_phy.exit != NULL) 4658 mac->mac_phy.exit(mac); 4659 } 4660 4661 static void 4662 bwn_dma_free(struct bwn_mac *mac) 4663 { 4664 struct bwn_dma *dma; 4665 4666 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 4667 return; 4668 dma = &mac->mac_method.dma; 4669 4670 bwn_dma_ringfree(&dma->rx); 4671 bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 4672 bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 4673 bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 4674 bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 4675 bwn_dma_ringfree(&dma->mcast); 4676 } 4677 4678 static void 4679 bwn_core_stop(struct bwn_mac *mac) 4680 { 4681 struct bwn_softc *sc = mac->mac_sc; 4682 4683 BWN_ASSERT_LOCKED(sc); 4684 4685 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 4686 return; 4687 4688 callout_stop(&sc->sc_rfswitch_ch); 4689 callout_stop(&sc->sc_task_ch); 4690 callout_stop(&sc->sc_watchdog_ch); 4691 sc->sc_watchdog_timer = 0; 4692 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 4693 BWN_READ_4(mac, BWN_INTR_MASK); 4694 bwn_mac_suspend(mac); 4695 4696 mac->mac_status = BWN_MAC_STATUS_INITED; 4697 } 4698 4699 static int 4700 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan) 4701 { 4702 struct bwn_mac *up_dev = NULL; 4703 struct bwn_mac *down_dev; 4704 struct bwn_mac *mac; 4705 int err, status; 4706 uint8_t gmode; 4707 4708 BWN_ASSERT_LOCKED(sc); 4709 4710 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) { 4711 if (IEEE80211_IS_CHAN_2GHZ(chan) && 4712 mac->mac_phy.supports_2ghz) { 4713 up_dev = mac; 4714 gmode = 1; 4715 } else if (IEEE80211_IS_CHAN_5GHZ(chan) && 4716 mac->mac_phy.supports_5ghz) { 4717 up_dev = mac; 4718 gmode = 0; 4719 } else { 4720 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 4721 return (EINVAL); 4722 } 4723 if (up_dev != NULL) 4724 break; 4725 } 4726 if (up_dev == NULL) { 4727 device_printf(sc->sc_dev, "Could not find a device\n"); 4728 return (ENODEV); 4729 } 4730 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode) 4731 return (0); 4732 4733 DPRINTF(sc, BWN_DEBUG_RF | BWN_DEBUG_PHY | BWN_DEBUG_RESET, 4734 "switching to %s-GHz band\n", 4735 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 4736 4737 down_dev = sc->sc_curmac; 4738 status = down_dev->mac_status; 4739 if (status >= BWN_MAC_STATUS_STARTED) 4740 bwn_core_stop(down_dev); 4741 if (status >= BWN_MAC_STATUS_INITED) 4742 bwn_core_exit(down_dev); 4743 4744 if (down_dev != up_dev) 4745 bwn_phy_reset(down_dev); 4746 4747 up_dev->mac_phy.gmode = gmode; 4748 if (status >= BWN_MAC_STATUS_INITED) { 4749 err = bwn_core_init(up_dev); 4750 if (err) { 4751 device_printf(sc->sc_dev, 4752 "fatal: failed to initialize for %s-GHz\n", 4753 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5"); 4754 goto fail; 4755 } 4756 } 4757 if (status >= BWN_MAC_STATUS_STARTED) 4758 bwn_core_start(up_dev); 4759 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__)); 4760 sc->sc_curmac = up_dev; 4761 4762 return (0); 4763 fail: 4764 sc->sc_curmac = NULL; 4765 return (err); 4766 } 4767 4768 static void 4769 bwn_rf_turnon(struct bwn_mac *mac) 4770 { 4771 4772 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__); 4773 4774 bwn_mac_suspend(mac); 4775 mac->mac_phy.rf_onoff(mac, 1); 4776 mac->mac_phy.rf_on = 1; 4777 bwn_mac_enable(mac); 4778 } 4779 4780 static void 4781 bwn_rf_turnoff(struct bwn_mac *mac) 4782 { 4783 4784 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__); 4785 4786 bwn_mac_suspend(mac); 4787 mac->mac_phy.rf_onoff(mac, 0); 4788 mac->mac_phy.rf_on = 0; 4789 bwn_mac_enable(mac); 4790 } 4791 4792 /* 4793 * SSB PHY reset. 4794 * 4795 * XXX TODO: BCMA PHY reset. 4796 */ 4797 static void 4798 bwn_phy_reset(struct bwn_mac *mac) 4799 { 4800 struct bwn_softc *sc = mac->mac_sc; 4801 4802 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 4803 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) | 4804 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC); 4805 DELAY(1000); 4806 siba_write_4(sc->sc_dev, SIBA_TGSLOW, 4807 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC)); 4808 DELAY(1000); 4809 } 4810 4811 static int 4812 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 4813 { 4814 struct bwn_vap *bvp = BWN_VAP(vap); 4815 struct ieee80211com *ic= vap->iv_ic; 4816 enum ieee80211_state ostate = vap->iv_state; 4817 struct bwn_softc *sc = ic->ic_softc; 4818 struct bwn_mac *mac = sc->sc_curmac; 4819 int error; 4820 4821 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 4822 ieee80211_state_name[vap->iv_state], 4823 ieee80211_state_name[nstate]); 4824 4825 error = bvp->bv_newstate(vap, nstate, arg); 4826 if (error != 0) 4827 return (error); 4828 4829 BWN_LOCK(sc); 4830 4831 bwn_led_newstate(mac, nstate); 4832 4833 /* 4834 * Clear the BSSID when we stop a STA 4835 */ 4836 if (vap->iv_opmode == IEEE80211_M_STA) { 4837 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) { 4838 /* 4839 * Clear out the BSSID. If we reassociate to 4840 * the same AP, this will reinialize things 4841 * correctly... 4842 */ 4843 if (ic->ic_opmode == IEEE80211_M_STA && 4844 (sc->sc_flags & BWN_FLAG_INVALID) == 0) { 4845 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 4846 bwn_set_macaddr(mac); 4847 } 4848 } 4849 } 4850 4851 if (vap->iv_opmode == IEEE80211_M_MONITOR || 4852 vap->iv_opmode == IEEE80211_M_AHDEMO) { 4853 /* XXX nothing to do? */ 4854 } else if (nstate == IEEE80211_S_RUN) { 4855 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); 4856 bwn_set_opmode(mac); 4857 bwn_set_pretbtt(mac); 4858 bwn_spu_setdelay(mac, 0); 4859 bwn_set_macaddr(mac); 4860 } 4861 4862 BWN_UNLOCK(sc); 4863 4864 return (error); 4865 } 4866 4867 static void 4868 bwn_set_pretbtt(struct bwn_mac *mac) 4869 { 4870 struct bwn_softc *sc = mac->mac_sc; 4871 struct ieee80211com *ic = &sc->sc_ic; 4872 uint16_t pretbtt; 4873 4874 if (ic->ic_opmode == IEEE80211_M_IBSS) 4875 pretbtt = 2; 4876 else 4877 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250; 4878 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt); 4879 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt); 4880 } 4881 4882 #if defined(__DragonFly__) 4883 static void 4884 bwn_intr(void *arg) 4885 #else 4886 static int 4887 bwn_intr(void *arg) 4888 #endif 4889 { 4890 struct bwn_mac *mac = arg; 4891 struct bwn_softc *sc = mac->mac_sc; 4892 uint32_t reason; 4893 4894 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 4895 (sc->sc_flags & BWN_FLAG_INVALID)) { 4896 #if defined(__DragonFly__) 4897 return; 4898 #else 4899 return (FILTER_STRAY); 4900 #endif 4901 } 4902 4903 reason = BWN_READ_4(mac, BWN_INTR_REASON); 4904 if (reason == 0xffffffff) { /* shared IRQ */ 4905 #if defined(__DragonFly__) 4906 return; 4907 #else 4908 return (FILTER_STRAY); 4909 #endif 4910 } 4911 reason &= mac->mac_intr_mask; 4912 if (reason == 0) { 4913 #if defined(__DragonFly__) 4914 return; 4915 #else 4916 return (FILTER_HANDLED); 4917 #endif 4918 } 4919 4920 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00; 4921 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00; 4922 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00; 4923 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00; 4924 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00; 4925 BWN_WRITE_4(mac, BWN_INTR_REASON, reason); 4926 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]); 4927 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]); 4928 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]); 4929 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]); 4930 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]); 4931 4932 /* Disable interrupts. */ 4933 BWN_WRITE_4(mac, BWN_INTR_MASK, 0); 4934 4935 mac->mac_reason_intr = reason; 4936 4937 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 4938 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 4939 4940 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask); 4941 #if !defined(__DragonFly__) 4942 return (FILTER_HANDLED); 4943 #endif 4944 } 4945 4946 static void 4947 bwn_intrtask(void *arg, int npending) 4948 { 4949 struct bwn_mac *mac = arg; 4950 struct bwn_softc *sc = mac->mac_sc; 4951 uint32_t merged = 0; 4952 int i, tx = 0, rx = 0; 4953 4954 BWN_LOCK(sc); 4955 if (mac->mac_status < BWN_MAC_STATUS_STARTED || 4956 (sc->sc_flags & BWN_FLAG_INVALID)) { 4957 BWN_UNLOCK(sc); 4958 return; 4959 } 4960 4961 for (i = 0; i < N(mac->mac_reason); i++) 4962 merged |= mac->mac_reason[i]; 4963 4964 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR) 4965 device_printf(sc->sc_dev, "MAC trans error\n"); 4966 4967 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) { 4968 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__); 4969 mac->mac_phy.txerrors--; 4970 if (mac->mac_phy.txerrors == 0) { 4971 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 4972 bwn_restart(mac, "PHY TX errors"); 4973 } 4974 } 4975 4976 if (merged & BWN_DMAINTR_FATALMASK) { 4977 device_printf(sc->sc_dev, 4978 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n", 4979 mac->mac_reason[0], mac->mac_reason[1], 4980 mac->mac_reason[2], mac->mac_reason[3], 4981 mac->mac_reason[4], mac->mac_reason[5]); 4982 bwn_restart(mac, "DMA error"); 4983 BWN_UNLOCK(sc); 4984 return; 4985 } 4986 4987 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG) 4988 bwn_intr_ucode_debug(mac); 4989 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI) 4990 bwn_intr_tbtt_indication(mac); 4991 if (mac->mac_reason_intr & BWN_INTR_ATIM_END) 4992 bwn_intr_atim_end(mac); 4993 if (mac->mac_reason_intr & BWN_INTR_BEACON) 4994 bwn_intr_beacon(mac); 4995 if (mac->mac_reason_intr & BWN_INTR_PMQ) 4996 bwn_intr_pmq(mac); 4997 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK) 4998 bwn_intr_noise(mac); 4999 5000 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 5001 if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) { 5002 device_printf(sc->sc_dev, "RX descriptor overflow\n"); 5003 bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx); 5004 } 5005 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) { 5006 bwn_dma_rx(mac->mac_method.dma.rx); 5007 rx = 1; 5008 } 5009 } else 5010 rx = bwn_pio_rx(&mac->mac_method.pio.rx); 5011 5012 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5013 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5014 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5015 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5016 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__)); 5017 5018 if (mac->mac_reason_intr & BWN_INTR_TX_OK) { 5019 bwn_intr_txeof(mac); 5020 tx = 1; 5021 } 5022 5023 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask); 5024 5025 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 5026 int evt = BWN_LED_EVENT_NONE; 5027 5028 if (tx && rx) { 5029 if (sc->sc_rx_rate > sc->sc_tx_rate) 5030 evt = BWN_LED_EVENT_RX; 5031 else 5032 evt = BWN_LED_EVENT_TX; 5033 } else if (tx) { 5034 evt = BWN_LED_EVENT_TX; 5035 } else if (rx) { 5036 evt = BWN_LED_EVENT_RX; 5037 } else if (rx == 0) { 5038 evt = BWN_LED_EVENT_POLL; 5039 } 5040 5041 if (evt != BWN_LED_EVENT_NONE) 5042 bwn_led_event(mac, evt); 5043 } 5044 5045 if (mbufq_first(&sc->sc_snd) != NULL) 5046 bwn_start(sc); 5047 5048 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); 5049 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); 5050 5051 BWN_UNLOCK(sc); 5052 } 5053 5054 static void 5055 bwn_restart(struct bwn_mac *mac, const char *msg) 5056 { 5057 struct bwn_softc *sc = mac->mac_sc; 5058 struct ieee80211com *ic = &sc->sc_ic; 5059 5060 if (mac->mac_status < BWN_MAC_STATUS_INITED) 5061 return; 5062 5063 device_printf(sc->sc_dev, "HW reset: %s\n", msg); 5064 ieee80211_runtask(ic, &mac->mac_hwreset); 5065 } 5066 5067 static void 5068 bwn_intr_ucode_debug(struct bwn_mac *mac) 5069 { 5070 struct bwn_softc *sc = mac->mac_sc; 5071 uint16_t reason; 5072 5073 if (mac->mac_fw.opensource == 0) 5074 return; 5075 5076 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG); 5077 switch (reason) { 5078 case BWN_DEBUGINTR_PANIC: 5079 bwn_handle_fwpanic(mac); 5080 break; 5081 case BWN_DEBUGINTR_DUMP_SHM: 5082 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n"); 5083 break; 5084 case BWN_DEBUGINTR_DUMP_REGS: 5085 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n"); 5086 break; 5087 case BWN_DEBUGINTR_MARKER: 5088 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n"); 5089 break; 5090 default: 5091 device_printf(sc->sc_dev, 5092 "ucode debug unknown reason: %#x\n", reason); 5093 } 5094 5095 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG, 5096 BWN_DEBUGINTR_ACK); 5097 } 5098 5099 static void 5100 bwn_intr_tbtt_indication(struct bwn_mac *mac) 5101 { 5102 struct bwn_softc *sc = mac->mac_sc; 5103 struct ieee80211com *ic = &sc->sc_ic; 5104 5105 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 5106 bwn_psctl(mac, 0); 5107 if (ic->ic_opmode == IEEE80211_M_IBSS) 5108 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID; 5109 } 5110 5111 static void 5112 bwn_intr_atim_end(struct bwn_mac *mac) 5113 { 5114 5115 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) { 5116 BWN_WRITE_4(mac, BWN_MACCMD, 5117 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID); 5118 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID; 5119 } 5120 } 5121 5122 static void 5123 bwn_intr_beacon(struct bwn_mac *mac) 5124 { 5125 struct bwn_softc *sc = mac->mac_sc; 5126 struct ieee80211com *ic = &sc->sc_ic; 5127 uint32_t cmd, beacon0, beacon1; 5128 5129 if (ic->ic_opmode == IEEE80211_M_HOSTAP || 5130 ic->ic_opmode == IEEE80211_M_MBSS) 5131 return; 5132 5133 mac->mac_intr_mask &= ~BWN_INTR_BEACON; 5134 5135 cmd = BWN_READ_4(mac, BWN_MACCMD); 5136 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID); 5137 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID); 5138 5139 if (beacon0 && beacon1) { 5140 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON); 5141 mac->mac_intr_mask |= BWN_INTR_BEACON; 5142 return; 5143 } 5144 5145 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) { 5146 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP; 5147 bwn_load_beacon0(mac); 5148 bwn_load_beacon1(mac); 5149 cmd = BWN_READ_4(mac, BWN_MACCMD); 5150 cmd |= BWN_MACCMD_BEACON0_VALID; 5151 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 5152 } else { 5153 if (!beacon0) { 5154 bwn_load_beacon0(mac); 5155 cmd = BWN_READ_4(mac, BWN_MACCMD); 5156 cmd |= BWN_MACCMD_BEACON0_VALID; 5157 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 5158 } else if (!beacon1) { 5159 bwn_load_beacon1(mac); 5160 cmd = BWN_READ_4(mac, BWN_MACCMD); 5161 cmd |= BWN_MACCMD_BEACON1_VALID; 5162 BWN_WRITE_4(mac, BWN_MACCMD, cmd); 5163 } 5164 } 5165 } 5166 5167 static void 5168 bwn_intr_pmq(struct bwn_mac *mac) 5169 { 5170 uint32_t tmp; 5171 5172 while (1) { 5173 tmp = BWN_READ_4(mac, BWN_PS_STATUS); 5174 if (!(tmp & 0x00000008)) 5175 break; 5176 } 5177 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002); 5178 } 5179 5180 static void 5181 bwn_intr_noise(struct bwn_mac *mac) 5182 { 5183 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 5184 uint16_t tmp; 5185 uint8_t noise[4]; 5186 uint8_t i, j; 5187 int32_t average; 5188 5189 if (mac->mac_phy.type != BWN_PHYTYPE_G) 5190 return; 5191 5192 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__)); 5193 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac)); 5194 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f || 5195 noise[3] == 0x7f) 5196 goto new; 5197 5198 KASSERT(mac->mac_noise.noi_nsamples < 8, 5199 ("%s:%d: fail", __func__, __LINE__)); 5200 i = mac->mac_noise.noi_nsamples; 5201 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1); 5202 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1); 5203 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1); 5204 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1); 5205 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]]; 5206 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]]; 5207 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]]; 5208 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]]; 5209 mac->mac_noise.noi_nsamples++; 5210 if (mac->mac_noise.noi_nsamples == 8) { 5211 average = 0; 5212 for (i = 0; i < 8; i++) { 5213 for (j = 0; j < 4; j++) 5214 average += mac->mac_noise.noi_samples[i][j]; 5215 } 5216 average = (((average / 32) * 125) + 64) / 128; 5217 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f; 5218 if (tmp >= 8) 5219 average += 2; 5220 else 5221 average -= 25; 5222 average -= (tmp == 8) ? 72 : 48; 5223 5224 mac->mac_stats.link_noise = average; 5225 mac->mac_noise.noi_running = 0; 5226 return; 5227 } 5228 new: 5229 bwn_noise_gensample(mac); 5230 } 5231 5232 static int 5233 bwn_pio_rx(struct bwn_pio_rxqueue *prq) 5234 { 5235 struct bwn_mac *mac = prq->prq_mac; 5236 struct bwn_softc *sc = mac->mac_sc; 5237 unsigned int i; 5238 5239 BWN_ASSERT_LOCKED(sc); 5240 5241 if (mac->mac_status < BWN_MAC_STATUS_STARTED) 5242 return (0); 5243 5244 for (i = 0; i < 5000; i++) { 5245 if (bwn_pio_rxeof(prq) == 0) 5246 break; 5247 } 5248 if (i >= 5000) 5249 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n"); 5250 return ((i > 0) ? 1 : 0); 5251 } 5252 5253 static void 5254 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr) 5255 { 5256 int curslot, prevslot; 5257 5258 curslot = dr->get_curslot(dr); 5259 if (curslot == 0) 5260 prevslot = dr->dr_numslots - 1; 5261 else 5262 prevslot = curslot - 1; 5263 dr->set_curslot(dr, prevslot); 5264 } 5265 5266 static void 5267 bwn_dma_rx(struct bwn_dma_ring *dr) 5268 { 5269 int slot, curslot; 5270 5271 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 5272 curslot = dr->get_curslot(dr); 5273 KASSERT(curslot >= 0 && curslot < dr->dr_numslots, 5274 ("%s:%d: fail", __func__, __LINE__)); 5275 5276 slot = dr->dr_curslot; 5277 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot)) 5278 bwn_dma_rxeof(dr, &slot); 5279 5280 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap, 5281 BUS_DMASYNC_PREWRITE); 5282 5283 dr->set_curslot(dr, slot); 5284 dr->dr_curslot = slot; 5285 } 5286 5287 static void 5288 bwn_intr_txeof(struct bwn_mac *mac) 5289 { 5290 struct bwn_txstatus stat; 5291 uint32_t stat0, stat1; 5292 uint16_t tmp; 5293 5294 BWN_ASSERT_LOCKED(mac->mac_sc); 5295 5296 while (1) { 5297 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0); 5298 if (!(stat0 & 0x00000001)) 5299 break; 5300 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1); 5301 5302 DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT, 5303 "%s: stat0=0x%08x, stat1=0x%08x\n", 5304 __func__, 5305 stat0, 5306 stat1); 5307 5308 stat.cookie = (stat0 >> 16); 5309 stat.seq = (stat1 & 0x0000ffff); 5310 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16); 5311 tmp = (stat0 & 0x0000ffff); 5312 stat.framecnt = ((tmp & 0xf000) >> 12); 5313 stat.rtscnt = ((tmp & 0x0f00) >> 8); 5314 stat.sreason = ((tmp & 0x001c) >> 2); 5315 stat.pm = (tmp & 0x0080) ? 1 : 0; 5316 stat.im = (tmp & 0x0040) ? 1 : 0; 5317 stat.ampdu = (tmp & 0x0020) ? 1 : 0; 5318 stat.ack = (tmp & 0x0002) ? 1 : 0; 5319 5320 DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT, 5321 "%s: cookie=%d, seq=%d, phystat=0x%02x, framecnt=%d, " 5322 "rtscnt=%d, sreason=%d, pm=%d, im=%d, ampdu=%d, ack=%d\n", 5323 __func__, 5324 stat.cookie, 5325 stat.seq, 5326 stat.phy_stat, 5327 stat.framecnt, 5328 stat.rtscnt, 5329 stat.sreason, 5330 stat.pm, 5331 stat.im, 5332 stat.ampdu, 5333 stat.ack); 5334 5335 bwn_handle_txeof(mac, &stat); 5336 } 5337 } 5338 5339 static void 5340 bwn_hwreset(void *arg, int npending) 5341 { 5342 struct bwn_mac *mac = arg; 5343 struct bwn_softc *sc = mac->mac_sc; 5344 int error = 0; 5345 int prev_status; 5346 5347 BWN_LOCK(sc); 5348 5349 prev_status = mac->mac_status; 5350 if (prev_status >= BWN_MAC_STATUS_STARTED) 5351 bwn_core_stop(mac); 5352 if (prev_status >= BWN_MAC_STATUS_INITED) 5353 bwn_core_exit(mac); 5354 5355 if (prev_status >= BWN_MAC_STATUS_INITED) { 5356 error = bwn_core_init(mac); 5357 if (error) 5358 goto out; 5359 } 5360 if (prev_status >= BWN_MAC_STATUS_STARTED) 5361 bwn_core_start(mac); 5362 out: 5363 if (error) { 5364 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error); 5365 sc->sc_curmac = NULL; 5366 } 5367 BWN_UNLOCK(sc); 5368 } 5369 5370 static void 5371 bwn_handle_fwpanic(struct bwn_mac *mac) 5372 { 5373 struct bwn_softc *sc = mac->mac_sc; 5374 uint16_t reason; 5375 5376 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG); 5377 device_printf(sc->sc_dev,"fw panic (%u)\n", reason); 5378 5379 if (reason == BWN_FWPANIC_RESTART) 5380 bwn_restart(mac, "ucode panic"); 5381 } 5382 5383 static void 5384 bwn_load_beacon0(struct bwn_mac *mac) 5385 { 5386 5387 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5388 } 5389 5390 static void 5391 bwn_load_beacon1(struct bwn_mac *mac) 5392 { 5393 5394 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 5395 } 5396 5397 static uint32_t 5398 bwn_jssi_read(struct bwn_mac *mac) 5399 { 5400 uint32_t val = 0; 5401 5402 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a); 5403 val <<= 16; 5404 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088); 5405 5406 return (val); 5407 } 5408 5409 static void 5410 bwn_noise_gensample(struct bwn_mac *mac) 5411 { 5412 uint32_t jssi = 0x7f7f7f7f; 5413 5414 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff)); 5415 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16); 5416 BWN_WRITE_4(mac, BWN_MACCMD, 5417 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE); 5418 } 5419 5420 static int 5421 bwn_dma_freeslot(struct bwn_dma_ring *dr) 5422 { 5423 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 5424 5425 return (dr->dr_numslots - dr->dr_usedslot); 5426 } 5427 5428 static int 5429 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot) 5430 { 5431 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 5432 5433 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1, 5434 ("%s:%d: fail", __func__, __LINE__)); 5435 if (slot == dr->dr_numslots - 1) 5436 return (0); 5437 return (slot + 1); 5438 } 5439 5440 static void 5441 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) 5442 { 5443 struct bwn_mac *mac = dr->dr_mac; 5444 struct bwn_softc *sc = mac->mac_sc; 5445 struct bwn_dma *dma = &mac->mac_method.dma; 5446 struct bwn_dmadesc_generic *desc; 5447 struct bwn_dmadesc_meta *meta; 5448 struct bwn_rxhdr4 *rxhdr; 5449 struct mbuf *m; 5450 uint32_t macstat; 5451 int32_t tmp; 5452 int cnt = 0; 5453 uint16_t len; 5454 5455 dr->getdesc(dr, *slot, &desc, &meta); 5456 5457 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD); 5458 m = meta->mt_m; 5459 5460 if (bwn_dma_newbuf(dr, desc, meta, 0)) { 5461 #if defined(__DragonFly__) 5462 ++sc->sc_ic.ic_ierrors; 5463 #else 5464 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 5465 #endif 5466 return; 5467 } 5468 5469 rxhdr = mtod(m, struct bwn_rxhdr4 *); 5470 len = le16toh(rxhdr->frame_len); 5471 if (len <= 0) { 5472 #if defined(__DragonFly__) 5473 ++sc->sc_ic.ic_ierrors; 5474 #else 5475 counter_u64_add(sc->sc_ic.ic_ierrors, 1); 5476 #endif 5477 return; 5478 } 5479 if (bwn_dma_check_redzone(dr, m)) { 5480 device_printf(sc->sc_dev, "redzone error.\n"); 5481 bwn_dma_set_redzone(dr, m); 5482 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 5483 BUS_DMASYNC_PREWRITE); 5484 return; 5485 } 5486 if (len > dr->dr_rx_bufsize) { 5487 tmp = len; 5488 while (1) { 5489 dr->getdesc(dr, *slot, &desc, &meta); 5490 bwn_dma_set_redzone(dr, meta->mt_m); 5491 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 5492 BUS_DMASYNC_PREWRITE); 5493 *slot = bwn_dma_nextslot(dr, *slot); 5494 cnt++; 5495 tmp -= dr->dr_rx_bufsize; 5496 if (tmp <= 0) 5497 break; 5498 } 5499 device_printf(sc->sc_dev, "too small buffer " 5500 "(len %u buffer %u dropped %d)\n", 5501 len, dr->dr_rx_bufsize, cnt); 5502 return; 5503 } 5504 macstat = le32toh(rxhdr->mac_status); 5505 if (macstat & BWN_RX_MAC_FCSERR) { 5506 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 5507 device_printf(sc->sc_dev, "RX drop\n"); 5508 return; 5509 } 5510 } 5511 5512 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; 5513 m_adj(m, dr->dr_frameoffset); 5514 5515 bwn_rxeof(dr->dr_mac, m, rxhdr); 5516 } 5517 5518 static void 5519 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status) 5520 { 5521 struct bwn_softc *sc = mac->mac_sc; 5522 struct bwn_stats *stats = &mac->mac_stats; 5523 5524 BWN_ASSERT_LOCKED(mac->mac_sc); 5525 5526 if (status->im) 5527 device_printf(sc->sc_dev, "TODO: STATUS IM\n"); 5528 if (status->ampdu) 5529 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n"); 5530 if (status->rtscnt) { 5531 if (status->rtscnt == 0xf) 5532 stats->rtsfail++; 5533 else 5534 stats->rts++; 5535 } 5536 5537 if (mac->mac_flags & BWN_MAC_FLAG_DMA) { 5538 bwn_dma_handle_txeof(mac, status); 5539 } else { 5540 bwn_pio_handle_txeof(mac, status); 5541 } 5542 5543 bwn_phy_txpower_check(mac, 0); 5544 } 5545 5546 static uint8_t 5547 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) 5548 { 5549 struct bwn_mac *mac = prq->prq_mac; 5550 struct bwn_softc *sc = mac->mac_sc; 5551 struct bwn_rxhdr4 rxhdr; 5552 struct mbuf *m; 5553 uint32_t ctl32, macstat, v32; 5554 unsigned int i, padding; 5555 uint16_t ctl16, len, totlen, v16; 5556 unsigned char *mp; 5557 char *data; 5558 5559 memset(&rxhdr, 0, sizeof(rxhdr)); 5560 5561 if (prq->prq_rev >= 8) { 5562 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 5563 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY)) 5564 return (0); 5565 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 5566 BWN_PIO8_RXCTL_FRAMEREADY); 5567 for (i = 0; i < 10; i++) { 5568 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL); 5569 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY) 5570 goto ready; 5571 DELAY(10); 5572 } 5573 } else { 5574 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 5575 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY)) 5576 return (0); 5577 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, 5578 BWN_PIO_RXCTL_FRAMEREADY); 5579 for (i = 0; i < 10; i++) { 5580 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL); 5581 if (ctl16 & BWN_PIO_RXCTL_DATAREADY) 5582 goto ready; 5583 DELAY(10); 5584 } 5585 } 5586 device_printf(sc->sc_dev, "%s: timed out\n", __func__); 5587 return (1); 5588 ready: 5589 if (prq->prq_rev >= 8) 5590 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr), 5591 prq->prq_base + BWN_PIO8_RXDATA); 5592 else 5593 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr), 5594 prq->prq_base + BWN_PIO_RXDATA); 5595 len = le16toh(rxhdr.frame_len); 5596 if (len > 0x700) { 5597 device_printf(sc->sc_dev, "%s: len is too big\n", __func__); 5598 goto error; 5599 } 5600 if (len == 0) { 5601 device_printf(sc->sc_dev, "%s: len is 0\n", __func__); 5602 goto error; 5603 } 5604 5605 macstat = le32toh(rxhdr.mac_status); 5606 if (macstat & BWN_RX_MAC_FCSERR) { 5607 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) { 5608 device_printf(sc->sc_dev, "%s: FCS error", __func__); 5609 goto error; 5610 } 5611 } 5612 5613 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 5614 totlen = len + padding; 5615 KASSERT(totlen <= MCLBYTES, ("too big..\n")); 5616 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 5617 if (m == NULL) { 5618 device_printf(sc->sc_dev, "%s: out of memory", __func__); 5619 goto error; 5620 } 5621 mp = mtod(m, unsigned char *); 5622 if (prq->prq_rev >= 8) { 5623 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3), 5624 prq->prq_base + BWN_PIO8_RXDATA); 5625 if (totlen & 3) { 5626 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA); 5627 data = &(mp[totlen - 1]); 5628 switch (totlen & 3) { 5629 case 3: 5630 *data = (v32 >> 16); 5631 data--; 5632 case 2: 5633 *data = (v32 >> 8); 5634 data--; 5635 case 1: 5636 *data = v32; 5637 } 5638 } 5639 } else { 5640 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1), 5641 prq->prq_base + BWN_PIO_RXDATA); 5642 if (totlen & 1) { 5643 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA); 5644 mp[totlen - 1] = v16; 5645 } 5646 } 5647 5648 m->m_len = m->m_pkthdr.len = totlen; 5649 5650 bwn_rxeof(prq->prq_mac, m, &rxhdr); 5651 5652 return (1); 5653 error: 5654 if (prq->prq_rev >= 8) 5655 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL, 5656 BWN_PIO8_RXCTL_DATAREADY); 5657 else 5658 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY); 5659 return (1); 5660 } 5661 5662 static int 5663 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc, 5664 struct bwn_dmadesc_meta *meta, int init) 5665 { 5666 struct bwn_mac *mac = dr->dr_mac; 5667 struct bwn_dma *dma = &mac->mac_method.dma; 5668 struct bwn_rxhdr4 *hdr; 5669 bus_dmamap_t map; 5670 bus_addr_t paddr; 5671 struct mbuf *m; 5672 int error; 5673 5674 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 5675 if (m == NULL) { 5676 error = ENOBUFS; 5677 5678 /* 5679 * If the NIC is up and running, we need to: 5680 * - Clear RX buffer's header. 5681 * - Restore RX descriptor settings. 5682 */ 5683 if (init) 5684 return (error); 5685 else 5686 goto back; 5687 } 5688 m->m_len = m->m_pkthdr.len = MCLBYTES; 5689 5690 bwn_dma_set_redzone(dr, m); 5691 5692 /* 5693 * Try to load RX buf into temporary DMA map 5694 */ 5695 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m, 5696 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); 5697 if (error) { 5698 m_freem(m); 5699 5700 /* 5701 * See the comment above 5702 */ 5703 if (init) 5704 return (error); 5705 else 5706 goto back; 5707 } 5708 5709 if (!init) 5710 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap); 5711 meta->mt_m = m; 5712 meta->mt_paddr = paddr; 5713 5714 /* 5715 * Swap RX buf's DMA map with the loaded temporary one 5716 */ 5717 map = meta->mt_dmap; 5718 meta->mt_dmap = dr->dr_spare_dmap; 5719 dr->dr_spare_dmap = map; 5720 5721 back: 5722 /* 5723 * Clear RX buf header 5724 */ 5725 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *); 5726 bzero(hdr, sizeof(*hdr)); 5727 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, 5728 BUS_DMASYNC_PREWRITE); 5729 5730 /* 5731 * Setup RX buf descriptor 5732 */ 5733 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len - 5734 sizeof(*hdr), 0, 0, 0); 5735 return (error); 5736 } 5737 5738 static void 5739 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg, 5740 bus_size_t mapsz __unused, int error) 5741 { 5742 5743 if (!error) { 5744 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg)); 5745 *((bus_addr_t *)arg) = seg->ds_addr; 5746 } 5747 } 5748 5749 static int 5750 bwn_hwrate2ieeerate(int rate) 5751 { 5752 5753 switch (rate) { 5754 case BWN_CCK_RATE_1MB: 5755 return (2); 5756 case BWN_CCK_RATE_2MB: 5757 return (4); 5758 case BWN_CCK_RATE_5MB: 5759 return (11); 5760 case BWN_CCK_RATE_11MB: 5761 return (22); 5762 case BWN_OFDM_RATE_6MB: 5763 return (12); 5764 case BWN_OFDM_RATE_9MB: 5765 return (18); 5766 case BWN_OFDM_RATE_12MB: 5767 return (24); 5768 case BWN_OFDM_RATE_18MB: 5769 return (36); 5770 case BWN_OFDM_RATE_24MB: 5771 return (48); 5772 case BWN_OFDM_RATE_36MB: 5773 return (72); 5774 case BWN_OFDM_RATE_48MB: 5775 return (96); 5776 case BWN_OFDM_RATE_54MB: 5777 return (108); 5778 default: 5779 kprintf("Ooops\n"); 5780 return (0); 5781 } 5782 } 5783 5784 /* 5785 * Post process the RX provided RSSI. 5786 * 5787 * Valid for A, B, G, LP PHYs. 5788 */ 5789 static int8_t 5790 bwn_rx_rssi_calc(struct bwn_mac *mac, uint8_t in_rssi, 5791 int ofdm, int adjust_2053, int adjust_2050) 5792 { 5793 struct bwn_phy *phy = &mac->mac_phy; 5794 struct bwn_phy_g *gphy = &phy->phy_g; 5795 int tmp; 5796 5797 switch (phy->rf_ver) { 5798 case 0x2050: 5799 if (ofdm) { 5800 tmp = in_rssi; 5801 if (tmp > 127) 5802 tmp -= 256; 5803 tmp = tmp * 73 / 64; 5804 if (adjust_2050) 5805 tmp += 25; 5806 else 5807 tmp -= 3; 5808 } else { 5809 if (siba_sprom_get_bf_lo(mac->mac_sc->sc_dev) 5810 & BWN_BFL_RSSI) { 5811 if (in_rssi > 63) 5812 in_rssi = 63; 5813 tmp = gphy->pg_nrssi_lt[in_rssi]; 5814 tmp = (31 - tmp) * -131 / 128 - 57; 5815 } else { 5816 tmp = in_rssi; 5817 tmp = (31 - tmp) * -149 / 128 - 68; 5818 } 5819 if (phy->type == BWN_PHYTYPE_G && adjust_2050) 5820 tmp += 25; 5821 } 5822 break; 5823 case 0x2060: 5824 if (in_rssi > 127) 5825 tmp = in_rssi - 256; 5826 else 5827 tmp = in_rssi; 5828 break; 5829 default: 5830 tmp = in_rssi; 5831 tmp = (tmp - 11) * 103 / 64; 5832 if (adjust_2053) 5833 tmp -= 109; 5834 else 5835 tmp -= 83; 5836 } 5837 5838 return (tmp); 5839 } 5840 5841 static void 5842 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) 5843 { 5844 const struct bwn_rxhdr4 *rxhdr = _rxhdr; 5845 struct bwn_plcp6 *plcp; 5846 struct bwn_softc *sc = mac->mac_sc; 5847 struct ieee80211_frame_min *wh; 5848 struct ieee80211_node *ni; 5849 struct ieee80211com *ic = &sc->sc_ic; 5850 uint32_t macstat; 5851 int padding, rate, rssi = 0, noise = 0, type; 5852 uint16_t phytype, phystat0, phystat3, chanstat; 5853 unsigned char *mp = mtod(m, unsigned char *); 5854 static int rx_mac_dec_rpt = 0; 5855 5856 BWN_ASSERT_LOCKED(sc); 5857 5858 phystat0 = le16toh(rxhdr->phy_status0); 5859 phystat3 = le16toh(rxhdr->phy_status3); 5860 5861 /* XXX Note: mactime, macstat, chanstat need fixing for fw 598 */ 5862 macstat = le32toh(rxhdr->mac_status); 5863 chanstat = le16toh(rxhdr->channel); 5864 5865 phytype = chanstat & BWN_RX_CHAN_PHYTYPE; 5866 5867 if (macstat & BWN_RX_MAC_FCSERR) 5868 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n"); 5869 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV)) 5870 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n"); 5871 if (macstat & BWN_RX_MAC_DECERR) 5872 goto drop; 5873 5874 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0; 5875 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) { 5876 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 5877 m->m_pkthdr.len); 5878 goto drop; 5879 } 5880 plcp = (struct bwn_plcp6 *)(mp + padding); 5881 m_adj(m, sizeof(struct bwn_plcp6) + padding); 5882 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) { 5883 device_printf(sc->sc_dev, "frame too short (length=%d)\n", 5884 m->m_pkthdr.len); 5885 goto drop; 5886 } 5887 wh = mtod(m, struct ieee80211_frame_min *); 5888 5889 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50) 5890 device_printf(sc->sc_dev, 5891 "RX decryption attempted (old %d keyidx %#x)\n", 5892 BWN_ISOLDFMT(mac), 5893 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT); 5894 5895 if (phystat0 & BWN_RX_PHYST0_OFDM) 5896 rate = bwn_plcp_get_ofdmrate(mac, plcp, 5897 phytype == BWN_PHYTYPE_A); 5898 else 5899 rate = bwn_plcp_get_cckrate(mac, plcp); 5900 if (rate == -1) { 5901 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP)) 5902 goto drop; 5903 } 5904 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate); 5905 5906 /* rssi/noise */ 5907 switch (phytype) { 5908 case BWN_PHYTYPE_A: 5909 case BWN_PHYTYPE_B: 5910 case BWN_PHYTYPE_G: 5911 case BWN_PHYTYPE_LP: 5912 rssi = bwn_rx_rssi_calc(mac, rxhdr->phy.abg.rssi, 5913 !! (phystat0 & BWN_RX_PHYST0_OFDM), 5914 !! (phystat0 & BWN_RX_PHYST0_GAINCTL), 5915 !! (phystat3 & BWN_RX_PHYST3_TRSTATE)); 5916 break; 5917 case BWN_PHYTYPE_N: 5918 /* Broadcom has code for min/avg, but always used max */ 5919 if (rxhdr->phy.n.power0 == 16 || rxhdr->phy.n.power0 == 32) 5920 rssi = max(rxhdr->phy.n.power1, rxhdr->ps2.n.power2); 5921 else 5922 rssi = max(rxhdr->phy.n.power0, rxhdr->phy.n.power1); 5923 #if 0 5924 DPRINTF(mac->mac_sc, BWN_DEBUG_RECV, 5925 "%s: power0=%d, power1=%d, power2=%d\n", 5926 __func__, 5927 rxhdr->phy.n.power0, 5928 rxhdr->phy.n.power1, 5929 rxhdr->ps2.n.power2); 5930 #endif 5931 break; 5932 default: 5933 /* XXX TODO: implement rssi for other PHYs */ 5934 break; 5935 } 5936 5937 /* 5938 * RSSI here is absolute, not relative to the noise floor. 5939 */ 5940 noise = mac->mac_stats.link_noise; 5941 rssi = rssi - noise; 5942 5943 /* RX radio tap */ 5944 if (ieee80211_radiotap_active(ic)) 5945 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise); 5946 m_adj(m, -IEEE80211_CRC_LEN); 5947 5948 BWN_UNLOCK(sc); 5949 5950 ni = ieee80211_find_rxnode(ic, wh); 5951 if (ni != NULL) { 5952 type = ieee80211_input(ni, m, rssi, noise); 5953 ieee80211_free_node(ni); 5954 } else 5955 type = ieee80211_input_all(ic, m, rssi, noise); 5956 5957 BWN_LOCK(sc); 5958 return; 5959 drop: 5960 device_printf(sc->sc_dev, "%s: dropped\n", __func__); 5961 } 5962 5963 static void 5964 bwn_dma_handle_txeof(struct bwn_mac *mac, 5965 const struct bwn_txstatus *status) 5966 { 5967 struct bwn_dma *dma = &mac->mac_method.dma; 5968 struct bwn_dma_ring *dr; 5969 struct bwn_dmadesc_generic *desc; 5970 struct bwn_dmadesc_meta *meta; 5971 struct bwn_softc *sc = mac->mac_sc; 5972 int slot; 5973 int retrycnt = 0; 5974 5975 BWN_ASSERT_LOCKED(sc); 5976 5977 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot); 5978 if (dr == NULL) { 5979 device_printf(sc->sc_dev, "failed to parse cookie\n"); 5980 return; 5981 } 5982 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 5983 5984 while (1) { 5985 KASSERT(slot >= 0 && slot < dr->dr_numslots, 5986 ("%s:%d: fail", __func__, __LINE__)); 5987 dr->getdesc(dr, slot, &desc, &meta); 5988 5989 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) { 5990 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap); 5991 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) { 5992 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap); 5993 } 5994 5995 if (meta->mt_islast) { 5996 KASSERT(meta->mt_m != NULL, 5997 ("%s:%d: fail", __func__, __LINE__)); 5998 5999 /* 6000 * If we don't get an ACK, then we should log the 6001 * full framecnt. That may be 0 if it's a PHY 6002 * failure, so ensure that gets logged as some 6003 * retry attempt. 6004 */ 6005 if (status->ack) { 6006 retrycnt = status->framecnt - 1; 6007 } else { 6008 retrycnt = status->framecnt; 6009 if (retrycnt == 0) 6010 retrycnt = 1; 6011 } 6012 ieee80211_ratectl_tx_complete(meta->mt_ni->ni_vap, meta->mt_ni, 6013 status->ack ? 6014 IEEE80211_RATECTL_TX_SUCCESS : 6015 IEEE80211_RATECTL_TX_FAILURE, 6016 &retrycnt, 0); 6017 ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0); 6018 meta->mt_ni = NULL; 6019 meta->mt_m = NULL; 6020 } else 6021 KASSERT(meta->mt_m == NULL, 6022 ("%s:%d: fail", __func__, __LINE__)); 6023 6024 dr->dr_usedslot--; 6025 if (meta->mt_islast) 6026 break; 6027 slot = bwn_dma_nextslot(dr, slot); 6028 } 6029 sc->sc_watchdog_timer = 0; 6030 if (dr->dr_stop) { 6031 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, 6032 ("%s:%d: fail", __func__, __LINE__)); 6033 dr->dr_stop = 0; 6034 } 6035 } 6036 6037 static void 6038 bwn_pio_handle_txeof(struct bwn_mac *mac, 6039 const struct bwn_txstatus *status) 6040 { 6041 struct bwn_pio_txqueue *tq; 6042 struct bwn_pio_txpkt *tp = NULL; 6043 struct bwn_softc *sc = mac->mac_sc; 6044 int retrycnt = 0; 6045 6046 BWN_ASSERT_LOCKED(sc); 6047 6048 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp); 6049 if (tq == NULL) 6050 return; 6051 6052 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); 6053 tq->tq_free++; 6054 6055 if (tp->tp_ni != NULL) { 6056 /* 6057 * Do any tx complete callback. Note this must 6058 * be done before releasing the node reference. 6059 */ 6060 6061 /* 6062 * If we don't get an ACK, then we should log the 6063 * full framecnt. That may be 0 if it's a PHY 6064 * failure, so ensure that gets logged as some 6065 * retry attempt. 6066 */ 6067 if (status->ack) { 6068 retrycnt = status->framecnt - 1; 6069 } else { 6070 retrycnt = status->framecnt; 6071 if (retrycnt == 0) 6072 retrycnt = 1; 6073 } 6074 ieee80211_ratectl_tx_complete(tp->tp_ni->ni_vap, tp->tp_ni, 6075 status->ack ? 6076 IEEE80211_RATECTL_TX_SUCCESS : 6077 IEEE80211_RATECTL_TX_FAILURE, 6078 &retrycnt, 0); 6079 6080 if (tp->tp_m->m_flags & M_TXCB) 6081 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0); 6082 ieee80211_free_node(tp->tp_ni); 6083 tp->tp_ni = NULL; 6084 } 6085 m_freem(tp->tp_m); 6086 tp->tp_m = NULL; 6087 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); 6088 6089 sc->sc_watchdog_timer = 0; 6090 } 6091 6092 static void 6093 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) 6094 { 6095 struct bwn_softc *sc = mac->mac_sc; 6096 struct bwn_phy *phy = &mac->mac_phy; 6097 struct ieee80211com *ic = &sc->sc_ic; 6098 unsigned long now; 6099 bwn_txpwr_result_t result; 6100 6101 BWN_GETTIME(now); 6102 6103 if (!(flags & BWN_TXPWR_IGNORE_TIME) && ieee80211_time_before(now, phy->nexttime)) 6104 return; 6105 phy->nexttime = now + 2 * 1000; 6106 6107 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM && 6108 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306) 6109 return; 6110 6111 if (phy->recalc_txpwr != NULL) { 6112 result = phy->recalc_txpwr(mac, 6113 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0); 6114 if (result == BWN_TXPWR_RES_DONE) 6115 return; 6116 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST, 6117 ("%s: fail", __func__)); 6118 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__)); 6119 6120 ieee80211_runtask(ic, &mac->mac_txpower); 6121 } 6122 } 6123 6124 static uint16_t 6125 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset) 6126 { 6127 6128 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset)); 6129 } 6130 6131 static uint32_t 6132 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset) 6133 { 6134 6135 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset)); 6136 } 6137 6138 static void 6139 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value) 6140 { 6141 6142 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value); 6143 } 6144 6145 static void 6146 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value) 6147 { 6148 6149 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value); 6150 } 6151 6152 static int 6153 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate) 6154 { 6155 6156 switch (rate) { 6157 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 6158 case 12: 6159 return (BWN_OFDM_RATE_6MB); 6160 case 18: 6161 return (BWN_OFDM_RATE_9MB); 6162 case 24: 6163 return (BWN_OFDM_RATE_12MB); 6164 case 36: 6165 return (BWN_OFDM_RATE_18MB); 6166 case 48: 6167 return (BWN_OFDM_RATE_24MB); 6168 case 72: 6169 return (BWN_OFDM_RATE_36MB); 6170 case 96: 6171 return (BWN_OFDM_RATE_48MB); 6172 case 108: 6173 return (BWN_OFDM_RATE_54MB); 6174 /* CCK rates (NB: not IEEE std, device-specific) */ 6175 case 2: 6176 return (BWN_CCK_RATE_1MB); 6177 case 4: 6178 return (BWN_CCK_RATE_2MB); 6179 case 11: 6180 return (BWN_CCK_RATE_5MB); 6181 case 22: 6182 return (BWN_CCK_RATE_11MB); 6183 } 6184 6185 device_printf(sc->sc_dev, "unsupported rate %d\n", rate); 6186 return (BWN_CCK_RATE_1MB); 6187 } 6188 6189 static uint16_t 6190 bwn_set_txhdr_phyctl1(struct bwn_mac *mac, uint8_t bitrate) 6191 { 6192 struct bwn_phy *phy = &mac->mac_phy; 6193 uint16_t control = 0; 6194 uint16_t bw; 6195 6196 /* XXX TODO: this is for LP phy, what about N-PHY, etc? */ 6197 bw = BWN_TXH_PHY1_BW_20; 6198 6199 if (BWN_ISCCKRATE(bitrate) && phy->type != BWN_PHYTYPE_LP) { 6200 control = bw; 6201 } else { 6202 control = bw; 6203 /* Figure out coding rate and modulation */ 6204 /* XXX TODO: table-ize, for MCS transmit */ 6205 /* Note: this is BWN_*_RATE values */ 6206 switch (bitrate) { 6207 case BWN_CCK_RATE_1MB: 6208 control |= 0; 6209 break; 6210 case BWN_CCK_RATE_2MB: 6211 control |= 1; 6212 break; 6213 case BWN_CCK_RATE_5MB: 6214 control |= 2; 6215 break; 6216 case BWN_CCK_RATE_11MB: 6217 control |= 3; 6218 break; 6219 case BWN_OFDM_RATE_6MB: 6220 control |= BWN_TXH_PHY1_CRATE_1_2; 6221 control |= BWN_TXH_PHY1_MODUL_BPSK; 6222 break; 6223 case BWN_OFDM_RATE_9MB: 6224 control |= BWN_TXH_PHY1_CRATE_3_4; 6225 control |= BWN_TXH_PHY1_MODUL_BPSK; 6226 break; 6227 case BWN_OFDM_RATE_12MB: 6228 control |= BWN_TXH_PHY1_CRATE_1_2; 6229 control |= BWN_TXH_PHY1_MODUL_QPSK; 6230 break; 6231 case BWN_OFDM_RATE_18MB: 6232 control |= BWN_TXH_PHY1_CRATE_3_4; 6233 control |= BWN_TXH_PHY1_MODUL_QPSK; 6234 break; 6235 case BWN_OFDM_RATE_24MB: 6236 control |= BWN_TXH_PHY1_CRATE_1_2; 6237 control |= BWN_TXH_PHY1_MODUL_QAM16; 6238 break; 6239 case BWN_OFDM_RATE_36MB: 6240 control |= BWN_TXH_PHY1_CRATE_3_4; 6241 control |= BWN_TXH_PHY1_MODUL_QAM16; 6242 break; 6243 case BWN_OFDM_RATE_48MB: 6244 control |= BWN_TXH_PHY1_CRATE_1_2; 6245 control |= BWN_TXH_PHY1_MODUL_QAM64; 6246 break; 6247 case BWN_OFDM_RATE_54MB: 6248 control |= BWN_TXH_PHY1_CRATE_3_4; 6249 control |= BWN_TXH_PHY1_MODUL_QAM64; 6250 break; 6251 default: 6252 break; 6253 } 6254 control |= BWN_TXH_PHY1_MODE_SISO; 6255 } 6256 6257 return control; 6258 } 6259 6260 static int 6261 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, 6262 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie) 6263 { 6264 const struct bwn_phy *phy = &mac->mac_phy; 6265 struct bwn_softc *sc = mac->mac_sc; 6266 struct ieee80211_frame *wh; 6267 struct ieee80211_frame *protwh; 6268 struct ieee80211_frame_cts *cts; 6269 struct ieee80211_frame_rts *rts; 6270 const struct ieee80211_txparam *tp; 6271 struct ieee80211vap *vap = ni->ni_vap; 6272 struct ieee80211com *ic = &sc->sc_ic; 6273 struct mbuf *mprot; 6274 unsigned int len; 6275 uint32_t macctl = 0; 6276 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; 6277 uint16_t phyctl = 0; 6278 uint8_t rate, rate_fb; 6279 int fill_phy_ctl1 = 0; 6280 6281 wh = mtod(m, struct ieee80211_frame *); 6282 memset(txhdr, 0, sizeof(*txhdr)); 6283 6284 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 6285 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 6286 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 6287 6288 if ((phy->type == BWN_PHYTYPE_N) || (phy->type == BWN_PHYTYPE_LP) 6289 || (phy->type == BWN_PHYTYPE_HT)) 6290 fill_phy_ctl1 = 1; 6291 6292 /* 6293 * Find TX rate 6294 */ 6295 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 6296 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) 6297 rate = rate_fb = tp->mgmtrate; 6298 else if (ismcast) 6299 rate = rate_fb = tp->mcastrate; 6300 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 6301 rate = rate_fb = tp->ucastrate; 6302 else { 6303 /* XXX TODO: don't fall back to CCK rates for OFDM */ 6304 rix = ieee80211_ratectl_rate(ni, NULL, 0); 6305 rate = ni->ni_txrate; 6306 6307 if (rix > 0) 6308 rate_fb = ni->ni_rates.rs_rates[rix - 1] & 6309 IEEE80211_RATE_VAL; 6310 else 6311 rate_fb = rate; 6312 } 6313 6314 sc->sc_tx_rate = rate; 6315 6316 /* Note: this maps the select ieee80211 rate to hardware rate */ 6317 rate = bwn_ieeerate2hwrate(sc, rate); 6318 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb); 6319 6320 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) : 6321 bwn_plcp_getcck(rate); 6322 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc)); 6323 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN); 6324 6325 /* XXX rate/rate_fb is the hardware rate */ 6326 if ((rate_fb == rate) || 6327 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) || 6328 (*(u_int16_t *)wh->i_dur == htole16(0))) 6329 txhdr->dur_fb = *(u_int16_t *)wh->i_dur; 6330 else 6331 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt, 6332 m->m_pkthdr.len, rate, isshort); 6333 6334 /* XXX TX encryption */ 6335 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ? 6336 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) : 6337 (struct bwn_plcp4 *)(&txhdr->body.new.plcp), 6338 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate); 6339 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb), 6340 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb); 6341 6342 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM : 6343 BWN_TX_EFT_FB_CCK; 6344 txhdr->chan = phy->chan; 6345 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM : 6346 BWN_TX_PHY_ENC_CCK; 6347 /* XXX preamble? obey net80211 */ 6348 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 6349 rate == BWN_CCK_RATE_11MB)) 6350 phyctl |= BWN_TX_PHY_SHORTPRMBL; 6351 6352 if (! phy->gmode) 6353 macctl |= BWN_TX_MAC_5GHZ; 6354 6355 /* XXX TX antenna selection */ 6356 6357 switch (bwn_antenna_sanitize(mac, 0)) { 6358 case 0: 6359 phyctl |= BWN_TX_PHY_ANT01AUTO; 6360 break; 6361 case 1: 6362 phyctl |= BWN_TX_PHY_ANT0; 6363 break; 6364 case 2: 6365 phyctl |= BWN_TX_PHY_ANT1; 6366 break; 6367 case 3: 6368 phyctl |= BWN_TX_PHY_ANT2; 6369 break; 6370 case 4: 6371 phyctl |= BWN_TX_PHY_ANT3; 6372 break; 6373 default: 6374 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 6375 } 6376 6377 if (!ismcast) 6378 macctl |= BWN_TX_MAC_ACK; 6379 6380 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU); 6381 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 6382 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 6383 macctl |= BWN_TX_MAC_LONGFRAME; 6384 6385 if (ic->ic_flags & IEEE80211_F_USEPROT) { 6386 /* XXX RTS rate is always 1MB??? */ 6387 /* XXX TODO: don't fall back to CCK rates for OFDM */ 6388 rts_rate = BWN_CCK_RATE_1MB; 6389 rts_rate_fb = bwn_get_fbrate(rts_rate); 6390 6391 /* XXX 'rate' here is hardware rate now, not the net80211 rate */ 6392 protdur = ieee80211_compute_duration(ic->ic_rt, 6393 m->m_pkthdr.len, rate, isshort) + 6394 + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 6395 6396 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 6397 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ? 6398 (txhdr->body.old.rts_frame) : 6399 (txhdr->body.new.rts_frame)); 6400 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, 6401 protdur); 6402 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 6403 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, 6404 mprot->m_pkthdr.len); 6405 m_freem(mprot); 6406 macctl |= BWN_TX_MAC_SEND_CTSTOSELF; 6407 len = sizeof(struct ieee80211_frame_cts); 6408 } else { 6409 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ? 6410 (txhdr->body.old.rts_frame) : 6411 (txhdr->body.new.rts_frame)); 6412 /* XXX rate/rate_fb is the hardware rate */ 6413 protdur += ieee80211_ack_duration(ic->ic_rt, rate, 6414 isshort); 6415 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, 6416 wh->i_addr2, protdur); 6417 KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); 6418 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, 6419 mprot->m_pkthdr.len); 6420 m_freem(mprot); 6421 macctl |= BWN_TX_MAC_SEND_RTSCTS; 6422 len = sizeof(struct ieee80211_frame_rts); 6423 } 6424 len += IEEE80211_CRC_LEN; 6425 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ? 6426 &txhdr->body.old.rts_plcp : 6427 &txhdr->body.new.rts_plcp), len, rts_rate); 6428 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len, 6429 rts_rate_fb); 6430 6431 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ? 6432 (&txhdr->body.old.rts_frame) : 6433 (&txhdr->body.new.rts_frame)); 6434 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur; 6435 6436 if (BWN_ISOFDMRATE(rts_rate)) { 6437 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM; 6438 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate); 6439 } else { 6440 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK; 6441 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate); 6442 } 6443 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ? 6444 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK; 6445 6446 if (fill_phy_ctl1) { 6447 txhdr->phyctl_1rts = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate)); 6448 txhdr->phyctl_1rtsfb = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate_fb)); 6449 } 6450 } 6451 6452 if (fill_phy_ctl1) { 6453 txhdr->phyctl_1 = htole16(bwn_set_txhdr_phyctl1(mac, rate)); 6454 txhdr->phyctl_1fb = htole16(bwn_set_txhdr_phyctl1(mac, rate_fb)); 6455 } 6456 6457 if (BWN_ISOLDFMT(mac)) 6458 txhdr->body.old.cookie = htole16(cookie); 6459 else 6460 txhdr->body.new.cookie = htole16(cookie); 6461 6462 txhdr->macctl = htole32(macctl); 6463 txhdr->phyctl = htole16(phyctl); 6464 6465 /* 6466 * TX radio tap 6467 */ 6468 if (ieee80211_radiotap_active_vap(vap)) { 6469 sc->sc_tx_th.wt_flags = 0; 6470 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 6471 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 6472 if (isshort && 6473 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB || 6474 rate == BWN_CCK_RATE_11MB)) 6475 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 6476 sc->sc_tx_th.wt_rate = rate; 6477 6478 ieee80211_radiotap_tx(vap, m); 6479 } 6480 6481 return (0); 6482 } 6483 6484 static void 6485 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets, 6486 const uint8_t rate) 6487 { 6488 uint32_t d, plen; 6489 uint8_t *raw = plcp->o.raw; 6490 6491 if (BWN_ISOFDMRATE(rate)) { 6492 d = bwn_plcp_getofdm(rate); 6493 KASSERT(!(octets & 0xf000), 6494 ("%s:%d: fail", __func__, __LINE__)); 6495 d |= (octets << 5); 6496 plcp->o.data = htole32(d); 6497 } else { 6498 plen = octets * 16 / rate; 6499 if ((octets * 16 % rate) > 0) { 6500 plen++; 6501 if ((rate == BWN_CCK_RATE_11MB) 6502 && ((octets * 8 % 11) < 4)) { 6503 raw[1] = 0x84; 6504 } else 6505 raw[1] = 0x04; 6506 } else 6507 raw[1] = 0x04; 6508 plcp->o.data |= htole32(plen << 16); 6509 raw[0] = bwn_plcp_getcck(rate); 6510 } 6511 } 6512 6513 static uint8_t 6514 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n) 6515 { 6516 struct bwn_softc *sc = mac->mac_sc; 6517 uint8_t mask; 6518 6519 if (n == 0) 6520 return (0); 6521 if (mac->mac_phy.gmode) 6522 mask = siba_sprom_get_ant_bg(sc->sc_dev); 6523 else 6524 mask = siba_sprom_get_ant_a(sc->sc_dev); 6525 if (!(mask & (1 << (n - 1)))) 6526 return (0); 6527 return (n); 6528 } 6529 6530 /* 6531 * Return a fallback rate for the given rate. 6532 * 6533 * Note: Don't fall back from OFDM to CCK. 6534 */ 6535 static uint8_t 6536 bwn_get_fbrate(uint8_t bitrate) 6537 { 6538 switch (bitrate) { 6539 /* CCK */ 6540 case BWN_CCK_RATE_1MB: 6541 return (BWN_CCK_RATE_1MB); 6542 case BWN_CCK_RATE_2MB: 6543 return (BWN_CCK_RATE_1MB); 6544 case BWN_CCK_RATE_5MB: 6545 return (BWN_CCK_RATE_2MB); 6546 case BWN_CCK_RATE_11MB: 6547 return (BWN_CCK_RATE_5MB); 6548 6549 /* OFDM */ 6550 case BWN_OFDM_RATE_6MB: 6551 return (BWN_OFDM_RATE_6MB); 6552 case BWN_OFDM_RATE_9MB: 6553 return (BWN_OFDM_RATE_6MB); 6554 case BWN_OFDM_RATE_12MB: 6555 return (BWN_OFDM_RATE_9MB); 6556 case BWN_OFDM_RATE_18MB: 6557 return (BWN_OFDM_RATE_12MB); 6558 case BWN_OFDM_RATE_24MB: 6559 return (BWN_OFDM_RATE_18MB); 6560 case BWN_OFDM_RATE_36MB: 6561 return (BWN_OFDM_RATE_24MB); 6562 case BWN_OFDM_RATE_48MB: 6563 return (BWN_OFDM_RATE_36MB); 6564 case BWN_OFDM_RATE_54MB: 6565 return (BWN_OFDM_RATE_48MB); 6566 } 6567 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 6568 return (0); 6569 } 6570 6571 static uint32_t 6572 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6573 uint32_t ctl, const void *_data, int len) 6574 { 6575 struct bwn_softc *sc = mac->mac_sc; 6576 uint32_t value = 0; 6577 const uint8_t *data = _data; 6578 6579 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 | 6580 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31; 6581 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 6582 6583 siba_write_multi_4(sc->sc_dev, data, (len & ~3), 6584 tq->tq_base + BWN_PIO8_TXDATA); 6585 if (len & 3) { 6586 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 | 6587 BWN_PIO8_TXCTL_24_31); 6588 data = &(data[len - 1]); 6589 switch (len & 3) { 6590 case 3: 6591 ctl |= BWN_PIO8_TXCTL_16_23; 6592 value |= (uint32_t)(*data) << 16; 6593 data--; 6594 case 2: 6595 ctl |= BWN_PIO8_TXCTL_8_15; 6596 value |= (uint32_t)(*data) << 8; 6597 data--; 6598 case 1: 6599 value |= (uint32_t)(*data); 6600 } 6601 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl); 6602 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value); 6603 } 6604 6605 return (ctl); 6606 } 6607 6608 static void 6609 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6610 uint16_t offset, uint32_t value) 6611 { 6612 6613 BWN_WRITE_4(mac, tq->tq_base + offset, value); 6614 } 6615 6616 static uint16_t 6617 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6618 uint16_t ctl, const void *_data, int len) 6619 { 6620 struct bwn_softc *sc = mac->mac_sc; 6621 const uint8_t *data = _data; 6622 6623 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 6624 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6625 6626 siba_write_multi_2(sc->sc_dev, data, (len & ~1), 6627 tq->tq_base + BWN_PIO_TXDATA); 6628 if (len & 1) { 6629 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 6630 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6631 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]); 6632 } 6633 6634 return (ctl); 6635 } 6636 6637 static uint16_t 6638 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq, 6639 uint16_t ctl, struct mbuf *m0) 6640 { 6641 int i, j = 0; 6642 uint16_t data = 0; 6643 const uint8_t *buf; 6644 struct mbuf *m = m0; 6645 6646 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI; 6647 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6648 6649 for (; m != NULL; m = m->m_next) { 6650 buf = mtod(m, const uint8_t *); 6651 for (i = 0; i < m->m_len; i++) { 6652 if (!((j++) % 2)) 6653 data |= buf[i]; 6654 else { 6655 data |= (buf[i] << 8); 6656 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 6657 data = 0; 6658 } 6659 } 6660 } 6661 if (m0->m_pkthdr.len % 2) { 6662 ctl &= ~BWN_PIO_TXCTL_WRITEHI; 6663 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl); 6664 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data); 6665 } 6666 6667 return (ctl); 6668 } 6669 6670 static void 6671 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time) 6672 { 6673 6674 /* XXX should exit if 5GHz band .. */ 6675 if (mac->mac_phy.type != BWN_PHYTYPE_G) 6676 return; 6677 6678 BWN_WRITE_2(mac, 0x684, 510 + time); 6679 /* Disabled in Linux b43, can adversely effect performance */ 6680 #if 0 6681 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time); 6682 #endif 6683 } 6684 6685 static struct bwn_dma_ring * 6686 bwn_dma_select(struct bwn_mac *mac, uint8_t prio) 6687 { 6688 6689 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0) 6690 return (mac->mac_method.dma.wme[WME_AC_BE]); 6691 6692 switch (prio) { 6693 case 3: 6694 return (mac->mac_method.dma.wme[WME_AC_VO]); 6695 case 2: 6696 return (mac->mac_method.dma.wme[WME_AC_VI]); 6697 case 0: 6698 return (mac->mac_method.dma.wme[WME_AC_BE]); 6699 case 1: 6700 return (mac->mac_method.dma.wme[WME_AC_BK]); 6701 } 6702 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 6703 return (NULL); 6704 } 6705 6706 static int 6707 bwn_dma_getslot(struct bwn_dma_ring *dr) 6708 { 6709 int slot; 6710 6711 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc); 6712 6713 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__)); 6714 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__)); 6715 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__)); 6716 6717 slot = bwn_dma_nextslot(dr, dr->dr_curslot); 6718 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__)); 6719 dr->dr_curslot = slot; 6720 dr->dr_usedslot++; 6721 6722 return (slot); 6723 } 6724 6725 static struct bwn_pio_txqueue * 6726 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie, 6727 struct bwn_pio_txpkt **pack) 6728 { 6729 struct bwn_pio *pio = &mac->mac_method.pio; 6730 struct bwn_pio_txqueue *tq = NULL; 6731 unsigned int index; 6732 6733 switch (cookie & 0xf000) { 6734 case 0x1000: 6735 tq = &pio->wme[WME_AC_BK]; 6736 break; 6737 case 0x2000: 6738 tq = &pio->wme[WME_AC_BE]; 6739 break; 6740 case 0x3000: 6741 tq = &pio->wme[WME_AC_VI]; 6742 break; 6743 case 0x4000: 6744 tq = &pio->wme[WME_AC_VO]; 6745 break; 6746 case 0x5000: 6747 tq = &pio->mcast; 6748 break; 6749 } 6750 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__)); 6751 if (tq == NULL) 6752 return (NULL); 6753 index = (cookie & 0x0fff); 6754 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__)); 6755 if (index >= N(tq->tq_pkts)) 6756 return (NULL); 6757 *pack = &tq->tq_pkts[index]; 6758 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__)); 6759 return (tq); 6760 } 6761 6762 static void 6763 bwn_txpwr(void *arg, int npending) 6764 { 6765 struct bwn_mac *mac = arg; 6766 struct bwn_softc *sc = mac->mac_sc; 6767 6768 BWN_LOCK(sc); 6769 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED && 6770 mac->mac_phy.set_txpwr != NULL) 6771 mac->mac_phy.set_txpwr(mac); 6772 BWN_UNLOCK(sc); 6773 } 6774 6775 static void 6776 bwn_task_15s(struct bwn_mac *mac) 6777 { 6778 uint16_t reg; 6779 6780 if (mac->mac_fw.opensource) { 6781 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG); 6782 if (reg) { 6783 bwn_restart(mac, "fw watchdog"); 6784 return; 6785 } 6786 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1); 6787 } 6788 if (mac->mac_phy.task_15s) 6789 mac->mac_phy.task_15s(mac); 6790 6791 mac->mac_phy.txerrors = BWN_TXERROR_MAX; 6792 } 6793 6794 static void 6795 bwn_task_30s(struct bwn_mac *mac) 6796 { 6797 6798 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running) 6799 return; 6800 mac->mac_noise.noi_running = 1; 6801 mac->mac_noise.noi_nsamples = 0; 6802 6803 bwn_noise_gensample(mac); 6804 } 6805 6806 static void 6807 bwn_task_60s(struct bwn_mac *mac) 6808 { 6809 6810 if (mac->mac_phy.task_60s) 6811 mac->mac_phy.task_60s(mac); 6812 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME); 6813 } 6814 6815 static void 6816 bwn_tasks(void *arg) 6817 { 6818 struct bwn_mac *mac = arg; 6819 struct bwn_softc *sc = mac->mac_sc; 6820 6821 BWN_ASSERT_LOCKED(sc); 6822 if (mac->mac_status != BWN_MAC_STATUS_STARTED) 6823 return; 6824 6825 if (mac->mac_task_state % 4 == 0) 6826 bwn_task_60s(mac); 6827 if (mac->mac_task_state % 2 == 0) 6828 bwn_task_30s(mac); 6829 bwn_task_15s(mac); 6830 6831 mac->mac_task_state++; 6832 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac); 6833 } 6834 6835 static int 6836 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a) 6837 { 6838 struct bwn_softc *sc = mac->mac_sc; 6839 6840 KASSERT(a == 0, ("not support APHY\n")); 6841 6842 switch (plcp->o.raw[0] & 0xf) { 6843 case 0xb: 6844 return (BWN_OFDM_RATE_6MB); 6845 case 0xf: 6846 return (BWN_OFDM_RATE_9MB); 6847 case 0xa: 6848 return (BWN_OFDM_RATE_12MB); 6849 case 0xe: 6850 return (BWN_OFDM_RATE_18MB); 6851 case 0x9: 6852 return (BWN_OFDM_RATE_24MB); 6853 case 0xd: 6854 return (BWN_OFDM_RATE_36MB); 6855 case 0x8: 6856 return (BWN_OFDM_RATE_48MB); 6857 case 0xc: 6858 return (BWN_OFDM_RATE_54MB); 6859 } 6860 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n", 6861 plcp->o.raw[0] & 0xf); 6862 return (-1); 6863 } 6864 6865 static int 6866 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp) 6867 { 6868 struct bwn_softc *sc = mac->mac_sc; 6869 6870 switch (plcp->o.raw[0]) { 6871 case 0x0a: 6872 return (BWN_CCK_RATE_1MB); 6873 case 0x14: 6874 return (BWN_CCK_RATE_2MB); 6875 case 0x37: 6876 return (BWN_CCK_RATE_5MB); 6877 case 0x6e: 6878 return (BWN_CCK_RATE_11MB); 6879 } 6880 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]); 6881 return (-1); 6882 } 6883 6884 static void 6885 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m, 6886 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate, 6887 int rssi, int noise) 6888 { 6889 struct bwn_softc *sc = mac->mac_sc; 6890 const struct ieee80211_frame_min *wh; 6891 uint64_t tsf; 6892 uint16_t low_mactime_now; 6893 6894 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL) 6895 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 6896 6897 wh = mtod(m, const struct ieee80211_frame_min *); 6898 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 6899 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; 6900 6901 bwn_tsf_read(mac, &tsf); 6902 low_mactime_now = tsf; 6903 tsf = tsf & ~0xffffULL; 6904 tsf += le16toh(rxhdr->mac_time); 6905 if (low_mactime_now < le16toh(rxhdr->mac_time)) 6906 tsf -= 0x10000; 6907 6908 sc->sc_rx_th.wr_tsf = tsf; 6909 sc->sc_rx_th.wr_rate = rate; 6910 sc->sc_rx_th.wr_antsignal = rssi; 6911 sc->sc_rx_th.wr_antnoise = noise; 6912 } 6913 6914 static void 6915 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf) 6916 { 6917 uint32_t low, high; 6918 6919 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3, 6920 ("%s:%d: fail", __func__, __LINE__)); 6921 6922 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW); 6923 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH); 6924 *tsf = high; 6925 *tsf <<= 32; 6926 *tsf |= low; 6927 } 6928 6929 static int 6930 bwn_dma_attach(struct bwn_mac *mac) 6931 { 6932 struct bwn_dma *dma = &mac->mac_method.dma; 6933 struct bwn_softc *sc = mac->mac_sc; 6934 bus_addr_t lowaddr = 0; 6935 int error; 6936 6937 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0) 6938 return (0); 6939 6940 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__)); 6941 6942 mac->mac_flags |= BWN_MAC_FLAG_DMA; 6943 6944 dma->dmatype = bwn_dma_gettype(mac); 6945 if (dma->dmatype == BWN_DMA_30BIT) 6946 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT; 6947 else if (dma->dmatype == BWN_DMA_32BIT) 6948 lowaddr = BUS_SPACE_MAXADDR_32BIT; 6949 else 6950 lowaddr = BUS_SPACE_MAXADDR; 6951 6952 /* 6953 * Create top level DMA tag 6954 */ 6955 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 6956 BWN_ALIGN, 0, /* alignment, bounds */ 6957 lowaddr, /* lowaddr */ 6958 BUS_SPACE_MAXADDR, /* highaddr */ 6959 #if !defined(__DragonFly__) 6960 NULL, NULL, /* filter, filterarg */ 6961 #endif 6962 BUS_SPACE_MAXSIZE, /* maxsize */ 6963 BUS_SPACE_UNRESTRICTED, /* nsegments */ 6964 BUS_SPACE_MAXSIZE, /* maxsegsize */ 6965 0, /* flags */ 6966 #if !defined(__DragonFly__) 6967 NULL, NULL, /* lockfunc, lockarg */ 6968 #endif 6969 &dma->parent_dtag); 6970 if (error) { 6971 device_printf(sc->sc_dev, "can't create parent DMA tag\n"); 6972 return (error); 6973 } 6974 6975 /* 6976 * Create TX/RX mbuf DMA tag 6977 */ 6978 error = bus_dma_tag_create(dma->parent_dtag, 6979 1, 6980 0, 6981 BUS_SPACE_MAXADDR, 6982 BUS_SPACE_MAXADDR, 6983 #if !defined(__DragonFly__) 6984 NULL, NULL, 6985 #endif 6986 MCLBYTES, 6987 1, 6988 BUS_SPACE_MAXSIZE_32BIT, 6989 0, 6990 #if !defined(__DragonFly__) 6991 NULL, NULL, 6992 #endif 6993 &dma->rxbuf_dtag); 6994 if (error) { 6995 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 6996 goto fail0; 6997 } 6998 error = bus_dma_tag_create(dma->parent_dtag, 6999 1, 7000 0, 7001 BUS_SPACE_MAXADDR, 7002 BUS_SPACE_MAXADDR, 7003 #if !defined(__DragonFly__) 7004 NULL, NULL, 7005 #endif 7006 MCLBYTES, 7007 1, 7008 BUS_SPACE_MAXSIZE_32BIT, 7009 0, 7010 #if !defined(__DragonFly__) 7011 NULL, NULL, 7012 #endif 7013 &dma->txbuf_dtag); 7014 if (error) { 7015 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n"); 7016 goto fail1; 7017 } 7018 7019 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype); 7020 if (!dma->wme[WME_AC_BK]) 7021 goto fail2; 7022 7023 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype); 7024 if (!dma->wme[WME_AC_BE]) 7025 goto fail3; 7026 7027 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype); 7028 if (!dma->wme[WME_AC_VI]) 7029 goto fail4; 7030 7031 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype); 7032 if (!dma->wme[WME_AC_VO]) 7033 goto fail5; 7034 7035 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype); 7036 if (!dma->mcast) 7037 goto fail6; 7038 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype); 7039 if (!dma->rx) 7040 goto fail7; 7041 7042 return (error); 7043 7044 fail7: bwn_dma_ringfree(&dma->mcast); 7045 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]); 7046 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]); 7047 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]); 7048 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]); 7049 fail2: bus_dma_tag_destroy(dma->txbuf_dtag); 7050 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag); 7051 fail0: bus_dma_tag_destroy(dma->parent_dtag); 7052 return (error); 7053 } 7054 7055 static struct bwn_dma_ring * 7056 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status, 7057 uint16_t cookie, int *slot) 7058 { 7059 struct bwn_dma *dma = &mac->mac_method.dma; 7060 struct bwn_dma_ring *dr; 7061 struct bwn_softc *sc = mac->mac_sc; 7062 7063 BWN_ASSERT_LOCKED(mac->mac_sc); 7064 7065 switch (cookie & 0xf000) { 7066 case 0x1000: 7067 dr = dma->wme[WME_AC_BK]; 7068 break; 7069 case 0x2000: 7070 dr = dma->wme[WME_AC_BE]; 7071 break; 7072 case 0x3000: 7073 dr = dma->wme[WME_AC_VI]; 7074 break; 7075 case 0x4000: 7076 dr = dma->wme[WME_AC_VO]; 7077 break; 7078 case 0x5000: 7079 dr = dma->mcast; 7080 break; 7081 default: 7082 dr = NULL; 7083 KASSERT(0 == 1, 7084 ("invalid cookie value %d", cookie & 0xf000)); 7085 } 7086 *slot = (cookie & 0x0fff); 7087 if (*slot < 0 || *slot >= dr->dr_numslots) { 7088 /* 7089 * XXX FIXME: sometimes H/W returns TX DONE events duplicately 7090 * that it occurs events which have same H/W sequence numbers. 7091 * When it's occurred just prints a WARNING msgs and ignores. 7092 */ 7093 KASSERT(status->seq == dma->lastseq, 7094 ("%s:%d: fail", __func__, __LINE__)); 7095 device_printf(sc->sc_dev, 7096 "out of slot ranges (0 < %d < %d)\n", *slot, 7097 dr->dr_numslots); 7098 return (NULL); 7099 } 7100 dma->lastseq = status->seq; 7101 return (dr); 7102 } 7103 7104 static void 7105 bwn_dma_stop(struct bwn_mac *mac) 7106 { 7107 struct bwn_dma *dma; 7108 7109 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0) 7110 return; 7111 dma = &mac->mac_method.dma; 7112 7113 bwn_dma_ringstop(&dma->rx); 7114 bwn_dma_ringstop(&dma->wme[WME_AC_BK]); 7115 bwn_dma_ringstop(&dma->wme[WME_AC_BE]); 7116 bwn_dma_ringstop(&dma->wme[WME_AC_VI]); 7117 bwn_dma_ringstop(&dma->wme[WME_AC_VO]); 7118 bwn_dma_ringstop(&dma->mcast); 7119 } 7120 7121 static void 7122 bwn_dma_ringstop(struct bwn_dma_ring **dr) 7123 { 7124 7125 if (dr == NULL) 7126 return; 7127 7128 bwn_dma_cleanup(*dr); 7129 } 7130 7131 static void 7132 bwn_pio_stop(struct bwn_mac *mac) 7133 { 7134 struct bwn_pio *pio; 7135 7136 if (mac->mac_flags & BWN_MAC_FLAG_DMA) 7137 return; 7138 pio = &mac->mac_method.pio; 7139 7140 bwn_destroy_queue_tx(&pio->mcast); 7141 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]); 7142 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]); 7143 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]); 7144 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]); 7145 } 7146 7147 static void 7148 bwn_led_attach(struct bwn_mac *mac) 7149 { 7150 struct bwn_softc *sc = mac->mac_sc; 7151 const uint8_t *led_act = NULL; 7152 uint16_t val[BWN_LED_MAX]; 7153 int i; 7154 7155 sc->sc_led_idle = (2350 * hz) / 1000; 7156 sc->sc_led_blink = 1; 7157 7158 for (i = 0; i < N(bwn_vendor_led_act); ++i) { 7159 if (siba_get_pci_subvendor(sc->sc_dev) == 7160 bwn_vendor_led_act[i].vid) { 7161 led_act = bwn_vendor_led_act[i].led_act; 7162 break; 7163 } 7164 } 7165 if (led_act == NULL) 7166 led_act = bwn_default_led_act; 7167 7168 val[0] = siba_sprom_get_gpio0(sc->sc_dev); 7169 val[1] = siba_sprom_get_gpio1(sc->sc_dev); 7170 val[2] = siba_sprom_get_gpio2(sc->sc_dev); 7171 val[3] = siba_sprom_get_gpio3(sc->sc_dev); 7172 7173 for (i = 0; i < BWN_LED_MAX; ++i) { 7174 struct bwn_led *led = &sc->sc_leds[i]; 7175 7176 if (val[i] == 0xff) { 7177 led->led_act = led_act[i]; 7178 } else { 7179 if (val[i] & BWN_LED_ACT_LOW) 7180 led->led_flags |= BWN_LED_F_ACTLOW; 7181 led->led_act = val[i] & BWN_LED_ACT_MASK; 7182 } 7183 led->led_mask = (1 << i); 7184 7185 if (led->led_act == BWN_LED_ACT_BLINK_SLOW || 7186 led->led_act == BWN_LED_ACT_BLINK_POLL || 7187 led->led_act == BWN_LED_ACT_BLINK) { 7188 led->led_flags |= BWN_LED_F_BLINK; 7189 if (led->led_act == BWN_LED_ACT_BLINK_POLL) 7190 led->led_flags |= BWN_LED_F_POLLABLE; 7191 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW) 7192 led->led_flags |= BWN_LED_F_SLOW; 7193 7194 if (sc->sc_blink_led == NULL) { 7195 sc->sc_blink_led = led; 7196 if (led->led_flags & BWN_LED_F_SLOW) 7197 BWN_LED_SLOWDOWN(sc->sc_led_idle); 7198 } 7199 } 7200 7201 DPRINTF(sc, BWN_DEBUG_LED, 7202 "%dth led, act %d, lowact %d\n", i, 7203 led->led_act, led->led_flags & BWN_LED_F_ACTLOW); 7204 } 7205 #if defined(__DragonFly__) 7206 callout_init_lk(&sc->sc_led_blink_ch, &sc->sc_lk); 7207 #else 7208 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0); 7209 #endif 7210 } 7211 7212 static __inline uint16_t 7213 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on) 7214 { 7215 7216 if (led->led_flags & BWN_LED_F_ACTLOW) 7217 on = !on; 7218 if (on) 7219 val |= led->led_mask; 7220 else 7221 val &= ~led->led_mask; 7222 return val; 7223 } 7224 7225 static void 7226 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) 7227 { 7228 struct bwn_softc *sc = mac->mac_sc; 7229 struct ieee80211com *ic = &sc->sc_ic; 7230 uint16_t val; 7231 int i; 7232 7233 if (nstate == IEEE80211_S_INIT) { 7234 callout_stop(&sc->sc_led_blink_ch); 7235 sc->sc_led_blinking = 0; 7236 } 7237 7238 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) 7239 return; 7240 7241 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 7242 for (i = 0; i < BWN_LED_MAX; ++i) { 7243 struct bwn_led *led = &sc->sc_leds[i]; 7244 int on; 7245 7246 if (led->led_act == BWN_LED_ACT_UNKN || 7247 led->led_act == BWN_LED_ACT_NULL) 7248 continue; 7249 7250 if ((led->led_flags & BWN_LED_F_BLINK) && 7251 nstate != IEEE80211_S_INIT) 7252 continue; 7253 7254 switch (led->led_act) { 7255 case BWN_LED_ACT_ON: /* Always on */ 7256 on = 1; 7257 break; 7258 case BWN_LED_ACT_OFF: /* Always off */ 7259 case BWN_LED_ACT_5GHZ: /* TODO: 11A */ 7260 on = 0; 7261 break; 7262 default: 7263 on = 1; 7264 switch (nstate) { 7265 case IEEE80211_S_INIT: 7266 on = 0; 7267 break; 7268 case IEEE80211_S_RUN: 7269 if (led->led_act == BWN_LED_ACT_11G && 7270 ic->ic_curmode != IEEE80211_MODE_11G) 7271 on = 0; 7272 break; 7273 default: 7274 if (led->led_act == BWN_LED_ACT_ASSOC) 7275 on = 0; 7276 break; 7277 } 7278 break; 7279 } 7280 7281 val = bwn_led_onoff(led, val, on); 7282 } 7283 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 7284 } 7285 7286 static void 7287 bwn_led_event(struct bwn_mac *mac, int event) 7288 { 7289 struct bwn_softc *sc = mac->mac_sc; 7290 struct bwn_led *led = sc->sc_blink_led; 7291 int rate; 7292 7293 if (event == BWN_LED_EVENT_POLL) { 7294 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0) 7295 return; 7296 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 7297 return; 7298 } 7299 7300 sc->sc_led_ticks = ticks; 7301 if (sc->sc_led_blinking) 7302 return; 7303 7304 switch (event) { 7305 case BWN_LED_EVENT_RX: 7306 rate = sc->sc_rx_rate; 7307 break; 7308 case BWN_LED_EVENT_TX: 7309 rate = sc->sc_tx_rate; 7310 break; 7311 case BWN_LED_EVENT_POLL: 7312 rate = 0; 7313 break; 7314 default: 7315 panic("unknown LED event %d\n", event); 7316 break; 7317 } 7318 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur, 7319 bwn_led_duration[rate].off_dur); 7320 } 7321 7322 static void 7323 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur) 7324 { 7325 struct bwn_softc *sc = mac->mac_sc; 7326 struct bwn_led *led = sc->sc_blink_led; 7327 uint16_t val; 7328 7329 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 7330 val = bwn_led_onoff(led, val, 1); 7331 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 7332 7333 if (led->led_flags & BWN_LED_F_SLOW) { 7334 BWN_LED_SLOWDOWN(on_dur); 7335 BWN_LED_SLOWDOWN(off_dur); 7336 } 7337 7338 sc->sc_led_blinking = 1; 7339 sc->sc_led_blink_offdur = off_dur; 7340 7341 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac); 7342 } 7343 7344 static void 7345 bwn_led_blink_next(void *arg) 7346 { 7347 struct bwn_mac *mac = arg; 7348 struct bwn_softc *sc = mac->mac_sc; 7349 uint16_t val; 7350 7351 val = BWN_READ_2(mac, BWN_GPIO_CONTROL); 7352 val = bwn_led_onoff(sc->sc_blink_led, val, 0); 7353 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val); 7354 7355 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 7356 bwn_led_blink_end, mac); 7357 } 7358 7359 static void 7360 bwn_led_blink_end(void *arg) 7361 { 7362 struct bwn_mac *mac = arg; 7363 struct bwn_softc *sc = mac->mac_sc; 7364 7365 sc->sc_led_blinking = 0; 7366 } 7367 7368 static int 7369 bwn_suspend(device_t dev) 7370 { 7371 struct bwn_softc *sc = device_get_softc(dev); 7372 7373 BWN_LOCK(sc); 7374 bwn_stop(sc); 7375 BWN_UNLOCK(sc); 7376 return (0); 7377 } 7378 7379 static int 7380 bwn_resume(device_t dev) 7381 { 7382 struct bwn_softc *sc = device_get_softc(dev); 7383 int error = EDOOFUS; 7384 7385 BWN_LOCK(sc); 7386 if (sc->sc_ic.ic_nrunning > 0) 7387 error = bwn_init(sc); 7388 BWN_UNLOCK(sc); 7389 if (error == 0) 7390 ieee80211_start_all(&sc->sc_ic); 7391 return (0); 7392 } 7393 7394 static void 7395 bwn_rfswitch(void *arg) 7396 { 7397 struct bwn_softc *sc = arg; 7398 struct bwn_mac *mac = sc->sc_curmac; 7399 int cur = 0, prev = 0; 7400 7401 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED, 7402 ("%s: invalid MAC status %d", __func__, mac->mac_status)); 7403 7404 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP 7405 || mac->mac_phy.type == BWN_PHYTYPE_N) { 7406 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI) 7407 & BWN_RF_HWENABLED_HI_MASK)) 7408 cur = 1; 7409 } else { 7410 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO) 7411 & BWN_RF_HWENABLED_LO_MASK) 7412 cur = 1; 7413 } 7414 7415 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON) 7416 prev = 1; 7417 7418 DPRINTF(sc, BWN_DEBUG_RESET, "%s: called; cur=%d, prev=%d\n", 7419 __func__, cur, prev); 7420 7421 if (cur != prev) { 7422 if (cur) 7423 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON; 7424 else 7425 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON; 7426 7427 device_printf(sc->sc_dev, 7428 "status of RF switch is changed to %s\n", 7429 cur ? "ON" : "OFF"); 7430 if (cur != mac->mac_phy.rf_on) { 7431 if (cur) 7432 bwn_rf_turnon(mac); 7433 else 7434 bwn_rf_turnoff(mac); 7435 } 7436 } 7437 7438 #if defined(__DragonFly__) 7439 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); 7440 #else 7441 callout_schedule(&sc->sc_rfswitch_ch, hz); 7442 #endif 7443 } 7444 7445 static void 7446 bwn_sysctl_node(struct bwn_softc *sc) 7447 { 7448 device_t dev = sc->sc_dev; 7449 struct bwn_mac *mac; 7450 struct bwn_stats *stats; 7451 7452 /* XXX assume that count of MAC is only 1. */ 7453 7454 if ((mac = sc->sc_curmac) == NULL) 7455 return; 7456 stats = &mac->mac_stats; 7457 7458 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 7459 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7460 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level"); 7461 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 7462 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7463 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS"); 7464 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 7465 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7466 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send"); 7467 7468 #ifdef BWN_DEBUG 7469 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 7470 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 7471 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); 7472 #endif 7473 } 7474 7475 static device_method_t bwn_methods[] = { 7476 /* Device interface */ 7477 DEVMETHOD(device_probe, bwn_probe), 7478 DEVMETHOD(device_attach, bwn_attach), 7479 DEVMETHOD(device_detach, bwn_detach), 7480 DEVMETHOD(device_suspend, bwn_suspend), 7481 DEVMETHOD(device_resume, bwn_resume), 7482 DEVMETHOD_END 7483 }; 7484 static driver_t bwn_driver = { 7485 "bwn", 7486 bwn_methods, 7487 sizeof(struct bwn_softc) 7488 }; 7489 static devclass_t bwn_devclass; 7490 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, NULL, NULL); 7491 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); 7492 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ 7493 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ 7494 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); 7495 MODULE_VERSION(bwn, 1); 7496