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