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