1 /* $FreeBSD$ */ 2 3 /*- 4 * Copyright (c) 2006,2007 5 * Damien Bergamini <damien.bergamini@free.fr> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 struct wpi_rx_radiotap_header { 20 struct ieee80211_radiotap_header wr_ihdr; 21 uint64_t wr_tsft; 22 uint8_t wr_flags; 23 uint8_t wr_rate; 24 uint16_t wr_chan_freq; 25 uint16_t wr_chan_flags; 26 int8_t wr_dbm_antsignal; 27 int8_t wr_dbm_antnoise; 28 uint8_t wr_antenna; 29 } __packed; 30 31 #define WPI_RX_RADIOTAP_PRESENT \ 32 ((1 << IEEE80211_RADIOTAP_TSFT) | \ 33 (1 << IEEE80211_RADIOTAP_FLAGS) | \ 34 (1 << IEEE80211_RADIOTAP_RATE) | \ 35 (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 36 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 37 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 38 (1 << IEEE80211_RADIOTAP_ANTENNA)) 39 40 struct wpi_tx_radiotap_header { 41 struct ieee80211_radiotap_header wt_ihdr; 42 uint8_t wt_flags; 43 uint8_t wt_rate; 44 uint16_t wt_chan_freq; 45 uint16_t wt_chan_flags; 46 } __packed; 47 48 #define WPI_TX_RADIOTAP_PRESENT \ 49 ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 50 (1 << IEEE80211_RADIOTAP_RATE) | \ 51 (1 << IEEE80211_RADIOTAP_CHANNEL)) 52 53 struct wpi_dma_info { 54 bus_dma_tag_t tag; 55 bus_dmamap_t map; 56 bus_addr_t paddr; 57 caddr_t vaddr; 58 bus_size_t size; 59 }; 60 61 struct wpi_tx_data { 62 bus_dmamap_t map; 63 bus_addr_t cmd_paddr; 64 struct mbuf *m; 65 struct ieee80211_node *ni; 66 }; 67 68 struct wpi_tx_ring { 69 struct wpi_dma_info desc_dma; 70 struct wpi_dma_info cmd_dma; 71 struct wpi_tx_desc *desc; 72 struct wpi_tx_cmd *cmd; 73 struct wpi_tx_data data[WPI_TX_RING_COUNT]; 74 bus_dma_tag_t data_dmat; 75 uint8_t qid; 76 uint8_t cur; 77 uint8_t pending; 78 int16_t queued; 79 int update:1; 80 }; 81 82 struct wpi_rx_data { 83 struct mbuf *m; 84 bus_dmamap_t map; 85 }; 86 87 struct wpi_rx_ring { 88 struct wpi_dma_info desc_dma; 89 uint32_t *desc; 90 struct wpi_rx_data data[WPI_RX_RING_COUNT]; 91 bus_dma_tag_t data_dmat; 92 uint16_t cur; 93 int update; 94 }; 95 96 struct wpi_node { 97 struct ieee80211_node ni; /* must be the first */ 98 uint8_t id; 99 }; 100 #define WPI_NODE(ni) ((struct wpi_node *)(ni)) 101 102 struct wpi_power_sample { 103 uint8_t index; 104 int8_t power; 105 }; 106 107 struct wpi_power_group { 108 #define WPI_SAMPLES_COUNT 5 109 struct wpi_power_sample samples[WPI_SAMPLES_COUNT]; 110 uint8_t chan; 111 int8_t maxpwr; 112 int16_t temp; 113 }; 114 115 struct wpi_buf { 116 uint8_t data[56]; /* sizeof(struct wpi_cmd_beacon) */ 117 struct ieee80211_node *ni; 118 struct mbuf *m; 119 size_t size; 120 uint8_t code; 121 uint16_t ac; 122 }; 123 124 struct wpi_vap { 125 struct ieee80211vap wv_vap; 126 127 struct wpi_buf wv_bcbuf; 128 #if defined(__DragonFly__) 129 struct lock wv_mtx; 130 #else 131 struct mtx wv_mtx; 132 #endif 133 134 uint8_t wv_gtk; 135 #define WPI_VAP_KEY(kid) (1 << kid) 136 137 int (*wv_newstate)(struct ieee80211vap *, 138 enum ieee80211_state, int); 139 void (*wv_recv_mgmt)(struct ieee80211_node *, 140 struct mbuf *, int, 141 const struct ieee80211_rx_stats *, 142 int, int); 143 }; 144 #define WPI_VAP(vap) ((struct wpi_vap *)(vap)) 145 146 #define WPI_VAP_LOCK_INIT(_wvp) \ 147 lockinit(&(_wvp)->wv_mtx, "lock for wv_bcbuf/wv_boff structures", 0, 0) 148 #define WPI_VAP_LOCK(_wvp) lockmgr(&(_wvp)->wv_mtx, LK_EXCLUSIVE) 149 #define WPI_VAP_UNLOCK(_wvp) lockmgr(&(_wvp)->wv_mtx, LK_RELEASE) 150 #define WPI_VAP_LOCK_ASSERT(_wvp) KKASSERT(lockstatus(&(_wvp)->wv_mtx, curthread) == LK_EXCLUSIVE) 151 #define WPI_VAP_LOCK_DESTROY(_wvp) lockuninit(&(_wvp)->wv_mtx) 152 153 struct wpi_fw_part { 154 const uint8_t *text; 155 uint32_t textsz; 156 const uint8_t *data; 157 uint32_t datasz; 158 }; 159 160 struct wpi_fw_info { 161 const uint8_t *data; 162 size_t size; 163 struct wpi_fw_part init; 164 struct wpi_fw_part main; 165 struct wpi_fw_part boot; 166 }; 167 168 struct wpi_softc { 169 device_t sc_dev; 170 int sc_debug; 171 172 int sc_running; 173 174 #if defined(__DragonFly__) 175 struct lock sc_mtx; 176 #else 177 struct mtx sc_mtx; 178 #endif 179 struct ieee80211com sc_ic; 180 181 #if defined(__DragonFly__) 182 struct lock tx_mtx; 183 #else 184 struct mtx tx_mtx; 185 #endif 186 187 /* Shared area. */ 188 struct wpi_dma_info shared_dma; 189 struct wpi_shared *shared; 190 191 struct wpi_tx_ring txq[WPI_DRV_NTXQUEUES]; 192 #if defined(__DragonFly__) 193 struct lock txq_mtx; 194 struct lock txq_state_mtx; 195 #else 196 struct mtx txq_mtx; 197 struct mtx txq_state_mtx; 198 #endif 199 200 struct wpi_rx_ring rxq; 201 uint64_t rx_tstamp; 202 203 /* TX Thermal Callibration. */ 204 struct callout calib_to; 205 206 struct callout scan_timeout; 207 struct callout tx_timeout; 208 209 /* Watch dog timer. */ 210 struct callout watchdog_rfkill; 211 212 /* Firmware image. */ 213 struct wpi_fw_info fw; 214 uint32_t errptr; 215 216 struct resource *irq; 217 struct resource *mem; 218 bus_space_tag_t sc_st; 219 bus_space_handle_t sc_sh; 220 void *sc_ih; 221 bus_size_t sc_sz; 222 int sc_cap_off; /* PCIe Capabilities. */ 223 224 struct wpi_rxon rxon; 225 #if defined(__DragonFly__) 226 struct lock rxon_mtx; 227 #else 228 struct mtx rxon_mtx; 229 #endif 230 231 int temp; 232 233 uint32_t nodesmsk; 234 #if defined(__DragonFly__) 235 struct lock nt_mtx; 236 #else 237 struct mtx nt_mtx; 238 #endif 239 240 void (*sc_node_free)(struct ieee80211_node *); 241 void (*sc_update_rx_ring)(struct wpi_softc *); 242 void (*sc_update_tx_ring)(struct wpi_softc *, 243 struct wpi_tx_ring *); 244 245 struct wpi_rx_radiotap_header sc_rxtap; 246 struct wpi_tx_radiotap_header sc_txtap; 247 248 /* Firmware image. */ 249 const struct firmware *fw_fp; 250 251 /* Firmware DMA transfer. */ 252 struct wpi_dma_info fw_dma; 253 254 /* Tasks used by the driver. */ 255 struct task sc_radiooff_task; 256 struct task sc_radioon_task; 257 258 /* Eeprom info. */ 259 uint8_t cap; 260 uint16_t rev; 261 uint8_t type; 262 struct wpi_eeprom_chan 263 eeprom_channels[WPI_CHAN_BANDS_COUNT][WPI_MAX_CHAN_PER_BAND]; 264 struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT]; 265 int8_t maxpwr[IEEE80211_CHAN_MAX]; 266 char domain[4]; /* Regulatory domain. */ 267 }; 268 269 /* 270 * Locking order: 271 * 1. WPI_LOCK; 272 * 2. WPI_RXON_LOCK; 273 * 3. WPI_TX_LOCK; 274 * 4. WPI_NT_LOCK / WPI_VAP_LOCK; 275 * 5. WPI_TXQ_LOCK; 276 * 6. WPI_TXQ_STATE_LOCK; 277 */ 278 279 #if defined(__DragonFly__) 280 281 #define WPI_LOCK_INIT(_sc) \ 282 lockinit(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), 0, 0); 283 #define WPI_LOCK(_sc) lockmgr(&(_sc)->sc_mtx, LK_EXCLUSIVE) 284 #define WPI_UNLOCK(_sc) lockmgr(&(_sc)->sc_mtx, LK_RELEASE) 285 #define WPI_LOCK_ASSERT(_sc) KKASSERT(lockstatus(&(_sc)->sc_mtx, curthread) == LK_EXCLUSIVE) 286 #define WPI_LOCK_DESTROY(_sc) lockuninit(&(_sc)->sc_mtx) 287 288 #define WPI_RXON_LOCK_INIT(_sc) \ 289 lockinit(&(_sc)->rxon_mtx, "lock for wpi_rxon structure", 0, 0) 290 #define WPI_RXON_LOCK(_sc) lockmgr(&(_sc)->rxon_mtx, LK_EXCLUSIVE) 291 #define WPI_RXON_UNLOCK(_sc) lockmgr(&(_sc)->rxon_mtx, LK_RELEASE) 292 #define WPI_RXON_LOCK_ASSERT(_sc) KKASSERT(lockstatus(&(_sc)->rxon_mtx, curthread) == LK_EXCLUSIVE) 293 #define WPI_RXON_LOCK_DESTROY(_sc) lockuninit(&(_sc)->rxon_mtx) 294 295 #define WPI_TX_LOCK_INIT(_sc) \ 296 lockinit(&(_sc)->tx_mtx, "tx path lock", 0, 0) 297 #define WPI_TX_LOCK(_sc) lockmgr(&(_sc)->tx_mtx, LK_EXCLUSIVE) 298 #define WPI_TX_UNLOCK(_sc) lockmgr(&(_sc)->tx_mtx, LK_RELEASE) 299 #define WPI_TX_LOCK_DESTROY(_sc) lockuninit(&(_sc)->tx_mtx) 300 301 #define WPI_NT_LOCK_INIT(_sc) \ 302 lockinit(&(_sc)->nt_mtx, "node table lock", 0, 0) 303 #define WPI_NT_LOCK(_sc) lockmgr(&(_sc)->nt_mtx, LK_EXCLUSIVE) 304 #define WPI_NT_UNLOCK(_sc) lockmgr(&(_sc)->nt_mtx, LK_RELEASE) 305 #define WPI_NT_LOCK_DESTROY(_sc) lockuninit(&(_sc)->nt_mtx) 306 307 #define WPI_TXQ_LOCK_INIT(_sc) \ 308 lockinit(&(_sc)->txq_mtx, "txq/cmdq lock", 0, 0) 309 #define WPI_TXQ_LOCK(_sc) lockmgr(&(_sc)->txq_mtx, LK_EXCLUSIVE) 310 #define WPI_TXQ_UNLOCK(_sc) lockmgr(&(_sc)->txq_mtx, LK_RELEASE) 311 #define WPI_TXQ_LOCK_DESTROY(_sc) lockuninit(&(_sc)->txq_mtx) 312 313 #define WPI_TXQ_STATE_LOCK_INIT(_sc) \ 314 lockinit(&(_sc)->txq_state_mtx, "txq state lock", 0, 0) 315 #define WPI_TXQ_STATE_LOCK(_sc) lockmgr(&(_sc)->txq_state_mtx, LK_EXCLUSIVE) 316 #define WPI_TXQ_STATE_UNLOCK(_sc) lockmgr(&(_sc)->txq_state_mtx, LK_RELEASE) 317 #define WPI_TXQ_STATE_LOCK_DESTROY(_sc) lockuninit(&(_sc)->txq_state_mtx) 318 319 #else 320 321 #define WPI_LOCK_INIT(_sc) \ 322 mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 323 MTX_NETWORK_LOCK, MTX_DEF) 324 #define WPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 325 #define WPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 326 #define WPI_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 327 #define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 328 329 #define WPI_RXON_LOCK_INIT(_sc) \ 330 mtx_init(&(_sc)->rxon_mtx, "lock for wpi_rxon structure", NULL, MTX_DEF) 331 #define WPI_RXON_LOCK(_sc) mtx_lock(&(_sc)->rxon_mtx) 332 #define WPI_RXON_UNLOCK(_sc) mtx_unlock(&(_sc)->rxon_mtx) 333 #define WPI_RXON_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rxon_mtx, MA_OWNED) 334 #define WPI_RXON_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rxon_mtx) 335 336 #define WPI_TX_LOCK_INIT(_sc) \ 337 mtx_init(&(_sc)->tx_mtx, "tx path lock", NULL, MTX_DEF) 338 #define WPI_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) 339 #define WPI_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) 340 #define WPI_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) 341 342 #define WPI_NT_LOCK_INIT(_sc) \ 343 mtx_init(&(_sc)->nt_mtx, "node table lock", NULL, MTX_DEF) 344 #define WPI_NT_LOCK(_sc) mtx_lock(&(_sc)->nt_mtx) 345 #define WPI_NT_UNLOCK(_sc) mtx_unlock(&(_sc)->nt_mtx) 346 #define WPI_NT_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->nt_mtx) 347 348 #define WPI_TXQ_LOCK_INIT(_sc) \ 349 mtx_init(&(_sc)->txq_mtx, "txq/cmdq lock", NULL, MTX_DEF) 350 #define WPI_TXQ_LOCK(_sc) mtx_lock(&(_sc)->txq_mtx) 351 #define WPI_TXQ_UNLOCK(_sc) mtx_unlock(&(_sc)->txq_mtx) 352 #define WPI_TXQ_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->txq_mtx) 353 354 #define WPI_TXQ_STATE_LOCK_INIT(_sc) \ 355 mtx_init(&(_sc)->txq_state_mtx, "txq state lock", NULL, MTX_DEF) 356 #define WPI_TXQ_STATE_LOCK(_sc) mtx_lock(&(_sc)->txq_state_mtx) 357 #define WPI_TXQ_STATE_UNLOCK(_sc) mtx_unlock(&(_sc)->txq_state_mtx) 358 #define WPI_TXQ_STATE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->txq_state_mtx) 359 360 #endif 361