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 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 	if (ret = e1000_read_nvm(hw, 0x12, 1, &size_field)) {
172 		e1000g_log(Adapter, CE_WARN,
173 		    "e1000_read_nvm failed to read size: %d", ret);
174 		return;
175 	}
176 
177 	sign = (size_field & 0xc000) >> 14;
178 	if (sign != 1) {
179 		e1000g_log(Adapter, CE_WARN,
180 		    "eeprom_dump invalid signature: %d", sign);
181 	}
182 
183 	size = (size_field & 0x3c00) >> 10;
184 	if (size < 0 || size > 11) {
185 		e1000g_log(Adapter, CE_WARN,
186 		    "eeprom_dump invalid size: %d", size);
187 	}
188 
189 	e1000g_log(Adapter, CE_CONT,
190 	    "eeprom_dump size field: %d  eeprom bytes: %d\n",
191 	    size, ee_size[size]);
192 
193 	e1000g_log(Adapter, CE_CONT,
194 	    "e1000_read_nvm hebs: %d\n", ((size_field & 0x000f) >> 10));
195 
196 	lines = ee_size[size] / WPL / 2;
197 	e1000g_log(Adapter, CE_CONT,
198 	    "dump eeprom %d lines of %d words per line\n", lines, WPL);
199 
200 	for (i = 0; i < lines; i++) {
201 		if (ret = e1000_read_nvm(hw, offset, WPL, eeprom)) {
202 			e1000g_log(Adapter, CE_WARN,
203 			    "e1000_read_nvm failed: %d", ret);
204 			return;
205 		}
206 
207 		e1000g_log(Adapter, CE_CONT,
208 		    "0x%04x    %04x %04x %04x %04x %04x %04x %04x %04x\n",
209 		    offset,
210 		    eeprom[0], eeprom[1], eeprom[2], eeprom[3],
211 		    eeprom[4], eeprom[5], eeprom[6], eeprom[7]);
212 		offset += WPL;
213 	}
214 }
215 
216 /*
217  * phy_dump - dump important phy registers
218  */
219 void
220 phy_dump(void *instance)
221 {
222 	struct e1000g *Adapter = (struct e1000g *)instance;
223 	struct e1000_hw *hw = &Adapter->shared;
224 	/* offset to each phy register */
225 	int32_t offset[] =
226 	    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
227 	    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
228 	    30, 31, 0x1796, 0x187A, 0x1895, 0x1F30, 0x1F35, 0x1F3E, 0x1F54,
229 	    0x1F55, 0x1F56, 0x1F72, 0x1F76, 0x1F77, 0x1F78, 0x1F79, 0x1F98,
230 	    0x2010, 0x2011, 0x20DC, 0x20DD, 0x20DE, 0x28B4, 0x2F52, 0x2F5B,
231 	    0x2F70, 0x2F90, 0x2FB1, 0x2FB2 };
232 	uint16_t value;	/* register value */
233 	uint32_t stat;	/* status from e1000_read_phy_reg */
234 	int i;
235 
236 	e1000g_log(Adapter, CE_CONT, "Begin PHY dump\n");
237 	for (i = 0; i < ((sizeof (offset)) / sizeof (offset[0])); i++) {
238 
239 		stat = e1000_read_phy_reg(hw, offset[i], &value);
240 		if (stat == 0) {
241 			e1000g_log(Adapter, CE_CONT,
242 			    "phyreg offset: %d   value: 0x%x\n",
243 			    offset[i], value);
244 		} else {
245 			e1000g_log(Adapter, CE_WARN,
246 			    "phyreg offset: %d   ERROR: 0x%x\n",
247 			    offset[i], stat);
248 		}
249 	}
250 }
251 
252 uint32_t
253 e1000_read_reg(struct e1000_hw *hw, uint32_t offset)
254 {
255 	return (ddi_get32(((struct e1000g_osdep *)(hw)->back)->reg_handle,
256 	    (uint32_t *)((hw)->hw_addr + offset)));
257 }
258 
259 
260 /*
261  * mac_dump - dump important mac registers
262  */
263 void
264 mac_dump(void *instance)
265 {
266 	struct e1000g *Adapter = (struct e1000g *)instance;
267 	struct e1000_hw *hw = &Adapter->shared;
268 	int i;
269 
270 	/* {name, offset} for each mac register */
271 	Regi_t macreg[NUM_REGS] = {
272 	    {"CTRL",	E1000_CTRL},	{"STATUS",	E1000_STATUS},
273 	    {"EECD",	E1000_EECD},	{"EERD",	E1000_EERD},
274 	    {"CTRL_EXT", E1000_CTRL_EXT}, {"FLA",	E1000_FLA},
275 	    {"MDIC",	E1000_MDIC},	{"SCTL",	E1000_SCTL},
276 	    {"FCAL",	E1000_FCAL},	{"FCAH",	E1000_FCAH},
277 	    {"FCT",	E1000_FCT},	{"VET",		E1000_VET},
278 	    {"ICR",	E1000_ICR},	{"ITR",		E1000_ITR},
279 	    {"ICS",	E1000_ICS},	{"IMS",		E1000_IMS},
280 	    {"IMC",	E1000_IMC},	{"IAM",		E1000_IAM},
281 	    {"RCTL",	E1000_RCTL},	{"FCTTV",	E1000_FCTTV},
282 	    {"TXCW",	E1000_TXCW},	{"RXCW",	E1000_RXCW},
283 	    {"TCTL",	E1000_TCTL},	{"TIPG",	E1000_TIPG},
284 	    {"AIT",	E1000_AIT},	{"LEDCTL",	E1000_LEDCTL},
285 	    {"PBA",	E1000_PBA},	{"PBS",		E1000_PBS},
286 	    {"EEMNGCTL", E1000_EEMNGCTL}, {"ERT",	E1000_ERT},
287 	    {"FCRTL",	E1000_FCRTL},	{"FCRTH",	E1000_FCRTH},
288 	    {"PSRCTL",	E1000_PSRCTL},	{"RDBAL(0)",	E1000_RDBAL(0)},
289 	    {"RDBAH(0)", E1000_RDBAH(0)}, {"RDLEN(0)",	E1000_RDLEN(0)},
290 	    {"RDH(0)",	E1000_RDH(0)},	{"RDT(0)",	E1000_RDT(0)},
291 	    {"RDTR",	E1000_RDTR},	{"RXDCTL(0)",	E1000_RXDCTL(0)},
292 	    {"RADV",	E1000_RADV},	{"RDBAL(1)",	E1000_RDBAL(1)},
293 	    {"RDBAH(1)", E1000_RDBAH(1)}, {"RDLEN(1)",	E1000_RDLEN(1)},
294 	    {"RDH(1)",	E1000_RDH(1)},	{"RDT(1)",	E1000_RDT(1)},
295 	    {"RXDCTL(1)", E1000_RXDCTL(1)}, {"RSRPD",	E1000_RSRPD},
296 	    {"RAID",	E1000_RAID},	{"CPUVEC",	E1000_CPUVEC},
297 	    {"TDFH",	E1000_TDFH},	{"TDFT",	E1000_TDFT},
298 	    {"TDFHS",	E1000_TDFHS},	{"TDFTS",	E1000_TDFTS},
299 	    {"TDFPC",	E1000_TDFPC},	{"TDBAL(0)",	E1000_TDBAL(0)},
300 	    {"TDBAH(0)", E1000_TDBAH(0)}, {"TDLEN(0)",	E1000_TDLEN(0)},
301 	    {"TDH(0)",	E1000_TDH(0)},	{"TDT(0)",	E1000_TDT(0)},
302 	    {"TIDV",	E1000_TIDV},	{"TXDCTL(0)",	E1000_TXDCTL(0)},
303 	    {"TADV",	E1000_TADV},	{"TARC(0)",	E1000_TARC(0)},
304 	    {"TDBAL(1)", E1000_TDBAL(1)}, {"TDBAH(1)",	E1000_TDBAH(1)},
305 	    {"TDLEN(1)", E1000_TDLEN(1)}, {"TDH(1)",	E1000_TDH(1)},
306 	    {"TDT(1)",	E1000_TDT(1)},	{"TXDCTL(1)",	E1000_TXDCTL(1)},
307 	    {"TARC(1)",	E1000_TARC(1)},	{"ALGNERRC",	E1000_ALGNERRC},
308 	    {"RXERRC",	E1000_RXERRC},	{"MPC",		E1000_MPC},
309 	    {"SCC",	E1000_SCC},	{"ECOL",	E1000_ECOL},
310 	    {"MCC",	E1000_MCC},	{"LATECOL",	E1000_LATECOL},
311 	    {"COLC",	E1000_COLC},	{"DC",		E1000_DC},
312 	    {"TNCRS",	E1000_TNCRS},	{"SEC",		E1000_SEC},
313 	    {"CEXTERR",	E1000_CEXTERR},	{"RLEC",	E1000_RLEC},
314 	    {"XONRXC",	E1000_XONRXC},	{"XONTXC",	E1000_XONTXC},
315 	    {"XOFFRXC",	E1000_XOFFRXC},	{"XOFFTXC",	E1000_XOFFTXC},
316 	    {"FCRUC",	E1000_FCRUC},	{"PRC64",	E1000_PRC64},
317 	    {"PRC127",	E1000_PRC127},	{"PRC255",	E1000_PRC255},
318 	    {"PRC511",	E1000_PRC511},	{"PRC1023",	E1000_PRC1023},
319 	    {"PRC1522",	E1000_PRC1522},	{"GPRC",	E1000_GPRC},
320 	    {"BPRC",	E1000_BPRC},	{"MPRC",	E1000_MPRC},
321 	    {"GPTC",	E1000_GPTC},	{"GORCL",	E1000_GORCL},
322 	    {"GORCH",	E1000_GORCH},	{"GOTCL",	E1000_GOTCL},
323 	    {"GOTCH",	E1000_GOTCH},	{"RNBC",	E1000_RNBC},
324 	    {"RUC",	E1000_RUC},	{"RFC",		E1000_RFC},
325 	    {"ROC",	E1000_ROC},	{"RJC",		E1000_RJC},
326 	    {"MGTPRC",	E1000_MGTPRC},	{"MGTPDC",	E1000_MGTPDC},
327 	    {"MGTPTC",	E1000_MGTPTC},	{"TORL",	E1000_TORL},
328 	    {"TORH",	E1000_TORH},	{"TOTL",	E1000_TOTL},
329 	    {"TOTH",	E1000_TOTH},	{"TPR",		E1000_TPR},
330 	    {"TPT",	E1000_TPT},	{"PTC64",	E1000_PTC64},
331 	    {"PTC127",	E1000_PTC127},	{"PTC255",	E1000_PTC255},
332 	    {"PTC511",	E1000_PTC511},	{"PTC1023",	E1000_PTC1023},
333 	    {"PTC1522",	E1000_PTC1522},	{"MPTC",	E1000_MPTC},
334 	    {"BPTC",	E1000_BPTC},	{"TSCTC",	E1000_TSCTC},
335 	    {"TSCTFC",	E1000_TSCTFC},	{"IAC",		E1000_IAC},
336 	    {"ICRXPTC",	E1000_ICRXPTC},	{"ICRXATC",	E1000_ICRXATC},
337 	    {"ICTXPTC",	E1000_ICTXPTC},	{"ICTXATC",	E1000_ICTXATC},
338 	    {"ICTXQEC",	E1000_ICTXQEC},	{"ICTXQMTC",	E1000_ICTXQMTC},
339 	    {"ICRXDMTC", E1000_ICRXDMTC}, {"ICRXOC",	E1000_ICRXOC},
340 	    {"RXCSUM",	E1000_RXCSUM},	{"RFCTL",	E1000_RFCTL},
341 	    {"WUC",	E1000_WUC},	{"WUFC",	E1000_WUFC},
342 	    {"WUS",	E1000_WUS},	{"MRQC",	E1000_MRQC},
343 	    {"MANC",	E1000_MANC},	{"IPAV",	E1000_IPAV},
344 	    {"MANC2H",	E1000_MANC2H},	{"RSSIM",	E1000_RSSIM},
345 	    {"RSSIR",	E1000_RSSIR},	{"WUPL",	E1000_WUPL},
346 	    {"GCR",	E1000_GCR},	{"GSCL_1",	E1000_GSCL_1},
347 	    {"GSCL_2",	E1000_GSCL_2},	{"GSCL_3",	E1000_GSCL_3},
348 	    {"GSCL_4",	E1000_GSCL_4},	{"FACTPS",	E1000_FACTPS},
349 	    {"FWSM",	E1000_FWSM},
350 	};
351 
352 	e1000g_log(Adapter, CE_CONT, "Begin MAC dump\n");
353 
354 	for (i = 0; i < NUM_REGS; i++) {
355 		e1000g_log(Adapter, CE_CONT,
356 		    "macreg %10s offset: 0x%x   value: 0x%x\n",
357 		    macreg[i].name, macreg[i].offset,
358 		    e1000_read_reg(hw, macreg[i].offset));
359 	}
360 }
361 
362 void
363 pciconfig_dump(void *instance)
364 {
365 	struct e1000g *Adapter = (struct e1000g *)instance;
366 	ddi_acc_handle_t handle;
367 	uint8_t cap_ptr;
368 	uint8_t next_ptr;
369 	off_t offset;
370 
371 	handle = Adapter->osdep.cfg_handle;
372 
373 	e1000g_log(Adapter, CE_CONT, "Begin dump PCI config space\n");
374 
375 	e1000g_log(Adapter, CE_CONT,
376 	    "PCI_CONF_VENID:\t0x%x\n",
377 	    pci_config_get16(handle, PCI_CONF_VENID));
378 	e1000g_log(Adapter, CE_CONT,
379 	    "PCI_CONF_DEVID:\t0x%x\n",
380 	    pci_config_get16(handle, PCI_CONF_DEVID));
381 	e1000g_log(Adapter, CE_CONT,
382 	    "PCI_CONF_COMMAND:\t0x%x\n",
383 	    pci_config_get16(handle, PCI_CONF_COMM));
384 	e1000g_log(Adapter, CE_CONT,
385 	    "PCI_CONF_STATUS:\t0x%x\n",
386 	    pci_config_get16(handle, PCI_CONF_STAT));
387 	e1000g_log(Adapter, CE_CONT,
388 	    "PCI_CONF_REVID:\t0x%x\n",
389 	    pci_config_get8(handle, PCI_CONF_REVID));
390 	e1000g_log(Adapter, CE_CONT,
391 	    "PCI_CONF_PROG_CLASS:\t0x%x\n",
392 	    pci_config_get8(handle, PCI_CONF_PROGCLASS));
393 	e1000g_log(Adapter, CE_CONT,
394 	    "PCI_CONF_SUB_CLASS:\t0x%x\n",
395 	    pci_config_get8(handle, PCI_CONF_SUBCLASS));
396 	e1000g_log(Adapter, CE_CONT,
397 	    "PCI_CONF_BAS_CLASS:\t0x%x\n",
398 	    pci_config_get8(handle, PCI_CONF_BASCLASS));
399 	e1000g_log(Adapter, CE_CONT,
400 	    "PCI_CONF_CACHE_LINESZ:\t0x%x\n",
401 	    pci_config_get8(handle, PCI_CONF_CACHE_LINESZ));
402 	e1000g_log(Adapter, CE_CONT,
403 	    "PCI_CONF_LATENCY_TIMER:\t0x%x\n",
404 	    pci_config_get8(handle, PCI_CONF_LATENCY_TIMER));
405 	e1000g_log(Adapter, CE_CONT,
406 	    "PCI_CONF_HEADER_TYPE:\t0x%x\n",
407 	    pci_config_get8(handle, PCI_CONF_HEADER));
408 	e1000g_log(Adapter, CE_CONT,
409 	    "PCI_CONF_BIST:\t0x%x\n",
410 	    pci_config_get8(handle, PCI_CONF_BIST));
411 
412 	pciconfig_bar(Adapter, PCI_CONF_BASE0, "PCI_CONF_BASE0");
413 	pciconfig_bar(Adapter, PCI_CONF_BASE1, "PCI_CONF_BASE1");
414 	pciconfig_bar(Adapter, PCI_CONF_BASE2, "PCI_CONF_BASE2");
415 	pciconfig_bar(Adapter, PCI_CONF_BASE3, "PCI_CONF_BASE3");
416 	pciconfig_bar(Adapter, PCI_CONF_BASE4, "PCI_CONF_BASE4");
417 	pciconfig_bar(Adapter, PCI_CONF_BASE5, "PCI_CONF_BASE5");
418 
419 	e1000g_log(Adapter, CE_CONT,
420 	    "PCI_CONF_CIS:\t0x%x\n",
421 	    pci_config_get32(handle, PCI_CONF_CIS));
422 	e1000g_log(Adapter, CE_CONT,
423 	    "PCI_CONF_SUBVENID:\t0x%x\n",
424 	    pci_config_get16(handle, PCI_CONF_SUBVENID));
425 	e1000g_log(Adapter, CE_CONT,
426 	    "PCI_CONF_SUBSYSID:\t0x%x\n",
427 	    pci_config_get16(handle, PCI_CONF_SUBSYSID));
428 	e1000g_log(Adapter, CE_CONT,
429 	    "PCI_CONF_ROM:\t0x%x\n",
430 	    pci_config_get32(handle, PCI_CONF_ROM));
431 
432 	cap_ptr = pci_config_get8(handle, PCI_CONF_CAP_PTR);
433 
434 	e1000g_log(Adapter, CE_CONT,
435 	    "PCI_CONF_CAP_PTR:\t0x%x\n", cap_ptr);
436 	e1000g_log(Adapter, CE_CONT,
437 	    "PCI_CONF_ILINE:\t0x%x\n",
438 	    pci_config_get8(handle, PCI_CONF_ILINE));
439 	e1000g_log(Adapter, CE_CONT,
440 	    "PCI_CONF_IPIN:\t0x%x\n",
441 	    pci_config_get8(handle, PCI_CONF_IPIN));
442 	e1000g_log(Adapter, CE_CONT,
443 	    "PCI_CONF_MIN_G:\t0x%x\n",
444 	    pci_config_get8(handle, PCI_CONF_MIN_G));
445 	e1000g_log(Adapter, CE_CONT,
446 	    "PCI_CONF_MAX_L:\t0x%x\n",
447 	    pci_config_get8(handle, PCI_CONF_MAX_L));
448 
449 	/* Power Management */
450 	offset = cap_ptr;
451 
452 	e1000g_log(Adapter, CE_CONT,
453 	    "PCI_PM_CAP_ID:\t0x%x\n",
454 	    pci_config_get8(handle, offset));
455 
456 	next_ptr = pci_config_get8(handle, offset + 1);
457 
458 	e1000g_log(Adapter, CE_CONT,
459 	    "PCI_PM_NEXT_PTR:\t0x%x\n", next_ptr);
460 	e1000g_log(Adapter, CE_CONT,
461 	    "PCI_PM_CAP:\t0x%x\n",
462 	    pci_config_get16(handle, offset + PCI_PMCAP));
463 	e1000g_log(Adapter, CE_CONT,
464 	    "PCI_PM_CSR:\t0x%x\n",
465 	    pci_config_get16(handle, offset + PCI_PMCSR));
466 	e1000g_log(Adapter, CE_CONT,
467 	    "PCI_PM_CSR_BSE:\t0x%x\n",
468 	    pci_config_get8(handle, offset + PCI_PMCSR_BSE));
469 	e1000g_log(Adapter, CE_CONT,
470 	    "PCI_PM_DATA:\t0x%x\n",
471 	    pci_config_get8(handle, offset + PCI_PMDATA));
472 
473 	/* MSI Configuration */
474 	offset = next_ptr;
475 
476 	e1000g_log(Adapter, CE_CONT,
477 	    "PCI_MSI_CAP_ID:\t0x%x\n",
478 	    pci_config_get8(handle, offset));
479 
480 	next_ptr = pci_config_get8(handle, offset + 1);
481 
482 	e1000g_log(Adapter, CE_CONT,
483 	    "PCI_MSI_NEXT_PTR:\t0x%x\n", next_ptr);
484 	e1000g_log(Adapter, CE_CONT,
485 	    "PCI_MSI_CTRL:\t0x%x\n",
486 	    pci_config_get16(handle, offset + PCI_MSI_CTRL));
487 	e1000g_log(Adapter, CE_CONT,
488 	    "PCI_MSI_ADDR:\t0x%x\n",
489 	    pci_config_get32(handle, offset + PCI_MSI_ADDR_OFFSET));
490 	e1000g_log(Adapter, CE_CONT,
491 	    "PCI_MSI_ADDR_HI:\t0x%x\n",
492 	    pci_config_get32(handle, offset + 0x8));
493 	e1000g_log(Adapter, CE_CONT,
494 	    "PCI_MSI_DATA:\t0x%x\n",
495 	    pci_config_get16(handle, offset + 0xC));
496 
497 	/* PCI Express Configuration */
498 	offset = next_ptr;
499 
500 	e1000g_log(Adapter, CE_CONT,
501 	    "PCIE_CAP_ID:\t0x%x\n",
502 	    pci_config_get8(handle, offset + PCIE_CAP_ID));
503 
504 	next_ptr = pci_config_get8(handle, offset + PCIE_CAP_NEXT_PTR);
505 
506 	e1000g_log(Adapter, CE_CONT,
507 	    "PCIE_CAP_NEXT_PTR:\t0x%x\n", next_ptr);
508 	e1000g_log(Adapter, CE_CONT,
509 	    "PCIE_PCIECAP:\t0x%x\n",
510 	    pci_config_get16(handle, offset + PCIE_PCIECAP));
511 	e1000g_log(Adapter, CE_CONT,
512 	    "PCIE_DEVCAP:\t0x%x\n",
513 	    pci_config_get32(handle, offset + PCIE_DEVCAP));
514 	e1000g_log(Adapter, CE_CONT,
515 	    "PCIE_DEVCTL:\t0x%x\n",
516 	    pci_config_get16(handle, offset + PCIE_DEVCTL));
517 	e1000g_log(Adapter, CE_CONT,
518 	    "PCIE_DEVSTS:\t0x%x\n",
519 	    pci_config_get16(handle, offset + PCIE_DEVSTS));
520 	e1000g_log(Adapter, CE_CONT,
521 	    "PCIE_LINKCAP:\t0x%x\n",
522 	    pci_config_get32(handle, offset + PCIE_LINKCAP));
523 	e1000g_log(Adapter, CE_CONT,
524 	    "PCIE_LINKCTL:\t0x%x\n",
525 	    pci_config_get16(handle, offset + PCIE_LINKCTL));
526 	e1000g_log(Adapter, CE_CONT,
527 	    "PCIE_LINKSTS:\t0x%x\n",
528 	    pci_config_get16(handle, offset + PCIE_LINKSTS));
529 }
530 
531 void
532 pciconfig_bar(void *instance, uint32_t offset, char *name)
533 {
534 	struct e1000g *Adapter = (struct e1000g *)instance;
535 	ddi_acc_handle_t handle = Adapter->osdep.cfg_handle;
536 	uint32_t base = pci_config_get32(handle, offset);
537 	uint16_t comm = pci_config_get16(handle, PCI_CONF_COMM);
538 	uint32_t size;		/* derived size of the region */
539 	uint32_t bits_comm;	/* command word bits to disable */
540 	uint32_t size_mask;	/* mask for size extraction */
541 	char tag_type[32];	/* tag to show memory vs. i/o */
542 	char tag_mem[32];	/* tag to show memory characteristiccs */
543 
544 	/* base address zero, simple print */
545 	if (base == 0) {
546 		e1000g_log(Adapter, CE_CONT, "%s:\t0x%x\n", name, base);
547 
548 	/* base address non-zero, get size */
549 	} else {
550 		/* i/o factors that decode from the base address */
551 		if (base & PCI_BASE_SPACE_IO) {
552 			bits_comm = PCI_COMM_IO;
553 			size_mask = PCI_BASE_IO_ADDR_M;
554 			strcpy(tag_type, "i/o port size:");
555 			strcpy(tag_mem, "");
556 		/* memory factors that decode from the base address */
557 		} else {
558 			bits_comm = PCI_COMM_MAE;
559 			size_mask = PCI_BASE_M_ADDR_M;
560 			strcpy(tag_type, "memory size:");
561 			if (base & PCI_BASE_TYPE_ALL)
562 				strcpy(tag_mem, "64bit ");
563 			else
564 				strcpy(tag_mem, "32bit ");
565 			if (base & PCI_BASE_PREF_M)
566 				strcat(tag_mem, "prefetchable");
567 			else
568 				strcat(tag_mem, "non-prefetchable");
569 		}
570 
571 		/* disable memory decode */
572 		pci_config_put16(handle, PCI_CONF_COMM, (comm & ~bits_comm));
573 
574 		/* write to base register */
575 		pci_config_put32(handle, offset, 0xffffffff);
576 
577 		/* read back & compute size */
578 		size = pci_config_get32(handle, offset);
579 		size &= size_mask;
580 		size = (~size) + 1;
581 
582 		/* restore base register */
583 		pci_config_put32(handle, offset, base);
584 
585 		/* re-enable memory decode */
586 		pci_config_put16(handle, PCI_CONF_COMM, comm);
587 
588 		/* print results */
589 		e1000g_log(Adapter, CE_CONT, "%s:\t0x%x %s 0x%x %s\n",
590 		    name, base, tag_type, size, tag_mem);
591 	}
592 }
593 #endif
594