1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source. A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * This file is part of the Chelsio T4 support code.
14  *
15  * Copyright (C) 2011-2013 Chelsio Communications.  All rights reserved.
16  *
17  * This program is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the LICENSE file included in this
20  * release for licensing terms and conditions.
21  */
22 
23 #include <sys/ddi.h>
24 #include <sys/sunddi.h>
25 #include <sys/queue.h>
26 
27 #include "t4nex.h"
28 #include "common/common.h"
29 #include "common/t4_regs.h"
30 
31 /* helpers */
32 static int pci_rw(struct adapter *sc, void *data, int flags, int write);
33 static int reg_rw(struct adapter *sc, void *data, int flags, int write);
34 static void reg_block_dump(struct adapter *sc, uint8_t *buf, unsigned int start,
35     unsigned int end);
36 static int regdump(struct adapter *sc, void *data, int flags);
37 static int get_sge_context(struct adapter *sc, void *data, int flags);
38 static int get_devlog(struct adapter *sc, void *data, int flags);
39 static int validate_mem_range(struct adapter *, uint32_t, int);
40 static int read_card_mem(struct adapter *sc, void *data, int flags);
41 static int read_tid_tab(struct adapter *sc, void *data, int flags);
42 static int read_mbox(struct adapter *sc, void *data, int flags);
43 static int read_cim_la(struct adapter *sc, void *data, int flags);
44 static int read_cim_qcfg(struct adapter *sc, void *data, int flags);
45 static int read_cim_ibq(struct adapter *sc, void *data, int flags);
46 static int read_edc(struct adapter *sc, void *data, int flags);
47 static int flash_fw(struct adapter *, void *, int);
48 
49 int
50 t4_ioctl(struct adapter *sc, int cmd, void *data, int mode)
51 {
52 	int rc = ENOTSUP;
53 
54 	switch (cmd) {
55 	case T4_IOCTL_PCIGET32:
56 	case T4_IOCTL_PCIPUT32:
57 		rc = pci_rw(sc, data, mode, cmd == T4_IOCTL_PCIPUT32);
58 		break;
59 	case T4_IOCTL_GET32:
60 	case T4_IOCTL_PUT32:
61 		rc = reg_rw(sc, data, mode, cmd == T4_IOCTL_PUT32);
62 		break;
63 	case T4_IOCTL_REGDUMP:
64 		rc = regdump(sc, data, mode);
65 		break;
66 	case T4_IOCTL_SGE_CONTEXT:
67 		rc = get_sge_context(sc, data, mode);
68 		break;
69 	case T4_IOCTL_DEVLOG:
70 		rc = get_devlog(sc, data, mode);
71 		break;
72 	case T4_IOCTL_GET_MEM:
73 		rc = read_card_mem(sc, data, mode);
74 		break;
75 	case T4_IOCTL_GET_TID_TAB:
76 		rc = read_tid_tab(sc, data, mode);
77 		break;
78 	case T4_IOCTL_GET_MBOX:
79 		rc = read_mbox(sc, data, mode);
80 		break;
81 	case T4_IOCTL_GET_CIM_LA:
82 		rc = read_cim_la(sc, data, mode);
83 		break;
84 	case T4_IOCTL_GET_CIM_QCFG:
85 		rc = read_cim_qcfg(sc, data, mode);
86 		break;
87 	case T4_IOCTL_GET_CIM_IBQ:
88 		rc = read_cim_ibq(sc, data, mode);
89 		break;
90 	case T4_IOCTL_GET_EDC:
91 		rc = read_edc(sc, data, mode);
92 		break;
93 	case T4_IOCTL_LOAD_FW:
94 		rc = flash_fw(sc, data, mode);
95 		break;
96 	default:
97 		return (EINVAL);
98 	}
99 
100 	return (rc);
101 }
102 
103 static int
104 pci_rw(struct adapter *sc, void *data, int flags, int write)
105 {
106 	struct t4_reg32_cmd r;
107 
108 	if (ddi_copyin(data, &r, sizeof (r), flags) < 0)
109 		return (EFAULT);
110 
111 	/* address must be 32 bit aligned */
112 	r.reg &= ~0x3;
113 
114 	if (write != 0)
115 		t4_os_pci_write_cfg4(sc, r.reg, r.value);
116 	else {
117 		t4_os_pci_read_cfg4(sc, r.reg, &r.value);
118 		if (ddi_copyout(&r, data, sizeof (r), flags) < 0)
119 			return (EFAULT);
120 	}
121 
122 	return (0);
123 }
124 
125 static int
126 reg_rw(struct adapter *sc, void *data, int flags, int write)
127 {
128 	struct t4_reg32_cmd r;
129 
130 	if (ddi_copyin(data, &r, sizeof (r), flags) < 0)
131 		return (EFAULT);
132 
133 	/* Register address must be 32 bit aligned */
134 	r.reg &= ~0x3;
135 
136 	if (write != 0)
137 		t4_write_reg(sc, r.reg, r.value);
138 	else {
139 		r.value = t4_read_reg(sc, r.reg);
140 		if (ddi_copyout(&r, data, sizeof (r), flags) < 0)
141 			return (EFAULT);
142 	}
143 
144 	return (0);
145 }
146 
147 static void
148 reg_block_dump(struct adapter *sc, uint8_t *buf, unsigned int start,
149     unsigned int end)
150 {
151 	/* LINTED: E_BAD_PTR_CAST_ALIGN */
152 	uint32_t *p = (uint32_t *)(buf + start);
153 
154 	for (/* */; start <= end; start += sizeof (uint32_t))
155 		*p++ = t4_read_reg(sc, start);
156 }
157 
158 /*
159  * Return a version number to identify the type of adapter.  The scheme is:
160  * - bits 0..9: chip version
161  * - bits 10..15: chip revision
162  * - bits 16..23: register dump version
163  */
164 static inline
165 unsigned int mk_adap_vers(const struct adapter *sc)
166 {
167 	return CHELSIO_CHIP_VERSION(sc->params.chip) |
168 		(CHELSIO_CHIP_RELEASE(sc->params.chip) << 10) | (1 << 16);
169 }
170 
171 static int
172 regdump(struct adapter *sc, void *data, int flags)
173 {
174 	struct t4_regdump r;
175 	uint8_t *buf;
176 	static const unsigned int *reg_ranges;
177 	int rc = 0, arr_size = 0, buf_size = 0, i;
178 	static const unsigned int t4_reg_ranges[] = {
179 		0x1008, 0x1108,
180 		0x1180, 0x11b4,
181 		0x11fc, 0x123c,
182 		0x1300, 0x173c,
183 		0x1800, 0x18fc,
184 		0x3000, 0x30d8,
185 		0x30e0, 0x5924,
186 		0x5960, 0x59d4,
187 		0x5a00, 0x5af8,
188 		0x6000, 0x6098,
189 		0x6100, 0x6150,
190 		0x6200, 0x6208,
191 		0x6240, 0x6248,
192 		0x6280, 0x6338,
193 		0x6370, 0x638c,
194 		0x6400, 0x643c,
195 		0x6500, 0x6524,
196 		0x6a00, 0x6a38,
197 		0x6a60, 0x6a78,
198 		0x6b00, 0x6b84,
199 		0x6bf0, 0x6c84,
200 		0x6cf0, 0x6d84,
201 		0x6df0, 0x6e84,
202 		0x6ef0, 0x6f84,
203 		0x6ff0, 0x7084,
204 		0x70f0, 0x7184,
205 		0x71f0, 0x7284,
206 		0x72f0, 0x7384,
207 		0x73f0, 0x7450,
208 		0x7500, 0x7530,
209 		0x7600, 0x761c,
210 		0x7680, 0x76cc,
211 		0x7700, 0x7798,
212 		0x77c0, 0x77fc,
213 		0x7900, 0x79fc,
214 		0x7b00, 0x7c38,
215 		0x7d00, 0x7efc,
216 		0x8dc0, 0x8e1c,
217 		0x8e30, 0x8e78,
218 		0x8ea0, 0x8f6c,
219 		0x8fc0, 0x9074,
220 		0x90fc, 0x90fc,
221 		0x9400, 0x9458,
222 		0x9600, 0x96bc,
223 		0x9800, 0x9808,
224 		0x9820, 0x983c,
225 		0x9850, 0x9864,
226 		0x9c00, 0x9c6c,
227 		0x9c80, 0x9cec,
228 		0x9d00, 0x9d6c,
229 		0x9d80, 0x9dec,
230 		0x9e00, 0x9e6c,
231 		0x9e80, 0x9eec,
232 		0x9f00, 0x9f6c,
233 		0x9f80, 0x9fec,
234 		0xd004, 0xd03c,
235 		0xdfc0, 0xdfe0,
236 		0xe000, 0xea7c,
237 		0xf000, 0x11190,
238 		0x19040, 0x19124,
239 		0x19150, 0x191b0,
240 		0x191d0, 0x191e8,
241 		0x19238, 0x1924c,
242 		0x193f8, 0x19474,
243 		0x19490, 0x194f8,
244 		0x19800, 0x19f30,
245 		0x1a000, 0x1a06c,
246 		0x1a0b0, 0x1a120,
247 		0x1a128, 0x1a138,
248 		0x1a190, 0x1a1c4,
249 		0x1a1fc, 0x1a1fc,
250 		0x1e040, 0x1e04c,
251 		0x1e240, 0x1e28c,
252 		0x1e2c0, 0x1e2c0,
253 		0x1e2e0, 0x1e2e0,
254 		0x1e300, 0x1e384,
255 		0x1e3c0, 0x1e3c8,
256 		0x1e440, 0x1e44c,
257 		0x1e640, 0x1e68c,
258 		0x1e6c0, 0x1e6c0,
259 		0x1e6e0, 0x1e6e0,
260 		0x1e700, 0x1e784,
261 		0x1e7c0, 0x1e7c8,
262 		0x1e840, 0x1e84c,
263 		0x1ea40, 0x1ea8c,
264 		0x1eac0, 0x1eac0,
265 		0x1eae0, 0x1eae0,
266 		0x1eb00, 0x1eb84,
267 		0x1ebc0, 0x1ebc8,
268 		0x1ec40, 0x1ec4c,
269 		0x1ee40, 0x1ee8c,
270 		0x1eec0, 0x1eec0,
271 		0x1eee0, 0x1eee0,
272 		0x1ef00, 0x1ef84,
273 		0x1efc0, 0x1efc8,
274 		0x1f040, 0x1f04c,
275 		0x1f240, 0x1f28c,
276 		0x1f2c0, 0x1f2c0,
277 		0x1f2e0, 0x1f2e0,
278 		0x1f300, 0x1f384,
279 		0x1f3c0, 0x1f3c8,
280 		0x1f440, 0x1f44c,
281 		0x1f640, 0x1f68c,
282 		0x1f6c0, 0x1f6c0,
283 		0x1f6e0, 0x1f6e0,
284 		0x1f700, 0x1f784,
285 		0x1f7c0, 0x1f7c8,
286 		0x1f840, 0x1f84c,
287 		0x1fa40, 0x1fa8c,
288 		0x1fac0, 0x1fac0,
289 		0x1fae0, 0x1fae0,
290 		0x1fb00, 0x1fb84,
291 		0x1fbc0, 0x1fbc8,
292 		0x1fc40, 0x1fc4c,
293 		0x1fe40, 0x1fe8c,
294 		0x1fec0, 0x1fec0,
295 		0x1fee0, 0x1fee0,
296 		0x1ff00, 0x1ff84,
297 		0x1ffc0, 0x1ffc8,
298 		0x20000, 0x2002c,
299 		0x20100, 0x2013c,
300 		0x20190, 0x201c8,
301 		0x20200, 0x20318,
302 		0x20400, 0x20528,
303 		0x20540, 0x20614,
304 		0x21000, 0x21040,
305 		0x2104c, 0x21060,
306 		0x210c0, 0x210ec,
307 		0x21200, 0x21268,
308 		0x21270, 0x21284,
309 		0x212fc, 0x21388,
310 		0x21400, 0x21404,
311 		0x21500, 0x21518,
312 		0x2152c, 0x2153c,
313 		0x21550, 0x21554,
314 		0x21600, 0x21600,
315 		0x21608, 0x21628,
316 		0x21630, 0x2163c,
317 		0x21700, 0x2171c,
318 		0x21780, 0x2178c,
319 		0x21800, 0x21c38,
320 		0x21c80, 0x21d7c,
321 		0x21e00, 0x21e04,
322 		0x22000, 0x2202c,
323 		0x22100, 0x2213c,
324 		0x22190, 0x221c8,
325 		0x22200, 0x22318,
326 		0x22400, 0x22528,
327 		0x22540, 0x22614,
328 		0x23000, 0x23040,
329 		0x2304c, 0x23060,
330 		0x230c0, 0x230ec,
331 		0x23200, 0x23268,
332 		0x23270, 0x23284,
333 		0x232fc, 0x23388,
334 		0x23400, 0x23404,
335 		0x23500, 0x23518,
336 		0x2352c, 0x2353c,
337 		0x23550, 0x23554,
338 		0x23600, 0x23600,
339 		0x23608, 0x23628,
340 		0x23630, 0x2363c,
341 		0x23700, 0x2371c,
342 		0x23780, 0x2378c,
343 		0x23800, 0x23c38,
344 		0x23c80, 0x23d7c,
345 		0x23e00, 0x23e04,
346 		0x24000, 0x2402c,
347 		0x24100, 0x2413c,
348 		0x24190, 0x241c8,
349 		0x24200, 0x24318,
350 		0x24400, 0x24528,
351 		0x24540, 0x24614,
352 		0x25000, 0x25040,
353 		0x2504c, 0x25060,
354 		0x250c0, 0x250ec,
355 		0x25200, 0x25268,
356 		0x25270, 0x25284,
357 		0x252fc, 0x25388,
358 		0x25400, 0x25404,
359 		0x25500, 0x25518,
360 		0x2552c, 0x2553c,
361 		0x25550, 0x25554,
362 		0x25600, 0x25600,
363 		0x25608, 0x25628,
364 		0x25630, 0x2563c,
365 		0x25700, 0x2571c,
366 		0x25780, 0x2578c,
367 		0x25800, 0x25c38,
368 		0x25c80, 0x25d7c,
369 		0x25e00, 0x25e04,
370 		0x26000, 0x2602c,
371 		0x26100, 0x2613c,
372 		0x26190, 0x261c8,
373 		0x26200, 0x26318,
374 		0x26400, 0x26528,
375 		0x26540, 0x26614,
376 		0x27000, 0x27040,
377 		0x2704c, 0x27060,
378 		0x270c0, 0x270ec,
379 		0x27200, 0x27268,
380 		0x27270, 0x27284,
381 		0x272fc, 0x27388,
382 		0x27400, 0x27404,
383 		0x27500, 0x27518,
384 		0x2752c, 0x2753c,
385 		0x27550, 0x27554,
386 		0x27600, 0x27600,
387 		0x27608, 0x27628,
388 		0x27630, 0x2763c,
389 		0x27700, 0x2771c,
390 		0x27780, 0x2778c,
391 		0x27800, 0x27c38,
392 		0x27c80, 0x27d7c,
393 		0x27e00, 0x27e04
394 	};
395 
396 	static const unsigned int t5_reg_ranges[] = {
397 		0x1008, 0x10c0,
398 		0x10cc, 0x10f8,
399 		0x1100, 0x1100,
400 		0x110c, 0x1148,
401 		0x1180, 0x1184,
402 		0x1190, 0x1194,
403 		0x11a0, 0x11a4,
404 		0x11b0, 0x11b4,
405 		0x11fc, 0x123c,
406 		0x1280, 0x173c,
407 		0x1800, 0x18fc,
408 		0x3000, 0x3028,
409 		0x3060, 0x30b0,
410 		0x30b8, 0x30d8,
411 		0x30e0, 0x30fc,
412 		0x3140, 0x357c,
413 		0x35a8, 0x35cc,
414 		0x35ec, 0x35ec,
415 		0x3600, 0x5624,
416 		0x56cc, 0x56ec,
417 		0x56f4, 0x5720,
418 		0x5728, 0x575c,
419 		0x580c, 0x5814,
420 		0x5890, 0x589c,
421 		0x58a4, 0x58ac,
422 		0x58b8, 0x58bc,
423 		0x5940, 0x59c8,
424 		0x59d0, 0x59dc,
425 		0x59fc, 0x5a18,
426 		0x5a60, 0x5a70,
427 		0x5a80, 0x5a9c,
428 		0x5b94, 0x5bfc,
429 		0x6000, 0x6020,
430 		0x6028, 0x6040,
431 		0x6058, 0x609c,
432 		0x60a8, 0x614c,
433 		0x7700, 0x7798,
434 		0x77c0, 0x78fc,
435 		0x7b00, 0x7b58,
436 		0x7b60, 0x7b84,
437 		0x7b8c, 0x7c54,
438 		0x7d00, 0x7d38,
439 		0x7d40, 0x7d80,
440 		0x7d8c, 0x7ddc,
441 		0x7de4, 0x7e04,
442 		0x7e10, 0x7e1c,
443 		0x7e24, 0x7e38,
444 		0x7e40, 0x7e44,
445 		0x7e4c, 0x7e78,
446 		0x7e80, 0x7edc,
447 		0x7ee8, 0x7efc,
448 		0x8dc0, 0x8de0,
449 		0x8df8, 0x8e04,
450 		0x8e10, 0x8e84,
451 		0x8ea0, 0x8f84,
452 		0x8fc0, 0x9058,
453 		0x9060, 0x9060,
454 		0x9068, 0x90f8,
455 		0x9400, 0x9408,
456 		0x9410, 0x9470,
457 		0x9600, 0x9600,
458 		0x9608, 0x9638,
459 		0x9640, 0x96f4,
460 		0x9800, 0x9808,
461 		0x9820, 0x983c,
462 		0x9850, 0x9864,
463 		0x9c00, 0x9c6c,
464 		0x9c80, 0x9cec,
465 		0x9d00, 0x9d6c,
466 		0x9d80, 0x9dec,
467 		0x9e00, 0x9e6c,
468 		0x9e80, 0x9eec,
469 		0x9f00, 0x9f6c,
470 		0x9f80, 0xa020,
471 		0xd004, 0xd004,
472 		0xd010, 0xd03c,
473 		0xdfc0, 0xdfe0,
474 		0xe000, 0x1106c,
475 		0x11074, 0x11088,
476 		0x1109c, 0x1117c,
477 		0x11190, 0x11204,
478 		0x19040, 0x1906c,
479 		0x19078, 0x19080,
480 		0x1908c, 0x190e8,
481 		0x190f0, 0x190f8,
482 		0x19100, 0x19110,
483 		0x19120, 0x19124,
484 		0x19150, 0x19194,
485 		0x1919c, 0x191b0,
486 		0x191d0, 0x191e8,
487 		0x19238, 0x19290,
488 		0x193f8, 0x19428,
489 		0x19430, 0x19444,
490 		0x1944c, 0x1946c,
491 		0x19474, 0x19474,
492 		0x19490, 0x194cc,
493 		0x194f0, 0x194f8,
494 		0x19c00, 0x19c08,
495 		0x19c10, 0x19c60,
496 		0x19c94, 0x19ce4,
497 		0x19cf0, 0x19d40,
498 		0x19d50, 0x19d94,
499 		0x19da0, 0x19de8,
500 		0x19df0, 0x19e10,
501 		0x19e50, 0x19e90,
502 		0x19ea0, 0x19f24,
503 		0x19f34, 0x19f34,
504 		0x19f40, 0x19f50,
505 		0x19f90, 0x19fb4,
506 		0x19fc4, 0x19fe4,
507 		0x1a000, 0x1a004,
508 		0x1a010, 0x1a06c,
509 		0x1a0b0, 0x1a0e4,
510 		0x1a0ec, 0x1a0f8,
511 		0x1a100, 0x1a108,
512 		0x1a114, 0x1a120,
513 		0x1a128, 0x1a130,
514 		0x1a138, 0x1a138,
515 		0x1a190, 0x1a1c4,
516 		0x1a1fc, 0x1a1fc,
517 		0x1e008, 0x1e00c,
518 		0x1e040, 0x1e044,
519 		0x1e04c, 0x1e04c,
520 		0x1e284, 0x1e290,
521 		0x1e2c0, 0x1e2c0,
522 		0x1e2e0, 0x1e2e0,
523 		0x1e300, 0x1e384,
524 		0x1e3c0, 0x1e3c8,
525 		0x1e408, 0x1e40c,
526 		0x1e440, 0x1e444,
527 		0x1e44c, 0x1e44c,
528 		0x1e684, 0x1e690,
529 		0x1e6c0, 0x1e6c0,
530 		0x1e6e0, 0x1e6e0,
531 		0x1e700, 0x1e784,
532 		0x1e7c0, 0x1e7c8,
533 		0x1e808, 0x1e80c,
534 		0x1e840, 0x1e844,
535 		0x1e84c, 0x1e84c,
536 		0x1ea84, 0x1ea90,
537 		0x1eac0, 0x1eac0,
538 		0x1eae0, 0x1eae0,
539 		0x1eb00, 0x1eb84,
540 		0x1ebc0, 0x1ebc8,
541 		0x1ec08, 0x1ec0c,
542 		0x1ec40, 0x1ec44,
543 		0x1ec4c, 0x1ec4c,
544 		0x1ee84, 0x1ee90,
545 		0x1eec0, 0x1eec0,
546 		0x1eee0, 0x1eee0,
547 		0x1ef00, 0x1ef84,
548 		0x1efc0, 0x1efc8,
549 		0x1f008, 0x1f00c,
550 		0x1f040, 0x1f044,
551 		0x1f04c, 0x1f04c,
552 		0x1f284, 0x1f290,
553 		0x1f2c0, 0x1f2c0,
554 		0x1f2e0, 0x1f2e0,
555 		0x1f300, 0x1f384,
556 		0x1f3c0, 0x1f3c8,
557 		0x1f408, 0x1f40c,
558 		0x1f440, 0x1f444,
559 		0x1f44c, 0x1f44c,
560 		0x1f684, 0x1f690,
561 		0x1f6c0, 0x1f6c0,
562 		0x1f6e0, 0x1f6e0,
563 		0x1f700, 0x1f784,
564 		0x1f7c0, 0x1f7c8,
565 		0x1f808, 0x1f80c,
566 		0x1f840, 0x1f844,
567 		0x1f84c, 0x1f84c,
568 		0x1fa84, 0x1fa90,
569 		0x1fac0, 0x1fac0,
570 		0x1fae0, 0x1fae0,
571 		0x1fb00, 0x1fb84,
572 		0x1fbc0, 0x1fbc8,
573 		0x1fc08, 0x1fc0c,
574 		0x1fc40, 0x1fc44,
575 		0x1fc4c, 0x1fc4c,
576 		0x1fe84, 0x1fe90,
577 		0x1fec0, 0x1fec0,
578 		0x1fee0, 0x1fee0,
579 		0x1ff00, 0x1ff84,
580 		0x1ffc0, 0x1ffc8,
581 		0x30000, 0x30030,
582 		0x30038, 0x30038,
583 		0x30040, 0x30040,
584 		0x30100, 0x30144,
585 		0x30190, 0x301a0,
586 		0x301a8, 0x301b8,
587 		0x301c4, 0x301c8,
588 		0x301d0, 0x301d0,
589 		0x30200, 0x30318,
590 		0x30400, 0x304b4,
591 		0x304c0, 0x3052c,
592 		0x30540, 0x3061c,
593 		0x30800, 0x30828,
594 		0x30834, 0x30834,
595 		0x308c0, 0x30908,
596 		0x30910, 0x309ac,
597 		0x30a00, 0x30a14,
598 		0x30a1c, 0x30a2c,
599 		0x30a44, 0x30a50,
600 		0x30a74, 0x30a74,
601 		0x30a7c, 0x30afc,
602 		0x30b08, 0x30c24,
603 		0x30d00, 0x30d00,
604 		0x30d08, 0x30d14,
605 		0x30d1c, 0x30d20,
606 		0x30d3c, 0x30d3c,
607 		0x30d48, 0x30d50,
608 		0x31200, 0x3120c,
609 		0x31220, 0x31220,
610 		0x31240, 0x31240,
611 		0x31600, 0x3160c,
612 		0x31a00, 0x31a1c,
613 		0x31e00, 0x31e20,
614 		0x31e38, 0x31e3c,
615 		0x31e80, 0x31e80,
616 		0x31e88, 0x31ea8,
617 		0x31eb0, 0x31eb4,
618 		0x31ec8, 0x31ed4,
619 		0x31fb8, 0x32004,
620 		0x32200, 0x32200,
621 		0x32208, 0x32240,
622 		0x32248, 0x32280,
623 		0x32288, 0x322c0,
624 		0x322c8, 0x322fc,
625 		0x32600, 0x32630,
626 		0x32a00, 0x32abc,
627 		0x32b00, 0x32b10,
628 		0x32b20, 0x32b30,
629 		0x32b40, 0x32b50,
630 		0x32b60, 0x32b70,
631 		0x33000, 0x33028,
632 		0x33030, 0x33048,
633 		0x33060, 0x33068,
634 		0x33070, 0x3309c,
635 		0x330f0, 0x33128,
636 		0x33130, 0x33148,
637 		0x33160, 0x33168,
638 		0x33170, 0x3319c,
639 		0x331f0, 0x33238,
640 		0x33240, 0x33240,
641 		0x33248, 0x33250,
642 		0x3325c, 0x33264,
643 		0x33270, 0x332b8,
644 		0x332c0, 0x332e4,
645 		0x332f8, 0x33338,
646 		0x33340, 0x33340,
647 		0x33348, 0x33350,
648 		0x3335c, 0x33364,
649 		0x33370, 0x333b8,
650 		0x333c0, 0x333e4,
651 		0x333f8, 0x33428,
652 		0x33430, 0x33448,
653 		0x33460, 0x33468,
654 		0x33470, 0x3349c,
655 		0x334f0, 0x33528,
656 		0x33530, 0x33548,
657 		0x33560, 0x33568,
658 		0x33570, 0x3359c,
659 		0x335f0, 0x33638,
660 		0x33640, 0x33640,
661 		0x33648, 0x33650,
662 		0x3365c, 0x33664,
663 		0x33670, 0x336b8,
664 		0x336c0, 0x336e4,
665 		0x336f8, 0x33738,
666 		0x33740, 0x33740,
667 		0x33748, 0x33750,
668 		0x3375c, 0x33764,
669 		0x33770, 0x337b8,
670 		0x337c0, 0x337e4,
671 		0x337f8, 0x337fc,
672 		0x33814, 0x33814,
673 		0x3382c, 0x3382c,
674 		0x33880, 0x3388c,
675 		0x338e8, 0x338ec,
676 		0x33900, 0x33928,
677 		0x33930, 0x33948,
678 		0x33960, 0x33968,
679 		0x33970, 0x3399c,
680 		0x339f0, 0x33a38,
681 		0x33a40, 0x33a40,
682 		0x33a48, 0x33a50,
683 		0x33a5c, 0x33a64,
684 		0x33a70, 0x33ab8,
685 		0x33ac0, 0x33ae4,
686 		0x33af8, 0x33b10,
687 		0x33b28, 0x33b28,
688 		0x33b3c, 0x33b50,
689 		0x33bf0, 0x33c10,
690 		0x33c28, 0x33c28,
691 		0x33c3c, 0x33c50,
692 		0x33cf0, 0x33cfc,
693 		0x34000, 0x34030,
694 		0x34038, 0x34038,
695 		0x34040, 0x34040,
696 		0x34100, 0x34144,
697 		0x34190, 0x341a0,
698 		0x341a8, 0x341b8,
699 		0x341c4, 0x341c8,
700 		0x341d0, 0x341d0,
701 		0x34200, 0x34318,
702 		0x34400, 0x344b4,
703 		0x344c0, 0x3452c,
704 		0x34540, 0x3461c,
705 		0x34800, 0x34828,
706 		0x34834, 0x34834,
707 		0x348c0, 0x34908,
708 		0x34910, 0x349ac,
709 		0x34a00, 0x34a14,
710 		0x34a1c, 0x34a2c,
711 		0x34a44, 0x34a50,
712 		0x34a74, 0x34a74,
713 		0x34a7c, 0x34afc,
714 		0x34b08, 0x34c24,
715 		0x34d00, 0x34d00,
716 		0x34d08, 0x34d14,
717 		0x34d1c, 0x34d20,
718 		0x34d3c, 0x34d3c,
719 		0x34d48, 0x34d50,
720 		0x35200, 0x3520c,
721 		0x35220, 0x35220,
722 		0x35240, 0x35240,
723 		0x35600, 0x3560c,
724 		0x35a00, 0x35a1c,
725 		0x35e00, 0x35e20,
726 		0x35e38, 0x35e3c,
727 		0x35e80, 0x35e80,
728 		0x35e88, 0x35ea8,
729 		0x35eb0, 0x35eb4,
730 		0x35ec8, 0x35ed4,
731 		0x35fb8, 0x36004,
732 		0x36200, 0x36200,
733 		0x36208, 0x36240,
734 		0x36248, 0x36280,
735 		0x36288, 0x362c0,
736 		0x362c8, 0x362fc,
737 		0x36600, 0x36630,
738 		0x36a00, 0x36abc,
739 		0x36b00, 0x36b10,
740 		0x36b20, 0x36b30,
741 		0x36b40, 0x36b50,
742 		0x36b60, 0x36b70,
743 		0x37000, 0x37028,
744 		0x37030, 0x37048,
745 		0x37060, 0x37068,
746 		0x37070, 0x3709c,
747 		0x370f0, 0x37128,
748 		0x37130, 0x37148,
749 		0x37160, 0x37168,
750 		0x37170, 0x3719c,
751 		0x371f0, 0x37238,
752 		0x37240, 0x37240,
753 		0x37248, 0x37250,
754 		0x3725c, 0x37264,
755 		0x37270, 0x372b8,
756 		0x372c0, 0x372e4,
757 		0x372f8, 0x37338,
758 		0x37340, 0x37340,
759 		0x37348, 0x37350,
760 		0x3735c, 0x37364,
761 		0x37370, 0x373b8,
762 		0x373c0, 0x373e4,
763 		0x373f8, 0x37428,
764 		0x37430, 0x37448,
765 		0x37460, 0x37468,
766 		0x37470, 0x3749c,
767 		0x374f0, 0x37528,
768 		0x37530, 0x37548,
769 		0x37560, 0x37568,
770 		0x37570, 0x3759c,
771 		0x375f0, 0x37638,
772 		0x37640, 0x37640,
773 		0x37648, 0x37650,
774 		0x3765c, 0x37664,
775 		0x37670, 0x376b8,
776 		0x376c0, 0x376e4,
777 		0x376f8, 0x37738,
778 		0x37740, 0x37740,
779 		0x37748, 0x37750,
780 		0x3775c, 0x37764,
781 		0x37770, 0x377b8,
782 		0x377c0, 0x377e4,
783 		0x377f8, 0x377fc,
784 		0x37814, 0x37814,
785 		0x3782c, 0x3782c,
786 		0x37880, 0x3788c,
787 		0x378e8, 0x378ec,
788 		0x37900, 0x37928,
789 		0x37930, 0x37948,
790 		0x37960, 0x37968,
791 		0x37970, 0x3799c,
792 		0x379f0, 0x37a38,
793 		0x37a40, 0x37a40,
794 		0x37a48, 0x37a50,
795 		0x37a5c, 0x37a64,
796 		0x37a70, 0x37ab8,
797 		0x37ac0, 0x37ae4,
798 		0x37af8, 0x37b10,
799 		0x37b28, 0x37b28,
800 		0x37b3c, 0x37b50,
801 		0x37bf0, 0x37c10,
802 		0x37c28, 0x37c28,
803 		0x37c3c, 0x37c50,
804 		0x37cf0, 0x37cfc,
805 		0x38000, 0x38030,
806 		0x38038, 0x38038,
807 		0x38040, 0x38040,
808 		0x38100, 0x38144,
809 		0x38190, 0x381a0,
810 		0x381a8, 0x381b8,
811 		0x381c4, 0x381c8,
812 		0x381d0, 0x381d0,
813 		0x38200, 0x38318,
814 		0x38400, 0x384b4,
815 		0x384c0, 0x3852c,
816 		0x38540, 0x3861c,
817 		0x38800, 0x38828,
818 		0x38834, 0x38834,
819 		0x388c0, 0x38908,
820 		0x38910, 0x389ac,
821 		0x38a00, 0x38a14,
822 		0x38a1c, 0x38a2c,
823 		0x38a44, 0x38a50,
824 		0x38a74, 0x38a74,
825 		0x38a7c, 0x38afc,
826 		0x38b08, 0x38c24,
827 		0x38d00, 0x38d00,
828 		0x38d08, 0x38d14,
829 		0x38d1c, 0x38d20,
830 		0x38d3c, 0x38d3c,
831 		0x38d48, 0x38d50,
832 		0x39200, 0x3920c,
833 		0x39220, 0x39220,
834 		0x39240, 0x39240,
835 		0x39600, 0x3960c,
836 		0x39a00, 0x39a1c,
837 		0x39e00, 0x39e20,
838 		0x39e38, 0x39e3c,
839 		0x39e80, 0x39e80,
840 		0x39e88, 0x39ea8,
841 		0x39eb0, 0x39eb4,
842 		0x39ec8, 0x39ed4,
843 		0x39fb8, 0x3a004,
844 		0x3a200, 0x3a200,
845 		0x3a208, 0x3a240,
846 		0x3a248, 0x3a280,
847 		0x3a288, 0x3a2c0,
848 		0x3a2c8, 0x3a2fc,
849 		0x3a600, 0x3a630,
850 		0x3aa00, 0x3aabc,
851 		0x3ab00, 0x3ab10,
852 		0x3ab20, 0x3ab30,
853 		0x3ab40, 0x3ab50,
854 		0x3ab60, 0x3ab70,
855 		0x3b000, 0x3b028,
856 		0x3b030, 0x3b048,
857 		0x3b060, 0x3b068,
858 		0x3b070, 0x3b09c,
859 		0x3b0f0, 0x3b128,
860 		0x3b130, 0x3b148,
861 		0x3b160, 0x3b168,
862 		0x3b170, 0x3b19c,
863 		0x3b1f0, 0x3b238,
864 		0x3b240, 0x3b240,
865 		0x3b248, 0x3b250,
866 		0x3b25c, 0x3b264,
867 		0x3b270, 0x3b2b8,
868 		0x3b2c0, 0x3b2e4,
869 		0x3b2f8, 0x3b338,
870 		0x3b340, 0x3b340,
871 		0x3b348, 0x3b350,
872 		0x3b35c, 0x3b364,
873 		0x3b370, 0x3b3b8,
874 		0x3b3c0, 0x3b3e4,
875 		0x3b3f8, 0x3b428,
876 		0x3b430, 0x3b448,
877 		0x3b460, 0x3b468,
878 		0x3b470, 0x3b49c,
879 		0x3b4f0, 0x3b528,
880 		0x3b530, 0x3b548,
881 		0x3b560, 0x3b568,
882 		0x3b570, 0x3b59c,
883 		0x3b5f0, 0x3b638,
884 		0x3b640, 0x3b640,
885 		0x3b648, 0x3b650,
886 		0x3b65c, 0x3b664,
887 		0x3b670, 0x3b6b8,
888 		0x3b6c0, 0x3b6e4,
889 		0x3b6f8, 0x3b738,
890 		0x3b740, 0x3b740,
891 		0x3b748, 0x3b750,
892 		0x3b75c, 0x3b764,
893 		0x3b770, 0x3b7b8,
894 		0x3b7c0, 0x3b7e4,
895 		0x3b7f8, 0x3b7fc,
896 		0x3b814, 0x3b814,
897 		0x3b82c, 0x3b82c,
898 		0x3b880, 0x3b88c,
899 		0x3b8e8, 0x3b8ec,
900 		0x3b900, 0x3b928,
901 		0x3b930, 0x3b948,
902 		0x3b960, 0x3b968,
903 		0x3b970, 0x3b99c,
904 		0x3b9f0, 0x3ba38,
905 		0x3ba40, 0x3ba40,
906 		0x3ba48, 0x3ba50,
907 		0x3ba5c, 0x3ba64,
908 		0x3ba70, 0x3bab8,
909 		0x3bac0, 0x3bae4,
910 		0x3baf8, 0x3bb10,
911 		0x3bb28, 0x3bb28,
912 		0x3bb3c, 0x3bb50,
913 		0x3bbf0, 0x3bc10,
914 		0x3bc28, 0x3bc28,
915 		0x3bc3c, 0x3bc50,
916 		0x3bcf0, 0x3bcfc,
917 		0x3c000, 0x3c030,
918 		0x3c038, 0x3c038,
919 		0x3c040, 0x3c040,
920 		0x3c100, 0x3c144,
921 		0x3c190, 0x3c1a0,
922 		0x3c1a8, 0x3c1b8,
923 		0x3c1c4, 0x3c1c8,
924 		0x3c1d0, 0x3c1d0,
925 		0x3c200, 0x3c318,
926 		0x3c400, 0x3c4b4,
927 		0x3c4c0, 0x3c52c,
928 		0x3c540, 0x3c61c,
929 		0x3c800, 0x3c828,
930 		0x3c834, 0x3c834,
931 		0x3c8c0, 0x3c908,
932 		0x3c910, 0x3c9ac,
933 		0x3ca00, 0x3ca14,
934 		0x3ca1c, 0x3ca2c,
935 		0x3ca44, 0x3ca50,
936 		0x3ca74, 0x3ca74,
937 		0x3ca7c, 0x3cafc,
938 		0x3cb08, 0x3cc24,
939 		0x3cd00, 0x3cd00,
940 		0x3cd08, 0x3cd14,
941 		0x3cd1c, 0x3cd20,
942 		0x3cd3c, 0x3cd3c,
943 		0x3cd48, 0x3cd50,
944 		0x3d200, 0x3d20c,
945 		0x3d220, 0x3d220,
946 		0x3d240, 0x3d240,
947 		0x3d600, 0x3d60c,
948 		0x3da00, 0x3da1c,
949 		0x3de00, 0x3de20,
950 		0x3de38, 0x3de3c,
951 		0x3de80, 0x3de80,
952 		0x3de88, 0x3dea8,
953 		0x3deb0, 0x3deb4,
954 		0x3dec8, 0x3ded4,
955 		0x3dfb8, 0x3e004,
956 		0x3e200, 0x3e200,
957 		0x3e208, 0x3e240,
958 		0x3e248, 0x3e280,
959 		0x3e288, 0x3e2c0,
960 		0x3e2c8, 0x3e2fc,
961 		0x3e600, 0x3e630,
962 		0x3ea00, 0x3eabc,
963 		0x3eb00, 0x3eb10,
964 		0x3eb20, 0x3eb30,
965 		0x3eb40, 0x3eb50,
966 		0x3eb60, 0x3eb70,
967 		0x3f000, 0x3f028,
968 		0x3f030, 0x3f048,
969 		0x3f060, 0x3f068,
970 		0x3f070, 0x3f09c,
971 		0x3f0f0, 0x3f128,
972 		0x3f130, 0x3f148,
973 		0x3f160, 0x3f168,
974 		0x3f170, 0x3f19c,
975 		0x3f1f0, 0x3f238,
976 		0x3f240, 0x3f240,
977 		0x3f248, 0x3f250,
978 		0x3f25c, 0x3f264,
979 		0x3f270, 0x3f2b8,
980 		0x3f2c0, 0x3f2e4,
981 		0x3f2f8, 0x3f338,
982 		0x3f340, 0x3f340,
983 		0x3f348, 0x3f350,
984 		0x3f35c, 0x3f364,
985 		0x3f370, 0x3f3b8,
986 		0x3f3c0, 0x3f3e4,
987 		0x3f3f8, 0x3f428,
988 		0x3f430, 0x3f448,
989 		0x3f460, 0x3f468,
990 		0x3f470, 0x3f49c,
991 		0x3f4f0, 0x3f528,
992 		0x3f530, 0x3f548,
993 		0x3f560, 0x3f568,
994 		0x3f570, 0x3f59c,
995 		0x3f5f0, 0x3f638,
996 		0x3f640, 0x3f640,
997 		0x3f648, 0x3f650,
998 		0x3f65c, 0x3f664,
999 		0x3f670, 0x3f6b8,
1000 		0x3f6c0, 0x3f6e4,
1001 		0x3f6f8, 0x3f738,
1002 		0x3f740, 0x3f740,
1003 		0x3f748, 0x3f750,
1004 		0x3f75c, 0x3f764,
1005 		0x3f770, 0x3f7b8,
1006 		0x3f7c0, 0x3f7e4,
1007 		0x3f7f8, 0x3f7fc,
1008 		0x3f814, 0x3f814,
1009 		0x3f82c, 0x3f82c,
1010 		0x3f880, 0x3f88c,
1011 		0x3f8e8, 0x3f8ec,
1012 		0x3f900, 0x3f928,
1013 		0x3f930, 0x3f948,
1014 		0x3f960, 0x3f968,
1015 		0x3f970, 0x3f99c,
1016 		0x3f9f0, 0x3fa38,
1017 		0x3fa40, 0x3fa40,
1018 		0x3fa48, 0x3fa50,
1019 		0x3fa5c, 0x3fa64,
1020 		0x3fa70, 0x3fab8,
1021 		0x3fac0, 0x3fae4,
1022 		0x3faf8, 0x3fb10,
1023 		0x3fb28, 0x3fb28,
1024 		0x3fb3c, 0x3fb50,
1025 		0x3fbf0, 0x3fc10,
1026 		0x3fc28, 0x3fc28,
1027 		0x3fc3c, 0x3fc50,
1028 		0x3fcf0, 0x3fcfc,
1029 		0x40000, 0x4000c,
1030 		0x40040, 0x40050,
1031 		0x40060, 0x40068,
1032 		0x4007c, 0x4008c,
1033 		0x40094, 0x400b0,
1034 		0x400c0, 0x40144,
1035 		0x40180, 0x4018c,
1036 		0x40200, 0x40254,
1037 		0x40260, 0x40264,
1038 		0x40270, 0x40288,
1039 		0x40290, 0x40298,
1040 		0x402ac, 0x402c8,
1041 		0x402d0, 0x402e0,
1042 		0x402f0, 0x402f0,
1043 		0x40300, 0x4033c,
1044 		0x403f8, 0x403fc,
1045 		0x41304, 0x413c4,
1046 		0x41400, 0x4140c,
1047 		0x41414, 0x4141c,
1048 		0x41480, 0x414d0,
1049 		0x44000, 0x44054,
1050 		0x4405c, 0x44078,
1051 		0x440c0, 0x44174,
1052 		0x44180, 0x441ac,
1053 		0x441b4, 0x441b8,
1054 		0x441c0, 0x44254,
1055 		0x4425c, 0x44278,
1056 		0x442c0, 0x44374,
1057 		0x44380, 0x443ac,
1058 		0x443b4, 0x443b8,
1059 		0x443c0, 0x44454,
1060 		0x4445c, 0x44478,
1061 		0x444c0, 0x44574,
1062 		0x44580, 0x445ac,
1063 		0x445b4, 0x445b8,
1064 		0x445c0, 0x44654,
1065 		0x4465c, 0x44678,
1066 		0x446c0, 0x44774,
1067 		0x44780, 0x447ac,
1068 		0x447b4, 0x447b8,
1069 		0x447c0, 0x44854,
1070 		0x4485c, 0x44878,
1071 		0x448c0, 0x44974,
1072 		0x44980, 0x449ac,
1073 		0x449b4, 0x449b8,
1074 		0x449c0, 0x449fc,
1075 		0x45000, 0x45004,
1076 		0x45010, 0x45030,
1077 		0x45040, 0x45060,
1078 		0x45068, 0x45068,
1079 		0x45080, 0x45084,
1080 		0x450a0, 0x450b0,
1081 		0x45200, 0x45204,
1082 		0x45210, 0x45230,
1083 		0x45240, 0x45260,
1084 		0x45268, 0x45268,
1085 		0x45280, 0x45284,
1086 		0x452a0, 0x452b0,
1087 		0x460c0, 0x460e4,
1088 		0x47000, 0x4703c,
1089 		0x47044, 0x4708c,
1090 		0x47200, 0x47250,
1091 		0x47400, 0x47408,
1092 		0x47414, 0x47420,
1093 		0x47600, 0x47618,
1094 		0x47800, 0x47814,
1095 		0x48000, 0x4800c,
1096 		0x48040, 0x48050,
1097 		0x48060, 0x48068,
1098 		0x4807c, 0x4808c,
1099 		0x48094, 0x480b0,
1100 		0x480c0, 0x48144,
1101 		0x48180, 0x4818c,
1102 		0x48200, 0x48254,
1103 		0x48260, 0x48264,
1104 		0x48270, 0x48288,
1105 		0x48290, 0x48298,
1106 		0x482ac, 0x482c8,
1107 		0x482d0, 0x482e0,
1108 		0x482f0, 0x482f0,
1109 		0x48300, 0x4833c,
1110 		0x483f8, 0x483fc,
1111 		0x49304, 0x493c4,
1112 		0x49400, 0x4940c,
1113 		0x49414, 0x4941c,
1114 		0x49480, 0x494d0,
1115 		0x4c000, 0x4c054,
1116 		0x4c05c, 0x4c078,
1117 		0x4c0c0, 0x4c174,
1118 		0x4c180, 0x4c1ac,
1119 		0x4c1b4, 0x4c1b8,
1120 		0x4c1c0, 0x4c254,
1121 		0x4c25c, 0x4c278,
1122 		0x4c2c0, 0x4c374,
1123 		0x4c380, 0x4c3ac,
1124 		0x4c3b4, 0x4c3b8,
1125 		0x4c3c0, 0x4c454,
1126 		0x4c45c, 0x4c478,
1127 		0x4c4c0, 0x4c574,
1128 		0x4c580, 0x4c5ac,
1129 		0x4c5b4, 0x4c5b8,
1130 		0x4c5c0, 0x4c654,
1131 		0x4c65c, 0x4c678,
1132 		0x4c6c0, 0x4c774,
1133 		0x4c780, 0x4c7ac,
1134 		0x4c7b4, 0x4c7b8,
1135 		0x4c7c0, 0x4c854,
1136 		0x4c85c, 0x4c878,
1137 		0x4c8c0, 0x4c974,
1138 		0x4c980, 0x4c9ac,
1139 		0x4c9b4, 0x4c9b8,
1140 		0x4c9c0, 0x4c9fc,
1141 		0x4d000, 0x4d004,
1142 		0x4d010, 0x4d030,
1143 		0x4d040, 0x4d060,
1144 		0x4d068, 0x4d068,
1145 		0x4d080, 0x4d084,
1146 		0x4d0a0, 0x4d0b0,
1147 		0x4d200, 0x4d204,
1148 		0x4d210, 0x4d230,
1149 		0x4d240, 0x4d260,
1150 		0x4d268, 0x4d268,
1151 		0x4d280, 0x4d284,
1152 		0x4d2a0, 0x4d2b0,
1153 		0x4e0c0, 0x4e0e4,
1154 		0x4f000, 0x4f03c,
1155 		0x4f044, 0x4f08c,
1156 		0x4f200, 0x4f250,
1157 		0x4f400, 0x4f408,
1158 		0x4f414, 0x4f420,
1159 		0x4f600, 0x4f618,
1160 		0x4f800, 0x4f814,
1161 		0x50000, 0x50084,
1162 		0x50090, 0x500cc,
1163 		0x50400, 0x50400,
1164 		0x50800, 0x50884,
1165 		0x50890, 0x508cc,
1166 		0x50c00, 0x50c00,
1167 		0x51000, 0x5101c,
1168 		0x51300, 0x51308,
1169 	};
1170 
1171 	if (ddi_copyin(data, &r, sizeof (r), flags) < 0)
1172 		return (EFAULT);
1173 
1174 	if (r.len > T4_REGDUMP_SIZE)
1175 		r.len = T4_REGDUMP_SIZE;
1176 	else if (r.len < T4_REGDUMP_SIZE)
1177 		return (E2BIG);
1178 
1179 	r.version = mk_adap_vers(sc);
1180 
1181 	if (is_t4(sc->params.chip)) {
1182 		reg_ranges = &t4_reg_ranges[0];
1183 		arr_size = ARRAY_SIZE(t4_reg_ranges);
1184 		buf_size = T4_REGDUMP_SIZE;
1185 	} else {
1186 		reg_ranges = &t5_reg_ranges[0];
1187 		arr_size = ARRAY_SIZE(t5_reg_ranges);
1188 		buf_size = T5_REGDUMP_SIZE;
1189 	}
1190 
1191 	buf = kmem_zalloc(buf_size, KM_SLEEP);
1192 	if (buf == NULL)
1193 		return (ENOMEM);
1194 
1195 	for (i = 0; i < arr_size; i += 2)
1196 		reg_block_dump(sc, buf, reg_ranges[i], reg_ranges[i + 1]);
1197 
1198 	if (ddi_copyout(buf, r.data, r.len, flags) < 0)
1199 		rc = EFAULT;
1200 
1201 	if (rc == 0 && ddi_copyout(&r, data, sizeof (r), flags) < 0)
1202 		rc = EFAULT;
1203 
1204 	kmem_free(buf, buf_size);
1205 	return (rc);
1206 }
1207 
1208 static int
1209 get_sge_context(struct adapter *sc, void *data, int flags)
1210 {
1211 	struct t4_sge_context sgec;
1212 	uint32_t buff[SGE_CTXT_SIZE / 4];
1213 	int rc = 0;
1214 
1215 	if (ddi_copyin(data, &sgec, sizeof (sgec), flags) < 0) {
1216 		rc = EFAULT;
1217 		goto _exit;
1218 	}
1219 
1220 	if (sgec.len < SGE_CTXT_SIZE || sgec.addr > M_CTXTQID) {
1221 		rc = EINVAL;
1222 		goto _exit;
1223 	}
1224 
1225 	if ((sgec.mem_id != T4_CTXT_EGRESS) && (sgec.mem_id != T4_CTXT_FLM) &&
1226 	    (sgec.mem_id != T4_CTXT_INGRESS)) {
1227 		rc = EINVAL;
1228 		goto _exit;
1229 	}
1230 
1231 	rc = (sc->flags & FW_OK) ?
1232 	    -t4_sge_ctxt_rd(sc, sc->mbox, sgec.addr, sgec.mem_id, buff) :
1233 	    -t4_sge_ctxt_rd_bd(sc, sgec.addr, sgec.mem_id, buff);
1234 	if (rc != 0)
1235 		goto _exit;
1236 
1237 	sgec.version = 4 | (sc->params.chip << 10);
1238 
1239 	/* copyout data and then t4_sge_context */
1240 	rc = ddi_copyout(buff, sgec.data, sgec.len, flags);
1241 	if (rc == 0)
1242 		rc = ddi_copyout(&sgec, data, sizeof (sgec), flags);
1243 	/* if ddi_copyout fails, return EFAULT - for either of the two */
1244 	if (rc != 0)
1245 		rc = EFAULT;
1246 
1247 _exit:
1248 	return (rc);
1249 }
1250 
1251 static int
1252 read_tid_tab(struct adapter *sc, void *data, int flags)
1253 {
1254 	struct t4_tid_info t4tid;
1255 	uint32_t *buf, *b;
1256 	struct tid_info *t = &sc->tids;
1257 	int rc = 0;
1258 
1259 	if (ddi_copyin(data, &t4tid, sizeof (t4tid), flags) < 0) {
1260 		rc = EFAULT;
1261 		goto _exit;
1262 	}
1263 
1264 	buf = b = kmem_zalloc(t4tid.len, KM_NOSLEEP);
1265 	if (buf == NULL) {
1266 		rc = ENOMEM;
1267 		goto _exit;
1268 	}
1269 
1270 	*b++ = t->tids_in_use;
1271 	*b++ = t->atids_in_use;
1272 	*b = t->stids_in_use;
1273 
1274 	if (ddi_copyout(buf, t4tid.data, t4tid.len, flags) < 0)
1275 		rc = EFAULT;
1276 
1277 	kmem_free(buf, t4tid.len);
1278 
1279 _exit:
1280 	return (rc);
1281 }
1282 
1283 /*
1284  * Verify that the memory range specified by the addr/len pair is valid and lies
1285  * entirely within a single region (EDCx or MCx).
1286  */
1287 static int
1288 validate_mem_range(struct adapter *sc, uint32_t addr, int len)
1289 {
1290 	uint32_t em, addr_len, maddr, mlen;
1291 
1292 	/* Memory can only be accessed in naturally aligned 4 byte units */
1293 	if (addr & 3 || len & 3 || len == 0)
1294 		return (EINVAL);
1295 
1296 	/* Enabled memories */
1297 	em = t4_read_reg(sc, A_MA_TARGET_MEM_ENABLE);
1298 	if (em & F_EDRAM0_ENABLE) {
1299 		addr_len = t4_read_reg(sc, A_MA_EDRAM0_BAR);
1300 		maddr = G_EDRAM0_BASE(addr_len) << 20;
1301 		mlen = G_EDRAM0_SIZE(addr_len) << 20;
1302 		if (mlen > 0 && addr >= maddr && addr < maddr + mlen &&
1303 				addr + len <= maddr + mlen)
1304 			return (0);
1305 	}
1306 	if (em & F_EDRAM1_ENABLE) {
1307 		addr_len = t4_read_reg(sc, A_MA_EDRAM1_BAR);
1308 		maddr = G_EDRAM1_BASE(addr_len) << 20;
1309 		mlen = G_EDRAM1_SIZE(addr_len) << 20;
1310 		if (mlen > 0 && addr >= maddr && addr < maddr + mlen &&
1311 				addr + len <= maddr + mlen)
1312 			return (0);
1313 	}
1314 	if (em & F_EXT_MEM_ENABLE) {
1315 		addr_len = t4_read_reg(sc, A_MA_EXT_MEMORY_BAR);
1316 		maddr = G_EXT_MEM_BASE(addr_len) << 20;
1317 		mlen = G_EXT_MEM_SIZE(addr_len) << 20;
1318 		if (mlen > 0 && addr >= maddr && addr < maddr + mlen &&
1319 				addr + len <= maddr + mlen)
1320 			return (0);
1321 	}
1322 	if (!is_t4(sc->params.chip) && em & F_EXT_MEM1_ENABLE) {
1323 		addr_len = t4_read_reg(sc, A_MA_EXT_MEMORY1_BAR);
1324 		maddr = G_EXT_MEM1_BASE(addr_len) << 20;
1325 		mlen = G_EXT_MEM1_SIZE(addr_len) << 20;
1326 		if (mlen > 0 && addr >= maddr && addr < maddr + mlen &&
1327 				addr + len <= maddr + mlen)
1328 			return (0);
1329 	}
1330 
1331 	return (EFAULT);
1332 }
1333 
1334 static int
1335 read_card_mem(struct adapter *sc, void *data, int flags)
1336 {
1337 	struct t4_mem_range mr;
1338 	uint32_t addr, off, remaining, i, n;
1339 	uint32_t *buf, *b;
1340 	int rc = 0;
1341 	uint32_t mw_base, mw_aperture;
1342 	uint8_t *dst;
1343 
1344 	if (ddi_copyin(data, &mr, sizeof (mr), flags) < 0) {
1345 		rc = EFAULT;
1346 		goto _exit;
1347 	}
1348 
1349 	rc = validate_mem_range(sc, mr.addr, mr.len);
1350 	if (rc != 0)
1351 		return (rc);
1352 
1353 	memwin_info(sc, 2, &mw_base, &mw_aperture);
1354 	buf = b = kmem_zalloc(min(mr.len, mw_aperture), KM_NOSLEEP);
1355 	if (buf == NULL) {
1356 		rc = ENOMEM;
1357 		goto _exit;
1358 	}
1359 
1360 	addr = mr.addr;
1361 	remaining = mr.len;
1362 	dst = (void *)mr.data;
1363 
1364 	while (remaining) {
1365 		off = position_memwin(sc, 2, addr);
1366 
1367 		/* number of bytes that we'll copy in the inner loop */
1368 		n = min(remaining, mw_aperture - off);
1369 
1370 		for (i = 0; i < n; i += 4)
1371 			*b++ = t4_read_reg(sc, mw_base + off + i);
1372 		rc = ddi_copyout(buf, dst, n, flags);
1373 		if (rc != 0) {
1374 			rc = EFAULT;
1375 			break;
1376 		}
1377 
1378 		b = buf;
1379 		dst += n;
1380 		remaining -= n;
1381 		addr += n;
1382 	}
1383 
1384 	kmem_free(buf, min(mr.len, mw_aperture));
1385 _exit:
1386 	return (rc);
1387 }
1388 
1389 static int
1390 get_devlog(struct adapter *sc, void *data, int flags)
1391 {
1392 	struct devlog_params *dparams = &sc->params.devlog;
1393 	struct fw_devlog_e *buf;
1394 	struct t4_devlog dl;
1395 	int rc = 0;
1396 
1397 	if (ddi_copyin(data, &dl, sizeof (dl), flags) < 0) {
1398 		rc = EFAULT;
1399 		goto done;
1400 	}
1401 
1402 	if (dparams->start == 0) {
1403 		dparams->memtype = 0;
1404 		dparams->start = 0x84000;
1405 		dparams->size = 32768;
1406 	}
1407 
1408 	if (dl.len < dparams->size) {
1409 		dl.len = dparams->size;
1410 		rc = ddi_copyout(&dl, data, sizeof (dl), flags);
1411 		/*
1412 		 * rc = 0 indicates copyout was successful, then return ENOBUFS
1413 		 * to indicate that the buffer size was not enough. Return of
1414 		 * EFAULT indicates that the copyout was not successful.
1415 		 */
1416 		rc = (rc == 0) ? ENOBUFS : EFAULT;
1417 		goto done;
1418 	}
1419 
1420 	buf = kmem_zalloc(dparams->size, KM_NOSLEEP);
1421 	if (buf == NULL) {
1422 		rc = ENOMEM;
1423 		goto done;
1424 	}
1425 
1426 	rc = -t4_memory_rw(sc, sc->params.drv_memwin, dparams->memtype,
1427 			   dparams->start, dparams->size, (void *)buf,
1428 			   T4_MEMORY_READ);
1429 	if (rc != 0)
1430 		goto done1;
1431 
1432 	/* Copyout device log buffer and then carrier buffer */
1433 	if (ddi_copyout(buf, (void *)((uintptr_t)data + sizeof(dl)), dl.len,
1434 	    flags) < 0)
1435 		rc = EFAULT;
1436 
1437 	if (ddi_copyout(&dl, data, sizeof(dl), flags) < 0)
1438 		rc = EFAULT;
1439 
1440 done1:
1441 	kmem_free(buf, dparams->size);
1442 
1443 done:
1444 	return (rc);
1445 }
1446 
1447 static int
1448 read_cim_qcfg(struct adapter *sc, void *data, int flags)
1449 {
1450 	struct t4_cim_qcfg t4cimqcfg;
1451 	int rc = 0;
1452 	unsigned int ibq_rdaddr, obq_rdaddr, nq;
1453 
1454 	if (ddi_copyin(data, &t4cimqcfg, sizeof (t4cimqcfg), flags) < 0) {
1455 		rc = EFAULT;
1456 		goto _exit;
1457 	}
1458 
1459         if (is_t4(sc->params.chip)) {
1460 		t4cimqcfg.num_obq = CIM_NUM_OBQ;
1461                 ibq_rdaddr = A_UP_IBQ_0_RDADDR;
1462                 obq_rdaddr = A_UP_OBQ_0_REALADDR;
1463         } else {
1464                 t4cimqcfg.num_obq = CIM_NUM_OBQ_T5;
1465                 ibq_rdaddr = A_UP_IBQ_0_SHADOW_RDADDR;
1466                 obq_rdaddr = A_UP_OBQ_0_SHADOW_REALADDR;
1467         }
1468 	nq = CIM_NUM_IBQ + t4cimqcfg.num_obq;
1469 
1470 	rc = -t4_cim_read(sc, ibq_rdaddr, 4 * nq, t4cimqcfg.stat);
1471 	if (rc == 0)
1472 		rc = -t4_cim_read(sc, obq_rdaddr, 2 * t4cimqcfg.num_obq,
1473 		    t4cimqcfg.obq_wr);
1474 	if (rc != 0)
1475 		return (rc);
1476 
1477 	t4_read_cimq_cfg(sc, t4cimqcfg.base, t4cimqcfg.size, t4cimqcfg.thres);
1478 
1479 	if (ddi_copyout(&t4cimqcfg, data, sizeof (t4cimqcfg), flags) < 0)
1480 		rc = EFAULT;
1481 
1482 _exit:
1483 	return (rc);
1484 }
1485 
1486 static int
1487 read_edc(struct adapter *sc, void *data, int flags)
1488 {
1489 	struct t4_edc t4edc;
1490 	int rc = 0;
1491 	u32 count, pos = 0;
1492 	u32 memoffset;
1493 	__be32 *edc = NULL;
1494 
1495 	if (ddi_copyin(data, &t4edc, sizeof (t4edc), flags) < 0) {
1496 		rc = EFAULT;
1497 		goto _exit;
1498 	}
1499 
1500 	if (t4edc.mem > 2)
1501 		goto _exit;
1502 
1503 	edc = kmem_zalloc(t4edc.len, KM_NOSLEEP);
1504 	if (edc == NULL) {
1505 		rc = ENOMEM;
1506 		goto _exit;
1507 	}
1508 	/*
1509 	 * Offset into the region of memory which is being accessed
1510 	 * MEM_EDC0 = 0
1511 	 * MEM_EDC1 = 1
1512 	 * MEM_MC   = 2
1513 	 */
1514 	memoffset = (t4edc.mem * (5 * 1024 * 1024));
1515 	count = t4edc.len;
1516 	pos = t4edc.pos;
1517 
1518 	while (count) {
1519 		u32 len;
1520 
1521 		rc = t4_memory_rw(sc, sc->params.drv_memwin, memoffset, pos,
1522 				  count, edc, T4_MEMORY_READ);
1523 		if (rc != 0) {
1524 			kmem_free(edc, t4edc.len);
1525 			goto _exit;
1526 		}
1527 
1528 		len = MEMWIN0_APERTURE;
1529 		pos += len;
1530 		count -= len;
1531 	}
1532 
1533 	if (ddi_copyout(edc, t4edc.data, t4edc.len, flags) < 0)
1534 		rc = EFAULT;
1535 
1536 	kmem_free(edc, t4edc.len);
1537 _exit:
1538 	return (rc);
1539 }
1540 
1541 static int
1542 read_cim_ibq(struct adapter *sc, void *data, int flags)
1543 {
1544 	struct t4_ibq t4ibq;
1545 	int rc = 0;
1546 	__be64 *buf;
1547 
1548 	if (ddi_copyin(data, &t4ibq, sizeof (t4ibq), flags) < 0) {
1549 		rc = EFAULT;
1550 		goto _exit;
1551 	}
1552 
1553 	buf = kmem_zalloc(t4ibq.len, KM_NOSLEEP);
1554 	if (buf == NULL) {
1555 		rc = ENOMEM;
1556 		goto _exit;
1557 	}
1558 
1559 	rc = t4_read_cim_ibq(sc, 3, (u32 *)buf, CIM_IBQ_SIZE * 4);
1560 	if (rc < 0) {
1561 		kmem_free(buf, t4ibq.len);
1562 		return (rc);
1563 	} else
1564 		rc = 0;
1565 
1566 	if (ddi_copyout(buf, t4ibq.data, t4ibq.len, flags) < 0)
1567 		rc = EFAULT;
1568 
1569 	kmem_free(buf, t4ibq.len);
1570 
1571 _exit:
1572 	return (rc);
1573 }
1574 
1575 static int
1576 read_cim_la(struct adapter *sc, void *data, int flags)
1577 {
1578 	struct t4_cim_la t4cimla;
1579 	int rc = 0;
1580 	unsigned int cfg;
1581 	__be64 *buf;
1582 
1583 	rc = t4_cim_read(sc, A_UP_UP_DBG_LA_CFG, 1, &cfg);
1584 	if (rc != 0)
1585 		return (rc);
1586 
1587 	if (ddi_copyin(data, &t4cimla, sizeof (t4cimla), flags) < 0) {
1588 		rc = EFAULT;
1589 		goto _exit;
1590 	}
1591 
1592 	buf = kmem_zalloc(t4cimla.len, KM_NOSLEEP);
1593 	if (buf == NULL) {
1594 		rc = ENOMEM;
1595 		goto _exit;
1596 	}
1597 
1598 	rc = t4_cim_read_la(sc, (u32 *)buf, NULL);
1599 	if (rc != 0) {
1600 		kmem_free(buf, t4cimla.len);
1601 		return (rc);
1602 	}
1603 
1604 	if (ddi_copyout(buf, t4cimla.data, t4cimla.len, flags) < 0)
1605 		rc = EFAULT;
1606 
1607 	kmem_free(buf, t4cimla.len);
1608 
1609 _exit:
1610 	return (rc);
1611 }
1612 
1613 static int
1614 read_mbox(struct adapter *sc, void *data, int flags)
1615 {
1616 	struct t4_mbox t4mbox;
1617 	int rc = 0, i;
1618 	__be64 *p, *buf;
1619 
1620 	u32 data_reg = PF_REG(4, A_CIM_PF_MAILBOX_DATA);
1621 
1622 	if (ddi_copyin(data, &t4mbox, sizeof (t4mbox), flags) < 0) {
1623 		rc = EFAULT;
1624 		goto _exit;
1625 	}
1626 
1627 	buf = p = kmem_zalloc(t4mbox.len, KM_NOSLEEP);
1628 	if (buf == NULL) {
1629 		rc = ENOMEM;
1630 		goto _exit;
1631 	}
1632 
1633 	for (i = 0; i < t4mbox.len; i += 8, p++)
1634 		*p =  t4_read_reg64(sc, data_reg + i);
1635 
1636 	if (ddi_copyout(buf, t4mbox.data, t4mbox.len, flags) < 0)
1637 		rc = EFAULT;
1638 
1639 	kmem_free(buf, t4mbox.len);
1640 
1641 _exit:
1642 	return (rc);
1643 }
1644 
1645 static int
1646 flash_fw(struct adapter *sc, void *data, int flags)
1647 {
1648 	unsigned int mbox = M_PCIE_FW_MASTER + 1;
1649 	struct t4_ldfw fw;
1650 	u8 *ptr = NULL;
1651 	int rc = 0;
1652 
1653 	if (ddi_copyin(data, &fw, sizeof(struct t4_ldfw), flags) < 0)
1654 		return EFAULT;
1655 
1656 	if (!fw.len)
1657 		return EINVAL;
1658 
1659 	ptr = (u8 *)kmem_zalloc(fw.len, KM_NOSLEEP);
1660 	if (ptr == NULL)
1661 		return ENOMEM;
1662 
1663 	if (ddi_copyin((void *)((uintptr_t)data + sizeof(fw)), ptr, fw.len,
1664 	    flags) < 0) {
1665 		kmem_free(ptr, fw.len);
1666 		return EFAULT;
1667 	}
1668 
1669 	if (sc->flags & FULL_INIT_DONE)
1670 		mbox = sc->mbox;
1671 
1672 	rc = -t4_fw_upgrade(sc, mbox, ptr, fw.len, true);
1673 
1674 	kmem_free(ptr, fw.len);
1675 
1676 	return (rc);
1677 }
1678