/* $OpenBSD: pgtvar.h,v 1.9 2006/10/06 21:55:33 mglocker Exp $ */ /* * Copyright (c) 2006 Claudio Jeker * Copyright (c) 2006 Marcus Glocker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 2004 Fujitsu Laboratories of America, Inc. * Copyright (c) 2004 Brian Fundakowski Feldman * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __PGTVAR_H__ #define __PGTVAR_H__ #define PGT_RX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_RSSI)) struct pgt_rx_radiotap_hdr { struct ieee80211_radiotap_header wr_ihdr; uint8_t wr_flags; uint16_t wr_chan_freq; uint16_t wr_chan_flags; uint8_t wr_rssi; uint8_t wr_max_rssi; } __packed; #define PGT_TX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL)) struct pgt_tx_radiotap_hdr { struct ieee80211_radiotap_header wt_ihdr; uint8_t wt_flags; uint8_t wt_rate; uint16_t wt_chan_freq; uint16_t wt_chan_flags; } __packed; /* * The struct pgt_desc is used to either enqueue or dequeue pgt_frags * (packets) when either free or in flight. */ struct pgt_desc { TAILQ_ENTRY(pgt_desc) pd_link; void *pd_mem; bus_addr_t pd_dmaaddr; bus_dmamap_t pd_dmam; bus_dma_segment_t pd_dmas; struct pgt_frag *pd_fragp; unsigned int pd_fragnum; }; TAILQ_HEAD(pgt_descq, pgt_desc); /* * The struct pgt_mgmt_desc is used to enqueue a management request * and await response. */ struct pgt_mgmt_desc { TAILQ_ENTRY(pgt_mgmt_desc) pmd_link; const void *pmd_sendbuf; /* NULL = get op */ void *pmd_recvbuf; /* NULL = set op */ size_t pmd_len; uint32_t pmd_oid; int pmd_error; }; TAILQ_HEAD(pgt_mgmt_descq, pgt_mgmt_desc); /* * These events are put on the per-device kthread to be * able to trigger actions from inside the interrupt; as most * operations require waiting for another interrupt for response * (that is, management packets), this is common. */ struct pgt_async_trap { TAILQ_ENTRY(pgt_async_trap) pa_link; struct mbuf *pa_mbuf; /* followed by the rest of the mbuf data */ }; struct pgt_ieee80211_node { struct ieee80211_node pin_node; enum pin_dot1x_authorization { PIN_DOT1X_UNAUTHORIZED, PIN_DOT1X_AUTHORIZED } pin_dot1x_auth_desired, pin_dot1x_auth; uint16_t pin_mlme_state; }; struct pgt_softc { struct device sc_dev; struct ieee80211com sc_ic; unsigned int sc_flags; #define SC_NEEDS_FIRMWARE 0x00000001 /* do firmware upload on reset */ #define SC_UNINITIALIZED 0x00000002 /* still awaiting initial intr */ #define SC_DYING 0x00000004 /* going away */ #define SC_NEEDS_RESET 0x00000008 /* going to reset when refcnt = 1 */ #define SC_INTR_RESET 0x00000020 /* interrupt resets at end */ #define SC_POWERSAVE 0x00000040 /* device is asleep */ #define SC_NOFREE_ALLNODES 0x00000100 /* do not free assoc w/reinit */ #define SC_START_DESIRED 0x00000200 /* tried to start during mgmt-crit */ #define SC_KTHREAD 0x00000400 /* has a kthread around */ #define SC_ISL3877 0x00000800 /* chipset */ struct timeout sc_chanscan_timer; /* configuration sysctls */ int sc_dot1x; int sc_wds; /* cached values */ int sc_if_flags; int16_t sc_80211_ioc_wep; int16_t sc_80211_ioc_auth; uint32_t sc_noise; unsigned int sc_debug; #define SC_DEBUG_QUEUES 0x00000001 #define SC_DEBUG_MGMT 0x00000002 #define SC_DEBUG_UNEXPECTED 0x00000004 #define SC_DEBUG_TRIGGER 0x00000008 #define SC_DEBUG_EVENTS 0x00000010 #define SC_DEBUG_POWER 0x00000020 #define SC_DEBUG_TRAP 0x00000040 #define SC_DEBUG_LINK 0x00000080 #define SC_DEBUG_RXANNEX 0x00000100 #define SC_DEBUG_RXFRAG 0x00000200 #define SC_DEBUG_RXETHER 0x00000400 bus_space_tag_t sc_iotag; bus_space_handle_t sc_iohandle; bus_dma_tag_t sc_dmat; bus_dmamap_t sc_cbdmam; bus_dma_segment_t sc_cbdmas; struct pgt_control_block *sc_cb; /* DMA-mapped control block */ bus_dmamap_t sc_psmdmam; bus_dma_segment_t sc_psmdmas; void *sc_psmbuf; /* DMA-mapped psm frame area */ int (*sc_newstate) (struct ieee80211com *, enum ieee80211_state, int); int (*sc_enable)(struct pgt_softc *); void (*sc_disable)(struct pgt_softc *); void (*sc_power)(struct pgt_softc *, int); struct pgt_mgmt_descq sc_mgmtinprog; struct pgt_descq sc_freeq[PGT_QUEUE_COUNT]; size_t sc_freeq_count[PGT_QUEUE_COUNT]; struct pgt_descq sc_dirtyq[PGT_QUEUE_COUNT]; size_t sc_dirtyq_count[PGT_QUEUE_COUNT]; int sc_txtimer; struct pgt_softc_kthread { struct proc *sck_proc; // struct cv sck_needed; int sck_exit, sck_reset, sck_update; TAILQ_HEAD(, pgt_async_trap) sck_traps; } sc_kthread; #if NBPFILTER > 0 caddr_t sc_drvbpf; union { struct pgt_rx_radiotap_hdr th; uint8_t pad[64]; } sc_rxtapu; #define sc_rxtap sc_rxtapu.th int sc_rxtap_len; union { struct pgt_tx_radiotap_hdr th; uint8_t pad[64]; } sc_txtapu; #define sc_txtap sc_txtapu.th int sc_txtap_len; #endif }; int pgt_intr(void *); void pgt_attach(void *); int pgt_detach(struct pgt_softc *sc); void pgt_reboot(struct pgt_softc *); static __inline int pgt_queue_is_rx(enum pgt_queue pq) { return (pq == PGT_QUEUE_DATA_LOW_RX || pq == PGT_QUEUE_DATA_HIGH_RX || pq == PGT_QUEUE_MGMT_RX); } static __inline int pgt_queue_is_tx(enum pgt_queue pq) { return (pq == PGT_QUEUE_DATA_LOW_TX || pq == PGT_QUEUE_DATA_HIGH_TX || pq == PGT_QUEUE_MGMT_TX); } static __inline int pgt_queue_is_data(enum pgt_queue pq) { return (pq == PGT_QUEUE_DATA_LOW_RX || pq == PGT_QUEUE_DATA_HIGH_RX || pq == PGT_QUEUE_DATA_LOW_TX || pq == PGT_QUEUE_DATA_HIGH_TX); } static __inline int pgt_queue_is_mgmt(enum pgt_queue pq) { return (pq == PGT_QUEUE_MGMT_RX || pq == PGT_QUEUE_MGMT_TX); } #endif