xref: /dragonfly/sys/dev/netif/wpi/if_wpireg.h (revision 7370bffcb64eb03375b862bc589756a04c51b43e)
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 
20 #define WPI_TX_RING_COUNT     256
21 #define WPI_TX_RING_LOMARK    192
22 #define WPI_TX_RING_HIMARK    224
23 
24 #ifdef DIAGNOSTIC
25 #define WPI_RX_RING_COUNT_LOG 8
26 #else
27 #define WPI_RX_RING_COUNT_LOG 6
28 #endif
29 
30 #define WPI_RX_RING_COUNT     (1 << WPI_RX_RING_COUNT_LOG)
31 
32 #define WPI_NTXQUEUES                   8
33 #define WPI_DRV_NTXQUEUES     5
34 #define WPI_CMD_QUEUE_NUM     4
35 
36 #define WPI_NDMACHNLS                   6
37 
38 /* Maximum scatter/gather. */
39 #define WPI_MAX_SCATTER                 4
40 
41 /*
42  * Rings must be aligned on a 16K boundary.
43  */
44 #define WPI_RING_DMA_ALIGN    0x4000
45 
46 /* Maximum Rx buffer size. */
47 #define WPI_RBUF_SIZE ( 3 * 1024 ) /* XXX 3000 but must be aligned */
48 
49 /*
50  * Control and status registers.
51  */
52 #define WPI_HW_IF_CONFIG      0x000
53 #define WPI_INT                         0x008
54 #define WPI_INT_MASK                    0x00c
55 #define WPI_FH_INT            0x010
56 #define WPI_GPIO_IN           0x018
57 #define WPI_RESET             0x020
58 #define WPI_GP_CNTRL                    0x024
59 #define WPI_EEPROM            0x02c
60 #define WPI_EEPROM_GP                   0x030
61 #define WPI_GIO                         0x03c
62 #define WPI_UCODE_GP1                   0x054
63 #define WPI_UCODE_GP1_SET     0x058
64 #define WPI_UCODE_GP1_CLR     0x05c
65 #define WPI_UCODE_GP2                   0x060
66 #define WPI_GIO_CHICKEN                 0x100
67 #define WPI_ANA_PLL           0x20c
68 #define WPI_DBG_HPET_MEM      0x240
69 #define WPI_MEM_RADDR                   0x40c
70 #define WPI_MEM_WADDR                   0x410
71 #define WPI_MEM_WDATA                   0x418
72 #define WPI_MEM_RDATA                   0x41c
73 #define WPI_PRPH_WADDR                  0x444
74 #define WPI_PRPH_RADDR                  0x448
75 #define WPI_PRPH_WDATA                  0x44c
76 #define WPI_PRPH_RDATA                  0x450
77 #define WPI_HBUS_TARG_WRPTR   0x460
78 
79 /*
80  * Flow-Handler registers.
81  */
82 #define WPI_FH_CBBC_CTRL(qid) (0x940 + (qid) * 8)
83 #define WPI_FH_CBBC_BASE(qid) (0x944 + (qid) * 8)
84 #define WPI_FH_RX_CONFIG      0xc00
85 #define WPI_FH_RX_BASE                  0xc04
86 #define WPI_FH_RX_WPTR                  0xc20
87 #define WPI_FH_RX_RPTR_ADDR   0xc24
88 #define WPI_FH_RSSR_TBL                 0xcc0
89 #define WPI_FH_RX_STATUS      0xcc4
90 #define WPI_FH_TX_CONFIG(qid) (0xd00 + (qid) * 32)
91 #define WPI_FH_TX_BASE                  0xe80
92 #define WPI_FH_MSG_CONFIG     0xe88
93 #define WPI_FH_TX_STATUS      0xe90
94 
95 
96 /*
97  * NIC internal memory offsets.
98  */
99 #define WPI_ALM_SCHED_MODE              0x2e00
100 #define WPI_ALM_SCHED_ARASTAT           0x2e04
101 #define WPI_ALM_SCHED_TXFACT            0x2e10
102 #define WPI_ALM_SCHED_TXF4MF            0x2e14
103 #define WPI_ALM_SCHED_TXF5MF            0x2e20
104 #define WPI_ALM_SCHED_SBYPASS_MODE1     0x2e2c
105 #define WPI_ALM_SCHED_SBYPASS_MODE2     0x2e30
106 #define WPI_APMG_CLK_CTRL               0x3000
107 #define WPI_APMG_CLK_EN                           0x3004
108 #define WPI_APMG_CLK_DIS                0x3008
109 #define WPI_APMG_PS                     0x300c
110 #define WPI_APMG_PCI_STT                0x3010
111 #define WPI_APMG_RFKILL                           0x3014
112 #define WPI_BSM_WR_CTRL                           0x3400
113 #define WPI_BSM_WR_MEM_SRC              0x3404
114 #define WPI_BSM_WR_MEM_DST              0x3408
115 #define WPI_BSM_WR_DWCOUNT              0x340c
116 #define WPI_BSM_DRAM_TEXT_ADDR                    0x3490
117 #define WPI_BSM_DRAM_TEXT_SIZE                    0x3494
118 #define WPI_BSM_DRAM_DATA_ADDR                    0x3498
119 #define WPI_BSM_DRAM_DATA_SIZE                    0x349c
120 #define WPI_BSM_SRAM_BASE               0x3800
121 
122 
123 /* Possible flags for register WPI_HW_IF_CONFIG. */
124 #define WPI_HW_IF_CONFIG_ALM_MB                   (1 << 8)
125 #define WPI_HW_IF_CONFIG_ALM_MM                   (1 << 9)
126 #define WPI_HW_IF_CONFIG_SKU_MRC        (1 << 10)
127 #define WPI_HW_IF_CONFIG_REV_D                    (1 << 11)
128 #define WPI_HW_IF_CONFIG_TYPE_B                   (1 << 12)
129 
130 /* Possible flags for registers WPI_PRPH_RADDR/WPI_PRPH_WADDR. */
131 #define WPI_PRPH_DWORD        ((sizeof (uint32_t) - 1) << 24)
132 
133 /* Possible values for WPI_BSM_WR_MEM_DST. */
134 #define WPI_FW_TEXT_BASE      0x00000000
135 #define WPI_FW_DATA_BASE      0x00800000
136 
137 /* Possible flags for WPI_GPIO_IN. */
138 #define WPI_GPIO_IN_VMAIN     (1 << 9)
139 
140 /* Possible flags for register WPI_RESET. */
141 #define WPI_RESET_NEVO                            (1 << 0)
142 #define WPI_RESET_SW                              (1 << 7)
143 #define WPI_RESET_MASTER_DISABLED       (1 << 8)
144 #define WPI_RESET_STOP_MASTER           (1 << 9)
145 
146 /* Possible flags for register WPI_GP_CNTRL. */
147 #define WPI_GP_CNTRL_MAC_ACCESS_ENA     (1 <<  0)
148 #define WPI_GP_CNTRL_MAC_CLOCK_READY    (1 <<  0)
149 #define WPI_GP_CNTRL_INIT_DONE                    (1 <<  2)
150 #define WPI_GP_CNTRL_MAC_ACCESS_REQ     (1 <<  3)
151 #define WPI_GP_CNTRL_SLEEP              (1 <<  4)
152 #define WPI_GP_CNTRL_PS_MASK            (7 << 24)
153 #define WPI_GP_CNTRL_MAC_PS             (4 << 24)
154 #define WPI_GP_CNTRL_RFKILL             (1 << 27)
155 
156 /* Possible flags for register WPI_GIO_CHICKEN. */
157 #define WPI_GIO_CHICKEN_L1A_NO_L0S_RX   (1 << 23)
158 #define WPI_GIO_CHICKEN_DIS_L0S_TIMER   (1 << 29)
159 
160 /* Possible flags for register WPI_GIO. */
161 #define WPI_GIO_L0S_ENA                           (1 << 1)
162 
163 /* Possible flags for register WPI_FH_RX_CONFIG. */
164 #define WPI_FH_RX_CONFIG_DMA_ENA        (1U  << 31)
165 #define WPI_FH_RX_CONFIG_RDRBD_ENA      (1   << 29)
166 #define WPI_FH_RX_CONFIG_WRSTATUS_ENA   (1   << 27)
167 #define WPI_FH_RX_CONFIG_MAXFRAG        (1   << 24)
168 #define WPI_FH_RX_CONFIG_NRBD(x)        ((x) << 20)
169 #define WPI_FH_RX_CONFIG_IRQ_DST_HOST   (1   << 12)
170 #define WPI_FH_RX_CONFIG_IRQ_TIMEOUT(x) ((x) <<  4)
171 
172 /* Possible flags for register WPI_ANA_PLL. */
173 #define WPI_ANA_PLL_INIT      (1 << 24)
174 
175 /* Possible flags for register WPI_UCODE_GP1*. */
176 #define WPI_UCODE_GP1_MAC_SLEEP                   (1 << 0)
177 #define WPI_UCODE_GP1_RFKILL            (1 << 1)
178 #define WPI_UCODE_GP1_CMD_BLOCKED       (1 << 2)
179 
180 /* Possible flags for register WPI_FH_RX_STATUS. */
181 #define   WPI_FH_RX_STATUS_IDLE         (1 << 24)
182 
183 /* Possible flags for register WPI_BSM_WR_CTRL. */
184 #define WPI_BSM_WR_CTRL_START_EN        (1  << 30)
185 #define WPI_BSM_WR_CTRL_START           (1U << 31)
186 
187 /* Possible flags for register WPI_INT. */
188 #define WPI_INT_ALIVE                   (1  <<  0)
189 #define WPI_INT_WAKEUP                  (1  <<  1)
190 #define WPI_INT_SW_RX                   (1  <<  3)
191 #define WPI_INT_SW_ERR                  (1  << 25)
192 #define WPI_INT_FH_TX                   (1  << 27)
193 #define WPI_INT_HW_ERR                  (1  << 29)
194 #define WPI_INT_FH_RX                   (1U << 31)
195 
196 /* Shortcut. */
197 #define WPI_INT_MASK_DEF                                              \
198           (WPI_INT_SW_ERR | WPI_INT_HW_ERR | WPI_INT_FH_TX  |         \
199            WPI_INT_FH_RX  | WPI_INT_ALIVE  | WPI_INT_WAKEUP |         \
200            WPI_INT_SW_RX)
201 
202 /* Possible flags for register WPI_FH_INT. */
203 #define WPI_FH_INT_RX_CHNL(x) (1 << ((x) + 16))
204 #define WPI_FH_INT_HI_PRIOR   (1 << 30)
205 /* Shortcuts for the above. */
206 #define WPI_FH_INT_RX                             \
207           (WPI_FH_INT_RX_CHNL(0) |      \
208            WPI_FH_INT_RX_CHNL(1) |      \
209            WPI_FH_INT_RX_CHNL(2) |      \
210            WPI_FH_INT_HI_PRIOR)
211 
212 /* Possible flags for register WPI_FH_TX_STATUS. */
213 #define WPI_FH_TX_STATUS_IDLE(qid)      \
214           (1 << ((qid) + 24) | 1 << ((qid) + 16))
215 
216 /* Possible flags for register WPI_EEPROM. */
217 #define WPI_EEPROM_READ_VALID (1 << 0)
218 
219 /* Possible flags for register WPI_EEPROM_GP. */
220 #define WPI_EEPROM_VERSION    0x00000007
221 #define WPI_EEPROM_GP_IF_OWNER          0x00000180
222 
223 /* Possible flags for register WPI_APMG_PS. */
224 #define WPI_APMG_PS_PWR_SRC_MASK        (3 << 24)
225 
226 /* Possible flags for registers WPI_APMG_CLK_*. */
227 #define WPI_APMG_CLK_CTRL_DMA_CLK_RQT   (1 <<  9)
228 #define WPI_APMG_CLK_CTRL_BSM_CLK_RQT   (1 << 11)
229 
230 /* Possible flags for register WPI_APMG_PCI_STT. */
231 #define WPI_APMG_PCI_STT_L1A_DIS        (1 << 11)
232 
233 struct wpi_shared {
234           uint32_t  txbase[WPI_NTXQUEUES];
235           uint32_t  next;
236           uint32_t  reserved[2];
237 } __packed;
238 
239 #define WPI_MAX_SEG_LEN       65520
240 struct wpi_tx_desc {
241           uint8_t             reserved1[3];
242           uint8_t             nsegs;
243 #define WPI_PAD32(x)          (roundup2(x, 4) - (x))
244 
245           struct {
246                     uint32_t  addr;
247                     uint32_t  len;
248           } __packed          segs[WPI_MAX_SCATTER];
249           uint8_t             reserved2[28];
250 } __packed;
251 
252 struct wpi_tx_stat {
253           uint8_t             rtsfailcnt;
254           uint8_t             ackfailcnt;
255           uint8_t             btkillcnt;
256           uint8_t             rate;
257           uint32_t  duration;
258           uint32_t  status;
259 #define WPI_TX_STATUS_SUCCESS                     0x01
260 #define WPI_TX_STATUS_DIRECT_DONE                 0x02
261 #define WPI_TX_STATUS_FAIL                        0x80
262 #define WPI_TX_STATUS_FAIL_SHORT_LIMIT            0x82
263 #define WPI_TX_STATUS_FAIL_LONG_LIMIT             0x83
264 #define WPI_TX_STATUS_FAIL_FIFO_UNDERRUN          0x84
265 #define WPI_TX_STATUS_FAIL_MGMNT_ABORT            0x85
266 #define WPI_TX_STATUS_FAIL_NEXT_FRAG              0x86
267 #define WPI_TX_STATUS_FAIL_LIFE_EXPIRE            0x87
268 #define WPI_TX_STATUS_FAIL_NODE_PS                0x88
269 #define WPI_TX_STATUS_FAIL_ABORTED                0x89
270 #define WPI_TX_STATUS_FAIL_BT_RETRY               0x8a
271 #define WPI_TX_STATUS_FAIL_NODE_INVALID           0x8b
272 #define WPI_TX_STATUS_FAIL_FRAG_DROPPED           0x8c
273 #define WPI_TX_STATUS_FAIL_TID_DISABLE            0x8d
274 #define WPI_TX_STATUS_FAIL_FRAME_FLUSHED          0x8e
275 #define WPI_TX_STATUS_FAIL_INSUFFICIENT_CF_POLL   0x8f
276 #define WPI_TX_STATUS_FAIL_TX_LOCKED              0x90
277 #define WPI_TX_STATUS_FAIL_NO_BEACON_ON_RADAR     0x91
278 
279 } __packed;
280 
281 struct wpi_rx_desc {
282           uint32_t  len;
283           uint8_t             type;
284 #define WPI_UC_READY                      1
285 #define WPI_RX_DONE            27
286 #define WPI_TX_DONE            28
287 #define WPI_START_SCAN                  130
288 #define WPI_SCAN_RESULTS      131
289 #define WPI_STOP_SCAN                   132
290 #define WPI_BEACON_SENT                 144
291 #define WPI_RX_STATISTICS     156
292 #define WPI_BEACON_STATISTICS 157
293 #define WPI_STATE_CHANGED     161
294 #define WPI_BEACON_MISSED     162
295 
296           uint8_t             flags;
297           uint8_t             idx;
298           uint8_t             qid;
299 } __packed;
300 
301 #define WPI_RX_DESC_QID_MSK             0x07
302 #define WPI_UNSOLICITED_RX_NOTIF        0x80
303 
304 struct wpi_rx_stat {
305           uint8_t             len;
306 #define WPI_STAT_MAXLEN       20
307 
308           uint8_t             id;
309           uint8_t             rssi;     /* received signal strength */
310 #define WPI_RSSI_OFFSET       -95
311 
312           uint8_t             agc;      /* access gain control */
313           uint16_t  signal;
314           uint16_t  noise;
315 } __packed;
316 
317 struct wpi_rx_head {
318           uint16_t  chan;
319           uint16_t  flags;
320 #define WPI_STAT_FLAG_SHPREAMBLE        (1 << 2)
321 
322           uint8_t             reserved;
323           uint8_t             plcp;
324           uint16_t  len;
325 } __packed;
326 
327 struct wpi_rx_tail {
328           uint32_t  flags;
329 #define WPI_RX_NO_CRC_ERR     (1 << 0)
330 #define WPI_RX_NO_OVFL_ERR    (1 << 1)
331 /* shortcut for the above */
332 #define WPI_RX_NOERROR                  (WPI_RX_NO_CRC_ERR | WPI_RX_NO_OVFL_ERR)
333 #define WPI_RX_CIPHER_MASK    (7 <<  8)
334 #define WPI_RX_CIPHER_CCMP    (2 <<  8)
335 #define WPI_RX_DECRYPT_MASK   (3 << 11)
336 #define WPI_RX_DECRYPT_OK     (3 << 11)
337 
338           uint64_t  tstamp;
339           uint32_t  tbeacon;
340 } __packed;
341 
342 struct wpi_tx_cmd {
343           uint8_t   code;
344 #define WPI_CMD_RXON                     16
345 #define WPI_CMD_RXON_ASSOC     17
346 #define WPI_CMD_EDCA_PARAMS    19
347 #define WPI_CMD_TIMING                   20
348 #define WPI_CMD_ADD_NODE       24
349 #define WPI_CMD_DEL_NODE       25
350 #define WPI_CMD_TX_DATA                  28
351 #define WPI_CMD_MRR_SETUP      71
352 #define WPI_CMD_SET_LED                  72
353 #define WPI_CMD_SET_POWER_MODE          119
354 #define WPI_CMD_SCAN                    128
355 #define WPI_CMD_SCAN_ABORT    129
356 #define WPI_CMD_SET_BEACON    145
357 #define WPI_CMD_TXPOWER                 151
358 #define WPI_CMD_BT_COEX                 155
359 #define WPI_CMD_GET_STATISTICS          156
360 
361           uint8_t   flags;
362           uint8_t   idx;
363           uint8_t   qid;
364           uint8_t   data[124];
365 } __packed;
366 
367 /* Structure for command WPI_CMD_RXON. */
368 struct wpi_rxon {
369           uint8_t             myaddr[IEEE80211_ADDR_LEN];
370           uint16_t  reserved1;
371           uint8_t             bssid[IEEE80211_ADDR_LEN];
372           uint16_t  reserved2;
373           uint8_t             wlap[IEEE80211_ADDR_LEN];
374           uint16_t  reserved3;
375           uint8_t             mode;
376 #define WPI_MODE_HOSTAP                 1
377 #define WPI_MODE_STA                    3
378 #define WPI_MODE_IBSS                   4
379 #define WPI_MODE_MONITOR      6
380 
381           uint8_t             air;
382           uint16_t  reserved4;
383           uint8_t             ofdm_mask;
384           uint8_t             cck_mask;
385           uint16_t  associd;
386           uint32_t  flags;
387 #define WPI_RXON_24GHZ                  (1 <<  0)
388 #define WPI_RXON_CCK                    (1 <<  1)
389 #define WPI_RXON_AUTO                   (1 <<  2)
390 #define WPI_RXON_SHSLOT                 (1 <<  4)
391 #define WPI_RXON_SHPREAMBLE   (1 <<  5)
392 #define WPI_RXON_NODIVERSITY  (1 <<  7)
393 #define WPI_RXON_ANTENNA_A    (1 <<  8)
394 #define WPI_RXON_ANTENNA_B    (1 <<  9)
395 #define WPI_RXON_TSF                    (1 << 15)
396 #define WPI_RXON_CTS_TO_SELF  (1 << 30)
397 
398           uint32_t  filter;
399 #define WPI_FILTER_PROMISC    (1 << 0)
400 #define WPI_FILTER_CTL                  (1 << 1)
401 #define WPI_FILTER_MULTICAST  (1 << 2)
402 #define WPI_FILTER_NODECRYPT  (1 << 3)
403 #define WPI_FILTER_BSS                  (1 << 5)
404 #define WPI_FILTER_BEACON     (1 << 6)
405 #define WPI_FILTER_ASSOC      (1 << 7)    /* Accept associaton requests. */
406 
407           uint8_t             chan;
408           uint16_t  reserved5;
409 } __packed;
410 
411 /* Structure for command WPI_CMD_RXON_ASSOC. */
412 struct wpi_assoc {
413           uint32_t  flags;
414           uint32_t  filter;
415           uint8_t             ofdm_mask;
416           uint8_t             cck_mask;
417           uint16_t  reserved;
418 } __packed;
419 
420 /* Structure for command WPI_CMD_EDCA_PARAMS. */
421 struct wpi_edca_params {
422           uint32_t  flags;
423 #define WPI_EDCA_UPDATE       (1 << 0)
424 
425           struct {
426                     uint16_t  cwmin;
427                     uint16_t  cwmax;
428                     uint8_t             aifsn;
429                     uint8_t             reserved;
430                     uint16_t  txoplimit;
431           } __packed          ac[WME_NUM_AC];
432 } __packed;
433 
434 /* Structure for command WPI_CMD_TIMING. */
435 struct wpi_cmd_timing {
436           uint64_t  tstamp;
437           uint16_t  bintval;
438           uint16_t  atim;
439           uint32_t  binitval;
440           uint16_t  lintval;
441           uint16_t  reserved;
442 } __packed;
443 
444 /* Structure for command WPI_CMD_ADD_NODE. */
445 struct wpi_node_info {
446           uint8_t             control;
447 #define WPI_NODE_UPDATE                 (1 << 0)
448 
449           uint8_t             reserved1[3];
450           uint8_t             macaddr[IEEE80211_ADDR_LEN];
451           uint16_t  reserved2;
452           uint8_t             id;
453 #define WPI_ID_BSS            0
454 #define WPI_ID_IBSS_MIN                 2
455 #define WPI_ID_IBSS_MAX                 23
456 #define WPI_ID_BROADCAST      24
457 #define WPI_ID_UNDEFINED      (uint8_t)-1
458 
459           uint8_t             flags;
460 #define WPI_FLAG_KEY_SET      (1 << 0)
461 
462           uint16_t  reserved3;
463           uint16_t  kflags;
464 #define WPI_KFLAG_CCMP                  (1 <<  1)
465 #define WPI_KFLAG_KID(kid)    ((kid) << 8)
466 #define WPI_KFLAG_MULTICAST   (1 << 14)
467 
468           uint8_t             tsc2;
469           uint8_t             reserved4;
470           uint16_t  ttak[5];
471           uint16_t  reserved5;
472           uint8_t             key[IEEE80211_KEYBUF_SIZE];
473           uint32_t  action;
474 #define WPI_ACTION_SET_RATE   (1 << 2)
475 
476           uint32_t  mask;
477           uint16_t  tid;
478           uint8_t             plcp;
479           uint8_t             antenna;
480 #define WPI_ANTENNA_A                   (1 << 6)
481 #define WPI_ANTENNA_B                   (1 << 7)
482 #define WPI_ANTENNA_BOTH      (WPI_ANTENNA_A | WPI_ANTENNA_B)
483 
484           uint8_t             add_imm;
485           uint8_t             del_imm;
486           uint16_t  add_imm_start;
487 } __packed;
488 
489 /* Structure for command WPI_CMD_DEL_NODE. */
490 struct wpi_cmd_del_node {
491           uint8_t             count;
492           uint8_t             reserved1[3];
493           uint8_t             macaddr[IEEE80211_ADDR_LEN];
494           uint16_t  reserved2;
495 } __packed;
496 
497 /* Structure for command WPI_CMD_TX_DATA. */
498 struct wpi_cmd_data {
499           uint16_t  len;
500           uint16_t  lnext;
501           uint32_t  flags;
502 #define WPI_TX_NEED_RTS                 (1 <<  1)
503 #define WPI_TX_NEED_CTS                 (1 <<  2)
504 #define WPI_TX_NEED_ACK                 (1 <<  3)
505 #define WPI_TX_FULL_TXOP      (1 <<  7)
506 #define WPI_TX_BT_DISABLE     (1 << 12)           /* bluetooth coexistence */
507 #define WPI_TX_AUTO_SEQ                 (1 << 13)
508 #define WPI_TX_MORE_FRAG      (1 << 14)
509 #define WPI_TX_INSERT_TSTAMP  (1 << 16)
510 
511           uint8_t             plcp;
512           uint8_t             id;
513           uint8_t             tid;
514           uint8_t             security;
515 #define WPI_CIPHER_WEP                  1
516 #define WPI_CIPHER_CCMP                 2
517 #define WPI_CIPHER_TKIP                 3
518 #define WPI_CIPHER_WEP104     9
519 
520           uint8_t             key[IEEE80211_KEYBUF_SIZE];
521           uint8_t             tkip[IEEE80211_WEP_MICLEN];
522           uint32_t  fnext;
523 #define WPI_NEXT_STA_ID(id)   ((id) << 8)
524 
525           uint32_t  lifetime;
526 #define WPI_LIFETIME_INFINITE 0xffffffff
527 
528           uint8_t             ofdm_mask;
529           uint8_t             cck_mask;
530           uint8_t             rts_ntries;
531           uint8_t             data_ntries;
532           uint16_t  timeout;
533           uint16_t  txop;
534 } __packed;
535 
536 /* Structure for command WPI_CMD_SET_BEACON. */
537 struct wpi_cmd_beacon {
538           uint16_t  len;
539           uint16_t  reserved1;
540           uint32_t  flags;    /* same as wpi_cmd_data */
541           uint8_t             plcp;
542           uint8_t             id;
543           uint8_t             reserved2[30];
544           uint32_t  lifetime;
545           uint8_t             ofdm_mask;
546           uint8_t             cck_mask;
547           uint16_t  reserved3[3];
548           uint16_t  tim;
549           uint8_t             timsz;
550           uint8_t             reserved4;
551 } __packed;
552 
553 /* Structure for notification WPI_BEACON_MISSED. */
554 struct wpi_beacon_missed {
555           uint32_t consecutive;
556           uint32_t total;
557           uint32_t expected;
558           uint32_t received;
559 } __packed;
560 
561 
562 /* Structure for command WPI_CMD_MRR_SETUP. */
563 #define WPI_RIDX_MAX          11
564 struct wpi_mrr_setup {
565           uint32_t  which;
566 #define WPI_MRR_CTL 0
567 #define WPI_MRR_DATA          1
568 
569           struct {
570                     uint8_t   plcp;
571                     uint8_t   flags;
572                     uint8_t   ntries;
573 #define             WPI_NTRIES_DEFAULT  2
574 
575                     uint8_t   next;
576           } __packed          rates[WPI_RIDX_MAX + 1];
577 } __packed;
578 
579 /* Structure for command WPI_CMD_SET_LED. */
580 struct wpi_cmd_led {
581           uint32_t  unit;     /* multiplier (in usecs) */
582           uint8_t             which;
583 #define WPI_LED_ACTIVITY      1
584 #define WPI_LED_LINK                    2
585 
586           uint8_t             off;
587           uint8_t             on;
588           uint8_t             reserved;
589 } __packed;
590 
591 /* Structure for command WPI_CMD_SET_POWER_MODE. */
592 struct wpi_pmgt_cmd {
593           uint16_t  flags;
594 #define WPI_PS_ALLOW_SLEEP    (1 << 0)
595 #define WPI_PS_NOTIFY                   (1 << 1)
596 #define WPI_PS_SLEEP_OVER_DTIM          (1 << 2)
597 #define WPI_PS_PCI_PMGT                 (1 << 3)
598 
599           uint8_t             reserved[2];
600           uint32_t  rxtimeout;
601           uint32_t  txtimeout;
602           uint32_t  intval[5];
603 } __packed;
604 
605 /* Structures for command WPI_CMD_SCAN. */
606 #define WPI_SCAN_MAX_ESSIDS   4
607 struct wpi_scan_essid {
608           uint8_t   id;
609           uint8_t   len;
610           uint8_t   data[IEEE80211_NWID_LEN];
611 } __packed;
612 
613 struct wpi_scan_hdr {
614           uint16_t  len;
615           uint8_t             reserved1;
616           uint8_t             nchan;
617           uint16_t  quiet_time;         /* timeout in milliseconds */
618 #define WPI_QUIET_TIME_DEFAULT                    10
619 
620           uint16_t  quiet_threshold; /* min # of packets */
621           uint16_t  crc_threshold;
622           uint16_t  reserved2;
623           uint32_t  max_svc;  /* background scans */
624           uint32_t  pause_svc;          /* background scans */
625 #define WPI_PAUSE_MAX_TIME              ((1 << 20) - 1)
626 #define WPI_PAUSE_SCAN(nbeacons, time)  ((nbeacons << 24) | time)
627 
628           uint32_t  flags;
629           uint32_t  filter;
630 
631           /* Followed by a struct wpi_cmd_data. */
632           /* Followed by an array of 4 structs wpi_scan_essid. */
633           /* Followed by probe request body. */
634           /* Followed by an array of ``nchan'' structs wpi_scan_chan. */
635 } __packed;
636 
637 struct wpi_scan_chan {
638           uint8_t             flags;
639 #define WPI_CHAN_ACTIVE                 (1 << 0)
640 #define WPI_CHAN_NPBREQS(x)   (((1 << (x)) - 1) << 1)
641 
642           uint8_t             chan;
643           uint8_t             rf_gain;
644           uint8_t             dsp_gain;
645           uint16_t  active;             /* msecs */
646           uint16_t  passive;  /* msecs */
647 } __packed;
648 
649 #define WPI_SCAN_CRC_TH_DEFAULT                   htole16(1)
650 #define WPI_SCAN_CRC_TH_NEVER           htole16(0xffff)
651 
652 /* Maximum size of a scan command. */
653 #define WPI_SCAN_MAXSZ        (MCLBYTES - 4)
654 
655 #define WPI_ACTIVE_DWELL_TIME_2GHZ      (30)      /* all times in msec */
656 #define WPI_ACTIVE_DWELL_TIME_5GHZ      (20)
657 #define WPI_ACTIVE_DWELL_FACTOR_2GHZ    ( 3)
658 #define WPI_ACTIVE_DWELL_FACTOR_5GHZ    ( 2)
659 
660 #define WPI_PASSIVE_DWELL_TIME_2GHZ     ( 20)
661 #define WPI_PASSIVE_DWELL_TIME_5GHZ     ( 10)
662 #define WPI_PASSIVE_DWELL_BASE                    (100)
663 #define WPI_CHANNEL_TUNE_TIME           (  6)
664 
665 /* Structure for command WPI_CMD_TXPOWER. */
666 struct wpi_cmd_txpower {
667           uint8_t             band;
668 #define WPI_BAND_5GHZ         0
669 #define WPI_BAND_2GHZ         1
670 
671           uint8_t             reserved;
672           uint16_t  chan;
673 
674           struct {
675                     uint8_t   plcp;
676                     uint8_t   rf_gain;
677                     uint8_t   dsp_gain;
678                     uint8_t   reserved;
679           } __packed          rates[WPI_RIDX_MAX + 1];
680 
681 } __packed;
682 
683 /* Structure for command WPI_CMD_BT_COEX. */
684 struct wpi_bluetooth {
685           uint8_t             flags;
686 #define WPI_BT_COEX_DISABLE   0
687 #define WPI_BT_COEX_MODE_2WIRE          1
688 #define WPI_BT_COEX_MODE_3WIRE          2
689 #define WPI_BT_COEX_MODE_4WIRE          3
690 
691           uint8_t             lead_time;
692 #define WPI_BT_LEAD_TIME_DEF  30
693 
694           uint8_t             max_kill;
695 #define WPI_BT_MAX_KILL_DEF   5
696 
697           uint8_t             reserved;
698           uint32_t  kill_ack;
699           uint32_t  kill_cts;
700 } __packed;
701 
702 /* Structure for WPI_UC_READY notification. */
703 struct wpi_ucode_info {
704           uint8_t             minor;
705           uint8_t             major;
706           uint16_t  reserved1;
707           uint8_t             revision[8];
708           uint8_t             type;
709           uint8_t             subtype;
710           uint16_t  reserved2;
711           uint32_t  logptr;
712           uint32_t  errptr;
713           uint32_t  tstamp;
714           uint32_t  valid;
715 } __packed;
716 
717 /* Structure for WPI_START_SCAN notification. */
718 struct wpi_start_scan {
719           uint64_t  tstamp;
720           uint32_t  tbeacon;
721           uint8_t             chan;
722           uint8_t             band;
723           uint16_t  reserved;
724           uint32_t  status;
725 } __packed;
726 
727 /* Structure for WPI_STOP_SCAN notification. */
728 struct wpi_stop_scan {
729           uint8_t             nchan;
730           uint8_t             status;
731 #define WPI_SCAN_COMPLETED    1
732 #define WPI_SCAN_ABORTED      2
733 
734           uint8_t             reserved;
735           uint8_t             chan;
736           uint64_t  tsf;
737 } __packed;
738 
739 /* Structures for WPI_{RX,BEACON}_STATISTICS notification. */
740 struct wpi_rx_phy_stats {
741           uint32_t  ina;
742           uint32_t  fina;
743           uint32_t  bad_plcp;
744           uint32_t  bad_crc32;
745           uint32_t  overrun;
746           uint32_t  eoverrun;
747           uint32_t  good_crc32;
748           uint32_t  fa;
749           uint32_t  bad_fina_sync;
750           uint32_t  sfd_timeout;
751           uint32_t  fina_timeout;
752           uint32_t  no_rts_ack;
753           uint32_t  rxe_limit;
754           uint32_t  ack;
755           uint32_t  cts;
756 } __packed;
757 
758 struct wpi_rx_general_stats {
759           uint32_t  bad_cts;
760           uint32_t  bad_ack;
761           uint32_t  not_bss;
762           uint32_t  filtered;
763           uint32_t  bad_chan;
764 } __packed;
765 
766 struct wpi_rx_stats {
767           struct wpi_rx_phy_stats                 ofdm;
768           struct wpi_rx_phy_stats                 cck;
769           struct wpi_rx_general_stats   general;
770 } __packed;
771 
772 struct wpi_tx_stats {
773           uint32_t  preamble;
774           uint32_t  rx_detected;
775           uint32_t  bt_defer;
776           uint32_t  bt_kill;
777           uint32_t  short_len;
778           uint32_t  cts_timeout;
779           uint32_t  ack_timeout;
780           uint32_t  exp_ack;
781           uint32_t  ack;
782 } __packed;
783 
784 struct wpi_general_stats {
785           uint32_t  temp;
786           uint32_t  burst_check;
787           uint32_t  burst;
788           uint32_t  reserved[4];
789           uint32_t  sleep;
790           uint32_t  slot_out;
791           uint32_t  slot_idle;
792           uint32_t  ttl_tstamp;
793           uint32_t  tx_ant_a;
794           uint32_t  tx_ant_b;
795           uint32_t  exec;
796           uint32_t  probe;
797 } __packed;
798 
799 struct wpi_stats {
800           uint32_t                      flags;
801           struct wpi_rx_stats           rx;
802           struct wpi_tx_stats           tx;
803           struct wpi_general_stats      general;
804 } __packed;
805 
806 /* Possible flags for command WPI_CMD_GET_STATISTICS. */
807 #define WPI_STATISTICS_BEACON_DISABLE   (1 << 1)
808 
809 
810 /* Firmware error dump entry. */
811 struct wpi_fw_dump {
812           uint32_t  desc;
813           uint32_t  time;
814           uint32_t  blink[2];
815           uint32_t  ilink[2];
816           uint32_t  data;
817 } __packed;
818 
819 /* Firmware image file header. */
820 struct wpi_firmware_hdr {
821 
822 #define WPI_FW_MINVERSION 2144
823 #define WPI_FW_NAME "wpifw"
824 
825           uint16_t  driver;
826           uint8_t             minor;
827           uint8_t             major;
828           uint32_t  rtextsz;
829           uint32_t  rdatasz;
830           uint32_t  itextsz;
831           uint32_t  idatasz;
832           uint32_t  btextsz;
833 } __packed;
834 
835 #define WPI_FW_TEXT_MAXSZ      ( 80 * 1024 )
836 #define WPI_FW_DATA_MAXSZ      ( 32 * 1024 )
837 #define WPI_FW_BOOT_TEXT_MAXSZ                    1024
838 
839 #define WPI_FW_UPDATED        (1U << 31 )
840 
841 /*
842  * Offsets into EEPROM.
843  */
844 #define WPI_EEPROM_MAC                  0x015
845 #define WPI_EEPROM_REVISION   0x035
846 #define WPI_EEPROM_SKU_CAP    0x045
847 #define WPI_EEPROM_TYPE                 0x04a
848 #define WPI_EEPROM_DOMAIN     0x060
849 #define WPI_EEPROM_BAND1      0x063
850 #define WPI_EEPROM_BAND2      0x072
851 #define WPI_EEPROM_BAND3      0x080
852 #define WPI_EEPROM_BAND4      0x08d
853 #define WPI_EEPROM_BAND5      0x099
854 #define WPI_EEPROM_POWER_GRP  0x100
855 
856 struct wpi_eeprom_chan {
857           uint8_t   flags;
858 #define WPI_EEPROM_CHAN_VALID (1 << 0)
859 #define   WPI_EEPROM_CHAN_IBSS          (1 << 1)
860 #define WPI_EEPROM_CHAN_ACTIVE          (1 << 3)
861 #define WPI_EEPROM_CHAN_RADAR (1 << 4)
862 
863           int8_t    maxpwr;
864 } __packed;
865 
866 struct wpi_eeprom_sample {
867           uint8_t             index;
868           int8_t              power;
869           uint16_t  volt;
870 } __packed;
871 
872 #define WPI_POWER_GROUPS_COUNT          5
873 struct wpi_eeprom_group {
874           struct              wpi_eeprom_sample samples[5];
875           int32_t             coef[5];
876           int32_t             corr[5];
877           int8_t              maxpwr;
878           uint8_t             chan;
879           int16_t             temp;
880 } __packed;
881 
882 #define WPI_CHAN_BANDS_COUNT   5
883 #define WPI_MAX_CHAN_PER_BAND 14
884 static const struct wpi_chan_band {
885           uint32_t  addr;     /* offset in EEPROM */
886           uint8_t             nchan;
887           uint8_t             chan[WPI_MAX_CHAN_PER_BAND];
888 } wpi_bands[] = {
889           /* 20MHz channels, 2GHz band. */
890           { WPI_EEPROM_BAND1, 14,
891               { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
892           /* 20MHz channels, 5GHz band. */
893           { WPI_EEPROM_BAND2, 13,
894               { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
895           { WPI_EEPROM_BAND3, 12,
896               { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
897           { WPI_EEPROM_BAND4, 11,
898               { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
899           { WPI_EEPROM_BAND5, 6,
900               { 145, 149, 153, 157, 161, 165 } }
901 };
902 
903 /* HW rate indices. */
904 #define WPI_RIDX_OFDM6         0
905 #define WPI_RIDX_OFDM36        5
906 #define WPI_RIDX_OFDM48        6
907 #define WPI_RIDX_OFDM54        7
908 #define WPI_RIDX_CCK1          8
909 #define WPI_RIDX_CCK2          9
910 #define WPI_RIDX_CCK11        11
911 
912 static const uint8_t wpi_ridx_to_plcp[] = {
913           /* OFDM: IEEE Std 802.11a-1999, pp. 14 Table 80 */
914           /* R1-R4 (ral/ural is R4-R1) */
915           0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3,
916           /* CCK: device-dependent */
917           10, 20, 55, 110
918 };
919 
920 #define WPI_MAX_PWR_INDEX     77
921 
922 /*
923  * RF Tx gain values from highest to lowest power (values obtained from
924  * the reference driver.)
925  */
926 static const uint8_t wpi_rf_gain_2ghz[WPI_MAX_PWR_INDEX + 1] = {
927           0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xbb, 0xbb, 0xbb,
928           0xbb, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xd3, 0xd3, 0xb3, 0xb3, 0xb3,
929           0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x73, 0xeb, 0xeb, 0xeb,
930           0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xab, 0xab, 0xab, 0x8b,
931           0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xc3, 0xc3, 0xc3, 0xc3, 0xa3,
932           0xa3, 0xa3, 0xa3, 0x83, 0x83, 0x83, 0x83, 0x63, 0x63, 0x63, 0x63,
933           0x43, 0x43, 0x43, 0x43, 0x23, 0x23, 0x23, 0x23, 0x03, 0x03, 0x03,
934           0x03
935 };
936 
937 static const uint8_t wpi_rf_gain_5ghz[WPI_MAX_PWR_INDEX + 1] = {
938           0xfb, 0xfb, 0xfb, 0xdb, 0xdb, 0xbb, 0xbb, 0x9b, 0x9b, 0x7b, 0x7b,
939           0x7b, 0x7b, 0x5b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x1b, 0x1b,
940           0x1b, 0x73, 0x73, 0x73, 0x53, 0x53, 0x53, 0x53, 0x53, 0x33, 0x33,
941           0x33, 0x33, 0x13, 0x13, 0x13, 0x13, 0x13, 0xab, 0xab, 0xab, 0x8b,
942           0x8b, 0x8b, 0x8b, 0x6b, 0x6b, 0x6b, 0x6b, 0x4b, 0x4b, 0x4b, 0x4b,
943           0x2b, 0x2b, 0x2b, 0x2b, 0x0b, 0x0b, 0x0b, 0x0b, 0x83, 0x83, 0x63,
944           0x63, 0x63, 0x63, 0x43, 0x43, 0x43, 0x43, 0x23, 0x23, 0x23, 0x23,
945           0x03
946 };
947 
948 /*
949  * DSP pre-DAC gain values from highest to lowest power (values obtained
950  * from the reference driver.)
951  */
952 static const uint8_t wpi_dsp_gain_2ghz[WPI_MAX_PWR_INDEX + 1] = {
953           0x7f, 0x7f, 0x7f, 0x7f, 0x7d, 0x6e, 0x69, 0x62, 0x7d, 0x73, 0x6c,
954           0x63, 0x77, 0x6f, 0x69, 0x61, 0x5c, 0x6a, 0x64, 0x78, 0x71, 0x6b,
955           0x7d, 0x77, 0x70, 0x6a, 0x65, 0x61, 0x5b, 0x6b, 0x79, 0x73, 0x6d,
956           0x7f, 0x79, 0x73, 0x6c, 0x66, 0x60, 0x5c, 0x6e, 0x68, 0x62, 0x74,
957           0x7d, 0x77, 0x71, 0x6b, 0x65, 0x60, 0x71, 0x6a, 0x66, 0x5f, 0x71,
958           0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f,
959           0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66,
960           0x5f
961 };
962 
963 static const uint8_t wpi_dsp_gain_5ghz[WPI_MAX_PWR_INDEX + 1] = {
964           0x7f, 0x78, 0x72, 0x77, 0x65, 0x71, 0x66, 0x72, 0x67, 0x75, 0x6b,
965           0x63, 0x5c, 0x6c, 0x7d, 0x76, 0x6d, 0x66, 0x60, 0x5a, 0x68, 0x62,
966           0x5c, 0x76, 0x6f, 0x68, 0x7e, 0x79, 0x71, 0x69, 0x63, 0x76, 0x6f,
967           0x68, 0x62, 0x74, 0x6d, 0x66, 0x62, 0x5d, 0x71, 0x6b, 0x63, 0x78,
968           0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63,
969           0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x6b, 0x63, 0x78,
970           0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63,
971           0x78
972 };
973 
974 /*
975  * Power saving settings (values obtained from the reference driver.)
976  */
977 #define WPI_NDTIMRANGES                 2
978 #define WPI_NPOWERLEVELS      6
979 static const struct wpi_pmgt {
980           uint32_t  rxtimeout;
981           uint32_t  txtimeout;
982           uint32_t  intval[5];
983           uint8_t             skip_dtim;
984 } wpi_pmgt[WPI_NDTIMRANGES][WPI_NPOWERLEVELS] = {
985           /* DTIM <= 10 */
986           {
987           {   0,   0, {  0,  0,  0,  0,  0 }, 0 },          /* CAM */
988           { 200, 500, {  1,  2,  3,  4,  4 }, 0 },          /* PS level 1 */
989           { 200, 300, {  2,  4,  6,  7,  7 }, 0 },          /* PS level 2 */
990           {  50, 100, {  2,  6,  9,  9, 10 }, 0 },          /* PS level 3 */
991           {  50,  25, {  2,  7,  9,  9, 10 }, 1 },          /* PS level 4 */
992           {  25,  25, {  4,  7, 10, 10, 10 }, 1 }           /* PS level 5 */
993           },
994           /* DTIM >= 11 */
995           {
996           {   0,   0, {  0,  0,  0,  0,  0 }, 0 },          /* CAM */
997           { 200, 500, {  1,  2,  3,  4, -1 }, 0 },          /* PS level 1 */
998           { 200, 300, {  2,  4,  6,  7, -1 }, 0 },          /* PS level 2 */
999           {  50, 100, {  2,  6,  9,  9, -1 }, 0 },          /* PS level 3 */
1000           {  50,  25, {  2,  7,  9,  9, -1 }, 0 },          /* PS level 4 */
1001           {  25,  25, {  4,  7, 10, 10, -1 }, 0 }           /* PS level 5 */
1002           }
1003 };
1004 
1005 /* Firmware errors. */
1006 static const char * const wpi_fw_errmsg[] = {
1007           "OK",
1008           "FAIL",
1009           "BAD_PARAM",
1010           "BAD_CHECKSUM",
1011           "NMI_INTERRUPT",
1012           "SYSASSERT",
1013           "FATAL_ERROR"
1014 };
1015 
1016 #define WPI_READ(sc, reg)                                                       \
1017           bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
1018 
1019 #define WPI_WRITE(sc, reg, val)                                                           \
1020           bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
1021 
1022 #define WPI_WRITE_REGION_4(sc, offset, datap, count)                            \
1023           bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset),          \
1024               (datap), (count))
1025 
1026 #define WPI_SETBITS(sc, reg, mask)                                              \
1027           WPI_WRITE(sc, reg, WPI_READ(sc, reg) | (mask))
1028 
1029 #define WPI_CLRBITS(sc, reg, mask)                                              \
1030           WPI_WRITE(sc, reg, WPI_READ(sc, reg) & ~(mask))
1031 
1032 #define WPI_BARRIER_WRITE(sc)                                                   \
1033           bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz, \
1034               BUS_SPACE_BARRIER_WRITE)
1035 
1036 #define WPI_BARRIER_READ_WRITE(sc)                                              \
1037           bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz, \
1038               BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
1039