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