xref: /illumos-gate/usr/src/uts/common/io/wpi/wpireg.h (revision 626dff79)
1 /*
2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2006
8  *	Damien Bergamini <damien.bergamini@free.fr>
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #ifndef	_WPIREG_H_
24 #define	_WPIREG_H_
25 
26 #ifdef	__cplusplus
27 extern "C" {
28 #endif
29 
30 #define	WPI_TX_RING_COUNT	256
31 #define	WPI_SVC_RING_COUNT	256
32 #define	WPI_CMD_RING_COUNT	256
33 #define	WPI_RX_RING_COUNT	64
34 
35 /*
36  * Rings must be aligned on a four 4K-pages boundary.
37  * I had a hard time figuring this out.
38  */
39 #define	WPI_RING_DMA_ALIGN	0x4000
40 
41 /*
42  * maximum scatter/gather
43  */
44 #define	WPI_MAX_SCATTER	4
45 
46 /*
47  * Control and status registers.
48  */
49 #define	WPI_HWCONFIG		0x000
50 #define	WPI_INTR		0x008
51 #define	WPI_MASK		0x00c
52 #define	WPI_INTR_STATUS		0x010
53 #define	WPI_GPIO_STATUS		0x018
54 #define	WPI_RESET		0x020
55 #define	WPI_GPIO_CTL		0x024
56 #define	WPI_EEPROM_CTL		0x02c
57 #define	WPI_EEPROM_STATUS	0x030
58 #define	WPI_UCODE_CLR		0x05c
59 #define	WPI_TEMPERATURE		0x060
60 #define	WPI_CHICKEN		0x100
61 #define	WPI_PLL_CTL		0x20c
62 #define	WPI_FW_TARGET		0x410
63 #define	WPI_WRITE_MEM_ADDR  	0x444
64 #define	WPI_READ_MEM_ADDR   	0x448
65 #define	WPI_WRITE_MEM_DATA  	0x44c
66 #define	WPI_READ_MEM_DATA   	0x450
67 #define	WPI_TX_WIDX		0x460
68 #define	WPI_TX_CTL(qid)		(0x940 + (qid) * 8)
69 #define	WPI_TX_BASE(qid)	(0x944 + (qid) * 8)
70 #define	WPI_TX_DESC(qid)	(0x980 + (qid) * 80)
71 #define	WPI_RX_CONFIG		0xc00
72 #define	WPI_RX_BASE		0xc04
73 #define	WPI_RX_WIDX		0xc20
74 #define	WPI_RX_RIDX_PTR		0xc24
75 #define	WPI_RX_CTL		0xcc0
76 #define	WPI_RX_STATUS		0xcc4
77 #define	WPI_TX_CONFIG(qid)	(0xd00 + (qid) * 32)
78 #define	WPI_TX_CREDIT(qid)	(0xd04 + (qid) * 32)
79 #define	WPI_TX_STATE(qid)	(0xd08 + (qid) * 32)
80 #define	WPI_TX_BASE_PTR		0xe80
81 #define	WPI_MSG_CONFIG		0xe88
82 #define	WPI_TX_STATUS		0xe90
83 
84 
85 /*
86  * NIC internal memory offsets.
87  */
88 #define	WPI_MEM_MODE		0x2e00
89 #define	WPI_MEM_RA		0x2e04
90 #define	WPI_MEM_TXCFG		0x2e10
91 #define	WPI_MEM_MAGIC4		0x2e14
92 #define	WPI_MEM_MAGIC5		0x2e20
93 #define	WPI_MEM_BYPASS1		0x2e2c
94 #define	WPI_MEM_BYPASS2		0x2e30
95 #define	WPI_MEM_CLOCK1		0x3004
96 #define	WPI_MEM_CLOCK2		0x3008
97 #define	WPI_MEM_POWER		0x300c
98 #define	WPI_MEM_PCIDEV		0x3010
99 #define	WPI_MEM_UCODE_CTL	0x3400
100 #define	WPI_MEM_UCODE_SRC	0x3404
101 #define	WPI_MEM_UCODE_DST	0x3408
102 #define	WPI_MEM_UCODE_SIZE	0x340c
103 #define	WPI_MEM_UCODE_BASE	0x3800
104 
105 
106 /*
107  * possible flags for register WPI_HWCONFIG
108  */
109 #define	WPI_HW_ALM_MB	(1 << 8)
110 #define	WPI_HW_ALM_MM	(1 << 9)
111 #define	WPI_HW_SKU_MRC	(1 << 10)
112 #define	WPI_HW_REV_D	(1 << 11)
113 #define	WPI_HW_TYPE_B	(1 << 12)
114 
115 /*
116  * possible flags for registers WPI_READ_MEM_ADDR/WPI_WRITE_MEM_ADDR
117  */
118 #define	WPI_MEM_4	((sizeof (uint32_t) - 1) << 24)
119 
120 /*
121  * possible values for WPI_FW_TARGET
122  */
123 #define	WPI_FW_TEXT	0x00000000
124 #define	WPI_FW_DATA	0x00800000
125 
126 /*
127  * possible flags for WPI_GPIO_STATUS
128  */
129 #define	WPI_POWERED		(1 << 9)
130 
131 /*
132  * possible flags for register WPI_RESET
133  */
134 #define	WPI_NEVO_RESET		(1 << 0)
135 #define	WPI_SW_RESET		(1 << 7)
136 #define	WPI_MASTER_DISABLED	(1 << 8)
137 #define	WPI_STOP_MASTER		(1 << 9)
138 
139 /*
140  * possible flags for register WPI_GPIO_CTL
141  */
142 #define	WPI_GPIO_CLOCK		(1 << 0)
143 #define	WPI_GPIO_INIT		(1 << 2)
144 #define	WPI_GPIO_MAC		(1 << 3)
145 #define	WPI_GPIO_SLEEP		(1 << 4)
146 #define	WPI_GPIO_PWR_STATUS	0x07000000
147 #define	WPI_GPIO_PWR_SLEEP	(4 << 24)
148 #define	WPI_GPIO_HW_RF_KILL	(1 << 27)
149 
150 /*
151  * possible flags for register WPI_CHICKEN
152  */
153 #define	WPI_CHICKEN_RXNOLOS	(1 << 23)
154 
155 /*
156  * possible flags for register WPI_PLL_CTL
157  */
158 #define	WPI_PLL_INIT		(1 << 24)
159 
160 /*
161  * possible flags for register WPI_UCODE_CLR
162  */
163 #define	WPI_RADIO_OFF		(1 << 1)
164 #define	WPI_DISABLE_CMD		(1 << 2)
165 
166 /*
167  * possible flags for WPI_RX_STATUS
168  */
169 #define	WPI_RX_IDLE	(1 << 24)
170 
171 /*
172  * possible flags for register WPI_UC_CTL
173  */
174 #define	WPI_UC_RUN	(1 << 30)
175 
176 /*
177  * possible flags for register WPI_INTR_CSR
178  */
179 #define	WPI_ALIVE_INTR	(1 << 0)
180 #define	WPI_WAKEUP_INTR	(1 << 1)
181 #define	WPI_RX_SWINT	(1 << 3)
182 #define	WPI_RF_KILL	(1 << 7)
183 #define	WPI_SW_ERROR	(1 << 25)
184 #define	WPI_TX_INTR	(1 << 27)
185 #define	WPI_HW_ERROR	(1 << 29)
186 #define	WPI_RX_INTR	(((uint32_t)1) << 31)
187 
188 #define	WPI_INTR_MASK							\
189 	(WPI_SW_ERROR | WPI_HW_ERROR | WPI_TX_INTR | WPI_RX_INTR |	\
190 	WPI_ALIVE_INTR | WPI_WAKEUP_INTR)
191 
192 /*
193  * possible flags for register WPI_TX_STATUS
194  */
195 #define	WPI_TX_IDLE(qid)	(1 << ((qid) + 24) | 1 << ((qid) + 16))
196 
197 /*
198  * possible flags for register WPI_EEPROM_CTL
199  */
200 #define	WPI_EEPROM_READY	(1 << 0)
201 
202 /*
203  * possible flags for register WPI_EEPROM_STATUS
204  */
205 #define	WPI_EEPROM_VERSION	0x00000007
206 #define	WPI_EEPROM_LOCKED	0x00000180
207 
208 
209 typedef struct wpi_shared {
210 	uint32_t	txbase[8];
211 	uint32_t	next;
212 	uint32_t	reserved[2];
213 } wpi_shared_t;
214 
215 #define	WPI_MAX_SEG_LEN	65520
216 typedef struct wpi_tx_desc {
217 	uint32_t	flags;
218 #define	WPI_PAD32(x)	(roundup(x, 4) - (x))
219 
220 	struct {
221 		uint32_t	addr;
222 		uint32_t	len;
223 	} segs[WPI_MAX_SCATTER];
224 	uint8_t		reserved[28];
225 } wpi_tx_desc_t;
226 
227 typedef struct wpi_tx_stat {
228 	uint8_t		nrts;
229 	uint8_t		ntries;
230 	uint8_t		nkill;
231 	uint8_t		rate;
232 	uint32_t	duration;
233 	uint32_t	status;
234 } wpi_tx_stat_t;
235 
236 typedef struct wpi_rx_desc {
237 	uint32_t	len;
238 	uint8_t		type;
239 #define	WPI_UC_READY		  1
240 #define	WPI_RX_DONE		 27
241 #define	WPI_TX_DONE		 28
242 #define	WPI_START_SCAN		130
243 #define	WPI_START_RESULT	131
244 #define	WPI_STOP_SCAN		132
245 #define	WPI_STATE_CHANGED	161
246 
247 	uint8_t		flags;
248 	uint8_t		idx;
249 	uint8_t		qid;
250 } wpi_rx_desc_t;
251 
252 typedef struct wpi_rx_stat {
253 	uint8_t		len;
254 #define	WPI_STAT_MAXLEN	20
255 
256 	uint8_t		id;
257 	uint8_t		rssi;	/* received signal strength */
258 #define	WPI_RSSI_OFFSET	95
259 
260 	uint8_t		agc;	/* access gain control */
261 	uint16_t	signal;
262 	uint16_t	noise;
263 } wpi_rx_stat_t;
264 
265 typedef struct wpi_rx_head {
266 	uint16_t	chan;
267 	uint16_t	flags;
268 	uint8_t		reserved;
269 	uint8_t		rate;
270 	uint16_t	len;
271 } wpi_rx_head_t;
272 
273 typedef struct wpi_rx_tail {
274 	uint32_t	flags;
275 #define	WPI_RX_NO_CRC_ERR	(1 << 0)
276 #define	WPI_RX_NO_OVFL_ERR	(1 << 1)
277 #define	WPI_RX_NOERROR		(WPI_RX_NO_CRC_ERR | WPI_RX_NO_OVFL_ERR)
278 
279 	uint64_t	tstamp;
280 	uint32_t	tbeacon;
281 } wpi_rx_tail_t;
282 
283 typedef struct wpi_tx_cmd {
284 	uint8_t	code;
285 #define	WPI_CMD_CONFIGURE	 16
286 #define	WPI_CMD_ASSOCIATE	 17
287 #define	WPI_CMD_SET_WME		 19
288 #define	WPI_CMD_TSF		 20
289 #define	WPI_CMD_ADD_NODE	 24
290 #define	WPI_CMD_TX_DATA		 28
291 #define	WPI_CMD_MRR_SETUP	 71
292 #define	WPI_CMD_SET_LED		 72
293 #define	WPI_CMD_SET_POWER_MODE	119
294 #define	WPI_CMD_SCAN		128
295 #define	WPI_CMD_SET_BEACON	145
296 #define	WPI_CMD_BLUETOOTH	155
297 #define	WPI_CMD_TXPOWER		176
298 
299 	uint8_t	flags;
300 	uint8_t	idx;
301 	uint8_t	qid;
302 	uint8_t	data[124];
303 } wpi_tx_cmd_t;
304 
305 /*
306  * structure for WPI_CMD_CONFIGURE
307  */
308 typedef struct wpi_config {
309 	uint8_t		myaddr[IEEE80211_ADDR_LEN];
310 	uint16_t	reserved1;
311 	uint8_t		bssid[IEEE80211_ADDR_LEN];
312 	uint16_t	reserved2;
313 	uint32_t	reserved3[2];
314 	uint8_t		mode;
315 #define	WPI_MODE_HOSTAP		1
316 #define	WPI_MODE_STA		3
317 #define	WPI_MODE_IBSS		4
318 #define	WPI_MODE_MONITOR	6
319 
320 	uint8_t		reserved4[3];
321 	uint8_t		ofdm_mask;
322 	uint8_t		cck_mask;
323 	uint16_t	state;
324 #define	WPI_CONFIG_ASSOCIATED	4
325 
326 	uint32_t	flags;
327 #define	WPI_CONFIG_24GHZ	(1 << 0)
328 #define	WPI_CONFIG_CCK		(1 << 1)
329 #define	WPI_CONFIG_AUTO		(1 << 2)
330 #define	WPI_CONFIG_SHSLOT	(1 << 4)
331 #define	WPI_CONFIG_SHPREAMBLE	(1 << 5)
332 #define	WPI_CONFIG_NODIVERSITY	(1 << 7)
333 #define	WPI_CONFIG_ANTENNA_A	(1 << 8)
334 #define	WPI_CONFIG_ANTENNA_B	(1 << 9)
335 #define	WPI_CONFIG_TSF		(1 << 15)
336 
337 	uint32_t	filter;
338 #define	WPI_FILTER_PROMISC	(1 << 0)
339 #define	WPI_FILTER_CTL		(1 << 1)
340 #define	WPI_FILTER_MULTICAST	(1 << 2)
341 #define	WPI_FILTER_NODECRYPTUNI	(1 << 3)
342 #define	WPI_FILTER_NODECRYPTMUL	(1 << 4)
343 #define	WPI_FILTER_BSS		(1 << 5)
344 #define	WPI_FILTER_BEACON	(1 << 6)
345 
346 	uint8_t		chan;
347 	uint8_t		reserved6[3];
348 } wpi_config_t;
349 
350 /*
351  * structure for command WPI_CMD_ASSOCIATE
352  */
353 typedef struct wpi_assoc {
354 	uint32_t	flags;
355 	uint32_t	filter;
356 	uint8_t		ofdm_mask;
357 	uint8_t		cck_mask;
358 	uint16_t	reserved;
359 } wpi_assoc_t;
360 
361 /*
362  * structure for command WPI_CMD_SET_WME
363  */
364 typedef struct wpi_wme_setup {
365 	uint32_t	flags;
366 	struct {
367 		uint16_t	cwmin;
368 		uint16_t	cwmax;
369 		uint8_t		aifsn;
370 		uint8_t		reserved;
371 		uint16_t	txop;
372 	} ac[WME_NUM_AC];
373 } wpi_wme_setup_t;
374 
375 /*
376  * structure for command WPI_CMD_TSF
377  */
378 typedef struct wpi_cmd_tsf {
379 	uint64_t	tstamp;
380 	uint16_t	bintval;
381 	uint16_t	atim;
382 	uint32_t	binitval;
383 	uint16_t	lintval;
384 	uint16_t	reserved;
385 } wpi_cmd_tsf_t;
386 
387 /*
388  * structure for WPI_CMD_ADD_NODE
389  */
390 typedef struct wpi_node {
391 	uint8_t		control;
392 #define	WPI_NODE_UPDATE	(1 << 0)
393 
394 	uint8_t		reserved1[3];
395 	uint8_t		bssid[IEEE80211_ADDR_LEN];
396 	uint16_t	reserved2;
397 	uint8_t		id;
398 #define	WPI_ID_BSS		0
399 #define	WPI_ID_BROADCAST	24
400 
401 	uint8_t		sta_mask;
402 	uint16_t	reserved3;
403 	uint16_t	key_flags;
404 	uint8_t		tkip;
405 	uint8_t		reserved4;
406 	uint16_t	ttak[5];
407 	uint8_t		keyp;
408 	uint8_t		reserved5;
409 	uint8_t		key[16];
410 	uint32_t	flags;
411 	uint32_t	mask;
412 	uint16_t	tid;
413 	uint8_t		rate;
414 	uint8_t		reserved6;
415 	uint8_t		add_imm;
416 	uint8_t		del_imm;
417 	uint16_t	add_imm_start;
418 } wpi_node_t;
419 
420 /*
421  * structure for command WPI_CMD_TX_DATA
422  */
423 typedef struct wpi_cmd_data {
424 	uint16_t	len;
425 	uint16_t	lnext;
426 	uint32_t	flags;
427 #define	WPI_TX_NEED_RTS		(1 <<  1)
428 #define	WPI_TX_NEED_ACK		(1 <<  3)
429 #define	WPI_TX_FULL_TXOP	(1 <<  7)
430 #define	WPI_TX_BT_DISABLE	(1 << 12)
431 #define	WPI_TX_AUTO_SEQ		(1 << 13)
432 #define	WPI_TX_INSERT_TSTAMP	(1 << 16)
433 #define	WPI_TX_CALIBRATION	(1 << 17)
434 
435 	uint8_t		rate;
436 	uint8_t		id;
437 	uint8_t		tid;
438 	uint8_t		security;
439 	uint8_t		key[16];
440 	uint8_t		tkip[8];
441 	uint32_t	fnext;
442 	uint32_t	lifetime;
443 	uint8_t		ofdm_mask;
444 	uint8_t		cck_mask;
445 	uint8_t		rts_ntries;
446 	uint8_t		data_ntries;
447 	uint16_t	timeout;
448 	uint16_t	txop;
449 } wpi_cmd_data_t;
450 
451 /*
452  * structure for command WPI_CMD_SET_BEACON
453  */
454 typedef struct wpi_cmd_beacon {
455 	uint16_t	len;
456 	uint16_t	reserved1;
457 	uint32_t	flags;	/* same as wpi_cmd_data */
458 	uint8_t		rate;
459 	uint8_t		id;
460 	uint8_t		reserved2[30];
461 	uint32_t	lifetime;
462 	uint8_t		ofdm_mask;
463 	uint8_t		cck_mask;
464 	uint16_t	reserved3[3];
465 	uint16_t	tim;
466 	uint8_t		timsz;
467 	uint8_t		reserved4;
468 	struct		ieee80211_frame wh;
469 } wpi_cmd_beacon_t;
470 
471 /*
472  * structure for WPI_CMD_MRR_SETUP
473  */
474 typedef struct wpi_mrr_setup {
475 	uint32_t	which;
476 #define	WPI_MRR_CTL	0
477 #define	WPI_MRR_DATA	1
478 
479 	struct {
480 		uint8_t	signal;
481 		uint8_t	flags;
482 		uint8_t	ntries;
483 		uint8_t	next;
484 #define	WPI_OFDM6	0
485 #define	WPI_OFDM54	7
486 #define	WPI_CCK1	8
487 #define	WPI_CCK11	11
488 
489 	} rates[WPI_CCK11 + 1];
490 } wpi_mrr_setup_t;
491 
492 /*
493  * structure for WPI_CMD_SET_LED
494  */
495 typedef struct wpi_cmd_led {
496 	uint32_t	unit;	/* multiplier (in usecs) */
497 	uint8_t		which;
498 #define	WPI_LED_ACTIVITY	1
499 #define	WPI_LED_LINK		2
500 
501 	uint8_t		off;
502 	uint8_t		on;
503 	uint8_t		reserved;
504 } wpi_cmd_led_t;
505 
506 /*
507  * structure for WPI_CMD_SET_POWER_MODE
508  */
509 typedef struct wpi_power {
510 	uint32_t	flags;
511 	uint32_t	rx_timeout;
512 	uint32_t	tx_timeout;
513 	uint32_t	sleep[5];
514 } wpi_power_t;
515 
516 /*
517  * structure for command WPI_CMD_SCAN
518  */
519 typedef struct wpi_scan_hdr {
520 	uint8_t		len;
521 	uint8_t		first;
522 	uint8_t		reserved1;
523 	uint8_t		nchan;
524 	uint16_t	quiet;
525 	uint16_t	threshold;
526 	uint32_t	reserved2[3];
527 	uint32_t	filter;
528 	uint32_t	reserved3;
529 	uint16_t	pbrlen;
530 	uint16_t	reserved4;
531 	uint32_t	magic1;
532 	uint8_t		rate;
533 	uint8_t		id;
534 	uint16_t	reserved5;
535 	uint32_t	reserved6[7];
536 	uint32_t	mask;
537 	uint32_t	reserved7[2];
538 	uint8_t		reserved8;
539 	uint8_t		esslen;
540 	uint8_t		essid[134];
541 
542 	/* followed by probe request body */
543 	/* followed by nchan x wpi_scan_chan */
544 } wpi_scan_hdr_t;
545 
546 typedef struct wpi_scan_chan {
547 	uint8_t		flags;
548 	uint8_t		chan;
549 	uint16_t	magic;		/* XXX */
550 	uint16_t	active;		/* dwell time */
551 	uint16_t	passive;	/* dwell time */
552 } wpi_scan_chan_t;
553 
554 /*
555  * structure for WPI_CMD_BLUETOOTH
556  */
557 typedef struct wpi_bluetooth {
558 	uint8_t		flags;
559 	uint8_t		lead;
560 	uint8_t		kill;
561 	uint8_t		reserved;
562 	uint32_t	ack;
563 	uint32_t	cts;
564 } wpi_bluetooth_t;
565 
566 /*
567  * structure for command WPI_CMD_TXPOWER
568  */
569 typedef struct wpi_txpower {
570 	uint32_t	reserved1;
571 	uint16_t	pwr1[14];
572 	uint32_t	reserved2[2];
573 	uint16_t	pwr2[14];
574 	uint32_t	reserved3[2];
575 } wpi_txpower_t;
576 
577 
578 /*
579  * firmware image header
580  */
581 typedef struct wpi_firmware_hdr {
582 	uint32_t	version;
583 	uint32_t	textsz;
584 	uint32_t	datasz;
585 	uint32_t	bootsz;
586 } wpi_firmware_hdr_t;
587 
588 /*
589  * structure for WPI_UC_READY notification
590  */
591 typedef struct wpi_ucode_info {
592 	uint32_t	version;
593 	uint8_t		revision[8];
594 	uint8_t		type;
595 	uint8_t		subtype;
596 	uint16_t	reserved;
597 	uint32_t	logptr;
598 	uint32_t	errorptr;
599 	uint32_t	timestamp;
600 	uint32_t	valid;
601 } wpi_ucode_info_t;
602 
603 /*
604  * structure for WPI_START_SCAN notification
605  */
606 typedef struct wpi_start_scan {
607 	uint64_t	tstamp;
608 	uint32_t	tbeacon;
609 	uint8_t		chan;
610 	uint8_t		band;
611 	uint16_t	reserved;
612 	uint32_t	status;
613 } wpi_start_scan_t;
614 
615 /*
616  * structure for WPI_STOP_SCAN notification
617  */
618 typedef struct wpi_stop_scan {
619 	uint8_t		nchan;
620 	uint8_t		status;
621 	uint8_t		reserved;
622 	uint8_t		chan;
623 	uint64_t	tsf;
624 } wpi_stop_scan_t;
625 
626 #define	WPI_EEPROM_MAC		0x015
627 #define	WPI_EEPROM_REVISION	0x035
628 #define	WPI_EEPROM_CAPABILITIES	0x045
629 #define	WPI_EEPROM_TYPE		0x04a
630 #define	WPI_EEPROM_PWR1		0x1ae
631 #define	WPI_EEPROM_PWR2		0x1bc
632 
633 #define	WPI_READ(sc, reg)						\
634 	ddi_get32((sc)->sc_handle, (uint32_t *)((sc)->sc_base + (reg)))
635 
636 #define	WPI_WRITE(sc, reg, val)						\
637 	ddi_put32((sc)->sc_handle, (uint32_t *)((sc)->sc_base + (reg)), (val))
638 
639 #define	WPI_WRITE_REGION_4(sc, offset, datap, count) {			\
640 	uint32_t *p = (datap);						\
641 	uint32_t s = (offset);						\
642 	uint32_t c = (count);						\
643 	while (--c > 0) {						\
644 		ddi_put32((sc)->sc_handle,				\
645 		    (uint32_t *)((sc)->sc_base + s), *p);		\
646 		p++;							\
647 		s += 4;							\
648 	}								\
649 }
650 
651 #ifdef __cplusplus
652 }
653 #endif
654 
655 #endif /* _WPIREG_H_ */
656