Date: Thu, 27 Apr 2006 23:48:51 GMT From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 96271 for review Message-ID: <200604272348.k3RNmpBY089934@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=96271 Change 96271 by marcel@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@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604272348.k3RNmpBY089934>