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