if_iwnvar.h revision 262422
1139749Simp/* $FreeBSD: head/sys/dev/iwn/if_iwnvar.h 262422 2014-02-24 02:37:04Z adrian $ */ 2135048Swpaul/* $OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $ */ 3135048Swpaul 4135048Swpaul/*- 5135048Swpaul * Copyright (c) 2013 Cedric GROSS <cg@cgross.info> 6135048Swpaul * Copyright (c) 2011 Intel Corporation 7135048Swpaul * Copyright (c) 2007, 2008 8135048Swpaul * Damien Bergamini <damien.bergamini@free.fr> 9135048Swpaul * Copyright (c) 2008 Sam Leffler, Errno Consulting 10135048Swpaul * 11135048Swpaul * Permission to use, copy, modify, and distribute this software for any 12135048Swpaul * purpose with or without fee is hereby granted, provided that the above 13135048Swpaul * copyright notice and this permission notice appear in all copies. 14135048Swpaul * 15135048Swpaul * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16135048Swpaul * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17135048Swpaul * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18135048Swpaul * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19135048Swpaul * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20135048Swpaul * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21135048Swpaul * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22135048Swpaul */ 23135048Swpaulenum iwn_rxon_ctx_id { 24135048Swpaul IWN_RXON_BSS_CTX, 25135048Swpaul IWN_RXON_PAN_CTX, 26135048Swpaul IWN_NUM_RXON_CTX 27135048Swpaul}; 28135048Swpaul 29135048Swpaulstruct iwn_pan_slot { 30135048Swpaul uint16_t time; 31135048Swpaul uint8_t type; 32135048Swpaul uint8_t reserved; 33135048Swpaul} __packed; 34135048Swpaul 35135048Swpaulstruct iwn_pan_params_cmd { 36135048Swpaul uint16_t flags; 37135048Swpaul#define IWN_PAN_PARAMS_FLG_SLOTTED_MODE (1 << 3) 38135048Swpaul 39135048Swpaul uint8_t reserved; 40135048Swpaul uint8_t num_slots; 41135048Swpaul struct iwn_pan_slot slots[10]; 42135048Swpaul} __packed; 43135048Swpaul 44135048Swpaulstruct iwn_led_mode 45135048Swpaul{ 46135048Swpaul uint8_t led_cur_mode; 47135048Swpaul uint64_t led_cur_bt; 48135048Swpaul uint64_t led_last_bt; 49135048Swpaul uint64_t led_cur_tpt; 50135048Swpaul uint64_t led_last_tpt; 51135048Swpaul uint64_t led_bt_diff; 52135048Swpaul int led_cur_time; 53135048Swpaul int led_last_time; 54135048Swpaul}; 55135048Swpaul 56135048Swpaulstruct iwn_rx_radiotap_header { 57135048Swpaul struct ieee80211_radiotap_header wr_ihdr; 58135048Swpaul uint64_t wr_tsft; 59135048Swpaul uint8_t wr_flags; 60135048Swpaul uint8_t wr_rate; 61135048Swpaul uint16_t wr_chan_freq; 62135048Swpaul uint16_t wr_chan_flags; 63135048Swpaul int8_t wr_dbm_antsignal; 64135048Swpaul int8_t wr_dbm_antnoise; 65135048Swpaul} __packed; 66135048Swpaul 67135048Swpaul#define IWN_RX_RADIOTAP_PRESENT \ 68135048Swpaul ((1 << IEEE80211_RADIOTAP_TSFT) | \ 69135048Swpaul (1 << IEEE80211_RADIOTAP_FLAGS) | \ 70135048Swpaul (1 << IEEE80211_RADIOTAP_RATE) | \ 71135048Swpaul (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 72135048Swpaul (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 73135048Swpaul (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 74135048Swpaul 75135048Swpaulstruct iwn_tx_radiotap_header { 76135048Swpaul struct ieee80211_radiotap_header wt_ihdr; 77135048Swpaul uint8_t wt_flags; 78135048Swpaul uint8_t wt_rate; 79135048Swpaul uint16_t wt_chan_freq; 80135048Swpaul uint16_t wt_chan_flags; 81135048Swpaul} __packed; 82135048Swpaul 83150968Sglebius#define IWN_TX_RADIOTAP_PRESENT \ 84150968Sglebius ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 85150968Sglebius (1 << IEEE80211_RADIOTAP_RATE) | \ 86150968Sglebius (1 << IEEE80211_RADIOTAP_CHANNEL)) 87135048Swpaul 88135048Swpaulstruct iwn_dma_info { 89135048Swpaul bus_dma_tag_t tag; 90135048Swpaul bus_dmamap_t map; 91135048Swpaul bus_dma_segment_t seg; 92135048Swpaul bus_addr_t paddr; 93135048Swpaul caddr_t vaddr; 94135048Swpaul bus_size_t size; 95135048Swpaul}; 96135048Swpaul 97135048Swpaulstruct iwn_tx_data { 98135048Swpaul bus_dmamap_t map; 99135048Swpaul bus_addr_t cmd_paddr; 100135048Swpaul bus_addr_t scratch_paddr; 101135048Swpaul struct mbuf *m; 102147256Sbrooks struct ieee80211_node *ni; 103135048Swpaul}; 104135048Swpaul 105135048Swpaulstruct iwn_tx_ring { 106135048Swpaul struct iwn_dma_info desc_dma; 107135048Swpaul struct iwn_dma_info cmd_dma; 108135048Swpaul struct iwn_tx_desc *desc; 109135048Swpaul struct iwn_tx_cmd *cmd; 110135048Swpaul struct iwn_tx_data data[IWN_TX_RING_COUNT]; 111135048Swpaul bus_dma_tag_t data_dmat; 112135048Swpaul int qid; 113135048Swpaul int queued; 114135048Swpaul int cur; 115135048Swpaul int read; 116135048Swpaul}; 117135048Swpaul 118135048Swpaulstruct iwn_softc; 119135048Swpaul 120135048Swpaulstruct iwn_rx_data { 121135048Swpaul struct mbuf *m; 122151545Simp bus_dmamap_t map; 123135048Swpaul}; 124135048Swpaul 125135048Swpaulstruct iwn_rx_ring { 126135048Swpaul struct iwn_dma_info desc_dma; 127135048Swpaul struct iwn_dma_info stat_dma; 128135048Swpaul uint32_t *desc; 129135048Swpaul struct iwn_rx_status *stat; 130200541Syongari struct iwn_rx_data data[IWN_RX_RING_COUNT]; 131200541Syongari bus_dma_tag_t data_dmat; 132200541Syongari int cur; 133200541Syongari}; 134135048Swpaul 135135048Swpaulstruct iwn_node { 136135048Swpaul struct ieee80211_node ni; /* must be the first */ 137135048Swpaul uint16_t disable_tid; 138135048Swpaul uint8_t id; 139135048Swpaul struct { 140135048Swpaul uint64_t bitmap; 141135048Swpaul int startidx; 142135048Swpaul int nframes; 143200548Syongari } agg[IEEE80211_TID_SIZE]; 144200548Syongari}; 145200548Syongari 146200548Syongaristruct iwn_calib_state { 147200548Syongari uint8_t state; 148200548Syongari#define IWN_CALIB_STATE_INIT 0 149135048Swpaul#define IWN_CALIB_STATE_ASSOC 1 150200548Syongari#define IWN_CALIB_STATE_RUN 2 151200548Syongari 152200548Syongari u_int nbeacons; 153200548Syongari uint32_t noise[3]; 154200548Syongari uint32_t rssi[3]; 155200548Syongari uint32_t ofdm_x1; 156200548Syongari uint32_t ofdm_mrc_x1; 157200548Syongari uint32_t ofdm_x4; 158200548Syongari uint32_t ofdm_mrc_x4; 159200548Syongari uint32_t cck_x4; 160200525Syongari uint32_t cck_mrc_x4; 161200548Syongari uint32_t bad_plcp_ofdm; 162200548Syongari uint32_t fa_ofdm; 163135048Swpaul uint32_t bad_plcp_cck; 164200548Syongari uint32_t fa_cck; 165200548Syongari uint32_t low_fa; 166200548Syongari uint32_t bad_plcp_ht; 167200548Syongari uint8_t cck_state; 168200548Syongari#define IWN_CCK_STATE_INIT 0 169200548Syongari#define IWN_CCK_STATE_LOFA 1 170200548Syongari#define IWN_CCK_STATE_HIFA 2 171200551Syongari 172200548Syongari uint8_t noise_samples[20]; 173200548Syongari u_int cur_noise_sample; 174200548Syongari uint8_t noise_ref; 175200548Syongari uint32_t energy_samples[10]; 176200548Syongari u_int cur_energy_sample; 177200548Syongari uint32_t energy_cck; 178200548Syongari}; 179200548Syongari 180200548Syongaristruct iwn_calib_info { 181200548Syongari uint8_t *buf; 182200548Syongari u_int len; 183200548Syongari}; 184200548Syongari 185200548Syongaristruct iwn_fw_part { 186200548Syongari const uint8_t *text; 187200548Syongari uint32_t textsz; 188200548Syongari const uint8_t *data; 189135048Swpaul uint32_t datasz; 190135048Swpaul}; 191135048Swpaul 192135048Swpaulstruct iwn_fw_info { 193135048Swpaul const uint8_t *data; 194135048Swpaul size_t size; 195135048Swpaul struct iwn_fw_part init; 196135048Swpaul struct iwn_fw_part main; 197135048Swpaul struct iwn_fw_part boot; 198135048Swpaul}; 199135048Swpaul 200135048Swpaulstruct iwn_ops { 201135048Swpaul int (*load_firmware)(struct iwn_softc *); 202135048Swpaul void (*read_eeprom)(struct iwn_softc *); 203135048Swpaul int (*post_alive)(struct iwn_softc *); 204135048Swpaul int (*nic_config)(struct iwn_softc *); 205135048Swpaul void (*update_sched)(struct iwn_softc *, int, int, uint8_t, 206135048Swpaul uint16_t); 207135048Swpaul int (*get_temperature)(struct iwn_softc *); 208135048Swpaul int (*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *); 209135048Swpaul int (*set_txpower)(struct iwn_softc *, 210135048Swpaul struct ieee80211_channel *, int); 211135048Swpaul int (*init_gains)(struct iwn_softc *); 212135048Swpaul int (*set_gains)(struct iwn_softc *); 213135048Swpaul int (*add_node)(struct iwn_softc *, struct iwn_node_info *, 214135048Swpaul int); 215135048Swpaul void (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *, 216135048Swpaul struct iwn_rx_data *); 217135048Swpaul void (*ampdu_tx_start)(struct iwn_softc *, 218135048Swpaul struct ieee80211_node *, int, uint8_t, uint16_t); 219135048Swpaul void (*ampdu_tx_stop)(struct iwn_softc *, int, uint8_t, 220135048Swpaul uint16_t); 221135048Swpaul}; 222145520Swpaul 223135048Swpaulstruct iwn_vap { 224135048Swpaul struct ieee80211vap iv_vap; 225135048Swpaul uint8_t iv_ridx; 226135048Swpaul 227200533Syongari int (*iv_newstate)(struct ieee80211vap *, 228135048Swpaul enum ieee80211_state, int); 229200536Syongari int ctx; 230200536Syongari int beacon_int; 231135048Swpaul uint8_t macaddr[IEEE80211_ADDR_LEN]; 232135048Swpaul 233135048Swpaul}; 234135048Swpaul#define IWN_VAP(_vap) ((struct iwn_vap *)(_vap)) 235135048Swpaul 236135048Swpaulstruct iwn_softc { 237135048Swpaul device_t sc_dev; 238135048Swpaul 239135048Swpaul struct ifnet *sc_ifp; 240135048Swpaul int sc_debug; 241135048Swpaul 242135048Swpaul struct mtx sc_mtx; 243135048Swpaul 244135048Swpaul u_int sc_flags; 245135048Swpaul#define IWN_FLAG_HAS_OTPROM (1 << 1) 246135048Swpaul#define IWN_FLAG_CALIB_DONE (1 << 2) 247135048Swpaul#define IWN_FLAG_USE_ICT (1 << 3) 248135048Swpaul#define IWN_FLAG_INTERNAL_PA (1 << 4) 249135048Swpaul#define IWN_FLAG_HAS_11N (1 << 6) 250135048Swpaul#define IWN_FLAG_ENH_SENS (1 << 7) 251135048Swpaul#define IWN_FLAG_ADV_BTCOEX (1 << 8) 252135048Swpaul#define IWN_FLAG_PAN_SUPPORT (1 << 9) 253135048Swpaul#define IWN_FLAG_BTCOEX (1 << 10) 254135048Swpaul 255135048Swpaul uint8_t hw_type; 256135048Swpaul /* subdevice_id used to adjust configuration */ 257135048Swpaul uint16_t subdevice_id; 258135048Swpaul 259135048Swpaul struct iwn_ops ops; 260135048Swpaul const char *fwname; 261135048Swpaul const struct iwn_sensitivity_limits 262135048Swpaul *limits; 263135048Swpaul int ntxqs; 264135048Swpaul int firstaggqueue; 265135048Swpaul int ndmachnls; 266135048Swpaul uint8_t broadcast_id; 267145520Swpaul int rxonsz; 268135048Swpaul int schedsz; 269135048Swpaul uint32_t fw_text_maxsz; 270135048Swpaul uint32_t fw_data_maxsz; 271135048Swpaul uint32_t fwsz; 272135048Swpaul bus_size_t sched_txfact_addr; 273200531Syongari uint32_t reset_noise_gain; 274135048Swpaul uint32_t noise_gain; 275200536Syongari 276145520Swpaul /* TX scheduler rings. */ 277200536Syongari struct iwn_dma_info sched_dma; 278135048Swpaul uint16_t *sched; 279135048Swpaul uint32_t sched_base; 280135048Swpaul 281200533Syongari /* "Keep Warm" page. */ 282135048Swpaul struct iwn_dma_info kw_dma; 283135048Swpaul 284135048Swpaul /* Firmware image. */ 285135048Swpaul const struct firmware *fw_fp; 286135048Swpaul 287145520Swpaul /* Firmware DMA transfer. */ 288145520Swpaul struct iwn_dma_info fw_dma; 289145520Swpaul 290145520Swpaul /* ICT table. */ 291135048Swpaul struct iwn_dma_info ict_dma; 292135048Swpaul uint32_t *ict; 293135048Swpaul int ict_cur; 294200531Syongari 295135048Swpaul /* TX/RX rings. */ 296200536Syongari struct iwn_tx_ring txq[IWN5000_NTXQUEUES]; 297135048Swpaul struct iwn_rx_ring rxq; 298135048Swpaul 299135048Swpaul struct resource *mem; 300135048Swpaul bus_space_tag_t sc_st; 301135048Swpaul bus_space_handle_t sc_sh; 302135048Swpaul struct resource *irq; 303135048Swpaul void *sc_ih; 304135048Swpaul bus_size_t sc_sz; 305135048Swpaul int sc_cap_off; /* PCIe Capabilities. */ 306135048Swpaul 307135048Swpaul /* Tasks used by the driver */ 308135048Swpaul struct task sc_reinit_task; 309135048Swpaul struct task sc_radioon_task; 310135048Swpaul struct task sc_radiooff_task; 311200531Syongari 312135048Swpaul /* Calibration information */ 313200536Syongari struct callout calib_to; 314135048Swpaul int calib_cnt; 315135048Swpaul struct iwn_calib_state calib; 316135048Swpaul int last_calib_ticks; 317135048Swpaul struct callout watchdog_to; 318135048Swpaul struct callout ct_kill_exit_to; 319135048Swpaul struct iwn_fw_info fw; 320135048Swpaul struct iwn_calib_info calibcmd[IWN5000_PHY_CALIB_MAX_RESULT]; 321135048Swpaul uint32_t errptr; 322135048Swpaul 323135048Swpaul struct iwn_rx_stat last_rx_stat; 324135048Swpaul int last_rx_valid; 325135048Swpaul struct iwn_ucode_info ucode_info; 326135048Swpaul struct iwn_rxon rx_on[IWN_NUM_RXON_CTX]; 327135048Swpaul struct iwn_rxon *rxon; 328135048Swpaul int ctx; 329135048Swpaul struct ieee80211vap *ivap[IWN_NUM_RXON_CTX]; 330135048Swpaul 331135048Swpaul /* General statistics */ 332135048Swpaul /* 333135048Swpaul * The statistics are reset after each channel 334135048Swpaul * change. So it may be zeroed after things like 335135048Swpaul * a background scan. 336135048Swpaul * 337135048Swpaul * So for now, this is just a cheap hack to 338135048Swpaul * expose the last received statistics dump 339135048Swpaul * via an ioctl(). Later versions of this 340135048Swpaul * could expose the last 'n' messages, or just 341135048Swpaul * provide a pipeline for the firmware responses 342135048Swpaul * via something like BPF. 343135048Swpaul */ 344135048Swpaul struct iwn_stats last_stat; 345135048Swpaul int last_stat_valid; 346135048Swpaul 347135048Swpaul uint8_t uc_scan_progress; 348200531Syongari uint32_t rawtemp; 349135048Swpaul int temp; 350200536Syongari int noise; 351200536Syongari uint32_t qfullmsk; 352200536Syongari 353135048Swpaul uint32_t prom_base; 354135048Swpaul struct iwn4965_eeprom_band 355135048Swpaul bands[IWN_NBANDS]; 356200540Syongari struct iwn_eeprom_chan eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND]; 357200536Syongari uint16_t rfcfg; 358135048Swpaul uint8_t calib_ver; 359135048Swpaul char eeprom_domain[4]; 360135048Swpaul uint32_t eeprom_crystal; 361135048Swpaul int16_t eeprom_temp; 362135048Swpaul int16_t eeprom_temp_high; 363135048Swpaul int16_t eeprom_voltage; 364135048Swpaul int8_t maxpwr2GHz; 365135048Swpaul int8_t maxpwr5GHz; 366135048Swpaul int8_t maxpwr[IEEE80211_CHAN_MAX]; 367135048Swpaul 368135048Swpaul uint32_t tlv_feature_flags; 369135048Swpaul 370135048Swpaul int32_t temp_off; 371135048Swpaul uint32_t int_mask; 372135048Swpaul uint8_t ntxchains; 373135048Swpaul uint8_t nrxchains; 374135048Swpaul uint8_t txchainmask; 375135048Swpaul uint8_t rxchainmask; 376135048Swpaul uint8_t chainmask; 377135048Swpaul 378135048Swpaul int sc_tx_timer; 379135048Swpaul int sc_scan_timer; 380135048Swpaul 381135048Swpaul /* Are we doing a scan? */ 382135048Swpaul int sc_is_scanning; 383135048Swpaul 384135048Swpaul struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES]; 385200531Syongari 386135048Swpaul int (*sc_ampdu_rx_start)(struct ieee80211_node *, 387200536Syongari struct ieee80211_rx_ampdu *, int, int, int); 388200536Syongari void (*sc_ampdu_rx_stop)(struct ieee80211_node *, 389135048Swpaul struct ieee80211_rx_ampdu *); 390135048Swpaul int (*sc_addba_request)(struct ieee80211_node *, 391135048Swpaul struct ieee80211_tx_ampdu *, int, int, int); 392200540Syongari int (*sc_addba_response)(struct ieee80211_node *, 393200536Syongari struct ieee80211_tx_ampdu *, int, int, int); 394135048Swpaul void (*sc_addba_stop)(struct ieee80211_node *, 395135048Swpaul struct ieee80211_tx_ampdu *); 396135048Swpaul 397135048Swpaul struct iwn_led_mode sc_led; 398135048Swpaul 399135048Swpaul struct iwn_rx_radiotap_header sc_rxtap; 400135048Swpaul struct iwn_tx_radiotap_header sc_txtap; 401135048Swpaul 402135048Swpaul /* The power save level originally configured by user */ 403135048Swpaul int desired_pwrsave_level; 404135048Swpaul 405135048Swpaul /* 406135048Swpaul * The current power save level, this may differ from the 407135048Swpaul * configured value due to thermal throttling etc. 408135048Swpaul */ 409135048Swpaul int current_pwrsave_level; 410135048Swpaul 411135048Swpaul /* For specific params */ 412135048Swpaul const struct iwn_base_params *base_params; 413135048Swpaul}; 414135048Swpaul 415135048Swpaul#define IWN_LOCK_INIT(_sc) \ 416135048Swpaul mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 417135048Swpaul MTX_NETWORK_LOCK, MTX_DEF) 418135048Swpaul#define IWN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 419135048Swpaul#define IWN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 420135048Swpaul#define IWN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 421135048Swpaul#define IWN_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 422135048Swpaul