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