1*c4fe7bb1SImre Vadász /* $FreeBSD: head/sys/dev/iwi/if_iwivar.h 290407 2015-11-05 17:58:18Z avos $ */ 20e474d75SJohannes Hofmann 30e474d75SJohannes Hofmann /*- 4b50e4759SMatthew Dillon * Copyright (c) 2004, 2005 50e474d75SJohannes Hofmann * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. 6b50e4759SMatthew Dillon * 7b50e4759SMatthew Dillon * Redistribution and use in source and binary forms, with or without 8b50e4759SMatthew Dillon * modification, are permitted provided that the following conditions 9b50e4759SMatthew Dillon * are met: 10b50e4759SMatthew Dillon * 1. Redistributions of source code must retain the above copyright 11b50e4759SMatthew Dillon * notice unmodified, this list of conditions, and the following 12b50e4759SMatthew Dillon * disclaimer. 13b50e4759SMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 14b50e4759SMatthew Dillon * notice, this list of conditions and the following disclaimer in the 15b50e4759SMatthew Dillon * documentation and/or other materials provided with the distribution. 16b50e4759SMatthew Dillon * 17b50e4759SMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18b50e4759SMatthew Dillon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19b50e4759SMatthew Dillon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20b50e4759SMatthew Dillon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21b50e4759SMatthew Dillon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22b50e4759SMatthew Dillon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23b50e4759SMatthew Dillon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24b50e4759SMatthew Dillon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25b50e4759SMatthew Dillon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26b50e4759SMatthew Dillon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27b50e4759SMatthew Dillon * SUCH DAMAGE. 28b50e4759SMatthew Dillon */ 29b50e4759SMatthew Dillon 30b50e4759SMatthew Dillon struct iwi_rx_radiotap_header { 31b50e4759SMatthew Dillon struct ieee80211_radiotap_header wr_ihdr; 32841ab66cSSepherosa Ziehau uint8_t wr_flags; 33841ab66cSSepherosa Ziehau uint8_t wr_rate; 34841ab66cSSepherosa Ziehau uint16_t wr_chan_freq; 35841ab66cSSepherosa Ziehau uint16_t wr_chan_flags; 360e474d75SJohannes Hofmann int8_t wr_antsignal; 370e474d75SJohannes Hofmann int8_t wr_antnoise; 38841ab66cSSepherosa Ziehau uint8_t wr_antenna; 39b50e4759SMatthew Dillon }; 40b50e4759SMatthew Dillon 41b50e4759SMatthew Dillon #define IWI_RX_RADIOTAP_PRESENT \ 42b50e4759SMatthew Dillon ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 43b50e4759SMatthew Dillon (1 << IEEE80211_RADIOTAP_RATE) | \ 44b50e4759SMatthew Dillon (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 450e474d75SJohannes Hofmann (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 460e474d75SJohannes Hofmann (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 47b50e4759SMatthew Dillon (1 << IEEE80211_RADIOTAP_ANTENNA)) 48b50e4759SMatthew Dillon 49b50e4759SMatthew Dillon struct iwi_tx_radiotap_header { 50b50e4759SMatthew Dillon struct ieee80211_radiotap_header wt_ihdr; 51841ab66cSSepherosa Ziehau uint8_t wt_flags; 52841ab66cSSepherosa Ziehau uint16_t wt_chan_freq; 53841ab66cSSepherosa Ziehau uint16_t wt_chan_flags; 54b50e4759SMatthew Dillon }; 55b50e4759SMatthew Dillon 56b50e4759SMatthew Dillon #define IWI_TX_RADIOTAP_PRESENT \ 57b50e4759SMatthew Dillon ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 58b50e4759SMatthew Dillon (1 << IEEE80211_RADIOTAP_CHANNEL)) 59b50e4759SMatthew Dillon 60841ab66cSSepherosa Ziehau struct iwi_cmd_ring { 61841ab66cSSepherosa Ziehau bus_dma_tag_t desc_dmat; 62841ab66cSSepherosa Ziehau bus_dmamap_t desc_map; 63841ab66cSSepherosa Ziehau bus_addr_t physaddr; 64841ab66cSSepherosa Ziehau struct iwi_cmd_desc *desc; 65841ab66cSSepherosa Ziehau int count; 66841ab66cSSepherosa Ziehau int queued; 67841ab66cSSepherosa Ziehau int cur; 68841ab66cSSepherosa Ziehau int next; 69841ab66cSSepherosa Ziehau }; 70b50e4759SMatthew Dillon 71841ab66cSSepherosa Ziehau struct iwi_tx_data { 72b50e4759SMatthew Dillon bus_dmamap_t map; 73b50e4759SMatthew Dillon struct mbuf *m; 74b50e4759SMatthew Dillon struct ieee80211_node *ni; 75841ab66cSSepherosa Ziehau }; 76b50e4759SMatthew Dillon 77841ab66cSSepherosa Ziehau struct iwi_tx_ring { 78841ab66cSSepherosa Ziehau bus_dma_tag_t desc_dmat; 79841ab66cSSepherosa Ziehau bus_dma_tag_t data_dmat; 80841ab66cSSepherosa Ziehau bus_dmamap_t desc_map; 81841ab66cSSepherosa Ziehau bus_addr_t physaddr; 82841ab66cSSepherosa Ziehau bus_addr_t csr_ridx; 83841ab66cSSepherosa Ziehau bus_addr_t csr_widx; 84841ab66cSSepherosa Ziehau struct iwi_tx_desc *desc; 85841ab66cSSepherosa Ziehau struct iwi_tx_data *data; 86841ab66cSSepherosa Ziehau int count; 87841ab66cSSepherosa Ziehau int queued; 88841ab66cSSepherosa Ziehau int cur; 89841ab66cSSepherosa Ziehau int next; 90841ab66cSSepherosa Ziehau }; 91b50e4759SMatthew Dillon 92841ab66cSSepherosa Ziehau struct iwi_rx_data { 93b50e4759SMatthew Dillon bus_dmamap_t map; 94b50e4759SMatthew Dillon bus_addr_t physaddr; 95841ab66cSSepherosa Ziehau uint32_t reg; 96b50e4759SMatthew Dillon struct mbuf *m; 97841ab66cSSepherosa Ziehau }; 98b50e4759SMatthew Dillon 99841ab66cSSepherosa Ziehau struct iwi_rx_ring { 100841ab66cSSepherosa Ziehau bus_dma_tag_t data_dmat; 101841ab66cSSepherosa Ziehau struct iwi_rx_data *data; 102841ab66cSSepherosa Ziehau int count; 103841ab66cSSepherosa Ziehau int cur; 104841ab66cSSepherosa Ziehau }; 105841ab66cSSepherosa Ziehau 106841ab66cSSepherosa Ziehau struct iwi_node { 107841ab66cSSepherosa Ziehau struct ieee80211_node in_node; 108841ab66cSSepherosa Ziehau int in_station; 1090e474d75SJohannes Hofmann #define IWI_MAX_IBSSNODE 32 110841ab66cSSepherosa Ziehau }; 111841ab66cSSepherosa Ziehau 1120e474d75SJohannes Hofmann struct iwi_fw { 1130e474d75SJohannes Hofmann const struct firmware *fp; /* image handle */ 1140e474d75SJohannes Hofmann const char *data; /* firmware image data */ 1150e474d75SJohannes Hofmann size_t size; /* firmware image size */ 1160e474d75SJohannes Hofmann const char *name; /* associated image name */ 1170e474d75SJohannes Hofmann }; 1180e474d75SJohannes Hofmann 1190e474d75SJohannes Hofmann struct iwi_vap { 1200e474d75SJohannes Hofmann struct ieee80211vap iwi_vap; 1210e474d75SJohannes Hofmann 1220e474d75SJohannes Hofmann int (*iwi_newstate)(struct ieee80211vap *, 123841ab66cSSepherosa Ziehau enum ieee80211_state, int); 1240e474d75SJohannes Hofmann }; 1250e474d75SJohannes Hofmann #define IWI_VAP(vap) ((struct iwi_vap *)(vap)) 1260e474d75SJohannes Hofmann 1270e474d75SJohannes Hofmann struct iwi_softc { 128*c4fe7bb1SImre Vadász #if defined(__DragonFly__) 129*c4fe7bb1SImre Vadász struct lock sc_lock; 130*c4fe7bb1SImre Vadász #else 131*c4fe7bb1SImre Vadász struct mtx sc_mtx; 132*c4fe7bb1SImre Vadász #endif 133*c4fe7bb1SImre Vadász struct ieee80211com sc_ic; 134*c4fe7bb1SImre Vadász struct mbufq sc_snd; 135841ab66cSSepherosa Ziehau device_t sc_dev; 136841ab66cSSepherosa Ziehau 137*c4fe7bb1SImre Vadász void (*sc_node_free)(struct ieee80211_node *); 138*c4fe7bb1SImre Vadász 1390e474d75SJohannes Hofmann uint8_t sc_mcast[IEEE80211_ADDR_LEN]; 140*c4fe7bb1SImre Vadász #if defined(__DragonFly__) 1410e474d75SJohannes Hofmann struct devfs_bitmap sc_unr; 142*c4fe7bb1SImre Vadász #else 143*c4fe7bb1SImre Vadász struct unrhdr *sc_unr; 144*c4fe7bb1SImre Vadász #endif 145841ab66cSSepherosa Ziehau 1460e474d75SJohannes Hofmann uint32_t flags; 1470e474d75SJohannes Hofmann #define IWI_FLAG_FW_INITED (1 << 0) 1480e474d75SJohannes Hofmann #define IWI_FLAG_BUSY (1 << 3) /* busy sending a command */ 1490e474d75SJohannes Hofmann #define IWI_FLAG_ASSOCIATED (1 << 4) /* currently associated */ 1500e474d75SJohannes Hofmann #define IWI_FLAG_CHANNEL_SCAN (1 << 5) 1510e474d75SJohannes Hofmann uint32_t fw_state; 1520e474d75SJohannes Hofmann #define IWI_FW_IDLE 0 1530e474d75SJohannes Hofmann #define IWI_FW_LOADING 1 1540e474d75SJohannes Hofmann #define IWI_FW_ASSOCIATING 2 1550e474d75SJohannes Hofmann #define IWI_FW_DISASSOCIATING 3 1560e474d75SJohannes Hofmann #define IWI_FW_SCANNING 4 157841ab66cSSepherosa Ziehau struct iwi_cmd_ring cmdq; 158841ab66cSSepherosa Ziehau struct iwi_tx_ring txq[WME_NUM_AC]; 159841ab66cSSepherosa Ziehau struct iwi_rx_ring rxq; 160b50e4759SMatthew Dillon 161b50e4759SMatthew Dillon struct resource *irq; 162b50e4759SMatthew Dillon struct resource *mem; 163b50e4759SMatthew Dillon bus_space_tag_t sc_st; 164b50e4759SMatthew Dillon bus_space_handle_t sc_sh; 165b50e4759SMatthew Dillon void *sc_ih; 166b50e4759SMatthew Dillon 1670e474d75SJohannes Hofmann /* 1680e474d75SJohannes Hofmann * The card needs external firmware images to work, which is made of a 1690e474d75SJohannes Hofmann * bootloader, microcode and firmware proper. In version 3.00 and 1700e474d75SJohannes Hofmann * above, all pieces are contained in a single image, preceded by a 1710e474d75SJohannes Hofmann * struct iwi_firmware_hdr indicating the size of the 3 pieces. 1720e474d75SJohannes Hofmann * Old firmware < 3.0 has separate boot and ucode, so we need to 1730e474d75SJohannes Hofmann * load all of them explicitly. 1740e474d75SJohannes Hofmann * To avoid issues related to fragmentation, we keep the block of 1750e474d75SJohannes Hofmann * dma-ble memory around until detach time, and reallocate it when 1760e474d75SJohannes Hofmann * it becomes too small. fw_dma_size is the size currently allocated. 1770e474d75SJohannes Hofmann */ 1780e474d75SJohannes Hofmann int fw_dma_size; 1790e474d75SJohannes Hofmann uint32_t fw_flags; /* allocation status */ 1800e474d75SJohannes Hofmann #define IWI_FW_HAVE_DMAT 0x01 1810e474d75SJohannes Hofmann #define IWI_FW_HAVE_MAP 0x02 1820e474d75SJohannes Hofmann #define IWI_FW_HAVE_PHY 0x04 1830e474d75SJohannes Hofmann bus_dma_tag_t fw_dmat; 1840e474d75SJohannes Hofmann bus_dmamap_t fw_map; 1850e474d75SJohannes Hofmann bus_addr_t fw_physaddr; 1860e474d75SJohannes Hofmann void *fw_virtaddr; 1870e474d75SJohannes Hofmann enum ieee80211_opmode fw_mode; /* mode of current firmware */ 1880e474d75SJohannes Hofmann struct iwi_fw fw_boot; /* boot firmware */ 1890e474d75SJohannes Hofmann struct iwi_fw fw_uc; /* microcode */ 1900e474d75SJohannes Hofmann struct iwi_fw fw_fw; /* operating mode support */ 1910e474d75SJohannes Hofmann 1920e474d75SJohannes Hofmann int curchan; /* current h/w channel # */ 193841ab66cSSepherosa Ziehau int antenna; 194841ab66cSSepherosa Ziehau int bluetooth; 1950e474d75SJohannes Hofmann struct iwi_associate assoc; 1960e474d75SJohannes Hofmann struct iwi_wme_params wme[3]; 1970e474d75SJohannes Hofmann u_int sc_scangen; 1980e474d75SJohannes Hofmann 1990e474d75SJohannes Hofmann struct task sc_radiontask; /* radio on processing */ 2000e474d75SJohannes Hofmann struct task sc_radiofftask; /* radio off processing */ 2010e474d75SJohannes Hofmann struct task sc_restarttask; /* restart adapter processing */ 2020e474d75SJohannes Hofmann struct task sc_disassoctask; 203*c4fe7bb1SImre Vadász struct task sc_monitortask; 2040e474d75SJohannes Hofmann 205*c4fe7bb1SImre Vadász unsigned int sc_running : 1, /* initialized */ 206*c4fe7bb1SImre Vadász sc_softled : 1, /* enable LED gpio status */ 2070e474d75SJohannes Hofmann sc_ledstate: 1, /* LED on/off state */ 2080e474d75SJohannes Hofmann sc_blinking: 1; /* LED blink operation active */ 2090e474d75SJohannes Hofmann u_int sc_nictype; /* NIC type from EEPROM */ 2100e474d75SJohannes Hofmann u_int sc_ledpin; /* mask for activity LED */ 2110e474d75SJohannes Hofmann u_int sc_ledidle; /* idle polling interval */ 2120e474d75SJohannes Hofmann int sc_ledevent; /* time of last LED event */ 2130e474d75SJohannes Hofmann u_int8_t sc_rxrate; /* current rx rate for LED */ 2140e474d75SJohannes Hofmann u_int8_t sc_rxrix; 2150e474d75SJohannes Hofmann u_int8_t sc_txrate; /* current tx rate for LED */ 2160e474d75SJohannes Hofmann u_int8_t sc_txrix; 2170e474d75SJohannes Hofmann u_int16_t sc_ledoff; /* off time for current blink */ 218*c4fe7bb1SImre Vadász struct callout sc_ledtimer; /* led off timer */ 219*c4fe7bb1SImre Vadász struct callout sc_wdtimer; /* watchdog timer */ 220*c4fe7bb1SImre Vadász struct callout sc_rftimer; /* rfkill timer */ 221b50e4759SMatthew Dillon 222b50e4759SMatthew Dillon int sc_tx_timer; 2230e474d75SJohannes Hofmann int sc_state_timer; /* firmware state timer */ 2240e474d75SJohannes Hofmann int sc_busy_timer; /* firmware cmd timer */ 225b50e4759SMatthew Dillon 2260e474d75SJohannes Hofmann struct iwi_rx_radiotap_header sc_rxtap; 2270e474d75SJohannes Hofmann struct iwi_tx_radiotap_header sc_txtap; 228*c4fe7bb1SImre Vadász 229*c4fe7bb1SImre Vadász struct iwi_notif_link_quality sc_linkqual; 230*c4fe7bb1SImre Vadász int sc_linkqual_valid; 231b50e4759SMatthew Dillon }; 232b50e4759SMatthew Dillon 2330e474d75SJohannes Hofmann #define IWI_STATE_BEGIN(_sc, _state) do { \ 2340e474d75SJohannes Hofmann KASSERT(_sc->fw_state == IWI_FW_IDLE, \ 2350e474d75SJohannes Hofmann ("iwi firmware not idle, state %s", iwi_fw_states[_sc->fw_state]));\ 2360e474d75SJohannes Hofmann _sc->fw_state = _state; \ 2370e474d75SJohannes Hofmann _sc->sc_state_timer = 5; \ 2380e474d75SJohannes Hofmann DPRINTF(("enter %s state\n", iwi_fw_states[_state])); \ 2390e474d75SJohannes Hofmann } while (0) 240b50e4759SMatthew Dillon 2410e474d75SJohannes Hofmann #define IWI_STATE_END(_sc, _state) do { \ 2420e474d75SJohannes Hofmann if (_sc->fw_state == _state) \ 2430e474d75SJohannes Hofmann DPRINTF(("exit %s state\n", iwi_fw_states[_state])); \ 2440e474d75SJohannes Hofmann else \ 2450e474d75SJohannes Hofmann DPRINTF(("expected %s state, got %s\n", \ 2460e474d75SJohannes Hofmann iwi_fw_states[_state], iwi_fw_states[_sc->fw_state])); \ 2470e474d75SJohannes Hofmann _sc->fw_state = IWI_FW_IDLE; \ 2480e474d75SJohannes Hofmann wakeup(_sc); \ 2490e474d75SJohannes Hofmann _sc->sc_state_timer = 0; \ 2500e474d75SJohannes Hofmann } while (0) 251*c4fe7bb1SImre Vadász 252*c4fe7bb1SImre Vadász /* 253*c4fe7bb1SImre Vadász * NB.: This models the only instance of async locking in iwi_init_locked 254*c4fe7bb1SImre Vadász * and must be kept in sync. 255*c4fe7bb1SImre Vadász */ 256*c4fe7bb1SImre Vadász #if defined(__DragonFly__) 257*c4fe7bb1SImre Vadász 258*c4fe7bb1SImre Vadász #define IWI_LOCK_INIT(sc) \ 259*c4fe7bb1SImre Vadász lockinit(&(sc)->sc_lock, device_get_nameunit((sc)->sc_dev), 0, 0) 260*c4fe7bb1SImre Vadász #define IWI_LOCK_DESTROY(sc) lockuninit(&(sc)->sc_lock) 261*c4fe7bb1SImre Vadász #define IWI_LOCK_DECL int __waslocked = 0 262*c4fe7bb1SImre Vadász #define IWI_LOCK_ASSERT(sc) KKASSERT(lockstatus(&(sc)->sc_lock, curthread) == LK_EXCLUSIVE) 263*c4fe7bb1SImre Vadász #define IWI_LOCK(sc) do { \ 264*c4fe7bb1SImre Vadász if (!(__waslocked = (lockstatus(&(sc)->sc_lock, curthread) == LK_EXCLUSIVE))) \ 265*c4fe7bb1SImre Vadász lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE); \ 266*c4fe7bb1SImre Vadász } while (0) 267*c4fe7bb1SImre Vadász #define IWI_UNLOCK(sc) do { \ 268*c4fe7bb1SImre Vadász if (!__waslocked) \ 269*c4fe7bb1SImre Vadász lockmgr(&(sc)->sc_lock, LK_RELEASE); \ 270*c4fe7bb1SImre Vadász } while (0) 271*c4fe7bb1SImre Vadász 272*c4fe7bb1SImre Vadász #else 273*c4fe7bb1SImre Vadász 274*c4fe7bb1SImre Vadász #define IWI_LOCK_INIT(sc) \ 275*c4fe7bb1SImre Vadász mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \ 276*c4fe7bb1SImre Vadász MTX_NETWORK_LOCK, MTX_DEF) 277*c4fe7bb1SImre Vadász #define IWI_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx) 278*c4fe7bb1SImre Vadász #define IWI_LOCK_DECL int __waslocked = 0 279*c4fe7bb1SImre Vadász #define IWI_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 280*c4fe7bb1SImre Vadász #define IWI_LOCK(sc) do { \ 281*c4fe7bb1SImre Vadász if (!(__waslocked = mtx_owned(&(sc)->sc_mtx))) \ 282*c4fe7bb1SImre Vadász mtx_lock(&(sc)->sc_mtx); \ 283*c4fe7bb1SImre Vadász } while (0) 284*c4fe7bb1SImre Vadász #define IWI_UNLOCK(sc) do { \ 285*c4fe7bb1SImre Vadász if (!__waslocked) \ 286*c4fe7bb1SImre Vadász mtx_unlock(&(sc)->sc_mtx); \ 287*c4fe7bb1SImre Vadász } while (0) 288*c4fe7bb1SImre Vadász 289*c4fe7bb1SImre Vadász #endif 290