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