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