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