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