xref: /illumos-gate/usr/src/uts/common/io/e1000g/e1000g_debug.c (revision 69a119caa6570c7077699161b7c28b6ee9f8b0f4)
1 /*
2  * This file is provided under a CDDLv1 license.  When using or
3  * redistributing this file, you may do so under this license.
4  * In redistributing this file this license must be included
5  * and no other modification of this header file is permitted.
6  *
7  * CDDL LICENSE SUMMARY
8  *
9  * Copyright(c) 1999 - 2009 Intel Corporation. All rights reserved.
10  *
11  * The contents of this file are subject to the terms of Version
12  * 1.0 of the Common Development and Distribution License (the "License").
13  *
14  * You should have received a copy of the License with this software.
15  * You can obtain a copy of the License at
16  *	http://www.opensolaris.org/os/licensing.
17  * See the License for the specific language governing permissions
18  * and limitations under the License.
19  */
20 
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms of the CDDLv1.
24  */
25 
26 /*
27  * **********************************************************************
28  *									*
29  * Module Name:								*
30  * 	e1000g_debug.c							*
31  *									*
32  * Abstract:								*
33  *	This module includes the debug routines				*
34  *									*
35  * **********************************************************************
36  */
37 #ifdef GCC
38 #ifdef __STDC__
39 #include <stdarg.h>
40 #else
41 #include <varargs.h>
42 #endif
43 #define	_SYS_VARARGS_H
44 #endif
45 
46 #include "e1000g_debug.h"
47 #include "e1000g_sw.h"
48 #ifdef E1000G_DEBUG
49 #include <sys/pcie.h>
50 #endif
51 
52 #ifdef E1000G_DEBUG
53 #define	WPL		8	/* 8 16-bit words per line */
54 #define	NUM_REGS	155	/* must match the array initializer */
55 typedef struct {
56 	char		name[10];
57 	uint32_t	offset;
58 } Regi_t;
59 
60 int e1000g_debug = E1000G_WARN_LEVEL;
61 #endif	/* E1000G_DEBUG */
62 int e1000g_log_mode = E1000G_LOG_PRINT;
63 
64 void
65 e1000g_log(void *instance, int level, char *fmt, ...)
66 {
67 	struct e1000g *Adapter = (struct e1000g *)instance;
68 	auto char name[NAMELEN];
69 	auto char buf[BUFSZ];
70 	va_list ap;
71 
72 	switch (level) {
73 #ifdef E1000G_DEBUG
74 	case E1000G_VERBOSE_LEVEL:	/* 16 or 0x010 */
75 		if (e1000g_debug < E1000G_VERBOSE_LEVEL)
76 			return;
77 		level = CE_CONT;
78 		break;
79 
80 	case E1000G_TRACE_LEVEL:	/* 8 or 0x008 */
81 		if (e1000g_debug < E1000G_TRACE_LEVEL)
82 			return;
83 		level = CE_CONT;
84 		break;
85 
86 	case E1000G_INFO_LEVEL:		/* 4 or 0x004 */
87 		if (e1000g_debug < E1000G_INFO_LEVEL)
88 			return;
89 		level = CE_CONT;
90 		break;
91 
92 	case E1000G_WARN_LEVEL:		/* 2 or 0x002 */
93 		if (e1000g_debug < E1000G_WARN_LEVEL)
94 			return;
95 		level = CE_CONT;
96 		break;
97 
98 	case E1000G_ERRS_LEVEL:		/* 1 or 0x001 */
99 		level = CE_CONT;
100 		break;
101 #else
102 	case CE_CONT:
103 	case CE_NOTE:
104 	case CE_WARN:
105 	case CE_PANIC:
106 		break;
107 #endif
108 	default:
109 		level = CE_CONT;
110 		break;
111 	}
112 
113 	if (Adapter != NULL) {
114 		(void) sprintf(name, "%s - e1000g[%d] ",
115 		    ddi_get_name(Adapter->dip), ddi_get_instance(Adapter->dip));
116 	} else {
117 		(void) sprintf(name, "e1000g");
118 	}
119 	/*
120 	 * va_start uses built in macro __builtin_va_alist from the
121 	 * compiler libs which requires compiler system to have
122 	 * __BUILTIN_VA_ARG_INCR defined.
123 	 */
124 	/*
125 	 * Many compilation systems depend upon the use of special functions
126 	 * built into the the compilation system to handle variable argument
127 	 * lists and stack allocations.  The method to obtain this in SunOS
128 	 * is to define the feature test macro "__BUILTIN_VA_ARG_INCR" which
129 	 * enables the following special built-in functions:
130 	 *	__builtin_alloca
131 	 *	__builtin_va_alist
132 	 *	__builtin_va_arg_incr
133 	 * It is intended that the compilation system define this feature test
134 	 * macro, not the user of the system.
135 	 *
136 	 * The tests on the processor type are to provide a transitional period
137 	 * for existing compilation systems, and may be removed in a future
138 	 * release.
139 	 */
140 	/*
141 	 * Using GNU gcc compiler it doesn't expand to va_start....
142 	 */
143 	va_start(ap, fmt);
144 	(void) vsprintf(buf, fmt, ap);
145 	va_end(ap);
146 
147 	if ((e1000g_log_mode & E1000G_LOG_ALL) == E1000G_LOG_ALL)
148 		cmn_err(level, "%s: %s", name, buf);
149 	else if (e1000g_log_mode & E1000G_LOG_DISPLAY)
150 		cmn_err(level, "^%s: %s", name, buf);
151 	else if (e1000g_log_mode & E1000G_LOG_PRINT)
152 		cmn_err(level, "!%s: %s", name, buf);
153 	else /* if they are not set properly then do both */
154 		cmn_err(level, "%s: %s", name, buf);
155 }
156 
157 
158 
159 #ifdef E1000G_DEBUG
160 extern kmutex_t e1000g_nvm_lock;
161 
162 void
163 eeprom_dump(void *instance)
164 {
165 	struct e1000g *Adapter = (struct e1000g *)instance;
166 	struct e1000_hw *hw = &Adapter->shared;
167 	uint16_t eeprom[WPL], size_field;
168 	int i, ret, sign, size, lines, offset = 0;
169 	int ee_size[] =
170 	    {128, 256, 512, 1024, 2048, 4096, 16 * 1024, 32 * 1024, 64 * 1024};
171 
172 	mutex_enter(&e1000g_nvm_lock);
173 
174 	if (ret = e1000_read_nvm(hw, 0x12, 1, &size_field)) {
175 		e1000g_log(Adapter, CE_WARN,
176 		    "e1000_read_nvm failed to read size: %d", ret);
177 		goto eeprom_dump_end;
178 	}
179 
180 	sign = (size_field & 0xc000) >> 14;
181 	if (sign != 1) {
182 		e1000g_log(Adapter, CE_WARN,
183 		    "eeprom_dump invalid signature: %d", sign);
184 	}
185 
186 	size = (size_field & 0x3c00) >> 10;
187 	if (size < 0 || size > 11) {
188 		e1000g_log(Adapter, CE_WARN,
189 		    "eeprom_dump invalid size: %d", size);
190 	}
191 
192 	e1000g_log(Adapter, CE_CONT,
193 	    "eeprom_dump size field: %d  eeprom bytes: %d\n",
194 	    size, ee_size[size]);
195 
196 	e1000g_log(Adapter, CE_CONT,
197 	    "e1000_read_nvm hebs: %d\n", ((size_field & 0x000f) >> 10));
198 
199 	lines = ee_size[size] / WPL / 2;
200 	e1000g_log(Adapter, CE_CONT,
201 	    "dump eeprom %d lines of %d words per line\n", lines, WPL);
202 
203 	for (i = 0; i < lines; i++) {
204 		if (ret = e1000_read_nvm(hw, offset, WPL, eeprom)) {
205 			e1000g_log(Adapter, CE_WARN,
206 			    "e1000_read_nvm failed: %d", ret);
207 			goto eeprom_dump_end;
208 		}
209 
210 		e1000g_log(Adapter, CE_CONT,
211 		    "0x%04x    %04x %04x %04x %04x %04x %04x %04x %04x\n",
212 		    offset,
213 		    eeprom[0], eeprom[1], eeprom[2], eeprom[3],
214 		    eeprom[4], eeprom[5], eeprom[6], eeprom[7]);
215 		offset += WPL;
216 	}
217 
218 eeprom_dump_end:
219 	mutex_exit(&e1000g_nvm_lock);
220 }
221 
222 /*
223  * phy_dump - dump important phy registers
224  */
225 void
226 phy_dump(void *instance)
227 {
228 	struct e1000g *Adapter = (struct e1000g *)instance;
229 	struct e1000_hw *hw = &Adapter->shared;
230 	/* offset to each phy register */
231 	int32_t offset[] =
232 	    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
233 	    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
234 	    30, 31, 0x1796, 0x187A, 0x1895, 0x1F30, 0x1F35, 0x1F3E, 0x1F54,
235 	    0x1F55, 0x1F56, 0x1F72, 0x1F76, 0x1F77, 0x1F78, 0x1F79, 0x1F98,
236 	    0x2010, 0x2011, 0x20DC, 0x20DD, 0x20DE, 0x28B4, 0x2F52, 0x2F5B,
237 	    0x2F70, 0x2F90, 0x2FB1, 0x2FB2 };
238 	uint16_t value;	/* register value */
239 	uint32_t stat;	/* status from e1000_read_phy_reg */
240 	int i;
241 
242 	e1000g_log(Adapter, CE_CONT, "Begin PHY dump\n");
243 	for (i = 0; i < ((sizeof (offset)) / sizeof (offset[0])); i++) {
244 
245 		stat = e1000_read_phy_reg(hw, offset[i], &value);
246 		if (stat == 0) {
247 			e1000g_log(Adapter, CE_CONT,
248 			    "phyreg offset: %d   value: 0x%x\n",
249 			    offset[i], value);
250 		} else {
251 			e1000g_log(Adapter, CE_WARN,
252 			    "phyreg offset: %d   ERROR: 0x%x\n",
253 			    offset[i], stat);
254 		}
255 	}
256 }
257 
258 uint32_t
259 e1000_read_reg(struct e1000_hw *hw, uint32_t offset)
260 {
261 	return (ddi_get32(((struct e1000g_osdep *)(hw)->back)->reg_handle,
262 	    (uint32_t *)((uintptr_t)(hw)->hw_addr + offset)));
263 }
264 
265 
266 /*
267  * mac_dump - dump important mac registers
268  */
269 void
270 mac_dump(void *instance)
271 {
272 	struct e1000g *Adapter = (struct e1000g *)instance;
273 	struct e1000_hw *hw = &Adapter->shared;
274 	int i;
275 
276 	/* {name, offset} for each mac register */
277 	Regi_t macreg[NUM_REGS] = {
278 	    {"CTRL",	E1000_CTRL},	{"STATUS",	E1000_STATUS},
279 	    {"EECD",	E1000_EECD},	{"EERD",	E1000_EERD},
280 	    {"CTRL_EXT", E1000_CTRL_EXT}, {"FLA",	E1000_FLA},
281 	    {"MDIC",	E1000_MDIC},	{"SCTL",	E1000_SCTL},
282 	    {"FCAL",	E1000_FCAL},	{"FCAH",	E1000_FCAH},
283 	    {"FCT",	E1000_FCT},	{"VET",		E1000_VET},
284 	    {"ICR",	E1000_ICR},	{"ITR",		E1000_ITR},
285 	    {"ICS",	E1000_ICS},	{"IMS",		E1000_IMS},
286 	    {"IMC",	E1000_IMC},	{"IAM",		E1000_IAM},
287 	    {"RCTL",	E1000_RCTL},	{"FCTTV",	E1000_FCTTV},
288 	    {"TXCW",	E1000_TXCW},	{"RXCW",	E1000_RXCW},
289 	    {"TCTL",	E1000_TCTL},	{"TIPG",	E1000_TIPG},
290 	    {"AIT",	E1000_AIT},	{"LEDCTL",	E1000_LEDCTL},
291 	    {"PBA",	E1000_PBA},	{"PBS",		E1000_PBS},
292 	    {"EEMNGCTL", E1000_EEMNGCTL}, {"ERT",	E1000_ERT},
293 	    {"FCRTL",	E1000_FCRTL},	{"FCRTH",	E1000_FCRTH},
294 	    {"PSRCTL",	E1000_PSRCTL},	{"RDBAL(0)",	E1000_RDBAL(0)},
295 	    {"RDBAH(0)", E1000_RDBAH(0)}, {"RDLEN(0)",	E1000_RDLEN(0)},
296 	    {"RDH(0)",	E1000_RDH(0)},	{"RDT(0)",	E1000_RDT(0)},
297 	    {"RDTR",	E1000_RDTR},	{"RXDCTL(0)",	E1000_RXDCTL(0)},
298 	    {"RADV",	E1000_RADV},	{"RDBAL(1)",	E1000_RDBAL(1)},
299 	    {"RDBAH(1)", E1000_RDBAH(1)}, {"RDLEN(1)",	E1000_RDLEN(1)},
300 	    {"RDH(1)",	E1000_RDH(1)},	{"RDT(1)",	E1000_RDT(1)},
301 	    {"RXDCTL(1)", E1000_RXDCTL(1)}, {"RSRPD",	E1000_RSRPD},
302 	    {"RAID",	E1000_RAID},	{"CPUVEC",	E1000_CPUVEC},
303 	    {"TDFH",	E1000_TDFH},	{"TDFT",	E1000_TDFT},
304 	    {"TDFHS",	E1000_TDFHS},	{"TDFTS",	E1000_TDFTS},
305 	    {"TDFPC",	E1000_TDFPC},	{"TDBAL(0)",	E1000_TDBAL(0)},
306 	    {"TDBAH(0)", E1000_TDBAH(0)}, {"TDLEN(0)",	E1000_TDLEN(0)},
307 	    {"TDH(0)",	E1000_TDH(0)},	{"TDT(0)",	E1000_TDT(0)},
308 	    {"TIDV",	E1000_TIDV},	{"TXDCTL(0)",	E1000_TXDCTL(0)},
309 	    {"TADV",	E1000_TADV},	{"TARC(0)",	E1000_TARC(0)},
310 	    {"TDBAL(1)", E1000_TDBAL(1)}, {"TDBAH(1)",	E1000_TDBAH(1)},
311 	    {"TDLEN(1)", E1000_TDLEN(1)}, {"TDH(1)",	E1000_TDH(1)},
312 	    {"TDT(1)",	E1000_TDT(1)},	{"TXDCTL(1)",	E1000_TXDCTL(1)},
313 	    {"TARC(1)",	E1000_TARC(1)},	{"ALGNERRC",	E1000_ALGNERRC},
314 	    {"RXERRC",	E1000_RXERRC},	{"MPC",		E1000_MPC},
315 	    {"SCC",	E1000_SCC},	{"ECOL",	E1000_ECOL},
316 	    {"MCC",	E1000_MCC},	{"LATECOL",	E1000_LATECOL},
317 	    {"COLC",	E1000_COLC},	{"DC",		E1000_DC},
318 	    {"TNCRS",	E1000_TNCRS},	{"SEC",		E1000_SEC},
319 	    {"CEXTERR",	E1000_CEXTERR},	{"RLEC",	E1000_RLEC},
320 	    {"XONRXC",	E1000_XONRXC},	{"XONTXC",	E1000_XONTXC},
321 	    {"XOFFRXC",	E1000_XOFFRXC},	{"XOFFTXC",	E1000_XOFFTXC},
322 	    {"FCRUC",	E1000_FCRUC},	{"PRC64",	E1000_PRC64},
323 	    {"PRC127",	E1000_PRC127},	{"PRC255",	E1000_PRC255},
324 	    {"PRC511",	E1000_PRC511},	{"PRC1023",	E1000_PRC1023},
325 	    {"PRC1522",	E1000_PRC1522},	{"GPRC",	E1000_GPRC},
326 	    {"BPRC",	E1000_BPRC},	{"MPRC",	E1000_MPRC},
327 	    {"GPTC",	E1000_GPTC},	{"GORCL",	E1000_GORCL},
328 	    {"GORCH",	E1000_GORCH},	{"GOTCL",	E1000_GOTCL},
329 	    {"GOTCH",	E1000_GOTCH},	{"RNBC",	E1000_RNBC},
330 	    {"RUC",	E1000_RUC},	{"RFC",		E1000_RFC},
331 	    {"ROC",	E1000_ROC},	{"RJC",		E1000_RJC},
332 	    {"MGTPRC",	E1000_MGTPRC},	{"MGTPDC",	E1000_MGTPDC},
333 	    {"MGTPTC",	E1000_MGTPTC},	{"TORL",	E1000_TORL},
334 	    {"TORH",	E1000_TORH},	{"TOTL",	E1000_TOTL},
335 	    {"TOTH",	E1000_TOTH},	{"TPR",		E1000_TPR},
336 	    {"TPT",	E1000_TPT},	{"PTC64",	E1000_PTC64},
337 	    {"PTC127",	E1000_PTC127},	{"PTC255",	E1000_PTC255},
338 	    {"PTC511",	E1000_PTC511},	{"PTC1023",	E1000_PTC1023},
339 	    {"PTC1522",	E1000_PTC1522},	{"MPTC",	E1000_MPTC},
340 	    {"BPTC",	E1000_BPTC},	{"TSCTC",	E1000_TSCTC},
341 	    {"TSCTFC",	E1000_TSCTFC},	{"IAC",		E1000_IAC},
342 	    {"ICRXPTC",	E1000_ICRXPTC},	{"ICRXATC",	E1000_ICRXATC},
343 	    {"ICTXPTC",	E1000_ICTXPTC},	{"ICTXATC",	E1000_ICTXATC},
344 	    {"ICTXQEC",	E1000_ICTXQEC},	{"ICTXQMTC",	E1000_ICTXQMTC},
345 	    {"ICRXDMTC", E1000_ICRXDMTC}, {"ICRXOC",	E1000_ICRXOC},
346 	    {"RXCSUM",	E1000_RXCSUM},	{"RFCTL",	E1000_RFCTL},
347 	    {"WUC",	E1000_WUC},	{"WUFC",	E1000_WUFC},
348 	    {"WUS",	E1000_WUS},	{"MRQC",	E1000_MRQC},
349 	    {"MANC",	E1000_MANC},	{"IPAV",	E1000_IPAV},
350 	    {"MANC2H",	E1000_MANC2H},	{"RSSIM",	E1000_RSSIM},
351 	    {"RSSIR",	E1000_RSSIR},	{"WUPL",	E1000_WUPL},
352 	    {"GCR",	E1000_GCR},	{"GSCL_1",	E1000_GSCL_1},
353 	    {"GSCL_2",	E1000_GSCL_2},	{"GSCL_3",	E1000_GSCL_3},
354 	    {"GSCL_4",	E1000_GSCL_4},	{"FACTPS",	E1000_FACTPS},
355 	    {"FWSM",	E1000_FWSM},
356 	};
357 
358 	e1000g_log(Adapter, CE_CONT, "Begin MAC dump\n");
359 
360 	for (i = 0; i < NUM_REGS; i++) {
361 		e1000g_log(Adapter, CE_CONT,
362 		    "macreg %10s offset: 0x%x   value: 0x%x\n",
363 		    macreg[i].name, macreg[i].offset,
364 		    e1000_read_reg(hw, macreg[i].offset));
365 	}
366 }
367 
368 void
369 pciconfig_dump(void *instance)
370 {
371 	struct e1000g *Adapter = (struct e1000g *)instance;
372 	ddi_acc_handle_t handle;
373 	uint8_t cap_ptr;
374 	uint8_t next_ptr;
375 	off_t offset;
376 
377 	handle = Adapter->osdep.cfg_handle;
378 
379 	e1000g_log(Adapter, CE_CONT, "Begin dump PCI config space\n");
380 
381 	e1000g_log(Adapter, CE_CONT,
382 	    "PCI_CONF_VENID:\t0x%x\n",
383 	    pci_config_get16(handle, PCI_CONF_VENID));
384 	e1000g_log(Adapter, CE_CONT,
385 	    "PCI_CONF_DEVID:\t0x%x\n",
386 	    pci_config_get16(handle, PCI_CONF_DEVID));
387 	e1000g_log(Adapter, CE_CONT,
388 	    "PCI_CONF_COMMAND:\t0x%x\n",
389 	    pci_config_get16(handle, PCI_CONF_COMM));
390 	e1000g_log(Adapter, CE_CONT,
391 	    "PCI_CONF_STATUS:\t0x%x\n",
392 	    pci_config_get16(handle, PCI_CONF_STAT));
393 	e1000g_log(Adapter, CE_CONT,
394 	    "PCI_CONF_REVID:\t0x%x\n",
395 	    pci_config_get8(handle, PCI_CONF_REVID));
396 	e1000g_log(Adapter, CE_CONT,
397 	    "PCI_CONF_PROG_CLASS:\t0x%x\n",
398 	    pci_config_get8(handle, PCI_CONF_PROGCLASS));
399 	e1000g_log(Adapter, CE_CONT,
400 	    "PCI_CONF_SUB_CLASS:\t0x%x\n",
401 	    pci_config_get8(handle, PCI_CONF_SUBCLASS));
402 	e1000g_log(Adapter, CE_CONT,
403 	    "PCI_CONF_BAS_CLASS:\t0x%x\n",
404 	    pci_config_get8(handle, PCI_CONF_BASCLASS));
405 	e1000g_log(Adapter, CE_CONT,
406 	    "PCI_CONF_CACHE_LINESZ:\t0x%x\n",
407 	    pci_config_get8(handle, PCI_CONF_CACHE_LINESZ));
408 	e1000g_log(Adapter, CE_CONT,
409 	    "PCI_CONF_LATENCY_TIMER:\t0x%x\n",
410 	    pci_config_get8(handle, PCI_CONF_LATENCY_TIMER));
411 	e1000g_log(Adapter, CE_CONT,
412 	    "PCI_CONF_HEADER_TYPE:\t0x%x\n",
413 	    pci_config_get8(handle, PCI_CONF_HEADER));
414 	e1000g_log(Adapter, CE_CONT,
415 	    "PCI_CONF_BIST:\t0x%x\n",
416 	    pci_config_get8(handle, PCI_CONF_BIST));
417 
418 	pciconfig_bar(Adapter, PCI_CONF_BASE0, "PCI_CONF_BASE0");
419 	pciconfig_bar(Adapter, PCI_CONF_BASE1, "PCI_CONF_BASE1");
420 	pciconfig_bar(Adapter, PCI_CONF_BASE2, "PCI_CONF_BASE2");
421 	pciconfig_bar(Adapter, PCI_CONF_BASE3, "PCI_CONF_BASE3");
422 	pciconfig_bar(Adapter, PCI_CONF_BASE4, "PCI_CONF_BASE4");
423 	pciconfig_bar(Adapter, PCI_CONF_BASE5, "PCI_CONF_BASE5");
424 
425 	e1000g_log(Adapter, CE_CONT,
426 	    "PCI_CONF_CIS:\t0x%x\n",
427 	    pci_config_get32(handle, PCI_CONF_CIS));
428 	e1000g_log(Adapter, CE_CONT,
429 	    "PCI_CONF_SUBVENID:\t0x%x\n",
430 	    pci_config_get16(handle, PCI_CONF_SUBVENID));
431 	e1000g_log(Adapter, CE_CONT,
432 	    "PCI_CONF_SUBSYSID:\t0x%x\n",
433 	    pci_config_get16(handle, PCI_CONF_SUBSYSID));
434 	e1000g_log(Adapter, CE_CONT,
435 	    "PCI_CONF_ROM:\t0x%x\n",
436 	    pci_config_get32(handle, PCI_CONF_ROM));
437 
438 	cap_ptr = pci_config_get8(handle, PCI_CONF_CAP_PTR);
439 
440 	e1000g_log(Adapter, CE_CONT,
441 	    "PCI_CONF_CAP_PTR:\t0x%x\n", cap_ptr);
442 	e1000g_log(Adapter, CE_CONT,
443 	    "PCI_CONF_ILINE:\t0x%x\n",
444 	    pci_config_get8(handle, PCI_CONF_ILINE));
445 	e1000g_log(Adapter, CE_CONT,
446 	    "PCI_CONF_IPIN:\t0x%x\n",
447 	    pci_config_get8(handle, PCI_CONF_IPIN));
448 	e1000g_log(Adapter, CE_CONT,
449 	    "PCI_CONF_MIN_G:\t0x%x\n",
450 	    pci_config_get8(handle, PCI_CONF_MIN_G));
451 	e1000g_log(Adapter, CE_CONT,
452 	    "PCI_CONF_MAX_L:\t0x%x\n",
453 	    pci_config_get8(handle, PCI_CONF_MAX_L));
454 
455 	/* Power Management */
456 	offset = cap_ptr;
457 
458 	e1000g_log(Adapter, CE_CONT,
459 	    "PCI_PM_CAP_ID:\t0x%x\n",
460 	    pci_config_get8(handle, offset));
461 
462 	next_ptr = pci_config_get8(handle, offset + 1);
463 
464 	e1000g_log(Adapter, CE_CONT,
465 	    "PCI_PM_NEXT_PTR:\t0x%x\n", next_ptr);
466 	e1000g_log(Adapter, CE_CONT,
467 	    "PCI_PM_CAP:\t0x%x\n",
468 	    pci_config_get16(handle, offset + PCI_PMCAP));
469 	e1000g_log(Adapter, CE_CONT,
470 	    "PCI_PM_CSR:\t0x%x\n",
471 	    pci_config_get16(handle, offset + PCI_PMCSR));
472 	e1000g_log(Adapter, CE_CONT,
473 	    "PCI_PM_CSR_BSE:\t0x%x\n",
474 	    pci_config_get8(handle, offset + PCI_PMCSR_BSE));
475 	e1000g_log(Adapter, CE_CONT,
476 	    "PCI_PM_DATA:\t0x%x\n",
477 	    pci_config_get8(handle, offset + PCI_PMDATA));
478 
479 	/* MSI Configuration */
480 	offset = next_ptr;
481 
482 	e1000g_log(Adapter, CE_CONT,
483 	    "PCI_MSI_CAP_ID:\t0x%x\n",
484 	    pci_config_get8(handle, offset));
485 
486 	next_ptr = pci_config_get8(handle, offset + 1);
487 
488 	e1000g_log(Adapter, CE_CONT,
489 	    "PCI_MSI_NEXT_PTR:\t0x%x\n", next_ptr);
490 	e1000g_log(Adapter, CE_CONT,
491 	    "PCI_MSI_CTRL:\t0x%x\n",
492 	    pci_config_get16(handle, offset + PCI_MSI_CTRL));
493 	e1000g_log(Adapter, CE_CONT,
494 	    "PCI_MSI_ADDR:\t0x%x\n",
495 	    pci_config_get32(handle, offset + PCI_MSI_ADDR_OFFSET));
496 	e1000g_log(Adapter, CE_CONT,
497 	    "PCI_MSI_ADDR_HI:\t0x%x\n",
498 	    pci_config_get32(handle, offset + 0x8));
499 	e1000g_log(Adapter, CE_CONT,
500 	    "PCI_MSI_DATA:\t0x%x\n",
501 	    pci_config_get16(handle, offset + 0xC));
502 
503 	/* PCI Express Configuration */
504 	offset = next_ptr;
505 
506 	e1000g_log(Adapter, CE_CONT,
507 	    "PCIE_CAP_ID:\t0x%x\n",
508 	    pci_config_get8(handle, offset + PCIE_CAP_ID));
509 
510 	next_ptr = pci_config_get8(handle, offset + PCIE_CAP_NEXT_PTR);
511 
512 	e1000g_log(Adapter, CE_CONT,
513 	    "PCIE_CAP_NEXT_PTR:\t0x%x\n", next_ptr);
514 	e1000g_log(Adapter, CE_CONT,
515 	    "PCIE_PCIECAP:\t0x%x\n",
516 	    pci_config_get16(handle, offset + PCIE_PCIECAP));
517 	e1000g_log(Adapter, CE_CONT,
518 	    "PCIE_DEVCAP:\t0x%x\n",
519 	    pci_config_get32(handle, offset + PCIE_DEVCAP));
520 	e1000g_log(Adapter, CE_CONT,
521 	    "PCIE_DEVCTL:\t0x%x\n",
522 	    pci_config_get16(handle, offset + PCIE_DEVCTL));
523 	e1000g_log(Adapter, CE_CONT,
524 	    "PCIE_DEVSTS:\t0x%x\n",
525 	    pci_config_get16(handle, offset + PCIE_DEVSTS));
526 	e1000g_log(Adapter, CE_CONT,
527 	    "PCIE_LINKCAP:\t0x%x\n",
528 	    pci_config_get32(handle, offset + PCIE_LINKCAP));
529 	e1000g_log(Adapter, CE_CONT,
530 	    "PCIE_LINKCTL:\t0x%x\n",
531 	    pci_config_get16(handle, offset + PCIE_LINKCTL));
532 	e1000g_log(Adapter, CE_CONT,
533 	    "PCIE_LINKSTS:\t0x%x\n",
534 	    pci_config_get16(handle, offset + PCIE_LINKSTS));
535 }
536 
537 void
538 pciconfig_bar(void *instance, uint32_t offset, char *name)
539 {
540 	struct e1000g *Adapter = (struct e1000g *)instance;
541 	ddi_acc_handle_t handle = Adapter->osdep.cfg_handle;
542 	uint32_t base = pci_config_get32(handle, offset);
543 	uint16_t comm = pci_config_get16(handle, PCI_CONF_COMM);
544 	uint32_t size;		/* derived size of the region */
545 	uint32_t bits_comm;	/* command word bits to disable */
546 	uint32_t size_mask;	/* mask for size extraction */
547 	char tag_type[32];	/* tag to show memory vs. i/o */
548 	char tag_mem[32];	/* tag to show memory characteristiccs */
549 
550 	/* base address zero, simple print */
551 	if (base == 0) {
552 		e1000g_log(Adapter, CE_CONT, "%s:\t0x%x\n", name, base);
553 
554 	/* base address non-zero, get size */
555 	} else {
556 		/* i/o factors that decode from the base address */
557 		if (base & PCI_BASE_SPACE_IO) {
558 			bits_comm = PCI_COMM_IO;
559 			size_mask = PCI_BASE_IO_ADDR_M;
560 			(void) strcpy(tag_type, "i/o port size:");
561 			(void) strcpy(tag_mem, "");
562 		/* memory factors that decode from the base address */
563 		} else {
564 			bits_comm = PCI_COMM_MAE;
565 			size_mask = PCI_BASE_M_ADDR_M;
566 			(void) strcpy(tag_type, "memory size:");
567 			if (base & PCI_BASE_TYPE_ALL)
568 				(void) strcpy(tag_mem, "64bit ");
569 			else
570 				(void) strcpy(tag_mem, "32bit ");
571 			if (base & PCI_BASE_PREF_M)
572 				(void) strcat(tag_mem, "prefetchable");
573 			else
574 				(void) strcat(tag_mem, "non-prefetchable");
575 		}
576 
577 		/* disable memory decode */
578 		pci_config_put16(handle, PCI_CONF_COMM, (comm & ~bits_comm));
579 
580 		/* write to base register */
581 		pci_config_put32(handle, offset, 0xffffffff);
582 
583 		/* read back & compute size */
584 		size = pci_config_get32(handle, offset);
585 		size &= size_mask;
586 		size = (~size) + 1;
587 
588 		/* restore base register */
589 		pci_config_put32(handle, offset, base);
590 
591 		/* re-enable memory decode */
592 		pci_config_put16(handle, PCI_CONF_COMM, comm);
593 
594 		/* print results */
595 		e1000g_log(Adapter, CE_CONT, "%s:\t0x%x %s 0x%x %s\n",
596 		    name, base, tag_type, size, tag_mem);
597 	}
598 }
599 #endif	/* E1000G_DEBUG */
600