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