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