if_iwnvar.h revision 284588
1178676Ssam/* $FreeBSD: head/sys/dev/iwn/if_iwnvar.h 284588 2015-06-19 01:44:17Z adrian $ */ 2210111Sbschmidt/* $OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $ */ 3198429Srpaulo 4178676Ssam/*- 5254204Sadrian * Copyright (c) 2013 Cedric GROSS <cg@cgross.info> 6254204Sadrian * Copyright (c) 2011 Intel Corporation 7198429Srpaulo * Copyright (c) 2007, 2008 8178676Ssam * Damien Bergamini <damien.bergamini@free.fr> 9178676Ssam * Copyright (c) 2008 Sam Leffler, Errno Consulting 10178676Ssam * 11178676Ssam * Permission to use, copy, modify, and distribute this software for any 12178676Ssam * purpose with or without fee is hereby granted, provided that the above 13178676Ssam * copyright notice and this permission notice appear in all copies. 14178676Ssam * 15178676Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16178676Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17178676Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18178676Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19178676Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20178676Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21178676Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22178676Ssam */ 23254204Sadrianenum iwn_rxon_ctx_id { 24254204Sadrian IWN_RXON_BSS_CTX, 25254204Sadrian IWN_RXON_PAN_CTX, 26254204Sadrian IWN_NUM_RXON_CTX 27254204Sadrian}; 28178676Ssam 29254204Sadrianstruct iwn_pan_slot { 30254204Sadrian uint16_t time; 31254204Sadrian uint8_t type; 32254204Sadrian uint8_t reserved; 33254204Sadrian} __packed; 34254204Sadrian 35254204Sadrianstruct iwn_pan_params_cmd { 36254204Sadrian uint16_t flags; 37254204Sadrian#define IWN_PAN_PARAMS_FLG_SLOTTED_MODE (1 << 3) 38254204Sadrian 39254204Sadrian uint8_t reserved; 40254204Sadrian uint8_t num_slots; 41254204Sadrian struct iwn_pan_slot slots[10]; 42254204Sadrian} __packed; 43254204Sadrian 44254204Sadrianstruct iwn_led_mode 45254204Sadrian{ 46254204Sadrian uint8_t led_cur_mode; 47254204Sadrian uint64_t led_cur_bt; 48254204Sadrian uint64_t led_last_bt; 49254204Sadrian uint64_t led_cur_tpt; 50254204Sadrian uint64_t led_last_tpt; 51254204Sadrian uint64_t led_bt_diff; 52254204Sadrian int led_cur_time; 53254204Sadrian int led_last_time; 54254204Sadrian}; 55254204Sadrian 56178676Ssamstruct iwn_rx_radiotap_header { 57178676Ssam struct ieee80211_radiotap_header wr_ihdr; 58178676Ssam uint64_t wr_tsft; 59178676Ssam uint8_t wr_flags; 60178676Ssam uint8_t wr_rate; 61178676Ssam uint16_t wr_chan_freq; 62178676Ssam uint16_t wr_chan_flags; 63178676Ssam int8_t wr_dbm_antsignal; 64178676Ssam int8_t wr_dbm_antnoise; 65178676Ssam} __packed; 66178676Ssam 67178676Ssam#define IWN_RX_RADIOTAP_PRESENT \ 68178676Ssam ((1 << IEEE80211_RADIOTAP_TSFT) | \ 69178676Ssam (1 << IEEE80211_RADIOTAP_FLAGS) | \ 70178676Ssam (1 << IEEE80211_RADIOTAP_RATE) | \ 71178676Ssam (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 72178676Ssam (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 73178676Ssam (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 74178676Ssam 75178676Ssamstruct iwn_tx_radiotap_header { 76178676Ssam struct ieee80211_radiotap_header wt_ihdr; 77178676Ssam uint8_t wt_flags; 78178676Ssam uint8_t wt_rate; 79178676Ssam uint16_t wt_chan_freq; 80178676Ssam uint16_t wt_chan_flags; 81178676Ssam} __packed; 82178676Ssam 83178676Ssam#define IWN_TX_RADIOTAP_PRESENT \ 84178676Ssam ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 85178676Ssam (1 << IEEE80211_RADIOTAP_RATE) | \ 86178676Ssam (1 << IEEE80211_RADIOTAP_CHANNEL)) 87178676Ssam 88178676Ssamstruct iwn_dma_info { 89178676Ssam bus_dma_tag_t tag; 90178676Ssam bus_dmamap_t map; 91178676Ssam bus_dma_segment_t seg; 92178676Ssam bus_addr_t paddr; 93178676Ssam caddr_t vaddr; 94178676Ssam bus_size_t size; 95178676Ssam}; 96178676Ssam 97178676Ssamstruct iwn_tx_data { 98178676Ssam bus_dmamap_t map; 99198429Srpaulo bus_addr_t cmd_paddr; 100198429Srpaulo bus_addr_t scratch_paddr; 101178676Ssam struct mbuf *m; 102178676Ssam struct ieee80211_node *ni; 103178676Ssam}; 104178676Ssam 105178676Ssamstruct iwn_tx_ring { 106178676Ssam struct iwn_dma_info desc_dma; 107178676Ssam struct iwn_dma_info cmd_dma; 108178676Ssam struct iwn_tx_desc *desc; 109178676Ssam struct iwn_tx_cmd *cmd; 110178676Ssam struct iwn_tx_data data[IWN_TX_RING_COUNT]; 111201209Srpaulo bus_dma_tag_t data_dmat; 112178676Ssam int qid; 113178676Ssam int queued; 114178676Ssam int cur; 115221651Sbschmidt int read; 116178676Ssam}; 117178676Ssam 118198429Srpaulostruct iwn_softc; 119198429Srpaulo 120178676Ssamstruct iwn_rx_data { 121198429Srpaulo struct mbuf *m; 122198429Srpaulo bus_dmamap_t map; 123178676Ssam}; 124178676Ssam 125178676Ssamstruct iwn_rx_ring { 126178676Ssam struct iwn_dma_info desc_dma; 127198429Srpaulo struct iwn_dma_info stat_dma; 128178676Ssam uint32_t *desc; 129198429Srpaulo struct iwn_rx_status *stat; 130178676Ssam struct iwn_rx_data data[IWN_RX_RING_COUNT]; 131201209Srpaulo bus_dma_tag_t data_dmat; 132178676Ssam int cur; 133178676Ssam}; 134178676Ssam 135178676Ssamstruct iwn_node { 136178676Ssam struct ieee80211_node ni; /* must be the first */ 137198429Srpaulo uint16_t disable_tid; 138198429Srpaulo uint8_t id; 139221651Sbschmidt struct { 140221651Sbschmidt uint64_t bitmap; 141221651Sbschmidt int startidx; 142221651Sbschmidt int nframes; 143221651Sbschmidt } agg[IEEE80211_TID_SIZE]; 144178676Ssam}; 145178676Ssam 146178676Ssamstruct iwn_calib_state { 147178676Ssam uint8_t state; 148178676Ssam#define IWN_CALIB_STATE_INIT 0 149178676Ssam#define IWN_CALIB_STATE_ASSOC 1 150178676Ssam#define IWN_CALIB_STATE_RUN 2 151198429Srpaulo 152178676Ssam u_int nbeacons; 153178676Ssam uint32_t noise[3]; 154178676Ssam uint32_t rssi[3]; 155198429Srpaulo uint32_t ofdm_x1; 156198429Srpaulo uint32_t ofdm_mrc_x1; 157198429Srpaulo uint32_t ofdm_x4; 158198429Srpaulo uint32_t ofdm_mrc_x4; 159198429Srpaulo uint32_t cck_x4; 160198429Srpaulo uint32_t cck_mrc_x4; 161178676Ssam uint32_t bad_plcp_ofdm; 162178676Ssam uint32_t fa_ofdm; 163178676Ssam uint32_t bad_plcp_cck; 164178676Ssam uint32_t fa_cck; 165178676Ssam uint32_t low_fa; 166259061Sadrian uint32_t bad_plcp_ht; 167178676Ssam uint8_t cck_state; 168178676Ssam#define IWN_CCK_STATE_INIT 0 169178676Ssam#define IWN_CCK_STATE_LOFA 1 170178676Ssam#define IWN_CCK_STATE_HIFA 2 171198429Srpaulo 172178676Ssam uint8_t noise_samples[20]; 173178676Ssam u_int cur_noise_sample; 174178676Ssam uint8_t noise_ref; 175178676Ssam uint32_t energy_samples[10]; 176178676Ssam u_int cur_energy_sample; 177178676Ssam uint32_t energy_cck; 178178676Ssam}; 179178676Ssam 180198429Srpaulostruct iwn_calib_info { 181198429Srpaulo uint8_t *buf; 182198429Srpaulo u_int len; 183198429Srpaulo}; 184198429Srpaulo 185198429Srpaulostruct iwn_fw_part { 186198429Srpaulo const uint8_t *text; 187198429Srpaulo uint32_t textsz; 188198429Srpaulo const uint8_t *data; 189198429Srpaulo uint32_t datasz; 190198429Srpaulo}; 191198429Srpaulo 192198429Srpaulostruct iwn_fw_info { 193210111Sbschmidt const uint8_t *data; 194210111Sbschmidt size_t size; 195198429Srpaulo struct iwn_fw_part init; 196198429Srpaulo struct iwn_fw_part main; 197198429Srpaulo struct iwn_fw_part boot; 198198429Srpaulo}; 199198429Srpaulo 200220728Sbschmidtstruct iwn_ops { 201198429Srpaulo int (*load_firmware)(struct iwn_softc *); 202198429Srpaulo void (*read_eeprom)(struct iwn_softc *); 203198429Srpaulo int (*post_alive)(struct iwn_softc *); 204198429Srpaulo int (*nic_config)(struct iwn_softc *); 205198429Srpaulo void (*update_sched)(struct iwn_softc *, int, int, uint8_t, 206198429Srpaulo uint16_t); 207198429Srpaulo int (*get_temperature)(struct iwn_softc *); 208198429Srpaulo int (*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *); 209201882Skeramida int (*set_txpower)(struct iwn_softc *, 210201882Skeramida struct ieee80211_channel *, int); 211198429Srpaulo int (*init_gains)(struct iwn_softc *); 212198429Srpaulo int (*set_gains)(struct iwn_softc *); 213198429Srpaulo int (*add_node)(struct iwn_softc *, struct iwn_node_info *, 214198429Srpaulo int); 215198429Srpaulo void (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *, 216198429Srpaulo struct iwn_rx_data *); 217201209Srpaulo void (*ampdu_tx_start)(struct iwn_softc *, 218221651Sbschmidt struct ieee80211_node *, int, uint8_t, uint16_t); 219221651Sbschmidt void (*ampdu_tx_stop)(struct iwn_softc *, int, uint8_t, 220201209Srpaulo uint16_t); 221198429Srpaulo}; 222198429Srpaulo 223178676Ssamstruct iwn_vap { 224178676Ssam struct ieee80211vap iv_vap; 225198429Srpaulo uint8_t iv_ridx; 226178676Ssam 227178676Ssam int (*iv_newstate)(struct ieee80211vap *, 228178676Ssam enum ieee80211_state, int); 229254204Sadrian int ctx; 230254204Sadrian int beacon_int; 231254204Sadrian uint8_t macaddr[IEEE80211_ADDR_LEN]; 232254204Sadrian 233178676Ssam}; 234178676Ssam#define IWN_VAP(_vap) ((struct iwn_vap *)(_vap)) 235178676Ssam 236178676Ssamstruct iwn_softc { 237220726Sbschmidt device_t sc_dev; 238220723Sbschmidt 239178676Ssam struct ifnet *sc_ifp; 240178676Ssam int sc_debug; 241178676Ssam 242178676Ssam struct mtx sc_mtx; 243178676Ssam 244198429Srpaulo u_int sc_flags; 245198429Srpaulo#define IWN_FLAG_HAS_OTPROM (1 << 1) 246201209Srpaulo#define IWN_FLAG_CALIB_DONE (1 << 2) 247201209Srpaulo#define IWN_FLAG_USE_ICT (1 << 3) 248201209Srpaulo#define IWN_FLAG_INTERNAL_PA (1 << 4) 249220729Sbschmidt#define IWN_FLAG_HAS_11N (1 << 6) 250220729Sbschmidt#define IWN_FLAG_ENH_SENS (1 << 7) 251220891Sbschmidt#define IWN_FLAG_ADV_BTCOEX (1 << 8) 252254204Sadrian#define IWN_FLAG_PAN_SUPPORT (1 << 9) 253257134Sadrian#define IWN_FLAG_BTCOEX (1 << 10) 254178676Ssam 255198429Srpaulo uint8_t hw_type; 256254204Sadrian /* subdevice_id used to adjust configuration */ 257254204Sadrian uint16_t subdevice_id; 258220728Sbschmidt 259220728Sbschmidt struct iwn_ops ops; 260198429Srpaulo const char *fwname; 261201209Srpaulo const struct iwn_sensitivity_limits 262201209Srpaulo *limits; 263220728Sbschmidt int ntxqs; 264221651Sbschmidt int firstaggqueue; 265220728Sbschmidt int ndmachnls; 266220728Sbschmidt uint8_t broadcast_id; 267220728Sbschmidt int rxonsz; 268220728Sbschmidt int schedsz; 269220728Sbschmidt uint32_t fw_text_maxsz; 270220728Sbschmidt uint32_t fw_data_maxsz; 271220728Sbschmidt uint32_t fwsz; 272220728Sbschmidt bus_size_t sched_txfact_addr; 273220866Sbschmidt uint32_t reset_noise_gain; 274220866Sbschmidt uint32_t noise_gain; 275198429Srpaulo 276198429Srpaulo /* TX scheduler rings. */ 277198429Srpaulo struct iwn_dma_info sched_dma; 278198429Srpaulo uint16_t *sched; 279198429Srpaulo uint32_t sched_base; 280198429Srpaulo 281198429Srpaulo /* "Keep Warm" page. */ 282178676Ssam struct iwn_dma_info kw_dma; 283178676Ssam 284198429Srpaulo /* Firmware image. */ 285178676Ssam const struct firmware *fw_fp; 286178676Ssam 287198429Srpaulo /* Firmware DMA transfer. */ 288178676Ssam struct iwn_dma_info fw_dma; 289178676Ssam 290201209Srpaulo /* ICT table. */ 291201209Srpaulo struct iwn_dma_info ict_dma; 292201209Srpaulo uint32_t *ict; 293201209Srpaulo int ict_cur; 294201209Srpaulo 295198429Srpaulo /* TX/RX rings. */ 296198429Srpaulo struct iwn_tx_ring txq[IWN5000_NTXQUEUES]; 297178676Ssam struct iwn_rx_ring rxq; 298178676Ssam 299220726Sbschmidt struct resource *mem; 300178676Ssam bus_space_tag_t sc_st; 301178676Ssam bus_space_handle_t sc_sh; 302220723Sbschmidt struct resource *irq; 303178676Ssam void *sc_ih; 304178676Ssam bus_size_t sc_sz; 305198429Srpaulo int sc_cap_off; /* PCIe Capabilities. */ 306178676Ssam 307178676Ssam /* Tasks used by the driver */ 308220726Sbschmidt struct task sc_reinit_task; 309191746Sthompsa struct task sc_radioon_task; 310191746Sthompsa struct task sc_radiooff_task; 311266546Strasz struct task sc_panic_task; 312284588Sadrian struct task sc_xmit_task; 313201209Srpaulo 314266546Strasz /* Taskqueue */ 315266546Strasz struct taskqueue *sc_tq; 316266546Strasz 317259061Sadrian /* Calibration information */ 318220667Sbschmidt struct callout calib_to; 319178676Ssam int calib_cnt; 320178676Ssam struct iwn_calib_state calib; 321259061Sadrian int last_calib_ticks; 322220667Sbschmidt struct callout watchdog_to; 323254204Sadrian struct callout ct_kill_exit_to; 324198429Srpaulo struct iwn_fw_info fw; 325258035Sadrian struct iwn_calib_info calibcmd[IWN5000_PHY_CALIB_MAX_RESULT]; 326198429Srpaulo uint32_t errptr; 327198429Srpaulo 328178676Ssam struct iwn_rx_stat last_rx_stat; 329178676Ssam int last_rx_valid; 330178676Ssam struct iwn_ucode_info ucode_info; 331254204Sadrian struct iwn_rxon rx_on[IWN_NUM_RXON_CTX]; 332254204Sadrian struct iwn_rxon *rxon; 333254204Sadrian int ctx; 334254204Sadrian struct ieee80211vap *ivap[IWN_NUM_RXON_CTX]; 335254204Sadrian 336262422Sadrian /* General statistics */ 337262422Sadrian /* 338262422Sadrian * The statistics are reset after each channel 339262422Sadrian * change. So it may be zeroed after things like 340262422Sadrian * a background scan. 341262422Sadrian * 342262422Sadrian * So for now, this is just a cheap hack to 343262422Sadrian * expose the last received statistics dump 344262422Sadrian * via an ioctl(). Later versions of this 345262422Sadrian * could expose the last 'n' messages, or just 346262422Sadrian * provide a pipeline for the firmware responses 347262422Sadrian * via something like BPF. 348262422Sadrian */ 349262422Sadrian struct iwn_stats last_stat; 350262422Sadrian int last_stat_valid; 351262422Sadrian 352254204Sadrian uint8_t uc_scan_progress; 353178676Ssam uint32_t rawtemp; 354178676Ssam int temp; 355178676Ssam int noise; 356198429Srpaulo uint32_t qfullmsk; 357178676Ssam 358201209Srpaulo uint32_t prom_base; 359198429Srpaulo struct iwn4965_eeprom_band 360198429Srpaulo bands[IWN_NBANDS]; 361201209Srpaulo struct iwn_eeprom_chan eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND]; 362198429Srpaulo uint16_t rfcfg; 363206444Sbschmidt uint8_t calib_ver; 364198429Srpaulo char eeprom_domain[4]; 365220674Sbschmidt uint32_t eeprom_crystal; 366220674Sbschmidt int16_t eeprom_temp; 367254204Sadrian int16_t eeprom_temp_high; 368178676Ssam int16_t eeprom_voltage; 369178676Ssam int8_t maxpwr2GHz; 370178676Ssam int8_t maxpwr5GHz; 371198429Srpaulo int8_t maxpwr[IEEE80211_CHAN_MAX]; 372198429Srpaulo 373254204Sadrian uint32_t tlv_feature_flags; 374254204Sadrian 375201209Srpaulo int32_t temp_off; 376201209Srpaulo uint32_t int_mask; 377198429Srpaulo uint8_t ntxchains; 378198429Srpaulo uint8_t nrxchains; 379201209Srpaulo uint8_t txchainmask; 380201209Srpaulo uint8_t rxchainmask; 381201209Srpaulo uint8_t chainmask; 382198429Srpaulo 383198429Srpaulo int sc_tx_timer; 384254204Sadrian int sc_scan_timer; 385198429Srpaulo 386258829Sadrian /* Are we doing a scan? */ 387258829Sadrian int sc_is_scanning; 388258829Sadrian 389284588Sadrian /* Are we waiting for a beacon before xmit? */ 390284588Sadrian int sc_beacon_wait; 391284588Sadrian 392221651Sbschmidt struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES]; 393221651Sbschmidt 394221650Sbschmidt int (*sc_ampdu_rx_start)(struct ieee80211_node *, 395221650Sbschmidt struct ieee80211_rx_ampdu *, int, int, int); 396221650Sbschmidt void (*sc_ampdu_rx_stop)(struct ieee80211_node *, 397221650Sbschmidt struct ieee80211_rx_ampdu *); 398221651Sbschmidt int (*sc_addba_request)(struct ieee80211_node *, 399221651Sbschmidt struct ieee80211_tx_ampdu *, int, int, int); 400221651Sbschmidt int (*sc_addba_response)(struct ieee80211_node *, 401221651Sbschmidt struct ieee80211_tx_ampdu *, int, int, int); 402221651Sbschmidt void (*sc_addba_stop)(struct ieee80211_node *, 403221651Sbschmidt struct ieee80211_tx_ampdu *); 404221650Sbschmidt 405254204Sadrian struct iwn_led_mode sc_led; 406221651Sbschmidt 407198429Srpaulo struct iwn_rx_radiotap_header sc_rxtap; 408198429Srpaulo struct iwn_tx_radiotap_header sc_txtap; 409254204Sadrian 410254204Sadrian /* The power save level originally configured by user */ 411254204Sadrian int desired_pwrsave_level; 412254204Sadrian 413254204Sadrian /* 414254204Sadrian * The current power save level, this may differ from the 415254204Sadrian * configured value due to thermal throttling etc. 416254204Sadrian */ 417254204Sadrian int current_pwrsave_level; 418254204Sadrian 419258035Sadrian /* For specific params */ 420258035Sadrian const struct iwn_base_params *base_params; 421270738Sadrian 422270738Sadrian#define IWN_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) 423270738Sadrian uint32_t ucode_rev; 424284588Sadrian 425284588Sadrian /* 426284588Sadrian * Global queue for queuing xmit frames 427284588Sadrian * when we can't yet transmit (eg raw 428284588Sadrian * frames whilst waiting for beacons.) 429284588Sadrian */ 430284588Sadrian struct mbufq sc_xmit_queue; 431178676Ssam}; 432178676Ssam 433178676Ssam#define IWN_LOCK_INIT(_sc) \ 434178676Ssam mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 435210108Sbschmidt MTX_NETWORK_LOCK, MTX_DEF) 436178676Ssam#define IWN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 437178676Ssam#define IWN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 438178676Ssam#define IWN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 439178676Ssam#define IWN_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 440