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