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