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