changeset 4732:4edaffb4494b

6501667 ncp/n2cp drivers should not assume a static number of crypto units 6558981 Allow Errata 175 workaround to be fully enabled/disabled 6519970 Niagara crypto providers should recognize maramba specific device compatibility properties PSARC 2007/306 Victoria Falls IO FMA 6539545 Support new VF PIU errors 6556056 DE should consume ereport.io.n2.pec.lwc PSARC 2007/117 Maramba 1u/2u Platform Support 6531673 ON support for vf processor 6491129 psrinfo -pv doesn't report correct chip info on sun4v 6530592 Topo maps for maramba 6551884 Add nxge driver support for Maramba platforms 6560113 nxge driver should send message to console & /var/adm/messages when onboard port0 or 1 is disabled 6569931 Enhance sun4v trapstat to support at least 256 CPUs FWARC 2007/237 Victoria Falls Perf Regs HV API 6562095 Maramba system panics with send_mondo_set timeout while booting 6437543 sun4v NCPU update to 256
author davemq
date Wed, 25 Jul 2007 18:20:14 -0700
parents e202adc835b4
children 1966c7fad027
files usr/src/cmd/fm/dicts/SUN4V.dict usr/src/cmd/fm/dicts/SUN4V.po usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2piu.esc usr/src/cmd/fm/eversholt/files/sparc/sun4v/vfncx.esc usr/src/cmd/picl/plugins/sun4v/ontario/piclsbl/Makefile usr/src/cmd/psrinfo/psrinfo.pl usr/src/lib/fm/topo/maps/Makefile usr/src/lib/fm/topo/maps/SUNW,T5140/Makefile usr/src/lib/fm/topo/maps/SUNW,T5140/T5140-hc-topology.xml usr/src/lib/fm/topo/maps/SUNW,T5140/T5240-hc-topology.xml usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h usr/src/lib/libpcp/sparc/Makefile usr/src/pkgdefs/SUNWcart200.v/prototype_com usr/src/pkgdefs/SUNWfmd/prototype_sparc usr/src/pkgdefs/SUNWkvmt200.v/prototype_com usr/src/pkgdefs/SUNWn2cp.v/postinstall usr/src/pkgdefs/SUNWpiclu/prototype_sparc usr/src/pkgdefs/SUNWust2.v/pkginfo.tmpl usr/src/pkgdefs/SUNWust2.v/prototype_com usr/src/pkgdefs/etc/exception_list_sparc usr/src/psm/stand/boot/sparcv9/sun4v/Makefile usr/src/uts/common/Makefile.files usr/src/uts/common/io/nxge/nxge_fflp.c usr/src/uts/common/io/nxge/nxge_fzc.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_mac.c usr/src/uts/common/io/nxge/nxge_main.c usr/src/uts/common/io/nxge/nxge_ndd.c usr/src/uts/common/io/nxge/nxge_virtual.c usr/src/uts/common/io/nxge/nxge_zcp.c usr/src/uts/common/sys/nxge/nxge.h usr/src/uts/common/sys/nxge/nxge_common.h usr/src/uts/common/sys/nxge/nxge_impl.h usr/src/uts/common/sys/nxge/nxge_mac_hw.h usr/src/uts/common/sys/nxge/nxge_phy_hw.h usr/src/uts/sparc/os/driver_aliases usr/src/uts/sun4/io/trapstat.c usr/src/uts/sun4/sys/trapstat.h usr/src/uts/sun4u/Makefile.files usr/src/uts/sun4v/Makefile usr/src/uts/sun4v/Makefile.files usr/src/uts/sun4v/Makefile.maramba usr/src/uts/sun4v/Makefile.sun4v.shared usr/src/uts/sun4v/cpu/generic.c usr/src/uts/sun4v/cpu/mach_cpu_module.c usr/src/uts/sun4v/cpu/niagara.c usr/src/uts/sun4v/cpu/niagara2.c usr/src/uts/sun4v/cpu/niagara2_asm.s usr/src/uts/sun4v/cpu/niagara2_atomic.s usr/src/uts/sun4v/cpu/niagara_copy.s usr/src/uts/sun4v/cpu/niagara_perfctr.c usr/src/uts/sun4v/io/n2rng/n2rng.c usr/src/uts/sun4v/maramba/Makefile usr/src/uts/sun4v/niagara2_pcbe/Makefile usr/src/uts/sun4v/os/cmp.c usr/src/uts/sun4v/os/fillsysinfo.c usr/src/uts/sun4v/pcbe/niagara2_pcbe.c usr/src/uts/sun4v/sys/cpu_module.h usr/src/uts/sun4v/sys/hsvc.h usr/src/uts/sun4v/sys/machcpuvar.h usr/src/uts/sun4v/sys/machparam.h usr/src/uts/sun4v/sys/n2rng.h usr/src/uts/sun4v/sys/niagara2regs.h usr/src/uts/sun4v/sys/niagaraasi.h usr/src/uts/sun4v/vfalls/Makefile usr/src/uts/sun4v/vfalls_pcbe/Makefile
diffstat 68 files changed, 4443 insertions(+), 1300 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fm/dicts/SUN4V.dict	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/cmd/fm/dicts/SUN4V.dict	Wed Jul 25 18:20:14 2007 -0700
@@ -65,3 +65,4 @@
 fault.io.n2.soc=35
 fault.io.n2.crossbar=36
 fault.io.fire.fw-epkt fault.io.fire.sw-epkt fault.io.fire.sw-fw-mismatch=37
+fault.io.vf.ncx=38
--- a/usr/src/cmd/fm/dicts/SUN4V.po	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/cmd/fm/dicts/SUN4V.po	Wed Jul 25 18:20:14 2007 -0700
@@ -617,3 +617,19 @@
 msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
 msgid "SUN4V-8001-5Q.action"
 msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
+#
+# code: SUN4V-8001-64
+# keys: fault.io.vf.ncx
+#
+msgid "SUN4V-8001-64.type"
+msgstr "Fault"
+msgid "SUN4V-8001-64.severity"
+msgstr "Critical"
+msgid "SUN4V-8001-64.description"
+msgstr "An uncorrectable problem was detected in the NCX subsystem.\n  Refer to %s for more information."
+msgid "SUN4V-8001-64.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4V-8001-64.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4V-8001-64.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile	Wed Jul 25 18:20:14 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.
 #
 #
@@ -28,7 +28,7 @@
 include ../sun4/Makefile.sun4
 
 EFT_PLAT= sun4v
-SUN4VEFTFILES= n2piu.eft
+SUN4VEFTFILES= n2piu.eft vfncx.eft
 EFT_PLAT_FILES= $(SUN4VEFTFILES) $(SUN4EFTFILES)
 
 include ../../Makefile.com
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2piu.esc	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2piu.esc	Wed Jul 25 18:20:14 2007 -0700
@@ -105,6 +105,7 @@
  * Additional "PEC" errors to fire.
  */
 event ereport.io.n2.peu.err_sds_los@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.peu.lwc@hostbridge/pciexrc{within(5s)};
 event ereport.io.n2.peu.nfp@hostbridge/pciexrc{within(5s)}; 
 
 /*
@@ -201,7 +202,8 @@
  * don't diag.
  */
 prop upset.io.fire.nodiag@hostbridge (0)-> 
-    ereport.io.n2.peu.err_sds_los@hostbridge/pciexrc;
+    ereport.io.n2.peu.err_sds_los@hostbridge/pciexrc,
+    ereport.io.n2.peu.lwc@hostbridge/pciexrc;
 
 /* SOC Errors */ 
 /* fault.io.n2.soc */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/vfncx.esc	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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 "SUN4V" 
+
+/*
+ * Eversholt rules for the VF PIU extention to Fire nexus driver
+ */
+#define HB_FIT			400 
+
+/*
+ * Faults, upsets and defects
+ */
+/* VF Asic */
+fru hostbridge/pciexrc; 
+asru hostbridge/pciexrc; 
+event fault.io.vf.ncx@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+
+/* fault.io.vf.ncx */
+event ereport.io.vf.ncx.to-fdr@hostbridge/pciexrc{within(0s)}; 
+event ereport.io.vf.ncx.to-fsr@hostbridge/pciexrc{within(0s)}; 
+event ereport.io.vf.ncx.fre@hostbridge/pciexrc{within(0s)}; 
+event ereport.io.vf.ncx.fse@hostbridge/pciexrc{within(0s)}; 
+event ereport.io.vf.ncx.fde@hostbridge/pciexrc{within(0s)}; 
+
+/* fault.io.vf.ncx */
+prop fault.io.vf.ncx@hostbridge/pciexrc (1)-> 
+	ereport.io.vf.ncx.to-fdr@hostbridge/pciexrc,
+	ereport.io.vf.ncx.to-fsr@hostbridge/pciexrc,
+	ereport.io.vf.ncx.fre@hostbridge/pciexrc,
+	ereport.io.vf.ncx.fse@hostbridge/pciexrc,
+	ereport.io.vf.ncx.fde@hostbridge/pciexrc;
+
--- a/usr/src/cmd/picl/plugins/sun4v/ontario/piclsbl/Makefile	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/cmd/picl/plugins/sun4v/ontario/piclsbl/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -75,7 +75,7 @@
 
 LINTFLAGS +=	-erroff=E_BAD_PTR_CAST_ALIGN -v
 
-LINKED_PLATFORMS	= SUNW,Sun-Blade-T6300
+LINKED_PLATFORMS	= SUNW,Sun-Blade-T6300 SUNW,T5140
 LINKED_PLATFORMS	+= SUNW,Sun-Blade-T6320
 LINKED_PLATFORMS	+= SUNW,SPARC-Enterprise-T5120
 
--- a/usr/src/cmd/psrinfo/psrinfo.pl	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/cmd/psrinfo/psrinfo.pl	Wed Jul 25 18:20:14 2007 -0700
@@ -20,7 +20,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.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -301,7 +301,7 @@
 sub property_list
 {
 	my $prop_name = shift;
-	return (uniqsort(map { $cpu_list{$_}->{$prop_name} || 0 } @_));
+	return (grep {$_ >= 0} uniqsort(map { $cpu_list{$_}->{$prop_name} || 0 } @_));
 }
 
 #
--- a/usr/src/lib/fm/topo/maps/Makefile	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/lib/fm/topo/maps/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -32,7 +32,8 @@
 		SUNW,Sun-Fire-15000 \
 		SUNW,SPARC-Enterprise \
 		SUNW,Sun-Blade-T6320 \
-		SUNW,SPARC-Enterprise-T5120
+		SUNW,SPARC-Enterprise-T5120 \
+		SUNW,T5140
 
 i386_SUBDIRS = i86pc \
 		SUNW,Sun-Fire-X4500
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/SUNW,T5140/Makefile	Wed Jul 25 18:20:14 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"
+
+PLATFORMS = SUNW,T5140
+CLASS = platform
+DTDFILE =
+TOPOFILE = T5140-hc-topology.xml \
+	T5240-hc-topology.xml
+SRCDIR = ../SUNW,T5140
+
+include ../Makefile.map
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/SUNW,T5140/T5140-hc-topology.xml	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,46 @@
+<?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='SUNW,T5140' scheme='hc'>
+  <range name='motherboard' min='0' max='0'>
+   <enum-method name='motherboard' version='1'/>
+ 
+     <dependents grouping='children'>
+       <range name='chip' min='0' max='1'>
+         <enum-method name='chip' version='1'/>
+       </range>
+     </dependents>
+ 
+     <dependents grouping='children'>
+       <range name='hostbridge' min='0' max='254'>
+         <enum-method name='hostbridge' version='1'/>
+       </range>
+     </dependents>
+
+   </range>
+</topology>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/SUNW,T5140/T5240-hc-topology.xml	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,46 @@
+<?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='SUNW,T5240' scheme='hc'>
+  <range name='motherboard' min='0' max='0'>
+   <enum-method name='motherboard' version='1'/>
+ 
+     <dependents grouping='children'>
+       <range name='chip' min='0' max='1'>
+         <enum-method name='chip' version='1'/>
+       </range>
+     </dependents>
+ 
+     <dependents grouping='children'>
+       <range name='hostbridge' min='0' max='254'>
+         <enum-method name='hostbridge' version='1'/>
+       </range>
+     </dependents>
+
+   </range>
+</topology>
--- a/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h	Wed Jul 25 18:20:14 2007 -0700
@@ -68,11 +68,21 @@
 	    t5120_pnms },
 	{ "SPARC-Enterprise-T5220",
 	    sizeof (t5220_pnms) / sizeof (physnm_t),
+	    t5220_pnms },
+	/*
+	 * T5140/T5240 uses the same chassis as T5120/T5220, hence
+	 * the same PCI slot mappings
+	 */
+	{ "T5140",
+	    sizeof (t5120_pnms) / sizeof (physnm_t),
+	    t5120_pnms },
+	{ "T5240",
+	    sizeof (t5220_pnms) / sizeof (physnm_t),
 	    t5220_pnms }
 };
 
 physlot_names_t PhyslotNMs = {
-	3,
+	sizeof (plat_pnames) / sizeof (pphysnm_t),
 	plat_pnames
 };
 
@@ -91,11 +101,17 @@
 	    NULL },
 	{ "SPARC-Enterprise-T5220",
 	    0,
+	    NULL },
+	{ "T5140",
+	    0,
+	    NULL },
+	{ "T5240",
+	    0,
 	    NULL }
 };
 
 missing_names_t Missing = {
-	3,
+	sizeof (plats_missing) / sizeof (pdevlabs_t),
 	plats_missing
 };
 
--- a/usr/src/lib/libpcp/sparc/Makefile	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/lib/libpcp/sparc/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -40,7 +40,8 @@
 		SUNW,Netra-CP3060 \
 		SUNW,Sun-Blade-T6300 \
 		SUNW,Sun-Blade-T6320 \
-		SUNW,SPARC-Enterprise-T5120
+		SUNW,SPARC-Enterprise-T5120 \
+		SUNW,T5140
 
 
 include ../Makefile.com
--- a/usr/src/pkgdefs/SUNWcart200.v/prototype_com	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/SUNWcart200.v/prototype_com	Wed Jul 25 18:20:14 2007 -0700
@@ -60,6 +60,8 @@
 s none platform/SUNW,Netra-CP3060/lib=../sun4v/lib
 s none platform/SUNW,SPARC-Enterprise-T5220=sun4v
 s none platform/SUNW,SPARC-Enterprise-T5120=sun4v
+s none platform/SUNW,T5140=sun4v
+s none platform/SUNW,T5240=sun4v
 s none platform/SUNW,SPARC-Enterprise-T2000=SUNW,Sun-Fire-T200
 s none platform/SUNW,SPARC-Enterprise-T1000=sun4v
 s none platform/SUNW,Sun-Blade-T6300=sun4v
--- a/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Wed Jul 25 18:20:14 2007 -0700
@@ -118,6 +118,7 @@
 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/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
 d none usr/platform/sun4v/lib/fm/fmd/plugins 755 root bin
 f none usr/platform/sun4v/lib/fm/fmd/plugins/cpumem-diagnosis.so 555 root bin
@@ -192,3 +193,10 @@
 d none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/fm/topo/maps 755 root bin
 f none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/fm/topo/maps/SPARC-Enterprise-T5120-hc-topology.xml 444 root bin
 f none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/fm/topo/maps/SPARC-Enterprise-T5220-hc-topology.xml 444 root bin
+d none usr/platform/SUNW,T5140 755 root sys
+d none usr/platform/SUNW,T5140/lib 755 root bin
+d none usr/platform/SUNW,T5140/lib/fm 755 root bin
+d none usr/platform/SUNW,T5140/lib/fm/topo 755 root bin
+d none usr/platform/SUNW,T5140/lib/fm/topo/maps 755 root bin
+f none usr/platform/SUNW,T5140/lib/fm/topo/maps/T5140-hc-topology.xml 444 root bin
+f none usr/platform/SUNW,T5140/lib/fm/topo/maps/T5240-hc-topology.xml 444 root bin
--- a/usr/src/pkgdefs/SUNWkvmt200.v/prototype_com	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/SUNWkvmt200.v/prototype_com	Wed Jul 25 18:20:14 2007 -0700
@@ -51,6 +51,7 @@
 d none usr/platform/SUNW,Sun-Blade-T6300 755 root sys
 d none usr/platform/SUNW,Sun-Blade-T6320 755 root sys
 d none usr/platform/SUNW,SPARC-Enterprise-T5120 755 root sys
+d none usr/platform/SUNW,T5140 755 root sys
 #
 # create links to sun4v platform
 #
@@ -58,6 +59,7 @@
 s none usr/platform/SUNW,Sun-Blade-T6300/sbin=../sun4v/sbin
 s none usr/platform/SUNW,Sun-Blade-T6320/sbin=../sun4v/sbin
 s none usr/platform/SUNW,SPARC-Enterprise-T5120/sbin=../sun4v/sbin
+s none usr/platform/SUNW,T5140/sbin=../sun4v/sbin
 #
 #
 # create lib directory 
@@ -67,6 +69,7 @@
 d none usr/platform/SUNW,Sun-Blade-T6300/lib 755 root bin
 d none usr/platform/SUNW,Sun-Blade-T6320/lib 755 root bin
 d none usr/platform/SUNW,SPARC-Enterprise-T5120/lib 755 root bin
+d none usr/platform/SUNW,T5140/lib 755 root bin
 #
 # add binary and libraries for prtdiag
 #
@@ -81,12 +84,14 @@
 s none usr/platform/SUNW,Sun-Blade-T6300/lib/libpcp.so=../../sun4v/lib/libpcp.so
 s none usr/platform/SUNW,Sun-Blade-T6320/lib/libpcp.so=../../sun4v/lib/libpcp.so
 s none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/libpcp.so=../../sun4v/lib/libpcp.so
+s none usr/platform/SUNW,T5140/lib/libpcp.so=../../sun4v/lib/libpcp.so
 
 s none usr/platform/SUNW,Sun-Fire-T200/lib/libpcp.so.1=../../sun4v/lib/libpcp.so.1
 s none usr/platform/SUNW,Netra-CP3060/lib/libpcp.so.1=../../sun4v/lib/libpcp.so.1
 s none usr/platform/SUNW,Sun-Blade-T6300/lib/libpcp.so.1=../../sun4v/lib/libpcp.so.1
 s none usr/platform/SUNW,Sun-Blade-T6320/lib/libpcp.so.1=../../sun4v/lib/libpcp.so.1
 s none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/libpcp.so.1=../../sun4v/lib/libpcp.so.1
+s none usr/platform/SUNW,T5140/lib/libpcp.so.1=../../sun4v/lib/libpcp.so.1
 
 #
 # platform-dependent boot object
@@ -96,6 +101,7 @@
 s none usr/platform/SUNW,Sun-Blade-T6300/lib/fs=../../sun4v/lib/fs
 s none usr/platform/SUNW,Sun-Blade-T6320/lib/fs=../../sun4v/lib/fs
 s none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/fs=../../sun4v/lib/fs
+s none usr/platform/SUNW,T5140/lib/fs=../../sun4v/lib/fs
 #
 # add erie link
 #
@@ -109,6 +115,10 @@
 #
 s none usr/platform/SUNW,SPARC-Enterprise-T5220=SUNW,SPARC-Enterprise-T5120
 #
+# add Maramba 2U link
+#
+s none usr/platform/SUNW,T5240=SUNW,T5140
+#
 # add erie fujitsu link
 #
 s none usr/platform/SUNW,SPARC-Enterprise-T1000=SUNW,Sun-Fire-T200
--- a/usr/src/pkgdefs/SUNWn2cp.v/postinstall	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/SUNWn2cp.v/postinstall	Wed Jul 25 18:20:14 2007 -0700
@@ -21,7 +21,7 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -111,7 +111,7 @@
 grep -w n2cp ${NAMEMAJOR} > /dev/null 2>&1
 if [ $? -ne 0 ]
 then
-    $ADD_DRV -i "SUNW,n2-cwq" n2cp || exit 1
+    $ADD_DRV -i '"SUNW,n2-cwq" "SUNW,vf-cwq"' n2cp || exit 1
 fi
 
 exit 0
--- a/usr/src/pkgdefs/SUNWpiclu/prototype_sparc	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/SUNWpiclu/prototype_sparc	Wed Jul 25 18:20:14 2007 -0700
@@ -156,6 +156,12 @@
 d none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/picl/plugins 755 root sys
 s none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/picl/plugins/libpiclsbl.so=../../../../SUNW,Sun-Fire-T200/lib/picl/plugins/libpiclsbl.so.1
 s none usr/platform/SUNW,SPARC-Enterprise-T5120/lib/picl/plugins/libpiclsbl.so.1=../../../../SUNW,Sun-Fire-T200/lib/picl/plugins/libpiclsbl.so.1
+d none usr/platform/SUNW,T5140 755 root sys
+d none usr/platform/SUNW,T5140/lib 755 root bin
+d none usr/platform/SUNW,T5140/lib/picl 755 root sys
+d none usr/platform/SUNW,T5140/lib/picl/plugins 755 root sys
+s none usr/platform/SUNW,T5140/lib/picl/plugins/libpiclsbl.so=../../../../SUNW,Sun-Fire-T200/lib/picl/plugins/libpiclsbl.so.1
+s none usr/platform/SUNW,T5140/lib/picl/plugins/libpiclsbl.so.1=../../../../SUNW,Sun-Fire-T200/lib/picl/plugins/libpiclsbl.so.1
 d none usr/platform/SUNW,Sun-Fire-V240 755 root sys
 d none usr/platform/SUNW,Sun-Fire-V240/lib 755 root bin
 s none usr/platform/SUNW,Sun-Fire-V240/lib/libprtdiag_psr.so.1=../../SUNW,Sun-Blade-100/lib/libprtdiag_psr.so.1
--- a/usr/src/pkgdefs/SUNWust2.v/pkginfo.tmpl	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/SUNWust2.v/pkginfo.tmpl	Wed Jul 25 18:20:14 2007 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # CDDL HEADER START
@@ -28,7 +28,7 @@
 # and package architecture.
 #
 PKG="SUNWust2"
-NAME="UltraSPARC-T2 (Root)"
+NAME="UltraSPARC-T2 family (Root)"
 ARCH="sparc.sun4v"
 VERSION="ONVERS,REV=0.0.0"
 SUNW_PRODNAME="SunOS"
@@ -36,7 +36,7 @@
 SUNW_PKGTYPE="root"
 MAXINST="1000"
 CATEGORY="system"
-DESC="UltraSPARC-T2 core kernel software"
+DESC="UltraSPARC-T2 family core kernel software"
 VENDOR="Sun Microsystems, Inc."
 HOTLINE="Please contact your local service provider"
 EMAIL=""
--- a/usr/src/pkgdefs/SUNWust2.v/prototype_com	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/SUNWust2.v/prototype_com	Wed Jul 25 18:20:14 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.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -50,6 +50,8 @@
 d none platform/sun4v/kernel/cpu 755 root sys
 d none platform/sun4v/kernel/cpu/sparcv9 755 root sys
 f none platform/sun4v/kernel/cpu/sparcv9/SUNW,UltraSPARC-T2 755 root sys
+f none platform/sun4v/kernel/cpu/sparcv9/SUNW,UltraSPARC-T2+ 755 root sys
 d none platform/sun4v/kernel/pcbe 755 root sys
 d none platform/sun4v/kernel/pcbe/sparcv9 755 root sys
 f none platform/sun4v/kernel/pcbe/sparcv9/pcbe.SUNW,UltraSPARC-T2 755 root sys
+f none platform/sun4v/kernel/pcbe/sparcv9/pcbe.SUNW,UltraSPARC-T2+ 755 root sys
--- a/usr/src/pkgdefs/etc/exception_list_sparc	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/pkgdefs/etc/exception_list_sparc	Wed Jul 25 18:20:14 2007 -0700
@@ -811,6 +811,7 @@
 #
 usr/platform/SUNW,Sun-Blade-T6320/lib/llib-lpcp.ln	sparc
 usr/platform/SUNW,Sun-Blade-T6300/lib/llib-lpcp.ln	sparc
+usr/platform/SUNW,T5140/lib/llib-lpcp.ln		sparc
 usr/platform/SUNW,Sun-Fire-T200/lib/llib-lpcp.ln	sparc
 usr/platform/SUNW,Netra-CP3060/lib/llib-lpcp.ln		sparc
 usr/platform/SUNW,SPARC-Enterprise-T5120/lib/llib-lpcp.ln		sparc
--- a/usr/src/psm/stand/boot/sparcv9/sun4v/Makefile	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/psm/stand/boot/sparcv9/sun4v/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -36,6 +36,7 @@
 PLATLINKS	+= SUNW,Sun-Blade-T6300
 PLATLINKS	+= SUNW,Sun-Blade-T6320
 PLATLINKS	+= SUNW,SPARC-Enterprise-T5120
+PLATLINKS	+= SUNW,T5140
 
 LINKED_DIRS	= $(PLATLINKS:%=$(USR_PLAT_DIR)/%)
 LINKED_LIB_DIRS	= $(PLATLINKS:%=$(USR_PLAT_DIR)/%/lib)
--- a/usr/src/uts/common/Makefile.files	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/Makefile.files	Wed Jul 25 18:20:14 2007 -0700
@@ -30,13 +30,13 @@
 # common to all SunOS systems.
 
 i386_CORE_OBJS += \
+		atomic.o	\
 		avintr.o	\
 		pic.o
 
 sparc_CORE_OBJS +=
 
 COMMON_CORE_OBJS +=		\
-		atomic.o	\
 		bitset.o	\
 		bp_map.o	\
 		brand.o		\
--- a/usr/src/uts/common/io/nxge/nxge_fflp.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_fflp.c	Wed Jul 25 18:20:14 2007 -0700
@@ -541,7 +541,7 @@
 
 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
 
-	if (nxgep->niu_type == NEPTUNE) {
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		status = nxge_fflp_fcram_init(nxgep);
 		if (status != NXGE_OK) {
 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
@@ -596,7 +596,7 @@
 	}
 
 	/* invalidate FCRAM entries */
-	if (nxgep->niu_type == NEPTUNE) {
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		status = nxge_fflp_fcram_invalidate_all(nxgep);
 		if (status != NXGE_OK) {
 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
@@ -836,7 +836,7 @@
 	classify_ptr->tcam_size = TCAM_NIU_TCAM_MAX_ENTRY;
 
 	/* init data structures, based on HW type */
-	if (nxgep->niu_type == NEPTUNE) {
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		classify_ptr->tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY;
 		/*
 		 * check if fcram based classification is required and init the
@@ -1441,7 +1441,7 @@
 	int insert_hash = 0;
 	nxge_status_t status = NXGE_OK;
 
-	if (nxgep->niu_type == NEPTUNE) {
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		/* determine whether to do TCAM or Hash flow */
 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
 	}
--- a/usr/src/uts/common/io/nxge/nxge_fzc.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_fzc.c	Wed Jul 25 18:20:14 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.
  */
 
@@ -119,25 +119,20 @@
 		return (status);
 	}
 
-	switch (nxgep->niu_type) {
-	case NEPTUNE:
-	case NEPTUNE_2:
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		/*
 		 * Set up the logical device group's logical devices that
 		 * the group owns.
 		 */
-		if ((status = nxge_fzc_intr_ldg_num_set(nxgep))
-				!= NXGE_OK) {
-			break;
-		}
+		if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK)
+			goto fzc_intr_init_exit;
 
 		/* Configure the system interrupt data */
-		if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK) {
-			break;
-		}
+		if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK)
+			goto fzc_intr_init_exit;
+	}
 
-		break;
-	}
+fzc_intr_init_exit:
 
 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init"));
 
@@ -269,25 +264,12 @@
 	nxge_status_t	status = NXGE_OK;
 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel"));
 
-	switch (nxgep->niu_type) {
-	case NEPTUNE:
-	case NEPTUNE_2:
-	default:
-		/* Initialize the RXDMA logical pages */
-		status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel,
-			rbr_p);
-		if (status != NXGE_OK) {
-			return (status);
-		}
-
-		break;
-
+	if (nxgep->niu_type == N2_NIU) {
 #ifndef	NIU_HV_WORKAROUND
-	case N2_NIU:
 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
-			"==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV "
-			"set up logical pages"));
+		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV "
+		    "set up logical pages"));
 		/* Initialize the RXDMA logical pages */
 		status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel,
 			rbr_p);
@@ -295,21 +277,27 @@
 			return (status);
 		}
 #endif
-		break;
+		status = NXGE_OK;
 #else
-	case N2_NIU:
 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
-			"==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
-			"set up logical pages"));
+		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
+		    "set up logical pages"));
 		/* Initialize the RXDMA logical pages */
 		status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel,
-			rbr_p);
+		    rbr_p);
 		if (status != NXGE_OK) {
 			return (status);
 		}
-
-		break;
 #endif
+	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
+		/* Initialize the RXDMA logical pages */
+		status = nxge_init_fzc_rxdma_channel_pages(nxgep,
+		    channel, rbr_p);
+		if (status != NXGE_OK) {
+			return (status);
+		}
+	} else {
+		return (NXGE_ERROR);
 	}
 
 	/* Configure RED parameters */
@@ -419,38 +407,33 @@
 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
 		"==> nxge_init_fzc_txdma_channel"));
 
-	switch (nxgep->niu_type) {
-	case NEPTUNE:
-	case NEPTUNE_2:
-	default:
-		/* Initialize the TXDMA logical pages */
-		(void) nxge_init_fzc_txdma_channel_pages(nxgep, channel,
-			tx_ring_p);
-		break;
-
+	if (nxgep->niu_type == N2_NIU) {
 #ifndef	NIU_HV_WORKAROUND
-	case N2_NIU:
 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
-			"==> nxge_init_fzc_txdma_channel "
-			"N2_NIU: call HV to set up txdma logical pages"));
+		    "==> nxge_init_fzc_txdma_channel "
+		    "N2_NIU: call HV to set up txdma logical pages"));
 		status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel,
-			tx_ring_p);
+		    tx_ring_p);
 		if (status != NXGE_OK) {
 			return (status);
 		}
 #endif
-		break;
+		status = NXGE_OK;
 #else
-	case N2_NIU:
 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
-			"==> nxge_init_fzc_txdma_channel "
-			"N2_NIU: NEED to set up txdma logical pages"));
+		    "==> nxge_init_fzc_txdma_channel "
+		    "N2_NIU: NEED to set up txdma logical pages"));
 		/* Initialize the TXDMA logical pages */
 		(void) nxge_init_fzc_txdma_channel_pages(nxgep, channel,
-			tx_ring_p);
-		break;
+		    tx_ring_p);
 #endif
+	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
+		/* Initialize the TXDMA logical pages */
+		(void) nxge_init_fzc_txdma_channel_pages(nxgep,
+		    channel, tx_ring_p);
+	} else {
+		return (NXGE_ERROR);
 	}
 
 	/*
@@ -589,12 +572,12 @@
 	 * npi_rxdma_cfg_port_ddr_weight();
 	 */
 
-	if (nxgep->niu_type == NEPTUNE) {
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
-			(nxgep->mac.portmode == PORT_1G_FIBER)) {
+		    (nxgep->mac.portmode == PORT_1G_FIBER)) {
 			rs = npi_rxdma_cfg_port_ddr_weight(handle,
-							    nxgep->function_num,
-							    NXGE_RX_DRR_WT_1G);
+			    nxgep->function_num,
+			    NXGE_RX_DRR_WT_1G);
 			if (rs != NPI_SUCCESS) {
 				return (NXGE_ERROR | rs);
 			}
--- a/usr/src/uts/common/io/nxge/nxge_hw.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_hw.c	Wed Jul 25 18:20:14 2007 -0700
@@ -831,7 +831,7 @@
 		(nxgep->statsp->port_stats.lb_mode == nxge_lb_phy)) {
 
 		(void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP);
-		(void) nxge_xcvr_find(nxgep);
+		(void) nxge_setup_xcvr_table(nxgep);
 		(void) nxge_link_init(nxgep);
 		(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
 	}
@@ -889,7 +889,7 @@
 	nxge_global_reset(nxgep);
 
 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP);
-	(void) nxge_xcvr_find(nxgep);
+	(void) nxge_setup_xcvr_table(nxgep);
 	(void) nxge_link_init(nxgep);
 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
 
--- a/usr/src/uts/common/io/nxge/nxge_ipp.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_ipp.c	Wed Jul 25 18:20:14 2007 -0700
@@ -51,15 +51,16 @@
 	NXGE_DEBUG_MSG((nxgep, IPP_CTL, "==> nxge_ipp_init: port%d", portn));
 
 	/* Initialize ECC and parity in SRAM of DFIFO and PFIFO */
-	if ((nxgep->niu_type == NEPTUNE) || (nxgep->niu_type == NEPTUNE_2)) {
+	if (nxgep->niu_type == N2_NIU) {
+		dfifo_entries = IPP_NIU_DFIFO_ENTRIES;
+	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		if (portn < 2)
 			dfifo_entries = IPP_P0_P1_DFIFO_ENTRIES;
 		else
 			dfifo_entries = IPP_P2_P3_DFIFO_ENTRIES;
-	} else if (nxgep->niu_type == N2_NIU) {
-		dfifo_entries = IPP_NIU_DFIFO_ENTRIES;
-	} else
+	} else {
 		goto fail;
+	}
 
 	for (i = 0; i < dfifo_entries; i++) {
 		if ((rs = npi_ipp_write_dfifo(handle,
@@ -558,15 +559,16 @@
 		 */
 	}
 
-	if ((nxgep->niu_type == NEPTUNE) || (nxgep->niu_type == NEPTUNE_2)) {
+	if (nxgep->niu_type == N2_NIU) {
+		dfifo_entries = IPP_NIU_DFIFO_ENTRIES;
+	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		if (portn < 2)
 			dfifo_entries = IPP_P0_P1_DFIFO_ENTRIES;
 		else
 			dfifo_entries = IPP_P2_P3_DFIFO_ENTRIES;
-	} else if (nxgep->niu_type == N2_NIU) {
-		dfifo_entries = IPP_NIU_DFIFO_ENTRIES;
-	} else
+	} else {
 		goto fail;
+	}
 
 	/* Clean up DFIFO SRAM entries */
 	for (i = 0; i < dfifo_entries; i++) {
--- a/usr/src/uts/common/io/nxge/nxge_mac.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_mac.c	Wed Jul 25 18:20:14 2007 -0700
@@ -32,6 +32,7 @@
 #define	LM_WAIT_MULTIPLIER	8
 
 extern uint32_t nxge_no_link_notify;
+extern boolean_t nxge_no_msg;
 extern uint32_t nxge_lb_dbg;
 extern nxge_os_mutex_t	nxge_mdio_lock;
 extern nxge_os_mutex_t	nxge_mii_lock;
@@ -49,11 +50,197 @@
  */
 static ether_addr_st etherbroadcastaddr =
 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
+/*
+ * Ethernet zero address definition.
+ */
 static ether_addr_st etherzeroaddr =
 				{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
+/*
+ * Supported chip types
+ */
+static uint32_t nxge_supported_cl45_ids[] = {BCM8704_DEV_ID};
+static uint32_t nxge_supported_cl22_ids[] = {BCM5464R_PHY_ID};
+
+#define	NUM_CLAUSE_45_IDS	(sizeof (nxge_supported_cl45_ids) /	\
+				sizeof (uint32_t))
+#define	NUM_CLAUSE_22_IDS	(sizeof (nxge_supported_cl22_ids) /	\
+				sizeof (uint32_t))
+/*
+ * static functions
+ */
+static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
+static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
+static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
+static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
+static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
+static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
+static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
+static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
+static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
+static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
+static nxge_status_t nxge_check_mii_link(p_nxge_t);
+static nxge_status_t nxge_check_10g_link(p_nxge_t);
+static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
+static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
+static void nxge_bcm5464_link_led_off(p_nxge_t);
+
+/*
+ * xcvr tables for supported transceivers
+ */
+
+static nxge_xcvr_table_t nxge_n2_table = {
+	nxge_n2_serdes_init,
+	nxge_10G_xcvr_init,
+	nxge_10G_link_intr_stop,
+	nxge_10G_link_intr_start,
+	nxge_check_10g_link,
+	BCM8704_DEV_ID,
+	PCS_XCVR,
+	BCM8704_N2_PORT_ADDR_BASE
+};
+
+static nxge_xcvr_table_t nxge_10G_fiber_table = {
+	nxge_neptune_10G_serdes_init,
+	nxge_10G_xcvr_init,
+	nxge_10G_link_intr_stop,
+	nxge_10G_link_intr_start,
+	nxge_check_10g_link,
+	BCM8704_DEV_ID,
+	PCS_XCVR,
+	BCM8704_NEPTUNE_PORT_ADDR_BASE
+};
+
+static nxge_xcvr_table_t nxge_1G_copper_table = {
+	NULL,
+	nxge_1G_xcvr_init,
+	nxge_1G_copper_link_intr_stop,
+	nxge_1G_copper_link_intr_start,
+	nxge_check_mii_link,
+	BCM5464R_PHY_ID,
+	INT_MII_XCVR,
+	BCM5464_NEPTUNE_PORT_ADDR_BASE
+};
+
+static nxge_xcvr_table_t nxge_1G_fiber_table = {
+	nxge_1G_serdes_init,
+	nxge_1G_xcvr_init,
+	nxge_1G_fiber_link_intr_stop,
+	nxge_1G_fiber_link_intr_start,
+	nxge_check_mii_link,
+	0,
+	PCS_XCVR,
+	0
+};
+
+static nxge_xcvr_table_t nxge_10G_copper_table = {
+	nxge_neptune_10G_serdes_init,
+	NULL,
+	NULL,
+	NULL,
+	0,
+	PCS_XCVR,
+	0
+};
 
 nxge_status_t nxge_mac_init(p_nxge_t);
 
+/* Set up the PHY specific values. */
+
+nxge_status_t
+nxge_setup_xcvr_table(p_nxge_t nxgep)
+{
+	nxge_status_t	status = NXGE_OK;
+	uint32_t	port_type;
+	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
+
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
+	    portn));
+
+	if (nxgep->niu_type == N2_NIU) {
+		nxgep->mac.portmode = PORT_10G_FIBER;
+		nxgep->xcvr = nxge_n2_table;
+		nxgep->xcvr.xcvr_addr += portn;
+	} else {
+		port_type = nxgep->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn);
+		port_type = port_type & (NXGE_PORT_TYPE_MASK);
+		switch (port_type) {
+		case NXGE_PORT_1G_COPPER:
+			nxgep->mac.portmode = PORT_1G_COPPER;
+			nxgep->xcvr = nxge_1G_copper_table;
+			if (nxgep->nxge_hw_p->platform_type ==
+			    P_NEPTUNE_MARAMBA_P1) {
+				nxgep->xcvr.xcvr_addr =
+				    BCM5464_MARAMBA_P1_PORT_ADDR_BASE;
+			} else if (nxgep->nxge_hw_p->platform_type ==
+			    P_NEPTUNE_MARAMBA_P0) {
+				nxgep->xcvr.xcvr_addr =
+				    BCM5464_MARAMBA_P0_PORT_ADDR_BASE;
+			}
+			/*
+			 * For Altas 4-1G copper, Xcvr port numbers are
+			 * swapped with ethernet port number. This is
+			 * designed for better signal integrity in routing.
+			 */
+			switch (portn) {
+			case 0:
+				nxgep->xcvr.xcvr_addr += 3;
+				break;
+			case 1:
+				nxgep->xcvr.xcvr_addr += 2;
+				break;
+			case 2:
+				nxgep->xcvr.xcvr_addr += 1;
+				break;
+			case 3:
+				break;
+			default:
+				return (NXGE_ERROR);
+			}
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
+			break;
+		case NXGE_PORT_10G_COPPER:
+			nxgep->mac.portmode = PORT_10G_COPPER;
+			nxgep->xcvr = nxge_10G_copper_table;
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
+			break;
+		case NXGE_PORT_1G_FIBRE:
+			nxgep->mac.portmode = PORT_1G_FIBER;
+			nxgep->xcvr = nxge_1G_fiber_table;
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Fiber Xcvr"));
+			break;
+		case NXGE_PORT_10G_FIBRE:
+			nxgep->mac.portmode = PORT_10G_FIBER;
+			nxgep->xcvr = nxge_10G_fiber_table;
+			if ((nxgep->nxge_hw_p->platform_type ==
+			    P_NEPTUNE_MARAMBA_P0) ||
+			    (nxgep->nxge_hw_p->platform_type ==
+			    P_NEPTUNE_MARAMBA_P1)) {
+				nxgep->xcvr.xcvr_addr =
+				    BCM8704_MARAMBA_PORT_ADDR_BASE;
+				/*
+				 * Switch off LED for corresponding copper
+				 * port
+				 */
+				nxge_bcm5464_link_led_off(nxgep);
+			}
+			nxgep->xcvr.xcvr_addr += portn;
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr"));
+			break;
+		default:
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			    "Unknown port-type: 0x%x", port_type));
+			return (NXGE_ERROR);
+		}
+	}
+
+	nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse;
+	nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr.xcvr_addr;
+	nxgep->statsp->mac_stats.xcvr_id = nxgep->xcvr.device_id;
+	nxgep->mac.linkchkmode = LINKCHK_TIMER;
+
+	return (status);
+}
+
 /* Initialize the entire MAC and physical layer */
 
 nxge_status_t
@@ -383,41 +570,33 @@
 #ifdef	NXGE_DEBUG
 	portn = nxgep->mac.portnum;
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-		"==> nxge_serdes_init port<%d>", portn));
+	    "==> nxge_serdes_init port<%d>", portn));
 #endif
 
-	statsp = nxgep->statsp;
-
-	if (nxgep->niu_type == N2_NIU) {
-		if (nxge_n2_serdes_init(nxgep) != NXGE_OK)
+	if (nxgep->xcvr.serdes_init) {
+		statsp = nxgep->statsp;
+		status = nxgep->xcvr.serdes_init(nxgep);
+		if (status != NXGE_OK)
 			goto fail;
-	} else if ((nxgep->niu_type == NEPTUNE) ||
-				(nxgep->niu_type == NEPTUNE_2)) {
-			if ((status = nxge_neptune_serdes_init(nxgep))
-								!= NXGE_OK)
-				goto fail;
-	} else {
-		goto fail;
+		statsp->mac_stats.serdes_inits++;
 	}
 
-	statsp->mac_stats.serdes_inits++;
-
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
-			portn));
+	    portn));
 
 	return (NXGE_OK);
 
 fail:
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-		"nxge_serdes_init: Failed to initialize serdes for port<%d>",
-			portn));
+	    "nxge_serdes_init: Failed to initialize serdes for port<%d>",
+	    portn));
 
 	return (status);
 }
 
 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
 
-nxge_status_t
+static nxge_status_t
 nxge_n2_serdes_init(p_nxge_t nxgep)
 {
 	uint8_t portn;
@@ -542,14 +721,13 @@
 	return (status);
 }
 
-/* Initialize Neptune Internal Serdes (Neptune only) */
-
-nxge_status_t
-nxge_neptune_serdes_init(p_nxge_t nxgep)
+/* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
+
+static nxge_status_t
+nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
 {
 	npi_handle_t		handle;
 	uint8_t			portn;
-	nxge_port_mode_t	portmode;
 	int			chan;
 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
@@ -565,304 +743,236 @@
 	if ((portn != 0) && (portn != 1))
 		return (NXGE_OK);
 
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_neptune_serdes_init port<%d>",
-			portn));
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "==> nxge_neptune_10G_serdes_init port<%d>", portn));
 
 	handle = nxgep->npi_handle;
-	portmode = nxgep->mac.portmode;
-
-	if ((portmode == PORT_10G_FIBER) || (portmode == PORT_10G_COPPER)) {
-
-		switch (portn) {
-		case 0:
-			ESR_REG_WR(handle, ESR_0_CONTROL_REG,
-				ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
-				ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
-				(0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_3_SHIFT));
-
-				/* Set Serdes0 Internal Loopback if necessary */
-				if (nxgep->statsp->port_stats.lb_mode ==
-							nxge_lb_serdes10g) {
-					ESR_REG_WR(handle,
-						ESR_0_TEST_CONFIG_REG,
-						ESR_PAD_LOOPBACK_CH3 |
-						ESR_PAD_LOOPBACK_CH2 |
-						ESR_PAD_LOOPBACK_CH1 |
-						ESR_PAD_LOOPBACK_CH0);
-				} else {
-					ESR_REG_WR(handle,
-						ESR_0_TEST_CONFIG_REG, 0);
-				}
-			break;
-		case 1:
-			ESR_REG_WR(handle, ESR_1_CONTROL_REG,
-				ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
-				ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
-				(0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
-				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
-				(0x1 << ESR_CTL_LOSADJ_3_SHIFT));
-
-				/* Set Serdes1 Internal Loopback if necessary */
-				if (nxgep->statsp->port_stats.lb_mode ==
-							nxge_lb_serdes10g) {
-					ESR_REG_WR(handle,
-						ESR_1_TEST_CONFIG_REG,
-						ESR_PAD_LOOPBACK_CH3 |
-						ESR_PAD_LOOPBACK_CH2 |
-						ESR_PAD_LOOPBACK_CH1 |
-						ESR_PAD_LOOPBACK_CH0);
-				} else {
-					ESR_REG_WR(handle,
-						ESR_1_TEST_CONFIG_REG, 0);
-				}
-			break;
-		default:
-			/* Nothing to do here */
-			goto done;
+	switch (portn) {
+	case 0:
+		ESR_REG_WR(handle, ESR_0_CONTROL_REG,
+		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
+		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
+		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
+
+		/* Set Serdes0 Internal Loopback if necessary */
+		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
+			ESR_REG_WR(handle,
+			    ESR_0_TEST_CONFIG_REG,
+			    ESR_PAD_LOOPBACK_CH3 |
+			    ESR_PAD_LOOPBACK_CH2 |
+			    ESR_PAD_LOOPBACK_CH1 |
+			    ESR_PAD_LOOPBACK_CH0);
+		} else {
+			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
 		}
-
-		/* init TX RX channels */
-		for (chan = 0; chan < 4; chan++) {
-			if ((status = nxge_mdio_read(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
-					&rx_tx_ctrl_l.value)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_read(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
-					&rx_tx_ctrl_h.value)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_read(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
-					&glue_ctrl0_l.value)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_read(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
-					&glue_ctrl0_h.value)) != NXGE_OK)
-				goto fail;
-			rx_tx_ctrl_l.bits.enstretch = 1;
-			rx_tx_ctrl_h.bits.vmuxlo = 2;
-			rx_tx_ctrl_h.bits.vpulselo = 2;
-			glue_ctrl0_l.bits.rxlosenable = 1;
-			glue_ctrl0_l.bits.samplerate = 0xF;
-			glue_ctrl0_l.bits.thresholdcount = 0xFF;
-			glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
-			if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
-					rx_tx_ctrl_l.value)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
-					rx_tx_ctrl_h.value)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
-					glue_ctrl0_l.value)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
-					glue_ctrl0_h.value)) != NXGE_OK)
-				goto fail;
+		break;
+	case 1:
+		ESR_REG_WR(handle, ESR_1_CONTROL_REG,
+		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
+		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
+		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
+		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
+		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
+
+		/* Set Serdes1 Internal Loopback if necessary */
+		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
+			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
+			    ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 |
+			    ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0);
+		} else {
+			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
 		}
-
-		/* Apply Tx core reset */
-		if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
-					(uint16_t)0)) != NXGE_OK)
-			goto fail;
-
-		if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(),
-					(uint16_t)0xffff)) != NXGE_OK)
+		break;
+	default:
+		/* Nothing to do here */
+		goto done;
+	}
+
+	/* init TX RX channels */
+	for (chan = 0; chan < 4; chan++) {
+		if ((status = nxge_mdio_read(nxgep, portn,
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
+		    &rx_tx_ctrl_l.value)) != NXGE_OK)
 			goto fail;
-
-		NXGE_DELAY(200);
-
-		/* Apply Rx core reset */
-		if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
-					(uint16_t)0xffff)) != NXGE_OK)
+		if ((status = nxge_mdio_read(nxgep, portn,
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
+		    &rx_tx_ctrl_h.value)) != NXGE_OK)
 			goto fail;
-
-		NXGE_DELAY(200);
-		if ((status = nxge_mdio_write(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(),
-					(uint16_t)0)) != NXGE_OK)
-			goto fail;
-
-		NXGE_DELAY(200);
 		if ((status = nxge_mdio_read(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
-					&val16l)) != NXGE_OK)
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
+		    &glue_ctrl0_l.value)) != NXGE_OK)
 			goto fail;
 		if ((status = nxge_mdio_read(nxgep, portn,
-					ESR_NEPTUNE_DEV_ADDR,
-					ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(),
-					&val16h)) != NXGE_OK)
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
+		    &glue_ctrl0_h.value)) != NXGE_OK)
+			goto fail;
+		rx_tx_ctrl_l.bits.enstretch = 1;
+		rx_tx_ctrl_h.bits.vmuxlo = 2;
+		rx_tx_ctrl_h.bits.vpulselo = 2;
+		glue_ctrl0_l.bits.rxlosenable = 1;
+		glue_ctrl0_l.bits.samplerate = 0xF;
+		glue_ctrl0_l.bits.thresholdcount = 0xFF;
+		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
+		if ((status = nxge_mdio_write(nxgep, portn,
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
+		    rx_tx_ctrl_l.value)) != NXGE_OK)
+			goto fail;
+		if ((status = nxge_mdio_write(nxgep, portn,
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
+		    rx_tx_ctrl_h.value)) != NXGE_OK)
+			goto fail;
+		if ((status = nxge_mdio_write(nxgep, portn,
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
+		    glue_ctrl0_l.value)) != NXGE_OK)
+			goto fail;
+		if ((status = nxge_mdio_write(nxgep, portn,
+		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
+		    glue_ctrl0_h.value)) != NXGE_OK)
 			goto fail;
-		if ((val16l != 0) || (val16h != 0)) {
-			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-					"Failed to reset port<%d> XAUI Serdes",
-					portn));
 		}
 
-		ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
-
-		if (portn == 0) {
-			if ((val & ESR_SIG_P0_BITS_MASK) !=
+	/* Apply Tx core reset */
+	if ((status = nxge_mdio_write(nxgep, portn,
+	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
+	    (uint16_t)0)) != NXGE_OK)
+		goto fail;
+
+	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
+	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
+	    NXGE_OK)
+		goto fail;
+
+	NXGE_DELAY(200);
+
+	/* Apply Rx core reset */
+	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
+	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
+	    NXGE_OK)
+		goto fail;
+
+	NXGE_DELAY(200);
+	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
+	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK)
+		goto fail;
+
+	NXGE_DELAY(200);
+	if ((status = nxge_mdio_read(nxgep, portn,
+	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
+	    &val16l)) != NXGE_OK)
+		goto fail;
+	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
+	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK)
+		goto fail;
+	if ((val16l != 0) || (val16h != 0)) {
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+		    "Failed to reset port<%d> XAUI Serdes", portn));
+	}
+
+	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
+
+	if (portn == 0) {
+		if ((val & ESR_SIG_P0_BITS_MASK) !=
 				(ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
 					ESR_SIG_XSERDES_RDY_P0 |
 					ESR_SIG_XDETECT_P0_CH3 |
 					ESR_SIG_XDETECT_P0_CH2 |
 					ESR_SIG_XDETECT_P0_CH1 |
 					ESR_SIG_XDETECT_P0_CH0)) {
-				goto fail;
-			}
-		} else if (portn == 1) {
-			if ((val & ESR_SIG_P1_BITS_MASK) !=
+			goto fail;
+		}
+	} else if (portn == 1) {
+		if ((val & ESR_SIG_P1_BITS_MASK) !=
 				(ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
 					ESR_SIG_XSERDES_RDY_P1 |
 					ESR_SIG_XDETECT_P1_CH3 |
 					ESR_SIG_XDETECT_P1_CH2 |
 					ESR_SIG_XDETECT_P1_CH1 |
 					ESR_SIG_XDETECT_P1_CH0)) {
-				goto fail;
-			}
-		}
-
-	} else if (portmode == PORT_1G_FIBER) {
-		ESR_REG_RD(handle, ESR_1_PLL_CONFIG_REG, &val)
-		val &= ~ESR_PLL_CFG_FBDIV_2;
-		switch (portn) {
-		case 0:
-			val |= ESR_PLL_CFG_HALF_RATE_0;
-			break;
-		case 1:
-			val |= ESR_PLL_CFG_HALF_RATE_1;
-			break;
-		case 2:
-			val |= ESR_PLL_CFG_HALF_RATE_2;
-			break;
-		case 3:
-			val |= ESR_PLL_CFG_HALF_RATE_3;
-			break;
-		default:
 			goto fail;
 		}
-
-		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, val);
 	}
 
 done:
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_neptune_serdes_init port<%d>",
-			portn));
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "<== nxge_neptune_10G_serdes_init port<%d>", portn));
+
 	return (NXGE_OK);
 fail:
-	NXGE_DEBUG_MSG((nxgep, TX_CTL,
-			"nxge_neptune_serdes_init: "
-			"Failed to initialize Neptune serdes for port<%d>",
-			portn));
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "nxge_neptune_10G_serdes_init: "
+	    "Failed to initialize Neptune serdes for port<%d>", portn));
 
 	return (status);
 }
 
-/* Look for transceiver type */
-
-nxge_status_t
-nxge_xcvr_find(p_nxge_t nxgep)
+/* Initialize Neptune Internal Serdes for 1G (Neptune only) */
+
+static nxge_status_t
+nxge_1G_serdes_init(p_nxge_t nxgep)
 {
-	uint8_t		portn;
+	npi_handle_t		handle;
+	uint8_t			portn;
+	uint64_t		val;
 
 	portn = nxgep->mac.portnum;
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", portn));
-
-	if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
-		return (NXGE_ERROR);
-
-	nxgep->mac.linkchkmode = LINKCHK_TIMER;
-	if (nxgep->mac.portmode == PORT_10G_FIBER) {
-		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
-		if ((nxgep->niu_type == NEPTUNE) ||
-			(nxgep->niu_type == NEPTUNE_2)) {
-			nxgep->statsp->mac_stats.xcvr_portn =
-					BCM8704_NEPTUNE_PORT_ADDR_BASE + portn;
-		} else if (nxgep->niu_type == N2_NIU) {
-			nxgep->statsp->mac_stats.xcvr_portn =
-					BCM8704_N2_PORT_ADDR_BASE + portn;
-		} else
-			return (NXGE_ERROR);
-	} else if (nxgep->mac.portmode == PORT_1G_COPPER) {
-		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
-		/*
-		 * For Altas, Xcvr port numbers are swapped with ethernet
-		 * port number. This is designed for better signal
-		 * integrity in routing.
-		 */
-
-		switch (portn) {
-		case 0:
-			nxgep->statsp->mac_stats.xcvr_portn =
-					BCM5464_NEPTUNE_PORT_ADDR_BASE + 3;
-			break;
-		case 1:
-			nxgep->statsp->mac_stats.xcvr_portn =
-					BCM5464_NEPTUNE_PORT_ADDR_BASE + 2;
-			break;
-		case 2:
-			nxgep->statsp->mac_stats.xcvr_portn =
-					BCM5464_NEPTUNE_PORT_ADDR_BASE + 1;
-			break;
-		case 3:
-			nxgep->statsp->mac_stats.xcvr_portn =
-					BCM5464_NEPTUNE_PORT_ADDR_BASE;
-			break;
-		default:
-			return (NXGE_ERROR);
-		}
-	} else if (nxgep->mac.portmode == PORT_1G_FIBER) {
-		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
-		nxgep->statsp->mac_stats.xcvr_portn = portn;
-	} else {
-		return (NXGE_ERROR);
+
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "==> nxge_1G_serdes_init port<%d>", portn));
+
+	handle = nxgep->npi_handle;
+
+	ESR_REG_RD(handle, ESR_1_PLL_CONFIG_REG, &val);
+	val &= ~ESR_PLL_CFG_FBDIV_2;
+	switch (portn) {
+	case 0:
+		val |= ESR_PLL_CFG_HALF_RATE_0;
+		break;
+	case 1:
+		val |= ESR_PLL_CFG_HALF_RATE_1;
+		break;
+	case 2:
+		val |= ESR_PLL_CFG_HALF_RATE_2;
+		break;
+	case 3:
+		val |= ESR_PLL_CFG_HALF_RATE_3;
+		break;
+	default:
+		goto fail;
 	}
 
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
-					nxgep->statsp->mac_stats.xcvr_inuse));
+	ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, val);
+
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "<== nxge_1G_serdes_init port<%d>", portn));
 	return (NXGE_OK);
+fail:
+	NXGE_DEBUG_MSG((nxgep, TX_CTL,
+	    "nxge_1G_serdes_init: "
+	    "Failed to initialize Neptune serdes for port<%d>",
+	    portn));
+
+	return (NXGE_ERROR);
 }
 
-/* Initialize transceiver */
-
-nxge_status_t
-nxge_xcvr_init(p_nxge_t nxgep)
+/* Initialize the 10G (BCM8704) Transceiver */
+
+static nxge_status_t
+nxge_10G_xcvr_init(p_nxge_t nxgep)
 {
-	p_nxge_param_t		param_arr;
 	p_nxge_stats_t		statsp;
 	uint16_t		val;
 #ifdef	NXGE_DEBUG
@@ -880,9 +990,231 @@
 #ifdef	NXGE_DEBUG
 	portn = nxgep->mac.portnum;
 #endif
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
+	    portn));
+
+	statsp = nxgep->statsp;
+
+	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
+
+	/* Disable Link LEDs */
+	if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
+		goto fail;
+
+	/* Set Clause 45 */
+	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
+
+	/* Reset the transceiver */
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
+	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
+		goto fail;
+
+	phyxs_ctl.bits.reset = 1;
+	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
+	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
+		goto fail;
+
+	do {
+		drv_usecwait(500);
+		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
+		    &phyxs_ctl.value)) != NXGE_OK)
+			goto fail;
+		delay++;
+	} while ((phyxs_ctl.bits.reset) && (delay < 100));
+	if (delay == 100) {
+		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
+		    "failed to reset Transceiver on port<%d>", portn));
+		status = NXGE_ERROR;
+		goto fail;
+	}
+
+	/* Set to 0x7FBF */
+	ctl.value = 0;
+	ctl.bits.res1 = 0x3F;
+	ctl.bits.optxon_lvl = 1;
+	ctl.bits.oprxflt_lvl = 1;
+	ctl.bits.optrxlos_lvl = 1;
+	ctl.bits.optxflt_lvl = 1;
+	ctl.bits.opprflt_lvl = 1;
+	ctl.bits.obtmpflt_lvl = 1;
+	ctl.bits.opbiasflt_lvl = 1;
+	ctl.bits.optxrst_lvl = 1;
+	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value))
+	    != NXGE_OK)
+		goto fail;
+
+	/* Set to 0x164 */
+	tx_ctl.value = 0;
+	tx_ctl.bits.tsck_lpwren = 1;
+	tx_ctl.bits.tx_dac_txck = 0x2;
+	tx_ctl.bits.tx_dac_txd = 0x1;
+	tx_ctl.bits.xfp_clken = 1;
+	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG,
+	    tx_ctl.value)) != NXGE_OK)
+		goto fail;
+	/*
+	 * According to Broadcom's instruction, SW needs to read
+	 * back these registers twice after written.
+	 */
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
+	    != NXGE_OK)
+		goto fail;
+
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
+	    != NXGE_OK)
+		goto fail;
+
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
+	    != NXGE_OK)
+		goto fail;
+
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
+	    != NXGE_OK)
+		goto fail;
+
+	/* Enable Tx and Rx LEDs to be driven by traffic */
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
+	    &op_ctr.value)) != NXGE_OK)
+		goto fail;
+	op_ctr.bits.gpio_sel = 0x3;
+	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
+	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
+	    op_ctr.value)) != NXGE_OK)
+		goto fail;
+
+	NXGE_DELAY(1000000);
+
+	/* Set BCM8704 Internal Loopback mode if necessary */
+	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
+	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
+	    != NXGE_OK)
+		goto fail;
+	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
+		pcs_ctl.bits.loopback = 1;
+	else
+		pcs_ctl.bits.loopback = 0;
+	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
+	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
+	    != NXGE_OK)
+		goto fail;
+
+	status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
+	if (status != NXGE_OK)
+		goto fail;
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
+	status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
+	if (status != NXGE_OK)
+		goto fail;
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
+	status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
+	if (status != NXGE_OK)
+		goto fail;
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
+
+#ifdef	NXGE_DEBUG
+	/* Diagnose link issue if link is not up */
+	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
+	    BCM8704_USER_ANALOG_STATUS0_REG,
+	    &val);
+	if (status != NXGE_OK)
+		goto fail;
+
+	status = nxge_mdio_read(nxgep, phy_port_addr,
+				BCM8704_USER_DEV3_ADDR,
+				BCM8704_USER_ANALOG_STATUS0_REG,
+				&val);
+	if (status != NXGE_OK)
+		goto fail;
+
+	status = nxge_mdio_read(nxgep, phy_port_addr,
+				BCM8704_USER_DEV3_ADDR,
+				BCM8704_USER_TX_ALARM_STATUS_REG,
+				&val1);
+	if (status != NXGE_OK)
+		goto fail;
+
+	status = nxge_mdio_read(nxgep, phy_port_addr,
+				BCM8704_USER_DEV3_ADDR,
+				BCM8704_USER_TX_ALARM_STATUS_REG,
+				&val1);
+	if (status != NXGE_OK)
+		goto fail;
+
+	if (val != 0x3FC) {
+		if ((val == 0x43BC) && (val1 != 0)) {
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Cable not connected to peer or bad"
+			    " cable on port<%d>\n", portn));
+		} else if (val == 0x639C) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			    "Optical module (XFP) is bad or absent"
+			    " on port<%d>\n", portn));
+		}
+	}
+#endif
+
+	statsp->mac_stats.cap_10gfdx = 1;
+	statsp->mac_stats.lp_cap_10gfdx = 1;
+
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
+	    portn));
+	return (NXGE_OK);
+
+fail:
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "nxge_10G_xcvr_init: failed to initialize transceiver for "
+	    "port<%d>", portn));
+	return (status);
+}
+
+/* Initialize the 1G copper (BCM 5464) Transceiver */
+
+static nxge_status_t
+nxge_1G_xcvr_init(p_nxge_t nxgep)
+{
+	p_nxge_param_t		param_arr = nxgep->param_arr;
+	p_nxge_stats_t		statsp = nxgep->statsp;
+	nxge_status_t		status = NXGE_OK;
+
+	/* Set Clause 22 */
+	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
+
+	/* Set capability flags */
+	statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value;
+	statsp->mac_stats.cap_100fdx = param_arr[param_anar_100fdx].value;
+	statsp->mac_stats.cap_10fdx = param_arr[param_anar_10fdx].value;
+
+	status = nxge_mii_xcvr_init(nxgep);
+
+	return (status);
+}
+
+/* Initialize transceiver */
+
+nxge_status_t
+nxge_xcvr_init(p_nxge_t nxgep)
+{
+	p_nxge_stats_t		statsp;
+#ifdef	NXGE_DEBUG
+	uint8_t			portn;
+#endif
+
+	nxge_status_t		status = NXGE_OK;
+#ifdef	NXGE_DEBUG
+	portn = nxgep->mac.portnum;
+#endif
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
-
-	param_arr = nxgep->param_arr;
 	statsp = nxgep->statsp;
 
 	/*
@@ -908,246 +1240,21 @@
 	statsp->mac_stats.link_asmpause = 0;
 	statsp->mac_stats.link_pause = 0;
 
-	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
-
-	switch (nxgep->mac.portmode) {
-	case PORT_10G_FIBER:
-		/* Disable Link LEDs */
-		if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
-			goto fail;
-
-		/* Set Clause 45 */
-		npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
-
-		/* Reset the transceiver */
-		if ((status = nxge_mdio_read(nxgep,
-				phy_port_addr,
-				BCM8704_PHYXS_ADDR,
-				BCM8704_PHYXS_CONTROL_REG,
-				&phyxs_ctl.value)) != NXGE_OK)
-			goto fail;
-
-		phyxs_ctl.bits.reset = 1;
-		if ((status = nxge_mdio_write(nxgep,
-				phy_port_addr,
-				BCM8704_PHYXS_ADDR,
-				BCM8704_PHYXS_CONTROL_REG,
-				phyxs_ctl.value)) != NXGE_OK)
-			goto fail;
-
-		do {
-			drv_usecwait(500);
-			if ((status = nxge_mdio_read(nxgep,
-					phy_port_addr,
-					BCM8704_PHYXS_ADDR,
-					BCM8704_PHYXS_CONTROL_REG,
-					&phyxs_ctl.value)) != NXGE_OK)
-				goto fail;
-			delay++;
-		} while ((phyxs_ctl.bits.reset) && (delay < 100));
-		if (delay == 100) {
-			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				"nxge_xcvr_init: "
-				"failed to reset Transceiver on port<%d>",
-				portn));
-			status = NXGE_ERROR;
-			goto fail;
-		}
-
-		/* Set to 0x7FBF */
-		ctl.value = 0;
-		ctl.bits.res1 = 0x3F;
-		ctl.bits.optxon_lvl = 1;
-		ctl.bits.oprxflt_lvl = 1;
-		ctl.bits.optrxlos_lvl = 1;
-		ctl.bits.optxflt_lvl = 1;
-		ctl.bits.opprflt_lvl = 1;
-		ctl.bits.obtmpflt_lvl = 1;
-		ctl.bits.opbiasflt_lvl = 1;
-		ctl.bits.optxrst_lvl = 1;
-		if ((status = nxge_mdio_write(nxgep,
-				phy_port_addr,
-				BCM8704_USER_DEV3_ADDR,
-				BCM8704_USER_CONTROL_REG, ctl.value))
-				!= NXGE_OK)
-			goto fail;
-
-		/* Set to 0x164 */
-		tx_ctl.value = 0;
-		tx_ctl.bits.tsck_lpwren = 1;
-		tx_ctl.bits.tx_dac_txck = 0x2;
-		tx_ctl.bits.tx_dac_txd = 0x1;
-		tx_ctl.bits.xfp_clken = 1;
-		if ((status = nxge_mdio_write(nxgep,
-				phy_port_addr,
-				BCM8704_USER_DEV3_ADDR,
-				BCM8704_USER_PMD_TX_CONTROL_REG, tx_ctl.value))
-				!= NXGE_OK)
-			goto fail;
-		/*
-		 * According to Broadcom's instruction, SW needs to read
-		 * back these registers twice after written.
-		 */
-		if ((status = nxge_mdio_read(nxgep,
-				phy_port_addr,
-				BCM8704_USER_DEV3_ADDR,
-				BCM8704_USER_CONTROL_REG, &val))
-				!= NXGE_OK)
-			goto fail;
-
-		if ((status = nxge_mdio_read(nxgep,
-				phy_port_addr,
-				BCM8704_USER_DEV3_ADDR,
-				BCM8704_USER_CONTROL_REG, &val))
-				!= NXGE_OK)
-			goto fail;
-
-		if ((status = nxge_mdio_read(nxgep,
-				phy_port_addr,
-				BCM8704_USER_DEV3_ADDR,
-				BCM8704_USER_PMD_TX_CONTROL_REG, &val))
-				!= NXGE_OK)
-			goto fail;
-
-		if ((status = nxge_mdio_read(nxgep,
-				phy_port_addr,
-				BCM8704_USER_DEV3_ADDR,
-				BCM8704_USER_PMD_TX_CONTROL_REG, &val))
-				!= NXGE_OK)
-			goto fail;
-
-
-		/* Enable Tx and Rx LEDs to be driven by traffic */
-		if ((status = nxge_mdio_read(nxgep,
-					phy_port_addr,
-					BCM8704_USER_DEV3_ADDR,
-					BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
-					&op_ctr.value)) != NXGE_OK)
-			goto fail;
-		op_ctr.bits.gpio_sel = 0x3;
-		if ((status = nxge_mdio_write(nxgep,
-					phy_port_addr,
-					BCM8704_USER_DEV3_ADDR,
-					BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
-					op_ctr.value)) != NXGE_OK)
-			goto fail;
-
-		NXGE_DELAY(1000000);
-
-		/* Set BCM8704 Internal Loopback mode if necessary */
-		if ((status = nxge_mdio_read(nxgep,
-					phy_port_addr,
-					BCM8704_PCS_DEV_ADDR,
-					BCM8704_PCS_CONTROL_REG,
-					&pcs_ctl.value)) != NXGE_OK)
-			goto fail;
-		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
-			pcs_ctl.bits.loopback = 1;
-		else
-			pcs_ctl.bits.loopback = 0;
-		if ((status = nxge_mdio_write(nxgep,
-					phy_port_addr,
-					BCM8704_PCS_DEV_ADDR,
-					BCM8704_PCS_CONTROL_REG,
-					pcs_ctl.value)) != NXGE_OK)
-			goto fail;
-
-		status = nxge_mdio_read(nxgep, phy_port_addr,
-				0x1, 0xA, &val);
+	if (nxgep->xcvr.xcvr_init) {
+		status = nxgep->xcvr.xcvr_init(nxgep);
 		if (status != NXGE_OK)
 			goto fail;
-		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				"BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n",
-				portn, val));
-		status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
-		if (status != NXGE_OK)
-			goto fail;
-		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				"BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n",
-				portn, val));
-		status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
-		if (status != NXGE_OK)
-			goto fail;
-		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				"BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n",
-				portn, val));
-
-#ifdef	NXGE_DEBUG
-		/* Diagnose link issue if link is not up */
-		status = nxge_mdio_read(nxgep, phy_port_addr,
-					BCM8704_USER_DEV3_ADDR,
-					BCM8704_USER_ANALOG_STATUS0_REG,
-					&val);
-		if (status != NXGE_OK)
-			goto fail;
-
-		status = nxge_mdio_read(nxgep, phy_port_addr,
-					BCM8704_USER_DEV3_ADDR,
-					BCM8704_USER_ANALOG_STATUS0_REG,
-					&val);
-		if (status != NXGE_OK)
-			goto fail;
-
-		status = nxge_mdio_read(nxgep, phy_port_addr,
-					BCM8704_USER_DEV3_ADDR,
-					BCM8704_USER_TX_ALARM_STATUS_REG,
-					&val1);
-		if (status != NXGE_OK)
-			goto fail;
-
-		status = nxge_mdio_read(nxgep, phy_port_addr,
-					BCM8704_USER_DEV3_ADDR,
-					BCM8704_USER_TX_ALARM_STATUS_REG,
-					&val1);
-		if (status != NXGE_OK)
-			goto fail;
-
-		if (val != 0x3FC) {
-			if ((val == 0x43BC) && (val1 != 0)) {
-				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-					"Cable not connected to peer or bad"
-					" cable on port<%d>\n", portn));
-			} else if (val == 0x639C) {
-				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-					"Optical module (XFP) is bad or absence"
-					" on port<%d>\n", portn));
-			}
-		}
-#endif
-
-		statsp->mac_stats.cap_10gfdx = 1;
-		statsp->mac_stats.lp_cap_10gfdx = 1;
-		break;
-	case PORT_10G_COPPER:
-		break;
-	case PORT_1G_FIBER:
-	case PORT_1G_COPPER:
-		/* Set Clause 22 */
-		npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
-
-		/* Set capability flags */
-		statsp->mac_stats.cap_1000fdx =
-					param_arr[param_anar_1000fdx].value;
-		statsp->mac_stats.cap_100fdx =
-					param_arr[param_anar_100fdx].value;
-		statsp->mac_stats.cap_10fdx = param_arr[param_anar_10fdx].value;
-
-		if ((status = nxge_mii_xcvr_init(nxgep)) != NXGE_OK)
-			goto fail;
-		break;
-	default:
-		goto fail;
+		statsp->mac_stats.xcvr_inits++;
 	}
 
-	statsp->mac_stats.xcvr_inits++;
-
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
+	    portn));
 	return (NXGE_OK);
 
 fail:
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-		"nxge_xcvr_init: failed to initialize transceiver for port<%d>",
-		portn));
+	    "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
+	    portn));
 	return (status);
 }
 
@@ -1617,58 +1724,122 @@
 	return (NXGE_ERROR | rs);
 }
 
-
-/* Enable/Disable MII Link Status change interrupt */
+/* 10G fiber link interrupt start routine */
+
+static nxge_status_t
+nxge_10G_link_intr_start(p_nxge_t nxgep)
+{
+	npi_status_t	rs = NPI_SUCCESS;
+	uint8_t		portn = nxgep->mac.portnum;
+
+	rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn);
+
+	if (rs != NPI_SUCCESS)
+		return (NXGE_ERROR | rs);
+	else
+		return (NXGE_OK);
+}
+
+/* 10G fiber link interrupt stop routine */
+
+static nxge_status_t
+nxge_10G_link_intr_stop(p_nxge_t nxgep)
+{
+	npi_status_t	rs = NPI_SUCCESS;
+	uint8_t		portn = nxgep->mac.portnum;
+
+	rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn);
+
+	if (rs != NPI_SUCCESS)
+		return (NXGE_ERROR | rs);
+	else
+		return (NXGE_OK);
+}
+
+/* 1G fiber link interrupt start routine */
+
+static nxge_status_t
+nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)
+{
+	npi_status_t	rs = NPI_SUCCESS;
+	uint8_t		portn = nxgep->mac.portnum;
+
+	rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn);
+	if (rs != NPI_SUCCESS)
+		return (NXGE_ERROR | rs);
+	else
+		return (NXGE_OK);
+}
+
+/* 1G fiber link interrupt stop routine */
+
+static nxge_status_t
+nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)
+{
+	npi_status_t	rs = NPI_SUCCESS;
+	uint8_t		portn = nxgep->mac.portnum;
+
+	rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn);
+
+	if (rs != NPI_SUCCESS)
+		return (NXGE_ERROR | rs);
+	else
+		return (NXGE_OK);
+}
+
+/* 1G copper link interrupt start routine */
+
+static nxge_status_t
+nxge_1G_copper_link_intr_start(p_nxge_t nxgep)
+{
+	npi_status_t	rs = NPI_SUCCESS;
+	uint8_t		portn = nxgep->mac.portnum;
+
+	rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn,
+	    MII_BMSR, BMSR_LSTATUS);
+
+	if (rs != NPI_SUCCESS)
+		return (NXGE_ERROR | rs);
+	else
+		return (NXGE_OK);
+}
+
+/* 1G copper link interrupt stop routine */
+
+static nxge_status_t
+nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)
+{
+	npi_status_t	rs = NPI_SUCCESS;
+	uint8_t		portn = nxgep->mac.portnum;
+
+	rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn);
+
+	if (rs != NPI_SUCCESS)
+		return (NXGE_ERROR | rs);
+	else
+		return (NXGE_OK);
+}
+
+/* Enable/Disable Link Status change interrupt */
 
 nxge_status_t
 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
 {
-	uint8_t			portn;
-	nxge_port_mode_t	portmode;
-	npi_status_t		rs = NPI_SUCCESS;
+	uint8_t		portn;
+	nxge_status_t	status = NXGE_OK;
 
 	portn = nxgep->mac.portnum;
-	portmode = nxgep->mac.portmode;
 
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
-
-	if (enable == LINK_INTR_START) {
-		if (portmode == PORT_10G_FIBER) {
-			if ((rs = npi_xmac_xpcs_link_intr_enable(
-						nxgep->npi_handle,
-						portn)) != NPI_SUCCESS)
-				goto fail;
-		} else if (portmode == PORT_1G_FIBER) {
-			if ((rs = npi_mac_pcs_link_intr_enable(
-						nxgep->npi_handle,
-						portn)) != NPI_SUCCESS)
-				goto fail;
-		} else if (portmode == PORT_1G_COPPER) {
-			if ((rs = npi_mac_mif_link_intr_enable(
-				nxgep->npi_handle,
-				portn, MII_BMSR, BMSR_LSTATUS)) != NPI_SUCCESS)
-				goto fail;
-		} else
-			goto fail;
-	} else if (enable == LINK_INTR_STOP) {
-		if (portmode == PORT_10G_FIBER) {
-			if ((rs = npi_xmac_xpcs_link_intr_disable(
-						nxgep->npi_handle,
-						portn)) != NPI_SUCCESS)
-				goto fail;
-		} else  if (portmode == PORT_1G_FIBER) {
-			if ((rs = npi_mac_pcs_link_intr_disable(
-						nxgep->npi_handle,
-						portn)) != NPI_SUCCESS)
-				goto fail;
-		} else if (portmode == PORT_1G_COPPER) {
-			if ((rs = npi_mac_mif_link_intr_disable(
-						nxgep->npi_handle,
-						portn)) != NPI_SUCCESS)
-				goto fail;
-		} else
-			goto fail;
-	}
+	if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start)
+		return (NXGE_OK);
+
+	if (enable == LINK_INTR_START)
+		status = nxgep->xcvr.link_intr_start(nxgep);
+	else if (enable == LINK_INTR_STOP)
+		status = nxgep->xcvr.link_intr_stop(nxgep);
+	if (status != NXGE_OK)
+		goto fail;
 
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
 
@@ -1678,7 +1849,7 @@
 			"nxge_link_intr: Failed to set port<%d> mif intr mode",
 			portn));
 
-	return (NXGE_ERROR | rs);
+	return (status);
 }
 
 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
@@ -2497,7 +2668,7 @@
 
 /* Check status of MII (MIF or PCS) link */
 
-nxge_status_t
+static nxge_status_t
 nxge_check_mii_link(p_nxge_t nxgep)
 {
 	mii_bmsr_t bmsr_ints, bmsr_data;
@@ -2563,7 +2734,8 @@
 
 	/* Workaround for link down issue */
 	if (bmsr_data.value == 0) {
-		cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
+		cmn_err(CE_NOTE, "nxge%d: !LINK DEBUG: Read zero bmsr\n",
+		    nxgep->instance);
 		goto nxge_check_mii_link_exit;
 	}
 
@@ -2599,7 +2771,7 @@
 
 
 /*ARGSUSED*/
-nxge_status_t
+static nxge_status_t
 nxge_check_10g_link(p_nxge_t nxgep)
 {
 	uint8_t		portn;
@@ -2641,7 +2813,7 @@
 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
 				goto fail;
 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-					"Link down cable problem"));
+			    "Link down cable problem"));
 			nxgep->statsp->mac_stats.link_up = 0;
 			nxgep->statsp->mac_stats.link_speed = 0;
 			nxgep->statsp->mac_stats.link_duplex = 0;
@@ -2671,8 +2843,19 @@
 void
 nxge_link_is_down(p_nxge_t nxgep)
 {
+	p_nxge_stats_t statsp;
+	char link_stat_msg[64];
+
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
 
+	statsp = nxgep->statsp;
+	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down",
+	    statsp->mac_stats.xcvr_portn);
+
+	if (nxge_no_msg == B_FALSE) {
+		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
+	}
+
 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
 
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
@@ -2683,10 +2866,24 @@
 void
 nxge_link_is_up(p_nxge_t nxgep)
 {
+	p_nxge_stats_t statsp;
+	char link_stat_msg[64];
 	uint32_t val;
 
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
 
+	statsp = nxgep->statsp;
+	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ",
+	    statsp->mac_stats.xcvr_portn,
+	    statsp->mac_stats.link_speed);
+
+	if (statsp->mac_stats.link_T4)
+		(void) strcat(link_stat_msg, "T4");
+	else if (statsp->mac_stats.link_duplex == 2)
+		(void) strcat(link_stat_msg, "full duplex");
+	else
+		(void) strcat(link_stat_msg, "half duplex");
+
 	(void) nxge_xif_init(nxgep);
 
 	/* Clean up symbol errors incurred during link transition */
@@ -2697,6 +2894,10 @@
 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
 	}
 
+	if (nxge_no_msg == B_FALSE) {
+		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
+	}
+
 	mac_link_update(nxgep->mach, LINK_STATE_UP);
 
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
@@ -2783,25 +2984,17 @@
 			if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
 				return (NXGE_OK);
 
-			switch (nxgep->mac.portmode) {
-			case PORT_10G_FIBER:
-				timerid = timeout((fptrv_t)nxge_check_10g_link,
+			if (nxgep->xcvr.check_link) {
+				timerid = timeout(
+				    (fptrv_t)(nxgep->xcvr.check_link),
 				    nxgep,
 				    drv_usectohz(LINK_MONITOR_PERIOD));
-				break;
-
-			case PORT_1G_COPPER:
-			case PORT_1G_FIBER:
-				timerid = timeout((fptrv_t)nxge_check_mii_link,
-				    nxgep,
-				    drv_usectohz(LINK_MONITOR_PERIOD));
-				break;
-			default:
+				MUTEX_ENTER(&nxgep->poll_lock);
+				nxgep->nxge_link_poll_timerid = timerid;
+				MUTEX_EXIT(&nxgep->poll_lock);
+			} else {
 				return (NXGE_ERROR);
 			}
-			MUTEX_ENTER(&nxgep->poll_lock);
-			nxgep->nxge_link_poll_timerid = timerid;
-			MUTEX_EXIT(&nxgep->poll_lock);
 		}
 	} else {
 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
@@ -2853,8 +3046,7 @@
 {
 	nxge_status_t status = NXGE_OK;
 
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-		"==> nxge_set_promisc: on %d", on));
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
 
 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
 
@@ -2880,7 +3072,7 @@
 fail:
 	RW_EXIT(&nxgep->filter_lock);
 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
-			"Unable to set promisc (%d)", on));
+	    "Unable to set promisc (%d)", on));
 
 	return (status);
 }
@@ -2935,7 +3127,7 @@
 
 	ldgp = ldvp->ldgp;
 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
-		"group %d", ldgp->ldg));
+	    "group %d", ldgp->ldg));
 
 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
 	/*
@@ -2946,7 +3138,7 @@
 	portn = nxgep->mac.portnum;
 
 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
-		"==> nxge_mac_intr: reading mac stats: port<%d>", portn));
+	    "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
 
 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
 		rs = npi_xmac_tx_get_istatus(handle, portn,
@@ -3297,115 +3489,11 @@
 	return (status);
 }
 
-
-nxge_status_t
-nxge_get_xcvr_type(p_nxge_t nxgep)
-{
-	nxge_status_t status = NXGE_OK;
-	char *phy_type;
-	char *prop_val;
-
-	if (nxgep->niu_type == N2_NIU) {
-		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
-		    "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
-			if (strcmp("xgf", prop_val) == 0) {
-				nxgep->statsp->mac_stats.xcvr_inuse =
-				    XPCS_XCVR;
-				nxgep->mac.portmode = PORT_10G_FIBER;
-				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				    "10G Fiber Xcvr"));
-			} else if (strcmp("mif", prop_val) == 0) {
-				nxgep->statsp->mac_stats.xcvr_inuse =
-				    INT_MII_XCVR;
-				nxgep->mac.portmode = PORT_1G_COPPER;
-				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				    "1G Copper Xcvr"));
-			} else if (strcmp("pcs", prop_val) == 0) {
-				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
-				nxgep->mac.portmode = PORT_1G_FIBER;
-				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				    "1G Fiber Xcvr"));
-			} else if (strcmp("xgc", prop_val) == 0) {
-				nxgep->statsp->mac_stats.xcvr_inuse =
-				    XPCS_XCVR;
-				nxgep->mac.portmode = PORT_10G_COPPER;
-				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-				    "10G Copper Xcvr"));
-			} else {
-				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				    "Unknown phy-type: %s", prop_val));
-				ddi_prop_free(prop_val);
-				return (NXGE_ERROR);
-			}
-			status = NXGE_OK;
-			(void) ddi_prop_update_string(DDI_DEV_T_NONE,
-			    nxgep->dip, "phy-type", prop_val);
-			ddi_prop_free(prop_val);
-			return (status);
-		} else {
-			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-			    "Exiting...phy-type property not found"));
-			return (NXGE_ERROR);
-		}
-	}
-
-	if (!nxgep->vpd_info.ver_valid) {
-		/*
-		 * read the phy type from the SEEPROM - NCR registers
-		 */
-		status = nxge_espc_phy_type_get(nxgep);
-		if (status != NXGE_OK)
-			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
-			    "[%s] invalid...please update",
-			    nxgep->vpd_info.ver));
-		return (status);
-	}
-
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-	    "Reading phy type from expansion ROM"));
-	/*
-	 * Try to read the phy type from the vpd data read off the
-	 * expansion ROM.
-	 */
-	phy_type = nxgep->vpd_info.phy_type;
-	if (phy_type[0] == 'm' && phy_type[1] == 'i' && phy_type[2] == 'f') {
-		nxgep->mac.portmode = PORT_1G_COPPER;
-		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
-	} else if (phy_type[0] == 'x' && phy_type[1] == 'g' &&
-	    phy_type[2] == 'f') {
-		nxgep->mac.portmode = PORT_10G_FIBER;
-		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
-	} else if (phy_type[0] == 'p' && phy_type[1] == 'c' &&
-	    phy_type[2] == 's') {
-		nxgep->mac.portmode = PORT_1G_FIBER;
-		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
-	} else if (phy_type[0] == 'x' && phy_type[1] == 'g' &&
-	    phy_type[2] == 'c') {
-		nxgep->mac.portmode = PORT_10G_COPPER;
-		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
-	} else {
-		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
-		    "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
-		    phy_type[0], phy_type[1], phy_type[2]));
-		/*
-		 * read the phy type from the SEEPROM - NCR registers
-		 */
-		status = nxge_espc_phy_type_get(nxgep);
-		if (status != NXGE_OK)
-			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
-			    "[%s] invalid...please update",
-			    nxgep->vpd_info.ver));
-	}
-
-	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
-	return (status);
-}
-
 nxge_status_t
 nxge_10g_link_led_on(p_nxge_t nxgep)
 {
 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
-							!= NPI_SUCCESS)
+	    != NPI_SUCCESS)
 		return (NXGE_ERROR);
 	else
 		return (NXGE_OK);
@@ -3415,12 +3503,455 @@
 nxge_10g_link_led_off(p_nxge_t nxgep)
 {
 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
-							!= NPI_SUCCESS)
+	    != NPI_SUCCESS)
 		return (NXGE_ERROR);
 	else
 		return (NXGE_OK);
 }
 
+/* Check if the given id read using the given MDIO Clause is supported */
+
+static boolean_t
+nxge_is_supported_phy(uint32_t id, uint8_t type)
+{
+	int		i;
+	int		cl45_arr_len = NUM_CLAUSE_45_IDS;
+	int		cl22_arr_len = NUM_CLAUSE_22_IDS;
+	boolean_t	found = B_FALSE;
+
+	switch (type) {
+	case CLAUSE_45_TYPE:
+		for (i = 0; i < cl45_arr_len; i++) {
+			if ((nxge_supported_cl45_ids[i] & PHY_ID_MASK) ==
+			    (id & PHY_ID_MASK)) {
+				found = B_TRUE;
+				break;
+			}
+		}
+		break;
+	case CLAUSE_22_TYPE:
+		for (i = 0; i < cl22_arr_len; i++) {
+			if ((nxge_supported_cl22_ids[i] & PHY_ID_MASK) ==
+			    (id & PHY_ID_MASK)) {
+				found = B_TRUE;
+				break;
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	return (found);
+}
+
+/*
+ * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
+ * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO
+ * read. Then use the values obtained to determine the phy type of each port
+ * and the Neptune type.
+ */
+
+nxge_status_t
+nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p)
+{
+	int		i, j, k, l;
+	uint16_t	val1 = 0;
+	uint16_t	val2 = 0;
+	uint32_t	pma_pmd_dev_id = 0;
+	uint32_t	pcs_dev_id = 0;
+	uint32_t	phy_id = 0;
+	uint32_t	port_pma_pmd_dev_id[4];
+	uint32_t	port_pcs_dev_id[4];
+	uint32_t	port_phy_id[4];
+	uint8_t		pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS];
+	uint8_t		pcs_dev_fd[NXGE_MAX_PHY_PORTS];
+	uint8_t		phy_fd[NXGE_MAX_PHY_PORTS];
+	uint8_t		port_fd[NXGE_MAX_PHY_PORTS];
+	uint8_t		total_port_fd, total_phy_fd;
+	nxge_status_t	status = NXGE_OK;
+	npi_status_t	npi_status = NPI_SUCCESS;
+	npi_handle_t	handle;
+	int		prt_id = -1;
+
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+	    "==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
+	    nxgep->niu_type));
+
+	handle = NXGE_DEV_NPI_HANDLE(nxgep);
+	j = k = l = 0;
+	total_port_fd = total_phy_fd = 0;
+	/*
+	 * Clause 45 and Clause 22 port/phy addresses 0 through 7 are reserved
+	 * for on chip serdes usages.
+	 */
+	for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
+		(void) npi_mac_mif_mdio_read(handle, i, NXGE_PMA_PMD_DEV_ADDR,
+		    NXGE_DEV_ID_REG_1, &val1);
+		(void) npi_mac_mif_mdio_read(handle, i, NXGE_PMA_PMD_DEV_ADDR,
+		    NXGE_DEV_ID_REG_2, &val2);
+		pma_pmd_dev_id = val1;
+		pma_pmd_dev_id = (pma_pmd_dev_id << 16);
+		pma_pmd_dev_id |= val2;
+		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD "
+		    "devid[0x%llx]", i, pma_pmd_dev_id));
+
+		if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) {
+			pma_pmd_dev_fd[i] = 1;
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
+			    "PMA/PMD dev found", i));
+			if (j < 4) {
+				port_pma_pmd_dev_id[j] = pma_pmd_dev_id;
+				j++;
+			}
+		} else {
+			pma_pmd_dev_fd[i] = 0;
+		}
+
+		(void) npi_mac_mif_mdio_read(handle, i, NXGE_PCS_DEV_ADDR,
+		    NXGE_DEV_ID_REG_1, &val1);
+		(void) npi_mac_mif_mdio_read(handle, i, NXGE_PCS_DEV_ADDR,
+		    NXGE_DEV_ID_REG_2, &val2);
+		pcs_dev_id = val1;
+		pcs_dev_id = (pcs_dev_id << 16);
+		pcs_dev_id |= val2;
+		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
+		    "devid[0x%llx]", i, pcs_dev_id));
+
+		if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) {
+			pcs_dev_fd[i] = 1;
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
+			    "dev found", i));
+			if (k < 4) {
+				port_pcs_dev_id[k] = pcs_dev_id;
+				k++;
+			}
+		} else {
+			pcs_dev_fd[i] = 0;
+		}
+
+		if (pcs_dev_fd[i] || pma_pmd_dev_fd[i])
+			port_fd[i] = 1;
+		else
+			port_fd[i] = 0;
+		total_port_fd += port_fd[i];
+
+		npi_status = npi_mac_mif_mii_read(handle, i,
+		    NXGE_PHY_ID_REG_1, &val1);
+		if (npi_status != NPI_SUCCESS) {
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
+			    "clause 22 read to reg 2 failed!!!"));
+			goto error_exit;
+		}
+		npi_status = npi_mac_mif_mii_read(handle, i,
+		    NXGE_PHY_ID_REG_2, &val2);
+		if (npi_status != 0) {
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
+			    "clause 22 read to reg 3 failed!!!"));
+			goto error_exit;
+		}
+		phy_id = val1;
+		phy_id = (phy_id << 16);
+		phy_id |= val2;
+		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
+		    "[0x%llx]", i, phy_id));
+
+		if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
+			phy_fd[i] = 1;
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
+			    "found", i));
+			if (l < 4) {
+				port_phy_id[l] = phy_id;
+				l++;
+			}
+		} else {
+			phy_fd[i] = 0;
+		}
+		total_phy_fd += phy_fd[i];
+	}
+
+	switch (total_port_fd) {
+	case 2:
+		switch (total_phy_fd) {
+		case 2:
+			/* 2 10G, 2 1G */
+			if (((port_pcs_dev_id[0] == PHY_10G_FIBRE &&
+			    port_pcs_dev_id[1] == PHY_10G_FIBRE) ||
+			    (port_pma_pmd_dev_id[0] == PHY_10G_FIBRE &&
+			    port_pma_pmd_dev_id[1] == PHY_10G_FIBRE)) &&
+			    (port_phy_id[0] == PHY_1G_COPPER &&
+			    port_phy_id[1] == PHY_1G_COPPER)) {
+				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
+			} else {
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Unsupported neptune type 1"));
+				goto error_exit;
+			}
+			break;
+		case 1:
+			/* TODO - 2 10G, 1 1G */
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 2 10G, 1 1G"));
+			goto error_exit;
+		case 0:
+			/* 2 10G */
+			if ((port_pcs_dev_id[0] == PHY_10G_FIBRE &&
+			    port_pcs_dev_id[1] == PHY_10G_FIBRE) ||
+			    (port_pma_pmd_dev_id[0] == PHY_10G_FIBRE &&
+			    port_pma_pmd_dev_id[1] == PHY_10G_FIBRE)) {
+				hw_p->niu_type = NEPTUNE_2_10GF;
+			} else {
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Unsupported neptune type 2"));
+				goto error_exit;
+			}
+			break;
+		case 4:
+			/* Maramba with 2 XAUI */
+			if (((port_pcs_dev_id[0] == PHY_10G_FIBRE &&
+			    port_pcs_dev_id[1] == PHY_10G_FIBRE) ||
+			    (port_pma_pmd_dev_id[0] == PHY_10G_FIBRE &&
+			    port_pma_pmd_dev_id[1] == PHY_10G_FIBRE)) &&
+			    (port_phy_id[0] == PHY_1G_COPPER &&
+			    port_phy_id[1] == PHY_1G_COPPER &&
+			    port_phy_id[2] == PHY_1G_COPPER &&
+			    port_phy_id[3] == PHY_1G_COPPER)) {
+				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
+
+				/*
+				 * Check the first phy port address against
+				 * the known phy start addresses to determine
+				 * the platform type.
+				 */
+				for (i = NXGE_EXT_PHY_PORT_ST;
+				    i < NXGE_MAX_PHY_PORTS; i++) {
+					if (phy_fd[i] == 1)
+						break;
+				}
+				if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) {
+					hw_p->platform_type =
+					    P_NEPTUNE_MARAMBA_P0;
+				} else if (i ==
+				    BCM5464_MARAMBA_P1_PORT_ADDR_BASE) {
+					hw_p->platform_type =
+					    P_NEPTUNE_MARAMBA_P1;
+				} else {
+					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+					    "Unknown port %d...Cannot "
+					    "determine platform type", i));
+				}
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Maramba with 2 XAUI"));
+			} else {
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Unsupported neptune type 3"));
+				goto error_exit;
+			}
+			break;
+		default:
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 5"));
+			goto error_exit;
+		}
+	case 1:
+		switch (total_phy_fd) {
+		case 3:
+			if (((port_pcs_dev_id[0] & PHY_ID_MASK) ==
+			    (BCM8704_DEV_ID & PHY_ID_MASK)) ||
+			    ((port_pma_pmd_dev_id[0] & PHY_ID_MASK) ==
+			    (BCM8704_DEV_ID & PHY_ID_MASK))) {
+				/* The 10G port is BCM8704 */
+				for (i = NXGE_EXT_PHY_PORT_ST;
+				    i < NXGE_MAX_PHY_PORTS; i++) {
+					if (port_fd[i] == 1) {
+						prt_id = i;
+						break;
+					}
+				}
+
+				if (nxgep->niu_type == N2_NIU)
+					prt_id %= BCM8704_N2_PORT_ADDR_BASE;
+				else
+					prt_id %=
+					    BCM8704_NEPTUNE_PORT_ADDR_BASE;
+
+				if (prt_id == 0) {
+					hw_p->niu_type = NEPTUNE_1_10GF_3_1GC;
+				} else if (prt_id == 1) {
+					hw_p->niu_type =
+					    NEPTUNE_1_1GC_1_10GF_2_1GC;
+				} else {
+					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+					    "Unsupported neptune type 6"));
+					goto error_exit;
+				}
+			} else {
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Unsupported neptune type 7"));
+				goto error_exit;
+			}
+			break;
+		case 2:
+			/*
+			 * TODO 2 1G, 1 10G mode.
+			 * Differentiate between 1_1G_1_10G_1_1G and
+			 * 1_10G_2_1G
+			 */
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 8"));
+			goto error_exit;
+		case 1:
+			/*
+			 * TODO 1 1G, 1 10G mode.
+			 * Differentiate between 1_1G_1_10G and
+			 * 1_10G_1_1G
+			 */
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 9"));
+			goto error_exit;
+		case 0:
+			/* TODO 1 10G mode */
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 10"));
+			goto error_exit;
+		case 4:
+			/* Maramba with 1 XAUI */
+			if (((port_pcs_dev_id[0] & PHY_ID_MASK) ==
+			    (BCM8704_DEV_ID & PHY_ID_MASK)) ||
+			    ((port_pma_pmd_dev_id[0] & PHY_ID_MASK) ==
+			    (BCM8704_DEV_ID & PHY_ID_MASK))) {
+				/* The 10G port is BCM8704 */
+				for (i = NXGE_EXT_PHY_PORT_ST;
+				    i < NXGE_MAX_PHY_PORTS; i++) {
+					if (port_fd[i] == 1) {
+						prt_id = i;
+						break;
+					}
+				}
+
+				prt_id %= BCM8704_MARAMBA_PORT_ADDR_BASE;
+				if (prt_id == 0) {
+					hw_p->niu_type = NEPTUNE_1_10GF_3_1GC;
+				} else if (prt_id == 1) {
+					hw_p->niu_type =
+					    NEPTUNE_1_1GC_1_10GF_2_1GC;
+				} else {
+					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+					    "Unsupported neptune type 11"));
+					goto error_exit;
+				}
+
+				/*
+				 * Check the first phy port address against
+				 * the known phy start addresses to determine
+				 * the platform type.
+				 */
+				for (i = NXGE_EXT_PHY_PORT_ST;
+				    i < NXGE_MAX_PHY_PORTS; i++) {
+					if (phy_fd[i] == 1)
+						break;
+				}
+
+				if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) {
+					hw_p->platform_type =
+					    P_NEPTUNE_MARAMBA_P0;
+				} else if (i ==
+				    BCM5464_MARAMBA_P1_PORT_ADDR_BASE) {
+					hw_p->platform_type =
+					    P_NEPTUNE_MARAMBA_P1;
+				} else {
+					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+					    "Unknown port %d...Cannot "
+					    "determine platform type", i));
+				}
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Maramba with 1 XAUI"));
+			} else {
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Unsupported neptune type 12"));
+				goto error_exit;
+			}
+			break;
+		default:
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 13"));
+			goto error_exit;
+		}
+		break;
+	case 0:
+		switch (total_phy_fd) {
+		case 4:
+			if (((port_phy_id[0] & PHY_ID_MASK) ==
+			    (BCM5464R_PHY_ID & PHY_ID_MASK)) &&
+			    ((port_phy_id[1] & PHY_ID_MASK) ==
+			    (BCM5464R_PHY_ID & PHY_ID_MASK)) &&
+			    ((port_phy_id[2] & PHY_ID_MASK) ==
+			    (BCM5464R_PHY_ID & PHY_ID_MASK)) &&
+			    ((port_phy_id[3] & PHY_ID_MASK) ==
+			    (BCM5464R_PHY_ID & PHY_ID_MASK))) {
+
+				hw_p->niu_type = NEPTUNE_4_1GC;
+
+				/*
+				 * Check the first phy port address against
+				 * the known phy start addresses to determine
+				 * the platform type.
+				 */
+				for (i = NXGE_EXT_PHY_PORT_ST;
+				    i < NXGE_MAX_PHY_PORTS; i++) {
+					if (phy_fd[i] == 1)
+						break;
+				}
+
+				if (i == BCM5464_MARAMBA_P1_PORT_ADDR_BASE) {
+					hw_p->platform_type =
+					    P_NEPTUNE_MARAMBA_P1;
+				}
+			} else {
+				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+				    "Unsupported neptune type 14"));
+				goto error_exit;
+			}
+			break;
+		case 3:
+			/* TODO 3 1G mode */
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 15"));
+			goto error_exit;
+		case 2:
+			/* TODO 2 1G mode */
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 16"));
+			goto error_exit;
+		case 1:
+			/* TODO 1 1G mode */
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 17"));
+			goto error_exit;
+		default:
+			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+			    "Unsupported neptune type 18, total phy fd %d",
+			    total_phy_fd));
+			goto error_exit;
+		}
+		break;
+	default:
+		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
+		    "Unsupported neptune type 19"));
+		goto error_exit;
+	}
+
+scan_exit:
+
+	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
+	    "niu type [0x%x]\n", hw_p->niu_type));
+	return (status);
+
+error_exit:
+	return (NXGE_ERROR);
+}
+
 boolean_t
 nxge_is_valid_local_mac(ether_addr_st mac_addr)
 {
@@ -3431,3 +3962,61 @@
 	else
 		return (B_TRUE);
 }
+
+static void
+nxge_bcm5464_link_led_off(p_nxge_t nxgep) {
+
+	npi_status_t rs = NPI_SUCCESS;
+	uint8_t xcvr_portn;
+	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
+
+	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off"));
+
+	if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) {
+		xcvr_portn = BCM5464_MARAMBA_P1_PORT_ADDR_BASE;
+	} else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) {
+		xcvr_portn = BCM5464_MARAMBA_P0_PORT_ADDR_BASE;
+	}
+	/*
+	 * For Altas 4-1G copper, Xcvr port numbers are
+	 * swapped with ethernet port number. This is
+	 * designed for better signal integrity in routing.
+	 */
+	switch (portn) {
+	case 0:
+		xcvr_portn += 3;
+		break;
+	case 1:
+		xcvr_portn += 2;
+		break;
+	case 2:
+		xcvr_portn += 1;
+		break;
+	case 3:
+	default:
+		break;
+	}
+
+	MUTEX_ENTER(&nxge_mii_lock);
+	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
+	    xcvr_portn, BCM5464R_MISC, 0xb4ee);
+	if (rs != NPI_SUCCESS) {
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
+		    "returned error 0x[%x]", rs));
+		MUTEX_EXIT(&nxge_mii_lock);
+		return;
+	}
+
+	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
+	    xcvr_portn, BCM5464R_MISC, 0xb8ee);
+	if (rs != NPI_SUCCESS) {
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
+		    "returned error 0x[%x]", rs));
+		MUTEX_EXIT(&nxge_mii_lock);
+		return;
+	}
+
+	MUTEX_EXIT(&nxge_mii_lock);
+}
--- a/usr/src/uts/common/io/nxge/nxge_main.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_main.c	Wed Jul 25 18:20:14 2007 -0700
@@ -334,7 +334,7 @@
 	0xffffffffffffffff,	/* maximum segment size */
 	1,			/* scatter/gather list length */
 	(unsigned int) 1,	/* granularity */
-	DDI_DMA_RELAXED_ORDERING /* attribute flags */
+	0			/* attribute flags */
 };
 
 ddi_dma_lim_t nxge_dma_limits = {
@@ -462,6 +462,16 @@
 		goto nxge_attach_fail;
 	}
 
+	if (nxgep->niu_type == NEPTUNE_2_10GF) {
+		if (nxgep->function_num > 1) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Unsupported"
+			    " function %d. Only functions 0 and 1 are "
+			    "supported for this card.", nxgep->function_num));
+			status = NXGE_ERROR;
+			goto nxge_attach_fail;
+		}
+	}
+
 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
 	nxgep->mac.portnum = portn;
 	if ((portn == 0) || (portn == 1))
@@ -494,7 +504,7 @@
 	/* init stats ptr */
 	nxge_init_statsp(nxgep);
 
-	if (nxgep->niu_type != N2_NIU) {
+	if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_ATLAS) {
 		/*
 		 * read the vpd info from the eeprom into local data
 		 * structure and check for the VPD info validity
@@ -502,7 +512,7 @@
 		(void) nxge_vpd_info_get(nxgep);
 	}
 
-	status = nxge_get_xcvr_type(nxgep);
+	status = nxge_setup_xcvr_table(nxgep);
 
 	if (status != NXGE_OK) {
 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_attach: "
@@ -511,19 +521,6 @@
 		goto nxge_attach_fail;
 	}
 
-	if ((nxgep->niu_type == NEPTUNE) &&
-		(nxgep->mac.portmode == PORT_10G_FIBER)) {
-		nxgep->niu_type = NEPTUNE_2;
-	}
-
-	if ((nxgep->niu_type == NEPTUNE_2) && (nxgep->function_num > 1)) {
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Unsupported function %d."
-		    "Only functions 0 and 1 are supported by this card",
-		    nxgep->function_num));
-		status = NXGE_ERROR;
-		goto nxge_attach_fail;
-	}
-
 	status = nxge_get_config_properties(nxgep);
 
 	if (status != NXGE_OK) {
@@ -810,7 +807,7 @@
 	dev_regs->nxge_msix_regh = NULL;
 	dev_regs->nxge_vir_regh = NULL;
 	dev_regs->nxge_vir2_regh = NULL;
-	nxgep->niu_type = NEPTUNE;
+	nxgep->niu_type = NIU_TYPE_NONE;
 
 	devname = ddi_pathname(nxgep->dip, buf);
 	ASSERT(strlen(devname) > 0);
@@ -852,8 +849,6 @@
 	}
 
 	switch (nxgep->niu_type) {
-	case NEPTUNE:
-	case NEPTUNE_2:
 	default:
 		(void) ddi_dev_regsize(nxgep->dip, 0, &regsize);
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
@@ -1147,10 +1142,10 @@
 		 * handlers.
 		 */
 	MUTEX_INIT(&classify_ptr->tcam_lock, NULL,
-			    NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie);
-	if (nxgep->niu_type == NEPTUNE) {
+	    NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie);
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		MUTEX_INIT(&classify_ptr->fcram_lock, NULL,
-			    NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie);
+		    NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie);
 		for (partition = 0; partition < MAX_PARTITION; partition++) {
 			MUTEX_INIT(&classify_ptr->hash_lock[partition], NULL,
 			    NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie);
@@ -1159,7 +1154,7 @@
 
 nxge_setup_mutexes_exit:
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"<== nxge_setup_mutexes status = %x", status));
+	    "<== nxge_setup_mutexes status = %x", status));
 
 	if (ddi_status != DDI_SUCCESS)
 		status |= (NXGE_ERROR | NXGE_DDI_FAILED);
@@ -1187,7 +1182,7 @@
 	cv_destroy(&nxgep->poll_cv);
 
 	/* free data structures, based on HW type */
-	if (nxgep->niu_type == NEPTUNE) {
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		MUTEX_DESTROY(&classify_ptr->fcram_lock);
 		for (partition = 0; partition < MAX_PARTITION; partition++) {
 			MUTEX_DESTROY(&classify_ptr->hash_lock[partition]);
@@ -1549,50 +1544,50 @@
 	dev_handle = nxgep->dev_regs->nxge_regh;
 	dev_ptr = (char *)nxgep->dev_regs->nxge_regp;
 
-	if (nxgep->niu_type == NEPTUNE) {
+	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		cfg_handle = nxgep->dev_regs->nxge_pciregh;
 		cfg_ptr = (void *)nxgep->dev_regs->nxge_pciregp;
 
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"Neptune PCI regp cfg_ptr 0x%llx", (char *)cfg_ptr));
+		    "Neptune PCI regp cfg_ptr 0x%llx", (char *)cfg_ptr));
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"Neptune PCI cfg_ptr vendor id ptr 0x%llx",
-			&cfg_ptr->vendorid));
+		    "Neptune PCI cfg_ptr vendor id ptr 0x%llx",
+		    &cfg_ptr->vendorid));
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"\tvendorid 0x%x devid 0x%x",
-			NXGE_PIO_READ16(cfg_handle, &cfg_ptr->vendorid, 0),
-			NXGE_PIO_READ16(cfg_handle, &cfg_ptr->devid,    0)));
+		    "\tvendorid 0x%x devid 0x%x",
+		    NXGE_PIO_READ16(cfg_handle, &cfg_ptr->vendorid, 0),
+		    NXGE_PIO_READ16(cfg_handle, &cfg_ptr->devid,    0)));
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"PCI BAR: base 0x%x base14 0x%x base 18 0x%x "
-			"bar1c 0x%x",
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base,   0),
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base14, 0),
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base18, 0),
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base1c, 0)));
+		    "PCI BAR: base 0x%x base14 0x%x base 18 0x%x "
+		    "bar1c 0x%x",
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base,   0),
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base14, 0),
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base18, 0),
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base1c, 0)));
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"\nNeptune PCI BAR: base20 0x%x base24 0x%x "
-			"base 28 0x%x bar2c 0x%x\n",
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base20, 0),
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base24, 0),
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base28, 0),
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base2c, 0)));
+		    "\nNeptune PCI BAR: base20 0x%x base24 0x%x "
+		    "base 28 0x%x bar2c 0x%x\n",
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base20, 0),
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base24, 0),
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base28, 0),
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base2c, 0)));
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"\nNeptune PCI BAR: base30 0x%x\n",
-			NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base30, 0)));
+		    "\nNeptune PCI BAR: base30 0x%x\n",
+		    NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base30, 0)));
 
 		cfg_handle = nxgep->dev_regs->nxge_pciregh;
 		cfg_ptr = (void *)nxgep->dev_regs->nxge_pciregp;
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			"first  0x%llx second 0x%llx third 0x%llx "
-			"last 0x%llx ",
-			NXGE_PIO_READ64(dev_handle,
-				    (uint64_t *)(dev_ptr + 0),  0),
-			NXGE_PIO_READ64(dev_handle,
-				    (uint64_t *)(dev_ptr + 8),  0),
-			NXGE_PIO_READ64(dev_handle,
-				    (uint64_t *)(dev_ptr + 16), 0),
-			NXGE_PIO_READ64(cfg_handle,
-				    (uint64_t *)(dev_ptr + 24), 0)));
+		    "first  0x%llx second 0x%llx third 0x%llx "
+		    "last 0x%llx ",
+		    NXGE_PIO_READ64(dev_handle,
+		    (uint64_t *)(dev_ptr + 0),  0),
+		    NXGE_PIO_READ64(dev_handle,
+		    (uint64_t *)(dev_ptr + 8),  0),
+		    NXGE_PIO_READ64(dev_handle,
+		    (uint64_t *)(dev_ptr + 16), 0),
+		    NXGE_PIO_READ64(cfg_handle,
+		    (uint64_t *)(dev_ptr + 24), 0)));
 	}
 }
 
@@ -1636,15 +1631,7 @@
 	nxge_status_t	status = NXGE_OK;
 
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_setup_dev port %d",
-			nxgep->mac.portnum));
-
-	status = nxge_xcvr_find(nxgep);
-	if (status != NXGE_OK) {
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-			    " nxge_setup_dev status "
-			    " (xcvr find 0x%08x)", status));
-		goto nxge_setup_dev_exit;
-	}
+	    nxgep->mac.portnum));
 
 	status = nxge_link_init(nxgep);
 
@@ -4147,8 +4134,6 @@
 
 	nrequired = 0;
 	switch (nxgep->niu_type) {
-	case NEPTUNE:
-	case NEPTUNE_2:
 	default:
 		status = nxge_ldgv_init(nxgep, &nactual, &nrequired);
 		break;
@@ -4311,8 +4296,6 @@
 
 	nrequired = 0;
 	switch (nxgep->niu_type) {
-	case NEPTUNE:
-	case NEPTUNE_2:
 	default:
 		status = nxge_ldgv_init(nxgep, &nactual, &nrequired);
 		break;
@@ -4694,6 +4677,13 @@
 		hw_p->ndevs++;
 		hw_p->nxge_p[nxgep->function_num] = nxgep;
 		hw_p->next = nxge_hw_list;
+		if (nxgep->niu_type == N2_NIU) {
+			hw_p->niu_type = N2_NIU;
+			hw_p->platform_type = P_NEPTUNE_NIU;
+		} else {
+			hw_p->niu_type = NIU_TYPE_NONE;
+			hw_p->platform_type = P_NEPTUNE_ATLAS;
+		}
 
 		MUTEX_INIT(&hw_p->nxge_cfg_lock, NULL, MUTEX_DRIVER, NULL);
 		MUTEX_INIT(&hw_p->nxge_tcam_lock, NULL, MUTEX_DRIVER, NULL);
@@ -4702,9 +4692,22 @@
 		MUTEX_INIT(&hw_p->nxge_mii_lock, NULL, MUTEX_DRIVER, NULL);
 
 		nxge_hw_list = hw_p;
+
+		(void) nxge_scan_ports_phy(nxgep, nxge_hw_list);
 	}
 
 	MUTEX_EXIT(&nxge_common_lock);
+
+	if (nxgep->niu_type != N2_NIU) {
+		nxgep->niu_type = hw_p->niu_type;
+		if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			    "<== nxge_init_common_device"
+			    " Invalid Neptune type [0x%x]", nxgep->niu_type));
+			return (NXGE_ERROR);
+		}
+	}
+
 	NXGE_DEBUG_MSG((nxgep, MOD_CTL,
 		"==> nxge_init_common_device (nxge_hw_list) $%p",
 		nxge_hw_list));
@@ -4804,3 +4807,33 @@
 
 	NXGE_DEBUG_MSG((nxgep, MOD_CTL, "<= nxge_uninit_common_device"));
 }
+
+/*
+ * Determines the number of ports from the given niu_type.
+ * Returns the number of ports, or returns zero on failure.
+ */
+
+int
+nxge_nports_from_niu_type(niu_type_t niu_type)
+{
+	int	nports = 0;
+
+	switch (niu_type) {
+	case N2_NIU:
+		nports = 2;
+		break;
+	case NEPTUNE_2_10GF:
+		nports = 2;
+		break;
+	case NEPTUNE_4_1GC:
+	case NEPTUNE_2_10GF_2_1GC:
+	case NEPTUNE_1_10GF_3_1GC:
+	case NEPTUNE_1_1GC_1_10GF_2_1GC:
+		nports = 4;
+		break;
+	default:
+		break;
+	}
+
+	return (nports);
+}
--- a/usr/src/uts/common/io/nxge/nxge_ndd.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_ndd.c	Wed Jul 25 18:20:14 2007 -0700
@@ -779,6 +779,8 @@
 
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_destroy_param"));
 
+	if (nxgep->param_arr == NULL)
+		return;
 	/*
 	 * Make sure the param_instance is set to a valid device instance.
 	 */
--- a/usr/src/uts/common/io/nxge/nxge_virtual.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_virtual.c	Wed Jul 25 18:20:14 2007 -0700
@@ -44,7 +44,7 @@
 static nxge_status_t nxge_use_default_dma_config_n2(p_nxge_t);
 static void nxge_ldgv_setup(p_nxge_ldg_t *, p_nxge_ldv_t *, uint8_t,
 	uint8_t, int *);
-static void nxge_init_mmac(p_nxge_t);
+static void nxge_init_mmac(p_nxge_t, boolean_t);
 
 uint32_t nxge_use_hw_property = 1;
 uint32_t nxge_groups_per_port = 2;
@@ -83,7 +83,6 @@
 static uint8_t p4_tx_equal[4] = {6, 6, 6, 6};
 static uint8_t p2_rx_fair[2] = {8, 8};
 static uint8_t p2_rx_equal[2] = {8, 8};
-
 static uint8_t p4_rx_fair[4] = {4, 4, 4, 4};
 static uint8_t p4_rx_equal[4] = {4, 4, 4, 4};
 
@@ -94,6 +93,18 @@
 static uint8_t p2_rdcgrp_cls[2] = {1, 1};
 static uint8_t p4_rdcgrp_cls[4] = {1, 1, 1, 1};
 
+static uint8_t rx_4_1G[4] = {4, 4, 4, 4};
+static uint8_t rx_2_10G[2] = {8, 8};
+static uint8_t rx_2_10G_2_1G[4] = {6, 6, 2, 2};
+static uint8_t rx_1_10G_3_1G[4] = {10, 2, 2, 2};
+static uint8_t rx_1_1G_1_10G_2_1G[4] = {2, 10, 2, 2};
+
+static uint8_t tx_4_1G[4] = {6, 6, 6, 6};
+static uint8_t tx_2_10G[2] = {12, 12};
+static uint8_t tx_2_10G_2_1G[4] = {10, 10, 2, 2};
+static uint8_t tx_1_10G_3_1G[4] = {12, 4, 4, 4};
+static uint8_t tx_1_1G_1_10G_2_1G[4] = {4, 12, 4, 4};
+
 typedef enum {
 	DEFAULT = 0,
 	EQUAL,
@@ -349,7 +360,7 @@
 	uchar_t *prop_val;
 	uint_t prop_len;
 
-	*niu_type = NEPTUNE;
+	*niu_type = NIU_TYPE_NONE;
 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0,
 			"niu-type", (uchar_t **)&prop_val,
 			&prop_len) == DDI_PROP_SUCCESS) {
@@ -1602,58 +1613,16 @@
 	/*
 	 * Get info on how many ports Neptune card has.
 	 */
-	switch (nxgep->niu_type) {
-	case N2_NIU:
-		nxgep->nports = 2;
-		nxgep->classifier.tcam_size = TCAM_NIU_TCAM_MAX_ENTRY;
-		if (nxgep->function_num > 1) {
-			return (NXGE_ERROR);
-		}
-		break;
-
-	case NEPTUNE_2:
-	case NEPTUNE:
-	default:
-
-		if ((nxgep->niu_type == NEPTUNE_2) &&
-				(nxgep->function_num > 1)) {
-			return (NXGE_ERROR);
-		}
-		if (!nxgep->vpd_info.ver_valid) {
-			status = nxge_espc_num_ports_get(nxgep);
-			if (status != NXGE_OK) {
-				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				    "EEPROM version [%s] invalid...please "
-				    "update", nxgep->vpd_info.ver));
-				return (status);
-			}
-			nxgep->classifier.tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY;
-			break;
-		}
-		/*
-		 * First try to get the no. of ports from the info
-		 * in the VPD read off the EEPROM.
-		 */
-		if ((strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_LP_BM_STR,
-		    strlen(NXGE_QGC_LP_BM_STR)) == 0) ||
-		    (strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_PEM_BM_STR,
-		    strlen(NXGE_QGC_PEM_BM_STR)) == 0)) {
-			nxgep->nports = NXGE_NUM_OF_PORTS_QUAD;
-		} else if ((strncmp(nxgep->vpd_info.bd_model,
-		    NXGE_2XGF_LP_BM_STR, strlen(NXGE_2XGF_LP_BM_STR)) == 0) ||
-		    (strncmp(nxgep->vpd_info.bd_model, NXGE_2XGF_PEM_BM_STR,
-		    strlen(NXGE_2XGF_PEM_BM_STR)) == 0)) {
-			nxgep->nports = NXGE_NUM_OF_PORTS_DUAL;
-		} else {
-			NXGE_DEBUG_MSG((nxgep, VPD_CTL,
-			    "nxge_get_config_properties: port num not set in"
-			    " EEPROM...Reading from SEEPROM"));
-			status = nxge_espc_num_ports_get(nxgep);
-			if (status != NXGE_OK)
-				return (status);
-		}
-		nxgep->classifier.tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY;
-		break;
+	nxgep->nports = nxge_nports_from_niu_type(nxgep->niu_type);
+	if (nxgep->nports <= 0) {
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+		    "<==nxge_get_config_properties: Invalid Neptune type 0x%x",
+		    nxgep->niu_type));
+		return (NXGE_ERROR);
+	}
+	nxgep->classifier.tcam_size = TCAM_NIU_TCAM_MAX_ENTRY;
+	if (nxgep->function_num >= nxgep->nports) {
+		return (NXGE_ERROR);
 	}
 
 	status = nxge_get_mac_addr_properties(nxgep);
@@ -1690,8 +1659,14 @@
 		MUTEX_EXIT(&hw_p->nxge_cfg_lock);
 		status = nxge_use_cfg_n2niu_properties(nxgep);
 		break;
-
-	case NEPTUNE:
+	default:
+		if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			    " nxge_get_config_properties:"
+			    " unknown NIU type 0x%x", nxgep->niu_type));
+			return (NXGE_ERROR);
+		}
+
 		NXGE_DEBUG_MSG((nxgep, VPD_CTL,
 			" ==> nxge_get_config_properties: Neptune"));
 		status = nxge_cfg_verify_set_quick_config(nxgep);
@@ -1712,38 +1687,6 @@
 		nxge_use_cfg_neptune_properties(nxgep);
 		status = NXGE_OK;
 		break;
-
-	case NEPTUNE_2:
-		NXGE_DEBUG_MSG((nxgep, VPD_CTL,
-			" ==> nxge_get_config_properties: Neptune-2"));
-		if (nxgep->function_num > 1)
-			return (NXGE_ERROR);
-		status = nxge_cfg_verify_set_quick_config(nxgep);
-		MUTEX_ENTER(&hw_p->nxge_cfg_lock);
-
-		if ((hw_p->flags & COMMON_CFG_VALID) !=
-			COMMON_CFG_VALID) {
-			status = nxge_cfg_verify_set(nxgep,
-				COMMON_TXDMA_CFG);
-			status = nxge_cfg_verify_set(nxgep,
-				COMMON_RXDMA_CFG);
-			status = nxge_cfg_verify_set(nxgep,
-				COMMON_RXDMA_GRP_CFG);
-			status = nxge_cfg_verify_set(nxgep,
-				COMMON_CLASS_CFG);
-			hw_p->flags |= COMMON_CFG_VALID;
-		}
-		MUTEX_EXIT(&hw_p->nxge_cfg_lock);
-
-		nxge_use_cfg_neptune_properties(nxgep);
-		status = NXGE_OK;
-		break;
-
-	default:
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-			" nxge_get_config_properties:"
-			" unknown NIU type %x", nxgep->niu_type));
-		return (NXGE_ERROR);
 	}
 
 	NXGE_DEBUG_MSG((nxgep, VPD_CTL, " <== nxge_get_config_properties"));
@@ -1990,7 +1933,7 @@
 static void
 nxge_use_cfg_dma_config(p_nxge_t nxgep)
 {
-	int tx_ndmas, rx_ndmas, nrxgp;
+	int tx_ndmas, rx_ndmas, nrxgp, st_txdma, st_rxdma;
 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
 	p_nxge_hw_pt_cfg_t p_cfgp;
 	dev_info_t *dip;
@@ -1998,6 +1941,8 @@
 	char *prop;
 	int *prop_val;
 	uint_t prop_len;
+	int i;
+	uint8_t *ch_arr_p;
 
 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_dma_config"));
 	param_arr = nxgep->param_arr;
@@ -2013,14 +1958,33 @@
 		p_cfgp->start_tdc = *prop_val;
 		ddi_prop_free(prop_val);
 	} else {
-		if (nxgep->nports == 2) {
-			tx_ndmas = (nxgep->function_num * p2_tx_equal[0]);
-		} else {
-			tx_ndmas = (nxgep->function_num * p4_tx_equal[0]);
+		switch (nxgep->niu_type) {
+		case NEPTUNE_4_1GC:
+			ch_arr_p = &tx_4_1G[0];
+			break;
+		case NEPTUNE_2_10GF:
+			ch_arr_p = &tx_2_10G[0];
+			break;
+		case NEPTUNE_2_10GF_2_1GC:
+			ch_arr_p = &tx_2_10G_2_1G[0];
+			break;
+		case NEPTUNE_1_10GF_3_1GC:
+			ch_arr_p = &tx_1_10G_3_1G[0];
+			break;
+		case NEPTUNE_1_1GC_1_10GF_2_1GC:
+			ch_arr_p = &tx_1_1G_1_10G_2_1G[0];
+			break;
+		default:
+			ch_arr_p = &p4_tx_equal[0];
+			break;
 		}
+		st_txdma = 0;
+		for (i = 0; i < nxgep->function_num; i++, ch_arr_p++)
+			st_txdma += *ch_arr_p;
+
 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
-			prop, tx_ndmas);
-		p_cfgp->start_tdc = tx_ndmas;
+		    prop, st_txdma);
+		p_cfgp->start_tdc = st_txdma;
 	}
 
 	prop = param_arr[param_txdma_channels].fcode_name;
@@ -2029,10 +1993,25 @@
 		tx_ndmas = *prop_val;
 		ddi_prop_free(prop_val);
 	} else {
-		if (nxgep->nports == 2) {
-			tx_ndmas = p2_tx_equal[0];
-		} else {
-			tx_ndmas = p4_tx_equal[0];
+		switch (nxgep->niu_type) {
+		case NEPTUNE_4_1GC:
+			tx_ndmas = tx_4_1G[nxgep->function_num];
+			break;
+		case NEPTUNE_2_10GF:
+			tx_ndmas = tx_2_10G[nxgep->function_num];
+			break;
+		case NEPTUNE_2_10GF_2_1GC:
+			tx_ndmas = tx_2_10G_2_1G[nxgep->function_num];
+			break;
+		case NEPTUNE_1_10GF_3_1GC:
+			tx_ndmas = tx_1_10G_3_1G[nxgep->function_num];
+			break;
+		case NEPTUNE_1_1GC_1_10GF_2_1GC:
+			tx_ndmas = tx_1_1G_1_10G_2_1G[nxgep->function_num];
+			break;
+		default:
+			tx_ndmas = p4_tx_equal[nxgep->function_num];
+			break;
 		}
 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
 			prop, tx_ndmas);
@@ -2051,14 +2030,33 @@
 		p_cfgp->start_rdc = *prop_val;
 		ddi_prop_free(prop_val);
 	} else {
-		if (nxgep->nports == 2) {
-			rx_ndmas = (nxgep->function_num * p2_rx_equal[0]);
-		} else {
-			rx_ndmas = (nxgep->function_num * p4_rx_equal[0]);
+		switch (nxgep->niu_type) {
+		case NEPTUNE_4_1GC:
+			ch_arr_p = &rx_4_1G[0];
+			break;
+		case NEPTUNE_2_10GF:
+			ch_arr_p = &rx_2_10G[0];
+			break;
+		case NEPTUNE_2_10GF_2_1GC:
+			ch_arr_p = &rx_2_10G_2_1G[0];
+			break;
+		case NEPTUNE_1_10GF_3_1GC:
+			ch_arr_p = &rx_1_10G_3_1G[0];
+			break;
+		case NEPTUNE_1_1GC_1_10GF_2_1GC:
+			ch_arr_p = &rx_1_1G_1_10G_2_1G[0];
+			break;
+		default:
+			ch_arr_p = &p4_rx_equal[0];
+			break;
 		}
+		st_rxdma = 0;
+		for (i = 0; i < nxgep->function_num; i++, ch_arr_p++)
+			st_rxdma += *ch_arr_p;
+
 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
-			prop, rx_ndmas);
-		p_cfgp->start_rdc = rx_ndmas;
+		    prop, st_rxdma);
+		p_cfgp->start_rdc = st_rxdma;
 	}
 
 	prop = param_arr[param_rxdma_channels].fcode_name;
@@ -2068,10 +2066,25 @@
 		rx_ndmas = *prop_val;
 		ddi_prop_free(prop_val);
 	} else {
-		if (nxgep->nports == 2) {
-			rx_ndmas = p2_rx_equal[0];
-		} else {
-			rx_ndmas = p4_rx_equal[0];
+		switch (nxgep->niu_type) {
+		case NEPTUNE_4_1GC:
+			rx_ndmas = rx_4_1G[nxgep->function_num];
+			break;
+		case NEPTUNE_2_10GF:
+			rx_ndmas = rx_2_10G[nxgep->function_num];
+			break;
+		case NEPTUNE_2_10GF_2_1GC:
+			rx_ndmas = rx_2_10G_2_1G[nxgep->function_num];
+			break;
+		case NEPTUNE_1_10GF_3_1GC:
+			rx_ndmas = rx_1_10G_3_1G[nxgep->function_num];
+			break;
+		case NEPTUNE_1_1GC_1_10GF_2_1GC:
+			rx_ndmas = rx_1_1G_1_10G_2_1G[nxgep->function_num];
+			break;
+		default:
+			rx_ndmas = p4_rx_equal[nxgep->function_num];
+			break;
 		}
 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
 			prop, rx_ndmas);
@@ -2157,6 +2170,11 @@
 	}
 	nxge_set_hw_dma_config(nxgep);
 
+	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config: "
+	    "sTDC[%d] nTDC[%d] sRDC[%d] nRDC[%d]",
+	    p_cfgp->start_tdc, p_cfgp->max_tdcs,
+	    p_cfgp->start_rdc, p_cfgp->max_rdcs));
+
 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config"));
 }
 
@@ -3374,11 +3392,14 @@
 static nxge_status_t
 nxge_get_mac_addr_properties(p_nxge_t nxgep)
 {
+#if defined(_BIG_ENDIAN)
 	uchar_t *prop_val;
 	uint_t prop_len;
+	uint_t j;
+#endif
 	uint_t i;
 	uint8_t func_num;
-	uint8_t total_factory_macs;
+	boolean_t compute_macs = B_TRUE;
 
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_mac_addr_properties "));
 
@@ -3417,8 +3438,8 @@
 		nxgep->ouraddr = nxgep->factaddr;
 	}
 
-	if ((nxgep->niu_type == N2_NIU) ||
-	    nxge_is_valid_local_mac(nxgep->factaddr))
+	if ((nxgep->nxge_hw_p->platform_type != P_NEPTUNE_ATLAS) ||
+	    (nxge_is_valid_local_mac(nxgep->factaddr)))
 		goto got_mac_addr;
 
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_get_mac_addr_properties: "
@@ -3441,7 +3462,7 @@
 	 * from the EEPROM.
 	 */
 	nxge_espc_get_next_mac_addr(nxgep->vpd_info.mac_addr,
-	    nxgep->mac.portnum, &nxgep->factaddr);
+	    nxgep->function_num, &nxgep->factaddr);
 
 	if (!nxge_is_valid_local_mac(nxgep->factaddr)) {
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
@@ -3463,91 +3484,70 @@
 	func_num = nxgep->function_num;
 
 	/*
-	 * total_factory_macs is the total number of MACs the factory assigned
-	 * to the whole Neptune device.  NIU does not need this parameter
-	 * because it derives the number of factory MACs for each port from
-	 * the device properties.
-	 */
-	if (nxgep->niu_type == NEPTUNE || nxgep->niu_type == NEPTUNE_2) {
-		/* First get VPD data from EEPROM */
-		if (nxgep->vpd_info.ver_valid && nxgep->vpd_info.num_macs) {
-			nxgep->nxge_mmac_info.total_factory_macs =
-			    nxgep->vpd_info.num_macs;
-		} else {
-			NXGE_DEBUG_MSG((nxgep, DDI_CTL,
-			    "nxge_get_mac_addr_properties: Number of MAC "
-			    "addresses in EEPROM VPD data not valid"
-			    "...reading from NCR registers"));
-			if (nxge_espc_num_macs_get(nxgep,
-			    &total_factory_macs) == NXGE_OK) {
-				nxgep->nxge_mmac_info.total_factory_macs =
-					total_factory_macs;
-			} else {
-				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				    "EEPROM version [%s] invalid...please "
-				    "update", nxgep->vpd_info.ver));
-				return (NXGE_ERROR);
-			}
-		}
-	}
-
-	/*
-	 * Note: mac-addresses of n2-niu is the list of mac addresses for a
-	 * port. #mac-addresses stored in Neptune's SEEPROM is the total number
-	 * of MAC addresses allocated for a board.
+	 * Note: mac-addresses property is the list of mac addresses for a
+	 * port. NXGE_MAX_MMAC_ADDRS is the total number of MAC addresses
+	 * allocated for a board.
 	 */
-	if (nxgep->niu_type == N2_NIU) {
-		if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
-				"mac-addresses", &prop_val, &prop_len) ==
-			DDI_PROP_SUCCESS) {
-			/*
-			 * XAUI may have up to 18 MACs, more than the XMAC can
-			 * use (1 unique MAC plus 16 alternate MACs)
-			 */
-			nxgep->nxge_mmac_info.num_factory_mmac
-			    = prop_len / ETHERADDRL - 1;
-			if (nxgep->nxge_mmac_info.num_factory_mmac >
-				XMAC_MAX_ALT_ADDR_ENTRY) {
-				nxgep->nxge_mmac_info.num_factory_mmac =
-					XMAC_MAX_ALT_ADDR_ENTRY;
-			}
-			ddi_prop_free(prop_val);
-		}
-	} else {
+	nxgep->nxge_mmac_info.total_factory_macs = NXGE_MAX_MMAC_ADDRS;
+
+#if defined(_BIG_ENDIAN)
+	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
+	    "mac-addresses", &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
 		/*
-		 * total_factory_macs = 32
-		 * num_factory_mmac = (32 >> (nports/2)) - 1
-		 * So if nports = 4, then num_factory_mmac =  7
-		 *    if nports = 2, then num_factory_mmac = 15
+		 * XAUI may have up to 18 MACs, more than the XMAC can
+		 * use (1 unique MAC plus 16 alternate MACs)
 		 */
-		nxgep->nxge_mmac_info.num_factory_mmac
-			= ((nxgep->nxge_mmac_info.total_factory_macs >>
-			(nxgep->nports >> 1))) - 1;
-
-		if (nxgep->nxge_mmac_info.num_factory_mmac < 1) {
-			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-			    "Invalid value [0x%x] for num_factory_mmac",
-			    nxgep->nxge_mmac_info.num_factory_mmac));
-			return (NXGE_ERROR);
-		}
-		if ((nxgep->function_num < 2) &&
-		    (nxgep->nxge_mmac_info.num_factory_mmac >
-		    XMAC_MAX_ALT_ADDR_ENTRY)) {
+		nxgep->nxge_mmac_info.num_factory_mmac =
+		    prop_len / ETHERADDRL - 1;
+		if (nxgep->nxge_mmac_info.num_factory_mmac >
+		    XMAC_MAX_ALT_ADDR_ENTRY) {
 			nxgep->nxge_mmac_info.num_factory_mmac =
-				XMAC_MAX_ALT_ADDR_ENTRY;
-		} else if ((nxgep->function_num > 1) &&
-		    (nxgep->nxge_mmac_info.num_factory_mmac >
-		    BMAC_MAX_ALT_ADDR_ENTRY)) {
-			nxgep->nxge_mmac_info.num_factory_mmac =
-				BMAC_MAX_ALT_ADDR_ENTRY;
+			    XMAC_MAX_ALT_ADDR_ENTRY;
+		}
+
+		for (i = 1; i <= nxgep->nxge_mmac_info.num_factory_mmac; i++) {
+			for (j = 0; j < ETHERADDRL; j++) {
+				nxgep->nxge_mmac_info.factory_mac_pool[i][j] =
+				    *(prop_val + (i * ETHERADDRL) + j);
+			}
+			NXGE_DEBUG_MSG((nxgep, DDI_CTL,
+			    "nxge_get_mac_addr_properties: Alt mac[%d] from "
+			    "mac-addresses property[%2x:%2x:%2x:%2x:%2x:%2x]",
+			    i, nxgep->nxge_mmac_info.factory_mac_pool[i][0],
+			    nxgep->nxge_mmac_info.factory_mac_pool[i][1],
+			    nxgep->nxge_mmac_info.factory_mac_pool[i][2],
+			    nxgep->nxge_mmac_info.factory_mac_pool[i][3],
+			    nxgep->nxge_mmac_info.factory_mac_pool[i][4],
+			    nxgep->nxge_mmac_info.factory_mac_pool[i][5]));
 		}
+
+		compute_macs = B_FALSE;
+		ddi_prop_free(prop_val);
+		goto got_mmac_info;
 	}
-
-	if (nxgep->nxge_mmac_info.num_mmac < 1) {
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-		    "Invalid value [0x%x] for num_mmac",
-		    nxgep->nxge_mmac_info.num_mmac));
-		return (NXGE_ERROR);
+#endif
+	/*
+	 * total_factory_macs = 32
+	 * num_factory_mmac = (32 >> (nports/2)) - 1
+	 * So if nports = 4, then num_factory_mmac =  7
+	 *    if nports = 2, then num_factory_mmac = 15
+	 */
+	nxgep->nxge_mmac_info.num_factory_mmac =
+	    ((nxgep->nxge_mmac_info.total_factory_macs >>
+	    (nxgep->nports >> 1))) - 1;
+
+got_mmac_info:
+
+	if ((nxgep->function_num < 2) &&
+	    (nxgep->nxge_mmac_info.num_factory_mmac >
+	    XMAC_MAX_ALT_ADDR_ENTRY)) {
+		nxgep->nxge_mmac_info.num_factory_mmac =
+		    XMAC_MAX_ALT_ADDR_ENTRY;
+	} else if ((nxgep->function_num > 1) &&
+	    (nxgep->nxge_mmac_info.num_factory_mmac >
+	    BMAC_MAX_ALT_ADDR_ENTRY)) {
+		nxgep->nxge_mmac_info.num_factory_mmac =
+		    BMAC_MAX_ALT_ADDR_ENTRY;
 	}
 
 	for (i = 0; i <= nxgep->nxge_mmac_info.num_mmac; i++) {
@@ -3555,7 +3555,7 @@
 			NXGE_GET_PORT_NUM(func_num), i);
 	}
 
-	(void) nxge_init_mmac(nxgep);
+	(void) nxge_init_mmac(nxgep, compute_macs);
 	return (NXGE_OK);
 }
 
@@ -3676,10 +3676,14 @@
  *     --------------
  *
  * For N2/NIU the mac addresses is from XAUI card.
+ *
+ * When 'compute_addrs' is true, the alternate mac addresses are computed
+ * using the unique mac address as base. Otherwise the alternate addresses
+ * are assigned from the list read off the 'mac-addresses' property.
  */
 
 static void
-nxge_init_mmac(p_nxge_t nxgep)
+nxge_init_mmac(p_nxge_t nxgep, boolean_t compute_addrs)
 {
 	int slot;
 	uint8_t func_num;
@@ -3694,14 +3698,18 @@
 	base_mmac_addr = (uint16_t *)&nxgep->factaddr;
 	mmac_info = (nxge_mmac_t *)&nxgep->nxge_mmac_info;
 
-	base_mac_ls4b = ((uint32_t)base_mmac_addr[1]) << 16 |
-		base_mmac_addr[2];
-
-	if (nxgep->niu_type == N2_NIU) {
-		alt_mac_ls4b = base_mac_ls4b + 1; /* ls4b of 1st altmac */
-	} else {			/* Neptune */
-		alt_mac_ls4b = base_mac_ls4b + (nxgep->nports - func_num)
-			+ (func_num * (mmac_info->num_factory_mmac));
+	if (compute_addrs) {
+		base_mac_ls4b = ((uint32_t)base_mmac_addr[1]) << 16 |
+		    base_mmac_addr[2];
+
+		if (nxgep->niu_type == N2_NIU) {
+			/* ls4b of 1st altmac */
+			alt_mac_ls4b = base_mac_ls4b + 1;
+		} else {			/* Neptune */
+			alt_mac_ls4b = base_mac_ls4b +
+			    (nxgep->nports - func_num) +
+			    (func_num * (mmac_info->num_factory_mmac));
+		}
 	}
 
 	/* Set flags for unique MAC */
@@ -3718,22 +3726,38 @@
 	/* Generate and store factory alternate MACs */
 	for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) {
 		mmac_addr = (uint16_t *)&mmac_info->factory_mac_pool[slot];
-		mmac_addr[0] = base_mmac_addr[0];
-		mac_addr.w2 = mmac_addr[0];
-
-		mmac_addr[1] = (alt_mac_ls4b >> 16) & 0x0FFFF;
-		mac_addr.w1 = mmac_addr[1];
-
-		mmac_addr[2] = alt_mac_ls4b & 0x0FFFF;
-		mac_addr.w0 = mmac_addr[2];
+		if (compute_addrs) {
+			mmac_addr[0] = base_mmac_addr[0];
+			mac_addr.w2 = mmac_addr[0];
+
+			mmac_addr[1] = (alt_mac_ls4b >> 16) & 0x0FFFF;
+			mac_addr.w1 = mmac_addr[1];
+
+			mmac_addr[2] = alt_mac_ls4b & 0x0FFFF;
+			mac_addr.w0 = mmac_addr[2];
+
+			alt_mac_ls4b++;
+		} else {
+			mac_addr.w2 = mmac_addr[0];
+			mac_addr.w1 = mmac_addr[1];
+			mac_addr.w0 = mmac_addr[2];
+		}
+
+		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
+		    "mac_pool_addr[%2x:%2x:%2x:%2x:%2x:%2x] npi_addr[%x%x%x]",
+		    mmac_info->factory_mac_pool[slot][0],
+		    mmac_info->factory_mac_pool[slot][1],
+		    mmac_info->factory_mac_pool[slot][2],
+		    mmac_info->factory_mac_pool[slot][3],
+		    mmac_info->factory_mac_pool[slot][4],
+		    mmac_info->factory_mac_pool[slot][5],
+		    mac_addr.w0, mac_addr.w1, mac_addr.w2));
 		/*
-		 * slot minus 1 because npi_mac_alraddr_entry expects 0
+		 * slot minus 1 because npi_mac_altaddr_entry expects 0
 		 * for the first alternate mac address.
 		 */
 		(void) npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET,
 			NXGE_GET_PORT_NUM(func_num), slot - 1, &mac_addr);
-
-		alt_mac_ls4b++;
 	}
 	/* Initialize the first two parameters for mmac kstat */
 	nxgep->statsp->mmac_stats.mmac_max_cnt = mmac_info->num_mmac;
--- a/usr/src/uts/common/io/nxge/nxge_zcp.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_zcp.c	Wed Jul 25 18:20:14 2007 -0700
@@ -44,13 +44,16 @@
 	handle = nxgep->npi_handle;
 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
 
-	if ((nxgep->niu_type == NEPTUNE) || (nxgep->niu_type == NEPTUNE_2)) {
+	if (nxgep->niu_type == N2_NIU) {
+		cfifo_depth = ZCP_NIU_CFIFO_DEPTH;
+	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		if (portn < 2)
 			cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH;
 		else
 			cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH;
-	} else if (nxgep->niu_type == N2_NIU)
-		cfifo_depth = ZCP_NIU_CFIFO_DEPTH;
+	} else {
+		goto fail;
+	}
 
 	/* Clean up CFIFO */
 	w_data.w0 = 0;
@@ -417,13 +420,16 @@
 	}
 
 	/* Clear up CFIFO */
-	if ((nxgep->niu_type == NEPTUNE) || (nxgep->niu_type == NEPTUNE_2)) {
+	if (nxgep->niu_type == N2_NIU) {
+		cfifo_depth = ZCP_NIU_CFIFO_DEPTH;
+	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
 		if (portn < 2)
 			cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH;
 		else
 			cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH;
-	} else if (nxgep->niu_type == N2_NIU)
-		cfifo_depth = ZCP_NIU_CFIFO_DEPTH;
+	} else {
+		goto fail;
+	}
 
 	w_data.w0 = 0;
 	w_data.w1 = 0;
--- a/usr/src/uts/common/sys/nxge/nxge.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/sys/nxge/nxge.h	Wed Jul 25 18:20:14 2007 -0700
@@ -533,6 +533,7 @@
 	npi_handle_t		npi_vreg_handle;
 	npi_handle_t		npi_v2reg_handle;
 
+	nxge_xcvr_table_t	xcvr;
 	nxge_mac_t		mac;
 	nxge_ipp_t		ipp;
 	nxge_txc_t		txc;
--- a/usr/src/uts/common/sys/nxge/nxge_common.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/sys/nxge/nxge_common.h	Wed Jul 25 18:20:14 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.
  */
 
@@ -478,6 +478,8 @@
 	uint32_t		ndevs;
 	uint32_t 		flags;
 	uint32_t 		magic;
+	uint32_t		niu_type;
+	uint32_t		platform_type;
 } nxge_hw_list_t, *p_nxge_hw_list_t;
 
 #ifdef	__cplusplus
--- a/usr/src/uts/common/sys/nxge/nxge_impl.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/sys/nxge/nxge_impl.h	Wed Jul 25 18:20:14 2007 -0700
@@ -301,12 +301,61 @@
 typedef struct _nxge_block_mv_t nxge_block_mv_t, *p_nxge_block_mv_t;
 
 typedef enum {
-	NEPTUNE,	/* 4 ports */
-	NEPTUNE_2,	/* 2 ports */
-	N2_NIU		/* N2/NIU 2 ports */
+	NIU_TYPE_NONE = 0,
+
+	NEPTUNE_4_1GC =
+	    (NXGE_PORT_1G_COPPER |
+	    (NXGE_PORT_1G_COPPER << 4) |
+	    (NXGE_PORT_1G_COPPER << 8) |
+	    (NXGE_PORT_1G_COPPER << 12)),
+
+	NEPTUNE_2_10GF =
+	    (NXGE_PORT_10G_FIBRE |
+	    (NXGE_PORT_10G_FIBRE << 4) |
+	    (NXGE_PORT_NONE << 8) |
+	    (NXGE_PORT_NONE << 12)),
+
+	NEPTUNE_2_10GF_2_1GC =
+	    (NXGE_PORT_10G_FIBRE |
+	    (NXGE_PORT_10G_FIBRE << 4) |
+	    (NXGE_PORT_1G_COPPER << 8) |
+	    (NXGE_PORT_1G_COPPER << 12)),
+
+	NEPTUNE_1_10GF_3_1GC =
+	    (NXGE_PORT_10G_FIBRE |
+	    (NXGE_PORT_1G_COPPER << 4) |
+	    (NXGE_PORT_1G_COPPER << 8) |
+	    (NXGE_PORT_1G_COPPER << 12)),
+
+	NEPTUNE_1_1GC_1_10GF_2_1GC =
+	    (NXGE_PORT_1G_COPPER |
+	    (NXGE_PORT_10G_FIBRE << 4) |
+	    (NXGE_PORT_1G_COPPER << 8) |
+	    (NXGE_PORT_1G_COPPER << 12)),
+
+	N2_NIU =
+	    (NXGE_PORT_RSVD |
+	    (NXGE_PORT_RSVD << 4) |
+	    (NXGE_PORT_RSVD << 8) |
+	    (NXGE_PORT_RSVD << 12))
+
 } niu_type_t;
 
 typedef enum {
+	P_NEPTUNE_NONE,
+	P_NEPTUNE_ATLAS,
+	P_NEPTUNE_MARAMBA_P0,
+	P_NEPTUNE_MARAMBA_P1,
+	P_NEPTUNE_NIU
+} platform_type_t;
+
+#define	NXGE_IS_VALID_NEPTUNE_TYPE(niu_type)	\
+	((niu_type) == NEPTUNE_4_1GC || (niu_type) == NEPTUNE_2_10GF ||	\
+	    (niu_type) == NEPTUNE_2_10GF_2_1GC ||	\
+	    (niu_type) == NEPTUNE_1_10GF_3_1GC ||	\
+	    (niu_type) == NEPTUNE_1_1GC_1_10GF_2_1GC)
+
+typedef enum {
 	CFG_DEFAULT = 0,	/* default cfg */
 	CFG_EQUAL,	/* Equal */
 	CFG_FAIR,	/* Equal */
@@ -351,6 +400,21 @@
 #endif
 
 /*
+ * Generic phy table to support different phy types.
+ */
+typedef struct _nxge_xcvr_table {
+	nxge_status_t	(*serdes_init)	();	/* Serdes init routine */
+	nxge_status_t	(*xcvr_init)	();	/* xcvr init routine */
+	nxge_status_t	(*link_intr_stop) ();	/* Link intr disable routine */
+	nxge_status_t	(*link_intr_start) ();	/* Link intr enable routine */
+	nxge_status_t	(*check_link) ();	/* Link check routine */
+
+	uint32_t	device_id;
+	uint32_t	xcvr_inuse;
+	uint32_t	xcvr_addr;
+} nxge_xcvr_table_t, *p_nxge_xcvr_table_t;
+
+/*
  * Common DMA data elements.
  */
 struct _nxge_dma_common_t {
@@ -574,10 +638,6 @@
 #define	NXGE_NUM_OF_PORTS_QUAD	4
 #define	NXGE_NUM_OF_PORTS_DUAL	2
 
-#define	NXGE_QGC_LP_BM_STR		"501-7606"
-#define	NXGE_2XGF_LP_BM_STR		"501-7283"
-#define	NXGE_QGC_PEM_BM_STR		"501-7765"
-#define	NXGE_2XGF_PEM_BM_STR		"501-7626"
 #define	NXGE_EROM_LEN			1048576
 
 #endif
@@ -797,10 +857,7 @@
 nxge_status_t nxge_xif_init(p_nxge_t);
 nxge_status_t nxge_pcs_init(p_nxge_t);
 nxge_status_t nxge_serdes_init(p_nxge_t);
-nxge_status_t nxge_n2_serdes_init(p_nxge_t);
-nxge_status_t nxge_neptune_serdes_init(p_nxge_t);
-nxge_status_t nxge_xcvr_find(p_nxge_t);
-nxge_status_t nxge_get_xcvr_type(p_nxge_t);
+nxge_status_t nxge_setup_xcvr_table(p_nxge_t);
 nxge_status_t nxge_xcvr_init(p_nxge_t);
 nxge_status_t nxge_tx_mac_init(p_nxge_t);
 nxge_status_t nxge_rx_mac_init(p_nxge_t);
@@ -825,9 +882,6 @@
 nxge_status_t nxge_add_mcast_addr(p_nxge_t, struct ether_addr *);
 nxge_status_t nxge_del_mcast_addr(p_nxge_t, struct ether_addr *);
 nxge_status_t nxge_set_mac_addr(p_nxge_t, struct ether_addr *);
-nxge_status_t nxge_check_mii_link(p_nxge_t);
-nxge_status_t nxge_check_10g_link(p_nxge_t);
-nxge_status_t nxge_check_serdes_link(p_nxge_t);
 nxge_status_t nxge_check_bcm8704_link(p_nxge_t, boolean_t *);
 void nxge_link_is_down(p_nxge_t);
 void nxge_link_is_up(p_nxge_t);
@@ -837,6 +891,7 @@
 nxge_status_t nxge_mac_handle_sys_errors(p_nxge_t);
 nxge_status_t nxge_10g_link_led_on(p_nxge_t);
 nxge_status_t nxge_10g_link_led_off(p_nxge_t);
+nxge_status_t nxge_scan_ports_phy(p_nxge_t, p_nxge_hw_list_t);
 boolean_t nxge_is_valid_local_mac(ether_addr_st);
 
 /* espc (sprom) prototypes */
@@ -844,11 +899,13 @@
 nxge_status_t nxge_espc_num_macs_get(p_nxge_t, uint8_t *);
 nxge_status_t nxge_espc_num_ports_get(p_nxge_t);
 nxge_status_t nxge_espc_phy_type_get(p_nxge_t);
+nxge_status_t nxge_espc_verify_chksum(p_nxge_t);
 void nxge_espc_get_next_mac_addr(uint8_t *, uint8_t, struct ether_addr *);
 nxge_status_t nxge_vpd_info_get(p_nxge_t);
 
 
 void nxge_debug_msg(p_nxge_t, uint64_t, char *, ...);
+int nxge_nports_from_niu_type(niu_type_t);
 
 uint64_t hv_niu_rx_logical_page_conf(uint64_t, uint64_t,
 	uint64_t, uint64_t);
--- a/usr/src/uts/common/sys/nxge/nxge_mac_hw.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/sys/nxge/nxge_mac_hw.h	Wed Jul 25 18:20:14 2007 -0700
@@ -74,6 +74,56 @@
 
 #define	MAC_ADDR_REG_MASK		0xFFFF
 
+/*
+ * Neptune port PHY type and Speed encoding.
+ *
+ * Per port, 4 bits are reserved for port speed (1G/10G) and 4 bits
+ * are reserved for port PHY type (Copper/Fibre). Bits 0 thru 3 are for port0
+ * speed, bits 4 thru 7 are for port1 speed, bits 8 thru 11 are for port2 speed
+ * and bits 12 thru 15 are for port3 speed. Thus, the first 16 bits hold the
+ * speed encoding for the 4 ports. The next 16 bits (16 thru 31) hold the phy
+ * type encoding for the ports 0 thru 3.
+ *
+ *  p3phy  p2phy  p1phy  p0phy  p3spd p2spd  p1spd p0spd
+ *    |      |      |      |      |     |      |     |
+ *   ---    ---    ---    ---    ---   ---    ---   ---
+ *  /   \  /   \  /   \  /   \  /   \ /   \  /   \ /   \
+ * 31..28 27..24 23..20 19..16 15..12 11.. 8 7.. 4 3.. 0
+ */
+#define	NXGE_PORT_SPD_NONE	0x0
+#define	NXGE_PORT_SPD_1G	0x1
+#define	NXGE_PORT_SPD_10G	0x2
+#define	NXGE_PORT_SPD_RSVD	0x7
+
+#define	NXGE_PHY_NONE		0x0
+#define	NXGE_PHY_COPPER		0x1
+#define	NXGE_PHY_FIBRE		0x2
+#define	NXGE_PHY_RSVD		0x7
+
+#define	NXGE_PORT_SPD_SHIFT	0
+#define	NXGE_PORT_SPD_MASK	0x0f
+
+#define	NXGE_PHY_SHIFT		16
+#define	NXGE_PHY_MASK		0x0f0000
+
+#define	NXGE_PORT_1G_COPPER	(NXGE_PORT_SPD_1G |	\
+	(NXGE_PHY_COPPER << NXGE_PHY_SHIFT))
+#define	NXGE_PORT_10G_COPPER	(NXGE_PORT_SPD_10G |	\
+	(NXGE_PHY_COPPER << NXGE_PHY_SHIFT))
+#define	NXGE_PORT_1G_FIBRE	(NXGE_PORT_SPD_1G |	\
+	(NXGE_PHY_FIBRE << NXGE_PHY_SHIFT))
+#define	NXGE_PORT_10G_FIBRE	(NXGE_PORT_SPD_10G |	\
+	(NXGE_PHY_FIBRE << NXGE_PHY_SHIFT))
+#define	NXGE_PORT_NONE		(NXGE_PORT_SPD_NONE |	\
+	(NXGE_PHY_NONE << NXGE_PHY_SHIFT))
+#define	NXGE_PORT_RSVD		(NXGE_PORT_SPD_RSVD |	\
+	(NXGE_PHY_RSVD << NXGE_PHY_SHIFT))
+
+#define	NXGE_PORT_TYPE_MASK	(NXGE_PORT_SPD_MASK | NXGE_PHY_MASK)
+
+/* number of bits used for phy/spd encoding per port */
+#define	NXGE_PORT_TYPE_SHIFT	4
+
 /* Network Modes */
 
 typedef enum nxge_network_mode {
--- a/usr/src/uts/common/sys/nxge/nxge_phy_hw.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/common/sys/nxge/nxge_phy_hw.h	Wed Jul 25 18:20:14 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.
  */
 
@@ -35,9 +35,37 @@
 
 #include <nxge_defs.h>
 
+#define	NXGE_MAX_PHY_PORTS		32
+#define	NXGE_EXT_PHY_PORT_ST		8
+
+#define	NXGE_PMA_PMD_DEV_ADDR		1
+#define	NXGE_PCS_DEV_ADDR		3
+#define	NXGE_DEV_ID_REG_1		2
+#define	NXGE_DEV_ID_REG_2		3
+#define	NXGE_PHY_ID_REG_1		2
+#define	NXGE_PHY_ID_REG_2		3
+
+#define	BCM8704_DEV_ID			0x206033
+#define	BCM5464R_PHY_ID			0x2060b1
+#define	PHY_10G_FIBRE			BCM8704_DEV_ID
+#define	PHY_1G_COPPER			BCM5464R_PHY_ID
+#define	PHY_ID_MASK			0xfffff0f0
+
+#define	CLAUSE_45_TYPE	1
+#define	CLAUSE_22_TYPE	2
+
 #define	BCM5464_NEPTUNE_PORT_ADDR_BASE		10
 #define	BCM8704_NEPTUNE_PORT_ADDR_BASE		8
 #define	BCM8704_N2_PORT_ADDR_BASE		16
+
+/*
+ * Phy addresses for Maramba support. Support for P0 will eventually
+ * be removed.
+ */
+#define	BCM5464_MARAMBA_P0_PORT_ADDR_BASE	10
+#define	BCM5464_MARAMBA_P1_PORT_ADDR_BASE	26
+#define	BCM8704_MARAMBA_PORT_ADDR_BASE		16
+
 #define	BCM8704_PMA_PMD_DEV_ADDR		1
 #define	BCM8704_PCS_DEV_ADDR			3
 #define	BCM8704_USER_DEV3_ADDR			3
--- a/usr/src/uts/sparc/os/driver_aliases	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sparc/os/driver_aliases	Wed Jul 25 18:20:14 2007 -0700
@@ -173,4 +173,6 @@
 scfd "FJSV,scfc"
 ncp "SUNW,sun4v-ncp"
 ncp "SUNW,n2-mau"
+ncp "SUNW,vf-mau"
 n2rng "SUNW,n2-rng"
+n2rng "SUNW,vf-rng"
--- a/usr/src/uts/sun4/io/trapstat.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4/io/trapstat.c	Wed Jul 25 18:20:14 2007 -0700
@@ -267,6 +267,40 @@
  * be added via a hybrid scheme, where the same 4M virtual address is used
  * on different MMUs.
  *
+ * On sun4v architecture, we currently don't use hybrid scheme as it imposes
+ * additional restriction on live migration and transparent CPU replacement.
+ * Instead, we increase the number of supported CPUs by reducing the virtual
+ * address space requirements per CPU via shared interposing trap table as
+ * follows:
+ *
+ *                                          Offset (within 4MB page)
+ *       +------------------------------------+- 0x400000
+ *       |  CPU 507 trap statistics (8KB)     |   .
+ *       |- - - - - - - - - - - - - - - - - - +- 0x3fe000
+ *       |                                    |
+ *       |   ...                              |
+ *       |                                    |
+ *       |- - - - - - - - - - - - - - - - - - +- 0x00c000
+ *       |  CPU 1 trap statistics (8KB)       |   .
+ *       |- - - - - - - - - - - - - - - - - - +- 0x00a000
+ *       |  CPU 0 trap statistics (8KB)       |   .
+ *       |- - - - - - - - - - - - - - - - - - +- 0x008000
+ *       |  Shared trap handler continuation  |   .
+ *       |- - - - - - - - - - - - - - - - - - +- 0x006000
+ *       |  Non-trap instruction, TL>0        |   .
+ *       |- - - - - - - - - - - - - - - - - - +- 0x004000
+ *       |  Trap instruction, TL=0            |   .
+ *       |- - - - - - - - - - - - - - - - - - +- 0x002000
+ *       |  Non-trap instruction, TL=0        |   .
+ *       +------------------------------------+- 0x000000
+ *
+ * Note that each CPU has its own 8K space for its trap statistics but
+ * shares the same interposing trap handlers.  Interposing trap handlers
+ * use the CPU ID to determine the location of per CPU trap statistics
+ * area dynamically. This increases the interposing trap handler overhead,
+ * but is acceptable as it allows us to support up to 508 CPUs with one
+ * 4MB page on sun4v architecture. Support for additional CPUs can be
+ * added via hybrid scheme as mentioned earlier.
  *
  * TLB Statistics
  *
@@ -504,15 +538,21 @@
 static size_t		tstat_data_t_size;
 static size_t		tstat_data_t_exported_size;
 
+#ifndef sun4v
+
 static size_t		tstat_data_pages;  /* number of pages of tstat data */
 static size_t		tstat_data_size;   /* tstat data size in bytes */
 static size_t		tstat_total_pages; /* #data pages + #instr pages */
 static size_t		tstat_total_size;  /* tstat data size + instr size */
-#ifdef sun4v
+
+#else /* sun4v */
+
 static caddr_t		tstat_va;	/* VA of memory reserved for TBA */
 static pfn_t		tstat_pfn;	/* PFN of memory reserved for TBA */
 static boolean_t	tstat_fast_tlbstat = B_FALSE;
-#endif
+static int		tstat_traptab_initialized;
+
+#endif /* sun4v */
 
 /*
  * In the above block comment, see "TLB Statistics: TLB Misses versus
@@ -573,25 +613,25 @@
 #ifndef sun4v
 	for (i = 0; i < tstat_total_pages; i++, va += MMU_PAGESIZE) {
 		tte.tte_inthi = TTE_VALID_INT | TTE_SZ_INT(TTE8K) |
-			TTE_PFN_INTHI(tcpu->tcpu_pfn[i]);
+		    TTE_PFN_INTHI(tcpu->tcpu_pfn[i]);
 		if (i < TSTAT_INSTR_PAGES) {
 			tte.tte_intlo = TTE_PFN_INTLO(tcpu->tcpu_pfn[i]) |
-				TTE_LCK_INT | TTE_CP_INT | TTE_PRIV_INT;
+			    TTE_LCK_INT | TTE_CP_INT | TTE_PRIV_INT;
 			sfmmu_itlb_ld_kva(va, &tte);
 		} else {
 			tte.tte_intlo = TTE_PFN_INTLO(tcpu->tcpu_pfn[i]) |
-				TTE_LCK_INT | TTE_CP_INT | TTE_CV_INT |
-				TTE_PRIV_INT | TTE_HWWR_INT;
+			    TTE_LCK_INT | TTE_CP_INT | TTE_CV_INT |
+			    TTE_PRIV_INT | TTE_HWWR_INT;
 			sfmmu_dtlb_ld_kva(va, &tte);
 		}
 	}
 #else /* sun4v */
 	tte.tte_inthi = TTE_VALID_INT | TTE_PFN_INTHI(tstat_pfn);
 	tte.tte_intlo = TTE_PFN_INTLO(tstat_pfn) | TTE_CP_INT |
-		TTE_CV_INT | TTE_PRIV_INT | TTE_HWWR_INT |
-		TTE_SZ_INTLO(TTE4M);
+	    TTE_CV_INT | TTE_PRIV_INT | TTE_HWWR_INT |
+	    TTE_SZ_INTLO(TTE4M);
 	ret = hv_mmu_map_perm_addr(va, KCONTEXT, *(uint64_t *)&tte,
-		MAP_ITLB | MAP_DTLB);
+	    MAP_ITLB | MAP_DTLB);
 
 	if (ret != H_EOK)
 		cmn_err(CE_PANIC, "trapstat: cannot map new TBA "
@@ -963,15 +1003,16 @@
 #define	TSTAT_RETENT_TIME_LD	19
 #define	TSTAT_RETENT_TIME_ST	21
 #else /* sun4v */
-#define	TSTAT_RETENT_STATHI	1
-#define	TSTAT_RETENT_STATLO	2
-#define	TSTAT_RETENT_SHIFT	5
-#define	TSTAT_RETENT_COUNT_LD	7
-#define	TSTAT_RETENT_COUNT_ST	9
-#define	TSTAT_RETENT_TMPTSHI	10
-#define	TSTAT_RETENT_TMPTSLO	11
-#define	TSTAT_RETENT_TIME_LD	13
-#define	TSTAT_RETENT_TIME_ST	15
+#define	TSTAT_RETENT_TDATASHFT	2
+#define	TSTAT_RETENT_STATHI	4
+#define	TSTAT_RETENT_STATLO	6
+#define	TSTAT_RETENT_SHIFT	9
+#define	TSTAT_RETENT_COUNT_LD	11
+#define	TSTAT_RETENT_COUNT_ST	13
+#define	TSTAT_RETENT_TMPTSHI	14
+#define	TSTAT_RETENT_TMPTSLO	16
+#define	TSTAT_RETENT_TIME_LD	18
+#define	TSTAT_RETENT_TIME_ST	20
 #endif /* sun4v */
 
 static void
@@ -979,7 +1020,12 @@
     tstat_missdata_t *data)
 {
 	uint32_t *ent = ret->ttlbrent_instr, shift;
-	uintptr_t base, tmptick = TSTAT_DATA_OFFS(tcpu, tdata_tmptick);
+	uintptr_t base;
+#ifndef sun4v
+	uintptr_t tmptick = TSTAT_DATA_OFFS(tcpu, tdata_tmptick);
+#else
+	uintptr_t tmptick = TSTAT_CPU0_DATA_OFFS(tcpu, tdata_tmptick);
+#endif
 
 	/*
 	 * This is the entry executed upon return from the TLB/TSB miss
@@ -1018,8 +1064,12 @@
 	    0xc4706000,		/* stx   %g2, [%g1 + tmiss_time]	*/
 	    0x83f00000		/* retry				*/
 #else /* sun4v */
+	    0x82102008,		/* mov   SCRATCHPAD_CPUID, %g1 		*/
+	    0xced84400,		/* ldxa  [%g1]ASI_SCRATCHPAD, %g7	*/
+	    0x8f29f000,		/* sllx  %g7, TSTAT_DATA_SHIFT, %g7	*/
 	    0x87410000,		/* rd    %tick, %g3			*/
 	    0x03000000, 	/* sethi %hi(stat), %g1			*/
+	    0x82004007,		/* add   %g1, %g7, %g1			*/
 	    0x82106000,		/* or    %g1, %lo(stat), %g1		*/
 	    0x8929703d,		/* sllx  %g5, 61, %g4			*/
 	    0x8931303d,		/* srlx  %g4, 61, %g4			*/
@@ -1029,6 +1079,7 @@
 	    0x8400a001,		/* add   %g2, 1, %g2			*/
 	    0xc4706000,		/* stx   %g2, [%g1 + tmiss_count]	*/
 	    0x0d000000, 	/* sethi %hi(tdata_tmptick), %g6	*/
+	    0x8c018007,		/* add   %g6, %g7, %g6			*/
 	    0xc459a000, 	/* ldx   [%g6 + %lo(tdata_tmptick)], %g2 */
 	    0x8620c002,		/* sub   %g3, %g2, %g3			*/
 	    0xc4586000,		/* ldx   [%g1 + tmiss_time], %g2	*/
@@ -1049,11 +1100,14 @@
 	for (shift = 1; (1 << shift) != sizeof (tstat_pgszdata_t); shift++)
 		continue;
 
-	base = (uintptr_t)tcpu->tcpu_dbase +
+	base = (uintptr_t)tcpu->tcpu_ibase + TSTAT_INSTR_SIZE +
 	    ((uintptr_t)data - (uintptr_t)tcpu->tcpu_data);
 
 	bcopy(retent, ent, sizeof (retent));
 
+#if defined(sun4v)
+	ent[TSTAT_RETENT_TDATASHFT] |= LO10((uintptr_t)TSTAT_DATA_SHIFT);
+#endif
 	ent[TSTAT_RETENT_STATHI] |= HI22(base);
 	ent[TSTAT_RETENT_STATLO] |= LO10(base);
 	ent[TSTAT_RETENT_SHIFT] |= shift;
@@ -1067,6 +1121,9 @@
 	ent[TSTAT_RETENT_TIME_ST] |= offsetof(tstat_missdata_t, tmiss_time);
 }
 
+#if defined(sun4v)
+#undef TSTAT_RETENT_TDATASHFT
+#endif
 #undef TSTAT_RETENT_STATHI
 #undef TSTAT_RETENT_STATLO
 #undef TSTAT_RETENT_SHIFT
@@ -1096,16 +1153,17 @@
 #define	TSTAT_TLBENT_TSLO	27
 #define	TSTAT_TLBENT_BA		28
 #else /* sun4v */
-#define	TSTAT_TLBENT_STATHI	0
-#define	TSTAT_TLBENT_STATLO_LD	1
-#define	TSTAT_TLBENT_STATLO_ST	3
-#define	TSTAT_TLBENT_TAGTARGET	19
-#define	TSTAT_TLBENT_TPCHI	21
-#define	TSTAT_TLBENT_TPCLO_USER	22
-#define	TSTAT_TLBENT_TPCLO_KERN	24
-#define	TSTAT_TLBENT_TSHI	28
-#define	TSTAT_TLBENT_TSLO	30
-#define	TSTAT_TLBENT_BA		31
+#define	TSTAT_TLBENT_TDATASHFT	2
+#define	TSTAT_TLBENT_STATHI	3
+#define	TSTAT_TLBENT_STATLO_LD	5
+#define	TSTAT_TLBENT_STATLO_ST	7
+#define	TSTAT_TLBENT_TAGTARGET	23
+#define	TSTAT_TLBENT_TPCHI	25
+#define	TSTAT_TLBENT_TPCLO_USER	26
+#define	TSTAT_TLBENT_TPCLO_KERN	28
+#define	TSTAT_TLBENT_TSHI	32
+#define	TSTAT_TLBENT_TSLO	35
+#define	TSTAT_TLBENT_BA		36
 #endif /* sun4v */
 
 static void
@@ -1115,19 +1173,22 @@
 	uintptr_t orig, va, baoffs;
 #ifndef sun4v
 	int itlb = entno == TSTAT_ENT_ITLBMISS;
+	uint32_t asi = itlb ? ASI(ASI_IMMU) : ASI(ASI_DMMU);
 #else
 	int itlb = (entno == TSTAT_ENT_IMMUMISS || entno == TSTAT_ENT_ITLBMISS);
+	uint32_t tagtarget_off = itlb ? MMFSA_I_CTX : MMFSA_D_CTX;
+	uint32_t *tent;			/* MMU trap vector entry */
+	uintptr_t tentva;		/* MMU trap vector entry va */
+	static const uint32_t mmumiss[TSTAT_ENT_NINSTR] = {
+	    0x30800000,			/* ba,a addr */
+	    NOP, NOP, NOP, NOP, NOP, NOP, NOP
+	};
 #endif
 	int entoffs = entno << TSTAT_ENT_SHIFT;
 	uintptr_t tmptick, stat, tpc, utpc;
 	tstat_pgszdata_t *data = &tcpu->tcpu_data->tdata_pgsz[0];
 	tstat_tlbdata_t *udata, *kdata;
 	tstat_tlbret_t *ret;
-#ifndef sun4v
-	uint32_t asi = itlb ? ASI(ASI_IMMU) : ASI(ASI_DMMU);
-#else
-	uint32_t tagtarget_off = itlb ? MMFSA_I_CTX : MMFSA_D_CTX;
-#endif
 
 	/*
 	 * When trapstat is run with TLB statistics, this is the entry for
@@ -1180,7 +1241,11 @@
 	    0x30800000,			/* ba,a  addr			*/
 	    NOP, NOP, NOP
 #else /* sun4v */
+	    0x82102008,			/* mov SCRATCHPAD_CPUID, %g1	*/
+	    0xc8d84400,			/* ldxa [%g1]ASI_SCRATCHPAD, %g4 */
+	    0x89293000,			/* sllx %g4, TSTAT_DATA_SHIFT, %g4 */
 	    0x03000000, 		/* sethi %hi(stat), %g1		*/
+	    0x82004004,			/* add %g1, %g4, %g1		*/
 	    0xc4586000,			/* ldx   [%g1 + %lo(stat)], %g2	*/
 	    0x8400a001,			/* add   %g2, 1, %g2		*/
 	    0xc4706000,			/* stx   %g2, [%g1 + %lo(stat)]	*/
@@ -1209,6 +1274,7 @@
 	    0x82006004,			/* add   %g1, 4, %g1		*/
 	    0x83904000,			/* wrpr  %g1, %g0, %tnpc	*/
 	    0x03000000, 		/* sethi %hi(tmptick), %g1	*/
+	    0x82004004,			/* add %g1, %g4, %g1		*/
 	    0x85410000,			/* rd    %tick, %g2		*/
 	    0xc4706000,			/* stx   %g2, [%g1 + %lo(tmptick)] */
 	    0x30800000			/* ba,a  addr			*/
@@ -1218,13 +1284,16 @@
 	ASSERT(MUTEX_HELD(&tstat_lock));
 #ifndef sun4v
 	ASSERT(entno == TSTAT_ENT_ITLBMISS || entno == TSTAT_ENT_DTLBMISS);
-#else
-	ASSERT(entno == TSTAT_ENT_ITLBMISS || entno == TSTAT_ENT_DTLBMISS ||
-	    entno == TSTAT_ENT_IMMUMISS || entno == TSTAT_ENT_DMMUMISS);
-#endif
 
 	stat = TSTAT_DATA_OFFS(tcpu, tdata_traps) + entoffs;
 	tmptick = TSTAT_DATA_OFFS(tcpu, tdata_tmptick);
+#else /* sun4v */
+	ASSERT(entno == TSTAT_ENT_ITLBMISS || entno == TSTAT_ENT_DTLBMISS ||
+	    entno == TSTAT_ENT_IMMUMISS || entno == TSTAT_ENT_DMMUMISS);
+
+	stat = TSTAT_CPU0_DATA_OFFS(tcpu, tdata_traps) + entoffs;
+	tmptick = TSTAT_CPU0_DATA_OFFS(tcpu, tdata_tmptick);
+#endif /* sun4v */
 
 	if (itlb) {
 		ret = &tcpu->tcpu_instr->tinst_itlbret;
@@ -1249,37 +1318,34 @@
 	baoffs = TSTAT_TLBENT_BA * sizeof (uint32_t);
 
 #ifdef sun4v
-	if (entno == TSTAT_ENT_IMMUMISS || entno == TSTAT_ENT_DMMUMISS) {
-		/*
-		 * Because of lack of space, interposing tlbent trap
-		 * handler for IMMU_miss and DMMU_miss traps cannot be
-		 * placed in-line. Instead, we copy it to the space set
-		 * aside for these traps in per CPU trapstat area and
-		 * invoke it by placing a branch in the trap table itself.
-		 */
-		static const uint32_t mmumiss[TSTAT_ENT_NINSTR] = {
-		    0x30800000,			/* ba,a addr */
-		    NOP, NOP, NOP, NOP, NOP, NOP, NOP
-		};
-		uint32_t *tent = ent;		/* trap vector entry */
-		uintptr_t tentva = va;		/* trap vector entry va */
+	/*
+	 * Because of lack of space, interposing tlbent trap handler
+	 * for TLB and MMU miss traps cannot be placed in-line. Instead,
+	 * we copy it to the space set aside for shared trap handlers
+	 * continuation in the interposing trap table and invoke it by
+	 * placing a branch in the trap table itself.
+	 */
+	tent = ent;		/* trap vector entry */
+	tentva = va;		/* trap vector entry va */
 
-		if (itlb) {
-			ent = (uint32_t *)((uintptr_t)
-				&tcpu->tcpu_instr->tinst_immumiss);
-			va = TSTAT_INSTR_OFFS(tcpu, tinst_immumiss);
-		} else {
-			ent = (uint32_t *)((uintptr_t)
-				&tcpu->tcpu_instr->tinst_dmmumiss);
-			va = TSTAT_INSTR_OFFS(tcpu, tinst_dmmumiss);
-		}
-		bcopy(mmumiss, tent, sizeof (mmumiss));
-		tent[0] |= DISP22(tentva, va);
+	if (itlb) {
+		ent = (uint32_t *)((uintptr_t)
+		    &tcpu->tcpu_instr->tinst_immumiss);
+		va = TSTAT_INSTR_OFFS(tcpu, tinst_immumiss);
+	} else {
+		ent = (uint32_t *)((uintptr_t)
+		    &tcpu->tcpu_instr->tinst_dmmumiss);
+		va = TSTAT_INSTR_OFFS(tcpu, tinst_dmmumiss);
 	}
+	bcopy(mmumiss, tent, sizeof (mmumiss));
+	tent[0] |= DISP22(tentva, va);
 #endif /* sun4v */
 
 	bcopy(tlbent, ent, sizeof (tlbent));
 
+#if defined(sun4v)
+	ent[TSTAT_TLBENT_TDATASHFT] |= LO10((uintptr_t)TSTAT_DATA_SHIFT);
+#endif
 	ent[TSTAT_TLBENT_STATHI] |= HI22(stat);
 	ent[TSTAT_TLBENT_STATLO_LD] |= LO10(stat);
 	ent[TSTAT_TLBENT_STATLO_ST] |= LO10(stat);
@@ -1304,6 +1370,9 @@
 	trapstat_tlbretent(tcpu, &ret->ttlbr_utsb, &udata->ttlb_tsb);
 }
 
+#if defined(sun4v)
+#undef TSTAT_TLBENT_TDATASHFT
+#endif
 #undef TSTAT_TLBENT_STATHI
 #undef TSTAT_TLBENT_STATLO_LD
 #undef TSTAT_TLBENT_STATLO_ST
@@ -1326,6 +1395,7 @@
  * #undef'd immediately afterwards.  Any change to "enabled" or "disabled"
  * in trapstat_make_traptab() will likely require changes to these constants.
  */
+#ifndef sun4v
 #define	TSTAT_ENABLED_STATHI	0
 #define	TSTAT_ENABLED_STATLO_LD	1
 #define	TSTAT_ENABLED_STATLO_ST 3
@@ -1401,6 +1471,137 @@
 #undef TSTAT_ENABLED_BA
 #undef TSTAT_DISABLED_BA
 
+#else /* sun4v */
+
+#define	TSTAT_ENABLED_STATHI	0
+#define	TSTAT_ENABLED_STATLO	1
+#define	TSTAT_ENABLED_ADDRHI	2
+#define	TSTAT_ENABLED_ADDRLO	3
+#define	TSTAT_ENABLED_CONTBA	6
+#define	TSTAT_ENABLED_TDATASHFT	7
+#define	TSTAT_DISABLED_BA	0
+
+static void
+trapstat_make_traptab(tstat_percpu_t *tcpu)
+{
+	uint32_t *ent;
+	uint64_t *stat;
+	uintptr_t orig, va, en_baoffs, dis_baoffs;
+	uintptr_t tstat_cont_va;
+	int nent;
+
+	/*
+	 * This is the entry in the interposing trap table for enabled trap
+	 * table entries.  It loads a counter, increments it and stores it
+	 * back before branching to the actual trap table entry.
+	 *
+	 * All CPUs share the same interposing trap entry to count the
+	 * number of traps. Note that the trap counter is kept in per CPU
+	 * trap statistics area. Its address is obtained dynamically by
+	 * adding the offset of that CPU's trap statistics area from CPU 0
+	 * (i.e. cpu_id * TSTAT_DATA_SIZE) to the address of the CPU 0
+	 * trap counter already coded in the interposing trap entry itself.
+	 *
+	 * Since this interposing code sequence to count traps takes more
+	 * than 8 instructions, it's split in two parts as follows:
+	 *
+	 *   tstat_trapcnt:
+	 *	sethi %hi(stat), %g1
+	 *	or    %g1, %lo[stat), %g1	! %g1 = CPU0 trap counter addr
+	 *	sethi %hi(addr), %g2
+	 *	or    %g2, %lo(addr), %g2	! %g2 = real trap handler addr
+	 *	mov   ASI_SCRATCHPAD_CPUID, %g3
+	 *	ldxa [%g3]ASI_SCRATCHPAD, %g3	! %g3 = CPU ID
+	 *	ba tstat_trapcnt_cont		! branch to tstat_trapcnt_cont
+	 *	sllx %g3, TSTAT_DATA_SHIFT, %g3	! %g3 = CPU trapstat data offset
+	 *
+	 *   tstat_trapcnt_cont:
+	 *	ldx [%g1 + %g3], %g4		! get counter value
+	 *	add %g4, 1, %g4			! increment value
+	 *	jmp %g2				! jump to original trap handler
+	 *	stx %g4, [%g1 + %g3]		! store counter value
+	 *
+	 * First part, i.e. tstat_trapcnt, is per trap and is kept in-line in
+	 * the interposing trap table. However, the tstat_trapcnt_cont code
+	 * sequence is shared by all traps and is kept right after the
+	 * the interposing trap table.
+	 */
+	static const uint32_t enabled[TSTAT_ENT_NINSTR] = {
+	    0x03000000, 		/* sethi %hi(stat), %g1		*/
+	    0x82106000,			/* or   %g1, %lo[stat), %g1	*/
+	    0x05000000, 		/* sethi %hi(addr), %g2		*/
+	    0x8410a000,			/* or   %g2, %lo(addr), %g2	*/
+	    0x86102008,			/* mov	ASI_SCRATCHPAD_CPUID, %g3 */
+	    0xc6d8c400,			/* ldxa [%g3]ASI_SCRATCHPAD, %g3 */
+	    0x10800000,			/* ba enabled_cont		*/
+	    0x8728f000			/* sllx %g3, TSTAT_DATA_SHIFT, %g3 */
+	};
+
+	static const uint32_t enabled_cont[TSTAT_ENT_NINSTR] = {
+	    0xc8584003, 		/* ldx [%g1 + %g3], %g4		*/
+	    0x88012001,			/* add %g4, 1, %g4		*/
+	    0x81c08000,			/* jmp %g2			*/
+	    0xc8704003,			/* stx %g4, [%g1 + %g3]		*/
+	    NOP, NOP, NOP, NOP
+	};
+
+	/*
+	 * This is the entry in the interposing trap table for disabled trap
+	 * table entries.  It simply branches to the actual, underlying trap
+	 * table entry.  As explained in the "Implementation Details" section
+	 * of the block comment, all TL>0 traps _must_ use the disabled entry;
+	 * additional entries may be explicitly disabled through the use
+	 * of TSTATIOC_ENTRY/TSTATIOC_NOENTRY.
+	 */
+	static const uint32_t disabled[TSTAT_ENT_NINSTR] = {
+	    0x30800000,			/* ba,a addr			*/
+	    NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+	};
+
+	ASSERT(MUTEX_HELD(&tstat_lock));
+	ent = tcpu->tcpu_instr->tinst_traptab;
+	stat = (uint64_t *)TSTAT_CPU0_DATA_OFFS(tcpu, tdata_traps);
+	orig = KERNELBASE;
+	va = (uintptr_t)tcpu->tcpu_ibase;
+	en_baoffs = TSTAT_ENABLED_CONTBA * sizeof (uint32_t);
+	dis_baoffs = TSTAT_DISABLED_BA * sizeof (uint32_t);
+	tstat_cont_va = TSTAT_INSTR_OFFS(tcpu, tinst_trapcnt);
+
+	for (nent = 0; nent < TSTAT_TOTAL_NENT; nent++) {
+		if (tstat_enabled[nent]) {
+			bcopy(enabled, ent, sizeof (enabled));
+			ent[TSTAT_ENABLED_STATHI] |= HI22((uintptr_t)stat);
+			ent[TSTAT_ENABLED_STATLO] |= LO10((uintptr_t)stat);
+			ent[TSTAT_ENABLED_ADDRHI] |= HI22((uintptr_t)orig);
+			ent[TSTAT_ENABLED_ADDRLO] |= LO10((uintptr_t)orig);
+			ent[TSTAT_ENABLED_CONTBA] |=
+			    DISP22(va + en_baoffs, tstat_cont_va);
+			ent[TSTAT_ENABLED_TDATASHFT] |=
+			    LO10((uintptr_t)TSTAT_DATA_SHIFT);
+		} else {
+			bcopy(disabled, ent, sizeof (disabled));
+			ent[TSTAT_DISABLED_BA] |= DISP22(va + dis_baoffs, orig);
+		}
+
+		stat++;
+		orig += sizeof (enabled);
+		ent += sizeof (enabled) / sizeof (*ent);
+		va += sizeof (enabled);
+	}
+	bcopy(enabled_cont, (uint32_t *)tcpu->tcpu_instr->tinst_trapcnt,
+	    sizeof (enabled_cont));
+}
+
+#undef	TSTAT_ENABLED_TDATASHFT
+#undef	TSTAT_ENABLED_STATHI
+#undef	TSTAT_ENABLED_STATLO
+#undef	TSTAT_ENABLED_ADDRHI
+#undef	TSTAT_ENABLED_ADDRLO
+#undef	TSTAT_ENABLED_CONTBA
+#undef	TSTAT_DISABLED_BA
+
+#endif /* sun4v */
+
 #ifndef sun4v
 /*
  * See Section A.6 in SPARC v9 Manual.
@@ -1430,11 +1631,11 @@
 	ASSERT(MUTEX_HELD(&cpu_lock));
 	ASSERT(MUTEX_HELD(&tstat_lock));
 
+#ifndef sun4v
 	/*
 	 * The lower fifteen bits of the %tba are always read as zero; we must
 	 * align our instruction base address appropriately.
 	 */
-#ifndef sun4v
 	tstat_offset = tstat_total_size;
 
 	cp = cpu_get(cpu);
@@ -1458,7 +1659,7 @@
 	}
 
 	tcpu->tcpu_ibase = (caddr_t)((KERNELBASE - tstat_offset)
-		& TSTAT_TBA_MASK);
+	    & TSTAT_TBA_MASK);
 	tcpu->tcpu_dbase = tcpu->tcpu_ibase + TSTAT_INSTR_SIZE;
 	tcpu->tcpu_vabase = tcpu->tcpu_ibase;
 
@@ -1487,20 +1688,6 @@
 	va = (caddr_t)tcpu->tcpu_data;
 	for (i = 0; i < tstat_data_pages; i++, va += MMU_PAGESIZE)
 		*pfn++ = hat_getpfnum(kas.a_hat, va);
-#else /* sun4v */
-	ASSERT(!(tstat_total_size > (1 + ~TSTAT_TBA_MASK)));
-	tcpu->tcpu_vabase = (caddr_t)(KERNELBASE - MMU_PAGESIZE4M);
-	tcpu->tcpu_ibase = tcpu->tcpu_vabase + (cpu * (1 + ~TSTAT_TBA_MASK));
-	tcpu->tcpu_dbase = tcpu->tcpu_ibase + TSTAT_INSTR_SIZE;
-
-	tcpu->tcpu_pfn = &tstat_pfn;
-	tcpu->tcpu_instr = (tstat_instr_t *)(tstat_va + (cpu *
-		(1 + ~TSTAT_TBA_MASK)));
-	tcpu->tcpu_data = (tstat_data_t *)(tstat_va + (cpu *
-		(1 + ~TSTAT_TBA_MASK)) + TSTAT_INSTR_SIZE);
-	bzero(tcpu->tcpu_data, tstat_data_size);
-	tcpu->tcpu_data->tdata_cpuid = cpu;
-#endif /* sun4v */
 
 	/*
 	 * Now that we have all of the instruction and data pages allocated,
@@ -1513,19 +1700,53 @@
 		 * TLB Statistics have been specified; set up the I- and D-TLB
 		 * entries and corresponding TLB return entries.
 		 */
-#ifndef sun4v
 		trapstat_tlbent(tcpu, TSTAT_ENT_ITLBMISS);
 		trapstat_tlbent(tcpu, TSTAT_ENT_DTLBMISS);
-#else
-		if (tstat_fast_tlbstat) {
-			trapstat_tlbent(tcpu, TSTAT_ENT_IMMUMISS);
-			trapstat_tlbent(tcpu, TSTAT_ENT_DMMUMISS);
-		} else {
-			trapstat_tlbent(tcpu, TSTAT_ENT_ITLBMISS);
-			trapstat_tlbent(tcpu, TSTAT_ENT_DTLBMISS);
+	}
+
+#else /* sun4v */
+
+	/*
+	 * The lower fifteen bits of the %tba are always read as zero; hence
+	 * it must be aligned at least on 512K boundary.
+	 */
+	tcpu->tcpu_vabase = (caddr_t)(KERNELBASE - MMU_PAGESIZE4M);
+	tcpu->tcpu_ibase = tcpu->tcpu_vabase;
+	tcpu->tcpu_dbase = tcpu->tcpu_ibase + TSTAT_INSTR_SIZE +
+	    cpu * TSTAT_DATA_SIZE;
+
+	tcpu->tcpu_pfn = &tstat_pfn;
+	tcpu->tcpu_instr = (tstat_instr_t *)tstat_va;
+	tcpu->tcpu_data = (tstat_data_t *)(tstat_va + TSTAT_INSTR_SIZE +
+	    cpu * TSTAT_DATA_SIZE);
+	bzero(tcpu->tcpu_data, TSTAT_DATA_SIZE);
+	tcpu->tcpu_data->tdata_cpuid = cpu;
+
+	/*
+	 * Now that we have all of the instruction and data pages allocated,
+	 * make the trap table from scratch. It should be done only once
+	 * as it is shared by all CPUs.
+	 */
+	if (!tstat_traptab_initialized)
+		trapstat_make_traptab(tcpu);
+
+	if (tstat_options & TSTAT_OPT_TLBDATA) {
+		/*
+		 * TLB Statistics have been specified; set up the I- and D-TLB
+		 * entries and corresponding TLB return entries.
+		 */
+		if (!tstat_traptab_initialized) {
+			if (tstat_fast_tlbstat) {
+				trapstat_tlbent(tcpu, TSTAT_ENT_IMMUMISS);
+				trapstat_tlbent(tcpu, TSTAT_ENT_DMMUMISS);
+			} else {
+				trapstat_tlbent(tcpu, TSTAT_ENT_ITLBMISS);
+				trapstat_tlbent(tcpu, TSTAT_ENT_DTLBMISS);
+			}
 		}
-#endif
 	}
+	tstat_traptab_initialized = 1;
+#endif /* sun4v */
 
 	tcpu->tcpu_flags |= TSTAT_CPU_ALLOCATED;
 
@@ -1607,6 +1828,7 @@
 	if (tstat_options & TSTAT_OPT_TLBDATA) {
 		int error;
 
+		tstat_fast_tlbstat = B_FALSE;
 		error = cpu_trapstat_conf(CPU_TSTATCONF_INIT);
 		if (error == 0)
 			tstat_fast_tlbstat = B_TRUE;
@@ -1617,7 +1839,7 @@
 			return (error);
 		}
 	}
-#endif
+#endif /* sun4v */
 
 	/*
 	 * First, perform any necessary hot patching.
@@ -1676,6 +1898,7 @@
 	}
 
 #ifdef sun4v
+	tstat_traptab_initialized = 0;
 	if (tstat_options & TSTAT_OPT_TLBDATA)
 		cpu_trapstat_conf(CPU_TSTATCONF_FINI);
 	contig_mem_free(tstat_va, MMU_PAGESIZE4M);
@@ -2138,11 +2361,7 @@
 	tstat_data_size = tstat_data_pages * MMU_PAGESIZE;
 	tstat_total_size = TSTAT_INSTR_SIZE + tstat_data_size;
 #else
-	tstat_data_pages = 0;
-	tstat_data_size = tstat_data_t_size;
-	tstat_total_pages = ((TSTAT_INSTR_SIZE + tstat_data_size) >>
-		MMU_PAGESHIFT) + 1;
-	tstat_total_size = tstat_total_pages * MMU_PAGESIZE;
+	ASSERT(tstat_data_t_size <= TSTAT_DATA_SIZE);
 #endif
 
 	tstat_percpu = kmem_zalloc((max_cpuid + 1) *
--- a/usr/src/uts/sun4/sys/trapstat.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4/sys/trapstat.h	Wed Jul 25 18:20:14 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -108,7 +107,8 @@
 #define	TSTAT_PROBE_NLAPS	10
 
 #ifdef sun4v
-#define	TSTAT_TLBENT_NINSTR	32
+#define	TSTAT_TRAPCNT_NINSTR	8
+#define	TSTAT_TLBENT_NINSTR	64
 #define	TSTAT_ENT_IMMUMISS	0x09
 #define	TSTAT_ENT_DMMUMISS	0x31
 #endif
@@ -140,6 +140,7 @@
 #ifdef sun4v
 	tstat_tlbent_t	tinst_immumiss;
 	tstat_tlbent_t	tinst_dmmumiss;
+	uint32_t	tinst_trapcnt[TSTAT_TRAPCNT_NINSTR];
 #endif
 } tstat_instr_t;
 
@@ -151,20 +152,33 @@
 #endif
 
 #ifdef sun4v
-#if (NCPU > 128)
-#error "sun4v trapstat supports upto 128 cpus"
+
+#if (NCPU > 508)
+#error "sun4v trapstat supports up to 508 cpus"
 #endif
+
 #define	TSTAT_TLB_STATS		0x1		/* cpu_tstat_flags */
-#define	TSTAT_INSTR_SIZE	(sizeof (tstat_instr_t))
-#define	TSTAT_TBA_MASK		~((1 << 15) - 1)	/* 32K per cpu */
+#define	TSTAT_INSTR_SIZE	\
+	((sizeof (tstat_instr_t) + MMU_PAGESIZE - 1) & ~(MMU_PAGESIZE - 1))
+#define	TSTAT_DATA_SHIFT	13
+#define	TSTAT_DATA_SIZE		(1 << TSTAT_DATA_SHIFT)	/* 8K per CPU */
+#define	TSTAT_TBA_MASK		~((1 << 15) - 1)	/* 32K boundary */
+
+#define	TSTAT_CPU0_DATA_OFFS(tcpu, mem)	\
+	((uintptr_t)(tcpu)->tcpu_ibase + TSTAT_INSTR_SIZE + \
+	    offsetof(tstat_data_t, mem))
+
 #else /* sun4v */
+
 #define	TSTAT_INSTR_PAGES	((sizeof (tstat_instr_t) >> MMU_PAGESHIFT) + 1)
 #define	TSTAT_INSTR_SIZE	(TSTAT_INSTR_PAGES * MMU_PAGESIZE)
 #define	TSTAT_TBA_MASK		~((1 << 16) - 1)	/* 64K per cpu */
-#endif /* sun4v */
 
 #define	TSTAT_DATA_OFFS(tcpu, mem)	\
 	((uintptr_t)(tcpu)->tcpu_dbase + offsetof(tstat_data_t, mem))
+
+#endif /* sun4v */
+
 #define	TSTAT_INSTR_OFFS(tcpu, mem)	\
 	((uintptr_t)(tcpu)->tcpu_ibase + offsetof(tstat_instr_t, mem))
 
--- a/usr/src/uts/sun4u/Makefile.files	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4u/Makefile.files	Wed Jul 25 18:20:14 2007 -0700
@@ -33,6 +33,7 @@
 #
 #	object lists
 #
+CORE_OBJS +=	atomic.o
 CORE_OBJS +=	bootops.o
 CORE_OBJS +=	cmp.o
 CORE_OBJS +=	cpc_hwreg.o
--- a/usr/src/uts/sun4v/Makefile	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -1,4 +1,4 @@
-#
+ #
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
@@ -33,6 +33,8 @@
 include Makefile.sun4v
 include Makefile.stpaul
 include Makefile.huron
+include Makefile.maramba
+
 USR_GLENDALE_DIR	= $(USR_PLAT_DIR)/SUNW,Sun-Blade-T6320
 USR_GLENDALE_SBIN_DIR	= $(USR_GLENDALE_DIR)/sbin
 USR_GLENDALE_LIB_DIR	= $(USR_GLENDALE_DIR)/lib
@@ -175,12 +177,14 @@
 
 PLATFORMS	+= $(IMPLEMENTED_PLATFORM)
 
+
 #
 # Make the /platforms directories.  This is hardwired here because
 # the first stage of the project (KBI) only implements the userland
 # changes, but the only reasonable place to record the aliases is
 # here in kernel land.
 #
+
 install_platforms:	$(ROOT_PSM_DIR) $(USR_PSM_DIR) \
 			$(ROOT_PLAT_DIRS) $(USR_PLAT_DIRS) \
 			$(LINKED_PLATFORMS:%=$(ROOT_PLAT_DIR)/%) \
@@ -191,7 +195,10 @@
 			$(USR_GLENDALE_DIR) $(USR_GLENDALE_SBIN_DIR) \
 			$(USR_GLENDALE_LIB_DIR) \
 			$(USR_HURON_DIR) \
-			$(USR_HURON_SBIN_DIR) $(USR_HURON_LIB_DIR)
+			$(USR_HURON_SBIN_DIR) $(USR_HURON_LIB_DIR) \
+			$(USR_MARAMBA_DIR) $(USR_MARAMBA_SBIN_DIR) \
+			$(USR_MARAMBA_LIB_DIR)
+
 
 #
 # rules for making include, sbin, lib dirs/links in
@@ -232,6 +239,16 @@
 
 $(USR_GLENDALE_LIB_DIR):		$(USR_GLENDALE_DIR)
 	-$(INS.dir.root.bin)
+
+$(USR_MARAMBA_DIR):		$(USR_SUN4V_PLAT_DIR)
+	-$(INS.dir.root.sys)
+
+$(USR_MARAMBA_SBIN_DIR):	$(USR_MARAMBA_DIR)
+	$(INS.slink5)
+
+$(USR_MARAMBA_LIB_DIR):		$(USR_MARAMBA_DIR)
+	-$(INS.dir.root.bin)
+
 #
 #	Full kernel lint target.
 #
--- a/usr/src/uts/sun4v/Makefile.files	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/Makefile.files	Wed Jul 25 18:20:14 2007 -0700
@@ -179,11 +179,11 @@
 # XXXQ Make generic4vcpu
 #
 CPU_OBJ		+= $(OBJS_DIR)/mach_cpu_module.o
-GENERIC_OBJS = generic.o generic_copy.o common_asm.o
+GENERIC_OBJS = generic.o generic_copy.o common_asm.o atomic.o
 NIAGARACPU_OBJS = niagara.o niagara_copy.o common_asm.o niagara_perfctr.o
-NIAGARACPU_OBJS += niagara_asm.o
+NIAGARACPU_OBJS += niagara_asm.o atomic.o
 NIAGARA2CPU_OBJS = niagara2.o niagara_copy.o common_asm.o niagara_perfctr.o
-NIAGARA2CPU_OBJS += niagara2_asm.o
+NIAGARA2CPU_OBJS += niagara2_asm.o niagara2_atomic.o
 
 #
 #			platform module
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4v/Makefile.maramba	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,37 @@
+#
+# 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"
+#
+#	Global definitions for sun4v maramba implementation specific modules.
+#
+
+#
+#	Define directories.
+#
+
+USR_MARAMBA_DIR		= $(USR_PLAT_DIR)/SUNW,T5140
+USR_MARAMBA_SBIN_DIR	= $(USR_MARAMBA_DIR)/sbin
+USR_MARAMBA_LIB_DIR	= $(USR_MARAMBA_DIR)/lib
--- a/usr/src/uts/sun4v/Makefile.sun4v.shared	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/Makefile.sun4v.shared	Wed Jul 25 18:20:14 2007 -0700
@@ -36,6 +36,8 @@
 LINKED_PLATFORMS += SUNW,Sun-Fire-T1000
 LINKED_PLATFORMS += SUNW,SPARC-Enterprise-T5120
 LINKED_PLATFORMS += SUNW,SPARC-Enterprise-T5220
+LINKED_PLATFORMS += SUNW,T5140
+LINKED_PLATFORMS += SUNW,T5240
 LINKED_PLATFORMS += SUNW,SPARC-Enterprise-T1000
 LINKED_PLATFORMS += SUNW,Sun-Blade-T6300
 LINKED_PLATFORMS += SUNW,Sun-Blade-T6320
@@ -76,7 +78,7 @@
 #IMPLEMENTED_PLATFORM	=
 #PLATFORMS                = $(IMPLEMENTED_PLATFORM)
 
-IMPLEMENTATIONS		= ontario montoya huron
+IMPLEMENTATIONS		= ontario montoya huron maramba
 
 #ROOT_PLAT_DIRS		= $(PLATFORMS:%=$(ROOT_PLAT_DIR)/%)
 #USR_PLAT_DIRS		= $(PLATFORMS:%=$(USR_PLAT_DIR)/%)
@@ -428,10 +430,11 @@
 #
 #	cpu modules
 #
-CPU_KMODS	+= generic niagara niagara2
+CPU_KMODS	+= generic niagara niagara2 vfalls
 
 #
 #	Performance Counter BackEnd Modules (/usr/kernel/pcbe):
 #
 PCBE_KMODS	+= niagara_pcbe
 PCBE_KMODS	+= niagara2_pcbe
+PCBE_KMODS	+= vfalls_pcbe
--- a/usr/src/uts/sun4v/cpu/generic.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/cpu/generic.c	Wed Jul 25 18:20:14 2007 -0700
@@ -168,6 +168,11 @@
 		cp->cpu_m.cpu_fpu = (id_t)(cp->cpu_id);
 
 	cp->cpu_m.cpu_core = (id_t)(cp->cpu_id);
+
+	/*
+	 * The cpu_chip field is set to invalid(unknown) for generic cpu.
+	 */
+	cp->cpu_m.cpu_chip = CPU_CHIPID_INVALID;
 }
 
 void
--- a/usr/src/uts/sun4v/cpu/mach_cpu_module.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/cpu/mach_cpu_module.c	Wed Jul 25 18:20:14 2007 -0700
@@ -153,6 +153,549 @@
 cpu_inv_tsb(caddr_t tsb_base, uint_t tsb_bytes)
 {}
 
+/*
+ *  Atomic Function Stubs
+ */
+
+uint8_t
+cas8(uint8_t *target, uint8_t value1, uint8_t value2)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+cas32(uint32_t *target, uint32_t value1, uint32_t value2)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+cas64(uint64_t *target, uint64_t value1, uint64_t value2)
+{ return (0); }
+
+/* ARGSUSED */
+ulong_t
+caslong(ulong_t *target, ulong_t value1, ulong_t value2)
+{ return (0); }
+
+/* ARGSUSED */
+void *
+casptr(void *ptr1, void *ptr2, void *ptr3)
+{ return (0); }
+
+/* ARGSUSED */
+void
+atomic_and_long(ulong_t *target, ulong_t value)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_long(ulong_t *target, ulong_t value)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_8(volatile uint8_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_uchar(volatile uchar_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_16(volatile uint16_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_ushort(volatile ushort_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_32(volatile uint32_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_uint(volatile uint_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_ulong(volatile ulong_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_inc_64(volatile uint64_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_8(volatile uint8_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_uchar(volatile uchar_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_16(volatile uint16_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_ushort(volatile ushort_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_32(volatile uint32_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_uint(volatile uint_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_ulong(volatile ulong_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_dec_64(volatile uint64_t *target)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_8(volatile uint8_t *target, int8_t value)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_char(volatile uchar_t *target, signed char value)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_16(volatile uint16_t *target, int16_t delta)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_ushort(volatile ushort_t *target, short value)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_32(volatile uint32_t *target, int32_t delta)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_ptr(volatile void *target, ssize_t value)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_long(volatile ulong_t *target, long delta)
+{}
+
+/* ARGSUSED */
+void
+atomic_add_64(volatile uint64_t *target, int64_t delta)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_8(volatile uint8_t *target, uint8_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_uchar(volatile uchar_t *target, uchar_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_16(volatile uint16_t *target, uint16_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_ushort(volatile ushort_t *target, ushort_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_32(volatile uint32_t *target, uint32_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_uint(volatile uint_t *target, uint_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_ulong(volatile ulong_t *target, ulong_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_or_64(volatile uint64_t *target, uint64_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_8(volatile uint8_t *target, uint8_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_uchar(volatile uchar_t *target, uchar_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_16(volatile uint16_t *target, uint16_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_ushort(volatile ushort_t *target, ushort_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_32(volatile uint32_t *target, uint32_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_uint(volatile uint_t *target, uint_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_ulong(volatile ulong_t *target, ulong_t bits)
+{}
+
+/* ARGSUSED */
+void
+atomic_and_64(volatile uint64_t *target, uint64_t bits)
+{}
+
+/* ARGSUSED */
+uint8_t
+atomic_inc_8_nv(volatile uint8_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uchar_t
+atomic_inc_uchar_nv(volatile uchar_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint16_t
+atomic_inc_16_nv(volatile uint16_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+ushort_t
+atomic_inc_ushort_nv(volatile ushort_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+atomic_inc_32_nv(volatile uint32_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint_t
+atomic_inc_uint_nv(volatile uint_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+ulong_t
+atomic_inc_ulong_nv(volatile ulong_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+atomic_inc_64_nv(volatile uint64_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint8_t
+atomic_dec_8_nv(volatile uint8_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uchar_t
+atomic_dec_uchar_nv(volatile uchar_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint16_t
+atomic_dec_16_nv(volatile uint16_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+ushort_t
+atomic_dec_ushort_nv(volatile ushort_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+atomic_dec_32_nv(volatile uint32_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint_t
+atomic_dec_uint_nv(volatile uint_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+ulong_t
+atomic_dec_ulong_nv(volatile ulong_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+atomic_dec_64_nv(volatile uint64_t *target)
+{ return (0); }
+
+/* ARGSUSED */
+uint8_t
+atomic_add_8_nv(volatile uint8_t *target, int8_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uchar_t
+atomic_add_char_nv(volatile uchar_t *target, signed char value)
+{ return (0); }
+
+/* ARGSUSED */
+uint16_t
+atomic_add_16_nv(volatile uint16_t *target, int16_t delta)
+{ return (0); }
+
+/* ARGSUSED */
+ushort_t
+atomic_add_short_nv(volatile ushort_t *target, short value)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+atomic_add_32_nv(volatile uint32_t *target, int32_t delta)
+{ return (0); }
+
+/* ARGSUSED */
+uint_t
+atomic_add_int_nv(volatile uint_t *target, int delta)
+{ return (0); }
+
+/* ARGSUSED */
+void *
+atomic_add_ptr_nv(volatile void *target, ssize_t value)
+{ return (NULL); }
+
+/* ARGSUSED */
+ulong_t
+atomic_add_long_nv(volatile ulong_t *target, long delta)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+atomic_add_64_nv(volatile uint64_t *target, int64_t delta)
+{ return (0); }
+
+/* ARGSUSED */
+uint8_t
+atomic_or_8_nv(volatile uint8_t *target, uint8_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uchar_t
+atomic_or_uchar_nv(volatile uchar_t *target, uchar_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint16_t
+atomic_or_16_nv(volatile uint16_t *target, uint16_t value)
+{ return (0); }
+
+/* ARGSUSED */
+ushort_t
+atomic_or_ushort_nv(volatile ushort_t *target, ushort_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+atomic_or_32_nv(volatile uint32_t *target, uint32_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint_t
+atomic_or_uint_nv(volatile uint_t *target, uint_t value)
+{ return (0); }
+
+/* ARGSUSED */
+ulong_t
+atomic_or_ulong_nv(volatile ulong_t *target, ulong_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+atomic_or_64_nv(volatile uint64_t *target, uint64_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint8_t
+atomic_and_8_nv(volatile uint8_t *target, uint8_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uchar_t
+atomic_and_uchar_nv(volatile uchar_t *target, uchar_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint16_t
+atomic_and_16_nv(volatile uint16_t *target, uint16_t value)
+{ return (0); }
+
+/* ARGSUSED */
+ushort_t
+atomic_and_ushort_nv(volatile ushort_t *target, ushort_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+atomic_and_32_nv(volatile uint32_t *target, uint32_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint_t
+atomic_and_uint_nv(volatile uint_t *target, uint_t value)
+{ return (0); }
+
+/* ARGSUSED */
+ulong_t
+atomic_and_ulong_nv(volatile ulong_t *target, ulong_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+atomic_and_64_nv(volatile uint64_t *target, uint64_t value)
+{ return (0); }
+
+/* ARGSUSED */
+uint8_t
+atomic_cas_8(volatile uint8_t *target, uint8_t cmp, uint8_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uchar_t
+atomic_cas_uchar(volatile uchar_t *target, uchar_t cmp, uchar_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint16_t
+atomic_cas_16(volatile uint16_t *target, uint16_t cmp, uint16_t new)
+{ return (0); }
+
+/* ARGSUSED */
+ushort_t
+atomic_cas_ushort(volatile ushort_t *target, ushort_t cmp, ushort_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+atomic_cas_32(volatile uint32_t *target, uint32_t cmp, uint32_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint_t
+atomic_cas_uint(volatile uint_t *target, uint_t cmp, uint_t new)
+{ return (0); }
+
+/* ARGSUSED */
+ulong_t
+atomic_cas_ulong(volatile ulong_t *target, ulong_t cmp, ulong_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+atomic_cas_uint64(volatile uint64_t *target, ulong_t cmp, uint64_t new)
+{ return (0); }
+
+/* ARGSUSED */
+void *
+atomic_cas_ptr(volatile void *target, void *cmp, void *new)
+{ return (NULL); }
+
+/* ARGSUSED */
+uint8_t
+atomic_swap_8(volatile uint8_t *target, uint8_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uchar_t
+atomic_swap_char(volatile uchar_t *target, uchar_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint16_t
+atomic_swap_16(volatile uint16_t *target, uint16_t new)
+{ return (0); }
+
+/* ARGSUSED */
+ushort_t
+atomic_swap_ushort(volatile ushort_t *target, ushort_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint32_t
+atomic_swap_32(volatile uint32_t *target, uint32_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint_t
+atomic_swap_uint(volatile uint_t *target, uint_t new)
+{ return (0); }
+
+/* ARGSUSED */
+uint64_t
+atomic_swap_64(volatile uint64_t *target, uint64_t new)
+{ return (0); }
+
+/* ARGSUSED */
+void *
+atomic_swap_ptr(volatile void *target, void *new)
+{ return (NULL); }
+
+/* ARGSUSED */
+ulong_t
+atomic_swap_ulong(volatile ulong_t *target, ulong_t new)
+{ return (0); }
+
+/* ARGSUSED */
+int
+atomic_set_long_excl(volatile ulong_t *target, uint_t value)
+{ return (0); }
+
+/* ARGSUSED */
+int
+atomic_clear_long_excl(volatile ulong_t *target, uint_t value)
+{ return (0); }
+
 void
 fp_zero(void)
 {}
--- a/usr/src/uts/sun4v/cpu/niagara.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/cpu/niagara.c	Wed Jul 25 18:20:14 2007 -0700
@@ -190,6 +190,12 @@
 	 * Niagara defines the the core to be at the ipipe level
 	 */
 	cp->cpu_m.cpu_core = cp->cpu_m.cpu_ipipe;
+
+	/*
+	 * Niagara systems just have one chip. Therefore, the chip id
+	 * is always 0.
+	 */
+	cp->cpu_m.cpu_chip = 0;
 }
 
 static int niagara_cpucnt;
--- a/usr/src/uts/sun4v/cpu/niagara2.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/cpu/niagara2.c	Wed Jul 25 18:20:14 2007 -0700
@@ -61,17 +61,29 @@
 #include <sys/trapstat.h>
 
 uint_t root_phys_addr_lo_mask = 0xffffffffU;
+#if defined(NIAGARA2_IMPL)
 char cpu_module_name[] = "SUNW,UltraSPARC-T2";
+#elif defined(VFALLS_IMPL)
+char cpu_module_name[] = "SUNW,UltraSPARC-T2+";
+#endif
 
 /*
- * Hypervisor services information for the NIAGARA2 CPU module
+ * Hypervisor services information for the NIAGARA2 and Victoria Falls
+ * CPU module
  */
-static boolean_t niagara2_hsvc_available = B_TRUE;
-static uint64_t niagara2_sup_minor;		/* Supported minor number */
-static hsvc_info_t niagara2_hsvc = {
+static boolean_t cpu_hsvc_available = B_TRUE;
+static uint64_t cpu_sup_minor;		/* Supported minor number */
+#if defined(NIAGARA2_IMPL)
+static hsvc_info_t cpu_hsvc = {
 	HSVC_REV_1, NULL, HSVC_GROUP_NIAGARA2_CPU, NIAGARA2_HSVC_MAJOR,
 	NIAGARA2_HSVC_MINOR, cpu_module_name
 };
+#elif defined(VFALLS_IMPL)
+static hsvc_info_t cpu_hsvc = {
+	HSVC_REV_1, NULL, HSVC_GROUP_VFALLS_CPU, VFALLS_HSVC_MAJOR,
+	VFALLS_HSVC_MINOR, cpu_module_name
+};
+#endif
 
 void
 cpu_setup(void)
@@ -85,13 +97,13 @@
 	 * Negotiate the API version for Niagara2 specific hypervisor
 	 * services.
 	 */
-	status = hsvc_register(&niagara2_hsvc, &niagara2_sup_minor);
+	status = hsvc_register(&cpu_hsvc, &cpu_sup_minor);
 	if (status != 0) {
 		cmn_err(CE_WARN, "%s: cannot negotiate hypervisor services "
 		    "group: 0x%lx major: 0x%lx minor: 0x%lx errno: %d",
-		    niagara2_hsvc.hsvc_modname, niagara2_hsvc.hsvc_group,
-		    niagara2_hsvc.hsvc_major, niagara2_hsvc.hsvc_minor, status);
-		niagara2_hsvc_available = B_FALSE;
+		    cpu_hsvc.hsvc_modname, cpu_hsvc.hsvc_group,
+		    cpu_hsvc.hsvc_major, cpu_hsvc.hsvc_minor, status);
+		cpu_hsvc_available = B_FALSE;
 	}
 
 	/*
@@ -179,9 +191,19 @@
 	 * Niagara 2 defines the core to be at the FPU level
 	 */
 	cp->cpu_m.cpu_core = cp->cpu_m.cpu_fpu;
+
+	/*
+	 * The cpu_chip field is initialized based on the information
+	 * in the MD and assume that all cpus within a chip
+	 * share the same L2 cache. If no such info is available, we
+	 * set the cpu to belong to the defacto chip 0.
+	 */
+	cp->cpu_m.cpu_chip = cpunodes[cp->cpu_id].l2_cache_mapping;
+	if (cp->cpu_m.cpu_chip == NO_CHIP_MAPPING_FOUND)
+		cp->cpu_m.cpu_chip = 0;
 }
 
-static int niagara2_cpucnt;
+static int cpucnt;
 
 void
 cpu_init_private(struct cpu *cp)
@@ -192,8 +214,8 @@
 
 	cpu_map_exec_units(cp);
 
-	if ((niagara2_cpucnt++ == 0) && (niagara2_hsvc_available == B_TRUE))
-		niagara_kstat_init();
+	if ((cpucnt++ == 0) && (cpu_hsvc_available == B_TRUE))
+		(void) niagara_kstat_init();
 }
 
 /*ARGSUSED*/
@@ -203,9 +225,8 @@
 	extern void niagara_kstat_fini(void);
 
 	ASSERT(MUTEX_HELD(&cpu_lock));
-
-	if ((--niagara2_cpucnt == 0) && (niagara2_hsvc_available == B_TRUE))
-		niagara_kstat_fini();
+	if ((--cpucnt == 0) && (cpu_hsvc_available == B_TRUE))
+		(void) niagara_kstat_fini();
 }
 
 /*
@@ -483,7 +504,7 @@
 			if (a > (colorequivszc[i] & 0xf) +
 			    (colorequivszc[i] >> 4)) {
 				if (a <= nequiv_shades_log2[i]) {
-					colorequivszc[i] = a;
+					colorequivszc[i] = (uchar_t)a;
 				} else {
 					colorequivszc[i] =
 					    ((a - nequiv_shades_log2[i]) << 4) |
--- a/usr/src/uts/sun4v/cpu/niagara2_asm.s	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/cpu/niagara2_asm.s	Wed Jul 25 18:20:14 2007 -0700
@@ -60,7 +60,11 @@
 	 */
 	ENTRY(hv_niagara_getperf)
 	mov     %o1, %o4                        ! save datap
+#if defined(NIAGARA2_IMPL)
 	mov     HV_NIAGARA2_GETPERF, %o5
+#elif defined(VFALLS_IMPL)
+	mov	HV_VFALLS_GETPERF, %o5
+#endif
 	ta      FAST_TRAP
 	brz,a   %o0, 1f
 	stx     %o1, [%o4]
@@ -73,7 +77,11 @@
 	 * hv_niagara_setperf(uint64_t perfreg, uint64_t data)
 	 */
 	ENTRY(hv_niagara_setperf)
+#if defined(NIAGARA2_IMPL)
 	mov     HV_NIAGARA2_SETPERF, %o5
+#elif defined(VFALLS_IMPL)
+	mov     HV_VFALLS_SETPERF, %o5
+#endif
 	ta      FAST_TRAP
 	retl
 	nop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4v/cpu/niagara2_atomic.s	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,729 @@
+/*
+ * 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"
+
+#if !defined(lint)
+#include <sys/asm_linkage.h>
+
+#if defined(_KERNEL)
+	/*
+	 * Legacy kernel interfaces; they will go away (eventually).
+	 */
+	ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function)
+	ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function)
+	ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function)
+	ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function)
+	ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function)
+	ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function)
+	ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function)
+	ANSI_PRAGMA_WEAK2(swapl,atomic_swap_32,function)
+#else
+	/*
+	 * Include the definitions for the libc weak aliases.
+	 */
+#include "../atomic_asm_weak.h"
+#endif
+
+#ifdef N2_ERRATUM_181_WORKAROUND
+#define	BACKOFF_INIT_VALUE	1
+#define	BACKOFF_LIMIT_VALUE	16384
+	
+#define	ATOMIC_BACKOFF_INIT(val) \
+	mov	BACKOFF_INIT_VALUE, val
+	
+#define	ATOMIC_BACKOFF_BRANCH(cr, backoff, loop) \
+	bne,a,pn cr, backoff
+	
+#define	ATOMIC_BACKOFF_BACKOFF(val, limit, label, retlabel) \
+	/* simplistic exponential back-off */ \
+	set	BACKOFF_LIMIT_VALUE, limit	; \
+	cmp	val, limit	; \
+	blu,a,pt %xcc, label/**/_0 ; \
+	  sllx	val, 1, val	; \
+label/**/_0:			; \
+	mov	val, limit	; \
+label/**/_1:			; \
+	deccc	limit		; \
+	bnz,pn	%xcc, label/**/_1 ; \
+	nop			; \
+	ba,pt	%xcc, retlabel	; \
+	nop
+#else
+#define	ATOMIC_BACKOFF_INIT(val)
+	
+#define	ATOMIC_BACKOFF_BRANCH(cr, backoff, loop) \
+	bne,a,pn cr, loop
+	
+#define	ATOMIC_BACKOFF_BACKOFF(val, limit, label, retlabel)
+#endif
+
+
+	ENTRY(atomic_inc_8)
+	ALTENTRY(atomic_inc_8_nv)
+	ALTENTRY(atomic_inc_uchar)
+	ALTENTRY(atomic_inc_uchar_nv)
+	ba	add_8
+	  add	%g0, 1, %o1
+	SET_SIZE(atomic_inc_uchar_nv)
+	SET_SIZE(atomic_inc_uchar)
+	SET_SIZE(atomic_inc_8_nv)
+	SET_SIZE(atomic_inc_8)
+
+	ENTRY(atomic_dec_8)
+	ALTENTRY(atomic_dec_8_nv)
+	ALTENTRY(atomic_dec_uchar)
+	ALTENTRY(atomic_dec_uchar_nv)
+	ba	add_8
+	  sub	%g0, 1, %o1
+	SET_SIZE(atomic_dec_uchar_nv)
+	SET_SIZE(atomic_dec_uchar)
+	SET_SIZE(atomic_dec_8_nv)
+	SET_SIZE(atomic_dec_8)
+
+	ENTRY(atomic_add_8)
+	ALTENTRY(atomic_add_8_nv)
+	ALTENTRY(atomic_add_char)
+	ALTENTRY(atomic_add_char_nv)
+add_8:
+	and	%o0, 0x3, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x3, %g1		! %g1 = byte offset, right-to-left
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	set	0xff, %o3		! %o3 = mask
+	sll	%o3, %g1, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single byte value
+	andn	%o0, 0x3, %o0		! %o0 = word address
+	ld	[%o0], %o2		! read old value
+1:
+	add	%o2, %o1, %o5		! add value to the old value
+	and	%o5, %o3, %o5		! clear other bits
+	andn	%o2, %o3, %o4		! clear target bits
+	or	%o4, %o5, %o5		! insert the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	add	%o2, %o1, %o5
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = new value
+	SET_SIZE(atomic_add_char_nv)
+	SET_SIZE(atomic_add_char)
+	SET_SIZE(atomic_add_8_nv)
+	SET_SIZE(atomic_add_8)
+
+	ENTRY(atomic_inc_16)
+	ALTENTRY(atomic_inc_16_nv)
+	ALTENTRY(atomic_inc_ushort)
+	ALTENTRY(atomic_inc_ushort_nv)
+	ba	add_16
+	  add	%g0, 1, %o1
+	SET_SIZE(atomic_inc_ushort_nv)
+	SET_SIZE(atomic_inc_ushort)
+	SET_SIZE(atomic_inc_16_nv)
+	SET_SIZE(atomic_inc_16)
+
+	ENTRY(atomic_dec_16)
+	ALTENTRY(atomic_dec_16_nv)
+	ALTENTRY(atomic_dec_ushort)
+	ALTENTRY(atomic_dec_ushort_nv)
+	ba	add_16
+	  sub	%g0, 1, %o1
+	SET_SIZE(atomic_dec_ushort_nv)
+	SET_SIZE(atomic_dec_ushort)
+	SET_SIZE(atomic_dec_16_nv)
+	SET_SIZE(atomic_dec_16)
+
+	ENTRY(atomic_add_16)
+	ALTENTRY(atomic_add_16_nv)
+	ALTENTRY(atomic_add_short)
+	ALTENTRY(atomic_add_short_nv)
+add_16:
+	and	%o0, 0x2, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x2, %g1		! %g1 = byte offset, right-to-left
+	sll	%o4, 3, %o4		! %o4 = bit offset, left-to-right
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	sethi	%hi(0xffff0000), %o3	! %o3 = mask
+	srl	%o3, %o4, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single short value
+	andn	%o0, 0x2, %o0		! %o0 = word address
+	! if low-order bit is 1, we will properly get an alignment fault here
+	ld	[%o0], %o2		! read old value
+1:
+	add	%o1, %o2, %o5		! add value to the old value
+	and	%o5, %o3, %o5		! clear other bits
+	andn	%o2, %o3, %o4		! clear target bits
+	or	%o4, %o5, %o5		! insert the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	add	%o1, %o2, %o5
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = new value
+	SET_SIZE(atomic_add_short_nv)
+	SET_SIZE(atomic_add_short)
+	SET_SIZE(atomic_add_16_nv)
+	SET_SIZE(atomic_add_16)
+
+	ENTRY(atomic_inc_32)
+	ALTENTRY(atomic_inc_32_nv)
+	ALTENTRY(atomic_inc_uint)
+	ALTENTRY(atomic_inc_uint_nv)
+	ba	add_32
+	  add	%g0, 1, %o1
+	SET_SIZE(atomic_inc_uint_nv)
+	SET_SIZE(atomic_inc_uint)
+	SET_SIZE(atomic_inc_32_nv)
+	SET_SIZE(atomic_inc_32)
+
+	ENTRY(atomic_dec_32)
+	ALTENTRY(atomic_dec_32_nv)
+	ALTENTRY(atomic_dec_uint)
+	ALTENTRY(atomic_dec_uint_nv)
+	ba	add_32
+	  sub	%g0, 1, %o1
+	SET_SIZE(atomic_dec_uint_nv)
+	SET_SIZE(atomic_dec_uint)
+	SET_SIZE(atomic_dec_32_nv)
+	SET_SIZE(atomic_dec_32)
+
+
+	ENTRY(atomic_add_32)
+	ALTENTRY(atomic_add_32_nv)
+	ALTENTRY(atomic_add_int)
+	ALTENTRY(atomic_add_int_nv)
+add_32:
+	ATOMIC_BACKOFF_INIT(%o4)
+	ld	[%o0], %o2
+1:
+	add	%o2, %o1, %o3
+	cas	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%icc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	add	%o2, %o1, %o0		! return new value
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, add32, 1b)
+	SET_SIZE(atomic_add_int_nv)
+	SET_SIZE(atomic_add_int)
+	SET_SIZE(atomic_add_32_nv)
+	SET_SIZE(atomic_add_32)
+
+	ENTRY(atomic_inc_64)
+	ALTENTRY(atomic_inc_64_nv)
+	ALTENTRY(atomic_inc_ulong)
+	ALTENTRY(atomic_inc_ulong_nv)
+	ba	add_64
+	  add	%g0, 1, %o1
+	SET_SIZE(atomic_inc_ulong_nv)
+	SET_SIZE(atomic_inc_ulong)
+	SET_SIZE(atomic_inc_64_nv)
+	SET_SIZE(atomic_inc_64)
+
+	ENTRY(atomic_dec_64)
+	ALTENTRY(atomic_dec_64_nv)
+	ALTENTRY(atomic_dec_ulong)
+	ALTENTRY(atomic_dec_ulong_nv)
+	ba	add_64
+	  sub	%g0, 1, %o1
+	SET_SIZE(atomic_dec_ulong_nv)
+	SET_SIZE(atomic_dec_ulong)
+	SET_SIZE(atomic_dec_64_nv)
+	SET_SIZE(atomic_dec_64)
+
+	ENTRY(atomic_add_64)
+	ALTENTRY(atomic_add_64_nv)
+	ALTENTRY(atomic_add_ptr)
+	ALTENTRY(atomic_add_ptr_nv)
+	ALTENTRY(atomic_add_long)
+	ALTENTRY(atomic_add_long_nv)
+add_64:
+	ATOMIC_BACKOFF_INIT(%o4)
+	ldx	[%o0], %o2
+1:
+	add	%o2, %o1, %o3
+	casx	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%xcc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	add	%o2, %o1, %o0		! return new value
+
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, add64, 1b)
+	SET_SIZE(atomic_add_long_nv)
+	SET_SIZE(atomic_add_long)
+	SET_SIZE(atomic_add_ptr_nv)
+	SET_SIZE(atomic_add_ptr)
+	SET_SIZE(atomic_add_64_nv)
+	SET_SIZE(atomic_add_64)
+
+	ENTRY(atomic_or_8)
+	ALTENTRY(atomic_or_8_nv)
+	ALTENTRY(atomic_or_uchar)
+	ALTENTRY(atomic_or_uchar_nv)
+	and	%o0, 0x3, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x3, %g1		! %g1 = byte offset, right-to-left
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	set	0xff, %o3		! %o3 = mask
+	sll	%o3, %g1, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single byte value
+	andn	%o0, 0x3, %o0		! %o0 = word address
+	ld	[%o0], %o2		! read old value
+1:
+	or	%o2, %o1, %o5		! or in the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	or	%o2, %o1, %o5
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = new value
+	SET_SIZE(atomic_or_uchar_nv)
+	SET_SIZE(atomic_or_uchar)
+	SET_SIZE(atomic_or_8_nv)
+	SET_SIZE(atomic_or_8)
+
+	ENTRY(atomic_or_16)
+	ALTENTRY(atomic_or_16_nv)
+	ALTENTRY(atomic_or_ushort)
+	ALTENTRY(atomic_or_ushort_nv)
+	and	%o0, 0x2, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x2, %g1		! %g1 = byte offset, right-to-left
+	sll	%o4, 3, %o4		! %o4 = bit offset, left-to-right
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	sethi	%hi(0xffff0000), %o3	! %o3 = mask
+	srl	%o3, %o4, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single short value
+	andn	%o0, 0x2, %o0		! %o0 = word address
+	! if low-order bit is 1, we will properly get an alignment fault here
+	ld	[%o0], %o2		! read old value
+1:
+	or	%o2, %o1, %o5		! or in the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	or	%o2, %o1, %o5		! or in the new value
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = new value
+	SET_SIZE(atomic_or_ushort_nv)
+	SET_SIZE(atomic_or_ushort)
+	SET_SIZE(atomic_or_16_nv)
+	SET_SIZE(atomic_or_16)
+
+	ENTRY(atomic_or_32)
+	ALTENTRY(atomic_or_32_nv)
+	ALTENTRY(atomic_or_uint)
+	ALTENTRY(atomic_or_uint_nv)
+	ATOMIC_BACKOFF_INIT(%o4)
+	ld	[%o0], %o2
+1:
+	or	%o2, %o1, %o3
+	cas	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%icc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	or	%o2, %o1, %o0		! return new value
+
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, or32, 1b)
+	SET_SIZE(atomic_or_uint_nv)
+	SET_SIZE(atomic_or_uint)
+	SET_SIZE(atomic_or_32_nv)
+	SET_SIZE(atomic_or_32)
+
+	ENTRY(atomic_or_64)
+	ALTENTRY(atomic_or_64_nv)
+	ALTENTRY(atomic_or_ulong)
+	ALTENTRY(atomic_or_ulong_nv)
+	ATOMIC_BACKOFF_INIT(%o4)
+	ldx	[%o0], %o2
+1:
+	or	%o2, %o1, %o3
+	casx	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%xcc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	or	%o2, %o1, %o0		! return new value
+	
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, or64, 1b)
+	SET_SIZE(atomic_or_ulong_nv)
+	SET_SIZE(atomic_or_ulong)
+	SET_SIZE(atomic_or_64_nv)
+	SET_SIZE(atomic_or_64)
+
+	ENTRY(atomic_and_8)
+	ALTENTRY(atomic_and_8_nv)
+	ALTENTRY(atomic_and_uchar)
+	ALTENTRY(atomic_and_uchar_nv)
+	and	%o0, 0x3, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x3, %g1		! %g1 = byte offset, right-to-left
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	set	0xff, %o3		! %o3 = mask
+	sll	%o3, %g1, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	orn	%o1, %o3, %o1		! all ones in other bytes
+	andn	%o0, 0x3, %o0		! %o0 = word address
+	ld	[%o0], %o2		! read old value
+1:
+	and	%o2, %o1, %o5		! and in the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	and	%o2, %o1, %o5
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = new value
+	SET_SIZE(atomic_and_uchar_nv)
+	SET_SIZE(atomic_and_uchar)
+	SET_SIZE(atomic_and_8_nv)
+	SET_SIZE(atomic_and_8)
+
+	ENTRY(atomic_and_16)
+	ALTENTRY(atomic_and_16_nv)
+	ALTENTRY(atomic_and_ushort)
+	ALTENTRY(atomic_and_ushort_nv)
+	and	%o0, 0x2, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x2, %g1		! %g1 = byte offset, right-to-left
+	sll	%o4, 3, %o4		! %o4 = bit offset, left-to-right
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	sethi	%hi(0xffff0000), %o3	! %o3 = mask
+	srl	%o3, %o4, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	orn	%o1, %o3, %o1		! all ones in the other half
+	andn	%o0, 0x2, %o0		! %o0 = word address
+	! if low-order bit is 1, we will properly get an alignment fault here
+	ld	[%o0], %o2		! read old value
+1:
+	and	%o2, %o1, %o5		! and in the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	and	%o2, %o1, %o5
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = new value
+	SET_SIZE(atomic_and_ushort_nv)
+	SET_SIZE(atomic_and_ushort)
+	SET_SIZE(atomic_and_16_nv)
+	SET_SIZE(atomic_and_16)
+
+	ENTRY(atomic_and_32)
+	ALTENTRY(atomic_and_32_nv)
+	ALTENTRY(atomic_and_uint)
+	ALTENTRY(atomic_and_uint_nv)
+	ATOMIC_BACKOFF_INIT(%o4)
+	ld	[%o0], %o2
+1:
+	and	%o2, %o1, %o3
+	cas	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%icc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	and	%o2, %o1, %o0		! return new value
+
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, and32, 1b)
+	SET_SIZE(atomic_and_uint_nv)
+	SET_SIZE(atomic_and_uint)
+	SET_SIZE(atomic_and_32_nv)
+	SET_SIZE(atomic_and_32)
+
+	ENTRY(atomic_and_64)
+	ALTENTRY(atomic_and_64_nv)
+	ALTENTRY(atomic_and_ulong)
+	ALTENTRY(atomic_and_ulong_nv)
+	ATOMIC_BACKOFF_INIT(%o4)
+	ldx	[%o0], %o2
+1:
+	and	%o2, %o1, %o3
+	casx	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%xcc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	and	%o2, %o1, %o0		! return new value
+
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, and64, 1b)
+	SET_SIZE(atomic_and_ulong_nv)
+	SET_SIZE(atomic_and_ulong)
+	SET_SIZE(atomic_and_64_nv)
+	SET_SIZE(atomic_and_64)
+
+	ENTRY(atomic_cas_8)
+	ALTENTRY(atomic_cas_uchar)
+	and	%o0, 0x3, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x3, %g1		! %g1 = byte offset, right-to-left
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	set	0xff, %o3		! %o3 = mask
+	sll	%o3, %g1, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single byte value
+	sll	%o2, %g1, %o2		! %o2 = shifted to bit offset
+	and	%o2, %o3, %o2		! %o2 = single byte value
+	andn	%o0, 0x3, %o0		! %o0 = word address
+	ld	[%o0], %o4		! read old value
+1:
+	andn	%o4, %o3, %o4		! clear target bits
+	or	%o4, %o2, %o5		! insert the new value
+	or	%o4, %o1, %o4		! insert the comparison value
+	cas	[%o0], %o4, %o5
+	cmp	%o4, %o5		! did we succeed?
+	be,pt	%icc, 2f
+	  and	%o5, %o3, %o4		! isolate the old value
+	cmp	%o1, %o4		! should we have succeeded?
+	be,a,pt	%icc, 1b		! yes, try again
+	  mov	%o5, %o4		! %o4 = old value
+2:
+	retl
+	srl	%o4, %g1, %o0		! %o0 = old value
+	SET_SIZE(atomic_cas_uchar)
+	SET_SIZE(atomic_cas_8)
+
+	ENTRY(atomic_cas_16)
+	ALTENTRY(atomic_cas_ushort)
+	and	%o0, 0x2, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x2, %g1		! %g1 = byte offset, right-to-left
+	sll	%o4, 3, %o4		! %o4 = bit offset, left-to-right
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	sethi	%hi(0xffff0000), %o3	! %o3 = mask
+	srl	%o3, %o4, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single short value
+	sll	%o2, %g1, %o2		! %o2 = shifted to bit offset
+	and	%o2, %o3, %o2		! %o2 = single short value
+	andn	%o0, 0x2, %o0		! %o0 = word address
+	! if low-order bit is 1, we will properly get an alignment fault here
+	ld	[%o0], %o4		! read old value
+1:
+	andn	%o4, %o3, %o4		! clear target bits
+	or	%o4, %o2, %o5		! insert the new value
+	or	%o4, %o1, %o4		! insert the comparison value
+	cas	[%o0], %o4, %o5
+	cmp	%o4, %o5		! did we succeed?
+	be,pt	%icc, 2f
+	  and	%o5, %o3, %o4		! isolate the old value
+	cmp	%o1, %o4		! should we have succeeded?
+	be,a,pt	%icc, 1b		! yes, try again
+	  mov	%o5, %o4		! %o4 = old value
+2:
+	retl
+	srl	%o4, %g1, %o0		! %o0 = old value
+	SET_SIZE(atomic_cas_ushort)
+	SET_SIZE(atomic_cas_16)
+
+	ENTRY(atomic_cas_32)
+	ALTENTRY(atomic_cas_uint)
+	cas	[%o0], %o1, %o2
+	retl
+	mov	%o2, %o0
+	SET_SIZE(atomic_cas_uint)
+	SET_SIZE(atomic_cas_32)
+
+	ENTRY(atomic_cas_64)
+	ALTENTRY(atomic_cas_ptr)
+	ALTENTRY(atomic_cas_ulong)
+	casx	[%o0], %o1, %o2
+	retl
+	mov	%o2, %o0
+	SET_SIZE(atomic_cas_ulong)
+	SET_SIZE(atomic_cas_ptr)
+	SET_SIZE(atomic_cas_64)
+
+	ENTRY(atomic_swap_8)
+	ALTENTRY(atomic_swap_uchar)
+	and	%o0, 0x3, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x3, %g1		! %g1 = byte offset, right-to-left
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	set	0xff, %o3		! %o3 = mask
+	sll	%o3, %g1, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single byte value
+	andn	%o0, 0x3, %o0		! %o0 = word address
+	ld	[%o0], %o2		! read old value
+1:
+	andn	%o2, %o3, %o5		! clear target bits
+	or	%o5, %o1, %o5		! insert the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = old value
+	SET_SIZE(atomic_swap_uchar)
+	SET_SIZE(atomic_swap_8)
+
+	ENTRY(atomic_swap_16)
+	ALTENTRY(atomic_swap_ushort)
+	and	%o0, 0x2, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x2, %g1		! %g1 = byte offset, right-to-left
+	sll	%o4, 3, %o4		! %o4 = bit offset, left-to-right
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	sethi	%hi(0xffff0000), %o3	! %o3 = mask
+	srl	%o3, %o4, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single short value
+	andn	%o0, 0x2, %o0		! %o0 = word address
+	! if low-order bit is 1, we will properly get an alignment fault here
+	ld	[%o0], %o2		! read old value
+1:
+	andn	%o2, %o3, %o5		! clear target bits
+	or	%o5, %o1, %o5		! insert the new value
+	cas	[%o0], %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = old value
+	SET_SIZE(atomic_swap_ushort)
+	SET_SIZE(atomic_swap_16)
+
+	ENTRY(atomic_swap_32)
+	ALTENTRY(atomic_swap_uint)
+	ATOMIC_BACKOFF_INIT(%o4)
+	ld	[%o0], %o2
+1:
+	mov	%o1, %o3
+	cas	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%icc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	mov	%o3, %o0
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, swap32, 1b)
+	SET_SIZE(atomic_swap_uint)
+	SET_SIZE(atomic_swap_32)
+
+	ENTRY(atomic_swap_64)
+	ALTENTRY(atomic_swap_ptr)
+	ALTENTRY(atomic_swap_ulong)
+	ATOMIC_BACKOFF_INIT(%o4)
+	ldx	[%o0], %o2
+1:
+	mov	%o1, %o3
+	casx	[%o0], %o2, %o3
+	cmp	%o2, %o3
+	ATOMIC_BACKOFF_BRANCH(%xcc, 2f, 1b)
+	  mov	%o3, %o2
+	retl
+	mov	%o3, %o0
+2:	
+	ATOMIC_BACKOFF_BACKOFF(%o4, %o5, swap64, 1b)
+	SET_SIZE(atomic_swap_ulong)
+	SET_SIZE(atomic_swap_ptr)
+	SET_SIZE(atomic_swap_64)
+
+	ENTRY(atomic_set_long_excl)
+	ATOMIC_BACKOFF_INIT(%o5)
+	mov	1, %o3
+	slln	%o3, %o1, %o3
+	ldn	[%o0], %o2
+1:
+	andcc	%o2, %o3, %g0		! test if the bit is set
+	bnz,a,pn %ncc, 2f		! if so, then fail out
+	  mov	-1, %o0
+	or	%o2, %o3, %o4		! set the bit, and try to commit it
+	casn	[%o0], %o2, %o4
+	cmp	%o2, %o4
+	ATOMIC_BACKOFF_BRANCH(%ncc, 5f, 1b)
+	  mov	%o4, %o2
+	mov	%g0, %o0
+2:
+	retl
+	nop
+5:	
+	ATOMIC_BACKOFF_BACKOFF(%o5, %g1, setlongexcl, 1b)
+	SET_SIZE(atomic_set_long_excl)
+
+	ENTRY(atomic_clear_long_excl)
+	ATOMIC_BACKOFF_INIT(%o5)
+	mov	1, %o3
+	slln	%o3, %o1, %o3
+	ldn	[%o0], %o2
+1:
+	andncc	%o3, %o2, %g0		! test if the bit is clear
+	bnz,a,pn %ncc, 2f		! if so, then fail out
+	  mov	-1, %o0
+	andn	%o2, %o3, %o4		! clear the bit, and try to commit it
+	casn	[%o0], %o2, %o4
+	cmp	%o2, %o4
+	ATOMIC_BACKOFF_BRANCH(%ncc, 5f, 1b)
+	  mov	%o4, %o2
+	mov	%g0, %o0
+2:
+	retl
+	nop
+5:	
+	ATOMIC_BACKOFF_BACKOFF(%o5, %g1, clrlongexcl, 1b)
+	SET_SIZE(atomic_clear_long_excl)
+
+#if !defined(_KERNEL)
+
+	ENTRY(membar_enter)
+	membar	#StoreLoad|#StoreStore
+	retl
+	nop
+	SET_SIZE(membar_enter)
+
+	ENTRY(membar_exit)
+	membar	#LoadStore|#StoreStore
+	retl
+	nop
+	SET_SIZE(membar_exit)
+
+	ENTRY(membar_producer)
+	membar	#StoreStore
+	retl
+	nop
+	SET_SIZE(membar_producer)
+
+	ENTRY(membar_consumer)
+	membar	#LoadLoad
+	retl
+	nop
+	SET_SIZE(membar_consumer)
+
+#endif	/* !_KERNEL */
+#endif	/* lint */
--- a/usr/src/uts/sun4v/cpu/niagara_copy.s	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/cpu/niagara_copy.s	Wed Jul 25 18:20:14 2007 -0700
@@ -261,6 +261,8 @@
 	faddd	%f0, %f2, %f60		;\
 	fmuld	%f0, %f2, %f62
 
+#if !defined(lint)
+
 /*
  * Macros to save and restore fp registers to/from the stack.
  * Used to save and restore in-use fp registers when we want to use FP.
@@ -288,6 +290,7 @@
 	membar	#Sync
 #endif	/* NIAGARA_IMPL */
 
+#endif	/* lint */
 /*
  * Copy a block of storage, returning an error code if `from' or
  * `to' takes a kernel pagefault which cannot be resolved.
--- a/usr/src/uts/sun4v/cpu/niagara_perfctr.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/cpu/niagara_perfctr.c	Wed Jul 25 18:20:14 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.
  */
 
@@ -35,7 +35,7 @@
 #include <sys/kstat.h>
 #if defined(NIAGARA_IMPL)
 #include <sys/niagararegs.h>
-#elif defined(NIAGARA2_IMPL)
+#elif defined(NIAGARA2_IMPL) || defined(VFALLS_IMPL)
 #include <sys/niagara2regs.h>
 #endif
 
@@ -110,7 +110,7 @@
 #endif
 
 /*
- * Niagara and Niagara2 DRAM Performance Events
+ * Niagara, Niagara2 and VFalls DRAM Performance Events
  */
 static ni_kev_mask_t
 niagara_dram_events[] = {
@@ -155,6 +155,7 @@
 {
 	int i;
 	ni_ksinfo_t *ksinfop;
+	uint64_t pic;
 
 #ifdef DEBUG
 	if (ni_perf_debug)
@@ -165,35 +166,44 @@
 	 * Create DRAM perf events kstat
 	 */
 	for (i = 0; i < NIAGARA_DRAM_BANKS; i++) {
-		ksinfop = (ni_ksinfo_t *)kmem_zalloc(sizeof (ni_ksinfo_t),
-		    KM_NOSLEEP);
+#ifdef VFALLS_IMPL
+		/* check if this dram instance is enabled in the HW */
+		if (hv_niagara_getperf(dram_perf_regs[i].pic_reg, &pic) !=
+		    H_EINVAL) {
+#endif
+			ksinfop = (ni_ksinfo_t *)kmem_zalloc(
+			    sizeof (ni_ksinfo_t), KM_NOSLEEP);
 
-		if (ksinfop == NULL) {
-			cmn_err(CE_WARN,
-			    "%s: no space for niagara dram kstat\n",
-			    cpu_module_name);
-			break;
-		}
-		ksinfop->pic_no_evs =
-			sizeof (niagara_dram_events) / sizeof (ni_kev_mask_t);
-		ksinfop->pic_sel_shift[0] = NIAGARA_DRAM_PIC0_SEL_SHIFT;
-		ksinfop->pic_shift[0] = NIAGARA_DRAM_PIC0_SHIFT;
-		ksinfop->pic_mask[0] = NIAGARA_DRAM_PIC0_MASK;
-		ksinfop->pic_sel_shift[1] = NIAGARA_DRAM_PIC1_SEL_SHIFT;
-		ksinfop->pic_shift[1] = NIAGARA_DRAM_PIC1_SHIFT;
-		ksinfop->pic_mask[1] = NIAGARA_DRAM_PIC1_MASK;
-		ksinfop->pic_reg = dram_perf_regs[i].pic_reg;
-		ksinfop->pcr_reg = dram_perf_regs[i].pcr_reg;
-		ni_dram_kstats[i] = ksinfop;
+			if (ksinfop == NULL) {
+				cmn_err(CE_WARN,
+				    "%s: no space for dram kstat\n",
+				    cpu_module_name);
+				break;
+			}
+			ksinfop->pic_no_evs =
+			    sizeof (niagara_dram_events) /
+			    sizeof (ni_kev_mask_t);
+			ksinfop->pic_sel_shift[0] = NIAGARA_DRAM_PIC0_SEL_SHIFT;
+			ksinfop->pic_shift[0] = NIAGARA_DRAM_PIC0_SHIFT;
+			ksinfop->pic_mask[0] = NIAGARA_DRAM_PIC0_MASK;
+			ksinfop->pic_sel_shift[1] = NIAGARA_DRAM_PIC1_SEL_SHIFT;
+			ksinfop->pic_shift[1] = NIAGARA_DRAM_PIC1_SHIFT;
+			ksinfop->pic_mask[1] = NIAGARA_DRAM_PIC1_MASK;
+			ksinfop->pic_reg = dram_perf_regs[i].pic_reg;
+			ksinfop->pcr_reg = dram_perf_regs[i].pcr_reg;
+			ni_dram_kstats[i] = ksinfop;
 
-		/* create basic pic event/mask pair (only once) */
-		if (i == 0)
-			ni_create_name_kstat("dram", ksinfop,
+			/* create basic pic event/mask pair (only once) */
+			if (i == 0)
+				ni_create_name_kstat("dram", ksinfop,
 				    niagara_dram_events);
 
-		/* create counter kstats */
-		ni_dram_kstats[i]->cntr_ksp = ni_create_cntr_kstat("dram", i,
-		    ni_cntr_kstat_update, ksinfop);
+			/* create counter kstats */
+			ni_dram_kstats[i]->cntr_ksp = ni_create_cntr_kstat(
+			    "dram", i, ni_cntr_kstat_update, ksinfop);
+#ifdef VFALLS_IMPL
+		}
+#endif
 	}
 
 #if defined(NIAGARA_IMPL)
@@ -201,14 +211,14 @@
 	 * Create JBUS perf events kstat
 	 */
 	ni_jbus_kstat = (ni_ksinfo_t *)kmem_alloc(sizeof (ni_ksinfo_t),
-		KM_NOSLEEP);
+	    KM_NOSLEEP);
 
 	if (ni_jbus_kstat == NULL) {
 		cmn_err(CE_WARN, "%s: no space for niagara jbus kstat\n",
 		    cpu_module_name);
 	} else {
 		ni_jbus_kstat->pic_no_evs =
-			sizeof (niagara_jbus_events) / sizeof (ni_kev_mask_t);
+		    sizeof (niagara_jbus_events) / sizeof (ni_kev_mask_t);
 		ni_jbus_kstat->pic_sel_shift[0] = NIAGARA_JBUS_PIC0_SEL_SHIFT;
 		ni_jbus_kstat->pic_shift[0] = NIAGARA_JBUS_PIC0_SHIFT;
 		ni_jbus_kstat->pic_mask[0] = NIAGARA_JBUS_PIC0_MASK;
@@ -266,7 +276,7 @@
 #endif
 	for (i = 0; i < NUM_OF_PICS; i++) {
 		pp->pic_name_ksp[i] = ni_create_picN_kstat(name,
-			i, pp->pic_sel_shift[i], pp->pic_no_evs, ev);
+		    i, pp->pic_sel_shift[i], pp->pic_no_evs, ev);
 
 		if (pp->pic_name_ksp[i] == NULL) {
 			cmn_err(CE_WARN, "%s: unable to create name kstat",
@@ -307,7 +317,7 @@
 	if ((picN_ksp = kstat_create(mod_name, inst, pic_name,
 	    "bus", KSTAT_TYPE_NAMED, num_ev, NULL)) == NULL) {
 		cmn_err(CE_WARN, "%s %s : kstat create failed",
-			mod_name, pic_name);
+		    mod_name, pic_name);
 
 		/*
 		 * It is up to the calling function to delete any kstats
@@ -327,18 +337,18 @@
 	 */
 	for (event = 0; event < num_ev - 1; event++) {
 		pic_named_data[event].value.ui64 =
-			(ev_array[event].pcr_mask << pic_sel_shift);
+		    (ev_array[event].pcr_mask << pic_sel_shift);
 
 		kstat_named_init(&pic_named_data[event],
-			ev_array[event].event_name,
-			KSTAT_DATA_UINT64);
+		    ev_array[event].event_name,
+		    KSTAT_DATA_UINT64);
 	}
 
 	/*
 	 * add the clear_pic entry.
 	 */
 	pic_named_data[event].value.ui64 =
-		(uint64_t)~(ev_array[event].pcr_mask << pic_sel_shift);
+	    (uint64_t)~(ev_array[event].pcr_mask << pic_sel_shift);
 
 	kstat_named_init(&pic_named_data[event], ev_array[event].event_name,
 	    KSTAT_DATA_UINT64);
--- a/usr/src/uts/sun4v/io/n2rng/n2rng.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/io/n2rng/n2rng.c	Wed Jul 25 18:20:14 2007 -0700
@@ -50,7 +50,6 @@
 #include <sys/hypervisor_api.h>
 #include <sys/n2rng.h>
 
-
 static int	n2rng_attach(dev_info_t *, ddi_attach_cmd_t);
 static int	n2rng_detach(dev_info_t *, ddi_detach_cmd_t);
 static int	n2rng_suspend(n2rng_t *);
@@ -64,6 +63,8 @@
 static uint64_t sticks_per_usec(void);
 u_longlong_t gettick(void);
 
+static void n2rng_config_task(void * targ);
+
 /*
  * Device operations.
  */
@@ -210,6 +211,16 @@
 		return (DDI_FAILURE);
 	}
 	rng_hsvc_available = B_TRUE;
+
+	/* Allocate single thread task queue for rng diags and registration */
+	n2rng->n_taskq = ddi_taskq_create(dip, "n2rng_taskq", 1,
+	    TASKQ_DEFAULTPRI, 0);
+
+	if (n2rng->n_taskq == NULL) {
+		n2rng_diperror(dip, "ddi_taskq_create() failed");
+		goto errorexit;
+	}
+
 	/* No locking, but it is okay */
 	n2rng->n_sticks_per_usec = sticks_per_usec();
 	/*
@@ -247,28 +258,13 @@
 	n2rng->n_preferred_config.ctlwds[3].fields.rnc_vcoctl = 0;
 	n2rng->n_preferred_config.ctlwds[3].fields.rnc_selbits = 7;
 
-	rv = n2rng_do_health_check(n2rng);
-
-	switch (rv) {
-	case 0:
-		/* We are a control domain.  Success. */
-		break;
-	case EPERM:
-		/* We must not be a control domain, declare success. */
-		rv = 0;
-		break;
-	default:
+	/* Dispatch task to configure the RNG and register with KCF */
+	if (ddi_taskq_dispatch(n2rng->n_taskq, n2rng_config_task,
+	    (void *)n2rng, DDI_SLEEP) != DDI_SUCCESS) {
+		n2rng_diperror(dip, "ddi_taskq_dispatch() failed");
 		goto errorexit;
 	}
 
-	/* Register with KCF---also sets up FIPS state */
-	rv = n2rng_init(n2rng);
-	if (rv != DDI_SUCCESS) {
-		goto errorexit;
-	}
-
-	n2rng->n_flags &= ~N2RNG_FAILED;
-
 	return (DDI_SUCCESS);
 
 errorexit:
@@ -276,6 +272,12 @@
 		(void) hsvc_unregister(&rng_hsvc);
 		rng_hsvc_available = B_FALSE;
 	}
+
+	if (n2rng->n_taskq != NULL) {
+		ddi_taskq_destroy(n2rng->n_taskq);
+		n2rng->n_taskq = NULL;
+	}
+
 	mutex_destroy(&n2rng->n_health_check_mutex);
 	ddi_soft_state_free(n2rng_softstate, instance);
 
@@ -305,10 +307,14 @@
 		return (DDI_FAILURE);
 	}
 
-
 	/* unregister with KCF---also tears down FIPS state */
 	rv = n2rng_uninit(n2rng) ? DDI_FAILURE : DDI_SUCCESS;
 
+	if (n2rng->n_taskq != NULL) {
+		ddi_taskq_destroy(n2rng->n_taskq);
+		n2rng->n_taskq = NULL;
+	}
+
 	if (rng_hsvc_available == B_TRUE) {
 		(void) hsvc_unregister(&rng_hsvc);
 		rng_hsvc_available = B_FALSE;
@@ -654,3 +660,46 @@
 
 	return ((1000 * (endtick - starttick)) / (endtime - starttime));
 }
+
+/*
+ * n2rng_config_task()
+ *
+ * Runs health checks on the RNG hardware
+ * Configures the RNG hardware
+ * Registers with crypto framework if successful.
+ */
+static void
+n2rng_config_task(void * targ)
+{
+	int		rv;
+	n2rng_t		*n2rng = (n2rng_t *)targ;
+
+	thread_affinity_set(curthread, CPU_CURRENT);
+	rv = n2rng_do_health_check(n2rng);
+	thread_affinity_clear(curthread);
+
+	switch (rv) {
+	case 0:
+		/* We are a control domain.  Success. */
+		break;
+	case EPERM:
+		/* We must not be a control domain, declare success. */
+		rv = 0;
+		break;
+	default:
+		goto errorexit;
+	}
+
+	/* Register with KCF and initialize FIPS state */
+	rv = n2rng_init(n2rng);
+	if (rv != DDI_SUCCESS) {
+		goto errorexit;
+	}
+
+	n2rng->n_flags &= ~N2RNG_FAILED;
+	return;
+
+errorexit:
+	cmn_err(CE_WARN, "n2rng_config_task: RNG configuration failed");
+	n2rng->n_flags |= N2RNG_FAILED;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4v/maramba/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,97 @@
+#
+# 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
+#
+#
+# uts/sun4v/maramba/Makefile
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+#
+#	This makefile creates the links that point at
+#	$(USR_PLAT_DIR)/SUNW,T5140
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Include common rules.
+#
+
+include $(UTSBASE)/sun4v/Makefile.sun4v
+
+USR_PLAT_DIR = $(ROOT)/usr/platform
+
+include $(UTSBASE)/sun4v/Makefile.maramba
+
+def		:=	TARGET= def
+all		:=	TARGET= all
+install		:=	TARGET= install
+install_h	:=	TARGET= install_h
+clean		:=	TARGET= clean
+clobber		:=	TARGET= clobber
+lint		:=	TARGET= lint
+lintlib		:=	TARGET= lintlib
+modlintlib	:=	TARGET= modlintlib
+modlist		:=	TARGET= modlist
+modlist		:=	NO_STATE= -K $$MODSTATE$$$$
+clean.lint	:=	TARGET= clean.lint
+check		:=	TARGET= check
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+modlist: 
+
+lintlib:      unix
+
+IMPLEMENTED_PLATFORM	= SUNW,T5140
+LINKED_PLATFORMS	= SUNW,T5240
+
+$(LINKED_PLATFORMS:%=$(USR_PLAT_DIR)/%): $(USR_PLAT_DIR)
+	$(INS.slink3)
+
+all:
+
+install:	$(LINKED_PLATFORMS:%=$(USR_PLAT_DIR)/%)
+
+install_h check:
+
+lint:
+
+clean:
+
+clobber: clean
+
+
+EXPORT_SRC:
+	$(RM) Makefile+	
+	sed -e "/^# EXPORT DELETE START/,/^# EXPORT DELETE END/d" \
+		< Makefile > Makefile+
+	$(MV) Makefile+ Makefile
+	$(CHMOD) 444 Makefile
+# EXPORT DELETE END
+
+#
--- a/usr/src/uts/sun4v/niagara2_pcbe/Makefile	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/niagara2_pcbe/Makefile	Wed Jul 25 18:20:14 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.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -51,6 +51,17 @@
 INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
 
 #
+# lint pass one enforcement
+#
+CFLAGS += -DNIAGARA2_IMPL
+
+#
+# niagara2-specific flags
+#
+CPPFLAGS += -DNIAGARA2_IMPL
+AS_CPPFLAGS += -DNIAGARA2_IMPL
+
+#
 #	Default build targets.
 #
 .KEEP_STATE:
--- a/usr/src/uts/sun4v/os/cmp.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/os/cmp.c	Wed Jul 25 18:20:14 2007 -0700
@@ -85,7 +85,7 @@
 chipid_t
 cmp_cpu_to_chip(processorid_t cpuid)
 {
-	return (0);
+	return (cpu[cpuid]->cpu_m.cpu_chip);
 }
 
 /*ARGSUSED*/
@@ -121,7 +121,7 @@
 	case PGHW_IPIPE:
 		return (cpu->cpu_m.cpu_ipipe);
 	case PGHW_CHIP:
-		return (cmp_cpu_to_chip(cpu->cpu_id));
+		return (cpu->cpu_m.cpu_chip);
 	case PGHW_FPU:
 		return (cpu->cpu_m.cpu_fpu);
 	default:
--- a/usr/src/uts/sun4v/os/fillsysinfo.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/os/fillsysinfo.c	Wed Jul 25 18:20:14 2007 -0700
@@ -185,12 +185,12 @@
 	cpunode->ecache_setsize =
 	    cpunode->ecache_size / cpunode->ecache_associativity;
 
-		/*
-		 * Start off by assigning the cpu id as the default
-		 * mapping index.
-		 */
-
+	/*
+	 * Initialize the mapping for exec unit, chip and core.
+	 */
 	cpunode->exec_unit_mapping = NO_EU_MAPPING_FOUND;
+	cpunode->l2_cache_mapping = NO_MAPPING_FOUND;
+	cpunode->core_mapping = NO_CORE_MAPPING_FOUND;
 
 	if (ecache_setsize == 0)
 		ecache_setsize = cpunode->ecache_setsize;
@@ -205,6 +205,64 @@
 	bzero(&cpunodes[cpuid], sizeof (struct cpu_node));
 }
 
+/*
+ * Use L2 cache node to derive the chip mapping.
+ */
+void
+setup_chip_mappings(md_t *mdp)
+{
+	uint64_t ncache, ncpu;
+	mde_cookie_t *node, *cachelist;
+	int i, j;
+	processorid_t cpuid;
+	int idx = 0;
+
+	ncache = md_alloc_scan_dag(mdp, md_root_node(mdp), "cache",
+	    "fwd", &cachelist);
+
+	/*
+	 * The "cache" node is optional in MD, therefore ncaches can be 0.
+	 */
+	if (ncache < 1) {
+		return;
+	}
+
+	for (i = 0; i < ncache; i++) {
+		uint64_t cache_level;
+		uint64_t lcpuid;
+
+		if (md_get_prop_val(mdp, cachelist[i], "level", &cache_level))
+			continue;
+
+		if (cache_level != 2)
+			continue;
+
+		/*
+		 * Found a l2 cache node. Find out the cpu nodes it
+		 * points to.
+		 */
+		ncpu = md_alloc_scan_dag(mdp, cachelist[i], "cpu",
+		    "back", &node);
+
+		if (ncpu < 1)
+			continue;
+
+		for (j = 0; j < ncpu; j++) {
+			if (md_get_prop_val(mdp, node[j], "id", &lcpuid))
+				continue;
+			if (lcpuid >= NCPU)
+				continue;
+			cpuid = (processorid_t)lcpuid;
+			cpunodes[cpuid].l2_cache_mapping = idx;
+		}
+		md_free_scan_dag(mdp, &node);
+
+		idx++;
+	}
+
+	md_free_scan_dag(mdp, &cachelist);
+}
+
 void
 setup_exec_unit_mappings(md_t *mdp)
 {
@@ -344,6 +402,7 @@
 	for (i = 0; i < nocpus; i++)
 		fill_cpu(mdp, cpulist[i]);
 
+	setup_chip_mappings(mdp);
 	setup_exec_unit_mappings(mdp);
 
 	/*
--- a/usr/src/uts/sun4v/pcbe/niagara2_pcbe.c	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/pcbe/niagara2_pcbe.c	Wed Jul 25 18:20:14 2007 -0700
@@ -43,6 +43,7 @@
 #include <sys/hypervisor_api.h>
 #include <sys/disp.h>
 
+/*LINTLIBRARY*/
 static int ni2_pcbe_init(void);
 static uint_t ni2_pcbe_ncounters(void);
 static const char *ni2_pcbe_impl_name(void);
@@ -152,7 +153,6 @@
 	EV_END
 };
 
-static const char	*ni2_impl_name = "UltraSPARC T2";
 static char		*evlist;
 static size_t		evlist_sz;
 static uint16_t 	pcr_pic0_mask;
@@ -161,18 +161,32 @@
 #define	CPU_REF_URL " Documentation for Sun processors can be found at: " \
 			"http://www.sun.com/processors/manuals"
 
-static const char *niagara2_cpuref = "See the \"UltraSPARC T2 User's Manual\" "
+#if defined(NIAGARA2_IMPL)
+static const char	*cpu_impl_name = "UltraSPARC T2";
+static const char *cpu_pcbe_ref = "See the \"UltraSPARC T2 User's Manual\" "
 			"for descriptions of these events." CPU_REF_URL;
+#elif defined(VFALLS_IMPL)
+static const char	*cpu_impl_name = "UltraSPARC T2+";
+static const char *cpu_pcbe_ref = "See the \"UltraSPARC T2+ User's Manual\" "
+			"for descriptions of these events." CPU_REF_URL;
+#endif
 
-static boolean_t niagara2_hsvc_available = B_TRUE;
+static boolean_t cpu_hsvc_available = B_TRUE;
 
 static int
 ni2_pcbe_init(void)
 {
 	ni2_event_t	*evp;
 	int		status;
-	uint64_t	niagara2_hsvc_major;
-	uint64_t	niagara2_hsvc_minor;
+	uint64_t	cpu_hsvc_major;
+	uint64_t	cpu_hsvc_minor;
+#if defined(NIAGARA2_IMPL)
+	uint64_t	hsvc_cpu_group = HSVC_GROUP_NIAGARA2_CPU;
+	uint64_t	hsvc_cpu_major = NIAGARA2_HSVC_MAJOR;
+#elif defined(VFALLS_IMPL)
+	uint64_t	hsvc_cpu_group = HSVC_GROUP_VFALLS_CPU;
+	uint64_t	hsvc_cpu_major = VFALLS_HSVC_MAJOR;
+#endif
 
 	pcr_pic0_mask = CPC_NIAGARA2_PCR_PIC0_MASK;
 	pcr_pic1_mask = CPC_NIAGARA2_PCR_PIC1_MASK;
@@ -180,14 +194,14 @@
 	/*
 	 * Validate API version for Niagara2 specific hypervisor services
 	 */
-	status = hsvc_version(HSVC_GROUP_NIAGARA2_CPU, &niagara2_hsvc_major,
-	    &niagara2_hsvc_minor);
-	if ((status != 0) || (niagara2_hsvc_major != NIAGARA2_HSVC_MAJOR)) {
+	status = hsvc_version(hsvc_cpu_group, &cpu_hsvc_major,
+	    &cpu_hsvc_minor);
+	if ((status != 0) || (cpu_hsvc_major != hsvc_cpu_major)) {
 		cmn_err(CE_WARN, "hypervisor services not negotiated "
-		    "or unsupported major number: group: 0x%x major: 0x%lx "
-		    "minor: 0x%lx errno: %d", HSVC_GROUP_NIAGARA2_CPU,
-		    niagara2_hsvc_major, niagara2_hsvc_minor, status);
-		niagara2_hsvc_available = B_FALSE;
+		    "or unsupported major number: group: 0x%lx major: 0x%lx "
+		    "minor: 0x%lx errno: %d", hsvc_cpu_group,
+		    cpu_hsvc_major, cpu_hsvc_minor, status);
+		cpu_hsvc_available = B_FALSE;
 	}
 
 	/*
@@ -225,13 +239,13 @@
 static const char *
 ni2_pcbe_impl_name(void)
 {
-	return (ni2_impl_name);
+	return (cpu_impl_name);
 }
 
 static const char *
 ni2_pcbe_cpuref(void)
 {
-	return (niagara2_cpuref);
+	return (cpu_pcbe_ref);
 }
 
 static char *
@@ -245,8 +259,12 @@
 static char *
 ni2_pcbe_list_attrs(void)
 {
-	if (niagara2_hsvc_available == B_TRUE)
+	if (cpu_hsvc_available == B_TRUE)
+#if defined(NIAGARA2_IMPL)
 		return ("hpriv,emask");
+#elif defined(VFALLS_IMPL)
+		return ("hpriv,l2ctl,emask");
+#endif
 	else
 		return ("emask");
 }
@@ -364,6 +382,21 @@
 			    evp->emask_valid)
 				return (CPC_ATTRIBUTE_OUT_OF_RANGE);
 			evsel |= attrs[i].ka_val;
+#if defined(VFALLS_IMPL)
+		} else if (strcmp(attrs[i].ka_name, "l2ctl") == 0) {
+			if ((attrs[i].ka_val | VFALLS_L2_CTL_MASK) !=
+			    VFALLS_L2_CTL_MASK)
+				return (CPC_ATTRIBUTE_OUT_OF_RANGE);
+			/*
+			 * Set PERF_CONTROL bits in L2_CONTROL_REG
+			 * only when events have SL bits equal to 3.
+			 */
+			if ((evsel & VFALLS_SL3_MASK) == VFALLS_SL3_MASK) {
+				if ((hv_niagara_setperf(HV_NIAGARA_L2_CTL,
+				    attrs[i].ka_val)) != 0)
+					return (CPC_HV_NO_ACCESS);
+			}
+#endif
 		} else
 			return (CPC_INVALID_ATTRIBUTE);
 	}
@@ -454,7 +487,7 @@
 	}
 
 	if (pic0->pcbe_picno != 0 || pic1->pcbe_picno != 1)
-		panic("%s: bad config on token %p\n", ni2_impl_name, token);
+		panic("%s: bad config on token %p\n", cpu_impl_name, token);
 
 	/*
 	 * UltraSPARC does not allow pic0 to be configured differently
@@ -550,7 +583,7 @@
 	DTRACE_PROBE1(niagara2__getpic, uint64_t, curpic);
 
 	if ((pic0 = kcpc_next_config(token, NULL, &pic0_data)) == NULL)
-		panic("%s: token %p has no configs", ni2_impl_name, token);
+		panic("%s: token %p has no configs", cpu_impl_name, token);
 
 	if ((pic1 = kcpc_next_config(token, pic0, &pic1_data)) == NULL) {
 		pic1 = &nullcfg;
@@ -568,7 +601,7 @@
 	}
 
 	if (pic0->pcbe_picno != 0 || pic1->pcbe_picno != 1)
-		panic("%s: bad config on token %p\n", ni2_impl_name, token);
+		panic("%s: bad config on token %p\n", cpu_impl_name, token);
 
 
 	if (pic0->pcbe_flags & CPC_COUNT_HV) {
@@ -610,7 +643,11 @@
 
 static struct modlpcbe modlpcbe = {
 	&mod_pcbeops,
+#if defined(NIAGARA2_IMPL)
 	"UltraSPARC T2 Performance Counters v%I%",
+#elif defined(VFALLS_IMPL)
+	"UltraSPARC T2+ Performance Counters v%I%",
+#endif
 	&ni2_pcbe_ops
 };
 
--- a/usr/src/uts/sun4v/sys/cpu_module.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/sys/cpu_module.h	Wed Jul 25 18:20:14 2007 -0700
@@ -147,7 +147,10 @@
 int	cpu_trapstat_conf(int cmd);
 void	cpu_trapstat_data(void *buf, uint_t pgszs);
 
-#define	NO_EU_MAPPING_FOUND		0xffffffff
+#define	NO_MAPPING_FOUND		0xffffffff
+#define	NO_EU_MAPPING_FOUND		NO_MAPPING_FOUND
+#define	NO_CHIP_MAPPING_FOUND		NO_MAPPING_FOUND
+#define	NO_CORE_MAPPING_FOUND		NO_MAPPING_FOUND
 /*
  * Default MMU pagesize mask for sun4v architecture.
  */
--- a/usr/src/uts/sun4v/sys/hsvc.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/sys/hsvc.h	Wed Jul 25 18:20:14 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.
  */
 
@@ -54,6 +54,7 @@
 #define	HSVC_GROUP_FIRE_PERF		0x0201
 #define	HSVC_GROUP_NIAGARA2_CPU		0x0202
 #define	HSVC_GROUP_NIU			0x0204
+#define	HSVC_GROUP_VFALLS_CPU		0x0205
 #define	HSVC_GROUP_DIAG			0x0300
 
 #ifndef _ASM
--- a/usr/src/uts/sun4v/sys/machcpuvar.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/sys/machcpuvar.h	Wed Jul 25 18:20:14 2007 -0700
@@ -99,6 +99,13 @@
 } ptl1_state_t;
 
 /*
+ * For cpu_chip and cpu_core in machcpu structure if we cannot get
+ * any chip id or core id information from MD.
+ */
+#define	CPU_CHIPID_INVALID	-1
+#define	CPU_COREID_INVALID	-1
+
+/*
  * Machine specific fields of the cpu struct
  * defined in common/sys/cpuvar.h.
  */
@@ -172,6 +179,7 @@
 	id_t		cpu_ipipe;		/* cpu int exec unit id */
 	id_t		cpu_fpu;		/* cpu fpu unit id */
 	id_t		cpu_core;		/* cpu core id */
+	id_t		cpu_chip;		/* cpu chip id */
 	kthread_t	*startup_thread;
 };
 
@@ -226,6 +234,8 @@
 	uint64_t	device_id;
 	id_t	exec_unit_mapping;
 	id_t	fpu_mapping;
+	id_t	l2_cache_mapping;
+	id_t	core_mapping;
 };
 
 extern struct cpu_node cpunodes[];
--- a/usr/src/uts/sun4v/sys/machparam.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/sys/machparam.h	Wed Jul 25 18:20:14 2007 -0700
@@ -60,7 +60,7 @@
  * makefile.
  */
 #ifndef NCPU
-#define	NCPU	64
+#define	NCPU	256
 #endif
 
 /*
--- a/usr/src/uts/sun4v/sys/n2rng.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/sys/n2rng.h	Wed Jul 25 18:20:14 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.
  */
 
@@ -176,6 +176,7 @@
 	uint64_t		n_rng_state; /* as last known in this drvr. */
 	uint64_t		n_sticks_per_usec;
 	uint64_t		n_anlg_settle_cycles;
+	ddi_taskq_t		*n_taskq;
 } n2rng_t;
 
 
--- a/usr/src/uts/sun4v/sys/niagara2regs.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/sys/niagara2regs.h	Wed Jul 25 18:20:14 2007 -0700
@@ -41,6 +41,9 @@
 #define	NIAGARA2_HSVC_MAJOR	1
 #define	NIAGARA2_HSVC_MINOR	0
 
+#define	VFALLS_HSVC_MAJOR	1
+#define	VFALLS_HSVC_MINOR	0
+
 #define	NIAGARA2_PREALLOC_BASE	MB(196)
 
 /* PIC overflow range is -16 to -1 */
@@ -84,12 +87,19 @@
 
 /*
  * Hypervisor FAST_TRAP API function numbers to get/set DRAM
- * performance counters
+ * performance counters for Niagara2
  */
 #define	HV_NIAGARA2_GETPERF		0x104
 #define	HV_NIAGARA2_SETPERF		0x105
 
 /*
+ * Hypervisor FAST_TRAP API function numbers to get/set DRAM
+ * performance counters for Victoria Falls
+ */
+#define	HV_VFALLS_GETPERF		0x106
+#define	HV_VFALLS_SETPERF		0x107
+
+/*
  * Niagara2 DRAM performance counters
  */
 #define	NIAGARA_DRAM_BANKS		0x4
@@ -102,9 +112,10 @@
 #define	NIAGARA_DRAM_PIC1_SHIFT		0x0
 #define	NIAGARA_DRAM_PIC1_MASK		0x7fffffff
 
+#if defined(NIAGARA2_IMPL)
 /*
  * SPARC/DRAM performance counter register numbers for HV_NIAGARA2_GETPERF
- * and HV_NIAGARA2_SETPERF
+ * and HV_NIAGARA2_SETPERF for Niagara2
  */
 #define	HV_NIAGARA_SPARC_CTL		0x0
 #define	HV_NIAGARA_DRAM_CTL0		0x1
@@ -116,6 +127,28 @@
 #define	HV_NIAGARA_DRAM_CTL3		0x7
 #define	HV_NIAGARA_DRAM_COUNT3		0x8
 
+#elif defined(VFALLS_IMPL)
+/*
+ * SPARC/DRAM performance counter register numbers for HV_VFALLS_GETPERF
+ * and HV_VFALLS_SETPERF for Victoria Falls
+ * Support for 2-node configuration
+ */
+#define	HV_NIAGARA_SPARC_CTL		0x0
+#define	HV_NIAGARA_L2_CTL		0x1
+#define	HV_NIAGARA_DRAM_CTL0		0x2
+#define	HV_NIAGARA_DRAM_COUNT0		0x3
+#define	HV_NIAGARA_DRAM_CTL1		0x4
+#define	HV_NIAGARA_DRAM_COUNT1		0x5
+#define	HV_NIAGARA_DRAM_CTL2		0x6
+#define	HV_NIAGARA_DRAM_COUNT2		0x7
+#define	HV_NIAGARA_DRAM_CTL3		0x8
+#define	HV_NIAGARA_DRAM_COUNT3		0x9
+
+#define	VFALLS_L2_CTL_MASK		0x3
+#define	VFALLS_SL3_MASK			0x300
+
+#endif
+
 #ifndef _ASM
 /*
  * prototypes for hypervisor interface to get/set SPARC and DRAM
--- a/usr/src/uts/sun4v/sys/niagaraasi.h	Wed Jul 25 16:57:01 2007 -0700
+++ b/usr/src/uts/sun4v/sys/niagaraasi.h	Wed Jul 25 18:20:14 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.
  */
 
@@ -40,16 +40,16 @@
 extern "C" {
 #endif
 
-#if defined(NIAGARA_IMPL) || defined(NIAGARA2_IMPL)
+#if defined(NIAGARA_IMPL) || defined(NIAGARA2_IMPL) || defined(VFALLS_IMPL)
 
 /*
- * NIAGARA and NIAGARA2 specific ASIs
+ * NIAGARA, NIAGARA2 and Victoria Falls specific ASIs
  */
 #define	ASI_BLK_INIT_QUAD_LDD_AIUS	0x23	/* block as if user secondary */
 #define	ASI_BLK_INIT_ST_QUAD_LDD_P	0xE2	/* block initializing primary */
 
 #else
-#error	"This file has ASIs which are specific to Niagara and Niagara2 CPUs"
+#error	"This file has ASIs specific to Niagara, Niagara2 and VFalls CPUs"
 #endif	/* NIAGARA_IMPL */
 
 #ifdef __cplusplus
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4v/vfalls/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,108 @@
+#
+# 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
+#
+#
+# uts/sun4v/vfalls/Makefile
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+#
+#	This makefile drives the production of the UltraSPARC-T2+ cpu module.
+#
+#	sun4v implementation architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= SUNW,UltraSPARC-T2+
+OBJECTS		= $(NIAGARA2CPU_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(NIAGARA2CPU_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_PSM_CPU_DIR)/$(MODULE)
+
+CPU_DIR		= .
+HERE		= ../vfalls
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/sun4v/Makefile.sun4v
+
+#
+#	Override defaults
+#
+CLEANFILES	+= $(CPULIB) $(SYM_MOD)
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(SYM_MOD)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= def $(BINARY) $(ROOTMODULE)
+
+#
+# lint pass one enforcement
+#
+CFLAGS += $(CCVERBOSE) -DVFALLS_IMPL -DN2_ERRATUM_181_WORKAROUND
+
+#
+# cpu-module-specific flags
+#
+CPPFLAGS += -DCPU_MODULE -DVFALLS_IMPL -DN2_ERRATUM_181_WORKAROUND
+AS_CPPFLAGS += -DCPU_MODULE -DVFALLS_IMPL -DN2_ERRATUM_181_WORKAROUND
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+$(CPULIB):	$(BINARY)
+	$(BUILD.SO) $(BINARY)
+
+$(SYM_MOD):	$(UNIX_O) $(CPULIB)
+	@echo "resolving symbols against unix.o"
+	@(cd $(UNIX_DIR); pwd; \
+	    CPU_DIR=$(HERE) SYM_MOD=$(HERE)/$(SYM_MOD) $(MAKE) symcheck)
+
+#	Include common targets.
+#
+include $(UTSBASE)/$(PLATFORM)/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4v/vfalls_pcbe/Makefile	Wed Jul 25 18:20:14 2007 -0700
@@ -0,0 +1,88 @@
+#
+# 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"
+#
+# This Makefile builds the UltraSPARC-T2+ Performance Counter BackEnd (PCBE).
+#
+
+UTSBASE = ../..
+
+#
+#	Define module and object file sets.
+#
+MODULE		= pcbe.SUNW,UltraSPARC-T2+
+OBJECTS		= $(N2_PCBE_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(N2_PCBE_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_PSM_PCBE_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/sun4v/Makefile.sun4v
+
+#
+#	Define targets.
+#
+ALL_TARGET	= $(BINARY)
+LINT_MODULE	= vfalls_pcbe
+LINT_TARGET	= $(LINT_MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+
+#
+# lint pass one enforcement
+#
+CFLAGS += -DVFALLS_IMPL
+
+#
+# vfalls-specific flags
+#
+CPPFLAGS += -DVFALLS_IMPL
+AS_CPPFLAGS += -DVFALLS_IMPL
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/sun4v/Makefile.targ