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