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