changeset 5060:222c7d448cfc

6505251 NIU FMA needs to diagnose XAUI and XFP faults 6558331 Should add detailed error info to ddi_fm_ereport_post 6559504 nxge_ipp_eccue_valid_check causes FMA errors 6562470 fm capabilities passed to ddi_fm_init should be set properly 6564290 Unused function nxge_fm_npi_error_handler should be deleted 6579032 When jumbo frame is enabled, nxge driver does not set the size of the incoming frame correctly. 6597303 XFP in the topology should be common instead of sun4v only 6597306 Fail to enumerate xaui and xfp when the the NIU is not nxge instance 0 or 1 6600077 _topo_init of xfp.c should return int intead of void
author yc148097
date Sun, 16 Sep 2007 21:47:51 -0700
parents 34cf4795eee2
children ea67f286dc7f
files deleted_files/usr/src/lib/fm/topo/modules/sun4v/xfp/Makefile deleted_files/usr/src/lib/fm/topo/modules/sun4v/xfp/xfp.c usr/src/cmd/fm/dicts/Makefile usr/src/cmd/fm/dicts/NXGE.dict usr/src/cmd/fm/dicts/NXGE.po usr/src/cmd/fm/eversholt/files/common/neptune_xaui.esc usr/src/cmd/fm/eversholt/files/common/neptune_xfp.esc usr/src/cmd/fm/eversholt/files/i386/Makefile usr/src/cmd/fm/eversholt/files/sparc/Makefile usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2niu_xaui.esc usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2niu_xfp.esc usr/src/lib/fm/topo/maps/Makefile usr/src/lib/fm/topo/maps/Makefile.map usr/src/lib/fm/topo/maps/common/xfp-hc-topology.xml usr/src/lib/fm/topo/maps/i386/Makefile usr/src/lib/fm/topo/maps/sparc/Makefile usr/src/lib/fm/topo/modules/common/Makefile usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c usr/src/lib/fm/topo/modules/common/pcibus/pcibus.h usr/src/lib/fm/topo/modules/common/xfp/Makefile usr/src/lib/fm/topo/modules/common/xfp/xfp.c usr/src/lib/fm/topo/modules/sun4v/Makefile usr/src/lib/fm/topo/modules/sun4v/niu/niu.c usr/src/lib/fm/topo/modules/sun4v/xfp/Makefile usr/src/lib/fm/topo/modules/sun4v/xfp/xfp.c usr/src/pkgdefs/SUNW0on/prototype_com usr/src/pkgdefs/SUNWfmd/prototype_com usr/src/pkgdefs/SUNWfmd/prototype_sparc usr/src/uts/common/io/nxge/npi/npi.h usr/src/uts/common/io/nxge/nxge_fm.c usr/src/uts/common/io/nxge/nxge_hw.c usr/src/uts/common/io/nxge/nxge_ipp.c usr/src/uts/common/io/nxge/nxge_rxdma.c usr/src/uts/common/sys/nxge/nxge_fm.h
diffstat 35 files changed, 1347 insertions(+), 605 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/lib/fm/topo/modules/sun4v/xfp/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,40 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MODULE = xfp
+ARCH = sun4v
+CLASS = arch
+XFPSRCS = xfp.c
+
+UTILDIR = ../xaui
+
+MODULESRCS = $(XFPSRCS)
+
+include ../../Makefile.plugin
+
+CPPFLAGS += -I$(UTILDIR)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/lib/fm/topo/modules/sun4v/xfp/xfp.c	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,216 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <string.h>
+#include <fm/topo_mod.h>
+#include <fm/topo_hc.h>
+#include <sys/fm/protocol.h>
+/*
+ * xfp.c
+ *	sun4v specific xfp enumerators
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	XFP_VERSION	TOPO_VERSION
+
+static int xfp_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
+		    topo_instance_t, void *, void *);
+
+static const topo_modops_t xfp_ops =
+	{ xfp_enum, NULL };
+
+const topo_modinfo_t xfp_info =
+	{XFP, FM_FMRI_SCHEME_HC, XFP_VERSION, &xfp_ops};
+
+static const topo_pgroup_info_t xfp_auth_pgroup = {
+	FM_FMRI_AUTHORITY,
+	TOPO_STABILITY_PRIVATE,
+	TOPO_STABILITY_PRIVATE,
+	1
+};
+
+/*ARGSUSED*/
+void
+_topo_init(topo_mod_t *mod, topo_version_t version)
+{
+	/*
+	 * Turn on module debugging output
+	 */
+	if (getenv("TOPOXFPDBG") != NULL)
+		topo_mod_setdebug(mod);
+	topo_mod_dprintf(mod, "initializing xfp enumerator\n");
+
+	if (topo_mod_register(mod, &xfp_info, TOPO_VERSION) < 0) {
+		topo_mod_dprintf(mod, "xfp registration failed: %s\n",
+		    topo_mod_errmsg(mod));
+		return; /* mod errno already set */
+	}
+	topo_mod_dprintf(mod, "xfp enum initd\n");
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	topo_mod_unregister(mod);
+}
+
+static tnode_t *
+xfp_tnode_create(topo_mod_t *mod, tnode_t *parent,
+    const char *name, topo_instance_t i, void *priv)
+{
+	int err;
+	nvlist_t *fmri;
+	tnode_t *ntn;
+	nvlist_t *auth = topo_mod_auth(mod, parent);
+
+	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
+	    NULL, auth, NULL, NULL, NULL);
+	nvlist_free(auth);
+
+	if (fmri == NULL) {
+		topo_mod_dprintf(mod,
+		    "Unable to make nvlist for %s bind: %s.\n",
+		    name, topo_mod_errmsg(mod));
+		return (NULL);
+	}
+
+	ntn = topo_node_bind(mod, parent, name, i, fmri);
+	nvlist_free(fmri);
+	if (ntn == NULL) {
+		topo_mod_dprintf(mod,
+		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
+		    topo_node_name(parent), topo_node_instance(parent),
+		    name, i,
+		    topo_strerror(topo_mod_errno(mod)));
+		return (NULL);
+	}
+
+	topo_node_setspecific(ntn, priv);
+	if (topo_pgroup_create(ntn, &xfp_auth_pgroup, &err) == 0) {
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_PRODUCT, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_CHASSIS, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_SERVER, &err);
+	}
+	return (ntn);
+}
+static int
+xfp_fru_set(topo_mod_t *mp, tnode_t *tn)
+{
+	nvlist_t *fmri;
+	int err, e;
+
+	if (topo_node_resource(tn, &fmri, &err) < 0 ||
+	    fmri == NULL) {
+		topo_mod_dprintf(mp, "FRU_fmri_set error: %s\n",
+		    topo_strerror(topo_mod_errno(mp)));
+		return (topo_mod_seterrno(mp, err));
+	}
+	e = topo_node_fru_set(tn, fmri, 0, &err);
+	nvlist_free(fmri);
+	if (e < 0)
+		return (topo_mod_seterrno(mp, err));
+	return (0);
+}
+static int
+xfp_label_set(topo_mod_t *mod, tnode_t *parent, tnode_t *node,
+	topo_instance_t n)
+{
+	char *label = NULL;
+	char *plabel = NULL;
+	const char *xfplabel = "/XFP";
+	int err, len;
+
+	if (topo_node_label(parent, &plabel, &err) != 0 ||
+	    plabel == NULL) {
+		return (-1);
+	}
+
+	len = strlen(plabel) + strlen(xfplabel) + 2;
+	label = topo_mod_alloc(mod, len);
+	(void) snprintf(label, len, "%s%s%d", plabel, xfplabel, n);
+	topo_mod_strfree(mod, plabel);
+
+	if (label != NULL) {
+		if (topo_prop_set_string(node, TOPO_PGROUP_PROTOCOL,
+		    TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label,
+		    &err) != 0) {
+			topo_mod_strfree(mod, label);
+			return (topo_mod_seterrno(mod, err));
+		}
+	}
+	topo_mod_free(mod, label, len);
+	return (0);
+}
+/*ARGSUSED*/
+static tnode_t *
+xfp_declare(tnode_t *parent, const char *name, topo_instance_t i,
+	void *priv, topo_mod_t *mod)
+{
+	tnode_t *ntn;
+	nvlist_t *fmri = NULL;
+	int e;
+
+	if ((ntn = xfp_tnode_create(mod, parent, name, i, NULL)) == NULL) {
+		topo_mod_dprintf(mod, "%s ntn = NULL\n", name);
+		return (NULL);
+	}
+
+	(void) xfp_fru_set(mod, ntn);
+
+	(void) xfp_label_set(mod, parent, ntn, i);
+	/* set ASRU to resource fmri */
+	if (topo_prop_get_fmri(ntn, TOPO_PGROUP_PROTOCOL,
+	    TOPO_PROP_RESOURCE, &fmri, &e) == 0)
+		(void) topo_node_asru_set(ntn, fmri, 0, &e);
+	nvlist_free(fmri);
+
+	return (ntn);
+}
+
+/*ARGSUSED*/
+static int
+xfp_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+	topo_instance_t min, topo_instance_t max, void *notused, void *data)
+{
+	if (strcmp(name, XFP) != 0) {
+		topo_mod_dprintf(mod,
+		    "Currently only know how to enumerate %s components.\n",
+		    XFP);
+		return (0);
+	}
+	if (xfp_declare(rnode, name, min, data, mod) == NULL)
+		return (-1);
+
+	return (0);
+}
--- a/usr/src/cmd/fm/dicts/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/cmd/fm/dicts/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -29,6 +29,7 @@
 common_DCNAMES = \
 	DISK \
 	FMD \
+	NXGE \
 	SUNOS \
 	PCI \
 	PCIEX \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/dicts/NXGE.dict	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,32 @@
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+#
+# DO NOT EDIT -- this file is generated by the Event Registry.
+#
+
+FMDICT: name=NXGE version=1 maxkey=1 dictid=0x4e58
+
+fault.io.n2.niu-xfp=0
+fault.io.n2.niu-xaui=1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/dicts/NXGE.po	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,59 @@
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+#
+# DO NOT EDIT -- this file is generated by the Event Registry.
+#
+#
+# code: NXGE-8000-0U
+# keys: fault.io.n2.niu-xfp
+#
+msgid "NXGE-8000-0U.type"
+msgstr "Fault"
+msgid "NXGE-8000-0U.severity"
+msgstr "Critical"
+msgid "NXGE-8000-0U.description"
+msgstr "The XFP optical transceiver is broken or missing.\n  Refer to %s for more information."
+msgid "NXGE-8000-0U.response"
+msgstr "The device instance will be disabled.\n"
+msgid "NXGE-8000-0U.impact"
+msgstr "Loss of services provided by the device instances\nassociated with this fault.\n"
+msgid "NXGE-8000-0U.action"
+msgstr "Check and make sure that the XFP optical transceiver\nis properly installed. If problem persists, schedule a repair\nprocedure to replace the affected device, which can be determined\nusing fmdump -v -u <EVENT_ID>\n"
+#
+# code: NXGE-8000-17
+# keys: fault.io.n2.niu-xaui
+#
+msgid "NXGE-8000-17.type"
+msgstr "Fault"
+msgid "NXGE-8000-17.severity"
+msgstr "Critical"
+msgid "NXGE-8000-17.description"
+msgstr "A fault in the XAUI component used for 10GbE networking. \n  Refer to %s for more information."
+msgid "NXGE-8000-17.response"
+msgstr "The device instance will be disabled.\n"
+msgid "NXGE-8000-17.impact"
+msgstr "Loss of services provided by the device instances\nassociated with this fault.\n"
+msgid "NXGE-8000-17.action"
+msgstr "Schedule a repair procedure for the affected device, which\ncan be determined using fmdump -v -u <EVENT_ID>\n"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/eversholt/files/common/neptune_xaui.esc	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma	ident	"%Z%%M%	%I%	%E% SMI"
+
+#pragma	dictionary "NXGE"
+/*
+ * Eversholt rules for a XAUI card inserted in a PCI-Express slot. 
+ */
+
+#define	PCIEX_DEV_FIT	1000
+
+asru pciexbus/pciexdev/pciexfn;
+fru pciexbus/pciexdev;
+
+event fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn,
+    FITrate=PCIEX_DEV_FIT, FRU=pciexbus/pciexdev,
+    ASRU=pciexbus/pciexdev/pciexfn;
+
+event error.io.device.nxge.xaui-err@pciexbus/pciexdev/pciexfn;
+event ereport.io.device.nxge.xaui-err@pciexbus/pciexdev/pciexfn {within(10s)};
+event ereport.io.service.lost@pciexbus/pciexdev/pciexfn {within(10s)};
+
+prop fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn (0) ->
+    error.io.device.nxge.xaui-err@pciexbus/pciexdev/pciexfn;
+
+prop error.io.device.nxge.xaui-err@pciexbus/pciexdev/pciexfn (2) ->
+     ereport.io.device.nxge.xaui-err@pciexbus/pciexdev/pciexfn,
+     ereport.io.service.lost@pciexbus/pciexdev/pciexfn;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/eversholt/files/common/neptune_xfp.esc	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#pragma dictionary "NXGE"
+
+/*
+ * Eversholt rules for the XFP optical transceiver inserted into 
+ * a Neptune based NIC card.
+ */
+
+#define	XFP_FIT	100
+
+asru pciexbus/pciexdev/pciexfn;
+fru  pciexbus/pciexdev/pciexfn/xfp;
+
+event fault.io.n2.niu-xfp@pciexbus/pciexdev/pciexfn/xfp
+    FITrate=XFP_FIT,  FRU=pciexbus/pciexdev/pciexfn/xfp,
+    ASRU=pciexbus/pciexdev/pciexfn;
+
+/*
+ * Add 5 seconds constraint so that multiple identical ereports
+ * occuring within 10 seconds are considered symptoms of a single fault
+ */
+event   error.io.device.nxge.xfp-err@pciexbus/pciexdev/pciexfn;
+event ereport.io.device.nxge.xfp-err@pciexbus/pciexdev/pciexfn {within(10s)};
+event ereport.io.service.lost@pciexbus/pciexdev/pciexfn {within(10s)};
+
+/*
+ * Events ereport.io.device.nxge.xfp-err and ereport.io.service.lost are 
+ * related because the driver calls ddi_fm_service_impact right after
+ * generating the xfp-err ereport. A internal error.io.device.nxge.xfp-err
+ * is generated only after the FMD has received both ereport.io.device.
+ * nxge.xfp-err and ereport.io.service.lost, then the error event will
+ * trigger fault.io.n2.niu-xfp.  Based on the following rules, the diagnose
+ * engine will generate only one fault (fault.io.n2.niu-xfp) instead of two
+ * (associated with ereport.io.device.nxge.xfp-err and  ereport.io.service.lost
+ * respectively).
+ */
+prop fault.io.n2.niu-xfp@pciexbus/pciexdev/pciexfn/xfp (1) ->
+    error.io.device.nxge.xfp-err@pciexbus/pciexdev/pciexfn;
+
+prop   error.io.device.nxge.xfp-err@pciexbus/pciexdev/pciexfn (2) ->
+     ereport.io.device.nxge.xfp-err@pciexbus/pciexdev/pciexfn,
+     ereport.io.service.lost@pciexbus/pciexdev/pciexfn;
--- a/usr/src/cmd/fm/eversholt/files/i386/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/cmd/fm/eversholt/files/i386/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -25,7 +25,7 @@
 #ident	"%Z%%M%	%I%	%E% SMI"
 
 SUBDIRS=i86pc
-EFT_COMMON_FILES= pci.eft pciex.eft sca500.eft sca1000.eft disk.eft
+EFT_COMMON_FILES= pci.eft pciex.eft sca500.eft sca1000.eft disk.eft neptune_xfp.eft neptune_xaui.eft
 
 include ../../../Makefile.subdirs
 
--- a/usr/src/cmd/fm/eversholt/files/sparc/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -25,7 +25,7 @@
 #ident	"%Z%%M%	%I%	%E% SMI"
 
 SUBDIRS=sun4u sun4v SUNW,Sun-Fire-15000
-EFT_COMMON_FILES= pci.eft pciex.eft sca500.eft sca1000.eft disk.eft
+EFT_COMMON_FILES= pci.eft pciex.eft sca500.eft sca1000.eft disk.eft neptune_xfp.eft neptune_xaui.eft
 
 include ../../../Makefile.subdirs
 
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -28,7 +28,7 @@
 include ../sun4/Makefile.sun4
 
 EFT_PLAT= sun4v
-SUN4VEFTFILES= n2piu.eft vfncx.eft
+SUN4VEFTFILES= n2piu.eft vfncx.eft n2niu_xaui.eft n2niu_xfp.eft
 EFT_PLAT_FILES= $(SUN4VEFTFILES) $(SUN4EFTFILES)
 
 include ../../Makefile.com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2niu_xaui.esc	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma	ident	"%Z%%M%	%I%	%E% SMI"
+
+#pragma	dictionary "NXGE"
+/*
+ * Eversholt rules for a XAUI card connected to the NIU of Niagara2 CPU
+ */
+
+#define	XAUI_FIT	100
+
+asru niufn;
+fru xaui;
+
+event fault.io.n2.niu-xaui@niufn/xaui,
+    FITrate=XAUI_FIT, ASRU=niufn, FRU=xaui;
+
+event   error.io.device.nxge.xaui-err@niufn;
+event ereport.io.device.nxge.xaui-err@niufn {within(10s)};
+event ereport.io.service.lost@niufn {within(10s)};
+
+prop fault.io.n2.niu-xaui@niufn/xaui (1) ->
+        error.io.device.nxge.xaui-err@niufn;
+
+prop   error.io.device.nxge.xaui-err@niufn (2) ->
+     ereport.io.device.nxge.xaui-err@niufn,
+     ereport.io.service.lost@niufn;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2niu_xfp.esc	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#pragma dictionary "NXGE"
+/*
+ * Eversholt rules for the XFP optical module inserted in the XAUI card,
+ * which is connected to the NIU of the Niagara2 CPU
+ */
+
+#define	XFP_FIT	100
+
+asru niufn;
+fru xaui/xfp;
+
+event fault.io.n2.niu-xfp@niufn/xaui/xfp,
+    FITrate=XFP_FIT, ASRU=niufn, FRU=xaui/xfp;
+
+event   error.io.device.nxge.xfp-err@niufn;
+event ereport.io.device.nxge.xfp-err@niufn {within(10s)};
+event ereport.io.service.lost@niufn {within(10s)};
+
+
+prop  fault.io.n2.niu-xfp@niufn/xaui/xfp (1) ->
+      error.io.device.nxge.xfp-err@niufn;
+
+prop  error.io.device.nxge.xfp-err@niufn (2) ->
+    ereport.io.device.nxge.xfp-err@niufn,
+    ereport.io.service.lost@niufn;
+
--- a/usr/src/lib/fm/topo/maps/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/lib/fm/topo/maps/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -27,6 +27,7 @@
 
 sparc_SUBDIRS =	sun4u \
 		sun4v \
+		sparc \
 		SUNW,Sun-Fire \
 		SUNW,Sun-Fire-T200 \
 		SUNW,Sun-Fire-15000 \
@@ -38,6 +39,7 @@
 		SUNW,Netra-T5220
 
 i386_SUBDIRS = i86pc \
+		i386 \
 		SUNW,Sun-Fire-X4500
 
 SUBDIRS = $($(MACH)_SUBDIRS)
--- a/usr/src/lib/fm/topo/maps/Makefile.map	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/lib/fm/topo/maps/Makefile.map	Sun Sep 16 21:47:51 2007 -0700
@@ -55,7 +55,7 @@
 	$(RM) $@ 
 	$(PERL) $< -p $(PLATFORM) -i $(TOPOBASE) -o $@
 	
-.xml:
+%.xml: ../common/%.xml
 	$(RM) $@
 	$(CAT) $< > $@
 
@@ -65,6 +65,7 @@
 
 clean:
 	$(RM) $(ROOTTOPOMAPS)
+	$(RM) $(TEMPTOPOFILE)
 
 clobber: clean
 
@@ -79,4 +80,3 @@
 	$(RM) $@; $(INS) -s -m 0444 -f $(@D) $(DTDSRC)
 
 install: all $(ROOTDTDTARG) $(ROOTTOPOROOT) $(ROOTTOPOMAPS)
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/common/xfp-hc-topology.xml	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
+<!--
+ Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+	ident	"%Z%%M%	%I%	%E% SMI"
+-->
+
+<topology name='xfp' scheme='hc'>
+	<range name='xfp' min='0' max='0'>
+		<enum-method name='xfp' version='1' />
+	</range>
+</topology>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/i386/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+
+CLASS = common 
+DTDFILE = topology.dtd.1
+TOPOFILE = xfp-hc-topology.xml
+SRCDIR = ../i386
+
+# TEMPTOPOFILE is copied from ../common and deleted by "make clean"
+TEMPTOPOFILE = xfp-hc-topology.xml
+
+include ../Makefile.map
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/sparc/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+
+CLASS = common 
+DTDFILE = topology.dtd.1
+TOPOFILE = xfp-hc-topology.xml
+SRCDIR = ../sparc
+
+# TEMPTOPOFILE is copied from ../common and deleted by "make clean"
+TEMPTOPOFILE = xfp-hc-topology.xml
+
+include ../Makefile.map
--- a/usr/src/lib/fm/topo/modules/common/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -25,7 +25,7 @@
 #
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-SUBDIRS = disk
+SUBDIRS = disk xfp
 
 .PARALLEL: $(SUBDIRS)
 
--- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c	Sun Sep 16 21:47:51 2007 -0700
@@ -384,6 +384,7 @@
 	int dcnt = 0;
 	tnode_t *fn;
 	uint_t class, subclass;
+	uint_t vid, did;
 
 	if (*dev == NULL) {
 		if (rc >= 0)
@@ -419,9 +420,22 @@
 	 * topology map file and kick off its enumeration of lower-level
 	 * devices.
 	 */
-	if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI)
+	if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) {
 		(void) pci_bridge_declare(mod, fn, din, board, bridge, rc,
 		    depth);
+	}
+	/*
+	 * Use xfp-hc-topology.xml to expand topology to include the XFP optical
+	 * module, which is a FRU on the Neptune based 10giga fiber NICs.
+	 */
+	else if (class == PCI_CLASS_NET &&
+	    di_uintprop_get(mod, din, DI_VENDIDPROP, &vid) >= 0 &&
+	    di_uintprop_get(mod, din, DI_DEVIDPROP, &did) >= 0) {
+		if (vid == SUN_VENDOR_ID && did == NEPTUNE_DEVICE_ID) {
+			(void) topo_mod_enummap(mod, fn,
+			    "xfp", FM_FMRI_SCHEME_HC);
+		}
+	}
 }
 
 int
--- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.h	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.h	Sun Sep 16 21:47:51 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -58,6 +58,10 @@
 #define	MAX_PCIBUS_DEVS	32
 #define	MAX_PCIDEV_FNS	8
 
+/* vendor/device ids for Neptune */
+#define	SUN_VENDOR_ID		0x108e
+#define	NEPTUNE_DEVICE_ID	0xabcd
+
 #define	GETCLASS(x) (((x) & 0xff0000) >> 16)
 #define	GETSUBCLASS(x) (((x) & 0xff00) >> 8)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/common/xfp/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MODULE = xfp 
+CLASS = common
+
+MODULESRCS = xfp.c
+
+include ../../Makefile.plugin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/common/xfp/xfp.c	Sun Sep 16 21:47:51 2007 -0700
@@ -0,0 +1,217 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <string.h>
+#include <fm/topo_mod.h>
+#include <fm/topo_hc.h>
+#include <sys/fm/protocol.h>
+/*
+ * xfp.c
+ *	sun4v specific xfp enumerators
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	XFP_VERSION	TOPO_VERSION
+
+static int xfp_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
+		    topo_instance_t, void *, void *);
+
+static const topo_modops_t xfp_ops =
+	{ xfp_enum, NULL };
+
+const topo_modinfo_t xfp_info =
+	{XFP, FM_FMRI_SCHEME_HC, XFP_VERSION, &xfp_ops};
+
+static const topo_pgroup_info_t xfp_auth_pgroup = {
+	FM_FMRI_AUTHORITY,
+	TOPO_STABILITY_PRIVATE,
+	TOPO_STABILITY_PRIVATE,
+	1
+};
+
+/*ARGSUSED*/
+int
+_topo_init(topo_mod_t *mod, topo_version_t version)
+{
+	/*
+	 * Turn on module debugging output
+	 */
+	if (getenv("TOPOXFPDBG") != NULL)
+		topo_mod_setdebug(mod);
+	topo_mod_dprintf(mod, "initializing xfp enumerator\n");
+
+	if (topo_mod_register(mod, &xfp_info, TOPO_VERSION) < 0) {
+		topo_mod_dprintf(mod, "xfp registration failed: %s\n",
+		    topo_mod_errmsg(mod));
+		return (-1); /* mod errno already set */
+	}
+	topo_mod_dprintf(mod, "xfp enum initd\n");
+	return (0);
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	topo_mod_unregister(mod);
+}
+
+static tnode_t *
+xfp_tnode_create(topo_mod_t *mod, tnode_t *parent,
+    const char *name, topo_instance_t i, void *priv)
+{
+	int err;
+	nvlist_t *fmri;
+	tnode_t *ntn;
+	nvlist_t *auth = topo_mod_auth(mod, parent);
+
+	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
+	    NULL, auth, NULL, NULL, NULL);
+	nvlist_free(auth);
+
+	if (fmri == NULL) {
+		topo_mod_dprintf(mod,
+		    "Unable to make nvlist for %s bind: %s.\n",
+		    name, topo_mod_errmsg(mod));
+		return (NULL);
+	}
+
+	ntn = topo_node_bind(mod, parent, name, i, fmri);
+	nvlist_free(fmri);
+	if (ntn == NULL) {
+		topo_mod_dprintf(mod,
+		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
+		    topo_node_name(parent), topo_node_instance(parent),
+		    name, i,
+		    topo_strerror(topo_mod_errno(mod)));
+		return (NULL);
+	}
+
+	topo_node_setspecific(ntn, priv);
+	if (topo_pgroup_create(ntn, &xfp_auth_pgroup, &err) == 0) {
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_PRODUCT, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_CHASSIS, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_SERVER, &err);
+	}
+	return (ntn);
+}
+static int
+xfp_fru_set(topo_mod_t *mp, tnode_t *tn)
+{
+	nvlist_t *fmri;
+	int err, e;
+
+	if (topo_node_resource(tn, &fmri, &err) < 0 ||
+	    fmri == NULL) {
+		topo_mod_dprintf(mp, "FRU_fmri_set error: %s\n",
+		    topo_strerror(topo_mod_errno(mp)));
+		return (topo_mod_seterrno(mp, err));
+	}
+	e = topo_node_fru_set(tn, fmri, 0, &err);
+	nvlist_free(fmri);
+	if (e < 0)
+		return (topo_mod_seterrno(mp, err));
+	return (0);
+}
+static int
+xfp_label_set(topo_mod_t *mod, tnode_t *parent, tnode_t *node,
+	topo_instance_t n)
+{
+	char *label = NULL;
+	char *plabel = NULL;
+	const char *xfplabel = "/XFP";
+	int err, len;
+
+	if (topo_node_label(parent, &plabel, &err) != 0 ||
+	    plabel == NULL) {
+		return (-1);
+	}
+
+	len = strlen(plabel) + strlen(xfplabel) + 2;
+	label = topo_mod_alloc(mod, len);
+	(void) snprintf(label, len, "%s%s%d", plabel, xfplabel, n);
+	topo_mod_strfree(mod, plabel);
+
+	if (label != NULL) {
+		if (topo_prop_set_string(node, TOPO_PGROUP_PROTOCOL,
+		    TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label,
+		    &err) != 0) {
+			topo_mod_strfree(mod, label);
+			return (topo_mod_seterrno(mod, err));
+		}
+	}
+	topo_mod_free(mod, label, len);
+	return (0);
+}
+/*ARGSUSED*/
+static tnode_t *
+xfp_declare(tnode_t *parent, const char *name, topo_instance_t i,
+	void *priv, topo_mod_t *mod)
+{
+	tnode_t *ntn;
+	nvlist_t *fmri = NULL;
+	int e;
+
+	if ((ntn = xfp_tnode_create(mod, parent, name, i, NULL)) == NULL) {
+		topo_mod_dprintf(mod, "%s ntn = NULL\n", name);
+		return (NULL);
+	}
+
+	(void) xfp_fru_set(mod, ntn);
+
+	(void) xfp_label_set(mod, parent, ntn, i);
+	/* set ASRU to resource fmri */
+	if (topo_prop_get_fmri(ntn, TOPO_PGROUP_PROTOCOL,
+	    TOPO_PROP_RESOURCE, &fmri, &e) == 0)
+		(void) topo_node_asru_set(ntn, fmri, 0, &e);
+	nvlist_free(fmri);
+
+	return (ntn);
+}
+
+/*ARGSUSED*/
+static int
+xfp_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+	topo_instance_t min, topo_instance_t max, void *notused, void *data)
+{
+	if (strcmp(name, XFP) != 0) {
+		topo_mod_dprintf(mod,
+		    "Currently only know how to enumerate %s components.\n",
+		    XFP);
+		return (0);
+	}
+	if (xfp_declare(rnode, name, min, data, mod) == NULL)
+		return (-1);
+
+	return (0);
+}
--- a/usr/src/lib/fm/topo/modules/sun4v/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/sun4v/Makefile	Sun Sep 16 21:47:51 2007 -0700
@@ -25,7 +25,7 @@
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 
-SUBDIRS = chip hostbridge pcibus motherboard niu platform-cpu xaui xfp
+SUBDIRS = chip hostbridge pcibus motherboard niu platform-cpu xaui
 
 
 include ../../../Makefile.subdirs
--- a/usr/src/lib/fm/topo/modules/sun4v/niu/niu.c	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/sun4v/niu/niu.c	Sun Sep 16 21:47:51 2007 -0700
@@ -35,6 +35,7 @@
 #include <sys/param.h>
 #include <sys/systeminfo.h>
 #include <assert.h>
+#include <stdlib.h>
 
 /*
  * niu.c
@@ -287,7 +288,7 @@
 
 	sib = di_child_node(pnode);
 	while (sib != DI_NODE_NIL) {
-		inst = di_instance(sib);
+		inst = strtoul(di_bus_addr(sib), NULL, 10);
 		if ((ntn = niufn_declare(parent, NIUFN, inst, sib, mod))
 		    == NULL) {
 			topo_mod_dprintf(mod, "Enumeration of %s=%d "
--- a/usr/src/lib/fm/topo/modules/sun4v/xfp/Makefile	Sun Sep 16 18:09:52 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
-
-MODULE = xfp
-ARCH = sun4v
-CLASS = arch
-XFPSRCS = xfp.c
-
-UTILDIR = ../xaui
-
-MODULESRCS = $(XFPSRCS)
-
-include ../../Makefile.plugin
-
-CPPFLAGS += -I$(UTILDIR)
--- a/usr/src/lib/fm/topo/modules/sun4v/xfp/xfp.c	Sun Sep 16 18:09:52 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#include <string.h>
-#include <fm/topo_mod.h>
-#include <fm/topo_hc.h>
-#include <sys/fm/protocol.h>
-/*
- * xfp.c
- *	sun4v specific xfp enumerators
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define	XFP_VERSION	TOPO_VERSION
-
-static int xfp_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
-		    topo_instance_t, void *, void *);
-
-static const topo_modops_t xfp_ops =
-	{ xfp_enum, NULL };
-
-const topo_modinfo_t xfp_info =
-	{XFP, FM_FMRI_SCHEME_HC, XFP_VERSION, &xfp_ops};
-
-static const topo_pgroup_info_t xfp_auth_pgroup = {
-	FM_FMRI_AUTHORITY,
-	TOPO_STABILITY_PRIVATE,
-	TOPO_STABILITY_PRIVATE,
-	1
-};
-
-/*ARGSUSED*/
-void
-_topo_init(topo_mod_t *mod, topo_version_t version)
-{
-	/*
-	 * Turn on module debugging output
-	 */
-	if (getenv("TOPOXFPDBG") != NULL)
-		topo_mod_setdebug(mod);
-	topo_mod_dprintf(mod, "initializing xfp enumerator\n");
-
-	if (topo_mod_register(mod, &xfp_info, TOPO_VERSION) < 0) {
-		topo_mod_dprintf(mod, "xfp registration failed: %s\n",
-		    topo_mod_errmsg(mod));
-		return; /* mod errno already set */
-	}
-	topo_mod_dprintf(mod, "xfp enum initd\n");
-}
-
-void
-_topo_fini(topo_mod_t *mod)
-{
-	topo_mod_unregister(mod);
-}
-
-static tnode_t *
-xfp_tnode_create(topo_mod_t *mod, tnode_t *parent,
-    const char *name, topo_instance_t i, void *priv)
-{
-	int err;
-	nvlist_t *fmri;
-	tnode_t *ntn;
-	nvlist_t *auth = topo_mod_auth(mod, parent);
-
-	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
-	    NULL, auth, NULL, NULL, NULL);
-	nvlist_free(auth);
-
-	if (fmri == NULL) {
-		topo_mod_dprintf(mod,
-		    "Unable to make nvlist for %s bind: %s.\n",
-		    name, topo_mod_errmsg(mod));
-		return (NULL);
-	}
-
-	ntn = topo_node_bind(mod, parent, name, i, fmri);
-	nvlist_free(fmri);
-	if (ntn == NULL) {
-		topo_mod_dprintf(mod,
-		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
-		    topo_node_name(parent), topo_node_instance(parent),
-		    name, i,
-		    topo_strerror(topo_mod_errno(mod)));
-		return (NULL);
-	}
-
-	topo_node_setspecific(ntn, priv);
-	if (topo_pgroup_create(ntn, &xfp_auth_pgroup, &err) == 0) {
-		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
-		    FM_FMRI_AUTH_PRODUCT, &err);
-		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
-		    FM_FMRI_AUTH_CHASSIS, &err);
-		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
-		    FM_FMRI_AUTH_SERVER, &err);
-	}
-	return (ntn);
-}
-static int
-xfp_fru_set(topo_mod_t *mp, tnode_t *tn)
-{
-	nvlist_t *fmri;
-	int err, e;
-
-	if (topo_node_resource(tn, &fmri, &err) < 0 ||
-	    fmri == NULL) {
-		topo_mod_dprintf(mp, "FRU_fmri_set error: %s\n",
-		    topo_strerror(topo_mod_errno(mp)));
-		return (topo_mod_seterrno(mp, err));
-	}
-	e = topo_node_fru_set(tn, fmri, 0, &err);
-	nvlist_free(fmri);
-	if (e < 0)
-		return (topo_mod_seterrno(mp, err));
-	return (0);
-}
-static int
-xfp_label_set(topo_mod_t *mod, tnode_t *parent, tnode_t *node,
-	topo_instance_t n)
-{
-	char *label = NULL;
-	char *plabel = NULL;
-	const char *xfplabel = "/XFP";
-	int err, len;
-
-	if (topo_node_label(parent, &plabel, &err) != 0 ||
-	    plabel == NULL) {
-		return (-1);
-	}
-
-	len = strlen(plabel) + strlen(xfplabel) + 2;
-	label = topo_mod_alloc(mod, len);
-	(void) snprintf(label, len, "%s%s%d", plabel, xfplabel, n);
-	topo_mod_strfree(mod, plabel);
-
-	if (label != NULL) {
-		if (topo_prop_set_string(node, TOPO_PGROUP_PROTOCOL,
-		    TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label,
-		    &err) != 0) {
-			topo_mod_strfree(mod, label);
-			return (topo_mod_seterrno(mod, err));
-		}
-	}
-	topo_mod_free(mod, label, len);
-	return (0);
-}
-/*ARGSUSED*/
-static tnode_t *
-xfp_declare(tnode_t *parent, const char *name, topo_instance_t i,
-	void *priv, topo_mod_t *mod)
-{
-	tnode_t *ntn;
-	nvlist_t *fmri = NULL;
-	int e;
-
-	if ((ntn = xfp_tnode_create(mod, parent, name, i, NULL)) == NULL) {
-		topo_mod_dprintf(mod, "%s ntn = NULL\n", name);
-		return (NULL);
-	}
-
-	(void) xfp_fru_set(mod, ntn);
-
-	(void) xfp_label_set(mod, parent, ntn, i);
-	/* set ASRU to resource fmri */
-	if (topo_prop_get_fmri(ntn, TOPO_PGROUP_PROTOCOL,
-	    TOPO_PROP_RESOURCE, &fmri, &e) == 0)
-		(void) topo_node_asru_set(ntn, fmri, 0, &e);
-	nvlist_free(fmri);
-
-	return (ntn);
-}
-
-/*ARGSUSED*/
-static int
-xfp_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
-	topo_instance_t min, topo_instance_t max, void *notused, void *data)
-{
-	if (strcmp(name, XFP) != 0) {
-		topo_mod_dprintf(mod,
-		    "Currently only know how to enumerate %s components.\n",
-		    XFP);
-		return (0);
-	}
-	if (xfp_declare(rnode, name, min, data, mod) == NULL)
-		return (-1);
-
-	return (0);
-}
--- a/usr/src/pkgdefs/SUNW0on/prototype_com	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/pkgdefs/SUNW0on/prototype_com	Sun Sep 16 21:47:51 2007 -0700
@@ -46,6 +46,7 @@
 f none usr/lib/locale/C/LC_MESSAGES/AMD.po               644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/DISK.po              644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/FMD.po               644 root bin
+f none usr/lib/locale/C/LC_MESSAGES/NXGE.po              644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/SCF.po               644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/SUN4.po              644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/SUN4U.po             644 root bin
--- a/usr/src/pkgdefs/SUNWfmd/prototype_com	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_com	Sun Sep 16 21:47:51 2007 -0700
@@ -50,12 +50,15 @@
 d none usr/lib/fm/dict 755 root bin
 f none usr/lib/fm/dict/DISK.dict 444 root bin
 f none usr/lib/fm/dict/FMD.dict 444 root bin
+f none usr/lib/fm/dict/NXGE.dict 444 root bin
 f none usr/lib/fm/dict/SUNOS.dict 444 root bin
 f none usr/lib/fm/dict/PCI.dict 444 root bin
 f none usr/lib/fm/dict/ZFS.dict 444 root bin
 f none usr/lib/fm/dict/PCIEX.dict 444 root bin
 d none usr/lib/fm/eft 755 root bin
 f none usr/lib/fm/eft/disk.eft 444 root bin
+f none usr/lib/fm/eft/neptune_xaui.eft 444 root bin
+f none usr/lib/fm/eft/neptune_xfp.eft 444 root bin
 f none usr/lib/fm/eft/pci.eft 444 root bin
 f none usr/lib/fm/eft/pciex.eft 444 root bin
 d none usr/lib/fm/fmd 755 root bin
@@ -125,13 +128,17 @@
 f none usr/lib/fm/llib-ltopo 644 root bin
 f none usr/lib/fm/llib-ltopo.ln 644 root bin
 d none usr/lib/fm/topo 755 root bin
+d none usr/lib/fm/topo/maps 755 root bin
+f none usr/lib/fm/topo/maps/xfp-hc-topology.xml 444 root bin
 d none usr/lib/fm/topo/plugins 755 root bin
 f none usr/lib/fm/topo/plugins/disk.so 555 root bin
+f none usr/lib/fm/topo/plugins/xfp.so 555 root bin
 d none usr/lib/locale 755 root bin
 d none usr/lib/locale/C 755 root bin
 d none usr/lib/locale/C/LC_MESSAGES 755 root bin
 f none usr/lib/locale/C/LC_MESSAGES/DISK.mo 444 root bin
 f none usr/lib/locale/C/LC_MESSAGES/FMD.mo 444 root bin
+f none usr/lib/locale/C/LC_MESSAGES/NXGE.mo 444 root bin
 f none usr/lib/locale/C/LC_MESSAGES/SUNOS.mo 444 root bin
 f none usr/lib/locale/C/LC_MESSAGES/PCI.mo 444 root bin
 f none usr/lib/locale/C/LC_MESSAGES/ZFS.mo 444 root bin
--- a/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Sun Sep 16 21:47:51 2007 -0700
@@ -117,6 +117,8 @@
 d none usr/platform/sun4v/lib/fm 755 root bin
 d none usr/platform/sun4v/lib/fm/eft 755 root bin
 f none usr/platform/sun4v/lib/fm/eft/fire.eft 444 root bin
+f none usr/platform/sun4v/lib/fm/eft/n2niu_xaui.eft 444 root bin
+f none usr/platform/sun4v/lib/fm/eft/n2niu_xfp.eft 444 root bin
 f none usr/platform/sun4v/lib/fm/eft/n2piu.eft 444 root bin
 f none usr/platform/sun4v/lib/fm/eft/vfncx.eft 444 root bin
 d none usr/platform/sun4v/lib/fm/fmd 755 root bin
@@ -138,7 +140,6 @@
 f none usr/platform/sun4v/lib/fm/topo/plugins/motherboard.so 555 root bin
 f none usr/platform/sun4v/lib/fm/topo/plugins/niu.so 555 root bin
 f none usr/platform/sun4v/lib/fm/topo/plugins/xaui.so 555 root bin
-f none usr/platform/sun4v/lib/fm/topo/plugins/xfp.so 555 root bin
 d none usr/platform/SUNW,SPARC-Enterprise 755 root sys
 d none usr/platform/SUNW,SPARC-Enterprise/lib 755 root bin
 d none usr/platform/SUNW,SPARC-Enterprise/lib/fm 755 root bin
--- a/usr/src/uts/common/io/nxge/npi/npi.h	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/uts/common/io/nxge/npi/npi.h	Sun Sep 16 21:47:51 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -53,6 +53,8 @@
 #define	ETHER_SERDES_BLK_ID		0xd
 #define	PCIE_SERDES_BLK_ID		0xe
 #define	VIR_BLK_ID			0xf
+#define	XAUI_BLK_ID			0x10
+#define	XFP_BLK_ID			0x11
 
 /* Common HW error code */
 /* HW unable to exit from reset state. */
--- a/usr/src/uts/common/io/nxge/nxge_fm.c	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_fm.c	Sun Sep 16 21:47:51 2007 -0700
@@ -34,6 +34,9 @@
 static nxge_fm_ereport_attr_t
 *nxge_fm_get_ereport_attr(nxge_fm_ereport_id_t);
 
+static int
+nxge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data);
+
 nxge_fm_ereport_attr_t	nxge_fm_ereport_pcs[] = {
 	{NXGE_FM_EREPORT_XPCS_LINK_DOWN,	"10g_link_down",
 						DDI_FM_DEVICE_INVAL_STATE,
@@ -317,6 +320,18 @@
 						DDI_SERVICE_LOST},
 };
 
+nxge_fm_ereport_attr_t nxge_fm_ereport_xaui[] = {
+	{NXGE_FM_EREPORT_XAUI_ERR,		"xaui_bad_or_missing",
+						NXGE_FM_DEVICE_XAUI_ERR,
+						DDI_SERVICE_LOST},
+};
+
+nxge_fm_ereport_attr_t nxge_fm_ereport_xfp[] = {
+	{NXGE_FM_EREPORT_XFP_ERR,		"xfp_bad_or_missing",
+						NXGE_FM_DEVICE_XFP_ERR,
+						DDI_SERVICE_LOST},
+};
+
 nxge_fm_ereport_attr_t nxge_fm_ereport_sw[] = {
 	{NXGE_FM_EREPORT_SW_INVALID_PORT_NUM,	"invalid_port_num",
 						DDI_FM_DEVICE_INVAL_STATE,
@@ -331,39 +346,71 @@
 
 void
 nxge_fm_init(p_nxge_t nxgep, ddi_device_acc_attr_t *reg_attr,
-		ddi_device_acc_attr_t *desc_attr, ddi_dma_attr_t *dma_attr)
+	ddi_device_acc_attr_t *desc_attr, ddi_dma_attr_t *dma_attr)
 {
 	ddi_iblock_cookie_t iblk;
 
+	/*
+	 * fm-capable in nxge.conf can be used to set fm_capabilities.
+	 * If fm-capable is not defined, then the last argument passed to
+	 * ddi_prop_get_int will be returned as the capabilities.
+	 */
 	nxgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, nxgep->dip,
-			DDI_PROP_DONTPASS, "fm-capable", 1);
+	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "fm-capable",
+	    DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE);
+
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL,
 		"FM capable = %d\n", nxgep->fm_capabilities));
 
-	/* Only register with IO Fault Services if we have some capability */
-	if (nxgep->fm_capabilities) {
-		reg_attr->devacc_attr_access = DDI_FLAGERR_ACC;
-		desc_attr->devacc_attr_access = DDI_FLAGERR_ACC;
-		dma_attr->dma_attr_flags |= DDI_DMA_FLAGERR;
-
-		/* Register capabilities with IO Fault Services */
+	/*
+	 * Register capabilities with IO Fault Services. The capabilities
+	 * set above may not be supported by the parent nexus, in that case
+	 * some capability bits may be cleared.
+	 */
+	if (nxgep->fm_capabilities)
 		ddi_fm_init(nxgep->dip, &nxgep->fm_capabilities, &iblk);
 
-		/*
-		 * Initialize pci ereport capabilities if ereport capable
-		 */
-		if (DDI_FM_EREPORT_CAP(nxgep->fm_capabilities) ||
-		    DDI_FM_ERRCB_CAP(nxgep->fm_capabilities))
-			pci_ereport_setup(nxgep->dip);
+	/*
+	 * Initialize pci ereport capabilities if ereport capable
+	 */
+	if (DDI_FM_EREPORT_CAP(nxgep->fm_capabilities) ||
+	    DDI_FM_ERRCB_CAP(nxgep->fm_capabilities)) {
+		pci_ereport_setup(nxgep->dip);
+	}
+
+	/* Register error callback if error callback capable */
+	if (DDI_FM_ERRCB_CAP(nxgep->fm_capabilities)) {
+		ddi_fm_handler_register(nxgep->dip,
+		    nxge_fm_error_cb, (void*) nxgep);
+	}
+
+	/*
+	 * DDI_FLGERR_ACC indicates:
+	 * o Driver will check its access handle(s) for faults on
+	 *   a regular basis by calling ddi_fm_acc_err_get
+	 * o Driver is able to cope with incorrect results of I/O
+	 *   operations resulted from an I/O fault
+	 */
+	if (DDI_FM_ACC_ERR_CAP(nxgep->fm_capabilities)) {
+		reg_attr->devacc_attr_access  = DDI_FLAGERR_ACC;
+		desc_attr->devacc_attr_access = DDI_FLAGERR_ACC;
 	} else {
-		/*
-		 * These fields have to be cleared of FMA if there are no
-		 * FMA capabilities at runtime.
-		 */
-		reg_attr->devacc_attr_access = DDI_DEFAULT_ACC;
+		reg_attr->devacc_attr_access  = DDI_DEFAULT_ACC;
 		desc_attr->devacc_attr_access = DDI_DEFAULT_ACC;
+	}
+
+	/*
+	 * DDI_DMA_FLAGERR indicates:
+	 * o Driver will check its DMA handle(s) for faults on a
+	 *   regular basis using ddi_fm_dma_err_get
+	 * o Driver is able to cope with incorrect results of DMA
+	 *   operations resulted from an I/O fault
+	 */
+	if (DDI_FM_DMA_ERR_CAP(nxgep->fm_capabilities))
+		dma_attr->dma_attr_flags |= DDI_DMA_FLAGERR;
+	else
 		dma_attr->dma_attr_flags &= ~DDI_DMA_FLAGERR;
-	}
+
 }
 
 void
@@ -390,143 +437,27 @@
 	}
 }
 
-void
-nxge_fm_npi_error_handler(p_nxge_t nxgep, npi_status_t status)
+/*ARGSUSED*/
+/*
+ * Simply call pci_ereport_post which generates ereports for errors
+ * that occur in the PCI local bus configuration status registers.
+ */
+static int
+nxge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err,
+	const void *impl_data)
 {
-	uint8_t			block_id;
-	uint8_t			error_type;
-	nxge_fm_ereport_id_t	fm_ereport_id;
-	nxge_fm_ereport_attr_t	*fm_ereport_attr;
-	char			*class_name;
-	uint64_t		ena;
-	uint8_t			portn = 0;
-	uint8_t			chan = 0;
-	boolean_t		is_port;
-	boolean_t		is_chan;
-
-	if (status == NPI_SUCCESS)
-		return;
-
-	block_id = (status >> NPI_BLOCK_ID_SHIFT) & 0xF;
-	error_type = status & 0xFF;
-	is_port = (status & IS_PORT)? B_TRUE: B_FALSE;
-	is_chan = (status & IS_CHAN)? B_TRUE: B_FALSE;
-
-	if (is_port)
-		portn = (status >> NPI_PORT_CHAN_SHIFT) & 0xF;
-	else if (is_chan)
-		chan = (status >> NPI_PORT_CHAN_SHIFT) & 0xF;
-
-	/* Map error type into FM ereport id */
-
-	/* Handle all software errors */
+	pci_ereport_post(dip, err, NULL);
+	return (err->fme_status);
+}
 
-	if (((error_type >= COMMON_SW_ERR_START) &&
-				(error_type <= COMMON_SW_ERR_END)) ||
-		((error_type >= BLK_SPEC_SW_ERR_START) &&
-				(error_type <= BLK_SPEC_SW_ERR_END))) {
-		switch (error_type) {
-		case PORT_INVALID:
-			fm_ereport_id = NXGE_FM_EREPORT_SW_INVALID_PORT_NUM;
-			break;
-		case CHANNEL_INVALID:
-			fm_ereport_id = NXGE_FM_EREPORT_SW_INVALID_CHAN_NUM;
-			break;
-		default:
-			fm_ereport_id = NXGE_FM_EREPORT_SW_INVALID_PARAM;
-		}
-	} else if (((error_type >= COMMON_HW_ERR_START) &&
-				(error_type <= COMMON_HW_ERR_END)) ||
-		((error_type >= BLK_SPEC_HW_ERR_START) &&
-				(error_type <= BLK_SPEC_SW_ERR_END))) {
-		/* Handle hardware errors */
-		switch (error_type) {
-		case RESET_FAILED:
-			switch (block_id) {
-			case TXMAC_BLK_ID:
-				fm_ereport_id =
-					NXGE_FM_EREPORT_TXMAC_RESET_FAIL;
-				break;
-			case RXMAC_BLK_ID:
-				fm_ereport_id =
-					NXGE_FM_EREPORT_RXMAC_RESET_FAIL;
-				break;
-			case IPP_BLK_ID:
-				fm_ereport_id = NXGE_FM_EREPORT_IPP_RESET_FAIL;
-				break;
-			case TXDMA_BLK_ID:
-				fm_ereport_id = NXGE_FM_EREPORT_TDMC_RESET_FAIL;
-				break;
-			default:
-				fm_ereport_id = NXGE_FM_EREPORT_UNKNOWN;
-			}
-			break;
-		case WRITE_FAILED:
-		case READ_FAILED:
-			switch (block_id) {
-			case MIF_BLK_ID:
-				fm_ereport_id = NXGE_FM_EREPORT_MIF_ACCESS_FAIL;
-				break;
-			case ZCP_BLK_ID:
-				fm_ereport_id = NXGE_FM_EREPORT_ZCP_ACCESS_FAIL;
-				break;
-			case ESPC_BLK_ID:
-				fm_ereport_id =
-					NXGE_FM_EREPORT_ESPC_ACCESS_FAIL;
-				break;
-			case FFLP_BLK_ID:
-				fm_ereport_id =
-					NXGE_FM_EREPORT_FFLP_ACCESS_FAIL;
-				break;
-			default:
-				fm_ereport_id = NXGE_FM_EREPORT_UNKNOWN;
-			}
-			break;
-		case TXDMA_HW_STOP_FAILED:
-		case TXDMA_HW_RESUME_FAILED:
-			fm_ereport_id = NXGE_FM_EREPORT_TDMC_RESET_FAIL;
-			break;
-		}
-	}
-
-	fm_ereport_attr = nxge_fm_get_ereport_attr(fm_ereport_id);
-	if (fm_ereport_attr == NULL)
-		return;
-	class_name = fm_ereport_attr->eclass;
-
-	ena = fm_ena_generate(0, FM_ENA_FMT1);
-
-	if ((is_port == B_FALSE) && (is_chan == B_FALSE)) {
-		ddi_fm_ereport_post(nxgep->dip, class_name, ena,
-			DDI_NOSLEEP,
-			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-			NULL);
-	} else if ((is_port == B_TRUE) && (is_chan == B_FALSE)) {
-		ddi_fm_ereport_post(nxgep->dip, class_name, ena, DDI_NOSLEEP,
-			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-			ERNAME_ERR_PORTN, DATA_TYPE_UINT8, portn,
-			NULL);
-	} else if ((is_port == B_FALSE) && (is_chan == B_TRUE)) {
-		ddi_fm_ereport_post(nxgep->dip, class_name, ena, DDI_NOSLEEP,
-			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-			ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, chan,
-			NULL);
-	} else if ((is_port == B_TRUE) && (is_chan == B_TRUE)) {
-		ddi_fm_ereport_post(nxgep->dip, class_name, ena, DDI_NOSLEEP,
-			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-			ERNAME_ERR_PORTN, DATA_TYPE_UINT8, portn,
-			ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, chan,
-			NULL);
-	}
-}
 
 static nxge_fm_ereport_attr_t *
 nxge_fm_get_ereport_attr(nxge_fm_ereport_id_t ereport_id)
 {
 	nxge_fm_ereport_attr_t *attr;
-	uint8_t	blk_id = ((ereport_id >> EREPORT_FM_ID_SHIFT) &
-							EREPORT_FM_ID_MASK);
-	uint8_t index = (ereport_id & EREPORT_INDEX_MASK);
+	uint8_t	blk_id = (ereport_id >> EREPORT_FM_ID_SHIFT) &
+	    EREPORT_FM_ID_MASK;
+	uint8_t index = ereport_id & EREPORT_INDEX_MASK;
 
 	switch (blk_id) {
 	case FM_SW_ID:
@@ -565,6 +496,12 @@
 	case FM_ESPC_ID:
 		attr = &nxge_fm_ereport_espc[index];
 		break;
+	case FM_XAUI_ID:
+		attr = &nxge_fm_ereport_xaui[index];
+		break;
+	case FM_XFP_ID:
+		attr = &nxge_fm_ereport_xfp[index];
+		break;
 	default:
 		attr = NULL;
 	}
@@ -595,84 +532,93 @@
 		case NXGE_FM_EREPORT_PCS_LINK_DOWN:
 		case NXGE_FM_EREPORT_PCS_REMOTE_FAULT:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_IPP_EOP_MISS:
 		case NXGE_FM_EREPORT_IPP_SOP_MISS:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_DFIFO_RD_PTR, DATA_TYPE_UINT16,
-					statsp->ipp_stats.errlog.dfifo_rd_ptr,
-				ERNAME_IPP_STATE_MACH, DATA_TYPE_UINT32,
-					statsp->ipp_stats.errlog.state_mach,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_DFIFO_RD_PTR, DATA_TYPE_UINT16,
+			    statsp->ipp_stats.errlog.dfifo_rd_ptr,
+			    ERNAME_IPP_STATE_MACH, DATA_TYPE_UINT32,
+			    statsp->ipp_stats.errlog.state_mach,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_IPP_DFIFO_UE:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_DFIFO_ENTRY, DATA_TYPE_UINT16,
-				nxgep->ipp.status.bits.w0.dfifo_ecc_err_idx,
-				ERNAME_DFIFO_SYNDROME, DATA_TYPE_UINT16,
-					statsp->ipp_stats.errlog.ecc_syndrome,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_DFIFO_ENTRY, DATA_TYPE_UINT16,
+			    nxgep->ipp.status.bits.w0.dfifo_ecc_err_idx,
+			    ERNAME_DFIFO_SYNDROME, DATA_TYPE_UINT16,
+			    statsp->ipp_stats.errlog.ecc_syndrome,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_IPP_PFIFO_PERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_PFIFO_ENTRY, DATA_TYPE_UINT8,
-				nxgep->ipp.status.bits.w0.pre_fifo_perr_idx,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_PFIFO_ENTRY, DATA_TYPE_UINT8,
+			    nxgep->ipp.status.bits.w0.pre_fifo_perr_idx,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_IPP_DFIFO_CE:
 		case NXGE_FM_EREPORT_IPP_ECC_ERR_MAX:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_IPP_PFIFO_OVER:
 		case NXGE_FM_EREPORT_IPP_PFIFO_UND:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_IPP_STATE_MACH, DATA_TYPE_UINT32,
-					statsp->ipp_stats.errlog.state_mach,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_IPP_STATE_MACH, DATA_TYPE_UINT32,
+			    statsp->ipp_stats.errlog.state_mach,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_IPP_BAD_CS_MX:
 		case NXGE_FM_EREPORT_IPP_PKT_DIS_MX:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_FFLP_TCAM_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_TCAM_ERR_LOG, DATA_TYPE_UINT32,
-					statsp->fflp_stats.errlog.tcam,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_TCAM_ERR_LOG, DATA_TYPE_UINT32,
+			    statsp->fflp_stats.errlog.tcam,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_VLANTAB_ERR_LOG, DATA_TYPE_UINT32,
-					statsp->fflp_stats.errlog.vlan,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_VLANTAB_ERR_LOG, DATA_TYPE_UINT32,
+			    statsp->fflp_stats.errlog.vlan,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR:
 		{
@@ -687,6 +633,8 @@
 						ena, DDI_NOSLEEP,
 						FM_VERSION, DATA_TYPE_UINT8,
 						FM_EREPORT_VERS0,
+						ERNAME_DETAILED_ERR_TYPE,
+						DATA_TYPE_STRING, err_str,
 						ERNAME_HASHTAB_ERR_LOG,
 						DATA_TYPE_UINT32,
 						nxgep->classifier.fflp_stats->
@@ -697,13 +645,14 @@
 			break;
 		case NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_HASHT_LOOKUP_ERR_LOG0, DATA_TYPE_UINT32,
-					statsp->fflp_stats.errlog. hash_lookup1,
-				ERNAME_HASHT_LOOKUP_ERR_LOG1, DATA_TYPE_UINT32,
-					statsp->fflp_stats.errlog.hash_lookup2,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_HASHT_LOOKUP_ERR_LOG0, DATA_TYPE_UINT32,
+			    statsp->fflp_stats.errlog. hash_lookup1,
+			    ERNAME_HASHT_LOOKUP_ERR_LOG1, DATA_TYPE_UINT32,
+			    statsp->fflp_stats.errlog.hash_lookup2,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_RDMC_DCF_ERR:
 		case NXGE_FM_EREPORT_RDMC_RBR_TMOUT:
@@ -722,11 +671,12 @@
 		case NXGE_FM_EREPORT_RDMC_ZCP_EOP_ERR:
 		case NXGE_FM_EREPORT_RDMC_IPP_EOP_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_RDMC_RBR_PRE_PAR:
 		case NXGE_FM_EREPORT_RDMC_RCR_SHA_PAR:
@@ -739,12 +689,13 @@
 				err_log = (uint32_t)statsp->
 				rdc_stats[err_chan].errlog.sha_par.value;
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
-				ERNAME_RDMC_PAR_ERR_LOG, DATA_TYPE_UINT8,
-				err_log, NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
+			    ERNAME_RDMC_PAR_ERR_LOG, DATA_TYPE_UINT8, err_log,
+			    NULL);
 			}
 			break;
 		case NXGE_FM_EREPORT_RDMC_COMPLETION_ERR:
@@ -753,12 +704,13 @@
 			err_type = statsp->
 				rdc_stats[err_chan].errlog.compl_err_type;
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
-				ERNAME_RDC_ERR_TYPE, DATA_TYPE_UINT8,
-				err_type, NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
+			    ERNAME_RDC_ERR_TYPE, DATA_TYPE_UINT8, err_type,
+			    NULL);
 			}
 			break;
 
@@ -770,19 +722,20 @@
 			sm = statsp->
 				zcp_stats.errlog.state_mach.bits.ldw.state;
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				sm, DATA_TYPE_UINT32,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    sm, DATA_TYPE_UINT32,
+			    NULL);
 			break;
 			}
 		case NXGE_FM_EREPORT_ZCP_CFIFO_ECC:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8,
-				err_portn,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR:
 		case NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR:
@@ -800,19 +753,21 @@
 		case NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP:
 		case NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_TDMC_MBOX_ERR:
 		case NXGE_FM_EREPORT_TDMC_TX_RING_OFLOW:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_TDMC_PREF_BUF_PAR_ERR:
 		case NXGE_FM_EREPORT_TDMC_NACK_PREF:
@@ -821,109 +776,107 @@
 		case NXGE_FM_EREPORT_TDMC_CONF_PART_ERR:
 		case NXGE_FM_EREPORT_TDMC_PKT_PRT_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
-				ERNAME_TDMC_ERR_LOG1, DATA_TYPE_UINT32,
-					statsp->
-					tdc_stats[err_chan].errlog.logl.value,
-				ERNAME_TDMC_ERR_LOG1, DATA_TYPE_UINT32,
-				statsp->tdc_stats[err_chan].errlog.logh.value,
-					DATA_TYPE_UINT32,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
+			    ERNAME_TDMC_ERR_LOG1, DATA_TYPE_UINT32,
+			    statsp->tdc_stats[err_chan].errlog.logl.value,
+			    ERNAME_TDMC_ERR_LOG1, DATA_TYPE_UINT32,
+			    statsp->tdc_stats[err_chan].errlog.logh.value,
+			    DATA_TYPE_UINT32,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR:
 		case NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_TXC_ROECC_ADDR, DATA_TYPE_UINT16,
-					statsp->txc_stats.errlog.ro_st.roecc.
-					bits.ldw.ecc_address,
-				ERNAME_TXC_ROECC_DATA0, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.ro_st.d0.
-					bits.ldw.ro_ecc_data0,
-				ERNAME_TXC_ROECC_DATA1, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.ro_st.d1.
-					bits.ldw.ro_ecc_data1,
-				ERNAME_TXC_ROECC_DATA2, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.ro_st.d2.
-					bits.ldw.ro_ecc_data2,
-				ERNAME_TXC_ROECC_DATA3, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.ro_st.d3.
-					bits.ldw.ro_ecc_data3,
-				ERNAME_TXC_ROECC_DATA4, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.ro_st.d4.
-					bits.ldw.ro_ecc_data4,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_TXC_ROECC_ADDR, DATA_TYPE_UINT16,
+			    statsp->txc_stats.errlog.ro_st.roecc.
+			    bits.ldw.ecc_address,
+			    ERNAME_TXC_ROECC_DATA0, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.ro_st.d0.
+			    bits.ldw.ro_ecc_data0,
+			    ERNAME_TXC_ROECC_DATA1, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.ro_st.d1.
+			    bits.ldw.ro_ecc_data1,
+			    ERNAME_TXC_ROECC_DATA2, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.ro_st.d2.
+			    bits.ldw.ro_ecc_data2,
+			    ERNAME_TXC_ROECC_DATA3, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.ro_st.d3.
+			    bits.ldw.ro_ecc_data3,
+			    ERNAME_TXC_ROECC_DATA4, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.ro_st.d4.
+			    bits.ldw.ro_ecc_data4,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_TXC_REORDER_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING,
-					err_str,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_TXC_RO_STATE0, DATA_TYPE_UINT32,
-					(uint32_t)statsp->
-					txc_stats.errlog.ro_st.st0.value,
-				ERNAME_TXC_RO_STATE1, DATA_TYPE_UINT32,
-					(uint32_t)statsp->
-					txc_stats.errlog.ro_st.st1.value,
-				ERNAME_TXC_RO_STATE2, DATA_TYPE_UINT32,
-					(uint32_t)statsp->
-					txc_stats.errlog.ro_st.st2.value,
-				ERNAME_TXC_RO_STATE3, DATA_TYPE_UINT32,
-					(uint32_t)statsp->
-					txc_stats.errlog.ro_st.st3.value,
-				ERNAME_TXC_RO_STATE_CTL, DATA_TYPE_UINT32,
-					(uint32_t)statsp->
-					txc_stats.errlog.ro_st.ctl.value,
-				ERNAME_TXC_RO_TIDS, DATA_TYPE_UINT32,
-					(uint32_t)statsp->
-					txc_stats.errlog.ro_st.tids.value,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_TXC_RO_STATE0, DATA_TYPE_UINT32,
+			    (uint32_t)statsp->txc_stats.errlog.ro_st.st0.value,
+			    ERNAME_TXC_RO_STATE1, DATA_TYPE_UINT32,
+			    (uint32_t)statsp->txc_stats.errlog.ro_st.st1.value,
+			    ERNAME_TXC_RO_STATE2, DATA_TYPE_UINT32,
+			    (uint32_t)statsp->txc_stats.errlog.ro_st.st2.value,
+			    ERNAME_TXC_RO_STATE3, DATA_TYPE_UINT32,
+			    (uint32_t)statsp->txc_stats.errlog.ro_st.st3.value,
+			    ERNAME_TXC_RO_STATE_CTL, DATA_TYPE_UINT32,
+			    (uint32_t)statsp->txc_stats.errlog.ro_st.ctl.value,
+			    ERNAME_TXC_RO_TIDS, DATA_TYPE_UINT32,
+			    (uint32_t)statsp->txc_stats.errlog.ro_st.tids.value,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR:
 		case NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				ERNAME_TXC_SFECC_ADDR, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.sf_st.sfecc.
-					bits.ldw.ecc_address,
-				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.sf_st.d0.
-					bits.ldw.sf_ecc_data0,
-				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.sf_st.d1.
-					bits.ldw.sf_ecc_data1,
-				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.sf_st.d2.
-					bits.ldw.sf_ecc_data2,
-				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.sf_st.d3.
-					bits.ldw.sf_ecc_data3,
-				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
-					statsp->txc_stats.errlog.sf_st.d4.
-					bits.ldw.sf_ecc_data4,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    ERNAME_TXC_SFECC_ADDR, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.sf_st.sfecc.
+			    bits.ldw.ecc_address,
+			    ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.sf_st.d0.
+			    bits.ldw.sf_ecc_data0,
+			    ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.sf_st.d1.
+			    bits.ldw.sf_ecc_data1,
+			    ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.sf_st.d2.
+			    bits.ldw.sf_ecc_data2,
+			    ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.sf_st.d3.
+			    bits.ldw.sf_ecc_data3,
+			    ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
+			    statsp->txc_stats.errlog.sf_st.d4.
+			    bits.ldw.sf_ecc_data4,
+			    NULL);
 			break;
 		case NXGE_FM_EREPORT_TXMAC_UNDERFLOW:
 		case NXGE_FM_EREPORT_TXMAC_OVERFLOW:
 		case NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR:
 		case NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR:
+		case NXGE_FM_EREPORT_XAUI_ERR:
+		case NXGE_FM_EREPORT_XFP_ERR:
 		case NXGE_FM_EREPORT_SW_INVALID_PORT_NUM:
 		case NXGE_FM_EREPORT_SW_INVALID_CHAN_NUM:
 		case NXGE_FM_EREPORT_SW_INVALID_PARAM:
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
-				DDI_NOSLEEP,
-				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
-				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
-				NULL);
+			    DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
+			    ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
+			    NULL);
 			break;
 		}
 
@@ -934,10 +887,9 @@
 nxge_fm_report_error(p_nxge_t nxgep, uint8_t err_portn, uint8_t err_chan,
 					nxge_fm_ereport_id_t fm_ereport_id)
 {
-	nxge_fm_ereport_attr_t	*fm_ereport_attr;
+	nxge_fm_ereport_attr_t		*fm_ereport_attr;
 
 	fm_ereport_attr = nxge_fm_get_ereport_attr(fm_ereport_id);
-
 	if (fm_ereport_attr != NULL) {
 		nxge_fm_ereport(nxgep, err_portn, err_chan, fm_ereport_attr);
 		ddi_fm_service_impact(nxgep->dip, fm_ereport_attr->impact);
--- a/usr/src/uts/common/io/nxge/nxge_hw.c	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_hw.c	Sun Sep 16 21:47:51 2007 -0700
@@ -50,6 +50,7 @@
 uint32_t nxge_lb_dbg = 1;
 void nxge_get_mii(p_nxge_t nxgep, p_mblk_t mp);
 void nxge_put_mii(p_nxge_t nxgep, p_mblk_t mp);
+static nxge_status_t nxge_check_xaui_xfp(p_nxge_t nxgep);
 
 extern uint32_t nxge_rx_mode;
 extern uint32_t nxge_jumbo_mtu;
@@ -261,6 +262,55 @@
 }
 
 /* ARGSUSED */
+static nxge_status_t
+nxge_check_xaui_xfp(p_nxge_t nxgep)
+{
+	nxge_status_t	status = NXGE_OK;
+	uint8_t		phy_port_addr;
+	uint16_t	val;
+	uint16_t	val1;
+	uint8_t		portn;
+
+	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_check_xaui_xfp"));
+
+	portn = nxgep->mac.portnum;
+	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
+
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR,
+	    BCM8704_USER_ANALOG_STATUS0_REG, &val)) == NXGE_OK) {
+		status = nxge_mdio_read(nxgep, phy_port_addr,
+		    BCM8704_USER_DEV3_ADDR,
+		    BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
+	}
+	if (status != NXGE_OK) {
+		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
+		    NXGE_FM_EREPORT_XAUI_ERR);
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+		    "XAUI is bad or absent on port<%d>\n", portn));
+	} else if (nxgep->mac.portmode == PORT_10G_FIBER) {
+		/*
+		 * 0x03FC = 0000 0011 1111 1100
+		 * 0x639C = 0110 0011 1001 1100
+		 * bit14 = 1: PDM loss-of-light indicator
+		 * bit13 = 1: PDM Rx loss-of-signal
+		 * bit6  = 0: Light is NOT ok
+		 * bit5  = 0: PMD Rx signal is NOT ok
+		 */
+		if (val != 0x3FC && val == 0x639C) {
+			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
+			    NXGE_FM_EREPORT_XFP_ERR);
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			    "XFP is bad or absent on port<%d>\n", portn));
+			status = NXGE_ERROR;
+		}
+	}
+	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_check_xaui_xfp"));
+	return (status);
+}
+
+
+/* ARGSUSED */
 uint_t
 nxge_syserr_intr(void *arg1, void *arg2)
 {
@@ -358,6 +408,15 @@
 			"==> nxge_syserr_intr: device error - FFLP"));
 		(void) nxge_fflp_handle_sys_errors(nxgep);
 	}
+
+	if (nxgep->mac.portmode == PORT_10G_FIBER ||
+	    nxgep->mac.portmode == PORT_10G_COPPER) {
+		if (nxge_check_xaui_xfp(nxgep) != NXGE_OK) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			    "==> nxge_syserr_intr: device error - XAUI"));
+		}
+	}
+
 	serviced = DDI_INTR_CLAIMED;
 
 	if (ldgp != NULL && ldvp != NULL && ldgp->nldvs == 1 &&
@@ -526,8 +585,9 @@
 			*(lb_info_sz_t *)mp->b_cont->b_rptr =
 				nxgep->statsp->port_stats.lb_mode;
 			miocack(wq, mp, sizeof (nxge_lb_t), 0);
-		} else
+		} else {
 			miocnak(wq, mp, 0, EINVAL);
+		}
 		break;
 	case LB_SET_MODE:
 		NXGE_DEBUG_MSG((nxgep, IOC_CTL, "NXGE_SET_LB_MODE command"));
--- a/usr/src/uts/common/io/nxge/nxge_ipp.c	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_ipp.c	Sun Sep 16 21:47:51 2007 -0700
@@ -615,7 +615,7 @@
 
 /* ARGSUSED */
 /*
- *    A hardware bug may cause a faked ECCUE(ECC Uncorrectable Error).
+ *    A hardware bug may cause faked ECCUEs (ECC Uncorrectable Error).
  * This function checks if a ECCUE is real(valid) or not.  It is not
  * real if rd_ptr == wr_ptr.
  *    The hardware module that has the bug is used not only by the IPP
@@ -651,6 +651,11 @@
 		*valid = B_FALSE; /* FIFO not stuck, so it's not a real ECCUE */
 	} else {
 		stall_cnt = 0;
+		/*
+		 * Check if the two pointers are moving, the ECCUE is invali
+		 * if either pointer is moving, which indicates that the FIFO
+		 * is functional.
+		 */
 		while (stall_cnt < 16) {
 			if ((rs = npi_ipp_get_dfifo_rd_ptr(handle,
 					portn, &curr_rd_ptr)) != NPI_SUCCESS)
@@ -659,19 +664,23 @@
 					portn, &curr_wr_ptr)) != NPI_SUCCESS)
 				goto fail;
 
-			if ((rd_ptr == curr_rd_ptr) && (wr_ptr == curr_wr_ptr))
+			if (rd_ptr == curr_rd_ptr && wr_ptr == curr_wr_ptr) {
 				stall_cnt++;
-			else {
+			} else {
 				*valid = B_FALSE;
 				break;
 			}
 		}
 
 		if (valid) {
-			/* futher check to see if ECC UE is valid */
-			if ((rs = npi_ipp_read_dfifo(handle, portn,
-					rd_ptr, &d0, &d1, &d2, &d3,
-					&d4)) != NPI_SUCCESS)
+			/*
+			 * Futher check to see if the ECCUE is valid. The
+			 * error is real if the LSB of d4 is 1, which
+			 * indicates that the data that has set the ECC
+			 * error flag is the 16-byte internal control word.
+			 */
+			if ((rs = npi_ipp_read_dfifo(handle, portn, rd_ptr,
+			    &d0, &d1, &d2, &d3, &d4)) != NPI_SUCCESS)
 				goto fail;
 			if ((d4 & 0x1) == 0)	/* Not the 1st line */
 				*valid = B_FALSE;
--- a/usr/src/uts/common/io/nxge/nxge_rxdma.c	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_rxdma.c	Sun Sep 16 21:47:51 2007 -0700
@@ -2475,6 +2475,9 @@
 		nxge_freeb(rx_msg_p);
 		return;
 	}
+
+	rcr_p->rcvd_pkt_bytes = bytes_read;
+
 	if (buffer_free == B_TRUE) {
 		rx_msg_p->free = B_TRUE;
 	}
--- a/usr/src/uts/common/sys/nxge/nxge_fm.h	Sun Sep 16 18:09:52 2007 -0700
+++ b/usr/src/uts/common/sys/nxge/nxge_fm.h	Sun Sep 16 21:47:51 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -81,6 +81,10 @@
 #define	EREPORT_INDEX_MASK		0xFF
 #define	NXGE_FM_EREPORT_UNKNOWN		0
 
+/* xaui and xfp ereport definitions */
+#define	NXGE_FM_DEVICE_XAUI_ERR		"nxge.xaui-err"
+#define	NXGE_FM_DEVICE_XFP_ERR		"nxge.xfp-err"
+
 #define	FM_SW_ID			0xFF
 #define	FM_PCS_ID			MAC_BLK_ID
 #define	FM_TXMAC_ID			TXMAC_BLK_ID
@@ -97,6 +101,8 @@
 #define	FM_ETHER_SERDES_ID		ETHER_SERDES_BLK_ID
 #define	FM_PCIE_SERDES_ID		PCIE_SERDES_BLK_ID
 #define	FM_VIR_ID			VIR_BLK_ID
+#define	FM_XAUI_ID			XAUI_BLK_ID
+#define	FM_XFP_ID			XFP_BLK_ID
 
 typedef	uint32_t nxge_fm_ereport_id_t;
 
@@ -239,6 +245,16 @@
 	NXGE_FM_EREPORT_SW_INVALID_PARAM
 } nxge_fm_ereport_sw_t;
 
+/* XAUI is broken or missing */
+typedef	enum {
+	NXGE_FM_EREPORT_XAUI_ERR = (FM_XAUI_ID << EREPORT_FM_ID_SHIFT)
+} nxge_fm_ereport_xaui_t;
+
+/* XFP optical module is broken or missing */
+typedef	enum {
+	NXGE_FM_EREPORT_XFP_ERR = (FM_XFP_ID << EREPORT_FM_ID_SHIFT)
+} nxge_fm_ereport_xfp_t;
+
 #define	NXGE_FM_EREPORT_UNKNOWN			0
 #define	NXGE_FM_EREPORT_UNKNOWN_NAME		""