1*1fdfd19eSstsp /* $OpenBSD: if_iwnvar.h,v 1.42 2021/11/12 11:41:04 stsp Exp $ */ 2fb942e08Sdamien 3fb942e08Sdamien /*- 41b861c8bSdamien * Copyright (c) 2007, 2008 5fb942e08Sdamien * Damien Bergamini <damien.bergamini@free.fr> 6fb942e08Sdamien * 7fb942e08Sdamien * Permission to use, copy, modify, and distribute this software for any 8fb942e08Sdamien * purpose with or without fee is hereby granted, provided that the above 9fb942e08Sdamien * copyright notice and this permission notice appear in all copies. 10fb942e08Sdamien * 11fb942e08Sdamien * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12fb942e08Sdamien * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13fb942e08Sdamien * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14fb942e08Sdamien * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15fb942e08Sdamien * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16fb942e08Sdamien * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17fb942e08Sdamien * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18fb942e08Sdamien */ 19fb942e08Sdamien 20fb942e08Sdamien struct iwn_rx_radiotap_header { 21fb942e08Sdamien struct ieee80211_radiotap_header wr_ihdr; 22fb942e08Sdamien uint64_t wr_tsft; 23fb942e08Sdamien uint8_t wr_flags; 24fb942e08Sdamien uint8_t wr_rate; 25fb942e08Sdamien uint16_t wr_chan_freq; 26fb942e08Sdamien uint16_t wr_chan_flags; 27fb942e08Sdamien int8_t wr_dbm_antsignal; 28fb942e08Sdamien int8_t wr_dbm_antnoise; 29fb942e08Sdamien } __packed; 30fb942e08Sdamien 31fb942e08Sdamien #define IWN_RX_RADIOTAP_PRESENT \ 32fb942e08Sdamien ((1 << IEEE80211_RADIOTAP_TSFT) | \ 33fb942e08Sdamien (1 << IEEE80211_RADIOTAP_FLAGS) | \ 34fb942e08Sdamien (1 << IEEE80211_RADIOTAP_RATE) | \ 35fb942e08Sdamien (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 36fb942e08Sdamien (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 37fb942e08Sdamien (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 38fb942e08Sdamien 39fb942e08Sdamien struct iwn_tx_radiotap_header { 40fb942e08Sdamien struct ieee80211_radiotap_header wt_ihdr; 41fb942e08Sdamien uint8_t wt_flags; 42fb942e08Sdamien uint8_t wt_rate; 43fb942e08Sdamien uint16_t wt_chan_freq; 44fb942e08Sdamien uint16_t wt_chan_flags; 45fb942e08Sdamien } __packed; 46fb942e08Sdamien 47fb942e08Sdamien #define IWN_TX_RADIOTAP_PRESENT \ 48fb942e08Sdamien ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 49fb942e08Sdamien (1 << IEEE80211_RADIOTAP_RATE) | \ 50eb1adcecSmpi (1 << IEEE80211_RADIOTAP_CHANNEL)) 51fb942e08Sdamien 52fb942e08Sdamien struct iwn_dma_info { 53fb942e08Sdamien bus_dma_tag_t tag; 54fb942e08Sdamien bus_dmamap_t map; 55fb942e08Sdamien bus_dma_segment_t seg; 56fb942e08Sdamien bus_addr_t paddr; 57fb942e08Sdamien caddr_t vaddr; 58fb942e08Sdamien bus_size_t size; 59fb942e08Sdamien }; 60fb942e08Sdamien 61fb942e08Sdamien struct iwn_tx_data { 62fb942e08Sdamien bus_dmamap_t map; 631b861c8bSdamien bus_addr_t cmd_paddr; 641b861c8bSdamien bus_addr_t scratch_paddr; 65fb942e08Sdamien struct mbuf *m; 66fb942e08Sdamien struct ieee80211_node *ni; 679b5eab13Sstsp int totlen; 687af7732eSstsp 697af7732eSstsp /* A-MPDU subframes */ 707af7732eSstsp int ampdu_txmcs; 717af7732eSstsp int ampdu_nframes; 72fb942e08Sdamien }; 73fb942e08Sdamien 74fb942e08Sdamien struct iwn_tx_ring { 75fb942e08Sdamien struct iwn_dma_info desc_dma; 76fb942e08Sdamien struct iwn_dma_info cmd_dma; 77fb942e08Sdamien struct iwn_tx_desc *desc; 78fb942e08Sdamien struct iwn_tx_cmd *cmd; 7965beb95eSdamien struct iwn_tx_data data[IWN_TX_RING_COUNT]; 80fb942e08Sdamien int qid; 81fb942e08Sdamien int queued; 82fb942e08Sdamien int cur; 83aefc44daSstsp int read; 84fb942e08Sdamien }; 85fb942e08Sdamien 86fb942e08Sdamien struct iwn_softc; 87fb942e08Sdamien 88fb942e08Sdamien struct iwn_rx_data { 89fb942e08Sdamien struct mbuf *m; 9080586280Sdamien bus_dmamap_t map; 91fb942e08Sdamien }; 92fb942e08Sdamien 93fb942e08Sdamien struct iwn_rx_ring { 94fb942e08Sdamien struct iwn_dma_info desc_dma; 951b861c8bSdamien struct iwn_dma_info stat_dma; 96fb942e08Sdamien uint32_t *desc; 971b861c8bSdamien struct iwn_rx_status *stat; 98fb942e08Sdamien struct iwn_rx_data data[IWN_RX_RING_COUNT]; 99fb942e08Sdamien int cur; 100fb942e08Sdamien }; 101fb942e08Sdamien 102fb942e08Sdamien struct iwn_node { 103fb942e08Sdamien struct ieee80211_node ni; /* must be the first */ 104fb942e08Sdamien struct ieee80211_amrr_node amn; 105e3fcb18eSstsp struct ieee80211_ra_node rn; 1061b861c8bSdamien uint16_t disable_tid; 1071b861c8bSdamien uint8_t id; 108fa43bc10Sdamien uint8_t ridx[IEEE80211_RATE_MAXSIZE]; 1097af7732eSstsp uint32_t next_ampdu_id; 110e3fcb18eSstsp int lq_rate_mismatch; 111fb942e08Sdamien }; 112fb942e08Sdamien 113fb942e08Sdamien struct iwn_calib_state { 114fb942e08Sdamien uint8_t state; 115fb942e08Sdamien #define IWN_CALIB_STATE_INIT 0 116fb942e08Sdamien #define IWN_CALIB_STATE_ASSOC 1 117fb942e08Sdamien #define IWN_CALIB_STATE_RUN 2 118fb942e08Sdamien 119fb942e08Sdamien u_int nbeacons; 120fb942e08Sdamien uint32_t noise[3]; 121fb942e08Sdamien uint32_t rssi[3]; 1221b861c8bSdamien uint32_t ofdm_x1; 1231b861c8bSdamien uint32_t ofdm_mrc_x1; 1241b861c8bSdamien uint32_t ofdm_x4; 1251b861c8bSdamien uint32_t ofdm_mrc_x4; 1261b861c8bSdamien uint32_t cck_x4; 1271b861c8bSdamien uint32_t cck_mrc_x4; 128fb942e08Sdamien uint32_t bad_plcp_ofdm; 129fb942e08Sdamien uint32_t fa_ofdm; 130fb942e08Sdamien uint32_t bad_plcp_cck; 131fb942e08Sdamien uint32_t fa_cck; 132fb942e08Sdamien uint32_t low_fa; 133fb942e08Sdamien uint8_t cck_state; 134fb942e08Sdamien #define IWN_CCK_STATE_INIT 0 135fb942e08Sdamien #define IWN_CCK_STATE_LOFA 1 136fb942e08Sdamien #define IWN_CCK_STATE_HIFA 2 137fb942e08Sdamien 138fb942e08Sdamien uint8_t noise_samples[20]; 139fb942e08Sdamien u_int cur_noise_sample; 140fb942e08Sdamien uint8_t noise_ref; 141fb942e08Sdamien uint32_t energy_samples[10]; 142fb942e08Sdamien u_int cur_energy_sample; 143fb942e08Sdamien uint32_t energy_cck; 144fb942e08Sdamien }; 145fb942e08Sdamien 1461b861c8bSdamien struct iwn_calib_info { 1471b861c8bSdamien uint8_t *buf; 1481b861c8bSdamien u_int len; 1491b861c8bSdamien }; 1501b861c8bSdamien 1511b861c8bSdamien struct iwn_fw_part { 1521b861c8bSdamien const uint8_t *text; 1531b861c8bSdamien uint32_t textsz; 1541b861c8bSdamien const uint8_t *data; 1551b861c8bSdamien uint32_t datasz; 1561b861c8bSdamien }; 1571b861c8bSdamien 1581b861c8bSdamien struct iwn_fw_info { 1591b861c8bSdamien u_char *data; 160fa9d83bfSdamien size_t size; 1611b861c8bSdamien struct iwn_fw_part init; 1621b861c8bSdamien struct iwn_fw_part main; 1631b861c8bSdamien struct iwn_fw_part boot; 1641b861c8bSdamien }; 1651b861c8bSdamien 1660bfcb362Sdamien struct iwn_ops { 1671b861c8bSdamien int (*load_firmware)(struct iwn_softc *); 1681b861c8bSdamien void (*read_eeprom)(struct iwn_softc *); 1691b861c8bSdamien int (*post_alive)(struct iwn_softc *); 1701b861c8bSdamien int (*nic_config)(struct iwn_softc *); 171aefc44daSstsp void (*reset_sched)(struct iwn_softc *, int, int); 1721b861c8bSdamien void (*update_sched)(struct iwn_softc *, int, int, uint8_t, 1731b861c8bSdamien uint16_t); 174b630d526Sstsp void (*update_rxon)(struct iwn_softc *); 1751b861c8bSdamien int (*get_temperature)(struct iwn_softc *); 1761b861c8bSdamien int (*get_rssi)(const struct iwn_rx_stat *); 1771b861c8bSdamien int (*set_txpower)(struct iwn_softc *, int); 1781b861c8bSdamien int (*init_gains)(struct iwn_softc *); 1791b861c8bSdamien int (*set_gains)(struct iwn_softc *); 1801b861c8bSdamien int (*add_node)(struct iwn_softc *, struct iwn_node_info *, 1811b861c8bSdamien int); 18280586280Sdamien void (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *, 18380586280Sdamien struct iwn_rx_data *); 184fef5740dSdamien void (*ampdu_tx_start)(struct iwn_softc *, 185fef5740dSdamien struct ieee80211_node *, uint8_t, uint16_t); 186fef5740dSdamien void (*ampdu_tx_stop)(struct iwn_softc *, uint8_t, 187fef5740dSdamien uint16_t); 1881b861c8bSdamien }; 1891b861c8bSdamien 190aefc44daSstsp struct iwn_tx_ba { 191aefc44daSstsp struct iwn_node * wn; 192aefc44daSstsp }; 193aefc44daSstsp 194fb942e08Sdamien struct iwn_softc { 195fb942e08Sdamien struct device sc_dev; 196fb942e08Sdamien 197fb942e08Sdamien struct ieee80211com sc_ic; 198fb942e08Sdamien int (*sc_newstate)(struct ieee80211com *, 199fb942e08Sdamien enum ieee80211_state, int); 200fb942e08Sdamien 201fb942e08Sdamien struct ieee80211_amrr amrr; 20228f37d94Sdamien uint8_t fixed_ridx; 203fb942e08Sdamien 204fb942e08Sdamien bus_dma_tag_t sc_dmat; 205fb942e08Sdamien 20617776de2Stedu struct rwlock sc_rwlock; 2071b861c8bSdamien u_int sc_flags; 2081b861c8bSdamien #define IWN_FLAG_HAS_5GHZ (1 << 0) 209f7ad7bd6Sdamien #define IWN_FLAG_HAS_OTPROM (1 << 1) 210f16141c2Sdamien #define IWN_FLAG_CALIB_DONE (1 << 2) 211f16141c2Sdamien #define IWN_FLAG_USE_ICT (1 << 3) 21231ac8e91Sdamien #define IWN_FLAG_INTERNAL_PA (1 << 4) 2130bfcb362Sdamien #define IWN_FLAG_HAS_11N (1 << 6) 2140bfcb362Sdamien #define IWN_FLAG_ENH_SENS (1 << 7) 21585fae3c7Skettenis #define IWN_FLAG_ADV_BT_COEX (1 << 8) 216e38d2b44Sstsp #define IWN_FLAG_BGSCAN (1 << 9) 217afe2e7dfSstsp #define IWN_FLAG_SCANNING (1 << 10) 218fb942e08Sdamien 2191b861c8bSdamien uint8_t hw_type; 2200bfcb362Sdamien 2210bfcb362Sdamien struct iwn_ops ops; 222d7ad9b84Sdamien const char *fwname; 2238fcba7c3Sdamien const struct iwn_sensitivity_limits 2248fcba7c3Sdamien *limits; 2250bfcb362Sdamien int ntxqs; 226aefc44daSstsp int first_agg_txq; 227aefc44daSstsp int agg_queue_mask; 2280bfcb362Sdamien int ndmachnls; 2290bfcb362Sdamien uint8_t broadcast_id; 2300bfcb362Sdamien int rxonsz; 2310bfcb362Sdamien int schedsz; 2320bfcb362Sdamien uint32_t fw_text_maxsz; 2330bfcb362Sdamien uint32_t fw_data_maxsz; 2340bfcb362Sdamien uint32_t fwsz; 2350bfcb362Sdamien bus_size_t sched_txfact_addr; 2361b861c8bSdamien 2371b861c8bSdamien /* TX scheduler rings. */ 2381b861c8bSdamien struct iwn_dma_info sched_dma; 2391b861c8bSdamien uint16_t *sched; 2401b861c8bSdamien uint32_t sched_base; 2411b861c8bSdamien 2421b861c8bSdamien /* "Keep Warm" page. */ 243fb942e08Sdamien struct iwn_dma_info kw_dma; 244fb942e08Sdamien 2451b861c8bSdamien /* Firmware DMA transfer. */ 246fb942e08Sdamien struct iwn_dma_info fw_dma; 247fb942e08Sdamien 248f16141c2Sdamien /* ICT table. */ 249f16141c2Sdamien struct iwn_dma_info ict_dma; 250f16141c2Sdamien uint32_t *ict; 251f16141c2Sdamien int ict_cur; 252f16141c2Sdamien 2531b861c8bSdamien /* TX/RX rings. */ 2541b861c8bSdamien struct iwn_tx_ring txq[IWN5000_NTXQUEUES]; 255fb942e08Sdamien struct iwn_rx_ring rxq; 256fb942e08Sdamien 257fb942e08Sdamien bus_space_tag_t sc_st; 258fb942e08Sdamien bus_space_handle_t sc_sh; 259fb942e08Sdamien void *sc_ih; 260fb942e08Sdamien pci_chipset_tag_t sc_pct; 261fb942e08Sdamien pcitag_t sc_pcitag; 262fb942e08Sdamien bus_size_t sc_sz; 2631b861c8bSdamien int sc_cap_off; /* PCIe Capabilities. */ 264fb942e08Sdamien 265fb942e08Sdamien struct timeout calib_to; 266fb942e08Sdamien int calib_cnt; 267fb942e08Sdamien struct iwn_calib_state calib; 268fb942e08Sdamien 26907ecdf11Skettenis struct task init_task; 27007ecdf11Skettenis 2711b861c8bSdamien struct iwn_fw_info fw; 272d7ad9b84Sdamien struct iwn_calib_info calibcmd[5]; 273fef5740dSdamien uint32_t errptr; 2741b861c8bSdamien 275e38d2b44Sstsp uint8_t bss_node_addr[IEEE80211_ADDR_LEN]; 276e38d2b44Sstsp 277fb942e08Sdamien struct iwn_rx_stat last_rx_stat; 278fb942e08Sdamien int last_rx_valid; 279e1dc77e9Sstsp #define IWN_LAST_RX_VALID 0x01 280e1dc77e9Sstsp #define IWN_LAST_RX_AMPDU 0x02 281fb942e08Sdamien struct iwn_ucode_info ucode_info; 2821b861c8bSdamien struct iwn_rxon rxon; 283*1fdfd19eSstsp uint32_t rx_stats_flags; 284fb942e08Sdamien uint32_t rawtemp; 285fb942e08Sdamien int temp; 286fb942e08Sdamien int noise; 2871b861c8bSdamien uint32_t qfullmsk; 288fb942e08Sdamien 289f16141c2Sdamien uint32_t prom_base; 2901b861c8bSdamien struct iwn4965_eeprom_band 2911b861c8bSdamien bands[IWN_NBANDS]; 2921b861c8bSdamien uint16_t rfcfg; 29347a1ebbaSdamien uint8_t calib_ver; 2941b861c8bSdamien char eeprom_domain[4]; 2951b861c8bSdamien uint32_t eeprom_crystal; 2960bfcb362Sdamien int16_t eeprom_temp; 297fb942e08Sdamien int16_t eeprom_voltage; 298b64e44edSkettenis int16_t eeprom_rawtemp; 299fb942e08Sdamien int8_t maxpwr2GHz; 300fb942e08Sdamien int8_t maxpwr5GHz; 301fb942e08Sdamien int8_t maxpwr[IEEE80211_CHAN_MAX]; 302*1fdfd19eSstsp int8_t maxpwr40[IEEE80211_CHAN_MAX]; 3037e2b46eaSdamien int8_t enh_maxpwr[35]; 304fb942e08Sdamien 305b64e44edSkettenis uint8_t reset_noise_gain; 306b64e44edSkettenis uint8_t noise_gain; 307b64e44edSkettenis 308eb6b032aSsthen uint32_t tlv_feature_flags; 309eb6b032aSsthen 310f16141c2Sdamien int32_t temp_off; 311f16141c2Sdamien uint32_t int_mask; 3121b861c8bSdamien uint8_t ntxchains; 3131b861c8bSdamien uint8_t nrxchains; 314f16141c2Sdamien uint8_t txchainmask; 315f16141c2Sdamien uint8_t rxchainmask; 316f16141c2Sdamien uint8_t chainmask; 3171b861c8bSdamien 318fb942e08Sdamien int sc_tx_timer; 319fb942e08Sdamien 320aefc44daSstsp struct iwn_tx_ba sc_tx_ba[IEEE80211_NUM_TID]; 321aefc44daSstsp 322fb942e08Sdamien #if NBPFILTER > 0 323fb942e08Sdamien caddr_t sc_drvbpf; 324fb942e08Sdamien 325fb942e08Sdamien union { 326fb942e08Sdamien struct iwn_rx_radiotap_header th; 327fb942e08Sdamien uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; 328fb942e08Sdamien } sc_rxtapu; 329fb942e08Sdamien #define sc_rxtap sc_rxtapu.th 330fb942e08Sdamien int sc_rxtap_len; 331fb942e08Sdamien 332fb942e08Sdamien union { 333fb942e08Sdamien struct iwn_tx_radiotap_header th; 334fb942e08Sdamien uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; 335fb942e08Sdamien } sc_txtapu; 336fb942e08Sdamien #define sc_txtap sc_txtapu.th 337fb942e08Sdamien int sc_txtap_len; 338fb942e08Sdamien #endif 339fb942e08Sdamien }; 340