16607310bSBenjamin Close 26607310bSBenjamin Close /*- 36607310bSBenjamin Close * Copyright (c) 2006,2007 46607310bSBenjamin Close * Damien Bergamini <damien.bergamini@free.fr> 56607310bSBenjamin Close * 66607310bSBenjamin Close * Permission to use, copy, modify, and distribute this software for any 76607310bSBenjamin Close * purpose with or without fee is hereby granted, provided that the above 86607310bSBenjamin Close * copyright notice and this permission notice appear in all copies. 96607310bSBenjamin Close * 106607310bSBenjamin Close * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 116607310bSBenjamin Close * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 126607310bSBenjamin Close * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 136607310bSBenjamin Close * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 146607310bSBenjamin Close * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 156607310bSBenjamin Close * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 166607310bSBenjamin Close * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 176607310bSBenjamin Close */ 186607310bSBenjamin Close struct wpi_rx_radiotap_header { 196607310bSBenjamin Close struct ieee80211_radiotap_header wr_ihdr; 206607310bSBenjamin Close uint64_t wr_tsft; 216607310bSBenjamin Close uint8_t wr_flags; 226607310bSBenjamin Close uint8_t wr_rate; 236607310bSBenjamin Close uint16_t wr_chan_freq; 246607310bSBenjamin Close uint16_t wr_chan_flags; 256607310bSBenjamin Close int8_t wr_dbm_antsignal; 266607310bSBenjamin Close int8_t wr_dbm_antnoise; 276607310bSBenjamin Close uint8_t wr_antenna; 28786ac703SAndriy Voskoboinyk } __packed __aligned(8); 296607310bSBenjamin Close 306607310bSBenjamin Close #define WPI_RX_RADIOTAP_PRESENT \ 316607310bSBenjamin Close ((1 << IEEE80211_RADIOTAP_TSFT) | \ 326607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_FLAGS) | \ 336607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_RATE) | \ 346607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 356607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 366607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 376607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_ANTENNA)) 386607310bSBenjamin Close 396607310bSBenjamin Close struct wpi_tx_radiotap_header { 406607310bSBenjamin Close struct ieee80211_radiotap_header wt_ihdr; 416607310bSBenjamin Close uint8_t wt_flags; 426607310bSBenjamin Close uint8_t wt_rate; 436607310bSBenjamin Close uint16_t wt_chan_freq; 446607310bSBenjamin Close uint16_t wt_chan_flags; 45692ad7caSAdrian Chadd } __packed; 466607310bSBenjamin Close 476607310bSBenjamin Close #define WPI_TX_RADIOTAP_PRESENT \ 486607310bSBenjamin Close ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 496607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_RATE) | \ 506607310bSBenjamin Close (1 << IEEE80211_RADIOTAP_CHANNEL)) 516607310bSBenjamin Close 526607310bSBenjamin Close struct wpi_dma_info { 536607310bSBenjamin Close bus_dma_tag_t tag; 546607310bSBenjamin Close bus_dmamap_t map; 55692ad7caSAdrian Chadd bus_addr_t paddr; 56692ad7caSAdrian Chadd caddr_t vaddr; 576607310bSBenjamin Close bus_size_t size; 586607310bSBenjamin Close }; 596607310bSBenjamin Close 606607310bSBenjamin Close struct wpi_tx_data { 616607310bSBenjamin Close bus_dmamap_t map; 62692ad7caSAdrian Chadd bus_addr_t cmd_paddr; 636607310bSBenjamin Close struct mbuf *m; 646607310bSBenjamin Close struct ieee80211_node *ni; 653f3d4d61SAndriy Voskoboinyk int hdrlen; 666607310bSBenjamin Close }; 676607310bSBenjamin Close 686607310bSBenjamin Close struct wpi_tx_ring { 696607310bSBenjamin Close struct wpi_dma_info desc_dma; 706607310bSBenjamin Close struct wpi_dma_info cmd_dma; 716607310bSBenjamin Close struct wpi_tx_desc *desc; 726607310bSBenjamin Close struct wpi_tx_cmd *cmd; 73692ad7caSAdrian Chadd struct wpi_tx_data data[WPI_TX_RING_COUNT]; 746607310bSBenjamin Close bus_dma_tag_t data_dmat; 75525a3d47SAdrian Chadd uint8_t qid; 76525a3d47SAdrian Chadd uint8_t cur; 77940aa808SAdrian Chadd uint8_t pending; 78525a3d47SAdrian Chadd int16_t queued; 79*bab8274cSDimitry Andric bool update:1; 806607310bSBenjamin Close }; 816607310bSBenjamin Close 826607310bSBenjamin Close struct wpi_rx_data { 836607310bSBenjamin Close struct mbuf *m; 84692ad7caSAdrian Chadd bus_dmamap_t map; 856607310bSBenjamin Close }; 866607310bSBenjamin Close 876607310bSBenjamin Close struct wpi_rx_ring { 886607310bSBenjamin Close struct wpi_dma_info desc_dma; 896607310bSBenjamin Close uint32_t *desc; 906607310bSBenjamin Close struct wpi_rx_data data[WPI_RX_RING_COUNT]; 9182f1b132SAndrew Thompson bus_dma_tag_t data_dmat; 92525a3d47SAdrian Chadd uint16_t cur; 93692ad7caSAdrian Chadd int update; 946607310bSBenjamin Close }; 956607310bSBenjamin Close 96692ad7caSAdrian Chadd struct wpi_node { 976607310bSBenjamin Close struct ieee80211_node ni; /* must be the first */ 98692ad7caSAdrian Chadd uint8_t id; 996607310bSBenjamin Close }; 100a5e093b0SAdrian Chadd #define WPI_NODE(ni) ((struct wpi_node *)(ni)) 1016607310bSBenjamin Close 1026607310bSBenjamin Close struct wpi_power_sample { 1036607310bSBenjamin Close uint8_t index; 1046607310bSBenjamin Close int8_t power; 1056607310bSBenjamin Close }; 1066607310bSBenjamin Close 1076607310bSBenjamin Close struct wpi_power_group { 1086607310bSBenjamin Close #define WPI_SAMPLES_COUNT 5 1096607310bSBenjamin Close struct wpi_power_sample samples[WPI_SAMPLES_COUNT]; 1106607310bSBenjamin Close uint8_t chan; 1116607310bSBenjamin Close int8_t maxpwr; 1126607310bSBenjamin Close int16_t temp; 1136607310bSBenjamin Close }; 1146607310bSBenjamin Close 115692ad7caSAdrian Chadd struct wpi_buf { 116565248e2SAdrian Chadd uint8_t data[56]; /* sizeof(struct wpi_cmd_beacon) */ 117692ad7caSAdrian Chadd struct ieee80211_node *ni; 118692ad7caSAdrian Chadd struct mbuf *m; 119692ad7caSAdrian Chadd size_t size; 120525a3d47SAdrian Chadd uint8_t code; 121525a3d47SAdrian Chadd uint16_t ac; 122692ad7caSAdrian Chadd }; 123692ad7caSAdrian Chadd 124b032f27cSSam Leffler struct wpi_vap { 125d036bb20SAdrian Chadd struct ieee80211vap wv_vap; 1266f8421f8SAdrian Chadd 127692ad7caSAdrian Chadd struct wpi_buf wv_bcbuf; 128b56fed3dSAdrian Chadd struct mtx wv_mtx; 129b032f27cSSam Leffler 130525a3d47SAdrian Chadd uint8_t wv_gtk; 131d29fcfb7SAdrian Chadd #define WPI_VAP_KEY(kid) (1 << kid) 132d29fcfb7SAdrian Chadd 133d036bb20SAdrian Chadd int (*wv_newstate)(struct ieee80211vap *, 134b032f27cSSam Leffler enum ieee80211_state, int); 135a20c9affSAdrian Chadd void (*wv_recv_mgmt)(struct ieee80211_node *, 136b66af287SAdrian Chadd struct mbuf *, int, 137b66af287SAdrian Chadd const struct ieee80211_rx_stats *, 138b66af287SAdrian Chadd int, int); 139b032f27cSSam Leffler }; 140b032f27cSSam Leffler #define WPI_VAP(vap) ((struct wpi_vap *)(vap)) 141b032f27cSSam Leffler 142b56fed3dSAdrian Chadd #define WPI_VAP_LOCK_INIT(_wvp) \ 143b56fed3dSAdrian Chadd mtx_init(&(_wvp)->wv_mtx, "lock for wv_bcbuf/wv_boff structures", \ 144b56fed3dSAdrian Chadd NULL, MTX_DEF) 145b56fed3dSAdrian Chadd #define WPI_VAP_LOCK(_wvp) mtx_lock(&(_wvp)->wv_mtx) 146b56fed3dSAdrian Chadd #define WPI_VAP_UNLOCK(_wvp) mtx_unlock(&(_wvp)->wv_mtx) 147b56fed3dSAdrian Chadd #define WPI_VAP_LOCK_ASSERT(_wvp) mtx_assert(&(_wvp)->wv_mtx, MA_OWNED) 148b56fed3dSAdrian Chadd #define WPI_VAP_LOCK_DESTROY(_wvp) mtx_destroy(&(_wvp)->wv_mtx) 149b56fed3dSAdrian Chadd 150692ad7caSAdrian Chadd struct wpi_fw_part { 151692ad7caSAdrian Chadd const uint8_t *text; 152692ad7caSAdrian Chadd uint32_t textsz; 153692ad7caSAdrian Chadd const uint8_t *data; 154692ad7caSAdrian Chadd uint32_t datasz; 155692ad7caSAdrian Chadd }; 156692ad7caSAdrian Chadd 157692ad7caSAdrian Chadd struct wpi_fw_info { 158692ad7caSAdrian Chadd const uint8_t *data; 159692ad7caSAdrian Chadd size_t size; 160692ad7caSAdrian Chadd struct wpi_fw_part init; 161692ad7caSAdrian Chadd struct wpi_fw_part main; 162692ad7caSAdrian Chadd struct wpi_fw_part boot; 163692ad7caSAdrian Chadd }; 164692ad7caSAdrian Chadd 1656607310bSBenjamin Close struct wpi_softc { 1666607310bSBenjamin Close device_t sc_dev; 167692ad7caSAdrian Chadd int sc_debug; 168692ad7caSAdrian Chadd 1697a79cebfSGleb Smirnoff int sc_running; 1705cacb17fSAdrian Chadd 1716607310bSBenjamin Close struct mtx sc_mtx; 1727a79cebfSGleb Smirnoff struct ieee80211com sc_ic; 173f6930becSAndriy Voskoboinyk struct ieee80211_ratectl_tx_status sc_txs; 1747a79cebfSGleb Smirnoff 1755effcbfdSAdrian Chadd struct mtx tx_mtx; 1766607310bSBenjamin Close 177692ad7caSAdrian Chadd /* Shared area. */ 1786607310bSBenjamin Close struct wpi_dma_info shared_dma; 1796607310bSBenjamin Close struct wpi_shared *shared; 1806607310bSBenjamin Close 18119053a54SAdrian Chadd struct wpi_tx_ring txq[WPI_DRV_NTXQUEUES]; 18263f57699SAdrian Chadd struct mtx txq_mtx; 183fc5870b4SAdrian Chadd struct mtx txq_state_mtx; 18463f57699SAdrian Chadd 1856607310bSBenjamin Close struct wpi_rx_ring rxq; 186a20c9affSAdrian Chadd uint64_t rx_tstamp; 1876607310bSBenjamin Close 188692ad7caSAdrian Chadd /* TX Thermal Callibration. */ 1896607310bSBenjamin Close struct callout calib_to; 1906607310bSBenjamin Close 1910bc39fc6SAdrian Chadd struct callout scan_timeout; 192d74e544aSAdrian Chadd struct callout tx_timeout; 1930bc39fc6SAdrian Chadd 194d74e544aSAdrian Chadd /* Watch dog timer. */ 195692ad7caSAdrian Chadd struct callout watchdog_rfkill; 196692ad7caSAdrian Chadd 197692ad7caSAdrian Chadd /* Firmware image. */ 198692ad7caSAdrian Chadd struct wpi_fw_info fw; 199692ad7caSAdrian Chadd uint32_t errptr; 2006607310bSBenjamin Close 2016607310bSBenjamin Close struct resource *irq; 2026607310bSBenjamin Close struct resource *mem; 2036607310bSBenjamin Close bus_space_tag_t sc_st; 2046607310bSBenjamin Close bus_space_handle_t sc_sh; 2056607310bSBenjamin Close void *sc_ih; 206692ad7caSAdrian Chadd bus_size_t sc_sz; 207692ad7caSAdrian Chadd int sc_cap_off; /* PCIe Capabilities. */ 2086607310bSBenjamin Close 209692ad7caSAdrian Chadd struct wpi_rxon rxon; 210446685e4SAdrian Chadd struct mtx rxon_mtx; 211446685e4SAdrian Chadd 2126607310bSBenjamin Close int temp; 2137964dd56SAdrian Chadd 214eca2eb39SAdrian Chadd uint32_t nodesmsk; 2157964dd56SAdrian Chadd struct mtx nt_mtx; 2166607310bSBenjamin Close 217692ad7caSAdrian Chadd void (*sc_node_free)(struct ieee80211_node *); 2185cacb17fSAdrian Chadd void (*sc_update_rx_ring)(struct wpi_softc *); 2195cacb17fSAdrian Chadd void (*sc_update_tx_ring)(struct wpi_softc *, 2205cacb17fSAdrian Chadd struct wpi_tx_ring *); 2216607310bSBenjamin Close 2226607310bSBenjamin Close struct wpi_rx_radiotap_header sc_rxtap; 2236607310bSBenjamin Close struct wpi_tx_radiotap_header sc_txtap; 2246607310bSBenjamin Close 225692ad7caSAdrian Chadd /* Firmware image. */ 2266607310bSBenjamin Close const struct firmware *fw_fp; 2276607310bSBenjamin Close 228692ad7caSAdrian Chadd /* Firmware DMA transfer. */ 2296607310bSBenjamin Close struct wpi_dma_info fw_dma; 2306607310bSBenjamin Close 231692ad7caSAdrian Chadd /* Tasks used by the driver. */ 232692ad7caSAdrian Chadd struct task sc_radiooff_task; 233692ad7caSAdrian Chadd struct task sc_radioon_task; 2346607310bSBenjamin Close 235692ad7caSAdrian Chadd /* Eeprom info. */ 2366607310bSBenjamin Close uint8_t cap; 2376607310bSBenjamin Close uint16_t rev; 2386607310bSBenjamin Close uint8_t type; 239692ad7caSAdrian Chadd struct wpi_eeprom_chan 240692ad7caSAdrian Chadd eeprom_channels[WPI_CHAN_BANDS_COUNT][WPI_MAX_CHAN_PER_BAND]; 2416607310bSBenjamin Close struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT]; 2426607310bSBenjamin Close int8_t maxpwr[IEEE80211_CHAN_MAX]; 243692ad7caSAdrian Chadd char domain[4]; /* Regulatory domain. */ 2446607310bSBenjamin Close }; 245692ad7caSAdrian Chadd 246fc5870b4SAdrian Chadd /* 247fc5870b4SAdrian Chadd * Locking order: 248fc5870b4SAdrian Chadd * 1. WPI_LOCK; 249fc5870b4SAdrian Chadd * 2. WPI_RXON_LOCK; 2505effcbfdSAdrian Chadd * 3. WPI_TX_LOCK; 2515effcbfdSAdrian Chadd * 4. WPI_NT_LOCK / WPI_VAP_LOCK; 2525effcbfdSAdrian Chadd * 5. WPI_TXQ_LOCK; 2535effcbfdSAdrian Chadd * 6. WPI_TXQ_STATE_LOCK; 254fc5870b4SAdrian Chadd */ 25563f57699SAdrian Chadd 2566607310bSBenjamin Close #define WPI_LOCK_INIT(_sc) \ 2576607310bSBenjamin Close mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 2586607310bSBenjamin Close MTX_NETWORK_LOCK, MTX_DEF) 25982f1b132SAndrew Thompson #define WPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 26082f1b132SAndrew Thompson #define WPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 261062c8139SAdrian Chadd #define WPI_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 2626607310bSBenjamin Close #define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 26363f57699SAdrian Chadd 264446685e4SAdrian Chadd #define WPI_RXON_LOCK_INIT(_sc) \ 265446685e4SAdrian Chadd mtx_init(&(_sc)->rxon_mtx, "lock for wpi_rxon structure", NULL, MTX_DEF) 266446685e4SAdrian Chadd #define WPI_RXON_LOCK(_sc) mtx_lock(&(_sc)->rxon_mtx) 267446685e4SAdrian Chadd #define WPI_RXON_UNLOCK(_sc) mtx_unlock(&(_sc)->rxon_mtx) 268446685e4SAdrian Chadd #define WPI_RXON_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rxon_mtx, MA_OWNED) 269446685e4SAdrian Chadd #define WPI_RXON_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rxon_mtx) 270446685e4SAdrian Chadd 2715effcbfdSAdrian Chadd #define WPI_TX_LOCK_INIT(_sc) \ 2725effcbfdSAdrian Chadd mtx_init(&(_sc)->tx_mtx, "tx path lock", NULL, MTX_DEF) 2735effcbfdSAdrian Chadd #define WPI_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) 2745effcbfdSAdrian Chadd #define WPI_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) 2755effcbfdSAdrian Chadd #define WPI_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) 2765effcbfdSAdrian Chadd 2777964dd56SAdrian Chadd #define WPI_NT_LOCK_INIT(_sc) \ 2787964dd56SAdrian Chadd mtx_init(&(_sc)->nt_mtx, "node table lock", NULL, MTX_DEF) 2797964dd56SAdrian Chadd #define WPI_NT_LOCK(_sc) mtx_lock(&(_sc)->nt_mtx) 2807964dd56SAdrian Chadd #define WPI_NT_UNLOCK(_sc) mtx_unlock(&(_sc)->nt_mtx) 2817964dd56SAdrian Chadd #define WPI_NT_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->nt_mtx) 2827964dd56SAdrian Chadd 28363f57699SAdrian Chadd #define WPI_TXQ_LOCK_INIT(_sc) \ 28463f57699SAdrian Chadd mtx_init(&(_sc)->txq_mtx, "txq/cmdq lock", NULL, MTX_DEF) 28563f57699SAdrian Chadd #define WPI_TXQ_LOCK(_sc) mtx_lock(&(_sc)->txq_mtx) 28663f57699SAdrian Chadd #define WPI_TXQ_UNLOCK(_sc) mtx_unlock(&(_sc)->txq_mtx) 28763f57699SAdrian Chadd #define WPI_TXQ_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->txq_mtx) 288fc5870b4SAdrian Chadd 289fc5870b4SAdrian Chadd #define WPI_TXQ_STATE_LOCK_INIT(_sc) \ 290fc5870b4SAdrian Chadd mtx_init(&(_sc)->txq_state_mtx, "txq state lock", NULL, MTX_DEF) 291fc5870b4SAdrian Chadd #define WPI_TXQ_STATE_LOCK(_sc) mtx_lock(&(_sc)->txq_state_mtx) 292fc5870b4SAdrian Chadd #define WPI_TXQ_STATE_UNLOCK(_sc) mtx_unlock(&(_sc)->txq_state_mtx) 293fc5870b4SAdrian Chadd #define WPI_TXQ_STATE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->txq_state_mtx) 294