1 /* $NetBSD: bwi.c,v 1.45 2025/10/23 21:19:25 jmcneill Exp $ */ 2 /* $OpenBSD: bwi.c,v 1.74 2008/02/25 21:13:30 mglocker Exp $ */ 3 4 /* 5 * Copyright (c) 2007 The DragonFly Project. All rights reserved. 6 * 7 * This code is derived from software contributed to The DragonFly Project 8 * by Sepherosa Ziehau <sepherosa (at) gmail.com> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 3. Neither the name of The DragonFly Project nor the names of its 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific, prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $ 38 */ 39 40 /* 41 * Broadcom AirForce BCM43xx IEEE 802.11b/g wireless network driver 42 * Generic back end 43 */ 44 45 /* [TRC: XXX Names beginning with `bwi_ieee80211_*' are those that I 46 think should be in NetBSD's generic 802.11 code, not in this 47 driver.] */ 48 49 50 #include <sys/cdefs.h> 51 __KERNEL_RCSID(0, "$NetBSD: bwi.c,v 1.45 2025/10/23 21:19:25 jmcneill Exp $"); 52 53 #include <sys/param.h> 54 #include <sys/callout.h> 55 #include <sys/device.h> 56 #include <sys/kernel.h> 57 #include <sys/malloc.h> 58 #include <sys/mbuf.h> 59 #include <sys/socket.h> 60 #include <sys/sockio.h> 61 #include <sys/sysctl.h> 62 #include <sys/systm.h> 63 #include <sys/bus.h> 64 #include <sys/intr.h> 65 #include <sys/pool.h> 66 #include <sys/workqueue.h> 67 #include <sys/mutex.h> 68 #include <sys/kmem.h> 69 70 #include <machine/endian.h> 71 72 #include <dev/firmload.h> 73 74 #include <net/if.h> 75 #include <net/if_dl.h> 76 #include <net/if_ether.h> 77 #include <net/if_media.h> 78 79 #include <net/bpf.h> 80 81 #include <net80211/ieee80211_var.h> 82 /* [TRC: XXX amrr] */ 83 #include <net80211/ieee80211_amrr.h> 84 #include <net80211/ieee80211_radiotap.h> 85 86 #include <dev/ic/bwireg.h> 87 #include <dev/ic/bwivar.h> 88 89 #ifdef BWI_DEBUG 90 int bwi_debug = 0; 91 92 #define DPRINTF(sc, dbg, fmt, ...) \ 93 do { \ 94 if ((sc)->sc_debug & (dbg)) \ 95 device_printf((sc)->sc_dev, fmt, ##__VA_ARGS__); \ 96 } while (0) 97 98 #else /* !BWI_DEBUG */ 99 100 #define DPRINTF(sc, dbg, fmt, ...) ((void)0) 101 102 #endif /* BWI_DEBUG */ 103 104 /* XXX temporary porting goop */ 105 #include <dev/pci/pcireg.h> 106 #include <dev/pci/pcidevs.h> 107 108 /* XXX does not belong here */ 109 #define IEEE80211_OFDM_PLCP_RATE_MASK 0x0000000f 110 #define IEEE80211_OFDM_PLCP_LEN_MASK 0x0001ffe0 111 112 /* 113 * Contention window (slots). [TRC: dfly/net80211/80211.h] 114 */ 115 #define IEEE80211_CW_MAX 1023 /* aCWmax */ 116 #define IEEE80211_CW_MIN_0 31 /* DS/CCK aCWmin, ERP aCWmin(0) */ 117 #define IEEE80211_CW_MIN_1 15 /* OFDM aCWmin, ERP aCWmin(1) */ 118 119 /* 120 * Slot time (microseconds). [TRC: dfly/net80211/80211.h] 121 */ 122 #define IEEE80211_DUR_SLOT 20 /* DS/CCK slottime, ERP long slottime */ 123 #define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */ 124 #define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */ 125 126 /* XXX end porting goop */ 127 128 /* MAC */ 129 struct bwi_retry_lim { 130 uint16_t shretry; 131 uint16_t shretry_fb; 132 uint16_t lgretry; 133 uint16_t lgretry_fb; 134 }; 135 136 struct bwi_clock_freq { 137 uint clkfreq_min; 138 uint clkfreq_max; 139 }; 140 141 /* XXX does not belong here */ 142 struct ieee80211_ds_plcp_hdr { 143 uint8_t i_signal; 144 uint8_t i_service; 145 uint16_t i_length; 146 uint16_t i_crc; 147 } __packed; 148 149 static void bwi_sysctlattach(struct bwi_softc *); 150 151 /* MAC */ 152 static void bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t); 153 static void bwi_hostflags_write(struct bwi_mac *, uint64_t); 154 static uint64_t bwi_hostflags_read(struct bwi_mac *); 155 static uint16_t bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t); 156 static uint32_t bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t); 157 static void bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t, 158 uint16_t); 159 static void bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t, 160 uint32_t); 161 static int bwi_mac_lateattach(struct bwi_mac *); 162 static int bwi_mac_init(struct bwi_mac *); 163 static void bwi_mac_reset(struct bwi_mac *, int); 164 static void bwi_mac_set_tpctl_11bg(struct bwi_mac *, 165 const struct bwi_tpctl *); 166 static int bwi_mac_test(struct bwi_mac *); 167 static void bwi_mac_setup_tpctl(struct bwi_mac *); 168 static void bwi_mac_dummy_xmit(struct bwi_mac *); 169 static void bwi_mac_init_tpctl_11bg(struct bwi_mac *); 170 static void bwi_mac_detach(struct bwi_mac *); 171 static int bwi_mac_fw_alloc(struct bwi_mac *); 172 static void bwi_mac_fw_free(struct bwi_mac *); 173 static int bwi_mac_fw_image_alloc(struct bwi_mac *, const char *, 174 int idx, struct bwi_fw_image *, uint8_t); 175 static void bwi_mac_fw_image_free(struct bwi_mac *, struct bwi_fw_image *); 176 static int bwi_mac_fw_load(struct bwi_mac *); 177 static int bwi_mac_gpio_init(struct bwi_mac *); 178 static int bwi_mac_gpio_fini(struct bwi_mac *); 179 static int bwi_mac_fw_load_iv(struct bwi_mac *, 180 const struct bwi_fw_image *); 181 static int bwi_mac_fw_init(struct bwi_mac *); 182 static void bwi_mac_opmode_init(struct bwi_mac *); 183 static void bwi_mac_hostflags_init(struct bwi_mac *); 184 static void bwi_mac_bss_param_init(struct bwi_mac *); 185 static void bwi_mac_set_retry_lim(struct bwi_mac *, 186 const struct bwi_retry_lim *); 187 static void bwi_mac_set_ackrates(struct bwi_mac *, 188 const struct ieee80211_rateset *); 189 static int bwi_mac_start(struct bwi_mac *); 190 static int bwi_mac_stop(struct bwi_mac *); 191 static int bwi_mac_config_ps(struct bwi_mac *); 192 static void bwi_mac_reset_hwkeys(struct bwi_mac *); 193 static void bwi_mac_shutdown(struct bwi_mac *); 194 static int bwi_mac_get_property(struct bwi_mac *); 195 static void bwi_mac_updateslot(struct bwi_mac *, int); 196 static int bwi_mac_attach(struct bwi_softc *, int, uint8_t); 197 static void bwi_mac_balance_atten(int *, int *); 198 static void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int); 199 static void bwi_mac_calibrate_txpower(struct bwi_mac *, 200 enum bwi_txpwrcb_type); 201 static void bwi_mac_lock(struct bwi_mac *); 202 static void bwi_mac_unlock(struct bwi_mac *); 203 static void bwi_mac_set_promisc(struct bwi_mac *, int); 204 205 /* PHY */ 206 static void bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t); 207 static uint16_t bwi_phy_read(struct bwi_mac *, uint16_t); 208 static int bwi_phy_attach(struct bwi_mac *); 209 static void bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t); 210 static int bwi_phy_calibrate(struct bwi_mac *); 211 static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t); 212 static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t); 213 static void bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t); 214 static int16_t bwi_nrssi_read(struct bwi_mac *, uint16_t); 215 static void bwi_phy_init_11a(struct bwi_mac *); 216 static void bwi_phy_init_11g(struct bwi_mac *); 217 static void bwi_phy_init_11b_rev2(struct bwi_mac *); 218 static void bwi_phy_init_11b_rev4(struct bwi_mac *); 219 static void bwi_phy_init_11b_rev5(struct bwi_mac *); 220 static void bwi_phy_init_11b_rev6(struct bwi_mac *); 221 static void bwi_phy_config_11g(struct bwi_mac *); 222 static void bwi_phy_config_agc(struct bwi_mac *); 223 static void bwi_set_gains(struct bwi_mac *, const struct bwi_gains *); 224 static void bwi_phy_clear_state(struct bwi_phy *); 225 226 /* RF */ 227 static int16_t bwi_nrssi_11g(struct bwi_mac *); 228 static struct bwi_rf_lo 229 *bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t); 230 static int bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *); 231 static void bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t); 232 static uint16_t bwi_rf_read(struct bwi_mac *, uint16_t); 233 static int bwi_rf_attach(struct bwi_mac *); 234 static void bwi_rf_set_chan(struct bwi_mac *, uint, int); 235 static void bwi_rf_get_gains(struct bwi_mac *); 236 static void bwi_rf_init(struct bwi_mac *); 237 static void bwi_rf_off_11a(struct bwi_mac *); 238 static void bwi_rf_off_11bg(struct bwi_mac *); 239 static void bwi_rf_off_11g_rev5(struct bwi_mac *); 240 static void bwi_rf_workaround(struct bwi_mac *, uint); 241 static struct bwi_rf_lo 242 *bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *); 243 static void bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *); 244 static void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *); 245 static int bwi_rf_gain_max_reached(struct bwi_mac *, int); 246 static uint16_t bwi_bitswap4(uint16_t); 247 static uint16_t bwi_phy812_value(struct bwi_mac *, uint16_t); 248 static void bwi_rf_init_bcm2050(struct bwi_mac *); 249 static uint16_t bwi_rf_calibval(struct bwi_mac *); 250 static int32_t _bwi_adjust_devide(int32_t, int32_t); 251 static int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]); 252 static int bwi_rf_map_txpower(struct bwi_mac *); 253 static void bwi_rf_lo_update_11g(struct bwi_mac *); 254 static uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t); 255 static uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *); 256 static uint8_t _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t); 257 static void bwi_rf_lo_measure_11g(struct bwi_mac *, 258 const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t); 259 static void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *); 260 static void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *); 261 static void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *); 262 static void bwi_rf_init_sw_nrssi_table(struct bwi_mac *); 263 static void bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t); 264 static void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *); 265 static int32_t _nrssi_threshold(const struct bwi_rf *, int32_t); 266 static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *); 267 static void bwi_rf_clear_tssi(struct bwi_mac *); 268 static void bwi_rf_clear_state(struct bwi_rf *); 269 static void bwi_rf_on_11a(struct bwi_mac *); 270 static void bwi_rf_on_11bg(struct bwi_mac *); 271 static void bwi_rf_set_ant_mode(struct bwi_mac *, int); 272 static int bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t); 273 static int bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *); 274 static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *, 275 const struct bwi_rxbuf_hdr *); 276 static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *, 277 const struct bwi_rxbuf_hdr *); 278 static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *, 279 const struct bwi_rxbuf_hdr *); 280 static uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *); 281 static void bwi_rf_lo_update_11b(struct bwi_mac *); 282 283 /* INTERFACE */ 284 static uint16_t bwi_read_sprom(struct bwi_softc *, uint16_t); 285 static void bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int, 286 int, bus_addr_t, int, int); 287 static void bwi_power_on(struct bwi_softc *, int); 288 static int bwi_power_off(struct bwi_softc *, int); 289 static int bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *, 290 struct bwi_regwin **); 291 static int bwi_regwin_select(struct bwi_softc *, int); 292 static void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *); 293 static void bwi_led_attach(struct bwi_softc *); 294 static void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state); 295 static uint16_t bwi_led_onoff(const struct bwi_led *, uint16_t, int); 296 static void bwi_led_event(struct bwi_softc *, int); 297 static void bwi_led_blink_start(struct bwi_softc *, int, int); 298 static void bwi_led_blink_next(void *); 299 static void bwi_led_blink_end(void *); 300 static int bwi_bbp_attach(struct bwi_softc *); 301 static int bwi_bus_init(struct bwi_softc *, struct bwi_mac *); 302 static void bwi_get_card_flags(struct bwi_softc *); 303 static void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *); 304 static void bwi_get_clock_freq(struct bwi_softc *, 305 struct bwi_clock_freq *); 306 static int bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode); 307 static int bwi_set_clock_delay(struct bwi_softc *); 308 static int bwi_init(struct ifnet *); 309 static void bwi_init_statechg(struct bwi_softc *, int); 310 static int bwi_ioctl(struct ifnet *, u_long, void *); 311 static void bwi_start(struct ifnet *); 312 static void bwi_watchdog(struct ifnet *); 313 static void bwi_stop(struct ifnet *, int); 314 static void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state); 315 static int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int); 316 static int bwi_newstate_sdio(struct ieee80211com *, enum ieee80211_state, 317 int); 318 static int bwi_media_change(struct ifnet *); 319 static void bwi_task(struct work *, void *); 320 /* [TRC: XXX amrr] */ 321 static void bwi_iter_func(void *, struct ieee80211_node *); 322 static void bwi_amrr_timeout(void *); 323 static void bwi_newassoc(struct ieee80211_node *, int); 324 static struct ieee80211_node * 325 bwi_node_alloc(struct ieee80211_node_table *); 326 static int bwi_pio_alloc(struct bwi_softc *); 327 static void bwi_pio_free(struct bwi_softc *); 328 static int bwi_dma_alloc(struct bwi_softc *); 329 static void bwi_dma_free(struct bwi_softc *); 330 static void bwi_ring_data_free(struct bwi_ring_data *, struct bwi_softc *); 331 static int bwi_dma_ring_alloc(struct bwi_softc *, 332 struct bwi_ring_data *, bus_size_t, uint32_t); 333 static int bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t, 334 bus_size_t); 335 static void bwi_dma_txstats_free(struct bwi_softc *); 336 static int bwi_dma_mbuf_create(struct bwi_softc *); 337 static void bwi_dma_mbuf_destroy(struct bwi_softc *, int, int); 338 static void bwi_enable_intrs(struct bwi_softc *, uint32_t); 339 static void bwi_disable_intrs(struct bwi_softc *, uint32_t); 340 static int bwi_init_tx_ring_pio(struct bwi_softc *, int); 341 static int bwi_init_rx_ring_pio(struct bwi_softc *); 342 static int bwi_init_txstats_pio(struct bwi_softc *); 343 static void bwi_setup_rx_desc_pio(struct bwi_softc *, int, bus_addr_t, 344 int); 345 static void bwi_setup_tx_desc_pio(struct bwi_softc *, 346 struct bwi_ring_data *, int, bus_addr_t, int); 347 static int bwi_init_tx_ring32(struct bwi_softc *, int); 348 static void bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t, 349 bus_addr_t, int, int); 350 static int bwi_init_rx_ring32(struct bwi_softc *); 351 static int bwi_init_txstats32(struct bwi_softc *); 352 static void bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int); 353 static void bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *, 354 int, bus_addr_t, int); 355 static int bwi_init_tx_ring64(struct bwi_softc *, int); 356 static int bwi_init_rx_ring64(struct bwi_softc *); 357 static int bwi_init_txstats64(struct bwi_softc *); 358 static void bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int); 359 static void bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *, 360 int, bus_addr_t, int); 361 static int bwi_newbuf(struct bwi_softc *, int, int); 362 static void bwi_set_addr_filter(struct bwi_softc *, uint16_t, 363 const uint8_t *); 364 static int bwi_set_chan(struct bwi_softc *, struct ieee80211_channel *); 365 static void bwi_next_scan(void *); 366 static int bwi_rxeof(struct bwi_softc *, int); 367 static int bwi_rxeof_pio(struct bwi_softc *); 368 static int bwi_rxeof32(struct bwi_softc *); 369 static int bwi_rxeof64(struct bwi_softc *); 370 static void bwi_free_txstats_pio(struct bwi_softc *); 371 static void bwi_free_rx_ring_pio(struct bwi_softc *); 372 static void bwi_free_tx_ring_pio(struct bwi_softc *, int); 373 static void bwi_reset_rx_ring32(struct bwi_softc *, uint32_t); 374 static void bwi_free_txstats32(struct bwi_softc *); 375 static void bwi_free_rx_ring32(struct bwi_softc *); 376 static void bwi_free_tx_ring32(struct bwi_softc *, int); 377 static void bwi_free_txstats64(struct bwi_softc *); 378 static void bwi_free_rx_ring64(struct bwi_softc *); 379 static void bwi_free_tx_ring64(struct bwi_softc *, int); 380 static uint8_t bwi_ieee80211_rate2plcp(uint8_t rate, enum ieee80211_phymode); 381 static uint8_t bwi_ieee80211_plcp2rate(uint8_t rate, enum ieee80211_phymode); 382 static enum bwi_ieee80211_modtype 383 bwi_ieee80211_rate2modtype(uint8_t rate); 384 static uint8_t bwi_ofdm_plcp2rate(const void *); 385 static uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *); 386 static void bwi_ofdm_plcp_header(uint32_t *, int, uint8_t); 387 static void bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int, 388 uint8_t); 389 static void bwi_plcp_header(void *, int, uint8_t); 390 static int bwi_encap(struct bwi_softc *, int, struct mbuf *, 391 struct ieee80211_node **, int); 392 static void bwi_start_tx_pio(struct bwi_softc *, uint32_t, int); 393 static void bwi_start_tx32(struct bwi_softc *, uint32_t, int); 394 static void bwi_start_tx64(struct bwi_softc *, uint32_t, int); 395 static void bwi_txeof_status_pio(struct bwi_softc *); 396 static void bwi_txeof_status32(struct bwi_softc *); 397 static void bwi_txeof_status64(struct bwi_softc *); 398 static void _bwi_txeof(struct bwi_softc *, uint16_t, uint8_t); 399 static void bwi_txeof_status(struct bwi_softc *, int); 400 static void bwi_txeof(struct bwi_softc *); 401 static int bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode); 402 static void bwi_bbp_power_off(struct bwi_softc *); 403 static int bwi_get_pwron_delay(struct bwi_softc *sc); 404 static int bwi_bus_attach(struct bwi_softc *); 405 static const char 406 *bwi_regwin_name(const struct bwi_regwin *); 407 static int bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *); 408 static uint32_t bwi_regwin_disable_bits(struct bwi_softc *); 409 static void bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *, 410 uint32_t); 411 static void bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *, 412 uint32_t); 413 static void bwi_set_bssid(struct bwi_softc *, const uint8_t *); 414 static void bwi_updateslot(struct ifnet *); 415 static void bwi_updateslot_sdio(struct ifnet *); 416 static void bwi_do_calibrate(struct bwi_softc *); 417 static void bwi_calibrate(void *); 418 static int bwi_calc_rssi(struct bwi_softc *, 419 const struct bwi_rxbuf_hdr *); 420 static uint8_t bwi_ieee80211_ack_rate(struct ieee80211_node *, uint8_t); 421 static uint16_t bwi_ieee80211_txtime(struct ieee80211com *, 422 struct ieee80211_node *, uint, uint8_t, uint32_t); 423 424 /* MAC */ 425 static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10, 12 }; 426 427 /* PHY */ 428 #define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num } 429 430 static const struct { 431 uint8_t rev; 432 void (*init)(struct bwi_mac *); 433 } bwi_sup_bphy[] = { 434 SUP_BPHY(2), 435 SUP_BPHY(4), 436 SUP_BPHY(5), 437 SUP_BPHY(6) 438 }; 439 440 #undef SUP_BPHY 441 442 #define BWI_PHYTBL_WRSSI 0x1000 443 #define BWI_PHYTBL_NOISE_SCALE 0x1400 444 #define BWI_PHYTBL_NOISE 0x1800 445 #define BWI_PHYTBL_ROTOR 0x2000 446 #define BWI_PHYTBL_DELAY 0x2400 447 #define BWI_PHYTBL_RSSI 0x4000 448 #define BWI_PHYTBL_SIGMA_SQ 0x5000 449 #define BWI_PHYTBL_WRSSI_REV1 0x5400 450 #define BWI_PHYTBL_FREQ 0x5800 451 452 static const uint16_t bwi_phy_freq_11g_rev1[] = 453 { BWI_PHY_FREQ_11G_REV1 }; 454 static const uint16_t bwi_phy_noise_11g_rev1[] = 455 { BWI_PHY_NOISE_11G_REV1 }; 456 static const uint16_t bwi_phy_noise_11g[] = 457 { BWI_PHY_NOISE_11G }; 458 static const uint32_t bwi_phy_rotor_11g_rev1[] = 459 { BWI_PHY_ROTOR_11G_REV1 }; 460 static const uint16_t bwi_phy_noise_scale_11g_rev2[] = 461 { BWI_PHY_NOISE_SCALE_11G_REV2 }; 462 static const uint16_t bwi_phy_noise_scale_11g_rev7[] = 463 { BWI_PHY_NOISE_SCALE_11G_REV7 }; 464 static const uint16_t bwi_phy_noise_scale_11g[] = 465 { BWI_PHY_NOISE_SCALE_11G }; 466 static const uint16_t bwi_phy_sigma_sq_11g_rev2[] = 467 { BWI_PHY_SIGMA_SQ_11G_REV2 }; 468 static const uint16_t bwi_phy_sigma_sq_11g_rev7[] = 469 { BWI_PHY_SIGMA_SQ_11G_REV7 }; 470 static const uint32_t bwi_phy_delay_11g_rev1[] = 471 { BWI_PHY_DELAY_11G_REV1 }; 472 473 /* RF */ 474 #define RF_LO_WRITE(mac, lo) bwi_rf_lo_write((mac), (lo)) 475 476 #define BWI_RF_2GHZ_CHAN(chan) \ 477 (ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400) 478 479 #define BWI_DEFAULT_IDLE_TSSI 52 480 481 struct rf_saveregs { 482 uint16_t phy_01; 483 uint16_t phy_03; 484 uint16_t phy_0a; 485 uint16_t phy_15; 486 uint16_t phy_2a; 487 uint16_t phy_30; 488 uint16_t phy_35; 489 uint16_t phy_60; 490 uint16_t phy_429; 491 uint16_t phy_802; 492 uint16_t phy_811; 493 uint16_t phy_812; 494 uint16_t phy_814; 495 uint16_t phy_815; 496 497 uint16_t rf_43; 498 uint16_t rf_52; 499 uint16_t rf_7a; 500 }; 501 502 #define SAVE_RF_REG(mac, regs, n) (regs)->rf_##n = RF_READ((mac), 0x##n) 503 #define RESTORE_RF_REG(mac, regs, n) RF_WRITE((mac), 0x##n, (regs)->rf_##n) 504 505 #define SAVE_PHY_REG(mac, regs, n) (regs)->phy_##n = PHY_READ((mac), 0x##n) 506 #define RESTORE_PHY_REG(mac, regs, n) PHY_WRITE((mac), 0x##n, (regs)->phy_##n) 507 508 static const int8_t bwi_txpower_map_11b[BWI_TSSI_MAX] = 509 { BWI_TXPOWER_MAP_11B }; 510 static const int8_t bwi_txpower_map_11g[BWI_TSSI_MAX] = 511 { BWI_TXPOWER_MAP_11G }; 512 513 /* INTERFACE */ 514 515 struct bwi_myaddr_bssid { 516 uint8_t myaddr[IEEE80211_ADDR_LEN]; 517 uint8_t bssid[IEEE80211_ADDR_LEN]; 518 } __packed; 519 520 /* [TRC: XXX What are these about?] */ 521 522 #define IEEE80211_DS_PLCP_SERVICE_LOCKED 0x04 523 #define IEEE80211_DS_PLCL_SERVICE_PBCC 0x08 524 #define IEEE80211_DS_PLCP_SERVICE_LENEXT5 0x20 525 #define IEEE80211_DS_PLCP_SERVICE_LENEXT6 0x40 526 #define IEEE80211_DS_PLCP_SERVICE_LENEXT7 0x80 527 528 static const struct { 529 uint16_t did_min; 530 uint16_t did_max; 531 uint16_t bbp_id; 532 } bwi_bbpid_map[] = { 533 { 0x4301, 0x4301, 0x4301 }, 534 { 0x4305, 0x4307, 0x4307 }, 535 { 0x4403, 0x4403, 0x4402 }, 536 { 0x4610, 0x4615, 0x4610 }, 537 { 0x4710, 0x4715, 0x4710 }, 538 { 0x4720, 0x4725, 0x4309 } 539 }; 540 541 static const struct { 542 uint16_t bbp_id; 543 int nregwin; 544 } bwi_regwin_count[] = { 545 { 0x4301, 5 }, 546 { 0x4306, 6 }, 547 { 0x4307, 5 }, 548 { 0x4310, 8 }, 549 { 0x4401, 3 }, 550 { 0x4402, 3 }, 551 { 0x4610, 9 }, 552 { 0x4704, 9 }, 553 { 0x4710, 9 }, 554 { 0x5365, 7 } 555 }; 556 557 #define CLKSRC(src) \ 558 [BWI_CLKSRC_ ## src] = { \ 559 .freq_min = BWI_CLKSRC_ ##src## _FMIN, \ 560 .freq_max = BWI_CLKSRC_ ##src## _FMAX \ 561 } 562 563 static const struct { 564 uint freq_min; 565 uint freq_max; 566 } bwi_clkfreq[BWI_CLKSRC_MAX] = { 567 CLKSRC(LP_OSC), 568 CLKSRC(CS_OSC), 569 CLKSRC(PCI) 570 }; 571 572 #undef CLKSRC 573 574 #define VENDOR_LED_ACT(vendor) \ 575 { \ 576 .vid = PCI_VENDOR_##vendor, \ 577 .led_act = { BWI_VENDOR_LED_ACT_##vendor } \ 578 } 579 580 static const struct { 581 uint16_t vid; 582 uint8_t led_act[BWI_LED_MAX]; 583 } bwi_vendor_led_act[] = { 584 VENDOR_LED_ACT(COMPAQ), 585 VENDOR_LED_ACT(LINKSYS) 586 }; 587 588 static const uint8_t bwi_default_led_act[BWI_LED_MAX] = 589 { BWI_VENDOR_LED_ACT_DEFAULT }; 590 591 #undef VENDOR_LED_ACT 592 593 static const struct { 594 int on_dur; 595 int off_dur; 596 } bwi_led_duration[109] = { 597 [0] = { 400, 100 }, 598 [2] = { 150, 75 }, 599 [4] = { 90, 45 }, 600 [11] = { 66, 34 }, 601 [12] = { 53, 26 }, 602 [18] = { 42, 21 }, 603 [22] = { 35, 17 }, 604 [24] = { 32, 16 }, 605 [36] = { 21, 10 }, 606 [48] = { 16, 8 }, 607 [72] = { 11, 5 }, 608 [96] = { 9, 4 }, 609 [108] = { 7, 3 } 610 }; 611 612 /* [TRC: XXX Should this be zeroed?] */ 613 614 static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN]; 615 616 /* [TRC: Derived from DragonFly's src/sys/netproto/802_11/_ieee80211.h */ 617 618 enum bwi_ieee80211_modtype { 619 IEEE80211_MODTYPE_DS = 0, /* DS/CCK modulation */ 620 IEEE80211_MODTYPE_PBCC = 1, /* PBCC modulation */ 621 IEEE80211_MODTYPE_OFDM = 2 /* OFDM modulation */ 622 }; 623 #define IEEE80211_MODTYPE_CCK IEEE80211_MODTYPE_DS 624 625 /* 626 * Setup sysctl(3) MIB, hw.bwi.* and hw.bwiN.* 627 */ 628 629 #ifdef BWI_DEBUG 630 SYSCTL_SETUP(sysctl_bwi, "sysctl bwi(4) subtree setup") 631 { 632 int rc; 633 const struct sysctlnode *rnode; 634 const struct sysctlnode *cnode; 635 636 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 637 CTLFLAG_PERMANENT, CTLTYPE_NODE, "bwi", 638 SYSCTL_DESCR("bwi global controls"), 639 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) 640 goto err; 641 642 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 643 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 644 "debug", SYSCTL_DESCR("default debug flags"), 645 NULL, 0, &bwi_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 646 goto err; 647 648 return; 649 650 err: 651 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 652 } 653 #endif /* BWI_DEBUG */ 654 655 static void 656 bwi_sysctlattach(struct bwi_softc *sc) 657 { 658 int rc; 659 const struct sysctlnode *rnode; 660 const struct sysctlnode *cnode; 661 662 struct sysctllog **clog = &sc->sc_sysctllog; 663 664 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 665 CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(sc->sc_dev), 666 SYSCTL_DESCR("bwi controls and statistics"), 667 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) 668 goto err; 669 670 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 671 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 672 "fw_version", SYSCTL_DESCR("firmware version"), 673 NULL, 0, &sc->sc_fw_version, 0, CTL_CREATE, CTL_EOL)) != 0) 674 goto err; 675 676 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 677 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 678 "dwell_time", SYSCTL_DESCR("channel dwell time during scan (msec)"), 679 NULL, 0, &sc->sc_dwell_time, 0, CTL_CREATE, CTL_EOL)) != 0) 680 goto err; 681 682 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 683 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 684 "led_idle", SYSCTL_DESCR("# ticks before LED enters idle state"), 685 NULL, 0, &sc->sc_led_idle, 0, CTL_CREATE, CTL_EOL)) != 0) 686 goto err; 687 688 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 689 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 690 "led_blink", SYSCTL_DESCR("allow LED to blink"), 691 NULL, 0, &sc->sc_led_blink, 0, CTL_CREATE, CTL_EOL)) != 0) 692 goto err; 693 694 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 695 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 696 "txpwr_calib", SYSCTL_DESCR("enable software TX power calibration"), 697 NULL, 0, &sc->sc_txpwr_calib, 0, CTL_CREATE, CTL_EOL)) != 0) 698 goto err; 699 700 #ifdef BWI_DEBUG 701 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 702 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 703 "debug", SYSCTL_DESCR("debug flags"), 704 NULL, 0, &sc->sc_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 705 goto err; 706 #endif 707 708 return; 709 710 err: 711 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 712 } 713 714 /* CODE */ 715 716 static void 717 bwi_softintr(void *arg) 718 { 719 struct bwi_softc *sc = arg; 720 struct bwi_mac *mac; 721 struct ifnet *ifp = &sc->sc_if; 722 const uint32_t intr_mask = BWI_INIT_INTRS; 723 uint32_t intr_status; 724 uint32_t txrx_intr_status[BWI_TXRX_NRING]; 725 int i, s, txrx_error, tx = 0, rx_data = -1; 726 727 if (!device_is_active(sc->sc_dev) || 728 (ifp->if_flags & IFF_RUNNING) == 0) 729 return; 730 731 for (;;) { 732 /* 733 * Get interrupt status 734 */ 735 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 736 if (intr_status == 0xffffffff) /* Not for us */ 737 goto out; 738 739 DPRINTF(sc, BWI_DBG_INTR, 740 "intr status 0x%08x mask 0x%08x -> 0x%08x\n", 741 intr_status, intr_mask, intr_status & intr_mask); 742 intr_status &= intr_mask; 743 if (intr_status == 0) { /* Nothing is interesting */ 744 goto out; 745 } 746 747 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 748 mac = (struct bwi_mac *)sc->sc_cur_regwin; 749 750 txrx_error = 0; 751 752 for (i = 0; i < BWI_TXRX_NRING; ++i) { 753 uint32_t mask; 754 755 if (BWI_TXRX_IS_RX(i)) 756 mask = BWI_TXRX_RX_INTRS; 757 else 758 mask = BWI_TXRX_TX_INTRS; 759 760 txrx_intr_status[i] = 761 CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask; 762 763 if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) { 764 aprint_error_dev(sc->sc_dev, 765 "intr fatal TX/RX (%d) error 0x%08x\n", 766 i, txrx_intr_status[i]); 767 txrx_error = 1; 768 } 769 } 770 771 /* 772 * Acknowledge interrupt 773 */ 774 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status); 775 776 for (i = 0; i < BWI_TXRX_NRING; ++i) 777 CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i), 778 txrx_intr_status[i]); 779 780 if (intr_status & BWI_INTR_PHY_TXERR) { 781 if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) { 782 aprint_error_dev(sc->sc_dev, 783 "intr PHY TX error\n"); 784 /* XXX to netisr0? */ 785 s = splnet(); 786 bwi_init_statechg(sc, 0); 787 splx(s); 788 goto out; 789 } 790 } 791 792 if (txrx_error) { 793 /* TODO: reset device */ 794 } 795 796 if (intr_status & BWI_INTR_TBTT) 797 bwi_mac_config_ps(mac); 798 799 if (intr_status & BWI_INTR_EO_ATIM) 800 aprint_normal_dev(sc->sc_dev, "EO_ATIM\n"); 801 802 if (intr_status & BWI_INTR_PMQ) { 803 for (;;) { 804 if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8) 805 == 0) 806 break; 807 } 808 CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2); 809 } 810 811 if (intr_status & BWI_INTR_NOISE) 812 aprint_normal_dev(sc->sc_dev, "intr noise\n"); 813 814 if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) { 815 rx_data = (sc->sc_rxeof)(sc); 816 } 817 818 if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) { 819 (sc->sc_txeof_status)(sc); 820 tx = 1; 821 } 822 823 if (intr_status & BWI_INTR_TX_DONE) { 824 bwi_txeof(sc); 825 tx = 1; 826 } 827 828 if (sc->sc_blink_led != NULL && sc->sc_led_blink && 829 !BWI_IS_SDIO(sc)) { 830 int evt = BWI_LED_EVENT_NONE; 831 832 if (tx && rx_data > 0) { 833 if (sc->sc_rx_rate > sc->sc_tx_rate) 834 evt = BWI_LED_EVENT_RX; 835 else 836 evt = BWI_LED_EVENT_TX; 837 } else if (tx) { 838 evt = BWI_LED_EVENT_TX; 839 } else if (rx_data > 0) { 840 evt = BWI_LED_EVENT_RX; 841 } else if (rx_data == 0) { 842 evt = BWI_LED_EVENT_POLL; 843 } 844 845 if (evt != BWI_LED_EVENT_NONE) 846 bwi_led_event(sc, evt); 847 } 848 } 849 850 out: 851 /* Re-enable interrupts */ 852 bwi_enable_intrs(sc, BWI_INIT_INTRS); 853 } 854 855 int 856 bwi_intr(void *arg) 857 { 858 struct bwi_softc *sc = arg; 859 struct ifnet *ifp = &sc->sc_if; 860 861 if (!device_is_active(sc->sc_dev) || 862 (ifp->if_flags & IFF_RUNNING) == 0) 863 return (0); 864 865 /* Disable all interrupts */ 866 bwi_disable_intrs(sc, BWI_ALL_INTRS); 867 868 if (BWI_IS_SDIO(sc)) { 869 bwi_softintr(sc); 870 } else { 871 softint_schedule(sc->sc_soft_ih); 872 } 873 874 return (1); 875 } 876 877 int 878 bwi_attach(struct bwi_softc *sc) 879 { 880 struct ieee80211com *ic = &sc->sc_ic; 881 struct ifnet *ifp = &sc->sc_if; 882 struct bwi_mac *mac; 883 struct bwi_phy *phy; 884 int s, i, error; 885 886 /* [TRC: XXX Is this necessary?] */ 887 s = splnet(); 888 889 if (BWI_IS_SDIO(sc)) { 890 error = workqueue_create(&sc->sc_taskq, 891 device_xname(sc->sc_dev), bwi_task, sc, PRI_NONE, 892 IPL_SOFTNET, 0); 893 if (error != 0) { 894 device_printf(sc->sc_dev, 895 "failed to create workqueue\n"); 896 goto fail; 897 } 898 sc->sc_freetask = pool_cache_init(sizeof(struct bwi_task), 899 0, 0, 0, "bwitask", NULL, IPL_SOFTNET, NULL, NULL, NULL); 900 pool_cache_prime(sc->sc_freetask, BWI_TASK_COUNT); 901 } else { 902 sc->sc_soft_ih = softint_establish(SOFTINT_NET, bwi_softintr, 903 sc); 904 if (sc->sc_soft_ih == NULL) { 905 error = ENXIO; 906 goto fail; 907 } 908 } 909 910 /* 911 * Initialize sysctl variables 912 */ 913 sc->sc_fw_version = BWI_FW_VERSION3; 914 sc->sc_dwell_time = 200; 915 sc->sc_led_idle = (2350 * hz) / 1000; 916 sc->sc_led_blink = 1; 917 sc->sc_txpwr_calib = 1; 918 #ifdef BWI_DEBUG 919 sc->sc_debug = bwi_debug; 920 #endif 921 922 DPRINTF(sc, BWI_DBG_ATTACH, "%s\n", __func__); 923 924 /* [TRC: XXX amrr] */ 925 /* AMRR rate control */ 926 sc->sc_amrr.amrr_min_success_threshold = 1; 927 sc->sc_amrr.amrr_max_success_threshold = 15; 928 callout_init(&sc->sc_amrr_ch, 0); 929 callout_setfunc(&sc->sc_amrr_ch, bwi_amrr_timeout, sc); 930 931 callout_init(&sc->sc_scan_ch, 0); 932 callout_setfunc(&sc->sc_scan_ch, bwi_next_scan, sc); 933 callout_init(&sc->sc_calib_ch, 0); 934 callout_setfunc(&sc->sc_calib_ch, bwi_calibrate, sc); 935 936 bwi_sysctlattach(sc); 937 938 bwi_power_on(sc, 1); 939 940 error = bwi_bbp_attach(sc); 941 if (error) 942 goto fail; 943 944 error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); 945 if (error) 946 goto fail; 947 948 if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) { 949 error = bwi_set_clock_delay(sc); 950 if (error) 951 goto fail; 952 953 error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST); 954 if (error) 955 goto fail; 956 957 error = bwi_get_pwron_delay(sc); 958 if (error) 959 goto fail; 960 } 961 962 error = bwi_bus_attach(sc); 963 if (error) 964 goto fail; 965 966 bwi_get_card_flags(sc); 967 968 bwi_led_attach(sc); 969 970 for (i = 0; i < sc->sc_nmac; ++i) { 971 struct bwi_regwin *old; 972 973 mac = &sc->sc_mac[i]; 974 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old); 975 if (error) 976 goto fail; 977 978 error = bwi_mac_lateattach(mac); 979 if (error) 980 goto fail; 981 982 error = bwi_regwin_switch(sc, old, NULL); 983 if (error) 984 goto fail; 985 } 986 987 /* 988 * XXX First MAC is known to exist 989 * TODO2 990 */ 991 mac = &sc->sc_mac[0]; 992 phy = &mac->mac_phy; 993 994 bwi_bbp_power_off(sc); 995 996 if (BWI_IS_PIO(sc)) { 997 error = bwi_pio_alloc(sc); 998 } else { 999 error = bwi_dma_alloc(sc); 1000 } 1001 if (error) 1002 goto fail; 1003 1004 /* setup interface */ 1005 ifp->if_softc = sc; 1006 ifp->if_init = bwi_init; 1007 ifp->if_ioctl = bwi_ioctl; 1008 ifp->if_start = bwi_start; 1009 ifp->if_watchdog = bwi_watchdog; 1010 ifp->if_stop = bwi_stop; 1011 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 1012 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 1013 IFQ_SET_READY(&ifp->if_snd); 1014 1015 /* Get locale */ 1016 sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO), 1017 BWI_SPROM_CARD_INFO_LOCALE); 1018 DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale); 1019 1020 /* 1021 * Setup ratesets, phytype, channels and get MAC address 1022 */ 1023 if (phy->phy_mode == IEEE80211_MODE_11B || 1024 phy->phy_mode == IEEE80211_MODE_11G) { 1025 uint16_t chan_flags; 1026 1027 ic->ic_sup_rates[IEEE80211_MODE_11B] = 1028 ieee80211_std_rateset_11b; 1029 1030 if (phy->phy_mode == IEEE80211_MODE_11B) { 1031 chan_flags = IEEE80211_CHAN_B; 1032 ic->ic_phytype = IEEE80211_T_DS; 1033 } else { 1034 chan_flags = IEEE80211_CHAN_CCK | 1035 IEEE80211_CHAN_OFDM | 1036 IEEE80211_CHAN_DYN | 1037 IEEE80211_CHAN_2GHZ; 1038 ic->ic_phytype = IEEE80211_T_OFDM; 1039 ic->ic_sup_rates[IEEE80211_MODE_11G] = 1040 ieee80211_std_rateset_11g; 1041 } 1042 1043 /* XXX depend on locale */ 1044 for (i = 1; i <= 14; ++i) { 1045 ic->ic_channels[i].ic_freq = 1046 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 1047 ic->ic_channels[i].ic_flags = chan_flags; 1048 } 1049 1050 bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_myaddr); 1051 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) { 1052 bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_myaddr); 1053 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) 1054 aprint_error_dev(sc->sc_dev, 1055 "invalid MAC address: %s\n", 1056 ether_sprintf(ic->ic_myaddr)); 1057 } 1058 } else if (phy->phy_mode == IEEE80211_MODE_11A) { 1059 /* TODO: 11A */ 1060 error = ENXIO; 1061 goto fail; 1062 } else 1063 panic("unknown phymode %d\n", phy->phy_mode); 1064 1065 ic->ic_ifp = ifp; 1066 ic->ic_caps = IEEE80211_C_SHSLOT | 1067 IEEE80211_C_SHPREAMBLE | 1068 IEEE80211_C_IBSS | 1069 IEEE80211_C_HOSTAP | 1070 IEEE80211_C_MONITOR; 1071 ic->ic_state = IEEE80211_S_INIT; 1072 ic->ic_opmode = IEEE80211_M_STA; 1073 1074 ic->ic_updateslot = BWI_IS_SDIO(sc) ? 1075 bwi_updateslot_sdio : bwi_updateslot; 1076 1077 if_initialize(ifp); 1078 ieee80211_ifattach(ic); 1079 ifp->if_percpuq = if_percpuq_create(ifp); 1080 if_register(ifp); 1081 1082 /* [TRC: XXX Not supported on NetBSD?] */ 1083 /* ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; */ 1084 1085 sc->sc_newstate = ic->ic_newstate; 1086 ic->ic_newstate = BWI_IS_SDIO(sc) ? bwi_newstate_sdio : bwi_newstate; 1087 /* [TRC: XXX amrr] */ 1088 ic->ic_newassoc = bwi_newassoc; 1089 ic->ic_node_alloc = bwi_node_alloc; 1090 1091 ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status); 1092 1093 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 1094 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, 1095 &sc->sc_drvbpf); 1096 1097 /* [TRC: XXX DragonFlyBSD rounds this up to a multiple of 1098 sizeof(uint32_t). Should we?] */ 1099 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); 1100 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 1101 sc->sc_rxtap.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT); 1102 1103 sc->sc_txtap_len = sizeof(sc->sc_txtapu); 1104 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 1105 sc->sc_txtap.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT); 1106 1107 splx(s); 1108 ieee80211_announce(ic); 1109 return (0); 1110 fail: 1111 /* [TRC: XXX DragonFlyBSD detaches the device here. Should we?] */ 1112 splx(s); 1113 return (error); 1114 } 1115 1116 void 1117 bwi_detach(struct bwi_softc *sc) 1118 { 1119 struct ifnet *ifp = &sc->sc_if; 1120 int i, s; 1121 1122 s = splnet(); 1123 1124 bwi_stop(ifp, 1); 1125 1126 bpf_detach(ifp); 1127 1128 ieee80211_ifdetach(&sc->sc_ic); 1129 if_detach(ifp); 1130 1131 for (i = 0; i < sc->sc_nmac; ++i) 1132 bwi_mac_detach(&sc->sc_mac[i]); 1133 1134 sysctl_teardown(&sc->sc_sysctllog); 1135 1136 if (sc->sc_soft_ih != NULL) 1137 softint_disestablish(sc->sc_soft_ih); 1138 1139 splx(s); 1140 1141 if (BWI_IS_PIO(sc)) { 1142 bwi_pio_free(sc); 1143 if (sc->sc_taskq != NULL) { 1144 workqueue_destroy(sc->sc_taskq); 1145 } 1146 if (sc->sc_freetask != NULL) { 1147 pool_cache_destroy(sc->sc_freetask); 1148 } 1149 } else { 1150 bwi_dma_free(sc); 1151 } 1152 } 1153 1154 /* MAC */ 1155 1156 static void 1157 bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val) 1158 { 1159 struct bwi_softc *sc = mac->mac_sc; 1160 1161 if (mac->mac_flags & BWI_MAC_F_BSWAP) 1162 val = bswap32(val); 1163 1164 CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs); 1165 CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val); 1166 } 1167 1168 static void 1169 bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags) 1170 { 1171 uint64_t val; 1172 1173 val = flags & 0xffff; 1174 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val); 1175 1176 val = (flags >> 16) & 0xffff; 1177 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val); 1178 1179 /* HI has unclear meaning, so leave it as it is */ 1180 } 1181 1182 static uint64_t 1183 bwi_hostflags_read(struct bwi_mac *mac) 1184 { 1185 uint64_t flags, val; 1186 1187 /* HI has unclear meaning, so don't touch it */ 1188 flags = 0; 1189 1190 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI); 1191 flags |= val << 16; 1192 1193 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO); 1194 flags |= val; 1195 1196 return (flags); 1197 } 1198 1199 static uint16_t 1200 bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0) 1201 { 1202 struct bwi_softc *sc = mac->mac_sc; 1203 uint32_t data_reg; 1204 int ofs; 1205 1206 data_reg = BWI_MOBJ_DATA; 1207 ofs = ofs0 / 4; 1208 1209 if (ofs0 % 4 != 0) 1210 data_reg = BWI_MOBJ_DATA_UNALIGN; 1211 1212 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 1213 return (CSR_READ_2(sc, data_reg)); 1214 } 1215 1216 static uint32_t 1217 bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0) 1218 { 1219 struct bwi_softc *sc = mac->mac_sc; 1220 int ofs; 1221 1222 ofs = ofs0 / 4; 1223 if (ofs0 % 4 != 0) { 1224 uint32_t ret; 1225 1226 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 1227 ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN); 1228 ret <<= 16; 1229 1230 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 1231 BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1)); 1232 ret |= CSR_READ_2(sc, BWI_MOBJ_DATA); 1233 1234 return (ret); 1235 } else { 1236 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 1237 return (CSR_READ_4(sc, BWI_MOBJ_DATA)); 1238 } 1239 } 1240 1241 static void 1242 bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0, 1243 uint16_t v) 1244 { 1245 struct bwi_softc *sc = mac->mac_sc; 1246 uint32_t data_reg; 1247 int ofs; 1248 1249 data_reg = BWI_MOBJ_DATA; 1250 ofs = ofs0 / 4; 1251 1252 if (ofs0 % 4 != 0) 1253 data_reg = BWI_MOBJ_DATA_UNALIGN; 1254 1255 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 1256 CSR_WRITE_2(sc, data_reg, v); 1257 } 1258 1259 static void 1260 bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0, 1261 uint32_t v) 1262 { 1263 struct bwi_softc *sc = mac->mac_sc; 1264 int ofs; 1265 1266 ofs = ofs0 / 4; 1267 if (ofs0 % 4 != 0) { 1268 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 1269 CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16); 1270 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 1271 BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1)); 1272 CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff); 1273 } else { 1274 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 1275 CSR_WRITE_4(sc, BWI_MOBJ_DATA, v); 1276 } 1277 } 1278 1279 static int 1280 bwi_mac_lateattach(struct bwi_mac *mac) 1281 { 1282 int error; 1283 1284 if (mac->mac_rev >= 5) 1285 CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */ 1286 1287 bwi_mac_reset(mac, 1); 1288 1289 error = bwi_phy_attach(mac); 1290 if (error) 1291 return (error); 1292 1293 error = bwi_rf_attach(mac); 1294 if (error) 1295 return (error); 1296 1297 /* Link 11B/G PHY, unlink 11A PHY */ 1298 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) 1299 bwi_mac_reset(mac, 0); 1300 else 1301 bwi_mac_reset(mac, 1); 1302 1303 error = bwi_mac_test(mac); 1304 if (error) 1305 return (error); 1306 1307 error = bwi_mac_get_property(mac); 1308 if (error) 1309 return (error); 1310 1311 error = bwi_rf_map_txpower(mac); 1312 if (error) 1313 return (error); 1314 1315 bwi_rf_off(mac); 1316 CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC); 1317 1318 if (BWI_IS_PIO(mac->mac_sc)) { 1319 /* Initialize RX padding data offset */ 1320 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RXPADOFF, 0); 1321 } 1322 1323 bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0); 1324 1325 return (0); 1326 } 1327 1328 static int 1329 bwi_mac_init(struct bwi_mac *mac) 1330 { 1331 struct bwi_softc *sc = mac->mac_sc; 1332 int error, i; 1333 1334 /* Clear MAC/PHY/RF states */ 1335 bwi_mac_setup_tpctl(mac); 1336 bwi_rf_clear_state(&mac->mac_rf); 1337 bwi_phy_clear_state(&mac->mac_phy); 1338 1339 /* Enable MAC and linked it to PHY */ 1340 if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin)) 1341 bwi_mac_reset(mac, 1); 1342 1343 /* Initialize backplane */ 1344 error = bwi_bus_init(sc, mac); 1345 if (error) 1346 return (error); 1347 1348 /* XXX work around for hardware bugs? */ 1349 if (sc->sc_bus_regwin.rw_rev <= 5 && 1350 sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) { 1351 CSR_SETBITS_4(sc, BWI_CONF_LO, 1352 __SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) | 1353 __SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK)); 1354 } 1355 1356 /* Calibrate PHY */ 1357 error = bwi_phy_calibrate(mac); 1358 if (error) { 1359 aprint_error_dev(sc->sc_dev, "PHY calibrate failed\n"); 1360 return (error); 1361 } 1362 1363 /* Prepare to initialize firmware */ 1364 CSR_WRITE_4(sc, BWI_MAC_STATUS, 1365 BWI_MAC_STATUS_UCODE_JUMP0 | 1366 BWI_MAC_STATUS_IHREN); 1367 1368 /* 1369 * Load and initialize firmwares 1370 */ 1371 error = bwi_mac_fw_alloc(mac); 1372 if (error) 1373 return (error); 1374 1375 error = bwi_mac_fw_load(mac); 1376 if (error) 1377 return (error); 1378 1379 error = bwi_mac_gpio_init(mac); 1380 if (error) 1381 return (error); 1382 1383 error = bwi_mac_fw_init(mac); 1384 if (error) 1385 return (error); 1386 1387 /* 1388 * Turn on RF 1389 */ 1390 bwi_rf_on(mac); 1391 1392 /* TODO: LED, hardware rf enabled is only related to LED setting */ 1393 1394 /* 1395 * Initialize PHY 1396 */ 1397 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); 1398 bwi_phy_init(mac); 1399 1400 /* TODO: interference mitigation */ 1401 1402 /* 1403 * Setup antenna mode 1404 */ 1405 bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode); 1406 1407 /* 1408 * Initialize operation mode (RX configuration) 1409 */ 1410 bwi_mac_opmode_init(mac); 1411 1412 /* XXX what's these */ 1413 if (mac->mac_rev < 3) { 1414 CSR_WRITE_2(sc, 0x60e, 0); 1415 CSR_WRITE_2(sc, 0x610, 0x8000); 1416 CSR_WRITE_2(sc, 0x604, 0); 1417 CSR_WRITE_2(sc, 0x606, 0x200); 1418 } else { 1419 CSR_WRITE_4(sc, 0x188, 0x80000000); 1420 CSR_WRITE_4(sc, 0x18c, 0x2000000); 1421 } 1422 1423 /* 1424 * Initialize TX/RX interrupts' mask 1425 */ 1426 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1); 1427 for (i = 0; i < BWI_TXRX_NRING; ++i) { 1428 uint32_t intrs; 1429 1430 if (BWI_TXRX_IS_RX(i)) 1431 intrs = BWI_TXRX_RX_INTRS; 1432 else 1433 intrs = BWI_TXRX_TX_INTRS; 1434 CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs); 1435 } 1436 1437 /* XXX what's this */ 1438 CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000); 1439 1440 /* Setup MAC power up delay */ 1441 CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay); 1442 1443 /* Set MAC regwin revision */ 1444 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev); 1445 1446 /* 1447 * Initialize host flags 1448 */ 1449 bwi_mac_hostflags_init(mac); 1450 1451 /* 1452 * Initialize BSS parameters 1453 */ 1454 bwi_mac_bss_param_init(mac); 1455 1456 /* 1457 * Initialize TX rings 1458 */ 1459 for (i = 0; i < BWI_TX_NRING; ++i) { 1460 error = (sc->sc_init_tx_ring)(sc, i); 1461 if (error) { 1462 aprint_error_dev(sc->sc_dev, 1463 "can't initialize %dth TX ring\n", i); 1464 return (error); 1465 } 1466 } 1467 1468 /* 1469 * Initialize RX ring 1470 */ 1471 error = (sc->sc_init_rx_ring)(sc); 1472 if (error) { 1473 aprint_error_dev(sc->sc_dev, "can't initialize RX ring\n"); 1474 return (error); 1475 } 1476 1477 /* 1478 * Initialize TX stats if the current MAC uses that 1479 */ 1480 if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) { 1481 error = (sc->sc_init_txstats)(sc); 1482 if (error) { 1483 aprint_error_dev(sc->sc_dev, 1484 "can't initialize TX stats ring\n"); 1485 return (error); 1486 } 1487 } 1488 1489 /* XXX what's these */ 1490 CSR_WRITE_2(sc, 0x612, 0x50); /* Force Pre-TBTT to 80? */ 1491 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50); 1492 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4); 1493 1494 mac->mac_flags |= BWI_MAC_F_INITED; 1495 1496 return (0); 1497 } 1498 1499 static void 1500 bwi_mac_reset(struct bwi_mac *mac, int link_phy) 1501 { 1502 struct bwi_softc *sc = mac->mac_sc; 1503 uint32_t flags, state_lo, status; 1504 1505 flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN; 1506 if (link_phy) 1507 flags |= BWI_STATE_LO_FLAG_PHYLNK; 1508 bwi_regwin_enable(sc, &mac->mac_regwin, flags); 1509 DELAY(2000); 1510 1511 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 1512 state_lo |= BWI_STATE_LO_GATED_CLOCK; 1513 state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST, 1514 BWI_STATE_LO_FLAGS_MASK); 1515 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 1516 /* Flush pending bus write */ 1517 CSR_READ_4(sc, BWI_STATE_LO); 1518 DELAY(1000); 1519 1520 state_lo &= ~BWI_STATE_LO_GATED_CLOCK; 1521 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 1522 /* Flush pending bus write */ 1523 CSR_READ_4(sc, BWI_STATE_LO); 1524 DELAY(1000); 1525 1526 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); 1527 1528 status = CSR_READ_4(sc, BWI_MAC_STATUS); 1529 status |= BWI_MAC_STATUS_IHREN; 1530 if (link_phy) 1531 status |= BWI_MAC_STATUS_PHYLNK; 1532 else 1533 status &= ~BWI_MAC_STATUS_PHYLNK; 1534 CSR_WRITE_4(sc, BWI_MAC_STATUS, status); 1535 1536 if (link_phy) { 1537 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT, 1538 "%s\n", "PHY is linked"); 1539 mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED; 1540 } else { 1541 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT, 1542 "%s\n", "PHY is unlinked"); 1543 mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED; 1544 } 1545 } 1546 1547 static void 1548 bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl) 1549 { 1550 struct bwi_rf *rf = &mac->mac_rf; 1551 struct bwi_tpctl *tpctl = &mac->mac_tpctl; 1552 1553 if (new_tpctl != NULL) { 1554 KASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX); 1555 KASSERT(new_tpctl->rf_atten <= 1556 (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0 1557 : BWI_RF_ATTEN_MAX1)); 1558 KASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX); 1559 1560 tpctl->bbp_atten = new_tpctl->bbp_atten; 1561 tpctl->rf_atten = new_tpctl->rf_atten; 1562 tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1; 1563 } 1564 1565 /* Set BBP attenuation */ 1566 bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten); 1567 1568 /* Set RF attenuation */ 1569 RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten); 1570 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN, 1571 tpctl->rf_atten); 1572 1573 /* Set TX power */ 1574 if (rf->rf_type == BWI_RF_T_BCM2050) { 1575 RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK, 1576 __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK)); 1577 } 1578 1579 /* Adjust RF Local Oscillator */ 1580 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G) 1581 bwi_rf_lo_adjust(mac, tpctl); 1582 } 1583 1584 static int 1585 bwi_mac_test(struct bwi_mac *mac) 1586 { 1587 struct bwi_softc *sc = mac->mac_sc; 1588 uint32_t orig_val, val; 1589 1590 #define TEST_VAL1 0xaa5555aa 1591 #define TEST_VAL2 0x55aaaa55 1592 /* Save it for later restoring */ 1593 orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0); 1594 1595 /* Test 1 */ 1596 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1); 1597 val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0); 1598 if (val != TEST_VAL1) { 1599 aprint_error_dev(sc->sc_dev, "TEST1 failed [0x%08x]\n", val); 1600 return (ENXIO); 1601 } 1602 1603 /* Test 2 */ 1604 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2); 1605 val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0); 1606 if (val != TEST_VAL2) { 1607 aprint_error_dev(sc->sc_dev, "TEST2 failed [0x%08x]\n", val); 1608 return (ENXIO); 1609 } 1610 1611 /* Restore to the original value */ 1612 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val); 1613 1614 val = CSR_READ_4(sc, BWI_MAC_STATUS); 1615 if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) { 1616 aprint_error_dev(sc->sc_dev, "%s failed, MAC status 0x%08x\n", 1617 __func__, val); 1618 return (ENXIO); 1619 } 1620 1621 val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 1622 if (val != 0) { 1623 aprint_error_dev(sc->sc_dev, "%s failed, intr status %08x\n", 1624 __func__, val); 1625 return (ENXIO); 1626 } 1627 #undef TEST_VAL2 1628 #undef TEST_VAL1 1629 1630 return (0); 1631 } 1632 1633 static void 1634 bwi_mac_setup_tpctl(struct bwi_mac *mac) 1635 { 1636 struct bwi_softc *sc = mac->mac_sc; 1637 struct bwi_rf *rf = &mac->mac_rf; 1638 struct bwi_phy *phy = &mac->mac_phy; 1639 struct bwi_tpctl *tpctl = &mac->mac_tpctl; 1640 1641 /* Calc BBP attenuation */ 1642 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6) 1643 tpctl->bbp_atten = 0; 1644 else 1645 tpctl->bbp_atten = 2; 1646 1647 /* Calc TX power CTRL1?? */ 1648 tpctl->tp_ctrl1 = 0; 1649 if (rf->rf_type == BWI_RF_T_BCM2050) { 1650 if (rf->rf_rev == 1) 1651 tpctl->tp_ctrl1 = 3; 1652 else if (rf->rf_rev < 6) 1653 tpctl->tp_ctrl1 = 2; 1654 else if (rf->rf_rev == 8) 1655 tpctl->tp_ctrl1 = 1; 1656 } 1657 1658 /* Empty TX power CTRL2?? */ 1659 tpctl->tp_ctrl2 = 0xffff; 1660 1661 /* 1662 * Calc RF attenuation 1663 */ 1664 if (phy->phy_mode == IEEE80211_MODE_11A) { 1665 tpctl->rf_atten = 0x60; 1666 goto back; 1667 } 1668 1669 if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) { 1670 tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3; 1671 goto back; 1672 } 1673 1674 tpctl->rf_atten = 5; 1675 1676 if (rf->rf_type != BWI_RF_T_BCM2050) { 1677 if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1) 1678 tpctl->rf_atten = 6; 1679 goto back; 1680 } 1681 1682 /* 1683 * NB: If we reaches here and the card is BRCM_BCM4309G, 1684 * then the card's PCI revision must >= 0x51 1685 */ 1686 1687 /* BCM2050 RF */ 1688 switch (rf->rf_rev) { 1689 case 1: 1690 if (phy->phy_mode == IEEE80211_MODE_11G) { 1691 if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc)) 1692 tpctl->rf_atten = 3; 1693 else 1694 tpctl->rf_atten = 1; 1695 } else { 1696 if (BWI_IS_BRCM_BCM4309G(sc)) 1697 tpctl->rf_atten = 7; 1698 else 1699 tpctl->rf_atten = 6; 1700 } 1701 break; 1702 case 2: 1703 if (phy->phy_mode == IEEE80211_MODE_11G) { 1704 /* 1705 * NOTE: Order of following conditions is critical 1706 */ 1707 if (BWI_IS_BRCM_BCM4309G(sc)) 1708 tpctl->rf_atten = 3; 1709 else if (BWI_IS_BRCM_BU4306(sc)) 1710 tpctl->rf_atten = 5; 1711 else if (sc->sc_bbp_id == BWI_BBPID_BCM4320) 1712 tpctl->rf_atten = 4; 1713 else 1714 tpctl->rf_atten = 3; 1715 } else { 1716 tpctl->rf_atten = 6; 1717 } 1718 break; 1719 case 4: 1720 case 5: 1721 tpctl->rf_atten = 1; 1722 break; 1723 case 8: 1724 tpctl->rf_atten = 0x1a; 1725 break; 1726 } 1727 back: 1728 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER, 1729 "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n", 1730 tpctl->bbp_atten, tpctl->rf_atten, 1731 tpctl->tp_ctrl1, tpctl->tp_ctrl2); 1732 } 1733 1734 static void 1735 bwi_mac_dummy_xmit(struct bwi_mac *mac) 1736 { 1737 #define PACKET_LEN 5 1738 static const uint32_t packet_11a[PACKET_LEN] = 1739 { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 }; 1740 static const uint32_t packet_11bg[PACKET_LEN] = 1741 { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 }; 1742 1743 struct bwi_softc *sc = mac->mac_sc; 1744 struct bwi_rf *rf = &mac->mac_rf; 1745 const uint32_t *packet; 1746 uint16_t val_50c; 1747 int wait_max, i; 1748 1749 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) { 1750 wait_max = 30; 1751 packet = packet_11a; 1752 val_50c = 1; 1753 } else { 1754 wait_max = 250; 1755 packet = packet_11bg; 1756 val_50c = 0; 1757 } 1758 1759 for (i = 0; i < PACKET_LEN; ++i) 1760 TMPLT_WRITE_4(mac, i * 4, packet[i]); 1761 1762 CSR_READ_4(sc, BWI_MAC_STATUS); /* dummy read */ 1763 1764 CSR_WRITE_2(sc, 0x568, 0); 1765 CSR_WRITE_2(sc, 0x7c0, 0); 1766 CSR_WRITE_2(sc, 0x50c, val_50c); 1767 CSR_WRITE_2(sc, 0x508, 0); 1768 CSR_WRITE_2(sc, 0x50a, 0); 1769 CSR_WRITE_2(sc, 0x54c, 0); 1770 CSR_WRITE_2(sc, 0x56a, 0x14); 1771 CSR_WRITE_2(sc, 0x568, 0x826); 1772 CSR_WRITE_2(sc, 0x500, 0); 1773 CSR_WRITE_2(sc, 0x502, 0x30); 1774 1775 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5) 1776 RF_WRITE(mac, 0x51, 0x17); 1777 1778 for (i = 0; i < wait_max; ++i) { 1779 if (CSR_READ_2(sc, 0x50e) & 0x80) 1780 break; 1781 DELAY(10); 1782 } 1783 for (i = 0; i < 10; ++i) { 1784 if (CSR_READ_2(sc, 0x50e) & 0x400) 1785 break; 1786 DELAY(10); 1787 } 1788 for (i = 0; i < 10; ++i) { 1789 if ((CSR_READ_2(sc, 0x690) & 0x100) == 0) 1790 break; 1791 DELAY(10); 1792 } 1793 1794 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5) 1795 RF_WRITE(mac, 0x51, 0x37); 1796 #undef PACKET_LEN 1797 } 1798 1799 static void 1800 bwi_mac_init_tpctl_11bg(struct bwi_mac *mac) 1801 { 1802 struct bwi_softc *sc = mac->mac_sc; 1803 struct bwi_phy *phy = &mac->mac_phy; 1804 struct bwi_rf *rf = &mac->mac_rf; 1805 struct bwi_tpctl tpctl_orig; 1806 int restore_tpctl = 0; 1807 1808 KASSERT(phy->phy_mode != IEEE80211_MODE_11A); 1809 1810 if (BWI_IS_BRCM_BU4306(sc)) 1811 return; 1812 1813 PHY_WRITE(mac, 0x28, 0x8018); 1814 CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20); 1815 1816 if (phy->phy_mode == IEEE80211_MODE_11G) { 1817 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0) 1818 return; 1819 PHY_WRITE(mac, 0x47a, 0xc111); 1820 } 1821 if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED) 1822 return; 1823 1824 if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 && 1825 rf->rf_type == BWI_RF_T_BCM2050) { 1826 RF_SETBITS(mac, 0x76, 0x84); 1827 } else { 1828 struct bwi_tpctl tpctl; 1829 1830 /* Backup original TX power control variables */ 1831 memcpy(&tpctl_orig, &mac->mac_tpctl, sizeof(tpctl_orig)); 1832 restore_tpctl = 1; 1833 1834 memcpy(&tpctl, &mac->mac_tpctl, sizeof(tpctl)); 1835 tpctl.bbp_atten = 11; 1836 tpctl.tp_ctrl1 = 0; 1837 #ifdef notyet 1838 if (rf->rf_rev >= 6 && rf->rf_rev <= 8) 1839 tpctl.rf_atten = 31; 1840 else 1841 #endif 1842 tpctl.rf_atten = 9; 1843 1844 bwi_mac_set_tpctl_11bg(mac, &tpctl); 1845 } 1846 1847 bwi_mac_dummy_xmit(mac); 1848 1849 mac->mac_flags |= BWI_MAC_F_TPCTL_INITED; 1850 rf->rf_base_tssi = PHY_READ(mac, 0x29); 1851 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER, 1852 "base tssi %d\n", rf->rf_base_tssi); 1853 1854 if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) { 1855 aprint_error_dev(sc->sc_dev, "base tssi measure failed\n"); 1856 mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR; 1857 } 1858 1859 if (restore_tpctl) 1860 bwi_mac_set_tpctl_11bg(mac, &tpctl_orig); 1861 else 1862 RF_CLRBITS(mac, 0x76, 0x84); 1863 1864 bwi_rf_clear_tssi(mac); 1865 } 1866 1867 static void 1868 bwi_mac_detach(struct bwi_mac *mac) 1869 { 1870 bwi_mac_fw_free(mac); 1871 } 1872 1873 static int 1874 bwi_mac_fw_alloc(struct bwi_mac *mac) 1875 { 1876 struct bwi_softc *sc = mac->mac_sc; 1877 int idx, error; 1878 1879 error = bwi_mac_fw_image_alloc(mac, BWI_FW_UCODE_PREFIX, 1880 mac->mac_rev >= 5 ? 5 : mac->mac_rev, &mac->mac_ucode_fwi, 1881 BWI_FW_T_UCODE); 1882 if (error) 1883 goto fail_ucode; 1884 1885 error = bwi_mac_fw_image_alloc(mac, BWI_FW_PCM_PREFIX, 1886 mac->mac_rev >= 5 ? 5 : mac->mac_rev, &mac->mac_pcm_fwi, 1887 BWI_FW_T_PCM); 1888 if (error) 1889 goto fail_pcm; 1890 1891 /* TODO: 11A */ 1892 if (mac->mac_rev == 2 || mac->mac_rev == 4) 1893 idx = 2; 1894 else if (mac->mac_rev >= 5 && mac->mac_rev <= 20) 1895 idx = 5; 1896 else { 1897 aprint_error_dev(sc->sc_dev, 1898 "no suitable IV for MAC rev %d\n", mac->mac_rev); 1899 error = ENODEV; 1900 goto fail_iv; 1901 } 1902 1903 error = bwi_mac_fw_image_alloc(mac, BWI_FW_IV_PREFIX, idx, 1904 &mac->mac_iv_fwi, BWI_FW_T_IV); 1905 if (error) 1906 goto fail_iv; 1907 1908 /* TODO: 11A */ 1909 if (mac->mac_rev == 2 || mac->mac_rev == 4 || 1910 mac->mac_rev >= 11) 1911 /* No extended IV */ 1912 goto back; 1913 else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) 1914 idx = 5; 1915 else { 1916 aprint_error_dev(sc->sc_dev, 1917 "no suitable ExtIV for MAC rev %d\n", mac->mac_rev); 1918 error = ENODEV; 1919 goto fail_iv_ext; 1920 } 1921 1922 error = bwi_mac_fw_image_alloc(mac, BWI_FW_IV_EXT_PREFIX, idx, 1923 &mac->mac_iv_ext_fwi, BWI_FW_T_IV); 1924 if (error) 1925 goto fail_iv_ext; 1926 1927 back: return (0); 1928 1929 fail_iv_ext: 1930 bwi_mac_fw_image_free(mac, &mac->mac_iv_fwi); 1931 1932 fail_iv: 1933 bwi_mac_fw_image_free(mac, &mac->mac_pcm_fwi); 1934 1935 fail_pcm: 1936 bwi_mac_fw_image_free(mac, &mac->mac_ucode_fwi); 1937 1938 fail_ucode: 1939 return (error); 1940 } 1941 1942 static void 1943 bwi_mac_fw_free(struct bwi_mac *mac) 1944 { 1945 bwi_mac_fw_image_free(mac, &mac->mac_ucode_fwi); 1946 bwi_mac_fw_image_free(mac, &mac->mac_pcm_fwi); 1947 bwi_mac_fw_image_free(mac, &mac->mac_iv_fwi); 1948 bwi_mac_fw_image_free(mac, &mac->mac_iv_ext_fwi); 1949 } 1950 1951 static int 1952 bwi_mac_fw_image_alloc(struct bwi_mac *mac, const char *prefix, int idx, 1953 struct bwi_fw_image *fwi, uint8_t fw_type) 1954 { 1955 struct bwi_softc *sc = mac->mac_sc; 1956 char *fw_name = fwi->fwi_name; 1957 size_t fw_name_size = sizeof(fwi->fwi_name); 1958 firmware_handle_t fwh; 1959 const struct bwi_fwhdr *hdr; 1960 int error; 1961 1962 /* [TRC: XXX ???] */ 1963 if (fwi->fwi_data != NULL) 1964 return (0); 1965 1966 snprintf(fw_name, fw_name_size, BWI_FW_NAME_FORMAT, sc->sc_fw_version, 1967 prefix, idx); 1968 1969 DPRINTF(sc, BWI_DBG_FIRMWARE, "opening firmware %s\n", fw_name); 1970 1971 error = firmware_open("bwi", fw_name, &fwh); 1972 if (error) { 1973 aprint_error_dev(sc->sc_dev, "firmware_open failed on %s\n", 1974 fw_name); 1975 goto fail; 1976 } 1977 1978 fwi->fwi_size = firmware_get_size(fwh); 1979 if (fwi->fwi_size < sizeof(struct bwi_fwhdr)) { 1980 aprint_error_dev(sc->sc_dev, 1981 "firmware image %s has no header\n", 1982 fw_name); 1983 error = EIO; 1984 goto fail; 1985 } 1986 1987 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 1988 "firmware image %s, size %zx\n", fw_name, fwi->fwi_size); 1989 1990 fwi->fwi_data = firmware_malloc(fwi->fwi_size); 1991 if (fwi->fwi_data == NULL) { 1992 error = ENOMEM; 1993 firmware_close(fwh); 1994 goto fail; 1995 } 1996 1997 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 1998 "firmware image %s loaded at %p\n", fw_name, fwi->fwi_data); 1999 2000 fwi->fwi_data = firmware_malloc(fwi->fwi_size); 2001 error = firmware_read(fwh, 0, fwi->fwi_data, fwi->fwi_size); 2002 firmware_close(fwh); 2003 if (error) 2004 goto free_and_fail; 2005 2006 hdr = (const struct bwi_fwhdr *)fwi->fwi_data; 2007 2008 if (fw_type != BWI_FW_T_IV) { 2009 /* 2010 * Don't verify IV's size, it has different meaning 2011 */ 2012 size_t fw_size = (size_t)be32toh(hdr->fw_size); 2013 if (fw_size != fwi->fwi_size - sizeof(*hdr)) { 2014 aprint_error_dev(sc->sc_dev, "firmware image %s" 2015 " size mismatch, fw %zx, real %zx\n", fw_name, 2016 fw_size, fwi->fwi_size - sizeof(*hdr)); 2017 goto invalid; 2018 } 2019 } 2020 2021 if (hdr->fw_type != fw_type) { 2022 aprint_error_dev(sc->sc_dev, "firmware image %s" 2023 " type mismatch, fw `%c', target `%c'\n", fw_name, 2024 hdr->fw_type, fw_type); 2025 goto invalid; 2026 } 2027 2028 if (hdr->fw_gen != BWI_FW_GEN_1) { 2029 aprint_error_dev(sc->sc_dev, "firmware image %s" 2030 " generation mismatch, fw %d, target %d\n", fw_name, 2031 hdr->fw_gen, BWI_FW_GEN_1); 2032 goto invalid; 2033 } 2034 2035 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 2036 "firmware image %s loaded successfully\n", fw_name); 2037 2038 return (0); 2039 2040 invalid: 2041 error = EINVAL; 2042 2043 free_and_fail: 2044 firmware_free(fwi->fwi_data, fwi->fwi_size); 2045 fwi->fwi_data = NULL; 2046 fwi->fwi_size = 0; 2047 2048 fail: 2049 return (error); 2050 } 2051 2052 static void 2053 bwi_mac_fw_image_free(struct bwi_mac *mac, struct bwi_fw_image *fwi) 2054 { 2055 if (fwi->fwi_data != NULL) { 2056 DPRINTF(mac->mac_sc, BWI_DBG_FIRMWARE, "freeing firmware %s\n", 2057 fwi->fwi_name); 2058 firmware_free(fwi->fwi_data, fwi->fwi_size); 2059 fwi->fwi_data = NULL; 2060 fwi->fwi_size = 0; 2061 } 2062 } 2063 2064 static int 2065 bwi_mac_fw_load(struct bwi_mac *mac) 2066 { 2067 struct bwi_softc *sc = mac->mac_sc; 2068 const uint32_t *fw; 2069 uint16_t fw_rev; 2070 size_t fw_len, i; 2071 2072 /* 2073 * Load ucode image 2074 */ 2075 fw = (const uint32_t *)(mac->mac_ucode + BWI_FWHDR_SZ); 2076 fw_len = (mac->mac_ucode_size - BWI_FWHDR_SZ) / sizeof(uint32_t); 2077 2078 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 2079 "loading ucode image at %p, length %zx\n", 2080 fw, fw_len); 2081 2082 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 2083 BWI_MOBJ_CTRL_VAL(BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0)); 2084 for (i = 0; i < fw_len; ++i) { 2085 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i])); 2086 DELAY(10); 2087 } 2088 2089 /* 2090 * Load PCM image 2091 */ 2092 fw = (const uint32_t *)(mac->mac_pcm + BWI_FWHDR_SZ); 2093 fw_len = (mac->mac_pcm_size - BWI_FWHDR_SZ) / sizeof(uint32_t); 2094 2095 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 2096 "loading PCM image at %p, length %zx\n", 2097 fw, fw_len); 2098 2099 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 2100 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea)); 2101 CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000); 2102 2103 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 2104 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb)); 2105 for (i = 0; i < fw_len; ++i) { 2106 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i])); 2107 DELAY(10); 2108 } 2109 2110 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS); 2111 CSR_WRITE_4(sc, BWI_MAC_STATUS, 2112 BWI_MAC_STATUS_UCODE_START | 2113 BWI_MAC_STATUS_IHREN | 2114 BWI_MAC_STATUS_INFRA); 2115 #define NRETRY 200 2116 for (i = 0; i < NRETRY; ++i) { 2117 uint32_t intr_status; 2118 2119 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 2120 if (intr_status == BWI_INTR_READY) 2121 break; 2122 DELAY(10); 2123 } 2124 if (i == NRETRY) { 2125 aprint_error_dev(sc->sc_dev, 2126 "timeout loading ucode & pcm firmware\n"); 2127 return (ETIMEDOUT); 2128 } 2129 #undef NRETRY 2130 2131 CSR_READ_4(sc, BWI_MAC_INTR_STATUS); /* dummy read */ 2132 2133 fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV); 2134 if (fw_rev > BWI_FW_VERSION3_REVMAX) { 2135 aprint_error_dev(sc->sc_dev, 2136 "firmware version 4 is not supported yet\n"); 2137 return (ENODEV); 2138 } 2139 2140 if (fw_rev != sc->sc_fw_rev) { 2141 aprint_normal_dev(sc->sc_dev, "firmware rev 0x%04x," 2142 " patch level 0x%04x\n", fw_rev, 2143 MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV)); 2144 sc->sc_fw_rev = fw_rev; 2145 } 2146 2147 return (0); 2148 } 2149 2150 static int 2151 bwi_mac_gpio_init(struct bwi_mac *mac) 2152 { 2153 struct bwi_softc *sc = mac->mac_sc; 2154 struct bwi_regwin *old, *gpio_rw; 2155 uint32_t filt, bits; 2156 int error; 2157 2158 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK); 2159 /* TODO: LED */ 2160 2161 CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf); 2162 2163 filt = 0x1f; 2164 bits = 0xf; 2165 if (sc->sc_bbp_id == BWI_BBPID_BCM4301) { 2166 filt |= 0x60; 2167 bits |= 0x60; 2168 } 2169 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) { 2170 CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200); 2171 filt |= 0x200; 2172 bits |= 0x200; 2173 } 2174 2175 gpio_rw = BWI_GPIO_REGWIN(sc); 2176 error = bwi_regwin_switch(sc, gpio_rw, &old); 2177 if (error) 2178 return (error); 2179 2180 CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits); 2181 2182 return (bwi_regwin_switch(sc, old, NULL)); 2183 } 2184 2185 static int 2186 bwi_mac_gpio_fini(struct bwi_mac *mac) 2187 { 2188 struct bwi_softc *sc = mac->mac_sc; 2189 struct bwi_regwin *old, *gpio_rw; 2190 int error; 2191 2192 gpio_rw = BWI_GPIO_REGWIN(sc); 2193 error = bwi_regwin_switch(sc, gpio_rw, &old); 2194 if (error) 2195 return (error); 2196 2197 CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0); 2198 2199 return (bwi_regwin_switch(sc, old, NULL)); 2200 } 2201 2202 static int 2203 bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct bwi_fw_image *fwi) 2204 { 2205 struct bwi_softc *sc = mac->mac_sc; 2206 const struct bwi_fwhdr *hdr; 2207 const struct bwi_fw_iv *iv; 2208 size_t iv_img_size; 2209 int n, i; 2210 2211 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 2212 "loading %s at %p\n", fwi->fwi_name, fwi->fwi_data); 2213 2214 /* Get the number of IVs in the IV image */ 2215 hdr = (const struct bwi_fwhdr *)fwi->fwi_data; 2216 n = be32toh(hdr->fw_iv_cnt); 2217 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 2218 "IV count %d\n", n); 2219 2220 /* Calculate the IV image size, for later sanity check */ 2221 iv_img_size = fwi->fwi_size - sizeof(*hdr); 2222 2223 /* Locate the first IV */ 2224 iv = (const struct bwi_fw_iv *)(fwi->fwi_data + sizeof(*hdr)); 2225 2226 for (i = 0; i < n; ++i) { 2227 uint16_t iv_ofs, ofs; 2228 int sz = 0; 2229 2230 if (iv_img_size < sizeof(iv->iv_ofs)) { 2231 aprint_error_dev(sc->sc_dev, 2232 "invalid IV image, ofs\n"); 2233 return (EINVAL); 2234 } 2235 iv_img_size -= sizeof(iv->iv_ofs); 2236 sz += sizeof(iv->iv_ofs); 2237 2238 iv_ofs = be16toh(iv->iv_ofs); 2239 2240 ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK); 2241 if (ofs >= 0x1000) { 2242 aprint_error_dev(sc->sc_dev, "invalid ofs (0x%04x) " 2243 "for %dth iv\n", ofs, i); 2244 return (EINVAL); 2245 } 2246 2247 if (iv_ofs & BWI_FW_IV_IS_32BIT) { 2248 uint32_t val32; 2249 2250 if (iv_img_size < sizeof(iv->iv_val.val32)) { 2251 aprint_error_dev(sc->sc_dev, 2252 "invalid IV image, val32\n"); 2253 return (EINVAL); 2254 } 2255 iv_img_size -= sizeof(iv->iv_val.val32); 2256 sz += sizeof(iv->iv_val.val32); 2257 2258 val32 = be32toh(iv->iv_val.val32); 2259 CSR_WRITE_4(sc, ofs, val32); 2260 } else { 2261 uint16_t val16; 2262 2263 if (iv_img_size < sizeof(iv->iv_val.val16)) { 2264 aprint_error_dev(sc->sc_dev, 2265 "invalid IV image, val16\n"); 2266 return (EINVAL); 2267 } 2268 iv_img_size -= sizeof(iv->iv_val.val16); 2269 sz += sizeof(iv->iv_val.val16); 2270 2271 val16 = be16toh(iv->iv_val.val16); 2272 CSR_WRITE_2(sc, ofs, val16); 2273 } 2274 2275 iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz); 2276 } 2277 2278 if (iv_img_size != 0) { 2279 aprint_error_dev(sc->sc_dev, 2280 "invalid IV image, size left %zx\n", iv_img_size); 2281 return (EINVAL); 2282 } 2283 2284 return (0); 2285 } 2286 2287 static int 2288 bwi_mac_fw_init(struct bwi_mac *mac) 2289 { 2290 struct bwi_softc *sc = mac->mac_sc; 2291 int error; 2292 2293 error = bwi_mac_fw_load_iv(mac, &mac->mac_iv_fwi); 2294 if (error) { 2295 aprint_error_dev(sc->sc_dev, "load IV failed\n"); 2296 return (error); 2297 } 2298 2299 if (mac->mac_iv_ext != NULL) { 2300 error = bwi_mac_fw_load_iv(mac, &mac->mac_iv_ext_fwi); 2301 if (error) 2302 aprint_error_dev(sc->sc_dev, "load ExtIV failed\n"); 2303 } 2304 2305 return (error); 2306 } 2307 2308 static void 2309 bwi_mac_opmode_init(struct bwi_mac *mac) 2310 { 2311 struct bwi_softc *sc = mac->mac_sc; 2312 struct ieee80211com *ic = &sc->sc_ic; 2313 uint32_t mac_status; 2314 uint16_t pre_tbtt; 2315 2316 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA); 2317 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA); 2318 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN); 2319 2320 /* Set probe resp timeout to infinite */ 2321 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0); 2322 2323 /* 2324 * TODO: factor out following part 2325 */ 2326 2327 mac_status = CSR_READ_4(sc, BWI_MAC_STATUS); 2328 mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP | 2329 BWI_MAC_STATUS_PASS_CTL | 2330 BWI_MAC_STATUS_PASS_BADPLCP | 2331 BWI_MAC_STATUS_PASS_BADFCS | 2332 BWI_MAC_STATUS_PROMISC); 2333 mac_status |= BWI_MAC_STATUS_INFRA; 2334 2335 /* Always turn on PROMISC on old hardware */ 2336 if (mac->mac_rev < 5) 2337 mac_status |= BWI_MAC_STATUS_PROMISC; 2338 2339 switch (ic->ic_opmode) { 2340 case IEEE80211_M_IBSS: 2341 mac_status &= ~BWI_MAC_STATUS_INFRA; 2342 break; 2343 case IEEE80211_M_HOSTAP: 2344 mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP; 2345 break; 2346 case IEEE80211_M_MONITOR: 2347 #if 0 2348 /* Do you want data from your microwave oven? */ 2349 mac_status |= BWI_MAC_STATUS_PASS_CTL | 2350 BWI_MAC_STATUS_PASS_BADPLCP | 2351 BWI_MAC_STATUS_PASS_BADFCS; 2352 #else 2353 mac_status |= BWI_MAC_STATUS_PASS_CTL; 2354 #endif 2355 /* Promisc? */ 2356 break; 2357 default: 2358 break; 2359 } 2360 2361 if (sc->sc_if.if_flags & IFF_PROMISC) 2362 mac_status |= BWI_MAC_STATUS_PROMISC; 2363 2364 CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status); 2365 2366 if (ic->ic_opmode != IEEE80211_M_IBSS && 2367 ic->ic_opmode != IEEE80211_M_HOSTAP) { 2368 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3) 2369 pre_tbtt = 100; 2370 else 2371 pre_tbtt = 50; 2372 } else 2373 pre_tbtt = 2; 2374 CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt); 2375 } 2376 2377 static void 2378 bwi_mac_hostflags_init(struct bwi_mac *mac) 2379 { 2380 struct bwi_softc *sc = mac->mac_sc; 2381 struct bwi_phy *phy = &mac->mac_phy; 2382 struct bwi_rf *rf = &mac->mac_rf; 2383 uint64_t host_flags; 2384 2385 if (phy->phy_mode == IEEE80211_MODE_11A) 2386 return; 2387 2388 host_flags = HFLAGS_READ(mac); 2389 host_flags |= BWI_HFLAG_SYM_WA; 2390 2391 if (phy->phy_mode == IEEE80211_MODE_11G) { 2392 if (phy->phy_rev == 1) 2393 host_flags |= BWI_HFLAG_GDC_WA; 2394 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 2395 host_flags |= BWI_HFLAG_OFDM_PA; 2396 } else if (phy->phy_mode == IEEE80211_MODE_11B) { 2397 if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050) 2398 host_flags &= ~BWI_HFLAG_GDC_WA; 2399 } else { 2400 panic("unknown PHY mode %u\n", phy->phy_mode); 2401 } 2402 2403 HFLAGS_WRITE(mac, host_flags); 2404 } 2405 2406 static void 2407 bwi_mac_bss_param_init(struct bwi_mac *mac) 2408 { 2409 struct bwi_softc *sc = mac->mac_sc; 2410 struct bwi_phy *phy = &mac->mac_phy; 2411 struct bwi_retry_lim lim; 2412 uint16_t cw_min; 2413 2414 /* 2415 * Set short/long retry limits 2416 */ 2417 memset(&lim, 0, sizeof(lim)); 2418 lim.shretry = BWI_SHRETRY; 2419 lim.shretry_fb = BWI_SHRETRY_FB; 2420 lim.lgretry = BWI_LGRETRY; 2421 lim.lgretry_fb = BWI_LGRETRY_FB; 2422 bwi_mac_set_retry_lim(mac, &lim); 2423 2424 /* 2425 * Implicitly prevent firmware from sending probe response 2426 * by setting its "probe response timeout" to 1us. 2427 */ 2428 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1); 2429 2430 /* 2431 * XXX MAC level acknowledge and CW min/max should depend 2432 * on the char rateset of the IBSS/BSS to join. 2433 */ 2434 2435 /* 2436 * Set MAC level acknowledge rates 2437 */ 2438 bwi_mac_set_ackrates(mac, &sc->sc_ic.ic_sup_rates[phy->phy_mode]); 2439 2440 /* 2441 * Set CW min 2442 */ 2443 if (phy->phy_mode == IEEE80211_MODE_11B) 2444 cw_min = IEEE80211_CW_MIN_0; 2445 else 2446 cw_min = IEEE80211_CW_MIN_1; 2447 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min); 2448 2449 /* 2450 * Set CW max 2451 */ 2452 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX, 2453 IEEE80211_CW_MAX); 2454 } 2455 2456 static void 2457 bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim) 2458 { 2459 /* Short/Long retry limit */ 2460 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY, 2461 lim->shretry); 2462 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY, 2463 lim->lgretry); 2464 2465 /* Short/Long retry fallback limit */ 2466 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB, 2467 lim->shretry_fb); 2468 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB, 2469 lim->lgretry_fb); 2470 } 2471 2472 static void 2473 bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs) 2474 { 2475 int i; 2476 2477 /* XXX not standard conforming */ 2478 for (i = 0; i < rs->rs_nrates; ++i) { 2479 enum bwi_ieee80211_modtype modtype; 2480 uint16_t ofs; 2481 2482 modtype = bwi_ieee80211_rate2modtype(rs->rs_rates[i]); 2483 switch (modtype) { 2484 case IEEE80211_MODTYPE_DS: 2485 ofs = 0x4c0; 2486 ofs += (bwi_ieee80211_rate2plcp(rs->rs_rates[i], 2487 IEEE80211_MODE_11B) & 0xf) * 2; 2488 break; 2489 case IEEE80211_MODTYPE_OFDM: 2490 ofs = 0x480; 2491 ofs += (bwi_ieee80211_rate2plcp(rs->rs_rates[i], 2492 IEEE80211_MODE_11G) & 0xf) * 2; 2493 break; 2494 default: 2495 panic("unsupported modtype %u\n", modtype); 2496 } 2497 2498 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20, 2499 MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs)); 2500 } 2501 } 2502 2503 static int 2504 bwi_mac_start(struct bwi_mac *mac) 2505 { 2506 struct bwi_softc *sc = mac->mac_sc; 2507 2508 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE); 2509 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY); 2510 2511 /* Flush pending bus writes */ 2512 CSR_READ_4(sc, BWI_MAC_STATUS); 2513 CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 2514 2515 return (bwi_mac_config_ps(mac)); 2516 } 2517 2518 static int 2519 bwi_mac_stop(struct bwi_mac *mac) 2520 { 2521 struct bwi_softc *sc = mac->mac_sc; 2522 int error, i; 2523 2524 error = bwi_mac_config_ps(mac); 2525 if (error) 2526 return (error); 2527 2528 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE); 2529 2530 /* Flush pending bus write */ 2531 CSR_READ_4(sc, BWI_MAC_STATUS); 2532 2533 #define NRETRY 10000 2534 for (i = 0; i < NRETRY; ++i) { 2535 if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY) 2536 break; 2537 DELAY(1); 2538 } 2539 if (i == NRETRY) { 2540 aprint_error_dev(sc->sc_dev, "can't stop MAC\n"); 2541 return (ETIMEDOUT); 2542 } 2543 #undef NRETRY 2544 2545 return (0); 2546 } 2547 2548 static int 2549 bwi_mac_config_ps(struct bwi_mac *mac) 2550 { 2551 struct bwi_softc *sc = mac->mac_sc; 2552 uint32_t status; 2553 2554 status = CSR_READ_4(sc, BWI_MAC_STATUS); 2555 2556 status &= ~BWI_MAC_STATUS_HW_PS; 2557 status |= BWI_MAC_STATUS_WAKEUP; 2558 CSR_WRITE_4(sc, BWI_MAC_STATUS, status); 2559 2560 /* Flush pending bus write */ 2561 CSR_READ_4(sc, BWI_MAC_STATUS); 2562 2563 if (mac->mac_rev >= 5) { 2564 int i; 2565 2566 #define NRETRY 100 2567 for (i = 0; i < NRETRY; ++i) { 2568 if (MOBJ_READ_2(mac, BWI_COMM_MOBJ, 2569 BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS) 2570 break; 2571 DELAY(10); 2572 } 2573 if (i == NRETRY) { 2574 aprint_error_dev(sc->sc_dev, "config PS failed\n"); 2575 return (ETIMEDOUT); 2576 } 2577 #undef NRETRY 2578 } 2579 return (0); 2580 } 2581 2582 static void 2583 bwi_mac_reset_hwkeys(struct bwi_mac *mac) 2584 { 2585 /* TODO: firmware crypto */ 2586 MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS); 2587 } 2588 2589 static void 2590 bwi_mac_shutdown(struct bwi_mac *mac) 2591 { 2592 struct bwi_softc *sc = mac->mac_sc; 2593 int i; 2594 2595 if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) 2596 (sc->sc_free_txstats)(sc); 2597 2598 (sc->sc_free_rx_ring)(sc); 2599 2600 for (i = 0; i < BWI_TX_NRING; ++i) 2601 (sc->sc_free_tx_ring)(sc, i); 2602 2603 bwi_rf_off(mac); 2604 2605 /* TODO: LED */ 2606 2607 bwi_mac_gpio_fini(mac); 2608 2609 bwi_rf_off(mac); /* XXX again */ 2610 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC); 2611 bwi_regwin_disable(sc, &mac->mac_regwin, 0); 2612 2613 mac->mac_flags &= ~BWI_MAC_F_INITED; 2614 } 2615 2616 static int 2617 bwi_mac_get_property(struct bwi_mac *mac) 2618 { 2619 struct bwi_softc *sc = mac->mac_sc; 2620 enum bwi_bus_space old_bus_space; 2621 uint32_t val; 2622 2623 /* 2624 * Byte swap 2625 */ 2626 val = CSR_READ_4(sc, BWI_MAC_STATUS); 2627 if (BWI_IS_PIO(sc) && (val & BWI_MAC_STATUS_BSWAP)) { 2628 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "disable byte swap\n"); 2629 val &= ~BWI_MAC_STATUS_BSWAP; 2630 CSR_WRITE_4(sc, BWI_MAC_STATUS, val); 2631 val = CSR_READ_4(sc, BWI_MAC_STATUS); 2632 } 2633 if (val & BWI_MAC_STATUS_BSWAP) { 2634 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "need byte swap\n"); 2635 mac->mac_flags |= BWI_MAC_F_BSWAP; 2636 } 2637 2638 /* 2639 * DMA address space 2640 */ 2641 old_bus_space = sc->sc_bus_space; 2642 2643 val = CSR_READ_4(sc, BWI_STATE_HI); 2644 if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) & 2645 BWI_STATE_HI_FLAG_64BIT) { 2646 /* 64bit address */ 2647 sc->sc_bus_space = BWI_BUS_SPACE_64BIT; 2648 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "64bit bus space\n"); 2649 } else { 2650 uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL; 2651 2652 CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK); 2653 if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) { 2654 /* 32bit address */ 2655 sc->sc_bus_space = BWI_BUS_SPACE_32BIT; 2656 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, 2657 "32bit bus space\n"); 2658 } else { 2659 /* 30bit address */ 2660 sc->sc_bus_space = BWI_BUS_SPACE_30BIT; 2661 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, 2662 "30bit bus space\n"); 2663 } 2664 } 2665 2666 if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) { 2667 aprint_error_dev(sc->sc_dev, "MACs bus space mismatch!\n"); 2668 return (ENXIO); 2669 } 2670 2671 return (0); 2672 } 2673 2674 static void 2675 bwi_mac_updateslot(struct bwi_mac *mac, int shslot) 2676 { 2677 uint16_t slot_time; 2678 2679 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) 2680 return; 2681 2682 if (shslot) 2683 slot_time = IEEE80211_DUR_SHSLOT; 2684 else 2685 slot_time = IEEE80211_DUR_SLOT; 2686 2687 CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME, 2688 slot_time + BWI_MAC_SLOTTIME_ADJUST); 2689 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time); 2690 } 2691 2692 static int 2693 bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev) 2694 { 2695 struct bwi_mac *mac; 2696 int i; 2697 2698 KASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0); 2699 2700 if (sc->sc_nmac == BWI_MAC_MAX) { 2701 aprint_error_dev(sc->sc_dev, "too many MACs\n"); 2702 return (0); 2703 } 2704 2705 /* 2706 * More than one MAC is only supported by BCM4309 2707 */ 2708 if (sc->sc_nmac != 0 && 2709 sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM4309) { 2710 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, 2711 "ignore %dth MAC\n", sc->sc_nmac); 2712 return (0); 2713 } 2714 2715 mac = &sc->sc_mac[sc->sc_nmac]; 2716 2717 /* XXX will this happen? */ 2718 if (BWI_REGWIN_EXIST(&mac->mac_regwin)) { 2719 aprint_error_dev(sc->sc_dev, "%dth MAC already attached\n", 2720 sc->sc_nmac); 2721 return (0); 2722 } 2723 2724 /* 2725 * Test whether the revision of this MAC is supported 2726 */ 2727 for (i = 0; i < __arraycount(bwi_sup_macrev); ++i) { 2728 if (bwi_sup_macrev[i] == rev) 2729 break; 2730 } 2731 if (i == __arraycount(bwi_sup_macrev)) { 2732 aprint_error_dev(sc->sc_dev, "MAC rev %u is not supported\n", 2733 rev); 2734 return (ENXIO); 2735 } 2736 2737 BWI_CREATE_MAC(mac, sc, id, rev); 2738 sc->sc_nmac++; 2739 2740 if (mac->mac_rev < 5) { 2741 mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS; 2742 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "has TX stats\n"); 2743 } else { 2744 mac->mac_flags |= BWI_MAC_F_PHYE_RESET; 2745 } 2746 2747 aprint_normal_dev(sc->sc_dev, "MAC: rev %u\n", rev); 2748 return (0); 2749 } 2750 2751 static void 2752 bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0) 2753 { 2754 int bbp_atten, rf_atten, rf_atten_lim = -1; 2755 2756 bbp_atten = *bbp_atten0; 2757 rf_atten = *rf_atten0; 2758 2759 /* 2760 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times 2761 * as much as BBP attenuation, so we try our best to keep RF 2762 * attenuation within range. BBP attenuation will be clamped 2763 * later if it is out of range during balancing. 2764 * 2765 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit. 2766 */ 2767 2768 /* 2769 * Use BBP attenuation to balance RF attenuation 2770 */ 2771 if (rf_atten < 0) 2772 rf_atten_lim = 0; 2773 else if (rf_atten > BWI_RF_ATTEN_MAX0) 2774 rf_atten_lim = BWI_RF_ATTEN_MAX0; 2775 2776 if (rf_atten_lim >= 0) { 2777 bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim)); 2778 rf_atten = rf_atten_lim; 2779 } 2780 2781 /* 2782 * If possible, use RF attenuation to balance BBP attenuation 2783 * NOTE: RF attenuation is still kept within range. 2784 */ 2785 while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) { 2786 bbp_atten -= BWI_RF_ATTEN_FACTOR; 2787 ++rf_atten; 2788 } 2789 while (rf_atten > 0 && bbp_atten < 0) { 2790 bbp_atten += BWI_RF_ATTEN_FACTOR; 2791 --rf_atten; 2792 } 2793 2794 /* RF attenuation MUST be within range */ 2795 KASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0); 2796 2797 /* 2798 * Clamp BBP attenuation 2799 */ 2800 if (bbp_atten < 0) 2801 bbp_atten = 0; 2802 else if (bbp_atten > BWI_BBP_ATTEN_MAX) 2803 bbp_atten = BWI_BBP_ATTEN_MAX; 2804 2805 *rf_atten0 = rf_atten; 2806 *bbp_atten0 = bbp_atten; 2807 } 2808 2809 static void 2810 bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj) 2811 { 2812 struct bwi_softc *sc = mac->mac_sc; 2813 struct bwi_rf *rf = &mac->mac_rf; 2814 struct bwi_tpctl tpctl; 2815 int bbp_atten, rf_atten, tp_ctrl1; 2816 2817 memcpy(&tpctl, &mac->mac_tpctl, sizeof(tpctl)); 2818 2819 /* NOTE: Use signed value to do calulation */ 2820 bbp_atten = tpctl.bbp_atten; 2821 rf_atten = tpctl.rf_atten; 2822 tp_ctrl1 = tpctl.tp_ctrl1; 2823 2824 bbp_atten += bbp_atten_adj; 2825 rf_atten += rf_atten_adj; 2826 2827 bwi_mac_balance_atten(&bbp_atten, &rf_atten); 2828 2829 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) { 2830 if (rf_atten <= 1) { 2831 if (tp_ctrl1 == 0) { 2832 tp_ctrl1 = 3; 2833 bbp_atten += 2; 2834 rf_atten += 2; 2835 } else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) { 2836 bbp_atten += 2837 (BWI_RF_ATTEN_FACTOR * (rf_atten - 2)); 2838 rf_atten = 2; 2839 } 2840 } else if (rf_atten > 4 && tp_ctrl1 != 0) { 2841 tp_ctrl1 = 0; 2842 if (bbp_atten < 3) { 2843 bbp_atten += 2; 2844 rf_atten -= 3; 2845 } else { 2846 bbp_atten -= 2; 2847 rf_atten -= 2; 2848 } 2849 } 2850 bwi_mac_balance_atten(&bbp_atten, &rf_atten); 2851 } 2852 2853 tpctl.bbp_atten = bbp_atten; 2854 tpctl.rf_atten = rf_atten; 2855 tpctl.tp_ctrl1 = tp_ctrl1; 2856 2857 bwi_mac_lock(mac); 2858 bwi_mac_set_tpctl_11bg(mac, &tpctl); 2859 bwi_mac_unlock(mac); 2860 } 2861 2862 /* 2863 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower 2864 */ 2865 static void 2866 bwi_mac_calibrate_txpower(struct bwi_mac *mac, enum bwi_txpwrcb_type type) 2867 { 2868 struct bwi_softc *sc = mac->mac_sc; 2869 struct bwi_rf *rf = &mac->mac_rf; 2870 int8_t tssi[4], tssi_avg, cur_txpwr; 2871 int error, i, ofdm_tssi; 2872 int txpwr_diff, rf_atten_adj, bbp_atten_adj; 2873 2874 if (!sc->sc_txpwr_calib) 2875 return; 2876 2877 if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) { 2878 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, 2879 "tpctl error happened, can't set txpower\n"); 2880 return; 2881 } 2882 2883 if (BWI_IS_BRCM_BU4306(sc)) { 2884 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, 2885 "BU4306, can't set txpower\n"); 2886 return; 2887 } 2888 2889 /* 2890 * Save latest TSSI and reset the related memory objects 2891 */ 2892 ofdm_tssi = 0; 2893 error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS); 2894 if (error) { 2895 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "no DS tssi\n"); 2896 2897 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) { 2898 if (type == BWI_TXPWR_FORCE) { 2899 rf_atten_adj = 0; 2900 bbp_atten_adj = 1; 2901 goto calib; 2902 } else { 2903 return; 2904 } 2905 } 2906 2907 error = bwi_rf_get_latest_tssi(mac, tssi, 2908 BWI_COMM_MOBJ_TSSI_OFDM); 2909 if (error) { 2910 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, 2911 "no OFDM tssi\n"); 2912 if (type == BWI_TXPWR_FORCE) { 2913 rf_atten_adj = 0; 2914 bbp_atten_adj = 1; 2915 goto calib; 2916 } else { 2917 return; 2918 } 2919 } 2920 2921 for (i = 0; i < 4; ++i) { 2922 tssi[i] += 0x20; 2923 tssi[i] &= 0x3f; 2924 } 2925 ofdm_tssi = 1; 2926 } 2927 bwi_rf_clear_tssi(mac); 2928 2929 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, 2930 "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n", 2931 tssi[0], tssi[1], tssi[2], tssi[3]); 2932 2933 /* 2934 * Calculate RF/BBP attenuation adjustment based on 2935 * the difference between desired TX power and sampled 2936 * TX power. 2937 */ 2938 /* +8 == "each incremented by 1/2" */ 2939 tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4; 2940 if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS)) 2941 tssi_avg -= 13; 2942 2943 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "tssi avg %d\n", tssi_avg); 2944 2945 error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr); 2946 if (error) 2947 return; 2948 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "current txpower %d\n", 2949 cur_txpwr); 2950 2951 txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */ 2952 2953 rf_atten_adj = -howmany(txpwr_diff, 8); 2954 2955 if (type == BWI_TXPWR_INIT) { 2956 /* 2957 * Move toward EEPROM max TX power as fast as we can 2958 */ 2959 bbp_atten_adj = -txpwr_diff; 2960 } else { 2961 bbp_atten_adj = -(txpwr_diff / 2); 2962 } 2963 bbp_atten_adj -= (BWI_RF_ATTEN_FACTOR * rf_atten_adj); 2964 2965 if (rf_atten_adj == 0 && bbp_atten_adj == 0) { 2966 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n", 2967 "no need to adjust RF/BBP attenuation"); 2968 /* TODO: LO */ 2969 return; 2970 } 2971 2972 calib: 2973 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, 2974 "rf atten adjust %d, bbp atten adjust %d\n", 2975 rf_atten_adj, bbp_atten_adj); 2976 bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj); 2977 /* TODO: LO */ 2978 } 2979 2980 static void 2981 bwi_mac_lock(struct bwi_mac *mac) 2982 { 2983 struct bwi_softc *sc = mac->mac_sc; 2984 struct ieee80211com *ic = &sc->sc_ic; 2985 2986 KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0); 2987 2988 if (mac->mac_rev < 3) 2989 bwi_mac_stop(mac); 2990 else if (ic->ic_opmode != IEEE80211_M_HOSTAP) 2991 bwi_mac_config_ps(mac); 2992 2993 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK); 2994 2995 /* Flush pending bus write */ 2996 CSR_READ_4(sc, BWI_MAC_STATUS); 2997 DELAY(10); 2998 2999 mac->mac_flags |= BWI_MAC_F_LOCKED; 3000 } 3001 3002 static void 3003 bwi_mac_unlock(struct bwi_mac *mac) 3004 { 3005 struct bwi_softc *sc = mac->mac_sc; 3006 struct ieee80211com *ic = &sc->sc_ic; 3007 3008 KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED); 3009 3010 CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */ 3011 3012 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK); 3013 3014 if (mac->mac_rev < 3) 3015 bwi_mac_start(mac); 3016 else if (ic->ic_opmode != IEEE80211_M_HOSTAP) 3017 bwi_mac_config_ps(mac); 3018 3019 mac->mac_flags &= ~BWI_MAC_F_LOCKED; 3020 } 3021 3022 static void 3023 bwi_mac_set_promisc(struct bwi_mac *mac, int promisc) 3024 { 3025 struct bwi_softc *sc = mac->mac_sc; 3026 3027 if (mac->mac_rev < 5) /* Promisc is always on */ 3028 return; 3029 3030 if (promisc) 3031 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC); 3032 else 3033 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC); 3034 } 3035 3036 /* PHY */ 3037 3038 static void 3039 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data) 3040 { 3041 struct bwi_softc *sc = mac->mac_sc; 3042 3043 /* TODO: 11A */ 3044 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl); 3045 CSR_WRITE_2(sc, BWI_PHY_DATA, data); 3046 } 3047 3048 static uint16_t 3049 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl) 3050 { 3051 struct bwi_softc *sc = mac->mac_sc; 3052 3053 /* TODO: 11A */ 3054 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl); 3055 return (CSR_READ_2(sc, BWI_PHY_DATA)); 3056 } 3057 3058 static int 3059 bwi_phy_attach(struct bwi_mac *mac) 3060 { 3061 struct bwi_softc *sc = mac->mac_sc; 3062 struct bwi_phy *phy = &mac->mac_phy; 3063 uint8_t phyrev, phytype, phyver; 3064 uint16_t val; 3065 int i; 3066 3067 /* Get PHY type/revision/version */ 3068 val = CSR_READ_2(sc, BWI_PHYINFO); 3069 phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK); 3070 phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK); 3071 phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK); 3072 aprint_normal_dev(sc->sc_dev, "PHY type %d, rev %d, ver %d\n", 3073 phytype, phyrev, phyver); 3074 3075 /* 3076 * Verify whether the revision of the PHY type is supported 3077 * Convert PHY type to ieee80211_phymode 3078 */ 3079 switch (phytype) { 3080 case BWI_PHYINFO_TYPE_11A: 3081 if (phyrev >= 4) { 3082 aprint_error_dev(sc->sc_dev, 3083 "unsupported 11A PHY, rev %u\n", 3084 phyrev); 3085 return (ENXIO); 3086 } 3087 phy->phy_init = bwi_phy_init_11a; 3088 phy->phy_mode = IEEE80211_MODE_11A; 3089 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A; 3090 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A; 3091 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A; 3092 break; 3093 case BWI_PHYINFO_TYPE_11B: 3094 for (i = 0; i < __arraycount(bwi_sup_bphy); ++i) { 3095 if (phyrev == bwi_sup_bphy[i].rev) { 3096 phy->phy_init = bwi_sup_bphy[i].init; 3097 break; 3098 } 3099 } 3100 if (i == __arraycount(bwi_sup_bphy)) { 3101 aprint_error_dev(sc->sc_dev, 3102 "unsupported 11B PHY, rev %u\n", 3103 phyrev); 3104 return (ENXIO); 3105 } 3106 phy->phy_mode = IEEE80211_MODE_11B; 3107 break; 3108 case BWI_PHYINFO_TYPE_11G: 3109 if (phyrev > 8) { 3110 aprint_error_dev(sc->sc_dev, 3111 "unsupported 11G PHY, rev %u\n", 3112 phyrev); 3113 return (ENXIO); 3114 } 3115 phy->phy_init = bwi_phy_init_11g; 3116 phy->phy_mode = IEEE80211_MODE_11G; 3117 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G; 3118 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G; 3119 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G; 3120 break; 3121 default: 3122 aprint_error_dev(sc->sc_dev, "unsupported PHY type %d\n", 3123 phytype); 3124 return (ENXIO); 3125 } 3126 phy->phy_rev = phyrev; 3127 phy->phy_version = phyver; 3128 3129 return (0); 3130 } 3131 3132 static void 3133 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten) 3134 { 3135 struct bwi_phy *phy = &mac->mac_phy; 3136 uint16_t mask = 0x000f; 3137 3138 if (phy->phy_version == 0) { 3139 CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask, 3140 __SHIFTIN(bbp_atten, mask)); 3141 } else { 3142 if (phy->phy_version > 1) 3143 mask <<= 2; 3144 else 3145 mask <<= 3; 3146 PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask, 3147 __SHIFTIN(bbp_atten, mask)); 3148 } 3149 } 3150 3151 static int 3152 bwi_phy_calibrate(struct bwi_mac *mac) 3153 { 3154 struct bwi_phy *phy = &mac->mac_phy; 3155 3156 /* Dummy read */ 3157 CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS); 3158 3159 /* Don't re-init */ 3160 if (phy->phy_flags & BWI_PHY_F_CALIBRATED) 3161 return (0); 3162 3163 if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) { 3164 bwi_mac_reset(mac, 0); 3165 bwi_phy_init_11g(mac); 3166 bwi_mac_reset(mac, 1); 3167 } 3168 3169 phy->phy_flags |= BWI_PHY_F_CALIBRATED; 3170 3171 return (0); 3172 } 3173 3174 static void 3175 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data) 3176 { 3177 struct bwi_phy *phy = &mac->mac_phy; 3178 3179 KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0); 3180 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); 3181 PHY_WRITE(mac, phy->phy_tbl_data_lo, data); 3182 } 3183 3184 static void 3185 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data) 3186 { 3187 struct bwi_phy *phy = &mac->mac_phy; 3188 3189 KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && 3190 phy->phy_tbl_ctrl != 0); 3191 3192 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); 3193 PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16); 3194 PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff); 3195 } 3196 3197 static void 3198 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data) 3199 { 3200 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs); 3201 PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data); 3202 } 3203 3204 static int16_t 3205 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs) 3206 { 3207 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs); 3208 return ((int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA)); 3209 } 3210 3211 static void 3212 bwi_phy_init_11a(struct bwi_mac *mac) 3213 { 3214 /* TODO: 11A */ 3215 } 3216 3217 static void 3218 bwi_phy_init_11g(struct bwi_mac *mac) 3219 { 3220 struct bwi_softc *sc = mac->mac_sc; 3221 struct bwi_phy *phy = &mac->mac_phy; 3222 struct bwi_rf *rf = &mac->mac_rf; 3223 const struct bwi_tpctl *tpctl = &mac->mac_tpctl; 3224 3225 if (phy->phy_rev == 1) 3226 bwi_phy_init_11b_rev5(mac); 3227 else 3228 bwi_phy_init_11b_rev6(mac); 3229 3230 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) 3231 bwi_phy_config_11g(mac); 3232 3233 if (phy->phy_rev >= 2) { 3234 PHY_WRITE(mac, 0x814, 0); 3235 PHY_WRITE(mac, 0x815, 0); 3236 3237 if (phy->phy_rev == 2) { 3238 PHY_WRITE(mac, 0x811, 0); 3239 PHY_WRITE(mac, 0x15, 0xc0); 3240 } else if (phy->phy_rev > 5) { 3241 PHY_WRITE(mac, 0x811, 0x400); 3242 PHY_WRITE(mac, 0x15, 0xc0); 3243 } 3244 } 3245 3246 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) { 3247 uint16_t val; 3248 3249 val = PHY_READ(mac, 0x400) & 0xff; 3250 if (val == 3 || val == 5) { 3251 PHY_WRITE(mac, 0x4c2, 0x1816); 3252 PHY_WRITE(mac, 0x4c3, 0x8006); 3253 if (val == 5) { 3254 PHY_FILT_SETBITS(mac, 0x4cc, 3255 0xff, 0x1f00); 3256 } 3257 } 3258 } 3259 3260 if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) || 3261 phy->phy_rev >= 2) 3262 PHY_WRITE(mac, 0x47e, 0x78); 3263 3264 if (rf->rf_rev == 8) { 3265 PHY_SETBITS(mac, 0x801, 0x80); 3266 PHY_SETBITS(mac, 0x43e, 0x4); 3267 } 3268 3269 if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) 3270 bwi_rf_get_gains(mac); 3271 3272 if (rf->rf_rev != 8) 3273 bwi_rf_init(mac); 3274 3275 if (tpctl->tp_ctrl2 == 0xffff) { 3276 bwi_rf_lo_update(mac); 3277 } else { 3278 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) { 3279 RF_WRITE(mac, 0x52, 3280 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2); 3281 } else { 3282 RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2); 3283 } 3284 3285 if (phy->phy_rev >= 6) { 3286 PHY_FILT_SETBITS(mac, 0x36, 0xfff, 3287 tpctl->tp_ctrl2 << 12); 3288 } 3289 3290 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 3291 PHY_WRITE(mac, 0x2e, 0x8075); 3292 else 3293 PHY_WRITE(mac, 0x2e, 0x807f); 3294 3295 if (phy->phy_rev < 2) 3296 PHY_WRITE(mac, 0x2f, 0x101); 3297 else 3298 PHY_WRITE(mac, 0x2f, 0x202); 3299 } 3300 3301 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 3302 bwi_rf_lo_adjust(mac, tpctl); 3303 PHY_WRITE(mac, 0x80f, 0x8078); 3304 } 3305 3306 if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) { 3307 bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */); 3308 bwi_rf_set_nrssi_thr(mac); 3309 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 3310 if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) { 3311 KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI); 3312 bwi_rf_calc_nrssi_slope(mac); 3313 } else { 3314 KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI); 3315 bwi_rf_set_nrssi_thr(mac); 3316 } 3317 } 3318 3319 if (rf->rf_rev == 8) 3320 PHY_WRITE(mac, 0x805, 0x3230); 3321 3322 bwi_mac_init_tpctl_11bg(mac); 3323 3324 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) { 3325 PHY_CLRBITS(mac, 0x429, 0x4000); 3326 PHY_CLRBITS(mac, 0x4c3, 0x8000); 3327 } 3328 } 3329 3330 static void 3331 bwi_phy_init_11b_rev2(struct bwi_mac *mac) 3332 { 3333 struct bwi_softc *sc; 3334 3335 sc = mac->mac_sc; 3336 3337 /* TODO: 11B */ 3338 aprint_error_dev(sc->sc_dev, "%s is not implemented yet\n", __func__); 3339 } 3340 3341 static void 3342 bwi_phy_init_11b_rev4(struct bwi_mac *mac) 3343 { 3344 struct bwi_softc *sc = mac->mac_sc; 3345 struct bwi_rf *rf = &mac->mac_rf; 3346 uint16_t val, ofs; 3347 uint chan; 3348 3349 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT); 3350 3351 PHY_WRITE(mac, 0x20, 0x301c); 3352 PHY_WRITE(mac, 0x26, 0); 3353 PHY_WRITE(mac, 0x30, 0xc6); 3354 PHY_WRITE(mac, 0x88, 0x3e00); 3355 3356 for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202) 3357 PHY_WRITE(mac, 0x89 + ofs, val); 3358 3359 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1); 3360 3361 chan = rf->rf_curchan; 3362 if (chan == IEEE80211_CHAN_ANY) 3363 chan = 6; /* Force to channel 6 */ 3364 bwi_rf_set_chan(mac, chan, 0); 3365 3366 if (rf->rf_type != BWI_RF_T_BCM2050) { 3367 RF_WRITE(mac, 0x75, 0x80); 3368 RF_WRITE(mac, 0x79, 0x81); 3369 } 3370 3371 RF_WRITE(mac, 0x50, 0x20); 3372 RF_WRITE(mac, 0x50, 0x23); 3373 3374 if (rf->rf_type == BWI_RF_T_BCM2050) { 3375 RF_WRITE(mac, 0x50, 0x20); 3376 RF_WRITE(mac, 0x5a, 0x70); 3377 RF_WRITE(mac, 0x5b, 0x7b); 3378 RF_WRITE(mac, 0x5c, 0xb0); 3379 RF_WRITE(mac, 0x7a, 0xf); 3380 PHY_WRITE(mac, 0x38, 0x677); 3381 bwi_rf_init_bcm2050(mac); 3382 } 3383 3384 PHY_WRITE(mac, 0x14, 0x80); 3385 PHY_WRITE(mac, 0x32, 0xca); 3386 if (rf->rf_type == BWI_RF_T_BCM2050) 3387 PHY_WRITE(mac, 0x32, 0xe0); 3388 PHY_WRITE(mac, 0x35, 0x7c2); 3389 3390 bwi_rf_lo_update(mac); 3391 3392 PHY_WRITE(mac, 0x26, 0xcc00); 3393 if (rf->rf_type == BWI_RF_T_BCM2050) 3394 PHY_WRITE(mac, 0x26, 0xce00); 3395 3396 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100); 3397 3398 PHY_WRITE(mac, 0x2a, 0x88a3); 3399 if (rf->rf_type == BWI_RF_T_BCM2050) 3400 PHY_WRITE(mac, 0x2a, 0x88c2); 3401 3402 bwi_mac_set_tpctl_11bg(mac, NULL); 3403 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 3404 bwi_rf_calc_nrssi_slope(mac); 3405 bwi_rf_set_nrssi_thr(mac); 3406 } 3407 bwi_mac_init_tpctl_11bg(mac); 3408 } 3409 3410 static void 3411 bwi_phy_init_11b_rev5(struct bwi_mac *mac) 3412 { 3413 struct bwi_softc *sc = mac->mac_sc; 3414 struct bwi_rf *rf = &mac->mac_rf; 3415 struct bwi_phy *phy = &mac->mac_phy; 3416 uint orig_chan; 3417 3418 if (phy->phy_version == 1) 3419 RF_SETBITS(mac, 0x7a, 0x50); 3420 3421 if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM && 3422 sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) { 3423 uint16_t ofs, val; 3424 3425 val = 0x2120; 3426 for (ofs = 0xa8; ofs < 0xc7; ++ofs) { 3427 PHY_WRITE(mac, ofs, val); 3428 val += 0x202; 3429 } 3430 } 3431 3432 PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700); 3433 3434 if (rf->rf_type == BWI_RF_T_BCM2050) 3435 PHY_WRITE(mac, 0x38, 0x667); 3436 3437 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 3438 if (rf->rf_type == BWI_RF_T_BCM2050) { 3439 RF_SETBITS(mac, 0x7a, 0x20); 3440 RF_SETBITS(mac, 0x51, 0x4); 3441 } 3442 3443 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0); 3444 3445 PHY_SETBITS(mac, 0x802, 0x100); 3446 PHY_SETBITS(mac, 0x42b, 0x2000); 3447 PHY_WRITE(mac, 0x1c, 0x186a); 3448 3449 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900); 3450 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64); 3451 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa); 3452 } 3453 3454 /* TODO: bad_frame_preempt? */ 3455 3456 if (phy->phy_version == 1) { 3457 PHY_WRITE(mac, 0x26, 0xce00); 3458 PHY_WRITE(mac, 0x21, 0x3763); 3459 PHY_WRITE(mac, 0x22, 0x1bc3); 3460 PHY_WRITE(mac, 0x23, 0x6f9); 3461 PHY_WRITE(mac, 0x24, 0x37e); 3462 } else 3463 PHY_WRITE(mac, 0x26, 0xcc00); 3464 PHY_WRITE(mac, 0x30, 0xc6); 3465 3466 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT); 3467 3468 if (phy->phy_version == 1) 3469 PHY_WRITE(mac, 0x20, 0x3e1c); 3470 else 3471 PHY_WRITE(mac, 0x20, 0x301c); 3472 3473 if (phy->phy_version == 0) 3474 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1); 3475 3476 /* Force to channel 7 */ 3477 orig_chan = rf->rf_curchan; 3478 bwi_rf_set_chan(mac, 7, 0); 3479 3480 if (rf->rf_type != BWI_RF_T_BCM2050) { 3481 RF_WRITE(mac, 0x75, 0x80); 3482 RF_WRITE(mac, 0x79, 0x81); 3483 } 3484 3485 RF_WRITE(mac, 0x50, 0x20); 3486 RF_WRITE(mac, 0x50, 0x23); 3487 3488 if (rf->rf_type == BWI_RF_T_BCM2050) { 3489 RF_WRITE(mac, 0x50, 0x20); 3490 RF_WRITE(mac, 0x5a, 0x70); 3491 } 3492 3493 RF_WRITE(mac, 0x5b, 0x7b); 3494 RF_WRITE(mac, 0x5c, 0xb0); 3495 RF_SETBITS(mac, 0x7a, 0x7); 3496 3497 bwi_rf_set_chan(mac, orig_chan, 0); 3498 3499 PHY_WRITE(mac, 0x14, 0x80); 3500 PHY_WRITE(mac, 0x32, 0xca); 3501 PHY_WRITE(mac, 0x2a, 0x88a3); 3502 3503 bwi_mac_set_tpctl_11bg(mac, NULL); 3504 3505 if (rf->rf_type == BWI_RF_T_BCM2050) 3506 RF_WRITE(mac, 0x5d, 0xd); 3507 3508 CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4); 3509 } 3510 3511 static void 3512 bwi_phy_init_11b_rev6(struct bwi_mac *mac) 3513 { 3514 struct bwi_softc *sc = mac->mac_sc; 3515 struct bwi_rf *rf = &mac->mac_rf; 3516 struct bwi_phy *phy = &mac->mac_phy; 3517 uint16_t val, ofs; 3518 uint orig_chan; 3519 3520 PHY_WRITE(mac, 0x3e, 0x817a); 3521 RF_SETBITS(mac, 0x7a, 0x58); 3522 3523 if (rf->rf_rev == 4 || rf->rf_rev == 5) { 3524 RF_WRITE(mac, 0x51, 0x37); 3525 RF_WRITE(mac, 0x52, 0x70); 3526 RF_WRITE(mac, 0x53, 0xb3); 3527 RF_WRITE(mac, 0x54, 0x9b); 3528 RF_WRITE(mac, 0x5a, 0x88); 3529 RF_WRITE(mac, 0x5b, 0x88); 3530 RF_WRITE(mac, 0x5d, 0x88); 3531 RF_WRITE(mac, 0x5e, 0x88); 3532 RF_WRITE(mac, 0x7d, 0x88); 3533 HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1); 3534 } else if (rf->rf_rev == 8) { 3535 RF_WRITE(mac, 0x51, 0); 3536 RF_WRITE(mac, 0x52, 0x40); 3537 RF_WRITE(mac, 0x53, 0xb7); 3538 RF_WRITE(mac, 0x54, 0x98); 3539 RF_WRITE(mac, 0x5a, 0x88); 3540 RF_WRITE(mac, 0x5b, 0x6b); 3541 RF_WRITE(mac, 0x5c, 0xf); 3542 if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) { 3543 RF_WRITE(mac, 0x5d, 0xfa); 3544 RF_WRITE(mac, 0x5e, 0xd8); 3545 } else { 3546 RF_WRITE(mac, 0x5d, 0xf5); 3547 RF_WRITE(mac, 0x5e, 0xb8); 3548 } 3549 RF_WRITE(mac, 0x73, 0x3); 3550 RF_WRITE(mac, 0x7d, 0xa8); 3551 RF_WRITE(mac, 0x7c, 0x1); 3552 RF_WRITE(mac, 0x7e, 0x8); 3553 } 3554 3555 val = 0x1e1f; 3556 for (ofs = 0x88; ofs < 0x98; ++ofs) { 3557 PHY_WRITE(mac, ofs, val); 3558 val -= 0x202; 3559 } 3560 3561 val = 0x3e3f; 3562 for (ofs = 0x98; ofs < 0xa8; ++ofs) { 3563 PHY_WRITE(mac, ofs, val); 3564 val -= 0x202; 3565 } 3566 3567 val = 0x2120; 3568 for (ofs = 0xa8; ofs < 0xc8; ++ofs) { 3569 PHY_WRITE(mac, ofs, (val & 0x3f3f)); 3570 val += 0x202; 3571 } 3572 3573 if (phy->phy_mode == IEEE80211_MODE_11G) { 3574 RF_SETBITS(mac, 0x7a, 0x20); 3575 RF_SETBITS(mac, 0x51, 0x4); 3576 PHY_SETBITS(mac, 0x802, 0x100); 3577 PHY_SETBITS(mac, 0x42b, 0x2000); 3578 PHY_WRITE(mac, 0x5b, 0); 3579 PHY_WRITE(mac, 0x5c, 0); 3580 } 3581 3582 /* Force to channel 7 */ 3583 orig_chan = rf->rf_curchan; 3584 if (orig_chan >= 8) 3585 bwi_rf_set_chan(mac, 1, 0); 3586 else 3587 bwi_rf_set_chan(mac, 13, 0); 3588 3589 RF_WRITE(mac, 0x50, 0x20); 3590 RF_WRITE(mac, 0x50, 0x23); 3591 3592 DELAY(40); 3593 3594 if (rf->rf_rev < 6 || rf->rf_rev == 8) { 3595 RF_SETBITS(mac, 0x7c, 0x2); 3596 RF_WRITE(mac, 0x50, 0x20); 3597 } 3598 if (rf->rf_rev <= 2) { 3599 RF_WRITE(mac, 0x7c, 0x20); 3600 RF_WRITE(mac, 0x5a, 0x70); 3601 RF_WRITE(mac, 0x5b, 0x7b); 3602 RF_WRITE(mac, 0x5c, 0xb0); 3603 } 3604 3605 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7); 3606 3607 bwi_rf_set_chan(mac, orig_chan, 0); 3608 3609 PHY_WRITE(mac, 0x14, 0x200); 3610 if (rf->rf_rev >= 6) 3611 PHY_WRITE(mac, 0x2a, 0x88c2); 3612 else 3613 PHY_WRITE(mac, 0x2a, 0x8ac0); 3614 PHY_WRITE(mac, 0x38, 0x668); 3615 3616 bwi_mac_set_tpctl_11bg(mac, NULL); 3617 3618 if (rf->rf_rev <= 5) { 3619 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3); 3620 if (rf->rf_rev <= 2) 3621 RF_WRITE(mac, 0x5d, 0xd); 3622 } 3623 3624 if (phy->phy_version == 4) { 3625 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2); 3626 PHY_CLRBITS(mac, 0x61, 0xf000); 3627 } else { 3628 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4); 3629 } 3630 3631 if (phy->phy_mode == IEEE80211_MODE_11B) { 3632 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2); 3633 PHY_WRITE(mac, 0x16, 0x410); 3634 PHY_WRITE(mac, 0x17, 0x820); 3635 PHY_WRITE(mac, 0x62, 0x7); 3636 3637 bwi_rf_init_bcm2050(mac); 3638 bwi_rf_lo_update(mac); 3639 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 3640 bwi_rf_calc_nrssi_slope(mac); 3641 bwi_rf_set_nrssi_thr(mac); 3642 } 3643 bwi_mac_init_tpctl_11bg(mac); 3644 } else 3645 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); 3646 } 3647 3648 static void 3649 bwi_phy_config_11g(struct bwi_mac *mac) 3650 { 3651 struct bwi_softc *sc = mac->mac_sc; 3652 struct bwi_phy *phy = &mac->mac_phy; 3653 const uint16_t *tbl; 3654 uint16_t wrd_ofs1, wrd_ofs2; 3655 int i, n; 3656 3657 if (phy->phy_rev == 1) { 3658 PHY_WRITE(mac, 0x406, 0x4f19); 3659 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340); 3660 PHY_WRITE(mac, 0x42c, 0x5a); 3661 PHY_WRITE(mac, 0x427, 0x1a); 3662 3663 /* Fill frequency table */ 3664 for (i = 0; i < __arraycount(bwi_phy_freq_11g_rev1); ++i) { 3665 bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i, 3666 bwi_phy_freq_11g_rev1[i]); 3667 } 3668 3669 /* Fill noise table */ 3670 for (i = 0; i < __arraycount(bwi_phy_noise_11g_rev1); ++i) { 3671 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, 3672 bwi_phy_noise_11g_rev1[i]); 3673 } 3674 3675 /* Fill rotor table */ 3676 for (i = 0; i < __arraycount(bwi_phy_rotor_11g_rev1); ++i) { 3677 /* NB: data length is 4 bytes */ 3678 bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i, 3679 bwi_phy_rotor_11g_rev1[i]); 3680 } 3681 } else { 3682 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */ 3683 3684 if (phy->phy_rev == 2) { 3685 PHY_WRITE(mac, 0x4c0, 0x1861); 3686 PHY_WRITE(mac, 0x4c1, 0x271); 3687 } else if (phy->phy_rev > 2) { 3688 PHY_WRITE(mac, 0x4c0, 0x98); 3689 PHY_WRITE(mac, 0x4c1, 0x70); 3690 PHY_WRITE(mac, 0x4c9, 0x80); 3691 } 3692 PHY_SETBITS(mac, 0x42b, 0x800); 3693 3694 /* Fill RSSI table */ 3695 for (i = 0; i < 64; ++i) 3696 bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i); 3697 3698 /* Fill noise table */ 3699 for (i = 0; i < __arraycount(bwi_phy_noise_11g); ++i) { 3700 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, 3701 bwi_phy_noise_11g[i]); 3702 } 3703 } 3704 3705 /* 3706 * Fill noise scale table 3707 */ 3708 if (phy->phy_rev <= 2) { 3709 tbl = bwi_phy_noise_scale_11g_rev2; 3710 n = __arraycount(bwi_phy_noise_scale_11g_rev2); 3711 } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) { 3712 tbl = bwi_phy_noise_scale_11g_rev7; 3713 n = __arraycount(bwi_phy_noise_scale_11g_rev7); 3714 } else { 3715 tbl = bwi_phy_noise_scale_11g; 3716 n = __arraycount(bwi_phy_noise_scale_11g); 3717 } 3718 for (i = 0; i < n; ++i) 3719 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]); 3720 3721 /* 3722 * Fill sigma square table 3723 */ 3724 if (phy->phy_rev == 2) { 3725 tbl = bwi_phy_sigma_sq_11g_rev2; 3726 n = __arraycount(bwi_phy_sigma_sq_11g_rev2); 3727 } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) { 3728 tbl = bwi_phy_sigma_sq_11g_rev7; 3729 n = __arraycount(bwi_phy_sigma_sq_11g_rev7); 3730 } else { 3731 tbl = NULL; 3732 n = 0; 3733 } 3734 for (i = 0; i < n; ++i) 3735 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]); 3736 3737 if (phy->phy_rev == 1) { 3738 /* Fill delay table */ 3739 for (i = 0; i < __arraycount(bwi_phy_delay_11g_rev1); ++i) { 3740 bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i, 3741 bwi_phy_delay_11g_rev1[i]); 3742 } 3743 3744 /* Fill WRSSI (Wide-Band RSSI) table */ 3745 for (i = 4; i < 20; ++i) 3746 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20); 3747 3748 bwi_phy_config_agc(mac); 3749 3750 wrd_ofs1 = 0x5001; 3751 wrd_ofs2 = 0x5002; 3752 } else { 3753 /* Fill WRSSI (Wide-Band RSSI) table */ 3754 for (i = 0; i < 0x20; ++i) 3755 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820); 3756 3757 bwi_phy_config_agc(mac); 3758 3759 PHY_READ(mac, 0x400); /* Dummy read */ 3760 PHY_WRITE(mac, 0x403, 0x1000); 3761 bwi_tbl_write_2(mac, 0x3c02, 0xf); 3762 bwi_tbl_write_2(mac, 0x3c03, 0x14); 3763 3764 wrd_ofs1 = 0x401; 3765 wrd_ofs2 = 0x402; 3766 } 3767 3768 if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) { 3769 bwi_tbl_write_2(mac, wrd_ofs1, 0x2); 3770 bwi_tbl_write_2(mac, wrd_ofs2, 0x1); 3771 } 3772 3773 /* phy->phy_flags & BWI_PHY_F_LINKED ? */ 3774 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 3775 PHY_WRITE(mac, 0x46e, 0x3cf); 3776 } 3777 3778 /* 3779 * Configure Automatic Gain Controller 3780 */ 3781 static void 3782 bwi_phy_config_agc(struct bwi_mac *mac) 3783 { 3784 struct bwi_phy *phy = &mac->mac_phy; 3785 uint16_t ofs; 3786 3787 ofs = phy->phy_rev == 1 ? 0x4c00 : 0; 3788 3789 bwi_tbl_write_2(mac, ofs, 0xfe); 3790 bwi_tbl_write_2(mac, ofs + 1, 0xd); 3791 bwi_tbl_write_2(mac, ofs + 2, 0x13); 3792 bwi_tbl_write_2(mac, ofs + 3, 0x19); 3793 3794 if (phy->phy_rev == 1) { 3795 bwi_tbl_write_2(mac, 0x1800, 0x2710); 3796 bwi_tbl_write_2(mac, 0x1801, 0x9b83); 3797 bwi_tbl_write_2(mac, 0x1802, 0x9b83); 3798 bwi_tbl_write_2(mac, 0x1803, 0xf8d); 3799 PHY_WRITE(mac, 0x455, 0x4); 3800 } 3801 3802 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700); 3803 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf); 3804 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80); 3805 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300); 3806 3807 RF_SETBITS(mac, 0x7a, 0x8); 3808 3809 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8); 3810 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600); 3811 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700); 3812 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100); 3813 3814 if (phy->phy_rev == 1) 3815 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7); 3816 3817 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c); 3818 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200); 3819 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c); 3820 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20); 3821 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200); 3822 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e); 3823 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00); 3824 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28); 3825 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00); 3826 3827 if (phy->phy_rev == 1) { 3828 PHY_WRITE(mac, 0x430, 0x92b); 3829 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2); 3830 } else { 3831 PHY_CLRBITS(mac, 0x41b, 0x1e); 3832 PHY_WRITE(mac, 0x41f, 0x287a); 3833 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4); 3834 3835 if (phy->phy_rev >= 6) { 3836 PHY_WRITE(mac, 0x422, 0x287a); 3837 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000); 3838 } 3839 } 3840 3841 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874); 3842 PHY_WRITE(mac, 0x48e, 0x1c00); 3843 3844 if (phy->phy_rev == 1) { 3845 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600); 3846 PHY_WRITE(mac, 0x48b, 0x5e); 3847 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e); 3848 PHY_WRITE(mac, 0x48d, 0x2); 3849 } 3850 3851 bwi_tbl_write_2(mac, ofs + 0x800, 0); 3852 bwi_tbl_write_2(mac, ofs + 0x801, 7); 3853 bwi_tbl_write_2(mac, ofs + 0x802, 16); 3854 bwi_tbl_write_2(mac, ofs + 0x803, 28); 3855 3856 if (phy->phy_rev >= 6) { 3857 PHY_CLRBITS(mac, 0x426, 0x3); 3858 PHY_CLRBITS(mac, 0x426, 0x1000); 3859 } 3860 } 3861 3862 static void 3863 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains) 3864 { 3865 struct bwi_phy *phy = &mac->mac_phy; 3866 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain; 3867 int i; 3868 3869 if (phy->phy_rev <= 1) { 3870 tbl_gain_ofs1 = 0x5000; 3871 tbl_gain_ofs2 = tbl_gain_ofs1 + 16; 3872 } else { 3873 tbl_gain_ofs1 = 0x400; 3874 tbl_gain_ofs2 = tbl_gain_ofs1 + 8; 3875 } 3876 3877 for (i = 0; i < 4; ++i) { 3878 if (gains != NULL) { 3879 tbl_gain = gains->tbl_gain1; 3880 } else { 3881 /* Bit swap */ 3882 tbl_gain = (i & 0x1) << 1; 3883 tbl_gain |= (i & 0x2) >> 1; 3884 } 3885 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain); 3886 } 3887 3888 for (i = 0; i < 16; ++i) { 3889 if (gains != NULL) 3890 tbl_gain = gains->tbl_gain2; 3891 else 3892 tbl_gain = i; 3893 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain); 3894 } 3895 3896 if (gains == NULL || gains->phy_gain != -1) { 3897 uint16_t phy_gain1, phy_gain2; 3898 3899 if (gains != NULL) { 3900 phy_gain1 = 3901 ((uint16_t)gains->phy_gain << 14) | 3902 ((uint16_t)gains->phy_gain << 6); 3903 phy_gain2 = phy_gain1; 3904 } else { 3905 phy_gain1 = 0x4040; 3906 phy_gain2 = 0x4000; 3907 } 3908 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1); 3909 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1); 3910 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2); 3911 } 3912 bwi_mac_dummy_xmit(mac); 3913 } 3914 3915 static void 3916 bwi_phy_clear_state(struct bwi_phy *phy) 3917 { 3918 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS; 3919 } 3920 3921 /* RF */ 3922 3923 static int16_t 3924 bwi_nrssi_11g(struct bwi_mac *mac) 3925 { 3926 int16_t val; 3927 3928 #define NRSSI_11G_MASK 0x3f00 3929 val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK); 3930 if (val >= 32) 3931 val -= 64; 3932 3933 return (val); 3934 #undef NRSSI_11G_MASK 3935 } 3936 3937 static struct bwi_rf_lo * 3938 bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten) 3939 { 3940 int n; 3941 3942 n = rf_atten + (14 * (bbp_atten / 2)); 3943 KASSERT(n < BWI_RFLO_MAX); 3944 3945 return (&mac->mac_rf.rf_lo[n]); 3946 } 3947 3948 static int 3949 bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo) 3950 { 3951 struct bwi_rf *rf = &mac->mac_rf; 3952 int idx; 3953 3954 idx = lo - rf->rf_lo; 3955 KASSERT(idx >= 0 && idx < BWI_RFLO_MAX); 3956 3957 return (isset(rf->rf_lo_used, idx)); 3958 } 3959 3960 static void 3961 bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data) 3962 { 3963 struct bwi_softc *sc = mac->mac_sc; 3964 3965 CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl); 3966 CSR_WRITE_2(sc, BWI_RF_DATA_LO, data); 3967 } 3968 3969 static uint16_t 3970 bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl) 3971 { 3972 struct bwi_rf *rf = &mac->mac_rf; 3973 struct bwi_softc *sc = mac->mac_sc; 3974 3975 ctrl |= rf->rf_ctrl_rd; 3976 if (rf->rf_ctrl_adj) { 3977 /* XXX */ 3978 if (ctrl < 0x70) 3979 ctrl += 0x80; 3980 else if (ctrl < 0x80) 3981 ctrl += 0x70; 3982 } 3983 3984 CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl); 3985 return (CSR_READ_2(sc, BWI_RF_DATA_LO)); 3986 } 3987 3988 static int 3989 bwi_rf_attach(struct bwi_mac *mac) 3990 { 3991 struct bwi_softc *sc = mac->mac_sc; 3992 struct bwi_phy *phy = &mac->mac_phy; 3993 struct bwi_rf *rf = &mac->mac_rf; 3994 uint16_t type, manu; 3995 uint8_t rev; 3996 3997 /* 3998 * Get RF manufacture/type/revision 3999 */ 4000 if (sc->sc_bbp_id == BWI_BBPID_BCM4317) { 4001 /* 4002 * Fake a BCM2050 RF 4003 */ 4004 manu = BWI_RF_MANUFACT_BCM; 4005 type = BWI_RF_T_BCM2050; 4006 if (sc->sc_bbp_rev == 0) 4007 rev = 3; 4008 else if (sc->sc_bbp_rev == 1) 4009 rev = 4; 4010 else 4011 rev = 5; 4012 } else { 4013 uint32_t val; 4014 4015 CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO); 4016 val = CSR_READ_2(sc, BWI_RF_DATA_HI); 4017 val <<= 16; 4018 4019 CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO); 4020 val |= CSR_READ_2(sc, BWI_RF_DATA_LO); 4021 4022 manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK); 4023 type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK); 4024 rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK); 4025 } 4026 aprint_normal_dev(sc->sc_dev, "RF manu 0x%03x, type 0x%04x, rev %u\n", 4027 manu, type, rev); 4028 4029 /* 4030 * Verify whether the RF is supported 4031 */ 4032 rf->rf_ctrl_rd = 0; 4033 rf->rf_ctrl_adj = 0; 4034 switch (phy->phy_mode) { 4035 case IEEE80211_MODE_11A: 4036 if (manu != BWI_RF_MANUFACT_BCM || 4037 type != BWI_RF_T_BCM2060 || 4038 rev != 1) { 4039 aprint_error_dev(sc->sc_dev, 4040 "only BCM2060 rev 1 RF is supported for" 4041 " 11A PHY\n"); 4042 return (ENXIO); 4043 } 4044 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A; 4045 rf->rf_on = bwi_rf_on_11a; 4046 rf->rf_off = bwi_rf_off_11a; 4047 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060; 4048 break; 4049 case IEEE80211_MODE_11B: 4050 if (type == BWI_RF_T_BCM2050) { 4051 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG; 4052 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050; 4053 } else if (type == BWI_RF_T_BCM2053) { 4054 rf->rf_ctrl_adj = 1; 4055 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053; 4056 } else { 4057 aprint_error_dev(sc->sc_dev, 4058 "only BCM2050/BCM2053 RF is supported for" 4059 " 11B phy\n"); 4060 return (ENXIO); 4061 } 4062 rf->rf_on = bwi_rf_on_11bg; 4063 rf->rf_off = bwi_rf_off_11bg; 4064 rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b; 4065 rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b; 4066 if (phy->phy_rev == 6) 4067 rf->rf_lo_update = bwi_rf_lo_update_11g; 4068 else 4069 rf->rf_lo_update = bwi_rf_lo_update_11b; 4070 break; 4071 case IEEE80211_MODE_11G: 4072 if (type != BWI_RF_T_BCM2050) { 4073 aprint_error_dev(sc->sc_dev, 4074 "only BCM2050 RF is supported for" 4075 " 11G PHY\n"); 4076 return (ENXIO); 4077 } 4078 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG; 4079 rf->rf_on = bwi_rf_on_11bg; 4080 if (mac->mac_rev >= 5) 4081 rf->rf_off = bwi_rf_off_11g_rev5; 4082 else 4083 rf->rf_off = bwi_rf_off_11bg; 4084 rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g; 4085 rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g; 4086 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050; 4087 rf->rf_lo_update = bwi_rf_lo_update_11g; 4088 break; 4089 default: 4090 aprint_error_dev(sc->sc_dev, "unsupported PHY mode\n"); 4091 return (ENXIO); 4092 } 4093 4094 rf->rf_type = type; 4095 rf->rf_rev = rev; 4096 rf->rf_manu = manu; 4097 rf->rf_curchan = IEEE80211_CHAN_ANY; 4098 rf->rf_ant_mode = BWI_ANT_MODE_AUTO; 4099 4100 return (0); 4101 } 4102 4103 static void 4104 bwi_rf_set_chan(struct bwi_mac *mac, uint chan, int work_around) 4105 { 4106 struct bwi_softc *sc = mac->mac_sc; 4107 4108 if (chan == IEEE80211_CHAN_ANY) 4109 return; 4110 4111 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan); 4112 4113 /* TODO: 11A */ 4114 4115 if (work_around) 4116 bwi_rf_workaround(mac, chan); 4117 4118 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan)); 4119 4120 if (chan == 14) { 4121 if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN) 4122 HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN); 4123 else 4124 HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN); 4125 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11)); /* XXX */ 4126 } else { 4127 CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840); /* XXX */ 4128 } 4129 DELAY(8000); /* DELAY(2000); */ 4130 4131 mac->mac_rf.rf_curchan = chan; 4132 } 4133 4134 static void 4135 bwi_rf_get_gains(struct bwi_mac *mac) 4136 { 4137 #define SAVE_PHY_MAX 15 4138 #define SAVE_RF_MAX 3 4139 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 4140 { 0x52, 0x43, 0x7a }; 4141 static const uint16_t save_phy_regs[SAVE_PHY_MAX] = { 4142 0x0429, 0x0001, 0x0811, 0x0812, 4143 0x0814, 0x0815, 0x005a, 0x0059, 4144 0x0058, 0x000a, 0x0003, 0x080f, 4145 0x0810, 0x002b, 0x0015 4146 }; 4147 4148 struct bwi_phy *phy = &mac->mac_phy; 4149 struct bwi_rf *rf = &mac->mac_rf; 4150 uint16_t save_phy[SAVE_PHY_MAX]; 4151 uint16_t save_rf[SAVE_RF_MAX]; 4152 uint16_t trsw; 4153 int i, j, loop1_max, loop1, loop2; 4154 4155 /* 4156 * Save PHY/RF registers for later restoration 4157 */ 4158 for (i = 0; i < SAVE_PHY_MAX; ++i) 4159 save_phy[i] = PHY_READ(mac, save_phy_regs[i]); 4160 PHY_READ(mac, 0x2d); /* dummy read */ 4161 4162 for (i = 0; i < SAVE_RF_MAX; ++i) 4163 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 4164 4165 PHY_CLRBITS(mac, 0x429, 0xc000); 4166 PHY_SETBITS(mac, 0x1, 0x8000); 4167 4168 PHY_SETBITS(mac, 0x811, 0x2); 4169 PHY_CLRBITS(mac, 0x812, 0x2); 4170 PHY_SETBITS(mac, 0x811, 0x1); 4171 PHY_CLRBITS(mac, 0x812, 0x1); 4172 4173 PHY_SETBITS(mac, 0x814, 0x1); 4174 PHY_CLRBITS(mac, 0x815, 0x1); 4175 PHY_SETBITS(mac, 0x814, 0x2); 4176 PHY_CLRBITS(mac, 0x815, 0x2); 4177 4178 PHY_SETBITS(mac, 0x811, 0xc); 4179 PHY_SETBITS(mac, 0x812, 0xc); 4180 PHY_SETBITS(mac, 0x811, 0x30); 4181 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10); 4182 4183 PHY_WRITE(mac, 0x5a, 0x780); 4184 PHY_WRITE(mac, 0x59, 0xc810); 4185 PHY_WRITE(mac, 0x58, 0xd); 4186 PHY_SETBITS(mac, 0xa, 0x2000); 4187 4188 PHY_SETBITS(mac, 0x814, 0x4); 4189 PHY_CLRBITS(mac, 0x815, 0x4); 4190 4191 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40); 4192 4193 if (rf->rf_rev == 8) { 4194 loop1_max = 15; 4195 RF_WRITE(mac, 0x43, loop1_max); 4196 } else { 4197 loop1_max = 9; 4198 RF_WRITE(mac, 0x52, 0x0); 4199 RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max); 4200 } 4201 4202 bwi_phy_set_bbp_atten(mac, 11); 4203 4204 if (phy->phy_rev >= 3) 4205 PHY_WRITE(mac, 0x80f, 0xc020); 4206 else 4207 PHY_WRITE(mac, 0x80f, 0x8020); 4208 PHY_WRITE(mac, 0x810, 0); 4209 4210 PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1); 4211 PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800); 4212 PHY_SETBITS(mac, 0x811, 0x100); 4213 PHY_CLRBITS(mac, 0x812, 0x3000); 4214 4215 if ((mac->mac_sc->sc_card_flags & BWI_CARD_F_EXT_LNA) && 4216 phy->phy_rev >= 7) { 4217 PHY_SETBITS(mac, 0x811, 0x800); 4218 PHY_SETBITS(mac, 0x812, 0x8000); 4219 } 4220 RF_CLRBITS(mac, 0x7a, 0xff08); 4221 4222 /* 4223 * Find out 'loop1/loop2', which will be used to calculate 4224 * max loopback gain later 4225 */ 4226 j = 0; 4227 for (i = 0; i < loop1_max; ++i) { 4228 for (j = 0; j < 16; ++j) { 4229 RF_WRITE(mac, 0x43, i); 4230 4231 if (bwi_rf_gain_max_reached(mac, j)) 4232 goto loop1_exit; 4233 } 4234 } 4235 loop1_exit: 4236 loop1 = i; 4237 loop2 = j; 4238 4239 /* 4240 * Find out 'trsw', which will be used to calculate 4241 * TRSW(TX/RX switch) RX gain later 4242 */ 4243 if (loop2 >= 8) { 4244 PHY_SETBITS(mac, 0x812, 0x30); 4245 trsw = 0x1b; 4246 for (i = loop2 - 8; i < 16; ++i) { 4247 trsw -= 3; 4248 if (bwi_rf_gain_max_reached(mac, i)) 4249 break; 4250 } 4251 } else { 4252 trsw = 0x18; 4253 } 4254 4255 /* 4256 * Restore saved PHY/RF registers 4257 */ 4258 /* First 4 saved PHY registers need special processing */ 4259 for (i = 4; i < SAVE_PHY_MAX; ++i) 4260 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]); 4261 4262 bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten); 4263 4264 for (i = 0; i < SAVE_RF_MAX; ++i) 4265 RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 4266 4267 PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3); 4268 DELAY(10); 4269 PHY_WRITE(mac, save_phy_regs[2], save_phy[2]); 4270 PHY_WRITE(mac, save_phy_regs[3], save_phy[3]); 4271 PHY_WRITE(mac, save_phy_regs[0], save_phy[0]); 4272 PHY_WRITE(mac, save_phy_regs[1], save_phy[1]); 4273 4274 /* 4275 * Calculate gains 4276 */ 4277 rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11; 4278 rf->rf_rx_gain = trsw * 2; 4279 DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_INIT, 4280 "lo gain: %u, rx gain: %u\n", 4281 rf->rf_lo_gain, rf->rf_rx_gain); 4282 4283 #undef SAVE_RF_MAX 4284 #undef SAVE_PHY_MAX 4285 } 4286 4287 static void 4288 bwi_rf_init(struct bwi_mac *mac) 4289 { 4290 struct bwi_rf *rf = &mac->mac_rf; 4291 4292 if (rf->rf_type == BWI_RF_T_BCM2060) { 4293 /* TODO: 11A */ 4294 } else { 4295 if (rf->rf_flags & BWI_RF_F_INITED) 4296 RF_WRITE(mac, 0x78, rf->rf_calib); 4297 else 4298 bwi_rf_init_bcm2050(mac); 4299 } 4300 } 4301 4302 static void 4303 bwi_rf_off_11a(struct bwi_mac *mac) 4304 { 4305 RF_WRITE(mac, 0x4, 0xff); 4306 RF_WRITE(mac, 0x5, 0xfb); 4307 4308 PHY_SETBITS(mac, 0x10, 0x8); 4309 PHY_SETBITS(mac, 0x11, 0x8); 4310 4311 PHY_WRITE(mac, 0x15, 0xaa00); 4312 } 4313 4314 static void 4315 bwi_rf_off_11bg(struct bwi_mac *mac) 4316 { 4317 PHY_WRITE(mac, 0x15, 0xaa00); 4318 } 4319 4320 static void 4321 bwi_rf_off_11g_rev5(struct bwi_mac *mac) 4322 { 4323 PHY_SETBITS(mac, 0x811, 0x8c); 4324 PHY_CLRBITS(mac, 0x812, 0x8c); 4325 } 4326 4327 static void 4328 bwi_rf_workaround(struct bwi_mac *mac, uint chan) 4329 { 4330 struct bwi_softc *sc = mac->mac_sc; 4331 struct bwi_rf *rf = &mac->mac_rf; 4332 4333 if (chan == IEEE80211_CHAN_ANY) { 4334 aprint_error_dev(sc->sc_dev, "%s invalid channel!\n", 4335 __func__); 4336 return; 4337 } 4338 4339 if (rf->rf_type != BWI_RF_T_BCM2050 || rf->rf_rev >= 6) 4340 return; 4341 4342 if (chan <= 10) 4343 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4)); 4344 else 4345 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1)); 4346 DELAY(1000); 4347 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan)); 4348 } 4349 4350 static struct bwi_rf_lo * 4351 bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl) 4352 { 4353 uint16_t rf_atten, bbp_atten; 4354 int remap_rf_atten; 4355 4356 remap_rf_atten = 1; 4357 if (tpctl == NULL) { 4358 bbp_atten = 2; 4359 rf_atten = 3; 4360 } else { 4361 if (tpctl->tp_ctrl1 == 3) 4362 remap_rf_atten = 0; 4363 4364 bbp_atten = tpctl->bbp_atten; 4365 rf_atten = tpctl->rf_atten; 4366 4367 if (bbp_atten > 6) 4368 bbp_atten = 6; 4369 } 4370 4371 if (remap_rf_atten) { 4372 #define MAP_MAX 10 4373 static const uint16_t map[MAP_MAX] = 4374 { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 }; 4375 #if 0 4376 KASSERT(rf_atten < MAP_MAX); 4377 rf_atten = map[rf_atten]; 4378 #else 4379 if (rf_atten >= MAP_MAX) { 4380 rf_atten = 0; /* XXX */ 4381 } else { 4382 rf_atten = map[rf_atten]; 4383 } 4384 #endif 4385 #undef MAP_MAX 4386 } 4387 4388 return (bwi_get_rf_lo(mac, rf_atten, bbp_atten)); 4389 } 4390 4391 static void 4392 bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl) 4393 { 4394 const struct bwi_rf_lo *lo; 4395 4396 lo = bwi_rf_lo_find(mac, tpctl); 4397 RF_LO_WRITE(mac, lo); 4398 } 4399 4400 static void 4401 bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo) 4402 { 4403 uint16_t val; 4404 4405 val = (uint8_t)lo->ctrl_lo; 4406 val |= ((uint8_t)lo->ctrl_hi) << 8; 4407 4408 PHY_WRITE(mac, BWI_PHYR_RF_LO, val); 4409 } 4410 4411 static int 4412 bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx) 4413 { 4414 PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8); 4415 PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000); 4416 PHY_SETBITS(mac, 0x15, 0xf000); 4417 4418 DELAY(20); 4419 4420 return ((PHY_READ(mac, 0x2d) >= 0xdfc)); 4421 } 4422 4423 /* XXX use bitmap array */ 4424 static uint16_t 4425 bwi_bitswap4(uint16_t val) 4426 { 4427 uint16_t ret; 4428 4429 ret = (val & 0x8) >> 3; 4430 ret |= (val & 0x4) >> 1; 4431 ret |= (val & 0x2) << 1; 4432 ret |= (val & 0x1) << 3; 4433 4434 return (ret); 4435 } 4436 4437 static uint16_t 4438 bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd) 4439 { 4440 struct bwi_softc *sc = mac->mac_sc; 4441 struct bwi_phy *phy = &mac->mac_phy; 4442 struct bwi_rf *rf = &mac->mac_rf; 4443 uint16_t lo_gain, ext_lna, loop; 4444 4445 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0) 4446 return (0); 4447 4448 lo_gain = rf->rf_lo_gain; 4449 if (rf->rf_rev == 8) 4450 lo_gain += 0x3e; 4451 else 4452 lo_gain += 0x26; 4453 4454 if (lo_gain >= 0x46) { 4455 lo_gain -= 0x46; 4456 ext_lna = 0x3000; 4457 } else if (lo_gain >= 0x3a) { 4458 lo_gain -= 0x3a; 4459 ext_lna = 0x1000; 4460 } else if (lo_gain >= 0x2e) { 4461 lo_gain -= 0x2e; 4462 ext_lna = 0x2000; 4463 } else { 4464 lo_gain -= 0x10; 4465 ext_lna = 0; 4466 } 4467 4468 for (loop = 0; loop < 16; ++loop) { 4469 lo_gain -= (6 * loop); 4470 if (lo_gain < 6) 4471 break; 4472 } 4473 4474 if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) { 4475 if (ext_lna) 4476 ext_lna |= 0x8000; 4477 ext_lna |= (loop << 8); 4478 switch (lpd) { 4479 case 0x011: 4480 return (0x8f92); 4481 case 0x001: 4482 return (0x8092 | ext_lna); 4483 case 0x101: 4484 return (0x2092 | ext_lna); 4485 case 0x100: 4486 return (0x2093 | ext_lna); 4487 default: 4488 panic("unsupported lpd\n"); 4489 } 4490 } else { 4491 ext_lna |= (loop << 8); 4492 switch (lpd) { 4493 case 0x011: 4494 return (0xf92); 4495 case 0x001: 4496 case 0x101: 4497 return (0x92 | ext_lna); 4498 case 0x100: 4499 return (0x93 | ext_lna); 4500 default: 4501 panic("unsupported lpd\n"); 4502 } 4503 } 4504 4505 panic("never reached\n"); 4506 return (0); 4507 } 4508 4509 static void 4510 bwi_rf_init_bcm2050(struct bwi_mac *mac) 4511 { 4512 #define SAVE_RF_MAX 3 4513 #define SAVE_PHY_COMM_MAX 4 4514 #define SAVE_PHY_11G_MAX 6 4515 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 4516 { 0x0043, 0x0051, 0x0052 }; 4517 static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] = 4518 { 0x0015, 0x005a, 0x0059, 0x0058 }; 4519 static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] = 4520 { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 }; 4521 4522 uint16_t save_rf[SAVE_RF_MAX]; 4523 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 4524 uint16_t save_phy_11g[SAVE_PHY_11G_MAX]; 4525 uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0; 4526 uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex; 4527 uint16_t phy812_val; 4528 uint16_t calib; 4529 uint32_t test_lim, test; 4530 struct bwi_softc *sc = mac->mac_sc; 4531 struct bwi_phy *phy = &mac->mac_phy; 4532 struct bwi_rf *rf = &mac->mac_rf; 4533 int i; 4534 4535 /* 4536 * Save registers for later restoring 4537 */ 4538 for (i = 0; i < SAVE_RF_MAX; ++i) 4539 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 4540 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 4541 save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]); 4542 4543 if (phy->phy_mode == IEEE80211_MODE_11B) { 4544 phyr_30 = PHY_READ(mac, 0x30); 4545 bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL); 4546 4547 PHY_WRITE(mac, 0x30, 0xff); 4548 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f); 4549 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4550 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) { 4551 save_phy_11g[i] = PHY_READ(mac, save_phy_regs_11g[i]); 4552 } 4553 4554 PHY_SETBITS(mac, 0x814, 0x3); 4555 PHY_CLRBITS(mac, 0x815, 0x3); 4556 PHY_CLRBITS(mac, 0x429, 0x8000); 4557 PHY_CLRBITS(mac, 0x802, 0x3); 4558 4559 phyr_80f = PHY_READ(mac, 0x80f); 4560 phyr_810 = PHY_READ(mac, 0x810); 4561 4562 if (phy->phy_rev >= 3) 4563 PHY_WRITE(mac, 0x80f, 0xc020); 4564 else 4565 PHY_WRITE(mac, 0x80f, 0x8020); 4566 PHY_WRITE(mac, 0x810, 0); 4567 4568 phy812_val = bwi_phy812_value(mac, 0x011); 4569 PHY_WRITE(mac, 0x812, phy812_val); 4570 if (phy->phy_rev < 7 || 4571 (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0) 4572 PHY_WRITE(mac, 0x811, 0x1b3); 4573 else 4574 PHY_WRITE(mac, 0x811, 0x9b3); 4575 } 4576 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000); 4577 4578 phyr_35 = PHY_READ(mac, 0x35); 4579 PHY_CLRBITS(mac, 0x35, 0x80); 4580 4581 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN); 4582 rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 4583 4584 if (phy->phy_version == 0) { 4585 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122); 4586 } else { 4587 if (phy->phy_version >= 2) 4588 PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40); 4589 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000); 4590 } 4591 4592 calib = bwi_rf_calibval(mac); 4593 4594 if (phy->phy_mode == IEEE80211_MODE_11B) 4595 RF_WRITE(mac, 0x78, 0x26); 4596 4597 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4598 phy812_val = bwi_phy812_value(mac, 0x011); 4599 PHY_WRITE(mac, 0x812, phy812_val); 4600 } 4601 4602 PHY_WRITE(mac, 0x15, 0xbfaf); 4603 PHY_WRITE(mac, 0x2b, 0x1403); 4604 4605 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4606 phy812_val = bwi_phy812_value(mac, 0x001); 4607 PHY_WRITE(mac, 0x812, phy812_val); 4608 } 4609 4610 PHY_WRITE(mac, 0x15, 0xbfa0); 4611 4612 RF_SETBITS(mac, 0x51, 0x4); 4613 if (rf->rf_rev == 8) 4614 RF_WRITE(mac, 0x43, 0x1f); 4615 else { 4616 RF_WRITE(mac, 0x52, 0); 4617 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9); 4618 } 4619 4620 test_lim = 0; 4621 PHY_WRITE(mac, 0x58, 0); 4622 for (i = 0; i < 16; ++i) { 4623 PHY_WRITE(mac, 0x5a, 0x480); 4624 PHY_WRITE(mac, 0x59, 0xc810); 4625 4626 PHY_WRITE(mac, 0x58, 0xd); 4627 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4628 phy812_val = bwi_phy812_value(mac, 0x101); 4629 PHY_WRITE(mac, 0x812, phy812_val); 4630 } 4631 PHY_WRITE(mac, 0x15, 0xafb0); 4632 DELAY(10); 4633 4634 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4635 phy812_val = bwi_phy812_value(mac, 0x101); 4636 PHY_WRITE(mac, 0x812, phy812_val); 4637 } 4638 PHY_WRITE(mac, 0x15, 0xefb0); 4639 DELAY(10); 4640 4641 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4642 phy812_val = bwi_phy812_value(mac, 0x100); 4643 PHY_WRITE(mac, 0x812, phy812_val); 4644 } 4645 PHY_WRITE(mac, 0x15, 0xfff0); 4646 DELAY(20); 4647 4648 test_lim += PHY_READ(mac, 0x2d); 4649 4650 PHY_WRITE(mac, 0x58, 0); 4651 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4652 phy812_val = bwi_phy812_value(mac, 0x101); 4653 PHY_WRITE(mac, 0x812, phy812_val); 4654 } 4655 PHY_WRITE(mac, 0x15, 0xafb0); 4656 } 4657 ++test_lim; 4658 test_lim >>= 9; 4659 4660 DELAY(10); 4661 4662 test = 0; 4663 PHY_WRITE(mac, 0x58, 0); 4664 for (i = 0; i < 16; ++i) { 4665 int j; 4666 4667 rfr_78 = (bwi_bitswap4(i) << 1) | 0x20; 4668 RF_WRITE(mac, 0x78, rfr_78); 4669 DELAY(10); 4670 4671 /* NB: This block is slight different than the above one */ 4672 for (j = 0; j < 16; ++j) { 4673 PHY_WRITE(mac, 0x5a, 0xd80); 4674 PHY_WRITE(mac, 0x59, 0xc810); 4675 4676 PHY_WRITE(mac, 0x58, 0xd); 4677 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4678 phy->phy_rev >= 2) { 4679 phy812_val = bwi_phy812_value(mac, 0x101); 4680 PHY_WRITE(mac, 0x812, phy812_val); 4681 } 4682 PHY_WRITE(mac, 0x15, 0xafb0); 4683 DELAY(10); 4684 4685 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4686 phy->phy_rev >= 2) { 4687 phy812_val = bwi_phy812_value(mac, 0x101); 4688 PHY_WRITE(mac, 0x812, phy812_val); 4689 } 4690 PHY_WRITE(mac, 0x15, 0xefb0); 4691 DELAY(10); 4692 4693 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4694 phy->phy_rev >= 2) { 4695 phy812_val = bwi_phy812_value(mac, 0x100); 4696 PHY_WRITE(mac, 0x812, phy812_val); 4697 } 4698 PHY_WRITE(mac, 0x15, 0xfff0); 4699 DELAY(10); 4700 4701 test += PHY_READ(mac, 0x2d); 4702 4703 PHY_WRITE(mac, 0x58, 0); 4704 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4705 phy->phy_rev >= 2) { 4706 phy812_val = bwi_phy812_value(mac, 0x101); 4707 PHY_WRITE(mac, 0x812, phy812_val); 4708 } 4709 PHY_WRITE(mac, 0x15, 0xafb0); 4710 } 4711 4712 ++test; 4713 test >>= 8; 4714 4715 if (test > test_lim) 4716 break; 4717 } 4718 if (i > 15) 4719 rf->rf_calib = rfr_78; 4720 else 4721 rf->rf_calib = calib; 4722 if (rf->rf_calib != 0xffff) { 4723 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT, 4724 "RF calibration value: 0x%04x\n", rf->rf_calib); 4725 rf->rf_flags |= BWI_RF_F_INITED; 4726 } 4727 4728 /* 4729 * Restore trashes registers 4730 */ 4731 PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]); 4732 4733 for (i = 0; i < SAVE_RF_MAX; ++i) { 4734 int pos = (i + 1) % SAVE_RF_MAX; 4735 4736 RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]); 4737 } 4738 for (i = 1; i < SAVE_PHY_COMM_MAX; ++i) 4739 PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]); 4740 4741 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten); 4742 if (phy->phy_version != 0) 4743 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex); 4744 4745 PHY_WRITE(mac, 0x35, phyr_35); 4746 bwi_rf_workaround(mac, rf->rf_curchan); 4747 4748 if (phy->phy_mode == IEEE80211_MODE_11B) { 4749 PHY_WRITE(mac, 0x30, phyr_30); 4750 CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl); 4751 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4752 /* XXX Spec only says when PHY is linked (gmode) */ 4753 CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000); 4754 4755 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) { 4756 PHY_WRITE(mac, save_phy_regs_11g[i], 4757 save_phy_11g[i]); 4758 } 4759 4760 PHY_WRITE(mac, 0x80f, phyr_80f); 4761 PHY_WRITE(mac, 0x810, phyr_810); 4762 } 4763 4764 #undef SAVE_PHY_11G_MAX 4765 #undef SAVE_PHY_COMM_MAX 4766 #undef SAVE_RF_MAX 4767 } 4768 4769 static uint16_t 4770 bwi_rf_calibval(struct bwi_mac *mac) 4771 { 4772 /* http://bcm-specs.sipsolutions.net/RCCTable */ 4773 static const uint16_t rf_calibvals[] = { 4774 0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf, 4775 0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf 4776 }; 4777 4778 uint16_t val, calib; 4779 int idx; 4780 4781 val = RF_READ(mac, BWI_RFR_BBP_ATTEN); 4782 idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX); 4783 KASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0]))); 4784 4785 calib = rf_calibvals[idx] << 1; 4786 if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT) 4787 calib |= 0x1; 4788 calib |= 0x20; 4789 4790 return (calib); 4791 } 4792 4793 static int32_t 4794 _bwi_adjust_devide(int32_t num, int32_t den) 4795 { 4796 if (num < 0) 4797 return (num / den); 4798 else 4799 return ((num + den / 2) / den); 4800 } 4801 4802 /* 4803 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table 4804 * "calculating table entries" 4805 */ 4806 static int 4807 bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[]) 4808 { 4809 int32_t m1, m2, f, dbm; 4810 int i; 4811 4812 m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32); 4813 m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1); 4814 4815 #define ITER_MAX 16 4816 f = 256; 4817 for (i = 0; i < ITER_MAX; ++i) { 4818 int32_t q, d; 4819 4820 q = _bwi_adjust_devide( 4821 f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048); 4822 d = abs(q - f); 4823 f = q; 4824 4825 if (d < 2) 4826 break; 4827 } 4828 if (i == ITER_MAX) 4829 return (EINVAL); 4830 #undef ITER_MAX 4831 4832 dbm = _bwi_adjust_devide(m1 * f, 8192); 4833 if (dbm < -127) 4834 dbm = -127; 4835 else if (dbm > 128) 4836 dbm = 128; 4837 4838 *txpwr = dbm; 4839 4840 return (0); 4841 } 4842 4843 static int 4844 bwi_rf_map_txpower(struct bwi_mac *mac) 4845 { 4846 struct bwi_softc *sc = mac->mac_sc; 4847 struct bwi_rf *rf = &mac->mac_rf; 4848 struct bwi_phy *phy = &mac->mac_phy; 4849 uint16_t sprom_ofs, val, mask; 4850 int16_t pa_params[3]; 4851 int error = 0, i, ant_gain, reg_txpower_max; 4852 #ifdef BWI_DEBUG 4853 int debug = sc->sc_debug & 4854 (BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH); 4855 #endif 4856 4857 /* 4858 * Find out max TX power 4859 */ 4860 val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR); 4861 if (phy->phy_mode == IEEE80211_MODE_11A) { 4862 rf->rf_txpower_max = __SHIFTOUT(val, 4863 BWI_SPROM_MAX_TXPWR_MASK_11A); 4864 } else { 4865 rf->rf_txpower_max = __SHIFTOUT(val, 4866 BWI_SPROM_MAX_TXPWR_MASK_11BG); 4867 4868 if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) && 4869 phy->phy_mode == IEEE80211_MODE_11G) 4870 rf->rf_txpower_max -= 3; 4871 } 4872 if (rf->rf_txpower_max <= 0) { 4873 aprint_error_dev(sc->sc_dev, 4874 "invalid max txpower in sprom\n"); 4875 rf->rf_txpower_max = 74; 4876 } 4877 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH, 4878 "max txpower from sprom: %d dBm\n", rf->rf_txpower_max); 4879 4880 /* 4881 * Find out region/domain max TX power, which is adjusted 4882 * by antenna gain and 1.5 dBm fluctuation as mentioned 4883 * in v3 spec. 4884 */ 4885 val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN); 4886 if (phy->phy_mode == IEEE80211_MODE_11A) 4887 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A); 4888 else 4889 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG); 4890 if (ant_gain == 0xff) { 4891 /* XXX why this always invalid? */ 4892 aprint_error_dev(sc->sc_dev, 4893 "invalid antenna gain in sprom\n"); 4894 ant_gain = 2; 4895 } 4896 ant_gain *= 4; 4897 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH, 4898 "ant gain %d dBm\n", ant_gain); 4899 4900 reg_txpower_max = 90 - ant_gain - 6; /* XXX magic number */ 4901 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH, 4902 "region/domain max txpower %d dBm\n", reg_txpower_max); 4903 4904 /* 4905 * Force max TX power within region/domain TX power limit 4906 */ 4907 if (rf->rf_txpower_max > reg_txpower_max) 4908 rf->rf_txpower_max = reg_txpower_max; 4909 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH, 4910 "max txpower %d dBm\n", rf->rf_txpower_max); 4911 4912 /* 4913 * Create TSSI to TX power mapping 4914 */ 4915 4916 if (sc->sc_bbp_id == BWI_BBPID_BCM4301 && 4917 rf->rf_type != BWI_RF_T_BCM2050) { 4918 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI; 4919 memcpy(rf->rf_txpower_map0, bwi_txpower_map_11b, 4920 sizeof(rf->rf_txpower_map0)); 4921 goto back; 4922 } 4923 4924 #define IS_VALID_PA_PARAM(p) ((p) != 0 && (p) != -1) 4925 /* 4926 * Extract PA parameters 4927 */ 4928 if (phy->phy_mode == IEEE80211_MODE_11A) 4929 sprom_ofs = BWI_SPROM_PA_PARAM_11A; 4930 else 4931 sprom_ofs = BWI_SPROM_PA_PARAM_11BG; 4932 for (i = 0; i < __arraycount(pa_params); ++i) 4933 pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2)); 4934 4935 for (i = 0; i < __arraycount(pa_params); ++i) { 4936 /* 4937 * If one of the PA parameters from SPROM is not valid, 4938 * fall back to the default values, if there are any. 4939 */ 4940 if (!IS_VALID_PA_PARAM(pa_params[i])) { 4941 const int8_t *txpower_map; 4942 4943 if (phy->phy_mode == IEEE80211_MODE_11A) { 4944 aprint_error_dev(sc->sc_dev, 4945 "no tssi2dbm table for 11a PHY\n"); 4946 return (ENXIO); 4947 } 4948 4949 if (phy->phy_mode == IEEE80211_MODE_11G) { 4950 DPRINTF(sc, 4951 BWI_DBG_RF | BWI_DBG_TXPOWER | 4952 BWI_DBG_ATTACH, 4953 "use default 11g TSSI map\n"); 4954 txpower_map = bwi_txpower_map_11g; 4955 } else { 4956 DPRINTF(sc, 4957 BWI_DBG_RF | BWI_DBG_TXPOWER | 4958 BWI_DBG_ATTACH, 4959 "use default 11b TSSI map\n"); 4960 txpower_map = bwi_txpower_map_11b; 4961 } 4962 4963 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI; 4964 memcpy(rf->rf_txpower_map0, txpower_map, 4965 sizeof(rf->rf_txpower_map0)); 4966 goto back; 4967 } 4968 } 4969 4970 /* 4971 * All of the PA parameters from SPROM are valid. 4972 */ 4973 4974 /* 4975 * Extract idle TSSI from SPROM. 4976 */ 4977 val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI); 4978 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH, 4979 "sprom idle tssi: 0x%04x\n", val); 4980 4981 if (phy->phy_mode == IEEE80211_MODE_11A) 4982 mask = BWI_SPROM_IDLE_TSSI_MASK_11A; 4983 else 4984 mask = BWI_SPROM_IDLE_TSSI_MASK_11BG; 4985 4986 rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask); 4987 if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0)) 4988 rf->rf_idle_tssi0 = 62; 4989 4990 #undef IS_VALID_PA_PARAM 4991 4992 /* 4993 * Calculate TX power map, which is indexed by TSSI 4994 */ 4995 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH, 4996 "TSSI-TX power map:\n"); 4997 for (i = 0; i < BWI_TSSI_MAX; ++i) { 4998 error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i, 4999 pa_params); 5000 if (error) { 5001 aprint_error_dev(sc->sc_dev, 5002 "bwi_rf_calc_txpower failed\n"); 5003 break; 5004 } 5005 #ifdef BWI_DEBUG 5006 if (debug) { 5007 if (i % 8 == 0) { 5008 if (i != 0) 5009 aprint_debug("\n"); 5010 aprint_debug_dev(sc->sc_dev, ""); 5011 } 5012 aprint_debug(" %d", rf->rf_txpower_map0[i]); 5013 } 5014 #endif 5015 } 5016 #ifdef BWI_DEBUG 5017 if (debug) 5018 aprint_debug("\n"); 5019 #endif 5020 back: 5021 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH, 5022 "idle tssi0: %d\n", rf->rf_idle_tssi0); 5023 5024 return (error); 5025 } 5026 5027 static void 5028 bwi_rf_lo_update_11g(struct bwi_mac *mac) 5029 { 5030 struct bwi_softc *sc = mac->mac_sc; 5031 struct ifnet *ifp = &sc->sc_if; 5032 struct bwi_rf *rf = &mac->mac_rf; 5033 struct bwi_phy *phy = &mac->mac_phy; 5034 struct bwi_tpctl *tpctl = &mac->mac_tpctl; 5035 struct rf_saveregs regs; 5036 uint16_t ant_div, chan_ex; 5037 uint8_t devi_ctrl; 5038 uint orig_chan; 5039 5040 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT, "%s enter\n", __func__); 5041 5042 /* 5043 * Save RF/PHY registers for later restoration 5044 */ 5045 orig_chan = rf->rf_curchan; 5046 memset(®s, 0, sizeof(regs)); 5047 5048 if (phy->phy_flags & BWI_PHY_F_LINKED) { 5049 SAVE_PHY_REG(mac, ®s, 429); 5050 SAVE_PHY_REG(mac, ®s, 802); 5051 5052 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff); 5053 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc); 5054 } 5055 5056 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV); 5057 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000); 5058 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 5059 5060 SAVE_PHY_REG(mac, ®s, 15); 5061 SAVE_PHY_REG(mac, ®s, 2a); 5062 SAVE_PHY_REG(mac, ®s, 35); 5063 SAVE_PHY_REG(mac, ®s, 60); 5064 SAVE_RF_REG(mac, ®s, 43); 5065 SAVE_RF_REG(mac, ®s, 7a); 5066 SAVE_RF_REG(mac, ®s, 52); 5067 if (phy->phy_flags & BWI_PHY_F_LINKED) { 5068 SAVE_PHY_REG(mac, ®s, 811); 5069 SAVE_PHY_REG(mac, ®s, 812); 5070 SAVE_PHY_REG(mac, ®s, 814); 5071 SAVE_PHY_REG(mac, ®s, 815); 5072 } 5073 5074 /* Force to channel 6 */ 5075 bwi_rf_set_chan(mac, 6, 0); 5076 5077 if (phy->phy_flags & BWI_PHY_F_LINKED) { 5078 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff); 5079 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc); 5080 bwi_mac_dummy_xmit(mac); 5081 } 5082 RF_WRITE(mac, 0x43, 0x6); 5083 5084 bwi_phy_set_bbp_atten(mac, 2); 5085 5086 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0); 5087 5088 PHY_WRITE(mac, 0x2e, 0x7f); 5089 PHY_WRITE(mac, 0x80f, 0x78); 5090 PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f); 5091 RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0); 5092 PHY_WRITE(mac, 0x2b, 0x203); 5093 PHY_WRITE(mac, 0x2a, 0x8a3); 5094 5095 if (phy->phy_flags & BWI_PHY_F_LINKED) { 5096 PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3); 5097 PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc); 5098 PHY_WRITE(mac, 0x811, 0x1b3); 5099 PHY_WRITE(mac, 0x812, 0xb2); 5100 } 5101 5102 if ((ifp->if_flags & IFF_RUNNING) == 0) 5103 tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac); 5104 PHY_WRITE(mac, 0x80f, 0x8078); 5105 5106 /* 5107 * Measure all RF LO 5108 */ 5109 devi_ctrl = _bwi_rf_lo_update_11g(mac, regs.rf_7a); 5110 5111 /* 5112 * Restore saved RF/PHY registers 5113 */ 5114 if (phy->phy_flags & BWI_PHY_F_LINKED) { 5115 PHY_WRITE(mac, 0x15, 0xe300); 5116 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0); 5117 DELAY(5); 5118 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2); 5119 DELAY(2); 5120 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3); 5121 } else 5122 PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0); 5123 5124 if ((ifp->if_flags & IFF_RUNNING) == 0) 5125 tpctl = NULL; 5126 bwi_rf_lo_adjust(mac, tpctl); 5127 5128 PHY_WRITE(mac, 0x2e, 0x807f); 5129 if (phy->phy_flags & BWI_PHY_F_LINKED) 5130 PHY_WRITE(mac, 0x2f, 0x202); 5131 else 5132 PHY_WRITE(mac, 0x2f, 0x101); 5133 5134 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex); 5135 5136 RESTORE_PHY_REG(mac, ®s, 15); 5137 RESTORE_PHY_REG(mac, ®s, 2a); 5138 RESTORE_PHY_REG(mac, ®s, 35); 5139 RESTORE_PHY_REG(mac, ®s, 60); 5140 5141 RESTORE_RF_REG(mac, ®s, 43); 5142 RESTORE_RF_REG(mac, ®s, 7a); 5143 5144 regs.rf_52 &= 0xf0; 5145 regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf); 5146 RF_WRITE(mac, 0x52, regs.rf_52); 5147 5148 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div); 5149 5150 if (phy->phy_flags & BWI_PHY_F_LINKED) { 5151 RESTORE_PHY_REG(mac, ®s, 811); 5152 RESTORE_PHY_REG(mac, ®s, 812); 5153 RESTORE_PHY_REG(mac, ®s, 814); 5154 RESTORE_PHY_REG(mac, ®s, 815); 5155 RESTORE_PHY_REG(mac, ®s, 429); 5156 RESTORE_PHY_REG(mac, ®s, 802); 5157 } 5158 5159 bwi_rf_set_chan(mac, orig_chan, 1); 5160 } 5161 5162 static uint32_t 5163 bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl) 5164 { 5165 struct bwi_phy *phy = &mac->mac_phy; 5166 uint32_t devi = 0; 5167 int i; 5168 5169 if (phy->phy_flags & BWI_PHY_F_LINKED) 5170 ctrl <<= 8; 5171 5172 for (i = 0; i < 8; ++i) { 5173 if (phy->phy_flags & BWI_PHY_F_LINKED) { 5174 PHY_WRITE(mac, 0x15, 0xe300); 5175 PHY_WRITE(mac, 0x812, ctrl | 0xb0); 5176 DELAY(5); 5177 PHY_WRITE(mac, 0x812, ctrl | 0xb2); 5178 DELAY(2); 5179 PHY_WRITE(mac, 0x812, ctrl | 0xb3); 5180 DELAY(4); 5181 PHY_WRITE(mac, 0x15, 0xf300); 5182 } else { 5183 PHY_WRITE(mac, 0x15, ctrl | 0xefa0); 5184 DELAY(2); 5185 PHY_WRITE(mac, 0x15, ctrl | 0xefe0); 5186 DELAY(4); 5187 PHY_WRITE(mac, 0x15, ctrl | 0xffe0); 5188 } 5189 DELAY(8); 5190 devi += PHY_READ(mac, 0x2d); 5191 } 5192 5193 return (devi); 5194 } 5195 5196 static uint16_t 5197 bwi_rf_get_tp_ctrl2(struct bwi_mac *mac) 5198 { 5199 uint32_t devi_min; 5200 uint16_t tp_ctrl2 = 0; 5201 int i; 5202 5203 RF_WRITE(mac, 0x52, 0); 5204 DELAY(10); 5205 devi_min = bwi_rf_lo_devi_measure(mac, 0); 5206 5207 for (i = 0; i < 16; ++i) { 5208 uint32_t devi; 5209 5210 RF_WRITE(mac, 0x52, i); 5211 DELAY(10); 5212 devi = bwi_rf_lo_devi_measure(mac, 0); 5213 5214 if (devi < devi_min) { 5215 devi_min = devi; 5216 tp_ctrl2 = i; 5217 } 5218 } 5219 5220 return (tp_ctrl2); 5221 } 5222 5223 static uint8_t 5224 _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a) 5225 { 5226 #define RF_ATTEN_LISTSZ 14 5227 #define BBP_ATTEN_MAX 4 /* half */ 5228 static const int rf_atten_list[RF_ATTEN_LISTSZ] = 5229 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 }; 5230 static const int rf_atten_init_list[RF_ATTEN_LISTSZ] = 5231 { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 }; 5232 static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] = 5233 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 }; 5234 5235 struct ifnet *ifp = &mac->mac_sc->sc_if; 5236 struct bwi_rf_lo lo_save, *lo; 5237 uint8_t devi_ctrl = 0; 5238 int idx, adj_rf7a = 0; 5239 5240 memset(&lo_save, 0, sizeof(lo_save)); 5241 for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) { 5242 int init_rf_atten = rf_atten_init_list[idx]; 5243 int rf_atten = rf_atten_list[idx]; 5244 int bbp_atten; 5245 5246 for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) { 5247 uint16_t tp_ctrl2, rf7a; 5248 5249 if ((ifp->if_flags & IFF_RUNNING) == 0) { 5250 if (idx == 0) { 5251 memset(&lo_save, 0, sizeof(lo_save)); 5252 } else if (init_rf_atten < 0) { 5253 lo = bwi_get_rf_lo(mac, 5254 rf_atten, 2 * bbp_atten); 5255 memcpy(&lo_save, lo, sizeof(lo_save)); 5256 } else { 5257 lo = bwi_get_rf_lo(mac, 5258 init_rf_atten, 0); 5259 memcpy(&lo_save, lo, sizeof(lo_save)); 5260 } 5261 5262 devi_ctrl = 0; 5263 adj_rf7a = 0; 5264 5265 /* 5266 * XXX 5267 * Linux driver overflows 'val' 5268 */ 5269 if (init_rf_atten >= 0) { 5270 int val; 5271 5272 val = rf_atten * 2 + bbp_atten; 5273 if (val > 14) { 5274 adj_rf7a = 1; 5275 if (val > 17) 5276 devi_ctrl = 1; 5277 if (val > 19) 5278 devi_ctrl = 2; 5279 } 5280 } 5281 } else { 5282 lo = bwi_get_rf_lo(mac, 5283 rf_atten, 2 * bbp_atten); 5284 if (!bwi_rf_lo_isused(mac, lo)) 5285 continue; 5286 memcpy(&lo_save, lo, sizeof(lo_save)); 5287 5288 devi_ctrl = 3; 5289 adj_rf7a = 0; 5290 } 5291 5292 RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten); 5293 5294 tp_ctrl2 = mac->mac_tpctl.tp_ctrl2; 5295 if (init_rf_atten < 0) 5296 tp_ctrl2 |= (3 << 4); 5297 RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2); 5298 5299 DELAY(10); 5300 5301 bwi_phy_set_bbp_atten(mac, bbp_atten * 2); 5302 5303 rf7a = orig_rf7a & 0xfff0; 5304 if (adj_rf7a) 5305 rf7a |= 0x8; 5306 RF_WRITE(mac, 0x7a, rf7a); 5307 5308 lo = bwi_get_rf_lo(mac, 5309 rf_lo_measure_order[idx], bbp_atten * 2); 5310 bwi_rf_lo_measure_11g(mac, &lo_save, lo, devi_ctrl); 5311 } 5312 } 5313 5314 return (devi_ctrl); 5315 5316 #undef RF_ATTEN_LISTSZ 5317 #undef BBP_ATTEN_MAX 5318 } 5319 5320 static void 5321 bwi_rf_lo_measure_11g(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo, 5322 struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl) 5323 { 5324 #define LO_ADJUST_MIN 1 5325 #define LO_ADJUST_MAX 8 5326 #define LO_ADJUST(hi, lo) { .ctrl_hi = hi, .ctrl_lo = lo } 5327 static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = { 5328 LO_ADJUST(1, 1), 5329 LO_ADJUST(1, 0), 5330 LO_ADJUST(1, -1), 5331 LO_ADJUST(0, -1), 5332 LO_ADJUST(-1, -1), 5333 LO_ADJUST(-1, 0), 5334 LO_ADJUST(-1, 1), 5335 LO_ADJUST(0, 1) 5336 }; 5337 #undef LO_ADJUST 5338 5339 struct bwi_rf_lo lo_min; 5340 uint32_t devi_min; 5341 int found, loop_count, adjust_state; 5342 5343 memcpy(&lo_min, src_lo, sizeof(lo_min)); 5344 RF_LO_WRITE(mac, &lo_min); 5345 devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl); 5346 5347 loop_count = 12; /* XXX */ 5348 adjust_state = 0; 5349 do { 5350 struct bwi_rf_lo lo_base; 5351 int i, fin; 5352 5353 found = 0; 5354 if (adjust_state == 0) { 5355 i = LO_ADJUST_MIN; 5356 fin = LO_ADJUST_MAX; 5357 } else if (adjust_state % 2 == 0) { 5358 i = adjust_state - 1; 5359 fin = adjust_state + 1; 5360 } else { 5361 i = adjust_state - 2; 5362 fin = adjust_state + 2; 5363 } 5364 5365 if (i < LO_ADJUST_MIN) 5366 i += LO_ADJUST_MAX; 5367 KASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN); 5368 5369 if (fin > LO_ADJUST_MAX) 5370 fin -= LO_ADJUST_MAX; 5371 KASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN); 5372 5373 memcpy(&lo_base, &lo_min, sizeof(lo_base)); 5374 for (;;) { 5375 struct bwi_rf_lo lo; 5376 5377 lo.ctrl_hi = lo_base.ctrl_hi + 5378 rf_lo_adjust[i - 1].ctrl_hi; 5379 lo.ctrl_lo = lo_base.ctrl_lo + 5380 rf_lo_adjust[i - 1].ctrl_lo; 5381 5382 if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) { 5383 uint32_t devi; 5384 5385 RF_LO_WRITE(mac, &lo); 5386 devi = bwi_rf_lo_devi_measure(mac, devi_ctrl); 5387 if (devi < devi_min) { 5388 devi_min = devi; 5389 adjust_state = i; 5390 found = 1; 5391 memcpy(&lo_min, &lo, sizeof(lo_min)); 5392 } 5393 } 5394 if (i == fin) 5395 break; 5396 if (i == LO_ADJUST_MAX) 5397 i = LO_ADJUST_MIN; 5398 else 5399 ++i; 5400 } 5401 } while (loop_count-- && found); 5402 5403 memcpy(dst_lo, &lo_min, sizeof(*dst_lo)); 5404 5405 #undef LO_ADJUST_MIN 5406 #undef LO_ADJUST_MAX 5407 } 5408 5409 static void 5410 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac) 5411 { 5412 #define SAVE_RF_MAX 3 5413 #define SAVE_PHY_MAX 8 5414 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 5415 { 0x7a, 0x52, 0x43 }; 5416 static const uint16_t save_phy_regs[SAVE_PHY_MAX] = 5417 { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 }; 5418 5419 struct bwi_softc *sc = mac->mac_sc; 5420 struct bwi_rf *rf = &mac->mac_rf; 5421 struct bwi_phy *phy = &mac->mac_phy; 5422 uint16_t save_rf[SAVE_RF_MAX]; 5423 uint16_t save_phy[SAVE_PHY_MAX]; 5424 uint16_t ant_div, chan_ex; 5425 int16_t nrssi[2]; 5426 int i; 5427 5428 /* 5429 * Save RF/PHY registers for later restoration 5430 */ 5431 for (i = 0; i < SAVE_RF_MAX; ++i) 5432 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 5433 for (i = 0; i < SAVE_PHY_MAX; ++i) 5434 save_phy[i] = PHY_READ(mac, save_phy_regs[i]); 5435 5436 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV); 5437 (void)CSR_READ_2(sc, BWI_BBP_ATTEN); 5438 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 5439 5440 /* 5441 * Calculate nrssi0 5442 */ 5443 if (phy->phy_rev >= 5) 5444 RF_CLRBITS(mac, 0x7a, 0xff80); 5445 else 5446 RF_CLRBITS(mac, 0x7a, 0xfff0); 5447 PHY_WRITE(mac, 0x30, 0xff); 5448 5449 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f); 5450 5451 PHY_WRITE(mac, 0x26, 0); 5452 PHY_SETBITS(mac, 0x15, 0x20); 5453 PHY_WRITE(mac, 0x2a, 0x8a3); 5454 RF_SETBITS(mac, 0x7a, 0x80); 5455 5456 nrssi[0] = (int16_t)PHY_READ(mac, 0x27); 5457 5458 /* 5459 * Calculate nrssi1 5460 */ 5461 RF_CLRBITS(mac, 0x7a, 0xff80); 5462 if (phy->phy_version >= 2) 5463 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40); 5464 else if (phy->phy_version == 0) 5465 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122); 5466 else 5467 CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff); 5468 5469 PHY_WRITE(mac, 0x20, 0x3f3f); 5470 PHY_WRITE(mac, 0x15, 0xf330); 5471 5472 RF_WRITE(mac, 0x5a, 0x60); 5473 RF_CLRBITS(mac, 0x43, 0xff0f); 5474 5475 PHY_WRITE(mac, 0x5a, 0x480); 5476 PHY_WRITE(mac, 0x59, 0x810); 5477 PHY_WRITE(mac, 0x58, 0xd); 5478 5479 DELAY(20); 5480 5481 nrssi[1] = (int16_t)PHY_READ(mac, 0x27); 5482 5483 /* 5484 * Restore saved RF/PHY registers 5485 */ 5486 PHY_WRITE(mac, save_phy_regs[0], save_phy[0]); 5487 RF_WRITE(mac, save_rf_regs[0], save_rf[0]); 5488 5489 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div); 5490 5491 for (i = 1; i < 4; ++i) 5492 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]); 5493 5494 bwi_rf_workaround(mac, rf->rf_curchan); 5495 5496 if (phy->phy_version != 0) 5497 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex); 5498 5499 for (; i < SAVE_PHY_MAX; ++i) 5500 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]); 5501 5502 for (i = 1; i < SAVE_RF_MAX; ++i) 5503 RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 5504 5505 /* 5506 * Install calculated narrow RSSI values 5507 */ 5508 if (nrssi[0] == nrssi[1]) 5509 rf->rf_nrssi_slope = 0x10000; 5510 else 5511 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]); 5512 if (nrssi[0] <= -4) { 5513 rf->rf_nrssi[0] = nrssi[0]; 5514 rf->rf_nrssi[1] = nrssi[1]; 5515 } 5516 5517 #undef SAVE_RF_MAX 5518 #undef SAVE_PHY_MAX 5519 } 5520 5521 static void 5522 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac) 5523 { 5524 #define SAVE_RF_MAX 2 5525 #define SAVE_PHY_COMM_MAX 10 5526 #define SAVE_PHY6_MAX 8 5527 static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 }; 5528 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 5529 0x0001, 0x0811, 0x0812, 0x0814, 5530 0x0815, 0x005a, 0x0059, 0x0058, 5531 0x000a, 0x0003 5532 }; 5533 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 5534 0x002e, 0x002f, 0x080f, 0x0810, 5535 0x0801, 0x0060, 0x0014, 0x0478 5536 }; 5537 5538 struct bwi_phy *phy = &mac->mac_phy; 5539 uint16_t save_rf[SAVE_RF_MAX]; 5540 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 5541 uint16_t save_phy6[SAVE_PHY6_MAX]; 5542 uint16_t rf7b = 0xffff; 5543 int16_t nrssi; 5544 int i, phy6_idx = 0; 5545 5546 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 5547 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]); 5548 for (i = 0; i < SAVE_RF_MAX; ++i) 5549 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 5550 5551 PHY_CLRBITS(mac, 0x429, 0x8000); 5552 PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000); 5553 PHY_SETBITS(mac, 0x811, 0xc); 5554 PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4); 5555 PHY_CLRBITS(mac, 0x802, 0x3); 5556 5557 if (phy->phy_rev >= 6) { 5558 for (i = 0; i < SAVE_PHY6_MAX; ++i) 5559 save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]); 5560 5561 PHY_WRITE(mac, 0x2e, 0); 5562 PHY_WRITE(mac, 0x2f, 0); 5563 PHY_WRITE(mac, 0x80f, 0); 5564 PHY_WRITE(mac, 0x810, 0); 5565 PHY_SETBITS(mac, 0x478, 0x100); 5566 PHY_SETBITS(mac, 0x801, 0x40); 5567 PHY_SETBITS(mac, 0x60, 0x40); 5568 PHY_SETBITS(mac, 0x14, 0x200); 5569 } 5570 5571 RF_SETBITS(mac, 0x7a, 0x70); 5572 RF_SETBITS(mac, 0x7a, 0x80); 5573 5574 DELAY(30); 5575 5576 nrssi = bwi_nrssi_11g(mac); 5577 if (nrssi == 31) { 5578 for (i = 7; i >= 4; --i) { 5579 RF_WRITE(mac, 0x7b, i); 5580 DELAY(20); 5581 nrssi = bwi_nrssi_11g(mac); 5582 if (nrssi < 31 && rf7b == 0xffff) 5583 rf7b = i; 5584 } 5585 if (rf7b == 0xffff) 5586 rf7b = 4; 5587 } else { 5588 struct bwi_gains gains; 5589 5590 RF_CLRBITS(mac, 0x7a, 0xff80); 5591 5592 PHY_SETBITS(mac, 0x814, 0x1); 5593 PHY_CLRBITS(mac, 0x815, 0x1); 5594 PHY_SETBITS(mac, 0x811, 0xc); 5595 PHY_SETBITS(mac, 0x812, 0xc); 5596 PHY_SETBITS(mac, 0x811, 0x30); 5597 PHY_SETBITS(mac, 0x812, 0x30); 5598 PHY_WRITE(mac, 0x5a, 0x480); 5599 PHY_WRITE(mac, 0x59, 0x810); 5600 PHY_WRITE(mac, 0x58, 0xd); 5601 if (phy->phy_version == 0) 5602 PHY_WRITE(mac, 0x3, 0x122); 5603 else 5604 PHY_SETBITS(mac, 0xa, 0x2000); 5605 PHY_SETBITS(mac, 0x814, 0x4); 5606 PHY_CLRBITS(mac, 0x815, 0x4); 5607 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40); 5608 RF_SETBITS(mac, 0x7a, 0xf); 5609 5610 memset(&gains, 0, sizeof(gains)); 5611 gains.tbl_gain1 = 3; 5612 gains.tbl_gain2 = 0; 5613 gains.phy_gain = 1; 5614 bwi_set_gains(mac, &gains); 5615 5616 RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf); 5617 DELAY(30); 5618 5619 nrssi = bwi_nrssi_11g(mac); 5620 if (nrssi == -32) { 5621 for (i = 0; i < 4; ++i) { 5622 RF_WRITE(mac, 0x7b, i); 5623 DELAY(20); 5624 nrssi = bwi_nrssi_11g(mac); 5625 if (nrssi > -31 && rf7b == 0xffff) 5626 rf7b = i; 5627 } 5628 if (rf7b == 0xffff) 5629 rf7b = 3; 5630 } else { 5631 rf7b = 0; 5632 } 5633 } 5634 RF_WRITE(mac, 0x7b, rf7b); 5635 5636 /* 5637 * Restore saved RF/PHY registers 5638 */ 5639 if (phy->phy_rev >= 6) { 5640 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 5641 PHY_WRITE(mac, save_phy6_regs[phy6_idx], 5642 save_phy6[phy6_idx]); 5643 } 5644 } 5645 5646 /* Saved PHY registers 0, 1, 2 are handled later */ 5647 for (i = 3; i < SAVE_PHY_COMM_MAX; ++i) 5648 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 5649 5650 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 5651 RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 5652 5653 PHY_SETBITS(mac, 0x802, 0x3); 5654 PHY_SETBITS(mac, 0x429, 0x8000); 5655 5656 bwi_set_gains(mac, NULL); 5657 5658 if (phy->phy_rev >= 6) { 5659 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 5660 PHY_WRITE(mac, save_phy6_regs[phy6_idx], 5661 save_phy6[phy6_idx]); 5662 } 5663 } 5664 5665 PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 5666 PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 5667 PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 5668 5669 #undef SAVE_RF_MAX 5670 #undef SAVE_PHY_COMM_MAX 5671 #undef SAVE_PHY6_MAX 5672 } 5673 5674 static void 5675 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac) 5676 { 5677 #define SAVE_RF_MAX 3 5678 #define SAVE_PHY_COMM_MAX 4 5679 #define SAVE_PHY3_MAX 8 5680 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 5681 { 0x7a, 0x52, 0x43 }; 5682 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 5683 { 0x15, 0x5a, 0x59, 0x58 }; 5684 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 5685 0x002e, 0x002f, 0x080f, 0x0810, 5686 0x0801, 0x0060, 0x0014, 0x0478 5687 }; 5688 5689 struct bwi_softc *sc = mac->mac_sc; 5690 struct bwi_phy *phy = &mac->mac_phy; 5691 struct bwi_rf *rf = &mac->mac_rf; 5692 uint16_t save_rf[SAVE_RF_MAX]; 5693 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 5694 uint16_t save_phy3[SAVE_PHY3_MAX]; 5695 uint16_t ant_div, bbp_atten, chan_ex; 5696 struct bwi_gains gains; 5697 int16_t nrssi[2]; 5698 int i, phy3_idx = 0; 5699 5700 if (rf->rf_rev >= 9) 5701 return; 5702 else if (rf->rf_rev == 8) 5703 bwi_rf_set_nrssi_ofs_11g(mac); 5704 5705 PHY_CLRBITS(mac, 0x429, 0x8000); 5706 PHY_CLRBITS(mac, 0x802, 0x3); 5707 5708 /* 5709 * Save RF/PHY registers for later restoration 5710 */ 5711 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV); 5712 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000); 5713 5714 for (i = 0; i < SAVE_RF_MAX; ++i) 5715 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 5716 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 5717 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]); 5718 5719 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN); 5720 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 5721 5722 if (phy->phy_rev >= 3) { 5723 for (i = 0; i < SAVE_PHY3_MAX; ++i) 5724 save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]); 5725 5726 PHY_WRITE(mac, 0x2e, 0); 5727 PHY_WRITE(mac, 0x810, 0); 5728 5729 if (phy->phy_rev == 4 || phy->phy_rev == 6 || 5730 phy->phy_rev == 7) { 5731 PHY_SETBITS(mac, 0x478, 0x100); 5732 PHY_SETBITS(mac, 0x810, 0x40); 5733 } else if (phy->phy_rev == 3 || phy->phy_rev == 5) 5734 PHY_CLRBITS(mac, 0x810, 0x40); 5735 5736 PHY_SETBITS(mac, 0x60, 0x40); 5737 PHY_SETBITS(mac, 0x14, 0x200); 5738 } 5739 5740 /* 5741 * Calculate nrssi0 5742 */ 5743 RF_SETBITS(mac, 0x7a, 0x70); 5744 5745 memset(&gains, 0, sizeof(gains)); 5746 gains.tbl_gain1 = 0; 5747 gains.tbl_gain2 = 8; 5748 gains.phy_gain = 0; 5749 bwi_set_gains(mac, &gains); 5750 5751 RF_CLRBITS(mac, 0x7a, 0xff08); 5752 if (phy->phy_rev >= 2) { 5753 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30); 5754 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10); 5755 } 5756 5757 RF_SETBITS(mac, 0x7a, 0x80); 5758 DELAY(20); 5759 nrssi[0] = bwi_nrssi_11g(mac); 5760 5761 /* 5762 * Calculate nrssi1 5763 */ 5764 RF_CLRBITS(mac, 0x7a, 0xff80); 5765 if (phy->phy_version >= 2) 5766 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40); 5767 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000); 5768 5769 RF_SETBITS(mac, 0x7a, 0xf); 5770 PHY_WRITE(mac, 0x15, 0xf330); 5771 if (phy->phy_rev >= 2) { 5772 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20); 5773 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20); 5774 } 5775 5776 memset(&gains, 0, sizeof(gains)); 5777 gains.tbl_gain1 = 3; 5778 gains.tbl_gain2 = 0; 5779 gains.phy_gain = 1; 5780 bwi_set_gains(mac, &gains); 5781 5782 if (rf->rf_rev == 8) { 5783 RF_WRITE(mac, 0x43, 0x1f); 5784 } else { 5785 RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60); 5786 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9); 5787 } 5788 PHY_WRITE(mac, 0x5a, 0x480); 5789 PHY_WRITE(mac, 0x59, 0x810); 5790 PHY_WRITE(mac, 0x58, 0xd); 5791 DELAY(20); 5792 5793 nrssi[1] = bwi_nrssi_11g(mac); 5794 5795 /* 5796 * Install calculated narrow RSSI values 5797 */ 5798 if (nrssi[1] == nrssi[0]) 5799 rf->rf_nrssi_slope = 0x10000; 5800 else 5801 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]); 5802 if (nrssi[0] >= -4) { 5803 rf->rf_nrssi[0] = nrssi[1]; 5804 rf->rf_nrssi[1] = nrssi[0]; 5805 } 5806 5807 /* 5808 * Restore saved RF/PHY registers 5809 */ 5810 if (phy->phy_rev >= 3) { 5811 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 5812 PHY_WRITE(mac, save_phy3_regs[phy3_idx], 5813 save_phy3[phy3_idx]); 5814 } 5815 } 5816 if (phy->phy_rev >= 2) { 5817 PHY_CLRBITS(mac, 0x812, 0x30); 5818 PHY_CLRBITS(mac, 0x811, 0x30); 5819 } 5820 5821 for (i = 0; i < SAVE_RF_MAX; ++i) 5822 RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 5823 5824 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div); 5825 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten); 5826 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex); 5827 5828 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 5829 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 5830 5831 bwi_rf_workaround(mac, rf->rf_curchan); 5832 PHY_SETBITS(mac, 0x802, 0x3); 5833 bwi_set_gains(mac, NULL); 5834 PHY_SETBITS(mac, 0x429, 0x8000); 5835 5836 if (phy->phy_rev >= 3) { 5837 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 5838 PHY_WRITE(mac, save_phy3_regs[phy3_idx], 5839 save_phy3[phy3_idx]); 5840 } 5841 } 5842 5843 bwi_rf_init_sw_nrssi_table(mac); 5844 bwi_rf_set_nrssi_thr_11g(mac); 5845 5846 #undef SAVE_RF_MAX 5847 #undef SAVE_PHY_COMM_MAX 5848 #undef SAVE_PHY3_MAX 5849 } 5850 5851 static void 5852 bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac) 5853 { 5854 struct bwi_rf *rf = &mac->mac_rf; 5855 int d, i; 5856 5857 d = 0x1f - rf->rf_nrssi[0]; 5858 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) { 5859 int val; 5860 5861 val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a; 5862 if (val < 0) 5863 val = 0; 5864 else if (val > 0x3f) 5865 val = 0x3f; 5866 5867 rf->rf_nrssi_table[i] = val; 5868 } 5869 } 5870 5871 static void 5872 bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust) 5873 { 5874 int i; 5875 5876 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) { 5877 int16_t val; 5878 5879 val = bwi_nrssi_read(mac, i); 5880 5881 val -= adjust; 5882 if (val < -32) 5883 val = -32; 5884 else if (val > 31) 5885 val = 31; 5886 5887 bwi_nrssi_write(mac, i, val); 5888 } 5889 } 5890 5891 static void 5892 bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac) 5893 { 5894 struct bwi_rf *rf = &mac->mac_rf; 5895 int32_t thr; 5896 5897 if (rf->rf_type != BWI_RF_T_BCM2050 || 5898 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) 5899 return; 5900 5901 /* 5902 * Calculate nrssi threshold 5903 */ 5904 if (rf->rf_rev >= 6) { 5905 thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32; 5906 thr += 20 * (rf->rf_nrssi[0] + 1); 5907 thr /= 40; 5908 } else { 5909 thr = rf->rf_nrssi[1] - 5; 5910 } 5911 if (thr < 0) 5912 thr = 0; 5913 else if (thr > 0x3e) 5914 thr = 0x3e; 5915 5916 PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B); /* dummy read */ 5917 PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c); 5918 5919 if (rf->rf_rev >= 6) { 5920 PHY_WRITE(mac, 0x87, 0xe0d); 5921 PHY_WRITE(mac, 0x86, 0xc0b); 5922 PHY_WRITE(mac, 0x85, 0xa09); 5923 PHY_WRITE(mac, 0x84, 0x808); 5924 PHY_WRITE(mac, 0x83, 0x808); 5925 PHY_WRITE(mac, 0x82, 0x604); 5926 PHY_WRITE(mac, 0x81, 0x302); 5927 PHY_WRITE(mac, 0x80, 0x100); 5928 } 5929 } 5930 5931 static int32_t 5932 _nrssi_threshold(const struct bwi_rf *rf, int32_t val) 5933 { 5934 val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]); 5935 val += (rf->rf_nrssi[0] << 6); 5936 if (val < 32) 5937 val += 31; 5938 else 5939 val += 32; 5940 val >>= 6; 5941 if (val < -31) 5942 val = -31; 5943 else if (val > 31) 5944 val = 31; 5945 5946 return (val); 5947 } 5948 5949 static void 5950 bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac) 5951 { 5952 int32_t thr1, thr2; 5953 uint16_t thr; 5954 5955 /* 5956 * Find the two nrssi thresholds 5957 */ 5958 if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 || 5959 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) { 5960 int16_t nrssi; 5961 5962 nrssi = bwi_nrssi_read(mac, 0x20); 5963 if (nrssi >= 32) 5964 nrssi -= 64; 5965 5966 if (nrssi < 3) { 5967 thr1 = 0x2b; 5968 thr2 = 0x27; 5969 } else { 5970 thr1 = 0x2d; 5971 thr2 = 0x2b; 5972 } 5973 } else { 5974 /* TODO Interfere mode */ 5975 thr1 = _nrssi_threshold(&mac->mac_rf, 0x11); 5976 thr2 = _nrssi_threshold(&mac->mac_rf, 0xe); 5977 } 5978 5979 #define NRSSI_THR1_MASK 0x003f 5980 #define NRSSI_THR2_MASK 0x0fc0 5981 thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) | 5982 __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK); 5983 PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr); 5984 #undef NRSSI_THR1_MASK 5985 #undef NRSSI_THR2_MASK 5986 } 5987 5988 static void 5989 bwi_rf_clear_tssi(struct bwi_mac *mac) 5990 { 5991 /* XXX use function pointer */ 5992 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) { 5993 /* TODO: 11A */ 5994 } else { 5995 uint16_t val; 5996 int i; 5997 5998 val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) | 5999 __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK); 6000 6001 for (i = 0; i < 2; ++i) { 6002 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 6003 BWI_COMM_MOBJ_TSSI_DS + (i * 2), val); 6004 } 6005 6006 for (i = 0; i < 2; ++i) { 6007 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 6008 BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val); 6009 } 6010 } 6011 } 6012 6013 static void 6014 bwi_rf_clear_state(struct bwi_rf *rf) 6015 { 6016 int i; 6017 6018 rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS; 6019 memset(rf->rf_lo, 0, sizeof(rf->rf_lo)); 6020 memset(rf->rf_lo_used, 0, sizeof(rf->rf_lo_used)); 6021 6022 rf->rf_nrssi_slope = 0; 6023 rf->rf_nrssi[0] = BWI_INVALID_NRSSI; 6024 rf->rf_nrssi[1] = BWI_INVALID_NRSSI; 6025 6026 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) 6027 rf->rf_nrssi_table[i] = i; 6028 6029 rf->rf_lo_gain = 0; 6030 rf->rf_rx_gain = 0; 6031 6032 memcpy(rf->rf_txpower_map, rf->rf_txpower_map0, 6033 sizeof(rf->rf_txpower_map)); 6034 rf->rf_idle_tssi = rf->rf_idle_tssi0; 6035 } 6036 6037 static void 6038 bwi_rf_on_11a(struct bwi_mac *mac) 6039 { 6040 /* TODO: 11A */ 6041 } 6042 6043 static void 6044 bwi_rf_on_11bg(struct bwi_mac *mac) 6045 { 6046 struct bwi_phy *phy = &mac->mac_phy; 6047 6048 PHY_WRITE(mac, 0x15, 0x8000); 6049 PHY_WRITE(mac, 0x15, 0xcc00); 6050 if (phy->phy_flags & BWI_PHY_F_LINKED) 6051 PHY_WRITE(mac, 0x15, 0xc0); 6052 else 6053 PHY_WRITE(mac, 0x15, 0); 6054 6055 bwi_rf_set_chan(mac, 6 /* XXX */, 1); 6056 } 6057 6058 static void 6059 bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode) 6060 { 6061 struct bwi_softc *sc = mac->mac_sc; 6062 struct bwi_phy *phy = &mac->mac_phy; 6063 uint16_t val; 6064 6065 KASSERT(ant_mode == BWI_ANT_MODE_0 || 6066 ant_mode == BWI_ANT_MODE_1 || 6067 ant_mode == BWI_ANT_MODE_AUTO); 6068 6069 HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV); 6070 6071 if (phy->phy_mode == IEEE80211_MODE_11B) { 6072 /* NOTE: v4/v3 conflicts, take v3 */ 6073 if (mac->mac_rev == 2) 6074 val = BWI_ANT_MODE_AUTO; 6075 else 6076 val = ant_mode; 6077 val <<= 7; 6078 PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val); 6079 } else { /* 11a/g */ 6080 /* XXX reg/value naming */ 6081 val = ant_mode << 7; 6082 PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val); 6083 6084 if (ant_mode == BWI_ANT_MODE_AUTO) 6085 PHY_CLRBITS(mac, 0x42b, 0x100); 6086 6087 if (phy->phy_mode == IEEE80211_MODE_11A) { 6088 /* TODO: 11A */ 6089 } else { /* 11g */ 6090 if (ant_mode == BWI_ANT_MODE_AUTO) 6091 PHY_SETBITS(mac, 0x48c, 0x2000); 6092 else 6093 PHY_CLRBITS(mac, 0x48c, 0x2000); 6094 6095 if (phy->phy_rev >= 2) { 6096 PHY_SETBITS(mac, 0x461, 0x10); 6097 PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15); 6098 if (phy->phy_rev == 2) { 6099 PHY_WRITE(mac, 0x427, 0x8); 6100 } else { 6101 PHY_FILT_SETBITS(mac, 0x427, 6102 0xff00, 0x8); 6103 } 6104 6105 if (phy->phy_rev >= 6) 6106 PHY_WRITE(mac, 0x49b, 0xdc); 6107 } 6108 } 6109 } 6110 6111 /* XXX v4 set AUTO_ANTDIV unconditionally */ 6112 if (ant_mode == BWI_ANT_MODE_AUTO) 6113 HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV); 6114 6115 val = ant_mode << 8; 6116 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON, 6117 0xfc3f, val); 6118 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK, 6119 0xfc3f, val); 6120 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP, 6121 0xfc3f, val); 6122 6123 /* XXX what's these */ 6124 if (phy->phy_mode == IEEE80211_MODE_11B) 6125 CSR_SETBITS_2(sc, 0x5e, 0x4); 6126 6127 CSR_WRITE_4(sc, 0x100, 0x1000000); 6128 if (mac->mac_rev < 5) 6129 CSR_WRITE_4(sc, 0x10c, 0x1000000); 6130 6131 mac->mac_rf.rf_ant_mode = ant_mode; 6132 } 6133 6134 static int 6135 bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs) 6136 { 6137 int i; 6138 6139 for (i = 0; i < 4; ) { 6140 uint16_t val; 6141 6142 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i); 6143 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK); 6144 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK); 6145 } 6146 6147 for (i = 0; i < 4; ++i) { 6148 if (tssi[i] == BWI_INVALID_TSSI) 6149 return (EINVAL); 6150 } 6151 6152 return (0); 6153 } 6154 6155 static int 6156 bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr) 6157 { 6158 struct bwi_rf *rf = &mac->mac_rf; 6159 int pwr_idx; 6160 6161 pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi; 6162 #if 0 6163 if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX) 6164 return (EINVAL); 6165 #else 6166 if (pwr_idx < 0) 6167 pwr_idx = 0; 6168 else if (pwr_idx >= BWI_TSSI_MAX) 6169 pwr_idx = BWI_TSSI_MAX - 1; 6170 #endif 6171 *txpwr = rf->rf_txpower_map[pwr_idx]; 6172 6173 return (0); 6174 } 6175 6176 static int 6177 bwi_rf_calc_rssi_bcm2050(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr) 6178 { 6179 uint16_t flags1, flags3; 6180 int rssi, lna_gain; 6181 6182 rssi = hdr->rxh_rssi; 6183 flags1 = le16toh(hdr->rxh_flags1); 6184 flags3 = le16toh(hdr->rxh_flags3); 6185 6186 #define NEW_BCM2050_RSSI 6187 #ifdef NEW_BCM2050_RSSI 6188 if (flags1 & BWI_RXH_F1_OFDM) { 6189 if (rssi > 127) 6190 rssi -= 256; 6191 if (flags3 & BWI_RXH_F3_BCM2050_RSSI) 6192 rssi += 17; 6193 else 6194 rssi -= 4; 6195 return (rssi); 6196 } 6197 6198 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 6199 struct bwi_rf *rf = &mac->mac_rf; 6200 6201 if (rssi >= BWI_NRSSI_TBLSZ) 6202 rssi = BWI_NRSSI_TBLSZ - 1; 6203 6204 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128; 6205 rssi -= 67; 6206 } else { 6207 rssi = ((31 - rssi) * -149) / 128; 6208 rssi -= 68; 6209 } 6210 6211 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G) 6212 return (rssi); 6213 6214 if (flags3 & BWI_RXH_F3_BCM2050_RSSI) 6215 rssi += 20; 6216 6217 lna_gain = __SHIFTOUT(le16toh(hdr->rxh_phyinfo), 6218 BWI_RXH_PHYINFO_LNAGAIN); 6219 /* [TRC: XXX This causes some seriously verbose output. I hope it 6220 just verbose and not actually a symptom of a problem.] 6221 6222 DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_RX, 6223 "lna_gain %d, phyinfo 0x%04x\n", 6224 lna_gain, le16toh(hdr->rxh_phyinfo)); 6225 */ 6226 switch (lna_gain) { 6227 case 0: 6228 rssi += 27; 6229 break; 6230 case 1: 6231 rssi += 6; 6232 break; 6233 case 2: 6234 rssi += 12; 6235 break; 6236 case 3: 6237 /* 6238 * XXX 6239 * According to v3 spec, we should do _nothing_ here, 6240 * but it seems that the result RSSI will be too low 6241 * (relative to what ath(4) says). Raise it a little 6242 * bit. 6243 */ 6244 rssi += 5; 6245 break; 6246 default: 6247 panic("impossible lna gain %d", lna_gain); 6248 } 6249 #else /* !NEW_BCM2050_RSSI */ 6250 lna_gain = 0; /* shut up gcc warning */ 6251 6252 if (flags1 & BWI_RXH_F1_OFDM) { 6253 if (rssi > 127) 6254 rssi -= 256; 6255 rssi = (rssi * 73) / 64; 6256 6257 if (flags3 & BWI_RXH_F3_BCM2050_RSSI) 6258 rssi += 25; 6259 else 6260 rssi -= 3; 6261 return (rssi); 6262 } 6263 6264 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 6265 struct bwi_rf *rf = &mac->mac_rf; 6266 6267 if (rssi >= BWI_NRSSI_TBLSZ) 6268 rssi = BWI_NRSSI_TBLSZ - 1; 6269 6270 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128; 6271 rssi -= 57; 6272 } else { 6273 rssi = ((31 - rssi) * -149) / 128; 6274 rssi -= 68; 6275 } 6276 6277 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G) 6278 return (rssi); 6279 6280 if (flags3 & BWI_RXH_F3_BCM2050_RSSI) 6281 rssi += 25; 6282 #endif /* NEW_BCM2050_RSSI */ 6283 return (rssi); 6284 } 6285 6286 static int 6287 bwi_rf_calc_rssi_bcm2053(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr) 6288 { 6289 uint16_t flags1; 6290 int rssi; 6291 6292 rssi = (((int)hdr->rxh_rssi - 11) * 103) / 64; 6293 6294 flags1 = le16toh(hdr->rxh_flags1); 6295 if (flags1 & BWI_RXH_F1_BCM2053_RSSI) 6296 rssi -= 109; 6297 else 6298 rssi -= 83; 6299 6300 return (rssi); 6301 } 6302 6303 static int 6304 bwi_rf_calc_rssi_bcm2060(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr) 6305 { 6306 int rssi; 6307 6308 rssi = hdr->rxh_rssi; 6309 if (rssi > 127) 6310 rssi -= 256; 6311 6312 return (rssi); 6313 } 6314 6315 static uint16_t 6316 bwi_rf_lo_measure_11b(struct bwi_mac *mac) 6317 { 6318 uint16_t val; 6319 int i; 6320 6321 val = 0; 6322 for (i = 0; i < 10; ++i) { 6323 PHY_WRITE(mac, 0x15, 0xafa0); 6324 DELAY(1); 6325 PHY_WRITE(mac, 0x15, 0xefa0); 6326 DELAY(10); 6327 PHY_WRITE(mac, 0x15, 0xffa0); 6328 DELAY(40); 6329 6330 val += PHY_READ(mac, 0x2c); 6331 } 6332 6333 return (val); 6334 } 6335 6336 static void 6337 bwi_rf_lo_update_11b(struct bwi_mac *mac) 6338 { 6339 struct bwi_softc *sc = mac->mac_sc; 6340 struct bwi_rf *rf = &mac->mac_rf; 6341 struct rf_saveregs regs; 6342 uint16_t rf_val, phy_val, min_val, val; 6343 uint16_t rf52, bphy_ctrl; 6344 int i; 6345 6346 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT, "%s enter\n", __func__); 6347 6348 memset(®s, 0, sizeof(regs)); 6349 bphy_ctrl = 0; 6350 6351 /* 6352 * Save RF/PHY registers for later restoration 6353 */ 6354 SAVE_PHY_REG(mac, ®s, 15); 6355 rf52 = RF_READ(mac, 0x52) & 0xfff0; 6356 if (rf->rf_type == BWI_RF_T_BCM2050) { 6357 SAVE_PHY_REG(mac, ®s, 0a); 6358 SAVE_PHY_REG(mac, ®s, 2a); 6359 SAVE_PHY_REG(mac, ®s, 35); 6360 SAVE_PHY_REG(mac, ®s, 03); 6361 SAVE_PHY_REG(mac, ®s, 01); 6362 SAVE_PHY_REG(mac, ®s, 30); 6363 6364 SAVE_RF_REG(mac, ®s, 43); 6365 SAVE_RF_REG(mac, ®s, 7a); 6366 6367 bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL); 6368 6369 SAVE_RF_REG(mac, ®s, 52); 6370 regs.rf_52 &= 0xf0; 6371 6372 PHY_WRITE(mac, 0x30, 0xff); 6373 CSR_WRITE_2(sc, BWI_PHY_CTRL, 0x3f3f); 6374 PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f); 6375 RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0); 6376 } 6377 6378 PHY_WRITE(mac, 0x15, 0xb000); 6379 6380 if (rf->rf_type == BWI_RF_T_BCM2050) { 6381 PHY_WRITE(mac, 0x2b, 0x203); 6382 PHY_WRITE(mac, 0x2a, 0x8a3); 6383 } else { 6384 PHY_WRITE(mac, 0x2b, 0x1402); 6385 } 6386 6387 /* 6388 * Setup RF signal 6389 */ 6390 rf_val = 0; 6391 min_val = UINT16_MAX; 6392 6393 for (i = 0; i < 4; ++i) { 6394 RF_WRITE(mac, 0x52, rf52 | i); 6395 bwi_rf_lo_measure_11b(mac); /* Ignore return value */ 6396 } 6397 for (i = 0; i < 10; ++i) { 6398 RF_WRITE(mac, 0x52, rf52 | i); 6399 6400 val = bwi_rf_lo_measure_11b(mac) / 10; 6401 if (val < min_val) { 6402 min_val = val; 6403 rf_val = i; 6404 } 6405 } 6406 RF_WRITE(mac, 0x52, rf52 | rf_val); 6407 6408 /* 6409 * Setup PHY signal 6410 */ 6411 phy_val = 0; 6412 min_val = UINT16_MAX; 6413 6414 for (i = -4; i < 5; i += 2) { 6415 int j; 6416 6417 for (j = -4; j < 5; j += 2) { 6418 uint16_t phy2f; 6419 6420 phy2f = (0x100 * i) + j; 6421 if (j < 0) 6422 phy2f += 0x100; 6423 PHY_WRITE(mac, 0x2f, phy2f); 6424 6425 val = bwi_rf_lo_measure_11b(mac) / 10; 6426 if (val < min_val) { 6427 min_val = val; 6428 phy_val = phy2f; 6429 } 6430 } 6431 } 6432 PHY_WRITE(mac, 0x2f, phy_val + 0x101); 6433 6434 /* 6435 * Restore saved RF/PHY registers 6436 */ 6437 if (rf->rf_type == BWI_RF_T_BCM2050) { 6438 RESTORE_PHY_REG(mac, ®s, 0a); 6439 RESTORE_PHY_REG(mac, ®s, 2a); 6440 RESTORE_PHY_REG(mac, ®s, 35); 6441 RESTORE_PHY_REG(mac, ®s, 03); 6442 RESTORE_PHY_REG(mac, ®s, 01); 6443 RESTORE_PHY_REG(mac, ®s, 30); 6444 6445 RESTORE_RF_REG(mac, ®s, 43); 6446 RESTORE_RF_REG(mac, ®s, 7a); 6447 6448 RF_FILT_SETBITS(mac, 0x52, 0xf, regs.rf_52); 6449 6450 CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl); 6451 } 6452 RESTORE_PHY_REG(mac, ®s, 15); 6453 6454 bwi_rf_workaround(mac, rf->rf_curchan); 6455 } 6456 6457 /* INTERFACE */ 6458 6459 static uint16_t 6460 bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs) 6461 { 6462 return (CSR_READ_2(sc, ofs + BWI_SPROM_START)); 6463 } 6464 6465 static void 6466 bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array, 6467 int ndesc, int desc_idx, bus_addr_t paddr, int buf_len, int tx) 6468 { 6469 struct bwi_desc32 *desc = &desc_array[desc_idx]; 6470 uint32_t ctrl, addr, addr_hi, addr_lo; 6471 6472 addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK); 6473 addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK); 6474 6475 addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK) | 6476 __SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK); 6477 6478 ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK) | 6479 __SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK); 6480 if (desc_idx == ndesc - 1) 6481 ctrl |= BWI_DESC32_C_EOR; 6482 if (tx) { 6483 /* XXX */ 6484 ctrl |= BWI_DESC32_C_FRAME_START | 6485 BWI_DESC32_C_FRAME_END | 6486 BWI_DESC32_C_INTR; 6487 } 6488 6489 desc->addr = htole32(addr); 6490 desc->ctrl = htole32(ctrl); 6491 } 6492 6493 static void 6494 bwi_power_on(struct bwi_softc *sc, int with_pll) 6495 { 6496 uint32_t gpio_in, gpio_out, gpio_en, status; 6497 6498 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 6499 6500 if (BWI_IS_SDIO(sc)) { 6501 return; 6502 } 6503 6504 gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); 6505 if (gpio_in & BWI_PCIM_GPIO_PWR_ON) 6506 goto back; 6507 6508 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 6509 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE); 6510 6511 gpio_out |= BWI_PCIM_GPIO_PWR_ON; 6512 gpio_en |= BWI_PCIM_GPIO_PWR_ON; 6513 if (with_pll) { 6514 /* Turn off PLL first */ 6515 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6516 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6517 } 6518 6519 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 6520 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en); 6521 DELAY(1000); 6522 6523 if (with_pll) { 6524 /* Turn on PLL */ 6525 gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF; 6526 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 6527 DELAY(5000); 6528 } 6529 6530 back: 6531 /* [TRC: XXX This looks totally wrong -- what's PCI doing in here?] */ 6532 /* Clear "Signaled Target Abort" */ 6533 status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG); 6534 status &= ~PCI_STATUS_TARGET_TARGET_ABORT; 6535 (sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status); 6536 } 6537 6538 static int 6539 bwi_power_off(struct bwi_softc *sc, int with_pll) 6540 { 6541 uint32_t gpio_out, gpio_en; 6542 6543 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 6544 6545 if (BWI_IS_SDIO(sc)) { 6546 return (0); 6547 } 6548 6549 (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */ 6550 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 6551 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE); 6552 6553 gpio_out &= ~BWI_PCIM_GPIO_PWR_ON; 6554 gpio_en |= BWI_PCIM_GPIO_PWR_ON; 6555 if (with_pll) { 6556 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6557 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6558 } 6559 6560 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 6561 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en); 6562 6563 return (0); 6564 } 6565 6566 static int 6567 bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw, 6568 struct bwi_regwin **old_rw) 6569 { 6570 int error; 6571 6572 if (old_rw != NULL) 6573 *old_rw = NULL; 6574 6575 if (!BWI_REGWIN_EXIST(rw)) 6576 return (EINVAL); 6577 6578 if (sc->sc_cur_regwin != rw) { 6579 error = bwi_regwin_select(sc, rw->rw_id); 6580 if (error) { 6581 aprint_error_dev(sc->sc_dev, 6582 "can't select regwin %d\n", rw->rw_id); 6583 return (error); 6584 } 6585 } 6586 6587 if (old_rw != NULL) 6588 *old_rw = sc->sc_cur_regwin; 6589 sc->sc_cur_regwin = rw; 6590 6591 return (0); 6592 } 6593 6594 static int 6595 bwi_regwin_select(struct bwi_softc *sc, int id) 6596 { 6597 uint32_t win = BWI_PCIM_REGWIN(id); 6598 int i; 6599 6600 #define RETRY_MAX 50 6601 for (i = 0; i < RETRY_MAX; ++i) { 6602 (sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win); 6603 if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win) 6604 return (0); 6605 DELAY(10); 6606 } 6607 #undef RETRY_MAX 6608 6609 return (ENXIO); 6610 } 6611 6612 static void 6613 bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev) 6614 { 6615 uint32_t val; 6616 6617 val = CSR_READ_4(sc, BWI_ID_HI); 6618 *type = BWI_ID_HI_REGWIN_TYPE(val); 6619 *rev = BWI_ID_HI_REGWIN_REV(val); 6620 6621 DPRINTF(sc, BWI_DBG_ATTACH, "regwin: type 0x%03x, rev %d," 6622 " vendor 0x%04x\n", *type, *rev, 6623 __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK)); 6624 } 6625 6626 static void 6627 bwi_led_attach(struct bwi_softc *sc) 6628 { 6629 const uint8_t *led_act = NULL; 6630 uint16_t gpio, val[BWI_LED_MAX]; 6631 int i; 6632 6633 for (i = 0; i < __arraycount(bwi_vendor_led_act); ++i) { 6634 if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) { 6635 led_act = bwi_vendor_led_act[i].led_act; 6636 break; 6637 } 6638 } 6639 if (led_act == NULL) 6640 led_act = bwi_default_led_act; 6641 6642 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01); 6643 val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0); 6644 val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1); 6645 6646 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO23); 6647 val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2); 6648 val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3); 6649 6650 for (i = 0; i < BWI_LED_MAX; ++i) { 6651 struct bwi_led *led = &sc->sc_leds[i]; 6652 6653 if (val[i] == 0xff) { 6654 led->l_act = led_act[i]; 6655 } else { 6656 if (val[i] & BWI_LED_ACT_LOW) 6657 led->l_flags |= BWI_LED_F_ACTLOW; 6658 led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK); 6659 } 6660 led->l_mask = (1 << i); 6661 6662 if (led->l_act == BWI_LED_ACT_BLINK_SLOW || 6663 led->l_act == BWI_LED_ACT_BLINK_POLL || 6664 led->l_act == BWI_LED_ACT_BLINK) { 6665 led->l_flags |= BWI_LED_F_BLINK; 6666 if (led->l_act == BWI_LED_ACT_BLINK_POLL) 6667 led->l_flags |= BWI_LED_F_POLLABLE; 6668 else if (led->l_act == BWI_LED_ACT_BLINK_SLOW) 6669 led->l_flags |= BWI_LED_F_SLOW; 6670 6671 if (sc->sc_blink_led == NULL) { 6672 sc->sc_blink_led = led; 6673 if (led->l_flags & BWI_LED_F_SLOW) 6674 BWI_LED_SLOWDOWN(sc->sc_led_idle); 6675 } 6676 } 6677 6678 DPRINTF(sc, BWI_DBG_LED | BWI_DBG_ATTACH, 6679 "%dth led, act %d, lowact %d\n", i, led->l_act, 6680 led->l_flags & BWI_LED_F_ACTLOW); 6681 } 6682 callout_init(&sc->sc_led_blink_ch, 0); 6683 } 6684 6685 static uint16_t 6686 bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on) 6687 { 6688 if (led->l_flags & BWI_LED_F_ACTLOW) 6689 on = !on; 6690 if (on) 6691 val |= led->l_mask; 6692 else 6693 val &= ~led->l_mask; 6694 6695 return (val); 6696 } 6697 6698 static void 6699 bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate) 6700 { 6701 struct ieee80211com *ic = &sc->sc_ic; 6702 struct ifnet *ifp = &sc->sc_if; 6703 uint16_t val; 6704 int i; 6705 6706 if (nstate == IEEE80211_S_INIT) { 6707 callout_stop(&sc->sc_led_blink_ch); 6708 sc->sc_led_blinking = 0; 6709 } 6710 6711 if ((ifp->if_flags & IFF_RUNNING) == 0) 6712 return; 6713 6714 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); 6715 for (i = 0; i < BWI_LED_MAX; ++i) { 6716 struct bwi_led *led = &sc->sc_leds[i]; 6717 int on; 6718 6719 if (led->l_act == BWI_LED_ACT_UNKN || 6720 led->l_act == BWI_LED_ACT_NULL) 6721 continue; 6722 6723 if ((led->l_flags & BWI_LED_F_BLINK) && 6724 nstate != IEEE80211_S_INIT) 6725 continue; 6726 6727 switch (led->l_act) { 6728 case BWI_LED_ACT_ON: /* Always on */ 6729 on = 1; 6730 break; 6731 case BWI_LED_ACT_OFF: /* Always off */ 6732 case BWI_LED_ACT_5GHZ: /* TODO: 11A */ 6733 on = 0; 6734 break; 6735 default: 6736 on = 1; 6737 switch (nstate) { 6738 case IEEE80211_S_INIT: 6739 on = 0; 6740 break; 6741 case IEEE80211_S_RUN: 6742 if (led->l_act == BWI_LED_ACT_11G && 6743 ic->ic_curmode != IEEE80211_MODE_11G) 6744 on = 0; 6745 break; 6746 default: 6747 if (led->l_act == BWI_LED_ACT_ASSOC) 6748 on = 0; 6749 break; 6750 } 6751 break; 6752 } 6753 6754 val = bwi_led_onoff(led, val, on); 6755 } 6756 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val); 6757 } 6758 6759 static void 6760 bwi_led_event(struct bwi_softc *sc, int event) 6761 { 6762 struct bwi_led *led = sc->sc_blink_led; 6763 int rate; 6764 6765 if (event == BWI_LED_EVENT_POLL) { 6766 if ((led->l_flags & BWI_LED_F_POLLABLE) == 0) 6767 return; 6768 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 6769 return; 6770 } 6771 6772 sc->sc_led_ticks = ticks; 6773 if (sc->sc_led_blinking) 6774 return; 6775 6776 switch (event) { 6777 case BWI_LED_EVENT_RX: 6778 rate = sc->sc_rx_rate; 6779 break; 6780 case BWI_LED_EVENT_TX: 6781 rate = sc->sc_tx_rate; 6782 break; 6783 case BWI_LED_EVENT_POLL: 6784 rate = 0; 6785 break; 6786 default: 6787 panic("unknown LED event %d\n", event); 6788 break; 6789 } 6790 bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur, 6791 bwi_led_duration[rate].off_dur); 6792 } 6793 6794 static void 6795 bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur) 6796 { 6797 struct bwi_led *led = sc->sc_blink_led; 6798 uint16_t val; 6799 6800 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); 6801 val = bwi_led_onoff(led, val, 1); 6802 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val); 6803 6804 if (led->l_flags & BWI_LED_F_SLOW) { 6805 BWI_LED_SLOWDOWN(on_dur); 6806 BWI_LED_SLOWDOWN(off_dur); 6807 } 6808 6809 sc->sc_led_blinking = 1; 6810 sc->sc_led_blink_offdur = off_dur; 6811 6812 callout_reset(&sc->sc_led_blink_ch, on_dur, bwi_led_blink_next, sc); 6813 } 6814 6815 static void 6816 bwi_led_blink_next(void *xsc) 6817 { 6818 struct bwi_softc *sc = xsc; 6819 uint16_t val; 6820 6821 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); 6822 val = bwi_led_onoff(sc->sc_blink_led, val, 0); 6823 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val); 6824 6825 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 6826 bwi_led_blink_end, sc); 6827 } 6828 6829 static void 6830 bwi_led_blink_end(void *xsc) 6831 { 6832 struct bwi_softc *sc = xsc; 6833 6834 sc->sc_led_blinking = 0; 6835 } 6836 6837 static int 6838 bwi_bbp_attach(struct bwi_softc *sc) 6839 { 6840 uint16_t bbp_id, rw_type; 6841 uint8_t rw_rev; 6842 uint32_t info; 6843 int error, nregwin, i, nretry = 0; 6844 6845 /* 6846 * Get 0th regwin information 6847 * NOTE: 0th regwin should exist 6848 */ 6849 retry_com: 6850 error = bwi_regwin_select(sc, 0); 6851 if (error) { 6852 aprint_error_dev(sc->sc_dev, "can't select regwin 0\n"); 6853 return (error); 6854 } 6855 bwi_regwin_info(sc, &rw_type, &rw_rev); 6856 6857 /* Sometimes it takes a few tries to read SDIO common regwin. */ 6858 if (rw_type != BWI_REGWIN_T_COM && 6859 BWI_IS_SDIO(sc) && nretry++ < 5) { 6860 goto retry_com; 6861 } 6862 6863 /* 6864 * Find out BBP id 6865 */ 6866 bbp_id = 0; 6867 info = 0; 6868 if (rw_type == BWI_REGWIN_T_COM) { 6869 info = CSR_READ_4(sc, BWI_INFO); 6870 bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK); 6871 6872 BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev); 6873 6874 sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY); 6875 } else { 6876 uint16_t did = sc->sc_pci_did; 6877 uint8_t revid = sc->sc_pci_revid; 6878 6879 for (i = 0; i < __arraycount(bwi_bbpid_map); ++i) { 6880 if (did >= bwi_bbpid_map[i].did_min && 6881 did <= bwi_bbpid_map[i].did_max) { 6882 bbp_id = bwi_bbpid_map[i].bbp_id; 6883 break; 6884 } 6885 } 6886 if (bbp_id == 0) { 6887 aprint_error_dev(sc->sc_dev, "no BBP id for device id" 6888 " 0x%04x\n", did); 6889 return (ENXIO); 6890 } 6891 6892 info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) | 6893 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK); 6894 } 6895 6896 /* 6897 * Find out number of regwins 6898 */ 6899 nregwin = 0; 6900 if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) { 6901 nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK); 6902 } else { 6903 for (i = 0; i < __arraycount(bwi_regwin_count); ++i) { 6904 if (bwi_regwin_count[i].bbp_id == bbp_id) { 6905 nregwin = bwi_regwin_count[i].nregwin; 6906 break; 6907 } 6908 } 6909 if (nregwin == 0) { 6910 aprint_error_dev(sc->sc_dev, "no number of win for" 6911 " BBP id 0x%04x\n", bbp_id); 6912 return (ENXIO); 6913 } 6914 } 6915 6916 /* Record BBP id/rev for later using */ 6917 sc->sc_bbp_id = bbp_id; 6918 sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK); 6919 sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK); 6920 aprint_normal_dev(sc->sc_dev, 6921 "BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n", 6922 sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg); 6923 DPRINTF(sc, BWI_DBG_ATTACH, "nregwin %d, cap 0x%08x\n", 6924 nregwin, sc->sc_cap); 6925 6926 /* 6927 * Create rest of the regwins 6928 */ 6929 6930 /* Don't re-create common regwin, if it is already created */ 6931 i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0; 6932 6933 for (; i < nregwin; ++i) { 6934 /* 6935 * Get regwin information 6936 */ 6937 error = bwi_regwin_select(sc, i); 6938 if (error) { 6939 aprint_error_dev(sc->sc_dev, "can't select regwin" 6940 " %d\n", i); 6941 return (error); 6942 } 6943 bwi_regwin_info(sc, &rw_type, &rw_rev); 6944 6945 /* 6946 * Try attach: 6947 * 1) Bus (PCI/PCIE) regwin 6948 * 2) MAC regwin 6949 * Ignore rest types of regwin 6950 */ 6951 if (rw_type == BWI_REGWIN_T_BUSPCI || 6952 rw_type == BWI_REGWIN_T_BUSPCIE) { 6953 if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) { 6954 aprint_error_dev(sc->sc_dev, 6955 "bus regwin already exists\n"); 6956 } else { 6957 BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i, 6958 rw_type, rw_rev); 6959 } 6960 } else if (rw_type == BWI_REGWIN_T_MAC) { 6961 /* XXX ignore return value */ 6962 bwi_mac_attach(sc, i, rw_rev); 6963 } 6964 } 6965 6966 /* At least one MAC shold exist */ 6967 if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) { 6968 aprint_error_dev(sc->sc_dev, "no MAC was found\n"); 6969 return (ENXIO); 6970 } 6971 KASSERT(sc->sc_nmac > 0); 6972 6973 /* Bus regwin must exist */ 6974 if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) { 6975 aprint_error_dev(sc->sc_dev, "no bus regwin was found\n"); 6976 return (ENXIO); 6977 } 6978 6979 /* Start with first MAC */ 6980 error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL); 6981 if (error) 6982 return (error); 6983 6984 return (0); 6985 } 6986 6987 static int 6988 bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac) 6989 { 6990 struct bwi_regwin *old, *bus; 6991 uint32_t val; 6992 int error; 6993 6994 bus = &sc->sc_bus_regwin; 6995 KASSERT(sc->sc_cur_regwin == &mac->mac_regwin); 6996 6997 if (BWI_IS_SDIO(sc)) { 6998 sc->sc_flags |= BWI_F_BUS_INITED; 6999 return (0); 7000 } 7001 7002 /* 7003 * Tell bus to generate requested interrupts (PCI and Cardbus only). 7004 */ 7005 if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) { 7006 /* 7007 * NOTE: Read BWI_FLAGS from MAC regwin 7008 */ 7009 val = CSR_READ_4(sc, BWI_FLAGS); 7010 7011 error = bwi_regwin_switch(sc, bus, &old); 7012 if (error) 7013 return (error); 7014 7015 CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK)); 7016 } else { 7017 uint32_t mac_mask; 7018 7019 mac_mask = 1 << mac->mac_id; 7020 7021 error = bwi_regwin_switch(sc, bus, &old); 7022 if (error) 7023 return (error); 7024 7025 val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL); 7026 val |= mac_mask << 8; 7027 (sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val); 7028 } 7029 7030 if (sc->sc_flags & BWI_F_BUS_INITED) 7031 goto back; 7032 7033 if (bus->rw_type == BWI_REGWIN_T_BUSPCI) { 7034 /* 7035 * Enable prefetch and burst 7036 */ 7037 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, 7038 BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST); 7039 7040 if (bus->rw_rev < 5) { 7041 struct bwi_regwin *com = &sc->sc_com_regwin; 7042 7043 /* 7044 * Configure timeouts for bus operation 7045 */ 7046 7047 /* 7048 * Set service timeout and request timeout 7049 */ 7050 CSR_SETBITS_4(sc, BWI_CONF_LO, 7051 __SHIFTIN(BWI_CONF_LO_SERVTO, 7052 BWI_CONF_LO_SERVTO_MASK) | 7053 __SHIFTIN(BWI_CONF_LO_REQTO, 7054 BWI_CONF_LO_REQTO_MASK)); 7055 7056 /* 7057 * If there is common regwin, we switch to that regwin 7058 * and switch back to bus regwin once we have done. 7059 */ 7060 if (BWI_REGWIN_EXIST(com)) { 7061 error = bwi_regwin_switch(sc, com, NULL); 7062 if (error) 7063 return (error); 7064 } 7065 7066 /* Let bus know what we have changed */ 7067 CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC); 7068 CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */ 7069 CSR_WRITE_4(sc, BWI_BUS_DATA, 0); 7070 CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */ 7071 7072 if (BWI_REGWIN_EXIST(com)) { 7073 error = bwi_regwin_switch(sc, bus, NULL); 7074 if (error) 7075 return (error); 7076 } 7077 } else if (bus->rw_rev >= 11) { 7078 /* 7079 * Enable memory read multiple 7080 */ 7081 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM); 7082 } 7083 } else { 7084 /* TODO: PCIE */ 7085 } 7086 7087 sc->sc_flags |= BWI_F_BUS_INITED; 7088 back: 7089 return (bwi_regwin_switch(sc, old, NULL)); 7090 } 7091 7092 static void 7093 bwi_get_card_flags(struct bwi_softc *sc) 7094 { 7095 sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS); 7096 if (sc->sc_card_flags == 0xffff) 7097 sc->sc_card_flags = 0; 7098 7099 if (sc->sc_pci_subvid == PCI_VENDOR_APPLE && 7100 sc->sc_pci_subdid == 0x4e && /* XXX */ 7101 sc->sc_pci_revid > 0x40) 7102 sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9; 7103 7104 DPRINTF(sc, BWI_DBG_ATTACH, "card flags 0x%04x\n", sc->sc_card_flags); 7105 } 7106 7107 static void 7108 bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr) 7109 { 7110 int i; 7111 7112 for (i = 0; i < 3; ++i) { 7113 *((uint16_t *)eaddr + i) = 7114 htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i)); 7115 } 7116 } 7117 7118 static void 7119 bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq) 7120 { 7121 struct bwi_regwin *com; 7122 uint32_t val; 7123 uint div; 7124 int src; 7125 7126 memset(freq, 0, sizeof(*freq)); 7127 com = &sc->sc_com_regwin; 7128 7129 KASSERT(BWI_REGWIN_EXIST(com)); 7130 KASSERT(sc->sc_cur_regwin == com); 7131 KASSERT(sc->sc_cap & BWI_CAP_CLKMODE); 7132 7133 /* 7134 * Calculate clock frequency 7135 */ 7136 src = -1; 7137 div = 0; 7138 if (com->rw_rev < 6) { 7139 val = BWI_IS_SDIO(sc) ? 7140 0 : (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 7141 if (val & BWI_PCIM_GPIO_OUT_CLKSRC) { 7142 src = BWI_CLKSRC_PCI; 7143 div = 64; 7144 } else { 7145 src = BWI_CLKSRC_CS_OSC; 7146 div = 32; 7147 } 7148 } else if (com->rw_rev < 10) { 7149 val = CSR_READ_4(sc, BWI_CLOCK_CTRL); 7150 7151 src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC); 7152 if (src == BWI_CLKSRC_LP_OSC) 7153 div = 1; 7154 else { 7155 div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2; 7156 7157 /* Unknown source */ 7158 if (src >= BWI_CLKSRC_MAX) 7159 src = BWI_CLKSRC_CS_OSC; 7160 } 7161 } else { 7162 val = CSR_READ_4(sc, BWI_CLOCK_INFO); 7163 7164 src = BWI_CLKSRC_CS_OSC; 7165 div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2; 7166 } 7167 7168 KASSERT(src >= 0 && src < BWI_CLKSRC_MAX); 7169 KASSERT(div != 0); 7170 7171 DPRINTF(sc, BWI_DBG_ATTACH, "clksrc %s\n", 7172 src == BWI_CLKSRC_PCI ? "PCI" : 7173 (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC")); 7174 7175 freq->clkfreq_min = bwi_clkfreq[src].freq_min / div; 7176 freq->clkfreq_max = bwi_clkfreq[src].freq_max / div; 7177 7178 DPRINTF(sc, BWI_DBG_ATTACH, "clkfreq min %u, max %u\n", 7179 freq->clkfreq_min, freq->clkfreq_max); 7180 } 7181 7182 static int 7183 bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) 7184 { 7185 struct bwi_regwin *old, *com; 7186 uint32_t clk_ctrl, clk_src; 7187 int error, pwr_off = 0; 7188 7189 com = &sc->sc_com_regwin; 7190 if (!BWI_REGWIN_EXIST(com)) 7191 return (0); 7192 7193 if (com->rw_rev >= 10 || com->rw_rev < 6) 7194 return (0); 7195 7196 /* 7197 * For common regwin whose rev is [6, 10), the chip 7198 * must be capable to change clock mode. 7199 */ 7200 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0) 7201 return (0); 7202 7203 error = bwi_regwin_switch(sc, com, &old); 7204 if (error) 7205 return (error); 7206 7207 if (clk_mode == BWI_CLOCK_MODE_FAST) 7208 bwi_power_on(sc, 0); /* Don't turn on PLL */ 7209 7210 clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL); 7211 clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC); 7212 7213 switch (clk_mode) { 7214 case BWI_CLOCK_MODE_FAST: 7215 clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW; 7216 clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL; 7217 break; 7218 case BWI_CLOCK_MODE_SLOW: 7219 clk_ctrl |= BWI_CLOCK_CTRL_SLOW; 7220 break; 7221 case BWI_CLOCK_MODE_DYN: 7222 clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW | 7223 BWI_CLOCK_CTRL_IGNPLL | 7224 BWI_CLOCK_CTRL_NODYN); 7225 if (clk_src != BWI_CLKSRC_CS_OSC) { 7226 clk_ctrl |= BWI_CLOCK_CTRL_NODYN; 7227 pwr_off = 1; 7228 } 7229 break; 7230 } 7231 CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl); 7232 7233 if (pwr_off) 7234 bwi_power_off(sc, 0); /* Leave PLL as it is */ 7235 7236 return (bwi_regwin_switch(sc, old, NULL)); 7237 } 7238 7239 static int 7240 bwi_set_clock_delay(struct bwi_softc *sc) 7241 { 7242 struct bwi_regwin *old, *com; 7243 int error; 7244 7245 com = &sc->sc_com_regwin; 7246 if (!BWI_REGWIN_EXIST(com)) 7247 return (0); 7248 7249 error = bwi_regwin_switch(sc, com, &old); 7250 if (error) 7251 return (error); 7252 7253 if (sc->sc_bbp_id == BWI_BBPID_BCM4321) { 7254 if (sc->sc_bbp_rev == 0) 7255 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0); 7256 else if (sc->sc_bbp_rev == 1) 7257 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1); 7258 } 7259 7260 if (sc->sc_cap & BWI_CAP_CLKMODE) { 7261 if (com->rw_rev >= 10) 7262 CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000); 7263 else { 7264 struct bwi_clock_freq freq; 7265 7266 bwi_get_clock_freq(sc, &freq); 7267 CSR_WRITE_4(sc, BWI_PLL_ON_DELAY, 7268 howmany(freq.clkfreq_max * 150, 1000000)); 7269 CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY, 7270 howmany(freq.clkfreq_max * 15, 1000000)); 7271 } 7272 } 7273 7274 return (bwi_regwin_switch(sc, old, NULL)); 7275 } 7276 7277 static int 7278 bwi_init(struct ifnet *ifp) 7279 { 7280 struct bwi_softc *sc = ifp->if_softc; 7281 7282 bwi_init_statechg(sc, 1); 7283 7284 return (0); 7285 } 7286 7287 static void 7288 bwi_init_statechg(struct bwi_softc *sc, int statechg) 7289 { 7290 struct ieee80211com *ic = &sc->sc_ic; 7291 struct ifnet *ifp = &sc->sc_if; 7292 struct bwi_mac *mac; 7293 int error; 7294 7295 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 7296 7297 bwi_stop(ifp, statechg); 7298 7299 /* power on cardbus socket */ 7300 if (sc->sc_enable != NULL) 7301 (sc->sc_enable)(sc, 0); 7302 7303 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); 7304 7305 /* TODO: 2 MAC */ 7306 7307 mac = &sc->sc_mac[0]; 7308 error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL); 7309 if (error) 7310 goto back; 7311 7312 error = bwi_mac_init(mac); 7313 if (error) 7314 goto back; 7315 7316 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN); 7317 7318 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 7319 7320 bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */ 7321 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr); 7322 7323 bwi_mac_reset_hwkeys(mac); 7324 7325 if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) { 7326 int i; 7327 7328 #define NRETRY 1000 7329 /* 7330 * Drain any possible pending TX status 7331 */ 7332 for (i = 0; i < NRETRY; ++i) { 7333 if ((CSR_READ_4(sc, BWI_TXSTATUS_0) & 7334 BWI_TXSTATUS_0_MORE) == 0) 7335 break; 7336 CSR_READ_4(sc, BWI_TXSTATUS_1); 7337 } 7338 if (i == NRETRY) 7339 aprint_error_dev(sc->sc_dev, 7340 "can't drain TX status\n"); 7341 #undef NRETRY 7342 } 7343 7344 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G) 7345 bwi_mac_updateslot(mac, 1); 7346 7347 /* Start MAC */ 7348 error = bwi_mac_start(mac); 7349 if (error) 7350 goto back; 7351 7352 ifp->if_flags |= IFF_RUNNING; 7353 ifp->if_flags &= ~IFF_OACTIVE; 7354 7355 /* Enable intrs */ 7356 bwi_enable_intrs(sc, BWI_INIT_INTRS); 7357 7358 if (statechg) { 7359 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 7360 /* [TRC: XXX OpenBSD omits this conditional.] */ 7361 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) 7362 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 7363 } else { 7364 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 7365 } 7366 } else { 7367 ieee80211_new_state(ic, ic->ic_state, -1); 7368 } 7369 7370 back: 7371 if (error) 7372 bwi_stop(ifp, 1); 7373 else 7374 /* [TRC: XXX DragonFlyBD uses ifp->if_start(ifp).] */ 7375 bwi_start(ifp); 7376 7377 DPRINTF(sc, BWI_DBG_MISC, "%s done\n", __func__); 7378 } 7379 7380 static int 7381 bwi_ioctl(struct ifnet *ifp, u_long cmd, void *data) 7382 { 7383 struct bwi_softc *sc = ifp->if_softc; 7384 struct ieee80211com *ic = &sc->sc_ic; 7385 int s, error = 0; 7386 7387 /* [TRC: XXX Superstitiously cargo-culted from wi(4).] */ 7388 if (!device_is_active(sc->sc_dev)) 7389 return (ENXIO); 7390 7391 s = splnet(); 7392 7393 switch (cmd) { 7394 case SIOCSIFFLAGS: 7395 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 7396 break; 7397 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7398 (IFF_UP | IFF_RUNNING)) { 7399 struct bwi_mac *mac; 7400 int promisc = -1; 7401 7402 KASSERT(sc->sc_cur_regwin->rw_type == 7403 BWI_REGWIN_T_MAC); 7404 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7405 7406 if ((ifp->if_flags & IFF_PROMISC) && 7407 (sc->sc_flags & BWI_F_PROMISC) == 0) { 7408 promisc = 1; 7409 sc->sc_flags |= BWI_F_PROMISC; 7410 } else if ((ifp->if_flags & IFF_PROMISC) == 0 && 7411 (sc->sc_flags & BWI_F_PROMISC)) { 7412 promisc = 0; 7413 sc->sc_flags &= ~BWI_F_PROMISC; 7414 } 7415 7416 if (promisc >= 0) 7417 bwi_mac_set_promisc(mac, promisc); 7418 } 7419 7420 if (ifp->if_flags & IFF_UP) { 7421 if (!(ifp->if_flags & IFF_RUNNING)) 7422 bwi_init(ifp); 7423 } else { 7424 if (ifp->if_flags & IFF_RUNNING) 7425 bwi_stop(ifp, 1); 7426 } 7427 break; 7428 7429 case SIOCADDMULTI: 7430 case SIOCDELMULTI: 7431 /* [TRC: Several other drivers appear to have this 7432 copied & pasted, so I'm following suit.] */ 7433 /* XXX no h/w multicast filter? --dyoung */ 7434 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 7435 /* setup multicast filter, etc */ 7436 error = 0; 7437 } 7438 break; 7439 7440 case SIOCS80211CHANNEL: 7441 /* [TRC: Pilfered from OpenBSD. No clue whether it works.] */ 7442 /* allow fast channel switching in monitor mode */ 7443 error = ieee80211_ioctl(ic, cmd, data); 7444 if (error == ENETRESET && 7445 ic->ic_opmode == IEEE80211_M_MONITOR) { 7446 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7447 (IFF_UP | IFF_RUNNING)) { 7448 /* [TRC: XXX ????] */ 7449 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 7450 ic->ic_curchan = ic->ic_ibss_chan; 7451 bwi_set_chan(sc, ic->ic_bss->ni_chan); 7452 } 7453 error = 0; 7454 } 7455 break; 7456 7457 default: 7458 error = ieee80211_ioctl(ic, cmd, data); 7459 break; 7460 } 7461 7462 if (error == ENETRESET) { 7463 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7464 (IFF_UP | IFF_RUNNING) && 7465 /* [TRC: XXX Superstitiously cargo-culted from iwi(4). */ 7466 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) 7467 bwi_init(ifp); 7468 error = 0; 7469 } 7470 7471 splx(s); 7472 7473 return (error); 7474 } 7475 7476 static void 7477 bwi_start(struct ifnet *ifp) 7478 { 7479 struct bwi_softc *sc = ifp->if_softc; 7480 struct ieee80211com *ic = &sc->sc_ic; 7481 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 7482 int trans, idx; 7483 7484 /* [TRC: XXX I'm not sure under which conditions we're actually 7485 supposed to refuse to start, so I'm copying what OpenBSD and 7486 DragonFlyBSD do, even if no one else on NetBSD does it. */ 7487 if ((ifp->if_flags & IFF_OACTIVE) || 7488 (ifp->if_flags & IFF_RUNNING) == 0) 7489 return; 7490 7491 trans = 0; 7492 idx = tbd->tbd_idx; 7493 7494 while (tbd->tbd_buf[idx].tb_mbuf == NULL) { 7495 struct ieee80211_frame *wh; 7496 struct ieee80211_node *ni; 7497 struct mbuf *m; 7498 int mgt_pkt = 0; 7499 7500 IF_DEQUEUE(&ic->ic_mgtq, m); 7501 if (m != NULL) { 7502 ni = M_GETCTX(m, struct ieee80211_node *); 7503 M_CLEARCTX(m); 7504 7505 mgt_pkt = 1; 7506 } else { 7507 struct ether_header *eh; 7508 7509 if (ic->ic_state != IEEE80211_S_RUN) 7510 break; 7511 7512 IFQ_DEQUEUE(&ifp->if_snd, m); 7513 if (m == NULL) 7514 break; 7515 7516 if (m->m_len < sizeof(*eh)) { 7517 m = m_pullup(m, sizeof(*eh)); 7518 if (m == NULL) { 7519 if_statinc(ifp, if_oerrors); 7520 continue; 7521 } 7522 } 7523 eh = mtod(m, struct ether_header *); 7524 7525 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 7526 if (ni == NULL) { 7527 if_statinc(ifp, if_oerrors); 7528 m_freem(m); 7529 continue; 7530 } 7531 7532 /* [TRC: XXX Superstitiously cargo-culted from 7533 ath(4) and wi(4).] */ 7534 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && 7535 (m->m_flags & M_PWR_SAV) == 0) { 7536 ieee80211_pwrsave(ic, ni, m); 7537 ieee80211_free_node(ni); 7538 continue; 7539 } 7540 7541 /* [TRC: XXX I *think* we're supposed to do 7542 this, but honestly I have no clue. We don't 7543 use M_WME_GETAC, so...] */ 7544 if (ieee80211_classify(ic, m, ni)) { 7545 /* [TRC: XXX What debug flag?] */ 7546 DPRINTF(sc, BWI_DBG_MISC, 7547 "%s: discard, classification failure\n", 7548 __func__); 7549 if_statinc(ifp, if_oerrors); 7550 m_freem(m); 7551 ieee80211_free_node(ni); 7552 continue; 7553 } 7554 7555 /* [TRC: XXX wi(4) and awi(4) do this; iwi(4) 7556 doesn't.] */ 7557 if_statinc(ifp, if_opackets); 7558 7559 /* [TRC: XXX When should the packet be 7560 filtered? Different drivers appear to do it 7561 at different times.] */ 7562 /* TODO: PS */ 7563 bpf_mtap(ifp, m, BPF_D_OUT); 7564 m = ieee80211_encap(ic, m, ni); 7565 if (m == NULL) { 7566 if_statinc(ifp, if_oerrors); 7567 ieee80211_free_node(ni); 7568 continue; 7569 } 7570 } 7571 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); 7572 7573 wh = mtod(m, struct ieee80211_frame *); 7574 /* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */ 7575 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 7576 if (ieee80211_crypto_encap(ic, ni, m) == NULL) { 7577 if_statinc(ifp, if_oerrors); 7578 m_freem(m); 7579 ieee80211_free_node(ni); 7580 continue; 7581 } 7582 } 7583 wh = NULL; /* [TRC: XXX Huh?] */ 7584 7585 if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) { 7586 /* 'm' is freed in bwi_encap() if we reach here */ 7587 if_statinc(ifp, if_oerrors); 7588 if (ni != NULL) 7589 ieee80211_free_node(ni); 7590 continue; 7591 } 7592 7593 trans = 1; 7594 tbd->tbd_used++; 7595 idx = (idx + 1) % BWI_TX_NDESC; 7596 7597 if (tbd->tbd_used + BWI_TX_NSPRDESC >= 7598 (BWI_IS_SDIO(sc) ? 32 : BWI_TX_NDESC)) { 7599 ifp->if_flags |= IFF_OACTIVE; 7600 break; 7601 } 7602 } 7603 tbd->tbd_idx = idx; 7604 7605 if (trans) 7606 sc->sc_tx_timer = 5; 7607 ifp->if_timer = 1; 7608 7609 if (BWI_IS_PIO(sc)) { 7610 mutex_enter(&sc->sc_pio_txlock); 7611 if (!STAILQ_EMPTY(&sc->sc_pio_txpend)) { 7612 struct bwi_task *t; 7613 7614 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT); 7615 if (t == NULL) { 7616 device_printf(sc->sc_dev, "no free tasks\n"); 7617 } else { 7618 t->t_ic = &sc->sc_ic; 7619 t->t_cmd = BWI_TASK_TX; 7620 workqueue_enqueue(sc->sc_taskq, &t->t_work, 7621 NULL); 7622 } 7623 } 7624 mutex_exit(&sc->sc_pio_txlock); 7625 } 7626 } 7627 7628 static void 7629 bwi_watchdog(struct ifnet *ifp) 7630 { 7631 struct bwi_softc *sc = ifp->if_softc; 7632 7633 ifp->if_timer = 0; 7634 7635 if ((ifp->if_flags & IFF_RUNNING) == 0 || 7636 !device_is_active(sc->sc_dev)) 7637 return; 7638 7639 if (sc->sc_tx_timer) { 7640 if (--sc->sc_tx_timer == 0) { 7641 aprint_error_dev(sc->sc_dev, "device timeout\n"); 7642 if_statinc(ifp, if_oerrors); 7643 /* TODO */ 7644 /* [TRC: XXX TODO what? Stop the device? 7645 Bring it down? iwi(4) does this.] */ 7646 } else 7647 ifp->if_timer = 1; 7648 } 7649 7650 ieee80211_watchdog(&sc->sc_ic); 7651 } 7652 7653 static void 7654 bwi_stop(struct ifnet *ifp, int state_chg) 7655 { 7656 struct bwi_softc *sc = ifp->if_softc; 7657 struct ieee80211com *ic = &sc->sc_ic; 7658 struct bwi_mac *mac; 7659 int i, error, pwr_off = 0; 7660 7661 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 7662 7663 if (state_chg) 7664 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 7665 else 7666 bwi_newstate_begin(sc, IEEE80211_S_INIT); 7667 7668 if (ifp->if_flags & IFF_RUNNING) { 7669 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7670 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7671 7672 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 7673 7674 bwi_disable_intrs(sc, BWI_ALL_INTRS); 7675 CSR_READ_4(sc, BWI_MAC_INTR_MASK); 7676 bwi_mac_stop(mac); 7677 } 7678 7679 for (i = 0; i < sc->sc_nmac; ++i) { 7680 struct bwi_regwin *old_rw; 7681 7682 mac = &sc->sc_mac[i]; 7683 if ((mac->mac_flags & BWI_MAC_F_INITED) == 0) 7684 continue; 7685 7686 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw); 7687 if (error) 7688 continue; 7689 7690 bwi_mac_shutdown(mac); 7691 pwr_off = 1; 7692 7693 bwi_regwin_switch(sc, old_rw, NULL); 7694 } 7695 7696 if (pwr_off) 7697 bwi_bbp_power_off(sc); 7698 7699 sc->sc_tx_timer = 0; 7700 ifp->if_timer = 0; 7701 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 7702 7703 /* power off cardbus socket */ 7704 if (sc->sc_disable != NULL) 7705 (sc->sc_disable)(sc, 0); 7706 7707 return; 7708 } 7709 7710 static void 7711 bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate) 7712 { 7713 callout_stop(&sc->sc_scan_ch); 7714 callout_stop(&sc->sc_calib_ch); 7715 7716 bwi_led_newstate(sc, nstate); 7717 7718 if (nstate == IEEE80211_S_INIT) 7719 sc->sc_txpwrcb_type = BWI_TXPWR_INIT; 7720 } 7721 7722 static int 7723 bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 7724 { 7725 struct bwi_softc *sc = ic->ic_ifp->if_softc; 7726 struct ieee80211_node *ni; 7727 int error; 7728 7729 /* [TRC: XXX amrr] */ 7730 callout_stop(&sc->sc_amrr_ch); 7731 7732 bwi_newstate_begin(sc, nstate); 7733 7734 if (nstate == IEEE80211_S_INIT) 7735 goto back; 7736 7737 /* [TRC: XXX What channel do we set this to? */ 7738 error = bwi_set_chan(sc, ic->ic_curchan); 7739 if (error) { 7740 aprint_error_dev(sc->sc_dev, "can't set channel to %u\n", 7741 ieee80211_chan2ieee(ic, ic->ic_curchan)); 7742 return (error); 7743 } 7744 7745 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7746 /* Nothing to do */ 7747 } else if (nstate == IEEE80211_S_RUN) { 7748 struct bwi_mac *mac; 7749 7750 ni = ic->ic_bss; 7751 7752 bwi_set_bssid(sc, ic->ic_bss->ni_bssid); 7753 7754 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7755 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7756 7757 /* Initial TX power calibration */ 7758 bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT); 7759 #ifdef notyet 7760 sc->sc_txpwrcb_type = BWI_TXPWR_FORCE; 7761 #else 7762 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB; 7763 #endif 7764 /* [TRC: XXX amrr] */ 7765 if (ic->ic_opmode == IEEE80211_M_STA) { 7766 /* fake a join to init the tx rate */ 7767 bwi_newassoc(ni, 1); 7768 } 7769 7770 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 7771 /* start automatic rate control timer */ 7772 if (ic->ic_fixed_rate == -1) 7773 callout_schedule(&sc->sc_amrr_ch, hz / 2); 7774 } 7775 } else 7776 bwi_set_bssid(sc, bwi_zero_addr); 7777 7778 back: 7779 error = (sc->sc_newstate)(ic, nstate, arg); 7780 7781 if (nstate == IEEE80211_S_SCAN) { 7782 callout_schedule(&sc->sc_scan_ch, 7783 (sc->sc_dwell_time * hz) / 1000); 7784 } else if (nstate == IEEE80211_S_RUN) { 7785 /* XXX 15 seconds */ 7786 callout_schedule(&sc->sc_calib_ch, hz); 7787 } 7788 7789 return (error); 7790 } 7791 7792 static int 7793 bwi_newstate_sdio(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 7794 { 7795 struct bwi_softc *sc = ic->ic_ifp->if_softc; 7796 struct bwi_task *t; 7797 7798 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT); 7799 if (t == NULL) { 7800 device_printf(sc->sc_dev, "no free tasks\n"); 7801 return EIO; 7802 } 7803 7804 t->t_ic = ic; 7805 t->t_cmd = BWI_TASK_NEWSTATE; 7806 t->t_newstate.state = nstate; 7807 t->t_newstate.arg = arg; 7808 workqueue_enqueue(sc->sc_taskq, &t->t_work, NULL); 7809 7810 return 0; 7811 } 7812 7813 static inline bool 7814 bwi_tx_fifo_pkt_valid(struct bwi_softc *sc, u_int len) 7815 { 7816 return len >= sizeof(uint32_t) && len <= sc->sc_pio_fifolen; 7817 } 7818 7819 static inline bool 7820 bwi_tx_fifo_avail(struct bwi_softc *sc, u_int len) 7821 { 7822 return len <= sc->sc_pio_fifoavail; 7823 } 7824 7825 static void 7826 bwi_tx_frame_data_pio(struct bwi_softc *sc, u_int idx, uint32_t *ctl, 7827 uint8_t *buf, u_int buflen) 7828 { 7829 size_t count; 7830 7831 *ctl |= BWI_PIO_TXCTL_VALID_BYTES(4); 7832 CSR_WRITE_4(sc, BWI_PIO_TXCTL(idx), *ctl); 7833 7834 count = buflen / sizeof(uint32_t); 7835 CSR_WRITE_MULTI_4(sc, BWI_PIO_TXDATA(idx), (uint32_t *)buf, count); 7836 buf += count * sizeof(uint32_t); 7837 buflen -= count * sizeof(uint32_t); 7838 if (buflen != 0) { 7839 uint32_t data = 0; 7840 7841 *ctl &= ~BWI_PIO_TXCTL_VALID; 7842 *ctl |= BWI_PIO_TXCTL_VALID_BYTES(buflen); 7843 CSR_WRITE_4(sc, BWI_PIO_TXCTL(idx), *ctl); 7844 7845 memcpy(&data, buf, buflen); 7846 CSR_WRITE_MULTI_4(sc, BWI_PIO_TXDATA(idx), &data, 1); 7847 } 7848 } 7849 7850 static void 7851 bwi_tx_frame_pio(struct bwi_softc *sc, struct bwi_txbuf *tb) 7852 { 7853 struct mbuf *m = tb->tb_mbuf; 7854 const u_int idx = BWI_TX_DATA_RING; 7855 uint32_t ctl; 7856 uint8_t *txbuf = sc->sc_pio_databuf; 7857 u_int pktlen = m_length(m); 7858 7859 m_copydata(m, 0, pktlen, txbuf); 7860 7861 ctl = CSR_READ_4(sc, BWI_PIO_TXCTL(idx)); 7862 ctl |= BWI_PIO_TXCTL_FREADY; 7863 ctl &= ~BWI_PIO_TXCTL_EOF; 7864 7865 bwi_tx_frame_data_pio(sc, idx, &ctl, txbuf, pktlen); 7866 7867 ctl |= BWI_PIO_TXCTL_EOF; 7868 CSR_WRITE_4(sc, BWI_PIO_TXCTL(idx), ctl); 7869 } 7870 7871 static void 7872 bwi_tx_pending(struct bwi_softc *sc) 7873 { 7874 struct ifnet *ifp = &sc->sc_if; 7875 struct bwi_txbuf *tb; 7876 7877 mutex_enter(&sc->sc_pio_txlock); 7878 while ((tb = STAILQ_FIRST(&sc->sc_pio_txpend)) != NULL) { 7879 const u_int pktlen = m_length(tb->tb_mbuf); 7880 7881 if (!bwi_tx_fifo_pkt_valid(sc, pktlen)) { 7882 device_printf(sc->sc_dev, 7883 "dropping large packet (%u bytes)\n", pktlen); 7884 7885 STAILQ_REMOVE_HEAD(&sc->sc_pio_txpend, tb_entry); 7886 if_statinc(ifp, if_oerrors); 7887 m_freem(tb->tb_mbuf); 7888 tb->tb_mbuf = NULL; 7889 continue; 7890 } 7891 7892 if (!bwi_tx_fifo_avail(sc, pktlen)) { 7893 break; 7894 } 7895 7896 STAILQ_REMOVE_HEAD(&sc->sc_pio_txpend, tb_entry); 7897 7898 sc->sc_pio_fifoavail -= roundup(pktlen, 4); 7899 mutex_exit(&sc->sc_pio_txlock); 7900 7901 bwi_tx_frame_pio(sc, tb); 7902 7903 mutex_enter(&sc->sc_pio_txlock); 7904 } 7905 mutex_exit(&sc->sc_pio_txlock); 7906 } 7907 7908 static void 7909 bwi_task(struct work *wk, void *arg) 7910 { 7911 struct bwi_task *t = (struct bwi_task *)wk; 7912 struct ieee80211com *ic = t->t_ic; 7913 struct bwi_softc *sc = ic->ic_ifp->if_softc; 7914 7915 switch (t->t_cmd) { 7916 case BWI_TASK_NEWSTATE: 7917 bwi_newstate(ic, t->t_newstate.state, t->t_newstate.arg); 7918 break; 7919 case BWI_TASK_UPDATESLOT: 7920 bwi_updateslot(ic->ic_ifp); 7921 break; 7922 case BWI_TASK_TX: 7923 bwi_tx_pending(sc); 7924 break; 7925 case BWI_TASK_INIT: 7926 bwi_init(ic->ic_ifp); 7927 break; 7928 case BWI_TASK_CALIBRATE: 7929 bwi_do_calibrate(sc); 7930 break; 7931 default: 7932 panic("bwi: unknown task command %d", t->t_cmd); 7933 } 7934 7935 pool_cache_put(sc->sc_freetask, t); 7936 } 7937 7938 static int 7939 bwi_media_change(struct ifnet *ifp) 7940 { 7941 struct bwi_softc *sc = ifp->if_softc; 7942 int error; 7943 7944 error = ieee80211_media_change(ifp); 7945 if (error != ENETRESET) 7946 return (error); 7947 7948 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) { 7949 if (BWI_IS_SDIO(sc)) { 7950 struct bwi_task *t; 7951 7952 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT); 7953 if (t == NULL) { 7954 device_printf(sc->sc_dev, "no free tasks\n"); 7955 return (ENOBUFS); 7956 } 7957 7958 t->t_ic = &sc->sc_ic; 7959 t->t_cmd = BWI_TASK_INIT; 7960 workqueue_enqueue(sc->sc_taskq, &t->t_work, NULL); 7961 } else { 7962 bwi_init(ifp); 7963 } 7964 } 7965 7966 return (0); 7967 } 7968 7969 /* [TRC: XXX amrr] */ 7970 static void 7971 bwi_iter_func(void *arg, struct ieee80211_node *ni) 7972 { 7973 struct bwi_softc *sc = arg; 7974 struct bwi_node *bn = (struct bwi_node *)ni; 7975 7976 ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn); 7977 } 7978 7979 static void 7980 bwi_amrr_timeout(void *arg) 7981 { 7982 struct bwi_softc *sc = arg; 7983 struct ieee80211com *ic = &sc->sc_ic; 7984 int s; 7985 7986 s = splnet(); 7987 if (ic->ic_opmode == IEEE80211_M_STA) 7988 bwi_iter_func(sc, ic->ic_bss); 7989 else 7990 /* [TRC: XXX I'm making a wild guess about what to 7991 supply for the node table.] */ 7992 ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc); 7993 7994 callout_schedule(&sc->sc_amrr_ch, hz / 2); 7995 splx(s); 7996 } 7997 7998 static void 7999 bwi_newassoc(struct ieee80211_node *ni, int isnew) 8000 { 8001 struct ieee80211com *ic = ni->ni_ic; 8002 struct bwi_softc *sc = ic->ic_ifp->if_softc; 8003 int i; 8004 8005 DPRINTF(sc, BWI_DBG_STATION, "%s\n", __func__); 8006 8007 ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn); 8008 8009 /* set rate to some reasonable initial value */ 8010 for (i = ni->ni_rates.rs_nrates - 1; 8011 i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; 8012 i--); 8013 8014 ni->ni_txrate = i; 8015 } 8016 8017 static struct ieee80211_node * 8018 bwi_node_alloc(struct ieee80211_node_table *nt) 8019 { 8020 struct bwi_node *bn; 8021 8022 bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO); 8023 8024 return ((struct ieee80211_node *)bn); 8025 } 8026 /* [TRC: XXX amrr end] */ 8027 8028 static int 8029 bwi_pio_alloc(struct bwi_softc *sc) 8030 { 8031 struct bwi_mac *mac = &sc->sc_mac[0]; 8032 int i, j, has_txstats; 8033 8034 KASSERT(BWI_IS_PIO(sc)); 8035 8036 if (mac->mac_rev < 8) { 8037 aprint_error_dev(sc->sc_dev, 8038 "driver does not support MAC rev %u in PIO mode\n", 8039 mac->mac_rev); 8040 return EINVAL; 8041 } 8042 8043 has_txstats = (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) != 0; 8044 8045 sc->sc_init_tx_ring = bwi_init_tx_ring_pio; 8046 sc->sc_free_tx_ring = bwi_free_tx_ring_pio; 8047 sc->sc_init_rx_ring = bwi_init_rx_ring_pio; 8048 sc->sc_free_rx_ring = bwi_free_rx_ring_pio; 8049 sc->sc_setup_rxdesc = bwi_setup_rx_desc_pio; 8050 sc->sc_setup_txdesc = bwi_setup_tx_desc_pio; 8051 sc->sc_rxeof = bwi_rxeof_pio; 8052 sc->sc_start_tx = bwi_start_tx_pio; 8053 if (has_txstats) { 8054 sc->sc_init_txstats = bwi_init_txstats_pio; 8055 sc->sc_free_txstats = bwi_free_txstats_pio; 8056 sc->sc_txeof_status = bwi_txeof_status_pio; 8057 } 8058 8059 mutex_init(&sc->sc_pio_txlock, MUTEX_DEFAULT, IPL_SOFTNET); 8060 STAILQ_INIT(&sc->sc_pio_txpend); 8061 8062 sc->sc_pio_fifolen = 2000 - 80; 8063 sc->sc_pio_fifoavail = sc->sc_pio_fifolen; 8064 8065 sc->sc_pio_databuf = kmem_alloc(sc->sc_pio_fifolen, KM_SLEEP); 8066 8067 for (i = 0; i < BWI_TX_NRING; ++i) { 8068 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 8069 for (j = 0; j < BWI_TX_NDESC; ++j) { 8070 tbd->tbd_buf[j].tb_data = tbd; 8071 } 8072 } 8073 8074 return 0; 8075 } 8076 8077 static void 8078 bwi_pio_free(struct bwi_softc *sc) 8079 { 8080 KASSERT(BWI_IS_PIO(sc)); 8081 8082 kmem_free(sc->sc_pio_databuf, sc->sc_pio_fifolen); 8083 mutex_destroy(&sc->sc_pio_txlock); 8084 } 8085 8086 static int 8087 bwi_dma_alloc(struct bwi_softc *sc) 8088 { 8089 int error, i, has_txstats; 8090 /* [TRC: XXX DragonFlyBSD adjusts the low address for different 8091 bus spaces. Should we?] */ 8092 bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0; 8093 uint32_t txrx_ctrl_step = 0; 8094 8095 KASSERT(!BWI_IS_PIO(sc)); 8096 8097 has_txstats = 0; 8098 for (i = 0; i < sc->sc_nmac; ++i) { 8099 if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) { 8100 has_txstats = 1; 8101 break; 8102 } 8103 } 8104 8105 switch (sc->sc_bus_space) { 8106 case BWI_BUS_SPACE_30BIT: 8107 case BWI_BUS_SPACE_32BIT: 8108 desc_sz = sizeof(struct bwi_desc32); 8109 txrx_ctrl_step = 0x20; 8110 8111 sc->sc_init_tx_ring = bwi_init_tx_ring32; 8112 sc->sc_free_tx_ring = bwi_free_tx_ring32; 8113 sc->sc_init_rx_ring = bwi_init_rx_ring32; 8114 sc->sc_free_rx_ring = bwi_free_rx_ring32; 8115 sc->sc_setup_rxdesc = bwi_setup_rx_desc32; 8116 sc->sc_setup_txdesc = bwi_setup_tx_desc32; 8117 sc->sc_rxeof = bwi_rxeof32; 8118 sc->sc_start_tx = bwi_start_tx32; 8119 if (has_txstats) { 8120 sc->sc_init_txstats = bwi_init_txstats32; 8121 sc->sc_free_txstats = bwi_free_txstats32; 8122 sc->sc_txeof_status = bwi_txeof_status32; 8123 } 8124 break; 8125 8126 case BWI_BUS_SPACE_64BIT: 8127 desc_sz = sizeof(struct bwi_desc64); 8128 txrx_ctrl_step = 0x40; 8129 8130 sc->sc_init_tx_ring = bwi_init_tx_ring64; 8131 sc->sc_free_tx_ring = bwi_free_tx_ring64; 8132 sc->sc_init_rx_ring = bwi_init_rx_ring64; 8133 sc->sc_free_rx_ring = bwi_free_rx_ring64; 8134 sc->sc_setup_rxdesc = bwi_setup_rx_desc64; 8135 sc->sc_setup_txdesc = bwi_setup_tx_desc64; 8136 sc->sc_rxeof = bwi_rxeof64; 8137 sc->sc_start_tx = bwi_start_tx64; 8138 if (has_txstats) { 8139 sc->sc_init_txstats = bwi_init_txstats64; 8140 sc->sc_free_txstats = bwi_free_txstats64; 8141 sc->sc_txeof_status = bwi_txeof_status64; 8142 } 8143 break; 8144 } 8145 8146 KASSERT(desc_sz != 0); 8147 KASSERT(txrx_ctrl_step != 0); 8148 8149 tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN); 8150 rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN); 8151 8152 /* [TRC: XXX Using OpenBSD's code, which is rather different 8153 from DragonFlyBSD's.] */ 8154 #define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step) 8155 /* 8156 * Create TX ring DMA stuffs 8157 */ 8158 for (i = 0; i < BWI_TX_NRING; ++i) { 8159 error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1, 8160 tx_ring_sz, 0, BUS_DMA_NOWAIT, 8161 &sc->sc_tx_rdata[i].rdata_dmap); 8162 if (error) { 8163 aprint_error_dev(sc->sc_dev, 8164 "%dth TX ring DMA create failed\n", i); 8165 return (error); 8166 } 8167 error = bwi_dma_ring_alloc(sc, 8168 &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i)); 8169 if (error) { 8170 aprint_error_dev(sc->sc_dev, 8171 "%dth TX ring DMA alloc failed\n", i); 8172 return (error); 8173 } 8174 } 8175 8176 /* 8177 * Create RX ring DMA stuffs 8178 */ 8179 error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1, 8180 rx_ring_sz, 0, BUS_DMA_NOWAIT, 8181 &sc->sc_rx_rdata.rdata_dmap); 8182 if (error) { 8183 aprint_error_dev(sc->sc_dev, "RX ring DMA create failed\n"); 8184 return (error); 8185 } 8186 8187 error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata, 8188 rx_ring_sz, TXRX_CTRL(0)); 8189 if (error) { 8190 aprint_error_dev(sc->sc_dev, "RX ring DMA alloc failed\n"); 8191 return (error); 8192 } 8193 8194 if (has_txstats) { 8195 error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz); 8196 if (error) { 8197 aprint_error_dev(sc->sc_dev, 8198 "TX stats DMA alloc failed\n"); 8199 return (error); 8200 } 8201 } 8202 #undef TXRX_CTRL 8203 8204 return (bwi_dma_mbuf_create(sc)); 8205 } 8206 8207 static void 8208 bwi_dma_free(struct bwi_softc *sc) 8209 { 8210 int i; 8211 8212 KASSERT(!BWI_IS_PIO(sc)); 8213 8214 for (i = 0; i < BWI_TX_NRING; ++i) 8215 bwi_ring_data_free(&sc->sc_tx_rdata[i], sc); 8216 8217 bwi_ring_data_free(&sc->sc_rx_rdata, sc); 8218 bwi_dma_txstats_free(sc); 8219 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1); 8220 } 8221 8222 static void 8223 bwi_ring_data_free(struct bwi_ring_data *rd, struct bwi_softc *sc) 8224 { 8225 if (rd->rdata_desc != NULL) { 8226 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap); 8227 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1); 8228 } 8229 } 8230 8231 static int 8232 bwi_dma_ring_alloc(struct bwi_softc *sc, 8233 struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl) 8234 { 8235 int error, nsegs; 8236 8237 error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0, 8238 &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT); 8239 if (error) { 8240 aprint_error_dev(sc->sc_dev, "can't allocate DMA mem\n"); 8241 return (error); 8242 } 8243 8244 error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs, 8245 size, (void **)&rd->rdata_desc, BUS_DMA_NOWAIT); 8246 if (error) { 8247 aprint_error_dev(sc->sc_dev, "can't map DMA mem\n"); 8248 return (error); 8249 } 8250 8251 error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc, 8252 size, NULL, BUS_DMA_WAITOK); 8253 if (error) { 8254 aprint_error_dev(sc->sc_dev, "can't load DMA mem\n"); 8255 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs); 8256 rd->rdata_desc = NULL; 8257 return (error); 8258 } 8259 8260 rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr; 8261 rd->rdata_txrx_ctrl = txrx_ctrl; 8262 8263 return (0); 8264 } 8265 8266 static int 8267 bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base, 8268 bus_size_t desc_sz) 8269 { 8270 struct bwi_txstats_data *st; 8271 bus_size_t dma_size; 8272 int error, nsegs; 8273 8274 st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO); 8275 sc->sc_txstats = st; 8276 8277 /* 8278 * Create TX stats descriptor DMA stuffs 8279 */ 8280 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN); 8281 8282 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 8283 BUS_DMA_NOWAIT, &st->stats_ring_dmap); 8284 if (error) { 8285 aprint_error_dev(sc->sc_dev, 8286 "can't create txstats ring DMA mem\n"); 8287 return (error); 8288 } 8289 8290 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0, 8291 &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT); 8292 if (error) { 8293 aprint_error_dev(sc->sc_dev, 8294 "can't allocate txstats ring DMA mem\n"); 8295 return (error); 8296 } 8297 8298 error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs, 8299 dma_size, (void **)&st->stats_ring, BUS_DMA_NOWAIT); 8300 if (error) { 8301 aprint_error_dev(sc->sc_dev, 8302 "can't map txstats ring DMA mem\n"); 8303 return (error); 8304 } 8305 8306 error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap, 8307 st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK); 8308 if (error) { 8309 aprint_error_dev(sc->sc_dev, 8310 "can't load txstats ring DMA mem\n"); 8311 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs); 8312 return (error); 8313 } 8314 8315 memset(st->stats_ring, 0, dma_size); 8316 st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr; 8317 8318 /* 8319 * Create TX stats DMA stuffs 8320 */ 8321 dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC, 8322 BWI_ALIGN); 8323 8324 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 8325 BUS_DMA_NOWAIT, &st->stats_dmap); 8326 if (error) { 8327 aprint_error_dev(sc->sc_dev, 8328 "can't create txstats ring DMA mem\n"); 8329 return (error); 8330 } 8331 8332 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0, 8333 &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT); 8334 if (error) { 8335 aprint_error_dev(sc->sc_dev, 8336 "can't allocate txstats DMA mem\n"); 8337 return (error); 8338 } 8339 8340 error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs, 8341 dma_size, (void **)&st->stats, BUS_DMA_NOWAIT); 8342 if (error) { 8343 aprint_error_dev(sc->sc_dev, "can't map txstats DMA mem\n"); 8344 return (error); 8345 } 8346 8347 error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats, 8348 dma_size, NULL, BUS_DMA_WAITOK); 8349 if (error) { 8350 aprint_error_dev(sc->sc_dev, "can't load txstats DMA mem\n"); 8351 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs); 8352 return (error); 8353 } 8354 8355 memset(st->stats, 0, dma_size); 8356 st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr; 8357 st->stats_ctrl_base = ctrl_base; 8358 8359 return (0); 8360 } 8361 8362 static void 8363 bwi_dma_txstats_free(struct bwi_softc *sc) 8364 { 8365 struct bwi_txstats_data *st; 8366 8367 if (sc->sc_txstats == NULL) 8368 return; 8369 st = sc->sc_txstats; 8370 8371 bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap); 8372 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1); 8373 8374 bus_dmamap_unload(sc->sc_dmat, st->stats_dmap); 8375 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1); 8376 8377 free(st, M_DEVBUF); 8378 } 8379 8380 static int 8381 bwi_dma_mbuf_create(struct bwi_softc *sc) 8382 { 8383 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8384 int i, j, k, ntx, error; 8385 8386 ntx = 0; 8387 8388 /* 8389 * Create TX mbuf DMA map 8390 */ 8391 for (i = 0; i < BWI_TX_NRING; ++i) { 8392 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 8393 8394 for (j = 0; j < BWI_TX_NDESC; ++j) { 8395 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 8396 0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap); 8397 if (error) { 8398 aprint_error_dev(sc->sc_dev, 8399 "can't create %dth tbd, %dth DMA map\n", 8400 i, j); 8401 ntx = i; 8402 for (k = 0; k < j; ++k) { 8403 bus_dmamap_destroy(sc->sc_dmat, 8404 tbd->tbd_buf[k].tb_dmap); 8405 } 8406 goto fail; 8407 } 8408 } 8409 } 8410 ntx = BWI_TX_NRING; 8411 8412 /* 8413 * Create RX mbuf DMA map and a spare DMA map 8414 */ 8415 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 8416 BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap); 8417 if (error) { 8418 aprint_error_dev(sc->sc_dev, 8419 "can't create spare RX buf DMA map\n"); 8420 goto fail; 8421 } 8422 8423 for (j = 0; j < BWI_RX_NDESC; ++j) { 8424 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 8425 BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap); 8426 if (error) { 8427 aprint_error_dev(sc->sc_dev, 8428 "can't create %dth RX buf DMA map\n", j); 8429 8430 for (k = 0; k < j; ++k) { 8431 bus_dmamap_destroy(sc->sc_dmat, 8432 rbd->rbd_buf[j].rb_dmap); 8433 } 8434 bus_dmamap_destroy(sc->sc_dmat, 8435 rbd->rbd_tmp_dmap); 8436 goto fail; 8437 } 8438 } 8439 8440 return (0); 8441 fail: 8442 bwi_dma_mbuf_destroy(sc, ntx, 0); 8443 8444 return (error); 8445 } 8446 8447 static void 8448 bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx) 8449 { 8450 int i, j; 8451 8452 for (i = 0; i < ntx; ++i) { 8453 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 8454 8455 for (j = 0; j < BWI_TX_NDESC; ++j) { 8456 struct bwi_txbuf *tb = &tbd->tbd_buf[j]; 8457 8458 if (tb->tb_mbuf != NULL) { 8459 bus_dmamap_unload(sc->sc_dmat, 8460 tb->tb_dmap); 8461 m_freem(tb->tb_mbuf); 8462 } 8463 if (tb->tb_ni != NULL) 8464 ieee80211_free_node(tb->tb_ni); 8465 bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap); 8466 } 8467 } 8468 8469 if (nrx) { 8470 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8471 8472 bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap); 8473 for (j = 0; j < BWI_RX_NDESC; ++j) { 8474 struct bwi_rxbuf *rb = &rbd->rbd_buf[j]; 8475 8476 if (rb->rb_mbuf != NULL) { 8477 bus_dmamap_unload(sc->sc_dmat, 8478 rb->rb_dmap); 8479 m_freem(rb->rb_mbuf); 8480 } 8481 bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap); 8482 } 8483 } 8484 } 8485 8486 static void 8487 bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs) 8488 { 8489 DPRINTF(sc, BWI_DBG_INTR, "enable_intrs 0x%08x\n", enable_intrs); 8490 CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs); 8491 } 8492 8493 static void 8494 bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs) 8495 { 8496 DPRINTF(sc, BWI_DBG_INTR, "disable_intrs 0x%08x\n", disable_intrs); 8497 CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs); 8498 } 8499 8500 static int 8501 bwi_init_tx_ring_pio(struct bwi_softc *sc, int ring_idx) 8502 { 8503 return (0); 8504 } 8505 8506 static int 8507 bwi_init_rx_ring_pio(struct bwi_softc *sc) 8508 { 8509 uint32_t ctrl_base = BWI_TXRX_CTRL_BASE; 8510 uint32_t val; 8511 int error; 8512 8513 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_CTRL); 8514 val |= BWI_TXRX32_CTRL_ENABLE | 8515 BWI_RX32_CTRL_DIRECT_FIFO; 8516 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val); 8517 8518 error = bwi_newbuf(sc, 0, 1); 8519 if (error) { 8520 aprint_error_dev(sc->sc_dev, 8521 "can't allocate RX buffer\n"); 8522 return (error); 8523 } 8524 8525 return (0); 8526 } 8527 8528 static int 8529 bwi_init_txstats_pio(struct bwi_softc *sc) 8530 { 8531 return (0); 8532 } 8533 8534 static void 8535 bwi_setup_rx_desc_pio(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 8536 int buf_len) 8537 { 8538 } 8539 8540 static void 8541 bwi_setup_tx_desc_pio(struct bwi_softc *sc, struct bwi_ring_data *rd, 8542 int buf_idx, bus_addr_t paddr, int buf_len) 8543 { 8544 } 8545 8546 static int 8547 bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx) 8548 { 8549 struct bwi_ring_data *rd; 8550 struct bwi_txbuf_data *tbd; 8551 uint32_t val, addr_hi, addr_lo; 8552 8553 KASSERT(ring_idx < BWI_TX_NRING); 8554 rd = &sc->sc_tx_rdata[ring_idx]; 8555 tbd = &sc->sc_tx_bdata[ring_idx]; 8556 8557 tbd->tbd_idx = 0; 8558 tbd->tbd_used = 0; 8559 8560 memset(rd->rdata_desc, 0, sizeof(struct bwi_desc32) * BWI_TX_NDESC); 8561 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8562 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8563 8564 addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 8565 addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 8566 8567 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 8568 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 8569 BWI_TXRX32_RINGINFO_FUNC_MASK); 8570 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val); 8571 8572 val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 8573 BWI_TXRX32_CTRL_ENABLE; 8574 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val); 8575 8576 return (0); 8577 } 8578 8579 static void 8580 bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base, 8581 bus_addr_t paddr, int hdr_size, int ndesc) 8582 { 8583 uint32_t val, addr_hi, addr_lo; 8584 8585 addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 8586 addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 8587 8588 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 8589 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 8590 BWI_TXRX32_RINGINFO_FUNC_MASK); 8591 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val); 8592 8593 val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) | 8594 __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 8595 BWI_TXRX32_CTRL_ENABLE; 8596 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val); 8597 8598 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 8599 (ndesc - 1) * sizeof(struct bwi_desc32)); 8600 } 8601 8602 static int 8603 bwi_init_rx_ring32(struct bwi_softc *sc) 8604 { 8605 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8606 int i, error; 8607 8608 sc->sc_rx_bdata.rbd_idx = 0; 8609 8610 for (i = 0; i < BWI_RX_NDESC; ++i) { 8611 error = bwi_newbuf(sc, i, 1); 8612 if (error) { 8613 aprint_error_dev(sc->sc_dev, 8614 "can't allocate %dth RX buffer\n", i); 8615 return (error); 8616 } 8617 } 8618 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8619 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8620 8621 bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr, 8622 sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC); 8623 return (0); 8624 } 8625 8626 static int 8627 bwi_init_txstats32(struct bwi_softc *sc) 8628 { 8629 struct bwi_txstats_data *st = sc->sc_txstats; 8630 bus_addr_t stats_paddr; 8631 int i; 8632 8633 memset(st->stats, 0, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats)); 8634 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 8635 st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8636 8637 st->stats_idx = 0; 8638 8639 stats_paddr = st->stats_paddr; 8640 for (i = 0; i < BWI_TXSTATS_NDESC; ++i) { 8641 bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i, 8642 stats_paddr, sizeof(struct bwi_txstats), 0); 8643 stats_paddr += sizeof(struct bwi_txstats); 8644 } 8645 bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0, 8646 st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8647 8648 bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base, 8649 st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC); 8650 8651 return (0); 8652 } 8653 8654 static void 8655 bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 8656 int buf_len) 8657 { 8658 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8659 8660 KASSERT(buf_idx < BWI_RX_NDESC); 8661 bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx, 8662 paddr, buf_len, 0); 8663 } 8664 8665 static void 8666 bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd, 8667 int buf_idx, bus_addr_t paddr, int buf_len) 8668 { 8669 KASSERT(buf_idx < BWI_TX_NDESC); 8670 bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx, 8671 paddr, buf_len, 1); 8672 } 8673 static int 8674 bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx) 8675 { 8676 /* TODO: 64 */ 8677 return (EOPNOTSUPP); 8678 } 8679 8680 static int 8681 bwi_init_rx_ring64(struct bwi_softc *sc) 8682 { 8683 /* TODO: 64 */ 8684 return (EOPNOTSUPP); 8685 } 8686 8687 static int 8688 bwi_init_txstats64(struct bwi_softc *sc) 8689 { 8690 /* TODO: 64 */ 8691 return (EOPNOTSUPP); 8692 } 8693 8694 static void 8695 bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 8696 int buf_len) 8697 { 8698 /* TODO: 64 */ 8699 } 8700 8701 static void 8702 bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd, 8703 int buf_idx, bus_addr_t paddr, int buf_len) 8704 { 8705 /* TODO: 64 */ 8706 } 8707 8708 static int 8709 bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init) 8710 { 8711 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8712 struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx]; 8713 struct bwi_rxbuf_hdr *hdr; 8714 bus_dmamap_t map; 8715 bus_addr_t paddr; 8716 struct mbuf *m; 8717 int error = 0; 8718 8719 KASSERT(buf_idx < BWI_RX_NDESC); 8720 8721 MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA); 8722 if (m == NULL) 8723 return (ENOBUFS); 8724 MCLGET(m, init ? M_WAITOK : M_DONTWAIT); 8725 if ((m->m_flags & M_EXT) == 0) { 8726 error = ENOBUFS; 8727 8728 /* 8729 * If the NIC is up and running, we need to: 8730 * - Clear RX buffer's header. 8731 * - Restore RX descriptor settings. 8732 */ 8733 if (init) 8734 return error; 8735 else 8736 goto back; 8737 } 8738 m->m_len = m->m_pkthdr.len = MCLBYTES; 8739 8740 if (!BWI_IS_PIO(sc)) { 8741 /* 8742 * Try to load RX buf into temporary DMA map 8743 */ 8744 error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m, 8745 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT); 8746 if (error) { 8747 m_freem(m); 8748 8749 /* 8750 * See the comment above 8751 */ 8752 if (init) 8753 return error; 8754 else 8755 goto back; 8756 } 8757 8758 if (!init) 8759 bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap); 8760 } 8761 rxbuf->rb_mbuf = m; 8762 8763 if (!BWI_IS_PIO(sc)) { 8764 /* 8765 * Swap RX buf's DMA map with the loaded temporary one 8766 */ 8767 map = rxbuf->rb_dmap; 8768 rxbuf->rb_dmap = rbd->rbd_tmp_dmap; 8769 rbd->rbd_tmp_dmap = map; 8770 paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr; 8771 rxbuf->rb_paddr = paddr; 8772 } 8773 8774 back: 8775 /* 8776 * Clear RX buf header 8777 */ 8778 hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *); 8779 memset(hdr, 0, sizeof(*hdr)); 8780 if (!BWI_IS_PIO(sc)) { 8781 bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0, 8782 rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8783 } 8784 8785 /* 8786 * Setup RX buf descriptor 8787 */ 8788 (sc->sc_setup_rxdesc)(sc, buf_idx, rxbuf->rb_paddr, 8789 rxbuf->rb_mbuf->m_len - sizeof(*hdr)); 8790 return error; 8791 } 8792 8793 static void 8794 bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs, 8795 const uint8_t *addr) 8796 { 8797 int i; 8798 8799 CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL, 8800 BWI_ADDR_FILTER_CTRL_SET | addr_ofs); 8801 8802 for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) { 8803 uint16_t addr_val; 8804 8805 addr_val = (uint16_t)addr[i * 2] | 8806 (((uint16_t)addr[(i * 2) + 1]) << 8); 8807 CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val); 8808 } 8809 } 8810 8811 static int 8812 bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c) 8813 { 8814 struct ieee80211com *ic = &sc->sc_ic; 8815 struct bwi_mac *mac; 8816 /* uint16_t flags; */ /* [TRC: XXX See below.] */ 8817 uint chan; 8818 8819 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 8820 mac = (struct bwi_mac *)sc->sc_cur_regwin; 8821 8822 chan = ieee80211_chan2ieee(ic, c); 8823 8824 bwi_rf_set_chan(mac, chan, 0); 8825 8826 /* [TRC: XXX DragonFlyBSD sets up radio tap channel frequency 8827 and flags here. OpenBSD does not, and appears to do so 8828 later (in bwi_rxeof and bwi_encap).] */ 8829 8830 return (0); 8831 } 8832 8833 static void 8834 bwi_next_scan(void *xsc) 8835 { 8836 struct bwi_softc *sc = xsc; 8837 struct ieee80211com *ic = &sc->sc_ic; 8838 int s; 8839 8840 s = splnet(); 8841 8842 if (ic->ic_state == IEEE80211_S_SCAN) 8843 ieee80211_next_scan(ic); 8844 8845 splx(s); 8846 } 8847 8848 static int 8849 bwi_rxeof(struct bwi_softc *sc, int end_idx) 8850 { 8851 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8852 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8853 struct ieee80211com *ic = &sc->sc_ic; 8854 struct ifnet *ifp = &sc->sc_if; 8855 int s, idx, rx_data = 0; 8856 8857 idx = rbd->rbd_idx; 8858 while (idx != end_idx) { 8859 struct bwi_rxbuf *rb = &rbd->rbd_buf[idx]; 8860 struct bwi_rxbuf_hdr *hdr; 8861 struct ieee80211_frame_min *wh; 8862 struct ieee80211_node *ni; 8863 struct mbuf *m; 8864 const void *plcp; 8865 uint16_t flags2; 8866 int buflen, wh_ofs, hdr_extra, rssi, type, rate; 8867 8868 m = rb->rb_mbuf; 8869 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0, 8870 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 8871 8872 if (bwi_newbuf(sc, idx, 0)) { 8873 if_statinc(ifp, if_ierrors); 8874 goto next; 8875 } 8876 8877 hdr = mtod(m, struct bwi_rxbuf_hdr *); 8878 flags2 = le16toh(hdr->rxh_flags2); 8879 8880 hdr_extra = 0; 8881 if (flags2 & BWI_RXH_F2_TYPE2FRAME) 8882 hdr_extra = 2; 8883 wh_ofs = hdr_extra + 6; /* XXX magic number */ 8884 8885 buflen = le16toh(hdr->rxh_buflen); 8886 if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { 8887 aprint_error_dev(sc->sc_dev, "short frame %d," 8888 " hdr_extra %d\n", buflen, hdr_extra); 8889 if_statinc(ifp, if_ierrors); 8890 m_freem(m); 8891 goto next; 8892 } 8893 8894 plcp = ((const uint8_t *)(hdr + 1) + hdr_extra); 8895 rssi = bwi_calc_rssi(sc, hdr); 8896 8897 m_set_rcvif(m, ifp); 8898 m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); 8899 m_adj(m, sizeof(*hdr) + wh_ofs); 8900 8901 if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM) 8902 rate = bwi_ofdm_plcp2rate(plcp); 8903 else 8904 rate = bwi_ds_plcp2rate(plcp); 8905 8906 s = splnet(); 8907 8908 /* RX radio tap */ 8909 if (sc->sc_drvbpf != NULL) { 8910 struct mbuf mb; 8911 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap; 8912 8913 tap->wr_tsf = hdr->rxh_tsf; 8914 tap->wr_flags = 0; 8915 tap->wr_rate = rate; 8916 tap->wr_chan_freq = 8917 htole16(ic->ic_bss->ni_chan->ic_freq); 8918 tap->wr_chan_flags = 8919 htole16(ic->ic_bss->ni_chan->ic_flags); 8920 tap->wr_antsignal = rssi; 8921 tap->wr_antnoise = BWI_NOISE_FLOOR; 8922 8923 mb.m_data = (void *)tap; 8924 mb.m_len = sc->sc_rxtap_len; 8925 mb.m_next = m; 8926 mb.m_nextpkt = NULL; 8927 mb.m_owner = NULL; 8928 mb.m_type = 0; 8929 mb.m_flags = 0; 8930 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_IN); 8931 } 8932 8933 m_adj(m, -IEEE80211_CRC_LEN); 8934 8935 wh = mtod(m, struct ieee80211_frame_min *); 8936 ni = ieee80211_find_rxnode(ic, wh); 8937 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 8938 8939 ieee80211_input(ic, m, ni, hdr->rxh_rssi, 8940 le16toh(hdr->rxh_tsf)); 8941 8942 ieee80211_free_node(ni); 8943 8944 if (type == IEEE80211_FC0_TYPE_DATA) { 8945 rx_data = 1; 8946 sc->sc_rx_rate = rate; 8947 } 8948 8949 splx(s); 8950 next: 8951 idx = (idx + 1) % BWI_RX_NDESC; 8952 } 8953 8954 rbd->rbd_idx = idx; 8955 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8956 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8957 8958 return (rx_data); 8959 } 8960 8961 static void 8962 bwi_rx_frame_data_pio(struct bwi_softc *sc, struct bwi_rxbuf_hdr *hdr, int qid) 8963 { 8964 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8965 struct bwi_rxbuf *rb = &rbd->rbd_buf[0]; 8966 struct ieee80211_frame_min *wh; 8967 struct ieee80211_node *ni; 8968 struct ifnet *ifp = &sc->sc_if; 8969 struct ieee80211com *ic = &sc->sc_ic; 8970 struct mbuf *m; 8971 const void *plcp; 8972 uint16_t flags2; 8973 int buflen, hdr_extra, rssi, type, rate; 8974 int s; 8975 8976 m = rb->rb_mbuf; 8977 8978 if (bwi_newbuf(sc, 0, 0)) { 8979 device_printf(sc->sc_dev, "couldn't create mbuf\n"); 8980 if_statinc(ifp, if_ierrors); 8981 return; 8982 } 8983 8984 flags2 = le16toh(hdr->rxh_flags2); 8985 8986 hdr_extra = 0; 8987 if (flags2 & BWI_RXH_F2_TYPE2FRAME) 8988 hdr_extra = 2; 8989 8990 buflen = le16toh(hdr->rxh_buflen); 8991 8992 /* Read the packet data into the mbuf */ 8993 CSR_READ_MULTI_4(sc, BWI_PIO_RXDATA(qid), mtod(m, uint32_t *), 8994 buflen / sizeof(uint32_t)); 8995 if (buflen & 0x3) { 8996 uint8_t data[4]; 8997 uint8_t *ppkt; 8998 u_int resid; 8999 u_int n; 9000 9001 resid = buflen & 0x3; 9002 ppkt = mtod(m, uint8_t *) + (buflen & ~0x3); 9003 CSR_READ_MULTI_4(sc, BWI_PIO_RXDATA(qid), (uint32_t *)&data, 1); 9004 for (n = 0; n < resid; n++, ppkt++) { 9005 *ppkt = data[n]; 9006 } 9007 } 9008 9009 plcp = mtod(m, uint8_t *) + hdr_extra; 9010 rssi = bwi_calc_rssi(sc, hdr); 9011 9012 m_set_rcvif(m, ifp); 9013 m->m_len = m->m_pkthdr.len = buflen + hdr_extra; 9014 m_adj(m, hdr_extra + 6); 9015 9016 if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM) 9017 rate = bwi_ofdm_plcp2rate(plcp); 9018 else 9019 rate = bwi_ds_plcp2rate(plcp); 9020 9021 s = splnet(); 9022 9023 /* RX radio tap */ 9024 if (sc->sc_drvbpf != NULL) { 9025 struct mbuf mb; 9026 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap; 9027 9028 tap->wr_tsf = hdr->rxh_tsf; 9029 tap->wr_flags = 0; 9030 tap->wr_rate = rate; 9031 tap->wr_chan_freq = 9032 htole16(ic->ic_bss->ni_chan->ic_freq); 9033 tap->wr_chan_flags = 9034 htole16(ic->ic_bss->ni_chan->ic_flags); 9035 tap->wr_antsignal = rssi; 9036 tap->wr_antnoise = BWI_NOISE_FLOOR; 9037 9038 mb.m_data = (void *)tap; 9039 mb.m_len = sc->sc_rxtap_len; 9040 mb.m_next = m; 9041 mb.m_nextpkt = NULL; 9042 mb.m_owner = NULL; 9043 mb.m_type = 0; 9044 mb.m_flags = 0; 9045 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_IN); 9046 } 9047 9048 m_adj(m, -IEEE80211_CRC_LEN); 9049 9050 wh = mtod(m, struct ieee80211_frame_min *); 9051 ni = ieee80211_find_rxnode(ic, wh); 9052 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 9053 9054 ieee80211_input(ic, m, ni, hdr->rxh_rssi, 9055 le16toh(hdr->rxh_tsf)); 9056 9057 ieee80211_free_node(ni); 9058 9059 if (type == IEEE80211_FC0_TYPE_DATA) { 9060 sc->sc_rx_rate = rate; 9061 } 9062 9063 splx(s); 9064 } 9065 9066 static int 9067 bwi_rx_frame_pio(struct bwi_softc *sc) 9068 { 9069 struct bwi_rxbuf_hdr rxh; 9070 struct ifnet *ifp = &sc->sc_if; 9071 const u_int qid = 0; 9072 const size_t pio_hdrlen = 20; 9073 struct timeval start, diff; 9074 uint32_t val; 9075 uint16_t pktlen; 9076 uint16_t flags2; 9077 9078 /* Check for frame ready bit and acknowledge it */ 9079 val = CSR_READ_4(sc, BWI_PIO_RXCTL(qid)); 9080 if ((val & BWI_PIO_RXCTL_FRAMERDY) == 0) { 9081 return 0; 9082 } 9083 CSR_WRITE_4(sc, BWI_PIO_RXCTL(qid), BWI_PIO_RXCTL_FRAMERDY); 9084 9085 /* Wait for up to 100us for data ready */ 9086 microuptime(&start); 9087 for (;;) { 9088 val = CSR_READ_4(sc, BWI_PIO_RXCTL(qid)); 9089 if ((val & BWI_PIO_RXCTL_DATARDY) != 0) { 9090 break; 9091 } 9092 microuptime(&diff); 9093 timersub(&diff, &start, &diff); 9094 if (diff.tv_sec != 0 || diff.tv_usec > 100) { 9095 device_printf(sc->sc_dev, "RX timeout\n"); 9096 if_statinc(ifp, if_ierrors); 9097 goto ack; 9098 } 9099 } 9100 9101 /* Read 20 bytes of the packet RX header from the FIFO... */ 9102 CSR_READ_MULTI_4(sc, BWI_PIO_RXDATA(qid), (uint32_t *)&rxh, 9103 pio_hdrlen / sizeof(uint32_t)); 9104 /* ... and zero the rest of it. */ 9105 memset(((uint8_t *)&rxh) + pio_hdrlen, 0, sizeof(rxh) - pio_hdrlen); 9106 9107 /* Validate packet */ 9108 pktlen = le16toh(rxh.rxh_buflen); 9109 if (pktlen > 0x700 || pktlen == 0) { 9110 device_printf(sc->sc_dev, "RX error (length %#x)\n", pktlen); 9111 if_statinc(ifp, if_ierrors); 9112 goto ack; 9113 } 9114 flags2 = le16toh(rxh.rxh_flags2); 9115 if ((flags2 & BWI_RXH_F2_INVALID) != 0) { 9116 device_printf(sc->sc_dev, "RX frame invalid\n"); 9117 if_statinc(ifp, if_ierrors); 9118 goto ack; 9119 } 9120 9121 /* Process frame data */ 9122 bwi_rx_frame_data_pio(sc, &rxh, qid); 9123 9124 ack: 9125 CSR_WRITE_4(sc, BWI_PIO_RXCTL(qid), BWI_PIO_RXCTL_DATARDY); 9126 return 1; 9127 } 9128 9129 static int 9130 bwi_rxeof_pio(struct bwi_softc *sc) 9131 { 9132 unsigned npkt = 0; 9133 9134 while (bwi_rx_frame_pio(sc) && npkt++ < 1000) { 9135 preempt_point(); 9136 } 9137 9138 return (npkt != 0); 9139 } 9140 9141 static int 9142 bwi_rxeof32(struct bwi_softc *sc) 9143 { 9144 uint32_t val, rx_ctrl; 9145 int end_idx, rx_data; 9146 9147 rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl; 9148 9149 val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 9150 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 9151 sizeof(struct bwi_desc32); 9152 9153 rx_data = bwi_rxeof(sc, end_idx); 9154 9155 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX, 9156 end_idx * sizeof(struct bwi_desc32)); 9157 9158 return (rx_data); 9159 } 9160 9161 static int 9162 bwi_rxeof64(struct bwi_softc *sc) 9163 { 9164 /* TODO: 64 */ 9165 return (0); 9166 } 9167 9168 static void 9169 bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl) 9170 { 9171 int i; 9172 9173 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0); 9174 9175 #define NRETRY 10 9176 for (i = 0; i < NRETRY; ++i) { 9177 uint32_t status; 9178 9179 status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 9180 if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) == 9181 BWI_RX32_STATUS_STATE_DISABLED) 9182 break; 9183 9184 DELAY(1000); 9185 } 9186 if (i == NRETRY) 9187 aprint_error_dev(sc->sc_dev, "reset rx ring timedout\n"); 9188 #undef NRETRY 9189 9190 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0); 9191 } 9192 9193 static void 9194 bwi_free_txstats_pio(struct bwi_softc *sc) 9195 { 9196 } 9197 9198 static void 9199 bwi_free_txstats32(struct bwi_softc *sc) 9200 { 9201 bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base); 9202 } 9203 9204 static void 9205 bwi_free_rx_ring_pio(struct bwi_softc *sc) 9206 { 9207 } 9208 9209 static void 9210 bwi_free_tx_ring_pio(struct bwi_softc *sc, int ring_idx) 9211 { 9212 bwi_free_tx_ring32(sc, ring_idx); 9213 } 9214 9215 static void 9216 bwi_free_rx_ring32(struct bwi_softc *sc) 9217 { 9218 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 9219 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 9220 int i; 9221 9222 bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl); 9223 9224 for (i = 0; i < BWI_RX_NDESC; ++i) { 9225 struct bwi_rxbuf *rb = &rbd->rbd_buf[i]; 9226 9227 if (rb->rb_mbuf != NULL) { 9228 bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap); 9229 m_freem(rb->rb_mbuf); 9230 rb->rb_mbuf = NULL; 9231 } 9232 } 9233 } 9234 9235 static void 9236 bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx) 9237 { 9238 struct bwi_ring_data *rd; 9239 struct bwi_txbuf_data *tbd; 9240 uint32_t state, val; 9241 int i; 9242 9243 KASSERT(ring_idx < BWI_TX_NRING); 9244 rd = &sc->sc_tx_rdata[ring_idx]; 9245 tbd = &sc->sc_tx_bdata[ring_idx]; 9246 9247 #define NRETRY 10 9248 for (i = 0; i < NRETRY; ++i) { 9249 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 9250 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 9251 if (state == BWI_TX32_STATUS_STATE_DISABLED || 9252 state == BWI_TX32_STATUS_STATE_IDLE || 9253 state == BWI_TX32_STATUS_STATE_STOPPED) 9254 break; 9255 9256 DELAY(1000); 9257 } 9258 if (i == NRETRY) 9259 aprint_error_dev(sc->sc_dev, 9260 "wait for TX ring(%d) stable timed out\n", ring_idx); 9261 9262 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0); 9263 for (i = 0; i < NRETRY; ++i) { 9264 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 9265 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 9266 if (state == BWI_TX32_STATUS_STATE_DISABLED) 9267 break; 9268 9269 DELAY(1000); 9270 } 9271 if (i == NRETRY) 9272 aprint_error_dev(sc->sc_dev, "reset TX ring (%d) timed out\n", 9273 ring_idx); 9274 #undef NRETRY 9275 9276 DELAY(1000); 9277 9278 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0); 9279 9280 for (i = 0; i < BWI_TX_NDESC; ++i) { 9281 struct bwi_txbuf *tb = &tbd->tbd_buf[i]; 9282 9283 if (tb->tb_mbuf != NULL) { 9284 if (!BWI_IS_PIO(sc)) { 9285 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 9286 } 9287 m_freem(tb->tb_mbuf); 9288 tb->tb_mbuf = NULL; 9289 } 9290 if (tb->tb_ni != NULL) { 9291 ieee80211_free_node(tb->tb_ni); 9292 tb->tb_ni = NULL; 9293 } 9294 } 9295 } 9296 9297 static void 9298 bwi_free_txstats64(struct bwi_softc *sc) 9299 { 9300 /* TODO: 64 */ 9301 } 9302 9303 static void 9304 bwi_free_rx_ring64(struct bwi_softc *sc) 9305 { 9306 /* TODO: 64 */ 9307 } 9308 9309 static void 9310 bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx) 9311 { 9312 /* TODO: 64 */ 9313 } 9314 9315 /* XXX does not belong here */ 9316 /* [TRC: Begin pilferage from OpenBSD.] */ 9317 9318 /* 9319 * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa. 9320 */ 9321 uint8_t 9322 bwi_ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode) 9323 { 9324 rate &= IEEE80211_RATE_VAL; 9325 9326 if (mode == IEEE80211_MODE_11B) { 9327 /* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */ 9328 switch (rate) { 9329 case 2: return 10; 9330 case 4: return 20; 9331 case 11: return 55; 9332 case 22: return 110; 9333 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 9334 case 44: return 220; 9335 } 9336 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 9337 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 9338 switch (rate) { 9339 case 12: return 0x0b; 9340 case 18: return 0x0f; 9341 case 24: return 0x0a; 9342 case 36: return 0x0e; 9343 case 48: return 0x09; 9344 case 72: return 0x0d; 9345 case 96: return 0x08; 9346 case 108: return 0x0c; 9347 } 9348 } else 9349 panic("Unexpected mode %u", mode); 9350 9351 return 0; 9352 } 9353 9354 static uint8_t 9355 bwi_ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phymode mode) 9356 { 9357 if (mode == IEEE80211_MODE_11B) { 9358 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 9359 switch (plcp) { 9360 case 10: return 2; 9361 case 20: return 4; 9362 case 55: return 11; 9363 case 110: return 22; 9364 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 9365 case 220: return 44; 9366 } 9367 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 9368 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 9369 switch (plcp) { 9370 case 0x0b: return 12; 9371 case 0x0f: return 18; 9372 case 0x0a: return 24; 9373 case 0x0e: return 36; 9374 case 0x09: return 48; 9375 case 0x0d: return 72; 9376 case 0x08: return 96; 9377 case 0x0c: return 108; 9378 } 9379 } else 9380 panic("Unexpected mode %u", mode); 9381 9382 return 0; 9383 } 9384 /* [TRC: End pilferage from OpenBSD.] */ 9385 9386 static enum bwi_ieee80211_modtype 9387 bwi_ieee80211_rate2modtype(uint8_t rate) 9388 { 9389 rate &= IEEE80211_RATE_VAL; 9390 9391 if (rate == 44) 9392 return (IEEE80211_MODTYPE_PBCC); 9393 else if (rate == 22 || rate < 12) 9394 return (IEEE80211_MODTYPE_DS); 9395 else 9396 return (IEEE80211_MODTYPE_OFDM); 9397 } 9398 9399 static uint8_t 9400 bwi_ofdm_plcp2rate(const void *plcp0) 9401 { 9402 uint32_t plcp; 9403 uint8_t plcp_rate; 9404 9405 /* plcp0 may not be 32-bit aligned. */ 9406 plcp = le32dec(plcp0); 9407 plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK); 9408 9409 return (bwi_ieee80211_plcp2rate(plcp_rate, IEEE80211_MODE_11G)); 9410 } 9411 9412 static uint8_t 9413 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr) 9414 { 9415 return (bwi_ieee80211_plcp2rate(hdr->i_signal, IEEE80211_MODE_11B)); 9416 } 9417 9418 static void 9419 bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate) 9420 { 9421 uint32_t plcp; 9422 9423 plcp = __SHIFTIN(bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11G), 9424 IEEE80211_OFDM_PLCP_RATE_MASK) | 9425 __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK); 9426 *plcp0 = htole32(plcp); 9427 } 9428 9429 static void 9430 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len, 9431 uint8_t rate) 9432 { 9433 int len, service, pkt_bitlen; 9434 9435 pkt_bitlen = pkt_len * NBBY; 9436 len = howmany(pkt_bitlen * 2, rate); 9437 9438 service = IEEE80211_DS_PLCP_SERVICE_LOCKED; 9439 if (rate == (11 * 2)) { 9440 int pkt_bitlen1; 9441 9442 /* 9443 * PLCP service field needs to be adjusted, 9444 * if TX rate is 11Mbytes/s 9445 */ 9446 pkt_bitlen1 = len * 11; 9447 if (pkt_bitlen1 - pkt_bitlen >= NBBY) 9448 service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7; 9449 } 9450 9451 plcp->i_signal = bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11B); 9452 plcp->i_service = service; 9453 plcp->i_length = htole16(len); 9454 /* NOTE: do NOT touch i_crc */ 9455 } 9456 9457 static void 9458 bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate) 9459 { 9460 enum bwi_ieee80211_modtype modtype; 9461 9462 /* 9463 * Assume caller has zeroed 'plcp' 9464 */ 9465 9466 modtype = bwi_ieee80211_rate2modtype(rate); 9467 if (modtype == IEEE80211_MODTYPE_OFDM) 9468 bwi_ofdm_plcp_header(plcp, pkt_len, rate); 9469 else if (modtype == IEEE80211_MODTYPE_DS) 9470 bwi_ds_plcp_header(plcp, pkt_len, rate); 9471 else 9472 panic("unsupport modulation type %u\n", modtype); 9473 } 9474 9475 static uint8_t 9476 bwi_ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate) 9477 { 9478 const struct ieee80211_rateset *rs = &ni->ni_rates; 9479 uint8_t ack_rate = 0; 9480 enum bwi_ieee80211_modtype modtype; 9481 int i; 9482 9483 rate &= IEEE80211_RATE_VAL; 9484 9485 modtype = bwi_ieee80211_rate2modtype(rate); 9486 9487 for (i = 0; i < rs->rs_nrates; ++i) { 9488 uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL; 9489 9490 if (rate1 > rate) { 9491 if (ack_rate != 0) 9492 return (ack_rate); 9493 else 9494 break; 9495 } 9496 9497 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && 9498 bwi_ieee80211_rate2modtype(rate1) == modtype) 9499 ack_rate = rate1; 9500 } 9501 9502 switch (rate) { 9503 /* CCK */ 9504 case 2: 9505 case 4: 9506 case 11: 9507 case 22: 9508 ack_rate = rate; 9509 break; 9510 /* PBCC */ 9511 case 44: 9512 ack_rate = 22; 9513 break; 9514 9515 /* OFDM */ 9516 case 12: 9517 case 18: 9518 ack_rate = 12; 9519 break; 9520 case 24: 9521 case 36: 9522 ack_rate = 24; 9523 break; 9524 case 48: 9525 case 72: 9526 case 96: 9527 case 108: 9528 ack_rate = 48; 9529 break; 9530 default: 9531 panic("unsupported rate %d\n", rate); 9532 } 9533 return (ack_rate); 9534 } 9535 9536 /* [TRC: XXX does not belong here] */ 9537 9538 #define IEEE80211_OFDM_TXTIME(kbps, frmlen) \ 9539 (IEEE80211_OFDM_PREAMBLE_TIME + \ 9540 IEEE80211_OFDM_SIGNAL_TIME + \ 9541 (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME)) 9542 9543 #define IEEE80211_OFDM_SYM_TIME 4 9544 #define IEEE80211_OFDM_PREAMBLE_TIME 16 9545 #define IEEE80211_OFDM_SIGNAL_EXT_TIME 6 9546 #define IEEE80211_OFDM_SIGNAL_TIME 4 9547 9548 #define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16 9549 #define IEEE80211_OFDM_TAIL_NBITS 6 9550 9551 #define IEEE80211_OFDM_NBITS(frmlen) \ 9552 (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \ 9553 ((frmlen) * NBBY) + \ 9554 IEEE80211_OFDM_TAIL_NBITS) 9555 9556 #define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \ 9557 (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000) 9558 9559 #define IEEE80211_OFDM_NSYMS(kbps, frmlen) \ 9560 howmany(IEEE80211_OFDM_NBITS((frmlen)), \ 9561 IEEE80211_OFDM_NBITS_PER_SYM((kbps))) 9562 9563 #define IEEE80211_CCK_TXTIME(kbps, frmlen) \ 9564 (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps)) 9565 9566 #define IEEE80211_CCK_PREAMBLE_LEN 144 9567 #define IEEE80211_CCK_PLCP_HDR_TIME 48 9568 #define IEEE80211_CCK_SHPREAMBLE_LEN 72 9569 #define IEEE80211_CCK_SHPLCP_HDR_TIME 24 9570 9571 #define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY) 9572 9573 static uint16_t 9574 bwi_ieee80211_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, 9575 uint len, uint8_t rs_rate, uint32_t flags) 9576 { 9577 enum bwi_ieee80211_modtype modtype; 9578 uint16_t txtime; 9579 int rate; 9580 9581 rs_rate &= IEEE80211_RATE_VAL; 9582 9583 rate = rs_rate * 500; /* ieee80211 rate -> kbps */ 9584 9585 modtype = bwi_ieee80211_rate2modtype(rs_rate); 9586 if (modtype == IEEE80211_MODTYPE_OFDM) { 9587 /* 9588 * IEEE Std 802.11a-1999, page 37, equation (29) 9589 * IEEE Std 802.11g-2003, page 44, equation (42) 9590 */ 9591 txtime = IEEE80211_OFDM_TXTIME(rate, len); 9592 if (ic->ic_curmode == IEEE80211_MODE_11G) 9593 txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME; 9594 } else { 9595 /* 9596 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4 9597 * IEEE Std 802.11g-2003, page 45, equation (43) 9598 */ 9599 if (modtype == IEEE80211_MODTYPE_PBCC) 9600 ++len; 9601 txtime = IEEE80211_CCK_TXTIME(rate, len); 9602 9603 /* 9604 * Short preamble is not applicable for DS 1Mbits/s 9605 */ 9606 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) { 9607 txtime += IEEE80211_CCK_SHPREAMBLE_LEN + 9608 IEEE80211_CCK_SHPLCP_HDR_TIME; 9609 } else { 9610 txtime += IEEE80211_CCK_PREAMBLE_LEN + 9611 IEEE80211_CCK_PLCP_HDR_TIME; 9612 } 9613 } 9614 return (txtime); 9615 } 9616 9617 static int 9618 bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, 9619 struct ieee80211_node **nip, int mgt_pkt) 9620 { 9621 struct ieee80211com *ic = &sc->sc_ic; 9622 struct ieee80211_node *ni = *nip; 9623 struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; 9624 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 9625 struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; 9626 struct bwi_mac *mac; 9627 struct bwi_txbuf_hdr *hdr; 9628 struct ieee80211_frame *wh; 9629 uint8_t rate; /* [TRC: XXX Use a fallback rate?] */ 9630 uint32_t mac_ctrl; 9631 uint16_t phy_ctrl; 9632 bus_addr_t paddr; 9633 int pkt_len, error, mcast_pkt = 0; 9634 #if 0 9635 const uint8_t *p; 9636 int i; 9637 #endif 9638 9639 KASSERT(ni != NULL); 9640 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9641 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9642 9643 wh = mtod(m, struct ieee80211_frame *); 9644 9645 /* Get 802.11 frame len before prepending TX header */ 9646 pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN; 9647 9648 /* 9649 * Find TX rate 9650 */ 9651 memset(tb->tb_rate_idx, 0, sizeof(tb->tb_rate_idx)); 9652 if (!mgt_pkt) { 9653 if (ic->ic_fixed_rate != -1) { 9654 rate = ic->ic_sup_rates[ic->ic_curmode]. 9655 rs_rates[ic->ic_fixed_rate]; 9656 /* [TRC: XXX Set fallback rate.] */ 9657 } else { 9658 /* AMRR rate control */ 9659 rate = ni->ni_rates.rs_rates[ni->ni_txrate]; 9660 } 9661 } else { 9662 /* Fixed at 1Mbits/s for mgt frames */ 9663 /* [TRC: XXX Set fallback rate.] */ 9664 rate = (1 * 2); 9665 } 9666 9667 rate &= IEEE80211_RATE_VAL; 9668 9669 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 9670 /* [TRC: XXX Set fallback rate.] */ 9671 rate = ic->ic_mcast_rate; 9672 mcast_pkt = 1; 9673 } 9674 9675 /* [TRC: XXX Check fallback rate.] */ 9676 if (rate == 0) { 9677 aprint_error_dev(sc->sc_dev, "invalid rate %u", rate); 9678 /* [TRC: In the margin of the following line, 9679 DragonFlyBSD writes `Force 1Mbits/s', whereas 9680 OpenBSD writes `Force 1Mbytes/s'.] */ 9681 rate = (1 * 2); 9682 /* [TRC: XXX Set fallback rate.] */ 9683 } 9684 sc->sc_tx_rate = rate; 9685 9686 /* TX radio tap */ 9687 if (sc->sc_drvbpf != NULL) { 9688 struct mbuf mb; 9689 struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap; 9690 9691 tap->wt_flags = 0; 9692 tap->wt_rate = rate; 9693 tap->wt_chan_freq = 9694 htole16(ic->ic_bss->ni_chan->ic_freq); 9695 tap->wt_chan_flags = 9696 htole16(ic->ic_bss->ni_chan->ic_flags); 9697 9698 mb.m_data = (void *)tap; 9699 mb.m_len = sc->sc_txtap_len; 9700 mb.m_next = m; 9701 mb.m_nextpkt = NULL; 9702 mb.m_type = 0; 9703 mb.m_flags = 0; 9704 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_OUT); 9705 } 9706 9707 /* 9708 * Setup the embedded TX header 9709 */ 9710 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT); 9711 if (m == NULL) { 9712 aprint_error_dev(sc->sc_dev, "prepend TX header failed\n"); 9713 return (ENOBUFS); 9714 } 9715 hdr = mtod(m, struct bwi_txbuf_hdr *); 9716 9717 memset(hdr, 0, sizeof(*hdr)); 9718 9719 memcpy(hdr->txh_fc, wh->i_fc, sizeof(hdr->txh_fc)); 9720 memcpy(hdr->txh_addr1, wh->i_addr1, sizeof(hdr->txh_addr1)); 9721 9722 if (!mcast_pkt) { 9723 uint16_t dur; 9724 uint8_t ack_rate; 9725 9726 /* [TRC: XXX Set fallback rate.] */ 9727 ack_rate = bwi_ieee80211_ack_rate(ni, rate); 9728 dur = bwi_ieee80211_txtime(ic, ni, 9729 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, 9730 ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); 9731 9732 hdr->txh_fb_duration = htole16(dur); 9733 } 9734 9735 hdr->txh_id = htole16( 9736 __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) | 9737 __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK)); 9738 9739 bwi_plcp_header(hdr->txh_plcp, pkt_len, rate); 9740 /* [TRC: XXX Use fallback rate.] */ 9741 bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate); 9742 9743 phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode, 9744 BWI_TXH_PHY_C_ANTMODE_MASK); 9745 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) 9746 phy_ctrl |= BWI_TXH_PHY_C_OFDM; 9747 else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1)) 9748 phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE; 9749 9750 mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG; 9751 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) 9752 mac_ctrl |= BWI_TXH_MAC_C_ACK; 9753 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) 9754 mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM; 9755 9756 hdr->txh_mac_ctrl = htole32(mac_ctrl); 9757 hdr->txh_phy_ctrl = htole16(phy_ctrl); 9758 9759 /* Catch any further usage */ 9760 hdr = NULL; 9761 wh = NULL; 9762 9763 if (BWI_IS_PIO(sc)) { 9764 error = 0; 9765 } else { 9766 /* DMA load */ 9767 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 9768 BUS_DMA_NOWAIT); 9769 if (error && error != EFBIG) { 9770 aprint_error_dev(sc->sc_dev, 9771 "can't load TX buffer (1) %d\n", error); 9772 goto back; 9773 } 9774 } 9775 9776 if (error) { /* error == EFBIG */ 9777 struct mbuf *m_new; 9778 9779 KASSERT(!BWI_IS_PIO(sc)); 9780 9781 error = 0; 9782 9783 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 9784 if (m_new == NULL) { 9785 error = ENOBUFS; 9786 aprint_error_dev(sc->sc_dev, 9787 "can't defrag TX buffer (1)\n"); 9788 goto back; 9789 } 9790 9791 m_copy_pkthdr(m_new, m); 9792 if (m->m_pkthdr.len > MHLEN) { 9793 MCLGET(m_new, M_DONTWAIT); 9794 if (!(m_new->m_flags & M_EXT)) { 9795 m_freem(m_new); 9796 error = ENOBUFS; 9797 } 9798 } 9799 9800 if (error) { 9801 aprint_error_dev(sc->sc_dev, 9802 "can't defrag TX buffer (2)\n"); 9803 goto back; 9804 } 9805 9806 m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, void *)); 9807 m_freem(m); 9808 m_new->m_len = m_new->m_pkthdr.len; 9809 m = m_new; 9810 9811 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 9812 BUS_DMA_NOWAIT); 9813 if (error) { 9814 aprint_error_dev(sc->sc_dev, 9815 "can't load TX buffer (2) %d\n", error); 9816 goto back; 9817 } 9818 } 9819 error = 0; 9820 9821 if (!BWI_IS_PIO(sc)) { 9822 bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0, 9823 tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 9824 } 9825 9826 if (mgt_pkt || mcast_pkt) { 9827 /* Don't involve mcast/mgt packets into TX rate control */ 9828 ieee80211_free_node(ni); 9829 *nip = ni = NULL; 9830 } 9831 9832 tb->tb_mbuf = m; 9833 tb->tb_ni = ni; 9834 9835 #if 0 9836 p = mtod(m, const uint8_t *); 9837 for (i = 0; i < m->m_pkthdr.len; ++i) { 9838 if (i % 8 == 0) { 9839 if (i != 0) 9840 aprint_debug("\n"); 9841 aprint_debug_dev(sc->sc_dev, ""); 9842 } 9843 aprint_debug(" %02x", p[i]); 9844 } 9845 aprint_debug("\n"); 9846 #endif 9847 9848 DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n", 9849 idx, pkt_len, m->m_pkthdr.len); 9850 9851 if (!BWI_IS_PIO(sc)) { 9852 /* Setup TX descriptor */ 9853 paddr = tb->tb_dmap->dm_segs[0].ds_addr; 9854 (sc->sc_setup_txdesc)(sc, rd, idx, paddr, m->m_pkthdr.len); 9855 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 9856 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 9857 } 9858 9859 /* Kick start */ 9860 (sc->sc_start_tx)(sc, rd->rdata_txrx_ctrl, idx); 9861 9862 back: 9863 if (error) 9864 m_freem(m); 9865 return (error); 9866 } 9867 9868 static void 9869 bwi_start_tx_pio(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 9870 { 9871 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 9872 struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; 9873 9874 mutex_enter(&sc->sc_pio_txlock); 9875 STAILQ_INSERT_TAIL(&sc->sc_pio_txpend, tb, tb_entry); 9876 mutex_exit(&sc->sc_pio_txlock); 9877 } 9878 9879 static void 9880 bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 9881 { 9882 idx = (idx + 1) % BWI_TX_NDESC; 9883 CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX, 9884 idx * sizeof(struct bwi_desc32)); 9885 } 9886 9887 static void 9888 bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 9889 { 9890 /* TODO: 64 */ 9891 } 9892 9893 static void 9894 bwi_txeof_status_pio(struct bwi_softc *sc) 9895 { 9896 /* TODO: PIO */ 9897 } 9898 9899 static void 9900 bwi_txeof_status32(struct bwi_softc *sc) 9901 { 9902 struct ifnet *ifp = &sc->sc_if; 9903 uint32_t val, ctrl_base; 9904 int end_idx, s; 9905 9906 s = splnet(); 9907 9908 ctrl_base = sc->sc_txstats->stats_ctrl_base; 9909 9910 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS); 9911 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 9912 sizeof(struct bwi_desc32); 9913 9914 bwi_txeof_status(sc, end_idx); 9915 9916 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 9917 end_idx * sizeof(struct bwi_desc32)); 9918 9919 if ((ifp->if_flags & IFF_OACTIVE) == 0) 9920 ifp->if_start(ifp); /* [TRC: XXX Why not bwi_start?] */ 9921 9922 splx(s); 9923 } 9924 9925 static void 9926 bwi_txeof_status64(struct bwi_softc *sc) 9927 { 9928 /* TODO: 64 */ 9929 } 9930 9931 static void 9932 _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, uint8_t retry_cnt) 9933 { 9934 struct ifnet *ifp = &sc->sc_if; 9935 struct bwi_txbuf_data *tbd; 9936 struct bwi_txbuf *tb; 9937 int ring_idx, buf_idx; 9938 9939 if (tx_id == 0) { 9940 /* [TRC: XXX What is the severity of this message?] */ 9941 aprint_normal_dev(sc->sc_dev, "zero tx id\n"); 9942 return; 9943 } 9944 9945 ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK); 9946 buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK); 9947 9948 KASSERT(ring_idx == BWI_TX_DATA_RING); 9949 KASSERT(buf_idx < BWI_TX_NDESC); 9950 tbd = &sc->sc_tx_bdata[ring_idx]; 9951 KASSERT(tbd->tbd_used > 0); 9952 tbd->tbd_used--; 9953 9954 tb = &tbd->tbd_buf[buf_idx]; 9955 9956 if (BWI_IS_PIO(sc)) { 9957 mutex_enter(&sc->sc_pio_txlock); 9958 const u_int pktlen = m_length(tb->tb_mbuf); 9959 sc->sc_pio_fifoavail += roundup(pktlen, sizeof(uint32_t)); 9960 KASSERT(sc->sc_pio_fifoavail <= sc->sc_pio_fifolen); 9961 mutex_exit(&sc->sc_pio_txlock); 9962 } else { 9963 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 9964 } 9965 m_freem(tb->tb_mbuf); 9966 tb->tb_mbuf = NULL; 9967 9968 if (tb->tb_ni != NULL) { 9969 struct bwi_node *bn = (struct bwi_node *)tb->tb_ni; 9970 9971 /* Update rate control statistics for the node. */ 9972 bn->amn.amn_txcnt++; 9973 if (retry_cnt) { 9974 bn->amn.amn_retrycnt++; 9975 } 9976 9977 ieee80211_free_node(tb->tb_ni); 9978 tb->tb_ni = NULL; 9979 } 9980 9981 if (tbd->tbd_used == 0) 9982 sc->sc_tx_timer = 0; 9983 9984 ifp->if_flags &= ~IFF_OACTIVE; 9985 } 9986 9987 static void 9988 bwi_txeof_status(struct bwi_softc *sc, int end_idx) 9989 { 9990 struct bwi_txstats_data *st = sc->sc_txstats; 9991 int idx; 9992 9993 if (!BWI_IS_PIO(sc)) { 9994 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 9995 st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 9996 } 9997 9998 idx = st->stats_idx; 9999 while (idx != end_idx) { 10000 /* [TRC: XXX Filter this out if it is not pending; see 10001 DragonFlyBSD's revision 1.5. */ 10002 _bwi_txeof(sc, le16toh(st->stats[idx].txs_id), 10003 st->stats[idx].txs_retry_cnt); 10004 idx = (idx + 1) % BWI_TXSTATS_NDESC; 10005 } 10006 st->stats_idx = idx; 10007 } 10008 10009 static void 10010 bwi_txeof(struct bwi_softc *sc) 10011 { 10012 struct ifnet *ifp = &sc->sc_if; 10013 int s; 10014 10015 s = splnet(); 10016 10017 for (;;) { 10018 uint32_t tx_status0; 10019 uint16_t tx_id; 10020 uint8_t tx_cnt; 10021 10022 tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0); 10023 if ((tx_status0 & BWI_TXSTATUS_0_MORE) == 0) 10024 break; 10025 (void)CSR_READ_4(sc, BWI_TXSTATUS_1); 10026 10027 tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK); 10028 tx_cnt = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_DATA_TXCNT_MASK); 10029 10030 if ((tx_status0 & 10031 (BWI_TXSTATUS_0_PENDING | BWI_TXSTATUS_0_AMPDU)) != 0) { 10032 continue; 10033 } 10034 10035 _bwi_txeof(sc, tx_id, tx_cnt != 1); 10036 10037 if_statinc(ifp, if_opackets); 10038 if (tx_cnt == 0) { 10039 if_statinc(ifp, if_oerrors); 10040 } 10041 } 10042 10043 if ((ifp->if_flags & IFF_OACTIVE) == 0) 10044 ifp->if_start(ifp); 10045 10046 splx(s); 10047 } 10048 10049 static int 10050 bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) 10051 { 10052 bwi_power_on(sc, 1); 10053 10054 return (bwi_set_clock_mode(sc, clk_mode)); 10055 } 10056 10057 static void 10058 bwi_bbp_power_off(struct bwi_softc *sc) 10059 { 10060 bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW); 10061 bwi_power_off(sc, 1); 10062 } 10063 10064 static int 10065 bwi_get_pwron_delay(struct bwi_softc *sc) 10066 { 10067 struct bwi_regwin *com, *old; 10068 struct bwi_clock_freq freq; 10069 uint32_t val; 10070 int error; 10071 10072 com = &sc->sc_com_regwin; 10073 KASSERT(BWI_REGWIN_EXIST(com)); 10074 10075 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0) 10076 return (0); 10077 10078 error = bwi_regwin_switch(sc, com, &old); 10079 if (error) 10080 return (error); 10081 10082 bwi_get_clock_freq(sc, &freq); 10083 10084 val = CSR_READ_4(sc, BWI_PLL_ON_DELAY); 10085 sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min); 10086 DPRINTF(sc, BWI_DBG_ATTACH, "power on delay %u\n", sc->sc_pwron_delay); 10087 10088 return (bwi_regwin_switch(sc, old, NULL)); 10089 } 10090 10091 static int 10092 bwi_bus_attach(struct bwi_softc *sc) 10093 { 10094 struct bwi_regwin *bus, *old; 10095 int error; 10096 10097 bus = &sc->sc_bus_regwin; 10098 10099 error = bwi_regwin_switch(sc, bus, &old); 10100 if (error) 10101 return (error); 10102 10103 if (!bwi_regwin_is_enabled(sc, bus)) 10104 bwi_regwin_enable(sc, bus, 0); 10105 10106 /* Disable interripts */ 10107 CSR_WRITE_4(sc, BWI_INTRVEC, 0); 10108 10109 return (bwi_regwin_switch(sc, old, NULL)); 10110 } 10111 10112 static const char * 10113 bwi_regwin_name(const struct bwi_regwin *rw) 10114 { 10115 switch (rw->rw_type) { 10116 case BWI_REGWIN_T_COM: 10117 return ("COM"); 10118 case BWI_REGWIN_T_BUSPCI: 10119 return ("PCI"); 10120 case BWI_REGWIN_T_MAC: 10121 return ("MAC"); 10122 case BWI_REGWIN_T_BUSPCIE: 10123 return ("PCIE"); 10124 } 10125 panic("unknown regwin type 0x%04x\n", rw->rw_type); 10126 10127 return (NULL); 10128 } 10129 10130 static uint32_t 10131 bwi_regwin_disable_bits(struct bwi_softc *sc) 10132 { 10133 uint32_t busrev; 10134 10135 /* XXX cache this */ 10136 busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK); 10137 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_MISC, 10138 "bus rev %u\n", busrev); 10139 10140 if (busrev == BWI_BUSREV_0) 10141 return (BWI_STATE_LO_DISABLE1); 10142 else if (busrev == BWI_BUSREV_1) 10143 return (BWI_STATE_LO_DISABLE2); 10144 else 10145 return (BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2); 10146 } 10147 10148 static int 10149 bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw) 10150 { 10151 uint32_t val, disable_bits; 10152 10153 disable_bits = bwi_regwin_disable_bits(sc); 10154 val = CSR_READ_4(sc, BWI_STATE_LO); 10155 10156 if ((val & (BWI_STATE_LO_CLOCK | 10157 BWI_STATE_LO_RESET | 10158 disable_bits)) == BWI_STATE_LO_CLOCK) { 10159 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is enabled\n", 10160 bwi_regwin_name(rw)); 10161 return (1); 10162 } else { 10163 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is disabled\n", 10164 bwi_regwin_name(rw)); 10165 return (0); 10166 } 10167 } 10168 10169 static void 10170 bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 10171 { 10172 uint32_t state_lo, disable_bits; 10173 int i; 10174 10175 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 10176 10177 /* 10178 * If current regwin is in 'reset' state, it was already disabled. 10179 */ 10180 if (state_lo & BWI_STATE_LO_RESET) { 10181 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, 10182 "%s was already disabled\n", bwi_regwin_name(rw)); 10183 return; 10184 } 10185 10186 disable_bits = bwi_regwin_disable_bits(sc); 10187 10188 /* 10189 * Disable normal clock 10190 */ 10191 state_lo = BWI_STATE_LO_CLOCK | disable_bits; 10192 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 10193 10194 /* 10195 * Wait until normal clock is disabled 10196 */ 10197 #define NRETRY 1000 10198 for (i = 0; i < NRETRY; ++i) { 10199 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 10200 if (state_lo & disable_bits) 10201 break; 10202 DELAY(10); 10203 } 10204 if (i == NRETRY) { 10205 aprint_error_dev(sc->sc_dev, "%s disable clock timeout\n", 10206 bwi_regwin_name(rw)); 10207 } 10208 10209 for (i = 0; i < NRETRY; ++i) { 10210 uint32_t state_hi; 10211 10212 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 10213 if ((state_hi & BWI_STATE_HI_BUSY) == 0) 10214 break; 10215 DELAY(10); 10216 } 10217 if (i == NRETRY) { 10218 aprint_error_dev(sc->sc_dev, "%s wait BUSY unset timeout\n", 10219 bwi_regwin_name(rw)); 10220 } 10221 #undef NRETRY 10222 10223 /* 10224 * Reset and disable regwin with gated clock 10225 */ 10226 state_lo = BWI_STATE_LO_RESET | disable_bits | 10227 BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK | 10228 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 10229 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 10230 10231 /* Flush pending bus write */ 10232 CSR_READ_4(sc, BWI_STATE_LO); 10233 DELAY(1); 10234 10235 /* Reset and disable regwin */ 10236 state_lo = BWI_STATE_LO_RESET | disable_bits | 10237 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 10238 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 10239 10240 /* Flush pending bus write */ 10241 CSR_READ_4(sc, BWI_STATE_LO); 10242 DELAY(1); 10243 } 10244 10245 static void 10246 bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 10247 { 10248 uint32_t state_lo, state_hi, imstate; 10249 10250 bwi_regwin_disable(sc, rw, flags); 10251 10252 /* Reset regwin with gated clock */ 10253 state_lo = BWI_STATE_LO_RESET | 10254 BWI_STATE_LO_CLOCK | 10255 BWI_STATE_LO_GATED_CLOCK | 10256 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 10257 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 10258 10259 /* Flush pending bus write */ 10260 CSR_READ_4(sc, BWI_STATE_LO); 10261 DELAY(1); 10262 10263 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 10264 if (state_hi & BWI_STATE_HI_SERROR) 10265 CSR_WRITE_4(sc, BWI_STATE_HI, 0); 10266 10267 imstate = CSR_READ_4(sc, BWI_IMSTATE); 10268 if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) { 10269 imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT); 10270 CSR_WRITE_4(sc, BWI_IMSTATE, imstate); 10271 } 10272 10273 /* Enable regwin with gated clock */ 10274 state_lo = BWI_STATE_LO_CLOCK | 10275 BWI_STATE_LO_GATED_CLOCK | 10276 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 10277 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 10278 10279 /* Flush pending bus write */ 10280 CSR_READ_4(sc, BWI_STATE_LO); 10281 DELAY(1); 10282 10283 /* Enable regwin with normal clock */ 10284 state_lo = BWI_STATE_LO_CLOCK | 10285 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 10286 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 10287 10288 /* Flush pending bus write */ 10289 CSR_READ_4(sc, BWI_STATE_LO); 10290 DELAY(1); 10291 } 10292 10293 static void 10294 bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid) 10295 { 10296 struct ieee80211com *ic = &sc->sc_ic; 10297 struct bwi_mac *mac; 10298 struct bwi_myaddr_bssid buf; 10299 const uint8_t *p; 10300 uint32_t val; 10301 int n, i; 10302 10303 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 10304 mac = (struct bwi_mac *)sc->sc_cur_regwin; 10305 10306 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid); 10307 10308 memcpy(buf.myaddr, ic->ic_myaddr, sizeof(buf.myaddr)); 10309 memcpy(buf.bssid, bssid, sizeof(buf.bssid)); 10310 10311 n = sizeof(buf) / sizeof(val); 10312 p = (const uint8_t *)&buf; 10313 for (i = 0; i < n; ++i) { 10314 int j; 10315 10316 val = 0; 10317 for (j = 0; j < sizeof(val); ++j) 10318 val |= ((uint32_t)(*p++)) << (j * 8); 10319 10320 TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val); 10321 } 10322 } 10323 10324 static void 10325 bwi_updateslot(struct ifnet *ifp) 10326 { 10327 struct bwi_softc *sc = ifp->if_softc; 10328 struct ieee80211com *ic = &sc->sc_ic; 10329 struct bwi_mac *mac; 10330 10331 if ((ifp->if_flags & IFF_RUNNING) == 0) 10332 return; 10333 10334 DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__); 10335 10336 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 10337 mac = (struct bwi_mac *)sc->sc_cur_regwin; 10338 10339 bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT)); 10340 } 10341 10342 static void 10343 bwi_updateslot_sdio(struct ifnet *ifp) 10344 { 10345 struct bwi_softc *sc = ifp->if_softc; 10346 struct bwi_task *t; 10347 10348 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT); 10349 if (t == NULL) { 10350 device_printf(sc->sc_dev, "no free tasks\n"); 10351 return; 10352 } 10353 10354 t->t_ic = &sc->sc_ic; 10355 t->t_cmd = BWI_TASK_UPDATESLOT; 10356 workqueue_enqueue(sc->sc_taskq, &t->t_work, NULL); 10357 } 10358 10359 static void 10360 bwi_do_calibrate(struct bwi_softc *sc) 10361 { 10362 struct bwi_mac *mac; 10363 struct ieee80211com *ic = &sc->sc_ic; 10364 10365 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 10366 mac = (struct bwi_mac *)sc->sc_cur_regwin; 10367 10368 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 10369 bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type); 10370 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB; 10371 } 10372 10373 /* XXX 15 seconds */ 10374 callout_schedule(&sc->sc_calib_ch, hz * 15); 10375 } 10376 10377 static void 10378 bwi_calibrate(void *xsc) 10379 { 10380 struct bwi_softc *sc = xsc; 10381 struct ieee80211com *ic = &sc->sc_ic; 10382 int s; 10383 10384 s = splnet(); 10385 10386 if (ic->ic_state == IEEE80211_S_RUN) { 10387 if (BWI_IS_SDIO(sc)) { 10388 struct bwi_task *t; 10389 10390 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT); 10391 if (t == NULL) { 10392 device_printf(sc->sc_dev, "no free tasks\n"); 10393 callout_schedule(&sc->sc_calib_ch, hz * 15); 10394 } else { 10395 t->t_ic = &sc->sc_ic; 10396 t->t_cmd = BWI_TASK_CALIBRATE; 10397 workqueue_enqueue(sc->sc_taskq, &t->t_work, 10398 NULL); 10399 } 10400 } else { 10401 bwi_do_calibrate(sc); 10402 } 10403 } 10404 10405 splx(s); 10406 } 10407 10408 static int 10409 bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr) 10410 { 10411 struct bwi_mac *mac; 10412 10413 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 10414 mac = (struct bwi_mac *)sc->sc_cur_regwin; 10415 10416 return (bwi_rf_calc_rssi(mac, hdr)); 10417 } 10418 10419 bool 10420 bwi_suspend(device_t dv, const pmf_qual_t *qual) 10421 { 10422 struct bwi_softc *sc = device_private(dv); 10423 10424 bwi_power_off(sc, 0); 10425 if (sc->sc_disable != NULL) 10426 (sc->sc_disable)(sc, 1); 10427 10428 return true; 10429 } 10430 10431 bool 10432 bwi_resume(device_t dv, const pmf_qual_t *qual) 10433 { 10434 struct bwi_softc *sc = device_private(dv); 10435 10436 if (sc->sc_enable != NULL) 10437 (sc->sc_enable)(sc, 1); 10438 bwi_power_on(sc, 1); 10439 10440 return true; 10441 } 10442