/* $FreeBSD$ */ /*- * Copyright (c) 2006,2007 * Damien Bergamini * * 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. */ #if ( __FreeBSD_version > 700000 ) #include #else #include #endif /* DMA mapping */ struct wpi_mapping { int nsegs; bus_dma_segment_t segs[WPI_MAX_SCATTER]; }; struct wpi_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; uint64_t wr_tsft; uint8_t wr_flags; uint8_t wr_rate; uint16_t wr_chan_freq; uint16_t wr_chan_flags; int8_t wr_dbm_antsignal; int8_t wr_dbm_antnoise; uint8_t wr_antenna; }; #define WPI_RX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_TSFT) | \ (1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ (1 << IEEE80211_RADIOTAP_ANTENNA)) struct wpi_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; uint8_t wt_flags; uint8_t wt_rate; uint16_t wt_chan_freq; uint16_t wt_chan_flags; uint8_t wt_hwqueue; }; #define WPI_TX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL)) struct wpi_dma_info { bus_dma_tag_t tag; bus_dmamap_t map; bus_addr_t paddr; caddr_t vaddr; bus_size_t size; }; struct wpi_tx_data { bus_dmamap_t map; struct mbuf *m; struct ieee80211_node *ni; }; struct wpi_tx_ring { struct wpi_dma_info desc_dma; struct wpi_dma_info cmd_dma; struct wpi_tx_desc *desc; struct wpi_tx_cmd *cmd; struct wpi_tx_data *data; bus_dma_tag_t data_dmat; int qid; int count; int queued; int cur; }; #define WPI_RBUF_COUNT ( WPI_RX_RING_COUNT + 16 ) struct wpi_softc; struct wpi_rbuf { struct wpi_softc *sc; bus_addr_t paddr; caddr_t vaddr; SLIST_ENTRY(wpi_rbuf) next; }; struct wpi_rx_data { struct mbuf *m; }; struct wpi_rx_ring { struct wpi_dma_info desc_dma; struct wpi_dma_info buf_dma; uint32_t *desc; struct wpi_rx_data data[WPI_RX_RING_COUNT]; struct wpi_rbuf rbuf[WPI_RBUF_COUNT]; SLIST_HEAD(, wpi_rbuf) freelist; int cur; }; struct wpi_amrr { struct ieee80211_node ni; /* must be the first */ int txcnt; int retrycnt; int success; int success_threshold; int recovery; }; struct wpi_node { struct ieee80211_node ni; /* must be the first */ struct ieee80211_amrr_node amn; }; struct wpi_power_sample { uint8_t index; int8_t power; }; struct wpi_power_group { #define WPI_SAMPLES_COUNT 5 struct wpi_power_sample samples[WPI_SAMPLES_COUNT]; uint8_t chan; int8_t maxpwr; int16_t temp; }; struct wpi_softc { device_t sc_dev; struct ifnet *sc_ifp; /* net80211 driver specifics */ struct ieee80211com sc_ic; int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); unsigned long maxdwell; /* Max dwell time whilst scanning */ struct mtx sc_mtx; struct ieee80211_amrr amrr; /* Flags indicating the current state the driver * expects the hardware to be in */ uint32_t flags; #define WPI_FLAG_HW_RADIO_OFF (1 << 0) #define WPI_FLAG_SCANNING (1 << 1) #define WPI_FLAG_BUSY (1 << 2) #define WPI_FLAG_AUTH (1 << 3) /* Flags indicating the state of the firmware */ uint32_t fw_state; #define WPI_FW_IDLE (1 << 0 ) /* shared area */ struct wpi_dma_info shared_dma; struct wpi_shared *shared; struct wpi_tx_ring txq[WME_NUM_AC]; struct wpi_tx_ring cmdq; struct wpi_rx_ring rxq; /* TX Thermal Callibration */ struct callout calib_to; int calib_cnt; /* Watch dog timer */ struct callout watchdog_to; int watchdog_cnt; struct resource *irq; struct resource *mem; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; void *sc_ih; int mem_rid; int irq_rid; struct wpi_config config; int temp; int sc_tx_timer; struct bpf_if *sc_drvbpf; struct wpi_rx_radiotap_header sc_rxtap; int sc_rxtap_len; struct wpi_tx_radiotap_header sc_txtap; int sc_txtap_len; /* firmware image */ const struct firmware *fw_fp; /* firmware DMA transfer */ struct wpi_dma_info fw_dma; /* command queue related variables */ #define WPI_CMD_MAXOPS 10 #define WPI_SCAN_START (1<<0) #define WPI_SCAN_CURCHAN (1<<1) #define WPI_SCAN_STOP (1<<2) #define WPI_SET_CHAN (1<<3) #define WPI_AUTH (1<<4) #define WPI_SCAN_NEXT (1<<5) int sc_cmd[WPI_CMD_MAXOPS]; int sc_cmd_cur; /* current queued scan task */ int sc_cmd_next; /* last queued scan task */ struct mtx sc_cmdlock; /* Task queues used to control the driver */ struct taskqueue *sc_tq; /* Main command task queue */ struct taskqueue *sc_tq2;/* firmware reset task queue */ /* Tasks used by the driver */ struct task sc_radioontask; /* enable rf transmitter task*/ struct task sc_radioofftask;/* disable rf transmitter task*/ struct task sc_opstask; /* operation handling task */ struct task sc_restarttask; /* reset firmware task */ /* Eeprom info */ uint8_t cap; uint16_t rev; uint8_t type; struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT]; int8_t maxpwr[IEEE80211_CHAN_MAX]; char domain[4]; //reglatory domain //XXX }; #define WPI_LOCK_INIT(_sc) \ mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ MTX_NETWORK_LOCK, MTX_DEF) #define WPI_LOCK_DECL int __waslocked = 0 #define WPI_LOCK(_sc) do {\ if (!(__waslocked = mtx_owned(&(_sc)->sc_mtx))) \ mtx_lock(&(_sc)->sc_mtx); \ } while(0) #define WPI_UNLOCK(_sc) do { \ if (!__waslocked) \ mtx_unlock(&(_sc)->sc_mtx); \ } while (0) #define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) #define WPI_CMD_LOCK_INIT(_sc) \ mtx_init(&(_sc)->sc_cmdlock, device_get_nameunit((_sc)->sc_dev), NULL, MTX_DEF); #define WPI_CMD_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_cmdlock) #define WPI_CMD_LOCK(_sc) mtx_lock(&(_sc)->sc_cmdlock) #define WPI_CMD_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_cmdlock) #if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) #define WPI_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) #else #define WPI_LOCK_ASSERT(sc) #endif