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