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