Home | History | Annotate | Line # | Download | only in pci
if_iwi.c revision 1.37.2.2
      1  1.37.2.2  yamt /*	$NetBSD: if_iwi.c,v 1.37.2.2 2005/11/22 16:08:11 yamt Exp $  */
      2  1.37.2.2  yamt 
      3  1.37.2.2  yamt /*-
      4  1.37.2.2  yamt  * Copyright (c) 2004, 2005
      5  1.37.2.2  yamt  *      Damien Bergamini <damien.bergamini (at) free.fr>. All rights reserved.
      6  1.37.2.2  yamt  *
      7  1.37.2.2  yamt  * Redistribution and use in source and binary forms, with or without
      8  1.37.2.2  yamt  * modification, are permitted provided that the following conditions
      9  1.37.2.2  yamt  * are met:
     10  1.37.2.2  yamt  * 1. Redistributions of source code must retain the above copyright
     11  1.37.2.2  yamt  *    notice unmodified, this list of conditions, and the following
     12  1.37.2.2  yamt  *    disclaimer.
     13  1.37.2.2  yamt  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.37.2.2  yamt  *    notice, this list of conditions and the following disclaimer in the
     15  1.37.2.2  yamt  *    documentation and/or other materials provided with the distribution.
     16  1.37.2.2  yamt  *
     17  1.37.2.2  yamt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     18  1.37.2.2  yamt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  1.37.2.2  yamt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  1.37.2.2  yamt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21  1.37.2.2  yamt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  1.37.2.2  yamt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  1.37.2.2  yamt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  1.37.2.2  yamt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  1.37.2.2  yamt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  1.37.2.2  yamt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  1.37.2.2  yamt  * SUCH DAMAGE.
     28  1.37.2.2  yamt  */
     29  1.37.2.2  yamt 
     30  1.37.2.2  yamt #include <sys/cdefs.h>
     31  1.37.2.2  yamt __KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.37.2.2 2005/11/22 16:08:11 yamt Exp $");
     32  1.37.2.2  yamt 
     33  1.37.2.2  yamt /*-
     34  1.37.2.2  yamt  * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
     35  1.37.2.2  yamt  * http://www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm
     36  1.37.2.2  yamt  */
     37  1.37.2.2  yamt 
     38  1.37.2.2  yamt #include "bpfilter.h"
     39  1.37.2.2  yamt 
     40  1.37.2.2  yamt #include <sys/param.h>
     41  1.37.2.2  yamt #include <sys/sockio.h>
     42  1.37.2.2  yamt #include <sys/sysctl.h>
     43  1.37.2.2  yamt #include <sys/mbuf.h>
     44  1.37.2.2  yamt #include <sys/kernel.h>
     45  1.37.2.2  yamt #include <sys/socket.h>
     46  1.37.2.2  yamt #include <sys/systm.h>
     47  1.37.2.2  yamt #include <sys/malloc.h>
     48  1.37.2.2  yamt #include <sys/conf.h>
     49  1.37.2.2  yamt 
     50  1.37.2.2  yamt #include <machine/bus.h>
     51  1.37.2.2  yamt #include <machine/endian.h>
     52  1.37.2.2  yamt #include <machine/intr.h>
     53  1.37.2.2  yamt 
     54  1.37.2.2  yamt #include <dev/pci/pcireg.h>
     55  1.37.2.2  yamt #include <dev/pci/pcivar.h>
     56  1.37.2.2  yamt #include <dev/pci/pcidevs.h>
     57  1.37.2.2  yamt 
     58  1.37.2.2  yamt #if NBPFILTER > 0
     59  1.37.2.2  yamt #include <net/bpf.h>
     60  1.37.2.2  yamt #endif
     61  1.37.2.2  yamt #include <net/if.h>
     62  1.37.2.2  yamt #include <net/if_arp.h>
     63  1.37.2.2  yamt #include <net/if_dl.h>
     64  1.37.2.2  yamt #include <net/if_ether.h>
     65  1.37.2.2  yamt #include <net/if_media.h>
     66  1.37.2.2  yamt #include <net/if_types.h>
     67  1.37.2.2  yamt 
     68  1.37.2.2  yamt #include <net80211/ieee80211_var.h>
     69  1.37.2.2  yamt #include <net80211/ieee80211_radiotap.h>
     70  1.37.2.2  yamt 
     71  1.37.2.2  yamt #include <netinet/in.h>
     72  1.37.2.2  yamt #include <netinet/in_systm.h>
     73  1.37.2.2  yamt #include <netinet/in_var.h>
     74  1.37.2.2  yamt #include <netinet/ip.h>
     75  1.37.2.2  yamt 
     76  1.37.2.2  yamt #include <crypto/arc4/arc4.h>
     77  1.37.2.2  yamt 
     78  1.37.2.2  yamt #include <dev/pci/if_iwireg.h>
     79  1.37.2.2  yamt #include <dev/pci/if_iwivar.h>
     80  1.37.2.2  yamt 
     81  1.37.2.2  yamt #ifdef IWI_DEBUG
     82  1.37.2.2  yamt #define DPRINTF(x)	if (iwi_debug > 0) printf x
     83  1.37.2.2  yamt #define DPRINTFN(n, x)	if (iwi_debug >= (n)) printf x
     84  1.37.2.2  yamt int iwi_debug = 4;
     85  1.37.2.2  yamt #else
     86  1.37.2.2  yamt #define DPRINTF(x)
     87  1.37.2.2  yamt #define DPRINTFN(n, x)
     88  1.37.2.2  yamt #endif
     89  1.37.2.2  yamt 
     90  1.37.2.2  yamt static int	iwi_match(struct device *, struct cfdata *, void *);
     91  1.37.2.2  yamt static void	iwi_attach(struct device *, struct device *, void *);
     92  1.37.2.2  yamt static int	iwi_detach(struct device *, int);
     93  1.37.2.2  yamt 
     94  1.37.2.2  yamt static void	iwi_shutdown(void *);
     95  1.37.2.2  yamt static int	iwi_suspend(struct iwi_softc *);
     96  1.37.2.2  yamt static int	iwi_resume(struct iwi_softc *);
     97  1.37.2.2  yamt static void	iwi_powerhook(int, void *);
     98  1.37.2.2  yamt 
     99  1.37.2.2  yamt static int	iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *,
    100  1.37.2.2  yamt     int);
    101  1.37.2.2  yamt static void	iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
    102  1.37.2.2  yamt static void	iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
    103  1.37.2.2  yamt static int	iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *,
    104  1.37.2.2  yamt     int, bus_addr_t, bus_addr_t);
    105  1.37.2.2  yamt static void	iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
    106  1.37.2.2  yamt static void	iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
    107  1.37.2.2  yamt static struct mbuf *
    108  1.37.2.2  yamt 		iwi_alloc_rx_buf(struct iwi_softc *sc);
    109  1.37.2.2  yamt static int	iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *,
    110  1.37.2.2  yamt     int);
    111  1.37.2.2  yamt static void	iwi_reset_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
    112  1.37.2.2  yamt static void	iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
    113  1.37.2.2  yamt 
    114  1.37.2.2  yamt static struct	ieee80211_node *iwi_node_alloc(struct ieee80211_node_table *);
    115  1.37.2.2  yamt static void	iwi_node_free(struct ieee80211_node *);
    116  1.37.2.2  yamt 
    117  1.37.2.2  yamt static int	iwi_media_change(struct ifnet *);
    118  1.37.2.2  yamt static void	iwi_media_status(struct ifnet *, struct ifmediareq *);
    119  1.37.2.2  yamt static int	iwi_wme_update(struct ieee80211com *);
    120  1.37.2.2  yamt static uint16_t	iwi_read_prom_word(struct iwi_softc *, uint8_t);
    121  1.37.2.2  yamt static int	iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
    122  1.37.2.2  yamt static void	iwi_fix_channel(struct ieee80211com *, struct mbuf *);
    123  1.37.2.2  yamt static void	iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
    124  1.37.2.2  yamt     struct iwi_frame *);
    125  1.37.2.2  yamt static void	iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
    126  1.37.2.2  yamt static void	iwi_rx_intr(struct iwi_softc *);
    127  1.37.2.2  yamt static void	iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
    128  1.37.2.2  yamt static int	iwi_intr(void *);
    129  1.37.2.2  yamt static int	iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int);
    130  1.37.2.2  yamt static void	iwi_write_ibssnode(struct iwi_softc *, const struct iwi_node *);
    131  1.37.2.2  yamt static int	iwi_tx_start(struct ifnet *, struct mbuf *, struct ieee80211_node *,
    132  1.37.2.2  yamt     int);
    133  1.37.2.2  yamt static void	iwi_start(struct ifnet *);
    134  1.37.2.2  yamt static void	iwi_watchdog(struct ifnet *);
    135  1.37.2.2  yamt 
    136  1.37.2.2  yamt static int	iwi_alloc_unr(struct iwi_softc *);
    137  1.37.2.2  yamt static void	iwi_free_unr(struct iwi_softc *, int);
    138  1.37.2.2  yamt 
    139  1.37.2.2  yamt static int	iwi_get_table0(struct iwi_softc *, uint32_t *);
    140  1.37.2.2  yamt static int	iwi_get_radio(struct iwi_softc *, int *);
    141  1.37.2.2  yamt 
    142  1.37.2.2  yamt static int	iwi_ioctl(struct ifnet *, u_long, caddr_t);
    143  1.37.2.2  yamt static void	iwi_stop_master(struct iwi_softc *);
    144  1.37.2.2  yamt static int	iwi_reset(struct iwi_softc *);
    145  1.37.2.2  yamt static int	iwi_load_ucode(struct iwi_softc *, void *, int);
    146  1.37.2.2  yamt static int	iwi_load_firmware(struct iwi_softc *, void *, int);
    147  1.37.2.2  yamt static int	iwi_cache_firmware(struct iwi_softc *, void *);
    148  1.37.2.2  yamt static void	iwi_free_firmware(struct iwi_softc *);
    149  1.37.2.2  yamt static int	iwi_config(struct iwi_softc *);
    150  1.37.2.2  yamt static int	iwi_set_chan(struct iwi_softc *, struct ieee80211_channel *);
    151  1.37.2.2  yamt static int	iwi_scan(struct iwi_softc *);
    152  1.37.2.2  yamt static int	iwi_auth_and_assoc(struct iwi_softc *);
    153  1.37.2.2  yamt static int	iwi_init(struct ifnet *);
    154  1.37.2.2  yamt static void	iwi_stop(struct ifnet *, int);
    155  1.37.2.2  yamt static void	iwi_error_log(struct iwi_softc *);
    156  1.37.2.2  yamt 
    157  1.37.2.2  yamt /*
    158  1.37.2.2  yamt  * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
    159  1.37.2.2  yamt  */
    160  1.37.2.2  yamt static const struct ieee80211_rateset iwi_rateset_11a =
    161  1.37.2.2  yamt 	{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
    162  1.37.2.2  yamt 
    163  1.37.2.2  yamt static const struct ieee80211_rateset iwi_rateset_11b =
    164  1.37.2.2  yamt 	{ 4, { 2, 4, 11, 22 } };
    165  1.37.2.2  yamt 
    166  1.37.2.2  yamt static const struct ieee80211_rateset iwi_rateset_11g =
    167  1.37.2.2  yamt 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
    168  1.37.2.2  yamt 
    169  1.37.2.2  yamt static __inline uint8_t
    170  1.37.2.2  yamt MEM_READ_1(struct iwi_softc *sc, uint32_t addr)
    171  1.37.2.2  yamt {
    172  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
    173  1.37.2.2  yamt 	return CSR_READ_1(sc, IWI_CSR_INDIRECT_DATA);
    174  1.37.2.2  yamt }
    175  1.37.2.2  yamt 
    176  1.37.2.2  yamt static __inline uint32_t
    177  1.37.2.2  yamt MEM_READ_4(struct iwi_softc *sc, uint32_t addr)
    178  1.37.2.2  yamt {
    179  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
    180  1.37.2.2  yamt 	return CSR_READ_4(sc, IWI_CSR_INDIRECT_DATA);
    181  1.37.2.2  yamt }
    182  1.37.2.2  yamt 
    183  1.37.2.2  yamt static void
    184  1.37.2.2  yamt MEM_CPY(struct iwi_softc *sc, void *dst, uint32_t base, size_t sz)
    185  1.37.2.2  yamt {
    186  1.37.2.2  yamt 	KASSERT(sz % 4 == 0);
    187  1.37.2.2  yamt 	int j;
    188  1.37.2.2  yamt 
    189  1.37.2.2  yamt 	uint32_t *p = dst;
    190  1.37.2.2  yamt 
    191  1.37.2.2  yamt 	for (j = 0; j < sz / 4; j++)
    192  1.37.2.2  yamt 		p[j] = MEM_READ_4(sc, base + j * sizeof(uint32_t));
    193  1.37.2.2  yamt }
    194  1.37.2.2  yamt 
    195  1.37.2.2  yamt CFATTACH_DECL(iwi, sizeof (struct iwi_softc), iwi_match, iwi_attach,
    196  1.37.2.2  yamt     iwi_detach, NULL);
    197  1.37.2.2  yamt 
    198  1.37.2.2  yamt static int
    199  1.37.2.2  yamt iwi_match(struct device *parent, struct cfdata *match, void *aux)
    200  1.37.2.2  yamt {
    201  1.37.2.2  yamt 	struct pci_attach_args *pa = aux;
    202  1.37.2.2  yamt 
    203  1.37.2.2  yamt 	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
    204  1.37.2.2  yamt 		return 0;
    205  1.37.2.2  yamt 
    206  1.37.2.2  yamt 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2200BG ||
    207  1.37.2.2  yamt 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2225BG ||
    208  1.37.2.2  yamt 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1 ||
    209  1.37.2.2  yamt 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_2)
    210  1.37.2.2  yamt 		return 1;
    211  1.37.2.2  yamt 
    212  1.37.2.2  yamt 	return 0;
    213  1.37.2.2  yamt }
    214  1.37.2.2  yamt 
    215  1.37.2.2  yamt /* Base Address Register */
    216  1.37.2.2  yamt #define IWI_PCI_BAR0	0x10
    217  1.37.2.2  yamt 
    218  1.37.2.2  yamt static void
    219  1.37.2.2  yamt iwi_attach(struct device *parent, struct device *self, void *aux)
    220  1.37.2.2  yamt {
    221  1.37.2.2  yamt 	struct iwi_softc *sc = (struct iwi_softc *)self;
    222  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
    223  1.37.2.2  yamt 	struct ifnet *ifp = &sc->sc_if;
    224  1.37.2.2  yamt 	struct pci_attach_args *pa = aux;
    225  1.37.2.2  yamt 	const char *intrstr;
    226  1.37.2.2  yamt 	char devinfo[256];
    227  1.37.2.2  yamt 	bus_space_tag_t memt;
    228  1.37.2.2  yamt 	bus_space_handle_t memh;
    229  1.37.2.2  yamt 	bus_addr_t base;
    230  1.37.2.2  yamt 	pci_intr_handle_t ih;
    231  1.37.2.2  yamt 	pcireg_t data;
    232  1.37.2.2  yamt 	uint16_t val;
    233  1.37.2.2  yamt 	int error, revision, i;
    234  1.37.2.2  yamt 
    235  1.37.2.2  yamt 	sc->sc_pct = pa->pa_pc;
    236  1.37.2.2  yamt 	sc->sc_pcitag = pa->pa_tag;
    237  1.37.2.2  yamt 
    238  1.37.2.2  yamt 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo);
    239  1.37.2.2  yamt 	revision = PCI_REVISION(pa->pa_class);
    240  1.37.2.2  yamt 	aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision);
    241  1.37.2.2  yamt 
    242  1.37.2.2  yamt 	/* clear device specific PCI configuration register 0x41 */
    243  1.37.2.2  yamt 	data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
    244  1.37.2.2  yamt 	data &= ~0x0000ff00;
    245  1.37.2.2  yamt 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
    246  1.37.2.2  yamt 
    247  1.37.2.2  yamt 	/* clear unit numbers allocated to IBSS */
    248  1.37.2.2  yamt 	sc->sc_unr = 0;
    249  1.37.2.2  yamt 
    250  1.37.2.2  yamt 	/* enable bus-mastering */
    251  1.37.2.2  yamt 	data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
    252  1.37.2.2  yamt 	data |= PCI_COMMAND_MASTER_ENABLE;
    253  1.37.2.2  yamt 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, data);
    254  1.37.2.2  yamt 
    255  1.37.2.2  yamt 	/* map the register window */
    256  1.37.2.2  yamt 	error = pci_mapreg_map(pa, IWI_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
    257  1.37.2.2  yamt 	    PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, &base, &sc->sc_sz);
    258  1.37.2.2  yamt 	if (error != 0) {
    259  1.37.2.2  yamt 		aprint_error("%s: could not map memory space\n",
    260  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    261  1.37.2.2  yamt 		return;
    262  1.37.2.2  yamt 	}
    263  1.37.2.2  yamt 
    264  1.37.2.2  yamt 	sc->sc_st = memt;
    265  1.37.2.2  yamt 	sc->sc_sh = memh;
    266  1.37.2.2  yamt 	sc->sc_dmat = pa->pa_dmat;
    267  1.37.2.2  yamt 
    268  1.37.2.2  yamt 	/* disable interrupts */
    269  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
    270  1.37.2.2  yamt 
    271  1.37.2.2  yamt 	if (pci_intr_map(pa, &ih) != 0) {
    272  1.37.2.2  yamt 		aprint_error("%s: could not map interrupt\n",
    273  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    274  1.37.2.2  yamt 		return;
    275  1.37.2.2  yamt 	}
    276  1.37.2.2  yamt 
    277  1.37.2.2  yamt 	intrstr = pci_intr_string(sc->sc_pct, ih);
    278  1.37.2.2  yamt 	sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwi_intr, sc);
    279  1.37.2.2  yamt 	if (sc->sc_ih == NULL) {
    280  1.37.2.2  yamt 		aprint_error("%s: could not establish interrupt",
    281  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    282  1.37.2.2  yamt 		if (intrstr != NULL)
    283  1.37.2.2  yamt 			aprint_error(" at %s", intrstr);
    284  1.37.2.2  yamt 		aprint_error("\n");
    285  1.37.2.2  yamt 		return;
    286  1.37.2.2  yamt 	}
    287  1.37.2.2  yamt 	aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
    288  1.37.2.2  yamt 
    289  1.37.2.2  yamt 	if (iwi_reset(sc) != 0) {
    290  1.37.2.2  yamt 		aprint_error("%s: could not reset adapter\n",
    291  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    292  1.37.2.2  yamt 		return;
    293  1.37.2.2  yamt 	}
    294  1.37.2.2  yamt 
    295  1.37.2.2  yamt 	/*
    296  1.37.2.2  yamt 	 * Allocate rings.
    297  1.37.2.2  yamt 	 */
    298  1.37.2.2  yamt 	if (iwi_alloc_cmd_ring(sc, &sc->cmdq, IWI_CMD_RING_COUNT) != 0) {
    299  1.37.2.2  yamt 		aprint_error("%s: could not allocate command ring\n",
    300  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    301  1.37.2.2  yamt 		goto fail;
    302  1.37.2.2  yamt 	}
    303  1.37.2.2  yamt 
    304  1.37.2.2  yamt 	error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_TX_RING_COUNT,
    305  1.37.2.2  yamt 	    IWI_CSR_TX1_RIDX, IWI_CSR_TX1_WIDX);
    306  1.37.2.2  yamt 	if (error != 0) {
    307  1.37.2.2  yamt 		aprint_error("%s: could not allocate Tx ring 1\n",
    308  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    309  1.37.2.2  yamt 		goto fail;
    310  1.37.2.2  yamt 	}
    311  1.37.2.2  yamt 
    312  1.37.2.2  yamt 	error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_TX_RING_COUNT,
    313  1.37.2.2  yamt 	    IWI_CSR_TX2_RIDX, IWI_CSR_TX2_WIDX);
    314  1.37.2.2  yamt 	if (error != 0) {
    315  1.37.2.2  yamt 		aprint_error("%s: could not allocate Tx ring 2\n",
    316  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    317  1.37.2.2  yamt 		goto fail;
    318  1.37.2.2  yamt 	}
    319  1.37.2.2  yamt 
    320  1.37.2.2  yamt 	error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_TX_RING_COUNT,
    321  1.37.2.2  yamt 	    IWI_CSR_TX3_RIDX, IWI_CSR_TX3_WIDX);
    322  1.37.2.2  yamt 	if (error != 0) {
    323  1.37.2.2  yamt 		aprint_error("%s: could not allocate Tx ring 3\n",
    324  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    325  1.37.2.2  yamt 		goto fail;
    326  1.37.2.2  yamt 	}
    327  1.37.2.2  yamt 
    328  1.37.2.2  yamt 	error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_TX_RING_COUNT,
    329  1.37.2.2  yamt 	    IWI_CSR_TX4_RIDX, IWI_CSR_TX4_WIDX);
    330  1.37.2.2  yamt 	if (error != 0) {
    331  1.37.2.2  yamt 		aprint_error("%s: could not allocate Tx ring 4\n",
    332  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    333  1.37.2.2  yamt 		goto fail;
    334  1.37.2.2  yamt 	}
    335  1.37.2.2  yamt 
    336  1.37.2.2  yamt 	if (iwi_alloc_rx_ring(sc, &sc->rxq, IWI_RX_RING_COUNT) != 0) {
    337  1.37.2.2  yamt 		aprint_error("%s: could not allocate Rx ring\n",
    338  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    339  1.37.2.2  yamt 		goto fail;
    340  1.37.2.2  yamt 	}
    341  1.37.2.2  yamt 
    342  1.37.2.2  yamt 	ic->ic_ifp = ifp;
    343  1.37.2.2  yamt 	ic->ic_wme.wme_update = iwi_wme_update;
    344  1.37.2.2  yamt 	ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
    345  1.37.2.2  yamt 	ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
    346  1.37.2.2  yamt 	ic->ic_state = IEEE80211_S_INIT;
    347  1.37.2.2  yamt 
    348  1.37.2.2  yamt 	/* set device capabilities */
    349  1.37.2.2  yamt 	ic->ic_caps =
    350  1.37.2.2  yamt 	    IEEE80211_C_IBSS |		/* IBSS mode supported */
    351  1.37.2.2  yamt 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
    352  1.37.2.2  yamt 	    IEEE80211_C_TXPMGT |	/* tx power management */
    353  1.37.2.2  yamt 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
    354  1.37.2.2  yamt 	    IEEE80211_C_WPA |		/* 802.11i */
    355  1.37.2.2  yamt 	    IEEE80211_C_WME;		/* 802.11e */
    356  1.37.2.2  yamt 
    357  1.37.2.2  yamt 	/* read MAC address from EEPROM */
    358  1.37.2.2  yamt 	val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
    359  1.37.2.2  yamt 	ic->ic_myaddr[0] = val & 0xff;
    360  1.37.2.2  yamt 	ic->ic_myaddr[1] = val >> 8;
    361  1.37.2.2  yamt 	val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1);
    362  1.37.2.2  yamt 	ic->ic_myaddr[2] = val & 0xff;
    363  1.37.2.2  yamt 	ic->ic_myaddr[3] = val >> 8;
    364  1.37.2.2  yamt 	val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2);
    365  1.37.2.2  yamt 	ic->ic_myaddr[4] = val & 0xff;
    366  1.37.2.2  yamt 	ic->ic_myaddr[5] = val >> 8;
    367  1.37.2.2  yamt 
    368  1.37.2.2  yamt 	aprint_normal("%s: 802.11 address %s\n", sc->sc_dev.dv_xname,
    369  1.37.2.2  yamt 	    ether_sprintf(ic->ic_myaddr));
    370  1.37.2.2  yamt 
    371  1.37.2.2  yamt 
    372  1.37.2.2  yamt 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1 ||
    373  1.37.2.2  yamt 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_2) {
    374  1.37.2.2  yamt 		/* set supported .11a rates (2915ABG only) */
    375  1.37.2.2  yamt 		ic->ic_sup_rates[IEEE80211_MODE_11A] = iwi_rateset_11a;
    376  1.37.2.2  yamt 
    377  1.37.2.2  yamt 		/* set supported .11a channels */
    378  1.37.2.2  yamt 		for (i = 36; i <= 64; i += 4) {
    379  1.37.2.2  yamt 			ic->ic_channels[i].ic_freq =
    380  1.37.2.2  yamt 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
    381  1.37.2.2  yamt 			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
    382  1.37.2.2  yamt 		}
    383  1.37.2.2  yamt 		for (i = 149; i <= 165; i += 4) {
    384  1.37.2.2  yamt 			ic->ic_channels[i].ic_freq =
    385  1.37.2.2  yamt 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
    386  1.37.2.2  yamt 			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
    387  1.37.2.2  yamt 		}
    388  1.37.2.2  yamt 	}
    389  1.37.2.2  yamt 
    390  1.37.2.2  yamt 	/* set supported .11b and .11g rates */
    391  1.37.2.2  yamt 	ic->ic_sup_rates[IEEE80211_MODE_11B] = iwi_rateset_11b;
    392  1.37.2.2  yamt 	ic->ic_sup_rates[IEEE80211_MODE_11G] = iwi_rateset_11g;
    393  1.37.2.2  yamt 
    394  1.37.2.2  yamt 	/* set supported .11b and .11g channels (1 through 14) */
    395  1.37.2.2  yamt 	for (i = 1; i <= 14; i++) {
    396  1.37.2.2  yamt 		ic->ic_channels[i].ic_freq =
    397  1.37.2.2  yamt 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
    398  1.37.2.2  yamt 		ic->ic_channels[i].ic_flags =
    399  1.37.2.2  yamt 		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
    400  1.37.2.2  yamt 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
    401  1.37.2.2  yamt 	}
    402  1.37.2.2  yamt 
    403  1.37.2.2  yamt 	ifp->if_softc = sc;
    404  1.37.2.2  yamt 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    405  1.37.2.2  yamt 	ifp->if_init = iwi_init;
    406  1.37.2.2  yamt 	ifp->if_stop = iwi_stop;
    407  1.37.2.2  yamt 	ifp->if_ioctl = iwi_ioctl;
    408  1.37.2.2  yamt 	ifp->if_start = iwi_start;
    409  1.37.2.2  yamt 	ifp->if_watchdog = iwi_watchdog;
    410  1.37.2.2  yamt 	IFQ_SET_READY(&ifp->if_snd);
    411  1.37.2.2  yamt 	memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
    412  1.37.2.2  yamt 
    413  1.37.2.2  yamt 	if_attach(ifp);
    414  1.37.2.2  yamt 	ieee80211_ifattach(ic);
    415  1.37.2.2  yamt 	/* override default methods */
    416  1.37.2.2  yamt 	ic->ic_node_alloc = iwi_node_alloc;
    417  1.37.2.2  yamt 	sc->sc_node_free = ic->ic_node_free;
    418  1.37.2.2  yamt 	ic->ic_node_free = iwi_node_free;
    419  1.37.2.2  yamt 	/* override state transition machine */
    420  1.37.2.2  yamt 	sc->sc_newstate = ic->ic_newstate;
    421  1.37.2.2  yamt 	ic->ic_newstate = iwi_newstate;
    422  1.37.2.2  yamt 	ieee80211_media_init(ic, iwi_media_change, iwi_media_status);
    423  1.37.2.2  yamt 
    424  1.37.2.2  yamt #if NBPFILTER > 0
    425  1.37.2.2  yamt 	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
    426  1.37.2.2  yamt 	    sizeof (struct ieee80211_frame) + 64, &sc->sc_drvbpf);
    427  1.37.2.2  yamt 
    428  1.37.2.2  yamt 	sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
    429  1.37.2.2  yamt 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
    430  1.37.2.2  yamt 	sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT);
    431  1.37.2.2  yamt 
    432  1.37.2.2  yamt 	sc->sc_txtap_len = sizeof sc->sc_txtapu;
    433  1.37.2.2  yamt 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
    434  1.37.2.2  yamt 	sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
    435  1.37.2.2  yamt #endif
    436  1.37.2.2  yamt 
    437  1.37.2.2  yamt 	/*
    438  1.37.2.2  yamt 	 * Make sure the interface is shutdown during reboot.
    439  1.37.2.2  yamt 	 */
    440  1.37.2.2  yamt 	sc->sc_sdhook = shutdownhook_establish(iwi_shutdown, sc);
    441  1.37.2.2  yamt 	if (sc->sc_sdhook == NULL)
    442  1.37.2.2  yamt 		aprint_error("%s: WARNING: unable to establish shutdown hook\n",
    443  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    444  1.37.2.2  yamt 	sc->sc_powerhook = powerhook_establish(iwi_powerhook, sc);
    445  1.37.2.2  yamt 	if (sc->sc_powerhook == NULL)
    446  1.37.2.2  yamt 		printf("%s: WARNING: unable to establish power hook\n",
    447  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    448  1.37.2.2  yamt 
    449  1.37.2.2  yamt 	ieee80211_announce(ic);
    450  1.37.2.2  yamt 	/*
    451  1.37.2.2  yamt 	 * Add a few sysctl knobs.
    452  1.37.2.2  yamt 	 * XXX: Not yet.
    453  1.37.2.2  yamt 	 */
    454  1.37.2.2  yamt 	sc->dwelltime = 100;
    455  1.37.2.2  yamt 	sc->bluetooth = 1;
    456  1.37.2.2  yamt 	sc->antenna = 0;
    457  1.37.2.2  yamt 
    458  1.37.2.2  yamt 	return;
    459  1.37.2.2  yamt 
    460  1.37.2.2  yamt fail:	iwi_detach(self, 0);
    461  1.37.2.2  yamt }
    462  1.37.2.2  yamt 
    463  1.37.2.2  yamt static int
    464  1.37.2.2  yamt iwi_detach(struct device* self, int flags)
    465  1.37.2.2  yamt {
    466  1.37.2.2  yamt 	struct iwi_softc *sc = (struct iwi_softc *)self;
    467  1.37.2.2  yamt 	struct ifnet *ifp = &sc->sc_if;
    468  1.37.2.2  yamt 
    469  1.37.2.2  yamt 	iwi_stop(ifp, 1);
    470  1.37.2.2  yamt 	iwi_free_firmware(sc);
    471  1.37.2.2  yamt 
    472  1.37.2.2  yamt #if NBPFILTER > 0
    473  1.37.2.2  yamt 	if (ifp != NULL)
    474  1.37.2.2  yamt 		bpfdetach(ifp);
    475  1.37.2.2  yamt #endif
    476  1.37.2.2  yamt 	ieee80211_ifdetach(&sc->sc_ic);
    477  1.37.2.2  yamt 	if (ifp != NULL)
    478  1.37.2.2  yamt 		if_detach(ifp);
    479  1.37.2.2  yamt 
    480  1.37.2.2  yamt 	iwi_free_cmd_ring(sc, &sc->cmdq);
    481  1.37.2.2  yamt 	iwi_free_tx_ring(sc, &sc->txq[0]);
    482  1.37.2.2  yamt 	iwi_free_tx_ring(sc, &sc->txq[1]);
    483  1.37.2.2  yamt 	iwi_free_tx_ring(sc, &sc->txq[2]);
    484  1.37.2.2  yamt 	iwi_free_tx_ring(sc, &sc->txq[3]);
    485  1.37.2.2  yamt 	iwi_free_rx_ring(sc, &sc->rxq);
    486  1.37.2.2  yamt 
    487  1.37.2.2  yamt 	if (sc->sc_ih != NULL) {
    488  1.37.2.2  yamt 		pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
    489  1.37.2.2  yamt 		sc->sc_ih = NULL;
    490  1.37.2.2  yamt 	}
    491  1.37.2.2  yamt 
    492  1.37.2.2  yamt 	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
    493  1.37.2.2  yamt 
    494  1.37.2.2  yamt 	powerhook_disestablish(sc->sc_powerhook);
    495  1.37.2.2  yamt 	shutdownhook_disestablish(sc->sc_sdhook);
    496  1.37.2.2  yamt 
    497  1.37.2.2  yamt 	return 0;
    498  1.37.2.2  yamt }
    499  1.37.2.2  yamt 
    500  1.37.2.2  yamt static int
    501  1.37.2.2  yamt iwi_alloc_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring,
    502  1.37.2.2  yamt     int count)
    503  1.37.2.2  yamt {
    504  1.37.2.2  yamt 	int error, nsegs;
    505  1.37.2.2  yamt 
    506  1.37.2.2  yamt 	ring->count = count;
    507  1.37.2.2  yamt 	ring->queued = 0;
    508  1.37.2.2  yamt 	ring->cur = ring->next = 0;
    509  1.37.2.2  yamt 
    510  1.37.2.2  yamt 	/*
    511  1.37.2.2  yamt 	 * Allocate and map command ring
    512  1.37.2.2  yamt 	 */
    513  1.37.2.2  yamt 	error = bus_dmamap_create(sc->sc_dmat,
    514  1.37.2.2  yamt 	    IWI_CMD_DESC_SIZE * count, 1,
    515  1.37.2.2  yamt 	    IWI_CMD_DESC_SIZE * count, 0,
    516  1.37.2.2  yamt 	    BUS_DMA_NOWAIT, &ring->desc_map);
    517  1.37.2.2  yamt 	if (error != 0) {
    518  1.37.2.2  yamt 		aprint_error("%s: could not create command ring DMA map\n",
    519  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    520  1.37.2.2  yamt 		goto fail;
    521  1.37.2.2  yamt 	}
    522  1.37.2.2  yamt 
    523  1.37.2.2  yamt 	error = bus_dmamem_alloc(sc->sc_dmat,
    524  1.37.2.2  yamt 	    IWI_CMD_DESC_SIZE * count, PAGE_SIZE, 0,
    525  1.37.2.2  yamt 	    &sc->cmdq.desc_seg, 1, &nsegs, BUS_DMA_NOWAIT);
    526  1.37.2.2  yamt 	if (error != 0) {
    527  1.37.2.2  yamt 		aprint_error("%s: could not allocate command ring DMA memory\n",
    528  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    529  1.37.2.2  yamt 		goto fail;
    530  1.37.2.2  yamt 	}
    531  1.37.2.2  yamt 
    532  1.37.2.2  yamt 	error = bus_dmamem_map(sc->sc_dmat, &sc->cmdq.desc_seg, nsegs,
    533  1.37.2.2  yamt 	    IWI_CMD_DESC_SIZE * count,
    534  1.37.2.2  yamt 	    (caddr_t *)&sc->cmdq.desc, BUS_DMA_NOWAIT);
    535  1.37.2.2  yamt 	if (error != 0) {
    536  1.37.2.2  yamt 		aprint_error("%s: could not map command ring DMA memory\n",
    537  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    538  1.37.2.2  yamt 		goto fail;
    539  1.37.2.2  yamt 	}
    540  1.37.2.2  yamt 
    541  1.37.2.2  yamt 	error = bus_dmamap_load(sc->sc_dmat, sc->cmdq.desc_map, sc->cmdq.desc,
    542  1.37.2.2  yamt 	    IWI_CMD_DESC_SIZE * count, NULL,
    543  1.37.2.2  yamt 	    BUS_DMA_NOWAIT);
    544  1.37.2.2  yamt 	if (error != 0) {
    545  1.37.2.2  yamt 		aprint_error("%s: could not load command ring DMA map\n",
    546  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    547  1.37.2.2  yamt 		goto fail;
    548  1.37.2.2  yamt 	}
    549  1.37.2.2  yamt 
    550  1.37.2.2  yamt 	memset(sc->cmdq.desc, 0,
    551  1.37.2.2  yamt 	    IWI_CMD_DESC_SIZE * count);
    552  1.37.2.2  yamt 
    553  1.37.2.2  yamt 	return 0;
    554  1.37.2.2  yamt 
    555  1.37.2.2  yamt fail:	iwi_free_cmd_ring(sc, ring);
    556  1.37.2.2  yamt 	return error;
    557  1.37.2.2  yamt }
    558  1.37.2.2  yamt 
    559  1.37.2.2  yamt static void
    560  1.37.2.2  yamt iwi_reset_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
    561  1.37.2.2  yamt {
    562  1.37.2.2  yamt 	ring->queued = 0;
    563  1.37.2.2  yamt 	ring->cur = ring->next = 0;
    564  1.37.2.2  yamt }
    565  1.37.2.2  yamt 
    566  1.37.2.2  yamt static void
    567  1.37.2.2  yamt iwi_free_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
    568  1.37.2.2  yamt {
    569  1.37.2.2  yamt 	if (ring->desc_map != NULL) {
    570  1.37.2.2  yamt 		if (ring->desc != NULL) {
    571  1.37.2.2  yamt 			bus_dmamap_unload(sc->sc_dmat, ring->desc_map);
    572  1.37.2.2  yamt 			bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
    573  1.37.2.2  yamt 			    IWI_CMD_DESC_SIZE * ring->count);
    574  1.37.2.2  yamt 			bus_dmamem_free(sc->sc_dmat, &ring->desc_seg, 1);
    575  1.37.2.2  yamt 		}
    576  1.37.2.2  yamt 		bus_dmamap_destroy(sc->sc_dmat, ring->desc_map);
    577  1.37.2.2  yamt 	}
    578  1.37.2.2  yamt }
    579  1.37.2.2  yamt 
    580  1.37.2.2  yamt static int
    581  1.37.2.2  yamt iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring,
    582  1.37.2.2  yamt     int count, bus_addr_t csr_ridx, bus_addr_t csr_widx)
    583  1.37.2.2  yamt {
    584  1.37.2.2  yamt 	int i, error, nsegs;
    585  1.37.2.2  yamt 
    586  1.37.2.2  yamt 	ring->count = count;
    587  1.37.2.2  yamt 	ring->queued = 0;
    588  1.37.2.2  yamt 	ring->cur = ring->next = 0;
    589  1.37.2.2  yamt 	ring->csr_ridx = csr_ridx;
    590  1.37.2.2  yamt 	ring->csr_widx = csr_widx;
    591  1.37.2.2  yamt 
    592  1.37.2.2  yamt 	/*
    593  1.37.2.2  yamt 	 * Allocate and map Tx ring
    594  1.37.2.2  yamt 	 */
    595  1.37.2.2  yamt 	error = bus_dmamap_create(sc->sc_dmat,
    596  1.37.2.2  yamt 	    IWI_TX_DESC_SIZE * count, 1,
    597  1.37.2.2  yamt 	    IWI_TX_DESC_SIZE * count, 0, BUS_DMA_NOWAIT,
    598  1.37.2.2  yamt 	    &ring->desc_map);
    599  1.37.2.2  yamt 	if (error != 0) {
    600  1.37.2.2  yamt 		aprint_error("%s: could not create tx ring DMA map\n",
    601  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    602  1.37.2.2  yamt 		goto fail;
    603  1.37.2.2  yamt 	}
    604  1.37.2.2  yamt 
    605  1.37.2.2  yamt 	error = bus_dmamem_alloc(sc->sc_dmat,
    606  1.37.2.2  yamt 	    IWI_TX_DESC_SIZE * count, PAGE_SIZE, 0,
    607  1.37.2.2  yamt 	    &ring->desc_seg, 1, &nsegs, BUS_DMA_NOWAIT);
    608  1.37.2.2  yamt 	if (error != 0) {
    609  1.37.2.2  yamt 		aprint_error("%s: could not allocate tx ring DMA memory\n",
    610  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    611  1.37.2.2  yamt 		goto fail;
    612  1.37.2.2  yamt 	}
    613  1.37.2.2  yamt 
    614  1.37.2.2  yamt 	error = bus_dmamem_map(sc->sc_dmat, &ring->desc_seg, nsegs,
    615  1.37.2.2  yamt 	    IWI_TX_DESC_SIZE * count,
    616  1.37.2.2  yamt 	    (caddr_t *)&ring->desc, BUS_DMA_NOWAIT);
    617  1.37.2.2  yamt 	if (error != 0) {
    618  1.37.2.2  yamt 		aprint_error("%s: could not map tx ring DMA memory\n",
    619  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    620  1.37.2.2  yamt 		goto fail;
    621  1.37.2.2  yamt 	}
    622  1.37.2.2  yamt 
    623  1.37.2.2  yamt 	error = bus_dmamap_load(sc->sc_dmat, ring->desc_map, ring->desc,
    624  1.37.2.2  yamt 	    IWI_TX_DESC_SIZE * count, NULL,
    625  1.37.2.2  yamt 	    BUS_DMA_NOWAIT);
    626  1.37.2.2  yamt 	if (error != 0) {
    627  1.37.2.2  yamt 		aprint_error("%s: could not load tx ring DMA map\n",
    628  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    629  1.37.2.2  yamt 		goto fail;
    630  1.37.2.2  yamt 	}
    631  1.37.2.2  yamt 
    632  1.37.2.2  yamt 	memset(ring->desc, 0, IWI_TX_DESC_SIZE * count);
    633  1.37.2.2  yamt 
    634  1.37.2.2  yamt 	ring->data = malloc(count * sizeof (struct iwi_tx_data), M_DEVBUF,
    635  1.37.2.2  yamt 	    M_NOWAIT | M_ZERO);
    636  1.37.2.2  yamt 	if (ring->data == NULL) {
    637  1.37.2.2  yamt 		aprint_error("%s: could not allocate soft data\n",
    638  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    639  1.37.2.2  yamt 		error = ENOMEM;
    640  1.37.2.2  yamt 		goto fail;
    641  1.37.2.2  yamt 	}
    642  1.37.2.2  yamt 
    643  1.37.2.2  yamt 	/*
    644  1.37.2.2  yamt 	 * Allocate Tx buffers DMA maps
    645  1.37.2.2  yamt 	 */
    646  1.37.2.2  yamt 	for (i = 0; i < count; i++) {
    647  1.37.2.2  yamt 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, IWI_MAX_NSEG,
    648  1.37.2.2  yamt 		    MCLBYTES, 0, BUS_DMA_NOWAIT, &ring->data[i].map);
    649  1.37.2.2  yamt 		if (error != 0) {
    650  1.37.2.2  yamt 			aprint_error("%s: could not create tx buf DMA map",
    651  1.37.2.2  yamt 			    sc->sc_dev.dv_xname);
    652  1.37.2.2  yamt 			goto fail;
    653  1.37.2.2  yamt 		}
    654  1.37.2.2  yamt 	}
    655  1.37.2.2  yamt 	return 0;
    656  1.37.2.2  yamt 
    657  1.37.2.2  yamt fail:	iwi_free_tx_ring(sc, ring);
    658  1.37.2.2  yamt 	return error;
    659  1.37.2.2  yamt }
    660  1.37.2.2  yamt 
    661  1.37.2.2  yamt static void
    662  1.37.2.2  yamt iwi_reset_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
    663  1.37.2.2  yamt {
    664  1.37.2.2  yamt 	struct iwi_tx_data *data;
    665  1.37.2.2  yamt 	int i;
    666  1.37.2.2  yamt 
    667  1.37.2.2  yamt 	for (i = 0; i < ring->count; i++) {
    668  1.37.2.2  yamt 		data = &ring->data[i];
    669  1.37.2.2  yamt 
    670  1.37.2.2  yamt 		if (data->m != NULL) {
    671  1.37.2.2  yamt 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
    672  1.37.2.2  yamt 			    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
    673  1.37.2.2  yamt 			bus_dmamap_unload(sc->sc_dmat, data->map);
    674  1.37.2.2  yamt 			m_freem(data->m);
    675  1.37.2.2  yamt 			data->m = NULL;
    676  1.37.2.2  yamt 		}
    677  1.37.2.2  yamt 
    678  1.37.2.2  yamt 		if (data->ni != NULL) {
    679  1.37.2.2  yamt 			ieee80211_free_node(data->ni);
    680  1.37.2.2  yamt 			data->ni = NULL;
    681  1.37.2.2  yamt 		}
    682  1.37.2.2  yamt 	}
    683  1.37.2.2  yamt 
    684  1.37.2.2  yamt 	ring->queued = 0;
    685  1.37.2.2  yamt 	ring->cur = ring->next = 0;
    686  1.37.2.2  yamt }
    687  1.37.2.2  yamt 
    688  1.37.2.2  yamt static void
    689  1.37.2.2  yamt iwi_free_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
    690  1.37.2.2  yamt {
    691  1.37.2.2  yamt 	int i;
    692  1.37.2.2  yamt 
    693  1.37.2.2  yamt 	if (ring->desc_map != NULL) {
    694  1.37.2.2  yamt 		if (ring->desc != NULL) {
    695  1.37.2.2  yamt 			bus_dmamap_unload(sc->sc_dmat, ring->desc_map);
    696  1.37.2.2  yamt 			bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
    697  1.37.2.2  yamt 			    IWI_TX_DESC_SIZE * ring->count);
    698  1.37.2.2  yamt 			bus_dmamem_free(sc->sc_dmat, &ring->desc_seg, 1);
    699  1.37.2.2  yamt 		}
    700  1.37.2.2  yamt 		bus_dmamap_destroy(sc->sc_dmat, ring->desc_map);
    701  1.37.2.2  yamt 	}
    702  1.37.2.2  yamt 
    703  1.37.2.2  yamt 	for (i = 0; i < ring->count; i++) {
    704  1.37.2.2  yamt 		if (ring->data[i].m != NULL) {
    705  1.37.2.2  yamt 			bus_dmamap_unload(sc->sc_dmat, ring->data[i].map);
    706  1.37.2.2  yamt 			m_freem(ring->data[i].m);
    707  1.37.2.2  yamt 		}
    708  1.37.2.2  yamt 		bus_dmamap_destroy(sc->sc_dmat, ring->data[i].map);
    709  1.37.2.2  yamt 	}
    710  1.37.2.2  yamt }
    711  1.37.2.2  yamt 
    712  1.37.2.2  yamt static int
    713  1.37.2.2  yamt iwi_alloc_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring,
    714  1.37.2.2  yamt     int count)
    715  1.37.2.2  yamt {
    716  1.37.2.2  yamt 	int i, error;
    717  1.37.2.2  yamt 
    718  1.37.2.2  yamt 	ring->count = count;
    719  1.37.2.2  yamt 	ring->cur = 0;
    720  1.37.2.2  yamt 
    721  1.37.2.2  yamt 	ring->data = malloc(count * sizeof (struct iwi_rx_data), M_DEVBUF,
    722  1.37.2.2  yamt 	    M_NOWAIT | M_ZERO);
    723  1.37.2.2  yamt 	if (ring->data == NULL) {
    724  1.37.2.2  yamt 		aprint_error("%s: could not allocate soft data\n",
    725  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
    726  1.37.2.2  yamt 		error = ENOMEM;
    727  1.37.2.2  yamt 		goto fail;
    728  1.37.2.2  yamt 	}
    729  1.37.2.2  yamt 
    730  1.37.2.2  yamt 	/*
    731  1.37.2.2  yamt 	 * Allocate and map Rx buffers
    732  1.37.2.2  yamt 	 */
    733  1.37.2.2  yamt 	for (i = 0; i < count; i++) {
    734  1.37.2.2  yamt 
    735  1.37.2.2  yamt 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
    736  1.37.2.2  yamt 		    0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &ring->data[i].map);
    737  1.37.2.2  yamt 		if (error != 0) {
    738  1.37.2.2  yamt 			aprint_error("%s: could not create rx buf DMA map",
    739  1.37.2.2  yamt 			    sc->sc_dev.dv_xname);
    740  1.37.2.2  yamt 			goto fail;
    741  1.37.2.2  yamt 		}
    742  1.37.2.2  yamt 
    743  1.37.2.2  yamt 		if ((ring->data[i].m = iwi_alloc_rx_buf(sc)) == NULL) {
    744  1.37.2.2  yamt 			error = ENOMEM;
    745  1.37.2.2  yamt 			goto fail;
    746  1.37.2.2  yamt 		}
    747  1.37.2.2  yamt 
    748  1.37.2.2  yamt 		error = bus_dmamap_load_mbuf(sc->sc_dmat, ring->data[i].map,
    749  1.37.2.2  yamt 		    ring->data[i].m, BUS_DMA_READ | BUS_DMA_NOWAIT);
    750  1.37.2.2  yamt 		if (error != 0) {
    751  1.37.2.2  yamt 			aprint_error("%s: could not load rx buffer DMA map\n",
    752  1.37.2.2  yamt 			    sc->sc_dev.dv_xname);
    753  1.37.2.2  yamt 			goto fail;
    754  1.37.2.2  yamt 		}
    755  1.37.2.2  yamt 	}
    756  1.37.2.2  yamt 
    757  1.37.2.2  yamt 	return 0;
    758  1.37.2.2  yamt 
    759  1.37.2.2  yamt fail:	iwi_free_rx_ring(sc, ring);
    760  1.37.2.2  yamt 	return error;
    761  1.37.2.2  yamt }
    762  1.37.2.2  yamt 
    763  1.37.2.2  yamt static void
    764  1.37.2.2  yamt iwi_reset_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
    765  1.37.2.2  yamt {
    766  1.37.2.2  yamt 	ring->cur = 0;
    767  1.37.2.2  yamt }
    768  1.37.2.2  yamt 
    769  1.37.2.2  yamt static void
    770  1.37.2.2  yamt iwi_free_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
    771  1.37.2.2  yamt {
    772  1.37.2.2  yamt 	int i;
    773  1.37.2.2  yamt 
    774  1.37.2.2  yamt 	for (i = 0; i < ring->count; i++) {
    775  1.37.2.2  yamt 		if (ring->data[i].m != NULL) {
    776  1.37.2.2  yamt 			bus_dmamap_unload(sc->sc_dmat, ring->data[i].map);
    777  1.37.2.2  yamt 			m_freem(ring->data[i].m);
    778  1.37.2.2  yamt 		}
    779  1.37.2.2  yamt 		bus_dmamap_destroy(sc->sc_dmat, ring->data[i].map);
    780  1.37.2.2  yamt 	}
    781  1.37.2.2  yamt }
    782  1.37.2.2  yamt 
    783  1.37.2.2  yamt static void
    784  1.37.2.2  yamt iwi_shutdown(void *arg)
    785  1.37.2.2  yamt {
    786  1.37.2.2  yamt 	struct iwi_softc *sc = (struct iwi_softc *)arg;
    787  1.37.2.2  yamt 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
    788  1.37.2.2  yamt 
    789  1.37.2.2  yamt 	iwi_stop(ifp, 1);
    790  1.37.2.2  yamt }
    791  1.37.2.2  yamt 
    792  1.37.2.2  yamt static int
    793  1.37.2.2  yamt iwi_suspend(struct iwi_softc *sc)
    794  1.37.2.2  yamt {
    795  1.37.2.2  yamt 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
    796  1.37.2.2  yamt 
    797  1.37.2.2  yamt 	iwi_stop(ifp, 1);
    798  1.37.2.2  yamt 
    799  1.37.2.2  yamt 	return 0;
    800  1.37.2.2  yamt }
    801  1.37.2.2  yamt 
    802  1.37.2.2  yamt static int
    803  1.37.2.2  yamt iwi_resume(struct iwi_softc *sc)
    804  1.37.2.2  yamt {
    805  1.37.2.2  yamt 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
    806  1.37.2.2  yamt 	pcireg_t data;
    807  1.37.2.2  yamt 
    808  1.37.2.2  yamt 	/* clear device specific PCI configuration register 0x41 */
    809  1.37.2.2  yamt 	data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
    810  1.37.2.2  yamt 	data &= ~0x0000ff00;
    811  1.37.2.2  yamt 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
    812  1.37.2.2  yamt 
    813  1.37.2.2  yamt 	if (ifp->if_flags & IFF_UP) {
    814  1.37.2.2  yamt 		iwi_init(ifp);
    815  1.37.2.2  yamt 		if (ifp->if_flags & IFF_RUNNING)
    816  1.37.2.2  yamt 			iwi_start(ifp);
    817  1.37.2.2  yamt 	}
    818  1.37.2.2  yamt 
    819  1.37.2.2  yamt 	return 0;
    820  1.37.2.2  yamt }
    821  1.37.2.2  yamt 
    822  1.37.2.2  yamt static void
    823  1.37.2.2  yamt iwi_powerhook(int why, void *arg)
    824  1.37.2.2  yamt {
    825  1.37.2.2  yamt         struct iwi_softc *sc = arg;
    826  1.37.2.2  yamt 	int s;
    827  1.37.2.2  yamt 
    828  1.37.2.2  yamt 	s = splnet();
    829  1.37.2.2  yamt 	switch (why) {
    830  1.37.2.2  yamt 	case PWR_SUSPEND:
    831  1.37.2.2  yamt 	case PWR_STANDBY:
    832  1.37.2.2  yamt 		iwi_suspend(sc);
    833  1.37.2.2  yamt 		break;
    834  1.37.2.2  yamt 	case PWR_RESUME:
    835  1.37.2.2  yamt 		iwi_resume(sc);
    836  1.37.2.2  yamt 		break;
    837  1.37.2.2  yamt 	case PWR_SOFTSUSPEND:
    838  1.37.2.2  yamt 	case PWR_SOFTSTANDBY:
    839  1.37.2.2  yamt 	case PWR_SOFTRESUME:
    840  1.37.2.2  yamt 		break;
    841  1.37.2.2  yamt 	}
    842  1.37.2.2  yamt 	splx(s);
    843  1.37.2.2  yamt }
    844  1.37.2.2  yamt 
    845  1.37.2.2  yamt static struct ieee80211_node *
    846  1.37.2.2  yamt iwi_node_alloc(struct ieee80211_node_table *nt)
    847  1.37.2.2  yamt {
    848  1.37.2.2  yamt 	struct iwi_node *in;
    849  1.37.2.2  yamt 
    850  1.37.2.2  yamt 	in = malloc(sizeof (struct iwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
    851  1.37.2.2  yamt 	if (in == NULL)
    852  1.37.2.2  yamt 		return NULL;
    853  1.37.2.2  yamt 
    854  1.37.2.2  yamt 	in->in_station = -1;
    855  1.37.2.2  yamt 
    856  1.37.2.2  yamt 	return &in->in_node;
    857  1.37.2.2  yamt }
    858  1.37.2.2  yamt 
    859  1.37.2.2  yamt static int
    860  1.37.2.2  yamt iwi_alloc_unr(struct iwi_softc *sc)
    861  1.37.2.2  yamt {
    862  1.37.2.2  yamt 	int i;
    863  1.37.2.2  yamt 
    864  1.37.2.2  yamt 	for (i = 0; i < IWI_MAX_IBSSNODE - 1; i++)
    865  1.37.2.2  yamt 		if ((sc->sc_unr & (1 << i)) == 0) {
    866  1.37.2.2  yamt 			sc->sc_unr |= 1 << i;
    867  1.37.2.2  yamt 			return i;
    868  1.37.2.2  yamt 		}
    869  1.37.2.2  yamt 
    870  1.37.2.2  yamt 	return -1;
    871  1.37.2.2  yamt }
    872  1.37.2.2  yamt 
    873  1.37.2.2  yamt static void
    874  1.37.2.2  yamt iwi_free_unr(struct iwi_softc *sc, int r)
    875  1.37.2.2  yamt {
    876  1.37.2.2  yamt 
    877  1.37.2.2  yamt 	sc->sc_unr &= 1 << r;
    878  1.37.2.2  yamt }
    879  1.37.2.2  yamt 
    880  1.37.2.2  yamt static void
    881  1.37.2.2  yamt iwi_node_free(struct ieee80211_node *ni)
    882  1.37.2.2  yamt {
    883  1.37.2.2  yamt 	struct ieee80211com *ic = ni->ni_ic;
    884  1.37.2.2  yamt 	struct iwi_softc *sc = ic->ic_ifp->if_softc;
    885  1.37.2.2  yamt 	struct iwi_node *in = (struct iwi_node *)ni;
    886  1.37.2.2  yamt 
    887  1.37.2.2  yamt 	if (in->in_station != -1)
    888  1.37.2.2  yamt 		iwi_free_unr(sc, in->in_station);
    889  1.37.2.2  yamt 
    890  1.37.2.2  yamt 	sc->sc_node_free(ni);
    891  1.37.2.2  yamt }
    892  1.37.2.2  yamt 
    893  1.37.2.2  yamt static int
    894  1.37.2.2  yamt iwi_media_change(struct ifnet *ifp)
    895  1.37.2.2  yamt {
    896  1.37.2.2  yamt 	int error;
    897  1.37.2.2  yamt 
    898  1.37.2.2  yamt 	error = ieee80211_media_change(ifp);
    899  1.37.2.2  yamt 	if (error != ENETRESET)
    900  1.37.2.2  yamt 		return error;
    901  1.37.2.2  yamt 
    902  1.37.2.2  yamt 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
    903  1.37.2.2  yamt 		iwi_init(ifp);
    904  1.37.2.2  yamt 
    905  1.37.2.2  yamt 	return 0;
    906  1.37.2.2  yamt }
    907  1.37.2.2  yamt 
    908  1.37.2.2  yamt /*
    909  1.37.2.2  yamt  * The firmware automatically adapts the transmit speed.  We report its current
    910  1.37.2.2  yamt  * value here.
    911  1.37.2.2  yamt  */
    912  1.37.2.2  yamt static void
    913  1.37.2.2  yamt iwi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
    914  1.37.2.2  yamt {
    915  1.37.2.2  yamt 	struct iwi_softc *sc = ifp->if_softc;
    916  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
    917  1.37.2.2  yamt #define N(a)	(sizeof (a) / sizeof (a[0]))
    918  1.37.2.2  yamt 	static const struct {
    919  1.37.2.2  yamt 		uint32_t	val;
    920  1.37.2.2  yamt 		int		rate;
    921  1.37.2.2  yamt 	} rates[] = {
    922  1.37.2.2  yamt 		{ IWI_RATE_DS1,      2 },
    923  1.37.2.2  yamt 		{ IWI_RATE_DS2,      4 },
    924  1.37.2.2  yamt 		{ IWI_RATE_DS5,     11 },
    925  1.37.2.2  yamt 		{ IWI_RATE_DS11,    22 },
    926  1.37.2.2  yamt 		{ IWI_RATE_OFDM6,   12 },
    927  1.37.2.2  yamt 		{ IWI_RATE_OFDM9,   18 },
    928  1.37.2.2  yamt 		{ IWI_RATE_OFDM12,  24 },
    929  1.37.2.2  yamt 		{ IWI_RATE_OFDM18,  36 },
    930  1.37.2.2  yamt 		{ IWI_RATE_OFDM24,  48 },
    931  1.37.2.2  yamt 		{ IWI_RATE_OFDM36,  72 },
    932  1.37.2.2  yamt 		{ IWI_RATE_OFDM48,  96 },
    933  1.37.2.2  yamt 		{ IWI_RATE_OFDM54, 108 },
    934  1.37.2.2  yamt 	};
    935  1.37.2.2  yamt 	uint32_t val;
    936  1.37.2.2  yamt 	int rate, i;
    937  1.37.2.2  yamt 
    938  1.37.2.2  yamt 	imr->ifm_status = IFM_AVALID;
    939  1.37.2.2  yamt 	imr->ifm_active = IFM_IEEE80211;
    940  1.37.2.2  yamt 	if (ic->ic_state == IEEE80211_S_RUN)
    941  1.37.2.2  yamt 		imr->ifm_status |= IFM_ACTIVE;
    942  1.37.2.2  yamt 
    943  1.37.2.2  yamt 	/* read current transmission rate from adapter */
    944  1.37.2.2  yamt 	val = CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE);
    945  1.37.2.2  yamt 
    946  1.37.2.2  yamt 	/* convert rate to 802.11 rate */
    947  1.37.2.2  yamt 	for (i = 0; i < N(rates) && rates[i].val != val; i++);
    948  1.37.2.2  yamt 	rate = (i < N(rates)) ? rates[i].rate : 0;
    949  1.37.2.2  yamt 
    950  1.37.2.2  yamt 	imr->ifm_active |= ieee80211_rate2media(ic, rate, ic->ic_curmode);
    951  1.37.2.2  yamt 	switch (ic->ic_opmode) {
    952  1.37.2.2  yamt 	case IEEE80211_M_STA:
    953  1.37.2.2  yamt 		break;
    954  1.37.2.2  yamt 
    955  1.37.2.2  yamt 	case IEEE80211_M_IBSS:
    956  1.37.2.2  yamt 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
    957  1.37.2.2  yamt 		break;
    958  1.37.2.2  yamt 
    959  1.37.2.2  yamt 	case IEEE80211_M_MONITOR:
    960  1.37.2.2  yamt 		imr->ifm_active |= IFM_IEEE80211_MONITOR;
    961  1.37.2.2  yamt 		break;
    962  1.37.2.2  yamt 
    963  1.37.2.2  yamt 	case IEEE80211_M_AHDEMO:
    964  1.37.2.2  yamt 	case IEEE80211_M_HOSTAP:
    965  1.37.2.2  yamt 		/* should not get there */
    966  1.37.2.2  yamt 		break;
    967  1.37.2.2  yamt 	}
    968  1.37.2.2  yamt #undef N
    969  1.37.2.2  yamt }
    970  1.37.2.2  yamt 
    971  1.37.2.2  yamt static int
    972  1.37.2.2  yamt iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
    973  1.37.2.2  yamt {
    974  1.37.2.2  yamt 	struct iwi_softc *sc = ic->ic_ifp->if_softc;
    975  1.37.2.2  yamt 
    976  1.37.2.2  yamt 	switch (nstate) {
    977  1.37.2.2  yamt 	case IEEE80211_S_SCAN:
    978  1.37.2.2  yamt 		if (sc->flags & IWI_FLAG_SCANNING)
    979  1.37.2.2  yamt 			break;
    980  1.37.2.2  yamt 
    981  1.37.2.2  yamt 		ieee80211_node_table_reset(&ic->ic_scan);
    982  1.37.2.2  yamt 		ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
    983  1.37.2.2  yamt 		sc->flags |= IWI_FLAG_SCANNING;
    984  1.37.2.2  yamt 		iwi_scan(sc);
    985  1.37.2.2  yamt 		break;
    986  1.37.2.2  yamt 
    987  1.37.2.2  yamt 	case IEEE80211_S_AUTH:
    988  1.37.2.2  yamt 		iwi_auth_and_assoc(sc);
    989  1.37.2.2  yamt 		break;
    990  1.37.2.2  yamt 
    991  1.37.2.2  yamt 	case IEEE80211_S_RUN:
    992  1.37.2.2  yamt 		if (ic->ic_opmode == IEEE80211_M_IBSS)
    993  1.37.2.2  yamt 			ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
    994  1.37.2.2  yamt 		else if (ic->ic_opmode == IEEE80211_M_MONITOR)
    995  1.37.2.2  yamt 			iwi_set_chan(sc, ic->ic_ibss_chan);
    996  1.37.2.2  yamt 
    997  1.37.2.2  yamt 		return (*sc->sc_newstate)(ic, nstate,
    998  1.37.2.2  yamt 		    IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
    999  1.37.2.2  yamt 
   1000  1.37.2.2  yamt 	case IEEE80211_S_ASSOC:
   1001  1.37.2.2  yamt 		break;
   1002  1.37.2.2  yamt 
   1003  1.37.2.2  yamt 	case IEEE80211_S_INIT:
   1004  1.37.2.2  yamt 		sc->flags &= ~IWI_FLAG_SCANNING;
   1005  1.37.2.2  yamt 		return (*sc->sc_newstate)(ic, nstate, arg);
   1006  1.37.2.2  yamt 	}
   1007  1.37.2.2  yamt 
   1008  1.37.2.2  yamt 	ic->ic_state = nstate;
   1009  1.37.2.2  yamt 	return 0;
   1010  1.37.2.2  yamt }
   1011  1.37.2.2  yamt 
   1012  1.37.2.2  yamt /*
   1013  1.37.2.2  yamt  * WME parameters coming from IEEE 802.11e specification.  These values are
   1014  1.37.2.2  yamt  * already declared in ieee80211_proto.c, but they are static so they can't
   1015  1.37.2.2  yamt  * be reused here.
   1016  1.37.2.2  yamt  */
   1017  1.37.2.2  yamt static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = {
   1018  1.37.2.2  yamt 	{ 0, 3, 5,  7,   0 },	/* WME_AC_BE */
   1019  1.37.2.2  yamt 	{ 0, 3, 5, 10,   0 },	/* WME_AC_BK */
   1020  1.37.2.2  yamt 	{ 0, 2, 4,  5, 188 },	/* WME_AC_VI */
   1021  1.37.2.2  yamt 	{ 0, 2, 3,  4, 102 }	/* WME_AC_VO */
   1022  1.37.2.2  yamt };
   1023  1.37.2.2  yamt 
   1024  1.37.2.2  yamt static const struct wmeParams iwi_wme_ofdm_params[WME_NUM_AC] = {
   1025  1.37.2.2  yamt 	{ 0, 3, 4,  6,   0 },	/* WME_AC_BE */
   1026  1.37.2.2  yamt 	{ 0, 3, 4, 10,   0 },	/* WME_AC_BK */
   1027  1.37.2.2  yamt 	{ 0, 2, 3,  4,  94 },	/* WME_AC_VI */
   1028  1.37.2.2  yamt 	{ 0, 2, 2,  3,  47 }	/* WME_AC_VO */
   1029  1.37.2.2  yamt };
   1030  1.37.2.2  yamt 
   1031  1.37.2.2  yamt static int
   1032  1.37.2.2  yamt iwi_wme_update(struct ieee80211com *ic)
   1033  1.37.2.2  yamt {
   1034  1.37.2.2  yamt #define IWI_EXP2(v)	htole16((1 << (v)) - 1)
   1035  1.37.2.2  yamt #define IWI_USEC(v)	htole16(IEEE80211_TXOP_TO_US(v))
   1036  1.37.2.2  yamt 	struct iwi_softc *sc = ic->ic_ifp->if_softc;
   1037  1.37.2.2  yamt 	struct iwi_wme_params wme[3];
   1038  1.37.2.2  yamt 	const struct wmeParams *wmep;
   1039  1.37.2.2  yamt 	int ac;
   1040  1.37.2.2  yamt 
   1041  1.37.2.2  yamt 	/*
   1042  1.37.2.2  yamt 	 * We shall not override firmware default WME values if WME is not
   1043  1.37.2.2  yamt 	 * actually enabled.
   1044  1.37.2.2  yamt 	 */
   1045  1.37.2.2  yamt 	if (!(ic->ic_flags & IEEE80211_F_WME))
   1046  1.37.2.2  yamt 		return 0;
   1047  1.37.2.2  yamt 
   1048  1.37.2.2  yamt 	for (ac = 0; ac < WME_NUM_AC; ac++) {
   1049  1.37.2.2  yamt 		/* set WME values for current operating mode */
   1050  1.37.2.2  yamt 		wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
   1051  1.37.2.2  yamt 		wme[0].aifsn[ac] = wmep->wmep_aifsn;
   1052  1.37.2.2  yamt 		wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
   1053  1.37.2.2  yamt 		wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
   1054  1.37.2.2  yamt 		wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
   1055  1.37.2.2  yamt 		wme[0].acm[ac]   = wmep->wmep_acm;
   1056  1.37.2.2  yamt 
   1057  1.37.2.2  yamt 		/* set WME values for CCK modulation */
   1058  1.37.2.2  yamt 		wmep = &iwi_wme_cck_params[ac];
   1059  1.37.2.2  yamt 		wme[1].aifsn[ac] = wmep->wmep_aifsn;
   1060  1.37.2.2  yamt 		wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
   1061  1.37.2.2  yamt 		wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
   1062  1.37.2.2  yamt 		wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
   1063  1.37.2.2  yamt 		wme[1].acm[ac]   = wmep->wmep_acm;
   1064  1.37.2.2  yamt 
   1065  1.37.2.2  yamt 		/* set WME values for OFDM modulation */
   1066  1.37.2.2  yamt 		wmep = &iwi_wme_ofdm_params[ac];
   1067  1.37.2.2  yamt 		wme[2].aifsn[ac] = wmep->wmep_aifsn;
   1068  1.37.2.2  yamt 		wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
   1069  1.37.2.2  yamt 		wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
   1070  1.37.2.2  yamt 		wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
   1071  1.37.2.2  yamt 		wme[2].acm[ac]   = wmep->wmep_acm;
   1072  1.37.2.2  yamt 	}
   1073  1.37.2.2  yamt 
   1074  1.37.2.2  yamt 	DPRINTF(("Setting WME parameters\n"));
   1075  1.37.2.2  yamt 	return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, wme, sizeof wme, 1);
   1076  1.37.2.2  yamt #undef IWI_USEC
   1077  1.37.2.2  yamt #undef IWI_EXP2
   1078  1.37.2.2  yamt }
   1079  1.37.2.2  yamt 
   1080  1.37.2.2  yamt /*
   1081  1.37.2.2  yamt  * Read 16 bits at address 'addr' from the serial EEPROM.
   1082  1.37.2.2  yamt  */
   1083  1.37.2.2  yamt static uint16_t
   1084  1.37.2.2  yamt iwi_read_prom_word(struct iwi_softc *sc, uint8_t addr)
   1085  1.37.2.2  yamt {
   1086  1.37.2.2  yamt 	uint32_t tmp;
   1087  1.37.2.2  yamt 	uint16_t val;
   1088  1.37.2.2  yamt 	int n;
   1089  1.37.2.2  yamt 
   1090  1.37.2.2  yamt 	/* Clock C once before the first command */
   1091  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, 0);
   1092  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
   1093  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
   1094  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
   1095  1.37.2.2  yamt 
   1096  1.37.2.2  yamt 	/* Write start bit (1) */
   1097  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
   1098  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
   1099  1.37.2.2  yamt 
   1100  1.37.2.2  yamt 	/* Write READ opcode (10) */
   1101  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
   1102  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
   1103  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
   1104  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
   1105  1.37.2.2  yamt 
   1106  1.37.2.2  yamt 	/* Write address A7-A0 */
   1107  1.37.2.2  yamt 	for (n = 7; n >= 0; n--) {
   1108  1.37.2.2  yamt 		IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
   1109  1.37.2.2  yamt 		    (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D));
   1110  1.37.2.2  yamt 		IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
   1111  1.37.2.2  yamt 		    (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D) | IWI_EEPROM_C);
   1112  1.37.2.2  yamt 	}
   1113  1.37.2.2  yamt 
   1114  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
   1115  1.37.2.2  yamt 
   1116  1.37.2.2  yamt 	/* Read data Q15-Q0 */
   1117  1.37.2.2  yamt 	val = 0;
   1118  1.37.2.2  yamt 	for (n = 15; n >= 0; n--) {
   1119  1.37.2.2  yamt 		IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
   1120  1.37.2.2  yamt 		IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
   1121  1.37.2.2  yamt 		tmp = MEM_READ_4(sc, IWI_MEM_EEPROM_CTL);
   1122  1.37.2.2  yamt 		val |= ((tmp & IWI_EEPROM_Q) >> IWI_EEPROM_SHIFT_Q) << n;
   1123  1.37.2.2  yamt 	}
   1124  1.37.2.2  yamt 
   1125  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, 0);
   1126  1.37.2.2  yamt 
   1127  1.37.2.2  yamt 	/* Clear Chip Select and clock C */
   1128  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
   1129  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, 0);
   1130  1.37.2.2  yamt 	IWI_EEPROM_CTL(sc, IWI_EEPROM_C);
   1131  1.37.2.2  yamt 
   1132  1.37.2.2  yamt 	return val;
   1133  1.37.2.2  yamt }
   1134  1.37.2.2  yamt 
   1135  1.37.2.2  yamt /*
   1136  1.37.2.2  yamt  * XXX: Hack to set the current channel to the value advertised in beacons or
   1137  1.37.2.2  yamt  * probe responses. Only used during AP detection.
   1138  1.37.2.2  yamt  */
   1139  1.37.2.2  yamt static void
   1140  1.37.2.2  yamt iwi_fix_channel(struct ieee80211com *ic, struct mbuf *m)
   1141  1.37.2.2  yamt {
   1142  1.37.2.2  yamt 	struct ieee80211_frame *wh;
   1143  1.37.2.2  yamt 	uint8_t subtype;
   1144  1.37.2.2  yamt 	uint8_t *frm, *efrm;
   1145  1.37.2.2  yamt 
   1146  1.37.2.2  yamt 	wh = mtod(m, struct ieee80211_frame *);
   1147  1.37.2.2  yamt 
   1148  1.37.2.2  yamt 	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
   1149  1.37.2.2  yamt 		return;
   1150  1.37.2.2  yamt 
   1151  1.37.2.2  yamt 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
   1152  1.37.2.2  yamt 
   1153  1.37.2.2  yamt 	if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
   1154  1.37.2.2  yamt 	    subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
   1155  1.37.2.2  yamt 		return;
   1156  1.37.2.2  yamt 
   1157  1.37.2.2  yamt 	frm = (uint8_t *)(wh + 1);
   1158  1.37.2.2  yamt 	efrm = mtod(m, uint8_t *) + m->m_len;
   1159  1.37.2.2  yamt 
   1160  1.37.2.2  yamt 	frm += 12;	/* skip tstamp, bintval and capinfo fields */
   1161  1.37.2.2  yamt 	while (frm < efrm) {
   1162  1.37.2.2  yamt 		if (*frm == IEEE80211_ELEMID_DSPARMS)
   1163  1.37.2.2  yamt #if IEEE80211_CHAN_MAX < 255
   1164  1.37.2.2  yamt 		if (frm[2] <= IEEE80211_CHAN_MAX)
   1165  1.37.2.2  yamt #endif
   1166  1.37.2.2  yamt 			ic->ic_curchan = &ic->ic_channels[frm[2]];
   1167  1.37.2.2  yamt 
   1168  1.37.2.2  yamt 		frm += frm[1] + 2;
   1169  1.37.2.2  yamt 	}
   1170  1.37.2.2  yamt }
   1171  1.37.2.2  yamt 
   1172  1.37.2.2  yamt static struct mbuf *
   1173  1.37.2.2  yamt iwi_alloc_rx_buf(struct iwi_softc *sc)
   1174  1.37.2.2  yamt {
   1175  1.37.2.2  yamt 	struct mbuf *m;
   1176  1.37.2.2  yamt 
   1177  1.37.2.2  yamt 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1178  1.37.2.2  yamt 	if (m == NULL) {
   1179  1.37.2.2  yamt 		aprint_error("%s: could not allocate rx mbuf\n",
   1180  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   1181  1.37.2.2  yamt 		return NULL;
   1182  1.37.2.2  yamt 	}
   1183  1.37.2.2  yamt 
   1184  1.37.2.2  yamt 	MCLGET(m, M_DONTWAIT);
   1185  1.37.2.2  yamt 	if (!(m->m_flags & M_EXT)) {
   1186  1.37.2.2  yamt 		aprint_error("%s: could not allocate rx mbuf cluster\n",
   1187  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   1188  1.37.2.2  yamt 		m_freem(m);
   1189  1.37.2.2  yamt 		return NULL;
   1190  1.37.2.2  yamt 	}
   1191  1.37.2.2  yamt 
   1192  1.37.2.2  yamt 	m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
   1193  1.37.2.2  yamt 	return m;
   1194  1.37.2.2  yamt }
   1195  1.37.2.2  yamt 
   1196  1.37.2.2  yamt static void
   1197  1.37.2.2  yamt iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
   1198  1.37.2.2  yamt     struct iwi_frame *frame)
   1199  1.37.2.2  yamt {
   1200  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   1201  1.37.2.2  yamt 	struct ifnet *ifp = ic->ic_ifp;
   1202  1.37.2.2  yamt 	struct mbuf *m, *m_new;
   1203  1.37.2.2  yamt 	struct ieee80211_frame *wh;
   1204  1.37.2.2  yamt 	struct ieee80211_node *ni;
   1205  1.37.2.2  yamt 	int error;
   1206  1.37.2.2  yamt 
   1207  1.37.2.2  yamt 	DPRINTFN(5, ("received frame len=%u chan=%u rssi=%u\n",
   1208  1.37.2.2  yamt 	    le16toh(frame->len), frame->chan, frame->rssi_dbm));
   1209  1.37.2.2  yamt 
   1210  1.37.2.2  yamt 	if (le16toh(frame->len) < sizeof (struct ieee80211_frame) ||
   1211  1.37.2.2  yamt 	    le16toh(frame->len) > MCLBYTES) {
   1212  1.37.2.2  yamt 		DPRINTF(("%s: bad frame length\n", sc->sc_dev.dv_xname));
   1213  1.37.2.2  yamt 		ifp->if_ierrors++;
   1214  1.37.2.2  yamt 		return;
   1215  1.37.2.2  yamt 	}
   1216  1.37.2.2  yamt 
   1217  1.37.2.2  yamt 	/*
   1218  1.37.2.2  yamt 	 * Try to allocate a new mbuf for this ring element and
   1219  1.37.2.2  yamt 	 * load it before processing the current mbuf. If the ring
   1220  1.37.2.2  yamt 	 * element cannot be reloaded, drop the received packet
   1221  1.37.2.2  yamt 	 * and reuse the old mbuf. In the unlikely case that
   1222  1.37.2.2  yamt 	 * the old mbuf can't be reloaded either, explicitly panic.
   1223  1.37.2.2  yamt 	 *
   1224  1.37.2.2  yamt 	 * XXX Reorganize buffer by moving elements from the logical
   1225  1.37.2.2  yamt 	 * end of the ring to the front instead of dropping.
   1226  1.37.2.2  yamt 	 */
   1227  1.37.2.2  yamt 	if ((m_new = iwi_alloc_rx_buf(sc)) == NULL) {
   1228  1.37.2.2  yamt 		ifp->if_ierrors++;
   1229  1.37.2.2  yamt 		return;
   1230  1.37.2.2  yamt 	}
   1231  1.37.2.2  yamt 
   1232  1.37.2.2  yamt 	bus_dmamap_unload(sc->sc_dmat, data->map);
   1233  1.37.2.2  yamt 
   1234  1.37.2.2  yamt 	error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m_new,
   1235  1.37.2.2  yamt 	    BUS_DMA_READ | BUS_DMA_NOWAIT);
   1236  1.37.2.2  yamt 	if (error != 0) {
   1237  1.37.2.2  yamt 		aprint_error("%s: could not load rx buf DMA map\n",
   1238  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   1239  1.37.2.2  yamt 		m_freem(m_new);
   1240  1.37.2.2  yamt 		ifp->if_ierrors++;
   1241  1.37.2.2  yamt 		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map,
   1242  1.37.2.2  yamt 		    data->m, BUS_DMA_READ | BUS_DMA_NOWAIT);
   1243  1.37.2.2  yamt 		if (error)
   1244  1.37.2.2  yamt 			panic("%s: unable to remap rx buf",
   1245  1.37.2.2  yamt 			    sc->sc_dev.dv_xname);
   1246  1.37.2.2  yamt 		return;
   1247  1.37.2.2  yamt 	}
   1248  1.37.2.2  yamt 
   1249  1.37.2.2  yamt 	/*
   1250  1.37.2.2  yamt 	 * New mbuf successfully loaded, update RX ring and continue
   1251  1.37.2.2  yamt 	 * processing.
   1252  1.37.2.2  yamt 	 */
   1253  1.37.2.2  yamt 	m = data->m;
   1254  1.37.2.2  yamt 	data->m = m_new;
   1255  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RX_BASE + i * 4, data->map->dm_segs[0].ds_addr);
   1256  1.37.2.2  yamt 
   1257  1.37.2.2  yamt 	/* Finalize mbuf */
   1258  1.37.2.2  yamt 	m->m_pkthdr.rcvif = ifp;
   1259  1.37.2.2  yamt 	m->m_pkthdr.len = m->m_len = sizeof (struct iwi_hdr) +
   1260  1.37.2.2  yamt 	    sizeof (struct iwi_frame) + le16toh(frame->len);
   1261  1.37.2.2  yamt 
   1262  1.37.2.2  yamt 	m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
   1263  1.37.2.2  yamt 
   1264  1.37.2.2  yamt 	if (ic->ic_state == IEEE80211_S_SCAN)
   1265  1.37.2.2  yamt 		iwi_fix_channel(ic, m);
   1266  1.37.2.2  yamt 
   1267  1.37.2.2  yamt #if NBPFILTER > 0
   1268  1.37.2.2  yamt 	if (sc->sc_drvbpf != NULL) {
   1269  1.37.2.2  yamt 		struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
   1270  1.37.2.2  yamt 
   1271  1.37.2.2  yamt 		tap->wr_flags = 0;
   1272  1.37.2.2  yamt 		tap->wr_rate = frame->rate;
   1273  1.37.2.2  yamt 		tap->wr_chan_freq =
   1274  1.37.2.2  yamt 		    htole16(ic->ic_channels[frame->chan].ic_freq);
   1275  1.37.2.2  yamt 		tap->wr_chan_flags =
   1276  1.37.2.2  yamt 		    htole16(ic->ic_channels[frame->chan].ic_flags);
   1277  1.37.2.2  yamt 		tap->wr_antsignal = frame->signal;
   1278  1.37.2.2  yamt 		tap->wr_antenna = frame->antenna;
   1279  1.37.2.2  yamt 
   1280  1.37.2.2  yamt 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
   1281  1.37.2.2  yamt 	}
   1282  1.37.2.2  yamt #endif
   1283  1.37.2.2  yamt 
   1284  1.37.2.2  yamt 	wh = mtod(m, struct ieee80211_frame *);
   1285  1.37.2.2  yamt 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
   1286  1.37.2.2  yamt 
   1287  1.37.2.2  yamt 	/* Send the frame to the upper layer */
   1288  1.37.2.2  yamt 	ieee80211_input(ic, m, ni, frame->rssi_dbm, 0);
   1289  1.37.2.2  yamt 
   1290  1.37.2.2  yamt 	/* node is no longer needed */
   1291  1.37.2.2  yamt 	ieee80211_free_node(ni);
   1292  1.37.2.2  yamt }
   1293  1.37.2.2  yamt 
   1294  1.37.2.2  yamt static void
   1295  1.37.2.2  yamt iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
   1296  1.37.2.2  yamt {
   1297  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   1298  1.37.2.2  yamt 	struct iwi_notif_scan_channel *chan;
   1299  1.37.2.2  yamt 	struct iwi_notif_scan_complete *scan;
   1300  1.37.2.2  yamt 	struct iwi_notif_authentication *auth;
   1301  1.37.2.2  yamt 	struct iwi_notif_association *assoc;
   1302  1.37.2.2  yamt 
   1303  1.37.2.2  yamt 	switch (notif->type) {
   1304  1.37.2.2  yamt 	case IWI_NOTIF_TYPE_SCAN_CHANNEL:
   1305  1.37.2.2  yamt 		chan = (struct iwi_notif_scan_channel *)(notif + 1);
   1306  1.37.2.2  yamt 
   1307  1.37.2.2  yamt 		DPRINTFN(2, ("Finished scanning channel (%u)\n", chan->nchan));
   1308  1.37.2.2  yamt 		break;
   1309  1.37.2.2  yamt 
   1310  1.37.2.2  yamt 	case IWI_NOTIF_TYPE_SCAN_COMPLETE:
   1311  1.37.2.2  yamt 		scan = (struct iwi_notif_scan_complete *)(notif + 1);
   1312  1.37.2.2  yamt 
   1313  1.37.2.2  yamt 		DPRINTFN(2, ("Scan completed (%u, %u)\n", scan->nchan,
   1314  1.37.2.2  yamt 		    scan->status));
   1315  1.37.2.2  yamt 
   1316  1.37.2.2  yamt 		/* monitor mode uses scan to set the channel ... */
   1317  1.37.2.2  yamt 		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
   1318  1.37.2.2  yamt 			sc->flags &= ~IWI_FLAG_SCANNING;
   1319  1.37.2.2  yamt 			ieee80211_end_scan(ic);
   1320  1.37.2.2  yamt 		} else
   1321  1.37.2.2  yamt 			iwi_set_chan(sc, ic->ic_ibss_chan);
   1322  1.37.2.2  yamt 		break;
   1323  1.37.2.2  yamt 
   1324  1.37.2.2  yamt 	case IWI_NOTIF_TYPE_AUTHENTICATION:
   1325  1.37.2.2  yamt 		auth = (struct iwi_notif_authentication *)(notif + 1);
   1326  1.37.2.2  yamt 
   1327  1.37.2.2  yamt 		DPRINTFN(2, ("Authentication (%u)\n", auth->state));
   1328  1.37.2.2  yamt 
   1329  1.37.2.2  yamt 		switch (auth->state) {
   1330  1.37.2.2  yamt 		case IWI_AUTHENTICATED:
   1331  1.37.2.2  yamt 			ieee80211_node_authorize(ic->ic_bss);
   1332  1.37.2.2  yamt 			ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
   1333  1.37.2.2  yamt 			break;
   1334  1.37.2.2  yamt 
   1335  1.37.2.2  yamt 		case IWI_DEAUTHENTICATED:
   1336  1.37.2.2  yamt 			break;
   1337  1.37.2.2  yamt 
   1338  1.37.2.2  yamt 		default:
   1339  1.37.2.2  yamt 			aprint_error("%s: unknown authentication state %u\n",
   1340  1.37.2.2  yamt 			    sc->sc_dev.dv_xname, auth->state);
   1341  1.37.2.2  yamt 		}
   1342  1.37.2.2  yamt 		break;
   1343  1.37.2.2  yamt 
   1344  1.37.2.2  yamt 	case IWI_NOTIF_TYPE_ASSOCIATION:
   1345  1.37.2.2  yamt 		assoc = (struct iwi_notif_association *)(notif + 1);
   1346  1.37.2.2  yamt 
   1347  1.37.2.2  yamt 		DPRINTFN(2, ("Association (%u, %u)\n", assoc->state,
   1348  1.37.2.2  yamt 		    assoc->status));
   1349  1.37.2.2  yamt 
   1350  1.37.2.2  yamt 		switch (assoc->state) {
   1351  1.37.2.2  yamt 		case IWI_AUTHENTICATED:
   1352  1.37.2.2  yamt 			/* re-association, do nothing */
   1353  1.37.2.2  yamt 			break;
   1354  1.37.2.2  yamt 
   1355  1.37.2.2  yamt 		case IWI_ASSOCIATED:
   1356  1.37.2.2  yamt 			ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   1357  1.37.2.2  yamt 			break;
   1358  1.37.2.2  yamt 
   1359  1.37.2.2  yamt 		case IWI_DEASSOCIATED:
   1360  1.37.2.2  yamt 			ieee80211_begin_scan(ic, 1);
   1361  1.37.2.2  yamt 			break;
   1362  1.37.2.2  yamt 
   1363  1.37.2.2  yamt 		default:
   1364  1.37.2.2  yamt 			aprint_error("%s: unknown association state %u\n",
   1365  1.37.2.2  yamt 			    sc->sc_dev.dv_xname, assoc->state);
   1366  1.37.2.2  yamt 		}
   1367  1.37.2.2  yamt 		break;
   1368  1.37.2.2  yamt 
   1369  1.37.2.2  yamt 	case IWI_NOTIF_TYPE_CALIBRATION:
   1370  1.37.2.2  yamt 	case IWI_NOTIF_TYPE_BEACON:
   1371  1.37.2.2  yamt 	case IWI_NOTIF_TYPE_NOISE:
   1372  1.37.2.2  yamt 		DPRINTFN(5, ("Notification (%u)\n", notif->type));
   1373  1.37.2.2  yamt 		break;
   1374  1.37.2.2  yamt 
   1375  1.37.2.2  yamt 	default:
   1376  1.37.2.2  yamt 		aprint_error("%s: unknown notification type %u\n",
   1377  1.37.2.2  yamt 		    sc->sc_dev.dv_xname, notif->type);
   1378  1.37.2.2  yamt 	}
   1379  1.37.2.2  yamt }
   1380  1.37.2.2  yamt 
   1381  1.37.2.2  yamt static void
   1382  1.37.2.2  yamt iwi_rx_intr(struct iwi_softc *sc)
   1383  1.37.2.2  yamt {
   1384  1.37.2.2  yamt 	struct iwi_rx_data *data;
   1385  1.37.2.2  yamt 	struct iwi_hdr *hdr;
   1386  1.37.2.2  yamt 	uint32_t hw;
   1387  1.37.2.2  yamt 
   1388  1.37.2.2  yamt 	hw = CSR_READ_4(sc, IWI_CSR_RX_RIDX);
   1389  1.37.2.2  yamt 
   1390  1.37.2.2  yamt 	for (; sc->rxq.cur != hw;) {
   1391  1.37.2.2  yamt 		data = &sc->rxq.data[sc->rxq.cur];
   1392  1.37.2.2  yamt 
   1393  1.37.2.2  yamt 		bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1394  1.37.2.2  yamt 		    data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1395  1.37.2.2  yamt 
   1396  1.37.2.2  yamt 		hdr = mtod(data->m, struct iwi_hdr *);
   1397  1.37.2.2  yamt 
   1398  1.37.2.2  yamt 		switch (hdr->type) {
   1399  1.37.2.2  yamt 		case IWI_HDR_TYPE_FRAME:
   1400  1.37.2.2  yamt 			iwi_frame_intr(sc, data, sc->rxq.cur,
   1401  1.37.2.2  yamt 			    (struct iwi_frame *)(hdr + 1));
   1402  1.37.2.2  yamt 			break;
   1403  1.37.2.2  yamt 
   1404  1.37.2.2  yamt 		case IWI_HDR_TYPE_NOTIF:
   1405  1.37.2.2  yamt 			iwi_notification_intr(sc,
   1406  1.37.2.2  yamt 			    (struct iwi_notif *)(hdr + 1));
   1407  1.37.2.2  yamt 			break;
   1408  1.37.2.2  yamt 
   1409  1.37.2.2  yamt 		default:
   1410  1.37.2.2  yamt 			aprint_error("%s: unknown hdr type %u\n",
   1411  1.37.2.2  yamt 			    sc->sc_dev.dv_xname, hdr->type);
   1412  1.37.2.2  yamt 		}
   1413  1.37.2.2  yamt 
   1414  1.37.2.2  yamt 		DPRINTFN(15, ("rx done idx=%u\n", sc->rxq.cur));
   1415  1.37.2.2  yamt 
   1416  1.37.2.2  yamt 		sc->rxq.cur = (sc->rxq.cur + 1) % sc->rxq.count;
   1417  1.37.2.2  yamt 	}
   1418  1.37.2.2  yamt 
   1419  1.37.2.2  yamt 
   1420  1.37.2.2  yamt 	/* Tell the firmware what we have processed */
   1421  1.37.2.2  yamt 	hw = (hw == 0) ? sc->rxq.count - 1 : hw - 1;
   1422  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, hw);
   1423  1.37.2.2  yamt }
   1424  1.37.2.2  yamt 
   1425  1.37.2.2  yamt static void
   1426  1.37.2.2  yamt iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
   1427  1.37.2.2  yamt {
   1428  1.37.2.2  yamt 	struct ifnet *ifp = &sc->sc_if;
   1429  1.37.2.2  yamt 	struct iwi_tx_data *data;
   1430  1.37.2.2  yamt 	uint32_t hw;
   1431  1.37.2.2  yamt 
   1432  1.37.2.2  yamt 	hw = CSR_READ_4(sc, txq->csr_ridx);
   1433  1.37.2.2  yamt 
   1434  1.37.2.2  yamt 	for (; txq->next != hw;) {
   1435  1.37.2.2  yamt 		data = &txq->data[txq->next];
   1436  1.37.2.2  yamt 
   1437  1.37.2.2  yamt 		bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1438  1.37.2.2  yamt 		    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1439  1.37.2.2  yamt 		bus_dmamap_unload(sc->sc_dmat, data->map);
   1440  1.37.2.2  yamt 		m_freem(data->m);
   1441  1.37.2.2  yamt 		data->m = NULL;
   1442  1.37.2.2  yamt 		ieee80211_free_node(data->ni);
   1443  1.37.2.2  yamt 		data->ni = NULL;
   1444  1.37.2.2  yamt 
   1445  1.37.2.2  yamt 		DPRINTFN(15, ("tx done idx=%u\n", txq->next));
   1446  1.37.2.2  yamt 
   1447  1.37.2.2  yamt 		ifp->if_opackets++;
   1448  1.37.2.2  yamt 
   1449  1.37.2.2  yamt 		txq->queued--;
   1450  1.37.2.2  yamt 		txq->next = (txq->next + 1) % txq->count;
   1451  1.37.2.2  yamt 	}
   1452  1.37.2.2  yamt 
   1453  1.37.2.2  yamt 	sc->sc_tx_timer = 0;
   1454  1.37.2.2  yamt 	ifp->if_flags &= ~IFF_OACTIVE;
   1455  1.37.2.2  yamt 
   1456  1.37.2.2  yamt 	/* Call start() since some buffer descriptors have been released */
   1457  1.37.2.2  yamt 	(*ifp->if_start)(ifp);
   1458  1.37.2.2  yamt }
   1459  1.37.2.2  yamt 
   1460  1.37.2.2  yamt static int
   1461  1.37.2.2  yamt iwi_intr(void *arg)
   1462  1.37.2.2  yamt {
   1463  1.37.2.2  yamt 	struct iwi_softc *sc = arg;
   1464  1.37.2.2  yamt 	uint32_t r;
   1465  1.37.2.2  yamt 
   1466  1.37.2.2  yamt 	if ((r = CSR_READ_4(sc, IWI_CSR_INTR)) == 0 || r == 0xffffffff)
   1467  1.37.2.2  yamt 		return 0;
   1468  1.37.2.2  yamt 
   1469  1.37.2.2  yamt 	/* Acknowledge interrupts */
   1470  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_INTR, r);
   1471  1.37.2.2  yamt 
   1472  1.37.2.2  yamt 	if (r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)) {
   1473  1.37.2.2  yamt 		aprint_error("%s: fatal error\n", sc->sc_dev.dv_xname);
   1474  1.37.2.2  yamt 		if (r & IWI_INTR_FATAL_ERROR)
   1475  1.37.2.2  yamt 			iwi_error_log(sc);
   1476  1.37.2.2  yamt 		sc->sc_ic.ic_ifp->if_flags &= ~IFF_UP;
   1477  1.37.2.2  yamt 		iwi_stop(&sc->sc_if, 1);
   1478  1.37.2.2  yamt 	}
   1479  1.37.2.2  yamt 
   1480  1.37.2.2  yamt 	if (r & IWI_INTR_FW_INITED) {
   1481  1.37.2.2  yamt 		if (!(r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)))
   1482  1.37.2.2  yamt 			wakeup(sc);
   1483  1.37.2.2  yamt 	}
   1484  1.37.2.2  yamt 
   1485  1.37.2.2  yamt 	if (r & IWI_INTR_RADIO_OFF) {
   1486  1.37.2.2  yamt 		DPRINTF(("radio transmitter off\n"));
   1487  1.37.2.2  yamt 		sc->sc_ic.ic_ifp->if_flags &= ~IFF_UP;
   1488  1.37.2.2  yamt 		iwi_stop(&sc->sc_if, 1);
   1489  1.37.2.2  yamt 	}
   1490  1.37.2.2  yamt 
   1491  1.37.2.2  yamt 	if (r & IWI_INTR_CMD_DONE)
   1492  1.37.2.2  yamt 		wakeup(sc);
   1493  1.37.2.2  yamt 
   1494  1.37.2.2  yamt 	if (r & IWI_INTR_TX1_DONE)
   1495  1.37.2.2  yamt 		iwi_tx_intr(sc, &sc->txq[0]);
   1496  1.37.2.2  yamt 
   1497  1.37.2.2  yamt 	if (r & IWI_INTR_TX2_DONE)
   1498  1.37.2.2  yamt 		iwi_tx_intr(sc, &sc->txq[1]);
   1499  1.37.2.2  yamt 
   1500  1.37.2.2  yamt 	if (r & IWI_INTR_TX3_DONE)
   1501  1.37.2.2  yamt 		iwi_tx_intr(sc, &sc->txq[2]);
   1502  1.37.2.2  yamt 
   1503  1.37.2.2  yamt 	if (r & IWI_INTR_TX4_DONE)
   1504  1.37.2.2  yamt 		iwi_tx_intr(sc, &sc->txq[3]);
   1505  1.37.2.2  yamt 
   1506  1.37.2.2  yamt 	if (r & IWI_INTR_RX_DONE)
   1507  1.37.2.2  yamt 		iwi_rx_intr(sc);
   1508  1.37.2.2  yamt 
   1509  1.37.2.2  yamt 	return 1;
   1510  1.37.2.2  yamt }
   1511  1.37.2.2  yamt 
   1512  1.37.2.2  yamt static int
   1513  1.37.2.2  yamt iwi_cmd(struct iwi_softc *sc, uint8_t type, void *data, uint8_t len,
   1514  1.37.2.2  yamt     int async)
   1515  1.37.2.2  yamt {
   1516  1.37.2.2  yamt 	struct iwi_cmd_desc *desc;
   1517  1.37.2.2  yamt 
   1518  1.37.2.2  yamt 	desc = &sc->cmdq.desc[sc->cmdq.cur];
   1519  1.37.2.2  yamt 
   1520  1.37.2.2  yamt 	desc->hdr.type = IWI_HDR_TYPE_COMMAND;
   1521  1.37.2.2  yamt 	desc->hdr.flags = IWI_HDR_FLAG_IRQ;
   1522  1.37.2.2  yamt 	desc->type = type;
   1523  1.37.2.2  yamt 	desc->len = len;
   1524  1.37.2.2  yamt 	memcpy(desc->data, data, len);
   1525  1.37.2.2  yamt 
   1526  1.37.2.2  yamt 	bus_dmamap_sync(sc->sc_dmat, sc->cmdq.desc_map,
   1527  1.37.2.2  yamt 	    sc->cmdq.cur * IWI_CMD_DESC_SIZE,
   1528  1.37.2.2  yamt 	    IWI_CMD_DESC_SIZE, BUS_DMASYNC_PREWRITE);
   1529  1.37.2.2  yamt 
   1530  1.37.2.2  yamt 	DPRINTFN(2, ("sending command idx=%u type=%u len=%u\n", sc->cmdq.cur,
   1531  1.37.2.2  yamt 	    type, len));
   1532  1.37.2.2  yamt 
   1533  1.37.2.2  yamt 	sc->cmdq.cur = (sc->cmdq.cur + 1) % sc->cmdq.count;
   1534  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
   1535  1.37.2.2  yamt 
   1536  1.37.2.2  yamt 	return async ? 0 : tsleep(sc, 0, "iwicmd", hz);
   1537  1.37.2.2  yamt }
   1538  1.37.2.2  yamt 
   1539  1.37.2.2  yamt static void
   1540  1.37.2.2  yamt iwi_write_ibssnode(struct iwi_softc *sc, const struct iwi_node *in)
   1541  1.37.2.2  yamt {
   1542  1.37.2.2  yamt 	struct iwi_ibssnode node;
   1543  1.37.2.2  yamt 
   1544  1.37.2.2  yamt 	/* write node information into NIC memory */
   1545  1.37.2.2  yamt 	memset(&node, 0, sizeof node);
   1546  1.37.2.2  yamt 	IEEE80211_ADDR_COPY(node.bssid, in->in_node.ni_macaddr);
   1547  1.37.2.2  yamt 
   1548  1.37.2.2  yamt 	CSR_WRITE_REGION_1(sc,
   1549  1.37.2.2  yamt 	    IWI_CSR_NODE_BASE + in->in_station * sizeof node,
   1550  1.37.2.2  yamt 	    (uint8_t *)&node, sizeof node);
   1551  1.37.2.2  yamt }
   1552  1.37.2.2  yamt 
   1553  1.37.2.2  yamt static int
   1554  1.37.2.2  yamt iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
   1555  1.37.2.2  yamt     int ac)
   1556  1.37.2.2  yamt {
   1557  1.37.2.2  yamt 	struct iwi_softc *sc = ifp->if_softc;
   1558  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   1559  1.37.2.2  yamt 	struct iwi_node *in = (struct iwi_node *)ni;
   1560  1.37.2.2  yamt 	struct ieee80211_frame *wh;
   1561  1.37.2.2  yamt 	struct ieee80211_key *k;
   1562  1.37.2.2  yamt 	const struct chanAccParams *cap;
   1563  1.37.2.2  yamt 	struct iwi_tx_ring *txq = &sc->txq[ac];
   1564  1.37.2.2  yamt 	struct iwi_tx_data *data;
   1565  1.37.2.2  yamt 	struct iwi_tx_desc *desc;
   1566  1.37.2.2  yamt 	struct mbuf *mnew;
   1567  1.37.2.2  yamt 	int error, hdrlen, i, noack = 0;
   1568  1.37.2.2  yamt 
   1569  1.37.2.2  yamt 	wh = mtod(m0, struct ieee80211_frame *);
   1570  1.37.2.2  yamt 
   1571  1.37.2.2  yamt 	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
   1572  1.37.2.2  yamt 		hdrlen = sizeof (struct ieee80211_qosframe);
   1573  1.37.2.2  yamt 		cap = &ic->ic_wme.wme_chanParams;
   1574  1.37.2.2  yamt 		noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
   1575  1.37.2.2  yamt 	} else
   1576  1.37.2.2  yamt 		hdrlen = sizeof (struct ieee80211_frame);
   1577  1.37.2.2  yamt 
   1578  1.37.2.2  yamt 	/*
   1579  1.37.2.2  yamt 	 * This is only used in IBSS mode where the firmware expect an index
   1580  1.37.2.2  yamt 	 * in a h/w table instead of a destination address.
   1581  1.37.2.2  yamt 	 */
   1582  1.37.2.2  yamt 	if (ic->ic_opmode == IEEE80211_M_IBSS && in->in_station == -1) {
   1583  1.37.2.2  yamt 		in->in_station = iwi_alloc_unr(sc);
   1584  1.37.2.2  yamt 
   1585  1.37.2.2  yamt 		if (in->in_station == -1) {	/* h/w table is full */
   1586  1.37.2.2  yamt 			m_freem(m0);
   1587  1.37.2.2  yamt 			ieee80211_free_node(ni);
   1588  1.37.2.2  yamt 			ifp->if_oerrors++;
   1589  1.37.2.2  yamt 			return 0;
   1590  1.37.2.2  yamt 		}
   1591  1.37.2.2  yamt 		iwi_write_ibssnode(sc, in);
   1592  1.37.2.2  yamt 	}
   1593  1.37.2.2  yamt 
   1594  1.37.2.2  yamt 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
   1595  1.37.2.2  yamt 		k = ieee80211_crypto_encap(ic, ni, m0);
   1596  1.37.2.2  yamt 		if (k == NULL) {
   1597  1.37.2.2  yamt 			m_freem(m0);
   1598  1.37.2.2  yamt 			return ENOBUFS;
   1599  1.37.2.2  yamt 		}
   1600  1.37.2.2  yamt 
   1601  1.37.2.2  yamt 		/* packet header may have moved, reset our local pointer */
   1602  1.37.2.2  yamt 		wh = mtod(m0, struct ieee80211_frame *);
   1603  1.37.2.2  yamt 	}
   1604  1.37.2.2  yamt 
   1605  1.37.2.2  yamt #if NBPFILTER > 0
   1606  1.37.2.2  yamt 	if (sc->sc_drvbpf != NULL) {
   1607  1.37.2.2  yamt 		struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
   1608  1.37.2.2  yamt 
   1609  1.37.2.2  yamt 		tap->wt_flags = 0;
   1610  1.37.2.2  yamt 		tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
   1611  1.37.2.2  yamt 		tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
   1612  1.37.2.2  yamt 
   1613  1.37.2.2  yamt 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
   1614  1.37.2.2  yamt 	}
   1615  1.37.2.2  yamt #endif
   1616  1.37.2.2  yamt 
   1617  1.37.2.2  yamt 	data = &txq->data[txq->cur];
   1618  1.37.2.2  yamt 	desc = &txq->desc[txq->cur];
   1619  1.37.2.2  yamt 
   1620  1.37.2.2  yamt 	/* save and trim IEEE802.11 header */
   1621  1.37.2.2  yamt 	m_copydata(m0, 0, hdrlen, (caddr_t)&desc->wh);
   1622  1.37.2.2  yamt 	m_adj(m0, hdrlen);
   1623  1.37.2.2  yamt 
   1624  1.37.2.2  yamt 	error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
   1625  1.37.2.2  yamt 	    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   1626  1.37.2.2  yamt 	if (error != 0 && error != EFBIG) {
   1627  1.37.2.2  yamt 		aprint_error("%s: could not map mbuf (error %d)\n",
   1628  1.37.2.2  yamt 		    sc->sc_dev.dv_xname, error);
   1629  1.37.2.2  yamt 		m_freem(m0);
   1630  1.37.2.2  yamt 		return error;
   1631  1.37.2.2  yamt 	}
   1632  1.37.2.2  yamt 	if (error != 0) {
   1633  1.37.2.2  yamt 		/* too many fragments, linearize */
   1634  1.37.2.2  yamt 
   1635  1.37.2.2  yamt 		MGETHDR(mnew, M_DONTWAIT, MT_DATA);
   1636  1.37.2.2  yamt 		if (mnew == NULL) {
   1637  1.37.2.2  yamt 			m_freem(m0);
   1638  1.37.2.2  yamt 			return ENOMEM;
   1639  1.37.2.2  yamt 		}
   1640  1.37.2.2  yamt 
   1641  1.37.2.2  yamt 		M_COPY_PKTHDR(mnew, m0);
   1642  1.37.2.2  yamt 
   1643  1.37.2.2  yamt 		/* If the data won't fit in the header, get a cluster */
   1644  1.37.2.2  yamt 		if (m0->m_pkthdr.len > MHLEN) {
   1645  1.37.2.2  yamt 			MCLGET(mnew, M_DONTWAIT);
   1646  1.37.2.2  yamt 			if (!(mnew->m_flags & M_EXT)) {
   1647  1.37.2.2  yamt 				m_freem(m0);
   1648  1.37.2.2  yamt 				m_freem(mnew);
   1649  1.37.2.2  yamt 				return ENOMEM;
   1650  1.37.2.2  yamt 			}
   1651  1.37.2.2  yamt 		}
   1652  1.37.2.2  yamt 		m_copydata(m0, 0, m0->m_pkthdr.len, mtod(mnew, caddr_t));
   1653  1.37.2.2  yamt 		m_freem(m0);
   1654  1.37.2.2  yamt 		mnew->m_len = mnew->m_pkthdr.len;
   1655  1.37.2.2  yamt 		m0 = mnew;
   1656  1.37.2.2  yamt 
   1657  1.37.2.2  yamt 		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
   1658  1.37.2.2  yamt 		    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   1659  1.37.2.2  yamt 		if (error != 0) {
   1660  1.37.2.2  yamt 			aprint_error("%s: could not map mbuf (error %d)\n",
   1661  1.37.2.2  yamt 			    sc->sc_dev.dv_xname, error);
   1662  1.37.2.2  yamt 			m_freem(m0);
   1663  1.37.2.2  yamt 			return error;
   1664  1.37.2.2  yamt 		}
   1665  1.37.2.2  yamt 	}
   1666  1.37.2.2  yamt 
   1667  1.37.2.2  yamt 	data->m = m0;
   1668  1.37.2.2  yamt 	data->ni = ni;
   1669  1.37.2.2  yamt 
   1670  1.37.2.2  yamt 	desc->hdr.type = IWI_HDR_TYPE_DATA;
   1671  1.37.2.2  yamt 	desc->hdr.flags = IWI_HDR_FLAG_IRQ;
   1672  1.37.2.2  yamt 	desc->station =
   1673  1.37.2.2  yamt 	    (ic->ic_opmode == IEEE80211_M_IBSS) ? in->in_station : 0;
   1674  1.37.2.2  yamt 	desc->cmd = IWI_DATA_CMD_TX;
   1675  1.37.2.2  yamt 	desc->len = htole16(m0->m_pkthdr.len);
   1676  1.37.2.2  yamt 	desc->flags = 0;
   1677  1.37.2.2  yamt 	desc->xflags = 0;
   1678  1.37.2.2  yamt 
   1679  1.37.2.2  yamt 	if (!noack && !IEEE80211_IS_MULTICAST(desc->wh.i_addr1))
   1680  1.37.2.2  yamt 		desc->flags |= IWI_DATA_FLAG_NEED_ACK;
   1681  1.37.2.2  yamt 
   1682  1.37.2.2  yamt #if 0
   1683  1.37.2.2  yamt 	if (ic->ic_flags & IEEE80211_F_PRIVACY) {
   1684  1.37.2.2  yamt 		desc->wh.i_fc[1] |= IEEE80211_FC1_WEP;
   1685  1.37.2.2  yamt 		desc->wep_txkey = ic->ic_crypto.cs_def_txkey;
   1686  1.37.2.2  yamt 	} else
   1687  1.37.2.2  yamt #endif
   1688  1.37.2.2  yamt 		desc->flags |= IWI_DATA_FLAG_NO_WEP;
   1689  1.37.2.2  yamt 
   1690  1.37.2.2  yamt 	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
   1691  1.37.2.2  yamt 		desc->flags |= IWI_DATA_FLAG_SHPREAMBLE;
   1692  1.37.2.2  yamt 
   1693  1.37.2.2  yamt 	if (desc->wh.i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)
   1694  1.37.2.2  yamt 		desc->xflags |= IWI_DATA_XFLAG_QOS;
   1695  1.37.2.2  yamt 
   1696  1.37.2.2  yamt 	desc->nseg = htole32(data->map->dm_nsegs);
   1697  1.37.2.2  yamt 	for (i = 0; i < data->map->dm_nsegs; i++) {
   1698  1.37.2.2  yamt 		desc->seg_addr[i] = htole32(data->map->dm_segs[i].ds_addr);
   1699  1.37.2.2  yamt 		desc->seg_len[i]  = htole16(data->map->dm_segs[i].ds_len);
   1700  1.37.2.2  yamt 	}
   1701  1.37.2.2  yamt 
   1702  1.37.2.2  yamt 	bus_dmamap_sync(sc->sc_dmat, txq->desc_map,
   1703  1.37.2.2  yamt 	    txq->cur * IWI_TX_DESC_SIZE,
   1704  1.37.2.2  yamt 	    IWI_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE);
   1705  1.37.2.2  yamt 
   1706  1.37.2.2  yamt 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
   1707  1.37.2.2  yamt 	    BUS_DMASYNC_PREWRITE);
   1708  1.37.2.2  yamt 
   1709  1.37.2.2  yamt 	DPRINTFN(5, ("sending data frame txq=%u idx=%u len=%u nseg=%u\n",
   1710  1.37.2.2  yamt 	    ac, txq->cur, le16toh(desc->len), le32toh(desc->nseg)));
   1711  1.37.2.2  yamt 
   1712  1.37.2.2  yamt 	/* Inform firmware about this new packet */
   1713  1.37.2.2  yamt 	txq->queued++;
   1714  1.37.2.2  yamt 	txq->cur = (txq->cur + 1) % txq->count;
   1715  1.37.2.2  yamt 	CSR_WRITE_4(sc, txq->csr_widx, txq->cur);
   1716  1.37.2.2  yamt 
   1717  1.37.2.2  yamt 	return 0;
   1718  1.37.2.2  yamt }
   1719  1.37.2.2  yamt 
   1720  1.37.2.2  yamt static void
   1721  1.37.2.2  yamt iwi_start(struct ifnet *ifp)
   1722  1.37.2.2  yamt {
   1723  1.37.2.2  yamt 	struct iwi_softc *sc = ifp->if_softc;
   1724  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   1725  1.37.2.2  yamt 	struct mbuf *m0;
   1726  1.37.2.2  yamt 	struct ether_header *eh;
   1727  1.37.2.2  yamt 	struct ieee80211_node *ni;
   1728  1.37.2.2  yamt 	int ac;
   1729  1.37.2.2  yamt 
   1730  1.37.2.2  yamt 	if (ic->ic_state != IEEE80211_S_RUN)
   1731  1.37.2.2  yamt 		return;
   1732  1.37.2.2  yamt 
   1733  1.37.2.2  yamt 	for (;;) {
   1734  1.37.2.2  yamt 		IF_DEQUEUE(&ifp->if_snd, m0);
   1735  1.37.2.2  yamt 		if (m0 == NULL)
   1736  1.37.2.2  yamt 			break;
   1737  1.37.2.2  yamt 
   1738  1.37.2.2  yamt 		if (m0->m_len < sizeof (struct ether_header) &&
   1739  1.37.2.2  yamt 		    (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) {
   1740  1.37.2.2  yamt 			ifp->if_oerrors++;
   1741  1.37.2.2  yamt 			continue;
   1742  1.37.2.2  yamt 		}
   1743  1.37.2.2  yamt 
   1744  1.37.2.2  yamt #if NBPFILTER > 0
   1745  1.37.2.2  yamt 		if (ifp->if_bpf != NULL)
   1746  1.37.2.2  yamt 			bpf_mtap(ifp->if_bpf, m0);
   1747  1.37.2.2  yamt #endif
   1748  1.37.2.2  yamt 
   1749  1.37.2.2  yamt 		eh = mtod(m0, struct ether_header *);
   1750  1.37.2.2  yamt 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   1751  1.37.2.2  yamt 		if (ni == NULL) {
   1752  1.37.2.2  yamt 			m_freem(m0);
   1753  1.37.2.2  yamt 			ifp->if_oerrors++;
   1754  1.37.2.2  yamt 			continue;
   1755  1.37.2.2  yamt 		}
   1756  1.37.2.2  yamt 
   1757  1.37.2.2  yamt 		/* classify mbuf so we can find which tx ring to use */
   1758  1.37.2.2  yamt 		if (ieee80211_classify(ic, m0, ni) != 0) {
   1759  1.37.2.2  yamt 			m_freem(m0);
   1760  1.37.2.2  yamt 			ieee80211_free_node(ni);
   1761  1.37.2.2  yamt 			ifp->if_oerrors++;
   1762  1.37.2.2  yamt 			continue;
   1763  1.37.2.2  yamt 		}
   1764  1.37.2.2  yamt 
   1765  1.37.2.2  yamt 		/* no QoS encapsulation for EAPOL frames */
   1766  1.37.2.2  yamt 		ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
   1767  1.37.2.2  yamt 		    M_WME_GETAC(m0) : WME_AC_BE;
   1768  1.37.2.2  yamt 
   1769  1.37.2.2  yamt 		if (sc->txq[ac].queued > sc->txq[ac].count - 8) {
   1770  1.37.2.2  yamt 			/* there is no place left in this ring */
   1771  1.37.2.2  yamt 			IF_PREPEND(&ifp->if_snd, m0);
   1772  1.37.2.2  yamt 			ifp->if_flags |= IFF_OACTIVE;
   1773  1.37.2.2  yamt 			break;
   1774  1.37.2.2  yamt 		}
   1775  1.37.2.2  yamt #ifdef XXXNH
   1776  1.37.2.2  yamt 		BPF_MTAP(ifp, m0);
   1777  1.37.2.2  yamt #endif
   1778  1.37.2.2  yamt 		m0 = ieee80211_encap(ic, m0, ni);
   1779  1.37.2.2  yamt 		if (m0 == NULL) {
   1780  1.37.2.2  yamt 			ieee80211_free_node(ni);
   1781  1.37.2.2  yamt 			ifp->if_oerrors++;
   1782  1.37.2.2  yamt 			continue;
   1783  1.37.2.2  yamt 		}
   1784  1.37.2.2  yamt 
   1785  1.37.2.2  yamt #if NBPFILTER > 0
   1786  1.37.2.2  yamt 		if (ic->ic_rawbpf != NULL)
   1787  1.37.2.2  yamt 			bpf_mtap(ic->ic_rawbpf, m0);
   1788  1.37.2.2  yamt #endif
   1789  1.37.2.2  yamt 
   1790  1.37.2.2  yamt 		if (iwi_tx_start(ifp, m0, ni, ac) != 0) {
   1791  1.37.2.2  yamt 			ieee80211_free_node(ni);
   1792  1.37.2.2  yamt 			ifp->if_oerrors++;
   1793  1.37.2.2  yamt 			break;
   1794  1.37.2.2  yamt 		}
   1795  1.37.2.2  yamt 
   1796  1.37.2.2  yamt 		/* start watchdog timer */
   1797  1.37.2.2  yamt 		sc->sc_tx_timer = 5;
   1798  1.37.2.2  yamt 		ifp->if_timer = 1;
   1799  1.37.2.2  yamt 	}
   1800  1.37.2.2  yamt }
   1801  1.37.2.2  yamt 
   1802  1.37.2.2  yamt static void
   1803  1.37.2.2  yamt iwi_watchdog(struct ifnet *ifp)
   1804  1.37.2.2  yamt {
   1805  1.37.2.2  yamt 	struct iwi_softc *sc = ifp->if_softc;
   1806  1.37.2.2  yamt 
   1807  1.37.2.2  yamt 	ifp->if_timer = 0;
   1808  1.37.2.2  yamt 
   1809  1.37.2.2  yamt 	if (sc->sc_tx_timer > 0) {
   1810  1.37.2.2  yamt 		if (--sc->sc_tx_timer == 0) {
   1811  1.37.2.2  yamt 			aprint_error("%s: device timeout\n",
   1812  1.37.2.2  yamt 			    sc->sc_dev.dv_xname);
   1813  1.37.2.2  yamt 			ifp->if_oerrors++;
   1814  1.37.2.2  yamt 			ifp->if_flags &= ~IFF_UP;
   1815  1.37.2.2  yamt 			iwi_stop(ifp, 1);
   1816  1.37.2.2  yamt 			return;
   1817  1.37.2.2  yamt 		}
   1818  1.37.2.2  yamt 		ifp->if_timer = 1;
   1819  1.37.2.2  yamt 	}
   1820  1.37.2.2  yamt 
   1821  1.37.2.2  yamt 	ieee80211_watchdog(&sc->sc_ic);
   1822  1.37.2.2  yamt }
   1823  1.37.2.2  yamt 
   1824  1.37.2.2  yamt static int
   1825  1.37.2.2  yamt iwi_get_table0(struct iwi_softc *sc, uint32_t *tbl)
   1826  1.37.2.2  yamt {
   1827  1.37.2.2  yamt 	uint32_t size, buf[128];
   1828  1.37.2.2  yamt 
   1829  1.37.2.2  yamt 	if (!(sc->flags & IWI_FLAG_FW_INITED)) {
   1830  1.37.2.2  yamt 		memset(buf, 0, sizeof buf);
   1831  1.37.2.2  yamt 		return copyout(buf, tbl, sizeof buf);
   1832  1.37.2.2  yamt 	}
   1833  1.37.2.2  yamt 
   1834  1.37.2.2  yamt 	size = min(CSR_READ_4(sc, IWI_CSR_TABLE0_SIZE), 128 - 1);
   1835  1.37.2.2  yamt 	CSR_READ_REGION_4(sc, IWI_CSR_TABLE0_BASE, &buf[1], size);
   1836  1.37.2.2  yamt 
   1837  1.37.2.2  yamt 	return copyout(buf, tbl, sizeof buf);
   1838  1.37.2.2  yamt }
   1839  1.37.2.2  yamt 
   1840  1.37.2.2  yamt static int
   1841  1.37.2.2  yamt iwi_get_radio(struct iwi_softc *sc, int *ret)
   1842  1.37.2.2  yamt {
   1843  1.37.2.2  yamt 	int val;
   1844  1.37.2.2  yamt 
   1845  1.37.2.2  yamt 	val = (CSR_READ_4(sc, IWI_CSR_IO) & IWI_IO_RADIO_ENABLED) ? 1 : 0;
   1846  1.37.2.2  yamt 	return copyout(&val, ret, sizeof val);
   1847  1.37.2.2  yamt }
   1848  1.37.2.2  yamt 
   1849  1.37.2.2  yamt static int
   1850  1.37.2.2  yamt iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
   1851  1.37.2.2  yamt {
   1852  1.37.2.2  yamt 	struct iwi_softc *sc = ifp->if_softc;
   1853  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   1854  1.37.2.2  yamt 	struct ifreq *ifr;
   1855  1.37.2.2  yamt 	int s, error = 0;
   1856  1.37.2.2  yamt 
   1857  1.37.2.2  yamt 	s = splnet();
   1858  1.37.2.2  yamt 
   1859  1.37.2.2  yamt 	switch (cmd) {
   1860  1.37.2.2  yamt 	case SIOCSIFFLAGS:
   1861  1.37.2.2  yamt 		if (ifp->if_flags & IFF_UP) {
   1862  1.37.2.2  yamt 			if (!(ifp->if_flags & IFF_RUNNING))
   1863  1.37.2.2  yamt 				iwi_init(ifp);
   1864  1.37.2.2  yamt 		} else {
   1865  1.37.2.2  yamt 			if (ifp->if_flags & IFF_RUNNING)
   1866  1.37.2.2  yamt 				iwi_stop(ifp, 1);
   1867  1.37.2.2  yamt 		}
   1868  1.37.2.2  yamt 		break;
   1869  1.37.2.2  yamt 
   1870  1.37.2.2  yamt 	case SIOCGTABLE0:
   1871  1.37.2.2  yamt 		ifr = (struct ifreq *)data;
   1872  1.37.2.2  yamt 		error = iwi_get_table0(sc, (uint32_t *)ifr->ifr_data);
   1873  1.37.2.2  yamt 		break;
   1874  1.37.2.2  yamt 
   1875  1.37.2.2  yamt 	case SIOCGRADIO:
   1876  1.37.2.2  yamt 		ifr = (struct ifreq *)data;
   1877  1.37.2.2  yamt 		error = iwi_get_radio(sc, (int *)ifr->ifr_data);
   1878  1.37.2.2  yamt 		break;
   1879  1.37.2.2  yamt 
   1880  1.37.2.2  yamt 	case SIOCSLOADFW:
   1881  1.37.2.2  yamt 		/* only super-user can do that! */
   1882  1.37.2.2  yamt 		if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0)
   1883  1.37.2.2  yamt 			break;
   1884  1.37.2.2  yamt 
   1885  1.37.2.2  yamt 		ifr = (struct ifreq *)data;
   1886  1.37.2.2  yamt 		error = iwi_cache_firmware(sc, ifr->ifr_data);
   1887  1.37.2.2  yamt 		break;
   1888  1.37.2.2  yamt 
   1889  1.37.2.2  yamt 	case SIOCSKILLFW:
   1890  1.37.2.2  yamt 		/* only super-user can do that! */
   1891  1.37.2.2  yamt 		if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0)
   1892  1.37.2.2  yamt 			break;
   1893  1.37.2.2  yamt 
   1894  1.37.2.2  yamt 		ifp->if_flags &= ~IFF_UP;
   1895  1.37.2.2  yamt 		iwi_stop(ifp, 1);
   1896  1.37.2.2  yamt 		iwi_free_firmware(sc);
   1897  1.37.2.2  yamt 		break;
   1898  1.37.2.2  yamt 
   1899  1.37.2.2  yamt 	default:
   1900  1.37.2.2  yamt 		error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
   1901  1.37.2.2  yamt 	}
   1902  1.37.2.2  yamt 
   1903  1.37.2.2  yamt 	if (error == ENETRESET && cmd != SIOCADDMULTI) {
   1904  1.37.2.2  yamt 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   1905  1.37.2.2  yamt 		    (IFF_UP | IFF_RUNNING) &&
   1906  1.37.2.2  yamt 		    (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
   1907  1.37.2.2  yamt 			iwi_init(ifp);
   1908  1.37.2.2  yamt 		error = 0;
   1909  1.37.2.2  yamt 	}
   1910  1.37.2.2  yamt 
   1911  1.37.2.2  yamt 	splx(s);
   1912  1.37.2.2  yamt 	return error;
   1913  1.37.2.2  yamt }
   1914  1.37.2.2  yamt 
   1915  1.37.2.2  yamt static void
   1916  1.37.2.2  yamt iwi_stop_master(struct iwi_softc *sc)
   1917  1.37.2.2  yamt {
   1918  1.37.2.2  yamt 	int ntries;
   1919  1.37.2.2  yamt 
   1920  1.37.2.2  yamt 	/* Disable interrupts */
   1921  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
   1922  1.37.2.2  yamt 
   1923  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_STOP_MASTER);
   1924  1.37.2.2  yamt 	for (ntries = 0; ntries < 5; ntries++) {
   1925  1.37.2.2  yamt 		if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
   1926  1.37.2.2  yamt 			break;
   1927  1.37.2.2  yamt 		DELAY(10);
   1928  1.37.2.2  yamt 	}
   1929  1.37.2.2  yamt 	if (ntries == 5)
   1930  1.37.2.2  yamt 		aprint_error("%s: timeout waiting for master\n",
   1931  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   1932  1.37.2.2  yamt 
   1933  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
   1934  1.37.2.2  yamt 	    IWI_RST_PRINCETON_RESET);
   1935  1.37.2.2  yamt 
   1936  1.37.2.2  yamt 	sc->flags &= ~IWI_FLAG_FW_INITED;
   1937  1.37.2.2  yamt }
   1938  1.37.2.2  yamt 
   1939  1.37.2.2  yamt static int
   1940  1.37.2.2  yamt iwi_reset(struct iwi_softc *sc)
   1941  1.37.2.2  yamt {
   1942  1.37.2.2  yamt 	int i, ntries;
   1943  1.37.2.2  yamt 
   1944  1.37.2.2  yamt 	iwi_stop_master(sc);
   1945  1.37.2.2  yamt 
   1946  1.37.2.2  yamt 	/* Move adapter to D0 state */
   1947  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
   1948  1.37.2.2  yamt 	    IWI_CTL_INIT);
   1949  1.37.2.2  yamt 
   1950  1.37.2.2  yamt 	/* Initialize Phase-Locked Level  (PLL) */
   1951  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_READ_INT, IWI_READ_INT_INIT_HOST);
   1952  1.37.2.2  yamt 
   1953  1.37.2.2  yamt 	/* Wait for clock stabilization */
   1954  1.37.2.2  yamt 	for (ntries = 0; ntries < 1000; ntries++) {
   1955  1.37.2.2  yamt 		if (CSR_READ_4(sc, IWI_CSR_CTL) & IWI_CTL_CLOCK_READY)
   1956  1.37.2.2  yamt 			break;
   1957  1.37.2.2  yamt 		DELAY(200);
   1958  1.37.2.2  yamt 	}
   1959  1.37.2.2  yamt 	if (ntries == 1000) {
   1960  1.37.2.2  yamt 		aprint_error("%s: timeout waiting for clock stabilization\n",
   1961  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   1962  1.37.2.2  yamt 		return EIO;
   1963  1.37.2.2  yamt 	}
   1964  1.37.2.2  yamt 
   1965  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
   1966  1.37.2.2  yamt 	    IWI_RST_SW_RESET);
   1967  1.37.2.2  yamt 
   1968  1.37.2.2  yamt 	DELAY(10);
   1969  1.37.2.2  yamt 
   1970  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
   1971  1.37.2.2  yamt 	    IWI_CTL_INIT);
   1972  1.37.2.2  yamt 
   1973  1.37.2.2  yamt 	/* Clear NIC memory */
   1974  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0);
   1975  1.37.2.2  yamt 	for (i = 0; i < 0xc000; i++)
   1976  1.37.2.2  yamt 		CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
   1977  1.37.2.2  yamt 
   1978  1.37.2.2  yamt 	return 0;
   1979  1.37.2.2  yamt }
   1980  1.37.2.2  yamt 
   1981  1.37.2.2  yamt static int
   1982  1.37.2.2  yamt iwi_load_ucode(struct iwi_softc *sc, void *uc, int size)
   1983  1.37.2.2  yamt {
   1984  1.37.2.2  yamt 	uint16_t *w;
   1985  1.37.2.2  yamt 	int ntries, i;
   1986  1.37.2.2  yamt 
   1987  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
   1988  1.37.2.2  yamt 	    IWI_RST_STOP_MASTER);
   1989  1.37.2.2  yamt 	for (ntries = 0; ntries < 5; ntries++) {
   1990  1.37.2.2  yamt 		if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
   1991  1.37.2.2  yamt 			break;
   1992  1.37.2.2  yamt 		DELAY(10);
   1993  1.37.2.2  yamt 	}
   1994  1.37.2.2  yamt 	if (ntries == 5) {
   1995  1.37.2.2  yamt 		aprint_error("%s: timeout waiting for master\n",
   1996  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   1997  1.37.2.2  yamt 		return EIO;
   1998  1.37.2.2  yamt 	}
   1999  1.37.2.2  yamt 
   2000  1.37.2.2  yamt 	MEM_WRITE_4(sc, 0x3000e0, 0x80000000);
   2001  1.37.2.2  yamt 	DELAY(5000);
   2002  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) &
   2003  1.37.2.2  yamt 	    ~IWI_RST_PRINCETON_RESET);
   2004  1.37.2.2  yamt 	DELAY(5000);
   2005  1.37.2.2  yamt 	MEM_WRITE_4(sc, 0x3000e0, 0);
   2006  1.37.2.2  yamt 	DELAY(1000);
   2007  1.37.2.2  yamt 	MEM_WRITE_4(sc, 0x300004, 1);
   2008  1.37.2.2  yamt 	DELAY(1000);
   2009  1.37.2.2  yamt 	MEM_WRITE_4(sc, 0x300004, 0);
   2010  1.37.2.2  yamt 	DELAY(1000);
   2011  1.37.2.2  yamt 	MEM_WRITE_1(sc, 0x200000, 0x00);
   2012  1.37.2.2  yamt 	MEM_WRITE_1(sc, 0x200000, 0x40);
   2013  1.37.2.2  yamt 	DELAY(1000);
   2014  1.37.2.2  yamt 
   2015  1.37.2.2  yamt 	/* Adapter is buggy, we must set the address for each word */
   2016  1.37.2.2  yamt 	for (w = uc; size > 0; w++, size -= 2)
   2017  1.37.2.2  yamt 		MEM_WRITE_2(sc, 0x200010, htole16(*w));
   2018  1.37.2.2  yamt 
   2019  1.37.2.2  yamt 	MEM_WRITE_1(sc, 0x200000, 0x00);
   2020  1.37.2.2  yamt 	MEM_WRITE_1(sc, 0x200000, 0x80);
   2021  1.37.2.2  yamt 
   2022  1.37.2.2  yamt 	/* Wait until we get a response in the uc queue */
   2023  1.37.2.2  yamt 	for (ntries = 0; ntries < 100; ntries++) {
   2024  1.37.2.2  yamt 		if (MEM_READ_1(sc, 0x200000) & 1)
   2025  1.37.2.2  yamt 			break;
   2026  1.37.2.2  yamt 		DELAY(100);
   2027  1.37.2.2  yamt 	}
   2028  1.37.2.2  yamt 	if (ntries == 100) {
   2029  1.37.2.2  yamt 		aprint_error("%s: timeout waiting for ucode to initialize\n",
   2030  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2031  1.37.2.2  yamt 		return EIO;
   2032  1.37.2.2  yamt 	}
   2033  1.37.2.2  yamt 
   2034  1.37.2.2  yamt 	/* Empty the uc queue or the firmware will not initialize properly */
   2035  1.37.2.2  yamt 	for (i = 0; i < 7; i++)
   2036  1.37.2.2  yamt 		MEM_READ_4(sc, 0x200004);
   2037  1.37.2.2  yamt 
   2038  1.37.2.2  yamt 	MEM_WRITE_1(sc, 0x200000, 0x00);
   2039  1.37.2.2  yamt 
   2040  1.37.2.2  yamt 	return 0;
   2041  1.37.2.2  yamt }
   2042  1.37.2.2  yamt 
   2043  1.37.2.2  yamt /* macro to handle unaligned little endian data in firmware image */
   2044  1.37.2.2  yamt #define GETLE32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
   2045  1.37.2.2  yamt static int
   2046  1.37.2.2  yamt iwi_load_firmware(struct iwi_softc *sc, void *fw, int size)
   2047  1.37.2.2  yamt {
   2048  1.37.2.2  yamt 	bus_dmamap_t map;
   2049  1.37.2.2  yamt 	u_char *p, *end;
   2050  1.37.2.2  yamt 	uint32_t sentinel, ctl, sum;
   2051  1.37.2.2  yamt 	uint32_t cs, sl, cd, cl;
   2052  1.37.2.2  yamt 	int ntries, nsegs, error;
   2053  1.37.2.2  yamt 	int sn;
   2054  1.37.2.2  yamt 
   2055  1.37.2.2  yamt 	nsegs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
   2056  1.37.2.2  yamt 
   2057  1.37.2.2  yamt 	/* Create a DMA map for the firmware image */
   2058  1.37.2.2  yamt 	error = bus_dmamap_create(sc->sc_dmat, size, nsegs, size, 0,
   2059  1.37.2.2  yamt 	    BUS_DMA_NOWAIT, &map);
   2060  1.37.2.2  yamt 	if (error != 0) {
   2061  1.37.2.2  yamt 		aprint_error("%s: could not create firmware DMA map\n",
   2062  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2063  1.37.2.2  yamt 		goto fail1;
   2064  1.37.2.2  yamt 	}
   2065  1.37.2.2  yamt 
   2066  1.37.2.2  yamt 	error = bus_dmamap_load(sc->sc_dmat, map, fw, size, NULL,
   2067  1.37.2.2  yamt 	    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
   2068  1.37.2.2  yamt 	if (error != 0) {
   2069  1.37.2.2  yamt 		aprint_error("%s: could not load fw dma map(%d)\n",
   2070  1.37.2.2  yamt 		    sc->sc_dev.dv_xname, error);
   2071  1.37.2.2  yamt 		goto fail2;
   2072  1.37.2.2  yamt 	}
   2073  1.37.2.2  yamt 
   2074  1.37.2.2  yamt 	/* Make sure the adapter will get up-to-date values */
   2075  1.37.2.2  yamt 	bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_PREWRITE);
   2076  1.37.2.2  yamt 
   2077  1.37.2.2  yamt 	/* Tell the adapter where the command blocks are stored */
   2078  1.37.2.2  yamt 	MEM_WRITE_4(sc, 0x3000a0, 0x27000);
   2079  1.37.2.2  yamt 
   2080  1.37.2.2  yamt 	/*
   2081  1.37.2.2  yamt 	 * Store command blocks into adapter's internal memory using register
   2082  1.37.2.2  yamt 	 * indirections. The adapter will read the firmware image through DMA
   2083  1.37.2.2  yamt 	 * using information stored in command blocks.
   2084  1.37.2.2  yamt 	 */
   2085  1.37.2.2  yamt 	p = fw;
   2086  1.37.2.2  yamt 	end = p + size;
   2087  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0x27000);
   2088  1.37.2.2  yamt 
   2089  1.37.2.2  yamt 	sn = 0;
   2090  1.37.2.2  yamt 	sl = cl = 0;
   2091  1.37.2.2  yamt 	cs = cd = 0;
   2092  1.37.2.2  yamt 	while (p < end) {
   2093  1.37.2.2  yamt 		if (sl == 0) {
   2094  1.37.2.2  yamt 			cs = map->dm_segs[sn].ds_addr;
   2095  1.37.2.2  yamt 			sl = map->dm_segs[sn].ds_len;
   2096  1.37.2.2  yamt 			sn++;
   2097  1.37.2.2  yamt 		}
   2098  1.37.2.2  yamt 		if (cl == 0) {
   2099  1.37.2.2  yamt 			cd = GETLE32(p); p += 4; cs += 4; sl -= 4;
   2100  1.37.2.2  yamt 			cl = GETLE32(p); p += 4; cs += 4; sl -= 4;
   2101  1.37.2.2  yamt 		}
   2102  1.37.2.2  yamt 		while (sl > 0 && cl > 0) {
   2103  1.37.2.2  yamt 			int len = min(cl, sl);
   2104  1.37.2.2  yamt 
   2105  1.37.2.2  yamt 			sl -= len;
   2106  1.37.2.2  yamt 			cl -= len;
   2107  1.37.2.2  yamt 			p += len;
   2108  1.37.2.2  yamt 
   2109  1.37.2.2  yamt 			while (len > 0) {
   2110  1.37.2.2  yamt 				int mlen = min(len, IWI_CB_MAXDATALEN);
   2111  1.37.2.2  yamt 
   2112  1.37.2.2  yamt 				ctl = IWI_CB_DEFAULT_CTL | mlen;
   2113  1.37.2.2  yamt 				sum = ctl ^ cs ^ cd;
   2114  1.37.2.2  yamt 
   2115  1.37.2.2  yamt 				/* Write a command block */
   2116  1.37.2.2  yamt 				CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, ctl);
   2117  1.37.2.2  yamt 				CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, cs);
   2118  1.37.2.2  yamt 				CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, cd);
   2119  1.37.2.2  yamt 				CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, sum);
   2120  1.37.2.2  yamt 
   2121  1.37.2.2  yamt 				cs += mlen;
   2122  1.37.2.2  yamt 				cd += mlen;
   2123  1.37.2.2  yamt 				len -= mlen;
   2124  1.37.2.2  yamt 			}
   2125  1.37.2.2  yamt 		}
   2126  1.37.2.2  yamt 	}
   2127  1.37.2.2  yamt 
   2128  1.37.2.2  yamt 	/* Write a fictive final command block (sentinel) */
   2129  1.37.2.2  yamt 	sentinel = CSR_READ_4(sc, IWI_CSR_AUTOINC_ADDR);
   2130  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
   2131  1.37.2.2  yamt 
   2132  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) &
   2133  1.37.2.2  yamt 	    ~(IWI_RST_MASTER_DISABLED | IWI_RST_STOP_MASTER));
   2134  1.37.2.2  yamt 
   2135  1.37.2.2  yamt 	/* Tell the adapter to start processing command blocks */
   2136  1.37.2.2  yamt 	MEM_WRITE_4(sc, 0x3000a4, 0x540100);
   2137  1.37.2.2  yamt 
   2138  1.37.2.2  yamt 	/* Wait until the adapter has processed all command blocks */
   2139  1.37.2.2  yamt 	for (ntries = 0; ntries < 400; ntries++) {
   2140  1.37.2.2  yamt 		if (MEM_READ_4(sc, 0x3000d0) >= sentinel)
   2141  1.37.2.2  yamt 			break;
   2142  1.37.2.2  yamt 		DELAY(100);
   2143  1.37.2.2  yamt 	}
   2144  1.37.2.2  yamt 	if (ntries == 400) {
   2145  1.37.2.2  yamt 		aprint_error("%s: timeout processing cb\n",
   2146  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2147  1.37.2.2  yamt 		error = EIO;
   2148  1.37.2.2  yamt 		goto fail2;
   2149  1.37.2.2  yamt 	}
   2150  1.37.2.2  yamt 
   2151  1.37.2.2  yamt 	/* We're done with command blocks processing */
   2152  1.37.2.2  yamt 	MEM_WRITE_4(sc, 0x3000a4, 0x540c00);
   2153  1.37.2.2  yamt 
   2154  1.37.2.2  yamt 	/* Allow interrupts so we know when the firmware is inited */
   2155  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK);
   2156  1.37.2.2  yamt 
   2157  1.37.2.2  yamt 	/* Tell the adapter to initialize the firmware */
   2158  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, 0);
   2159  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
   2160  1.37.2.2  yamt 	    IWI_CTL_ALLOW_STANDBY);
   2161  1.37.2.2  yamt 
   2162  1.37.2.2  yamt 	/* Wait at most one second for firmware initialization to complete */
   2163  1.37.2.2  yamt 	if ((error = tsleep(sc, 0, "iwiinit", hz)) != 0) {
   2164  1.37.2.2  yamt 		aprint_error("%s: timeout waiting for firmware initialization "
   2165  1.37.2.2  yamt 		    "to complete\n", sc->sc_dev.dv_xname);
   2166  1.37.2.2  yamt 		goto fail3;
   2167  1.37.2.2  yamt 	}
   2168  1.37.2.2  yamt 
   2169  1.37.2.2  yamt fail3:
   2170  1.37.2.2  yamt 	bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_POSTWRITE);
   2171  1.37.2.2  yamt 	bus_dmamap_unload(sc->sc_dmat, map);
   2172  1.37.2.2  yamt fail2:
   2173  1.37.2.2  yamt 	bus_dmamap_destroy(sc->sc_dmat, map);
   2174  1.37.2.2  yamt 
   2175  1.37.2.2  yamt fail1:
   2176  1.37.2.2  yamt 	return error;
   2177  1.37.2.2  yamt }
   2178  1.37.2.2  yamt 
   2179  1.37.2.2  yamt /*
   2180  1.37.2.2  yamt  * Store firmware into kernel memory so we can download it when we need to,
   2181  1.37.2.2  yamt  * e.g when the adapter wakes up from suspend mode.
   2182  1.37.2.2  yamt  */
   2183  1.37.2.2  yamt static int
   2184  1.37.2.2  yamt iwi_cache_firmware(struct iwi_softc *sc, void *data)
   2185  1.37.2.2  yamt {
   2186  1.37.2.2  yamt 	struct iwi_firmware *kfw = &sc->fw;
   2187  1.37.2.2  yamt 	struct iwi_firmware ufw;
   2188  1.37.2.2  yamt 	int error;
   2189  1.37.2.2  yamt 
   2190  1.37.2.2  yamt 	iwi_free_firmware(sc);
   2191  1.37.2.2  yamt 
   2192  1.37.2.2  yamt 	if ((error = copyin(data, &ufw, sizeof ufw)) != 0)
   2193  1.37.2.2  yamt 		goto fail1;
   2194  1.37.2.2  yamt 
   2195  1.37.2.2  yamt 	kfw->boot_size  = ufw.boot_size;
   2196  1.37.2.2  yamt 	kfw->ucode_size = ufw.ucode_size;
   2197  1.37.2.2  yamt 	kfw->main_size  = ufw.main_size;
   2198  1.37.2.2  yamt 
   2199  1.37.2.2  yamt 	kfw->boot = malloc(kfw->boot_size, M_DEVBUF, M_NOWAIT);
   2200  1.37.2.2  yamt 	if (kfw->boot == NULL) {
   2201  1.37.2.2  yamt 		error = ENOMEM;
   2202  1.37.2.2  yamt 		goto fail1;
   2203  1.37.2.2  yamt 	}
   2204  1.37.2.2  yamt 
   2205  1.37.2.2  yamt 	kfw->ucode = malloc(kfw->ucode_size, M_DEVBUF, M_NOWAIT);
   2206  1.37.2.2  yamt 	if (kfw->ucode == NULL) {
   2207  1.37.2.2  yamt 		error = ENOMEM;
   2208  1.37.2.2  yamt 		goto fail2;
   2209  1.37.2.2  yamt 	}
   2210  1.37.2.2  yamt 
   2211  1.37.2.2  yamt 	kfw->main = malloc(kfw->main_size, M_DEVBUF, M_NOWAIT);
   2212  1.37.2.2  yamt 	if (kfw->main == NULL) {
   2213  1.37.2.2  yamt 		error = ENOMEM;
   2214  1.37.2.2  yamt 		goto fail3;
   2215  1.37.2.2  yamt 	}
   2216  1.37.2.2  yamt 
   2217  1.37.2.2  yamt 	if ((error = copyin(ufw.boot, kfw->boot, kfw->boot_size)) != 0)
   2218  1.37.2.2  yamt 		goto fail4;
   2219  1.37.2.2  yamt 
   2220  1.37.2.2  yamt 	if ((error = copyin(ufw.ucode, kfw->ucode, kfw->ucode_size)) != 0)
   2221  1.37.2.2  yamt 		goto fail4;
   2222  1.37.2.2  yamt 
   2223  1.37.2.2  yamt 	if ((error = copyin(ufw.main, kfw->main, kfw->main_size)) != 0)
   2224  1.37.2.2  yamt 		goto fail4;
   2225  1.37.2.2  yamt 
   2226  1.37.2.2  yamt 	DPRINTF(("Firmware cached: boot %u, ucode %u, main %u\n",
   2227  1.37.2.2  yamt 	    kfw->boot_size, kfw->ucode_size, kfw->main_size));
   2228  1.37.2.2  yamt 
   2229  1.37.2.2  yamt 	sc->flags |= IWI_FLAG_FW_CACHED;
   2230  1.37.2.2  yamt 
   2231  1.37.2.2  yamt 	return 0;
   2232  1.37.2.2  yamt 
   2233  1.37.2.2  yamt fail4:	free(kfw->boot, M_DEVBUF);
   2234  1.37.2.2  yamt fail3:	free(kfw->ucode, M_DEVBUF);
   2235  1.37.2.2  yamt fail2:	free(kfw->main, M_DEVBUF);
   2236  1.37.2.2  yamt fail1:
   2237  1.37.2.2  yamt 	return error;
   2238  1.37.2.2  yamt }
   2239  1.37.2.2  yamt 
   2240  1.37.2.2  yamt static void
   2241  1.37.2.2  yamt iwi_free_firmware(struct iwi_softc *sc)
   2242  1.37.2.2  yamt {
   2243  1.37.2.2  yamt 	if (!(sc->flags & IWI_FLAG_FW_CACHED))
   2244  1.37.2.2  yamt 		return;
   2245  1.37.2.2  yamt 
   2246  1.37.2.2  yamt 	free(sc->fw.boot, M_DEVBUF);
   2247  1.37.2.2  yamt 	free(sc->fw.ucode, M_DEVBUF);
   2248  1.37.2.2  yamt 	free(sc->fw.main, M_DEVBUF);
   2249  1.37.2.2  yamt 
   2250  1.37.2.2  yamt 	sc->flags &= ~IWI_FLAG_FW_CACHED;
   2251  1.37.2.2  yamt }
   2252  1.37.2.2  yamt 
   2253  1.37.2.2  yamt static int
   2254  1.37.2.2  yamt iwi_config(struct iwi_softc *sc)
   2255  1.37.2.2  yamt {
   2256  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   2257  1.37.2.2  yamt 	struct ifnet *ifp = &sc->sc_if;
   2258  1.37.2.2  yamt 	struct iwi_configuration config;
   2259  1.37.2.2  yamt 	struct iwi_rateset rs;
   2260  1.37.2.2  yamt 	struct iwi_txpower power;
   2261  1.37.2.2  yamt 	struct ieee80211_key *wk;
   2262  1.37.2.2  yamt 	struct iwi_wep_key wepkey;
   2263  1.37.2.2  yamt 	uint32_t data;
   2264  1.37.2.2  yamt 	int error, i;
   2265  1.37.2.2  yamt 
   2266  1.37.2.2  yamt 	IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
   2267  1.37.2.2  yamt 	DPRINTF(("Setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr)));
   2268  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_myaddr,
   2269  1.37.2.2  yamt 	    IEEE80211_ADDR_LEN, 0);
   2270  1.37.2.2  yamt 	if (error != 0)
   2271  1.37.2.2  yamt 		return error;
   2272  1.37.2.2  yamt 
   2273  1.37.2.2  yamt 	memset(&config, 0, sizeof config);
   2274  1.37.2.2  yamt 	config.bluetooth_coexistence = sc->bluetooth;
   2275  1.37.2.2  yamt 	config.antenna = sc->antenna;
   2276  1.37.2.2  yamt 	config.multicast_enabled = 1;
   2277  1.37.2.2  yamt 	config.answer_pbreq = (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
   2278  1.37.2.2  yamt 	config.disable_unicast_decryption = 1;
   2279  1.37.2.2  yamt 	config.disable_multicast_decryption = 1;
   2280  1.37.2.2  yamt 	DPRINTF(("Configuring adapter\n"));
   2281  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_CONFIGURATION, &config, sizeof config,
   2282  1.37.2.2  yamt 	    0);
   2283  1.37.2.2  yamt 	if (error != 0)
   2284  1.37.2.2  yamt 		return error;
   2285  1.37.2.2  yamt 
   2286  1.37.2.2  yamt 	data = htole32(IWI_POWER_MODE_CAM);
   2287  1.37.2.2  yamt 	DPRINTF(("Setting power mode to %u\n", le32toh(data)));
   2288  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_POWER_MODE, &data, sizeof data, 0);
   2289  1.37.2.2  yamt 	if (error != 0)
   2290  1.37.2.2  yamt 		return error;
   2291  1.37.2.2  yamt 
   2292  1.37.2.2  yamt 	data = htole32(ic->ic_rtsthreshold);
   2293  1.37.2.2  yamt 	DPRINTF(("Setting RTS threshold to %u\n", le32toh(data)));
   2294  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_RTS_THRESHOLD, &data, sizeof data, 0);
   2295  1.37.2.2  yamt 	if (error != 0)
   2296  1.37.2.2  yamt 		return error;
   2297  1.37.2.2  yamt 
   2298  1.37.2.2  yamt 	data = htole32(ic->ic_fragthreshold);
   2299  1.37.2.2  yamt 	DPRINTF(("Setting fragmentation threshold to %u\n", le32toh(data)));
   2300  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_FRAG_THRESHOLD, &data, sizeof data, 0);
   2301  1.37.2.2  yamt 	if (error != 0)
   2302  1.37.2.2  yamt 		return error;
   2303  1.37.2.2  yamt 
   2304  1.37.2.2  yamt 	if (ic->ic_opmode == IEEE80211_M_IBSS) {
   2305  1.37.2.2  yamt 		power.mode = IWI_MODE_11B;
   2306  1.37.2.2  yamt 		power.nchan = 11;
   2307  1.37.2.2  yamt 		for (i = 0; i < 11; i++) {
   2308  1.37.2.2  yamt 			power.chan[i].chan = i + 1;
   2309  1.37.2.2  yamt 			power.chan[i].power = IWI_TXPOWER_MAX;
   2310  1.37.2.2  yamt 		}
   2311  1.37.2.2  yamt 		DPRINTF(("Setting .11b channels tx power\n"));
   2312  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power,
   2313  1.37.2.2  yamt 		    0);
   2314  1.37.2.2  yamt 		if (error != 0)
   2315  1.37.2.2  yamt 			return error;
   2316  1.37.2.2  yamt 
   2317  1.37.2.2  yamt 		power.mode = IWI_MODE_11G;
   2318  1.37.2.2  yamt 		DPRINTF(("Setting .11g channels tx power\n"));
   2319  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power,
   2320  1.37.2.2  yamt 		    0);
   2321  1.37.2.2  yamt 		if (error != 0)
   2322  1.37.2.2  yamt 			return error;
   2323  1.37.2.2  yamt 	}
   2324  1.37.2.2  yamt 
   2325  1.37.2.2  yamt 	rs.mode = IWI_MODE_11G;
   2326  1.37.2.2  yamt 	rs.type = IWI_RATESET_TYPE_SUPPORTED;
   2327  1.37.2.2  yamt 	rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates;
   2328  1.37.2.2  yamt 	memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11G].rs_rates,
   2329  1.37.2.2  yamt 	    rs.nrates);
   2330  1.37.2.2  yamt 	DPRINTF(("Setting .11bg supported rates (%u)\n", rs.nrates));
   2331  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
   2332  1.37.2.2  yamt 	if (error != 0)
   2333  1.37.2.2  yamt 		return error;
   2334  1.37.2.2  yamt 
   2335  1.37.2.2  yamt 	rs.mode = IWI_MODE_11A;
   2336  1.37.2.2  yamt 	rs.type = IWI_RATESET_TYPE_SUPPORTED;
   2337  1.37.2.2  yamt 	rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates;
   2338  1.37.2.2  yamt 	memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11A].rs_rates,
   2339  1.37.2.2  yamt 	    rs.nrates);
   2340  1.37.2.2  yamt 	DPRINTF(("Setting .11a supported rates (%u)\n", rs.nrates));
   2341  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
   2342  1.37.2.2  yamt 	if (error != 0)
   2343  1.37.2.2  yamt 		return error;
   2344  1.37.2.2  yamt 
   2345  1.37.2.2  yamt 	/* if we have a desired ESSID, set it now */
   2346  1.37.2.2  yamt 	if (ic->ic_des_esslen != 0) {
   2347  1.37.2.2  yamt #ifdef IWI_DEBUG
   2348  1.37.2.2  yamt 		if (iwi_debug > 0) {
   2349  1.37.2.2  yamt 			printf("Setting desired ESSID to ");
   2350  1.37.2.2  yamt 			ieee80211_print_essid(ic->ic_des_essid,
   2351  1.37.2.2  yamt 			    ic->ic_des_esslen);
   2352  1.37.2.2  yamt 			printf("\n");
   2353  1.37.2.2  yamt 		}
   2354  1.37.2.2  yamt #endif
   2355  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_essid,
   2356  1.37.2.2  yamt 		    ic->ic_des_esslen, 0);
   2357  1.37.2.2  yamt 		if (error != 0)
   2358  1.37.2.2  yamt 			return error;
   2359  1.37.2.2  yamt 	}
   2360  1.37.2.2  yamt 
   2361  1.37.2.2  yamt 	data = htole32(arc4random());
   2362  1.37.2.2  yamt 	DPRINTF(("Setting initialization vector to %u\n", le32toh(data)));
   2363  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data, 0);
   2364  1.37.2.2  yamt 	if (error != 0)
   2365  1.37.2.2  yamt 		return error;
   2366  1.37.2.2  yamt 
   2367  1.37.2.2  yamt 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
   2368  1.37.2.2  yamt 		wk = &ic->ic_crypto.cs_nw_keys[i];
   2369  1.37.2.2  yamt 
   2370  1.37.2.2  yamt 		wepkey.cmd = IWI_WEP_KEY_CMD_SETKEY;
   2371  1.37.2.2  yamt 		wepkey.idx = i;
   2372  1.37.2.2  yamt 		wepkey.len = wk->wk_keylen;
   2373  1.37.2.2  yamt 		memset(wepkey.key, 0, sizeof wepkey.key);
   2374  1.37.2.2  yamt 		memcpy(wepkey.key, wk->wk_key, wk->wk_keylen);
   2375  1.37.2.2  yamt 		DPRINTF(("Setting wep key index %u len %u\n",
   2376  1.37.2.2  yamt 		    wepkey.idx, wepkey.len));
   2377  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_WEP_KEY, &wepkey,
   2378  1.37.2.2  yamt 		    sizeof wepkey, 0);
   2379  1.37.2.2  yamt 		if (error != 0)
   2380  1.37.2.2  yamt 			return error;
   2381  1.37.2.2  yamt 	}
   2382  1.37.2.2  yamt 
   2383  1.37.2.2  yamt 	/* Enable adapter */
   2384  1.37.2.2  yamt 	DPRINTF(("Enabling adapter\n"));
   2385  1.37.2.2  yamt 	return iwi_cmd(sc, IWI_CMD_ENABLE, NULL, 0, 0);
   2386  1.37.2.2  yamt }
   2387  1.37.2.2  yamt 
   2388  1.37.2.2  yamt static int
   2389  1.37.2.2  yamt iwi_set_chan(struct iwi_softc *sc, struct ieee80211_channel *chan)
   2390  1.37.2.2  yamt {
   2391  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   2392  1.37.2.2  yamt 	struct iwi_scan_v2 scan;
   2393  1.37.2.2  yamt 
   2394  1.37.2.2  yamt 	(void)memset(&scan, 0, sizeof scan);
   2395  1.37.2.2  yamt 
   2396  1.37.2.2  yamt 	scan.dwelltime[IWI_SCAN_TYPE_PASSIVE] = htole16(2000);
   2397  1.37.2.2  yamt 	scan.channels[0] = 1 |
   2398  1.37.2.2  yamt 	    (IEEE80211_IS_CHAN_5GHZ(chan) ? IWI_CHAN_5GHZ : IWI_CHAN_2GHZ);
   2399  1.37.2.2  yamt 	scan.channels[1] = ieee80211_chan2ieee(ic, chan);
   2400  1.37.2.2  yamt 	iwi_scan_type_set(scan, 1, IWI_SCAN_TYPE_PASSIVE);
   2401  1.37.2.2  yamt 
   2402  1.37.2.2  yamt 	DPRINTF(("Setting channel to %u\n", ieee80211_chan2ieee(ic, chan)));
   2403  1.37.2.2  yamt 	return iwi_cmd(sc, IWI_CMD_SCAN_V2, &scan, sizeof scan, 1);
   2404  1.37.2.2  yamt }
   2405  1.37.2.2  yamt 
   2406  1.37.2.2  yamt static int
   2407  1.37.2.2  yamt iwi_scan(struct iwi_softc *sc)
   2408  1.37.2.2  yamt {
   2409  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   2410  1.37.2.2  yamt 	struct iwi_scan_v2 scan;
   2411  1.37.2.2  yamt 	uint32_t type;
   2412  1.37.2.2  yamt 	uint8_t *p;
   2413  1.37.2.2  yamt 	int i, count, idx;
   2414  1.37.2.2  yamt 
   2415  1.37.2.2  yamt 	(void)memset(&scan, 0, sizeof scan);
   2416  1.37.2.2  yamt 	scan.dwelltime[IWI_SCAN_TYPE_ACTIVE_BROADCAST] =
   2417  1.37.2.2  yamt 	    htole16(sc->dwelltime);
   2418  1.37.2.2  yamt 	scan.dwelltime[IWI_SCAN_TYPE_ACTIVE_BDIRECT] =
   2419  1.37.2.2  yamt 	    htole16(sc->dwelltime);
   2420  1.37.2.2  yamt 
   2421  1.37.2.2  yamt 	/* tell the firmware about the desired essid */
   2422  1.37.2.2  yamt 	if (ic->ic_des_esslen) {
   2423  1.37.2.2  yamt 		int error;
   2424  1.37.2.2  yamt 
   2425  1.37.2.2  yamt 		DPRINTF(("%s: Setting adapter desired ESSID to %s\n",
   2426  1.37.2.2  yamt 		    __func__, ic->ic_des_essid));
   2427  1.37.2.2  yamt 
   2428  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_ESSID,
   2429  1.37.2.2  yamt 		    ic->ic_des_essid, ic->ic_des_esslen, 1);
   2430  1.37.2.2  yamt 		if (error)
   2431  1.37.2.2  yamt 			return error;
   2432  1.37.2.2  yamt 
   2433  1.37.2.2  yamt 		type = IWI_SCAN_TYPE_ACTIVE_BDIRECT;
   2434  1.37.2.2  yamt 	} else {
   2435  1.37.2.2  yamt 		type = IWI_SCAN_TYPE_ACTIVE_BROADCAST;
   2436  1.37.2.2  yamt 	}
   2437  1.37.2.2  yamt 
   2438  1.37.2.2  yamt 	p = &scan.channels[0];
   2439  1.37.2.2  yamt 	count = idx = 0;
   2440  1.37.2.2  yamt 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
   2441  1.37.2.2  yamt 		if (IEEE80211_IS_CHAN_5GHZ(&ic->ic_channels[i]) &&
   2442  1.37.2.2  yamt 		    isset(ic->ic_chan_active, i)) {
   2443  1.37.2.2  yamt 			*++p = i;
   2444  1.37.2.2  yamt 			count++;
   2445  1.37.2.2  yamt 			idx++;
   2446  1.37.2.2  yamt  			iwi_scan_type_set(scan, idx, type);
   2447  1.37.2.2  yamt 		}
   2448  1.37.2.2  yamt 	}
   2449  1.37.2.2  yamt 	if (count) {
   2450  1.37.2.2  yamt 		*(p - count) = IWI_CHAN_5GHZ | count;
   2451  1.37.2.2  yamt 		p++;
   2452  1.37.2.2  yamt 	}
   2453  1.37.2.2  yamt 
   2454  1.37.2.2  yamt 	count = 0;
   2455  1.37.2.2  yamt 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
   2456  1.37.2.2  yamt 		if (IEEE80211_IS_CHAN_2GHZ(&ic->ic_channels[i]) &&
   2457  1.37.2.2  yamt 		    isset(ic->ic_chan_active, i)) {
   2458  1.37.2.2  yamt 			*++p = i;
   2459  1.37.2.2  yamt 			count++;
   2460  1.37.2.2  yamt 			idx++;
   2461  1.37.2.2  yamt 			iwi_scan_type_set(scan, idx, type);
   2462  1.37.2.2  yamt 		}
   2463  1.37.2.2  yamt 	}
   2464  1.37.2.2  yamt 	*(p - count) = IWI_CHAN_2GHZ | count;
   2465  1.37.2.2  yamt 
   2466  1.37.2.2  yamt 	DPRINTF(("Start scanning\n"));
   2467  1.37.2.2  yamt 	return iwi_cmd(sc, IWI_CMD_SCAN_V2, &scan, sizeof scan, 1);
   2468  1.37.2.2  yamt }
   2469  1.37.2.2  yamt 
   2470  1.37.2.2  yamt static int
   2471  1.37.2.2  yamt iwi_auth_and_assoc(struct iwi_softc *sc)
   2472  1.37.2.2  yamt {
   2473  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   2474  1.37.2.2  yamt 	struct ieee80211_node *ni = ic->ic_bss;
   2475  1.37.2.2  yamt 	struct ifnet *ifp = &sc->sc_if;
   2476  1.37.2.2  yamt 	struct ieee80211_wme_info wme;
   2477  1.37.2.2  yamt 	struct iwi_configuration config;
   2478  1.37.2.2  yamt 	struct iwi_associate assoc;
   2479  1.37.2.2  yamt 	struct iwi_rateset rs;
   2480  1.37.2.2  yamt 	uint16_t capinfo;
   2481  1.37.2.2  yamt 	uint32_t data;
   2482  1.37.2.2  yamt 	int error;
   2483  1.37.2.2  yamt 
   2484  1.37.2.2  yamt 	if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
   2485  1.37.2.2  yamt 		memset(&config, 0, sizeof config);
   2486  1.37.2.2  yamt 		config.bluetooth_coexistence = sc->bluetooth;
   2487  1.37.2.2  yamt 		config.antenna = sc->antenna;
   2488  1.37.2.2  yamt 		config.multicast_enabled = 1;
   2489  1.37.2.2  yamt 		config.use_protection = 1;
   2490  1.37.2.2  yamt 		config.answer_pbreq =
   2491  1.37.2.2  yamt 		    (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
   2492  1.37.2.2  yamt 		config.disable_unicast_decryption = 1;
   2493  1.37.2.2  yamt 		config.disable_multicast_decryption = 1;
   2494  1.37.2.2  yamt 		DPRINTF(("Configuring adapter\n"));
   2495  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_CONFIGURATION, &config,
   2496  1.37.2.2  yamt 		    sizeof config, 1);
   2497  1.37.2.2  yamt 		if (error != 0)
   2498  1.37.2.2  yamt 			return error;
   2499  1.37.2.2  yamt 	}
   2500  1.37.2.2  yamt 
   2501  1.37.2.2  yamt #ifdef IWI_DEBUG
   2502  1.37.2.2  yamt 	if (iwi_debug > 0) {
   2503  1.37.2.2  yamt 		printf("Setting ESSID to ");
   2504  1.37.2.2  yamt 		ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
   2505  1.37.2.2  yamt 		printf("\n");
   2506  1.37.2.2  yamt 	}
   2507  1.37.2.2  yamt #endif
   2508  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen, 1);
   2509  1.37.2.2  yamt 	if (error != 0)
   2510  1.37.2.2  yamt 		return error;
   2511  1.37.2.2  yamt 
   2512  1.37.2.2  yamt 	/* the rate set has already been "negotiated" */
   2513  1.37.2.2  yamt 	rs.mode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IWI_MODE_11A :
   2514  1.37.2.2  yamt 	    IWI_MODE_11G;
   2515  1.37.2.2  yamt 	rs.type = IWI_RATESET_TYPE_NEGOTIATED;
   2516  1.37.2.2  yamt 	rs.nrates = ni->ni_rates.rs_nrates;
   2517  1.37.2.2  yamt 	memcpy(rs.rates, ni->ni_rates.rs_rates, rs.nrates);
   2518  1.37.2.2  yamt 	DPRINTF(("Setting negotiated rates (%u)\n", rs.nrates));
   2519  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 1);
   2520  1.37.2.2  yamt 	if (error != 0)
   2521  1.37.2.2  yamt 		return error;
   2522  1.37.2.2  yamt 
   2523  1.37.2.2  yamt 	if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) {
   2524  1.37.2.2  yamt 		wme.wme_id = IEEE80211_ELEMID_VENDOR;
   2525  1.37.2.2  yamt 		wme.wme_len = sizeof (struct ieee80211_wme_info) - 2;
   2526  1.37.2.2  yamt 		wme.wme_oui[0] = 0x00;
   2527  1.37.2.2  yamt 		wme.wme_oui[1] = 0x50;
   2528  1.37.2.2  yamt 		wme.wme_oui[2] = 0xf2;
   2529  1.37.2.2  yamt 		wme.wme_type = WME_OUI_TYPE;
   2530  1.37.2.2  yamt 		wme.wme_subtype = WME_INFO_OUI_SUBTYPE;
   2531  1.37.2.2  yamt 		wme.wme_version = WME_VERSION;
   2532  1.37.2.2  yamt 		wme.wme_info = 0;
   2533  1.37.2.2  yamt 
   2534  1.37.2.2  yamt 		DPRINTF(("Setting WME IE (len=%u)\n", wme.wme_len));
   2535  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_WMEIE, &wme, sizeof wme, 1);
   2536  1.37.2.2  yamt 		if (error != 0)
   2537  1.37.2.2  yamt 			return error;
   2538  1.37.2.2  yamt 	}
   2539  1.37.2.2  yamt 
   2540  1.37.2.2  yamt 	if (ic->ic_opt_ie != NULL) {
   2541  1.37.2.2  yamt 		DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len));
   2542  1.37.2.2  yamt 		error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie,
   2543  1.37.2.2  yamt 		    ic->ic_opt_ie_len, 1);
   2544  1.37.2.2  yamt 		if (error != 0)
   2545  1.37.2.2  yamt 			return error;
   2546  1.37.2.2  yamt 	}
   2547  1.37.2.2  yamt 	data = htole32(ni->ni_rssi);
   2548  1.37.2.2  yamt 	DPRINTF(("Setting sensitivity to %d\n", (int8_t)ni->ni_rssi));
   2549  1.37.2.2  yamt 	error = iwi_cmd(sc, IWI_CMD_SET_SENSITIVITY, &data, sizeof data, 1);
   2550  1.37.2.2  yamt 	if (error != 0)
   2551  1.37.2.2  yamt 		return error;
   2552  1.37.2.2  yamt 
   2553  1.37.2.2  yamt 	memset(&assoc, 0, sizeof assoc);
   2554  1.37.2.2  yamt 	assoc.mode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IWI_MODE_11A :
   2555  1.37.2.2  yamt 	    IWI_MODE_11G;
   2556  1.37.2.2  yamt 	assoc.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
   2557  1.37.2.2  yamt 	if (ni->ni_authmode == IEEE80211_AUTH_SHARED)
   2558  1.37.2.2  yamt 		assoc.auth = (ic->ic_crypto.cs_def_txkey << 4) | IWI_AUTH_SHARED;
   2559  1.37.2.2  yamt 	if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
   2560  1.37.2.2  yamt 		assoc.policy |= htole16(IWI_POLICY_WME);
   2561  1.37.2.2  yamt 	if (ic->ic_opt_ie != NULL)
   2562  1.37.2.2  yamt 		assoc.policy |= htole16(IWI_POLICY_WPA);
   2563  1.37.2.2  yamt 	memcpy(assoc.tstamp, ni->ni_tstamp.data, 8);
   2564  1.37.2.2  yamt 
   2565  1.37.2.2  yamt 	if (ic->ic_opmode == IEEE80211_M_IBSS)
   2566  1.37.2.2  yamt 		capinfo = IEEE80211_CAPINFO_IBSS;
   2567  1.37.2.2  yamt 	else
   2568  1.37.2.2  yamt 		capinfo = IEEE80211_CAPINFO_ESS;
   2569  1.37.2.2  yamt 	if (ic->ic_flags & IEEE80211_F_PRIVACY)
   2570  1.37.2.2  yamt 		capinfo |= IEEE80211_CAPINFO_PRIVACY;
   2571  1.37.2.2  yamt 	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
   2572  1.37.2.2  yamt 	    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
   2573  1.37.2.2  yamt 		capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
   2574  1.37.2.2  yamt 	if (ic->ic_flags & IEEE80211_F_SHSLOT)
   2575  1.37.2.2  yamt 		capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
   2576  1.37.2.2  yamt 	assoc.capinfo = htole16(capinfo);
   2577  1.37.2.2  yamt 
   2578  1.37.2.2  yamt 	assoc.lintval = htole16(ic->ic_lintval);
   2579  1.37.2.2  yamt 	assoc.intval = htole16(ni->ni_intval);
   2580  1.37.2.2  yamt 	IEEE80211_ADDR_COPY(assoc.bssid, ni->ni_bssid);
   2581  1.37.2.2  yamt 	if (ic->ic_opmode == IEEE80211_M_IBSS)
   2582  1.37.2.2  yamt 		IEEE80211_ADDR_COPY(assoc.dst, ifp->if_broadcastaddr);
   2583  1.37.2.2  yamt 	else
   2584  1.37.2.2  yamt 		IEEE80211_ADDR_COPY(assoc.dst, ni->ni_bssid);
   2585  1.37.2.2  yamt 	DPRINTF(("Trying to associate to %s channel %u auth %u\n",
   2586  1.37.2.2  yamt 	    ether_sprintf(assoc.bssid), assoc.chan, assoc.auth));
   2587  1.37.2.2  yamt 	return iwi_cmd(sc, IWI_CMD_ASSOCIATE, &assoc, sizeof assoc, 1);
   2588  1.37.2.2  yamt }
   2589  1.37.2.2  yamt 
   2590  1.37.2.2  yamt static int
   2591  1.37.2.2  yamt iwi_init(struct ifnet *ifp)
   2592  1.37.2.2  yamt {
   2593  1.37.2.2  yamt 	struct iwi_softc *sc = ifp->if_softc;
   2594  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   2595  1.37.2.2  yamt 	struct iwi_firmware *fw = &sc->fw;
   2596  1.37.2.2  yamt 	int i, error;
   2597  1.37.2.2  yamt 
   2598  1.37.2.2  yamt 	/* exit immediately if firmware has not been ioctl'd */
   2599  1.37.2.2  yamt 	if (!(sc->flags & IWI_FLAG_FW_CACHED)) {
   2600  1.37.2.2  yamt 		if (!(sc->flags & IWI_FLAG_FW_WARNED))
   2601  1.37.2.2  yamt 			aprint_error("%s: Firmware not loaded\n",
   2602  1.37.2.2  yamt 			    sc->sc_dev.dv_xname);
   2603  1.37.2.2  yamt 		sc->flags |= IWI_FLAG_FW_WARNED;
   2604  1.37.2.2  yamt 		ifp->if_flags &= ~IFF_UP;
   2605  1.37.2.2  yamt 		return EIO;
   2606  1.37.2.2  yamt 	}
   2607  1.37.2.2  yamt 
   2608  1.37.2.2  yamt 	iwi_stop(ifp, 0);
   2609  1.37.2.2  yamt 
   2610  1.37.2.2  yamt 	if ((error = iwi_reset(sc)) != 0) {
   2611  1.37.2.2  yamt 		aprint_error("%s: could not reset adapter\n",
   2612  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2613  1.37.2.2  yamt 		goto fail;
   2614  1.37.2.2  yamt 	}
   2615  1.37.2.2  yamt 
   2616  1.37.2.2  yamt 	if ((error = iwi_load_firmware(sc, fw->boot, fw->boot_size)) != 0) {
   2617  1.37.2.2  yamt 		aprint_error("%s: could not load boot firmware\n",
   2618  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2619  1.37.2.2  yamt 		goto fail;
   2620  1.37.2.2  yamt 	}
   2621  1.37.2.2  yamt 
   2622  1.37.2.2  yamt 	if ((error = iwi_load_ucode(sc, fw->ucode, fw->ucode_size)) != 0) {
   2623  1.37.2.2  yamt 		aprint_error("%s: could not load microcode\n",
   2624  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2625  1.37.2.2  yamt 		goto fail;
   2626  1.37.2.2  yamt 	}
   2627  1.37.2.2  yamt 
   2628  1.37.2.2  yamt 	iwi_stop_master(sc);
   2629  1.37.2.2  yamt 
   2630  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_CMD_BASE, sc->cmdq.desc_map->dm_segs[0].ds_addr);
   2631  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, sc->cmdq.count);
   2632  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
   2633  1.37.2.2  yamt 
   2634  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq[0].desc_map->dm_segs[0].ds_addr);
   2635  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq[0].count);
   2636  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq[0].cur);
   2637  1.37.2.2  yamt 
   2638  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq[1].desc_map->dm_segs[0].ds_addr);
   2639  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq[1].count);
   2640  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq[1].cur);
   2641  1.37.2.2  yamt 
   2642  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq[2].desc_map->dm_segs[0].ds_addr);
   2643  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq[2].count);
   2644  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq[2].cur);
   2645  1.37.2.2  yamt 
   2646  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq[3].desc_map->dm_segs[0].ds_addr);
   2647  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq[3].count);
   2648  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq[3].cur);
   2649  1.37.2.2  yamt 
   2650  1.37.2.2  yamt 	for (i = 0; i < sc->rxq.count; i++)
   2651  1.37.2.2  yamt 		CSR_WRITE_4(sc, IWI_CSR_RX_BASE + i * 4,
   2652  1.37.2.2  yamt 		    sc->rxq.data[i].map->dm_segs[0].ds_addr);
   2653  1.37.2.2  yamt 
   2654  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, sc->rxq.count -1);
   2655  1.37.2.2  yamt 
   2656  1.37.2.2  yamt 	if ((error = iwi_load_firmware(sc, fw->main, fw->main_size)) != 0) {
   2657  1.37.2.2  yamt 		aprint_error("%s: could not load main firmware\n",
   2658  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2659  1.37.2.2  yamt 		goto fail;
   2660  1.37.2.2  yamt 	}
   2661  1.37.2.2  yamt 
   2662  1.37.2.2  yamt 	sc->flags |= IWI_FLAG_FW_INITED;
   2663  1.37.2.2  yamt 
   2664  1.37.2.2  yamt 	if ((error = iwi_config(sc)) != 0) {
   2665  1.37.2.2  yamt 		aprint_error("%s: device configuration failed\n",
   2666  1.37.2.2  yamt 		    sc->sc_dev.dv_xname);
   2667  1.37.2.2  yamt 		goto fail;
   2668  1.37.2.2  yamt 	}
   2669  1.37.2.2  yamt 
   2670  1.37.2.2  yamt 	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
   2671  1.37.2.2  yamt 		if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
   2672  1.37.2.2  yamt 			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   2673  1.37.2.2  yamt 	} else
   2674  1.37.2.2  yamt 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   2675  1.37.2.2  yamt 
   2676  1.37.2.2  yamt 	ifp->if_flags &= ~IFF_OACTIVE;
   2677  1.37.2.2  yamt 	ifp->if_flags |= IFF_RUNNING;
   2678  1.37.2.2  yamt 
   2679  1.37.2.2  yamt 	return 0;
   2680  1.37.2.2  yamt 
   2681  1.37.2.2  yamt fail:	ifp->if_flags &= ~IFF_UP;
   2682  1.37.2.2  yamt 	iwi_stop(ifp, 0);
   2683  1.37.2.2  yamt 
   2684  1.37.2.2  yamt 	return error;
   2685  1.37.2.2  yamt }
   2686  1.37.2.2  yamt 
   2687  1.37.2.2  yamt static void
   2688  1.37.2.2  yamt iwi_stop(struct ifnet *ifp, int disable)
   2689  1.37.2.2  yamt {
   2690  1.37.2.2  yamt 	struct iwi_softc *sc = ifp->if_softc;
   2691  1.37.2.2  yamt 	struct ieee80211com *ic = &sc->sc_ic;
   2692  1.37.2.2  yamt 
   2693  1.37.2.2  yamt 	iwi_stop_master(sc);
   2694  1.37.2.2  yamt 	CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SW_RESET);
   2695  1.37.2.2  yamt 
   2696  1.37.2.2  yamt 	/* reset rings */
   2697  1.37.2.2  yamt 	iwi_reset_cmd_ring(sc, &sc->cmdq);
   2698  1.37.2.2  yamt 	iwi_reset_tx_ring(sc, &sc->txq[0]);
   2699  1.37.2.2  yamt 	iwi_reset_tx_ring(sc, &sc->txq[1]);
   2700  1.37.2.2  yamt 	iwi_reset_tx_ring(sc, &sc->txq[2]);
   2701  1.37.2.2  yamt 	iwi_reset_tx_ring(sc, &sc->txq[3]);
   2702  1.37.2.2  yamt 	iwi_reset_rx_ring(sc, &sc->rxq);
   2703  1.37.2.2  yamt 
   2704  1.37.2.2  yamt 	ifp->if_timer = 0;
   2705  1.37.2.2  yamt 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   2706  1.37.2.2  yamt 
   2707  1.37.2.2  yamt 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   2708  1.37.2.2  yamt }
   2709  1.37.2.2  yamt 
   2710  1.37.2.2  yamt static void
   2711  1.37.2.2  yamt iwi_error_log(struct iwi_softc *sc)
   2712  1.37.2.2  yamt {
   2713  1.37.2.2  yamt 	uint32_t b, n;
   2714  1.37.2.2  yamt 	int i;
   2715  1.37.2.2  yamt 
   2716  1.37.2.2  yamt 	static const char *const msg[] = {
   2717  1.37.2.2  yamt 		"no error",
   2718  1.37.2.2  yamt 		"failed",
   2719  1.37.2.2  yamt 		"memory range low",
   2720  1.37.2.2  yamt 		"memory range high",
   2721  1.37.2.2  yamt 		"bad parameter",
   2722  1.37.2.2  yamt 		"checksum",
   2723  1.37.2.2  yamt 		"NMI",
   2724  1.37.2.2  yamt 		"bad database",
   2725  1.37.2.2  yamt 		"allocation failed",
   2726  1.37.2.2  yamt 		"DMA underrun",
   2727  1.37.2.2  yamt 		"DMA status",
   2728  1.37.2.2  yamt 		"DINO",
   2729  1.37.2.2  yamt 		"EEPROM",
   2730  1.37.2.2  yamt 		"device assert",
   2731  1.37.2.2  yamt 		"fatal"
   2732  1.37.2.2  yamt 	};
   2733  1.37.2.2  yamt 
   2734  1.37.2.2  yamt 	b = CSR_READ_4(sc, IWI_CSR_ERRORLOG);
   2735  1.37.2.2  yamt 	n = MEM_READ_4(sc, b);
   2736  1.37.2.2  yamt 
   2737  1.37.2.2  yamt 	b += 4;
   2738  1.37.2.2  yamt 
   2739  1.37.2.2  yamt 	for (i = 0; i < n ; i++) {
   2740  1.37.2.2  yamt 		struct iwi_error fw_error;
   2741  1.37.2.2  yamt 
   2742  1.37.2.2  yamt 		MEM_CPY(sc, &fw_error, b, sizeof(fw_error));
   2743  1.37.2.2  yamt 
   2744  1.37.2.2  yamt 		printf("%s: %s\n", sc->sc_dev.dv_xname,
   2745  1.37.2.2  yamt 		    msg[fw_error.type]);
   2746  1.37.2.2  yamt 
   2747  1.37.2.2  yamt 		b += sizeof(fw_error);
   2748  1.37.2.2  yamt 	}
   2749  1.37.2.2  yamt }
   2750