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