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