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