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