1173362Sbenjsc/* $FreeBSD$ */ 2173362Sbenjsc 3173362Sbenjsc/*- 4173362Sbenjsc * Copyright (c) 2006,2007 5173362Sbenjsc * Damien Bergamini <damien.bergamini@free.fr> 6173362Sbenjsc * 7173362Sbenjsc * Permission to use, copy, modify, and distribute this software for any 8173362Sbenjsc * purpose with or without fee is hereby granted, provided that the above 9173362Sbenjsc * copyright notice and this permission notice appear in all copies. 10173362Sbenjsc * 11173362Sbenjsc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12173362Sbenjsc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13173362Sbenjsc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14173362Sbenjsc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15173362Sbenjsc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16173362Sbenjsc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17173362Sbenjsc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18173362Sbenjsc */ 19173362Sbenjsc#include <net80211/ieee80211_amrr.h> 20173362Sbenjsc 21173362Sbenjscstruct wpi_rx_radiotap_header { 22173362Sbenjsc struct ieee80211_radiotap_header wr_ihdr; 23173362Sbenjsc uint64_t wr_tsft; 24173362Sbenjsc uint8_t wr_flags; 25173362Sbenjsc uint8_t wr_rate; 26173362Sbenjsc uint16_t wr_chan_freq; 27173362Sbenjsc uint16_t wr_chan_flags; 28173362Sbenjsc int8_t wr_dbm_antsignal; 29173362Sbenjsc int8_t wr_dbm_antnoise; 30173362Sbenjsc uint8_t wr_antenna; 31173362Sbenjsc}; 32173362Sbenjsc 33173362Sbenjsc#define WPI_RX_RADIOTAP_PRESENT \ 34173362Sbenjsc ((1 << IEEE80211_RADIOTAP_TSFT) | \ 35173362Sbenjsc (1 << IEEE80211_RADIOTAP_FLAGS) | \ 36173362Sbenjsc (1 << IEEE80211_RADIOTAP_RATE) | \ 37173362Sbenjsc (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 38173362Sbenjsc (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 39173362Sbenjsc (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 40173362Sbenjsc (1 << IEEE80211_RADIOTAP_ANTENNA)) 41173362Sbenjsc 42173362Sbenjscstruct wpi_tx_radiotap_header { 43173362Sbenjsc struct ieee80211_radiotap_header wt_ihdr; 44173362Sbenjsc uint8_t wt_flags; 45173362Sbenjsc uint8_t wt_rate; 46173362Sbenjsc uint16_t wt_chan_freq; 47173362Sbenjsc uint16_t wt_chan_flags; 48173362Sbenjsc uint8_t wt_hwqueue; 49173362Sbenjsc}; 50173362Sbenjsc 51173362Sbenjsc#define WPI_TX_RADIOTAP_PRESENT \ 52173362Sbenjsc ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 53173362Sbenjsc (1 << IEEE80211_RADIOTAP_RATE) | \ 54173362Sbenjsc (1 << IEEE80211_RADIOTAP_CHANNEL)) 55173362Sbenjsc 56173362Sbenjscstruct wpi_dma_info { 57173362Sbenjsc bus_dma_tag_t tag; 58173362Sbenjsc bus_dmamap_t map; 59177043Sthompsa bus_addr_t paddr; /* aligned p address */ 60177043Sthompsa bus_addr_t paddr_start; /* possibly unaligned p start*/ 61177043Sthompsa caddr_t vaddr; /* aligned v address */ 62177043Sthompsa caddr_t vaddr_start; /* possibly unaligned v start */ 63173362Sbenjsc bus_size_t size; 64173362Sbenjsc}; 65173362Sbenjsc 66173362Sbenjscstruct wpi_tx_data { 67173362Sbenjsc bus_dmamap_t map; 68173362Sbenjsc struct mbuf *m; 69173362Sbenjsc struct ieee80211_node *ni; 70173362Sbenjsc}; 71173362Sbenjsc 72173362Sbenjscstruct wpi_tx_ring { 73173362Sbenjsc struct wpi_dma_info desc_dma; 74173362Sbenjsc struct wpi_dma_info cmd_dma; 75173362Sbenjsc struct wpi_tx_desc *desc; 76173362Sbenjsc struct wpi_tx_cmd *cmd; 77173362Sbenjsc struct wpi_tx_data *data; 78173362Sbenjsc bus_dma_tag_t data_dmat; 79173362Sbenjsc int qid; 80173362Sbenjsc int count; 81173362Sbenjsc int queued; 82173362Sbenjsc int cur; 83173362Sbenjsc}; 84173362Sbenjsc 85173362Sbenjsc#define WPI_RBUF_COUNT ( WPI_RX_RING_COUNT + 16 ) 86173362Sbenjsc 87173362Sbenjscstruct wpi_rx_data { 88177043Sthompsa bus_dmamap_t map; 89177043Sthompsa struct mbuf *m; 90173362Sbenjsc}; 91173362Sbenjsc 92173362Sbenjscstruct wpi_rx_ring { 93173362Sbenjsc struct wpi_dma_info desc_dma; 94173362Sbenjsc uint32_t *desc; 95173362Sbenjsc struct wpi_rx_data data[WPI_RX_RING_COUNT]; 96177043Sthompsa bus_dma_tag_t data_dmat; 97173362Sbenjsc int cur; 98173362Sbenjsc}; 99173362Sbenjsc 100173362Sbenjscstruct wpi_amrr { 101173362Sbenjsc struct ieee80211_node ni; /* must be the first */ 102173362Sbenjsc int txcnt; 103173362Sbenjsc int retrycnt; 104173362Sbenjsc int success; 105173362Sbenjsc int success_threshold; 106173362Sbenjsc int recovery; 107173362Sbenjsc}; 108173362Sbenjsc 109173362Sbenjscstruct wpi_power_sample { 110173362Sbenjsc uint8_t index; 111173362Sbenjsc int8_t power; 112173362Sbenjsc}; 113173362Sbenjsc 114173362Sbenjscstruct wpi_power_group { 115173362Sbenjsc#define WPI_SAMPLES_COUNT 5 116178354Ssam struct wpi_power_sample samples[WPI_SAMPLES_COUNT]; 117178354Ssam uint8_t chan; 118178354Ssam int8_t maxpwr; 119178354Ssam int16_t temp; 120173362Sbenjsc}; 121173362Sbenjsc 122178354Ssamstruct wpi_vap { 123178354Ssam struct ieee80211vap vap; 124178354Ssam 125178354Ssam int (*newstate)(struct ieee80211vap *, 126178354Ssam enum ieee80211_state, int); 127178354Ssam}; 128178354Ssam#define WPI_VAP(vap) ((struct wpi_vap *)(vap)) 129178354Ssam 130173362Sbenjscstruct wpi_softc { 131173362Sbenjsc device_t sc_dev; 132173362Sbenjsc struct ifnet *sc_ifp; 133173362Sbenjsc struct mtx sc_mtx; 134173362Sbenjsc 135173362Sbenjsc /* Flags indicating the current state the driver 136173362Sbenjsc * expects the hardware to be in 137173362Sbenjsc */ 138173362Sbenjsc uint32_t flags; 139173362Sbenjsc#define WPI_FLAG_HW_RADIO_OFF (1 << 0) 140191746Sthompsa#define WPI_FLAG_BUSY (1 << 1) 141191746Sthompsa#define WPI_FLAG_AUTH (1 << 2) 142173362Sbenjsc 143173362Sbenjsc /* shared area */ 144173362Sbenjsc struct wpi_dma_info shared_dma; 145173362Sbenjsc struct wpi_shared *shared; 146173362Sbenjsc 147173362Sbenjsc struct wpi_tx_ring txq[WME_NUM_AC]; 148173362Sbenjsc struct wpi_tx_ring cmdq; 149173362Sbenjsc struct wpi_rx_ring rxq; 150173362Sbenjsc 151173362Sbenjsc /* TX Thermal Callibration */ 152173362Sbenjsc struct callout calib_to; 153173362Sbenjsc int calib_cnt; 154173362Sbenjsc 155173362Sbenjsc /* Watch dog timer */ 156173362Sbenjsc struct callout watchdog_to; 157177043Sthompsa /* Hardware switch polling timer */ 158177043Sthompsa struct callout hwswitch_to; 159173362Sbenjsc 160173362Sbenjsc struct resource *irq; 161173362Sbenjsc struct resource *mem; 162173362Sbenjsc bus_space_tag_t sc_st; 163173362Sbenjsc bus_space_handle_t sc_sh; 164173362Sbenjsc void *sc_ih; 165173362Sbenjsc 166173362Sbenjsc struct wpi_config config; 167173362Sbenjsc int temp; 168173362Sbenjsc 169173362Sbenjsc 170173362Sbenjsc int sc_tx_timer; 171177043Sthompsa int sc_scan_timer; 172173362Sbenjsc 173173362Sbenjsc struct bpf_if *sc_drvbpf; 174173362Sbenjsc 175173362Sbenjsc struct wpi_rx_radiotap_header sc_rxtap; 176173362Sbenjsc struct wpi_tx_radiotap_header sc_txtap; 177173362Sbenjsc 178173362Sbenjsc /* firmware image */ 179173362Sbenjsc const struct firmware *fw_fp; 180173362Sbenjsc 181173362Sbenjsc /* firmware DMA transfer */ 182173362Sbenjsc struct wpi_dma_info fw_dma; 183173362Sbenjsc 184178354Ssam /* Tasks used by the driver */ 185178354Ssam struct task sc_restarttask; /* reset firmware task */ 186191746Sthompsa struct task sc_radiotask; /* reset rf task */ 187173362Sbenjsc 188173362Sbenjsc /* Eeprom info */ 189173362Sbenjsc uint8_t cap; 190173362Sbenjsc uint16_t rev; 191173362Sbenjsc uint8_t type; 192173362Sbenjsc struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT]; 193173362Sbenjsc int8_t maxpwr[IEEE80211_CHAN_MAX]; 194178354Ssam char domain[4]; /*reglatory domain XXX */ 195173362Sbenjsc}; 196173362Sbenjsc#define WPI_LOCK_INIT(_sc) \ 197173362Sbenjsc mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 198173362Sbenjsc MTX_NETWORK_LOCK, MTX_DEF) 199177043Sthompsa#define WPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 200177043Sthompsa#define WPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 201177043Sthompsa#define WPI_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 202177043Sthompsa#define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 203