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