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