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