Home | History | Annotate | Line # | Download | only in ic
bwi.c revision 1.25
      1 /*	$NetBSD: bwi.c,v 1.24 2014/02/25 18:30:09 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.24 2014/02/25 18:30:09 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 /* XXX end porting goop */
    123 
    124 /* MAC */
    125 struct bwi_retry_lim {
    126 	uint16_t	shretry;
    127 	uint16_t	shretry_fb;
    128 	uint16_t	lgretry;
    129 	uint16_t	lgretry_fb;
    130 };
    131 
    132 struct bwi_clock_freq {
    133 	uint		clkfreq_min;
    134 	uint		clkfreq_max;
    135 };
    136 
    137 /* XXX does not belong here */
    138 struct ieee80211_ds_plcp_hdr {
    139 	uint8_t		i_signal;
    140 	uint8_t		i_service;
    141 	uint16_t	i_length;
    142 	uint16_t	i_crc;
    143 } __packed;
    144 
    145 static void	 bwi_sysctlattach(struct bwi_softc *);
    146 
    147 /* MAC */
    148 static void	 bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t);
    149 static void	 bwi_hostflags_write(struct bwi_mac *, uint64_t);
    150 static uint64_t	 bwi_hostflags_read(struct bwi_mac *);
    151 static uint16_t	 bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t);
    152 static uint32_t	 bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t);
    153 static void	 bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t,
    154 		     uint16_t);
    155 static void	 bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t,
    156 		     uint32_t);
    157 static int	 bwi_mac_lateattach(struct bwi_mac *);
    158 static int	 bwi_mac_init(struct bwi_mac *);
    159 static void	 bwi_mac_reset(struct bwi_mac *, int);
    160 static void	 bwi_mac_set_tpctl_11bg(struct bwi_mac *,
    161 		     const struct bwi_tpctl *);
    162 static int	 bwi_mac_test(struct bwi_mac *);
    163 static void	 bwi_mac_setup_tpctl(struct bwi_mac *);
    164 static void	 bwi_mac_dummy_xmit(struct bwi_mac *);
    165 static void	 bwi_mac_init_tpctl_11bg(struct bwi_mac *);
    166 static void	 bwi_mac_detach(struct bwi_mac *);
    167 static int	 bwi_mac_fw_alloc(struct bwi_mac *);
    168 static void	 bwi_mac_fw_free(struct bwi_mac *);
    169 static int	 bwi_mac_fw_image_alloc(struct bwi_mac *, const char *,
    170     		     int idx, struct bwi_fw_image *, uint8_t);
    171 static void	 bwi_mac_fw_image_free(struct bwi_mac *, struct bwi_fw_image *);
    172 static int	 bwi_mac_fw_load(struct bwi_mac *);
    173 static int	 bwi_mac_gpio_init(struct bwi_mac *);
    174 static int	 bwi_mac_gpio_fini(struct bwi_mac *);
    175 static int	 bwi_mac_fw_load_iv(struct bwi_mac *,
    176 		     const struct bwi_fw_image *);
    177 static int	 bwi_mac_fw_init(struct bwi_mac *);
    178 static void	 bwi_mac_opmode_init(struct bwi_mac *);
    179 static void	 bwi_mac_hostflags_init(struct bwi_mac *);
    180 static void	 bwi_mac_bss_param_init(struct bwi_mac *);
    181 static void	 bwi_mac_set_retry_lim(struct bwi_mac *,
    182 		     const struct bwi_retry_lim *);
    183 static void	 bwi_mac_set_ackrates(struct bwi_mac *,
    184 		     const struct ieee80211_rateset *);
    185 static int	 bwi_mac_start(struct bwi_mac *);
    186 static int	 bwi_mac_stop(struct bwi_mac *);
    187 static int	 bwi_mac_config_ps(struct bwi_mac *);
    188 static void	 bwi_mac_reset_hwkeys(struct bwi_mac *);
    189 static void	 bwi_mac_shutdown(struct bwi_mac *);
    190 static int	 bwi_mac_get_property(struct bwi_mac *);
    191 static void	 bwi_mac_updateslot(struct bwi_mac *, int);
    192 static int	 bwi_mac_attach(struct bwi_softc *, int, uint8_t);
    193 static void	 bwi_mac_balance_atten(int *, int *);
    194 static void	 bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
    195 static void	 bwi_mac_calibrate_txpower(struct bwi_mac *,
    196 		     enum bwi_txpwrcb_type);
    197 static void	 bwi_mac_lock(struct bwi_mac *);
    198 static void	 bwi_mac_unlock(struct bwi_mac *);
    199 static void	 bwi_mac_set_promisc(struct bwi_mac *, int);
    200 
    201 /* PHY */
    202 static void	 bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t);
    203 static uint16_t	 bwi_phy_read(struct bwi_mac *, uint16_t);
    204 static int	 bwi_phy_attach(struct bwi_mac *);
    205 static void	 bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t);
    206 static int	 bwi_phy_calibrate(struct bwi_mac *);
    207 static void	 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
    208 static void	 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
    209 static void	 bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t);
    210 static int16_t	 bwi_nrssi_read(struct bwi_mac *, uint16_t);
    211 static void	 bwi_phy_init_11a(struct bwi_mac *);
    212 static void	 bwi_phy_init_11g(struct bwi_mac *);
    213 static void	 bwi_phy_init_11b_rev2(struct bwi_mac *);
    214 static void	 bwi_phy_init_11b_rev4(struct bwi_mac *);
    215 static void	 bwi_phy_init_11b_rev5(struct bwi_mac *);
    216 static void	 bwi_phy_init_11b_rev6(struct bwi_mac *);
    217 static void	 bwi_phy_config_11g(struct bwi_mac *);
    218 static void	 bwi_phy_config_agc(struct bwi_mac *);
    219 static void	 bwi_set_gains(struct bwi_mac *, const struct bwi_gains *);
    220 static void	 bwi_phy_clear_state(struct bwi_phy *);
    221 
    222 /* RF */
    223 static int16_t	 bwi_nrssi_11g(struct bwi_mac *);
    224 static struct bwi_rf_lo
    225 		*bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t);
    226 static int	 bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *);
    227 static void	 bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t);
    228 static uint16_t	 bwi_rf_read(struct bwi_mac *, uint16_t);
    229 static int	 bwi_rf_attach(struct bwi_mac *);
    230 static void	 bwi_rf_set_chan(struct bwi_mac *, uint, int);
    231 static void	 bwi_rf_get_gains(struct bwi_mac *);
    232 static void	 bwi_rf_init(struct bwi_mac *);
    233 static void	 bwi_rf_off_11a(struct bwi_mac *);
    234 static void	 bwi_rf_off_11bg(struct bwi_mac *);
    235 static void	 bwi_rf_off_11g_rev5(struct bwi_mac *);
    236 static void	 bwi_rf_workaround(struct bwi_mac *, uint);
    237 static struct bwi_rf_lo
    238 		*bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *);
    239 static void	 bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *);
    240 static void	 bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
    241 static int	 bwi_rf_gain_max_reached(struct bwi_mac *, int);
    242 static uint16_t	 bwi_bitswap4(uint16_t);
    243 static uint16_t	 bwi_phy812_value(struct bwi_mac *, uint16_t);
    244 static void	 bwi_rf_init_bcm2050(struct bwi_mac *);
    245 static uint16_t	 bwi_rf_calibval(struct bwi_mac *);
    246 static int32_t	 _bwi_adjust_devide(int32_t, int32_t);
    247 static int	 bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
    248 static int	 bwi_rf_map_txpower(struct bwi_mac *);
    249 static void	 bwi_rf_lo_update_11g(struct bwi_mac *);
    250 static uint32_t	 bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
    251 static uint16_t	 bwi_rf_get_tp_ctrl2(struct bwi_mac *);
    252 static uint8_t	 _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t);
    253 static void	 bwi_rf_lo_measure_11g(struct bwi_mac *,
    254 		     const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
    255 static void	 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
    256 static void	 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
    257 static void	 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
    258 static void	 bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
    259 static void	 bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t);
    260 static void	 bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
    261 static int32_t	 _nrssi_threshold(const struct bwi_rf *, int32_t);
    262 static void	 bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
    263 static void	 bwi_rf_clear_tssi(struct bwi_mac *);
    264 static void	 bwi_rf_clear_state(struct bwi_rf *);
    265 static void	 bwi_rf_on_11a(struct bwi_mac *);
    266 static void	 bwi_rf_on_11bg(struct bwi_mac *);
    267 static void	 bwi_rf_set_ant_mode(struct bwi_mac *, int);
    268 static int	 bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t);
    269 static int	 bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *);
    270 static int	 bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
    271 		     const struct bwi_rxbuf_hdr *);
    272 static int	 bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
    273 		     const struct bwi_rxbuf_hdr *);
    274 static int	 bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
    275 		     const struct bwi_rxbuf_hdr *);
    276 static uint16_t	 bwi_rf_lo_measure_11b(struct bwi_mac *);
    277 static void	 bwi_rf_lo_update_11b(struct bwi_mac *);
    278 
    279 /* INTERFACE */
    280 static uint16_t	 bwi_read_sprom(struct bwi_softc *, uint16_t);
    281 static void	 bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int,
    282 		     int, bus_addr_t, int, int);
    283 static void	 bwi_power_on(struct bwi_softc *, int);
    284 static int	 bwi_power_off(struct bwi_softc *, int);
    285 static int	 bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *,
    286 		     struct bwi_regwin **);
    287 static int	 bwi_regwin_select(struct bwi_softc *, int);
    288 static void	 bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
    289 static void	 bwi_led_attach(struct bwi_softc *);
    290 static void	 bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
    291 static uint16_t	 bwi_led_onoff(const struct bwi_led *, uint16_t, int);
    292 static void	 bwi_led_event(struct bwi_softc *, int);
    293 static void	 bwi_led_blink_start(struct bwi_softc *, int, int);
    294 static void	 bwi_led_blink_next(void *);
    295 static void	 bwi_led_blink_end(void *);
    296 static int	 bwi_bbp_attach(struct bwi_softc *);
    297 static int	 bwi_bus_init(struct bwi_softc *, struct bwi_mac *);
    298 static void	 bwi_get_card_flags(struct bwi_softc *);
    299 static void	 bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
    300 static void	 bwi_get_clock_freq(struct bwi_softc *,
    301 		     struct bwi_clock_freq *);
    302 static int	 bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
    303 static int	 bwi_set_clock_delay(struct bwi_softc *);
    304 static int	 bwi_init(struct ifnet *);
    305 static void	 bwi_init_statechg(struct bwi_softc *, int);
    306 static int	 bwi_ioctl(struct ifnet *, u_long, void *);
    307 static void	 bwi_start(struct ifnet *);
    308 static void	 bwi_watchdog(struct ifnet *);
    309 static void	 bwi_stop(struct ifnet *, int);
    310 static void	 bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state);
    311 static int	 bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
    312 static int	 bwi_media_change(struct ifnet *);
    313 /* [TRC: XXX amrr] */
    314 static void	 bwi_iter_func(void *, struct ieee80211_node *);
    315 static void	 bwi_amrr_timeout(void *);
    316 static void	 bwi_newassoc(struct ieee80211_node *, int);
    317 static struct ieee80211_node *
    318 		 bwi_node_alloc(struct ieee80211_node_table *);
    319 static int	 bwi_dma_alloc(struct bwi_softc *);
    320 static void	 bwi_dma_free(struct bwi_softc *);
    321 static void	 bwi_ring_data_free(struct bwi_ring_data *, struct bwi_softc *);
    322 static int	 bwi_dma_ring_alloc(struct bwi_softc *,
    323 		     struct bwi_ring_data *, bus_size_t, uint32_t);
    324 static int	 bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t,
    325 		     bus_size_t);
    326 static void	 bwi_dma_txstats_free(struct bwi_softc *);
    327 static int	 bwi_dma_mbuf_create(struct bwi_softc *);
    328 static void	 bwi_dma_mbuf_destroy(struct bwi_softc *, int, int);
    329 static void	 bwi_enable_intrs(struct bwi_softc *, uint32_t);
    330 static void	 bwi_disable_intrs(struct bwi_softc *, uint32_t);
    331 static int	 bwi_init_tx_ring32(struct bwi_softc *, int);
    332 static void	 bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t,
    333 		     bus_addr_t, int, int);
    334 static int	 bwi_init_rx_ring32(struct bwi_softc *);
    335 static int	 bwi_init_txstats32(struct bwi_softc *);
    336 static void	 bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
    337 static void	 bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
    338 		     int, bus_addr_t, int);
    339 static int	 bwi_init_tx_ring64(struct bwi_softc *, int);
    340 static int	 bwi_init_rx_ring64(struct bwi_softc *);
    341 static int	 bwi_init_txstats64(struct bwi_softc *);
    342 static void	 bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int);
    343 static void	 bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *,
    344 		     int, bus_addr_t, int);
    345 static int	 bwi_newbuf(struct bwi_softc *, int, int);
    346 static void	 bwi_set_addr_filter(struct bwi_softc *, uint16_t,
    347 		     const uint8_t *);
    348 static int	 bwi_set_chan(struct bwi_softc *, struct ieee80211_channel *);
    349 static void	 bwi_next_scan(void *);
    350 static int	 bwi_rxeof(struct bwi_softc *, int);
    351 static int	 bwi_rxeof32(struct bwi_softc *);
    352 static int	 bwi_rxeof64(struct bwi_softc *);
    353 static void	 bwi_reset_rx_ring32(struct bwi_softc *, uint32_t);
    354 static void	 bwi_free_txstats32(struct bwi_softc *);
    355 static void	 bwi_free_rx_ring32(struct bwi_softc *);
    356 static void	 bwi_free_tx_ring32(struct bwi_softc *, int);
    357 static void	 bwi_free_txstats64(struct bwi_softc *);
    358 static void	 bwi_free_rx_ring64(struct bwi_softc *);
    359 static void	 bwi_free_tx_ring64(struct bwi_softc *, int);
    360 static uint8_t	 bwi_ieee80211_rate2plcp(uint8_t rate, enum ieee80211_phymode);
    361 static uint8_t	 bwi_ieee80211_plcp2rate(uint8_t rate, enum ieee80211_phymode);
    362 static enum bwi_ieee80211_modtype
    363 		 bwi_ieee80211_rate2modtype(uint8_t rate);
    364 static uint8_t	 bwi_ofdm_plcp2rate(const void *);
    365 static uint8_t	 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
    366 static void	 bwi_ofdm_plcp_header(uint32_t *, int, uint8_t);
    367 static void	 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int,
    368 		     uint8_t);
    369 static void	 bwi_plcp_header(void *, int, uint8_t);
    370 static int	 bwi_encap(struct bwi_softc *, int, struct mbuf *,
    371 		     struct ieee80211_node **, int);
    372 static void	 bwi_start_tx32(struct bwi_softc *, uint32_t, int);
    373 static void	 bwi_start_tx64(struct bwi_softc *, uint32_t, int);
    374 static void	 bwi_txeof_status32(struct bwi_softc *);
    375 static void	 bwi_txeof_status64(struct bwi_softc *);
    376 static void	 _bwi_txeof(struct bwi_softc *, uint16_t);
    377 static void	 bwi_txeof_status(struct bwi_softc *, int);
    378 static void	 bwi_txeof(struct bwi_softc *);
    379 static int	 bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode);
    380 static void	 bwi_bbp_power_off(struct bwi_softc *);
    381 static int	 bwi_get_pwron_delay(struct bwi_softc *sc);
    382 static int	 bwi_bus_attach(struct bwi_softc *);
    383 static const char
    384 		*bwi_regwin_name(const struct bwi_regwin *);
    385 static int	 bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *);
    386 static uint32_t	 bwi_regwin_disable_bits(struct bwi_softc *);
    387 static void	 bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *,
    388 		     uint32_t);
    389 static void	 bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *,
    390 		     uint32_t);
    391 static void	 bwi_set_bssid(struct bwi_softc *, const uint8_t *);
    392 static void	 bwi_updateslot(struct ifnet *);
    393 static void	 bwi_calibrate(void *);
    394 static int	 bwi_calc_rssi(struct bwi_softc *,
    395 		     const struct bwi_rxbuf_hdr *);
    396 static uint8_t	 bwi_ieee80211_ack_rate(struct ieee80211_node *, uint8_t);
    397 static uint16_t	 bwi_ieee80211_txtime(struct ieee80211com *,
    398 		     struct ieee80211_node *, uint, uint8_t, uint32_t);
    399 
    400 /* MAC */
    401 static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10, 12 };
    402 
    403 /* PHY */
    404 #define SUP_BPHY(num)	{ .rev = num, .init = bwi_phy_init_11b_rev##num }
    405 
    406 static const struct {
    407 	uint8_t	rev;
    408 	void	(*init)(struct bwi_mac *);
    409 } bwi_sup_bphy[] = {
    410 	SUP_BPHY(2),
    411 	SUP_BPHY(4),
    412 	SUP_BPHY(5),
    413 	SUP_BPHY(6)
    414 };
    415 
    416 #undef SUP_BPHY
    417 
    418 #define BWI_PHYTBL_WRSSI	0x1000
    419 #define BWI_PHYTBL_NOISE_SCALE	0x1400
    420 #define BWI_PHYTBL_NOISE	0x1800
    421 #define BWI_PHYTBL_ROTOR	0x2000
    422 #define BWI_PHYTBL_DELAY	0x2400
    423 #define BWI_PHYTBL_RSSI		0x4000
    424 #define BWI_PHYTBL_SIGMA_SQ	0x5000
    425 #define BWI_PHYTBL_WRSSI_REV1	0x5400
    426 #define BWI_PHYTBL_FREQ		0x5800
    427 
    428 static const uint16_t	bwi_phy_freq_11g_rev1[] =
    429 	{ BWI_PHY_FREQ_11G_REV1 };
    430 static const uint16_t	bwi_phy_noise_11g_rev1[] =
    431 	{ BWI_PHY_NOISE_11G_REV1 };
    432 static const uint16_t	bwi_phy_noise_11g[] =
    433 	{ BWI_PHY_NOISE_11G };
    434 static const uint32_t	bwi_phy_rotor_11g_rev1[] =
    435 	{ BWI_PHY_ROTOR_11G_REV1 };
    436 static const uint16_t	bwi_phy_noise_scale_11g_rev2[] =
    437 	{ BWI_PHY_NOISE_SCALE_11G_REV2 };
    438 static const uint16_t	bwi_phy_noise_scale_11g_rev7[] =
    439 	{ BWI_PHY_NOISE_SCALE_11G_REV7 };
    440 static const uint16_t	bwi_phy_noise_scale_11g[] =
    441 	{ BWI_PHY_NOISE_SCALE_11G };
    442 static const uint16_t	bwi_phy_sigma_sq_11g_rev2[] =
    443 	{ BWI_PHY_SIGMA_SQ_11G_REV2 };
    444 static const uint16_t	bwi_phy_sigma_sq_11g_rev7[] =
    445 	{ BWI_PHY_SIGMA_SQ_11G_REV7 };
    446 static const uint32_t	bwi_phy_delay_11g_rev1[] =
    447 	{ BWI_PHY_DELAY_11G_REV1 };
    448 
    449 /* RF */
    450 #define RF_LO_WRITE(mac, lo)	bwi_rf_lo_write((mac), (lo))
    451 
    452 #define BWI_RF_2GHZ_CHAN(chan) \
    453 	(ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
    454 
    455 #define BWI_DEFAULT_IDLE_TSSI	52
    456 
    457 struct rf_saveregs {
    458 	uint16_t	phy_01;
    459 	uint16_t	phy_03;
    460 	uint16_t	phy_0a;
    461 	uint16_t	phy_15;
    462 	uint16_t	phy_2a;
    463 	uint16_t	phy_30;
    464 	uint16_t	phy_35;
    465 	uint16_t	phy_60;
    466 	uint16_t	phy_429;
    467 	uint16_t	phy_802;
    468 	uint16_t	phy_811;
    469 	uint16_t	phy_812;
    470 	uint16_t	phy_814;
    471 	uint16_t	phy_815;
    472 
    473 	uint16_t	rf_43;
    474 	uint16_t	rf_52;
    475 	uint16_t	rf_7a;
    476 };
    477 
    478 #define SAVE_RF_REG(mac, regs, n)	(regs)->rf_##n = RF_READ((mac), 0x##n)
    479 #define RESTORE_RF_REG(mac, regs, n)	RF_WRITE((mac), 0x##n, (regs)->rf_##n)
    480 
    481 #define SAVE_PHY_REG(mac, regs, n)	(regs)->phy_##n = PHY_READ((mac), 0x##n)
    482 #define RESTORE_PHY_REG(mac, regs, n)	PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
    483 
    484 static const int8_t	bwi_txpower_map_11b[BWI_TSSI_MAX] =
    485 	{ BWI_TXPOWER_MAP_11B };
    486 static const int8_t	bwi_txpower_map_11g[BWI_TSSI_MAX] =
    487 	{ BWI_TXPOWER_MAP_11G };
    488 
    489 /* INTERFACE */
    490 
    491 struct bwi_myaddr_bssid {
    492 	uint8_t		myaddr[IEEE80211_ADDR_LEN];
    493 	uint8_t		bssid[IEEE80211_ADDR_LEN];
    494 } __packed;
    495 
    496 /* [TRC: XXX What are these about?] */
    497 
    498 #define IEEE80211_DS_PLCP_SERVICE_LOCKED	0x04
    499 #define IEEE80211_DS_PLCL_SERVICE_PBCC		0x08
    500 #define IEEE80211_DS_PLCP_SERVICE_LENEXT5	0x20
    501 #define IEEE80211_DS_PLCP_SERVICE_LENEXT6	0x40
    502 #define IEEE80211_DS_PLCP_SERVICE_LENEXT7	0x80
    503 
    504 static const struct {
    505 	uint16_t	did_min;
    506 	uint16_t	did_max;
    507 	uint16_t	bbp_id;
    508 } bwi_bbpid_map[] = {
    509 	{ 0x4301, 0x4301, 0x4301 },
    510 	{ 0x4305, 0x4307, 0x4307 },
    511 	{ 0x4403, 0x4403, 0x4402 },
    512 	{ 0x4610, 0x4615, 0x4610 },
    513 	{ 0x4710, 0x4715, 0x4710 },
    514 	{ 0x4720, 0x4725, 0x4309 }
    515 };
    516 
    517 static const struct {
    518 	uint16_t	bbp_id;
    519 	int		nregwin;
    520 } bwi_regwin_count[] = {
    521 	{ 0x4301, 5 },
    522 	{ 0x4306, 6 },
    523 	{ 0x4307, 5 },
    524 	{ 0x4310, 8 },
    525 	{ 0x4401, 3 },
    526 	{ 0x4402, 3 },
    527 	{ 0x4610, 9 },
    528 	{ 0x4704, 9 },
    529 	{ 0x4710, 9 },
    530 	{ 0x5365, 7 }
    531 };
    532 
    533 #define CLKSRC(src) 				\
    534 [BWI_CLKSRC_ ## src] = {			\
    535 	.freq_min = BWI_CLKSRC_ ##src## _FMIN,	\
    536 	.freq_max = BWI_CLKSRC_ ##src## _FMAX	\
    537 }
    538 
    539 static const struct {
    540 	uint	freq_min;
    541 	uint	freq_max;
    542 } bwi_clkfreq[BWI_CLKSRC_MAX] = {
    543 	CLKSRC(LP_OSC),
    544 	CLKSRC(CS_OSC),
    545 	CLKSRC(PCI)
    546 };
    547 
    548 #undef CLKSRC
    549 
    550 #define VENDOR_LED_ACT(vendor)				\
    551 {							\
    552 	.vid = PCI_VENDOR_##vendor,			\
    553 	.led_act = { BWI_VENDOR_LED_ACT_##vendor }	\
    554 }
    555 
    556 static const struct {
    557 	uint16_t	vid;
    558 	uint8_t		led_act[BWI_LED_MAX];
    559 } bwi_vendor_led_act[] = {
    560 	VENDOR_LED_ACT(COMPAQ),
    561 	VENDOR_LED_ACT(LINKSYS)
    562 };
    563 
    564 static const uint8_t bwi_default_led_act[BWI_LED_MAX] =
    565 	{ BWI_VENDOR_LED_ACT_DEFAULT };
    566 
    567 #undef VENDOR_LED_ACT
    568 
    569 static const struct {
    570 	int	on_dur;
    571 	int	off_dur;
    572 } bwi_led_duration[109] = {
    573 	[0]	= { 400, 100 },
    574 	[2]	= { 150, 75 },
    575 	[4]	= { 90, 45 },
    576 	[11]	= { 66, 34 },
    577 	[12]	= { 53, 26 },
    578 	[18]	= { 42, 21 },
    579 	[22]	= { 35, 17 },
    580 	[24]	= { 32, 16 },
    581 	[36]	= { 21, 10 },
    582 	[48]	= { 16, 8 },
    583 	[72]	= { 11, 5 },
    584 	[96]	= { 9, 4 },
    585 	[108]	= { 7, 3 }
    586 };
    587 
    588 /* [TRC: XXX Should this be zeroed?] */
    589 
    590 static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN];
    591 
    592 /* [TRC: Derived from DragonFly's src/sys/netproto/802_11/_ieee80211.h */
    593 
    594 enum bwi_ieee80211_modtype {
    595 	IEEE80211_MODTYPE_DS	= 0,	/* DS/CCK modulation */
    596 	IEEE80211_MODTYPE_PBCC	= 1,	/* PBCC modulation */
    597 	IEEE80211_MODTYPE_OFDM	= 2	/* OFDM modulation */
    598 };
    599 #define IEEE80211_MODTYPE_CCK   IEEE80211_MODTYPE_DS
    600 
    601 /*
    602  * Setup sysctl(3) MIB, hw.bwi.* and hw.bwiN.*
    603  */
    604 
    605 #ifdef BWI_DEBUG
    606 SYSCTL_SETUP(sysctl_bwi, "sysctl bwi(4) subtree setup")
    607 {
    608 	int rc;
    609 	const struct sysctlnode *rnode;
    610 	const struct sysctlnode *cnode;
    611 
    612 	if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
    613 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "bwi",
    614 	    SYSCTL_DESCR("bwi global controls"),
    615 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
    616 		goto err;
    617 
    618 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    619 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    620 	    "debug", SYSCTL_DESCR("default debug flags"),
    621 	    NULL, 0, &bwi_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
    622 		goto err;
    623 
    624 	return;
    625 
    626 err:
    627 	aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
    628 }
    629 #endif	/* BWI_DEBUG */
    630 
    631 static void
    632 bwi_sysctlattach(struct bwi_softc *sc)
    633 {
    634 	int rc;
    635 	const struct sysctlnode *rnode;
    636 	const struct sysctlnode *cnode;
    637 
    638 	struct sysctllog **clog = &sc->sc_sysctllog;
    639 
    640 	if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
    641 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(sc->sc_dev),
    642 	    SYSCTL_DESCR("bwi controls and statistics"),
    643 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
    644 		goto err;
    645 
    646 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    647 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    648 	    "fw_version", SYSCTL_DESCR("firmware version"),
    649 	    NULL, 0, &sc->sc_fw_version, 0, CTL_CREATE, CTL_EOL)) != 0)
    650 		goto err;
    651 
    652 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    653 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    654 	    "dwell_time", SYSCTL_DESCR("channel dwell time during scan (msec)"),
    655 	    NULL, 0, &sc->sc_dwell_time, 0, CTL_CREATE, CTL_EOL)) != 0)
    656 		goto err;
    657 
    658 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    659 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    660 	    "led_idle", SYSCTL_DESCR("# ticks before LED enters idle state"),
    661 	    NULL, 0, &sc->sc_led_idle, 0, CTL_CREATE, CTL_EOL)) != 0)
    662 		goto err;
    663 
    664 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    665 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    666 	    "led_blink", SYSCTL_DESCR("allow LED to blink"),
    667 	    NULL, 0, &sc->sc_led_blink, 0, CTL_CREATE, CTL_EOL)) != 0)
    668 		goto err;
    669 
    670 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    671 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    672 	    "txpwr_calib", SYSCTL_DESCR("enable software TX power calibration"),
    673 	    NULL, 0, &sc->sc_txpwr_calib, 0, CTL_CREATE, CTL_EOL)) != 0)
    674 		goto err;
    675 
    676 #ifdef BWI_DEBUG
    677 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    678 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    679 	    "debug", SYSCTL_DESCR("debug flags"),
    680 	    NULL, 0, &sc->sc_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
    681 		goto err;
    682 #endif
    683 
    684 	return;
    685 
    686 err:
    687 	aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
    688 }
    689 
    690 /* CODE */
    691 
    692 int
    693 bwi_intr(void *arg)
    694 {
    695 	struct bwi_softc *sc = arg;
    696 	struct bwi_mac *mac;
    697 	struct ifnet *ifp = &sc->sc_if;
    698 	uint32_t intr_status;
    699 	uint32_t txrx_intr_status[BWI_TXRX_NRING];
    700 	int i, txrx_error, tx = 0, rx_data = -1;
    701 
    702 	if (!device_is_active(sc->sc_dev) ||
    703 	    (ifp->if_flags & IFF_RUNNING) == 0)
    704 		return (0);
    705 
    706 	/*
    707 	 * Get interrupt status
    708 	 */
    709 	intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
    710 	if (intr_status == 0xffffffff)	/* Not for us */
    711 		return (0);
    712 
    713 	intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK);
    714 	if (intr_status == 0)		/* Nothing is interesting */
    715 		return (0);
    716 
    717 	DPRINTF(sc, BWI_DBG_INTR, "intr status 0x%08x\n", intr_status);
    718 
    719 	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
    720 	mac = (struct bwi_mac *)sc->sc_cur_regwin;
    721 
    722 	txrx_error = 0;
    723 
    724 	for (i = 0; i < BWI_TXRX_NRING; ++i) {
    725 		uint32_t mask;
    726 
    727 		if (BWI_TXRX_IS_RX(i))
    728 			mask = BWI_TXRX_RX_INTRS;
    729 		else
    730 			mask = BWI_TXRX_TX_INTRS;
    731 
    732 		txrx_intr_status[i] =
    733 		    CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask;
    734 
    735 		if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
    736 			aprint_error_dev(sc->sc_dev,
    737 			    "intr fatal TX/RX (%d) error 0x%08x\n",
    738 			    i, txrx_intr_status[i]);
    739 			txrx_error = 1;
    740 		}
    741 	}
    742 
    743 	/*
    744 	 * Acknowledge interrupt
    745 	 */
    746 	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status);
    747 
    748 	for (i = 0; i < BWI_TXRX_NRING; ++i)
    749 		CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i), txrx_intr_status[i]);
    750 
    751 	/* Disable all interrupts */
    752 	bwi_disable_intrs(sc, BWI_ALL_INTRS);
    753 
    754 	if (intr_status & BWI_INTR_PHY_TXERR) {
    755 		if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
    756 			aprint_error_dev(sc->sc_dev, "intr PHY TX error\n");
    757 			/* XXX to netisr0? */
    758 			bwi_init_statechg(sc, 0);
    759 			return (0);
    760 		}
    761 	}
    762 
    763 	if (txrx_error) {
    764 		/* TODO: reset device */
    765 	}
    766 
    767 	if (intr_status & BWI_INTR_TBTT)
    768 		bwi_mac_config_ps(mac);
    769 
    770 	if (intr_status & BWI_INTR_EO_ATIM)
    771 		aprint_normal_dev(sc->sc_dev, "EO_ATIM\n");
    772 
    773 	if (intr_status & BWI_INTR_PMQ) {
    774 		for (;;) {
    775 			if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8) == 0)
    776 				break;
    777 		}
    778 		CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2);
    779 	}
    780 
    781 	if (intr_status & BWI_INTR_NOISE)
    782 		aprint_normal_dev(sc->sc_dev, "intr noise\n");
    783 
    784 	if (txrx_intr_status[0] & BWI_TXRX_INTR_RX)
    785 		rx_data = (sc->sc_rxeof)(sc);
    786 
    787 	if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) {
    788 		(sc->sc_txeof_status)(sc);
    789 		tx = 1;
    790 	}
    791 
    792 	if (intr_status & BWI_INTR_TX_DONE) {
    793 		bwi_txeof(sc);
    794 		tx = 1;
    795 	}
    796 
    797 	/* Re-enable interrupts */
    798 	bwi_enable_intrs(sc, BWI_INIT_INTRS);
    799 
    800 	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
    801 		int evt = BWI_LED_EVENT_NONE;
    802 
    803 		if (tx && rx_data > 0) {
    804 			if (sc->sc_rx_rate > sc->sc_tx_rate)
    805 				evt = BWI_LED_EVENT_RX;
    806 			else
    807 				evt = BWI_LED_EVENT_TX;
    808 		} else if (tx) {
    809 			evt = BWI_LED_EVENT_TX;
    810 		} else if (rx_data > 0) {
    811 			evt = BWI_LED_EVENT_RX;
    812 		} else if (rx_data == 0) {
    813 			evt = BWI_LED_EVENT_POLL;
    814 		}
    815 
    816 		if (evt != BWI_LED_EVENT_NONE)
    817 			bwi_led_event(sc, evt);
    818 	}
    819 
    820 	return (1);
    821 }
    822 
    823 int
    824 bwi_attach(struct bwi_softc *sc)
    825 {
    826 	struct ieee80211com *ic = &sc->sc_ic;
    827 	struct ifnet *ifp = &sc->sc_if;
    828 	struct bwi_mac *mac;
    829 	struct bwi_phy *phy;
    830 	int s, i, error;
    831 
    832 	/* [TRC: XXX Is this necessary?] */
    833 	s = splnet();
    834 
    835 	/*
    836 	 * Initialize sysctl variables
    837 	 */
    838 	sc->sc_fw_version = BWI_FW_VERSION3;
    839 	sc->sc_dwell_time = 200;
    840 	sc->sc_led_idle = (2350 * hz) / 1000;
    841 	sc->sc_led_blink = 1;
    842 	sc->sc_txpwr_calib = 1;
    843 #ifdef BWI_DEBUG
    844 	sc->sc_debug = bwi_debug;
    845 #endif
    846 
    847 	DPRINTF(sc, BWI_DBG_ATTACH, "%s\n", __func__);
    848 
    849 	/* [TRC: XXX amrr] */
    850 	/* AMRR rate control */
    851 	sc->sc_amrr.amrr_min_success_threshold = 1;
    852 	sc->sc_amrr.amrr_max_success_threshold = 15;
    853 	callout_init(&sc->sc_amrr_ch, 0);
    854 	callout_setfunc(&sc->sc_amrr_ch, bwi_amrr_timeout, sc);
    855 
    856 	callout_init(&sc->sc_scan_ch, 0);
    857 	callout_setfunc(&sc->sc_scan_ch, bwi_next_scan, sc);
    858 	callout_init(&sc->sc_calib_ch, 0);
    859 	callout_setfunc(&sc->sc_calib_ch, bwi_calibrate, sc);
    860 
    861 	bwi_sysctlattach(sc);
    862 
    863 	bwi_power_on(sc, 1);
    864 
    865 	error = bwi_bbp_attach(sc);
    866 	if (error)
    867 		goto fail;
    868 
    869 	error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
    870 	if (error)
    871 		goto fail;
    872 
    873 	if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) {
    874 		error = bwi_set_clock_delay(sc);
    875 		if (error)
    876 			goto fail;
    877 
    878 		error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST);
    879 		if (error)
    880 			goto fail;
    881 
    882 		error = bwi_get_pwron_delay(sc);
    883 		if (error)
    884 			goto fail;
    885 	}
    886 
    887 	error = bwi_bus_attach(sc);
    888 	if (error)
    889 		goto fail;
    890 
    891 	bwi_get_card_flags(sc);
    892 
    893 	bwi_led_attach(sc);
    894 
    895 	for (i = 0; i < sc->sc_nmac; ++i) {
    896 		struct bwi_regwin *old;
    897 
    898 		mac = &sc->sc_mac[i];
    899 		error = bwi_regwin_switch(sc, &mac->mac_regwin, &old);
    900 		if (error)
    901 			goto fail;
    902 
    903 		error = bwi_mac_lateattach(mac);
    904 		if (error)
    905 			goto fail;
    906 
    907 		error = bwi_regwin_switch(sc, old, NULL);
    908 		if (error)
    909 			goto fail;
    910 	}
    911 
    912 	/*
    913 	 * XXX First MAC is known to exist
    914 	 * TODO2
    915 	 */
    916 	mac = &sc->sc_mac[0];
    917 	phy = &mac->mac_phy;
    918 
    919 	bwi_bbp_power_off(sc);
    920 
    921 	error = bwi_dma_alloc(sc);
    922 	if (error)
    923 		goto fail;
    924 
    925 	/* setup interface */
    926 	ifp->if_softc = sc;
    927 	ifp->if_init = bwi_init;
    928 	ifp->if_ioctl = bwi_ioctl;
    929 	ifp->if_start = bwi_start;
    930 	ifp->if_watchdog = bwi_watchdog;
    931 	ifp->if_stop = bwi_stop;
    932 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
    933 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    934 	IFQ_SET_READY(&ifp->if_snd);
    935 
    936 	/* Get locale */
    937 	sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
    938 	    BWI_SPROM_CARD_INFO_LOCALE);
    939 	DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale);
    940 
    941 	/*
    942 	 * Setup ratesets, phytype, channels and get MAC address
    943 	 */
    944 	if (phy->phy_mode == IEEE80211_MODE_11B ||
    945 	    phy->phy_mode == IEEE80211_MODE_11G) {
    946 		uint16_t chan_flags;
    947 
    948 		ic->ic_sup_rates[IEEE80211_MODE_11B] =
    949 		    ieee80211_std_rateset_11b;
    950 
    951 		if (phy->phy_mode == IEEE80211_MODE_11B) {
    952 			chan_flags = IEEE80211_CHAN_B;
    953 			ic->ic_phytype = IEEE80211_T_DS;
    954 		} else {
    955 			chan_flags = IEEE80211_CHAN_CCK |
    956 			    IEEE80211_CHAN_OFDM |
    957 			    IEEE80211_CHAN_DYN |
    958 			    IEEE80211_CHAN_2GHZ;
    959 			ic->ic_phytype = IEEE80211_T_OFDM;
    960 			ic->ic_sup_rates[IEEE80211_MODE_11G] =
    961 			    ieee80211_std_rateset_11g;
    962 		}
    963 
    964 		/* XXX depend on locale */
    965 		for (i = 1; i <= 14; ++i) {
    966 			ic->ic_channels[i].ic_freq =
    967 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
    968 			ic->ic_channels[i].ic_flags = chan_flags;
    969 		}
    970 
    971 		bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_myaddr);
    972 		if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) {
    973 			bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_myaddr);
    974 			if (IEEE80211_IS_MULTICAST(ic->ic_myaddr))
    975 				aprint_error_dev(sc->sc_dev,
    976 				    "invalid MAC address: %s\n",
    977 				    ether_sprintf(ic->ic_myaddr));
    978 		}
    979 	} else if (phy->phy_mode == IEEE80211_MODE_11A) {
    980 		/* TODO: 11A */
    981 		error = ENXIO;
    982 		goto fail;
    983 	} else
    984 		panic("unknown phymode %d\n", phy->phy_mode);
    985 
    986 	ic->ic_ifp = ifp;
    987 	ic->ic_caps = IEEE80211_C_SHSLOT |
    988 	    IEEE80211_C_SHPREAMBLE |
    989 	    IEEE80211_C_IBSS |
    990 	    IEEE80211_C_HOSTAP |
    991 	    IEEE80211_C_MONITOR;
    992 	ic->ic_state = IEEE80211_S_INIT;
    993 	ic->ic_opmode = IEEE80211_M_STA;
    994 
    995 	ic->ic_updateslot = bwi_updateslot;
    996 
    997 	if_attach(ifp);
    998 	ieee80211_ifattach(ic);
    999 
   1000 	/* [TRC: XXX Not supported on NetBSD?] */
   1001 	/* ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; */
   1002 
   1003 	sc->sc_newstate = ic->ic_newstate;
   1004 	ic->ic_newstate = bwi_newstate;
   1005 	/* [TRC: XXX amrr] */
   1006 	ic->ic_newassoc = bwi_newassoc;
   1007 	ic->ic_node_alloc = bwi_node_alloc;
   1008 
   1009 	ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status);
   1010 
   1011 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
   1012 	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
   1013 	    &sc->sc_drvbpf);
   1014 
   1015 	/* [TRC: XXX DragonFlyBSD rounds this up to a multiple of
   1016 	   sizeof(uint32_t).  Should we?] */
   1017 	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
   1018 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
   1019 	sc->sc_rxtap.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT);
   1020 
   1021 	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
   1022 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
   1023 	sc->sc_txtap.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT);
   1024 
   1025 	splx(s);
   1026 	ieee80211_announce(ic);
   1027 	return (0);
   1028 fail:
   1029 	/* [TRC: XXX DragonFlyBSD detaches the device here.  Should we?] */
   1030 	return (error);
   1031 }
   1032 
   1033 void
   1034 bwi_detach(struct bwi_softc *sc)
   1035 {
   1036 	struct ifnet *ifp = &sc->sc_if;
   1037 	int i, s;
   1038 
   1039 	s = splnet();
   1040 
   1041 	bwi_stop(ifp, 1);
   1042 
   1043 	bpf_detach(ifp);
   1044 
   1045 	ieee80211_ifdetach(&sc->sc_ic);
   1046 	if_detach(ifp);
   1047 
   1048 	for (i = 0; i < sc->sc_nmac; ++i)
   1049 		bwi_mac_detach(&sc->sc_mac[i]);
   1050 
   1051 	sysctl_teardown(&sc->sc_sysctllog);
   1052 
   1053 	splx(s);
   1054 
   1055 	bwi_dma_free(sc);
   1056 }
   1057 
   1058 /* MAC */
   1059 
   1060 static void
   1061 bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val)
   1062 {
   1063 	struct bwi_softc *sc = mac->mac_sc;
   1064 
   1065 	if (mac->mac_flags & BWI_MAC_F_BSWAP)
   1066 		val = bswap32(val);
   1067 
   1068 	CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs);
   1069 	CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val);
   1070 }
   1071 
   1072 static void
   1073 bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags)
   1074 {
   1075 	uint64_t val;
   1076 
   1077 	val = flags & 0xffff;
   1078 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val);
   1079 
   1080 	val = (flags >> 16) & 0xffff;
   1081 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val);
   1082 
   1083 	/* HI has unclear meaning, so leave it as it is */
   1084 }
   1085 
   1086 static uint64_t
   1087 bwi_hostflags_read(struct bwi_mac *mac)
   1088 {
   1089 	uint64_t flags, val;
   1090 
   1091 	/* HI has unclear meaning, so don't touch it */
   1092 	flags = 0;
   1093 
   1094 	val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI);
   1095 	flags |= val << 16;
   1096 
   1097 	val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO);
   1098 	flags |= val;
   1099 
   1100 	return (flags);
   1101 }
   1102 
   1103 static uint16_t
   1104 bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
   1105 {
   1106 	struct bwi_softc *sc = mac->mac_sc;
   1107 	uint32_t data_reg;
   1108 	int ofs;
   1109 
   1110 	data_reg = BWI_MOBJ_DATA;
   1111 	ofs = ofs0 / 4;
   1112 
   1113 	if (ofs0 % 4 != 0)
   1114 		data_reg = BWI_MOBJ_DATA_UNALIGN;
   1115 
   1116 	CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
   1117 	return (CSR_READ_2(sc, data_reg));
   1118 }
   1119 
   1120 static uint32_t
   1121 bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
   1122 {
   1123 	struct bwi_softc *sc = mac->mac_sc;
   1124 	int ofs;
   1125 
   1126 	ofs = ofs0 / 4;
   1127 	if (ofs0 % 4 != 0) {
   1128 		uint32_t ret;
   1129 
   1130 		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
   1131 		ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN);
   1132 		ret <<= 16;
   1133 
   1134 		CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
   1135 		    BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
   1136 		ret |= CSR_READ_2(sc, BWI_MOBJ_DATA);
   1137 
   1138 		return (ret);
   1139 	} else {
   1140 		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
   1141 		return (CSR_READ_4(sc, BWI_MOBJ_DATA));
   1142 	}
   1143 }
   1144 
   1145 static void
   1146 bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
   1147     uint16_t v)
   1148 {
   1149 	struct bwi_softc *sc = mac->mac_sc;
   1150 	uint32_t data_reg;
   1151 	int ofs;
   1152 
   1153 	data_reg = BWI_MOBJ_DATA;
   1154 	ofs = ofs0 / 4;
   1155 
   1156 	if (ofs0 % 4 != 0)
   1157 		data_reg = BWI_MOBJ_DATA_UNALIGN;
   1158 
   1159 	CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
   1160 	CSR_WRITE_2(sc, data_reg, v);
   1161 }
   1162 
   1163 static void
   1164 bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
   1165     uint32_t v)
   1166 {
   1167 	struct bwi_softc *sc = mac->mac_sc;
   1168 	int ofs;
   1169 
   1170 	ofs = ofs0 / 4;
   1171 	if (ofs0 % 4 != 0) {
   1172 		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
   1173 		CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16);
   1174 		CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
   1175 		    BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
   1176 		CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff);
   1177 	} else {
   1178 		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
   1179 		CSR_WRITE_4(sc, BWI_MOBJ_DATA, v);
   1180 	}
   1181 }
   1182 
   1183 static int
   1184 bwi_mac_lateattach(struct bwi_mac *mac)
   1185 {
   1186 	int error;
   1187 
   1188 	if (mac->mac_rev >= 5)
   1189 		CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */
   1190 
   1191 	bwi_mac_reset(mac, 1);
   1192 
   1193 	error = bwi_phy_attach(mac);
   1194 	if (error)
   1195 		return (error);
   1196 
   1197 	error = bwi_rf_attach(mac);
   1198 	if (error)
   1199 		return (error);
   1200 
   1201 	/* Link 11B/G PHY, unlink 11A PHY */
   1202 	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A)
   1203 		bwi_mac_reset(mac, 0);
   1204 	else
   1205 		bwi_mac_reset(mac, 1);
   1206 
   1207 	error = bwi_mac_test(mac);
   1208 	if (error)
   1209 		return (error);
   1210 
   1211 	error = bwi_mac_get_property(mac);
   1212 	if (error)
   1213 		return (error);
   1214 
   1215 	error = bwi_rf_map_txpower(mac);
   1216 	if (error)
   1217 		return (error);
   1218 
   1219 	bwi_rf_off(mac);
   1220 	CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
   1221 	bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0);
   1222 
   1223 	return (0);
   1224 }
   1225 
   1226 static int
   1227 bwi_mac_init(struct bwi_mac *mac)
   1228 {
   1229 	struct bwi_softc *sc = mac->mac_sc;
   1230 	int error, i;
   1231 
   1232 	/* Clear MAC/PHY/RF states */
   1233 	bwi_mac_setup_tpctl(mac);
   1234 	bwi_rf_clear_state(&mac->mac_rf);
   1235 	bwi_phy_clear_state(&mac->mac_phy);
   1236 
   1237 	/* Enable MAC and linked it to PHY */
   1238 	if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin))
   1239 		bwi_mac_reset(mac, 1);
   1240 
   1241 	/* Initialize backplane */
   1242 	error = bwi_bus_init(sc, mac);
   1243 	if (error)
   1244 		return (error);
   1245 
   1246 	/* XXX work around for hardware bugs? */
   1247 	if (sc->sc_bus_regwin.rw_rev <= 5 &&
   1248 	    sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) {
   1249 		CSR_SETBITS_4(sc, BWI_CONF_LO,
   1250 		__SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |
   1251 		__SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK));
   1252 	}
   1253 
   1254 	/* Calibrate PHY */
   1255 	error = bwi_phy_calibrate(mac);
   1256 	if (error) {
   1257 		aprint_error_dev(sc->sc_dev, "PHY calibrate failed\n");
   1258 		return (error);
   1259 	}
   1260 
   1261 	/* Prepare to initialize firmware */
   1262 	CSR_WRITE_4(sc, BWI_MAC_STATUS,
   1263 	    BWI_MAC_STATUS_UCODE_JUMP0 |
   1264 	    BWI_MAC_STATUS_IHREN);
   1265 
   1266 	/*
   1267 	 * Load and initialize firmwares
   1268 	 */
   1269 	error = bwi_mac_fw_alloc(mac);
   1270 	if (error)
   1271 		return (error);
   1272 
   1273 	error = bwi_mac_fw_load(mac);
   1274 	if (error)
   1275 		return (error);
   1276 
   1277 	error = bwi_mac_gpio_init(mac);
   1278 	if (error)
   1279 		return (error);
   1280 
   1281 	error = bwi_mac_fw_init(mac);
   1282 	if (error)
   1283 		return (error);
   1284 
   1285 	/*
   1286 	 * Turn on RF
   1287 	 */
   1288 	bwi_rf_on(mac);
   1289 
   1290 	/* TODO: LED, hardware rf enabled is only related to LED setting */
   1291 
   1292 	/*
   1293 	 * Initialize PHY
   1294 	 */
   1295 	CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
   1296 	bwi_phy_init(mac);
   1297 
   1298 	/* TODO: interference mitigation */
   1299 
   1300 	/*
   1301 	 * Setup antenna mode
   1302 	 */
   1303 	bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode);
   1304 
   1305 	/*
   1306 	 * Initialize operation mode (RX configuration)
   1307 	 */
   1308 	bwi_mac_opmode_init(mac);
   1309 
   1310 	/* XXX what's these */
   1311 	if (mac->mac_rev < 3) {
   1312 		CSR_WRITE_2(sc, 0x60e, 0);
   1313 		CSR_WRITE_2(sc, 0x610, 0x8000);
   1314 		CSR_WRITE_2(sc, 0x604, 0);
   1315 		CSR_WRITE_2(sc, 0x606, 0x200);
   1316 	} else {
   1317 		CSR_WRITE_4(sc, 0x188, 0x80000000);
   1318 		CSR_WRITE_4(sc, 0x18c, 0x2000000);
   1319 	}
   1320 
   1321 	/*
   1322 	 * Initialize TX/RX interrupts' mask
   1323 	 */
   1324 	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1);
   1325 	for (i = 0; i < BWI_TXRX_NRING; ++i) {
   1326 		uint32_t intrs;
   1327 
   1328 		if (BWI_TXRX_IS_RX(i))
   1329 			intrs = BWI_TXRX_RX_INTRS;
   1330 		else
   1331 			intrs = BWI_TXRX_TX_INTRS;
   1332 		CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs);
   1333 	}
   1334 
   1335 	/* XXX what's this */
   1336 	CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000);
   1337 
   1338 	/* Setup MAC power up delay */
   1339 	CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay);
   1340 
   1341 	/* Set MAC regwin revision */
   1342 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev);
   1343 
   1344 	/*
   1345 	 * Initialize host flags
   1346 	 */
   1347 	bwi_mac_hostflags_init(mac);
   1348 
   1349 	/*
   1350 	 * Initialize BSS parameters
   1351 	 */
   1352 	bwi_mac_bss_param_init(mac);
   1353 
   1354 	/*
   1355 	 * Initialize TX rings
   1356 	 */
   1357 	for (i = 0; i < BWI_TX_NRING; ++i) {
   1358 		error = (sc->sc_init_tx_ring)(sc, i);
   1359 		if (error) {
   1360 			aprint_error_dev(sc->sc_dev,
   1361 			    "can't initialize %dth TX ring\n", i);
   1362 			return (error);
   1363 		}
   1364 	}
   1365 
   1366 	/*
   1367 	 * Initialize RX ring
   1368 	 */
   1369 	error = (sc->sc_init_rx_ring)(sc);
   1370 	if (error) {
   1371 		aprint_error_dev(sc->sc_dev, "can't initialize RX ring\n");
   1372 		return (error);
   1373 	}
   1374 
   1375 	/*
   1376 	 * Initialize TX stats if the current MAC uses that
   1377 	 */
   1378 	if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) {
   1379 		error = (sc->sc_init_txstats)(sc);
   1380 		if (error) {
   1381 			aprint_error_dev(sc->sc_dev,
   1382 			    "can't initialize TX stats ring\n");
   1383 			return (error);
   1384 		}
   1385 	}
   1386 
   1387 	/* XXX what's these */
   1388 	CSR_WRITE_2(sc, 0x612, 0x50);	/* Force Pre-TBTT to 80? */
   1389 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50);
   1390 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4);
   1391 
   1392 	mac->mac_flags |= BWI_MAC_F_INITED;
   1393 
   1394 	return (0);
   1395 }
   1396 
   1397 static void
   1398 bwi_mac_reset(struct bwi_mac *mac, int link_phy)
   1399 {
   1400 	struct bwi_softc *sc = mac->mac_sc;
   1401 	uint32_t flags, state_lo, status;
   1402 
   1403 	flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN;
   1404 	if (link_phy)
   1405 		flags |= BWI_STATE_LO_FLAG_PHYLNK;
   1406 	bwi_regwin_enable(sc, &mac->mac_regwin, flags);
   1407 	DELAY(2000);
   1408 
   1409 	state_lo = CSR_READ_4(sc, BWI_STATE_LO);
   1410 	state_lo |= BWI_STATE_LO_GATED_CLOCK;
   1411 	state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST,
   1412 			       BWI_STATE_LO_FLAGS_MASK);
   1413 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
   1414 	/* Flush pending bus write */
   1415 	CSR_READ_4(sc, BWI_STATE_LO);
   1416 	DELAY(1000);
   1417 
   1418 	state_lo &= ~BWI_STATE_LO_GATED_CLOCK;
   1419 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
   1420 	/* Flush pending bus write */
   1421 	CSR_READ_4(sc, BWI_STATE_LO);
   1422 	DELAY(1000);
   1423 
   1424 	CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
   1425 
   1426 	status = CSR_READ_4(sc, BWI_MAC_STATUS);
   1427 	status |= BWI_MAC_STATUS_IHREN;
   1428 	if (link_phy)
   1429 		status |= BWI_MAC_STATUS_PHYLNK;
   1430 	else
   1431 		status &= ~BWI_MAC_STATUS_PHYLNK;
   1432 	CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
   1433 
   1434 	if (link_phy) {
   1435 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT,
   1436 		    "%s\n", "PHY is linked");
   1437 		mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED;
   1438 	} else {
   1439 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT,
   1440 		    "%s\n", "PHY is unlinked");
   1441 		mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED;
   1442 	}
   1443 }
   1444 
   1445 static void
   1446 bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl)
   1447 {
   1448 	struct bwi_rf *rf = &mac->mac_rf;
   1449 	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
   1450 
   1451 	if (new_tpctl != NULL) {
   1452 		KASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX);
   1453 		KASSERT(new_tpctl->rf_atten <=
   1454 		    (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0
   1455 		    : BWI_RF_ATTEN_MAX1));
   1456 		KASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX);
   1457 
   1458 		tpctl->bbp_atten = new_tpctl->bbp_atten;
   1459 		tpctl->rf_atten = new_tpctl->rf_atten;
   1460 		tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1;
   1461 	}
   1462 
   1463 	/* Set BBP attenuation */
   1464 	bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten);
   1465 
   1466 	/* Set RF attenuation */
   1467 	RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten);
   1468 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN,
   1469 	    tpctl->rf_atten);
   1470 
   1471 	/* Set TX power */
   1472 	if (rf->rf_type == BWI_RF_T_BCM2050) {
   1473 		RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK,
   1474 		    __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK));
   1475 	}
   1476 
   1477 	/* Adjust RF Local Oscillator */
   1478 	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
   1479 		bwi_rf_lo_adjust(mac, tpctl);
   1480 }
   1481 
   1482 static int
   1483 bwi_mac_test(struct bwi_mac *mac)
   1484 {
   1485 	struct bwi_softc *sc = mac->mac_sc;
   1486 	uint32_t orig_val, val;
   1487 
   1488 #define TEST_VAL1	0xaa5555aa
   1489 #define TEST_VAL2	0x55aaaa55
   1490 	/* Save it for later restoring */
   1491 	orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
   1492 
   1493 	/* Test 1 */
   1494 	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1);
   1495 	val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
   1496 	if (val != TEST_VAL1) {
   1497 		aprint_error_dev(sc->sc_dev, "TEST1 failed\n");
   1498 		return (ENXIO);
   1499 	}
   1500 
   1501 	/* Test 2 */
   1502 	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2);
   1503 	val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
   1504 	if (val != TEST_VAL2) {
   1505 		aprint_error_dev(sc->sc_dev, "TEST2 failed\n");
   1506 		return (ENXIO);
   1507 	}
   1508 
   1509 	/* Restore to the original value */
   1510 	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val);
   1511 
   1512 	val = CSR_READ_4(sc, BWI_MAC_STATUS);
   1513 	if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) {
   1514 		aprint_error_dev(sc->sc_dev, "%s failed, MAC status 0x%08x\n",
   1515 		    __func__, val);
   1516 		return (ENXIO);
   1517 	}
   1518 
   1519 	val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
   1520 	if (val != 0) {
   1521 		aprint_error_dev(sc->sc_dev, "%s failed, intr status %08x\n",
   1522 		    __func__, val);
   1523 		return (ENXIO);
   1524 	}
   1525 #undef TEST_VAL2
   1526 #undef TEST_VAL1
   1527 
   1528 	return (0);
   1529 }
   1530 
   1531 static void
   1532 bwi_mac_setup_tpctl(struct bwi_mac *mac)
   1533 {
   1534 	struct bwi_softc *sc = mac->mac_sc;
   1535 	struct bwi_rf *rf = &mac->mac_rf;
   1536 	struct bwi_phy *phy = &mac->mac_phy;
   1537 	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
   1538 
   1539 	/* Calc BBP attenuation */
   1540 	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6)
   1541 		tpctl->bbp_atten = 0;
   1542 	else
   1543 		tpctl->bbp_atten = 2;
   1544 
   1545 	/* Calc TX power CTRL1?? */
   1546 	tpctl->tp_ctrl1 = 0;
   1547 	if (rf->rf_type == BWI_RF_T_BCM2050) {
   1548 		if (rf->rf_rev == 1)
   1549 			tpctl->tp_ctrl1 = 3;
   1550 		else if (rf->rf_rev < 6)
   1551 			tpctl->tp_ctrl1 = 2;
   1552 		else if (rf->rf_rev == 8)
   1553 			tpctl->tp_ctrl1 = 1;
   1554 	}
   1555 
   1556 	/* Empty TX power CTRL2?? */
   1557 	tpctl->tp_ctrl2 = 0xffff;
   1558 
   1559 	/*
   1560 	 * Calc RF attenuation
   1561 	 */
   1562 	if (phy->phy_mode == IEEE80211_MODE_11A) {
   1563 		tpctl->rf_atten = 0x60;
   1564 		goto back;
   1565 	}
   1566 
   1567 	if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) {
   1568 		tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3;
   1569 		goto back;
   1570 	}
   1571 
   1572 	tpctl->rf_atten = 5;
   1573 
   1574 	if (rf->rf_type != BWI_RF_T_BCM2050) {
   1575 		if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1)
   1576 			tpctl->rf_atten = 6;
   1577 		goto back;
   1578 	}
   1579 
   1580 	/*
   1581 	 * NB: If we reaches here and the card is BRCM_BCM4309G,
   1582 	 *     then the card's PCI revision must >= 0x51
   1583 	 */
   1584 
   1585 	/* BCM2050 RF */
   1586 	switch (rf->rf_rev) {
   1587 	case 1:
   1588 		if (phy->phy_mode == IEEE80211_MODE_11G) {
   1589 			if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc))
   1590 				tpctl->rf_atten = 3;
   1591 			else
   1592 				tpctl->rf_atten = 1;
   1593 		} else {
   1594 			if (BWI_IS_BRCM_BCM4309G(sc))
   1595 				tpctl->rf_atten = 7;
   1596 			else
   1597 				tpctl->rf_atten = 6;
   1598 		}
   1599 		break;
   1600 	case 2:
   1601 		if (phy->phy_mode == IEEE80211_MODE_11G) {
   1602 			/*
   1603 			 * NOTE: Order of following conditions is critical
   1604 			 */
   1605 			if (BWI_IS_BRCM_BCM4309G(sc))
   1606 				tpctl->rf_atten = 3;
   1607 			else if (BWI_IS_BRCM_BU4306(sc))
   1608 				tpctl->rf_atten = 5;
   1609 			else if (sc->sc_bbp_id == BWI_BBPID_BCM4320)
   1610 				tpctl->rf_atten = 4;
   1611 			else
   1612 				tpctl->rf_atten = 3;
   1613 		} else {
   1614 			tpctl->rf_atten = 6;
   1615 		}
   1616 		break;
   1617 	case 4:
   1618 	case 5:
   1619 		tpctl->rf_atten = 1;
   1620 		break;
   1621 	case 8:
   1622 		tpctl->rf_atten = 0x1a;
   1623 		break;
   1624 	}
   1625 back:
   1626 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER,
   1627 	    "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
   1628 	    tpctl->bbp_atten, tpctl->rf_atten,
   1629 	    tpctl->tp_ctrl1, tpctl->tp_ctrl2);
   1630 }
   1631 
   1632 static void
   1633 bwi_mac_dummy_xmit(struct bwi_mac *mac)
   1634 {
   1635 #define PACKET_LEN	5
   1636 	static const uint32_t	packet_11a[PACKET_LEN] =
   1637 	    { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
   1638 	static const uint32_t	packet_11bg[PACKET_LEN] =
   1639 	    { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
   1640 
   1641 	struct bwi_softc *sc = mac->mac_sc;
   1642 	struct bwi_rf *rf = &mac->mac_rf;
   1643 	const uint32_t *packet;
   1644 	uint16_t val_50c;
   1645 	int wait_max, i;
   1646 
   1647 	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
   1648 		wait_max = 30;
   1649 		packet = packet_11a;
   1650 		val_50c = 1;
   1651 	} else {
   1652 		wait_max = 250;
   1653 		packet = packet_11bg;
   1654 		val_50c = 0;
   1655 	}
   1656 
   1657 	for (i = 0; i < PACKET_LEN; ++i)
   1658 		TMPLT_WRITE_4(mac, i * 4, packet[i]);
   1659 
   1660 	CSR_READ_4(sc, BWI_MAC_STATUS);	/* dummy read */
   1661 
   1662 	CSR_WRITE_2(sc, 0x568, 0);
   1663 	CSR_WRITE_2(sc, 0x7c0, 0);
   1664 	CSR_WRITE_2(sc, 0x50c, val_50c);
   1665 	CSR_WRITE_2(sc, 0x508, 0);
   1666 	CSR_WRITE_2(sc, 0x50a, 0);
   1667 	CSR_WRITE_2(sc, 0x54c, 0);
   1668 	CSR_WRITE_2(sc, 0x56a, 0x14);
   1669 	CSR_WRITE_2(sc, 0x568, 0x826);
   1670 	CSR_WRITE_2(sc, 0x500, 0);
   1671 	CSR_WRITE_2(sc, 0x502, 0x30);
   1672 
   1673 	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
   1674 		RF_WRITE(mac, 0x51, 0x17);
   1675 
   1676 	for (i = 0; i < wait_max; ++i) {
   1677 		if (CSR_READ_2(sc, 0x50e) & 0x80)
   1678 			break;
   1679 		DELAY(10);
   1680 	}
   1681 	for (i = 0; i < 10; ++i) {
   1682 		if (CSR_READ_2(sc, 0x50e) & 0x400)
   1683 			break;
   1684 		DELAY(10);
   1685 	}
   1686 	for (i = 0; i < 10; ++i) {
   1687 		if ((CSR_READ_2(sc, 0x690) & 0x100) == 0)
   1688 			break;
   1689 		DELAY(10);
   1690 	}
   1691 
   1692 	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
   1693 		RF_WRITE(mac, 0x51, 0x37);
   1694 #undef PACKET_LEN
   1695 }
   1696 
   1697 static void
   1698 bwi_mac_init_tpctl_11bg(struct bwi_mac *mac)
   1699 {
   1700 	struct bwi_softc *sc = mac->mac_sc;
   1701 	struct bwi_phy *phy = &mac->mac_phy;
   1702 	struct bwi_rf *rf = &mac->mac_rf;
   1703 	struct bwi_tpctl tpctl_orig;
   1704 	int restore_tpctl = 0;
   1705 
   1706 	KASSERT(phy->phy_mode != IEEE80211_MODE_11A);
   1707 
   1708 	if (BWI_IS_BRCM_BU4306(sc))
   1709 		return;
   1710 
   1711 	PHY_WRITE(mac, 0x28, 0x8018);
   1712 	CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20);
   1713 
   1714 	if (phy->phy_mode == IEEE80211_MODE_11G) {
   1715 		if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
   1716 			return;
   1717 		PHY_WRITE(mac, 0x47a, 0xc111);
   1718 	}
   1719 	if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED)
   1720 		return;
   1721 
   1722 	if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 &&
   1723 	    rf->rf_type == BWI_RF_T_BCM2050) {
   1724 		RF_SETBITS(mac, 0x76, 0x84);
   1725 	} else {
   1726 		struct bwi_tpctl tpctl;
   1727 
   1728 		/* Backup original TX power control variables */
   1729 		memcpy(&tpctl_orig, &mac->mac_tpctl, sizeof(tpctl_orig));
   1730 		restore_tpctl = 1;
   1731 
   1732 		memcpy(&tpctl, &mac->mac_tpctl, sizeof(tpctl));
   1733 		tpctl.bbp_atten = 11;
   1734 		tpctl.tp_ctrl1 = 0;
   1735 #ifdef notyet
   1736 		if (rf->rf_rev >= 6 && rf->rf_rev <= 8)
   1737 			tpctl.rf_atten = 31;
   1738 		else
   1739 #endif
   1740 			tpctl.rf_atten = 9;
   1741 
   1742 		bwi_mac_set_tpctl_11bg(mac, &tpctl);
   1743 	}
   1744 
   1745 	bwi_mac_dummy_xmit(mac);
   1746 
   1747 	mac->mac_flags |= BWI_MAC_F_TPCTL_INITED;
   1748 	rf->rf_base_tssi = PHY_READ(mac, 0x29);
   1749 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER,
   1750 	    "base tssi %d\n", rf->rf_base_tssi);
   1751 
   1752 	if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) {
   1753 		aprint_error_dev(sc->sc_dev, "base tssi measure failed\n");
   1754 		mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR;
   1755 	}
   1756 
   1757 	if (restore_tpctl)
   1758 		bwi_mac_set_tpctl_11bg(mac, &tpctl_orig);
   1759 	else
   1760 		RF_CLRBITS(mac, 0x76, 0x84);
   1761 
   1762 	bwi_rf_clear_tssi(mac);
   1763 }
   1764 
   1765 static void
   1766 bwi_mac_detach(struct bwi_mac *mac)
   1767 {
   1768 	bwi_mac_fw_free(mac);
   1769 }
   1770 
   1771 static int
   1772 bwi_mac_fw_alloc(struct bwi_mac *mac)
   1773 {
   1774 	struct bwi_softc *sc = mac->mac_sc;
   1775 	int idx, error;
   1776 
   1777 	error = bwi_mac_fw_image_alloc(mac, BWI_FW_UCODE_PREFIX,
   1778 	    mac->mac_rev >= 5 ? 5 : mac->mac_rev, &mac->mac_ucode_fwi,
   1779 	    BWI_FW_T_UCODE);
   1780 	if (error)
   1781 		goto fail_ucode;
   1782 
   1783 	error = bwi_mac_fw_image_alloc(mac, BWI_FW_PCM_PREFIX,
   1784 	    mac->mac_rev >= 5 ? 5 : mac->mac_rev, &mac->mac_pcm_fwi,
   1785 	    BWI_FW_T_PCM);
   1786 	if (error)
   1787 		goto fail_pcm;
   1788 
   1789 	/* TODO: 11A */
   1790 	if (mac->mac_rev == 2 || mac->mac_rev == 4)
   1791 		idx = 2;
   1792 	else if (mac->mac_rev >= 5 && mac->mac_rev <= 20)
   1793 		idx = 5;
   1794 	else {
   1795 		aprint_error_dev(sc->sc_dev,
   1796 		    "no suitable IV for MAC rev %d\n", mac->mac_rev);
   1797 		error = ENODEV;
   1798 		goto fail_iv;
   1799 	}
   1800 
   1801 	error = bwi_mac_fw_image_alloc(mac, BWI_FW_IV_PREFIX, idx,
   1802 	    &mac->mac_iv_fwi, BWI_FW_T_IV);
   1803 	if (error)
   1804 		goto fail_iv;
   1805 
   1806 	/* TODO: 11A */
   1807 	if (mac->mac_rev == 2 || mac->mac_rev == 4 ||
   1808 	    mac->mac_rev >= 11)
   1809 		/* No extended IV */
   1810 		goto back;
   1811 	else if (mac->mac_rev >= 5 && mac->mac_rev <= 10)
   1812 		idx = 5;
   1813 	else {
   1814 		aprint_error_dev(sc->sc_dev,
   1815 		    "no suitable ExtIV for MAC rev %d\n", mac->mac_rev);
   1816 		error = ENODEV;
   1817 		goto fail_iv_ext;
   1818 	}
   1819 
   1820 	error = bwi_mac_fw_image_alloc(mac, BWI_FW_IV_EXT_PREFIX, idx,
   1821 	    &mac->mac_iv_ext_fwi, BWI_FW_T_IV);
   1822 	if (error)
   1823 		goto fail_iv_ext;
   1824 
   1825 back:	return (0);
   1826 
   1827 fail_iv_ext:
   1828 	bwi_mac_fw_image_free(mac, &mac->mac_iv_fwi);
   1829 
   1830 fail_iv:
   1831 	bwi_mac_fw_image_free(mac, &mac->mac_pcm_fwi);
   1832 
   1833 fail_pcm:
   1834 	bwi_mac_fw_image_free(mac, &mac->mac_ucode_fwi);
   1835 
   1836 fail_ucode:
   1837 	return (error);
   1838 }
   1839 
   1840 static void
   1841 bwi_mac_fw_free(struct bwi_mac *mac)
   1842 {
   1843 	bwi_mac_fw_image_free(mac, &mac->mac_ucode_fwi);
   1844 	bwi_mac_fw_image_free(mac, &mac->mac_pcm_fwi);
   1845 	bwi_mac_fw_image_free(mac, &mac->mac_iv_fwi);
   1846 	bwi_mac_fw_image_free(mac, &mac->mac_iv_ext_fwi);
   1847 }
   1848 
   1849 static int
   1850 bwi_mac_fw_image_alloc(struct bwi_mac *mac, const char *prefix, int idx,
   1851     struct bwi_fw_image *fwi, uint8_t fw_type)
   1852 {
   1853 	struct bwi_softc *sc = mac->mac_sc;
   1854 	char *fw_name = fwi->fwi_name;
   1855 	size_t fw_name_size = sizeof(fwi->fwi_name);
   1856 	firmware_handle_t fwh;
   1857 	const struct bwi_fwhdr *hdr;
   1858 	int error;
   1859 
   1860 	/* [TRC: XXX ???] */
   1861 	if (fwi->fwi_data != NULL)
   1862 		return (0);
   1863 
   1864 	snprintf(fw_name, fw_name_size, BWI_FW_NAME_FORMAT, sc->sc_fw_version,
   1865 	    prefix, idx);
   1866 
   1867 	DPRINTF(sc, BWI_DBG_FIRMWARE, "opening firmware %s\n", fw_name);
   1868 
   1869 	error = firmware_open("bwi", fw_name, &fwh);
   1870 	if (error) {
   1871 		aprint_error_dev(sc->sc_dev, "firmware_open failed on %s\n",
   1872 		    fw_name);
   1873 		goto fail;
   1874 	}
   1875 
   1876 	fwi->fwi_size = firmware_get_size(fwh);
   1877 	if (fwi->fwi_size < sizeof(struct bwi_fwhdr)) {
   1878 		aprint_error_dev(sc->sc_dev,
   1879 		    "firmware image %s has no header\n",
   1880 		    fw_name);
   1881 		error = EIO;
   1882 		goto fail;
   1883 	}
   1884 
   1885 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
   1886 	    "firmware image %s, size %zx\n", fw_name, fwi->fwi_size);
   1887 
   1888 	fwi->fwi_data = firmware_malloc(fwi->fwi_size);
   1889 	if (fwi->fwi_data == NULL) {
   1890 		error = ENOMEM;
   1891 		firmware_close(fwh);
   1892 		goto fail;
   1893 	}
   1894 
   1895 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
   1896 	    "firmware image %s loaded at %p\n", fw_name, fwi->fwi_data);
   1897 
   1898 	fwi->fwi_data = firmware_malloc(fwi->fwi_size);
   1899 	error = firmware_read(fwh, 0, fwi->fwi_data, fwi->fwi_size);
   1900 	firmware_close(fwh);
   1901 	if (error)
   1902 		goto free_and_fail;
   1903 
   1904 	hdr = (const struct bwi_fwhdr *)fwi->fwi_data;
   1905 
   1906 	if (fw_type != BWI_FW_T_IV) {
   1907 		/*
   1908 		 * Don't verify IV's size, it has different meaning
   1909 		 */
   1910 		size_t fw_size = (size_t)be32toh(hdr->fw_size);
   1911 		if (fw_size != fwi->fwi_size - sizeof(*hdr)) {
   1912 			aprint_error_dev(sc->sc_dev, "firmware image %s"
   1913 			    " size mismatch, fw %zx, real %zx\n", fw_name,
   1914 			    fw_size, fwi->fwi_size - sizeof(*hdr));
   1915 			goto invalid;
   1916 		}
   1917 	}
   1918 
   1919 	if (hdr->fw_type != fw_type) {
   1920 		aprint_error_dev(sc->sc_dev, "firmware image %s"
   1921 		    " type mismatch, fw `%c', target `%c'\n", fw_name,
   1922 		    hdr->fw_type, fw_type);
   1923 		goto invalid;
   1924 	}
   1925 
   1926 	if (hdr->fw_gen != BWI_FW_GEN_1) {
   1927 		aprint_error_dev(sc->sc_dev, "firmware image %s"
   1928 		    " generation mismatch, fw %d, target %d\n", fw_name,
   1929 		    hdr->fw_gen, BWI_FW_GEN_1);
   1930 		goto invalid;
   1931 	}
   1932 
   1933 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
   1934 	    "firmware image %s loaded successfully\n", fw_name);
   1935 
   1936 	return (0);
   1937 
   1938 invalid:
   1939 	error = EINVAL;
   1940 
   1941 free_and_fail:
   1942 	firmware_free(fwi->fwi_data, fwi->fwi_size);
   1943 	fwi->fwi_data = NULL;
   1944 	fwi->fwi_size = 0;
   1945 
   1946 fail:
   1947 	return (error);
   1948 }
   1949 
   1950 static void
   1951 bwi_mac_fw_image_free(struct bwi_mac *mac, struct bwi_fw_image *fwi)
   1952 {
   1953 	if (fwi->fwi_data != NULL) {
   1954 		DPRINTF(mac->mac_sc, BWI_DBG_FIRMWARE, "freeing firmware %s\n",
   1955 		    fwi->fwi_name);
   1956 		firmware_free(fwi->fwi_data, fwi->fwi_size);
   1957 		fwi->fwi_data = NULL;
   1958 		fwi->fwi_size = 0;
   1959 	}
   1960 }
   1961 
   1962 static int
   1963 bwi_mac_fw_load(struct bwi_mac *mac)
   1964 {
   1965 	struct bwi_softc *sc = mac->mac_sc;
   1966 	const uint32_t *fw;
   1967 	uint16_t fw_rev;
   1968 	size_t fw_len, i;
   1969 
   1970 	/*
   1971 	 * Load ucode image
   1972 	 */
   1973 	fw = (const uint32_t *)(mac->mac_ucode + BWI_FWHDR_SZ);
   1974 	fw_len = (mac->mac_ucode_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
   1975 
   1976 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
   1977 	    "loading ucode image at %p, length %zx\n",
   1978 	    fw, fw_len);
   1979 
   1980 	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
   1981 	    BWI_MOBJ_CTRL_VAL(BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0));
   1982 	for (i = 0; i < fw_len; ++i) {
   1983 		CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
   1984 		DELAY(10);
   1985 	}
   1986 
   1987 	/*
   1988 	 * Load PCM image
   1989 	 */
   1990 	fw = (const uint32_t *)(mac->mac_pcm + BWI_FWHDR_SZ);
   1991 	fw_len = (mac->mac_pcm_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
   1992 
   1993 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
   1994 	    "loading PCM image at %p, length %zx\n",
   1995 	    fw, fw_len);
   1996 
   1997 	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
   1998 	    BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea));
   1999 	CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000);
   2000 
   2001 	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
   2002 	    BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb));
   2003 	for (i = 0; i < fw_len; ++i) {
   2004 		CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
   2005 		DELAY(10);
   2006 	}
   2007 
   2008 	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS);
   2009 	CSR_WRITE_4(sc, BWI_MAC_STATUS,
   2010 	    BWI_MAC_STATUS_UCODE_START |
   2011 	    BWI_MAC_STATUS_IHREN |
   2012 	    BWI_MAC_STATUS_INFRA);
   2013 #define NRETRY	200
   2014 	for (i = 0; i < NRETRY; ++i) {
   2015 		uint32_t intr_status;
   2016 
   2017 		intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
   2018 		if (intr_status == BWI_INTR_READY)
   2019 			break;
   2020 		DELAY(10);
   2021 	}
   2022 	if (i == NRETRY) {
   2023 		aprint_error_dev(sc->sc_dev,
   2024 		    "timeout loading ucode & pcm firmware\n");
   2025 		return (ETIMEDOUT);
   2026 	}
   2027 #undef NRETRY
   2028 
   2029 	CSR_READ_4(sc, BWI_MAC_INTR_STATUS);	/* dummy read */
   2030 
   2031 	fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV);
   2032 	if (fw_rev > BWI_FW_VERSION3_REVMAX) {
   2033 		aprint_error_dev(sc->sc_dev,
   2034 		    "firmware version 4 is not supported yet\n");
   2035 		return (ENODEV);
   2036 	}
   2037 
   2038 	aprint_normal_dev(sc->sc_dev, "firmware rev 0x%04x,"
   2039 	    " patch level 0x%04x\n", fw_rev,
   2040 	    MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
   2041 
   2042 	return (0);
   2043 }
   2044 
   2045 static int
   2046 bwi_mac_gpio_init(struct bwi_mac *mac)
   2047 {
   2048 	struct bwi_softc *sc = mac->mac_sc;
   2049 	struct bwi_regwin *old, *gpio_rw;
   2050 	uint32_t filt, bits;
   2051 	int error;
   2052 
   2053 	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK);
   2054 	/* TODO: LED */
   2055 
   2056 	CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf);
   2057 
   2058 	filt = 0x1f;
   2059 	bits = 0xf;
   2060 	if (sc->sc_bbp_id == BWI_BBPID_BCM4301) {
   2061 		filt |= 0x60;
   2062 		bits |= 0x60;
   2063 	}
   2064 	if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
   2065 		CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200);
   2066 		filt |= 0x200;
   2067 		bits |= 0x200;
   2068 	}
   2069 
   2070 	gpio_rw = BWI_GPIO_REGWIN(sc);
   2071 	error = bwi_regwin_switch(sc, gpio_rw, &old);
   2072 	if (error)
   2073 		return (error);
   2074 
   2075 	CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits);
   2076 
   2077 	return (bwi_regwin_switch(sc, old, NULL));
   2078 }
   2079 
   2080 static int
   2081 bwi_mac_gpio_fini(struct bwi_mac *mac)
   2082 {
   2083 	struct bwi_softc *sc = mac->mac_sc;
   2084 	struct bwi_regwin *old, *gpio_rw;
   2085 	int error;
   2086 
   2087 	gpio_rw = BWI_GPIO_REGWIN(sc);
   2088 	error = bwi_regwin_switch(sc, gpio_rw, &old);
   2089 	if (error)
   2090 		return (error);
   2091 
   2092 	CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0);
   2093 
   2094 	return (bwi_regwin_switch(sc, old, NULL));
   2095 }
   2096 
   2097 static int
   2098 bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct bwi_fw_image *fwi)
   2099 {
   2100 	struct bwi_softc *sc = mac->mac_sc;
   2101 	const struct bwi_fwhdr *hdr;
   2102 	const struct bwi_fw_iv *iv;
   2103 	size_t iv_img_size;
   2104 	int n, i;
   2105 
   2106 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
   2107 	    "loading %s at %p\n", fwi->fwi_name, fwi->fwi_data);
   2108 
   2109 	/* Get the number of IVs in the IV image */
   2110 	hdr = (const struct bwi_fwhdr *)fwi->fwi_data;
   2111 	n = be32toh(hdr->fw_iv_cnt);
   2112 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
   2113 	    "IV count %d\n", n);
   2114 
   2115 	/* Calculate the IV image size, for later sanity check */
   2116 	iv_img_size = fwi->fwi_size - sizeof(*hdr);
   2117 
   2118 	/* Locate the first IV */
   2119 	iv = (const struct bwi_fw_iv *)(fwi->fwi_data + sizeof(*hdr));
   2120 
   2121 	for (i = 0; i < n; ++i) {
   2122 		uint16_t iv_ofs, ofs;
   2123 		int sz = 0;
   2124 
   2125 		if (iv_img_size < sizeof(iv->iv_ofs)) {
   2126 			aprint_error_dev(sc->sc_dev,
   2127 			    "invalid IV image, ofs\n");
   2128 			return (EINVAL);
   2129 		}
   2130 		iv_img_size -= sizeof(iv->iv_ofs);
   2131 		sz += sizeof(iv->iv_ofs);
   2132 
   2133 		iv_ofs = be16toh(iv->iv_ofs);
   2134 
   2135 		ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK);
   2136 		if (ofs >= 0x1000) {
   2137 			aprint_error_dev(sc->sc_dev, "invalid ofs (0x%04x) "
   2138 			    "for %dth iv\n", ofs, i);
   2139 			return (EINVAL);
   2140 		}
   2141 
   2142 		if (iv_ofs & BWI_FW_IV_IS_32BIT) {
   2143 			uint32_t val32;
   2144 
   2145 			if (iv_img_size < sizeof(iv->iv_val.val32)) {
   2146 				aprint_error_dev(sc->sc_dev,
   2147 				    "invalid IV image, val32\n");
   2148 				return (EINVAL);
   2149 			}
   2150 			iv_img_size -= sizeof(iv->iv_val.val32);
   2151 			sz += sizeof(iv->iv_val.val32);
   2152 
   2153 			val32 = be32toh(iv->iv_val.val32);
   2154 			CSR_WRITE_4(sc, ofs, val32);
   2155 		} else {
   2156 			uint16_t val16;
   2157 
   2158 			if (iv_img_size < sizeof(iv->iv_val.val16)) {
   2159 				aprint_error_dev(sc->sc_dev,
   2160 				    "invalid IV image, val16\n");
   2161 				return (EINVAL);
   2162 			}
   2163 			iv_img_size -= sizeof(iv->iv_val.val16);
   2164 			sz += sizeof(iv->iv_val.val16);
   2165 
   2166 			val16 = be16toh(iv->iv_val.val16);
   2167 			CSR_WRITE_2(sc, ofs, val16);
   2168 		}
   2169 
   2170 		iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz);
   2171 	}
   2172 
   2173 	if (iv_img_size != 0) {
   2174 		aprint_error_dev(sc->sc_dev,
   2175 		    "invalid IV image, size left %zx\n", iv_img_size);
   2176 		return (EINVAL);
   2177 	}
   2178 
   2179 	return (0);
   2180 }
   2181 
   2182 static int
   2183 bwi_mac_fw_init(struct bwi_mac *mac)
   2184 {
   2185 	struct bwi_softc *sc = mac->mac_sc;
   2186 	int error;
   2187 
   2188 	error = bwi_mac_fw_load_iv(mac, &mac->mac_iv_fwi);
   2189 	if (error) {
   2190 		aprint_error_dev(sc->sc_dev, "load IV failed\n");
   2191 		return (error);
   2192 	}
   2193 
   2194 	if (mac->mac_iv_ext != NULL) {
   2195 		error = bwi_mac_fw_load_iv(mac, &mac->mac_iv_ext_fwi);
   2196 		if (error)
   2197 			aprint_error_dev(sc->sc_dev, "load ExtIV failed\n");
   2198 	}
   2199 
   2200 	return (error);
   2201 }
   2202 
   2203 static void
   2204 bwi_mac_opmode_init(struct bwi_mac *mac)
   2205 {
   2206 	struct bwi_softc *sc = mac->mac_sc;
   2207 	struct ieee80211com *ic = &sc->sc_ic;
   2208 	uint32_t mac_status;
   2209 	uint16_t pre_tbtt;
   2210 
   2211 	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
   2212 	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
   2213 	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
   2214 
   2215 	/* Set probe resp timeout to infinite */
   2216 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0);
   2217 
   2218 	/*
   2219 	 * TODO: factor out following part
   2220 	 */
   2221 
   2222 	mac_status = CSR_READ_4(sc, BWI_MAC_STATUS);
   2223 	mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP |
   2224 	    BWI_MAC_STATUS_PASS_CTL |
   2225 	    BWI_MAC_STATUS_PASS_BADPLCP |
   2226 	    BWI_MAC_STATUS_PASS_BADFCS |
   2227 	    BWI_MAC_STATUS_PROMISC);
   2228 	mac_status |= BWI_MAC_STATUS_INFRA;
   2229 
   2230 	/* Always turn on PROMISC on old hardware */
   2231 	if (mac->mac_rev < 5)
   2232 		mac_status |= BWI_MAC_STATUS_PROMISC;
   2233 
   2234 	switch (ic->ic_opmode) {
   2235 	case IEEE80211_M_IBSS:
   2236 		mac_status &= ~BWI_MAC_STATUS_INFRA;
   2237 		break;
   2238 	case IEEE80211_M_HOSTAP:
   2239 		mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP;
   2240 		break;
   2241 	case IEEE80211_M_MONITOR:
   2242 #if 0
   2243 		/* Do you want data from your microwave oven? */
   2244 		mac_status |= BWI_MAC_STATUS_PASS_CTL |
   2245 			      BWI_MAC_STATUS_PASS_BADPLCP |
   2246 			      BWI_MAC_STATUS_PASS_BADFCS;
   2247 #else
   2248 		mac_status |= BWI_MAC_STATUS_PASS_CTL;
   2249 #endif
   2250 		/* Promisc? */
   2251 		break;
   2252 	default:
   2253 		break;
   2254 	}
   2255 
   2256 	if (sc->sc_if.if_flags & IFF_PROMISC)
   2257 		mac_status |= BWI_MAC_STATUS_PROMISC;
   2258 
   2259 	CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status);
   2260 
   2261 	if (ic->ic_opmode != IEEE80211_M_IBSS &&
   2262 	    ic->ic_opmode != IEEE80211_M_HOSTAP) {
   2263 		if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3)
   2264 			pre_tbtt = 100;
   2265 		else
   2266 			pre_tbtt = 50;
   2267 	} else
   2268 		pre_tbtt = 2;
   2269 	CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt);
   2270 }
   2271 
   2272 static void
   2273 bwi_mac_hostflags_init(struct bwi_mac *mac)
   2274 {
   2275 	struct bwi_softc *sc = mac->mac_sc;
   2276 	struct bwi_phy *phy = &mac->mac_phy;
   2277 	struct bwi_rf *rf = &mac->mac_rf;
   2278 	uint64_t host_flags;
   2279 
   2280 	if (phy->phy_mode == IEEE80211_MODE_11A)
   2281 		return;
   2282 
   2283 	host_flags = HFLAGS_READ(mac);
   2284 	host_flags |= BWI_HFLAG_SYM_WA;
   2285 
   2286 	if (phy->phy_mode == IEEE80211_MODE_11G) {
   2287 		if (phy->phy_rev == 1)
   2288 			host_flags |= BWI_HFLAG_GDC_WA;
   2289 		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
   2290 			host_flags |= BWI_HFLAG_OFDM_PA;
   2291 	} else if (phy->phy_mode == IEEE80211_MODE_11B) {
   2292 		if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050)
   2293 			host_flags &= ~BWI_HFLAG_GDC_WA;
   2294 	} else {
   2295 		panic("unknown PHY mode %u\n", phy->phy_mode);
   2296 	}
   2297 
   2298 	HFLAGS_WRITE(mac, host_flags);
   2299 }
   2300 
   2301 static void
   2302 bwi_mac_bss_param_init(struct bwi_mac *mac)
   2303 {
   2304 	struct bwi_softc *sc = mac->mac_sc;
   2305 	struct bwi_phy *phy = &mac->mac_phy;
   2306 	struct bwi_retry_lim lim;
   2307 	uint16_t cw_min;
   2308 
   2309 	/*
   2310 	 * Set short/long retry limits
   2311 	 */
   2312 	memset(&lim, 0, sizeof(lim));
   2313 	lim.shretry = BWI_SHRETRY;
   2314 	lim.shretry_fb = BWI_SHRETRY_FB;
   2315 	lim.lgretry = BWI_LGRETRY;
   2316 	lim.lgretry_fb = BWI_LGRETRY_FB;
   2317 	bwi_mac_set_retry_lim(mac, &lim);
   2318 
   2319 	/*
   2320 	 * Implicitly prevent firmware from sending probe response
   2321 	 * by setting its "probe response timeout" to 1us.
   2322 	 */
   2323 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1);
   2324 
   2325 	/*
   2326 	 * XXX MAC level acknowledge and CW min/max should depend
   2327 	 * on the char rateset of the IBSS/BSS to join.
   2328 	 */
   2329 
   2330 	/*
   2331 	 * Set MAC level acknowledge rates
   2332 	 */
   2333 	bwi_mac_set_ackrates(mac, &sc->sc_ic.ic_sup_rates[phy->phy_mode]);
   2334 
   2335 	/*
   2336 	 * Set CW min
   2337 	 */
   2338 	if (phy->phy_mode == IEEE80211_MODE_11B)
   2339 		cw_min = IEEE80211_CW_MIN_0;
   2340 	else
   2341 		cw_min = IEEE80211_CW_MIN_1;
   2342 	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min);
   2343 
   2344 	/*
   2345 	 * Set CW max
   2346 	 */
   2347 	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX,
   2348 	    IEEE80211_CW_MAX);
   2349 }
   2350 
   2351 static void
   2352 bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim)
   2353 {
   2354 	/* Short/Long retry limit */
   2355 	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY,
   2356 	    lim->shretry);
   2357 	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY,
   2358 	    lim->lgretry);
   2359 
   2360 	/* Short/Long retry fallback limit */
   2361 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB,
   2362 	    lim->shretry_fb);
   2363 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB,
   2364 	    lim->lgretry_fb);
   2365 }
   2366 
   2367 static void
   2368 bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs)
   2369 {
   2370 	int i;
   2371 
   2372 	/* XXX not standard conforming */
   2373 	for (i = 0; i < rs->rs_nrates; ++i) {
   2374 		enum bwi_ieee80211_modtype modtype;
   2375 		uint16_t ofs;
   2376 
   2377 		modtype = bwi_ieee80211_rate2modtype(rs->rs_rates[i]);
   2378 		switch (modtype) {
   2379 		case IEEE80211_MODTYPE_DS:
   2380 			ofs = 0x4c0;
   2381 			ofs += (bwi_ieee80211_rate2plcp(rs->rs_rates[i],
   2382 			    IEEE80211_MODE_11B) & 0xf) * 2;
   2383 			break;
   2384 		case IEEE80211_MODTYPE_OFDM:
   2385 			ofs = 0x480;
   2386 			ofs += (bwi_ieee80211_rate2plcp(rs->rs_rates[i],
   2387 			    IEEE80211_MODE_11G) & 0xf) * 2;
   2388 			break;
   2389 		default:
   2390 			panic("unsupported modtype %u\n", modtype);
   2391 		}
   2392 
   2393 		MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20,
   2394 		    MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs));
   2395 	}
   2396 }
   2397 
   2398 static int
   2399 bwi_mac_start(struct bwi_mac *mac)
   2400 {
   2401 	struct bwi_softc *sc = mac->mac_sc;
   2402 
   2403 	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
   2404 	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY);
   2405 
   2406 	/* Flush pending bus writes */
   2407 	CSR_READ_4(sc, BWI_MAC_STATUS);
   2408 	CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
   2409 
   2410 	return (bwi_mac_config_ps(mac));
   2411 }
   2412 
   2413 static int
   2414 bwi_mac_stop(struct bwi_mac *mac)
   2415 {
   2416 	struct bwi_softc *sc = mac->mac_sc;
   2417 	int error, i;
   2418 
   2419 	error = bwi_mac_config_ps(mac);
   2420 	if (error)
   2421 		return (error);
   2422 
   2423 	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
   2424 
   2425 	/* Flush pending bus write */
   2426 	CSR_READ_4(sc, BWI_MAC_STATUS);
   2427 
   2428 #define NRETRY	10000
   2429 	for (i = 0; i < NRETRY; ++i) {
   2430 		if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY)
   2431 			break;
   2432 		DELAY(1);
   2433 	}
   2434 	if (i == NRETRY) {
   2435 		aprint_error_dev(sc->sc_dev, "can't stop MAC\n");
   2436 		return (ETIMEDOUT);
   2437 	}
   2438 #undef NRETRY
   2439 
   2440 	return (0);
   2441 }
   2442 
   2443 static int
   2444 bwi_mac_config_ps(struct bwi_mac *mac)
   2445 {
   2446 	struct bwi_softc *sc = mac->mac_sc;
   2447 	uint32_t status;
   2448 
   2449 	status = CSR_READ_4(sc, BWI_MAC_STATUS);
   2450 
   2451 	status &= ~BWI_MAC_STATUS_HW_PS;
   2452 	status |= BWI_MAC_STATUS_WAKEUP;
   2453 	CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
   2454 
   2455 	/* Flush pending bus write */
   2456 	CSR_READ_4(sc, BWI_MAC_STATUS);
   2457 
   2458 	if (mac->mac_rev >= 5) {
   2459 		int i;
   2460 
   2461 #define NRETRY	100
   2462 		for (i = 0; i < NRETRY; ++i) {
   2463 			if (MOBJ_READ_2(mac, BWI_COMM_MOBJ,
   2464 			    BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS)
   2465 				break;
   2466 			DELAY(10);
   2467 		}
   2468 		if (i == NRETRY) {
   2469 			aprint_error_dev(sc->sc_dev, "config PS failed\n");
   2470 			return (ETIMEDOUT);
   2471 		}
   2472 #undef NRETRY
   2473 	}
   2474 	return (0);
   2475 }
   2476 
   2477 static void
   2478 bwi_mac_reset_hwkeys(struct bwi_mac *mac)
   2479 {
   2480 	/* TODO: firmware crypto */
   2481 	MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS);
   2482 }
   2483 
   2484 static void
   2485 bwi_mac_shutdown(struct bwi_mac *mac)
   2486 {
   2487 	struct bwi_softc *sc = mac->mac_sc;
   2488 	int i;
   2489 
   2490 	if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS)
   2491 		(sc->sc_free_txstats)(sc);
   2492 
   2493 	(sc->sc_free_rx_ring)(sc);
   2494 
   2495 	for (i = 0; i < BWI_TX_NRING; ++i)
   2496 		(sc->sc_free_tx_ring)(sc, i);
   2497 
   2498 	bwi_rf_off(mac);
   2499 
   2500 	/* TODO: LED */
   2501 
   2502 	bwi_mac_gpio_fini(mac);
   2503 
   2504 	bwi_rf_off(mac); /* XXX again */
   2505 	CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
   2506 	bwi_regwin_disable(sc, &mac->mac_regwin, 0);
   2507 
   2508 	mac->mac_flags &= ~BWI_MAC_F_INITED;
   2509 }
   2510 
   2511 static int
   2512 bwi_mac_get_property(struct bwi_mac *mac)
   2513 {
   2514 	struct bwi_softc *sc = mac->mac_sc;
   2515 	enum bwi_bus_space old_bus_space;
   2516 	uint32_t val;
   2517 
   2518 	/*
   2519 	 * Byte swap
   2520 	 */
   2521 	val = CSR_READ_4(sc, BWI_MAC_STATUS);
   2522 	if (val & BWI_MAC_STATUS_BSWAP) {
   2523 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "need byte swap\n");
   2524 		mac->mac_flags |= BWI_MAC_F_BSWAP;
   2525 	}
   2526 
   2527 	/*
   2528 	 * DMA address space
   2529 	 */
   2530 	old_bus_space = sc->sc_bus_space;
   2531 
   2532 	val = CSR_READ_4(sc, BWI_STATE_HI);
   2533 	if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) &
   2534 	    BWI_STATE_HI_FLAG_64BIT) {
   2535 		/* 64bit address */
   2536 		sc->sc_bus_space = BWI_BUS_SPACE_64BIT;
   2537 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "64bit bus space\n");
   2538 	} else {
   2539 		uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL;
   2540 
   2541 		CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK);
   2542 		if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) {
   2543 			/* 32bit address */
   2544 			sc->sc_bus_space = BWI_BUS_SPACE_32BIT;
   2545 			DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH,
   2546 			    "32bit bus space\n");
   2547 		} else {
   2548 			/* 30bit address */
   2549 			sc->sc_bus_space = BWI_BUS_SPACE_30BIT;
   2550 			DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH,
   2551 			    "30bit bus space\n");
   2552 		}
   2553 	}
   2554 
   2555 	if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) {
   2556 		aprint_error_dev(sc->sc_dev, "MACs bus space mismatch!\n");
   2557 		return (ENXIO);
   2558 	}
   2559 
   2560 	return (0);
   2561 }
   2562 
   2563 static void
   2564 bwi_mac_updateslot(struct bwi_mac *mac, int shslot)
   2565 {
   2566 	uint16_t slot_time;
   2567 
   2568 	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
   2569 		return;
   2570 
   2571 	if (shslot)
   2572 		slot_time = IEEE80211_DUR_SHSLOT;
   2573 	else
   2574 		slot_time = IEEE80211_DUR_SLOT;
   2575 
   2576 	CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME,
   2577 	    slot_time + BWI_MAC_SLOTTIME_ADJUST);
   2578 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time);
   2579 }
   2580 
   2581 static int
   2582 bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev)
   2583 {
   2584 	struct bwi_mac *mac;
   2585 	int i;
   2586 
   2587 	KASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0);
   2588 
   2589 	if (sc->sc_nmac == BWI_MAC_MAX) {
   2590 		aprint_error_dev(sc->sc_dev, "too many MACs\n");
   2591 		return (0);
   2592 	}
   2593 
   2594 	/*
   2595 	 * More than one MAC is only supported by BCM4309
   2596 	 */
   2597 	if (sc->sc_nmac != 0 &&
   2598 	    sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM4309) {
   2599 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH,
   2600 		    "ignore %dth MAC\n", sc->sc_nmac);
   2601 		return (0);
   2602 	}
   2603 
   2604 	mac = &sc->sc_mac[sc->sc_nmac];
   2605 
   2606 	/* XXX will this happen? */
   2607 	if (BWI_REGWIN_EXIST(&mac->mac_regwin)) {
   2608 		aprint_error_dev(sc->sc_dev, "%dth MAC already attached\n",
   2609 		    sc->sc_nmac);
   2610 		return (0);
   2611 	}
   2612 
   2613 	/*
   2614 	 * Test whether the revision of this MAC is supported
   2615 	 */
   2616 	for (i = 0; i < __arraycount(bwi_sup_macrev); ++i) {
   2617 		if (bwi_sup_macrev[i] == rev)
   2618 			break;
   2619 	}
   2620 	if (i == __arraycount(bwi_sup_macrev)) {
   2621 		aprint_error_dev(sc->sc_dev, "MAC rev %u is not supported\n",
   2622 		    rev);
   2623 		return (ENXIO);
   2624 	}
   2625 
   2626 	BWI_CREATE_MAC(mac, sc, id, rev);
   2627 	sc->sc_nmac++;
   2628 
   2629 	if (mac->mac_rev < 5) {
   2630 		mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS;
   2631 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "has TX stats\n");
   2632 	} else {
   2633 		mac->mac_flags |= BWI_MAC_F_PHYE_RESET;
   2634 	}
   2635 
   2636 	aprint_normal_dev(sc->sc_dev, "MAC: rev %u\n", rev);
   2637 	return (0);
   2638 }
   2639 
   2640 static void
   2641 bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0)
   2642 {
   2643 	int bbp_atten, rf_atten, rf_atten_lim = -1;
   2644 
   2645 	bbp_atten = *bbp_atten0;
   2646 	rf_atten = *rf_atten0;
   2647 
   2648 	/*
   2649 	 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
   2650 	 * as much as BBP attenuation, so we try our best to keep RF
   2651 	 * attenuation within range.  BBP attenuation will be clamped
   2652 	 * later if it is out of range during balancing.
   2653 	 *
   2654 	 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
   2655 	 */
   2656 
   2657 	/*
   2658 	 * Use BBP attenuation to balance RF attenuation
   2659 	 */
   2660 	if (rf_atten < 0)
   2661 		rf_atten_lim = 0;
   2662 	else if (rf_atten > BWI_RF_ATTEN_MAX0)
   2663 		rf_atten_lim = BWI_RF_ATTEN_MAX0;
   2664 
   2665 	if (rf_atten_lim >= 0) {
   2666 		bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim));
   2667 		rf_atten = rf_atten_lim;
   2668 	}
   2669 
   2670 	/*
   2671 	 * If possible, use RF attenuation to balance BBP attenuation
   2672 	 * NOTE: RF attenuation is still kept within range.
   2673 	 */
   2674 	while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) {
   2675 		bbp_atten -= BWI_RF_ATTEN_FACTOR;
   2676 		++rf_atten;
   2677 	}
   2678 	while (rf_atten > 0 && bbp_atten < 0) {
   2679 		bbp_atten += BWI_RF_ATTEN_FACTOR;
   2680 		--rf_atten;
   2681 	}
   2682 
   2683 	/* RF attenuation MUST be within range */
   2684 	KASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0);
   2685 
   2686 	/*
   2687 	 * Clamp BBP attenuation
   2688 	 */
   2689 	if (bbp_atten < 0)
   2690 		bbp_atten = 0;
   2691 	else if (bbp_atten > BWI_BBP_ATTEN_MAX)
   2692 		bbp_atten = BWI_BBP_ATTEN_MAX;
   2693 
   2694 	*rf_atten0 = rf_atten;
   2695 	*bbp_atten0 = bbp_atten;
   2696 }
   2697 
   2698 static void
   2699 bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj)
   2700 {
   2701 	struct bwi_softc *sc = mac->mac_sc;
   2702 	struct bwi_rf *rf = &mac->mac_rf;
   2703 	struct bwi_tpctl tpctl;
   2704 	int bbp_atten, rf_atten, tp_ctrl1;
   2705 
   2706 	memcpy(&tpctl, &mac->mac_tpctl, sizeof(tpctl));
   2707 
   2708 	/* NOTE: Use signed value to do calulation */
   2709 	bbp_atten = tpctl.bbp_atten;
   2710 	rf_atten = tpctl.rf_atten;
   2711 	tp_ctrl1 = tpctl.tp_ctrl1;
   2712 
   2713 	bbp_atten += bbp_atten_adj;
   2714 	rf_atten += rf_atten_adj;
   2715 
   2716 	bwi_mac_balance_atten(&bbp_atten, &rf_atten);
   2717 
   2718 	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) {
   2719 		if (rf_atten <= 1) {
   2720 			if (tp_ctrl1 == 0) {
   2721 				tp_ctrl1 = 3;
   2722 				bbp_atten += 2;
   2723 				rf_atten += 2;
   2724 			} else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
   2725 				bbp_atten +=
   2726 				(BWI_RF_ATTEN_FACTOR * (rf_atten - 2));
   2727 				rf_atten = 2;
   2728 			}
   2729 		} else if (rf_atten > 4 && tp_ctrl1 != 0) {
   2730 			tp_ctrl1 = 0;
   2731 			if (bbp_atten < 3) {
   2732 				bbp_atten += 2;
   2733 				rf_atten -= 3;
   2734 			} else {
   2735 				bbp_atten -= 2;
   2736 				rf_atten -= 2;
   2737 			}
   2738 		}
   2739 		bwi_mac_balance_atten(&bbp_atten, &rf_atten);
   2740 	}
   2741 
   2742 	tpctl.bbp_atten = bbp_atten;
   2743 	tpctl.rf_atten = rf_atten;
   2744 	tpctl.tp_ctrl1 = tp_ctrl1;
   2745 
   2746 	bwi_mac_lock(mac);
   2747 	bwi_mac_set_tpctl_11bg(mac, &tpctl);
   2748 	bwi_mac_unlock(mac);
   2749 }
   2750 
   2751 /*
   2752  * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
   2753  */
   2754 static void
   2755 bwi_mac_calibrate_txpower(struct bwi_mac *mac, enum bwi_txpwrcb_type type)
   2756 {
   2757 	struct bwi_softc *sc = mac->mac_sc;
   2758 	struct bwi_rf *rf = &mac->mac_rf;
   2759 	int8_t tssi[4], tssi_avg, cur_txpwr;
   2760 	int error, i, ofdm_tssi;
   2761 	int txpwr_diff, rf_atten_adj, bbp_atten_adj;
   2762 
   2763 	if (!sc->sc_txpwr_calib)
   2764 		return;
   2765 
   2766 	if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) {
   2767 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
   2768 		    "tpctl error happened, can't set txpower\n");
   2769 		return;
   2770 	}
   2771 
   2772 	if (BWI_IS_BRCM_BU4306(sc)) {
   2773 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
   2774 		    "BU4306, can't set txpower\n");
   2775 		return;
   2776 	}
   2777 
   2778 	/*
   2779 	 * Save latest TSSI and reset the related memory objects
   2780 	 */
   2781 	ofdm_tssi = 0;
   2782 	error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS);
   2783 	if (error) {
   2784 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "no DS tssi\n");
   2785 
   2786 		if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) {
   2787 			if (type == BWI_TXPWR_FORCE) {
   2788 				rf_atten_adj = 0;
   2789 				bbp_atten_adj = 1;
   2790 				goto calib;
   2791 			} else {
   2792 				return;
   2793 			}
   2794 		}
   2795 
   2796 		error = bwi_rf_get_latest_tssi(mac, tssi,
   2797 		    BWI_COMM_MOBJ_TSSI_OFDM);
   2798 		if (error) {
   2799 			DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
   2800 			    "no OFDM tssi\n");
   2801 			if (type == BWI_TXPWR_FORCE) {
   2802 				rf_atten_adj = 0;
   2803 				bbp_atten_adj = 1;
   2804 				goto calib;
   2805 			} else {
   2806 				return;
   2807 			}
   2808 		}
   2809 
   2810 		for (i = 0; i < 4; ++i) {
   2811 			tssi[i] += 0x20;
   2812 			tssi[i] &= 0x3f;
   2813 		}
   2814 		ofdm_tssi = 1;
   2815 	}
   2816 	bwi_rf_clear_tssi(mac);
   2817 
   2818 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
   2819 	    "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
   2820 	    tssi[0], tssi[1], tssi[2], tssi[3]);
   2821 
   2822 	/*
   2823 	 * Calculate RF/BBP attenuation adjustment based on
   2824 	 * the difference between desired TX power and sampled
   2825 	 * TX power.
   2826 	 */
   2827 	/* +8 == "each incremented by 1/2" */
   2828 	tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4;
   2829 	if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS))
   2830 		tssi_avg -= 13;
   2831 
   2832 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "tssi avg %d\n", tssi_avg);
   2833 
   2834 	error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr);
   2835 	if (error)
   2836 		return;
   2837 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "current txpower %d\n",
   2838 	    cur_txpwr);
   2839 
   2840 	txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */
   2841 
   2842 	rf_atten_adj = -howmany(txpwr_diff, 8);
   2843 
   2844 	if (type == BWI_TXPWR_INIT) {
   2845 		/*
   2846 		 * Move toward EEPROM max TX power as fast as we can
   2847 		 */
   2848 		bbp_atten_adj = -txpwr_diff;
   2849 	} else {
   2850 		bbp_atten_adj = -(txpwr_diff / 2);
   2851 	}
   2852 	bbp_atten_adj -= (BWI_RF_ATTEN_FACTOR * rf_atten_adj);
   2853 
   2854 	if (rf_atten_adj == 0 && bbp_atten_adj == 0) {
   2855 		DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n",
   2856 		    "no need to adjust RF/BBP attenuation");
   2857 		/* TODO: LO */
   2858 		return;
   2859 	}
   2860 
   2861 calib:
   2862 	DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
   2863 	    "rf atten adjust %d, bbp atten adjust %d\n",
   2864 	    rf_atten_adj, bbp_atten_adj);
   2865 	bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj);
   2866 	/* TODO: LO */
   2867 }
   2868 
   2869 static void
   2870 bwi_mac_lock(struct bwi_mac *mac)
   2871 {
   2872 	struct bwi_softc *sc = mac->mac_sc;
   2873 	struct ieee80211com *ic = &sc->sc_ic;
   2874 
   2875 	KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0);
   2876 
   2877 	if (mac->mac_rev < 3)
   2878 		bwi_mac_stop(mac);
   2879 	else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
   2880 		bwi_mac_config_ps(mac);
   2881 
   2882 	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
   2883 
   2884 	/* Flush pending bus write */
   2885 	CSR_READ_4(sc, BWI_MAC_STATUS);
   2886 	DELAY(10);
   2887 
   2888 	mac->mac_flags |= BWI_MAC_F_LOCKED;
   2889 }
   2890 
   2891 static void
   2892 bwi_mac_unlock(struct bwi_mac *mac)
   2893 {
   2894 	struct bwi_softc *sc = mac->mac_sc;
   2895 	struct ieee80211com *ic = &sc->sc_ic;
   2896 
   2897 	KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED);
   2898 
   2899 	CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */
   2900 
   2901 	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
   2902 
   2903 	if (mac->mac_rev < 3)
   2904 		bwi_mac_start(mac);
   2905 	else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
   2906 		bwi_mac_config_ps(mac);
   2907 
   2908 	mac->mac_flags &= ~BWI_MAC_F_LOCKED;
   2909 }
   2910 
   2911 static void
   2912 bwi_mac_set_promisc(struct bwi_mac *mac, int promisc)
   2913 {
   2914 	struct bwi_softc *sc = mac->mac_sc;
   2915 
   2916 	if (mac->mac_rev < 5) /* Promisc is always on */
   2917 		return;
   2918 
   2919 	if (promisc)
   2920 		CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
   2921 	else
   2922 		CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
   2923 }
   2924 
   2925 /* PHY */
   2926 
   2927 static void
   2928 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
   2929 {
   2930 	struct bwi_softc *sc = mac->mac_sc;
   2931 
   2932 	/* TODO: 11A */
   2933 	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
   2934 	CSR_WRITE_2(sc, BWI_PHY_DATA, data);
   2935 }
   2936 
   2937 static uint16_t
   2938 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
   2939 {
   2940 	struct bwi_softc *sc = mac->mac_sc;
   2941 
   2942 	/* TODO: 11A */
   2943 	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
   2944 	return (CSR_READ_2(sc, BWI_PHY_DATA));
   2945 }
   2946 
   2947 static int
   2948 bwi_phy_attach(struct bwi_mac *mac)
   2949 {
   2950 	struct bwi_softc *sc = mac->mac_sc;
   2951 	struct bwi_phy *phy = &mac->mac_phy;
   2952 	uint8_t phyrev, phytype, phyver;
   2953 	uint16_t val;
   2954 	int i;
   2955 
   2956 	/* Get PHY type/revision/version */
   2957 	val = CSR_READ_2(sc, BWI_PHYINFO);
   2958 	phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
   2959 	phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
   2960 	phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
   2961 	aprint_normal_dev(sc->sc_dev, "PHY type %d, rev %d, ver %d\n",
   2962 	    phytype, phyrev, phyver);
   2963 
   2964 	/*
   2965 	 * Verify whether the revision of the PHY type is supported
   2966 	 * Convert PHY type to ieee80211_phymode
   2967 	 */
   2968 	switch (phytype) {
   2969 	case BWI_PHYINFO_TYPE_11A:
   2970 		if (phyrev >= 4) {
   2971 			aprint_error_dev(sc->sc_dev,
   2972 			    "unsupported 11A PHY, rev %u\n",
   2973 			    phyrev);
   2974 			return (ENXIO);
   2975 		}
   2976 		phy->phy_init = bwi_phy_init_11a;
   2977 		phy->phy_mode = IEEE80211_MODE_11A;
   2978 		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
   2979 		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
   2980 		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
   2981 		break;
   2982 	case BWI_PHYINFO_TYPE_11B:
   2983 		for (i = 0; i < __arraycount(bwi_sup_bphy); ++i) {
   2984 			if (phyrev == bwi_sup_bphy[i].rev) {
   2985 				phy->phy_init = bwi_sup_bphy[i].init;
   2986 				break;
   2987 			}
   2988 		}
   2989 		if (i == __arraycount(bwi_sup_bphy)) {
   2990 			aprint_error_dev(sc->sc_dev,
   2991 			    "unsupported 11B PHY, rev %u\n",
   2992 			    phyrev);
   2993 			return (ENXIO);
   2994 		}
   2995 		phy->phy_mode = IEEE80211_MODE_11B;
   2996 		break;
   2997 	case BWI_PHYINFO_TYPE_11G:
   2998 		if (phyrev > 8) {
   2999 			aprint_error_dev(sc->sc_dev,
   3000 			    "unsupported 11G PHY, rev %u\n",
   3001 			    phyrev);
   3002 			return (ENXIO);
   3003 		}
   3004 		phy->phy_init = bwi_phy_init_11g;
   3005 		phy->phy_mode = IEEE80211_MODE_11G;
   3006 		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
   3007 		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
   3008 		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
   3009 		break;
   3010 	default:
   3011 		aprint_error_dev(sc->sc_dev, "unsupported PHY type %d\n",
   3012 		    phytype);
   3013 		return (ENXIO);
   3014 	}
   3015 	phy->phy_rev = phyrev;
   3016 	phy->phy_version = phyver;
   3017 
   3018 	return (0);
   3019 }
   3020 
   3021 static void
   3022 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
   3023 {
   3024 	struct bwi_phy *phy = &mac->mac_phy;
   3025 	uint16_t mask = 0x000f;
   3026 
   3027 	if (phy->phy_version == 0) {
   3028 		CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
   3029 		    __SHIFTIN(bbp_atten, mask));
   3030 	} else {
   3031 		if (phy->phy_version > 1)
   3032 			mask <<= 2;
   3033 		else
   3034 			mask <<= 3;
   3035 		PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
   3036 		    __SHIFTIN(bbp_atten, mask));
   3037 	}
   3038 }
   3039 
   3040 static int
   3041 bwi_phy_calibrate(struct bwi_mac *mac)
   3042 {
   3043 	struct bwi_phy *phy = &mac->mac_phy;
   3044 
   3045 	/* Dummy read */
   3046 	CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
   3047 
   3048 	/* Don't re-init */
   3049 	if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
   3050 		return (0);
   3051 
   3052 	if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
   3053 		bwi_mac_reset(mac, 0);
   3054 		bwi_phy_init_11g(mac);
   3055 		bwi_mac_reset(mac, 1);
   3056 	}
   3057 
   3058 	phy->phy_flags |= BWI_PHY_F_CALIBRATED;
   3059 
   3060 	return (0);
   3061 }
   3062 
   3063 static void
   3064 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
   3065 {
   3066 	struct bwi_phy *phy = &mac->mac_phy;
   3067 
   3068 	KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0);
   3069 	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
   3070 	PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
   3071 }
   3072 
   3073 static void
   3074 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
   3075 {
   3076 	struct bwi_phy *phy = &mac->mac_phy;
   3077 
   3078 	KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
   3079 	    phy->phy_tbl_ctrl != 0);
   3080 
   3081 	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
   3082 	PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
   3083 	PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
   3084 }
   3085 
   3086 static void
   3087 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
   3088 {
   3089 	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
   3090 	PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
   3091 }
   3092 
   3093 static int16_t
   3094 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
   3095 {
   3096 	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
   3097 	return ((int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA));
   3098 }
   3099 
   3100 static void
   3101 bwi_phy_init_11a(struct bwi_mac *mac)
   3102 {
   3103 	/* TODO: 11A */
   3104 }
   3105 
   3106 static void
   3107 bwi_phy_init_11g(struct bwi_mac *mac)
   3108 {
   3109 	struct bwi_softc *sc = mac->mac_sc;
   3110 	struct bwi_phy *phy = &mac->mac_phy;
   3111 	struct bwi_rf *rf = &mac->mac_rf;
   3112 	const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
   3113 
   3114 	if (phy->phy_rev == 1)
   3115 		bwi_phy_init_11b_rev5(mac);
   3116 	else
   3117 		bwi_phy_init_11b_rev6(mac);
   3118 
   3119 	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
   3120 		bwi_phy_config_11g(mac);
   3121 
   3122 	if (phy->phy_rev >= 2) {
   3123 		PHY_WRITE(mac, 0x814, 0);
   3124 		PHY_WRITE(mac, 0x815, 0);
   3125 
   3126 		if (phy->phy_rev == 2) {
   3127 			PHY_WRITE(mac, 0x811, 0);
   3128 			PHY_WRITE(mac, 0x15, 0xc0);
   3129 		} else if (phy->phy_rev > 5) {
   3130 			PHY_WRITE(mac, 0x811, 0x400);
   3131 			PHY_WRITE(mac, 0x15, 0xc0);
   3132 		}
   3133 	}
   3134 
   3135 	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
   3136 		uint16_t val;
   3137 
   3138 		val = PHY_READ(mac, 0x400) & 0xff;
   3139 		if (val == 3 || val == 5) {
   3140 			PHY_WRITE(mac, 0x4c2, 0x1816);
   3141 			PHY_WRITE(mac, 0x4c3, 0x8006);
   3142 			if (val == 5) {
   3143 				PHY_FILT_SETBITS(mac, 0x4cc,
   3144 						 0xff, 0x1f00);
   3145 			}
   3146 		}
   3147 	}
   3148 
   3149 	if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
   3150 	    phy->phy_rev >= 2)
   3151 		PHY_WRITE(mac, 0x47e, 0x78);
   3152 
   3153 	if (rf->rf_rev == 8) {
   3154 		PHY_SETBITS(mac, 0x801, 0x80);
   3155 		PHY_SETBITS(mac, 0x43e, 0x4);
   3156 	}
   3157 
   3158 	if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
   3159 		bwi_rf_get_gains(mac);
   3160 
   3161 	if (rf->rf_rev != 8)
   3162 		bwi_rf_init(mac);
   3163 
   3164 	if (tpctl->tp_ctrl2 == 0xffff) {
   3165 		bwi_rf_lo_update(mac);
   3166 	} else {
   3167 		if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
   3168 			RF_WRITE(mac, 0x52,
   3169 			    (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
   3170 		} else {
   3171 			RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2);
   3172 		}
   3173 
   3174 		if (phy->phy_rev >= 6) {
   3175 			PHY_FILT_SETBITS(mac, 0x36, 0xfff,
   3176 			    tpctl->tp_ctrl2 << 12);
   3177 		}
   3178 
   3179 		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
   3180 			PHY_WRITE(mac, 0x2e, 0x8075);
   3181 		else
   3182 			PHY_WRITE(mac, 0x2e, 0x807f);
   3183 
   3184 		if (phy->phy_rev < 2)
   3185 			PHY_WRITE(mac, 0x2f, 0x101);
   3186 		else
   3187 			PHY_WRITE(mac, 0x2f, 0x202);
   3188 	}
   3189 
   3190 	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   3191 		bwi_rf_lo_adjust(mac, tpctl);
   3192 		PHY_WRITE(mac, 0x80f, 0x8078);
   3193 	}
   3194 
   3195 	if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
   3196 		bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
   3197 		bwi_rf_set_nrssi_thr(mac);
   3198 	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   3199 		if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
   3200 			KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI);
   3201 			bwi_rf_calc_nrssi_slope(mac);
   3202 		} else {
   3203 			KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI);
   3204 			bwi_rf_set_nrssi_thr(mac);
   3205 		}
   3206 	}
   3207 
   3208 	if (rf->rf_rev == 8)
   3209 		PHY_WRITE(mac, 0x805, 0x3230);
   3210 
   3211 	bwi_mac_init_tpctl_11bg(mac);
   3212 
   3213 	if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
   3214 		PHY_CLRBITS(mac, 0x429, 0x4000);
   3215 		PHY_CLRBITS(mac, 0x4c3, 0x8000);
   3216 	}
   3217 }
   3218 
   3219 static void
   3220 bwi_phy_init_11b_rev2(struct bwi_mac *mac)
   3221 {
   3222 	struct bwi_softc *sc;
   3223 
   3224 	sc = mac->mac_sc;
   3225 
   3226 	/* TODO: 11B */
   3227 	aprint_error_dev(sc->sc_dev, "%s is not implemented yet\n", __func__);
   3228 }
   3229 
   3230 static void
   3231 bwi_phy_init_11b_rev4(struct bwi_mac *mac)
   3232 {
   3233 	struct bwi_softc *sc = mac->mac_sc;
   3234 	struct bwi_rf *rf = &mac->mac_rf;
   3235 	uint16_t val, ofs;
   3236 	uint chan;
   3237 
   3238 	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
   3239 
   3240 	PHY_WRITE(mac, 0x20, 0x301c);
   3241 	PHY_WRITE(mac, 0x26, 0);
   3242 	PHY_WRITE(mac, 0x30, 0xc6);
   3243 	PHY_WRITE(mac, 0x88, 0x3e00);
   3244 
   3245 	for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
   3246 		PHY_WRITE(mac, 0x89 + ofs, val);
   3247 
   3248 	CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
   3249 
   3250 	chan = rf->rf_curchan;
   3251 	if (chan == IEEE80211_CHAN_ANY)
   3252 		chan = 6;	/* Force to channel 6 */
   3253 	bwi_rf_set_chan(mac, chan, 0);
   3254 
   3255 	if (rf->rf_type != BWI_RF_T_BCM2050) {
   3256 		RF_WRITE(mac, 0x75, 0x80);
   3257 		RF_WRITE(mac, 0x79, 0x81);
   3258 	}
   3259 
   3260 	RF_WRITE(mac, 0x50, 0x20);
   3261 	RF_WRITE(mac, 0x50, 0x23);
   3262 
   3263 	if (rf->rf_type == BWI_RF_T_BCM2050) {
   3264 		RF_WRITE(mac, 0x50, 0x20);
   3265 		RF_WRITE(mac, 0x5a, 0x70);
   3266 		RF_WRITE(mac, 0x5b, 0x7b);
   3267 		RF_WRITE(mac, 0x5c, 0xb0);
   3268 		RF_WRITE(mac, 0x7a, 0xf);
   3269 		PHY_WRITE(mac, 0x38, 0x677);
   3270 		bwi_rf_init_bcm2050(mac);
   3271 	}
   3272 
   3273 	PHY_WRITE(mac, 0x14, 0x80);
   3274 	PHY_WRITE(mac, 0x32, 0xca);
   3275 	if (rf->rf_type == BWI_RF_T_BCM2050)
   3276 		PHY_WRITE(mac, 0x32, 0xe0);
   3277 	PHY_WRITE(mac, 0x35, 0x7c2);
   3278 
   3279 	bwi_rf_lo_update(mac);
   3280 
   3281 	PHY_WRITE(mac, 0x26, 0xcc00);
   3282 	if (rf->rf_type == BWI_RF_T_BCM2050)
   3283 		PHY_WRITE(mac, 0x26, 0xce00);
   3284 
   3285 	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
   3286 
   3287 	PHY_WRITE(mac, 0x2a, 0x88a3);
   3288 	if (rf->rf_type == BWI_RF_T_BCM2050)
   3289 		PHY_WRITE(mac, 0x2a, 0x88c2);
   3290 
   3291 	bwi_mac_set_tpctl_11bg(mac, NULL);
   3292 	if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
   3293 		bwi_rf_calc_nrssi_slope(mac);
   3294 		bwi_rf_set_nrssi_thr(mac);
   3295 	}
   3296 	bwi_mac_init_tpctl_11bg(mac);
   3297 }
   3298 
   3299 static void
   3300 bwi_phy_init_11b_rev5(struct bwi_mac *mac)
   3301 {
   3302 	struct bwi_softc *sc = mac->mac_sc;
   3303 	struct bwi_rf *rf = &mac->mac_rf;
   3304 	struct bwi_phy *phy = &mac->mac_phy;
   3305 	uint orig_chan;
   3306 
   3307 	if (phy->phy_version == 1)
   3308 		RF_SETBITS(mac, 0x7a, 0x50);
   3309 
   3310 	if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
   3311 	    sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
   3312 		uint16_t ofs, val;
   3313 
   3314 		val = 0x2120;
   3315 		for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
   3316 			PHY_WRITE(mac, ofs, val);
   3317 			val += 0x202;
   3318 		}
   3319 	}
   3320 
   3321 	PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
   3322 
   3323 	if (rf->rf_type == BWI_RF_T_BCM2050)
   3324 		PHY_WRITE(mac, 0x38, 0x667);
   3325 
   3326 	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   3327 		if (rf->rf_type == BWI_RF_T_BCM2050) {
   3328 			RF_SETBITS(mac, 0x7a, 0x20);
   3329 			RF_SETBITS(mac, 0x51, 0x4);
   3330 		}
   3331 
   3332 		CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
   3333 
   3334 		PHY_SETBITS(mac, 0x802, 0x100);
   3335 		PHY_SETBITS(mac, 0x42b, 0x2000);
   3336 		PHY_WRITE(mac, 0x1c, 0x186a);
   3337 
   3338 		PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
   3339 		PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
   3340 		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
   3341 	}
   3342 
   3343 	/* TODO: bad_frame_preempt? */
   3344 
   3345 	if (phy->phy_version == 1) {
   3346 	    	PHY_WRITE(mac, 0x26, 0xce00);
   3347 		PHY_WRITE(mac, 0x21, 0x3763);
   3348 		PHY_WRITE(mac, 0x22, 0x1bc3);
   3349 		PHY_WRITE(mac, 0x23, 0x6f9);
   3350 		PHY_WRITE(mac, 0x24, 0x37e);
   3351 	} else
   3352 		PHY_WRITE(mac, 0x26, 0xcc00);
   3353 	PHY_WRITE(mac, 0x30, 0xc6);
   3354 
   3355 	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
   3356 
   3357 	if (phy->phy_version == 1)
   3358 		PHY_WRITE(mac, 0x20, 0x3e1c);
   3359 	else
   3360 		PHY_WRITE(mac, 0x20, 0x301c);
   3361 
   3362 	if (phy->phy_version == 0)
   3363 		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
   3364 
   3365 	/* Force to channel 7 */
   3366 	orig_chan = rf->rf_curchan;
   3367 	bwi_rf_set_chan(mac, 7, 0);
   3368 
   3369 	if (rf->rf_type != BWI_RF_T_BCM2050) {
   3370 		RF_WRITE(mac, 0x75, 0x80);
   3371 		RF_WRITE(mac, 0x79, 0x81);
   3372 	}
   3373 
   3374 	RF_WRITE(mac, 0x50, 0x20);
   3375 	RF_WRITE(mac, 0x50, 0x23);
   3376 
   3377 	if (rf->rf_type == BWI_RF_T_BCM2050) {
   3378 		RF_WRITE(mac, 0x50, 0x20);
   3379 		RF_WRITE(mac, 0x5a, 0x70);
   3380 	}
   3381 
   3382 	RF_WRITE(mac, 0x5b, 0x7b);
   3383 	RF_WRITE(mac, 0x5c, 0xb0);
   3384 	RF_SETBITS(mac, 0x7a, 0x7);
   3385 
   3386 	bwi_rf_set_chan(mac, orig_chan, 0);
   3387 
   3388 	PHY_WRITE(mac, 0x14, 0x80);
   3389 	PHY_WRITE(mac, 0x32, 0xca);
   3390 	PHY_WRITE(mac, 0x2a, 0x88a3);
   3391 
   3392 	bwi_mac_set_tpctl_11bg(mac, NULL);
   3393 
   3394 	if (rf->rf_type == BWI_RF_T_BCM2050)
   3395 		RF_WRITE(mac, 0x5d, 0xd);
   3396 
   3397 	CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
   3398 }
   3399 
   3400 static void
   3401 bwi_phy_init_11b_rev6(struct bwi_mac *mac)
   3402 {
   3403 	struct bwi_softc *sc = mac->mac_sc;
   3404 	struct bwi_rf *rf = &mac->mac_rf;
   3405 	struct bwi_phy *phy = &mac->mac_phy;
   3406 	uint16_t val, ofs;
   3407 	uint orig_chan;
   3408 
   3409 	PHY_WRITE(mac, 0x3e, 0x817a);
   3410 	RF_SETBITS(mac, 0x7a, 0x58);
   3411 
   3412 	if (rf->rf_rev == 4 || rf->rf_rev == 5) {
   3413 		RF_WRITE(mac, 0x51, 0x37);
   3414 		RF_WRITE(mac, 0x52, 0x70);
   3415 		RF_WRITE(mac, 0x53, 0xb3);
   3416 		RF_WRITE(mac, 0x54, 0x9b);
   3417 		RF_WRITE(mac, 0x5a, 0x88);
   3418 		RF_WRITE(mac, 0x5b, 0x88);
   3419 		RF_WRITE(mac, 0x5d, 0x88);
   3420 		RF_WRITE(mac, 0x5e, 0x88);
   3421 		RF_WRITE(mac, 0x7d, 0x88);
   3422 		HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
   3423 	} else if (rf->rf_rev == 8) {
   3424 		RF_WRITE(mac, 0x51, 0);
   3425 		RF_WRITE(mac, 0x52, 0x40);
   3426 		RF_WRITE(mac, 0x53, 0xb7);
   3427 		RF_WRITE(mac, 0x54, 0x98);
   3428 		RF_WRITE(mac, 0x5a, 0x88);
   3429 		RF_WRITE(mac, 0x5b, 0x6b);
   3430 		RF_WRITE(mac, 0x5c, 0xf);
   3431 		if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
   3432 			RF_WRITE(mac, 0x5d, 0xfa);
   3433 			RF_WRITE(mac, 0x5e, 0xd8);
   3434 		} else {
   3435 			RF_WRITE(mac, 0x5d, 0xf5);
   3436 			RF_WRITE(mac, 0x5e, 0xb8);
   3437 		}
   3438 		RF_WRITE(mac, 0x73, 0x3);
   3439 		RF_WRITE(mac, 0x7d, 0xa8);
   3440 		RF_WRITE(mac, 0x7c, 0x1);
   3441 		RF_WRITE(mac, 0x7e, 0x8);
   3442 	}
   3443 
   3444 	val = 0x1e1f;
   3445 	for (ofs = 0x88; ofs < 0x98; ++ofs) {
   3446 		PHY_WRITE(mac, ofs, val);
   3447 		val -= 0x202;
   3448 	}
   3449 
   3450 	val = 0x3e3f;
   3451 	for (ofs = 0x98; ofs < 0xa8; ++ofs) {
   3452 		PHY_WRITE(mac, ofs, val);
   3453 		val -= 0x202;
   3454 	}
   3455 
   3456 	val = 0x2120;
   3457 	for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
   3458 		PHY_WRITE(mac, ofs, (val & 0x3f3f));
   3459 		val += 0x202;
   3460 	}
   3461 
   3462 	if (phy->phy_mode == IEEE80211_MODE_11G) {
   3463 		RF_SETBITS(mac, 0x7a, 0x20);
   3464 		RF_SETBITS(mac, 0x51, 0x4);
   3465 		PHY_SETBITS(mac, 0x802, 0x100);
   3466 		PHY_SETBITS(mac, 0x42b, 0x2000);
   3467 		PHY_WRITE(mac, 0x5b, 0);
   3468 		PHY_WRITE(mac, 0x5c, 0);
   3469 	}
   3470 
   3471 	/* Force to channel 7 */
   3472 	orig_chan = rf->rf_curchan;
   3473 	if (orig_chan >= 8)
   3474 		bwi_rf_set_chan(mac, 1, 0);
   3475 	else
   3476 		bwi_rf_set_chan(mac, 13, 0);
   3477 
   3478 	RF_WRITE(mac, 0x50, 0x20);
   3479 	RF_WRITE(mac, 0x50, 0x23);
   3480 
   3481 	DELAY(40);
   3482 
   3483 	if (rf->rf_rev < 6 || rf->rf_rev == 8) {
   3484 		RF_SETBITS(mac, 0x7c, 0x2);
   3485 		RF_WRITE(mac, 0x50, 0x20);
   3486 	}
   3487 	if (rf->rf_rev <= 2) {
   3488 		RF_WRITE(mac, 0x7c, 0x20);
   3489 		RF_WRITE(mac, 0x5a, 0x70);
   3490 		RF_WRITE(mac, 0x5b, 0x7b);
   3491 		RF_WRITE(mac, 0x5c, 0xb0);
   3492 	}
   3493 
   3494 	RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
   3495 
   3496 	bwi_rf_set_chan(mac, orig_chan, 0);
   3497 
   3498 	PHY_WRITE(mac, 0x14, 0x200);
   3499 	if (rf->rf_rev >= 6)
   3500 		PHY_WRITE(mac, 0x2a, 0x88c2);
   3501 	else
   3502 		PHY_WRITE(mac, 0x2a, 0x8ac0);
   3503 	PHY_WRITE(mac, 0x38, 0x668);
   3504 
   3505 	bwi_mac_set_tpctl_11bg(mac, NULL);
   3506 
   3507 	if (rf->rf_rev <= 5) {
   3508 		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
   3509 		if (rf->rf_rev <= 2)
   3510 			RF_WRITE(mac, 0x5d, 0xd);
   3511 	}
   3512 
   3513 	if (phy->phy_version == 4) {
   3514 		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
   3515 		PHY_CLRBITS(mac, 0x61, 0xf000);
   3516 	} else {
   3517 		PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
   3518 	}
   3519 
   3520 	if (phy->phy_mode == IEEE80211_MODE_11B) {
   3521 		CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
   3522 		PHY_WRITE(mac, 0x16, 0x410);
   3523 		PHY_WRITE(mac, 0x17, 0x820);
   3524 		PHY_WRITE(mac, 0x62, 0x7);
   3525 
   3526 		bwi_rf_init_bcm2050(mac);
   3527 		bwi_rf_lo_update(mac);
   3528 		if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
   3529 			bwi_rf_calc_nrssi_slope(mac);
   3530 			bwi_rf_set_nrssi_thr(mac);
   3531 		}
   3532 		bwi_mac_init_tpctl_11bg(mac);
   3533 	} else
   3534 		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
   3535 }
   3536 
   3537 static void
   3538 bwi_phy_config_11g(struct bwi_mac *mac)
   3539 {
   3540 	struct bwi_softc *sc = mac->mac_sc;
   3541 	struct bwi_phy *phy = &mac->mac_phy;
   3542 	const uint16_t *tbl;
   3543 	uint16_t wrd_ofs1, wrd_ofs2;
   3544 	int i, n;
   3545 
   3546 	if (phy->phy_rev == 1) {
   3547 		PHY_WRITE(mac, 0x406, 0x4f19);
   3548 		PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
   3549 		PHY_WRITE(mac, 0x42c, 0x5a);
   3550 		PHY_WRITE(mac, 0x427, 0x1a);
   3551 
   3552 		/* Fill frequency table */
   3553 		for (i = 0; i < __arraycount(bwi_phy_freq_11g_rev1); ++i) {
   3554 			bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
   3555 			    bwi_phy_freq_11g_rev1[i]);
   3556 		}
   3557 
   3558 		/* Fill noise table */
   3559 		for (i = 0; i < __arraycount(bwi_phy_noise_11g_rev1); ++i) {
   3560 			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
   3561 			    bwi_phy_noise_11g_rev1[i]);
   3562 		}
   3563 
   3564 		/* Fill rotor table */
   3565 		for (i = 0; i < __arraycount(bwi_phy_rotor_11g_rev1); ++i) {
   3566 			/* NB: data length is 4 bytes */
   3567 			bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
   3568 			    bwi_phy_rotor_11g_rev1[i]);
   3569 		}
   3570 	} else {
   3571 		bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
   3572 
   3573 		if (phy->phy_rev == 2) {
   3574 			PHY_WRITE(mac, 0x4c0, 0x1861);
   3575 			PHY_WRITE(mac, 0x4c1, 0x271);
   3576 		} else if (phy->phy_rev > 2) {
   3577 			PHY_WRITE(mac, 0x4c0, 0x98);
   3578 			PHY_WRITE(mac, 0x4c1, 0x70);
   3579 			PHY_WRITE(mac, 0x4c9, 0x80);
   3580 		}
   3581 		PHY_SETBITS(mac, 0x42b, 0x800);
   3582 
   3583 		/* Fill RSSI table */
   3584 		for (i = 0; i < 64; ++i)
   3585 			bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
   3586 
   3587 		/* Fill noise table */
   3588 		for (i = 0; i < __arraycount(bwi_phy_noise_11g); ++i) {
   3589 			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
   3590 			    bwi_phy_noise_11g[i]);
   3591 		}
   3592 	}
   3593 
   3594 	/*
   3595 	 * Fill noise scale table
   3596 	 */
   3597 	if (phy->phy_rev <= 2) {
   3598 		tbl = bwi_phy_noise_scale_11g_rev2;
   3599 		n = __arraycount(bwi_phy_noise_scale_11g_rev2);
   3600 	} else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
   3601 		tbl = bwi_phy_noise_scale_11g_rev7;
   3602 		n = __arraycount(bwi_phy_noise_scale_11g_rev7);
   3603 	} else {
   3604 		tbl = bwi_phy_noise_scale_11g;
   3605 		n = __arraycount(bwi_phy_noise_scale_11g);
   3606 	}
   3607 	for (i = 0; i < n; ++i)
   3608 		bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
   3609 
   3610 	/*
   3611 	 * Fill sigma square table
   3612 	 */
   3613 	if (phy->phy_rev == 2) {
   3614 		tbl = bwi_phy_sigma_sq_11g_rev2;
   3615 		n = __arraycount(bwi_phy_sigma_sq_11g_rev2);
   3616 	} else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
   3617 		tbl = bwi_phy_sigma_sq_11g_rev7;
   3618 		n = __arraycount(bwi_phy_sigma_sq_11g_rev7);
   3619 	} else {
   3620 		tbl = NULL;
   3621 		n = 0;
   3622 	}
   3623 	for (i = 0; i < n; ++i)
   3624 		bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
   3625 
   3626 	if (phy->phy_rev == 1) {
   3627 		/* Fill delay table */
   3628 		for (i = 0; i < __arraycount(bwi_phy_delay_11g_rev1); ++i) {
   3629 			bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
   3630 			    bwi_phy_delay_11g_rev1[i]);
   3631 		}
   3632 
   3633 		/* Fill WRSSI (Wide-Band RSSI) table */
   3634 		for (i = 4; i < 20; ++i)
   3635 			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
   3636 
   3637 		bwi_phy_config_agc(mac);
   3638 
   3639 		wrd_ofs1 = 0x5001;
   3640 		wrd_ofs2 = 0x5002;
   3641 	} else {
   3642 		/* Fill WRSSI (Wide-Band RSSI) table */
   3643 		for (i = 0; i < 0x20; ++i)
   3644 			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
   3645 
   3646 		bwi_phy_config_agc(mac);
   3647 
   3648 		PHY_READ(mac, 0x400);	/* Dummy read */
   3649 		PHY_WRITE(mac, 0x403, 0x1000);
   3650 		bwi_tbl_write_2(mac, 0x3c02, 0xf);
   3651 		bwi_tbl_write_2(mac, 0x3c03, 0x14);
   3652 
   3653 		wrd_ofs1 = 0x401;
   3654 		wrd_ofs2 = 0x402;
   3655 	}
   3656 
   3657 	if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
   3658 		bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
   3659 		bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
   3660 	}
   3661 
   3662 	/* phy->phy_flags & BWI_PHY_F_LINKED ? */
   3663 	if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
   3664 		PHY_WRITE(mac, 0x46e, 0x3cf);
   3665 }
   3666 
   3667 /*
   3668  * Configure Automatic Gain Controller
   3669  */
   3670 static void
   3671 bwi_phy_config_agc(struct bwi_mac *mac)
   3672 {
   3673 	struct bwi_phy *phy = &mac->mac_phy;
   3674 	uint16_t ofs;
   3675 
   3676 	ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
   3677 
   3678 	bwi_tbl_write_2(mac, ofs, 0xfe);
   3679 	bwi_tbl_write_2(mac, ofs + 1, 0xd);
   3680 	bwi_tbl_write_2(mac, ofs + 2, 0x13);
   3681 	bwi_tbl_write_2(mac, ofs + 3, 0x19);
   3682 
   3683 	if (phy->phy_rev == 1) {
   3684 		bwi_tbl_write_2(mac, 0x1800, 0x2710);
   3685 		bwi_tbl_write_2(mac, 0x1801, 0x9b83);
   3686 		bwi_tbl_write_2(mac, 0x1802, 0x9b83);
   3687 		bwi_tbl_write_2(mac, 0x1803, 0xf8d);
   3688 		PHY_WRITE(mac, 0x455, 0x4);
   3689 	}
   3690 
   3691 	PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
   3692 	PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
   3693 	PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
   3694 	PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
   3695 
   3696 	RF_SETBITS(mac, 0x7a, 0x8);
   3697 
   3698 	PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
   3699 	PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
   3700 	PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
   3701 	PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
   3702 
   3703 	if (phy->phy_rev == 1)
   3704 		PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
   3705 
   3706 	PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
   3707 	PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
   3708 	PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
   3709 	PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
   3710 	PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
   3711 	PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
   3712 	PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
   3713 	PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
   3714 	PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
   3715 
   3716 	if (phy->phy_rev == 1) {
   3717 		PHY_WRITE(mac, 0x430, 0x92b);
   3718 		PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
   3719 	} else {
   3720 		PHY_CLRBITS(mac, 0x41b, 0x1e);
   3721 		PHY_WRITE(mac, 0x41f, 0x287a);
   3722 		PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
   3723 
   3724 		if (phy->phy_rev >= 6) {
   3725 			PHY_WRITE(mac, 0x422, 0x287a);
   3726 			PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
   3727 		}
   3728 	}
   3729 
   3730 	PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
   3731 	PHY_WRITE(mac, 0x48e, 0x1c00);
   3732 
   3733 	if (phy->phy_rev == 1) {
   3734 		PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
   3735 		PHY_WRITE(mac, 0x48b, 0x5e);
   3736 		PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
   3737 		PHY_WRITE(mac, 0x48d, 0x2);
   3738 	}
   3739 
   3740 	bwi_tbl_write_2(mac, ofs + 0x800, 0);
   3741 	bwi_tbl_write_2(mac, ofs + 0x801, 7);
   3742 	bwi_tbl_write_2(mac, ofs + 0x802, 16);
   3743 	bwi_tbl_write_2(mac, ofs + 0x803, 28);
   3744 
   3745 	if (phy->phy_rev >= 6) {
   3746 		PHY_CLRBITS(mac, 0x426, 0x3);
   3747 		PHY_CLRBITS(mac, 0x426, 0x1000);
   3748 	}
   3749 }
   3750 
   3751 static void
   3752 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
   3753 {
   3754 	struct bwi_phy *phy = &mac->mac_phy;
   3755 	uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
   3756 	int i;
   3757 
   3758 	if (phy->phy_rev <= 1) {
   3759 		tbl_gain_ofs1 = 0x5000;
   3760 		tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
   3761 	} else {
   3762 		tbl_gain_ofs1 = 0x400;
   3763 		tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
   3764 	}
   3765 
   3766 	for (i = 0; i < 4; ++i) {
   3767 		if (gains != NULL) {
   3768 			tbl_gain = gains->tbl_gain1;
   3769 		} else {
   3770 			/* Bit swap */
   3771 			tbl_gain = (i & 0x1) << 1;
   3772 			tbl_gain |= (i & 0x2) >> 1;
   3773 		}
   3774 		bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
   3775 	}
   3776 
   3777 	for (i = 0; i < 16; ++i) {
   3778 		if (gains != NULL)
   3779 			tbl_gain = gains->tbl_gain2;
   3780 		else
   3781 			tbl_gain = i;
   3782 		bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
   3783 	}
   3784 
   3785 	if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
   3786 		uint16_t phy_gain1, phy_gain2;
   3787 
   3788 		if (gains != NULL) {
   3789 			phy_gain1 =
   3790 			((uint16_t)gains->phy_gain << 14) |
   3791 			((uint16_t)gains->phy_gain << 6);
   3792 			phy_gain2 = phy_gain1;
   3793 		} else {
   3794 			phy_gain1 = 0x4040;
   3795 			phy_gain2 = 0x4000;
   3796 		}
   3797 		PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
   3798 		PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
   3799 		PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
   3800 	}
   3801 	bwi_mac_dummy_xmit(mac);
   3802 }
   3803 
   3804 static void
   3805 bwi_phy_clear_state(struct bwi_phy *phy)
   3806 {
   3807 	phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
   3808 }
   3809 
   3810 /* RF */
   3811 
   3812 static int16_t
   3813 bwi_nrssi_11g(struct bwi_mac *mac)
   3814 {
   3815 	int16_t val;
   3816 
   3817 #define NRSSI_11G_MASK		0x3f00
   3818 	val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK);
   3819 	if (val >= 32)
   3820 		val -= 64;
   3821 
   3822 	return (val);
   3823 #undef NRSSI_11G_MASK
   3824 }
   3825 
   3826 static struct bwi_rf_lo *
   3827 bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten)
   3828 {
   3829 	int n;
   3830 
   3831 	n = rf_atten + (14 * (bbp_atten / 2));
   3832 	KASSERT(n < BWI_RFLO_MAX);
   3833 
   3834 	return (&mac->mac_rf.rf_lo[n]);
   3835 }
   3836 
   3837 static int
   3838 bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
   3839 {
   3840 	struct bwi_rf *rf = &mac->mac_rf;
   3841 	int idx;
   3842 
   3843 	idx = lo - rf->rf_lo;
   3844 	KASSERT(idx >= 0 && idx < BWI_RFLO_MAX);
   3845 
   3846 	return (isset(rf->rf_lo_used, idx));
   3847 }
   3848 
   3849 static void
   3850 bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
   3851 {
   3852 	struct bwi_softc *sc = mac->mac_sc;
   3853 
   3854 	CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
   3855 	CSR_WRITE_2(sc, BWI_RF_DATA_LO, data);
   3856 }
   3857 
   3858 static uint16_t
   3859 bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl)
   3860 {
   3861 	struct bwi_rf *rf = &mac->mac_rf;
   3862 	struct bwi_softc *sc = mac->mac_sc;
   3863 
   3864 	ctrl |= rf->rf_ctrl_rd;
   3865 	if (rf->rf_ctrl_adj) {
   3866 		/* XXX */
   3867 		if (ctrl < 0x70)
   3868 			ctrl += 0x80;
   3869 		else if (ctrl < 0x80)
   3870 			ctrl += 0x70;
   3871 	}
   3872 
   3873 	CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
   3874 	return (CSR_READ_2(sc, BWI_RF_DATA_LO));
   3875 }
   3876 
   3877 static int
   3878 bwi_rf_attach(struct bwi_mac *mac)
   3879 {
   3880 	struct bwi_softc *sc = mac->mac_sc;
   3881 	struct bwi_phy *phy = &mac->mac_phy;
   3882 	struct bwi_rf *rf = &mac->mac_rf;
   3883 	uint16_t type, manu;
   3884 	uint8_t rev;
   3885 
   3886 	/*
   3887 	 * Get RF manufacture/type/revision
   3888 	 */
   3889 	if (sc->sc_bbp_id == BWI_BBPID_BCM4317) {
   3890 		/*
   3891 		 * Fake a BCM2050 RF
   3892 		 */
   3893 		manu = BWI_RF_MANUFACT_BCM;
   3894 		type = BWI_RF_T_BCM2050;
   3895 		if (sc->sc_bbp_rev == 0)
   3896 			rev = 3;
   3897 		else if (sc->sc_bbp_rev == 1)
   3898 			rev = 4;
   3899 		else
   3900 			rev = 5;
   3901 	} else {
   3902 		uint32_t val;
   3903 
   3904 		CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
   3905 		val = CSR_READ_2(sc, BWI_RF_DATA_HI);
   3906 		val <<= 16;
   3907 
   3908 		CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
   3909 		val |= CSR_READ_2(sc, BWI_RF_DATA_LO);
   3910 
   3911 		manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK);
   3912 		type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK);
   3913 		rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK);
   3914 	}
   3915 	aprint_normal_dev(sc->sc_dev, "RF manu 0x%03x, type 0x%04x, rev %u\n",
   3916 	    manu, type, rev);
   3917 
   3918 	/*
   3919 	 * Verify whether the RF is supported
   3920 	 */
   3921 	rf->rf_ctrl_rd = 0;
   3922 	rf->rf_ctrl_adj = 0;
   3923 	switch (phy->phy_mode) {
   3924 	case IEEE80211_MODE_11A:
   3925 		if (manu != BWI_RF_MANUFACT_BCM ||
   3926 		    type != BWI_RF_T_BCM2060 ||
   3927 		    rev != 1) {
   3928 			aprint_error_dev(sc->sc_dev,
   3929 			    "only BCM2060 rev 1 RF is supported for"
   3930 			    " 11A PHY\n");
   3931 			return (ENXIO);
   3932 		}
   3933 		rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A;
   3934 		rf->rf_on = bwi_rf_on_11a;
   3935 		rf->rf_off = bwi_rf_off_11a;
   3936 		rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060;
   3937 		break;
   3938 	case IEEE80211_MODE_11B:
   3939 		if (type == BWI_RF_T_BCM2050) {
   3940 			rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
   3941 			rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
   3942 		} else if (type == BWI_RF_T_BCM2053) {
   3943 			rf->rf_ctrl_adj = 1;
   3944 			rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053;
   3945 		} else {
   3946 			aprint_error_dev(sc->sc_dev,
   3947 			    "only BCM2050/BCM2053 RF is supported for"
   3948 			    " 11B phy\n");
   3949 			return (ENXIO);
   3950 		}
   3951 		rf->rf_on = bwi_rf_on_11bg;
   3952 		rf->rf_off = bwi_rf_off_11bg;
   3953 		rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b;
   3954 		rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b;
   3955 		if (phy->phy_rev == 6)
   3956 			rf->rf_lo_update = bwi_rf_lo_update_11g;
   3957 		else
   3958 			rf->rf_lo_update = bwi_rf_lo_update_11b;
   3959 		break;
   3960 	case IEEE80211_MODE_11G:
   3961 		if (type != BWI_RF_T_BCM2050) {
   3962 			aprint_error_dev(sc->sc_dev,
   3963 			    "only BCM2050 RF is supported for"
   3964 			    " 11G PHY\n");
   3965 			return (ENXIO);
   3966 		}
   3967 		rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
   3968 		rf->rf_on = bwi_rf_on_11bg;
   3969 		if (mac->mac_rev >= 5)
   3970 			rf->rf_off = bwi_rf_off_11g_rev5;
   3971 		else
   3972 			rf->rf_off = bwi_rf_off_11bg;
   3973 		rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g;
   3974 		rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g;
   3975 		rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
   3976 		rf->rf_lo_update = bwi_rf_lo_update_11g;
   3977 		break;
   3978 	default:
   3979 		aprint_error_dev(sc->sc_dev, "unsupported PHY mode\n");
   3980 		return (ENXIO);
   3981 	}
   3982 
   3983 	rf->rf_type = type;
   3984 	rf->rf_rev = rev;
   3985 	rf->rf_manu = manu;
   3986 	rf->rf_curchan = IEEE80211_CHAN_ANY;
   3987 	rf->rf_ant_mode = BWI_ANT_MODE_AUTO;
   3988 
   3989 	return (0);
   3990 }
   3991 
   3992 static void
   3993 bwi_rf_set_chan(struct bwi_mac *mac, uint chan, int work_around)
   3994 {
   3995 	struct bwi_softc *sc = mac->mac_sc;
   3996 
   3997 	if (chan == IEEE80211_CHAN_ANY)
   3998 		return;
   3999 
   4000 	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan);
   4001 
   4002 	/* TODO: 11A */
   4003 
   4004 	if (work_around)
   4005 		bwi_rf_workaround(mac, chan);
   4006 
   4007 	CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
   4008 
   4009 	if (chan == 14) {
   4010 		if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN)
   4011 			HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN);
   4012 		else
   4013 			HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN);
   4014 		CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11)); /* XXX */
   4015 	} else {
   4016 		CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840); /* XXX */
   4017 	}
   4018 	DELAY(8000);	/* DELAY(2000); */
   4019 
   4020 	mac->mac_rf.rf_curchan = chan;
   4021 }
   4022 
   4023 static void
   4024 bwi_rf_get_gains(struct bwi_mac *mac)
   4025 {
   4026 #define SAVE_PHY_MAX	15
   4027 #define SAVE_RF_MAX	3
   4028 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
   4029 	    { 0x52, 0x43, 0x7a };
   4030 	static const uint16_t save_phy_regs[SAVE_PHY_MAX] = {
   4031 	    0x0429, 0x0001, 0x0811, 0x0812,
   4032 	    0x0814, 0x0815, 0x005a, 0x0059,
   4033 	    0x0058, 0x000a, 0x0003, 0x080f,
   4034 	    0x0810, 0x002b, 0x0015
   4035 	};
   4036 
   4037 	struct bwi_phy *phy = &mac->mac_phy;
   4038 	struct bwi_rf *rf = &mac->mac_rf;
   4039 	uint16_t save_phy[SAVE_PHY_MAX];
   4040 	uint16_t save_rf[SAVE_RF_MAX];
   4041 	uint16_t trsw;
   4042 	int i, j, loop1_max, loop1, loop2;
   4043 
   4044 	/*
   4045 	 * Save PHY/RF registers for later restoration
   4046 	 */
   4047 	for (i = 0; i < SAVE_PHY_MAX; ++i)
   4048 		save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
   4049 	PHY_READ(mac, 0x2d); /* dummy read */
   4050 
   4051 	for (i = 0; i < SAVE_RF_MAX; ++i)
   4052 		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
   4053 
   4054 	PHY_CLRBITS(mac, 0x429, 0xc000);
   4055 	PHY_SETBITS(mac, 0x1, 0x8000);
   4056 
   4057 	PHY_SETBITS(mac, 0x811, 0x2);
   4058 	PHY_CLRBITS(mac, 0x812, 0x2);
   4059 	PHY_SETBITS(mac, 0x811, 0x1);
   4060 	PHY_CLRBITS(mac, 0x812, 0x1);
   4061 
   4062 	PHY_SETBITS(mac, 0x814, 0x1);
   4063 	PHY_CLRBITS(mac, 0x815, 0x1);
   4064 	PHY_SETBITS(mac, 0x814, 0x2);
   4065 	PHY_CLRBITS(mac, 0x815, 0x2);
   4066 
   4067 	PHY_SETBITS(mac, 0x811, 0xc);
   4068 	PHY_SETBITS(mac, 0x812, 0xc);
   4069 	PHY_SETBITS(mac, 0x811, 0x30);
   4070 	PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
   4071 
   4072 	PHY_WRITE(mac, 0x5a, 0x780);
   4073 	PHY_WRITE(mac, 0x59, 0xc810);
   4074 	PHY_WRITE(mac, 0x58, 0xd);
   4075 	PHY_SETBITS(mac, 0xa, 0x2000);
   4076 
   4077 	PHY_SETBITS(mac, 0x814, 0x4);
   4078 	PHY_CLRBITS(mac, 0x815, 0x4);
   4079 
   4080 	PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
   4081 
   4082 	if (rf->rf_rev == 8) {
   4083 		loop1_max = 15;
   4084 		RF_WRITE(mac, 0x43, loop1_max);
   4085 	} else {
   4086 		loop1_max = 9;
   4087 	    	RF_WRITE(mac, 0x52, 0x0);
   4088 		RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max);
   4089 	}
   4090 
   4091 	bwi_phy_set_bbp_atten(mac, 11);
   4092 
   4093 	if (phy->phy_rev >= 3)
   4094 		PHY_WRITE(mac, 0x80f, 0xc020);
   4095 	else
   4096 		PHY_WRITE(mac, 0x80f, 0x8020);
   4097 	PHY_WRITE(mac, 0x810, 0);
   4098 
   4099 	PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1);
   4100 	PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800);
   4101 	PHY_SETBITS(mac, 0x811, 0x100);
   4102 	PHY_CLRBITS(mac, 0x812, 0x3000);
   4103 
   4104 	if ((mac->mac_sc->sc_card_flags & BWI_CARD_F_EXT_LNA) &&
   4105 	    phy->phy_rev >= 7) {
   4106 		PHY_SETBITS(mac, 0x811, 0x800);
   4107 		PHY_SETBITS(mac, 0x812, 0x8000);
   4108 	}
   4109 	RF_CLRBITS(mac, 0x7a, 0xff08);
   4110 
   4111 	/*
   4112 	 * Find out 'loop1/loop2', which will be used to calculate
   4113 	 * max loopback gain later
   4114 	 */
   4115 	j = 0;
   4116 	for (i = 0; i < loop1_max; ++i) {
   4117 		for (j = 0; j < 16; ++j) {
   4118 			RF_WRITE(mac, 0x43, i);
   4119 
   4120 			if (bwi_rf_gain_max_reached(mac, j))
   4121 				goto loop1_exit;
   4122 		}
   4123 	}
   4124 loop1_exit:
   4125 	loop1 = i;
   4126 	loop2 = j;
   4127 
   4128 	/*
   4129 	 * Find out 'trsw', which will be used to calculate
   4130 	 * TRSW(TX/RX switch) RX gain later
   4131 	 */
   4132 	if (loop2 >= 8) {
   4133 		PHY_SETBITS(mac, 0x812, 0x30);
   4134 		trsw = 0x1b;
   4135 		for (i = loop2 - 8; i < 16; ++i) {
   4136 			trsw -= 3;
   4137 			if (bwi_rf_gain_max_reached(mac, i))
   4138 				break;
   4139 		}
   4140 	} else {
   4141 		trsw = 0x18;
   4142 	}
   4143 
   4144 	/*
   4145 	 * Restore saved PHY/RF registers
   4146 	 */
   4147 	/* First 4 saved PHY registers need special processing */
   4148 	for (i = 4; i < SAVE_PHY_MAX; ++i)
   4149 		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
   4150 
   4151 	bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten);
   4152 
   4153 	for (i = 0; i < SAVE_RF_MAX; ++i)
   4154 		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
   4155 
   4156 	PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3);
   4157 	DELAY(10);
   4158 	PHY_WRITE(mac, save_phy_regs[2], save_phy[2]);
   4159 	PHY_WRITE(mac, save_phy_regs[3], save_phy[3]);
   4160 	PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
   4161 	PHY_WRITE(mac, save_phy_regs[1], save_phy[1]);
   4162 
   4163 	/*
   4164 	 * Calculate gains
   4165 	 */
   4166 	rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11;
   4167 	rf->rf_rx_gain = trsw * 2;
   4168 	DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_INIT,
   4169 	    "lo gain: %u, rx gain: %u\n",
   4170 	    rf->rf_lo_gain, rf->rf_rx_gain);
   4171 
   4172 #undef SAVE_RF_MAX
   4173 #undef SAVE_PHY_MAX
   4174 }
   4175 
   4176 static void
   4177 bwi_rf_init(struct bwi_mac *mac)
   4178 {
   4179 	struct bwi_rf *rf = &mac->mac_rf;
   4180 
   4181 	if (rf->rf_type == BWI_RF_T_BCM2060) {
   4182 		/* TODO: 11A */
   4183 	} else {
   4184 		if (rf->rf_flags & BWI_RF_F_INITED)
   4185 			RF_WRITE(mac, 0x78, rf->rf_calib);
   4186 		else
   4187 			bwi_rf_init_bcm2050(mac);
   4188 	}
   4189 }
   4190 
   4191 static void
   4192 bwi_rf_off_11a(struct bwi_mac *mac)
   4193 {
   4194 	RF_WRITE(mac, 0x4, 0xff);
   4195 	RF_WRITE(mac, 0x5, 0xfb);
   4196 
   4197 	PHY_SETBITS(mac, 0x10, 0x8);
   4198 	PHY_SETBITS(mac, 0x11, 0x8);
   4199 
   4200 	PHY_WRITE(mac, 0x15, 0xaa00);
   4201 }
   4202 
   4203 static void
   4204 bwi_rf_off_11bg(struct bwi_mac *mac)
   4205 {
   4206 	PHY_WRITE(mac, 0x15, 0xaa00);
   4207 }
   4208 
   4209 static void
   4210 bwi_rf_off_11g_rev5(struct bwi_mac *mac)
   4211 {
   4212 	PHY_SETBITS(mac, 0x811, 0x8c);
   4213 	PHY_CLRBITS(mac, 0x812, 0x8c);
   4214 }
   4215 
   4216 static void
   4217 bwi_rf_workaround(struct bwi_mac *mac, uint chan)
   4218 {
   4219 	struct bwi_softc *sc = mac->mac_sc;
   4220 	struct bwi_rf *rf = &mac->mac_rf;
   4221 
   4222 	if (chan == IEEE80211_CHAN_ANY) {
   4223 		aprint_error_dev(sc->sc_dev, "%s invalid channel!\n",
   4224 		    __func__);
   4225 		return;
   4226 	}
   4227 
   4228 	if (rf->rf_type != BWI_RF_T_BCM2050 || rf->rf_rev >= 6)
   4229 		return;
   4230 
   4231 	if (chan <= 10)
   4232 		CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4));
   4233 	else
   4234 		CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1));
   4235 	DELAY(1000);
   4236 	CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
   4237 }
   4238 
   4239 static struct bwi_rf_lo *
   4240 bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
   4241 {
   4242 	uint16_t rf_atten, bbp_atten;
   4243 	int remap_rf_atten;
   4244 
   4245 	remap_rf_atten = 1;
   4246 	if (tpctl == NULL) {
   4247 		bbp_atten = 2;
   4248 		rf_atten = 3;
   4249 	} else {
   4250 		if (tpctl->tp_ctrl1 == 3)
   4251 			remap_rf_atten = 0;
   4252 
   4253 		bbp_atten = tpctl->bbp_atten;
   4254 		rf_atten = tpctl->rf_atten;
   4255 
   4256 		if (bbp_atten > 6)
   4257 			bbp_atten = 6;
   4258 	}
   4259 
   4260 	if (remap_rf_atten) {
   4261 #define MAP_MAX	10
   4262 		static const uint16_t map[MAP_MAX] =
   4263 		    { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
   4264 #if 0
   4265 		KASSERT(rf_atten < MAP_MAX);
   4266 		rf_atten = map[rf_atten];
   4267 #else
   4268 		if (rf_atten >= MAP_MAX) {
   4269 			rf_atten = 0;	/* XXX */
   4270 		} else {
   4271 			rf_atten = map[rf_atten];
   4272 		}
   4273 #endif
   4274 #undef MAP_MAX
   4275 	}
   4276 
   4277 	return (bwi_get_rf_lo(mac, rf_atten, bbp_atten));
   4278 }
   4279 
   4280 static void
   4281 bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
   4282 {
   4283 	const struct bwi_rf_lo *lo;
   4284 
   4285 	lo = bwi_rf_lo_find(mac, tpctl);
   4286 	RF_LO_WRITE(mac, lo);
   4287 }
   4288 
   4289 static void
   4290 bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
   4291 {
   4292 	uint16_t val;
   4293 
   4294 	val = (uint8_t)lo->ctrl_lo;
   4295 	val |= ((uint8_t)lo->ctrl_hi) << 8;
   4296 
   4297 	PHY_WRITE(mac, BWI_PHYR_RF_LO, val);
   4298 }
   4299 
   4300 static int
   4301 bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx)
   4302 {
   4303 	PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8);
   4304 	PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000);
   4305 	PHY_SETBITS(mac, 0x15, 0xf000);
   4306 
   4307 	DELAY(20);
   4308 
   4309 	return ((PHY_READ(mac, 0x2d) >= 0xdfc));
   4310 }
   4311 
   4312 /* XXX use bitmap array */
   4313 static uint16_t
   4314 bwi_bitswap4(uint16_t val)
   4315 {
   4316 	uint16_t ret;
   4317 
   4318 	ret = (val & 0x8) >> 3;
   4319 	ret |= (val & 0x4) >> 1;
   4320 	ret |= (val & 0x2) << 1;
   4321 	ret |= (val & 0x1) << 3;
   4322 
   4323 	return (ret);
   4324 }
   4325 
   4326 static uint16_t
   4327 bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd)
   4328 {
   4329 	struct bwi_softc *sc = mac->mac_sc;
   4330 	struct bwi_phy *phy = &mac->mac_phy;
   4331 	struct bwi_rf *rf = &mac->mac_rf;
   4332 	uint16_t lo_gain, ext_lna, loop;
   4333 
   4334 	if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
   4335 		return (0);
   4336 
   4337 	lo_gain = rf->rf_lo_gain;
   4338 	if (rf->rf_rev == 8)
   4339 		lo_gain += 0x3e;
   4340 	else
   4341 		lo_gain += 0x26;
   4342 
   4343 	if (lo_gain >= 0x46) {
   4344 		lo_gain -= 0x46;
   4345 		ext_lna = 0x3000;
   4346 	} else if (lo_gain >= 0x3a) {
   4347 		lo_gain -= 0x3a;
   4348 		ext_lna = 0x1000;
   4349 	} else if (lo_gain >= 0x2e) {
   4350 		lo_gain -= 0x2e;
   4351 		ext_lna = 0x2000;
   4352 	} else {
   4353 		lo_gain -= 0x10;
   4354 		ext_lna = 0;
   4355 	}
   4356 
   4357 	for (loop = 0; loop < 16; ++loop) {
   4358 		lo_gain -= (6 * loop);
   4359 		if (lo_gain < 6)
   4360 			break;
   4361 	}
   4362 
   4363 	if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) {
   4364 		if (ext_lna)
   4365 			ext_lna |= 0x8000;
   4366 		ext_lna |= (loop << 8);
   4367 		switch (lpd) {
   4368 		case 0x011:
   4369 			return (0x8f92);
   4370 		case 0x001:
   4371 			return (0x8092 | ext_lna);
   4372 		case 0x101:
   4373 			return (0x2092 | ext_lna);
   4374 		case 0x100:
   4375 			return (0x2093 | ext_lna);
   4376 		default:
   4377 			panic("unsupported lpd\n");
   4378 		}
   4379 	} else {
   4380 		ext_lna |= (loop << 8);
   4381 		switch (lpd) {
   4382 		case 0x011:
   4383 			return (0xf92);
   4384 		case 0x001:
   4385 		case 0x101:
   4386 			return (0x92 | ext_lna);
   4387 		case 0x100:
   4388 			return (0x93 | ext_lna);
   4389 		default:
   4390 			panic("unsupported lpd\n");
   4391 		}
   4392 	}
   4393 
   4394 	panic("never reached\n");
   4395 	return (0);
   4396 }
   4397 
   4398 static void
   4399 bwi_rf_init_bcm2050(struct bwi_mac *mac)
   4400 {
   4401 #define SAVE_RF_MAX		3
   4402 #define SAVE_PHY_COMM_MAX	4
   4403 #define SAVE_PHY_11G_MAX	6
   4404 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
   4405 	    { 0x0043, 0x0051, 0x0052 };
   4406 	static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] =
   4407 	    { 0x0015, 0x005a, 0x0059, 0x0058 };
   4408 	static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] =
   4409 	    { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
   4410 
   4411 	uint16_t save_rf[SAVE_RF_MAX];
   4412 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
   4413 	uint16_t save_phy_11g[SAVE_PHY_11G_MAX];
   4414 	uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0;
   4415 	uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex;
   4416 	uint16_t phy812_val;
   4417 	uint16_t calib;
   4418 	uint32_t test_lim, test;
   4419 	struct bwi_softc *sc = mac->mac_sc;
   4420 	struct bwi_phy *phy = &mac->mac_phy;
   4421 	struct bwi_rf *rf = &mac->mac_rf;
   4422 	int i;
   4423 
   4424 	/*
   4425 	 * Save registers for later restoring
   4426 	 */
   4427 	for (i = 0; i < SAVE_RF_MAX; ++i)
   4428 		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
   4429 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
   4430 		save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]);
   4431 
   4432 	if (phy->phy_mode == IEEE80211_MODE_11B) {
   4433 		phyr_30 = PHY_READ(mac, 0x30);
   4434 		bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
   4435 
   4436 		PHY_WRITE(mac, 0x30, 0xff);
   4437 		CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f);
   4438 	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4439 		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
   4440 			save_phy_11g[i] = PHY_READ(mac, save_phy_regs_11g[i]);
   4441 		}
   4442 
   4443 		PHY_SETBITS(mac, 0x814, 0x3);
   4444 		PHY_CLRBITS(mac, 0x815, 0x3);
   4445 		PHY_CLRBITS(mac, 0x429, 0x8000);
   4446 		PHY_CLRBITS(mac, 0x802, 0x3);
   4447 
   4448 		phyr_80f = PHY_READ(mac, 0x80f);
   4449 		phyr_810 = PHY_READ(mac, 0x810);
   4450 
   4451 		if (phy->phy_rev >= 3)
   4452 			PHY_WRITE(mac, 0x80f, 0xc020);
   4453 		else
   4454 			PHY_WRITE(mac, 0x80f, 0x8020);
   4455 		PHY_WRITE(mac, 0x810, 0);
   4456 
   4457 		phy812_val = bwi_phy812_value(mac, 0x011);
   4458 		PHY_WRITE(mac, 0x812, phy812_val);
   4459 		if (phy->phy_rev < 7 ||
   4460 		    (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0)
   4461 			PHY_WRITE(mac, 0x811, 0x1b3);
   4462 		else
   4463 			PHY_WRITE(mac, 0x811, 0x9b3);
   4464 	}
   4465 	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
   4466 
   4467 	phyr_35 = PHY_READ(mac, 0x35);
   4468 	PHY_CLRBITS(mac, 0x35, 0x80);
   4469 
   4470 	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
   4471 	rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
   4472 
   4473 	if (phy->phy_version == 0) {
   4474 		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
   4475 	} else {
   4476 		if (phy->phy_version >= 2)
   4477 			PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40);
   4478 		CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
   4479 	}
   4480 
   4481 	calib = bwi_rf_calibval(mac);
   4482 
   4483 	if (phy->phy_mode == IEEE80211_MODE_11B)
   4484 		RF_WRITE(mac, 0x78, 0x26);
   4485 
   4486 	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4487 		phy812_val = bwi_phy812_value(mac, 0x011);
   4488 		PHY_WRITE(mac, 0x812, phy812_val);
   4489 	}
   4490 
   4491 	PHY_WRITE(mac, 0x15, 0xbfaf);
   4492 	PHY_WRITE(mac, 0x2b, 0x1403);
   4493 
   4494 	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4495 		phy812_val = bwi_phy812_value(mac, 0x001);
   4496 		PHY_WRITE(mac, 0x812, phy812_val);
   4497 	}
   4498 
   4499 	PHY_WRITE(mac, 0x15, 0xbfa0);
   4500 
   4501 	RF_SETBITS(mac, 0x51, 0x4);
   4502 	if (rf->rf_rev == 8)
   4503 		RF_WRITE(mac, 0x43, 0x1f);
   4504 	else {
   4505 		RF_WRITE(mac, 0x52, 0);
   4506 		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
   4507 	}
   4508 
   4509 	test_lim = 0;
   4510 	PHY_WRITE(mac, 0x58, 0);
   4511 	for (i = 0; i < 16; ++i) {
   4512 		PHY_WRITE(mac, 0x5a, 0x480);
   4513 		PHY_WRITE(mac, 0x59, 0xc810);
   4514 
   4515 		PHY_WRITE(mac, 0x58, 0xd);
   4516 		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4517 			phy812_val = bwi_phy812_value(mac, 0x101);
   4518 			PHY_WRITE(mac, 0x812, phy812_val);
   4519 		}
   4520 		PHY_WRITE(mac, 0x15, 0xafb0);
   4521 		DELAY(10);
   4522 
   4523 		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4524 			phy812_val = bwi_phy812_value(mac, 0x101);
   4525 			PHY_WRITE(mac, 0x812, phy812_val);
   4526 		}
   4527 		PHY_WRITE(mac, 0x15, 0xefb0);
   4528 		DELAY(10);
   4529 
   4530 		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4531 			phy812_val = bwi_phy812_value(mac, 0x100);
   4532 			PHY_WRITE(mac, 0x812, phy812_val);
   4533 		}
   4534 		PHY_WRITE(mac, 0x15, 0xfff0);
   4535 		DELAY(20);
   4536 
   4537 		test_lim += PHY_READ(mac, 0x2d);
   4538 
   4539 		PHY_WRITE(mac, 0x58, 0);
   4540 		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4541 			phy812_val = bwi_phy812_value(mac, 0x101);
   4542 			PHY_WRITE(mac, 0x812, phy812_val);
   4543 		}
   4544 		PHY_WRITE(mac, 0x15, 0xafb0);
   4545 	}
   4546 	++test_lim;
   4547 	test_lim >>= 9;
   4548 
   4549 	DELAY(10);
   4550 
   4551 	test = 0;
   4552 	PHY_WRITE(mac, 0x58, 0);
   4553 	for (i = 0; i < 16; ++i) {
   4554 		int j;
   4555 
   4556 		rfr_78 = (bwi_bitswap4(i) << 1) | 0x20;
   4557 		RF_WRITE(mac, 0x78, rfr_78);
   4558 		DELAY(10);
   4559 
   4560 		/* NB: This block is slight different than the above one */
   4561 		for (j = 0; j < 16; ++j) {
   4562 			PHY_WRITE(mac, 0x5a, 0xd80);
   4563 			PHY_WRITE(mac, 0x59, 0xc810);
   4564 
   4565 			PHY_WRITE(mac, 0x58, 0xd);
   4566 			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
   4567 			    phy->phy_rev >= 2) {
   4568 				phy812_val = bwi_phy812_value(mac, 0x101);
   4569 				PHY_WRITE(mac, 0x812, phy812_val);
   4570 			}
   4571 			PHY_WRITE(mac, 0x15, 0xafb0);
   4572 			DELAY(10);
   4573 
   4574 			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
   4575 			    phy->phy_rev >= 2) {
   4576 				phy812_val = bwi_phy812_value(mac, 0x101);
   4577 				PHY_WRITE(mac, 0x812, phy812_val);
   4578 			}
   4579 			PHY_WRITE(mac, 0x15, 0xefb0);
   4580 			DELAY(10);
   4581 
   4582 			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
   4583 			    phy->phy_rev >= 2) {
   4584 				phy812_val = bwi_phy812_value(mac, 0x100);
   4585 				PHY_WRITE(mac, 0x812, phy812_val);
   4586 			}
   4587 			PHY_WRITE(mac, 0x15, 0xfff0);
   4588 			DELAY(10);
   4589 
   4590 			test += PHY_READ(mac, 0x2d);
   4591 
   4592 			PHY_WRITE(mac, 0x58, 0);
   4593 			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
   4594 			    phy->phy_rev >= 2) {
   4595 				phy812_val = bwi_phy812_value(mac, 0x101);
   4596 				PHY_WRITE(mac, 0x812, phy812_val);
   4597 			}
   4598 			PHY_WRITE(mac, 0x15, 0xafb0);
   4599 		}
   4600 
   4601 		++test;
   4602 		test >>= 8;
   4603 
   4604 		if (test > test_lim)
   4605 			break;
   4606 	}
   4607 	if (i > 15)
   4608 		rf->rf_calib = rfr_78;
   4609 	else
   4610 		rf->rf_calib = calib;
   4611 	if (rf->rf_calib != 0xffff) {
   4612 		DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT,
   4613 		    "RF calibration value: 0x%04x\n", rf->rf_calib);
   4614 		rf->rf_flags |= BWI_RF_F_INITED;
   4615 	}
   4616 
   4617 	/*
   4618 	 * Restore trashes registers
   4619 	 */
   4620 	PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]);
   4621 
   4622 	for (i = 0; i < SAVE_RF_MAX; ++i) {
   4623 		int pos = (i + 1) % SAVE_RF_MAX;
   4624 
   4625 		RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]);
   4626 	}
   4627 	for (i = 1; i < SAVE_PHY_COMM_MAX; ++i)
   4628 		PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]);
   4629 
   4630 	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
   4631 	if (phy->phy_version != 0)
   4632 		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex);
   4633 
   4634 	PHY_WRITE(mac, 0x35, phyr_35);
   4635 	bwi_rf_workaround(mac, rf->rf_curchan);
   4636 
   4637 	if (phy->phy_mode == IEEE80211_MODE_11B) {
   4638 		PHY_WRITE(mac, 0x30, phyr_30);
   4639 		CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
   4640 	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
   4641 		/* XXX Spec only says when PHY is linked (gmode) */
   4642 		CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
   4643 
   4644 		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
   4645 			PHY_WRITE(mac, save_phy_regs_11g[i],
   4646 			    save_phy_11g[i]);
   4647 		}
   4648 
   4649 		PHY_WRITE(mac, 0x80f, phyr_80f);
   4650 		PHY_WRITE(mac, 0x810, phyr_810);
   4651 	}
   4652 
   4653 #undef SAVE_PHY_11G_MAX
   4654 #undef SAVE_PHY_COMM_MAX
   4655 #undef SAVE_RF_MAX
   4656 }
   4657 
   4658 static uint16_t
   4659 bwi_rf_calibval(struct bwi_mac *mac)
   4660 {
   4661 	/* http://bcm-specs.sipsolutions.net/RCCTable */
   4662 	static const uint16_t rf_calibvals[] = {
   4663 	    0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
   4664 	    0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
   4665 	};
   4666 
   4667 	uint16_t val, calib;
   4668 	int idx;
   4669 
   4670 	val = RF_READ(mac, BWI_RFR_BBP_ATTEN);
   4671 	idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX);
   4672 	KASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0])));
   4673 
   4674 	calib = rf_calibvals[idx] << 1;
   4675 	if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT)
   4676 		calib |= 0x1;
   4677 	calib |= 0x20;
   4678 
   4679 	return (calib);
   4680 }
   4681 
   4682 static int32_t
   4683 _bwi_adjust_devide(int32_t num, int32_t den)
   4684 {
   4685 	if (num < 0)
   4686 		return (num / den);
   4687 	else
   4688 		return ((num + den / 2) / den);
   4689 }
   4690 
   4691 /*
   4692  * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
   4693  * "calculating table entries"
   4694  */
   4695 static int
   4696 bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[])
   4697 {
   4698 	int32_t m1, m2, f, dbm;
   4699 	int i;
   4700 
   4701 	m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32);
   4702 	m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1);
   4703 
   4704 #define ITER_MAX	16
   4705 	f = 256;
   4706 	for (i = 0; i < ITER_MAX; ++i) {
   4707 		int32_t q, d;
   4708 
   4709 		q = _bwi_adjust_devide(
   4710 		    f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048);
   4711 		d = abs(q - f);
   4712 		f = q;
   4713 
   4714 		if (d < 2)
   4715 			break;
   4716 	}
   4717 	if (i == ITER_MAX)
   4718 		return (EINVAL);
   4719 #undef ITER_MAX
   4720 
   4721 	dbm = _bwi_adjust_devide(m1 * f, 8192);
   4722 	if (dbm < -127)
   4723 		dbm = -127;
   4724 	else if (dbm > 128)
   4725 		dbm = 128;
   4726 
   4727 	*txpwr = dbm;
   4728 
   4729 	return (0);
   4730 }
   4731 
   4732 static int
   4733 bwi_rf_map_txpower(struct bwi_mac *mac)
   4734 {
   4735 	struct bwi_softc *sc = mac->mac_sc;
   4736 	struct bwi_rf *rf = &mac->mac_rf;
   4737 	struct bwi_phy *phy = &mac->mac_phy;
   4738 	uint16_t sprom_ofs, val, mask;
   4739 	int16_t pa_params[3];
   4740 	int error = 0, i, ant_gain, reg_txpower_max;
   4741 #ifdef BWI_DEBUG
   4742 	int debug = sc->sc_debug &
   4743 	    (BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH);
   4744 #endif
   4745 
   4746 	/*
   4747 	 * Find out max TX power
   4748 	 */
   4749 	val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR);
   4750 	if (phy->phy_mode == IEEE80211_MODE_11A) {
   4751 		rf->rf_txpower_max = __SHIFTOUT(val,
   4752 		    BWI_SPROM_MAX_TXPWR_MASK_11A);
   4753 	} else {
   4754 		rf->rf_txpower_max = __SHIFTOUT(val,
   4755 		    BWI_SPROM_MAX_TXPWR_MASK_11BG);
   4756 
   4757 		if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) &&
   4758 		    phy->phy_mode == IEEE80211_MODE_11G)
   4759 			rf->rf_txpower_max -= 3;
   4760 	}
   4761 	if (rf->rf_txpower_max <= 0) {
   4762 		aprint_error_dev(sc->sc_dev,
   4763 		    "invalid max txpower in sprom\n");
   4764 		rf->rf_txpower_max = 74;
   4765 	}
   4766 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
   4767 	    "max txpower from sprom: %d dBm\n", rf->rf_txpower_max);
   4768 
   4769 	/*
   4770 	 * Find out region/domain max TX power, which is adjusted
   4771 	 * by antenna gain and 1.5 dBm fluctuation as mentioned
   4772 	 * in v3 spec.
   4773 	 */
   4774 	val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN);
   4775 	if (phy->phy_mode == IEEE80211_MODE_11A)
   4776 		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A);
   4777 	else
   4778 		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG);
   4779 	if (ant_gain == 0xff) {
   4780 		/* XXX why this always invalid? */
   4781 		aprint_error_dev(sc->sc_dev,
   4782 		    "invalid antenna gain in sprom\n");
   4783 		ant_gain = 2;
   4784 	}
   4785 	ant_gain *= 4;
   4786 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
   4787 	    "ant gain %d dBm\n", ant_gain);
   4788 
   4789 	reg_txpower_max = 90 - ant_gain - 6;	/* XXX magic number */
   4790 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
   4791 	    "region/domain max txpower %d dBm\n", reg_txpower_max);
   4792 
   4793 	/*
   4794 	 * Force max TX power within region/domain TX power limit
   4795 	 */
   4796 	if (rf->rf_txpower_max > reg_txpower_max)
   4797 		rf->rf_txpower_max = reg_txpower_max;
   4798 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
   4799 	    "max txpower %d dBm\n", rf->rf_txpower_max);
   4800 
   4801 	/*
   4802 	 * Create TSSI to TX power mapping
   4803 	 */
   4804 
   4805 	if (sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
   4806 	    rf->rf_type != BWI_RF_T_BCM2050) {
   4807 		rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
   4808 		memcpy(rf->rf_txpower_map0, bwi_txpower_map_11b,
   4809 		      sizeof(rf->rf_txpower_map0));
   4810 		goto back;
   4811 	}
   4812 
   4813 #define IS_VALID_PA_PARAM(p)	((p) != 0 && (p) != -1)
   4814 	/*
   4815 	 * Extract PA parameters
   4816 	 */
   4817 	if (phy->phy_mode == IEEE80211_MODE_11A)
   4818 		sprom_ofs = BWI_SPROM_PA_PARAM_11A;
   4819 	else
   4820 		sprom_ofs = BWI_SPROM_PA_PARAM_11BG;
   4821 	for (i = 0; i < __arraycount(pa_params); ++i)
   4822 		pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2));
   4823 
   4824 	for (i = 0; i < __arraycount(pa_params); ++i) {
   4825 		/*
   4826 		 * If one of the PA parameters from SPROM is not valid,
   4827 		 * fall back to the default values, if there are any.
   4828 		 */
   4829 		if (!IS_VALID_PA_PARAM(pa_params[i])) {
   4830 			const int8_t *txpower_map;
   4831 
   4832 			if (phy->phy_mode == IEEE80211_MODE_11A) {
   4833 				aprint_error_dev(sc->sc_dev,
   4834 				    "no tssi2dbm table for 11a PHY\n");
   4835 				return (ENXIO);
   4836 			}
   4837 
   4838 			if (phy->phy_mode == IEEE80211_MODE_11G) {
   4839 				DPRINTF(sc,
   4840 				    BWI_DBG_RF | BWI_DBG_TXPOWER |
   4841 					BWI_DBG_ATTACH,
   4842 				    "use default 11g TSSI map\n");
   4843 				txpower_map = bwi_txpower_map_11g;
   4844 			} else {
   4845 				DPRINTF(sc,
   4846 				    BWI_DBG_RF | BWI_DBG_TXPOWER |
   4847 					BWI_DBG_ATTACH,
   4848 				    "use default 11b TSSI map\n");
   4849 				txpower_map = bwi_txpower_map_11b;
   4850 			}
   4851 
   4852 			rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
   4853 			memcpy(rf->rf_txpower_map0, txpower_map,
   4854 			      sizeof(rf->rf_txpower_map0));
   4855 			goto back;
   4856 		}
   4857 	}
   4858 
   4859 	/*
   4860 	 * All of the PA parameters from SPROM are valid.
   4861 	 */
   4862 
   4863 	/*
   4864 	 * Extract idle TSSI from SPROM.
   4865 	 */
   4866 	val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI);
   4867 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
   4868 	    "sprom idle tssi: 0x%04x\n", val);
   4869 
   4870 	if (phy->phy_mode == IEEE80211_MODE_11A)
   4871 		mask = BWI_SPROM_IDLE_TSSI_MASK_11A;
   4872 	else
   4873 		mask = BWI_SPROM_IDLE_TSSI_MASK_11BG;
   4874 
   4875 	rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask);
   4876 	if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0))
   4877 		rf->rf_idle_tssi0 = 62;
   4878 
   4879 #undef IS_VALID_PA_PARAM
   4880 
   4881 	/*
   4882 	 * Calculate TX power map, which is indexed by TSSI
   4883 	 */
   4884 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
   4885 	    "TSSI-TX power map:\n");
   4886 	for (i = 0; i < BWI_TSSI_MAX; ++i) {
   4887 		error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i,
   4888 					    pa_params);
   4889 		if (error) {
   4890 			aprint_error_dev(sc->sc_dev,
   4891 			    "bwi_rf_calc_txpower failed\n");
   4892 			break;
   4893 		}
   4894 #ifdef BWI_DEBUG
   4895 		if (debug) {
   4896 			if (i % 8 == 0) {
   4897 				if (i != 0)
   4898 					aprint_debug("\n");
   4899 				aprint_debug_dev(sc->sc_dev, "");
   4900 			}
   4901 			aprint_debug(" %d", rf->rf_txpower_map0[i]);
   4902 		}
   4903 #endif
   4904 	}
   4905 #ifdef BWI_DEBUG
   4906 	if (debug)
   4907 		aprint_debug("\n");
   4908 #endif
   4909 back:
   4910 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
   4911 	    "idle tssi0: %d\n", rf->rf_idle_tssi0);
   4912 
   4913 	return (error);
   4914 }
   4915 
   4916 static void
   4917 bwi_rf_lo_update_11g(struct bwi_mac *mac)
   4918 {
   4919 	struct bwi_softc *sc = mac->mac_sc;
   4920 	struct ifnet *ifp = &sc->sc_if;
   4921 	struct bwi_rf *rf = &mac->mac_rf;
   4922 	struct bwi_phy *phy = &mac->mac_phy;
   4923 	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
   4924 	struct rf_saveregs regs;
   4925 	uint16_t ant_div, chan_ex;
   4926 	uint8_t devi_ctrl;
   4927 	uint orig_chan;
   4928 
   4929 	DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT, "%s enter\n", __func__);
   4930 
   4931 	/*
   4932 	 * Save RF/PHY registers for later restoration
   4933 	 */
   4934 	orig_chan = rf->rf_curchan;
   4935 	memset(&regs, 0, sizeof(regs));
   4936 
   4937 	if (phy->phy_flags & BWI_PHY_F_LINKED) {
   4938 		SAVE_PHY_REG(mac, &regs, 429);
   4939 		SAVE_PHY_REG(mac, &regs, 802);
   4940 
   4941 		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
   4942 		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
   4943 	}
   4944 
   4945 	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
   4946 	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000);
   4947 	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
   4948 
   4949 	SAVE_PHY_REG(mac, &regs, 15);
   4950 	SAVE_PHY_REG(mac, &regs, 2a);
   4951 	SAVE_PHY_REG(mac, &regs, 35);
   4952 	SAVE_PHY_REG(mac, &regs, 60);
   4953 	SAVE_RF_REG(mac, &regs, 43);
   4954 	SAVE_RF_REG(mac, &regs, 7a);
   4955 	SAVE_RF_REG(mac, &regs, 52);
   4956 	if (phy->phy_flags & BWI_PHY_F_LINKED) {
   4957 		SAVE_PHY_REG(mac, &regs, 811);
   4958 		SAVE_PHY_REG(mac, &regs, 812);
   4959 		SAVE_PHY_REG(mac, &regs, 814);
   4960 		SAVE_PHY_REG(mac, &regs, 815);
   4961 	}
   4962 
   4963 	/* Force to channel 6 */
   4964 	bwi_rf_set_chan(mac, 6, 0);
   4965 
   4966 	if (phy->phy_flags & BWI_PHY_F_LINKED) {
   4967 		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
   4968 		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
   4969 		bwi_mac_dummy_xmit(mac);
   4970 	}
   4971 	RF_WRITE(mac, 0x43, 0x6);
   4972 
   4973 	bwi_phy_set_bbp_atten(mac, 2);
   4974 
   4975 	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0);
   4976 
   4977 	PHY_WRITE(mac, 0x2e, 0x7f);
   4978 	PHY_WRITE(mac, 0x80f, 0x78);
   4979 	PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
   4980 	RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
   4981 	PHY_WRITE(mac, 0x2b, 0x203);
   4982 	PHY_WRITE(mac, 0x2a, 0x8a3);
   4983 
   4984 	if (phy->phy_flags & BWI_PHY_F_LINKED) {
   4985 		PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3);
   4986 		PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc);
   4987 		PHY_WRITE(mac, 0x811, 0x1b3);
   4988 		PHY_WRITE(mac, 0x812, 0xb2);
   4989 	}
   4990 
   4991 	if ((ifp->if_flags & IFF_RUNNING) == 0)
   4992 		tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
   4993 	PHY_WRITE(mac, 0x80f, 0x8078);
   4994 
   4995 	/*
   4996 	 * Measure all RF LO
   4997 	 */
   4998 	devi_ctrl = _bwi_rf_lo_update_11g(mac, regs.rf_7a);
   4999 
   5000 	/*
   5001 	 * Restore saved RF/PHY registers
   5002 	 */
   5003 	if (phy->phy_flags & BWI_PHY_F_LINKED) {
   5004 		PHY_WRITE(mac, 0x15, 0xe300);
   5005 		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0);
   5006 		DELAY(5);
   5007 		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2);
   5008 		DELAY(2);
   5009 		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3);
   5010 	} else
   5011 		PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
   5012 
   5013 	if ((ifp->if_flags & IFF_RUNNING) == 0)
   5014 		tpctl = NULL;
   5015 	bwi_rf_lo_adjust(mac, tpctl);
   5016 
   5017 	PHY_WRITE(mac, 0x2e, 0x807f);
   5018 	if (phy->phy_flags & BWI_PHY_F_LINKED)
   5019 		PHY_WRITE(mac, 0x2f, 0x202);
   5020 	else
   5021 		PHY_WRITE(mac, 0x2f, 0x101);
   5022 
   5023 	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
   5024 
   5025 	RESTORE_PHY_REG(mac, &regs, 15);
   5026 	RESTORE_PHY_REG(mac, &regs, 2a);
   5027 	RESTORE_PHY_REG(mac, &regs, 35);
   5028 	RESTORE_PHY_REG(mac, &regs, 60);
   5029 
   5030 	RESTORE_RF_REG(mac, &regs, 43);
   5031 	RESTORE_RF_REG(mac, &regs, 7a);
   5032 
   5033 	regs.rf_52 &= 0xf0;
   5034 	regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf);
   5035 	RF_WRITE(mac, 0x52, regs.rf_52);
   5036 
   5037 	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
   5038 
   5039 	if (phy->phy_flags & BWI_PHY_F_LINKED) {
   5040 		RESTORE_PHY_REG(mac, &regs, 811);
   5041 		RESTORE_PHY_REG(mac, &regs, 812);
   5042 		RESTORE_PHY_REG(mac, &regs, 814);
   5043 		RESTORE_PHY_REG(mac, &regs, 815);
   5044 		RESTORE_PHY_REG(mac, &regs, 429);
   5045 		RESTORE_PHY_REG(mac, &regs, 802);
   5046 	}
   5047 
   5048 	bwi_rf_set_chan(mac, orig_chan, 1);
   5049 }
   5050 
   5051 static uint32_t
   5052 bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl)
   5053 {
   5054 	struct bwi_phy *phy = &mac->mac_phy;
   5055 	uint32_t devi = 0;
   5056 	int i;
   5057 
   5058 	if (phy->phy_flags & BWI_PHY_F_LINKED)
   5059 		ctrl <<= 8;
   5060 
   5061 	for (i = 0; i < 8; ++i) {
   5062 		if (phy->phy_flags & BWI_PHY_F_LINKED) {
   5063 			PHY_WRITE(mac, 0x15, 0xe300);
   5064 			PHY_WRITE(mac, 0x812, ctrl | 0xb0);
   5065 			DELAY(5);
   5066 			PHY_WRITE(mac, 0x812, ctrl | 0xb2);
   5067 			DELAY(2);
   5068 			PHY_WRITE(mac, 0x812, ctrl | 0xb3);
   5069 			DELAY(4);
   5070 			PHY_WRITE(mac, 0x15, 0xf300);
   5071 		} else {
   5072 			PHY_WRITE(mac, 0x15, ctrl | 0xefa0);
   5073 			DELAY(2);
   5074 			PHY_WRITE(mac, 0x15, ctrl | 0xefe0);
   5075 			DELAY(4);
   5076 			PHY_WRITE(mac, 0x15, ctrl | 0xffe0);
   5077 		}
   5078 		DELAY(8);
   5079 		devi += PHY_READ(mac, 0x2d);
   5080 	}
   5081 
   5082 	return (devi);
   5083 }
   5084 
   5085 static uint16_t
   5086 bwi_rf_get_tp_ctrl2(struct bwi_mac *mac)
   5087 {
   5088 	uint32_t devi_min;
   5089 	uint16_t tp_ctrl2 = 0;
   5090 	int i;
   5091 
   5092 	RF_WRITE(mac, 0x52, 0);
   5093 	DELAY(10);
   5094 	devi_min = bwi_rf_lo_devi_measure(mac, 0);
   5095 
   5096 	for (i = 0; i < 16; ++i) {
   5097 		uint32_t devi;
   5098 
   5099 		RF_WRITE(mac, 0x52, i);
   5100 		DELAY(10);
   5101 		devi = bwi_rf_lo_devi_measure(mac, 0);
   5102 
   5103 		if (devi < devi_min) {
   5104 			devi_min = devi;
   5105 			tp_ctrl2 = i;
   5106 		}
   5107 	}
   5108 
   5109 	return (tp_ctrl2);
   5110 }
   5111 
   5112 static uint8_t
   5113 _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a)
   5114 {
   5115 #define RF_ATTEN_LISTSZ	14
   5116 #define BBP_ATTEN_MAX	4	/* half */
   5117 	static const int rf_atten_list[RF_ATTEN_LISTSZ] =
   5118 	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
   5119 	static const int rf_atten_init_list[RF_ATTEN_LISTSZ] =
   5120             { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
   5121 	static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
   5122 	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
   5123 
   5124 	struct ifnet *ifp = &mac->mac_sc->sc_if;
   5125 	struct bwi_rf_lo lo_save, *lo;
   5126 	uint8_t devi_ctrl = 0;
   5127 	int idx, adj_rf7a = 0;
   5128 
   5129 	memset(&lo_save, 0, sizeof(lo_save));
   5130 	for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) {
   5131 		int init_rf_atten = rf_atten_init_list[idx];
   5132 		int rf_atten = rf_atten_list[idx];
   5133 		int bbp_atten;
   5134 
   5135 		for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
   5136 			uint16_t tp_ctrl2, rf7a;
   5137 
   5138 			if ((ifp->if_flags & IFF_RUNNING) == 0) {
   5139 				if (idx == 0) {
   5140 					memset(&lo_save, 0, sizeof(lo_save));
   5141 				} else if (init_rf_atten < 0) {
   5142 					lo = bwi_get_rf_lo(mac,
   5143 					    rf_atten, 2 * bbp_atten);
   5144 					memcpy(&lo_save, lo, sizeof(lo_save));
   5145 				} else {
   5146 					lo = bwi_get_rf_lo(mac,
   5147 					    init_rf_atten, 0);
   5148 					memcpy(&lo_save, lo, sizeof(lo_save));
   5149 				}
   5150 
   5151 				devi_ctrl = 0;
   5152 				adj_rf7a = 0;
   5153 
   5154 				/*
   5155 				 * XXX
   5156 				 * Linux driver overflows 'val'
   5157 				 */
   5158 				if (init_rf_atten >= 0) {
   5159 					int val;
   5160 
   5161 					val = rf_atten * 2 + bbp_atten;
   5162 					if (val > 14) {
   5163 						adj_rf7a = 1;
   5164 						if (val > 17)
   5165 							devi_ctrl = 1;
   5166 						if (val > 19)
   5167 							devi_ctrl = 2;
   5168 					}
   5169 				}
   5170 			} else {
   5171 				lo = bwi_get_rf_lo(mac,
   5172 					rf_atten, 2 * bbp_atten);
   5173 				if (!bwi_rf_lo_isused(mac, lo))
   5174 					continue;
   5175 				memcpy(&lo_save, lo, sizeof(lo_save));
   5176 
   5177 				devi_ctrl = 3;
   5178 				adj_rf7a = 0;
   5179 			}
   5180 
   5181 			RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten);
   5182 
   5183 			tp_ctrl2 = mac->mac_tpctl.tp_ctrl2;
   5184 			if (init_rf_atten < 0)
   5185 				tp_ctrl2 |= (3 << 4);
   5186 			RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2);
   5187 
   5188 			DELAY(10);
   5189 
   5190 			bwi_phy_set_bbp_atten(mac, bbp_atten * 2);
   5191 
   5192 			rf7a = orig_rf7a & 0xfff0;
   5193 			if (adj_rf7a)
   5194 				rf7a |= 0x8;
   5195 			RF_WRITE(mac, 0x7a, rf7a);
   5196 
   5197 			lo = bwi_get_rf_lo(mac,
   5198 				rf_lo_measure_order[idx], bbp_atten * 2);
   5199 			bwi_rf_lo_measure_11g(mac, &lo_save, lo, devi_ctrl);
   5200 		}
   5201 	}
   5202 
   5203 	return (devi_ctrl);
   5204 
   5205 #undef RF_ATTEN_LISTSZ
   5206 #undef BBP_ATTEN_MAX
   5207 }
   5208 
   5209 static void
   5210 bwi_rf_lo_measure_11g(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo,
   5211     struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl)
   5212 {
   5213 #define LO_ADJUST_MIN	1
   5214 #define LO_ADJUST_MAX	8
   5215 #define LO_ADJUST(hi, lo)	{ .ctrl_hi = hi, .ctrl_lo = lo }
   5216 	static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = {
   5217 		LO_ADJUST(1,	1),
   5218 		LO_ADJUST(1,	0),
   5219 		LO_ADJUST(1,	-1),
   5220 		LO_ADJUST(0,	-1),
   5221 		LO_ADJUST(-1,	-1),
   5222 		LO_ADJUST(-1,	0),
   5223 		LO_ADJUST(-1,	1),
   5224 		LO_ADJUST(0,	1)
   5225 	};
   5226 #undef LO_ADJUST
   5227 
   5228 	struct bwi_rf_lo lo_min;
   5229 	uint32_t devi_min;
   5230 	int found, loop_count, adjust_state;
   5231 
   5232 	memcpy(&lo_min, src_lo, sizeof(lo_min));
   5233 	RF_LO_WRITE(mac, &lo_min);
   5234 	devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl);
   5235 
   5236 	loop_count = 12;	/* XXX */
   5237 	adjust_state = 0;
   5238 	do {
   5239 		struct bwi_rf_lo lo_base;
   5240 		int i, fin;
   5241 
   5242 		found = 0;
   5243 		if (adjust_state == 0) {
   5244 			i = LO_ADJUST_MIN;
   5245 			fin = LO_ADJUST_MAX;
   5246 		} else if (adjust_state % 2 == 0) {
   5247 			i = adjust_state - 1;
   5248 			fin = adjust_state + 1;
   5249 		} else {
   5250 			i = adjust_state - 2;
   5251 			fin = adjust_state + 2;
   5252 		}
   5253 
   5254 		if (i < LO_ADJUST_MIN)
   5255 			i += LO_ADJUST_MAX;
   5256 		KASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN);
   5257 
   5258 		if (fin > LO_ADJUST_MAX)
   5259 			fin -= LO_ADJUST_MAX;
   5260 		KASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN);
   5261 
   5262 		memcpy(&lo_base, &lo_min, sizeof(lo_base));
   5263 		for (;;) {
   5264 			struct bwi_rf_lo lo;
   5265 
   5266 			lo.ctrl_hi = lo_base.ctrl_hi +
   5267 				rf_lo_adjust[i - 1].ctrl_hi;
   5268 			lo.ctrl_lo = lo_base.ctrl_lo +
   5269 				rf_lo_adjust[i - 1].ctrl_lo;
   5270 
   5271 			if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) {
   5272 				uint32_t devi;
   5273 
   5274 				RF_LO_WRITE(mac, &lo);
   5275 				devi = bwi_rf_lo_devi_measure(mac, devi_ctrl);
   5276 				if (devi < devi_min) {
   5277 					devi_min = devi;
   5278 					adjust_state = i;
   5279 					found = 1;
   5280 					memcpy(&lo_min, &lo, sizeof(lo_min));
   5281 				}
   5282 			}
   5283 			if (i == fin)
   5284 				break;
   5285 			if (i == LO_ADJUST_MAX)
   5286 				i = LO_ADJUST_MIN;
   5287 			else
   5288 				++i;
   5289 		}
   5290 	} while (loop_count-- && found);
   5291 
   5292 	memcpy(dst_lo, &lo_min, sizeof(*dst_lo));
   5293 
   5294 #undef LO_ADJUST_MIN
   5295 #undef LO_ADJUST_MAX
   5296 }
   5297 
   5298 static void
   5299 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac)
   5300 {
   5301 #define SAVE_RF_MAX	3
   5302 #define SAVE_PHY_MAX	8
   5303 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
   5304 	    { 0x7a, 0x52, 0x43 };
   5305 	static const uint16_t save_phy_regs[SAVE_PHY_MAX] =
   5306 	    { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
   5307 
   5308 	struct bwi_softc *sc = mac->mac_sc;
   5309 	struct bwi_rf *rf = &mac->mac_rf;
   5310 	struct bwi_phy *phy = &mac->mac_phy;
   5311 	uint16_t save_rf[SAVE_RF_MAX];
   5312 	uint16_t save_phy[SAVE_PHY_MAX];
   5313 	uint16_t ant_div, chan_ex;
   5314 	int16_t nrssi[2];
   5315 	int i;
   5316 
   5317 	/*
   5318 	 * Save RF/PHY registers for later restoration
   5319 	 */
   5320 	for (i = 0; i < SAVE_RF_MAX; ++i)
   5321 		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
   5322 	for (i = 0; i < SAVE_PHY_MAX; ++i)
   5323 		save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
   5324 
   5325 	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
   5326 	(void)CSR_READ_2(sc, BWI_BBP_ATTEN);
   5327 	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
   5328 
   5329 	/*
   5330 	 * Calculate nrssi0
   5331 	 */
   5332 	if (phy->phy_rev >= 5)
   5333 		RF_CLRBITS(mac, 0x7a, 0xff80);
   5334 	else
   5335 		RF_CLRBITS(mac, 0x7a, 0xfff0);
   5336 	PHY_WRITE(mac, 0x30, 0xff);
   5337 
   5338 	CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f);
   5339 
   5340 	PHY_WRITE(mac, 0x26, 0);
   5341 	PHY_SETBITS(mac, 0x15, 0x20);
   5342 	PHY_WRITE(mac, 0x2a, 0x8a3);
   5343 	RF_SETBITS(mac, 0x7a, 0x80);
   5344 
   5345 	nrssi[0] = (int16_t)PHY_READ(mac, 0x27);
   5346 
   5347 	/*
   5348 	 * Calculate nrssi1
   5349 	 */
   5350 	RF_CLRBITS(mac, 0x7a, 0xff80);
   5351 	if (phy->phy_version >= 2)
   5352 		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40);
   5353 	else if (phy->phy_version == 0)
   5354 		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
   5355 	else
   5356 		CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff);
   5357 
   5358 	PHY_WRITE(mac, 0x20, 0x3f3f);
   5359 	PHY_WRITE(mac, 0x15, 0xf330);
   5360 
   5361 	RF_WRITE(mac, 0x5a, 0x60);
   5362 	RF_CLRBITS(mac, 0x43, 0xff0f);
   5363 
   5364 	PHY_WRITE(mac, 0x5a, 0x480);
   5365 	PHY_WRITE(mac, 0x59, 0x810);
   5366 	PHY_WRITE(mac, 0x58, 0xd);
   5367 
   5368 	DELAY(20);
   5369 
   5370 	nrssi[1] = (int16_t)PHY_READ(mac, 0x27);
   5371 
   5372 	/*
   5373 	 * Restore saved RF/PHY registers
   5374 	 */
   5375 	PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
   5376 	RF_WRITE(mac, save_rf_regs[0], save_rf[0]);
   5377 
   5378 	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
   5379 
   5380 	for (i = 1; i < 4; ++i)
   5381 		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
   5382 
   5383 	bwi_rf_workaround(mac, rf->rf_curchan);
   5384 
   5385 	if (phy->phy_version != 0)
   5386 		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
   5387 
   5388 	for (; i < SAVE_PHY_MAX; ++i)
   5389 		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
   5390 
   5391 	for (i = 1; i < SAVE_RF_MAX; ++i)
   5392 		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
   5393 
   5394 	/*
   5395 	 * Install calculated narrow RSSI values
   5396 	 */
   5397 	if (nrssi[0] == nrssi[1])
   5398 		rf->rf_nrssi_slope = 0x10000;
   5399 	else
   5400 		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
   5401 	if (nrssi[0] <= -4) {
   5402 		rf->rf_nrssi[0] = nrssi[0];
   5403 		rf->rf_nrssi[1] = nrssi[1];
   5404 	}
   5405 
   5406 #undef SAVE_RF_MAX
   5407 #undef SAVE_PHY_MAX
   5408 }
   5409 
   5410 static void
   5411 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac)
   5412 {
   5413 #define SAVE_RF_MAX		2
   5414 #define SAVE_PHY_COMM_MAX	10
   5415 #define SAVE_PHY6_MAX		8
   5416 	static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 };
   5417 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
   5418 		0x0001, 0x0811, 0x0812, 0x0814,
   5419 		0x0815, 0x005a, 0x0059, 0x0058,
   5420 		0x000a, 0x0003
   5421 	};
   5422 	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
   5423 		0x002e, 0x002f, 0x080f, 0x0810,
   5424 		0x0801, 0x0060, 0x0014, 0x0478
   5425 	};
   5426 
   5427 	struct bwi_phy *phy = &mac->mac_phy;
   5428 	uint16_t save_rf[SAVE_RF_MAX];
   5429 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
   5430 	uint16_t save_phy6[SAVE_PHY6_MAX];
   5431 	uint16_t rf7b = 0xffff;
   5432 	int16_t nrssi;
   5433 	int i, phy6_idx = 0;
   5434 
   5435 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
   5436 		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
   5437 	for (i = 0; i < SAVE_RF_MAX; ++i)
   5438 		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
   5439 
   5440 	PHY_CLRBITS(mac, 0x429, 0x8000);
   5441 	PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000);
   5442 	PHY_SETBITS(mac, 0x811, 0xc);
   5443 	PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4);
   5444 	PHY_CLRBITS(mac, 0x802, 0x3);
   5445 
   5446 	if (phy->phy_rev >= 6) {
   5447 		for (i = 0; i < SAVE_PHY6_MAX; ++i)
   5448 			save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]);
   5449 
   5450 		PHY_WRITE(mac, 0x2e, 0);
   5451 		PHY_WRITE(mac, 0x2f, 0);
   5452 		PHY_WRITE(mac, 0x80f, 0);
   5453 		PHY_WRITE(mac, 0x810, 0);
   5454 		PHY_SETBITS(mac, 0x478, 0x100);
   5455 		PHY_SETBITS(mac, 0x801, 0x40);
   5456 		PHY_SETBITS(mac, 0x60, 0x40);
   5457 		PHY_SETBITS(mac, 0x14, 0x200);
   5458 	}
   5459 
   5460 	RF_SETBITS(mac, 0x7a, 0x70);
   5461 	RF_SETBITS(mac, 0x7a, 0x80);
   5462 
   5463 	DELAY(30);
   5464 
   5465 	nrssi = bwi_nrssi_11g(mac);
   5466 	if (nrssi == 31) {
   5467 		for (i = 7; i >= 4; --i) {
   5468 			RF_WRITE(mac, 0x7b, i);
   5469 			DELAY(20);
   5470 			nrssi = bwi_nrssi_11g(mac);
   5471 			if (nrssi < 31 && rf7b == 0xffff)
   5472 				rf7b = i;
   5473 		}
   5474 		if (rf7b == 0xffff)
   5475 			rf7b = 4;
   5476 	} else {
   5477 		struct bwi_gains gains;
   5478 
   5479 		RF_CLRBITS(mac, 0x7a, 0xff80);
   5480 
   5481 		PHY_SETBITS(mac, 0x814, 0x1);
   5482 		PHY_CLRBITS(mac, 0x815, 0x1);
   5483 		PHY_SETBITS(mac, 0x811, 0xc);
   5484 		PHY_SETBITS(mac, 0x812, 0xc);
   5485 		PHY_SETBITS(mac, 0x811, 0x30);
   5486 		PHY_SETBITS(mac, 0x812, 0x30);
   5487 		PHY_WRITE(mac, 0x5a, 0x480);
   5488 		PHY_WRITE(mac, 0x59, 0x810);
   5489 		PHY_WRITE(mac, 0x58, 0xd);
   5490 		if (phy->phy_version == 0)
   5491 			PHY_WRITE(mac, 0x3, 0x122);
   5492 		else
   5493 			PHY_SETBITS(mac, 0xa, 0x2000);
   5494 		PHY_SETBITS(mac, 0x814, 0x4);
   5495 		PHY_CLRBITS(mac, 0x815, 0x4);
   5496 		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
   5497 		RF_SETBITS(mac, 0x7a, 0xf);
   5498 
   5499 		memset(&gains, 0, sizeof(gains));
   5500 		gains.tbl_gain1 = 3;
   5501 		gains.tbl_gain2 = 0;
   5502 		gains.phy_gain = 1;
   5503 		bwi_set_gains(mac, &gains);
   5504 
   5505 		RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf);
   5506 		DELAY(30);
   5507 
   5508 		nrssi = bwi_nrssi_11g(mac);
   5509 		if (nrssi == -32) {
   5510 			for (i = 0; i < 4; ++i) {
   5511 				RF_WRITE(mac, 0x7b, i);
   5512 				DELAY(20);
   5513 				nrssi = bwi_nrssi_11g(mac);
   5514 				if (nrssi > -31 && rf7b == 0xffff)
   5515 					rf7b = i;
   5516 			}
   5517 			if (rf7b == 0xffff)
   5518 				rf7b = 3;
   5519 		} else {
   5520 			rf7b = 0;
   5521 		}
   5522 	}
   5523 	RF_WRITE(mac, 0x7b, rf7b);
   5524 
   5525 	/*
   5526 	 * Restore saved RF/PHY registers
   5527 	 */
   5528 	if (phy->phy_rev >= 6) {
   5529 		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
   5530 			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
   5531 			    save_phy6[phy6_idx]);
   5532 		}
   5533 	}
   5534 
   5535 	/* Saved PHY registers 0, 1, 2 are handled later */
   5536 	for (i = 3; i < SAVE_PHY_COMM_MAX; ++i)
   5537 		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
   5538 
   5539 	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
   5540 		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
   5541 
   5542 	PHY_SETBITS(mac, 0x802, 0x3);
   5543 	PHY_SETBITS(mac, 0x429, 0x8000);
   5544 
   5545 	bwi_set_gains(mac, NULL);
   5546 
   5547 	if (phy->phy_rev >= 6) {
   5548 		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
   5549 			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
   5550 			    save_phy6[phy6_idx]);
   5551 		}
   5552 	}
   5553 
   5554 	PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
   5555 	PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
   5556 	PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
   5557 
   5558 #undef SAVE_RF_MAX
   5559 #undef SAVE_PHY_COMM_MAX
   5560 #undef SAVE_PHY6_MAX
   5561 }
   5562 
   5563 static void
   5564 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac)
   5565 {
   5566 #define SAVE_RF_MAX		3
   5567 #define SAVE_PHY_COMM_MAX	4
   5568 #define SAVE_PHY3_MAX		8
   5569 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
   5570 	    { 0x7a, 0x52, 0x43 };
   5571 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
   5572 	    { 0x15, 0x5a, 0x59, 0x58 };
   5573 	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
   5574 		0x002e, 0x002f, 0x080f, 0x0810,
   5575 		0x0801, 0x0060, 0x0014, 0x0478
   5576 	};
   5577 
   5578 	struct bwi_softc *sc = mac->mac_sc;
   5579 	struct bwi_phy *phy = &mac->mac_phy;
   5580 	struct bwi_rf *rf = &mac->mac_rf;
   5581 	uint16_t save_rf[SAVE_RF_MAX];
   5582 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
   5583 	uint16_t save_phy3[SAVE_PHY3_MAX];
   5584 	uint16_t ant_div, bbp_atten, chan_ex;
   5585 	struct bwi_gains gains;
   5586 	int16_t nrssi[2];
   5587 	int i, phy3_idx = 0;
   5588 
   5589 	if (rf->rf_rev >= 9)
   5590 		return;
   5591 	else if (rf->rf_rev == 8)
   5592 		bwi_rf_set_nrssi_ofs_11g(mac);
   5593 
   5594 	PHY_CLRBITS(mac, 0x429, 0x8000);
   5595 	PHY_CLRBITS(mac, 0x802, 0x3);
   5596 
   5597 	/*
   5598 	 * Save RF/PHY registers for later restoration
   5599 	 */
   5600 	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
   5601 	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
   5602 
   5603 	for (i = 0; i < SAVE_RF_MAX; ++i)
   5604 		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
   5605 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
   5606 		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
   5607 
   5608 	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
   5609 	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
   5610 
   5611 	if (phy->phy_rev >= 3) {
   5612 		for (i = 0; i < SAVE_PHY3_MAX; ++i)
   5613 			save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]);
   5614 
   5615 		PHY_WRITE(mac, 0x2e, 0);
   5616 		PHY_WRITE(mac, 0x810, 0);
   5617 
   5618 		if (phy->phy_rev == 4 || phy->phy_rev == 6 ||
   5619 		    phy->phy_rev == 7) {
   5620 			PHY_SETBITS(mac, 0x478, 0x100);
   5621 			PHY_SETBITS(mac, 0x810, 0x40);
   5622 		} else if (phy->phy_rev == 3 || phy->phy_rev == 5)
   5623 			PHY_CLRBITS(mac, 0x810, 0x40);
   5624 
   5625 		PHY_SETBITS(mac, 0x60, 0x40);
   5626 		PHY_SETBITS(mac, 0x14, 0x200);
   5627 	}
   5628 
   5629 	/*
   5630 	 * Calculate nrssi0
   5631 	 */
   5632 	RF_SETBITS(mac, 0x7a, 0x70);
   5633 
   5634 	memset(&gains, 0, sizeof(gains));
   5635 	gains.tbl_gain1 = 0;
   5636 	gains.tbl_gain2 = 8;
   5637 	gains.phy_gain = 0;
   5638 	bwi_set_gains(mac, &gains);
   5639 
   5640 	RF_CLRBITS(mac, 0x7a, 0xff08);
   5641 	if (phy->phy_rev >= 2) {
   5642 		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30);
   5643 		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
   5644 	}
   5645 
   5646 	RF_SETBITS(mac, 0x7a, 0x80);
   5647 	DELAY(20);
   5648 	nrssi[0] = bwi_nrssi_11g(mac);
   5649 
   5650 	/*
   5651 	 * Calculate nrssi1
   5652 	 */
   5653 	RF_CLRBITS(mac, 0x7a, 0xff80);
   5654 	if (phy->phy_version >= 2)
   5655 		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
   5656 	CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
   5657 
   5658 	RF_SETBITS(mac, 0x7a, 0xf);
   5659 	PHY_WRITE(mac, 0x15, 0xf330);
   5660 	if (phy->phy_rev >= 2) {
   5661 		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20);
   5662 		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20);
   5663 	}
   5664 
   5665 	memset(&gains, 0, sizeof(gains));
   5666 	gains.tbl_gain1 = 3;
   5667 	gains.tbl_gain2 = 0;
   5668 	gains.phy_gain = 1;
   5669 	bwi_set_gains(mac, &gains);
   5670 
   5671 	if (rf->rf_rev == 8) {
   5672 		RF_WRITE(mac, 0x43, 0x1f);
   5673 	} else {
   5674 		RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60);
   5675 		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
   5676 	}
   5677 	PHY_WRITE(mac, 0x5a, 0x480);
   5678 	PHY_WRITE(mac, 0x59, 0x810);
   5679 	PHY_WRITE(mac, 0x58, 0xd);
   5680 	DELAY(20);
   5681 
   5682 	nrssi[1] = bwi_nrssi_11g(mac);
   5683 
   5684 	/*
   5685 	 * Install calculated narrow RSSI values
   5686 	 */
   5687 	if (nrssi[1] == nrssi[0])
   5688 		rf->rf_nrssi_slope = 0x10000;
   5689 	else
   5690 		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
   5691 	if (nrssi[0] >= -4) {
   5692 		rf->rf_nrssi[0] = nrssi[1];
   5693 		rf->rf_nrssi[1] = nrssi[0];
   5694 	}
   5695 
   5696 	/*
   5697 	 * Restore saved RF/PHY registers
   5698 	 */
   5699 	if (phy->phy_rev >= 3) {
   5700 		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
   5701 			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
   5702 				  save_phy3[phy3_idx]);
   5703 		}
   5704 	}
   5705 	if (phy->phy_rev >= 2) {
   5706 		PHY_CLRBITS(mac, 0x812, 0x30);
   5707 		PHY_CLRBITS(mac, 0x811, 0x30);
   5708 	}
   5709 
   5710 	for (i = 0; i < SAVE_RF_MAX; ++i)
   5711 		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
   5712 
   5713 	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
   5714 	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
   5715 	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
   5716 
   5717 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
   5718 		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
   5719 
   5720 	bwi_rf_workaround(mac, rf->rf_curchan);
   5721 	PHY_SETBITS(mac, 0x802, 0x3);
   5722 	bwi_set_gains(mac, NULL);
   5723 	PHY_SETBITS(mac, 0x429, 0x8000);
   5724 
   5725 	if (phy->phy_rev >= 3) {
   5726 		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
   5727 			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
   5728 			    save_phy3[phy3_idx]);
   5729 		}
   5730 	}
   5731 
   5732 	bwi_rf_init_sw_nrssi_table(mac);
   5733 	bwi_rf_set_nrssi_thr_11g(mac);
   5734 
   5735 #undef SAVE_RF_MAX
   5736 #undef SAVE_PHY_COMM_MAX
   5737 #undef SAVE_PHY3_MAX
   5738 }
   5739 
   5740 static void
   5741 bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac)
   5742 {
   5743 	struct bwi_rf *rf = &mac->mac_rf;
   5744 	int d, i;
   5745 
   5746 	d = 0x1f - rf->rf_nrssi[0];
   5747 	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
   5748 		int val;
   5749 
   5750 		val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a;
   5751 		if (val < 0)
   5752 			val = 0;
   5753 		else if (val > 0x3f)
   5754 			val = 0x3f;
   5755 
   5756 		rf->rf_nrssi_table[i] = val;
   5757 	}
   5758 }
   5759 
   5760 static void
   5761 bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust)
   5762 {
   5763 	int i;
   5764 
   5765 	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
   5766 		int16_t val;
   5767 
   5768 		val = bwi_nrssi_read(mac, i);
   5769 
   5770 		val -= adjust;
   5771 		if (val < -32)
   5772 			val = -32;
   5773 		else if (val > 31)
   5774 			val = 31;
   5775 
   5776 		bwi_nrssi_write(mac, i, val);
   5777 	}
   5778 }
   5779 
   5780 static void
   5781&