PERFORCE change 96271 for review

Marcel Moolenaar marcel at FreeBSD.org
Thu Apr 27 23:48:53 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=96271

Change 96271 by marcel at marcel_nfs on 2006/04/27 23:48:45

	IFC @96270

Affected files ...

.. //depot/projects/uart/amd64/amd64/pmap.c#35 integrate
.. //depot/projects/uart/conf/files.i386#26 integrate
.. //depot/projects/uart/ddb/db_ps.c#9 integrate
.. //depot/projects/uart/dev/bfe/if_bfe.c#11 integrate
.. //depot/projects/uart/dev/iwi/if_iwi.c#8 integrate
.. //depot/projects/uart/dev/iwi/if_iwireg.h#6 integrate
.. //depot/projects/uart/dev/iwi/if_iwivar.h#6 integrate
.. //depot/projects/uart/dev/pccard/pccard.c#15 integrate
.. //depot/projects/uart/dev/rr232x/LICENSE#1 branch
.. //depot/projects/uart/dev/rr232x/README#1 branch
.. //depot/projects/uart/dev/rr232x/amd64-elf.rr232x_lib.o.uu#1 branch
.. //depot/projects/uart/dev/rr232x/array.h#1 branch
.. //depot/projects/uart/dev/rr232x/him.h#1 branch
.. //depot/projects/uart/dev/rr232x/himfuncs.h#1 branch
.. //depot/projects/uart/dev/rr232x/hptintf.h#1 branch
.. //depot/projects/uart/dev/rr232x/i386-elf.rr232x_lib.o.uu#1 branch
.. //depot/projects/uart/dev/rr232x/ldm.h#1 branch
.. //depot/projects/uart/dev/rr232x/list.h#1 branch
.. //depot/projects/uart/dev/rr232x/os_bsd.c#1 branch
.. //depot/projects/uart/dev/rr232x/os_bsd.h#1 branch
.. //depot/projects/uart/dev/rr232x/osm.h#1 branch
.. //depot/projects/uart/dev/rr232x/osm_bsd.c#1 branch
.. //depot/projects/uart/dev/rr232x/rr232x_config.c#1 branch
.. //depot/projects/uart/dev/rr232x/rr232x_config.h#1 branch
.. //depot/projects/uart/dev/sk/if_sk.c#4 integrate
.. //depot/projects/uart/dev/sk/if_skreg.h#2 integrate
.. //depot/projects/uart/dev/sk/xmaciireg.h#2 integrate
.. //depot/projects/uart/dev/sk/yukonreg.h#2 integrate
.. //depot/projects/uart/dev/uart/uart_bus_pci.c#19 integrate
.. //depot/projects/uart/dev/usb/usbdevs#22 integrate
.. //depot/projects/uart/i386/conf/GENERIC#17 integrate
.. //depot/projects/uart/i386/conf/NOTES#18 integrate
.. //depot/projects/uart/i386/i386/pmap.c#36 integrate
.. //depot/projects/uart/kern/sched_4bsd.c#11 integrate
.. //depot/projects/uart/modules/Makefile#32 integrate
.. //depot/projects/uart/modules/rr232x/Makefile#1 branch
.. //depot/projects/uart/sparc64/conf/GENERIC#19 integrate

Differences ...

==== //depot/projects/uart/amd64/amd64/pmap.c#35 (text+ko) ====

@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.550 2006/04/26 21:34:07 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.551 2006/04/27 21:26:25 alc Exp $");
 
 /*
  *	Manages physical address maps.
@@ -2061,6 +2061,7 @@
 	   boolean_t wired)
 {
 	vm_paddr_t pa;
+	pd_entry_t *pde;
 	register pt_entry_t *pte;
 	vm_paddr_t opa;
 	pt_entry_t origpte, newpte;
@@ -2098,7 +2099,13 @@
 	}
 #endif
 
-	pte = pmap_pte(pmap, va);
+	pde = pmap_pde(pmap, va);
+	if (pde != NULL) {
+		if ((*pde & PG_PS) != 0)
+			panic("pmap_enter: attempted pmap_enter on 2MB page");
+		pte = pmap_pde_to_pte(pde, va);
+	} else
+		pte = NULL;
 
 	/*
 	 * Page Directory table entry not valid, we need a new PT page
@@ -2111,9 +2118,6 @@
 	origpte = *pte;
 	opa = origpte & PG_FRAME;
 
-	if (origpte & PG_PS)
-		panic("pmap_enter: attempted pmap_enter on 2MB page");
-
 	/*
 	 * Mapping has not changed, must be protection or wiring change.
 	 */

==== //depot/projects/uart/conf/files.i386#26 (text+ko) ====

@@ -1,7 +1,7 @@
 # This file tells config what files go into building a kernel,
 # files marked standard are always included.
 #
-# $FreeBSD: src/sys/conf/files.i386,v 1.555 2006/04/24 23:31:50 marcel Exp $
+# $FreeBSD: src/sys/conf/files.i386,v 1.556 2006/04/27 20:22:44 scottl Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -77,6 +77,11 @@
 	compile-with	"uudecode < $S/dev/hptmv/i386-elf.raid.o.uu" \
 	no-implicit-rule
 #
+rr232x_lib.o			optional	rr232x			\
+	dependency	"$S/dev/rr232x/i386-elf.rr232x_lib.o.uu"	\
+	compile-with	"uudecode < $S/dev/rr232x/i386-elf.rr232x_lib.o.uu" \
+	no-implicit-rule
+#
 #
 compat/linux/linux_file.c	optional compat_linux
 compat/linux/linux_getcwd.c	optional compat_linux
@@ -194,6 +199,9 @@
 dev/nve/if_nve.c		optional nve pci
 dev/pcf/pcf_isa.c		optional pcf
 dev/random/nehemiah.c		optional random
+dev/rr232x/os_bsd.c		optional rr232x
+dev/rr232x/osm_bsd.c		optional rr232x
+dev/rr232x/rr232x_config.c	optional rr232x
 dev/sbni/if_sbni.c		optional sbni
 dev/sbni/if_sbni_isa.c		optional sbni isa
 dev/sbni/if_sbni_pci.c		optional sbni pci

==== //depot/projects/uart/ddb/db_ps.c#9 (text+ko) ====

@@ -28,18 +28,16 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_ps.c,v 1.56 2006/04/25 20:34:04 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_ps.c,v 1.59 2006/04/27 22:09:18 jhb Exp $");
 
 #include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/cons.h>
 #include <sys/jail.h>
 #include <sys/kdb.h>
 #include <sys/linker_set.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/sysent.h>
-#include <sys/cons.h>
+#include <sys/systm.h>
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
@@ -91,7 +89,6 @@
 	np = nprocs;
 	quit = 0;
 
-	/* sx_slock(&allproc_lock); */
 	if (!LIST_EMPTY(&allproc))
 		p = LIST_FIRST(&allproc);
 	else
@@ -108,7 +105,6 @@
 			db_printf("oops, ran out of processes early!\n");
 			break;
 		}
-		/* PROC_LOCK(p); */
 		pp = p->p_pptr;
 		if (pp == NULL)
 			pp = p;
@@ -120,7 +116,7 @@
 		    pgrp != NULL ? pgrp->pg_id : 0);
 
 		/* Determine our primary process state. */
-		switch(p->p_state) {
+		switch (p->p_state) {
 		case PRS_NORMAL:
 			if (P_SHOULDSTOP(p))
 				state[0] = 'T';
@@ -209,13 +205,11 @@
 			if (quit)
 				break;
 		}
-		/* PROC_UNLOCK(p); */
 
 		p = LIST_NEXT(p, p_list);
 		if (p == NULL && np > 0)
 			p = LIST_FIRST(&zombproc);
     	}
-	/* sx_sunlock(&allproc_lock); */
 }
 
 static void

==== //depot/projects/uart/dev/bfe/if_bfe.c#11 (text+ko) ====

@@ -26,7 +26,7 @@
 
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/bfe/if_bfe.c,v 1.32 2006/04/04 22:30:12 pjd Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/bfe/if_bfe.c,v 1.34 2006/04/27 23:03:00 scottl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -197,22 +197,25 @@
 
 	sc = device_get_softc(dev);
 
-	/* parent tag */
+	/*
+	 * parent tag.  Apparently the chip cannot handle any DMA address
+	 * greater than 1GB.
+	 */
 	error = bus_dma_tag_create(NULL,  /* parent */
 			PAGE_SIZE, 0,             /* alignment, boundary */
-			BUS_SPACE_MAXADDR,        /* lowaddr */
-			BUS_SPACE_MAXADDR_32BIT,  /* highaddr */
+			0x40000000,               /* lowaddr */
+			BUS_SPACE_MAXADDR,        /* highaddr */
 			NULL, NULL,               /* filter, filterarg */
 			MAXBSIZE,                 /* maxsize */
 			BUS_SPACE_UNRESTRICTED,   /* num of segments */
 			BUS_SPACE_MAXSIZE_32BIT,  /* max segment size */
-			BUS_DMA_ALLOCNOW,         /* flags */
+			0,                        /* flags */
 			NULL, NULL,               /* lockfunc, lockarg */
 			&sc->bfe_parent_tag);
 
 	/* tag for TX ring */
 	error = bus_dma_tag_create(sc->bfe_parent_tag,
-			BFE_TX_LIST_SIZE, BFE_TX_LIST_SIZE,
+			1, 0,
 			BUS_SPACE_MAXADDR,
 			BUS_SPACE_MAXADDR,
 			NULL, NULL,
@@ -230,7 +233,7 @@
 
 	/* tag for RX ring */
 	error = bus_dma_tag_create(sc->bfe_parent_tag,
-			BFE_RX_LIST_SIZE, BFE_RX_LIST_SIZE,
+			1, 0,
 			BUS_SPACE_MAXADDR,
 			BUS_SPACE_MAXADDR,
 			NULL, NULL,
@@ -255,7 +258,7 @@
 			MCLBYTES,
 			1,
 			BUS_SPACE_MAXSIZE_32BIT,
-			0,
+			BUS_DMA_ALLOCNOW,
 			NULL, NULL,
 			&sc->bfe_tag);
 

==== //depot/projects/uart/dev/iwi/if_iwi.c#8 (text+ko) ====

@@ -1,8 +1,7 @@
-/*	$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.34 2006/03/12 18:54:40 damien Exp $	*/
-
 /*-
- * Copyright (c) 2004-2006
+ * Copyright (c) 2004, 2005
  *      Damien Bergamini <damien.bergamini at free.fr>. All rights reserved.
+ * Copyright (c) 2005-2006 Sam Leffler, Errno Consulting
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.34 2006/03/12 18:54:40 damien Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.35 2006/04/27 21:43:37 mlaier Exp $");
 
 /*-
  * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
@@ -43,13 +42,16 @@
 #include <sys/socket.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
-#include <sys/queue.h>
-#include <sys/taskqueue.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/endian.h>
+#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/namei.h>
 #include <sys/linker.h>
 #include <sys/firmware.h>
+#include <sys/kthread.h>
+#include <sys/taskqueue.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -76,9 +78,10 @@
 #include <netinet/ip.h>
 #include <netinet/if_ether.h>
 
+#include <dev/iwi/if_iwireg.h>
 #include <dev/iwi/if_iwivar.h>
-#include <dev/iwi/if_iwireg.h>
 
+#define IWI_DEBUG
 #ifdef IWI_DEBUG
 #define DPRINTF(x)	do { if (iwi_debug > 0) printf x; } while (0)
 #define DPRINTFN(n, x)	do { if (iwi_debug >= (n)) printf x; } while (0)
@@ -93,6 +96,12 @@
 MODULE_DEPEND(iwi, wlan, 1, 1, 1);
 MODULE_DEPEND(iwi, firmware, 1, 1, 1);
 
+enum {
+	IWI_LED_TX,
+	IWI_LED_RX,
+	IWI_LED_POLL,
+};
+
 struct iwi_ident {
 	uint16_t	vendor;
 	uint16_t	device;
@@ -126,17 +135,18 @@
 static int	iwi_media_change(struct ifnet *);
 static void	iwi_media_status(struct ifnet *, struct ifmediareq *);
 static int	iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
+static void	iwi_wme_init(struct iwi_softc *);
+static void	iwi_wme_setparams(void *, int);
 static int	iwi_wme_update(struct ieee80211com *);
 static uint16_t	iwi_read_prom_word(struct iwi_softc *, uint8_t);
-static void	iwi_fix_channel(struct ieee80211com *, struct mbuf *);
 static void	iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
 		    struct iwi_frame *);
 static void	iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
 static void	iwi_rx_intr(struct iwi_softc *);
 static void	iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
 static void	iwi_intr(void *);
-static int	iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int);
-static void	iwi_write_ibssnode(struct iwi_softc *, const struct iwi_node *);
+static int	iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t);
+static void	iwi_write_ibssnode(struct iwi_softc *, const u_int8_t [], int);
 static int	iwi_tx_start(struct ifnet *, struct mbuf *,
 		    struct ieee80211_node *, int);
 static void	iwi_start(struct ifnet *);
@@ -144,17 +154,28 @@
 static int	iwi_ioctl(struct ifnet *, u_long, caddr_t);
 static void	iwi_stop_master(struct iwi_softc *);
 static int	iwi_reset(struct iwi_softc *);
-static int	iwi_load_ucode(struct iwi_softc *, const char *, int);
-static int	iwi_load_firmware(struct iwi_softc *, const char *, int);
+static int	iwi_load_ucode(struct iwi_softc *, const struct iwi_fw *);
+static int	iwi_load_firmware(struct iwi_softc *, const struct iwi_fw *);
 static int	iwi_config(struct iwi_softc *);
-static int	iwi_set_chan(struct iwi_softc *, struct ieee80211_channel *);
-static int	iwi_scan(struct iwi_softc *);
+static int	iwi_get_firmware(struct iwi_softc *);
+static void	iwi_put_firmware(struct iwi_softc *);
+static void	iwi_scanabort(void *, int);
+static void	iwi_scandone(void *, int);
+static void	iwi_scanstart(void *, int);
+static void	iwi_scanchan(void *, int);
 static int	iwi_auth_and_assoc(struct iwi_softc *);
-static void	iwi_init_task(void *, int);
+static int	iwi_disassociate(struct iwi_softc *, int quiet);
+static void	iwi_down(void *, int);
 static void	iwi_init(void *);
+static void	iwi_init_locked(void *, int);
 static void	iwi_stop(void *);
-static int	iwi_sysctl_stats(SYSCTL_HANDLER_ARGS);
-static int	iwi_sysctl_radio(SYSCTL_HANDLER_ARGS);
+static void	iwi_restart(void *, int);
+static int	iwi_getrfkill(struct iwi_softc *);
+static void	iwi_radio_on(void *, int);
+static void	iwi_radio_off(void *, int);
+static void	iwi_sysctlattach(struct iwi_softc *);
+static void	iwi_led_event(struct iwi_softc *, int);
+static void	iwi_ledattach(struct iwi_softc *);
 
 static int iwi_probe(device_t);
 static int iwi_attach(device_t);
@@ -197,6 +218,20 @@
 static const struct ieee80211_rateset iwi_rateset_11g =
 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
 
+static __inline uint8_t
+MEM_READ_1(struct iwi_softc *sc, uint32_t addr)
+{
+	CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
+	return CSR_READ_1(sc, IWI_CSR_INDIRECT_DATA);
+}
+
+static __inline uint32_t
+MEM_READ_4(struct iwi_softc *sc, uint32_t addr)
+{
+	CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
+	return CSR_READ_4(sc, IWI_CSR_INDIRECT_DATA);
+}
+
 static int
 iwi_probe(device_t dev)
 {
@@ -227,11 +262,30 @@
 	sc->sc_dev = dev;
 
 	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
-	    MTX_DEF | MTX_RECURSE);
+	    MTX_DEF);
 
-	sc->sc_unr = new_unrhdr(0, IWI_MAX_IBSSNODE, &sc->sc_mtx);
+	sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx);
 
-	TASK_INIT(&sc->sc_init_task, 0, iwi_init_task, sc);
+#if __FreeBSD_version >= 700000
+	sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT,
+		taskqueue_thread_enqueue, &sc->sc_tq);
+	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
+		device_get_nameunit(dev));
+#else
+	sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT,
+		taskqueue_thread_enqueue, &sc->sc_tq, &sc->sc_tqproc);
+	kthread_create(taskqueue_thread_loop, &sc->sc_tq, &sc->sc_tqproc,
+		0, 0, "%s taskq", device_get_nameunit(dev));
+#endif
+	TASK_INIT(&sc->sc_radiontask, 0, iwi_radio_on, sc);
+	TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc);
+	TASK_INIT(&sc->sc_scanstarttask, 0, iwi_scanstart, sc);
+	TASK_INIT(&sc->sc_scanaborttask, 0, iwi_scanabort, sc);
+	TASK_INIT(&sc->sc_scandonetask, 0, iwi_scandone, sc);
+	TASK_INIT(&sc->sc_scantask, 0, iwi_scanchan, sc);
+	TASK_INIT(&sc->sc_setwmetask, 0, iwi_wme_setparams, sc);
+	TASK_INIT(&sc->sc_downtask, 0, iwi_down, sc);
+	TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc);
 
 	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
 		device_printf(dev, "chip is in D%d power mode "
@@ -309,6 +363,8 @@
 		goto fail;
 	}
 
+	iwi_wme_init(sc);
+
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		device_printf(dev, "can not if_alloc()\n");
@@ -335,7 +391,7 @@
 	ic->ic_caps =
 	    IEEE80211_C_IBSS |		/* IBSS mode supported */
 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
-	    IEEE80211_C_TXPMGT |	/* tx power management */
+	    IEEE80211_C_PMGT |		/* power save supported */
 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
 	    IEEE80211_C_WPA |		/* 802.11i */
 	    IEEE80211_C_WME;		/* 802.11e */
@@ -392,47 +448,19 @@
 	ieee80211_media_init(ic, iwi_media_change, iwi_media_status);
 
 	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
-	    sizeof (struct ieee80211_frame) + 64, &sc->sc_drvbpf);
+	    sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap),
+	    &sc->sc_drvbpf);
 
-	sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
+	sc->sc_rxtap_len = sizeof sc->sc_rxtap;
 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
 	sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT);
 
-	sc->sc_txtap_len = sizeof sc->sc_txtapu;
+	sc->sc_txtap_len = sizeof sc->sc_txtap;
 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
 	sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
 
-	/*
-	 * Add a few sysctl knobs.
-	 */
-	sc->dwelltime = 100;
-	sc->bluetooth = 1;
-	sc->antenna = 2;
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "radio",
-	    CTLTYPE_INT | CTLFLAG_RD, sc, 0, iwi_sysctl_radio, "I",
-	    "radio transmitter switch state (0=off, 1=on)");
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats",
-	    CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, iwi_sysctl_stats, "S",
-	    "statistics");
-
-	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell",
-	    CTLFLAG_RW, &sc->dwelltime, 0,
-	    "channel dwell time (ms) for AP/station scanning");
-
-	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
-	    "bluetooth", CTLFLAG_RW, &sc->bluetooth, 0,
-	    "bluetooth coexistence");
-
-	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "antenna",
-	    CTLFLAG_RW, &sc->antenna, 0,
-	    "antenna (0=auto,1=A,3=B,2=diversity)");
+	iwi_sysctlattach(sc);
+	iwi_ledattach(sc);
 
 	/*
 	 * Hook our interrupt after all initialization is complete.
@@ -461,6 +489,7 @@
 	struct ifnet *ifp = ic->ic_ifp;
 
 	iwi_stop(sc);
+	iwi_put_firmware(sc);
 
 	if (ifp != NULL) {
 		bpfdetach(ifp);
@@ -485,6 +514,8 @@
 	if (ifp != NULL)
 		if_free(ifp);
 
+	taskqueue_free(sc->sc_tq);
+
 	if (sc->sc_unr != NULL)
 		delete_unrhdr(sc->sc_unr);
 
@@ -605,7 +636,7 @@
 	}
 
 	error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
-	    BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWI_MAX_NSEG - 2,
+	    BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWI_MAX_NSEG,
 	    MCLBYTES, 0, NULL, NULL, &ring->data_dmat);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "could not create data DMA tag\n");
@@ -795,6 +826,7 @@
 	struct iwi_softc *sc = device_get_softc(dev);
 
 	iwi_stop(sc);
+	iwi_put_firmware(sc);		/* ??? XXX */
 
 	return 0;
 }
@@ -814,8 +846,9 @@
 {
 	struct iwi_softc *sc = device_get_softc(dev);
 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
+	IWI_LOCK_DECL;
 
-	mtx_lock(&sc->sc_mtx);
+	IWI_LOCK(sc);
 
 	pci_write_config(dev, 0x41, 0, 1);
 
@@ -825,7 +858,7 @@
 			ifp->if_start(ifp);
 	}
 
-	mtx_unlock(&sc->sc_mtx);
+	IWI_UNLOCK(sc);
 
 	return 0;
 }
@@ -851,8 +884,11 @@
 	struct iwi_softc *sc = ic->ic_ifp->if_softc;
 	struct iwi_node *in = (struct iwi_node *)ni;
 
-	if (in->in_station != -1)
+	if (in->in_station != -1) {
+		DPRINTF(("%s mac %6D station %u\n", __func__,
+		    ni->ni_macaddr, ":", in->in_station));
 		free_unr(sc->sc_unr, in->in_station);
+	}
 
 	sc->sc_node_free(ni);
 }
@@ -862,20 +898,40 @@
 {
 	struct iwi_softc *sc = ifp->if_softc;
 	int error;
+	IWI_LOCK_DECL;
 
-	mtx_lock(&sc->sc_mtx);
+	IWI_LOCK(sc);
 
 	error = ieee80211_media_change(ifp);
-	if (error != ENETRESET) {
-		mtx_unlock(&sc->sc_mtx);
-		return error;
-	}
+	if (error == ENETRESET &&
+	    (ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
+		iwi_init_locked(sc, 0);
 
-	if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
-		iwi_init(sc);
+	IWI_UNLOCK(sc);
 
-	mtx_unlock(&sc->sc_mtx);
+	return error;
+}
 
+/* 
+ * Convert h/w rate code to IEEE rate code.
+ */
+static int
+iwi_cvtrate(int iwirate)
+{
+	switch (iwirate) {
+	case IWI_RATE_DS1:	return 2;
+	case IWI_RATE_DS2:	return 4;
+	case IWI_RATE_DS5:	return 11;
+	case IWI_RATE_DS11:	return 22;
+	case IWI_RATE_OFDM6:	return 12;
+	case IWI_RATE_OFDM9:	return 18;
+	case IWI_RATE_OFDM12:	return 24;
+	case IWI_RATE_OFDM18:	return 36;
+	case IWI_RATE_OFDM24:	return 48;
+	case IWI_RATE_OFDM36:	return 72;
+	case IWI_RATE_OFDM48:	return 96;
+	case IWI_RATE_OFDM54:	return 108;
+	}
 	return 0;
 }
 
@@ -888,26 +944,7 @@
 {
 	struct iwi_softc *sc = ifp->if_softc;
 	struct ieee80211com *ic = &sc->sc_ic;
-#define N(a)	(sizeof (a) / sizeof (a[0]))
-	static const struct {
-		uint32_t	val;
-		int		rate;
-	} rates[] = {
-		{ IWI_RATE_DS1,      2 },
-		{ IWI_RATE_DS2,      4 },
-		{ IWI_RATE_DS5,     11 },
-		{ IWI_RATE_DS11,    22 },
-		{ IWI_RATE_OFDM6,   12 },
-		{ IWI_RATE_OFDM9,   18 },
-		{ IWI_RATE_OFDM12,  24 },
-		{ IWI_RATE_OFDM18,  36 },
-		{ IWI_RATE_OFDM24,  48 },
-		{ IWI_RATE_OFDM36,  72 },
-		{ IWI_RATE_OFDM48,  96 },
-		{ IWI_RATE_OFDM54, 108 },
-	};
-	uint32_t val;
-	int rate, i;
+	int rate;
 
 	imr->ifm_status = IFM_AVALID;
 	imr->ifm_active = IFM_IEEE80211;
@@ -915,31 +952,13 @@
 		imr->ifm_status |= IFM_ACTIVE;
 
 	/* read current transmission rate from adapter */
-	val = CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE);
-
-	/* convert rate to 802.11 rate */
-	for (i = 0; i < N(rates) && rates[i].val != val; i++);
-	rate = (i < N(rates)) ? rates[i].rate : 0;
-
+	rate = iwi_cvtrate(CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE));
 	imr->ifm_active |= ieee80211_rate2media(ic, rate, ic->ic_curmode);
-	switch (ic->ic_opmode) {
-	case IEEE80211_M_STA:
-		break;
 
-	case IEEE80211_M_IBSS:
+	if (ic->ic_opmode == IEEE80211_M_IBSS)
 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
-		break;
-
-	case IEEE80211_M_MONITOR:
+	else if (ic->ic_opmode == IEEE80211_M_MONITOR)
 		imr->ifm_active |= IFM_IEEE80211_MONITOR;
-		break;
-
-	case IEEE80211_M_AHDEMO:
-	case IEEE80211_M_HOSTAP:
-		/* should not get there */
-		break;
-	}
-#undef N
 }
 
 static int
@@ -947,20 +966,31 @@
 {
 	struct ifnet *ifp = ic->ic_ifp;
 	struct iwi_softc *sc = ifp->if_softc;
-	enum ieee80211_state ostate;
-	uint32_t tmp;
 
-	ostate = ic->ic_state;
+	DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
+		ieee80211_state_name[ic->ic_state],
+		ieee80211_state_name[nstate], sc->flags));
 
+	/* XXX state change race with taskqueue */
 	switch (nstate) {
 	case IEEE80211_S_SCAN:
-		if (sc->flags & IWI_FLAG_SCANNING)
+		if (ic->ic_state == IEEE80211_S_RUN) {
+			/*
+			 * Beacon miss, send disassoc and wait for a reply
+			 * from the card; we'll start a scan then.  Note
+			 * this only happens with auto roaming; otherwise
+			 * just notify users and wait to be directed.
+			 */
+			/* notify directly as we bypass net80211 */
+			ieee80211_sta_leave(ic, ic->ic_bss);
+			if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
+				taskqueue_enqueue(sc->sc_tq, &sc->sc_downtask);
 			break;
-
-		ieee80211_node_table_reset(&ic->ic_scan);
-		ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
-		sc->flags |= IWI_FLAG_SCANNING;
-		iwi_scan(sc);
+		}
+		if ((sc->flags & IWI_FLAG_SCANNING) == 0) {
+			sc->flags |= IWI_FLAG_SCANNING;
+			taskqueue_enqueue(sc->sc_tq, &sc->sc_scanstarttask);
+		}
 		break;
 
 	case IEEE80211_S_AUTH:
@@ -968,15 +998,21 @@
 		break;
 
 	case IEEE80211_S_RUN:
-		if (ic->ic_opmode == IEEE80211_M_IBSS)
-			iwi_auth_and_assoc(sc);
-		else if (ic->ic_opmode == IEEE80211_M_MONITOR)
-			iwi_set_chan(sc, ic->ic_ibss_chan);
+		if (ic->ic_opmode == IEEE80211_M_IBSS) {
+			/*
+			 * XXX when joining an ibss network we are called
+			 * with a SCAN -> RUN transition on scan complete.
+			 * Use that to call iwi_auth_and_assoc.  On completing
+			 * the join we are then called again with an
+			 * AUTH -> RUN transition and we want to do nothing.
+			 * This is all totally bogus and needs to be redone.
+			 */
+			if (ic->ic_state == IEEE80211_S_SCAN)
+				iwi_auth_and_assoc(sc);
+		} else if (ic->ic_opmode == IEEE80211_M_MONITOR)
+			taskqueue_enqueue(sc->sc_tq, &sc->sc_scantask);
 
-		/* assoc led on */
-		tmp = MEM_READ_4(sc, IWI_MEM_EVENT_CTL) & IWI_LED_MASK;
-		MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, tmp | IWI_LED_ASSOC);
-
+		/* XXX way wrong */
 		return sc->sc_newstate(ic, nstate,
 		    IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
 
@@ -984,19 +1020,17 @@
 		break;
 
 	case IEEE80211_S_INIT:
-		sc->flags &= ~IWI_FLAG_SCANNING;
-
-		if (ostate != IEEE80211_S_RUN)
-			break;
-
-		/* assoc led off */
-		tmp = MEM_READ_4(sc, IWI_MEM_EVENT_CTL) & IWI_LED_MASK;
-		MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, tmp & ~IWI_LED_ASSOC);
+		/*
+		 * NB: don't try to do this if iwi_stop_master has
+		 *     shutdown the firmware and disabled interrupts.
+		 */
+		if (ic->ic_state == IEEE80211_S_RUN &&
+		    (sc->flags & IWI_FLAG_FW_INITED))
+			taskqueue_enqueue(sc->sc_tq, &sc->sc_downtask);
 		break;
 	}
 
 	ic->ic_state = nstate;
-
 	return 0;
 }
 
@@ -1018,54 +1052,105 @@
 	{ 0, 2, 3,  4,  94 },	/* WME_AC_VI */
 	{ 0, 2, 2,  3,  47 }	/* WME_AC_VO */
 };
+#define IWI_EXP2(v)	htole16((1 << (v)) - 1)
+#define IWI_USEC(v)	htole16(IEEE80211_TXOP_TO_US(v))
 
-static int
-iwi_wme_update(struct ieee80211com *ic)
+static void
+iwi_wme_init(struct iwi_softc *sc)
 {
-#define IWI_EXP2(v)	htole16((1 << (v)) - 1)
-#define IWI_USEC(v)	htole16(IEEE80211_TXOP_TO_US(v))
-	struct iwi_softc *sc = ic->ic_ifp->if_softc;
-	struct iwi_wme_params wme[3];
 	const struct wmeParams *wmep;
 	int ac;
 
-	/*
-	 * We shall not override firmware default WME values if WME is not
-	 * actually enabled.
-	 */
-	if (!(ic->ic_flags & IEEE80211_F_WME))
-		return 0;
-
+	memset(sc->wme, 0, sizeof sc->wme);
 	for (ac = 0; ac < WME_NUM_AC; ac++) {
-		/* set WME values for current operating mode */
-		wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
-		wme[0].aifsn[ac] = wmep->wmep_aifsn;
-		wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
-		wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
-		wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
-		wme[0].acm[ac]   = wmep->wmep_acm;
-
 		/* set WME values for CCK modulation */
 		wmep = &iwi_wme_cck_params[ac];
-		wme[1].aifsn[ac] = wmep->wmep_aifsn;
-		wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
-		wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
-		wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
-		wme[1].acm[ac]   = wmep->wmep_acm;
+		sc->wme[1].aifsn[ac] = wmep->wmep_aifsn;
+		sc->wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+		sc->wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+		sc->wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+		sc->wme[1].acm[ac]   = wmep->wmep_acm;
 
 		/* set WME values for OFDM modulation */
 		wmep = &iwi_wme_ofdm_params[ac];
-		wme[2].aifsn[ac] = wmep->wmep_aifsn;
-		wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
-		wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
-		wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
-		wme[2].acm[ac]   = wmep->wmep_acm;
+		sc->wme[2].aifsn[ac] = wmep->wmep_aifsn;
+		sc->wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+		sc->wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+		sc->wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+		sc->wme[2].acm[ac]   = wmep->wmep_acm;
+	}
+}
+
+static int
+iwi_wme_setparams_locked(struct iwi_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	const struct wmeParams *wmep;
+	int ac;
+
+	for (ac = 0; ac < WME_NUM_AC; ac++) {
+		/* set WME values for current operating mode */
+		wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
+		sc->wme[0].aifsn[ac] = wmep->wmep_aifsn;
+		sc->wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+		sc->wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+		sc->wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+		sc->wme[0].acm[ac]   = wmep->wmep_acm;
 	}
 
 	DPRINTF(("Setting WME parameters\n"));
-	return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, wme, sizeof wme, 1);
+	return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, sc->wme, sizeof sc->wme);
+}
+
+static void
+iwi_wme_setparams(void *arg, int npending)
+{
+	struct iwi_softc *sc = arg;
+	IWI_LOCK_DECL;
+
+	IWI_LOCK(sc);
+	(void) iwi_wme_setparams_locked(sc);
+	IWI_UNLOCK(sc);
+}
 #undef IWI_USEC
 #undef IWI_EXP2
+
+static int
+iwi_wme_update(struct ieee80211com *ic)
+{
+	struct iwi_softc *sc = ic->ic_ifp->if_softc;
+
+	/*
+	 * We may be called to update the WME parameters in
+	 * the adapter at various places.  If we're already
+	 * associated then initiate the request immediately
+	 * (via the taskqueue); otherwise we assume the params
+	 * will get sent down to the adapter as part of the
+	 * work iwi_auth_and_assoc does.
+	 */
+	if (ic->ic_state == IEEE80211_S_RUN)
+		taskqueue_enqueue(sc->sc_tq, &sc->sc_setwmetask);
+	return 0;
+}
+
+static int
+iwi_wme_setie(struct iwi_softc *sc)
+{
+	struct ieee80211_wme_info wme;
+
+	memset(&wme, 0, sizeof wme);
+	wme.wme_id = IEEE80211_ELEMID_VENDOR;
+	wme.wme_len = sizeof (struct ieee80211_wme_info) - 2;
+	wme.wme_oui[0] = 0x00;
+	wme.wme_oui[1] = 0x50;
+	wme.wme_oui[2] = 0xf2;
+	wme.wme_type = WME_OUI_TYPE;
+	wme.wme_subtype = WME_INFO_OUI_SUBTYPE;
+	wme.wme_version = WME_VERSION;
+	wme.wme_info = 0;
+
+	DPRINTF(("Setting WME IE (len=%u)\n", wme.wme_len));
+	return iwi_cmd(sc, IWI_CMD_SET_WMEIE, &wme, sizeof wme);
 }
 
 /*
@@ -1123,41 +1208,18 @@
 	return val;
 }
 
-/*
- * XXX: Hack to set the current channel to the value advertised in beacons or
- * probe responses. Only used during AP detection.
- */
 static void
-iwi_fix_channel(struct ieee80211com *ic, struct mbuf *m)
+iwi_setcurchan(struct iwi_softc *sc, int chan)
 {
-	struct ieee80211_frame *wh;
-	uint8_t subtype;
-	uint8_t *frm, *efrm;
+	struct ieee80211com *ic = &sc->sc_ic;
 
-	wh = mtod(m, struct ieee80211_frame *);
+	ic->ic_curchan = &ic->ic_channels[chan];
+	sc->curchan = chan;
 
-	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
-		return;
-
-	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
-
-	if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
-	    subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
-		return;
-
-	frm = (uint8_t *)(wh + 1);
-	efrm = mtod(m, uint8_t *) + m->m_len;
-
-	frm += 12;	/* skip tstamp, bintval and capinfo fields */
-	while (frm < efrm) {
-		if (*frm == IEEE80211_ELEMID_DSPARMS)
-#if IEEE80211_CHAN_MAX < 255
-		if (frm[2] <= IEEE80211_CHAN_MAX)
-#endif
-			ic->ic_curchan = &ic->ic_channels[frm[2]];
-
-		frm += frm[1] + 2;
-	}
+	sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
+		htole16(ic->ic_curchan->ic_freq);
+	sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
+		htole16(ic->ic_curchan->ic_flags);
 }
 
 static void
@@ -1167,16 +1229,29 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = ic->ic_ifp;
 	struct mbuf *mnew, *m;
-	struct ieee80211_frame *wh;
 	struct ieee80211_node *ni;
-	int error;
+	int type, error, framelen;
+
+	framelen = le16toh(frame->len);
+	if (framelen < IEEE80211_MIN_LEN || framelen > MCLBYTES) {
+		/*
+		 * XXX >MCLBYTES is bogus as it means the h/w dma'd
+		 *     out of bounds; need to figure out how to limit
+		 *     frame size in the firmware
+		 */
+		/* XXX stat */
+		DPRINTFN(1,
+		    ("drop rx frame len=%u chan=%u rssi=%u rssi_dbm=%u\n",
+		    le16toh(frame->len), frame->chan, frame->rssi,
+		    frame->rssi_dbm));
+		return;
+	}
 
-	DPRINTFN(5, ("received frame len=%u chan=%u rssi=%u\n",
-	    le16toh(frame->len), frame->chan, frame->rssi_dbm));
+	DPRINTFN(5, ("received frame len=%u chan=%u rssi=%u rssi_dbm=%u\n",
+	    le16toh(frame->len), frame->chan, frame->rssi, frame->rssi_dbm));
 
-	if (le16toh(frame->len) < sizeof (struct ieee80211_frame) ||
-	    le16toh(frame->len) > MCLBYTES)
-		return;
+	if (frame->chan != sc->curchan)
+		iwi_setcurchan(sc, frame->chan);

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list