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