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