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