1 /* $NetBSD: bwi.c,v 1.4 2009/01/10 13:03:19 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.4 2009/01/10 13:03:19 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 bcopy(&mac->mac_tpctl, &tpctl_orig, sizeof(tpctl_orig)); 1753 restore_tpctl = 1; 1754 1755 bcopy(&mac->mac_tpctl, &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 bzero(&lim, 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 bcopy(&mac->mac_tpctl, &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 bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0, 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 bcopy(txpower_map, rf->rf_txpower_map0, 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 bzero(®s, 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 bzero(&lo_save, 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 bzero(&lo_save, sizeof(lo_save)); 5172 } else if (init_rf_atten < 0) { 5173 lo = bwi_get_rf_lo(mac, 5174 rf_atten, 2 * bbp_atten); 5175 bcopy(lo, &lo_save, sizeof(lo_save)); 5176 } else { 5177 lo = bwi_get_rf_lo(mac, 5178 init_rf_atten, 0); 5179 bcopy(lo, &lo_save, 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 bcopy(lo, &lo_save, 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 bcopy(src_lo, &lo_min, 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 bcopy(&lo_min, &lo_base, 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 bcopy(&lo, &lo_min, 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 bcopy(&lo_min, dst_lo, 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 bzero(&gains, 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 bzero(&gains, 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 bzero(&gains, 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 bzero(rf->rf_lo, sizeof(rf->rf_lo)); 5940 bzero(rf->rf_lo_used, 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 bcopy(rf->rf_txpower_map0, rf->rf_txpower_map, 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 bzero(®s, 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 bzero(freq, 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 ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7297 (IFF_UP | IFF_RUNNING)) { 7298 struct bwi_mac *mac; 7299 int promisc = -1; 7300 7301 KASSERT(sc->sc_cur_regwin->rw_type == 7302 BWI_REGWIN_T_MAC); 7303 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7304 7305 if ((ifp->if_flags & IFF_PROMISC) && 7306 (sc->sc_flags & BWI_F_PROMISC) == 0) { 7307 promisc = 1; 7308 sc->sc_flags |= BWI_F_PROMISC; 7309 } else if ((ifp->if_flags & IFF_PROMISC) == 0 && 7310 (sc->sc_flags & BWI_F_PROMISC)) { 7311 promisc = 0; 7312 sc->sc_flags &= ~BWI_F_PROMISC; 7313 } 7314 7315 if (promisc >= 0) 7316 bwi_mac_set_promisc(mac, promisc); 7317 } 7318 7319 if (ifp->if_flags & IFF_UP) { 7320 if (!(ifp->if_flags & IFF_RUNNING)) 7321 bwi_init(ifp); 7322 } else { 7323 if (ifp->if_flags & IFF_RUNNING) 7324 bwi_stop(ifp, 1); 7325 } 7326 break; 7327 7328 case SIOCADDMULTI: 7329 case SIOCDELMULTI: 7330 /* [TRC: Several other drivers appear to have this 7331 copied & pasted, so I'm following suit.] */ 7332 /* XXX no h/w multicast filter? --dyoung */ 7333 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 7334 /* setup multicast filter, etc */ 7335 error = 0; 7336 } 7337 break; 7338 7339 case SIOCS80211CHANNEL: 7340 /* [TRC: Pilfered from OpenBSD. No clue whether it works.] */ 7341 /* allow fast channel switching in monitor mode */ 7342 error = ieee80211_ioctl(ic, cmd, data); 7343 if (error == ENETRESET && 7344 ic->ic_opmode == IEEE80211_M_MONITOR) { 7345 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7346 (IFF_UP | IFF_RUNNING)) { 7347 /* [TRC: XXX ????] */ 7348 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 7349 ic->ic_curchan = ic->ic_ibss_chan; 7350 bwi_set_chan(sc, ic->ic_bss->ni_chan); 7351 } 7352 error = 0; 7353 } 7354 break; 7355 7356 default: 7357 error = ieee80211_ioctl(ic, cmd, data); 7358 break; 7359 } 7360 7361 if (error == ENETRESET) { 7362 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7363 (IFF_UP | IFF_RUNNING) && 7364 /* [TRC: XXX Superstitiously cargo-culted from iwi(4). */ 7365 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) 7366 bwi_init(ifp); 7367 error = 0; 7368 } 7369 7370 splx(s); 7371 7372 return (error); 7373 } 7374 7375 static void 7376 bwi_start(struct ifnet *ifp) 7377 { 7378 struct bwi_softc *sc = ifp->if_softc; 7379 struct ieee80211com *ic = &sc->sc_ic; 7380 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 7381 int trans, idx; 7382 7383 /* [TRC: XXX I'm not sure under which conditions we're actually 7384 supposed to refuse to start, so I'm copying what OpenBSD and 7385 DragonFlyBSD do, even if no one else on NetBSD does it. */ 7386 if ((ifp->if_flags & IFF_OACTIVE) || 7387 (ifp->if_flags & IFF_RUNNING) == 0) 7388 return; 7389 7390 trans = 0; 7391 idx = tbd->tbd_idx; 7392 7393 while (tbd->tbd_buf[idx].tb_mbuf == NULL) { 7394 struct ieee80211_frame *wh; 7395 struct ieee80211_node *ni; 7396 struct mbuf *m; 7397 int mgt_pkt = 0; 7398 7399 IF_DEQUEUE(&ic->ic_mgtq, m); 7400 if (m != NULL) { 7401 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 7402 m->m_pkthdr.rcvif = NULL; 7403 7404 mgt_pkt = 1; 7405 } else { 7406 struct ether_header *eh; 7407 7408 if (ic->ic_state != IEEE80211_S_RUN) 7409 break; 7410 7411 IFQ_DEQUEUE(&ifp->if_snd, m); 7412 if (m == NULL) 7413 break; 7414 7415 if (m->m_len < sizeof(*eh)) { 7416 m = m_pullup(m, sizeof(*eh)); 7417 if (m == NULL) { 7418 ifp->if_oerrors++; 7419 continue; 7420 } 7421 } 7422 eh = mtod(m, struct ether_header *); 7423 7424 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 7425 if (ni == NULL) { 7426 ifp->if_oerrors++; 7427 m_freem(m); 7428 continue; 7429 } 7430 7431 /* [TRC: XXX Superstitiously cargo-culted from 7432 ath(4) and wi(4).] */ 7433 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && 7434 (m->m_flags & M_PWR_SAV) == 0) { 7435 ieee80211_pwrsave(ic, ni, m); 7436 ieee80211_free_node(ni); 7437 continue; 7438 } 7439 7440 /* [TRC: XXX I *think* we're supposed to do 7441 this, but honestly I have no clue. We don't 7442 use M_WME_GETAC, so...] */ 7443 if (ieee80211_classify(ic, m, ni)) { 7444 /* [TRC: XXX What debug flag?] */ 7445 DPRINTF(sc, BWI_DBG_MISC, 7446 "%s: discard, classification failure\n", 7447 __func__); 7448 ifp->if_oerrors++; 7449 m_freem(m); 7450 ieee80211_free_node(ni); 7451 continue; 7452 } 7453 7454 /* [TRC: XXX wi(4) and awi(4) do this; iwi(4) 7455 doesn't.] */ 7456 ifp->if_opackets++; 7457 7458 /* [TRC: XXX When should the packet be 7459 filtered? Different drivers appear to do it 7460 at different times.] */ 7461 /* TODO: PS */ 7462 #if NBPFILTER > 0 7463 if (ifp->if_bpf != NULL) 7464 bpf_mtap(ifp->if_bpf, m); 7465 #endif 7466 m = ieee80211_encap(ic, m, ni); 7467 if (m == NULL) { 7468 ifp->if_oerrors++; 7469 ieee80211_free_node(ni); 7470 continue; 7471 } 7472 } 7473 #if NBPFILTER > 0 7474 if (ic->ic_rawbpf != NULL) 7475 bpf_mtap(ic->ic_rawbpf, m); 7476 #endif 7477 7478 wh = mtod(m, struct ieee80211_frame *); 7479 /* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */ 7480 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 7481 if (ieee80211_crypto_encap(ic, ni, m) == NULL) { 7482 ifp->if_oerrors++; 7483 m_freem(m); 7484 ieee80211_free_node(ni); 7485 continue; 7486 } 7487 } 7488 wh = NULL; /* [TRC: XXX Huh?] */ 7489 7490 if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) { 7491 /* 'm' is freed in bwi_encap() if we reach here */ 7492 ifp->if_oerrors++; 7493 if (ni != NULL) 7494 ieee80211_free_node(ni); 7495 continue; 7496 } 7497 7498 trans = 1; 7499 tbd->tbd_used++; 7500 idx = (idx + 1) % BWI_TX_NDESC; 7501 7502 if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { 7503 ifp->if_flags |= IFF_OACTIVE; 7504 break; 7505 } 7506 } 7507 tbd->tbd_idx = idx; 7508 7509 if (trans) 7510 sc->sc_tx_timer = 5; 7511 ifp->if_timer = 1; 7512 } 7513 7514 static void 7515 bwi_watchdog(struct ifnet *ifp) 7516 { 7517 struct bwi_softc *sc = ifp->if_softc; 7518 7519 ifp->if_timer = 0; 7520 7521 if ((ifp->if_flags & IFF_RUNNING) == 0 || 7522 !device_is_active(&sc->sc_dev)) 7523 return; 7524 7525 if (sc->sc_tx_timer) { 7526 if (--sc->sc_tx_timer == 0) { 7527 aprint_error_dev(&sc->sc_dev, "device timeout\n"); 7528 ifp->if_oerrors++; 7529 /* TODO */ 7530 /* [TRC: XXX TODO what? Stop the device? 7531 Bring it down? iwi(4) does this.] */ 7532 } else 7533 ifp->if_timer = 1; 7534 } 7535 7536 ieee80211_watchdog(&sc->sc_ic); 7537 } 7538 7539 static void 7540 bwi_stop(struct ifnet *ifp, int state_chg) 7541 { 7542 struct bwi_softc *sc = ifp->if_softc; 7543 struct ieee80211com *ic = &sc->sc_ic; 7544 struct bwi_mac *mac; 7545 int i, error, pwr_off = 0; 7546 7547 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 7548 7549 if (state_chg) 7550 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 7551 else 7552 bwi_newstate_begin(sc, IEEE80211_S_INIT); 7553 7554 if (ifp->if_flags & IFF_RUNNING) { 7555 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7556 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7557 7558 bwi_disable_intrs(sc, BWI_ALL_INTRS); 7559 CSR_READ_4(sc, BWI_MAC_INTR_MASK); 7560 bwi_mac_stop(mac); 7561 } 7562 7563 for (i = 0; i < sc->sc_nmac; ++i) { 7564 struct bwi_regwin *old_rw; 7565 7566 mac = &sc->sc_mac[i]; 7567 if ((mac->mac_flags & BWI_MAC_F_INITED) == 0) 7568 continue; 7569 7570 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw); 7571 if (error) 7572 continue; 7573 7574 bwi_mac_shutdown(mac); 7575 pwr_off = 1; 7576 7577 bwi_regwin_switch(sc, old_rw, NULL); 7578 } 7579 7580 if (pwr_off) 7581 bwi_bbp_power_off(sc); 7582 7583 sc->sc_tx_timer = 0; 7584 ifp->if_timer = 0; 7585 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 7586 7587 /* power off cardbus socket */ 7588 if (sc->sc_disable) 7589 (sc->sc_disable)(sc); 7590 7591 return; 7592 } 7593 7594 static void 7595 bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate) 7596 { 7597 callout_stop(&sc->sc_scan_ch); 7598 callout_stop(&sc->sc_calib_ch); 7599 7600 bwi_led_newstate(sc, nstate); 7601 7602 if (nstate == IEEE80211_S_INIT) 7603 sc->sc_txpwrcb_type = BWI_TXPWR_INIT; 7604 } 7605 7606 static int 7607 bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 7608 { 7609 struct bwi_softc *sc = ic->ic_ifp->if_softc; 7610 struct ieee80211_node *ni; 7611 int error; 7612 7613 /* [TRC: XXX amrr] */ 7614 callout_stop(&sc->sc_amrr_ch); 7615 7616 bwi_newstate_begin(sc, nstate); 7617 7618 if (nstate == IEEE80211_S_INIT) 7619 goto back; 7620 7621 /* [TRC: XXX What channel do we set this to? */ 7622 error = bwi_set_chan(sc, ic->ic_curchan); 7623 if (error) { 7624 aprint_error_dev(&sc->sc_dev, "can't set channel to %u\n", 7625 ieee80211_chan2ieee(ic, ic->ic_curchan)); 7626 return (error); 7627 } 7628 7629 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7630 /* Nothing to do */ 7631 } else if (nstate == IEEE80211_S_RUN) { 7632 struct bwi_mac *mac; 7633 7634 ni = ic->ic_bss; 7635 7636 bwi_set_bssid(sc, ic->ic_bss->ni_bssid); 7637 7638 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7639 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7640 7641 /* Initial TX power calibration */ 7642 bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT); 7643 #ifdef notyet 7644 sc->sc_txpwrcb_type = BWI_TXPWR_FORCE; 7645 #else 7646 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB; 7647 #endif 7648 /* [TRC: XXX amrr] */ 7649 if (ic->ic_opmode == IEEE80211_M_STA) { 7650 /* fake a join to init the tx rate */ 7651 bwi_newassoc(ni, 1); 7652 } 7653 7654 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 7655 /* start automatic rate control timer */ 7656 if (ic->ic_fixed_rate == -1) 7657 callout_schedule(&sc->sc_amrr_ch, hz / 2); 7658 } 7659 } else 7660 bwi_set_bssid(sc, bwi_zero_addr); 7661 7662 back: 7663 error = (sc->sc_newstate)(ic, nstate, arg); 7664 7665 if (nstate == IEEE80211_S_SCAN) { 7666 callout_schedule(&sc->sc_scan_ch, 7667 (sc->sc_dwell_time * hz) / 1000); 7668 } else if (nstate == IEEE80211_S_RUN) { 7669 /* XXX 15 seconds */ 7670 callout_schedule(&sc->sc_calib_ch, hz); 7671 } 7672 7673 return (error); 7674 } 7675 7676 static int 7677 bwi_media_change(struct ifnet *ifp) 7678 { 7679 int error; 7680 7681 error = ieee80211_media_change(ifp); 7682 if (error != ENETRESET) 7683 return (error); 7684 7685 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 7686 bwi_init(ifp); 7687 7688 return (0); 7689 } 7690 7691 /* [TRC: XXX amrr] */ 7692 static void 7693 bwi_iter_func(void *arg, struct ieee80211_node *ni) 7694 { 7695 struct bwi_softc *sc = arg; 7696 struct bwi_node *bn = (struct bwi_node *)ni; 7697 7698 ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn); 7699 } 7700 7701 static void 7702 bwi_amrr_timeout(void *arg) 7703 { 7704 struct bwi_softc *sc = arg; 7705 struct ieee80211com *ic = &sc->sc_ic; 7706 7707 if (ic->ic_opmode == IEEE80211_M_STA) 7708 bwi_iter_func(sc, ic->ic_bss); 7709 else 7710 /* [TRC: XXX I'm making a wild guess about what to 7711 supply for the node table.] */ 7712 ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc); 7713 7714 callout_schedule(&sc->sc_amrr_ch, hz / 2); 7715 } 7716 7717 static void 7718 bwi_newassoc(struct ieee80211_node *ni, int isnew) 7719 { 7720 struct ieee80211com *ic = ni->ni_ic; 7721 struct bwi_softc *sc = ic->ic_ifp->if_softc; 7722 int i; 7723 7724 DPRINTF(sc, BWI_DBG_STATION, "%s\n", __func__); 7725 7726 ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn); 7727 7728 /* set rate to some reasonable initial value */ 7729 for (i = ni->ni_rates.rs_nrates - 1; 7730 i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; 7731 i--); 7732 7733 ni->ni_txrate = i; 7734 } 7735 7736 static struct ieee80211_node * 7737 bwi_node_alloc(struct ieee80211_node_table *nt) 7738 { 7739 struct bwi_node *bn; 7740 7741 bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO); 7742 7743 return ((struct ieee80211_node *)bn); 7744 } 7745 /* [TRC: XXX amrr end] */ 7746 7747 static int 7748 bwi_dma_alloc(struct bwi_softc *sc) 7749 { 7750 int error, i, has_txstats; 7751 /* [TRC: XXX DragonFlyBSD adjusts the low address for different 7752 bus spaces. Should we?] */ 7753 bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0; 7754 uint32_t txrx_ctrl_step = 0; 7755 7756 has_txstats = 0; 7757 for (i = 0; i < sc->sc_nmac; ++i) { 7758 if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) { 7759 has_txstats = 1; 7760 break; 7761 } 7762 } 7763 7764 switch (sc->sc_bus_space) { 7765 case BWI_BUS_SPACE_30BIT: 7766 case BWI_BUS_SPACE_32BIT: 7767 desc_sz = sizeof(struct bwi_desc32); 7768 txrx_ctrl_step = 0x20; 7769 7770 sc->sc_init_tx_ring = bwi_init_tx_ring32; 7771 sc->sc_free_tx_ring = bwi_free_tx_ring32; 7772 sc->sc_init_rx_ring = bwi_init_rx_ring32; 7773 sc->sc_free_rx_ring = bwi_free_rx_ring32; 7774 sc->sc_setup_rxdesc = bwi_setup_rx_desc32; 7775 sc->sc_setup_txdesc = bwi_setup_tx_desc32; 7776 sc->sc_rxeof = bwi_rxeof32; 7777 sc->sc_start_tx = bwi_start_tx32; 7778 if (has_txstats) { 7779 sc->sc_init_txstats = bwi_init_txstats32; 7780 sc->sc_free_txstats = bwi_free_txstats32; 7781 sc->sc_txeof_status = bwi_txeof_status32; 7782 } 7783 break; 7784 7785 case BWI_BUS_SPACE_64BIT: 7786 desc_sz = sizeof(struct bwi_desc64); 7787 txrx_ctrl_step = 0x40; 7788 7789 sc->sc_init_tx_ring = bwi_init_tx_ring64; 7790 sc->sc_free_tx_ring = bwi_free_tx_ring64; 7791 sc->sc_init_rx_ring = bwi_init_rx_ring64; 7792 sc->sc_free_rx_ring = bwi_free_rx_ring64; 7793 sc->sc_setup_rxdesc = bwi_setup_rx_desc64; 7794 sc->sc_setup_txdesc = bwi_setup_tx_desc64; 7795 sc->sc_rxeof = bwi_rxeof64; 7796 sc->sc_start_tx = bwi_start_tx64; 7797 if (has_txstats) { 7798 sc->sc_init_txstats = bwi_init_txstats64; 7799 sc->sc_free_txstats = bwi_free_txstats64; 7800 sc->sc_txeof_status = bwi_txeof_status64; 7801 } 7802 break; 7803 } 7804 7805 KASSERT(desc_sz != 0); 7806 KASSERT(txrx_ctrl_step != 0); 7807 7808 tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN); 7809 rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN); 7810 7811 /* [TRC: XXX Using OpenBSD's code, which is rather different 7812 from DragonFlyBSD's.] */ 7813 #define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step) 7814 /* 7815 * Create TX ring DMA stuffs 7816 */ 7817 for (i = 0; i < BWI_TX_NRING; ++i) { 7818 error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1, 7819 tx_ring_sz, 0, BUS_DMA_NOWAIT, 7820 &sc->sc_tx_rdata[i].rdata_dmap); 7821 if (error) { 7822 aprint_error_dev(&sc->sc_dev, 7823 "%dth TX ring DMA create failed\n", i); 7824 return (error); 7825 } 7826 error = bwi_dma_ring_alloc(sc, 7827 &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i)); 7828 if (error) { 7829 aprint_error_dev(&sc->sc_dev, 7830 "%dth TX ring DMA alloc failed\n", i); 7831 return (error); 7832 } 7833 } 7834 7835 /* 7836 * Create RX ring DMA stuffs 7837 */ 7838 error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1, 7839 rx_ring_sz, 0, BUS_DMA_NOWAIT, 7840 &sc->sc_rx_rdata.rdata_dmap); 7841 if (error) { 7842 aprint_error_dev(&sc->sc_dev, "RX ring DMA create failed\n"); 7843 return (error); 7844 } 7845 7846 error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata, 7847 rx_ring_sz, TXRX_CTRL(0)); 7848 if (error) { 7849 aprint_error_dev(&sc->sc_dev, "RX ring DMA alloc failed\n"); 7850 return (error); 7851 } 7852 7853 if (has_txstats) { 7854 error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz); 7855 if (error) { 7856 aprint_error_dev(&sc->sc_dev, 7857 "TX stats DMA alloc failed\n"); 7858 return (error); 7859 } 7860 } 7861 #undef TXRX_CTRL 7862 7863 return (bwi_dma_mbuf_create(sc)); 7864 } 7865 7866 static void 7867 bwi_dma_free(struct bwi_softc *sc) 7868 { 7869 int i; 7870 7871 for (i = 0; i < BWI_TX_NRING; ++i) 7872 bwi_ring_data_free(&sc->sc_tx_rdata[i], sc); 7873 7874 bwi_ring_data_free(&sc->sc_rx_rdata, sc); 7875 bwi_dma_txstats_free(sc); 7876 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1); 7877 } 7878 7879 static void 7880 bwi_ring_data_free(struct bwi_ring_data *rd, struct bwi_softc *sc) 7881 { 7882 if (rd->rdata_desc != NULL) { 7883 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap); 7884 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1); 7885 } 7886 } 7887 7888 static int 7889 bwi_dma_ring_alloc(struct bwi_softc *sc, 7890 struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl) 7891 { 7892 int error, nsegs; 7893 7894 error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0, 7895 &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT); 7896 if (error) { 7897 aprint_error_dev(&sc->sc_dev, "can't allocate DMA mem\n"); 7898 return (error); 7899 } 7900 7901 error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs, 7902 size, (void **)&rd->rdata_desc, BUS_DMA_NOWAIT); 7903 if (error) { 7904 aprint_error_dev(&sc->sc_dev, "can't map DMA mem\n"); 7905 return (error); 7906 } 7907 7908 error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc, 7909 size, NULL, BUS_DMA_WAITOK); 7910 if (error) { 7911 aprint_error_dev(&sc->sc_dev, "can't load DMA mem\n"); 7912 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs); 7913 rd->rdata_desc = NULL; 7914 return (error); 7915 } 7916 7917 rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr; 7918 rd->rdata_txrx_ctrl = txrx_ctrl; 7919 7920 return (0); 7921 } 7922 7923 static int 7924 bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base, 7925 bus_size_t desc_sz) 7926 { 7927 struct bwi_txstats_data *st; 7928 bus_size_t dma_size; 7929 int error, nsegs; 7930 7931 st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO); 7932 sc->sc_txstats = st; 7933 7934 /* 7935 * Create TX stats descriptor DMA stuffs 7936 */ 7937 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN); 7938 7939 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 7940 BUS_DMA_NOWAIT, &st->stats_ring_dmap); 7941 if (error) { 7942 aprint_error_dev(&sc->sc_dev, 7943 "can't create txstats ring DMA mem\n"); 7944 return (error); 7945 } 7946 7947 /* 7948 * Create TX stats descriptor DMA stuffs 7949 */ 7950 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN); 7951 7952 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 7953 BUS_DMA_NOWAIT, &st->stats_ring_dmap); 7954 if (error) { 7955 aprint_error_dev(&sc->sc_dev, 7956 "can't create txstats ring DMA mem\n"); 7957 return (error); 7958 } 7959 7960 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0, 7961 &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT); 7962 if (error) { 7963 aprint_error_dev(&sc->sc_dev, 7964 "can't allocate txstats ring DMA mem\n"); 7965 return (error); 7966 } 7967 7968 error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs, 7969 dma_size, (void **)&st->stats_ring, BUS_DMA_NOWAIT); 7970 if (error) { 7971 aprint_error_dev(&sc->sc_dev, 7972 "can't map txstats ring DMA mem\n"); 7973 return (error); 7974 } 7975 7976 error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap, 7977 st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK); 7978 if (error) { 7979 aprint_error_dev(&sc->sc_dev, 7980 "can't load txstats ring DMA mem\n"); 7981 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs); 7982 return (error); 7983 } 7984 7985 bzero(st->stats_ring, dma_size); 7986 st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr; 7987 7988 /* 7989 * Create TX stats DMA stuffs 7990 */ 7991 dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC, 7992 BWI_ALIGN); 7993 7994 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 7995 BUS_DMA_NOWAIT, &st->stats_dmap); 7996 if (error) { 7997 aprint_error_dev(&sc->sc_dev, 7998 "can't create txstats ring DMA mem\n"); 7999 return (error); 8000 } 8001 8002 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0, 8003 &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT); 8004 if (error) { 8005 aprint_error_dev(&sc->sc_dev, 8006 "can't allocate txstats DMA mem\n"); 8007 return (error); 8008 } 8009 8010 error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs, 8011 dma_size, (void **)&st->stats, BUS_DMA_NOWAIT); 8012 if (error) { 8013 aprint_error_dev(&sc->sc_dev, "can't map txstats DMA mem\n"); 8014 return (error); 8015 } 8016 8017 error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats, 8018 dma_size, NULL, BUS_DMA_WAITOK); 8019 if (error) { 8020 aprint_error_dev(&sc->sc_dev, "can't load txstats DMA mem\n"); 8021 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs); 8022 return (error); 8023 } 8024 8025 bzero(st->stats, dma_size); 8026 st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr; 8027 st->stats_ctrl_base = ctrl_base; 8028 8029 return (0); 8030 } 8031 8032 static void 8033 bwi_dma_txstats_free(struct bwi_softc *sc) 8034 { 8035 struct bwi_txstats_data *st; 8036 8037 if (sc->sc_txstats == NULL) 8038 return; 8039 st = sc->sc_txstats; 8040 8041 bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap); 8042 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1); 8043 8044 bus_dmamap_unload(sc->sc_dmat, st->stats_dmap); 8045 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1); 8046 8047 free(st, M_DEVBUF); 8048 } 8049 8050 static int 8051 bwi_dma_mbuf_create(struct bwi_softc *sc) 8052 { 8053 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8054 int i, j, k, ntx, error; 8055 8056 ntx = 0; 8057 8058 /* 8059 * Create TX mbuf DMA map 8060 */ 8061 for (i = 0; i < BWI_TX_NRING; ++i) { 8062 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 8063 8064 for (j = 0; j < BWI_TX_NDESC; ++j) { 8065 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 8066 0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap); 8067 if (error) { 8068 aprint_error_dev(&sc->sc_dev, 8069 "can't create %dth tbd, %dth DMA map\n", 8070 i, j); 8071 ntx = i; 8072 for (k = 0; k < j; ++k) { 8073 bus_dmamap_destroy(sc->sc_dmat, 8074 tbd->tbd_buf[k].tb_dmap); 8075 } 8076 goto fail; 8077 } 8078 } 8079 } 8080 ntx = BWI_TX_NRING; 8081 8082 /* 8083 * Create RX mbuf DMA map and a spare DMA map 8084 */ 8085 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 8086 BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap); 8087 if (error) { 8088 aprint_error_dev(&sc->sc_dev, 8089 "can't create spare RX buf DMA map\n"); 8090 goto fail; 8091 } 8092 8093 for (j = 0; j < BWI_RX_NDESC; ++j) { 8094 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 8095 BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap); 8096 if (error) { 8097 aprint_error_dev(&sc->sc_dev, 8098 "can't create %dth RX buf DMA map\n", j); 8099 8100 for (k = 0; k < j; ++k) { 8101 bus_dmamap_destroy(sc->sc_dmat, 8102 rbd->rbd_buf[j].rb_dmap); 8103 } 8104 bus_dmamap_destroy(sc->sc_dmat, 8105 rbd->rbd_tmp_dmap); 8106 goto fail; 8107 } 8108 } 8109 8110 return (0); 8111 fail: 8112 bwi_dma_mbuf_destroy(sc, ntx, 0); 8113 8114 return (error); 8115 } 8116 8117 static void 8118 bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx) 8119 { 8120 int i, j; 8121 8122 for (i = 0; i < ntx; ++i) { 8123 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 8124 8125 for (j = 0; j < BWI_TX_NDESC; ++j) { 8126 struct bwi_txbuf *tb = &tbd->tbd_buf[j]; 8127 8128 if (tb->tb_mbuf != NULL) { 8129 bus_dmamap_unload(sc->sc_dmat, 8130 tb->tb_dmap); 8131 m_freem(tb->tb_mbuf); 8132 } 8133 if (tb->tb_ni != NULL) 8134 ieee80211_free_node(tb->tb_ni); 8135 bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap); 8136 } 8137 } 8138 8139 if (nrx) { 8140 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8141 8142 bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap); 8143 for (j = 0; j < BWI_RX_NDESC; ++j) { 8144 struct bwi_rxbuf *rb = &rbd->rbd_buf[j]; 8145 8146 if (rb->rb_mbuf != NULL) { 8147 bus_dmamap_unload(sc->sc_dmat, 8148 rb->rb_dmap); 8149 m_freem(rb->rb_mbuf); 8150 } 8151 bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap); 8152 } 8153 } 8154 } 8155 8156 static void 8157 bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs) 8158 { 8159 CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs); 8160 } 8161 8162 static void 8163 bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs) 8164 { 8165 CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs); 8166 } 8167 8168 static int 8169 bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx) 8170 { 8171 struct bwi_ring_data *rd; 8172 struct bwi_txbuf_data *tbd; 8173 uint32_t val, addr_hi, addr_lo; 8174 8175 KASSERT(ring_idx < BWI_TX_NRING); 8176 rd = &sc->sc_tx_rdata[ring_idx]; 8177 tbd = &sc->sc_tx_bdata[ring_idx]; 8178 8179 tbd->tbd_idx = 0; 8180 tbd->tbd_used = 0; 8181 8182 bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_TX_NDESC); 8183 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8184 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8185 8186 addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 8187 addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 8188 8189 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 8190 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 8191 BWI_TXRX32_RINGINFO_FUNC_MASK); 8192 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val); 8193 8194 val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 8195 BWI_TXRX32_CTRL_ENABLE; 8196 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val); 8197 8198 return (0); 8199 } 8200 8201 static void 8202 bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base, 8203 bus_addr_t paddr, int hdr_size, int ndesc) 8204 { 8205 uint32_t val, addr_hi, addr_lo; 8206 8207 addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 8208 addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 8209 8210 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 8211 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 8212 BWI_TXRX32_RINGINFO_FUNC_MASK); 8213 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val); 8214 8215 val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) | 8216 __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 8217 BWI_TXRX32_CTRL_ENABLE; 8218 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val); 8219 8220 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 8221 (ndesc - 1) * sizeof(struct bwi_desc32)); 8222 } 8223 8224 static int 8225 bwi_init_rx_ring32(struct bwi_softc *sc) 8226 { 8227 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8228 int i, error; 8229 8230 sc->sc_rx_bdata.rbd_idx = 0; 8231 8232 for (i = 0; i < BWI_RX_NDESC; ++i) { 8233 error = bwi_newbuf(sc, i, 1); 8234 if (error) { 8235 aprint_error_dev(&sc->sc_dev, 8236 "can't allocate %dth RX buffer\n", i); 8237 return (error); 8238 } 8239 } 8240 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8241 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8242 8243 bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr, 8244 sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC); 8245 return (0); 8246 } 8247 8248 static int 8249 bwi_init_txstats32(struct bwi_softc *sc) 8250 { 8251 struct bwi_txstats_data *st = sc->sc_txstats; 8252 bus_addr_t stats_paddr; 8253 int i; 8254 8255 bzero(st->stats, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats)); 8256 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 8257 st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8258 8259 st->stats_idx = 0; 8260 8261 stats_paddr = st->stats_paddr; 8262 for (i = 0; i < BWI_TXSTATS_NDESC; ++i) { 8263 bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i, 8264 stats_paddr, sizeof(struct bwi_txstats), 0); 8265 stats_paddr += sizeof(struct bwi_txstats); 8266 } 8267 bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0, 8268 st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8269 8270 bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base, 8271 st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC); 8272 8273 return (0); 8274 } 8275 8276 static void 8277 bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 8278 int buf_len) 8279 { 8280 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8281 8282 KASSERT(buf_idx < BWI_RX_NDESC); 8283 bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx, 8284 paddr, buf_len, 0); 8285 } 8286 8287 static void 8288 bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd, 8289 int buf_idx, bus_addr_t paddr, int buf_len) 8290 { 8291 KASSERT(buf_idx < BWI_TX_NDESC); 8292 bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx, 8293 paddr, buf_len, 1); 8294 } 8295 static int 8296 bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx) 8297 { 8298 /* TODO: 64 */ 8299 return (EOPNOTSUPP); 8300 } 8301 8302 static int 8303 bwi_init_rx_ring64(struct bwi_softc *sc) 8304 { 8305 /* TODO: 64 */ 8306 return (EOPNOTSUPP); 8307 } 8308 8309 static int 8310 bwi_init_txstats64(struct bwi_softc *sc) 8311 { 8312 /* TODO: 64 */ 8313 return (EOPNOTSUPP); 8314 } 8315 8316 static void 8317 bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 8318 int buf_len) 8319 { 8320 /* TODO: 64 */ 8321 } 8322 8323 static void 8324 bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd, 8325 int buf_idx, bus_addr_t paddr, int buf_len) 8326 { 8327 /* TODO: 64 */ 8328 } 8329 8330 static int 8331 bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init) 8332 { 8333 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8334 struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx]; 8335 struct bwi_rxbuf_hdr *hdr; 8336 bus_dmamap_t map; 8337 bus_addr_t paddr; 8338 struct mbuf *m; 8339 int error; 8340 8341 KASSERT(buf_idx < BWI_RX_NDESC); 8342 8343 MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA); 8344 if (m == NULL) 8345 return (ENOBUFS); 8346 MCLGET(m, init ? M_WAITOK : M_DONTWAIT); 8347 if (m == NULL) { 8348 error = ENOBUFS; 8349 8350 /* 8351 * If the NIC is up and running, we need to: 8352 * - Clear RX buffer's header. 8353 * - Restore RX descriptor settings. 8354 */ 8355 if (init) 8356 return error; 8357 else 8358 goto back; 8359 } 8360 m->m_len = m->m_pkthdr.len = MCLBYTES; 8361 8362 /* 8363 * Try to load RX buf into temporary DMA map 8364 */ 8365 error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m, 8366 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT); 8367 if (error) { 8368 m_freem(m); 8369 8370 /* 8371 * See the comment above 8372 */ 8373 if (init) 8374 return error; 8375 else 8376 goto back; 8377 } 8378 8379 if (!init) 8380 bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap); 8381 rxbuf->rb_mbuf = m; 8382 8383 /* 8384 * Swap RX buf's DMA map with the loaded temporary one 8385 */ 8386 map = rxbuf->rb_dmap; 8387 rxbuf->rb_dmap = rbd->rbd_tmp_dmap; 8388 rbd->rbd_tmp_dmap = map; 8389 paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr; 8390 rxbuf->rb_paddr = paddr; 8391 8392 back: 8393 /* 8394 * Clear RX buf header 8395 */ 8396 hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *); 8397 bzero(hdr, sizeof(*hdr)); 8398 bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0, 8399 rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8400 8401 /* 8402 * Setup RX buf descriptor 8403 */ 8404 (sc->sc_setup_rxdesc)(sc, buf_idx, rxbuf->rb_paddr, 8405 rxbuf->rb_mbuf->m_len - sizeof(*hdr)); 8406 return error; 8407 } 8408 8409 static void 8410 bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs, 8411 const uint8_t *addr) 8412 { 8413 int i; 8414 8415 CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL, 8416 BWI_ADDR_FILTER_CTRL_SET | addr_ofs); 8417 8418 for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) { 8419 uint16_t addr_val; 8420 8421 addr_val = (uint16_t)addr[i * 2] | 8422 (((uint16_t)addr[(i * 2) + 1]) << 8); 8423 CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val); 8424 } 8425 } 8426 8427 static int 8428 bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c) 8429 { 8430 struct ieee80211com *ic = &sc->sc_ic; 8431 struct bwi_mac *mac; 8432 /* uint16_t flags; */ /* [TRC: XXX See below.] */ 8433 uint chan; 8434 8435 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 8436 mac = (struct bwi_mac *)sc->sc_cur_regwin; 8437 8438 chan = ieee80211_chan2ieee(ic, c); 8439 8440 bwi_rf_set_chan(mac, chan, 0); 8441 8442 /* [TRC: XXX DragonFlyBSD sets up radio tap channel frequency 8443 and flags here. OpenBSD does not, and appears to do so 8444 later (in bwi_rxeof and bwi_encap).] */ 8445 8446 return (0); 8447 } 8448 8449 static void 8450 bwi_next_scan(void *xsc) 8451 { 8452 struct bwi_softc *sc = xsc; 8453 struct ieee80211com *ic = &sc->sc_ic; 8454 int s; 8455 8456 s = splnet(); 8457 8458 if (ic->ic_state == IEEE80211_S_SCAN) 8459 ieee80211_next_scan(ic); 8460 8461 splx(s); 8462 } 8463 8464 static int 8465 bwi_rxeof(struct bwi_softc *sc, int end_idx) 8466 { 8467 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8468 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8469 struct ieee80211com *ic = &sc->sc_ic; 8470 struct ifnet *ifp = &sc->sc_if; 8471 int idx, rx_data = 0; 8472 8473 idx = rbd->rbd_idx; 8474 while (idx != end_idx) { 8475 struct bwi_rxbuf *rb = &rbd->rbd_buf[idx]; 8476 struct bwi_rxbuf_hdr *hdr; 8477 struct ieee80211_frame_min *wh; 8478 struct ieee80211_node *ni; 8479 struct mbuf *m; 8480 const void *plcp; 8481 uint16_t flags2; 8482 int buflen, wh_ofs, hdr_extra, rssi, type, rate; 8483 8484 m = rb->rb_mbuf; 8485 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0, 8486 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 8487 8488 if (bwi_newbuf(sc, idx, 0)) { 8489 ifp->if_ierrors++; 8490 goto next; 8491 } 8492 8493 hdr = mtod(m, struct bwi_rxbuf_hdr *); 8494 flags2 = le16toh(hdr->rxh_flags2); 8495 8496 hdr_extra = 0; 8497 if (flags2 & BWI_RXH_F2_TYPE2FRAME) 8498 hdr_extra = 2; 8499 wh_ofs = hdr_extra + 6; /* XXX magic number */ 8500 8501 buflen = le16toh(hdr->rxh_buflen); 8502 if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { 8503 aprint_error_dev(&sc->sc_dev, "short frame %d," 8504 " hdr_extra %d\n", buflen, hdr_extra); 8505 ifp->if_ierrors++; 8506 m_freem(m); 8507 goto next; 8508 } 8509 8510 plcp = ((const uint8_t *)(hdr + 1) + hdr_extra); 8511 rssi = bwi_calc_rssi(sc, hdr); 8512 8513 m->m_pkthdr.rcvif = ifp; 8514 m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); 8515 m_adj(m, sizeof(*hdr) + wh_ofs); 8516 8517 if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM) 8518 rate = bwi_ofdm_plcp2rate(plcp); 8519 else 8520 rate = bwi_ds_plcp2rate(plcp); 8521 8522 #if NBPFILTER > 0 8523 /* RX radio tap */ 8524 if (sc->sc_drvbpf != NULL) { 8525 struct mbuf mb; 8526 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap; 8527 8528 tap->wr_tsf = hdr->rxh_tsf; 8529 tap->wr_flags = 0; 8530 tap->wr_rate = rate; 8531 tap->wr_chan_freq = 8532 htole16(ic->ic_bss->ni_chan->ic_freq); 8533 tap->wr_chan_flags = 8534 htole16(ic->ic_bss->ni_chan->ic_flags); 8535 tap->wr_antsignal = rssi; 8536 tap->wr_antnoise = BWI_NOISE_FLOOR; 8537 8538 mb.m_data = (void *)tap; 8539 mb.m_len = sc->sc_rxtap_len; 8540 mb.m_next = m; 8541 mb.m_nextpkt = NULL; 8542 mb.m_type = 0; 8543 mb.m_flags = 0; 8544 bpf_mtap(sc->sc_drvbpf, &mb); 8545 } 8546 #endif 8547 8548 m_adj(m, -IEEE80211_CRC_LEN); 8549 8550 wh = mtod(m, struct ieee80211_frame_min *); 8551 ni = ieee80211_find_rxnode(ic, wh); 8552 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 8553 8554 ieee80211_input(ic, m, ni, hdr->rxh_rssi, 8555 le16toh(hdr->rxh_tsf)); 8556 8557 ieee80211_free_node(ni); 8558 8559 if (type == IEEE80211_FC0_TYPE_DATA) { 8560 rx_data = 1; 8561 sc->sc_rx_rate = rate; 8562 } 8563 next: 8564 idx = (idx + 1) % BWI_RX_NDESC; 8565 } 8566 8567 rbd->rbd_idx = idx; 8568 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8569 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8570 8571 return (rx_data); 8572 } 8573 8574 static int 8575 bwi_rxeof32(struct bwi_softc *sc) 8576 { 8577 uint32_t val, rx_ctrl; 8578 int end_idx, rx_data; 8579 8580 rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl; 8581 8582 val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 8583 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 8584 sizeof(struct bwi_desc32); 8585 8586 rx_data = bwi_rxeof(sc, end_idx); 8587 8588 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX, 8589 end_idx * sizeof(struct bwi_desc32)); 8590 8591 return (rx_data); 8592 } 8593 8594 static int 8595 bwi_rxeof64(struct bwi_softc *sc) 8596 { 8597 /* TODO: 64 */ 8598 return (0); 8599 } 8600 8601 static void 8602 bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl) 8603 { 8604 int i; 8605 8606 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0); 8607 8608 #define NRETRY 10 8609 for (i = 0; i < NRETRY; ++i) { 8610 uint32_t status; 8611 8612 status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 8613 if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) == 8614 BWI_RX32_STATUS_STATE_DISABLED) 8615 break; 8616 8617 DELAY(1000); 8618 } 8619 if (i == NRETRY) 8620 aprint_error_dev(&sc->sc_dev, "reset rx ring timedout\n"); 8621 #undef NRETRY 8622 8623 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0); 8624 } 8625 8626 static void 8627 bwi_free_txstats32(struct bwi_softc *sc) 8628 { 8629 bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base); 8630 } 8631 8632 static void 8633 bwi_free_rx_ring32(struct bwi_softc *sc) 8634 { 8635 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8636 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8637 int i; 8638 8639 bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl); 8640 8641 for (i = 0; i < BWI_RX_NDESC; ++i) { 8642 struct bwi_rxbuf *rb = &rbd->rbd_buf[i]; 8643 8644 if (rb->rb_mbuf != NULL) { 8645 bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap); 8646 m_freem(rb->rb_mbuf); 8647 rb->rb_mbuf = NULL; 8648 } 8649 } 8650 } 8651 8652 static void 8653 bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx) 8654 { 8655 struct bwi_ring_data *rd; 8656 struct bwi_txbuf_data *tbd; 8657 uint32_t state, val; 8658 int i; 8659 8660 KASSERT(ring_idx < BWI_TX_NRING); 8661 rd = &sc->sc_tx_rdata[ring_idx]; 8662 tbd = &sc->sc_tx_bdata[ring_idx]; 8663 8664 #define NRETRY 10 8665 for (i = 0; i < NRETRY; ++i) { 8666 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 8667 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 8668 if (state == BWI_TX32_STATUS_STATE_DISABLED || 8669 state == BWI_TX32_STATUS_STATE_IDLE || 8670 state == BWI_TX32_STATUS_STATE_STOPPED) 8671 break; 8672 8673 DELAY(1000); 8674 } 8675 if (i == NRETRY) 8676 aprint_error_dev(&sc->sc_dev, 8677 "wait for TX ring(%d) stable timed out\n", ring_idx); 8678 8679 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0); 8680 for (i = 0; i < NRETRY; ++i) { 8681 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 8682 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 8683 if (state == BWI_TX32_STATUS_STATE_DISABLED) 8684 break; 8685 8686 DELAY(1000); 8687 } 8688 if (i == NRETRY) 8689 aprint_error_dev(&sc->sc_dev, "reset TX ring (%d) timed out\n", 8690 ring_idx); 8691 #undef NRETRY 8692 8693 DELAY(1000); 8694 8695 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0); 8696 8697 for (i = 0; i < BWI_TX_NDESC; ++i) { 8698 struct bwi_txbuf *tb = &tbd->tbd_buf[i]; 8699 8700 if (tb->tb_mbuf != NULL) { 8701 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 8702 m_freem(tb->tb_mbuf); 8703 tb->tb_mbuf = NULL; 8704 } 8705 if (tb->tb_ni != NULL) { 8706 ieee80211_free_node(tb->tb_ni); 8707 tb->tb_ni = NULL; 8708 } 8709 } 8710 } 8711 8712 static void 8713 bwi_free_txstats64(struct bwi_softc *sc) 8714 { 8715 /* TODO: 64 */ 8716 } 8717 8718 static void 8719 bwi_free_rx_ring64(struct bwi_softc *sc) 8720 { 8721 /* TODO: 64 */ 8722 } 8723 8724 static void 8725 bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx) 8726 { 8727 /* TODO: 64 */ 8728 } 8729 8730 /* XXX does not belong here */ 8731 /* [TRC: Begin pilferage from OpenBSD.] */ 8732 8733 /* 8734 * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa. 8735 */ 8736 uint8_t 8737 bwi_ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode) 8738 { 8739 rate &= IEEE80211_RATE_VAL; 8740 8741 if (mode == IEEE80211_MODE_11B) { 8742 /* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */ 8743 switch (rate) { 8744 case 2: return 10; 8745 case 4: return 20; 8746 case 11: return 55; 8747 case 22: return 110; 8748 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 8749 case 44: return 220; 8750 } 8751 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 8752 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 8753 switch (rate) { 8754 case 12: return 0x0b; 8755 case 18: return 0x0f; 8756 case 24: return 0x0a; 8757 case 36: return 0x0e; 8758 case 48: return 0x09; 8759 case 72: return 0x0d; 8760 case 96: return 0x08; 8761 case 108: return 0x0c; 8762 } 8763 } else 8764 panic("Unexpected mode %u", mode); 8765 8766 return 0; 8767 } 8768 8769 static uint8_t 8770 bwi_ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phymode mode) 8771 { 8772 if (mode == IEEE80211_MODE_11B) { 8773 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 8774 switch (plcp) { 8775 case 10: return 2; 8776 case 20: return 4; 8777 case 55: return 11; 8778 case 110: return 22; 8779 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 8780 case 220: return 44; 8781 } 8782 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 8783 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 8784 switch (plcp) { 8785 case 0x0b: return 12; 8786 case 0x0f: return 18; 8787 case 0x0a: return 24; 8788 case 0x0e: return 36; 8789 case 0x09: return 48; 8790 case 0x0d: return 72; 8791 case 0x08: return 96; 8792 case 0x0c: return 108; 8793 } 8794 } else 8795 panic("Unexpected mode %u", mode); 8796 8797 return 0; 8798 } 8799 /* [TRC: End pilferage from OpenBSD.] */ 8800 8801 static enum bwi_ieee80211_modtype 8802 bwi_ieee80211_rate2modtype(uint8_t rate) 8803 { 8804 rate &= IEEE80211_RATE_VAL; 8805 8806 if (rate == 44) 8807 return (IEEE80211_MODTYPE_PBCC); 8808 else if (rate == 22 || rate < 12) 8809 return (IEEE80211_MODTYPE_DS); 8810 else 8811 return (IEEE80211_MODTYPE_OFDM); 8812 } 8813 8814 static uint8_t 8815 bwi_ofdm_plcp2rate(const uint32_t *plcp0) 8816 { 8817 uint32_t plcp; 8818 uint8_t plcp_rate; 8819 8820 plcp = le32toh(*plcp0); 8821 plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK); 8822 8823 return (bwi_ieee80211_plcp2rate(plcp_rate, IEEE80211_MODE_11G)); 8824 } 8825 8826 static uint8_t 8827 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr) 8828 { 8829 return (bwi_ieee80211_plcp2rate(hdr->i_signal, IEEE80211_MODE_11B)); 8830 } 8831 8832 static void 8833 bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate) 8834 { 8835 uint32_t plcp; 8836 8837 plcp = __SHIFTIN(bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11G), 8838 IEEE80211_OFDM_PLCP_RATE_MASK) | 8839 __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK); 8840 *plcp0 = htole32(plcp); 8841 } 8842 8843 static void 8844 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len, 8845 uint8_t rate) 8846 { 8847 int len, service, pkt_bitlen; 8848 8849 pkt_bitlen = pkt_len * NBBY; 8850 len = howmany(pkt_bitlen * 2, rate); 8851 8852 service = IEEE80211_DS_PLCP_SERVICE_LOCKED; 8853 if (rate == (11 * 2)) { 8854 int pkt_bitlen1; 8855 8856 /* 8857 * PLCP service field needs to be adjusted, 8858 * if TX rate is 11Mbytes/s 8859 */ 8860 pkt_bitlen1 = len * 11; 8861 if (pkt_bitlen1 - pkt_bitlen >= NBBY) 8862 service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7; 8863 } 8864 8865 plcp->i_signal = bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11B); 8866 plcp->i_service = service; 8867 plcp->i_length = htole16(len); 8868 /* NOTE: do NOT touch i_crc */ 8869 } 8870 8871 static void 8872 bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate) 8873 { 8874 enum bwi_ieee80211_modtype modtype; 8875 8876 /* 8877 * Assume caller has zeroed 'plcp' 8878 */ 8879 8880 modtype = bwi_ieee80211_rate2modtype(rate); 8881 if (modtype == IEEE80211_MODTYPE_OFDM) 8882 bwi_ofdm_plcp_header(plcp, pkt_len, rate); 8883 else if (modtype == IEEE80211_MODTYPE_DS) 8884 bwi_ds_plcp_header(plcp, pkt_len, rate); 8885 else 8886 panic("unsupport modulation type %u\n", modtype); 8887 } 8888 8889 static uint8_t 8890 bwi_ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate) 8891 { 8892 const struct ieee80211_rateset *rs = &ni->ni_rates; 8893 uint8_t ack_rate = 0; 8894 enum bwi_ieee80211_modtype modtype; 8895 int i; 8896 8897 rate &= IEEE80211_RATE_VAL; 8898 8899 modtype = bwi_ieee80211_rate2modtype(rate); 8900 8901 for (i = 0; i < rs->rs_nrates; ++i) { 8902 uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL; 8903 8904 if (rate1 > rate) { 8905 if (ack_rate != 0) 8906 return (ack_rate); 8907 else 8908 break; 8909 } 8910 8911 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && 8912 bwi_ieee80211_rate2modtype(rate1) == modtype) 8913 ack_rate = rate1; 8914 } 8915 8916 switch (rate) { 8917 /* CCK */ 8918 case 2: 8919 case 4: 8920 case 11: 8921 case 22: 8922 ack_rate = rate; 8923 break; 8924 /* PBCC */ 8925 case 44: 8926 ack_rate = 22; 8927 break; 8928 8929 /* OFDM */ 8930 case 12: 8931 case 18: 8932 ack_rate = 12; 8933 break; 8934 case 24: 8935 case 36: 8936 ack_rate = 24; 8937 break; 8938 case 48: 8939 case 72: 8940 case 96: 8941 case 108: 8942 ack_rate = 48; 8943 break; 8944 default: 8945 panic("unsupported rate %d\n", rate); 8946 } 8947 return (ack_rate); 8948 } 8949 8950 /* [TRC: XXX does not belong here] */ 8951 8952 #define IEEE80211_OFDM_TXTIME(kbps, frmlen) \ 8953 (IEEE80211_OFDM_PREAMBLE_TIME + \ 8954 IEEE80211_OFDM_SIGNAL_TIME + \ 8955 (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME)) 8956 8957 #define IEEE80211_OFDM_SYM_TIME 4 8958 #define IEEE80211_OFDM_PREAMBLE_TIME 16 8959 #define IEEE80211_OFDM_SIGNAL_EXT_TIME 6 8960 #define IEEE80211_OFDM_SIGNAL_TIME 4 8961 8962 #define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16 8963 #define IEEE80211_OFDM_TAIL_NBITS 6 8964 8965 #define IEEE80211_OFDM_NBITS(frmlen) \ 8966 (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \ 8967 ((frmlen) * NBBY) + \ 8968 IEEE80211_OFDM_TAIL_NBITS) 8969 8970 #define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \ 8971 (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000) 8972 8973 #define IEEE80211_OFDM_NSYMS(kbps, frmlen) \ 8974 howmany(IEEE80211_OFDM_NBITS((frmlen)), \ 8975 IEEE80211_OFDM_NBITS_PER_SYM((kbps))) 8976 8977 #define IEEE80211_CCK_TXTIME(kbps, frmlen) \ 8978 (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps)) 8979 8980 #define IEEE80211_CCK_PREAMBLE_LEN 144 8981 #define IEEE80211_CCK_PLCP_HDR_TIME 48 8982 #define IEEE80211_CCK_SHPREAMBLE_LEN 72 8983 #define IEEE80211_CCK_SHPLCP_HDR_TIME 24 8984 8985 #define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY) 8986 8987 static uint16_t 8988 bwi_ieee80211_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, 8989 uint len, uint8_t rs_rate, uint32_t flags) 8990 { 8991 enum bwi_ieee80211_modtype modtype; 8992 uint16_t txtime; 8993 int rate; 8994 8995 rs_rate &= IEEE80211_RATE_VAL; 8996 8997 rate = rs_rate * 500; /* ieee80211 rate -> kbps */ 8998 8999 modtype = bwi_ieee80211_rate2modtype(rs_rate); 9000 if (modtype == IEEE80211_MODTYPE_OFDM) { 9001 /* 9002 * IEEE Std 802.11a-1999, page 37, equation (29) 9003 * IEEE Std 802.11g-2003, page 44, equation (42) 9004 */ 9005 txtime = IEEE80211_OFDM_TXTIME(rate, len); 9006 if (ic->ic_curmode == IEEE80211_MODE_11G) 9007 txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME; 9008 } else { 9009 /* 9010 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4 9011 * IEEE Std 802.11g-2003, page 45, equation (43) 9012 */ 9013 if (modtype == IEEE80211_MODTYPE_PBCC) 9014 ++len; 9015 txtime = IEEE80211_CCK_TXTIME(rate, len); 9016 9017 /* 9018 * Short preamble is not applicable for DS 1Mbits/s 9019 */ 9020 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) { 9021 txtime += IEEE80211_CCK_SHPREAMBLE_LEN + 9022 IEEE80211_CCK_SHPLCP_HDR_TIME; 9023 } else { 9024 txtime += IEEE80211_CCK_PREAMBLE_LEN + 9025 IEEE80211_CCK_PLCP_HDR_TIME; 9026 } 9027 } 9028 return (txtime); 9029 } 9030 9031 static int 9032 bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, 9033 struct ieee80211_node **nip, int mgt_pkt) 9034 { 9035 struct ieee80211com *ic = &sc->sc_ic; 9036 struct ieee80211_node *ni = *nip; 9037 struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; 9038 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 9039 struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; 9040 struct bwi_mac *mac; 9041 struct bwi_txbuf_hdr *hdr; 9042 struct ieee80211_frame *wh; 9043 uint8_t rate; /* [TRC: XXX Use a fallback rate?] */ 9044 uint32_t mac_ctrl; 9045 uint16_t phy_ctrl; 9046 bus_addr_t paddr; 9047 int pkt_len, error, mcast_pkt = 0; 9048 #if 0 9049 const uint8_t *p; 9050 int i; 9051 #endif 9052 9053 KASSERT(ni != NULL); 9054 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9055 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9056 9057 wh = mtod(m, struct ieee80211_frame *); 9058 9059 /* Get 802.11 frame len before prepending TX header */ 9060 pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN; 9061 9062 /* 9063 * Find TX rate 9064 */ 9065 bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx)); 9066 if (!mgt_pkt) { 9067 if (ic->ic_fixed_rate != -1) { 9068 rate = ic->ic_sup_rates[ic->ic_curmode]. 9069 rs_rates[ic->ic_fixed_rate]; 9070 /* [TRC: XXX Set fallback rate.] */ 9071 } else { 9072 /* AMRR rate control */ 9073 /* [TRC: XXX amrr] */ 9074 /* rate = ni->ni_rates.rs_rates[ni->ni_txrate]; */ 9075 rate = (1 * 2); 9076 /* [TRC: XXX Set fallback rate.] */ 9077 } 9078 } else { 9079 /* Fixed at 1Mbits/s for mgt frames */ 9080 /* [TRC: XXX Set fallback rate.] */ 9081 rate = (1 * 2); 9082 } 9083 9084 rate &= IEEE80211_RATE_VAL; 9085 9086 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 9087 /* [TRC: XXX Set fallback rate.] */ 9088 rate = ic->ic_mcast_rate; 9089 mcast_pkt = 1; 9090 } 9091 9092 /* [TRC: XXX Check fallback rate.] */ 9093 if (rate == 0) { 9094 aprint_error_dev(&sc->sc_dev, "invalid rate %u", rate); 9095 /* [TRC: In the margin of the following line, 9096 DragonFlyBSD writes `Force 1Mbits/s', whereas 9097 OpenBSD writes `Force 1Mbytes/s'.] */ 9098 rate = (1 * 2); 9099 /* [TRC: XXX Set fallback rate.] */ 9100 } 9101 sc->sc_tx_rate = rate; 9102 9103 #if NBPFILTER > 0 9104 /* TX radio tap */ 9105 if (sc->sc_drvbpf != NULL) { 9106 struct mbuf mb; 9107 struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap; 9108 9109 tap->wt_flags = 0; 9110 tap->wt_rate = rate; 9111 tap->wt_chan_freq = 9112 htole16(ic->ic_bss->ni_chan->ic_freq); 9113 tap->wt_chan_flags = 9114 htole16(ic->ic_bss->ni_chan->ic_flags); 9115 9116 mb.m_data = (void *)tap; 9117 mb.m_len = sc->sc_txtap_len; 9118 mb.m_next = m; 9119 mb.m_nextpkt = NULL; 9120 mb.m_type = 0; 9121 mb.m_flags = 0; 9122 bpf_mtap(sc->sc_drvbpf, &mb); 9123 } 9124 #endif 9125 9126 /* 9127 * Setup the embedded TX header 9128 */ 9129 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT); 9130 if (m == NULL) { 9131 aprint_error_dev(&sc->sc_dev, "prepend TX header failed\n"); 9132 return (ENOBUFS); 9133 } 9134 hdr = mtod(m, struct bwi_txbuf_hdr *); 9135 9136 bzero(hdr, sizeof(*hdr)); 9137 9138 bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc)); 9139 bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1)); 9140 9141 if (!mcast_pkt) { 9142 uint16_t dur; 9143 uint8_t ack_rate; 9144 9145 /* [TRC: XXX Set fallback rate.] */ 9146 ack_rate = bwi_ieee80211_ack_rate(ni, rate); 9147 dur = bwi_ieee80211_txtime(ic, ni, 9148 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, 9149 ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); 9150 9151 hdr->txh_fb_duration = htole16(dur); 9152 } 9153 9154 hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) | 9155 __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK); 9156 9157 bwi_plcp_header(hdr->txh_plcp, pkt_len, rate); 9158 /* [TRC: XXX Use fallback rate.] */ 9159 bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate); 9160 9161 phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode, 9162 BWI_TXH_PHY_C_ANTMODE_MASK); 9163 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) 9164 phy_ctrl |= BWI_TXH_PHY_C_OFDM; 9165 else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1)) 9166 phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE; 9167 9168 mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG; 9169 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) 9170 mac_ctrl |= BWI_TXH_MAC_C_ACK; 9171 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) 9172 mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM; 9173 9174 hdr->txh_mac_ctrl = htole32(mac_ctrl); 9175 hdr->txh_phy_ctrl = htole16(phy_ctrl); 9176 9177 /* Catch any further usage */ 9178 hdr = NULL; 9179 wh = NULL; 9180 9181 /* DMA load */ 9182 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 9183 BUS_DMA_NOWAIT); 9184 if (error && error != EFBIG) { 9185 aprint_error_dev(&sc->sc_dev, "can't load TX buffer (1) %d\n", 9186 error); 9187 goto back; 9188 } 9189 9190 if (error) { /* error == EFBIG */ 9191 struct mbuf *m_new; 9192 9193 error = 0; 9194 9195 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 9196 if (m_new == NULL) { 9197 m_freem(m); 9198 error = ENOBUFS; 9199 aprint_error_dev(&sc->sc_dev, 9200 "can't defrag TX buffer (1)\n"); 9201 goto back; 9202 } 9203 9204 M_COPY_PKTHDR(m_new, m); 9205 if (m->m_pkthdr.len > MHLEN) { 9206 MCLGET(m_new, M_DONTWAIT); 9207 if (!(m_new->m_flags & M_EXT)) { 9208 m_freem(m); 9209 m_freem(m_new); 9210 error = ENOBUFS; 9211 } 9212 } 9213 9214 if (error) { 9215 aprint_error_dev(&sc->sc_dev, 9216 "can't defrag TX buffer (2)\n"); 9217 goto back; 9218 } 9219 9220 m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, void *)); 9221 m_freem(m); 9222 m_new->m_len = m_new->m_pkthdr.len; 9223 m = m_new; 9224 9225 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 9226 BUS_DMA_NOWAIT); 9227 if (error) { 9228 aprint_error_dev(&sc->sc_dev, 9229 "can't load TX buffer (2) %d\n", error); 9230 goto back; 9231 } 9232 } 9233 error = 0; 9234 9235 bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0, 9236 tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 9237 9238 if (mgt_pkt || mcast_pkt) { 9239 /* Don't involve mcast/mgt packets into TX rate control */ 9240 ieee80211_free_node(ni); 9241 *nip = ni = NULL; 9242 } 9243 9244 tb->tb_mbuf = m; 9245 tb->tb_ni = ni; 9246 9247 #if 0 9248 p = mtod(m, const uint8_t *); 9249 for (i = 0; i < m->m_pkthdr.len; ++i) { 9250 if (i % 8 == 0) { 9251 if (i != 0) 9252 aprint_debug("\n"); 9253 aprint_debug_dev(&sc->sc_dev, ""); 9254 } 9255 aprint_debug(" %02x", p[i]); 9256 } 9257 aprint_debug("\n"); 9258 #endif 9259 9260 DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n", 9261 idx, pkt_len, m->m_pkthdr.len); 9262 9263 /* Setup TX descriptor */ 9264 paddr = tb->tb_dmap->dm_segs[0].ds_addr; 9265 (sc->sc_setup_txdesc)(sc, rd, idx, paddr, m->m_pkthdr.len); 9266 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 9267 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 9268 9269 /* Kick start */ 9270 (sc->sc_start_tx)(sc, rd->rdata_txrx_ctrl, idx); 9271 9272 back: 9273 if (error) 9274 m_freem(m); 9275 return (error); 9276 } 9277 9278 static void 9279 bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 9280 { 9281 idx = (idx + 1) % BWI_TX_NDESC; 9282 CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX, 9283 idx * sizeof(struct bwi_desc32)); 9284 } 9285 9286 static void 9287 bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 9288 { 9289 /* TODO: 64 */ 9290 } 9291 9292 static void 9293 bwi_txeof_status32(struct bwi_softc *sc) 9294 { 9295 struct ifnet *ifp = &sc->sc_if; 9296 uint32_t val, ctrl_base; 9297 int end_idx; 9298 9299 ctrl_base = sc->sc_txstats->stats_ctrl_base; 9300 9301 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS); 9302 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 9303 sizeof(struct bwi_desc32); 9304 9305 bwi_txeof_status(sc, end_idx); 9306 9307 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 9308 end_idx * sizeof(struct bwi_desc32)); 9309 9310 if ((ifp->if_flags & IFF_OACTIVE) == 0) 9311 ifp->if_start(ifp); /* [TRC: XXX Why not bwi_start?] */ 9312 } 9313 9314 static void 9315 bwi_txeof_status64(struct bwi_softc *sc) 9316 { 9317 /* TODO: 64 */ 9318 } 9319 9320 static void 9321 _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id) 9322 { 9323 struct ifnet *ifp = &sc->sc_if; 9324 struct bwi_txbuf_data *tbd; 9325 struct bwi_txbuf *tb; 9326 int ring_idx, buf_idx; 9327 9328 if (tx_id == 0) { 9329 /* [TRC: XXX What is the severity of this message?] */ 9330 aprint_normal_dev(&sc->sc_dev, "zero tx id\n"); 9331 return; 9332 } 9333 9334 ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK); 9335 buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK); 9336 9337 KASSERT(ring_idx == BWI_TX_DATA_RING); 9338 KASSERT(buf_idx < BWI_TX_NDESC); 9339 tbd = &sc->sc_tx_bdata[ring_idx]; 9340 KASSERT(tbd->tbd_used > 0); 9341 tbd->tbd_used--; 9342 9343 tb = &tbd->tbd_buf[buf_idx]; 9344 9345 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 9346 m_freem(tb->tb_mbuf); 9347 tb->tb_mbuf = NULL; 9348 9349 if (tb->tb_ni != NULL) { 9350 ieee80211_free_node(tb->tb_ni); 9351 tb->tb_ni = NULL; 9352 } 9353 9354 if (tbd->tbd_used == 0) 9355 sc->sc_tx_timer = 0; 9356 9357 ifp->if_flags &= ~IFF_OACTIVE; 9358 } 9359 9360 static void 9361 bwi_txeof_status(struct bwi_softc *sc, int end_idx) 9362 { 9363 struct bwi_txstats_data *st = sc->sc_txstats; 9364 int idx; 9365 9366 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 9367 st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 9368 9369 idx = st->stats_idx; 9370 while (idx != end_idx) { 9371 /* [TRC: XXX Filter this out if it is not pending; see 9372 DragonFlyBSD's revision 1.5. */ 9373 /* [TRC: XXX be16toh is wrong, probably due to the 9374 build environment] */ 9375 _bwi_txeof(sc, be16toh(st->stats[idx].txs_id)); 9376 idx = (idx + 1) % BWI_TXSTATS_NDESC; 9377 } 9378 st->stats_idx = idx; 9379 } 9380 9381 static void 9382 bwi_txeof(struct bwi_softc *sc) 9383 { 9384 struct ifnet *ifp = &sc->sc_if; 9385 9386 for (;;) { 9387 uint32_t tx_status0, tx_status1; 9388 uint16_t tx_id, tx_info; 9389 9390 tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0); 9391 if (tx_status0 == 0) 9392 break; 9393 tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS_1); 9394 9395 tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK); 9396 tx_info = BWI_TXSTATUS_0_INFO(tx_status0); 9397 9398 if (tx_info & 0x30) /* XXX */ 9399 continue; 9400 9401 _bwi_txeof(sc, le16toh(tx_id)); 9402 9403 ifp->if_opackets++; 9404 } 9405 9406 if ((ifp->if_flags & IFF_OACTIVE) == 0) 9407 ifp->if_start(ifp); 9408 } 9409 9410 static int 9411 bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) 9412 { 9413 bwi_power_on(sc, 1); 9414 9415 return (bwi_set_clock_mode(sc, clk_mode)); 9416 } 9417 9418 static void 9419 bwi_bbp_power_off(struct bwi_softc *sc) 9420 { 9421 bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW); 9422 bwi_power_off(sc, 1); 9423 } 9424 9425 static int 9426 bwi_get_pwron_delay(struct bwi_softc *sc) 9427 { 9428 struct bwi_regwin *com, *old; 9429 struct bwi_clock_freq freq; 9430 uint32_t val; 9431 int error; 9432 9433 com = &sc->sc_com_regwin; 9434 KASSERT(BWI_REGWIN_EXIST(com)); 9435 9436 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0) 9437 return (0); 9438 9439 error = bwi_regwin_switch(sc, com, &old); 9440 if (error) 9441 return (error); 9442 9443 bwi_get_clock_freq(sc, &freq); 9444 9445 val = CSR_READ_4(sc, BWI_PLL_ON_DELAY); 9446 sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min); 9447 DPRINTF(sc, BWI_DBG_ATTACH, "power on delay %u\n", sc->sc_pwron_delay); 9448 9449 return (bwi_regwin_switch(sc, old, NULL)); 9450 } 9451 9452 static int 9453 bwi_bus_attach(struct bwi_softc *sc) 9454 { 9455 struct bwi_regwin *bus, *old; 9456 int error; 9457 9458 bus = &sc->sc_bus_regwin; 9459 9460 error = bwi_regwin_switch(sc, bus, &old); 9461 if (error) 9462 return (error); 9463 9464 if (!bwi_regwin_is_enabled(sc, bus)) 9465 bwi_regwin_enable(sc, bus, 0); 9466 9467 /* Disable interripts */ 9468 CSR_WRITE_4(sc, BWI_INTRVEC, 0); 9469 9470 return (bwi_regwin_switch(sc, old, NULL)); 9471 } 9472 9473 static const char * 9474 bwi_regwin_name(const struct bwi_regwin *rw) 9475 { 9476 switch (rw->rw_type) { 9477 case BWI_REGWIN_T_COM: 9478 return ("COM"); 9479 case BWI_REGWIN_T_BUSPCI: 9480 return ("PCI"); 9481 case BWI_REGWIN_T_MAC: 9482 return ("MAC"); 9483 case BWI_REGWIN_T_BUSPCIE: 9484 return ("PCIE"); 9485 } 9486 panic("unknown regwin type 0x%04x\n", rw->rw_type); 9487 9488 return (NULL); 9489 } 9490 9491 static uint32_t 9492 bwi_regwin_disable_bits(struct bwi_softc *sc) 9493 { 9494 uint32_t busrev; 9495 9496 /* XXX cache this */ 9497 busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK); 9498 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_MISC, 9499 "bus rev %u\n", busrev); 9500 9501 if (busrev == BWI_BUSREV_0) 9502 return (BWI_STATE_LO_DISABLE1); 9503 else if (busrev == BWI_BUSREV_1) 9504 return (BWI_STATE_LO_DISABLE2); 9505 else 9506 return (BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2); 9507 } 9508 9509 static int 9510 bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw) 9511 { 9512 uint32_t val, disable_bits; 9513 9514 disable_bits = bwi_regwin_disable_bits(sc); 9515 val = CSR_READ_4(sc, BWI_STATE_LO); 9516 9517 if ((val & (BWI_STATE_LO_CLOCK | 9518 BWI_STATE_LO_RESET | 9519 disable_bits)) == BWI_STATE_LO_CLOCK) { 9520 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is enabled\n", 9521 bwi_regwin_name(rw)); 9522 return (1); 9523 } else { 9524 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is disabled\n", 9525 bwi_regwin_name(rw)); 9526 return (0); 9527 } 9528 } 9529 9530 static void 9531 bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 9532 { 9533 uint32_t state_lo, disable_bits; 9534 int i; 9535 9536 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 9537 9538 /* 9539 * If current regwin is in 'reset' state, it was already disabled. 9540 */ 9541 if (state_lo & BWI_STATE_LO_RESET) { 9542 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, 9543 "%s was already disabled\n", bwi_regwin_name(rw)); 9544 return; 9545 } 9546 9547 disable_bits = bwi_regwin_disable_bits(sc); 9548 9549 /* 9550 * Disable normal clock 9551 */ 9552 state_lo = BWI_STATE_LO_CLOCK | disable_bits; 9553 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9554 9555 /* 9556 * Wait until normal clock is disabled 9557 */ 9558 #define NRETRY 1000 9559 for (i = 0; i < NRETRY; ++i) { 9560 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 9561 if (state_lo & disable_bits) 9562 break; 9563 DELAY(10); 9564 } 9565 if (i == NRETRY) { 9566 aprint_error_dev(&sc->sc_dev, "%s disable clock timeout\n", 9567 bwi_regwin_name(rw)); 9568 } 9569 9570 for (i = 0; i < NRETRY; ++i) { 9571 uint32_t state_hi; 9572 9573 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 9574 if ((state_hi & BWI_STATE_HI_BUSY) == 0) 9575 break; 9576 DELAY(10); 9577 } 9578 if (i == NRETRY) { 9579 aprint_error_dev(&sc->sc_dev, "%s wait BUSY unset timeout\n", 9580 bwi_regwin_name(rw)); 9581 } 9582 #undef NRETRY 9583 9584 /* 9585 * Reset and disable regwin with gated clock 9586 */ 9587 state_lo = BWI_STATE_LO_RESET | disable_bits | 9588 BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK | 9589 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9590 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9591 9592 /* Flush pending bus write */ 9593 CSR_READ_4(sc, BWI_STATE_LO); 9594 DELAY(1); 9595 9596 /* Reset and disable regwin */ 9597 state_lo = BWI_STATE_LO_RESET | disable_bits | 9598 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9599 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9600 9601 /* Flush pending bus write */ 9602 CSR_READ_4(sc, BWI_STATE_LO); 9603 DELAY(1); 9604 } 9605 9606 static void 9607 bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 9608 { 9609 uint32_t state_lo, state_hi, imstate; 9610 9611 bwi_regwin_disable(sc, rw, flags); 9612 9613 /* Reset regwin with gated clock */ 9614 state_lo = BWI_STATE_LO_RESET | 9615 BWI_STATE_LO_CLOCK | 9616 BWI_STATE_LO_GATED_CLOCK | 9617 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9618 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9619 9620 /* Flush pending bus write */ 9621 CSR_READ_4(sc, BWI_STATE_LO); 9622 DELAY(1); 9623 9624 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 9625 if (state_hi & BWI_STATE_HI_SERROR) 9626 CSR_WRITE_4(sc, BWI_STATE_HI, 0); 9627 9628 imstate = CSR_READ_4(sc, BWI_IMSTATE); 9629 if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) { 9630 imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT); 9631 CSR_WRITE_4(sc, BWI_IMSTATE, imstate); 9632 } 9633 9634 /* Enable regwin with gated clock */ 9635 state_lo = BWI_STATE_LO_CLOCK | 9636 BWI_STATE_LO_GATED_CLOCK | 9637 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9638 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9639 9640 /* Flush pending bus write */ 9641 CSR_READ_4(sc, BWI_STATE_LO); 9642 DELAY(1); 9643 9644 /* Enable regwin with normal clock */ 9645 state_lo = BWI_STATE_LO_CLOCK | 9646 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9647 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9648 9649 /* Flush pending bus write */ 9650 CSR_READ_4(sc, BWI_STATE_LO); 9651 DELAY(1); 9652 } 9653 9654 static void 9655 bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid) 9656 { 9657 struct ieee80211com *ic = &sc->sc_ic; 9658 struct bwi_mac *mac; 9659 struct bwi_myaddr_bssid buf; 9660 const uint8_t *p; 9661 uint32_t val; 9662 int n, i; 9663 9664 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9665 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9666 9667 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid); 9668 9669 bcopy(ic->ic_myaddr, buf.myaddr, sizeof(buf.myaddr)); 9670 bcopy(bssid, buf.bssid, sizeof(buf.bssid)); 9671 9672 n = sizeof(buf) / sizeof(val); 9673 p = (const uint8_t *)&buf; 9674 for (i = 0; i < n; ++i) { 9675 int j; 9676 9677 val = 0; 9678 for (j = 0; j < sizeof(val); ++j) 9679 val |= ((uint32_t)(*p++)) << (j * 8); 9680 9681 TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val); 9682 } 9683 } 9684 9685 static void 9686 bwi_updateslot(struct ifnet *ifp) 9687 { 9688 struct bwi_softc *sc = ifp->if_softc; 9689 struct ieee80211com *ic = &sc->sc_ic; 9690 struct bwi_mac *mac; 9691 9692 if ((ifp->if_flags & IFF_RUNNING) == 0) 9693 return; 9694 9695 DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__); 9696 9697 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9698 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9699 9700 bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT)); 9701 } 9702 9703 static void 9704 bwi_calibrate(void *xsc) 9705 { 9706 struct bwi_softc *sc = xsc; 9707 struct ieee80211com *ic = &sc->sc_ic; 9708 int s; 9709 9710 s = splnet(); 9711 9712 if (ic->ic_state == IEEE80211_S_RUN) { 9713 struct bwi_mac *mac; 9714 9715 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9716 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9717 9718 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 9719 bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type); 9720 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB; 9721 } 9722 9723 /* XXX 15 seconds */ 9724 callout_schedule(&sc->sc_calib_ch, hz * 15); 9725 } 9726 9727 splx(s); 9728 } 9729 9730 static int 9731 bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr) 9732 { 9733 struct bwi_mac *mac; 9734 9735 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9736 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9737 9738 return (bwi_rf_calc_rssi(mac, hdr)); 9739 } 9740