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