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