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