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