1178676Ssam/* $FreeBSD$ */ 2210111Sbschmidt/* $OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $ */ 3198429Srpaulo 4178676Ssam/*- 5198429Srpaulo * Copyright (c) 2007, 2008 6178676Ssam * Damien Bergamini <damien.bergamini@free.fr> 7178676Ssam * Copyright (c) 2008 Sam Leffler, Errno Consulting 8178676Ssam * 9178676Ssam * Permission to use, copy, modify, and distribute this software for any 10178676Ssam * purpose with or without fee is hereby granted, provided that the above 11178676Ssam * copyright notice and this permission notice appear in all copies. 12178676Ssam * 13178676Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14178676Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15178676Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16178676Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17178676Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18178676Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19178676Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20178676Ssam */ 21178676Ssam 22178676Ssamstruct iwn_rx_radiotap_header { 23178676Ssam struct ieee80211_radiotap_header wr_ihdr; 24178676Ssam uint64_t wr_tsft; 25178676Ssam uint8_t wr_flags; 26178676Ssam uint8_t wr_rate; 27178676Ssam uint16_t wr_chan_freq; 28178676Ssam uint16_t wr_chan_flags; 29178676Ssam int8_t wr_dbm_antsignal; 30178676Ssam int8_t wr_dbm_antnoise; 31178676Ssam} __packed; 32178676Ssam 33178676Ssam#define IWN_RX_RADIOTAP_PRESENT \ 34178676Ssam ((1 << IEEE80211_RADIOTAP_TSFT) | \ 35178676Ssam (1 << IEEE80211_RADIOTAP_FLAGS) | \ 36178676Ssam (1 << IEEE80211_RADIOTAP_RATE) | \ 37178676Ssam (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 38178676Ssam (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 39178676Ssam (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 40178676Ssam 41178676Ssamstruct iwn_tx_radiotap_header { 42178676Ssam struct ieee80211_radiotap_header wt_ihdr; 43178676Ssam uint8_t wt_flags; 44178676Ssam uint8_t wt_rate; 45178676Ssam uint16_t wt_chan_freq; 46178676Ssam uint16_t wt_chan_flags; 47178676Ssam} __packed; 48178676Ssam 49178676Ssam#define IWN_TX_RADIOTAP_PRESENT \ 50178676Ssam ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 51178676Ssam (1 << IEEE80211_RADIOTAP_RATE) | \ 52178676Ssam (1 << IEEE80211_RADIOTAP_CHANNEL)) 53178676Ssam 54178676Ssamstruct iwn_dma_info { 55178676Ssam bus_dma_tag_t tag; 56178676Ssam bus_dmamap_t map; 57178676Ssam bus_dma_segment_t seg; 58178676Ssam bus_addr_t paddr; 59178676Ssam caddr_t vaddr; 60178676Ssam bus_size_t size; 61178676Ssam}; 62178676Ssam 63178676Ssamstruct iwn_tx_data { 64178676Ssam bus_dmamap_t map; 65198429Srpaulo bus_addr_t cmd_paddr; 66198429Srpaulo bus_addr_t scratch_paddr; 67178676Ssam struct mbuf *m; 68178676Ssam struct ieee80211_node *ni; 69178676Ssam}; 70178676Ssam 71178676Ssamstruct iwn_tx_ring { 72178676Ssam struct iwn_dma_info desc_dma; 73178676Ssam struct iwn_dma_info cmd_dma; 74178676Ssam struct iwn_tx_desc *desc; 75178676Ssam struct iwn_tx_cmd *cmd; 76178676Ssam struct iwn_tx_data data[IWN_TX_RING_COUNT]; 77201209Srpaulo bus_dma_tag_t data_dmat; 78178676Ssam int qid; 79178676Ssam int queued; 80178676Ssam int cur; 81221651Sbschmidt int read; 82178676Ssam}; 83178676Ssam 84198429Srpaulostruct iwn_softc; 85198429Srpaulo 86178676Ssamstruct iwn_rx_data { 87198429Srpaulo struct mbuf *m; 88198429Srpaulo bus_dmamap_t map; 89178676Ssam}; 90178676Ssam 91178676Ssamstruct iwn_rx_ring { 92178676Ssam struct iwn_dma_info desc_dma; 93198429Srpaulo struct iwn_dma_info stat_dma; 94178676Ssam uint32_t *desc; 95198429Srpaulo struct iwn_rx_status *stat; 96178676Ssam struct iwn_rx_data data[IWN_RX_RING_COUNT]; 97201209Srpaulo bus_dma_tag_t data_dmat; 98178676Ssam int cur; 99178676Ssam}; 100178676Ssam 101178676Ssamstruct iwn_node { 102178676Ssam struct ieee80211_node ni; /* must be the first */ 103198429Srpaulo uint16_t disable_tid; 104198429Srpaulo uint8_t id; 105221648Sbschmidt uint32_t ridx[256]; 106221651Sbschmidt struct { 107221651Sbschmidt uint64_t bitmap; 108221651Sbschmidt int startidx; 109221651Sbschmidt int nframes; 110221651Sbschmidt } agg[IEEE80211_TID_SIZE]; 111178676Ssam}; 112178676Ssam 113178676Ssamstruct iwn_calib_state { 114178676Ssam uint8_t state; 115178676Ssam#define IWN_CALIB_STATE_INIT 0 116178676Ssam#define IWN_CALIB_STATE_ASSOC 1 117178676Ssam#define IWN_CALIB_STATE_RUN 2 118198429Srpaulo 119178676Ssam u_int nbeacons; 120178676Ssam uint32_t noise[3]; 121178676Ssam uint32_t rssi[3]; 122198429Srpaulo uint32_t ofdm_x1; 123198429Srpaulo uint32_t ofdm_mrc_x1; 124198429Srpaulo uint32_t ofdm_x4; 125198429Srpaulo uint32_t ofdm_mrc_x4; 126198429Srpaulo uint32_t cck_x4; 127198429Srpaulo uint32_t cck_mrc_x4; 128178676Ssam uint32_t bad_plcp_ofdm; 129178676Ssam uint32_t fa_ofdm; 130178676Ssam uint32_t bad_plcp_cck; 131178676Ssam uint32_t fa_cck; 132178676Ssam uint32_t low_fa; 133178676Ssam uint8_t cck_state; 134178676Ssam#define IWN_CCK_STATE_INIT 0 135178676Ssam#define IWN_CCK_STATE_LOFA 1 136178676Ssam#define IWN_CCK_STATE_HIFA 2 137198429Srpaulo 138178676Ssam uint8_t noise_samples[20]; 139178676Ssam u_int cur_noise_sample; 140178676Ssam uint8_t noise_ref; 141178676Ssam uint32_t energy_samples[10]; 142178676Ssam u_int cur_energy_sample; 143178676Ssam uint32_t energy_cck; 144178676Ssam}; 145178676Ssam 146198429Srpaulostruct iwn_calib_info { 147198429Srpaulo uint8_t *buf; 148198429Srpaulo u_int len; 149198429Srpaulo}; 150198429Srpaulo 151198429Srpaulostruct iwn_fw_part { 152198429Srpaulo const uint8_t *text; 153198429Srpaulo uint32_t textsz; 154198429Srpaulo const uint8_t *data; 155198429Srpaulo uint32_t datasz; 156198429Srpaulo}; 157198429Srpaulo 158198429Srpaulostruct iwn_fw_info { 159210111Sbschmidt const uint8_t *data; 160210111Sbschmidt size_t size; 161198429Srpaulo struct iwn_fw_part init; 162198429Srpaulo struct iwn_fw_part main; 163198429Srpaulo struct iwn_fw_part boot; 164198429Srpaulo}; 165198429Srpaulo 166220728Sbschmidtstruct iwn_ops { 167198429Srpaulo int (*load_firmware)(struct iwn_softc *); 168198429Srpaulo void (*read_eeprom)(struct iwn_softc *); 169198429Srpaulo int (*post_alive)(struct iwn_softc *); 170198429Srpaulo int (*nic_config)(struct iwn_softc *); 171198429Srpaulo void (*update_sched)(struct iwn_softc *, int, int, uint8_t, 172198429Srpaulo uint16_t); 173198429Srpaulo int (*get_temperature)(struct iwn_softc *); 174198429Srpaulo int (*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *); 175201882Skeramida int (*set_txpower)(struct iwn_softc *, 176201882Skeramida struct ieee80211_channel *, int); 177198429Srpaulo int (*init_gains)(struct iwn_softc *); 178198429Srpaulo int (*set_gains)(struct iwn_softc *); 179198429Srpaulo int (*add_node)(struct iwn_softc *, struct iwn_node_info *, 180198429Srpaulo int); 181198429Srpaulo void (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *, 182198429Srpaulo struct iwn_rx_data *); 183201209Srpaulo void (*ampdu_tx_start)(struct iwn_softc *, 184221651Sbschmidt struct ieee80211_node *, int, uint8_t, uint16_t); 185221651Sbschmidt void (*ampdu_tx_stop)(struct iwn_softc *, int, uint8_t, 186201209Srpaulo uint16_t); 187198429Srpaulo}; 188198429Srpaulo 189178676Ssamstruct iwn_vap { 190178676Ssam struct ieee80211vap iv_vap; 191198429Srpaulo uint8_t iv_ridx; 192178676Ssam 193178676Ssam int (*iv_newstate)(struct ieee80211vap *, 194178676Ssam enum ieee80211_state, int); 195178676Ssam}; 196178676Ssam#define IWN_VAP(_vap) ((struct iwn_vap *)(_vap)) 197178676Ssam 198178676Ssamstruct iwn_softc { 199220726Sbschmidt device_t sc_dev; 200220723Sbschmidt 201178676Ssam struct ifnet *sc_ifp; 202178676Ssam int sc_debug; 203178676Ssam 204178676Ssam struct mtx sc_mtx; 205178676Ssam 206198429Srpaulo u_int sc_flags; 207198429Srpaulo#define IWN_FLAG_HAS_OTPROM (1 << 1) 208201209Srpaulo#define IWN_FLAG_CALIB_DONE (1 << 2) 209201209Srpaulo#define IWN_FLAG_USE_ICT (1 << 3) 210201209Srpaulo#define IWN_FLAG_INTERNAL_PA (1 << 4) 211220729Sbschmidt#define IWN_FLAG_HAS_11N (1 << 6) 212220729Sbschmidt#define IWN_FLAG_ENH_SENS (1 << 7) 213220891Sbschmidt#define IWN_FLAG_ADV_BTCOEX (1 << 8) 214178676Ssam 215198429Srpaulo uint8_t hw_type; 216220728Sbschmidt 217220728Sbschmidt struct iwn_ops ops; 218198429Srpaulo const char *fwname; 219201209Srpaulo const struct iwn_sensitivity_limits 220201209Srpaulo *limits; 221220728Sbschmidt int ntxqs; 222221651Sbschmidt int firstaggqueue; 223220728Sbschmidt int ndmachnls; 224220728Sbschmidt uint8_t broadcast_id; 225220728Sbschmidt int rxonsz; 226220728Sbschmidt int schedsz; 227220728Sbschmidt uint32_t fw_text_maxsz; 228220728Sbschmidt uint32_t fw_data_maxsz; 229220728Sbschmidt uint32_t fwsz; 230220728Sbschmidt bus_size_t sched_txfact_addr; 231220866Sbschmidt uint32_t reset_noise_gain; 232220866Sbschmidt uint32_t noise_gain; 233198429Srpaulo 234198429Srpaulo /* TX scheduler rings. */ 235198429Srpaulo struct iwn_dma_info sched_dma; 236198429Srpaulo uint16_t *sched; 237198429Srpaulo uint32_t sched_base; 238198429Srpaulo 239198429Srpaulo /* "Keep Warm" page. */ 240178676Ssam struct iwn_dma_info kw_dma; 241178676Ssam 242198429Srpaulo /* Firmware image. */ 243178676Ssam const struct firmware *fw_fp; 244178676Ssam 245198429Srpaulo /* Firmware DMA transfer. */ 246178676Ssam struct iwn_dma_info fw_dma; 247178676Ssam 248201209Srpaulo /* ICT table. */ 249201209Srpaulo struct iwn_dma_info ict_dma; 250201209Srpaulo uint32_t *ict; 251201209Srpaulo int ict_cur; 252201209Srpaulo 253198429Srpaulo /* TX/RX rings. */ 254198429Srpaulo struct iwn_tx_ring txq[IWN5000_NTXQUEUES]; 255178676Ssam struct iwn_rx_ring rxq; 256178676Ssam 257220726Sbschmidt struct resource *mem; 258178676Ssam bus_space_tag_t sc_st; 259178676Ssam bus_space_handle_t sc_sh; 260220723Sbschmidt struct resource *irq; 261178676Ssam void *sc_ih; 262178676Ssam bus_size_t sc_sz; 263198429Srpaulo int sc_cap_off; /* PCIe Capabilities. */ 264178676Ssam 265178676Ssam /* Tasks used by the driver */ 266220726Sbschmidt struct task sc_reinit_task; 267191746Sthompsa struct task sc_radioon_task; 268191746Sthompsa struct task sc_radiooff_task; 269201209Srpaulo 270220667Sbschmidt struct callout calib_to; 271178676Ssam int calib_cnt; 272178676Ssam struct iwn_calib_state calib; 273220667Sbschmidt struct callout watchdog_to; 274178676Ssam 275198429Srpaulo struct iwn_fw_info fw; 276220674Sbschmidt struct iwn_calib_info calibcmd[5]; 277198429Srpaulo uint32_t errptr; 278198429Srpaulo 279178676Ssam struct iwn_rx_stat last_rx_stat; 280178676Ssam int last_rx_valid; 281178676Ssam struct iwn_ucode_info ucode_info; 282198429Srpaulo struct iwn_rxon rxon; 283178676Ssam uint32_t rawtemp; 284178676Ssam int temp; 285178676Ssam int noise; 286198429Srpaulo uint32_t qfullmsk; 287178676Ssam 288201209Srpaulo uint32_t prom_base; 289198429Srpaulo struct iwn4965_eeprom_band 290198429Srpaulo bands[IWN_NBANDS]; 291201209Srpaulo struct iwn_eeprom_chan eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND]; 292198429Srpaulo uint16_t rfcfg; 293206444Sbschmidt uint8_t calib_ver; 294198429Srpaulo char eeprom_domain[4]; 295220674Sbschmidt uint32_t eeprom_crystal; 296220674Sbschmidt int16_t eeprom_temp; 297178676Ssam int16_t eeprom_voltage; 298178676Ssam int8_t maxpwr2GHz; 299178676Ssam int8_t maxpwr5GHz; 300198429Srpaulo int8_t maxpwr[IEEE80211_CHAN_MAX]; 301198429Srpaulo 302201209Srpaulo int32_t temp_off; 303201209Srpaulo uint32_t int_mask; 304198429Srpaulo uint8_t ntxchains; 305198429Srpaulo uint8_t nrxchains; 306201209Srpaulo uint8_t txchainmask; 307201209Srpaulo uint8_t rxchainmask; 308201209Srpaulo uint8_t chainmask; 309198429Srpaulo 310198429Srpaulo int sc_tx_timer; 311198429Srpaulo 312221651Sbschmidt struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES]; 313221651Sbschmidt 314221650Sbschmidt int (*sc_ampdu_rx_start)(struct ieee80211_node *, 315221650Sbschmidt struct ieee80211_rx_ampdu *, int, int, int); 316221650Sbschmidt void (*sc_ampdu_rx_stop)(struct ieee80211_node *, 317221650Sbschmidt struct ieee80211_rx_ampdu *); 318221651Sbschmidt int (*sc_addba_request)(struct ieee80211_node *, 319221651Sbschmidt struct ieee80211_tx_ampdu *, int, int, int); 320221651Sbschmidt int (*sc_addba_response)(struct ieee80211_node *, 321221651Sbschmidt struct ieee80211_tx_ampdu *, int, int, int); 322221651Sbschmidt void (*sc_addba_stop)(struct ieee80211_node *, 323221651Sbschmidt struct ieee80211_tx_ampdu *); 324221650Sbschmidt 325221651Sbschmidt 326198429Srpaulo struct iwn_rx_radiotap_header sc_rxtap; 327198429Srpaulo struct iwn_tx_radiotap_header sc_txtap; 328178676Ssam}; 329178676Ssam 330178676Ssam#define IWN_LOCK_INIT(_sc) \ 331178676Ssam mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 332210108Sbschmidt MTX_NETWORK_LOCK, MTX_DEF) 333178676Ssam#define IWN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 334178676Ssam#define IWN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 335178676Ssam#define IWN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 336178676Ssam#define IWN_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 337