1*ffd7c74aSJoe Talbott /* $FreeBSD$ */ 2*ffd7c74aSJoe Talbott /* $OpenBSD: if_iwnvar.h,v 1.17 2010/02/17 18:23:00 damien Exp $ */ 3*ffd7c74aSJoe Talbott 4*ffd7c74aSJoe Talbott /*- 5*ffd7c74aSJoe Talbott * Copyright (c) 2007, 2008 6*ffd7c74aSJoe Talbott * Damien Bergamini <damien.bergamini@free.fr> 7*ffd7c74aSJoe Talbott * Copyright (c) 2008 Sam Leffler, Errno Consulting 8*ffd7c74aSJoe Talbott * 9*ffd7c74aSJoe Talbott * Permission to use, copy, modify, and distribute this software for any 10*ffd7c74aSJoe Talbott * purpose with or without fee is hereby granted, provided that the above 11*ffd7c74aSJoe Talbott * copyright notice and this permission notice appear in all copies. 12*ffd7c74aSJoe Talbott * 13*ffd7c74aSJoe Talbott * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14*ffd7c74aSJoe Talbott * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15*ffd7c74aSJoe Talbott * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16*ffd7c74aSJoe Talbott * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17*ffd7c74aSJoe Talbott * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18*ffd7c74aSJoe Talbott * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19*ffd7c74aSJoe Talbott * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20*ffd7c74aSJoe Talbott */ 21*ffd7c74aSJoe Talbott 22*ffd7c74aSJoe Talbott struct iwn_rx_radiotap_header { 23*ffd7c74aSJoe Talbott struct ieee80211_radiotap_header wr_ihdr; 24*ffd7c74aSJoe Talbott uint64_t wr_tsft; 25*ffd7c74aSJoe Talbott uint8_t wr_flags; 26*ffd7c74aSJoe Talbott uint8_t wr_rate; 27*ffd7c74aSJoe Talbott uint16_t wr_chan_freq; 28*ffd7c74aSJoe Talbott uint16_t wr_chan_flags; 29*ffd7c74aSJoe Talbott int8_t wr_dbm_antsignal; 30*ffd7c74aSJoe Talbott int8_t wr_dbm_antnoise; 31*ffd7c74aSJoe Talbott } __packed; 32*ffd7c74aSJoe Talbott 33*ffd7c74aSJoe Talbott #define IWN_RX_RADIOTAP_PRESENT \ 34*ffd7c74aSJoe Talbott ((1 << IEEE80211_RADIOTAP_TSFT) | \ 35*ffd7c74aSJoe Talbott (1 << IEEE80211_RADIOTAP_FLAGS) | \ 36*ffd7c74aSJoe Talbott (1 << IEEE80211_RADIOTAP_RATE) | \ 37*ffd7c74aSJoe Talbott (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 38*ffd7c74aSJoe Talbott (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 39*ffd7c74aSJoe Talbott (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 40*ffd7c74aSJoe Talbott 41*ffd7c74aSJoe Talbott struct iwn_tx_radiotap_header { 42*ffd7c74aSJoe Talbott struct ieee80211_radiotap_header wt_ihdr; 43*ffd7c74aSJoe Talbott uint8_t wt_flags; 44*ffd7c74aSJoe Talbott uint8_t wt_rate; 45*ffd7c74aSJoe Talbott uint16_t wt_chan_freq; 46*ffd7c74aSJoe Talbott uint16_t wt_chan_flags; 47*ffd7c74aSJoe Talbott } __packed; 48*ffd7c74aSJoe Talbott 49*ffd7c74aSJoe Talbott #define IWN_TX_RADIOTAP_PRESENT \ 50*ffd7c74aSJoe Talbott ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 51*ffd7c74aSJoe Talbott (1 << IEEE80211_RADIOTAP_RATE) | \ 52*ffd7c74aSJoe Talbott (1 << IEEE80211_RADIOTAP_CHANNEL)) 53*ffd7c74aSJoe Talbott 54*ffd7c74aSJoe Talbott struct iwn_dma_info { 55*ffd7c74aSJoe Talbott bus_dma_tag_t tag; 56*ffd7c74aSJoe Talbott bus_dmamap_t map; 57*ffd7c74aSJoe Talbott bus_dma_segment_t seg; 58*ffd7c74aSJoe Talbott bus_addr_t paddr; 59*ffd7c74aSJoe Talbott caddr_t vaddr; 60*ffd7c74aSJoe Talbott bus_size_t size; 61*ffd7c74aSJoe Talbott }; 62*ffd7c74aSJoe Talbott 63*ffd7c74aSJoe Talbott struct iwn_tx_data { 64*ffd7c74aSJoe Talbott bus_dmamap_t map; 65*ffd7c74aSJoe Talbott bus_addr_t cmd_paddr; 66*ffd7c74aSJoe Talbott bus_addr_t scratch_paddr; 67*ffd7c74aSJoe Talbott struct mbuf *m; 68*ffd7c74aSJoe Talbott struct ieee80211_node *ni; 69*ffd7c74aSJoe Talbott }; 70*ffd7c74aSJoe Talbott 71*ffd7c74aSJoe Talbott struct iwn_tx_ring { 72*ffd7c74aSJoe Talbott struct iwn_dma_info desc_dma; 73*ffd7c74aSJoe Talbott struct iwn_dma_info cmd_dma; 74*ffd7c74aSJoe Talbott struct iwn_tx_desc *desc; 75*ffd7c74aSJoe Talbott struct iwn_tx_cmd *cmd; 76*ffd7c74aSJoe Talbott struct iwn_tx_data data[IWN_TX_RING_COUNT]; 77*ffd7c74aSJoe Talbott bus_dma_tag_t data_dmat; 78*ffd7c74aSJoe Talbott int qid; 79*ffd7c74aSJoe Talbott int queued; 80*ffd7c74aSJoe Talbott int cur; 81*ffd7c74aSJoe Talbott }; 82*ffd7c74aSJoe Talbott 83*ffd7c74aSJoe Talbott struct iwn_softc; 84*ffd7c74aSJoe Talbott 85*ffd7c74aSJoe Talbott struct iwn_rx_data { 86*ffd7c74aSJoe Talbott struct mbuf *m; 87*ffd7c74aSJoe Talbott bus_dmamap_t map; 88*ffd7c74aSJoe Talbott }; 89*ffd7c74aSJoe Talbott 90*ffd7c74aSJoe Talbott struct iwn_rx_ring { 91*ffd7c74aSJoe Talbott struct iwn_dma_info desc_dma; 92*ffd7c74aSJoe Talbott struct iwn_dma_info stat_dma; 93*ffd7c74aSJoe Talbott uint32_t *desc; 94*ffd7c74aSJoe Talbott struct iwn_rx_status *stat; 95*ffd7c74aSJoe Talbott struct iwn_rx_data data[IWN_RX_RING_COUNT]; 96*ffd7c74aSJoe Talbott bus_dma_tag_t data_dmat; 97*ffd7c74aSJoe Talbott int cur; 98*ffd7c74aSJoe Talbott }; 99*ffd7c74aSJoe Talbott 100*ffd7c74aSJoe Talbott struct iwn_node { 101*ffd7c74aSJoe Talbott struct ieee80211_node ni; /* must be the first */ 102*ffd7c74aSJoe Talbott uint16_t disable_tid; 103*ffd7c74aSJoe Talbott uint8_t id; 104*ffd7c74aSJoe Talbott uint8_t ridx[IEEE80211_RATE_MAXSIZE]; 105*ffd7c74aSJoe Talbott }; 106*ffd7c74aSJoe Talbott 107*ffd7c74aSJoe Talbott struct iwn_calib_state { 108*ffd7c74aSJoe Talbott uint8_t state; 109*ffd7c74aSJoe Talbott #define IWN_CALIB_STATE_INIT 0 110*ffd7c74aSJoe Talbott #define IWN_CALIB_STATE_ASSOC 1 111*ffd7c74aSJoe Talbott #define IWN_CALIB_STATE_RUN 2 112*ffd7c74aSJoe Talbott 113*ffd7c74aSJoe Talbott u_int nbeacons; 114*ffd7c74aSJoe Talbott uint32_t noise[3]; 115*ffd7c74aSJoe Talbott uint32_t rssi[3]; 116*ffd7c74aSJoe Talbott uint32_t ofdm_x1; 117*ffd7c74aSJoe Talbott uint32_t ofdm_mrc_x1; 118*ffd7c74aSJoe Talbott uint32_t ofdm_x4; 119*ffd7c74aSJoe Talbott uint32_t ofdm_mrc_x4; 120*ffd7c74aSJoe Talbott uint32_t cck_x4; 121*ffd7c74aSJoe Talbott uint32_t cck_mrc_x4; 122*ffd7c74aSJoe Talbott uint32_t bad_plcp_ofdm; 123*ffd7c74aSJoe Talbott uint32_t fa_ofdm; 124*ffd7c74aSJoe Talbott uint32_t bad_plcp_cck; 125*ffd7c74aSJoe Talbott uint32_t fa_cck; 126*ffd7c74aSJoe Talbott uint32_t low_fa; 127*ffd7c74aSJoe Talbott uint8_t cck_state; 128*ffd7c74aSJoe Talbott #define IWN_CCK_STATE_INIT 0 129*ffd7c74aSJoe Talbott #define IWN_CCK_STATE_LOFA 1 130*ffd7c74aSJoe Talbott #define IWN_CCK_STATE_HIFA 2 131*ffd7c74aSJoe Talbott 132*ffd7c74aSJoe Talbott uint8_t noise_samples[20]; 133*ffd7c74aSJoe Talbott u_int cur_noise_sample; 134*ffd7c74aSJoe Talbott uint8_t noise_ref; 135*ffd7c74aSJoe Talbott uint32_t energy_samples[10]; 136*ffd7c74aSJoe Talbott u_int cur_energy_sample; 137*ffd7c74aSJoe Talbott uint32_t energy_cck; 138*ffd7c74aSJoe Talbott }; 139*ffd7c74aSJoe Talbott 140*ffd7c74aSJoe Talbott struct iwn_calib_info { 141*ffd7c74aSJoe Talbott uint8_t *buf; 142*ffd7c74aSJoe Talbott u_int len; 143*ffd7c74aSJoe Talbott }; 144*ffd7c74aSJoe Talbott 145*ffd7c74aSJoe Talbott struct iwn_fw_part { 146*ffd7c74aSJoe Talbott const uint8_t *text; 147*ffd7c74aSJoe Talbott uint32_t textsz; 148*ffd7c74aSJoe Talbott const uint8_t *data; 149*ffd7c74aSJoe Talbott uint32_t datasz; 150*ffd7c74aSJoe Talbott }; 151*ffd7c74aSJoe Talbott 152*ffd7c74aSJoe Talbott struct iwn_fw_info { 153*ffd7c74aSJoe Talbott u_char *data; 154*ffd7c74aSJoe Talbott struct iwn_fw_part init; 155*ffd7c74aSJoe Talbott struct iwn_fw_part main; 156*ffd7c74aSJoe Talbott struct iwn_fw_part boot; 157*ffd7c74aSJoe Talbott }; 158*ffd7c74aSJoe Talbott 159*ffd7c74aSJoe Talbott struct iwn_hal { 160*ffd7c74aSJoe Talbott int (*load_firmware)(struct iwn_softc *); 161*ffd7c74aSJoe Talbott void (*read_eeprom)(struct iwn_softc *); 162*ffd7c74aSJoe Talbott int (*post_alive)(struct iwn_softc *); 163*ffd7c74aSJoe Talbott int (*nic_config)(struct iwn_softc *); 164*ffd7c74aSJoe Talbott void (*update_sched)(struct iwn_softc *, int, int, uint8_t, 165*ffd7c74aSJoe Talbott uint16_t); 166*ffd7c74aSJoe Talbott int (*get_temperature)(struct iwn_softc *); 167*ffd7c74aSJoe Talbott int (*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *); 168*ffd7c74aSJoe Talbott int (*set_txpower)(struct iwn_softc *, 169*ffd7c74aSJoe Talbott struct ieee80211_channel *, int); 170*ffd7c74aSJoe Talbott int (*init_gains)(struct iwn_softc *); 171*ffd7c74aSJoe Talbott int (*set_gains)(struct iwn_softc *); 172*ffd7c74aSJoe Talbott int (*add_node)(struct iwn_softc *, struct iwn_node_info *, 173*ffd7c74aSJoe Talbott int); 174*ffd7c74aSJoe Talbott void (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *, 175*ffd7c74aSJoe Talbott struct iwn_rx_data *); 176*ffd7c74aSJoe Talbott #if 0 /* HT */ 177*ffd7c74aSJoe Talbott void (*ampdu_tx_start)(struct iwn_softc *, 178*ffd7c74aSJoe Talbott struct ieee80211_node *, uint8_t, uint16_t); 179*ffd7c74aSJoe Talbott void (*ampdu_tx_stop)(struct iwn_softc *, uint8_t, 180*ffd7c74aSJoe Talbott uint16_t); 181*ffd7c74aSJoe Talbott #endif 182*ffd7c74aSJoe Talbott int ntxqs; 183*ffd7c74aSJoe Talbott int ndmachnls; 184*ffd7c74aSJoe Talbott uint8_t broadcast_id; 185*ffd7c74aSJoe Talbott int rxonsz; 186*ffd7c74aSJoe Talbott int schedsz; 187*ffd7c74aSJoe Talbott uint32_t fw_text_maxsz; 188*ffd7c74aSJoe Talbott uint32_t fw_data_maxsz; 189*ffd7c74aSJoe Talbott uint32_t fwsz; 190*ffd7c74aSJoe Talbott bus_size_t sched_txfact_addr; 191*ffd7c74aSJoe Talbott }; 192*ffd7c74aSJoe Talbott 193*ffd7c74aSJoe Talbott struct iwn_vap { 194*ffd7c74aSJoe Talbott struct ieee80211vap iv_vap; 195*ffd7c74aSJoe Talbott uint8_t iv_ridx; 196*ffd7c74aSJoe Talbott 197*ffd7c74aSJoe Talbott int (*iv_newstate)(struct ieee80211vap *, 198*ffd7c74aSJoe Talbott enum ieee80211_state, int); 199*ffd7c74aSJoe Talbott }; 200*ffd7c74aSJoe Talbott #define IWN_VAP(_vap) ((struct iwn_vap *)(_vap)) 201*ffd7c74aSJoe Talbott 202*ffd7c74aSJoe Talbott struct iwn_softc { 203*ffd7c74aSJoe Talbott struct ifnet *sc_ifp; 204*ffd7c74aSJoe Talbott int sc_debug; 205*ffd7c74aSJoe Talbott 206*ffd7c74aSJoe Talbott /* Locks */ 207*ffd7c74aSJoe Talbott struct mtx sc_mtx; 208*ffd7c74aSJoe Talbott 209*ffd7c74aSJoe Talbott /* Bus */ 210*ffd7c74aSJoe Talbott device_t sc_dev; 211*ffd7c74aSJoe Talbott int mem_rid; 212*ffd7c74aSJoe Talbott int irq_rid; 213*ffd7c74aSJoe Talbott struct resource *mem; 214*ffd7c74aSJoe Talbott struct resource *irq; 215*ffd7c74aSJoe Talbott 216*ffd7c74aSJoe Talbott u_int sc_flags; 217*ffd7c74aSJoe Talbott #define IWN_FLAG_HAS_5GHZ (1 << 0) 218*ffd7c74aSJoe Talbott #define IWN_FLAG_HAS_OTPROM (1 << 1) 219*ffd7c74aSJoe Talbott #define IWN_FLAG_CALIB_DONE (1 << 2) 220*ffd7c74aSJoe Talbott #define IWN_FLAG_USE_ICT (1 << 3) 221*ffd7c74aSJoe Talbott #define IWN_FLAG_INTERNAL_PA (1 << 4) 222*ffd7c74aSJoe Talbott 223*ffd7c74aSJoe Talbott uint8_t hw_type; 224*ffd7c74aSJoe Talbott const struct iwn_hal *sc_hal; 225*ffd7c74aSJoe Talbott const char *fwname; 226*ffd7c74aSJoe Talbott const struct iwn_sensitivity_limits 227*ffd7c74aSJoe Talbott *limits; 228*ffd7c74aSJoe Talbott 229*ffd7c74aSJoe Talbott /* TX scheduler rings. */ 230*ffd7c74aSJoe Talbott struct iwn_dma_info sched_dma; 231*ffd7c74aSJoe Talbott uint16_t *sched; 232*ffd7c74aSJoe Talbott uint32_t sched_base; 233*ffd7c74aSJoe Talbott 234*ffd7c74aSJoe Talbott /* "Keep Warm" page. */ 235*ffd7c74aSJoe Talbott struct iwn_dma_info kw_dma; 236*ffd7c74aSJoe Talbott 237*ffd7c74aSJoe Talbott /* Firmware image. */ 238*ffd7c74aSJoe Talbott const struct firmware *fw_fp; 239*ffd7c74aSJoe Talbott 240*ffd7c74aSJoe Talbott /* Firmware DMA transfer. */ 241*ffd7c74aSJoe Talbott struct iwn_dma_info fw_dma; 242*ffd7c74aSJoe Talbott 243*ffd7c74aSJoe Talbott /* ICT table. */ 244*ffd7c74aSJoe Talbott struct iwn_dma_info ict_dma; 245*ffd7c74aSJoe Talbott uint32_t *ict; 246*ffd7c74aSJoe Talbott int ict_cur; 247*ffd7c74aSJoe Talbott 248*ffd7c74aSJoe Talbott /* TX/RX rings. */ 249*ffd7c74aSJoe Talbott struct iwn_tx_ring txq[IWN5000_NTXQUEUES]; 250*ffd7c74aSJoe Talbott struct iwn_rx_ring rxq; 251*ffd7c74aSJoe Talbott 252*ffd7c74aSJoe Talbott bus_space_tag_t sc_st; 253*ffd7c74aSJoe Talbott bus_space_handle_t sc_sh; 254*ffd7c74aSJoe Talbott void *sc_ih; 255*ffd7c74aSJoe Talbott bus_size_t sc_sz; 256*ffd7c74aSJoe Talbott int sc_cap_off; /* PCIe Capabilities. */ 257*ffd7c74aSJoe Talbott 258*ffd7c74aSJoe Talbott /* Tasks used by the driver */ 259*ffd7c74aSJoe Talbott struct task sc_reinit_task; 260*ffd7c74aSJoe Talbott struct task sc_radioon_task; 261*ffd7c74aSJoe Talbott struct task sc_radiooff_task; 262*ffd7c74aSJoe Talbott 263*ffd7c74aSJoe Talbott int calib_cnt; 264*ffd7c74aSJoe Talbott struct iwn_calib_state calib; 265*ffd7c74aSJoe Talbott 266*ffd7c74aSJoe Talbott struct iwn_fw_info fw; 267*ffd7c74aSJoe Talbott struct iwn_calib_info calibcmd[5]; 268*ffd7c74aSJoe Talbott uint32_t errptr; 269*ffd7c74aSJoe Talbott 270*ffd7c74aSJoe Talbott struct iwn_rx_stat last_rx_stat; 271*ffd7c74aSJoe Talbott int last_rx_valid; 272*ffd7c74aSJoe Talbott struct iwn_ucode_info ucode_info; 273*ffd7c74aSJoe Talbott struct iwn_rxon rxon; 274*ffd7c74aSJoe Talbott uint32_t rawtemp; 275*ffd7c74aSJoe Talbott int temp; 276*ffd7c74aSJoe Talbott int noise; 277*ffd7c74aSJoe Talbott uint32_t qfullmsk; 278*ffd7c74aSJoe Talbott 279*ffd7c74aSJoe Talbott uint32_t prom_base; 280*ffd7c74aSJoe Talbott struct iwn4965_eeprom_band 281*ffd7c74aSJoe Talbott bands[IWN_NBANDS]; 282*ffd7c74aSJoe Talbott struct iwn_eeprom_chan eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND]; 283*ffd7c74aSJoe Talbott uint16_t rfcfg; 284*ffd7c74aSJoe Talbott uint8_t calib_ver; 285*ffd7c74aSJoe Talbott char eeprom_domain[4]; 286*ffd7c74aSJoe Talbott uint32_t eeprom_crystal; 287*ffd7c74aSJoe Talbott int16_t eeprom_voltage; 288*ffd7c74aSJoe Talbott int8_t maxpwr2GHz; 289*ffd7c74aSJoe Talbott int8_t maxpwr5GHz; 290*ffd7c74aSJoe Talbott int8_t maxpwr[IEEE80211_CHAN_MAX]; 291*ffd7c74aSJoe Talbott int8_t enh_maxpwr[35]; 292*ffd7c74aSJoe Talbott 293*ffd7c74aSJoe Talbott int32_t temp_off; 294*ffd7c74aSJoe Talbott uint32_t int_mask; 295*ffd7c74aSJoe Talbott uint8_t ntxchains; 296*ffd7c74aSJoe Talbott uint8_t nrxchains; 297*ffd7c74aSJoe Talbott uint8_t txchainmask; 298*ffd7c74aSJoe Talbott uint8_t rxchainmask; 299*ffd7c74aSJoe Talbott uint8_t chainmask; 300*ffd7c74aSJoe Talbott 301*ffd7c74aSJoe Talbott struct callout sc_timer_to; 302*ffd7c74aSJoe Talbott int sc_tx_timer; 303*ffd7c74aSJoe Talbott 304*ffd7c74aSJoe Talbott struct iwn_rx_radiotap_header sc_rxtap; 305*ffd7c74aSJoe Talbott struct iwn_tx_radiotap_header sc_txtap; 306*ffd7c74aSJoe Talbott }; 307*ffd7c74aSJoe Talbott 308*ffd7c74aSJoe Talbott #define IWN_LOCK_INIT(_sc) \ 309*ffd7c74aSJoe Talbott mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 310*ffd7c74aSJoe Talbott MTX_NETWORK_LOCK, MTX_DEF) 311*ffd7c74aSJoe Talbott #define IWN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 312*ffd7c74aSJoe Talbott #define IWN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 313*ffd7c74aSJoe Talbott #define IWN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 314*ffd7c74aSJoe Talbott #define IWN_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 315