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