if_iwnreg.h revision 1.2 1 /* $OpenBSD: if_iwnreg.h,v 1.9 2007/11/27 20:59:40 damien Exp $ */
2
3 /*-
4 * Copyright (c) 2007
5 * Damien Bergamini <damien.bergamini (at) 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
20 #define IWN_TX_RING_COUNT 256
21 #define IWN_RX_RING_COUNT 64
22
23 #define IWN_NTXQUEUES 16
24 #define IWN_NTXCHAINS 2
25
26 #define IWN_BUF_ALIGN 4096
27
28 /*
29 * Rings must be aligned on a 256-byte boundary.
30 */
31 #define IWN_RING_DMA_ALIGN 256
32
33 /* maximum scatter/gather */
34 #define IWN_MAX_SCATTER 20
35
36 /* Rx buffers must be large enough to hold a full 4K A-MPDU */
37 #define IWN_RBUF_SIZE (4 * 1024)
38
39 /*
40 * Control and status registers.
41 */
42 #define IWN_HWCONFIG 0x000
43 #define IWN_INTR_MIT 0x004
44 #define IWN_INTR 0x008
45 #define IWN_MASK 0x00c
46 #define IWN_INTR_STATUS 0x010
47 #define IWN_RESET 0x020
48 #define IWN_GPIO_CTL 0x024
49 #define IWN_EEPROM_CTL 0x02c
50 #define IWN_UCODE_CLR 0x05c
51 #define IWN_CHICKEN 0x100
52 #define IWN_QUEUE_OFFSET(qid) (0x380 + (qid) * 8)
53 #define IWN_MEM_WADDR 0x410
54 #define IWN_MEM_WDATA 0x418
55 #define IWN_WRITE_MEM_ADDR 0x444
56 #define IWN_READ_MEM_ADDR 0x448
57 #define IWN_WRITE_MEM_DATA 0x44c
58 #define IWN_READ_MEM_DATA 0x450
59 #define IWN_TX_WIDX 0x460
60
61 #define IWN_KW_BASE 0x197c
62 #define IWN_TX_BASE(qid) (0x19d0 + (qid) * 4)
63 #define IWN_RW_WIDX_PTR 0x1bc0
64 #define IWN_RX_BASE 0x1bc4
65 #define IWN_RX_WIDX 0x1bc8
66 #define IWN_RX_CONFIG 0x1c00
67 #define IWN_RX_STATUS 0x1c44
68 #define IWN_TX_CONFIG(qid) (0x1d00 + (qid) * 32)
69 #define IWN_TX_STATUS 0x1eb0
70
71 #define IWN_SRAM_BASE 0xa02c00
72 #define IWN_TX_ACTIVE (IWN_SRAM_BASE + 0x01c)
73 #define IWN_QUEUE_RIDX(qid) (IWN_SRAM_BASE + 0x064 + (qid) * 4)
74 #define IWN_SELECT_QCHAIN (IWN_SRAM_BASE + 0x0d0)
75 #define IWN_QUEUE_INTR_MASK (IWN_SRAM_BASE + 0x0e4)
76 #define IWN_TXQ_STATUS(qid) (IWN_SRAM_BASE + 0x104 + (qid) * 4)
77
78 /*
79 * NIC internal memory offsets.
80 */
81 #define IWN_CLOCK_CTL 0x3000
82 #define IWN_MEM_CLOCK2 0x3008
83 #define IWN_MEM_POWER 0x300c
84 #define IWN_MEM_PCIDEV 0x3010
85 #define IWN_MEM_UCODE_CTL 0x3400
86 #define IWN_MEM_UCODE_SRC 0x3404
87 #define IWN_MEM_UCODE_DST 0x3408
88 #define IWN_MEM_UCODE_SIZE 0x340c
89 #define IWN_MEM_TEXT_BASE 0x3490
90 #define IWN_MEM_TEXT_SIZE 0x3494
91 #define IWN_MEM_DATA_BASE 0x3498
92 #define IWN_MEM_DATA_SIZE 0x349c
93 #define IWN_MEM_UCODE_BASE 0x3800
94
95
96 /* possible flags for register IWN_HWCONFIG */
97 #define IWN_HW_EEPROM_LOCKED (1 << 21)
98
99 /* possible flags for registers IWN_READ_MEM_ADDR/IWN_WRITE_MEM_ADDR */
100 #define IWN_MEM_4 ((sizeof (uint32_t) - 1) << 24)
101
102 /* possible values for IWN_MEM_UCODE_DST */
103 #define IWN_FW_TEXT 0x00000000
104
105 /* possible flags for register IWN_RESET */
106 #define IWN_NEVO_RESET (1 << 0)
107 #define IWN_SW_RESET (1 << 7)
108 #define IWN_MASTER_DISABLED (1 << 8)
109 #define IWN_STOP_MASTER (1 << 9)
110
111 /* possible flags for register IWN_GPIO_CTL */
112 #define IWN_GPIO_CLOCK (1 << 0)
113 #define IWN_GPIO_INIT (1 << 2)
114 #define IWN_GPIO_MAC (1 << 3)
115 #define IWN_GPIO_SLEEP (1 << 4)
116 #define IWN_GPIO_PWR_STATUS 0x07000000
117 #define IWN_GPIO_PWR_SLEEP (4 << 24)
118 #define IWN_GPIO_RF_ENABLED (1 << 27)
119
120 /* possible flags for register IWN_CHICKEN */
121 #define IWN_CHICKEN_DISLOS (1 << 29)
122
123 /* possible flags for register IWN_UCODE_CLR */
124 #define IWN_RADIO_OFF (1 << 1)
125 #define IWN_DISABLE_CMD (1 << 2)
126 #define IWN_CTEMP_STOP_RF (1 << 3)
127
128 /* possible flags for IWN_RX_STATUS */
129 #define IWN_RX_IDLE (1 << 24)
130
131 /* possible flags for register IWN_UC_CTL */
132 #define IWN_UC_ENABLE (1 << 30)
133 #define IWN_UC_RUN (1 << 31)
134
135 /* possible flags for register IWN_INTR */
136 #define IWN_ALIVE_INTR (1 << 0)
137 #define IWN_WAKEUP_INTR (1 << 1)
138 #define IWN_SW_RX_INTR (1 << 3)
139 #define IWN_CT_REACHED (1 << 6)
140 #define IWN_RF_TOGGLED (1 << 7)
141 #define IWN_SW_ERROR (1 << 25)
142 #define IWN_TX_INTR (1 << 27)
143 #define IWN_HW_ERROR (1 << 29)
144 #define IWN_RX_INTR (1 << 31)
145
146 #define IWN_INTR_MASK \
147 (IWN_SW_ERROR | IWN_HW_ERROR | IWN_TX_INTR | IWN_RX_INTR | \
148 IWN_ALIVE_INTR | IWN_WAKEUP_INTR | IWN_SW_RX_INTR | \
149 IWN_CT_REACHED | IWN_RF_TOGGLED)
150
151 /* possible flags for register IWN_INTR_STATUS */
152 #define IWN_STATUS_TXQ(x) (1 << (x))
153 #define IWN_STATUS_RXQ(x) (1 << ((x) + 16))
154 #define IWN_STATUS_PRI (1 << 30)
155 /* shortcuts for the above */
156 #define IWN_TX_STATUS_INTR \
157 (IWN_STATUS_TXQ(0) | IWN_STATUS_TXQ(1) | IWN_STATUS_TXQ(6))
158 #define IWN_RX_STATUS_INTR \
159 (IWN_STATUS_RXQ(0) | IWN_STATUS_RXQ(1) | IWN_STATUS_RXQ(2) | \
160 IWN_STATUS_PRI)
161
162 /* possible flags for register IWN_TX_STATUS */
163 #define IWN_TX_IDLE(qid) (1 << ((qid) + 24) | 1 << ((qid) + 16))
164
165 /* possible flags for register IWN_EEPROM_CTL */
166 #define IWN_EEPROM_READY (1 << 0)
167 #define IWN_EEPROM_CMD (1 << 1)
168
169 /* possible flags for register IWN_TXQ_STATUS */
170 #define IWN_TXQ_STATUS_ACTIVE 0x0007fc01
171
172 /* possible flags for register IWN_MEM_POWER */
173 #define IWN_POWER_RESET (1 << 26)
174
175 /* possible flags for register IWN_MEM_TEXT_SIZE */
176 #define IWN_FW_UPDATED (1 << 31)
177
178 /* possible flags for device-specific PCI register 0xe8 */
179 #define IWN_DIS_NOSNOOP (1 << 11)
180
181 /* possible flags for device-specific PCI register 0xf0 */
182 #define IWN_ENA_L1 (1 << 1)
183
184
185 #define IWN_TX_WINDOW 64
186 struct iwn_shared {
187 uint16_t len[IWN_NTXQUEUES][512]; /* 16KB total */
188 uint16_t closed_count;
189 uint16_t closed_rx_count;
190 uint16_t finished_count;
191 uint16_t finished_rx_count;
192 uint32_t reserved[2];
193 } __packed;
194
195 struct iwn_tx_desc {
196 uint32_t flags;
197 struct {
198 uint32_t w1;
199 uint32_t w2;
200 uint32_t w3;
201 } __packed segs[IWN_MAX_SCATTER / 2];
202 /* pad to 128 bytes */
203 uint32_t reserved;
204 } __packed;
205
206 #define IWN_SET_DESC_NSEGS(d, x) \
207 (d)->flags = htole32(((x) & 0x1f) << 24)
208
209 /* set a segment physical address and length in a Tx descriptor */
210 #define IWN_SET_DESC_SEG(d, n, addr, size) do { \
211 if ((n) & 1) { \
212 (d)->segs[(n) / 2].w2 |= \
213 htole32(((addr) & 0xffff) << 16); \
214 (d)->segs[(n) / 2].w3 = \
215 htole32((((addr) >> 16) & 0xffff) | (size) << 20); \
216 } else { \
217 (d)->segs[(n) / 2].w1 = htole32(addr); \
218 (d)->segs[(n) / 2].w2 = htole32((size) << 4); \
219 } \
220 } while (0)
221
222 struct iwn_rx_desc {
223 uint32_t len;
224 uint8_t type;
225 #define IWN_UC_READY 1
226 #define IWN_ADD_NODE_DONE 24
227 #define IWN_TX_DONE 28
228 #define IWN_START_SCAN 130
229 #define IWN_STOP_SCAN 132
230 #define IWN_RX_STATISTICS 156
231 #define IWN_BEACON_STATISTICS 157
232 #define IWN_STATE_CHANGED 161
233 #define IWN_BEACON_MISSED 162
234 #define IWN_AMPDU_RX_START 192
235 #define IWN_AMPDU_RX_DONE 193
236 #define IWN_RX_DONE 195
237
238 uint8_t flags;
239 uint8_t idx;
240 uint8_t qid;
241 } __packed;
242
243 /* possible Rx status flags */
244 #define IWN_RX_NO_CRC_ERR (1 << 0)
245 #define IWN_RX_NO_OVFL_ERR (1 << 1)
246 /* shortcut for the above */
247 #define IWN_RX_NOERROR (IWN_RX_NO_CRC_ERR | IWN_RX_NO_OVFL_ERR)
248
249 struct iwn_tx_cmd {
250 uint8_t code;
251 #define IWN_CMD_CONFIGURE 16
252 #define IWN_CMD_ASSOCIATE 17
253 #define IWN_CMD_SET_WME 19
254 #define IWN_CMD_TSF 20
255 #define IWN_CMD_ADD_NODE 24
256 #define IWN_CMD_TX_DATA 28
257 #define IWN_CMD_NODE_MRR_SETUP 78
258 #define IWN_CMD_SET_LED 72
259 #define IWN_CMD_SET_POWER_MODE 119
260 #define IWN_CMD_SCAN 128
261 #define IWN_CMD_SET_BEACON 145
262 #define IWN_CMD_TXPOWER 151
263 #define IWN_CMD_BLUETOOTH 155
264 #define IWN_CMD_GET_STATISTICS 156
265 #define IWN_CMD_SET_CRITICAL_TEMP 164
266 #define IWN_SENSITIVITY 168
267 #define IWN_PHY_CALIB 176
268
269 uint8_t flags;
270 uint8_t idx;
271 uint8_t qid;
272 uint8_t data[136];
273 } __packed;
274
275 /* structure for command IWN_CMD_CONFIGURE */
276 struct iwn_config {
277 uint8_t myaddr[IEEE80211_ADDR_LEN];
278 uint16_t reserved1;
279 uint8_t bssid[IEEE80211_ADDR_LEN];
280 uint16_t reserved2;
281 uint8_t wlap[IEEE80211_ADDR_LEN];
282 uint16_t reserved3;
283 uint8_t mode;
284 #define IWN_MODE_HOSTAP 1
285 #define IWN_MODE_STA 3
286 #define IWN_MODE_IBSS 4
287 #define IWN_MODE_MONITOR 6
288
289 uint8_t reserved4;
290 uint16_t rxchain;
291 #define IWN_RXCHAIN_ANTMSK_SHIFT 1
292 #define IWN_RXCHAIN_FORCE_MIMO (1 << 14)
293
294 uint8_t ofdm_mask;
295 uint8_t cck_mask;
296 uint16_t associd;
297 uint32_t flags;
298 #define IWN_CONFIG_24GHZ (1 << 0)
299 #define IWN_CONFIG_CCK (1 << 1)
300 #define IWN_CONFIG_AUTO (1 << 2)
301 #define IWN_CONFIG_SHSLOT (1 << 4)
302 #define IWN_CONFIG_SHPREAMBLE (1 << 5)
303 #define IWN_CONFIG_NODIVERSITY (1 << 7)
304 #define IWN_CONFIG_ANTENNA_A (1 << 8)
305 #define IWN_CONFIG_ANTENNA_B (1 << 9)
306 #define IWN_CONFIG_TSF (1 << 15)
307
308 uint32_t filter;
309 #define IWN_FILTER_PROMISC (1 << 0)
310 #define IWN_FILTER_CTL (1 << 1)
311 #define IWN_FILTER_MULTICAST (1 << 2)
312 #define IWN_FILTER_NODECRYPT (1 << 3)
313 #define IWN_FILTER_BSS (1 << 5)
314
315 uint8_t chan;
316 uint8_t reserved5;
317 uint8_t ht_single_mask;
318 uint8_t ht_dual_mask;
319 } __packed;
320
321 /* structure for command IWN_CMD_ASSOCIATE */
322 struct iwn_assoc {
323 uint32_t flags;
324 uint32_t filter;
325 uint8_t ofdm_mask;
326 uint8_t cck_mask;
327 uint16_t reserved;
328 } __packed;
329
330 /* structure for command IWN_CMD_SET_WME */
331 struct iwn_wme_setup {
332 uint32_t flags;
333 #define IWN_EDCA_UPDATE (1 << 0)
334 #define IWN_EDCA_TXOP (1 << 4)
335
336 struct {
337 uint16_t cwmin;
338 uint16_t cwmax;
339 uint8_t aifsn;
340 uint8_t reserved;
341 uint16_t txop;
342 } __packed ac[WME_NUM_AC];
343 } __packed;
344
345 /* structure for command IWN_CMD_TSF */
346 struct iwn_cmd_tsf {
347 uint64_t tstamp;
348 uint16_t bintval;
349 uint16_t atim;
350 uint32_t binitval;
351 uint16_t lintval;
352 uint16_t reserved;
353 } __packed;
354
355 /* structure for command IWN_CMD_ADD_NODE */
356 struct iwn_node_info {
357 uint8_t control;
358 #define IWN_NODE_UPDATE (1 << 0)
359
360 uint8_t reserved1[3];
361 uint8_t macaddr[IEEE80211_ADDR_LEN];
362 uint16_t reserved2;
363 uint8_t id;
364 #define IWN_ID_BSS 0
365 #define IWN_ID_BROADCAST 31
366
367 uint8_t flags;
368 #define IWN_FLAG_SET_KEY (1 << 0)
369
370 uint16_t reserved3;
371 uint16_t security;
372 uint8_t tsc2; /* TKIP TSC2 */
373 uint8_t reserved4;
374 uint16_t ttak[5];
375 uint16_t reserved5;
376 uint8_t key[IEEE80211_KEYBUF_SIZE];
377 uint32_t htflags;
378 #define IWN_AMDPU_SIZE_FACTOR_SHIFT 19
379 #define IWN_AMDPU_DENSITY_SHIFT 23
380
381 uint32_t mask;
382 uint16_t tid;
383 uint8_t rate;
384 uint8_t rflags;
385 #define IWN_RFLAG_CCK (1 << 1)
386 #define IWN_RFLAG_ANT_A (1 << 6)
387 #define IWN_RFLAG_ANT_B (1 << 7)
388
389 uint8_t add_imm;
390 uint8_t del_imm;
391 uint16_t add_imm_start;
392 uint32_t reserved6;
393 } __packed;
394
395 /* structure for command IWN_CMD_TX_DATA */
396 struct iwn_cmd_data {
397 uint16_t len;
398 uint16_t lnext;
399 uint32_t flags;
400 #define IWN_TX_NEED_RTS (1 << 1)
401 #define IWN_TX_NEED_CTS (1 << 2)
402 #define IWN_TX_NEED_ACK (1 << 3)
403 #define IWN_TX_USE_NODE_RATE (1 << 4)
404 #define IWN_TX_FULL_TXOP (1 << 7)
405 #define IWN_TX_BT_DISABLE (1 << 12) /* bluetooth coexistence */
406 #define IWN_TX_AUTO_SEQ (1 << 13)
407 #define IWN_TX_INSERT_TSTAMP (1 << 16)
408 #define IWN_TX_NEED_PADDING (1 << 20)
409
410 uint8_t ntries;
411 uint8_t bluetooth;
412 uint16_t reserved1;
413 uint8_t rate;
414 uint8_t rflags;
415 uint16_t xrflags;
416 uint8_t id;
417 uint8_t security;
418 #define IWN_CIPHER_WEP40 1
419 #define IWN_CIPHER_CCMP 2
420 #define IWN_CIPHER_TKIP 3
421 #define IWN_CIPHER_WEP104 9
422
423 uint8_t ridx;
424 uint8_t reserved2;
425 uint8_t key[IEEE80211_KEYBUF_SIZE];
426 uint16_t fnext;
427 uint16_t reserved3;
428 uint32_t lifetime;
429 #define IWN_LIFETIME_INFINITE 0xffffffff
430
431 uint32_t loaddr;
432 uint8_t hiaddr;
433 uint8_t rts_ntries;
434 uint8_t data_ntries;
435 uint8_t tid;
436 uint16_t timeout;
437 uint16_t txop;
438 } __packed;
439
440 /* structure for command IWN_CMD_SET_BEACON */
441 struct iwn_cmd_beacon {
442 uint16_t len;
443 uint16_t reserved1;
444 uint32_t flags; /* same as iwn_cmd_data */
445 uint8_t rate;
446 uint8_t id;
447 uint8_t reserved2[30];
448 uint32_t lifetime;
449 uint8_t ofdm_mask;
450 uint8_t cck_mask;
451 uint16_t reserved3[3];
452 uint16_t tim;
453 uint8_t timsz;
454 uint8_t reserved4;
455 struct ieee80211_frame wh;
456 } __packed;
457
458 /* structure for command IWN_CMD_MRR_NODE_SETUP */
459 #define IWN_MAX_TX_RETRIES 16
460 struct iwn_cmd_mrr {
461 uint8_t id;
462 uint8_t reserved1;
463 uint16_t ctl;
464 uint8_t flags;
465 uint8_t mimo;
466 uint8_t ssmask;
467 uint8_t dsmask;
468 uint8_t ridx[WME_NUM_AC];
469 uint16_t ampdu_limit;
470 uint8_t ampdu_disable;
471 uint8_t ampdu_max;
472 uint32_t reserved2;
473 struct {
474 uint8_t rate;
475 #define IWN_CCK1 0
476 #define IWN_CCK11 3
477 #define IWN_OFDM6 4
478 #define IWN_OFDM54 11
479
480 uint8_t rflags;
481 uint16_t xrflags;
482 } table[IWN_MAX_TX_RETRIES];
483 uint32_t reserved3;
484 } __packed;
485
486 /* structure for command IWN_CMD_SET_LED */
487 struct iwn_cmd_led {
488 uint32_t unit; /* multiplier (in usecs) */
489 uint8_t which;
490 #define IWN_LED_ACTIVITY 1
491 #define IWN_LED_LINK 2
492
493 uint8_t off;
494 uint8_t on;
495 uint8_t reserved;
496 } __packed;
497
498 /* structure for command IWN_CMD_SET_POWER_MODE */
499 struct iwn_power {
500 uint16_t flags;
501 #define IWN_POWER_CAM 0 /* constantly awake mode */
502
503 uint8_t alive;
504 uint8_t debug;
505 uint32_t rx_timeout;
506 uint32_t tx_timeout;
507 uint32_t sleep[5];
508 uint32_t beacons;
509 } __packed;
510
511 /* structures for command IWN_CMD_SCAN */
512 struct iwn_scan_essid {
513 uint8_t id;
514 uint8_t len;
515 uint8_t data[IEEE80211_NWID_LEN];
516 } __packed;
517
518 struct iwn_scan_hdr {
519 uint16_t len;
520 uint8_t reserved1;
521 uint8_t nchan;
522 uint16_t quiet;
523 uint16_t plcp_threshold;
524 uint16_t crc_threshold;
525 uint16_t rxchain;
526 uint32_t max_svc; /* background scans */
527 uint32_t pause_svc; /* background scans */
528 uint32_t flags;
529 uint32_t filter;
530
531 /* followed by a struct iwn_cmd_data */
532 /* followed by an array of 4x struct iwn_scan_essid */
533 /* followed by probe request body */
534 /* followed by nchan x struct iwn_scan_chan */
535 } __packed;
536
537 struct iwn_scan_chan {
538 uint8_t flags;
539 #define IWN_CHAN_ACTIVE (1 << 0)
540 #define IWN_CHAN_DIRECT (1 << 1)
541
542 uint8_t chan;
543 uint8_t rf_gain;
544 uint8_t dsp_gain;
545 uint16_t active; /* msecs */
546 uint16_t passive; /* msecs */
547 } __packed;
548
549 /* structure for command IWN_CMD_TXPOWER */
550 #define IWN_RIDX_MAX 32
551 struct iwn_cmd_txpower {
552 uint8_t band;
553 uint8_t reserved1;
554 uint8_t chan;
555 uint8_t reserved2;
556 struct {
557 uint8_t rf_gain[IWN_NTXCHAINS];
558 uint8_t dsp_gain[IWN_NTXCHAINS];
559 } power[IWN_RIDX_MAX + 1];
560 } __packed;
561
562 /* structure for command IWN_CMD_BLUETOOTH */
563 struct iwn_bluetooth {
564 uint8_t flags;
565 uint8_t lead;
566 uint8_t kill;
567 uint8_t reserved;
568 uint32_t ack;
569 uint32_t cts;
570 } __packed;
571
572 /* structure for command IWN_CMD_SET_CRITICAL_TEMP */
573 struct iwn_critical_temp {
574 uint32_t reserved;
575 uint32_t tempM;
576 uint32_t tempR;
577 /* degK <-> degC conversion macros */
578 #define IWN_CTOK(c) ((c) + 273)
579 #define IWN_KTOC(k) ((k) - 273)
580 #define IWN_CTOMUK(c) (((c) * 1000000) + 273150000)
581 } __packed;
582
583 /* structure for command IWN_SENSITIVITY */
584 struct iwn_sensitivity_cmd {
585 uint16_t which;
586 #define IWN_SENSITIVITY_DEFAULTTBL 0
587 #define IWN_SENSITIVITY_WORKTBL 1
588
589 uint16_t energy_cck;
590 uint16_t energy_ofdm;
591 uint16_t corr_ofdm_x1;
592 uint16_t corr_ofdm_mrc_x1;
593 uint16_t corr_cck_mrc_x4;
594 uint16_t corr_ofdm_x4;
595 uint16_t corr_ofdm_mrc_x4;
596 uint16_t corr_barker;
597 uint16_t corr_barker_mrc;
598 uint16_t corr_cck_x4;
599 uint16_t energy_ofdm_th;
600 } __packed;
601
602 /* structure for command IWN_PHY_CALIB */
603 struct iwn_phy_calib_cmd {
604 uint8_t code;
605 #define IWN_SET_DIFF_GAIN 7
606
607 uint8_t flags;
608 uint16_t reserved1;
609 int8_t gain[3];
610 #define IWN_GAIN_SET (1 << 2)
611
612 uint8_t reserved2;
613 } __packed;
614
615
616 /* structure for IWN_UC_READY notification */
617 #define IWN_NATTEN_GROUPS 5
618 struct iwn_ucode_info {
619 uint8_t minor;
620 uint8_t major;
621 uint16_t reserved1;
622 uint8_t revision[8];
623 uint8_t type;
624 uint8_t subtype;
625 #define IWN_UCODE_RUNTIME 0
626 #define IWN_UCODE_INIT 9
627
628 uint16_t reserved2;
629 uint32_t logptr;
630 uint32_t errorptr;
631 uint32_t tstamp;
632 uint32_t valid;
633
634 /* the following fields are for UCODE_INIT only */
635 int32_t volt;
636 struct {
637 int32_t chan20MHz;
638 int32_t chan40MHz;
639 } __packed temp[4];
640 int32_t atten[IWN_NATTEN_GROUPS][IWN_NTXCHAINS];
641 } __packed;
642
643 /* structure for IWN_TX_DONE notification */
644 struct iwn_tx_stat {
645 uint8_t nframes;
646 uint8_t nkill;
647 uint8_t nrts;
648 uint8_t ntries;
649 uint8_t rate;
650 uint8_t rflags;
651 uint16_t xrflags;
652 uint16_t duration;
653 uint16_t reserved;
654 uint32_t power[2];
655 uint32_t status;
656 } __packed;
657
658 /* structure for IWN_BEACON_MISSED notification */
659 struct iwn_beacon_missed {
660 uint32_t consecutive;
661 uint32_t total;
662 uint32_t expected;
663 uint32_t received;
664 } __packed;
665
666 /* structure for IWN_AMPDU_RX_DONE notification */
667 struct iwn_rx_ampdu {
668 uint16_t len;
669 uint16_t reserved;
670 } __packed;
671
672 /* structure for IWN_RX_DONE and IWN_AMPDU_RX_START notifications */
673 struct iwn_rx_stat {
674 uint8_t phy_len;
675 uint8_t cfg_phy_len;
676 #define IWN_STAT_MAXLEN 20
677
678 uint8_t id;
679 uint8_t reserved1;
680 uint64_t tstamp;
681 uint32_t beacon;
682 uint16_t flags;
683 uint16_t chan;
684 uint16_t antenna;
685 uint16_t agc;
686 uint8_t rssi[6];
687 #define IWN_RSSI_TO_DBM 44
688
689 uint8_t reserved2[22];
690 uint8_t rate;
691 uint8_t rflags;
692 uint16_t xrflags;
693 uint16_t len;
694 uint16_t reserve3;
695 } __packed;
696
697 /* structure for IWN_START_SCAN notification */
698 struct iwn_start_scan {
699 uint64_t tstamp;
700 uint32_t tbeacon;
701 uint8_t chan;
702 uint8_t band;
703 uint16_t reserved;
704 uint32_t status;
705 } __packed;
706
707 /* structure for IWN_STOP_SCAN notification */
708 struct iwn_stop_scan {
709 uint8_t nchan;
710 uint8_t status;
711 uint8_t reserved;
712 uint8_t chan;
713 uint64_t tsf;
714 } __packed;
715
716 /* structure for IWN_{RX,BEACON}_STATISTICS notification */
717 struct iwn_rx_phy_stats {
718 uint32_t ina;
719 uint32_t fina;
720 uint32_t bad_plcp;
721 uint32_t bad_crc32;
722 uint32_t overrun;
723 uint32_t eoverrun;
724 uint32_t good_crc32;
725 uint32_t fa;
726 uint32_t bad_fina_sync;
727 uint32_t sfd_timeout;
728 uint32_t fina_timeout;
729 uint32_t no_rts_ack;
730 uint32_t rxe_limit;
731 uint32_t ack;
732 uint32_t cts;
733 uint32_t ba_resp;
734 uint32_t dsp_kill;
735 uint32_t bad_mh;
736 uint32_t rssi_sum;
737 uint32_t reserved;
738 } __packed;
739
740 struct iwn_rx_general_stats {
741 uint32_t bad_cts;
742 uint32_t bad_ack;
743 uint32_t not_bss;
744 uint32_t filtered;
745 uint32_t bad_chan;
746 uint32_t beacons;
747 uint32_t missed_beacons;
748 uint32_t adc_saturated; /* time in 0.8us */
749 uint32_t ina_searched; /* time in 0.8us */
750 uint32_t noise[3];
751 uint32_t flags;
752 uint32_t load;
753 uint32_t fa;
754 uint32_t rssi[3];
755 uint32_t energy[3];
756 } __packed;
757
758 struct iwn_rx_ht_phy_stats {
759 uint32_t bad_plcp;
760 uint32_t overrun;
761 uint32_t eoverrun;
762 uint32_t good_crc32;
763 uint32_t bad_crc32;
764 uint32_t bad_mh;
765 uint32_t good_ampdu_crc32;
766 uint32_t ampdu;
767 uint32_t fragment;
768 uint32_t reserved;
769 } __packed;
770
771 struct iwn_rx_stats {
772 struct iwn_rx_phy_stats ofdm;
773 struct iwn_rx_phy_stats cck;
774 struct iwn_rx_general_stats general;
775 struct iwn_rx_ht_phy_stats ht;
776 } __packed;
777
778 struct iwn_tx_stats {
779 uint32_t preamble;
780 uint32_t rx_detected;
781 uint32_t bt_defer;
782 uint32_t bt_kill;
783 uint32_t short_len;
784 uint32_t cts_timeout;
785 uint32_t ack_timeout;
786 uint32_t exp_ack;
787 uint32_t ack;
788 uint32_t msdu;
789 uint32_t busrt_err1;
790 uint32_t burst_err2;
791 uint32_t cts_collision;
792 uint32_t ack_collision;
793 uint32_t ba_timeout;
794 uint32_t ba_resched;
795 uint32_t query_ampdu;
796 uint32_t query;
797 uint32_t query_ampdu_frag;
798 uint32_t query_mismatch;
799 uint32_t not_ready;
800 uint32_t underrun;
801 uint32_t bt_ht_kill;
802 uint32_t rx_ba_resp;
803 uint32_t reserved[2];
804 } __packed;
805
806 struct iwn_general_stats {
807 uint32_t temp;
808 uint32_t temp_m;
809 uint32_t burst_check;
810 uint32_t burst;
811 uint32_t reserved1[4];
812 uint32_t sleep;
813 uint32_t slot_out;
814 uint32_t slot_idle;
815 uint32_t ttl_tstamp;
816 uint32_t tx_ant_a;
817 uint32_t tx_ant_b;
818 uint32_t exec;
819 uint32_t probe;
820 uint32_t reserved2[2];
821 uint32_t rx_enabled;
822 uint32_t reserved3[3];
823 } __packed;
824
825 struct iwn_stats {
826 uint32_t flags;
827 struct iwn_rx_stats rx;
828 struct iwn_tx_stats tx;
829 struct iwn_general_stats general;
830 } __packed;
831
832
833 /* firmware image header */
834 struct iwn_firmware_hdr {
835 uint32_t version;
836 uint32_t main_textsz;
837 uint32_t main_datasz;
838 uint32_t init_textsz;
839 uint32_t init_datasz;
840 uint32_t boot_textsz;
841 } __packed;
842
843 #define IWN_FW_MAIN_TEXT_MAXSZ (96 * 1024)
844 #define IWN_FW_MAIN_DATA_MAXSZ (40 * 1024)
845 #define IWN_FW_INIT_TEXT_MAXSZ (96 * 1024)
846 #define IWN_FW_INIT_DATA_MAXSZ (40 * 1024)
847 #define IWN_FW_BOOT_TEXT_MAXSZ 1024
848
849
850 /*
851 * Offsets into EEPROM.
852 */
853 #define IWN_EEPROM_MAC 0x015
854 #define IWN_EEPROM_DOMAIN 0x060
855 #define IWN_EEPROM_BAND1 0x063
856 #define IWN_EEPROM_BAND2 0x072
857 #define IWN_EEPROM_BAND3 0x080
858 #define IWN_EEPROM_BAND4 0x08d
859 #define IWN_EEPROM_BAND5 0x099
860 #define IWN_EEPROM_BAND6 0x0a0
861 #define IWN_EEPROM_BAND7 0x0a8
862 #define IWN_EEPROM_MAXPOW 0x0e8
863 #define IWN_EEPROM_VOLTAGE 0x0e9
864 #define IWN_EEPROM_BANDS 0x0ea
865
866 struct iwn_eeprom_chan {
867 uint8_t flags;
868 #define IWN_EEPROM_CHAN_VALID (1 << 0)
869 #define IWN_EEPROM_CHAN_IBSS (1 << 1)
870 #define IWN_EEPROM_CHAN_ACTIVE (1 << 3)
871 #define IWN_EEPROM_CHAN_RADAR (1 << 4)
872
873 int8_t maxpwr;
874 } __packed;
875
876 #define IWN_NSAMPLES 3
877 struct iwn_eeprom_chan_samples {
878 uint8_t num;
879 struct {
880 uint8_t temp;
881 uint8_t gain;
882 uint8_t power;
883 int8_t pa_det;
884 } samples[IWN_NTXCHAINS][IWN_NSAMPLES];
885 } __packed;
886
887 #define IWN_NBANDS 8
888 struct iwn_eeprom_band {
889 uint8_t lo; /* low channel number */
890 uint8_t hi; /* high channel number */
891 struct iwn_eeprom_chan_samples chans[2];
892 } __packed;
893
894 #define IWN_CHAN_BANDS_COUNT 7
895 #define IWN_MAX_CHAN_PER_BAND 14
896 static const struct iwn_chan_band {
897 uint32_t addr; /* offset in EEPROM */
898 uint8_t nchan;
899 uint8_t chan[IWN_MAX_CHAN_PER_BAND];
900 } iwn_bands[] = {
901 { IWN_EEPROM_BAND1, 14,
902 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
903 { IWN_EEPROM_BAND2, 13,
904 { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
905 { IWN_EEPROM_BAND3, 12,
906 { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
907 { IWN_EEPROM_BAND4, 11,
908 { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
909 { IWN_EEPROM_BAND5, 6,
910 { 145, 149, 153, 157, 161, 165 } },
911 { IWN_EEPROM_BAND6, 7,
912 { 1, 2, 3, 4, 5, 6, 7 } },
913 { IWN_EEPROM_BAND7, 11,
914 { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
915 };
916
917 static const uint8_t iwn_ridx_to_plcp[] = {
918 10, 20, 55, 110, /* CCK */
919 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
920 };
921
922 /* allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
923 static const uint8_t iwn_prev_ridx[] = {
924 0, 0, 1, 5, /* CCK */
925 2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
926 };
927
928 #define IWN_MAX_PWR_INDEX 107
929
930 /*
931 * RF Tx gain values from highest to lowest power (values obtained from
932 * the reference driver.)
933 */
934 static const uint8_t iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
935 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
936 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38,
937 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35,
938 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31,
939 0x31, 0x30, 0x30, 0x30, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x04,
940 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
944 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
945 };
946
947 static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
948 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d,
949 0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39,
950 0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35,
951 0x35, 0x35, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32,
952 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x25, 0x25, 0x25, 0x24, 0x24,
953 0x24, 0x23, 0x23, 0x23, 0x22, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16,
954 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13,
955 0x12, 0x08, 0x08, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x05, 0x05,
956 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01,
957 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
958 };
959
960 /*
961 * DSP pre-DAC gain values from highest to lowest power (values obtained
962 * from the reference driver.)
963 */
964 static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
965 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
966 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
967 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
968 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
969 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
970 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
971 0x6e, 0x68, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a,
972 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f,
973 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44,
974 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b
975 };
976
977 static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
978 0x7b, 0x75, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
979 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
980 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
981 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
982 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
983 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
984 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
985 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
986 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
987 0x68, 0x62, 0x6e, 0x68, 0x62, 0x5d, 0x58, 0x53, 0x4e
988 };
989
990 #define IWN_READ(sc, reg) \
991 bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
992
993 #define IWN_WRITE(sc, reg, val) \
994 bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
995
996 #define IWN_WRITE_REGION_4(sc, offset, datap, count) \
997 bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset), \
998 (datap), (count))
999