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