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