bwi.c revision 1.47
1/* $OpenBSD: bwi.c,v 1.47 2007/09/27 05:58:57 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 3932#if 0 3933 KKASSERT(rf_atten < MAP_MAX); 3934 rf_atten = map[rf_atten]; 3935#else 3936 if (rf_atten >= MAP_MAX) { 3937 rf_atten = 0; /* XXX */ 3938 } else { 3939 rf_atten = map[rf_atten]; 3940 } 3941#endif 3942#undef MAP_MAX 3943 } 3944 3945 return (bwi_get_rf_lo(mac, rf_atten, bbp_atten)); 3946} 3947 3948void 3949bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl) 3950{ 3951 const struct bwi_rf_lo *lo; 3952 3953 lo = bwi_rf_lo_find(mac, tpctl); 3954 RF_LO_WRITE(mac, lo); 3955} 3956 3957void 3958bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo) 3959{ 3960 uint16_t val; 3961 3962 val = (uint8_t)lo->ctrl_lo; 3963 val |= ((uint8_t)lo->ctrl_hi) << 8; 3964 3965 PHY_WRITE(mac, BWI_PHYR_RF_LO, val); 3966} 3967 3968int 3969bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx) 3970{ 3971 PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8); 3972 PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000); 3973 PHY_SETBITS(mac, 0x15, 0xf000); 3974 3975 DELAY(20); 3976 3977 return ((PHY_READ(mac, 0x2d) >= 0xdfc)); 3978} 3979 3980/* XXX use bitmap array */ 3981uint16_t 3982bwi_bitswap4(uint16_t val) 3983{ 3984 uint16_t ret; 3985 3986 ret = (val & 0x8) >> 3; 3987 ret |= (val & 0x4) >> 1; 3988 ret |= (val & 0x2) << 1; 3989 ret |= (val & 0x1) << 3; 3990 3991 return (ret); 3992} 3993 3994uint16_t 3995bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd) 3996{ 3997 struct bwi_softc *sc = mac->mac_sc; 3998 struct bwi_phy *phy = &mac->mac_phy; 3999 struct bwi_rf *rf = &mac->mac_rf; 4000 uint16_t lo_gain, ext_lna, loop; 4001 4002 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0) 4003 return (0); 4004 4005 lo_gain = rf->rf_lo_gain; 4006 if (rf->rf_rev == 8) 4007 lo_gain += 0x3e; 4008 else 4009 lo_gain += 0x26; 4010 4011 if (lo_gain >= 0x46) { 4012 lo_gain -= 0x46; 4013 ext_lna = 0x3000; 4014 } else if (lo_gain >= 0x3a) { 4015 lo_gain -= 0x3a; 4016 ext_lna = 0x1000; 4017 } else if (lo_gain >= 0x2e) { 4018 lo_gain -= 0x2e; 4019 ext_lna = 0x2000; 4020 } else { 4021 lo_gain -= 0x10; 4022 ext_lna = 0; 4023 } 4024 4025 for (loop = 0; loop < 16; ++loop) { 4026 lo_gain -= (6 * loop); 4027 if (lo_gain < 6) 4028 break; 4029 } 4030 4031 if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) { 4032 if (ext_lna) 4033 ext_lna |= 0x8000; 4034 ext_lna |= (loop << 8); 4035 switch (lpd) { 4036 case 0x011: 4037 return (0x8f92); 4038 case 0x001: 4039 return ((0x8092 | ext_lna)); 4040 case 0x101: 4041 return ((0x2092 | ext_lna)); 4042 case 0x100: 4043 return ((0x2093 | ext_lna)); 4044 default: 4045 panic("unsupported lpd\n"); 4046 } 4047 } else { 4048 ext_lna |= (loop << 8); 4049 switch (lpd) { 4050 case 0x011: 4051 return (0xf92); 4052 case 0x001: 4053 case 0x101: 4054 return ((0x92 | ext_lna)); 4055 case 0x100: 4056 return ((0x93 | ext_lna)); 4057 default: 4058 panic("unsupported lpd\n"); 4059 } 4060 } 4061 4062 panic("never reached\n"); 4063 4064 return (0); 4065} 4066 4067void 4068bwi_rf_init_bcm2050(struct bwi_mac *mac) 4069{ 4070#define SAVE_RF_MAX 3 4071#define SAVE_PHY_COMM_MAX 4 4072#define SAVE_PHY_11G_MAX 6 4073 uint16_t save_rf[SAVE_RF_MAX]; 4074 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 4075 uint16_t save_phy_11g[SAVE_PHY_11G_MAX]; 4076 uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0; 4077 uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex; 4078 uint16_t phy812_val; 4079 uint16_t calib; 4080 uint32_t test_lim, test; 4081 struct bwi_softc *sc = mac->mac_sc; 4082 struct bwi_phy *phy = &mac->mac_phy; 4083 struct bwi_rf *rf = &mac->mac_rf; 4084 int i; 4085 4086 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 4087 { 0x0043, 0x0051, 0x0052 }; 4088 static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] = 4089 { 0x0015, 0x005a, 0x0059, 0x0058 }; 4090 static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] = 4091 { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 }; 4092 4093 /* 4094 * Save registers for later restoring 4095 */ 4096 for (i = 0; i < SAVE_RF_MAX; ++i) 4097 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 4098 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 4099 save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]); 4100 4101 if (phy->phy_mode == IEEE80211_MODE_11B) { 4102 phyr_30 = PHY_READ(mac, 0x30); 4103 bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL); 4104 4105 PHY_WRITE(mac, 0x30, 0xff); 4106 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f); 4107 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4108 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) { 4109 save_phy_11g[i] = 4110 PHY_READ(mac, save_phy_regs_11g[i]); 4111 } 4112 4113 PHY_SETBITS(mac, 0x814, 0x3); 4114 PHY_CLRBITS(mac, 0x815, 0x3); 4115 PHY_CLRBITS(mac, 0x429, 0x8000); 4116 PHY_CLRBITS(mac, 0x802, 0x3); 4117 4118 phyr_80f = PHY_READ(mac, 0x80f); 4119 phyr_810 = PHY_READ(mac, 0x810); 4120 4121 if (phy->phy_rev >= 3) 4122 PHY_WRITE(mac, 0x80f, 0xc020); 4123 else 4124 PHY_WRITE(mac, 0x80f, 0x8020); 4125 PHY_WRITE(mac, 0x810, 0); 4126 4127 phy812_val = bwi_phy812_value(mac, 0x011); 4128 PHY_WRITE(mac, 0x812, phy812_val); 4129 if (phy->phy_rev < 7 || 4130 (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0) 4131 PHY_WRITE(mac, 0x811, 0x1b3); 4132 else 4133 PHY_WRITE(mac, 0x811, 0x9b3); 4134 } 4135 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000); 4136 4137 phyr_35 = PHY_READ(mac, 0x35); 4138 PHY_CLRBITS(mac, 0x35, 0x80); 4139 4140 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN); 4141 rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 4142 4143 if (phy->phy_version == 0) { 4144 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122); 4145 } else { 4146 if (phy->phy_version >= 2) 4147 PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40); 4148 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000); 4149 } 4150 4151 calib = bwi_rf_calibval(mac); 4152 4153 if (phy->phy_mode == IEEE80211_MODE_11B) 4154 RF_WRITE(mac, 0x78, 0x26); 4155 4156 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4157 phy812_val = bwi_phy812_value(mac, 0x011); 4158 PHY_WRITE(mac, 0x812, phy812_val); 4159 } 4160 4161 PHY_WRITE(mac, 0x15, 0xbfaf); 4162 PHY_WRITE(mac, 0x2b, 0x1403); 4163 4164 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4165 phy812_val = bwi_phy812_value(mac, 0x001); 4166 PHY_WRITE(mac, 0x812, phy812_val); 4167 } 4168 4169 PHY_WRITE(mac, 0x15, 0xbfa0); 4170 4171 RF_SETBITS(mac, 0x51, 0x4); 4172 if (rf->rf_rev == 8) 4173 RF_WRITE(mac, 0x43, 0x1f); 4174 else { 4175 RF_WRITE(mac, 0x52, 0); 4176 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9); 4177 } 4178 4179 test_lim = 0; 4180 PHY_WRITE(mac, 0x58, 0); 4181 for (i = 0; i < 16; ++i) { 4182 PHY_WRITE(mac, 0x5a, 0x480); 4183 PHY_WRITE(mac, 0x59, 0xc810); 4184 4185 PHY_WRITE(mac, 0x58, 0xd); 4186 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4187 phy812_val = bwi_phy812_value(mac, 0x101); 4188 PHY_WRITE(mac, 0x812, phy812_val); 4189 } 4190 PHY_WRITE(mac, 0x15, 0xafb0); 4191 DELAY(10); 4192 4193 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4194 phy812_val = bwi_phy812_value(mac, 0x101); 4195 PHY_WRITE(mac, 0x812, phy812_val); 4196 } 4197 PHY_WRITE(mac, 0x15, 0xefb0); 4198 DELAY(10); 4199 4200 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4201 phy812_val = bwi_phy812_value(mac, 0x100); 4202 PHY_WRITE(mac, 0x812, phy812_val); 4203 } 4204 PHY_WRITE(mac, 0x15, 0xfff0); 4205 DELAY(20); 4206 4207 test_lim += PHY_READ(mac, 0x2d); 4208 4209 PHY_WRITE(mac, 0x58, 0); 4210 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4211 phy812_val = bwi_phy812_value(mac, 0x101); 4212 PHY_WRITE(mac, 0x812, phy812_val); 4213 } 4214 PHY_WRITE(mac, 0x15, 0xafb0); 4215 } 4216 ++test_lim; 4217 test_lim >>= 9; 4218 4219 DELAY(10); 4220 4221 test = 0; 4222 PHY_WRITE(mac, 0x58, 0); 4223 for (i = 0; i < 16; ++i) { 4224 int j; 4225 4226 rfr_78 = (bwi_bitswap4(i) << 1) | 0x20; 4227 RF_WRITE(mac, 0x78, rfr_78); 4228 DELAY(10); 4229 4230 /* NB: This block is slight different than the above one */ 4231 for (j = 0; j < 16; ++j) { 4232 PHY_WRITE(mac, 0x5a, 0xd80); 4233 PHY_WRITE(mac, 0x59, 0xc810); 4234 4235 PHY_WRITE(mac, 0x58, 0xd); 4236 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4237 phy->phy_rev >= 2) { 4238 phy812_val = bwi_phy812_value(mac, 0x101); 4239 PHY_WRITE(mac, 0x812, phy812_val); 4240 } 4241 PHY_WRITE(mac, 0x15, 0xafb0); 4242 DELAY(10); 4243 4244 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4245 phy->phy_rev >= 2) { 4246 phy812_val = bwi_phy812_value(mac, 0x101); 4247 PHY_WRITE(mac, 0x812, phy812_val); 4248 } 4249 PHY_WRITE(mac, 0x15, 0xefb0); 4250 DELAY(10); 4251 4252 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4253 phy->phy_rev >= 2) { 4254 phy812_val = bwi_phy812_value(mac, 0x100); 4255 PHY_WRITE(mac, 0x812, phy812_val); 4256 } 4257 PHY_WRITE(mac, 0x15, 0xfff0); 4258 DELAY(10); 4259 4260 test += PHY_READ(mac, 0x2d); 4261 4262 PHY_WRITE(mac, 0x58, 0); 4263 if ((phy->phy_flags & BWI_PHY_F_LINKED) || 4264 phy->phy_rev >= 2) { 4265 phy812_val = bwi_phy812_value(mac, 0x101); 4266 PHY_WRITE(mac, 0x812, phy812_val); 4267 } 4268 PHY_WRITE(mac, 0x15, 0xafb0); 4269 } 4270 4271 ++test; 4272 test >>= 8; 4273 4274 if (test > test_lim) 4275 break; 4276 } 4277 if (i > 15) 4278 rf->rf_calib = rfr_78; 4279 else 4280 rf->rf_calib = calib; 4281 if (rf->rf_calib != 0xffff) { 4282 DPRINTF(1, "%s: RF calibration value: 0x%04x\n", 4283 sc->sc_dev.dv_xname, rf->rf_calib); 4284 rf->rf_flags |= BWI_RF_F_INITED; 4285 } 4286 4287 /* 4288 * Restore trashes registers 4289 */ 4290 PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]); 4291 4292 for (i = 0; i < SAVE_RF_MAX; ++i) { 4293 int pos = (i + 1) % SAVE_RF_MAX; 4294 4295 RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]); 4296 } 4297 for (i = 1; i < SAVE_PHY_COMM_MAX; ++i) 4298 PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]); 4299 4300 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten); 4301 if (phy->phy_version != 0) 4302 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex); 4303 4304 PHY_WRITE(mac, 0x35, phyr_35); 4305 bwi_rf_work_around(mac, rf->rf_curchan); 4306 4307 if (phy->phy_mode == IEEE80211_MODE_11B) { 4308 PHY_WRITE(mac, 0x30, phyr_30); 4309 CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl); 4310 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 4311 /* XXX Spec only says when PHY is linked (gmode) */ 4312 CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000); 4313 4314 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) { 4315 PHY_WRITE(mac, save_phy_regs_11g[i], 4316 save_phy_11g[i]); 4317 } 4318 4319 PHY_WRITE(mac, 0x80f, phyr_80f); 4320 PHY_WRITE(mac, 0x810, phyr_810); 4321 } 4322 4323#undef SAVE_PHY_11G_MAX 4324#undef SAVE_PHY_COMM_MAX 4325#undef SAVE_RF_MAX 4326} 4327 4328uint16_t 4329bwi_rf_calibval(struct bwi_mac *mac) 4330{ 4331 uint16_t val, calib; 4332 int idx; 4333 4334 /* http://bcm-specs.sipsolutions.net/RCCTable */ 4335 static const uint16_t rf_calibvals[] = { 4336 0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf, 4337 0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf 4338 }; 4339 4340 val = RF_READ(mac, BWI_RFR_BBP_ATTEN); 4341 idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX); 4342 KKASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0]))); 4343 4344 calib = rf_calibvals[idx] << 1; 4345 if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT) 4346 calib |= 0x1; 4347 calib |= 0x20; 4348 4349 return (calib); 4350} 4351 4352int32_t 4353_bwi_adjust_devide(int32_t num, int32_t den) 4354{ 4355 if (num < 0) 4356 return ((num / den)); 4357 else 4358 return ((num + den / 2) / den); 4359} 4360 4361/* 4362 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table 4363 * "calculating table entries" 4364 */ 4365int 4366bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[]) 4367{ 4368 int32_t m1, m2, f, dbm; 4369 int i; 4370 4371 m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32); 4372 m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1); 4373 4374#define ITER_MAX 16 4375 f = 256; 4376 for (i = 0; i < ITER_MAX; ++i) { 4377 int32_t q, d; 4378 4379 q = _bwi_adjust_devide( 4380 f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048); 4381 d = abs(q - f); 4382 f = q; 4383 4384 if (d < 2) 4385 break; 4386 } 4387 if (i == ITER_MAX) 4388 return (EINVAL); 4389#undef ITER_MAX 4390 4391 dbm = _bwi_adjust_devide(m1 * f, 8192); 4392 if (dbm < -127) 4393 dbm = -127; 4394 else if (dbm > 128) 4395 dbm = 128; 4396 4397 *txpwr = dbm; 4398 4399 return (0); 4400} 4401 4402int 4403bwi_rf_map_txpower(struct bwi_mac *mac) 4404{ 4405 struct bwi_softc *sc = mac->mac_sc; 4406 struct bwi_rf *rf = &mac->mac_rf; 4407 struct bwi_phy *phy = &mac->mac_phy; 4408 uint16_t sprom_ofs, val, mask; 4409 int16_t pa_params[3]; 4410 int error = 0, i, ant_gain, reg_txpower_max; 4411 4412 /* 4413 * Find out max TX power 4414 */ 4415 val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR); 4416 if (phy->phy_mode == IEEE80211_MODE_11A) { 4417 rf->rf_txpower_max = __SHIFTOUT(val, 4418 BWI_SPROM_MAX_TXPWR_MASK_11A); 4419 } else { 4420 rf->rf_txpower_max = __SHIFTOUT(val, 4421 BWI_SPROM_MAX_TXPWR_MASK_11BG); 4422 4423 if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) && 4424 phy->phy_mode == IEEE80211_MODE_11G) 4425 rf->rf_txpower_max -= 3; 4426 } 4427 if (rf->rf_txpower_max <= 0) { 4428 DPRINTF(1, "%s: invalid max txpower in sprom\n", 4429 sc->sc_dev.dv_xname); 4430 rf->rf_txpower_max = 74; 4431 } 4432 DPRINTF(1, "%s: max txpower from sprom: %d dBm\n", 4433 sc->sc_dev.dv_xname, rf->rf_txpower_max); 4434 4435 /* 4436 * Find out region/domain max TX power, which is adjusted 4437 * by antenna gain and 1.5 dBm fluctuation as mentioned 4438 * in v3 spec. 4439 */ 4440 val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN); 4441 if (phy->phy_mode == IEEE80211_MODE_11A) 4442 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A); 4443 else 4444 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG); 4445 if (ant_gain == 0xff) { 4446 DPRINTF(1, "%s: invalid antenna gain in sprom\n", 4447 sc->sc_dev.dv_xname); 4448 ant_gain = 2; 4449 } 4450 ant_gain *= 4; 4451 DPRINTF(1, "%s: ant gain %d dBm\n", sc->sc_dev.dv_xname, ant_gain); 4452 4453 reg_txpower_max = 90 - ant_gain - 6; /* XXX magic number */ 4454 DPRINTF(1, "%s: region/domain max txpower %d dBm\n", 4455 sc->sc_dev.dv_xname, reg_txpower_max); 4456 4457 /* 4458 * Force max TX power within region/domain TX power limit 4459 */ 4460 if (rf->rf_txpower_max > reg_txpower_max) 4461 rf->rf_txpower_max = reg_txpower_max; 4462 DPRINTF(1, "%s: max txpower %d dBm\n", 4463 sc->sc_dev.dv_xname, rf->rf_txpower_max); 4464 4465 /* 4466 * Create TSSI to TX power mapping 4467 */ 4468 4469 if (sc->sc_bbp_id == BWI_BBPID_BCM4301 && 4470 rf->rf_type != BWI_RF_T_BCM2050) { 4471 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI; 4472 bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0, 4473 sizeof(rf->rf_txpower_map0)); 4474 goto back; 4475 } 4476 4477#define IS_VALID_PA_PARAM(p) ((p) != 0 && (p) != -1) 4478#define N(arr) (int)(sizeof(arr) / sizeof(arr[0])) 4479 /* 4480 * Extract PA parameters 4481 */ 4482 if (phy->phy_mode == IEEE80211_MODE_11A) 4483 sprom_ofs = BWI_SPROM_PA_PARAM_11A; 4484 else 4485 sprom_ofs = BWI_SPROM_PA_PARAM_11BG; 4486 for (i = 0; i < N(pa_params); ++i) 4487 pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2)); 4488 4489 for (i = 0; i < N(pa_params); ++i) { 4490 /* 4491 * If one of the PA parameters from SPROM is not valid, 4492 * fall back to the default values, if there are any. 4493 */ 4494 if (!IS_VALID_PA_PARAM(pa_params[i])) { 4495 const int8_t *txpower_map; 4496 4497 if (phy->phy_mode == IEEE80211_MODE_11A) { 4498 printf("%s: no tssi2dbm table for 11a PHY\n", 4499 sc->sc_dev.dv_xname); 4500 return (ENXIO); 4501 } 4502 4503 if (phy->phy_mode == IEEE80211_MODE_11G) { 4504 DPRINTF(1, "%s: use default 11g TSSI map\n", 4505 sc->sc_dev.dv_xname); 4506 txpower_map = bwi_txpower_map_11g; 4507 } else { 4508 txpower_map = bwi_txpower_map_11b; 4509 } 4510 4511 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI; 4512 bcopy(txpower_map, rf->rf_txpower_map0, 4513 sizeof(rf->rf_txpower_map0)); 4514 goto back; 4515 } 4516 } 4517#undef N 4518 4519 /* 4520 * All of the PA parameters from SPROM are valid. 4521 */ 4522 4523 /* 4524 * Extract idle TSSI from SPROM. 4525 */ 4526 val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI); 4527 DPRINTF(1, "%s: sprom idle tssi: 0x%04x\n", sc->sc_dev.dv_xname, val); 4528 4529 if (phy->phy_mode == IEEE80211_MODE_11A) 4530 mask = BWI_SPROM_IDLE_TSSI_MASK_11A; 4531 else 4532 mask = BWI_SPROM_IDLE_TSSI_MASK_11BG; 4533 4534 rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask); 4535 if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0)) 4536 rf->rf_idle_tssi0 = 62; 4537 4538#undef IS_VALID_PA_PARAM 4539 4540 /* 4541 * Calculate TX power map, which is indexed by TSSI 4542 */ 4543 DPRINTF(1, "%s: TSSI-TX power map:\n", sc->sc_dev.dv_xname); 4544 for (i = 0; i < BWI_TSSI_MAX; ++i) { 4545 error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i, 4546 pa_params); 4547 if (error) { 4548 DPRINTF(1, "%s: bwi_rf_calc_txpower failed\n", 4549 sc->sc_dev.dv_xname); 4550 break; 4551 } 4552 if (i != 0 && i % 8 == 0) 4553 printf("\n"); 4554 printf("%d ", rf->rf_txpower_map0[i]); 4555 } 4556 printf("\n"); 4557back: 4558 DPRINTF(1, "%s: idle tssi0: %d\n", 4559 sc->sc_dev.dv_xname, rf->rf_idle_tssi0); 4560 4561 return (error); 4562} 4563 4564void 4565bwi_rf_lo_update(struct bwi_mac *mac) 4566{ 4567 struct bwi_softc *sc = mac->mac_sc; 4568 struct ifnet *ifp = &sc->sc_ic.ic_if; 4569 struct bwi_rf *rf = &mac->mac_rf; 4570 struct bwi_phy *phy = &mac->mac_phy; 4571 struct bwi_tpctl *tpctl = &mac->mac_tpctl; 4572 struct rf_saveregs regs; 4573 uint16_t ant_div, chan_ex; 4574 uint8_t devi_ctrl; 4575 u_int orig_chan; 4576 4577 /* 4578 * Save RF/PHY registers for later restoration 4579 */ 4580 orig_chan = rf->rf_curchan; 4581 bzero(®s, sizeof(regs)); 4582 4583 if (phy->phy_flags & BWI_PHY_F_LINKED) { 4584 SAVE_PHY_REG(mac, ®s, 429); 4585 SAVE_PHY_REG(mac, ®s, 802); 4586 4587 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff); 4588 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc); 4589 } 4590 4591 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV); 4592 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000); 4593 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 4594 4595 SAVE_PHY_REG(mac, ®s, 15); 4596 SAVE_PHY_REG(mac, ®s, 2a); 4597 SAVE_PHY_REG(mac, ®s, 35); 4598 SAVE_PHY_REG(mac, ®s, 60); 4599 SAVE_RF_REG(mac, ®s, 43); 4600 SAVE_RF_REG(mac, ®s, 7a); 4601 SAVE_RF_REG(mac, ®s, 52); 4602 if (phy->phy_flags & BWI_PHY_F_LINKED) { 4603 SAVE_PHY_REG(mac, ®s, 811); 4604 SAVE_PHY_REG(mac, ®s, 812); 4605 SAVE_PHY_REG(mac, ®s, 814); 4606 SAVE_PHY_REG(mac, ®s, 815); 4607 } 4608 4609 /* Force to channel 6 */ 4610 bwi_rf_set_chan(mac, 6, 0); 4611 4612 if (phy->phy_flags & BWI_PHY_F_LINKED) { 4613 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff); 4614 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc); 4615 bwi_mac_dummy_xmit(mac); 4616 } 4617 RF_WRITE(mac, 0x43, 0x6); 4618 4619 bwi_phy_set_bbp_atten(mac, 2); 4620 4621 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0); 4622 4623 PHY_WRITE(mac, 0x2e, 0x7f); 4624 PHY_WRITE(mac, 0x80f, 0x78); 4625 PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f); 4626 RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0); 4627 PHY_WRITE(mac, 0x2b, 0x203); 4628 PHY_WRITE(mac, 0x2a, 0x8a3); 4629 4630 if (phy->phy_flags & BWI_PHY_F_LINKED) { 4631 PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3); 4632 PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc); 4633 PHY_WRITE(mac, 0x811, 0x1b3); 4634 PHY_WRITE(mac, 0x812, 0xb2); 4635 } 4636 4637 if ((ifp->if_flags & IFF_RUNNING) == 0) 4638 tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac); 4639 PHY_WRITE(mac, 0x80f, 0x8078); 4640 4641 /* 4642 * Measure all RF LO 4643 */ 4644 devi_ctrl = _bwi_rf_lo_update(mac, regs.rf_7a); 4645 4646 /* 4647 * Restore saved RF/PHY registers 4648 */ 4649 if (phy->phy_flags & BWI_PHY_F_LINKED) { 4650 PHY_WRITE(mac, 0x15, 0xe300); 4651 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0); 4652 DELAY(5); 4653 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2); 4654 DELAY(2); 4655 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3); 4656 } else 4657 PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0); 4658 4659 if ((ifp->if_flags & IFF_RUNNING) == 0) 4660 tpctl = NULL; 4661 bwi_rf_lo_adjust(mac, tpctl); 4662 4663 PHY_WRITE(mac, 0x2e, 0x807f); 4664 if (phy->phy_flags & BWI_PHY_F_LINKED) 4665 PHY_WRITE(mac, 0x2f, 0x202); 4666 else 4667 PHY_WRITE(mac, 0x2f, 0x101); 4668 4669 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex); 4670 4671 RESTORE_PHY_REG(mac, ®s, 15); 4672 RESTORE_PHY_REG(mac, ®s, 2a); 4673 RESTORE_PHY_REG(mac, ®s, 35); 4674 RESTORE_PHY_REG(mac, ®s, 60); 4675 4676 RESTORE_RF_REG(mac, ®s, 43); 4677 RESTORE_RF_REG(mac, ®s, 7a); 4678 4679 regs.rf_52 &= 0xf0; 4680 regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf); 4681 RF_WRITE(mac, 0x52, regs.rf_52); 4682 4683 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div); 4684 4685 if (phy->phy_flags & BWI_PHY_F_LINKED) { 4686 RESTORE_PHY_REG(mac, ®s, 811); 4687 RESTORE_PHY_REG(mac, ®s, 812); 4688 RESTORE_PHY_REG(mac, ®s, 814); 4689 RESTORE_PHY_REG(mac, ®s, 815); 4690 RESTORE_PHY_REG(mac, ®s, 429); 4691 RESTORE_PHY_REG(mac, ®s, 802); 4692 } 4693 4694 bwi_rf_set_chan(mac, orig_chan, 1); 4695} 4696 4697uint32_t 4698bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl) 4699{ 4700 struct bwi_phy *phy = &mac->mac_phy; 4701 uint32_t devi = 0; 4702 int i; 4703 4704 if (phy->phy_flags & BWI_PHY_F_LINKED) 4705 ctrl <<= 8; 4706 4707 for (i = 0; i < 8; ++i) { 4708 if (phy->phy_flags & BWI_PHY_F_LINKED) { 4709 PHY_WRITE(mac, 0x15, 0xe300); 4710 PHY_WRITE(mac, 0x812, ctrl | 0xb0); 4711 DELAY(5); 4712 PHY_WRITE(mac, 0x812, ctrl | 0xb2); 4713 DELAY(2); 4714 PHY_WRITE(mac, 0x812, ctrl | 0xb3); 4715 DELAY(4); 4716 PHY_WRITE(mac, 0x15, 0xf300); 4717 } else { 4718 PHY_WRITE(mac, 0x15, ctrl | 0xefa0); 4719 DELAY(2); 4720 PHY_WRITE(mac, 0x15, ctrl | 0xefe0); 4721 DELAY(4); 4722 PHY_WRITE(mac, 0x15, ctrl | 0xffe0); 4723 } 4724 DELAY(8); 4725 devi += PHY_READ(mac, 0x2d); 4726 } 4727 4728 return (devi); 4729} 4730 4731uint16_t 4732bwi_rf_get_tp_ctrl2(struct bwi_mac *mac) 4733{ 4734 uint32_t devi_min; 4735 uint16_t tp_ctrl2 = 0; 4736 int i; 4737 4738 RF_WRITE(mac, 0x52, 0); 4739 DELAY(10); 4740 devi_min = bwi_rf_lo_devi_measure(mac, 0); 4741 4742 for (i = 0; i < 16; ++i) { 4743 uint32_t devi; 4744 4745 RF_WRITE(mac, 0x52, i); 4746 DELAY(10); 4747 devi = bwi_rf_lo_devi_measure(mac, 0); 4748 4749 if (devi < devi_min) { 4750 devi_min = devi; 4751 tp_ctrl2 = i; 4752 } 4753 } 4754 4755 return (tp_ctrl2); 4756} 4757 4758uint8_t 4759_bwi_rf_lo_update(struct bwi_mac *mac, uint16_t orig_rf7a) 4760{ 4761#define RF_ATTEN_LISTSZ 14 4762#define BBP_ATTEN_MAX 4 /* half */ 4763 struct ifnet *ifp = &mac->mac_sc->sc_ic.ic_if; 4764 struct bwi_rf_lo lo_save, *lo; 4765 uint8_t devi_ctrl = 0; 4766 int idx, adj_rf7a = 0; 4767 4768 static const int rf_atten_list[RF_ATTEN_LISTSZ] = 4769 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 }; 4770 static const int rf_atten_init_list[RF_ATTEN_LISTSZ] = 4771 { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 }; 4772 static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] = 4773 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 }; 4774 4775 bzero(&lo_save, sizeof(lo_save)); 4776 for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) { 4777 int init_rf_atten = rf_atten_init_list[idx]; 4778 int rf_atten = rf_atten_list[idx]; 4779 int bbp_atten; 4780 4781 for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) { 4782 uint16_t tp_ctrl2, rf7a; 4783 4784 if ((ifp->if_flags & IFF_RUNNING) == 0) { 4785 if (idx == 0) { 4786 bzero(&lo_save, sizeof(lo_save)); 4787 } else if (init_rf_atten < 0) { 4788 lo = bwi_get_rf_lo(mac, 4789 rf_atten, 2 * bbp_atten); 4790 bcopy(lo, &lo_save, sizeof(lo_save)); 4791 } else { 4792 lo = bwi_get_rf_lo(mac, 4793 init_rf_atten, 0); 4794 bcopy(lo, &lo_save, sizeof(lo_save)); 4795 } 4796 4797 devi_ctrl = 0; 4798 adj_rf7a = 0; 4799 4800 /* 4801 * XXX 4802 * Linux driver overflows 'val' 4803 */ 4804 if (init_rf_atten >= 0) { 4805 int val; 4806 4807 val = rf_atten * 2 + bbp_atten; 4808 if (val > 14) { 4809 adj_rf7a = 1; 4810 if (val > 17) 4811 devi_ctrl = 1; 4812 if (val > 19) 4813 devi_ctrl = 2; 4814 } 4815 } 4816 } else { 4817 lo = bwi_get_rf_lo(mac, 4818 rf_atten, 2 * bbp_atten); 4819 if (!bwi_rf_lo_isused(mac, lo)) 4820 continue; 4821 bcopy(lo, &lo_save, sizeof(lo_save)); 4822 4823 devi_ctrl = 3; 4824 adj_rf7a = 0; 4825 } 4826 4827 RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten); 4828 4829 tp_ctrl2 = mac->mac_tpctl.tp_ctrl2; 4830 if (init_rf_atten < 0) 4831 tp_ctrl2 |= (3 << 4); 4832 RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2); 4833 4834 DELAY(10); 4835 4836 bwi_phy_set_bbp_atten(mac, bbp_atten * 2); 4837 4838 rf7a = orig_rf7a & 0xfff0; 4839 if (adj_rf7a) 4840 rf7a |= 0x8; 4841 RF_WRITE(mac, 0x7a, rf7a); 4842 4843 lo = bwi_get_rf_lo(mac, 4844 rf_lo_measure_order[idx], bbp_atten * 2); 4845 bwi_rf_lo_measure(mac, &lo_save, lo, devi_ctrl); 4846 } 4847 } 4848 4849 return (devi_ctrl); 4850 4851#undef RF_ATTEN_LISTSZ 4852#undef BBP_ATTEN_MAX 4853} 4854 4855void 4856bwi_rf_lo_measure(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo, 4857 struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl) 4858{ 4859#define LO_ADJUST_MIN 1 4860#define LO_ADJUST_MAX 8 4861#define LO_ADJUST(hi, lo) { .ctrl_hi = hi, .ctrl_lo = lo } 4862 static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = { 4863 LO_ADJUST(1, 1), 4864 LO_ADJUST(1, 0), 4865 LO_ADJUST(1, -1), 4866 LO_ADJUST(0, -1), 4867 LO_ADJUST(-1, -1), 4868 LO_ADJUST(-1, 0), 4869 LO_ADJUST(-1, 1), 4870 LO_ADJUST(0, 1) 4871 }; 4872#undef LO_ADJUST 4873 4874 struct bwi_rf_lo lo_min; 4875 uint32_t devi_min; 4876 int found, loop_count, adjust_state; 4877 4878 bcopy(src_lo, &lo_min, sizeof(lo_min)); 4879 RF_LO_WRITE(mac, &lo_min); 4880 devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl); 4881 4882 loop_count = 12; /* XXX */ 4883 adjust_state = 0; 4884 do { 4885 struct bwi_rf_lo lo_base; 4886 int i, fin; 4887 4888 found = 0; 4889 if (adjust_state == 0) { 4890 i = LO_ADJUST_MIN; 4891 fin = LO_ADJUST_MAX; 4892 } else if (adjust_state % 2 == 0) { 4893 i = adjust_state - 1; 4894 fin = adjust_state + 1; 4895 } else { 4896 i = adjust_state - 2; 4897 fin = adjust_state + 2; 4898 } 4899 4900 if (i < LO_ADJUST_MIN) 4901 i += LO_ADJUST_MAX; 4902 KKASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN); 4903 4904 if (fin > LO_ADJUST_MAX) 4905 fin -= LO_ADJUST_MAX; 4906 KKASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN); 4907 4908 bcopy(&lo_min, &lo_base, sizeof(lo_base)); 4909 for (;;) { 4910 struct bwi_rf_lo lo; 4911 4912 lo.ctrl_hi = lo_base.ctrl_hi + 4913 rf_lo_adjust[i - 1].ctrl_hi; 4914 lo.ctrl_lo = lo_base.ctrl_lo + 4915 rf_lo_adjust[i - 1].ctrl_lo; 4916 4917 if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) { 4918 uint32_t devi; 4919 4920 RF_LO_WRITE(mac, &lo); 4921 devi = bwi_rf_lo_devi_measure(mac, devi_ctrl); 4922 if (devi < devi_min) { 4923 devi_min = devi; 4924 adjust_state = i; 4925 found = 1; 4926 bcopy(&lo, &lo_min, sizeof(lo_min)); 4927 } 4928 } 4929 if (i == fin) 4930 break; 4931 if (i == LO_ADJUST_MAX) 4932 i = LO_ADJUST_MIN; 4933 else 4934 ++i; 4935 } 4936 } while (loop_count-- && found); 4937 4938 bcopy(&lo_min, dst_lo, sizeof(*dst_lo)); 4939 4940#undef LO_ADJUST_MIN 4941#undef LO_ADJUST_MAX 4942} 4943 4944void 4945bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac) 4946{ 4947#define SAVE_RF_MAX 3 4948#define SAVE_PHY_MAX 8 4949 struct bwi_softc *sc = mac->mac_sc; 4950 struct bwi_rf *rf = &mac->mac_rf; 4951 struct bwi_phy *phy = &mac->mac_phy; 4952 uint16_t save_rf[SAVE_RF_MAX]; 4953 uint16_t save_phy[SAVE_PHY_MAX]; 4954 uint16_t ant_div, bbp_atten, chan_ex; 4955 int16_t nrssi[2]; 4956 int i; 4957 4958 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 4959 { 0x7a, 0x52, 0x43 }; 4960 static const uint16_t save_phy_regs[SAVE_PHY_MAX] = 4961 { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 }; 4962 4963 /* 4964 * Save RF/PHY registers for later restoration 4965 */ 4966 for (i = 0; i < SAVE_RF_MAX; ++i) 4967 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 4968 for (i = 0; i < SAVE_PHY_MAX; ++i) 4969 save_phy[i] = PHY_READ(mac, save_phy_regs[i]); 4970 4971 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV); 4972 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN); 4973 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 4974 4975 /* 4976 * Calculate nrssi0 4977 */ 4978 if (phy->phy_rev >= 5) 4979 RF_CLRBITS(mac, 0x7a, 0xff80); 4980 else 4981 RF_CLRBITS(mac, 0x7a, 0xfff0); 4982 PHY_WRITE(mac, 0x30, 0xff); 4983 4984 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f); 4985 4986 PHY_WRITE(mac, 0x26, 0); 4987 PHY_SETBITS(mac, 0x15, 0x20); 4988 PHY_WRITE(mac, 0x2a, 0x8a3); 4989 RF_SETBITS(mac, 0x7a, 0x80); 4990 4991 nrssi[0] = (int16_t)PHY_READ(mac, 0x27); 4992 4993 /* 4994 * Calculate nrssi1 4995 */ 4996 RF_CLRBITS(mac, 0x7a, 0xff80); 4997 if (phy->phy_version >= 2) 4998 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40); 4999 else if (phy->phy_version == 0) 5000 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122); 5001 else 5002 CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff); 5003 5004 PHY_WRITE(mac, 0x20, 0x3f3f); 5005 PHY_WRITE(mac, 0x15, 0xf330); 5006 5007 RF_WRITE(mac, 0x5a, 0x60); 5008 RF_CLRBITS(mac, 0x43, 0xff0f); 5009 5010 PHY_WRITE(mac, 0x5a, 0x480); 5011 PHY_WRITE(mac, 0x59, 0x810); 5012 PHY_WRITE(mac, 0x58, 0xd); 5013 5014 DELAY(20); 5015 5016 nrssi[1] = (int16_t)PHY_READ(mac, 0x27); 5017 5018 /* 5019 * Restore saved RF/PHY registers 5020 */ 5021 PHY_WRITE(mac, save_phy_regs[0], save_phy[0]); 5022 RF_WRITE(mac, save_rf_regs[0], save_rf[0]); 5023 5024 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div); 5025 5026 for (i = 1; i < 4; ++i) 5027 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]); 5028 5029 bwi_rf_work_around(mac, rf->rf_curchan); 5030 5031 if (phy->phy_version != 0) 5032 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex); 5033 5034 for (; i < SAVE_PHY_MAX; ++i) 5035 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]); 5036 5037 for (i = 1; i < SAVE_RF_MAX; ++i) 5038 RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 5039 5040 /* 5041 * Install calculated narrow RSSI values 5042 */ 5043 if (nrssi[0] == nrssi[1]) 5044 rf->rf_nrssi_slope = 0x10000; 5045 else 5046 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]); 5047 if (nrssi[0] <= -4) { 5048 rf->rf_nrssi[0] = nrssi[0]; 5049 rf->rf_nrssi[1] = nrssi[1]; 5050 } 5051 5052#undef SAVE_RF_MAX 5053#undef SAVE_PHY_MAX 5054} 5055 5056void 5057bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac) 5058{ 5059#define SAVE_RF_MAX 2 5060#define SAVE_PHY_COMM_MAX 10 5061#define SAVE_PHY6_MAX 8 5062 struct bwi_phy *phy = &mac->mac_phy; 5063 uint16_t save_rf[SAVE_RF_MAX]; 5064 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 5065 uint16_t save_phy6[SAVE_PHY6_MAX]; 5066 uint16_t rf7b = 0xffff; 5067 int16_t nrssi; 5068 int i, phy6_idx = 0; 5069 5070 static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 }; 5071 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 5072 0x0001, 0x0811, 0x0812, 0x0814, 5073 0x0815, 0x005a, 0x0059, 0x0058, 5074 0x000a, 0x0003 5075 }; 5076 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 5077 0x002e, 0x002f, 0x080f, 0x0810, 5078 0x0801, 0x0060, 0x0014, 0x0478 5079 }; 5080 5081 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 5082 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]); 5083 for (i = 0; i < SAVE_RF_MAX; ++i) 5084 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 5085 5086 PHY_CLRBITS(mac, 0x429, 0x8000); 5087 PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000); 5088 PHY_SETBITS(mac, 0x811, 0xc); 5089 PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4); 5090 PHY_CLRBITS(mac, 0x802, 0x3); 5091 5092 if (phy->phy_rev >= 6) { 5093 for (i = 0; i < SAVE_PHY6_MAX; ++i) 5094 save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]); 5095 5096 PHY_WRITE(mac, 0x2e, 0); 5097 PHY_WRITE(mac, 0x2f, 0); 5098 PHY_WRITE(mac, 0x80f, 0); 5099 PHY_WRITE(mac, 0x810, 0); 5100 PHY_SETBITS(mac, 0x478, 0x100); 5101 PHY_SETBITS(mac, 0x801, 0x40); 5102 PHY_SETBITS(mac, 0x60, 0x40); 5103 PHY_SETBITS(mac, 0x14, 0x200); 5104 } 5105 5106 RF_SETBITS(mac, 0x7a, 0x70); 5107 RF_SETBITS(mac, 0x7a, 0x80); 5108 5109 DELAY(30); 5110 5111 nrssi = bwi_nrssi_11g(mac); 5112 if (nrssi == 31) { 5113 for (i = 7; i >= 4; --i) { 5114 RF_WRITE(mac, 0x7b, i); 5115 DELAY(20); 5116 nrssi = bwi_nrssi_11g(mac); 5117 if (nrssi < 31 && rf7b == 0xffff) 5118 rf7b = i; 5119 } 5120 if (rf7b == 0xffff) 5121 rf7b = 4; 5122 } else { 5123 struct bwi_gains gains; 5124 5125 RF_CLRBITS(mac, 0x7a, 0xff80); 5126 5127 PHY_SETBITS(mac, 0x814, 0x1); 5128 PHY_CLRBITS(mac, 0x815, 0x1); 5129 PHY_SETBITS(mac, 0x811, 0xc); 5130 PHY_SETBITS(mac, 0x812, 0xc); 5131 PHY_SETBITS(mac, 0x811, 0x30); 5132 PHY_SETBITS(mac, 0x812, 0x30); 5133 PHY_WRITE(mac, 0x5a, 0x480); 5134 PHY_WRITE(mac, 0x59, 0x810); 5135 PHY_WRITE(mac, 0x58, 0xd); 5136 if (phy->phy_version == 0) 5137 PHY_WRITE(mac, 0x3, 0x122); 5138 else 5139 PHY_SETBITS(mac, 0xa, 0x2000); 5140 PHY_SETBITS(mac, 0x814, 0x4); 5141 PHY_CLRBITS(mac, 0x815, 0x4); 5142 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40); 5143 RF_SETBITS(mac, 0x7a, 0xf); 5144 5145 bzero(&gains, sizeof(gains)); 5146 gains.tbl_gain1 = 3; 5147 gains.tbl_gain2 = 0; 5148 gains.phy_gain = 1; 5149 bwi_set_gains(mac, &gains); 5150 5151 RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf); 5152 DELAY(30); 5153 5154 nrssi = bwi_nrssi_11g(mac); 5155 if (nrssi == -32) { 5156 for (i = 0; i < 4; ++i) { 5157 RF_WRITE(mac, 0x7b, i); 5158 DELAY(20); 5159 nrssi = bwi_nrssi_11g(mac); 5160 if (nrssi > -31 && rf7b == 0xffff) 5161 rf7b = i; 5162 } 5163 if (rf7b == 0xffff) 5164 rf7b = 3; 5165 } else { 5166 rf7b = 0; 5167 } 5168 } 5169 RF_WRITE(mac, 0x7b, rf7b); 5170 5171 /* 5172 * Restore saved RF/PHY registers 5173 */ 5174 if (phy->phy_rev >= 6) { 5175 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 5176 PHY_WRITE(mac, save_phy6_regs[phy6_idx], 5177 save_phy6[phy6_idx]); 5178 } 5179 } 5180 5181 /* Saved PHY registers 0, 1, 2 are handled later */ 5182 for (i = 3; i < SAVE_PHY_COMM_MAX; ++i) 5183 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 5184 5185 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 5186 RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 5187 5188 PHY_SETBITS(mac, 0x802, 0x3); 5189 PHY_SETBITS(mac, 0x429, 0x8000); 5190 5191 bwi_set_gains(mac, NULL); 5192 5193 if (phy->phy_rev >= 6) { 5194 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 5195 PHY_WRITE(mac, save_phy6_regs[phy6_idx], 5196 save_phy6[phy6_idx]); 5197 } 5198 } 5199 5200 PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 5201 PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 5202 PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 5203 5204#undef SAVE_RF_MAX 5205#undef SAVE_PHY_COMM_MAX 5206#undef SAVE_PHY6_MAX 5207} 5208 5209void 5210bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac) 5211{ 5212#define SAVE_RF_MAX 3 5213#define SAVE_PHY_COMM_MAX 4 5214#define SAVE_PHY3_MAX 8 5215 struct bwi_softc *sc = mac->mac_sc; 5216 struct bwi_phy *phy = &mac->mac_phy; 5217 struct bwi_rf *rf = &mac->mac_rf; 5218 uint16_t save_rf[SAVE_RF_MAX]; 5219 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 5220 uint16_t save_phy3[SAVE_PHY3_MAX]; 5221 uint16_t ant_div, bbp_atten, chan_ex; 5222 struct bwi_gains gains; 5223 int16_t nrssi[2]; 5224 int i, phy3_idx = 0; 5225 5226 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 5227 { 0x7a, 0x52, 0x43 }; 5228 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 5229 { 0x15, 0x5a, 0x59, 0x58 }; 5230 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 5231 0x002e, 0x002f, 0x080f, 0x0810, 5232 0x0801, 0x0060, 0x0014, 0x0478 5233 }; 5234 5235 if (rf->rf_rev >= 9) 5236 return; 5237 else if (rf->rf_rev == 8) 5238 bwi_rf_set_nrssi_ofs_11g(mac); 5239 5240 PHY_CLRBITS(mac, 0x429, 0x8000); 5241 PHY_CLRBITS(mac, 0x802, 0x3); 5242 5243 /* 5244 * Save RF/PHY registers for later restoration 5245 */ 5246 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV); 5247 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000); 5248 5249 for (i = 0; i < SAVE_RF_MAX; ++i) 5250 save_rf[i] = RF_READ(mac, save_rf_regs[i]); 5251 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 5252 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]); 5253 5254 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN); 5255 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX); 5256 5257 if (phy->phy_rev >= 3) { 5258 for (i = 0; i < SAVE_PHY3_MAX; ++i) 5259 save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]); 5260 5261 PHY_WRITE(mac, 0x2e, 0); 5262 PHY_WRITE(mac, 0x810, 0); 5263 5264 if (phy->phy_rev == 4 || phy->phy_rev == 6 || 5265 phy->phy_rev == 7) { 5266 PHY_SETBITS(mac, 0x478, 0x100); 5267 PHY_SETBITS(mac, 0x810, 0x40); 5268 } else if (phy->phy_rev == 3 || phy->phy_rev == 5) 5269 PHY_CLRBITS(mac, 0x810, 0x40); 5270 5271 PHY_SETBITS(mac, 0x60, 0x40); 5272 PHY_SETBITS(mac, 0x14, 0x200); 5273 } 5274 5275 /* 5276 * Calculate nrssi0 5277 */ 5278 RF_SETBITS(mac, 0x7a, 0x70); 5279 5280 bzero(&gains, sizeof(gains)); 5281 gains.tbl_gain1 = 0; 5282 gains.tbl_gain2 = 8; 5283 gains.phy_gain = 0; 5284 bwi_set_gains(mac, &gains); 5285 5286 RF_CLRBITS(mac, 0x7a, 0xff08); 5287 if (phy->phy_rev >= 2) { 5288 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30); 5289 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10); 5290 } 5291 5292 RF_SETBITS(mac, 0x7a, 0x80); 5293 DELAY(20); 5294 nrssi[0] = bwi_nrssi_11g(mac); 5295 5296 /* 5297 * Calculate nrssi1 5298 */ 5299 RF_CLRBITS(mac, 0x7a, 0xff80); 5300 if (phy->phy_version >= 2) 5301 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40); 5302 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000); 5303 5304 RF_SETBITS(mac, 0x7a, 0xf); 5305 PHY_WRITE(mac, 0x15, 0xf330); 5306 if (phy->phy_rev >= 2) { 5307 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20); 5308 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20); 5309 } 5310 5311 bzero(&gains, sizeof(gains)); 5312 gains.tbl_gain1 = 3; 5313 gains.tbl_gain2 = 0; 5314 gains.phy_gain = 1; 5315 bwi_set_gains(mac, &gains); 5316 5317 if (rf->rf_rev == 8) { 5318 RF_WRITE(mac, 0x43, 0x1f); 5319 } else { 5320 RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60); 5321 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9); 5322 } 5323 PHY_WRITE(mac, 0x5a, 0x480); 5324 PHY_WRITE(mac, 0x59, 0x810); 5325 PHY_WRITE(mac, 0x58, 0xd); 5326 DELAY(20); 5327 5328 nrssi[1] = bwi_nrssi_11g(mac); 5329 5330 /* 5331 * Install calculated narrow RSSI values 5332 */ 5333 if (nrssi[1] == nrssi[0]) 5334 rf->rf_nrssi_slope = 0x10000; 5335 else 5336 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]); 5337 if (nrssi[0] >= -4) { 5338 rf->rf_nrssi[0] = nrssi[1]; 5339 rf->rf_nrssi[1] = nrssi[0]; 5340 } 5341 5342 /* 5343 * Restore saved RF/PHY registers 5344 */ 5345 if (phy->phy_rev >= 3) { 5346 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 5347 PHY_WRITE(mac, save_phy3_regs[phy3_idx], 5348 save_phy3[phy3_idx]); 5349 } 5350 } 5351 if (phy->phy_rev >= 2) { 5352 PHY_CLRBITS(mac, 0x812, 0x30); 5353 PHY_CLRBITS(mac, 0x811, 0x30); 5354 } 5355 5356 for (i = 0; i < SAVE_RF_MAX; ++i) 5357 RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 5358 5359 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div); 5360 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten); 5361 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex); 5362 5363 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 5364 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 5365 5366 bwi_rf_work_around(mac, rf->rf_curchan); 5367 PHY_SETBITS(mac, 0x802, 0x3); 5368 bwi_set_gains(mac, NULL); 5369 PHY_SETBITS(mac, 0x429, 0x8000); 5370 5371 if (phy->phy_rev >= 3) { 5372 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 5373 PHY_WRITE(mac, save_phy3_regs[phy3_idx], 5374 save_phy3[phy3_idx]); 5375 } 5376 } 5377 5378 bwi_rf_init_sw_nrssi_table(mac); 5379 bwi_rf_set_nrssi_thr_11g(mac); 5380 5381#undef SAVE_RF_MAX 5382#undef SAVE_PHY_COMM_MAX 5383#undef SAVE_PHY3_MAX 5384} 5385 5386void 5387bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac) 5388{ 5389 struct bwi_rf *rf = &mac->mac_rf; 5390 int d, i; 5391 5392 d = 0x1f - rf->rf_nrssi[0]; 5393 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) { 5394 int val; 5395 5396 val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a; 5397 if (val < 0) 5398 val = 0; 5399 else if (val > 0x3f) 5400 val = 0x3f; 5401 5402 rf->rf_nrssi_table[i] = val; 5403 } 5404} 5405 5406void 5407bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust) 5408{ 5409 int i; 5410 5411 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) { 5412 int16_t val; 5413 5414 val = bwi_nrssi_read(mac, i); 5415 5416 val -= adjust; 5417 if (val < -32) 5418 val = -32; 5419 else if (val > 31); 5420 val = 31; 5421 5422 bwi_nrssi_write(mac, i, val); 5423 } 5424} 5425 5426void 5427bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac) 5428{ 5429 struct bwi_rf *rf = &mac->mac_rf; 5430 int32_t thr; 5431 5432 if (rf->rf_type != BWI_RF_T_BCM2050 || 5433 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) 5434 return; 5435 5436 /* 5437 * Calculate nrssi threshold 5438 */ 5439 if (rf->rf_rev >= 6) { 5440 thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32; 5441 thr += 20 * (rf->rf_nrssi[0] + 1); 5442 thr /= 40; 5443 } else { 5444 thr = rf->rf_nrssi[1] - 5; 5445 } 5446 if (thr < 0) 5447 thr = 0; 5448 else if (thr > 0x3e) 5449 thr = 0x3e; 5450 5451 PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B); /* dummy read */ 5452 PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c); 5453 5454 if (rf->rf_rev >= 6) { 5455 PHY_WRITE(mac, 0x87, 0xe0d); 5456 PHY_WRITE(mac, 0x86, 0xc0b); 5457 PHY_WRITE(mac, 0x85, 0xa09); 5458 PHY_WRITE(mac, 0x84, 0x808); 5459 PHY_WRITE(mac, 0x83, 0x808); 5460 PHY_WRITE(mac, 0x82, 0x604); 5461 PHY_WRITE(mac, 0x81, 0x302); 5462 PHY_WRITE(mac, 0x80, 0x100); 5463 } 5464} 5465 5466int32_t 5467_nrssi_threshold(const struct bwi_rf *rf, int32_t val) 5468{ 5469 val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]); 5470 val += (rf->rf_nrssi[0] << 6); 5471 if (val < 32) 5472 val += 31; 5473 else 5474 val += 32; 5475 val >>= 6; 5476 if (val < -31) 5477 val = -31; 5478 else if (val > 31) 5479 val = 31; 5480 5481 return (val); 5482} 5483 5484void 5485bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac) 5486{ 5487 int32_t thr1, thr2; 5488 uint16_t thr; 5489 5490 /* 5491 * Find the two nrssi thresholds 5492 */ 5493 if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 || 5494 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) { 5495 int16_t nrssi; 5496 5497 nrssi = bwi_nrssi_read(mac, 0x20); 5498 if (nrssi >= 32) 5499 nrssi -= 64; 5500 5501 if (nrssi < 3) { 5502 thr1 = 0x2b; 5503 thr2 = 0x27; 5504 } else { 5505 thr1 = 0x2d; 5506 thr2 = 0x2b; 5507 } 5508 } else { 5509 /* TODO Interfere mode */ 5510 thr1 = _nrssi_threshold(&mac->mac_rf, 0x11); 5511 thr2 = _nrssi_threshold(&mac->mac_rf, 0xe); 5512 } 5513 5514#define NRSSI_THR1_MASK 0x003f 5515#define NRSSI_THR2_MASK 0x0fc0 5516 thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) | 5517 __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK); 5518 PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr); 5519#undef NRSSI_THR1_MASK 5520#undef NRSSI_THR2_MASK 5521} 5522 5523void 5524bwi_rf_clear_tssi(struct bwi_mac *mac) 5525{ 5526 /* XXX use function pointer */ 5527 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) { 5528 /* TODO:11A */ 5529 } else { 5530 uint16_t val; 5531 int i; 5532 5533 val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) | 5534 __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK); 5535 5536 for (i = 0; i < 2; ++i) { 5537 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 5538 BWI_COMM_MOBJ_TSSI_DS + (i * 2), val); 5539 } 5540 5541 for (i = 0; i < 2; ++i) { 5542 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 5543 BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val); 5544 } 5545 } 5546} 5547 5548void 5549bwi_rf_clear_state(struct bwi_rf *rf) 5550{ 5551 int i; 5552 5553 rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS; 5554 bzero(rf->rf_lo, sizeof(rf->rf_lo)); 5555 bzero(rf->rf_lo_used, sizeof(rf->rf_lo_used)); 5556 5557 rf->rf_nrssi_slope = 0; 5558 rf->rf_nrssi[0] = BWI_INVALID_NRSSI; 5559 rf->rf_nrssi[1] = BWI_INVALID_NRSSI; 5560 5561 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) 5562 rf->rf_nrssi_table[i] = i; 5563 5564 rf->rf_lo_gain = 0; 5565 rf->rf_rx_gain = 0; 5566 5567 bcopy(rf->rf_txpower_map0, rf->rf_txpower_map, 5568 sizeof(rf->rf_txpower_map)); 5569 rf->rf_idle_tssi = rf->rf_idle_tssi0; 5570} 5571 5572void 5573bwi_rf_on_11a(struct bwi_mac *mac) 5574{ 5575 /* TODO:11A */ 5576} 5577 5578void 5579bwi_rf_on_11bg(struct bwi_mac *mac) 5580{ 5581 struct bwi_phy *phy = &mac->mac_phy; 5582 5583 PHY_WRITE(mac, 0x15, 0x8000); 5584 PHY_WRITE(mac, 0x15, 0xcc00); 5585 if (phy->phy_flags & BWI_PHY_F_LINKED) 5586 PHY_WRITE(mac, 0x15, 0xc0); 5587 else 5588 PHY_WRITE(mac, 0x15, 0); 5589 5590 bwi_rf_set_chan(mac, 6 /* XXX */, 1); 5591} 5592 5593void 5594bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode) 5595{ 5596 struct bwi_softc *sc = mac->mac_sc; 5597 struct bwi_phy *phy = &mac->mac_phy; 5598 uint16_t val; 5599 5600 KKASSERT(ant_mode == BWI_ANT_MODE_0 || 5601 ant_mode == BWI_ANT_MODE_1 || 5602 ant_mode == BWI_ANT_MODE_AUTO); 5603 5604 HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV); 5605 5606 if (phy->phy_mode == IEEE80211_MODE_11B) { 5607 /* NOTE: v4/v3 conflicts, take v3 */ 5608 if (mac->mac_rev == 2) 5609 val = BWI_ANT_MODE_AUTO; 5610 else 5611 val = ant_mode; 5612 val <<= 7; 5613 PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val); 5614 } else { /* 11a/g */ 5615 /* XXX reg/value naming */ 5616 val = ant_mode << 7; 5617 PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val); 5618 5619 if (ant_mode == BWI_ANT_MODE_AUTO) 5620 PHY_CLRBITS(mac, 0x42b, 0x100); 5621 5622 if (phy->phy_mode == IEEE80211_MODE_11A) { 5623 /* TODO:11A */ 5624 } else { /* 11g */ 5625 if (ant_mode == BWI_ANT_MODE_AUTO) 5626 PHY_SETBITS(mac, 0x48c, 0x2000); 5627 else 5628 PHY_CLRBITS(mac, 0x48c, 0x2000); 5629 5630 if (phy->phy_rev >= 2) { 5631 PHY_SETBITS(mac, 0x461, 0x10); 5632 PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15); 5633 if (phy->phy_rev == 2) { 5634 PHY_WRITE(mac, 0x427, 0x8); 5635 } else { 5636 PHY_FILT_SETBITS(mac, 0x427, 5637 0xff00, 0x8); 5638 } 5639 5640 if (phy->phy_rev >= 6) 5641 PHY_WRITE(mac, 0x49b, 0xdc); 5642 } 5643 } 5644 } 5645 5646 /* XXX v4 set AUTO_ANTDIV unconditionally */ 5647 if (ant_mode == BWI_ANT_MODE_AUTO) 5648 HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV); 5649 5650 val = ant_mode << 8; 5651 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON, 5652 0xfc3f, val); 5653 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK, 5654 0xfc3f, val); 5655 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP, 5656 0xfc3f, val); 5657 5658 /* XXX what's these */ 5659 if (phy->phy_mode == IEEE80211_MODE_11B) 5660 CSR_SETBITS_2(sc, 0x5e, 0x4); 5661 5662 CSR_WRITE_4(sc, 0x100, 0x1000000); 5663 if (mac->mac_rev < 5) 5664 CSR_WRITE_4(sc, 0x10c, 0x1000000); 5665 5666 mac->mac_rf.rf_ant_mode = ant_mode; 5667} 5668 5669int 5670bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs) 5671{ 5672 int i; 5673 5674 for (i = 0; i < 4; ) { 5675 uint16_t val; 5676 5677 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i); 5678 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK); 5679 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK); 5680 } 5681 5682 for (i = 0; i < 4; ++i) { 5683 if (tssi[i] == BWI_INVALID_TSSI) 5684 return (EINVAL); 5685 } 5686 5687 return (0); 5688} 5689 5690int 5691bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr) 5692{ 5693 struct bwi_rf *rf = &mac->mac_rf; 5694 int pwr_idx; 5695 5696 pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi; 5697#if 0 5698 if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX) 5699 return EINVAL; 5700#else 5701 if (pwr_idx < 0) 5702 pwr_idx = 0; 5703 else if (pwr_idx >= BWI_TSSI_MAX) 5704 pwr_idx = BWI_TSSI_MAX - 1; 5705#endif 5706 *txpwr = rf->rf_txpower_map[pwr_idx]; 5707 5708 return (0); 5709} 5710 5711/* IF_BWI */ 5712 5713uint16_t 5714bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs) 5715{ 5716 return (CSR_READ_2(sc, ofs + BWI_SPROM_START)); 5717} 5718 5719void 5720bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array, 5721 int ndesc, int desc_idx, bus_addr_t paddr, int buf_len, int tx) 5722{ 5723 struct bwi_desc32 *desc = &desc_array[desc_idx]; 5724 uint32_t ctrl, addr, addr_hi, addr_lo; 5725 5726 addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK); 5727 addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK); 5728 5729 addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK) | 5730 __SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK); 5731 5732 ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK) | 5733 __SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK); 5734 if (desc_idx == ndesc - 1) 5735 ctrl |= BWI_DESC32_C_EOR; 5736 if (tx) { 5737 /* XXX */ 5738 ctrl |= BWI_DESC32_C_FRAME_START | 5739 BWI_DESC32_C_FRAME_END | 5740 BWI_DESC32_C_INTR; 5741 } 5742 5743 desc->addr = htole32(addr); 5744 desc->ctrl = htole32(ctrl); 5745} 5746 5747void 5748bwi_power_on(struct bwi_softc *sc, int with_pll) 5749{ 5750 uint32_t gpio_in, gpio_out, gpio_en, status; 5751 5752 DPRINTF(1, "%s\n", __func__); 5753 5754 gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); 5755 if (gpio_in & BWI_PCIM_GPIO_PWR_ON) 5756 goto back; 5757 5758 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 5759 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE); 5760 5761 gpio_out |= BWI_PCIM_GPIO_PWR_ON; 5762 gpio_en |= BWI_PCIM_GPIO_PWR_ON; 5763 if (with_pll) { 5764 /* Turn off PLL first */ 5765 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF; 5766 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF; 5767 } 5768 5769 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 5770 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en); 5771 DELAY(1000); 5772 5773 if (with_pll) { 5774 /* Turn on PLL */ 5775 gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF; 5776 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 5777 DELAY(5000); 5778 } 5779 5780back: 5781 /* Clear "Signaled Target Abort" */ 5782 status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG); 5783 status &= ~PCI_STATUS_TARGET_TARGET_ABORT; 5784 (sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status); 5785} 5786 5787int 5788bwi_power_off(struct bwi_softc *sc, int with_pll) 5789{ 5790 uint32_t gpio_out, gpio_en; 5791 5792 DPRINTF(1, "%s\n", __func__); 5793 5794 (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */ 5795 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 5796 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE); 5797 5798 gpio_out &= ~BWI_PCIM_GPIO_PWR_ON; 5799 gpio_en |= BWI_PCIM_GPIO_PWR_ON; 5800 if (with_pll) { 5801 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF; 5802 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF; 5803 } 5804 5805 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 5806 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en); 5807 5808 return (0); 5809} 5810 5811int 5812bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw, 5813 struct bwi_regwin **old_rw) 5814{ 5815 int error; 5816 5817 if (old_rw != NULL) 5818 *old_rw = NULL; 5819 5820 if (!BWI_REGWIN_EXIST(rw)) 5821 return (EINVAL); 5822 5823 if (sc->sc_cur_regwin != rw) { 5824 error = bwi_regwin_select(sc, rw->rw_id); 5825 if (error) { 5826 DPRINTF(1, "%s: can't select regwin %d\n", 5827 sc->sc_dev.dv_xname, rw->rw_id); 5828 return (error); 5829 } 5830 } 5831 5832 if (old_rw != NULL) 5833 *old_rw = sc->sc_cur_regwin; 5834 sc->sc_cur_regwin = rw; 5835 5836 return (0); 5837} 5838 5839int 5840bwi_regwin_select(struct bwi_softc *sc, int id) 5841{ 5842 uint32_t win = BWI_PCIM_REGWIN(id); 5843 int i; 5844 5845#define RETRY_MAX 50 5846 for (i = 0; i < RETRY_MAX; ++i) { 5847 (sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win); 5848 if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win) 5849 return (0); 5850 DELAY(10); 5851 } 5852#undef RETRY_MAX 5853 5854 return (ENXIO); 5855} 5856 5857void 5858bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev) 5859{ 5860 uint32_t val; 5861 5862 val = CSR_READ_4(sc, BWI_ID_HI); 5863 *type = BWI_ID_HI_REGWIN_TYPE(val); 5864 *rev = BWI_ID_HI_REGWIN_REV(val); 5865 5866 DPRINTF(1, "%s: regwin: type 0x%03x, rev %d, vendor 0x%04x\n", 5867 sc->sc_dev.dv_xname, 5868 *type, *rev, __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK)); 5869} 5870 5871int 5872bwi_bbp_attach(struct bwi_softc *sc) 5873{ 5874#define N(arr) (int)(sizeof(arr) / sizeof(arr[0])) 5875 uint16_t bbp_id, rw_type; 5876 uint8_t rw_rev; 5877 uint32_t info; 5878 int error, nregwin, i; 5879 5880 /* 5881 * Get 0th regwin information 5882 * NOTE: 0th regwin should exist 5883 */ 5884 error = bwi_regwin_select(sc, 0); 5885 if (error) { 5886 DPRINTF(1, "%s: can't select regwin 0\n", sc->sc_dev.dv_xname); 5887 return (error); 5888 } 5889 bwi_regwin_info(sc, &rw_type, &rw_rev); 5890 5891 /* 5892 * Find out BBP id 5893 */ 5894 bbp_id = 0; 5895 info = 0; 5896 if (rw_type == BWI_REGWIN_T_COM) { 5897 info = CSR_READ_4(sc, BWI_INFO); 5898 bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK); 5899 5900 BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev); 5901 5902 sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY); 5903 } else { 5904 uint16_t did = sc->sc_pci_did; 5905 uint8_t revid = sc->sc_pci_revid; 5906 5907 for (i = 0; i < N(bwi_bbpid_map); ++i) { 5908 if (did >= bwi_bbpid_map[i].did_min && 5909 did <= bwi_bbpid_map[i].did_max) { 5910 bbp_id = bwi_bbpid_map[i].bbp_id; 5911 break; 5912 } 5913 } 5914 if (bbp_id == 0) { 5915 DPRINTF(1, "%s: no BBP id for device id 0x%04x\n", 5916 sc->sc_dev.dv_xname, did); 5917 return (ENXIO); 5918 } 5919 5920 info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) | 5921 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK); 5922 } 5923 5924 /* 5925 * Find out number of regwins 5926 */ 5927 nregwin = 0; 5928 if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) { 5929 nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK); 5930 } else { 5931 for (i = 0; i < N(bwi_regwin_count); ++i) { 5932 if (bwi_regwin_count[i].bbp_id == bbp_id) { 5933 nregwin = bwi_regwin_count[i].nregwin; 5934 break; 5935 } 5936 } 5937 if (nregwin == 0) { 5938 DPRINTF(1, "%s: no number of win for BBP id 0x%04x\n", 5939 sc->sc_dev.dv_xname, bbp_id); 5940 return (ENXIO); 5941 } 5942 } 5943 5944 /* Record BBP id/rev for later using */ 5945 sc->sc_bbp_id = bbp_id; 5946 sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK); 5947 sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK); 5948 DPRINTF(1, "%s: BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n", 5949 sc->sc_dev.dv_xname, sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg); 5950 DPRINTF(1, "%s: nregwin %d, cap 0x%08x\n", 5951 sc->sc_dev.dv_xname, nregwin, sc->sc_cap); 5952 5953 /* 5954 * Create rest of the regwins 5955 */ 5956 5957 /* Don't re-create common regwin, if it is already created */ 5958 i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0; 5959 5960 for (; i < nregwin; ++i) { 5961 /* 5962 * Get regwin information 5963 */ 5964 error = bwi_regwin_select(sc, i); 5965 if (error) { 5966 DPRINTF(1, "%s: can't select regwin %d\n", 5967 sc->sc_dev.dv_xname, i); 5968 return (error); 5969 } 5970 bwi_regwin_info(sc, &rw_type, &rw_rev); 5971 5972 /* 5973 * Try attach: 5974 * 1) Bus (PCI/PCIE) regwin 5975 * 2) MAC regwin 5976 * Ignore rest types of regwin 5977 */ 5978 if (rw_type == BWI_REGWIN_T_BUSPCI || 5979 rw_type == BWI_REGWIN_T_BUSPCIE) { 5980 if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) { 5981 DPRINTF(1, "%s: bus regwin already exists\n", 5982 sc->sc_dev.dv_xname); 5983 } else { 5984 BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i, 5985 rw_type, rw_rev); 5986 } 5987 } else if (rw_type == BWI_REGWIN_T_MAC) { 5988 /* XXX ignore return value */ 5989 bwi_mac_attach(sc, i, rw_rev); 5990 } 5991 } 5992 5993 /* At least one MAC shold exist */ 5994 if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) { 5995 DPRINTF(1, "%s: no MAC was found\n", sc->sc_dev.dv_xname); 5996 return (ENXIO); 5997 } 5998 KKASSERT(sc->sc_nmac > 0); 5999 6000 /* Bus regwin must exist */ 6001 if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) { 6002 DPRINTF(1, "%s: no bus regwin was found\n", 6003 sc->sc_dev.dv_xname); 6004 return (ENXIO); 6005 } 6006 6007 /* Start with first MAC */ 6008 error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL); 6009 if (error) 6010 return (error); 6011 6012 return (0); 6013#undef N 6014} 6015 6016int 6017bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac) 6018{ 6019 struct bwi_regwin *old, *bus; 6020 uint32_t val; 6021 int error; 6022 6023 bus = &sc->sc_bus_regwin; 6024 KKASSERT(sc->sc_cur_regwin == &mac->mac_regwin); 6025 6026 /* 6027 * Tell bus to generate requested interrupts 6028 */ 6029 if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) { 6030 /* 6031 * NOTE: Read BWI_FLAGS from MAC regwin 6032 */ 6033 val = CSR_READ_4(sc, BWI_FLAGS); 6034 6035 error = bwi_regwin_switch(sc, bus, &old); 6036 if (error) 6037 return (error); 6038 6039 CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK)); 6040 } else { 6041 uint32_t mac_mask; 6042 6043 mac_mask = 1 << mac->mac_id; 6044 6045 error = bwi_regwin_switch(sc, bus, &old); 6046 if (error) 6047 return (error); 6048 6049 val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL); 6050 val |= mac_mask << 8; 6051 (sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val); 6052 } 6053 6054 if (sc->sc_flags & BWI_F_BUS_INITED) 6055 goto back; 6056 6057 if (bus->rw_type == BWI_REGWIN_T_BUSPCI) { 6058 /* 6059 * Enable prefetch and burst 6060 */ 6061 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, 6062 BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST); 6063 6064 if (bus->rw_rev < 5) { 6065 struct bwi_regwin *com = &sc->sc_com_regwin; 6066 6067 /* 6068 * Configure timeouts for bus operation 6069 */ 6070 6071 /* 6072 * Set service timeout and request timeout 6073 */ 6074 CSR_SETBITS_4(sc, BWI_CONF_LO, 6075 __SHIFTIN(BWI_CONF_LO_SERVTO, 6076 BWI_CONF_LO_SERVTO_MASK) | 6077 __SHIFTIN(BWI_CONF_LO_REQTO, 6078 BWI_CONF_LO_REQTO_MASK)); 6079 6080 /* 6081 * If there is common regwin, we switch to that regwin 6082 * and switch back to bus regwin once we have done. 6083 */ 6084 if (BWI_REGWIN_EXIST(com)) { 6085 error = bwi_regwin_switch(sc, com, NULL); 6086 if (error) 6087 return (error); 6088 } 6089 6090 /* Let bus know what we have changed */ 6091 CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC); 6092 CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */ 6093 CSR_WRITE_4(sc, BWI_BUS_DATA, 0); 6094 CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */ 6095 6096 if (BWI_REGWIN_EXIST(com)) { 6097 error = bwi_regwin_switch(sc, bus, NULL); 6098 if (error) 6099 return (error); 6100 } 6101 } else if (bus->rw_rev >= 11) { 6102 /* 6103 * Enable memory read multiple 6104 */ 6105 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM); 6106 } 6107 } else { 6108 /* TODO:PCIE */ 6109 } 6110 6111 sc->sc_flags |= BWI_F_BUS_INITED; 6112back: 6113 return (bwi_regwin_switch(sc, old, NULL)); 6114} 6115 6116void 6117bwi_get_card_flags(struct bwi_softc *sc) 6118{ 6119 sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS); 6120 if (sc->sc_card_flags == 0xffff) 6121 sc->sc_card_flags = 0; 6122 6123 if (sc->sc_pci_subvid == PCI_VENDOR_APPLE && 6124 sc->sc_pci_subdid == 0x4e && /* XXX */ 6125 sc->sc_pci_revid > 0x40) 6126 sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9; 6127 6128 DPRINTF(1, "%s: card flags 0x%04x\n", 6129 sc->sc_dev.dv_xname, sc->sc_card_flags); 6130} 6131 6132void 6133bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr) 6134{ 6135 int i; 6136 6137 for (i = 0; i < 3; ++i) { 6138 *((uint16_t *)eaddr + i) = 6139 htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i)); 6140 } 6141} 6142 6143void 6144bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq) 6145{ 6146 struct bwi_regwin *com; 6147 uint32_t val; 6148 u_int div; 6149 int src; 6150 6151 bzero(freq, sizeof(*freq)); 6152 com = &sc->sc_com_regwin; 6153 6154 KKASSERT(BWI_REGWIN_EXIST(com)); 6155 KKASSERT(sc->sc_cur_regwin == com); 6156 KKASSERT(sc->sc_cap & BWI_CAP_CLKMODE); 6157 6158 /* 6159 * Calculate clock frequency 6160 */ 6161 src = -1; 6162 div = 0; 6163 if (com->rw_rev < 6) { 6164 val = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 6165 if (val & BWI_PCIM_GPIO_OUT_CLKSRC) { 6166 src = BWI_CLKSRC_PCI; 6167 div = 64; 6168 } else { 6169 src = BWI_CLKSRC_CS_OSC; 6170 div = 32; 6171 } 6172 } else if (com->rw_rev < 10) { 6173 val = CSR_READ_4(sc, BWI_CLOCK_CTRL); 6174 6175 src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC); 6176 if (src == BWI_CLKSRC_LP_OSC) 6177 div = 1; 6178 else { 6179 div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2; 6180 6181 /* Unknown source */ 6182 if (src >= BWI_CLKSRC_MAX) 6183 src = BWI_CLKSRC_CS_OSC; 6184 } 6185 } else { 6186 val = CSR_READ_4(sc, BWI_CLOCK_INFO); 6187 6188 src = BWI_CLKSRC_CS_OSC; 6189 div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2; 6190 } 6191 6192 KKASSERT(src >= 0 && src < BWI_CLKSRC_MAX); 6193 KKASSERT(div != 0); 6194 6195 DPRINTF(1, "%s: clksrc %s\n", 6196 sc->sc_dev.dv_xname, 6197 src == BWI_CLKSRC_PCI ? "PCI" : 6198 (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC")); 6199 6200 freq->clkfreq_min = bwi_clkfreq[src].freq_min / div; 6201 freq->clkfreq_max = bwi_clkfreq[src].freq_max / div; 6202 6203 DPRINTF(1, "%s: clkfreq min %u, max %u\n", 6204 sc->sc_dev.dv_xname, freq->clkfreq_min, freq->clkfreq_max); 6205} 6206 6207int 6208bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) 6209{ 6210 struct bwi_regwin *old, *com; 6211 uint32_t clk_ctrl, clk_src; 6212 int error, pwr_off = 0; 6213 6214 com = &sc->sc_com_regwin; 6215 if (!BWI_REGWIN_EXIST(com)) 6216 return (0); 6217 6218 if (com->rw_rev >= 10 || com->rw_rev < 6) 6219 return (0); 6220 6221 /* 6222 * For common regwin whose rev is [6, 10), the chip 6223 * must be capable to change clock mode. 6224 */ 6225 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0) 6226 return (0); 6227 6228 error = bwi_regwin_switch(sc, com, &old); 6229 if (error) 6230 return (error); 6231 6232 if (clk_mode == BWI_CLOCK_MODE_FAST) 6233 bwi_power_on(sc, 0); /* Don't turn on PLL */ 6234 6235 clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL); 6236 clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC); 6237 6238 switch (clk_mode) { 6239 case BWI_CLOCK_MODE_FAST: 6240 clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW; 6241 clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL; 6242 break; 6243 case BWI_CLOCK_MODE_SLOW: 6244 clk_ctrl |= BWI_CLOCK_CTRL_SLOW; 6245 break; 6246 case BWI_CLOCK_MODE_DYN: 6247 clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW | 6248 BWI_CLOCK_CTRL_IGNPLL | 6249 BWI_CLOCK_CTRL_NODYN); 6250 if (clk_src != BWI_CLKSRC_CS_OSC) { 6251 clk_ctrl |= BWI_CLOCK_CTRL_NODYN; 6252 pwr_off = 1; 6253 } 6254 break; 6255 } 6256 CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl); 6257 6258 if (pwr_off) 6259 bwi_power_off(sc, 0); /* Leave PLL as it is */ 6260 6261 return (bwi_regwin_switch(sc, old, NULL)); 6262} 6263 6264int 6265bwi_set_clock_delay(struct bwi_softc *sc) 6266{ 6267 struct bwi_regwin *old, *com; 6268 int error; 6269 6270 com = &sc->sc_com_regwin; 6271 if (!BWI_REGWIN_EXIST(com)) 6272 return (0); 6273 6274 error = bwi_regwin_switch(sc, com, &old); 6275 if (error) 6276 return (error); 6277 6278 if (sc->sc_bbp_id == BWI_BBPID_BCM4321) { 6279 if (sc->sc_bbp_rev == 0) 6280 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0); 6281 else if (sc->sc_bbp_rev == 1) 6282 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1); 6283 } 6284 6285 if (sc->sc_cap & BWI_CAP_CLKMODE) { 6286 if (com->rw_rev >= 10) 6287 CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000); 6288 else { 6289 struct bwi_clock_freq freq; 6290 6291 bwi_get_clock_freq(sc, &freq); 6292 CSR_WRITE_4(sc, BWI_PLL_ON_DELAY, 6293 howmany(freq.clkfreq_max * 150, 1000000)); 6294 CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY, 6295 howmany(freq.clkfreq_max * 15, 1000000)); 6296 } 6297 } 6298 6299 return (bwi_regwin_switch(sc, old, NULL)); 6300} 6301 6302int 6303bwi_init(struct ifnet *ifp) 6304{ 6305 struct bwi_softc *sc = ifp->if_softc; 6306 struct ieee80211com *ic = &sc->sc_ic; 6307 struct bwi_mac *mac; 6308 int error; 6309 6310 DPRINTF(1, "%s\n", __func__); 6311 6312 error = bwi_stop(sc); 6313 if (error) { 6314 DPRINTF(1, "%s: can't stop\n", sc->sc_dev.dv_xname); 6315 return (1); 6316 } 6317 6318 /* power on cardbus socket */ 6319 if (sc->sc_enable != NULL) 6320 (*sc->sc_enable)(sc); 6321 6322 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); 6323 6324 /* TODO: 2 MAC */ 6325 6326 mac = &sc->sc_mac[0]; 6327 error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL); 6328 if (error) 6329 goto back; 6330 6331 error = bwi_mac_init(mac); 6332 if (error) 6333 goto back; 6334 6335 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN); 6336 6337 IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl)); 6338 6339 bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */ 6340 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr); 6341 6342 bwi_mac_reset_hwkeys(mac); 6343 6344 if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) { 6345 int i; 6346 6347#define NRETRY 1000 6348 /* 6349 * Drain any possible pending TX status 6350 */ 6351 for (i = 0; i < NRETRY; ++i) { 6352 if ((CSR_READ_4(sc, BWI_TXSTATUS_0) & 6353 BWI_TXSTATUS_0_MORE) == 0) 6354 break; 6355 CSR_READ_4(sc, BWI_TXSTATUS_1); 6356 } 6357 if (i == NRETRY) 6358 DPRINTF(1, "%s: can't drain TX status\n", 6359 sc->sc_dev.dv_xname); 6360#undef NRETRY 6361 } 6362 6363 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G) 6364 bwi_mac_updateslot(mac, 1); 6365 6366 /* Start MAC */ 6367 error = bwi_mac_start(mac); 6368 if (error) 6369 goto back; 6370 6371 /* Enable intrs */ 6372 bwi_enable_intrs(sc, BWI_INIT_INTRS); 6373 6374 ifp->if_flags |= IFF_RUNNING; 6375 ifp->if_flags &= ~IFF_OACTIVE; 6376 6377 if (ic->ic_opmode != IEEE80211_M_MONITOR) 6378 /* start background scanning */ 6379 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 6380 else 6381 /* in monitor mode change directly into run state */ 6382 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 6383back: 6384 if (error) 6385 bwi_stop(sc); 6386 6387 return (0); 6388} 6389 6390int 6391bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 6392{ 6393 struct bwi_softc *sc = ifp->if_softc; 6394 struct ieee80211com *ic = &sc->sc_ic; 6395 struct ifaddr *ifa; 6396 struct ifreq *ifr; 6397 int s, error = 0; 6398 uint8_t chan; 6399 6400 s = splnet(); 6401 6402 switch (cmd) { 6403 case SIOCSIFADDR: 6404 ifa = (struct ifaddr *)data; 6405 ifp->if_flags |= IFF_UP; 6406#ifdef INET 6407 if (ifa->ifa_addr->sa_family == AF_INET) 6408 arp_ifinit(&ic->ic_ac, ifa); 6409#endif 6410 /* FALLTHROUGH */ 6411 case SIOCSIFFLAGS: 6412 if (ifp->if_flags & IFF_UP) { 6413 if ((ifp->if_flags & IFF_RUNNING) == 0) 6414 bwi_init(ifp); 6415 } else { 6416 if (ifp->if_flags & IFF_RUNNING) 6417 bwi_stop(sc); 6418 } 6419 break; 6420 case SIOCADDMULTI: 6421 case SIOCDELMULTI: 6422 ifr = (struct ifreq *)data; 6423 error = (cmd == SIOCADDMULTI) ? 6424 ether_addmulti(ifr, &ic->ic_ac) : 6425 ether_delmulti(ifr, &ic->ic_ac); 6426 6427 if (error == ENETRESET) 6428 error = 0; 6429 break; 6430 case SIOCS80211CHANNEL: 6431 /* allow fast channel switching in monitor mode */ 6432 error = ieee80211_ioctl(ifp, cmd, data); 6433 if (error == ENETRESET && 6434 ic->ic_opmode == IEEE80211_M_MONITOR) { 6435 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 6436 (IFF_UP | IFF_RUNNING)) { 6437 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 6438 chan = ieee80211_chan2ieee(ic, 6439 ic->ic_bss->ni_chan); 6440 bwi_set_chan(sc, chan); 6441 } 6442 error = 0; 6443 } 6444 break; 6445 default: 6446 error = ieee80211_ioctl(ifp, cmd, data); 6447 break; 6448 } 6449 6450 if (error == ENETRESET) { 6451 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 6452 (IFF_UP | IFF_RUNNING)) 6453 bwi_init(ifp); 6454 error = 0; 6455 } 6456 6457 splx(s); 6458 6459 return (error); 6460} 6461 6462void 6463bwi_start(struct ifnet *ifp) 6464{ 6465 struct bwi_softc *sc = ifp->if_softc; 6466 struct ieee80211com *ic = &sc->sc_ic; 6467 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 6468 int trans, idx; 6469 6470 if ((ifp->if_flags & IFF_OACTIVE) || (ifp->if_flags & IFF_RUNNING) == 0) 6471 return; 6472 6473 trans = 0; 6474 idx = tbd->tbd_idx; 6475 6476 while (tbd->tbd_buf[idx].tb_mbuf == NULL) { 6477 struct ieee80211_frame *wh; 6478 struct ieee80211_node *ni; 6479 struct mbuf *m; 6480 int mgt_pkt = 0; 6481 6482 IF_POLL(&ic->ic_mgtq, m); 6483 if (m != NULL) { 6484 IF_DEQUEUE(&ic->ic_mgtq, m); 6485 6486 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 6487 m->m_pkthdr.rcvif = NULL; 6488 6489 mgt_pkt = 1; 6490 } else { 6491 struct ether_header *eh; 6492 6493 if (ic->ic_state != IEEE80211_S_RUN) 6494 break; 6495 6496 IFQ_POLL(&ifp->if_snd, m); 6497 if (m == NULL) 6498 break; 6499 6500 IFQ_DEQUEUE(&ifp->if_snd, m); 6501 6502 if (m->m_len < sizeof(*eh)) { 6503 m = m_pullup(m, sizeof(*eh)); 6504 if (m == NULL) { 6505 ifp->if_oerrors++; 6506 continue; 6507 } 6508 } 6509 eh = mtod(m, struct ether_header *); 6510 6511 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 6512 if (ni == NULL) { 6513 m_freem(m); 6514 ifp->if_oerrors++; 6515 continue; 6516 } 6517 6518 /* TODO: PS */ 6519#if NBPFILTER > 0 6520 if (ifp->if_bpf != NULL) 6521 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 6522#endif 6523 m = ieee80211_encap(ifp, m, &ni); 6524 if (m == NULL) 6525 continue; 6526 } 6527#if NBPFILTER > 0 6528 if (ic->ic_rawbpf != NULL) 6529 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT); 6530#endif 6531 wh = mtod(m, struct ieee80211_frame *); 6532 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 6533 m = ieee80211_wep_crypt(ifp, m, 1); 6534 if (m == NULL) 6535 return; 6536 } 6537 wh = NULL; /* Catch any invalid use */ 6538 6539 if (mgt_pkt) { 6540 ieee80211_release_node(ic, ni); 6541 ni = NULL; 6542 } 6543 6544 if (bwi_encap(sc, idx, m, ni) != 0) { 6545 /* 'm' is freed in bwi_encap() if we reach here */ 6546 if (ni != NULL) 6547 ieee80211_release_node(ic, ni); 6548 ifp->if_oerrors++; 6549 continue; 6550 } 6551 6552 trans = 1; 6553 tbd->tbd_used++; 6554 idx = (idx + 1) % BWI_TX_NDESC; 6555 6556 if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { 6557 ifp->if_flags |= IFF_OACTIVE; 6558 break; 6559 } 6560 } 6561 tbd->tbd_idx = idx; 6562 6563 if (trans) 6564 sc->sc_tx_timer = 5; 6565 ifp->if_timer = 1; 6566} 6567 6568void 6569bwi_watchdog(struct ifnet *ifp) 6570{ 6571 struct bwi_softc *sc = ifp->if_softc; 6572 6573 ifp->if_timer = 0; 6574 6575 if ((ifp->if_flags & IFF_RUNNING) == 0) 6576 return; 6577 6578 if (sc->sc_tx_timer) { 6579 if (--sc->sc_tx_timer == 0) { 6580 DPRINTF(1, "%s: watchdog timeout\n", 6581 sc->sc_dev.dv_xname); 6582 ifp->if_oerrors++; 6583 /* TODO */ 6584 } else 6585 ifp->if_timer = 1; 6586 } 6587 6588 ieee80211_watchdog(ifp); 6589} 6590 6591int 6592bwi_stop(struct bwi_softc *sc) 6593{ 6594 struct ieee80211com *ic = &sc->sc_ic; 6595 struct ifnet *ifp = &ic->ic_if; 6596 struct bwi_mac *mac; 6597 int i, error, pwr_off = 0; 6598 6599 DPRINTF(1, "%s\n", __func__); 6600 6601 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 6602 6603 if (ifp->if_flags & IFF_RUNNING) { 6604 KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 6605 mac = (struct bwi_mac *)sc->sc_cur_regwin; 6606 6607 bwi_disable_intrs(sc, BWI_ALL_INTRS); 6608 CSR_READ_4(sc, BWI_MAC_INTR_MASK); 6609 bwi_mac_stop(mac); 6610 } 6611 6612 for (i = 0; i < sc->sc_nmac; ++i) { 6613 struct bwi_regwin *old_rw; 6614 6615 mac = &sc->sc_mac[i]; 6616 if ((mac->mac_flags & BWI_MAC_F_INITED) == 0) 6617 continue; 6618 6619 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw); 6620 if (error) 6621 continue; 6622 6623 bwi_mac_shutdown(mac); 6624 pwr_off = 1; 6625 6626 bwi_regwin_switch(sc, old_rw, NULL); 6627 } 6628 6629 if (pwr_off) 6630 bwi_bbp_power_off(sc); 6631 6632 sc->sc_tx_timer = 0; 6633 ifp->if_timer = 0; 6634 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 6635 6636 /* power off cardbus socket */ 6637 if (sc->sc_disable) 6638 sc->sc_disable(sc); 6639 6640 return (0); 6641} 6642 6643int 6644bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 6645{ 6646 struct bwi_softc *sc = ic->ic_if.if_softc; 6647 int error; 6648 uint8_t chan; 6649 6650 timeout_del(&sc->sc_scan_ch); 6651 timeout_del(&sc->sc_calib_ch); 6652 6653 if (nstate == IEEE80211_S_INIT) 6654 goto back; 6655 6656 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 6657 error = bwi_set_chan(sc, chan); 6658 if (error) { 6659 DPRINTF(1, "%s: can't set channel to %u\n", 6660 sc->sc_dev.dv_xname, 6661 ieee80211_chan2ieee(ic, ic->ic_des_chan)); 6662 return (error); 6663 } 6664 6665 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 6666 /* Nothing to do */ 6667 } else if (nstate == IEEE80211_S_RUN) { 6668 struct bwi_mac *mac; 6669 6670 bwi_set_bssid(sc, ic->ic_bss->ni_bssid); 6671 6672 KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 6673 mac = (struct bwi_mac *)sc->sc_cur_regwin; 6674 6675 /* Initial TX power calibration */ 6676 bwi_mac_calibrate_txpower(mac); 6677 } else 6678 bwi_set_bssid(sc, bwi_zero_addr); 6679 6680back: 6681 error = sc->sc_newstate(ic, nstate, arg); 6682 6683 if (nstate == IEEE80211_S_SCAN) { 6684 timeout_add(&sc->sc_scan_ch, 6685 (sc->sc_dwell_time * hz) / 1000); 6686 } else if (nstate == IEEE80211_S_RUN) { 6687 /* XXX 15 seconds */ 6688 timeout_add(&sc->sc_calib_ch, hz * 15); 6689 } 6690 6691 return (error); 6692} 6693 6694int 6695bwi_media_change(struct ifnet *ifp) 6696{ 6697 int error; 6698 6699 error = ieee80211_media_change(ifp); 6700 if (error != ENETRESET) 6701 return (error); 6702 6703 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 6704 bwi_init(ifp); 6705 6706 return (0); 6707} 6708 6709int 6710bwi_dma_alloc(struct bwi_softc *sc) 6711{ 6712 int error, i, has_txstats; 6713 bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0; 6714 uint32_t txrx_ctrl_step = 0; 6715 6716 has_txstats = 0; 6717 for (i = 0; i < sc->sc_nmac; ++i) { 6718 if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) { 6719 has_txstats = 1; 6720 break; 6721 } 6722 } 6723 6724 switch (sc->sc_bus_space) { 6725 case BWI_BUS_SPACE_30BIT: 6726 case BWI_BUS_SPACE_32BIT: 6727 desc_sz = sizeof(struct bwi_desc32); 6728 txrx_ctrl_step = 0x20; 6729 6730 sc->sc_init_tx_ring = bwi_init_tx_ring32; 6731 sc->sc_free_tx_ring = bwi_free_tx_ring32; 6732 sc->sc_init_rx_ring = bwi_init_rx_ring32; 6733 sc->sc_free_rx_ring = bwi_free_rx_ring32; 6734 sc->sc_setup_rxdesc = bwi_setup_rx_desc32; 6735 sc->sc_setup_txdesc = bwi_setup_tx_desc32; 6736 sc->sc_rxeof = bwi_rxeof32; 6737 sc->sc_start_tx = bwi_start_tx32; 6738 if (has_txstats) { 6739 sc->sc_init_txstats = bwi_init_txstats32; 6740 sc->sc_free_txstats = bwi_free_txstats32; 6741 sc->sc_txeof_status = bwi_txeof_status32; 6742 } 6743 break; 6744 6745 case BWI_BUS_SPACE_64BIT: 6746 desc_sz = sizeof(struct bwi_desc64); 6747 txrx_ctrl_step = 0x40; 6748 6749 sc->sc_init_tx_ring = bwi_init_tx_ring64; 6750 sc->sc_free_tx_ring = bwi_free_tx_ring64; 6751 sc->sc_init_rx_ring = bwi_init_rx_ring64; 6752 sc->sc_free_rx_ring = bwi_free_rx_ring64; 6753 sc->sc_setup_rxdesc = bwi_setup_rx_desc64; 6754 sc->sc_setup_txdesc = bwi_setup_tx_desc64; 6755 sc->sc_rxeof = bwi_rxeof64; 6756 sc->sc_start_tx = bwi_start_tx64; 6757 if (has_txstats) { 6758 sc->sc_init_txstats = bwi_init_txstats64; 6759 sc->sc_free_txstats = bwi_free_txstats64; 6760 sc->sc_txeof_status = bwi_txeof_status64; 6761 } 6762 break; 6763 } 6764 6765 KKASSERT(desc_sz != 0); 6766 KKASSERT(txrx_ctrl_step != 0); 6767 6768 tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN); 6769 rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN); 6770 6771#define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step) 6772 /* 6773 * Create TX ring DMA stuffs 6774 */ 6775 for (i = 0; i < BWI_TX_NRING; ++i) { 6776 error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1, 6777 tx_ring_sz, 0, BUS_DMA_NOWAIT, 6778 &sc->sc_tx_rdata[i].rdata_dmap); 6779 if (error) { 6780 DPRINTF(1, "%s: %dth TX ring DMA create failed\n", 6781 sc->sc_dev.dv_xname, i); 6782 return (error); 6783 } 6784 error = bwi_dma_ring_alloc(sc, 6785 &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i)); 6786 if (error) { 6787 DPRINTF(1, "%s: %dth TX ring DMA alloc failed\n", 6788 sc->sc_dev.dv_xname, i); 6789 return (error); 6790 } 6791 } 6792 6793 /* 6794 * Create RX ring DMA stuffs 6795 */ 6796 error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1, 6797 rx_ring_sz, 0, BUS_DMA_NOWAIT, 6798 &sc->sc_rx_rdata.rdata_dmap); 6799 if (error) { 6800 DPRINTF(1, "%s: RX ring DMA create failed\n", 6801 sc->sc_dev.dv_xname); 6802 return (error); 6803 } 6804 6805 error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata, 6806 rx_ring_sz, TXRX_CTRL(0)); 6807 if (error) { 6808 DPRINTF(1, "%s: RX ring DMA alloc failed\n", 6809 sc->sc_dev.dv_xname); 6810 return (error); 6811 } 6812 6813 if (has_txstats) { 6814 error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz); 6815 if (error) { 6816 DPRINTF(1, "%s: TX stats DMA alloc failed\n", 6817 sc->sc_dev.dv_xname); 6818 return (error); 6819 } 6820 } 6821#undef TXRX_CTRL 6822 6823 return (bwi_dma_mbuf_create(sc)); 6824} 6825 6826void 6827bwi_dma_free(struct bwi_softc *sc) 6828{ 6829 int i; 6830 6831 for (i = 0; i < BWI_TX_NRING; ++i) { 6832 struct bwi_ring_data *rd = &sc->sc_tx_rdata[i]; 6833 6834 if (rd->rdata_desc != NULL) { 6835 bus_dmamap_unload(sc->sc_dmat, 6836 rd->rdata_dmap); 6837 bus_dmamem_free(sc->sc_dmat, 6838 &rd->rdata_seg, 1); 6839 } 6840 } 6841 6842 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 6843 6844 if (rd->rdata_desc != NULL) { 6845 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap); 6846 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1); 6847 } 6848 6849 bwi_dma_txstats_free(sc); 6850 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1); 6851} 6852 6853int 6854bwi_dma_ring_alloc(struct bwi_softc *sc, 6855 struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl) 6856{ 6857 int error, nsegs; 6858 6859 error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0, 6860 &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT); 6861 if (error) { 6862 DPRINTF(1, "%s: can't allocate DMA mem\n", sc->sc_dev.dv_xname); 6863 return (error); 6864 } 6865 6866 error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs, 6867 size, (caddr_t *)&rd->rdata_desc, BUS_DMA_NOWAIT); 6868 if (error) { 6869 DPRINTF(1, "%s: can't map DMA mem\n", sc->sc_dev.dv_xname); 6870 return (error); 6871 } 6872 6873 error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc, 6874 size, NULL, BUS_DMA_WAITOK); 6875 if (error) { 6876 DPRINTF(1, "%s: can't load DMA mem\n", sc->sc_dev.dv_xname); 6877 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs); 6878 rd->rdata_desc = NULL; 6879 return (error); 6880 } 6881 6882 rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr; 6883 rd->rdata_txrx_ctrl = txrx_ctrl; 6884 6885 return (0); 6886} 6887 6888int 6889bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base, 6890 bus_size_t desc_sz) 6891{ 6892 struct bwi_txstats_data *st; 6893 bus_size_t dma_size; 6894 int error, nsegs; 6895 6896 st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO); 6897 sc->sc_txstats = st; 6898 6899 /* 6900 * Create TX stats descriptor DMA stuffs 6901 */ 6902 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN); 6903 6904 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 6905 BUS_DMA_NOWAIT, &st->stats_ring_dmap); 6906 if (error) { 6907 DPRINTF(1, "%s: can't create txstats ring DMA mem\n", 6908 sc->sc_dev.dv_xname); 6909 return (error); 6910 } 6911 6912 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0, 6913 &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT); 6914 if (error) { 6915 DPRINTF(1, "%s: can't allocate txstats ring DMA mem\n", 6916 sc->sc_dev.dv_xname); 6917 return (error); 6918 } 6919 6920 error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs, 6921 dma_size, (caddr_t *)&st->stats_ring, BUS_DMA_NOWAIT); 6922 if (error) { 6923 DPRINTF(1, "%s: can't map txstats ring DMA mem\n", 6924 sc->sc_dev.dv_xname); 6925 return (error); 6926 } 6927 6928 error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap, 6929 st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK); 6930 if (error) { 6931 DPRINTF(1, "%s: can't load txstats ring DMA mem\n", 6932 sc->sc_dev.dv_xname); 6933 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs); 6934 return (error); 6935 } 6936 6937 bzero(&st->stats_ring, dma_size); 6938 st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr; 6939 6940 /* 6941 * Create TX stats DMA stuffs 6942 */ 6943 dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC, 6944 BWI_ALIGN); 6945 6946 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 6947 BUS_DMA_NOWAIT, &st->stats_dmap); 6948 if (error) { 6949 DPRINTF(1, "%s: can't create txstats ring DMA mem\n", 6950 sc->sc_dev.dv_xname); 6951 return (error); 6952 } 6953 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0, 6954 &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT); 6955 if (error) { 6956 DPRINTF(1, "%s: can't allocate txstats DMA mem\n", 6957 sc->sc_dev.dv_xname); 6958 return (error); 6959 } 6960 6961 error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs, 6962 dma_size, (caddr_t *)&st->stats, BUS_DMA_NOWAIT); 6963 if (error) { 6964 DPRINTF(1, "%s: can't map txstats DMA mem\n", 6965 sc->sc_dev.dv_xname); 6966 return (error); 6967 } 6968 6969 error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats, 6970 dma_size, NULL, BUS_DMA_WAITOK); 6971 if (error) { 6972 DPRINTF(1, "%s: can't load txstats DMA mem\n", 6973 sc->sc_dev.dv_xname); 6974 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs); 6975 return (error); 6976 } 6977 6978 bzero(&st->stats, dma_size); 6979 st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr; 6980 st->stats_ctrl_base = ctrl_base; 6981 6982 return (0); 6983} 6984 6985void 6986bwi_dma_txstats_free(struct bwi_softc *sc) 6987{ 6988 struct bwi_txstats_data *st; 6989 6990 if (sc->sc_txstats == NULL) 6991 return; 6992 st = sc->sc_txstats; 6993 6994 bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap); 6995 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1); 6996 6997 bus_dmamap_unload(sc->sc_dmat, st->stats_dmap); 6998 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1); 6999 7000 free(st, M_DEVBUF); 7001} 7002 7003int 7004bwi_dma_mbuf_create(struct bwi_softc *sc) 7005{ 7006 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 7007 int i, j, k, ntx, error; 7008 7009 ntx = 0; 7010 7011 /* 7012 * Create TX mbuf DMA map 7013 */ 7014 for (i = 0; i < BWI_TX_NRING; ++i) { 7015 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 7016 7017 for (j = 0; j < BWI_TX_NDESC; ++j) { 7018 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 7019 0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap); 7020 if (error) { 7021 DPRINTF(1, 7022 "%s: can't create %dth tbd, %dth DMA map\n", 7023 sc->sc_dev.dv_xname, i, j); 7024 ntx = i; 7025 for (k = 0; k < j; ++k) { 7026 bus_dmamap_destroy(sc->sc_dmat, 7027 tbd->tbd_buf[k].tb_dmap); 7028 } 7029 goto fail; 7030 } 7031 } 7032 } 7033 ntx = BWI_TX_NRING; 7034 7035 /* 7036 * Create RX mbuf DMA map and a spare DMA map 7037 */ 7038 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 7039 BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap); 7040 if (error) { 7041 DPRINTF(1, "%s: can't create spare RX buf DMA map\n", 7042 sc->sc_dev.dv_xname); 7043 goto fail; 7044 } 7045 7046 for (j = 0; j < BWI_RX_NDESC; ++j) { 7047 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 7048 BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap); 7049 if (error) { 7050 DPRINTF(1, "%s: can't create %dth RX buf DMA map\n", 7051 sc->sc_dev.dv_xname, j); 7052 7053 for (k = 0; k < j; ++k) { 7054 bus_dmamap_destroy(sc->sc_dmat, 7055 rbd->rbd_buf[j].rb_dmap); 7056 } 7057 bus_dmamap_destroy(sc->sc_dmat, 7058 rbd->rbd_tmp_dmap); 7059 goto fail; 7060 } 7061 } 7062 7063 return 0; 7064fail: 7065 bwi_dma_mbuf_destroy(sc, ntx, 0); 7066 7067 return (error); 7068} 7069 7070void 7071bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx) 7072{ 7073 struct ieee80211com *ic = &sc->sc_ic; 7074 int i, j; 7075 7076 for (i = 0; i < ntx; ++i) { 7077 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 7078 7079 for (j = 0; j < BWI_TX_NDESC; ++j) { 7080 struct bwi_txbuf *tb = &tbd->tbd_buf[j]; 7081 7082 if (tb->tb_mbuf != NULL) { 7083 bus_dmamap_unload(sc->sc_dmat, 7084 tb->tb_dmap); 7085 m_freem(tb->tb_mbuf); 7086 } 7087 if (tb->tb_ni != NULL) 7088 ieee80211_release_node(ic, tb->tb_ni); 7089 bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap); 7090 } 7091 } 7092 7093 if (nrx) { 7094 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 7095 7096 bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap); 7097 for (j = 0; j < BWI_RX_NDESC; ++j) { 7098 struct bwi_rxbuf *rb = &rbd->rbd_buf[j]; 7099 7100 if (rb->rb_mbuf != NULL) { 7101 bus_dmamap_unload(sc->sc_dmat, 7102 rb->rb_dmap); 7103 m_freem(rb->rb_mbuf); 7104 } 7105 bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap); 7106 } 7107 } 7108} 7109 7110void 7111bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs) 7112{ 7113 CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs); 7114} 7115 7116void 7117bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs) 7118{ 7119 CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs); 7120} 7121 7122int 7123bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx) 7124{ 7125 struct bwi_ring_data *rd; 7126 struct bwi_txbuf_data *tbd; 7127 uint32_t val, addr_hi, addr_lo; 7128 7129 KKASSERT(ring_idx < BWI_TX_NRING); 7130 rd = &sc->sc_tx_rdata[ring_idx]; 7131 tbd = &sc->sc_tx_bdata[ring_idx]; 7132 7133 tbd->tbd_idx = 0; 7134 tbd->tbd_used = 0; 7135 7136 bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_TX_NDESC); 7137 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 7138 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 7139 7140 addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 7141 addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 7142 7143 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 7144 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 7145 BWI_TXRX32_RINGINFO_FUNC_MASK); 7146 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val); 7147 7148 val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 7149 BWI_TXRX32_CTRL_ENABLE; 7150 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val); 7151 7152 return (0); 7153} 7154 7155void 7156bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base, 7157 bus_addr_t paddr, int hdr_size, int ndesc) 7158{ 7159 uint32_t val, addr_hi, addr_lo; 7160 7161 addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 7162 addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 7163 7164 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 7165 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 7166 BWI_TXRX32_RINGINFO_FUNC_MASK); 7167 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val); 7168 7169 val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) | 7170 __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 7171 BWI_TXRX32_CTRL_ENABLE; 7172 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val); 7173 7174 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 7175 (ndesc - 1) * sizeof(struct bwi_desc32)); 7176} 7177 7178int 7179bwi_init_rx_ring32(struct bwi_softc *sc) 7180{ 7181 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 7182 int i, error; 7183 7184 sc->sc_rx_bdata.rbd_idx = 0; 7185 7186 for (i = 0; i < BWI_RX_NDESC; ++i) { 7187 error = bwi_newbuf(sc, i, 1); 7188 if (error) { 7189 DPRINTF(1, "%s: can't allocate %dth RX buffer\n", 7190 sc->sc_dev.dv_xname, i); 7191 return (error); 7192 } 7193 } 7194 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 7195 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 7196 7197 bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr, 7198 sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC); 7199 return (0); 7200} 7201 7202int 7203bwi_init_txstats32(struct bwi_softc *sc) 7204{ 7205 struct bwi_txstats_data *st = sc->sc_txstats; 7206 bus_addr_t stats_paddr; 7207 int i; 7208 7209 bzero(st->stats, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats)); 7210 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 7211 st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 7212 7213 st->stats_idx = 0; 7214 7215 stats_paddr = st->stats_paddr; 7216 for (i = 0; i < BWI_TXSTATS_NDESC; ++i) { 7217 bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i, 7218 stats_paddr, sizeof(struct bwi_txstats), 0); 7219 stats_paddr += sizeof(struct bwi_txstats); 7220 } 7221 bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0, 7222 st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 7223 7224 bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base, 7225 st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC); 7226 7227 return (0); 7228} 7229 7230void 7231bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 7232 int buf_len) 7233{ 7234 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 7235 7236 KKASSERT(buf_idx < BWI_RX_NDESC); 7237 bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx, 7238 paddr, buf_len, 0); 7239} 7240 7241void 7242bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd, 7243 int buf_idx, bus_addr_t paddr, int buf_len) 7244{ 7245 KKASSERT(buf_idx < BWI_TX_NDESC); 7246 bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx, 7247 paddr, buf_len, 1); 7248} 7249 7250int 7251bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx) 7252{ 7253 /* TODO:64 */ 7254 return (EOPNOTSUPP); 7255} 7256 7257int 7258bwi_init_rx_ring64(struct bwi_softc *sc) 7259{ 7260 /* TODO:64 */ 7261 return (EOPNOTSUPP); 7262} 7263 7264int 7265bwi_init_txstats64(struct bwi_softc *sc) 7266{ 7267 /* TODO:64 */ 7268 return (EOPNOTSUPP); 7269} 7270 7271void 7272bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 7273 int buf_len) 7274{ 7275 /* TODO:64 */ 7276} 7277 7278void 7279bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd, 7280 int buf_idx, bus_addr_t paddr, int buf_len) 7281{ 7282 /* TODO:64 */ 7283} 7284 7285int 7286bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init) 7287{ 7288 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 7289 struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx]; 7290 struct bwi_rxbuf_hdr *hdr; 7291 bus_dmamap_t map; 7292 bus_addr_t paddr; 7293 struct mbuf *m; 7294 int error; 7295 7296 KKASSERT(buf_idx < BWI_RX_NDESC); 7297 7298 MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA); 7299 if (m == NULL) 7300 return (ENOBUFS); 7301 MCLGET(m, init ? M_WAITOK : M_DONTWAIT); 7302 if (m == NULL) { 7303 error = ENOBUFS; 7304 7305 /* 7306 * If the NIC is up and running, we need to: 7307 * - Clear RX buffer's header. 7308 * - Restore RX descriptor settings. 7309 */ 7310 if (init) 7311 return error; 7312 else 7313 goto back; 7314 } 7315 m->m_len = m->m_pkthdr.len = MCLBYTES; 7316 7317 /* 7318 * Try to load RX buf into temporary DMA map 7319 */ 7320 error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m, 7321 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT); 7322 if (error) { 7323 m_freem(m); 7324 7325 /* 7326 * See the comment above 7327 */ 7328 if (init) 7329 return error; 7330 else 7331 goto back; 7332 } 7333 7334 if (!init) 7335 bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap); 7336 rxbuf->rb_mbuf = m; 7337 7338 /* 7339 * Swap RX buf's DMA map with the loaded temporary one 7340 */ 7341 map = rxbuf->rb_dmap; 7342 rxbuf->rb_dmap = rbd->rbd_tmp_dmap; 7343 rbd->rbd_tmp_dmap = map; 7344 paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr; 7345 rxbuf->rb_paddr = paddr; 7346 7347back: 7348 /* 7349 * Clear RX buf header 7350 */ 7351 hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *); 7352 bzero(hdr, sizeof(*hdr)); 7353 bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0, 7354 rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 7355 7356 /* 7357 * Setup RX buf descriptor 7358 */ 7359 sc->sc_setup_rxdesc(sc, buf_idx, rxbuf->rb_paddr, 7360 rxbuf->rb_mbuf->m_len - sizeof(*hdr)); 7361 return error; 7362} 7363 7364void 7365bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs, 7366 const uint8_t *addr) 7367{ 7368 int i; 7369 7370 CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL, 7371 BWI_ADDR_FILTER_CTRL_SET | addr_ofs); 7372 7373 for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) { 7374 uint16_t addr_val; 7375 7376 addr_val = (uint16_t)addr[i * 2] | 7377 (((uint16_t)addr[(i * 2) + 1]) << 8); 7378 CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val); 7379 } 7380} 7381 7382int 7383bwi_set_chan(struct bwi_softc *sc, u_int8_t chan) 7384{ 7385 struct bwi_mac *mac; 7386 7387 KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7388 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7389 7390 bwi_rf_set_chan(mac, chan, 0); 7391 7392 return (0); 7393} 7394 7395void 7396bwi_next_scan(void *xsc) 7397{ 7398 struct bwi_softc *sc = xsc; 7399 struct ieee80211com *ic = &sc->sc_ic; 7400 struct ifnet *ifp = &ic->ic_if; 7401 int s; 7402 7403 s = splnet(); 7404 7405 if (ic->ic_state == IEEE80211_S_SCAN) 7406 ieee80211_next_scan(ifp); 7407 7408 splx(s); 7409} 7410 7411void 7412bwi_rxeof(struct bwi_softc *sc, int end_idx) 7413{ 7414 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 7415 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 7416 struct ieee80211com *ic = &sc->sc_ic; 7417 struct ifnet *ifp = &ic->ic_if; 7418 int idx; 7419 7420 idx = rbd->rbd_idx; 7421 while (idx != end_idx) { 7422 struct bwi_rxbuf *rb = &rbd->rbd_buf[idx]; 7423 struct bwi_rxbuf_hdr *hdr; 7424 struct ieee80211_frame *wh; 7425 struct ieee80211_node *ni; 7426 struct mbuf *m; 7427 uint8_t plcp_signal; 7428 uint16_t flags2; 7429 int buflen, wh_ofs, hdr_extra; 7430 7431 m = rb->rb_mbuf; 7432 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0, 7433 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 7434 7435 if (bwi_newbuf(sc, idx, 0)) { 7436 ifp->if_ierrors++; 7437 goto next; 7438 } 7439 7440 hdr = mtod(m, struct bwi_rxbuf_hdr *); 7441 flags2 = letoh16(hdr->rxh_flags2); 7442 7443 hdr_extra = 0; 7444 if (flags2 & BWI_RXH_F2_TYPE2FRAME) 7445 hdr_extra = 2; 7446 wh_ofs = hdr_extra + 6; 7447 7448 buflen = letoh16(hdr->rxh_buflen); 7449 if (buflen <= wh_ofs) { 7450 DPRINTF(1, "%s: zero length data, hdr_extra %d\n", 7451 sc->sc_dev.dv_xname, hdr_extra); 7452 ifp->if_ierrors++; 7453 m_freem(m); 7454 goto next; 7455 } 7456 7457 plcp_signal = *((uint8_t *)(hdr + 1) + hdr_extra); 7458 7459 m->m_pkthdr.rcvif = ifp; 7460 m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); 7461 m_adj(m, sizeof(*hdr) + wh_ofs); 7462 7463#if NBPFILTER > 0 7464 /* RX radio tap */ 7465 if (sc->sc_drvbpf != NULL) { 7466 struct mbuf mb; 7467 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap; 7468 7469 /* TODO: calculate rate and signal */ 7470 tap->wr_tsf = hdr->rxh_tsf; 7471 tap->wr_flags = 0; 7472 tap->wr_rate = 0; 7473 tap->wr_chan_freq = 7474 htole16(ic->ic_bss->ni_chan->ic_freq); 7475 tap->wr_chan_flags = 7476 htole16(ic->ic_bss->ni_chan->ic_flags); 7477 tap->wr_antsignal = 0; 7478 tap->wr_antnoise = 0; 7479 7480 mb.m_data = (caddr_t)tap; 7481 mb.m_len = sc->sc_rxtap_len; 7482 mb.m_next = m; 7483 mb.m_nextpkt = NULL; 7484 mb.m_type = 0; 7485 mb.m_flags = 0; 7486 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); 7487 } 7488#endif 7489 7490 m_adj(m, -IEEE80211_CRC_LEN); 7491 7492 wh = mtod(m, struct ieee80211_frame *); 7493 ni = ieee80211_find_rxnode(ic, wh); 7494 7495 ieee80211_input(ifp, m, ni, hdr->rxh_rssi, 7496 letoh16(hdr->rxh_tsf)); 7497 7498 ieee80211_release_node(ic, ni); 7499next: 7500 idx = (idx + 1) % BWI_RX_NDESC; 7501 } 7502 7503 rbd->rbd_idx = idx; 7504 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 7505 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 7506} 7507 7508void 7509bwi_rxeof32(struct bwi_softc *sc) 7510{ 7511 uint32_t val, rx_ctrl; 7512 int end_idx; 7513 7514 rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl; 7515 7516 val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 7517 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 7518 sizeof(struct bwi_desc32); 7519 7520 bwi_rxeof(sc, end_idx); 7521 7522 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX, 7523 end_idx * sizeof(struct bwi_desc32)); 7524} 7525 7526void 7527bwi_rxeof64(struct bwi_softc *sc) 7528{ 7529 /* TODO:64 */ 7530} 7531 7532void 7533bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl) 7534{ 7535 int i; 7536 7537 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0); 7538 7539#define NRETRY 10 7540 for (i = 0; i < NRETRY; ++i) { 7541 uint32_t status; 7542 7543 status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 7544 if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) == 7545 BWI_RX32_STATUS_STATE_DISABLED) 7546 break; 7547 7548 DELAY(1000); 7549 } 7550 if (i == NRETRY) 7551 DPRINTF(1, "%s: reset rx ring timedout\n", sc->sc_dev.dv_xname); 7552#undef NRETRY 7553 7554 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0); 7555} 7556 7557void 7558bwi_free_txstats32(struct bwi_softc *sc) 7559{ 7560 bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base); 7561} 7562 7563void 7564bwi_free_rx_ring32(struct bwi_softc *sc) 7565{ 7566 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 7567 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 7568 int i; 7569 7570 bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl); 7571 7572 for (i = 0; i < BWI_RX_NDESC; ++i) { 7573 struct bwi_rxbuf *rb = &rbd->rbd_buf[i]; 7574 7575 if (rb->rb_mbuf != NULL) { 7576 bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap); 7577 m_freem(rb->rb_mbuf); 7578 rb->rb_mbuf = NULL; 7579 } 7580 } 7581} 7582 7583void 7584bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx) 7585{ 7586 struct ieee80211com *ic = &sc->sc_ic; 7587 struct bwi_ring_data *rd; 7588 struct bwi_txbuf_data *tbd; 7589 uint32_t state, val; 7590 int i; 7591 7592 KKASSERT(ring_idx < BWI_TX_NRING); 7593 rd = &sc->sc_tx_rdata[ring_idx]; 7594 tbd = &sc->sc_tx_bdata[ring_idx]; 7595 7596#define NRETRY 10 7597 for (i = 0; i < NRETRY; ++i) { 7598 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 7599 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 7600 if (state == BWI_TX32_STATUS_STATE_DISABLED || 7601 state == BWI_TX32_STATUS_STATE_IDLE || 7602 state == BWI_TX32_STATUS_STATE_STOPPED) 7603 break; 7604 7605 DELAY(1000); 7606 } 7607 if (i == NRETRY) { 7608 DPRINTF(1, "%s: wait for TX ring(%d) stable timed out\n", 7609 sc->sc_dev.dv_xname, ring_idx); 7610 } 7611 7612 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0); 7613 for (i = 0; i < NRETRY; ++i) { 7614 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 7615 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 7616 if (state == BWI_TX32_STATUS_STATE_DISABLED) 7617 break; 7618 7619 DELAY(1000); 7620 } 7621 if (i == NRETRY) 7622 DPRINTF(1, "%s: reset TX ring (%d) timed out\n", 7623 sc->sc_dev.dv_xname, ring_idx); 7624#undef NRETRY 7625 7626 DELAY(1000); 7627 7628 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0); 7629 7630 for (i = 0; i < BWI_TX_NDESC; ++i) { 7631 struct bwi_txbuf *tb = &tbd->tbd_buf[i]; 7632 7633 if (tb->tb_mbuf != NULL) { 7634 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 7635 m_freem(tb->tb_mbuf); 7636 tb->tb_mbuf = NULL; 7637 } 7638 if (tb->tb_ni != NULL) { 7639 ieee80211_release_node(ic, tb->tb_ni); 7640 tb->tb_ni = NULL; 7641 } 7642 } 7643} 7644 7645void 7646bwi_free_txstats64(struct bwi_softc *sc) 7647{ 7648 /* TODO:64 */ 7649} 7650 7651void 7652bwi_free_rx_ring64(struct bwi_softc *sc) 7653{ 7654 /* TODO:64 */ 7655} 7656 7657void 7658bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx) 7659{ 7660 /* TODO:64 */ 7661} 7662 7663/* XXX does not belong here */ 7664uint8_t 7665bwi_rate2plcp(uint8_t rate) 7666{ 7667 rate &= IEEE80211_RATE_VAL; 7668 7669 switch (rate) { 7670 case 2: return (0xa); 7671 case 4: return (0x14); 7672 case 11: return (0x37); 7673 case 22: return (0x6e); 7674 case 44: return (0xdc); 7675 7676 case 12: return (0xb); 7677 case 18: return (0xf); 7678 case 24: return (0xa); 7679 case 36: return (0xe); 7680 case 48: return (0x9); 7681 case 72: return (0xd); 7682 case 96: return (0x8); 7683 case 108: return (0xc); 7684 7685 default: 7686 panic("unsupported rate %u\n", rate); 7687 } 7688} 7689 7690void 7691bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate) 7692{ 7693/* XXX does not belong here */ 7694#define IEEE80211_OFDM_PLCP_SIG_MASK 0x0000000f 7695#define IEEE80211_OFDM_PLCP_LEN_MASK 0x0001ffe0 7696 7697 uint32_t plcp; 7698 7699 plcp = __SHIFTIN(bwi_rate2plcp(rate), IEEE80211_OFDM_PLCP_SIG_MASK) | 7700 __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK); 7701 *plcp0 = htole32(plcp); 7702} 7703 7704void 7705bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len, 7706 uint8_t rate) 7707{ 7708 int len, service, pkt_bitlen; 7709 7710 pkt_bitlen = pkt_len * NBBY; 7711 len = howmany(pkt_bitlen * 2, rate); 7712 7713 service = IEEE80211_DS_PLCP_SERVICE_LOCKED; 7714 if (rate == (11 * 2)) { 7715 int pkt_bitlen1; 7716 7717 /* 7718 * PLCP service field needs to be adjusted, 7719 * if TX rate is 11Mbytes/s 7720 */ 7721 pkt_bitlen1 = len * 11; 7722 if (pkt_bitlen1 - pkt_bitlen >= NBBY) 7723 service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7; 7724 } 7725 7726 plcp->i_signal = bwi_rate2plcp(rate); 7727 plcp->i_service = service; 7728 plcp->i_length = htole16(len); 7729 /* NOTE: do NOT touch i_crc */ 7730} 7731 7732void 7733bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate) 7734{ 7735 enum bwi_modtype modtype; 7736 7737 /* 7738 * Assume caller has zeroed 'plcp' 7739 */ 7740 7741 modtype = bwi_rate2modtype(rate); 7742 if (modtype == IEEE80211_MODTYPE_OFDM) 7743 bwi_ofdm_plcp_header(plcp, pkt_len, rate); 7744 else if (modtype == IEEE80211_MODTYPE_DS) 7745 bwi_ds_plcp_header(plcp, pkt_len, rate); 7746 else 7747 panic("unsupport modulation type %u\n", modtype); 7748} 7749 7750enum bwi_modtype 7751bwi_rate2modtype(u_int8_t rate) 7752{ 7753 rate &= IEEE80211_RATE_VAL; 7754 7755 if (rate == 44) 7756 return IEEE80211_MODTYPE_PBCC; 7757 else if (rate == 22 || rate < 12) 7758 return IEEE80211_MODTYPE_DS; 7759 else 7760 return IEEE80211_MODTYPE_OFDM; 7761} 7762 7763u_int8_t 7764bwi_ack_rate(struct ieee80211_node *ni, u_int8_t rate) 7765{ 7766 const struct ieee80211_rateset *rs = &ni->ni_rates; 7767 u_int8_t ack_rate = 0; 7768 enum bwi_modtype modtype; 7769 int i; 7770 7771 rate &= IEEE80211_RATE_VAL; 7772 7773 modtype = bwi_rate2modtype(rate); 7774 7775 for (i = 0; i < rs->rs_nrates; ++i) { 7776 u_int8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL; 7777 7778 if (rate1 > rate) { 7779 if (ack_rate != 0) 7780 return ack_rate; 7781 else 7782 break; 7783 } 7784 7785 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && 7786 bwi_rate2modtype(rate1) == modtype) 7787 ack_rate = rate1; 7788 } 7789 7790 switch (rate) { 7791 /* CCK */ 7792 case 2: 7793 case 4: 7794 case 11: 7795 case 22: 7796 ack_rate = rate; 7797 break; 7798 /* PBCC */ 7799 case 44: 7800 ack_rate = 22; 7801 break; 7802 7803 /* OFDM */ 7804 case 12: 7805 case 18: 7806 ack_rate = 12; 7807 break; 7808 case 24: 7809 case 36: 7810 ack_rate = 24; 7811 break; 7812 case 48: 7813 case 72: 7814 case 96: 7815 case 108: 7816 ack_rate = 48; 7817 break; 7818 default: 7819 panic("unsupported rate %d\n", rate); 7820 } 7821 return ack_rate; 7822} 7823 7824#define IEEE80211_OFDM_TXTIME(kbps, frmlen) \ 7825 (IEEE80211_OFDM_PREAMBLE_TIME + \ 7826 IEEE80211_OFDM_SIGNAL_TIME + \ 7827 (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME)) 7828 7829#define IEEE80211_OFDM_SYM_TIME 4 7830#define IEEE80211_OFDM_PREAMBLE_TIME 16 7831#define IEEE80211_OFDM_SIGNAL_EXT_TIME 6 7832#define IEEE80211_OFDM_SIGNAL_TIME 4 7833 7834#define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16 7835#define IEEE80211_OFDM_TAIL_NBITS 6 7836 7837#define IEEE80211_OFDM_NBITS(frmlen) \ 7838 (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \ 7839 ((frmlen) * NBBY) + \ 7840 IEEE80211_OFDM_TAIL_NBITS) 7841 7842#define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \ 7843 (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000) 7844 7845#define IEEE80211_OFDM_NSYMS(kbps, frmlen) \ 7846 howmany(IEEE80211_OFDM_NBITS((frmlen)), \ 7847 IEEE80211_OFDM_NBITS_PER_SYM((kbps))) 7848 7849#define IEEE80211_CCK_TXTIME(kbps, frmlen) \ 7850 (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps)) 7851 7852#define IEEE80211_CCK_PREAMBLE_LEN 144 7853#define IEEE80211_CCK_PLCP_HDR_TIME 48 7854#define IEEE80211_CCK_SHPREAMBLE_LEN 72 7855#define IEEE80211_CCK_SHPLCP_HDR_TIME 24 7856 7857#define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY) 7858 7859u_int16_t 7860bwi_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, u_int len, 7861 u_int8_t rs_rate, uint32_t flags) 7862{ 7863 enum bwi_modtype modtype; 7864 u_int16_t txtime; 7865 int rate; 7866 7867 rs_rate &= IEEE80211_RATE_VAL; 7868 7869 rate = rs_rate * 500; /* ieee80211 rate -> kbps */ 7870 7871 modtype = bwi_rate2modtype(rs_rate); 7872 if (modtype == IEEE80211_MODTYPE_OFDM) { 7873 /* 7874 * IEEE Std 802.11a-1999, page 37, equation (29) 7875 * IEEE Std 802.11g-2003, page 44, equation (42) 7876 */ 7877 txtime = IEEE80211_OFDM_TXTIME(rate, len); 7878 if (ic->ic_curmode == IEEE80211_MODE_11G) 7879 txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME; 7880 } else { 7881 /* 7882 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4 7883 * IEEE Std 802.11g-2003, page 45, equation (43) 7884 */ 7885 if (modtype == IEEE80211_MODTYPE_PBCC) 7886 ++len; 7887 txtime = IEEE80211_CCK_TXTIME(rate, len); 7888 7889 /* 7890 * Short preamble is not applicable for DS 1Mbits/s 7891 */ 7892 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) { 7893 txtime += IEEE80211_CCK_SHPREAMBLE_LEN + 7894 IEEE80211_CCK_SHPLCP_HDR_TIME; 7895 } else { 7896 txtime += IEEE80211_CCK_PREAMBLE_LEN + 7897 IEEE80211_CCK_PLCP_HDR_TIME; 7898 } 7899 } 7900 return txtime; 7901} 7902 7903int 7904bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, 7905 struct ieee80211_node *ni) 7906{ 7907 DPRINTF(2, "%s\n", __func__); 7908 7909 struct ieee80211com *ic = &sc->sc_ic; 7910 struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; 7911 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 7912 struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; 7913 struct bwi_mac *mac; 7914 struct bwi_txbuf_hdr *hdr; 7915 struct ieee80211_frame *wh; 7916 uint8_t rate, rate_fb; 7917 uint32_t mac_ctrl; 7918 uint16_t phy_ctrl; 7919 bus_addr_t paddr; 7920 int pkt_len, error; 7921#if 0 7922 const uint8_t *p; 7923 int i; 7924#endif 7925 7926 KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7927 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7928 7929 wh = mtod(m, struct ieee80211_frame *); 7930 7931 /* Get 802.11 frame len before prepending TX header */ 7932 pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN; 7933 7934 /* 7935 * Find TX rate 7936 */ 7937 bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx)); 7938 if (ni != NULL) { 7939 if (ic->ic_fixed_rate != -1) { 7940 rate = ic->ic_sup_rates[ic->ic_curmode]. 7941 rs_rates[ic->ic_fixed_rate]; 7942 } else { 7943 /* TODO: TX rate control */ 7944 rate = rate_fb = (1 * 2); 7945 } 7946 } else { 7947 /* Fixed at 1Mbytes/s for mgt frames */ 7948 rate = rate_fb = (1 * 2); 7949 } 7950 7951 rate &= IEEE80211_RATE_VAL; 7952 7953 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 7954 rate = rate_fb = (1 * 2); 7955 7956 if (rate == 0 || rate_fb == 0) { 7957 DPRINTF(1, "%s: invalid rate %u or fallback rate %u", 7958 sc->sc_dev.dv_xname, rate, rate_fb); 7959 rate = rate_fb = (1 * 2); /* Force 1Mbytes/s */ 7960 } 7961 7962#if NBPFILTER > 0 7963 /* TX radio tap */ 7964 if (sc->sc_drvbpf != NULL) { 7965 struct mbuf mb; 7966 struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap; 7967 7968 tap->wt_flags = 0; 7969 tap->wt_rate = rate; 7970 tap->wt_chan_freq = 7971 htole16(ic->ic_bss->ni_chan->ic_freq); 7972 tap->wt_chan_flags = 7973 htole16(ic->ic_bss->ni_chan->ic_flags); 7974 7975 mb.m_data = (caddr_t)tap; 7976 mb.m_len = sc->sc_txtap_len; 7977 mb.m_next = m; 7978 mb.m_nextpkt = NULL; 7979 mb.m_type = 0; 7980 mb.m_flags = 0; 7981 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT); 7982 } 7983#endif 7984 7985 /* 7986 * Setup the embedded TX header 7987 */ 7988 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT); 7989 if (m == NULL) { 7990 DPRINTF(1, "%s: prepend TX header failed\n", 7991 sc->sc_dev.dv_xname); 7992 return (ENOBUFS); 7993 } 7994 hdr = mtod(m, struct bwi_txbuf_hdr *); 7995 7996 bzero(hdr, sizeof(*hdr)); 7997 7998 bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc)); 7999 bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1)); 8000 8001 if (ni != NULL && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { 8002 uint16_t dur; 8003 uint8_t ack_rate; 8004 8005 ack_rate = bwi_ack_rate(ni, rate_fb); 8006 dur = bwi_txtime(ic, ni, 8007 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, 8008 ack_rate, ic->ic_flags & ~IEEE80211_F_SHPREAMBLE); 8009 8010 hdr->txh_fb_duration = htole16(dur); 8011 } 8012 8013 hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) | 8014 __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK); 8015 8016 bwi_plcp_header(hdr->txh_plcp, pkt_len, rate); 8017 bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate_fb); 8018 8019 phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode, 8020 BWI_TXH_PHY_C_ANTMODE_MASK); 8021 if (bwi_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) 8022 phy_ctrl |= BWI_TXH_PHY_C_OFDM; 8023 else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1)) 8024 phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE; 8025 8026 mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG; 8027 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) 8028 mac_ctrl |= BWI_TXH_MAC_C_ACK; 8029 if (bwi_rate2modtype(rate_fb) == IEEE80211_MODTYPE_OFDM) 8030 mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM; 8031 8032 hdr->txh_mac_ctrl = htole32(mac_ctrl); 8033 hdr->txh_phy_ctrl = htole16(phy_ctrl); 8034 8035 /* Catch any further usage */ 8036 hdr = NULL; 8037 wh = NULL; 8038 8039 /* DMA load */ 8040 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 8041 BUS_DMA_NOWAIT); 8042 if (error && error != EFBIG) { 8043 DPRINTF(1, "%s: can't load TX buffer (1) %d\n", 8044 sc->sc_dev.dv_xname, error); 8045 goto back; 8046 } 8047 8048 if (error) { /* error == EFBIG */ 8049 struct mbuf *m_new; 8050 8051 error = 0; 8052 8053 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 8054 if (m_new == NULL) { 8055 m_freem(m); 8056 error = ENOBUFS; 8057 printf("%s: can't defrag TX buffer\n", 8058 sc->sc_dev.dv_xname); 8059 goto back; 8060 } 8061 8062 M_DUP_PKTHDR(m_new, m); 8063 if (m->m_pkthdr.len > MHLEN) { 8064 MCLGET(m_new, M_DONTWAIT); 8065 if (!(m_new->m_flags & M_EXT)) { 8066 m_freem(m); 8067 m_freem(m_new); 8068 error = ENOBUFS; 8069 } 8070 } 8071 8072 if (error) { 8073 printf("%s: can't defrag TX buffer\n", 8074 sc->sc_dev.dv_xname); 8075 goto back; 8076 } 8077 8078 m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t)); 8079 m_freem(m); 8080 m_new->m_len = m_new->m_pkthdr.len; 8081 m = m_new; 8082 8083 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 8084 BUS_DMA_NOWAIT); 8085 if (error) { 8086 DPRINTF(1, "%s: can't load TX buffer (2) %d\n", 8087 sc->sc_dev.dv_xname, error); 8088 goto back; 8089 } 8090 } 8091 error = 0; 8092 8093 bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0, 8094 tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8095 8096 tb->tb_mbuf = m; 8097 tb->tb_ni = ni; 8098 8099#if 0 8100 p = mtod(m, const uint8_t *); 8101 for (i = 0; i < m->m_pkthdr.len; ++i) { 8102 if (i != 0 && i % 8 == 0) 8103 printf("\n"); 8104 printf("%02x ", p[i]); 8105 } 8106 printf("\n"); 8107 8108 DPRINTF(1, "%s: idx %d, pkt_len %d, buflen %d\n", 8109 sc->sc_dev.dv_xname, idx, pkt_len, m->m_pkthdr.len); 8110#endif 8111 8112 /* Setup TX descriptor */ 8113 paddr = tb->tb_dmap->dm_segs[0].ds_addr; 8114 sc->sc_setup_txdesc(sc, rd, idx, paddr, m->m_pkthdr.len); 8115 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8116 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8117 8118 /* Kick start */ 8119 sc->sc_start_tx(sc, rd->rdata_txrx_ctrl, idx); 8120 8121back: 8122 if (error) 8123 m_freem(m); 8124 return (error); 8125} 8126 8127void 8128bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 8129{ 8130 idx = (idx + 1) % BWI_TX_NDESC; 8131 CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX, 8132 idx * sizeof(struct bwi_desc32)); 8133} 8134 8135void 8136bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 8137{ 8138 /* TODO:64 */ 8139} 8140 8141void 8142bwi_txeof_status32(struct bwi_softc *sc) 8143{ 8144 struct ifnet *ifp = &sc->sc_ic.ic_if; 8145 uint32_t val, ctrl_base; 8146 int end_idx; 8147 8148 ctrl_base = sc->sc_txstats->stats_ctrl_base; 8149 8150 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS); 8151 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 8152 sizeof(struct bwi_desc32); 8153 8154 bwi_txeof_status(sc, end_idx); 8155 8156 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 8157 end_idx * sizeof(struct bwi_desc32)); 8158 8159 if ((ifp->if_flags & IFF_OACTIVE) == 0) 8160 ifp->if_start(ifp); 8161} 8162 8163void 8164bwi_txeof_status64(struct bwi_softc *sc) 8165{ 8166 /* TODO:64 */ 8167} 8168 8169void 8170_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id) 8171{ 8172 struct ieee80211com *ic = &sc->sc_ic; 8173 struct ifnet *ifp = &sc->sc_ic.ic_if; 8174 struct bwi_txbuf_data *tbd; 8175 struct bwi_txbuf *tb; 8176 int ring_idx, buf_idx; 8177 8178 if (tx_id == 0) { 8179 DPRINTF(1, "%s: zero tx id\n", sc->sc_dev.dv_xname); 8180 return; 8181 } 8182 8183 ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK); 8184 buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK); 8185 8186 KKASSERT(ring_idx == BWI_TX_DATA_RING); 8187 KKASSERT(buf_idx < BWI_TX_NDESC); 8188#if 0 8189 DPRINTF(1, "%s: txeof idx %d\n", sc->sc_dev.dv_xname, buf_idx); 8190#endif 8191 tbd = &sc->sc_tx_bdata[ring_idx]; 8192 KKASSERT(tbd->tbd_used > 0); 8193 tbd->tbd_used--; 8194 8195 tb = &tbd->tbd_buf[buf_idx]; 8196 8197 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 8198 m_freem(tb->tb_mbuf); 8199 tb->tb_mbuf = NULL; 8200 8201 if (tb->tb_ni != NULL) { 8202 ieee80211_release_node(ic, tb->tb_ni); 8203 tb->tb_ni = NULL; 8204 } 8205 8206 if (tbd->tbd_used == 0) 8207 sc->sc_tx_timer = 0; 8208 8209 ifp->if_flags &= ~IFF_OACTIVE; 8210} 8211 8212void 8213bwi_txeof_status(struct bwi_softc *sc, int end_idx) 8214{ 8215 struct bwi_txstats_data *st = sc->sc_txstats; 8216 int idx; 8217 8218 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 8219 st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 8220 8221 idx = st->stats_idx; 8222 while (idx != end_idx) { 8223 _bwi_txeof(sc, letoh16(st->stats[idx].txs_id)); 8224 idx = (idx + 1) % BWI_TXSTATS_NDESC; 8225 } 8226 st->stats_idx = idx; 8227} 8228 8229void 8230bwi_txeof(struct bwi_softc *sc) 8231{ 8232 struct ifnet *ifp = &sc->sc_ic.ic_if; 8233 8234 for (;;) { 8235 uint32_t tx_status0, tx_status1; 8236 uint16_t tx_id, tx_info; 8237 8238 tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0); 8239 if (tx_status0 == 0) 8240 break; 8241 tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS_1); 8242 8243 tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK); 8244 tx_info = BWI_TXSTATUS_0_INFO(tx_status0); 8245 8246 if (tx_info & 0x30) /* XXX */ 8247 continue; 8248 8249 _bwi_txeof(sc, tx_id); 8250 } 8251 8252 if ((ifp->if_flags & IFF_OACTIVE) == 0) 8253 ifp->if_start(ifp); 8254} 8255 8256int 8257bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) 8258{ 8259 bwi_power_on(sc, 1); 8260 8261 return (bwi_set_clock_mode(sc, clk_mode)); 8262} 8263 8264void 8265bwi_bbp_power_off(struct bwi_softc *sc) 8266{ 8267 bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW); 8268 bwi_power_off(sc, 1); 8269} 8270 8271int 8272bwi_get_pwron_delay(struct bwi_softc *sc) 8273{ 8274 struct bwi_regwin *com, *old; 8275 struct bwi_clock_freq freq; 8276 uint32_t val; 8277 int error; 8278 8279 com = &sc->sc_com_regwin; 8280 KKASSERT(BWI_REGWIN_EXIST(com)); 8281 8282 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0) 8283 return (0); 8284 8285 error = bwi_regwin_switch(sc, com, &old); 8286 if (error) 8287 return (error); 8288 8289 bwi_get_clock_freq(sc, &freq); 8290 8291 val = CSR_READ_4(sc, BWI_PLL_ON_DELAY); 8292 sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min); 8293 DPRINTF(1, "%s: power on delay %u\n", 8294 sc->sc_dev.dv_xname, sc->sc_pwron_delay); 8295 8296 return (bwi_regwin_switch(sc, old, NULL)); 8297} 8298 8299int 8300bwi_bus_attach(struct bwi_softc *sc) 8301{ 8302 struct bwi_regwin *bus, *old; 8303 int error; 8304 8305 bus = &sc->sc_bus_regwin; 8306 8307 error = bwi_regwin_switch(sc, bus, &old); 8308 if (error) 8309 return (error); 8310 8311 if (!bwi_regwin_is_enabled(sc, bus)) 8312 bwi_regwin_enable(sc, bus, 0); 8313 8314 /* Disable interripts */ 8315 CSR_WRITE_4(sc, BWI_INTRVEC, 0); 8316 8317 return (bwi_regwin_switch(sc, old, NULL)); 8318} 8319 8320const char * 8321bwi_regwin_name(const struct bwi_regwin *rw) 8322{ 8323 switch (rw->rw_type) { 8324 case BWI_REGWIN_T_COM: 8325 return ("COM"); 8326 case BWI_REGWIN_T_BUSPCI: 8327 return ("PCI"); 8328 case BWI_REGWIN_T_MAC: 8329 return ("MAC"); 8330 case BWI_REGWIN_T_BUSPCIE: 8331 return ("PCIE"); 8332 } 8333 panic("unknown regwin type 0x%04x\n", rw->rw_type); 8334 8335 return (NULL); 8336} 8337 8338uint32_t 8339bwi_regwin_disable_bits(struct bwi_softc *sc) 8340{ 8341 uint32_t busrev; 8342 8343 /* XXX cache this */ 8344 busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK); 8345 DPRINTF(1, "%s: bus rev %u\n", sc->sc_dev.dv_xname, busrev); 8346 8347 if (busrev == BWI_BUSREV_0) 8348 return (BWI_STATE_LO_DISABLE1); 8349 else if (busrev == BWI_BUSREV_1) 8350 return (BWI_STATE_LO_DISABLE2); 8351 else 8352 return ((BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2)); 8353} 8354 8355int 8356bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw) 8357{ 8358 uint32_t val, disable_bits; 8359 8360 disable_bits = bwi_regwin_disable_bits(sc); 8361 val = CSR_READ_4(sc, BWI_STATE_LO); 8362 8363 if ((val & (BWI_STATE_LO_CLOCK | 8364 BWI_STATE_LO_RESET | 8365 disable_bits)) == BWI_STATE_LO_CLOCK) { 8366 DPRINTF(1, "%s: %s is enabled\n", 8367 sc->sc_dev.dv_xname, bwi_regwin_name(rw)); 8368 return (1); 8369 } else { 8370 DPRINTF(1, "%s: %s is disabled\n", 8371 sc->sc_dev.dv_xname, bwi_regwin_name(rw)); 8372 return (0); 8373 } 8374} 8375 8376void 8377bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 8378{ 8379 uint32_t state_lo, disable_bits; 8380 int i; 8381 8382 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 8383 8384 /* 8385 * If current regwin is in 'reset' state, it was already disabled. 8386 */ 8387 if (state_lo & BWI_STATE_LO_RESET) { 8388 DPRINTF(1, "%s: %s was already disabled\n", 8389 sc->sc_dev.dv_xname, bwi_regwin_name(rw)); 8390 return; 8391 } 8392 8393 disable_bits = bwi_regwin_disable_bits(sc); 8394 8395 /* 8396 * Disable normal clock 8397 */ 8398 state_lo = BWI_STATE_LO_CLOCK | disable_bits; 8399 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 8400 8401 /* 8402 * Wait until normal clock is disabled 8403 */ 8404#define NRETRY 1000 8405 for (i = 0; i < NRETRY; ++i) { 8406 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 8407 if (state_lo & disable_bits) 8408 break; 8409 DELAY(10); 8410 } 8411 if (i == NRETRY) { 8412 DPRINTF(1, "%s: %s disable clock timeout\n", 8413 sc->sc_dev.dv_xname, bwi_regwin_name(rw)); 8414 } 8415 8416 for (i = 0; i < NRETRY; ++i) { 8417 uint32_t state_hi; 8418 8419 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 8420 if ((state_hi & BWI_STATE_HI_BUSY) == 0) 8421 break; 8422 DELAY(10); 8423 } 8424 if (i == NRETRY) { 8425 DPRINTF(1, "%s: %s wait BUSY unset timeout\n", 8426 sc->sc_dev.dv_xname, bwi_regwin_name(rw)); 8427 } 8428#undef NRETRY 8429 8430 /* 8431 * Reset and disable regwin with gated clock 8432 */ 8433 state_lo = BWI_STATE_LO_RESET | disable_bits | 8434 BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK | 8435 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 8436 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 8437 8438 /* Flush pending bus write */ 8439 CSR_READ_4(sc, BWI_STATE_LO); 8440 DELAY(1); 8441 8442 /* Reset and disable regwin */ 8443 state_lo = BWI_STATE_LO_RESET | disable_bits | 8444 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 8445 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 8446 8447 /* Flush pending bus write */ 8448 CSR_READ_4(sc, BWI_STATE_LO); 8449 DELAY(1); 8450} 8451 8452void 8453bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 8454{ 8455 uint32_t state_lo, state_hi, imstate; 8456 8457 bwi_regwin_disable(sc, rw, flags); 8458 8459 /* Reset regwin with gated clock */ 8460 state_lo = BWI_STATE_LO_RESET | 8461 BWI_STATE_LO_CLOCK | 8462 BWI_STATE_LO_GATED_CLOCK | 8463 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 8464 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 8465 8466 /* Flush pending bus write */ 8467 CSR_READ_4(sc, BWI_STATE_LO); 8468 DELAY(1); 8469 8470 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 8471 if (state_hi & BWI_STATE_HI_SERROR) 8472 CSR_WRITE_4(sc, BWI_STATE_HI, 0); 8473 8474 imstate = CSR_READ_4(sc, BWI_IMSTATE); 8475 if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) { 8476 imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT); 8477 CSR_WRITE_4(sc, BWI_IMSTATE, imstate); 8478 } 8479 8480 /* Enable regwin with gated clock */ 8481 state_lo = BWI_STATE_LO_CLOCK | 8482 BWI_STATE_LO_GATED_CLOCK | 8483 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 8484 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 8485 8486 /* Flush pending bus write */ 8487 CSR_READ_4(sc, BWI_STATE_LO); 8488 DELAY(1); 8489 8490 /* Enable regwin with normal clock */ 8491 state_lo = BWI_STATE_LO_CLOCK | 8492 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 8493 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 8494 8495 /* Flush pending bus write */ 8496 CSR_READ_4(sc, BWI_STATE_LO); 8497 DELAY(1); 8498} 8499 8500void 8501bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid) 8502{ 8503 struct ieee80211com *ic = &sc->sc_ic; 8504 struct bwi_mac *mac; 8505 struct bwi_myaddr_bssid buf; 8506 const uint8_t *p; 8507 uint32_t val; 8508 int n, i; 8509 8510 KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 8511 mac = (struct bwi_mac *)sc->sc_cur_regwin; 8512 8513 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid); 8514 8515 bcopy(ic->ic_myaddr, buf.myaddr, sizeof(buf.myaddr)); 8516 bcopy(bssid, buf.bssid, sizeof(buf.bssid)); 8517 8518 n = sizeof(buf) / sizeof(val); 8519 p = (const uint8_t *)&buf; 8520 for (i = 0; i < n; ++i) { 8521 int j; 8522 8523 val = 0; 8524 for (j = 0; j < sizeof(val); ++j) 8525 val |= ((uint32_t)(*p++)) << (j * 8); 8526 8527 TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val); 8528 } 8529} 8530 8531void 8532bwi_updateslot(struct ieee80211com *ic) 8533{ 8534 struct bwi_softc *sc = ic->ic_if.if_softc; 8535 struct bwi_mac *mac; 8536 struct ifnet *ifp = &ic->ic_if; 8537 8538 if ((ifp->if_flags & IFF_RUNNING) == 0) 8539 return; 8540 8541 DPRINTF(2, "%s\n", __func__); 8542 8543 KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 8544 mac = (struct bwi_mac *)sc->sc_cur_regwin; 8545 8546 bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT)); 8547} 8548 8549void 8550bwi_calibrate(void *xsc) 8551{ 8552 struct bwi_softc *sc = xsc; 8553 struct ieee80211com *ic = &sc->sc_ic; 8554 int s; 8555 8556 s = splnet(); 8557 8558 if (ic->ic_state == IEEE80211_S_RUN) { 8559 struct bwi_mac *mac; 8560 8561 KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 8562 mac = (struct bwi_mac *)sc->sc_cur_regwin; 8563 8564 if (ic->ic_opmode != IEEE80211_M_MONITOR) 8565 bwi_mac_calibrate_txpower(mac); 8566 8567 /* XXX 15 seconds */ 8568 timeout_add(&sc->sc_calib_ch, hz * 15); 8569 } 8570 8571 splx(s); 8572} 8573