changeset 7956:59ff93e4da95

PSARC 2008/045 NetXen 10 Gigabit Ethernet Driver 6472698 NetXen 1Gb/10Gb nic driver
author lucy wang - Sun Microsystems - Beijing China <xiuyan.wang@Sun.COM>
date Tue, 28 Oct 2008 10:06:13 +0800
parents 47745077dc33
children 1c8a50f3c8b3
files usr/src/pkgdefs/Makefile usr/src/pkgdefs/SUNWntxn/Makefile usr/src/pkgdefs/SUNWntxn/pkginfo.tmpl usr/src/pkgdefs/SUNWntxn/postinstall usr/src/pkgdefs/SUNWntxn/postremove usr/src/pkgdefs/SUNWntxn/prototype_com usr/src/pkgdefs/SUNWntxn/prototype_i386 usr/src/tools/opensolaris/license-list usr/src/uts/common/Makefile.files usr/src/uts/common/Makefile.rules usr/src/uts/common/io/ntxn/THIRDPARTYLICENSE usr/src/uts/common/io/ntxn/THIRDPARTYLICENSE.descrip usr/src/uts/common/io/ntxn/driver_info.h usr/src/uts/common/io/ntxn/message.h usr/src/uts/common/io/ntxn/nic_cmn.h usr/src/uts/common/io/ntxn/nic_phan_reg.h usr/src/uts/common/io/ntxn/niu.c usr/src/uts/common/io/ntxn/nx_errorcode.h usr/src/uts/common/io/ntxn/nx_hw_pci_regs.h usr/src/uts/common/io/ntxn/nxhal_nic_interface.h usr/src/uts/common/io/ntxn/unm_brdcfg.h usr/src/uts/common/io/ntxn/unm_gem.c usr/src/uts/common/io/ntxn/unm_inc.h usr/src/uts/common/io/ntxn/unm_ndd.c usr/src/uts/common/io/ntxn/unm_nic.h usr/src/uts/common/io/ntxn/unm_nic_ctx.c usr/src/uts/common/io/ntxn/unm_nic_hw.c usr/src/uts/common/io/ntxn/unm_nic_hw.h usr/src/uts/common/io/ntxn/unm_nic_init.c usr/src/uts/common/io/ntxn/unm_nic_ioctl.h usr/src/uts/common/io/ntxn/unm_nic_isr.c usr/src/uts/common/io/ntxn/unm_nic_main.c usr/src/uts/common/io/ntxn/unm_version.h usr/src/uts/intel/Makefile.intel.shared usr/src/uts/intel/ntxn/Makefile
diffstat 35 files changed, 14114 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/pkgdefs/Makefile	Tue Oct 28 09:59:16 2008 +0800
+++ b/usr/src/pkgdefs/Makefile	Tue Oct 28 10:06:13 2008 +0800
@@ -157,7 +157,8 @@
 	SUNWxsvc \
 	SUNWxvmipar \
 	SUNWxvmipau \
-	SUNWxvmpv
+	SUNWxvmpv	\
+	SUNWntxn
 
 i386_XMODS= \
 	BRCMbnx \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWntxn/Makefile	Tue Oct 28 10:06:13 2008 +0800
@@ -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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+DATAFILES += depend
+LICENSEFILES += ../../uts/common/io/ntxn/THIRDPARTYLICENSE
+
+.KEEP_STATE:
+
+all: $(FILES) postinstall postremove
+install: all pkg
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWntxn/pkginfo.tmpl	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,45 @@
+#
+# 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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PKG=SUNWntxn
+NAME=NetXen 1Gb/10Gb NIC Driver
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGVERS="1.0"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY=system
+VENDOR="Sun Microsystems, Inc."
+DESC="NetXen 1Gb/10Gb Ethernet Adapter Driver"
+CLASSES="none preserve"
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+BASEDIR=/
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="true"
+SUNW_PKG_THISZONE="false"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWntxn/postinstall	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,138 @@
+#!/sbin/sh
+#
+# 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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+# Function: check_add_drv()
+#
+# This function will check if the module has an entry in etc/name_to_major
+# If not simply calls add_drv with the arguments given. If there is
+# such an entry in name_to_major file, it adds entries in driver_aliases
+# driver_classes and minor_perm if necessary.
+# The syntax of this function is the same as add_drv. 
+
+check_add_drv()
+{
+	if [ "$BASEDIR" = "" ]
+	then
+		BASEDIR=/  
+	fi
+	alias=""
+	class=""
+	ADD_ALIAS=0
+	ADD_CLASS=0
+	ADD_MINOR=0
+	OPTIND=1
+	IS_NET_DRIVER=0
+
+	cmd="add_drv"
+
+	NO_CMD=
+	while getopts i:b:m:c:N  opt
+	do
+		case $opt in
+			N )	NO_CMD=1;;
+			i )	ADD_ALIAS=1	
+				alias=$OPTARG
+				cmd=$cmd" -i '$alias'"
+				;;
+			m )	ADD_MINOR=1
+				minor=$OPTARG
+				cmd=$cmd" -m '$minor'"
+				;;
+			c)	ADD_CLASS=1
+				class=$OPTARG
+				cmd=$cmd" -c $class"
+				;;
+			b)	BASEDIR=$OPTARG
+				cmd=$cmd" -b $BASEDIR"
+				;;
+			\?) 	echo "check_add_drv can not handle this option"
+				return
+				;;
+			esac
+	done 
+	shift `/usr/bin/expr $OPTIND - 1`
+	
+	drvname=$1
+
+	cmd=$cmd" "$drvname
+
+	drvname=`echo $drvname | /usr/bin/sed 's;.*/;;g'`
+
+	/usr/bin/grep "^$drvname[ 	]" $BASEDIR/etc/name_to_major >  /dev/null 2>&1
+
+	if [ "$NO_CMD" = "" -a $? -ne 0 ] 
+	then
+		eval $cmd
+	else	
+		# entry already in name_to_major, add alias, class, minorperm
+		# if necessary
+		if [ $ADD_ALIAS = 1 ]	
+		then
+			for i in $alias
+			do
+				/usr/bin/egrep "^$drvname[ 	]+$i" $BASEDIR/etc/driver_aliases>/dev/null 2>&1
+				if [ $? -ne 0 ]
+				then
+					echo "$drvname $i" >> $BASEDIR/etc/driver_aliases	
+				fi
+			done
+		fi
+
+		if [ $ADD_CLASS = 1 ]
+		then
+			/usr/bin/egrep "^$drvname[ 	]+$class( |	|$)" $BASEDIR/etc/driver_classes > /dev/null 2>&1
+			if [ $? -ne 0 ]
+			then 
+				echo "$drvname\t$class" >> $BASEDIR/etc/driver_classes
+			fi
+		fi
+
+		if [ $ADD_MINOR = 1 ]
+		then
+			/usr/bin/grep "^$drvname:" $BASEDIR/etc/minor_perm > /dev/null 2>&1
+			if [ $? -ne 0 ]
+			then 
+				minorentry="$drvname:$minor"
+				echo $minorentry >> $BASEDIR/etc/minor_perm
+			fi
+		fi
+
+	fi
+
+
+}
+
+	check_add_drv -b "$BASEDIR" -i \
+	'"pci4040,1"
+	"pci4040,2"
+	"pci4040,3"
+	"pci4040,4"
+	"pci4040,5"
+	"pci4040,24"
+	"pci4040,25"
+	"pci4040,100"' \
+	ntxn
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWntxn/postremove	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,37 @@
+#!/sbin/sh
+#
+# 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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+BD=${BASEDIR:-/}
+if grep -w ntxn $BD/etc/name_to_major > /dev/null 2>&1
+then
+	rem_drv -b ${BD} ntxn
+	if [ $? -ne 0 ]
+	then
+		exit 1 	
+	fi
+fi
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWntxn/prototype_com	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
+
+#
+#
+i pkginfo
+i copyright
+i depend
+i postinstall
+i postremove
+
+#
+#
+# NetXen 1Gb/10Gb NIC driver
+d none kernel		0755	root	sys
+d none kernel/drv	0755	root	sys
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWntxn/prototype_i386	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,48 @@
+#
+# 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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+
+# NetXen 1Gb/10Gb NIC driver
+d none kernel/drv/amd64		0755	root	sys
+f none kernel/drv/ntxn		0755	root	sys
+f none kernel/drv/amd64/ntxn	0755	root	sys
--- a/usr/src/tools/opensolaris/license-list	Tue Oct 28 09:59:16 2008 +0800
+++ b/usr/src/tools/opensolaris/license-list	Tue Oct 28 10:06:13 2008 +0800
@@ -166,3 +166,4 @@
 usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.boris_popov
 usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.bsd4
 usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.microsoft
+usr/src/uts/common/io/ntxn/THIRDPARTYLICENSE
--- a/usr/src/uts/common/Makefile.files	Tue Oct 28 09:59:16 2008 +0800
+++ b/usr/src/uts/common/Makefile.files	Tue Oct 28 10:06:13 2008 +0800
@@ -1780,3 +1780,9 @@
 			iscsi_sess.o radius_auth.o iscsi_crc.o	\
 			iscsi_stats.o radius_packet.o iscsi_doorclt.o	\
 			iscsi_targetparam.o utils.o
+
+#
+#	ntxn 10Gb/1Gb NIC driver module
+#
+NTXN_OBJS =	unm_nic_init.o unm_gem.o unm_nic_hw.o unm_ndd.o	\
+			unm_nic_main.o unm_nic_isr.o unm_nic_ctx.o niu.o
--- a/usr/src/uts/common/Makefile.rules	Tue Oct 28 09:59:16 2008 +0800
+++ b/usr/src/uts/common/Makefile.rules	Tue Oct 28 10:06:13 2008 +0800
@@ -1017,6 +1017,10 @@
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
 
+$(OBJS_DIR)/%.o:		$(UTSBASE)/common/io/ntxn/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
 $(OBJS_DIR)/%.o:		$(UTSBASE)/common/ipp/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -1945,6 +1949,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/io/ixgbe/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(UTSBASE)/common/io/ntxn/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/ipp/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/THIRDPARTYLICENSE	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,4 @@
+/*
+ * Copyright 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/THIRDPARTYLICENSE.descrip	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,1 @@
+ntxn - 10Gb/1Gb NIC driver for NetXen's Ethernet cards
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/driver_info.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,67 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _driver_info_h_
+#define	_driver_info_h_
+
+static const unm_brdinfo_t unm_boards[] = {
+	{UNM_BRDTYPE_P2_SB31_10G_CX4,	1, NX_P2_MN_TYPE_ROMIMAGE,
+			"XGb CX4"},
+	{UNM_BRDTYPE_P2_SB31_10G_HMEZ,	2, NX_P2_MN_TYPE_ROMIMAGE,
+			"XGb HMEZ"},
+	{UNM_BRDTYPE_P2_SB31_10G_IMEZ,	2, NX_P2_MN_TYPE_ROMIMAGE,
+			"XGb IMEZ"},
+	{UNM_BRDTYPE_P2_SB31_10G,		1, NX_P2_MN_TYPE_ROMIMAGE,
+			"XGb XFP"},
+	{UNM_BRDTYPE_P2_SB35_4G,		4, NX_P2_MN_TYPE_ROMIMAGE,
+		    "Quad Gb"},
+	{UNM_BRDTYPE_P2_SB31_2G,		2, NX_P2_MN_TYPE_ROMIMAGE,
+			"Dual Gb"},
+	{UNM_BRDTYPE_P3_REF_QG,			4, NX_P3_MN_TYPE_ROMIMAGE,
+			"Reference card - Quad Gig "},
+	{UNM_BRDTYPE_P3_HMEZ,			2, NX_P3_CT_TYPE_ROMIMAGE,
+			"Dual XGb HMEZ"},
+	{UNM_BRDTYPE_P3_10G_CX4_LP,    2, NX_P3_CT_TYPE_ROMIMAGE,
+			"Dual XGb CX4 LP"},
+	{UNM_BRDTYPE_P3_4_GB,			4, NX_P3_CT_TYPE_ROMIMAGE,
+			"Quad Gig LP"},
+	{UNM_BRDTYPE_P3_IMEZ,			2, NX_P3_CT_TYPE_ROMIMAGE,
+			"Dual XGb IMEZ"},
+	{UNM_BRDTYPE_P3_10G_SFP_PLUS,	2, NX_P3_CT_TYPE_ROMIMAGE,
+			"Dual XGb SFP+ LP"},
+	{UNM_BRDTYPE_P3_10000_BASE_T,	1, NX_P3_CT_TYPE_ROMIMAGE,
+			"XGB 10G BaseT LP"},
+	{UNM_BRDTYPE_P3_XG_LOM,			2, NX_P3_CT_TYPE_ROMIMAGE,
+			"Dual XGb LOM"},
+	{UNM_BRDTYPE_P3_4_GB_MM,		4, NX_P3_CT_TYPE_ROMIMAGE,
+			"NX3031 with Gigabit Ethernet"},
+	{UNM_BRDTYPE_P3_10G_CX4,		2, NX_P3_CT_TYPE_ROMIMAGE,
+			"Reference card - Dual CX4 Option"},
+	{UNM_BRDTYPE_P3_10G_XFP,		1, NX_P3_CT_TYPE_ROMIMAGE,
+			"Reference card - Single XFP Option"},
+	{UNM_BRDTYPE_P3_10G_TRP,		2, NX_P3_CT_TYPE_ROMIMAGE,
+			"NX3031 with 1/10 Gigabit Ethernet"},
+};
+
+#endif /* !_driver_info_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/message.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,31 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef __MESSAGE_H
+#define	__MESSAGE_H
+
+typedef __uint64_t	unm_msgword_t;
+typedef __uint32_t	unm_halfmsgword_t;
+
+#endif /* !__MESSAGE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/nic_cmn.h	Tue Oct 28 10:06:13 2008 +0800
@@ -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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef UNM_NIC_CMN_H
+#define	UNM_NIC_CMN_H
+
+#ifndef sun
+#include "unm_nic_config.h"
+#include "unm_compiler_defs.h"
+#endif
+
+#define	IP_ALIGNMENT_BYTES		2  /* make ip aligned on 16byteaddr */
+#define	P2_MAX_MTU			(8000)
+#define	P3_MAX_MTU			(9600)
+#define	NX_ETHERMTU			1500
+#define	NX_MAX_ETHERHDR			32 /* This contains some padding */
+
+#define	NX_RX_NORMAL_BUF_MAX_LEN	(NX_MAX_ETHERHDR + NX_ETHERMTU)
+#define	NX_P2_RX_JUMBO_BUF_MAX_LEN	(NX_MAX_ETHERHDR + P2_MAX_MTU)
+#define	NX_P3_RX_JUMBO_BUF_MAX_LEN	(NX_MAX_ETHERHDR + P3_MAX_MTU)
+
+#define	MAX_RX_LRO_BUFFER_LENGTH	((8*1024) - 512)
+#define	RX_LRO_DMA_MAP_LEN		(MAX_RX_LRO_BUFFER_LENGTH -\
+					    IP_ALIGNMENT_BYTES)
+
+/* Opcodes to be used with the commands */
+#define	TX_ETHER_PKT	0x01
+/* The following opcodes are for IP checksum    */
+#define	TX_TCP_PKT		0x02
+#define	TX_UDP_PKT		0x03
+#define	TX_IP_PKT		0x04
+#define	TX_TCP_LSO		0x05
+#define	TX_IPSEC		0x06
+#define	TX_IPSEC_CMD	0x07
+
+#define	NETXEN_MAC_NOOP		0
+#define	NETXEN_MAC_ADD		1
+#define	NETXEN_MAC_DEL		2
+
+/* The following opcodes are for internal consumption. */
+#define	UNM_CONTROL_OP		0x10
+#define	PEGNET_REQUEST		0x11
+#define	NX_HOST_REQUEST		0x13
+#define	NX_NIC_REQUEST		0x14
+#define	NX_NIC_LRO_REQUEST	0x15
+
+#define	NX_MAC_EVENT		0x1
+
+enum {
+	NX_NIC_H2C_OPCODE_START = 0,
+	NX_NIC_H2C_OPCODE_CONFIG_RSS,
+	NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL,
+	NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE,
+	NX_NIC_H2C_OPCODE_CONFIG_LED,
+	NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS,
+	NX_NIC_H2C_OPCODE_CONFIG_L2_MAC,
+	NX_NIC_H2C_OPCODE_LRO_REQUEST,
+	NX_NIC_H2C_OPCODE_GET_SNMP_STATS,
+	NX_NIC_H2C_OPCODE_PROXY_START_REQUEST,
+	NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST,
+	NX_NIC_H2C_OPCODE_PROXY_SET_MTU,
+	NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE,
+	NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST,
+	NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST,
+	NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST,
+	NX_NIC_H2C_OPCODE_GET_NET_STATS,
+	NX_NIC_H2C_OPCODE_LAST
+};
+
+#define	VPORT_MISS_MODE_DROP			0 /* drop all unmatched */
+#define	VPORT_MISS_MODE_ACCEPT_ALL		1 /* accept all packets */
+#define	VPORT_MISS_MODE_ACCEPT_MULTI	2 /* accept unmatched multicast */
+
+#ifdef UNM_RSS
+#define	RSS_CNTRL_CMD		0x20
+#endif
+#define	MAX_NUM_CARDS		4
+#define	MAX_NUM_PORTS		4 /* Deprecated. donot use this */
+#define	MAX_NIU_PORTS		MAX_NUM_PORTS
+#define	PORT1				0
+#define	PORT2				1
+#define	PORT3				2
+#define	PORT4				3
+
+
+#define	DESC_CHAIN		0xFF /* descriptor command continuation */
+
+#define	MAX_BUFFERS_PER_CMD		16
+#define	MAX_BUFFERS_PER_DESC	4
+
+#define	NX_P2_C0				0x24
+#define	NX_P2_C1				0x25
+
+#define	DUMMY_BUF_UNINIT	0x55555555
+#define	DUMMY_BUF_INIT		0
+
+/*
+ * Following are the states of the Phantom. Phantom will set them and
+ * Host will read to check if the fields are correct.
+ */
+#define	PHAN_INITIALIZE_START		0xff00
+#define	PHAN_INITIALIZE_FAILED		0xffff
+#define	PHAN_INITIALIZE_COMPLETE	0xff01
+
+/* Host writes the following to notify that it has done the init-handshake */
+#define	PHAN_INITIALIZE_ACK			0xf00f
+
+/* Following defines will be used in the status descriptor */
+#define	TX_ETHER_PKT_COMPLETE  0xB  /* same for both commands */
+
+#define	NUM_RCV_DESC_RINGS		3 /* No of Rcv Descriptor contexts */
+
+/* descriptor types */
+#define	RCV_DESC_NORMAL			0x01
+#define	RCV_DESC_JUMBO			0x02
+#define	RCV_DESC_LRO			0x04
+#define	RCV_DESC_NORMAL_CTXID	0
+#define	RCV_DESC_JUMBO_CTXID	1
+#define	RCV_DESC_LRO_CTXID		2
+
+#define	RCV_DESC_TYPE(ID) \
+	((ID == RCV_DESC_JUMBO_CTXID) ? RCV_DESC_JUMBO :  \
+	    ((ID == RCV_DESC_LRO_CTXID) ? RCV_DESC_LRO : (RCV_DESC_NORMAL)))
+
+#define	RCV_DESC_TYPE_NAME(ID) \
+	((ID	==	RCV_DESC_JUMBO_CTXID)	?	"Jumbo"	:	\
+	(ID == RCV_DESC_LRO_CTXID)    ? "LRO"    :  \
+	(ID == RCV_DESC_NORMAL_CTXID) ? "Normal" : "Unknown")
+
+#define	MAX_CMD_DESCRIPTORS			4096
+#define	MAX_CMD_DESCRIPTORS_HOST	(MAX_CMD_DESCRIPTORS / 4)
+
+#define	MAX_RCV_DESCRIPTORS			8192
+#define	MAX_JUMBO_RCV_DESCRIPTORS	1024
+#define	MAX_LRO_RCV_DESCRIPTORS		16
+
+#define	NX_MAX_SUPPORTED_RDS_SIZE	(32 * 1024)
+#define	NX_MAX_SUPPORTED_JUMBO_RDS_SIZE	(4 * 1024)
+
+#define	PHAN_PEG_RCV_INITIALIZED		0xff01
+#define	PHAN_PEG_RCV_START_INITIALIZE	0xff00
+
+#define	get_next_index(index, length)  ((((index)  + 1) == length)?0:(index) +1)
+
+#define	get_index_range(index, length, count)	\
+	((((index) + (count)) >= length)? \
+		(((index)  + (count))-(length)):((index) + (count)))
+
+#define	UNM_FLOW_TICKS_PER_SEC    2048
+#define	UNM_FLOW_TO_TV_SHIFT_SEC  11
+#define	UNM_FLOW_TO_TV_SHIFT_USEC 9
+#define	UNM_FLOW_TICK_USEC   (1000000ULL/UNM_FLOW_TICKS_PER_SEC)
+#define	UNM_GLOBAL_TICKS_PER_SEC  (4*UNM_FLOW_TICKS_PER_SEC)
+#define	UNM_GLOBAL_TICK_USEC (1000000ULL/UNM_GLOBAL_TICKS_PER_SEC)
+
+
+/*
+ * Following data structures describe the descriptors that will be used.
+ * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when
+ * we are doing LSO (above the 1500 size packet) only.
+ * This is an overhead but we need it. Let me know if you have questions.
+ */
+
+/*
+ * the size of reference handle been changed to 16 bits to pass the MSS fields
+ * for the LSO packet
+ */
+
+#define	FLAGS_CHECKSUM_ENABLED		0x01
+#define	FLAGS_LSO_ENABLED			0x02
+#define	FLAGS_IPSEC_SA_ADD			0x04
+#define	FLAGS_IPSEC_SA_DELETE		0x08
+#define	FLAGS_VLAN_TAGGED			0x10
+
+#if UNM_CONF_PROCESSOR == UNM_CONF_X86
+
+#ifndef U64
+typedef unsigned long long U64;
+typedef uint32_t U32;
+typedef uint16_t U16;
+typedef uint8_t  U8;
+#endif
+
+#endif
+
+#define	NUM_SUPPORTED_RINGSETS	4
+#define	MAX_RING_CTX			4
+#define	UNM_CTX_SIGNATURE		0xdee0
+#define	UNM_CTX_RESET			0xbad0
+#define	UNM_CTX_D3_RESET		0xacc0
+
+/* define opcode for ctx_msg */
+#define	RX_PRODUCER				0
+#define	RX_PRODUCER_JUMBO		1
+#define	RX_PRODUCER_LRO			2
+#define	TX_PRODUCER				3
+#define	UPDATE_STATUS_CONSUMER	4
+#define	RESET_CTX				5
+
+#define	NUM_DB_CODE				6
+
+#define	UNM_RCV_PRODUCER(ringid)	(ringid)
+#define	UNM_CMD_PRODUCER			TX_PRODUCER
+#define	UNM_RCV_STATUS_CONSUMER		UPDATE_STATUS_CONSUMER
+
+typedef struct __msg
+{
+    __uint32_t  PegId:2,   // 0x2 for tx and 01 for rx.
+			    privId:1, // must be 1
+			    Count:15, // for doorbell
+			    CtxId:10, // Ctx_id
+			    Opcode:4; /* opcode */
+}ctx_msg, CTX_MSG, *PCTX_MSG;
+
+typedef struct __int_msg
+{
+    __uint32_t  Count:18, // INT
+			    ConsumerIdx:10,
+			    CtxId:4; // Ctx_id
+
+}int_msg, INT_MSG, *PINT_MSG;
+
+/* For use in CRB_MPORT_MODE */
+#define	MPORT_SINGLE_FUNCTION_MODE	0x1111
+#define	MPORT_MULTI_FUNCTION_MODE	0x2222
+
+typedef struct _RcvContext
+{
+	__uint32_t		RcvRingAddrLo;
+	__uint32_t		RcvRingAddrHi;
+	__uint32_t		RcvRingSize;
+	__uint32_t		Rsrv;
+}RcvContext;
+
+typedef struct PREALIGN(64) _RingContext
+{
+
+	/* one command ring */
+	__uint64_t		CMD_CONSUMER_OFFSET;
+	__uint32_t		CmdRingAddrLo;
+	__uint32_t		CmdRingAddrHi;
+	__uint32_t		CmdRingSize;
+	__uint32_t		Rsrv;
+
+	/* three receive rings */
+	RcvContext		RcvContext[3];
+
+	/* one status ring */
+	__uint32_t		StsRingAddrLo;
+	__uint32_t		StsRingAddrHi;
+	__uint32_t		StsRingSize;
+
+	__uint32_t		CtxId;
+
+    __uint64_t		D3_STATE_REGISTER;
+    __uint32_t		DummyDmaAddrLo;
+    __uint32_t		DummyDmaAddrHi;
+
+}POSTALIGN(64) RingContext, RING_CTX, *PRING_CTX;
+
+#ifdef UNM_RSS
+/*
+ * RSS_SreInfo{} has the information for SRE to calculate the hash value
+ * Will be passed by the host=> as part of comd descriptor...
+ */
+
+#if UNM_CONF_PROCESSOR == UNM_CONF_X86
+typedef struct _RSS_SreInfo {
+	U32		HashKeySize;
+	U32		HashInformation;
+	char	key[40];
+}RSS_SreInfo;
+#endif
+
+/*
+ * The following Descriptor is used to send RSS commands to the
+ * PEG.... to be do the SRE registers..
+ */
+typedef struct PREALIGN(64) _rssCmdDesc
+{
+
+	/*
+	 * To keep the opcode at the same location as
+	 * the cmdDescType0, we will have to breakup the key into
+	 * 2 areas.... Dont like it but for now will do... FSL
+	 */
+
+#if UNM_CONF_PROCESSOR == UNM_CONF_X86
+	U8		Key0[16];
+
+	U64		HashMethod:32,
+			HashKeySize:8,
+			Unused:	16,
+			opcode:8;
+
+	U8		Key1[24];
+	U64		Unused1;
+	U64		Unused2;
+#else
+
+	unm_msgword_t		Key0[2];
+	unm_halfmsgword_t	HashMethod;
+    unm_halfmsgword_t
+						HashKeySize:8,
+						Unused:16,
+						opcode:8;
+
+    unm_msgword_t    Key1[3];
+    unm_msgword_t    Unused1;
+    unm_msgword_t    Unused2;
+
+#endif
+
+} POSTALIGN(64) rssCmdDesc_t;
+
+
+#endif /* UNM_RSS */
+
+
+typedef struct PREALIGN(64) cmdDescType0
+{
+	union {
+		struct {
+			__uint32_t	tcpHdrOffset:8, /* For LSO only */
+						ipHdrOffset:8,  // For LSO only
+						flags:7, /* as defined above */
+			/* This location/size must not change... */
+						opcode:6,
+						Unused:3;
+			/* total number of segments (buffers */
+			__uint32_t	numOfBuffers:8,
+			/* for this packet. (could be more than 4) */
+
+						/* Total size of the packet */
+						totalLength:24;
+	}s1;
+	__uint64_t	word0;
+	}u1;
+
+    union {
+		struct {
+			__uint32_t AddrLowPart2;
+			__uint32_t AddrHighPart2;
+		}s1;
+		__uint64_t AddrBuffer2;
+		__uint64_t	word1;
+	}u2;
+
+	union {
+		struct {
+					/* changed to U16 to add mss */
+			__uint32_t	referenceHandle:16,
+					/* passed by NDIS_PACKET for LSO */
+						mss:16;
+			__uint32_t	port:4,
+						ctx_id:4,
+					/* LSO only : MAC+IP+TCP Hdr size */
+						totalHdrLength:8,
+					/* IPSec offoad only */
+						connID:16;
+		}s1;
+		__uint64_t	word2;
+	}u3;
+
+	union {
+		struct {
+			__uint32_t AddrLowPart3;
+			__uint32_t AddrHighPart3;
+		}s1;
+		__uint64_t AddrBuffer3;
+		__uint64_t	word3;
+	}u4;
+
+	union {
+		struct {
+			__uint32_t AddrLowPart1;
+			__uint32_t AddrHighPart1;
+		}s1;
+		__uint64_t AddrBuffer1;
+		__uint64_t	word4;
+	}u5;
+
+	union {
+		struct {
+			__uint32_t	buffer1Length:16,
+						buffer2Length:16;
+			__uint32_t  buffer3Length:16,
+						buffer4Length:16;
+		}s1;
+		__uint64_t	word5;
+	}u6;
+
+	union {
+		struct {
+			__uint32_t AddrLowPart4;
+			__uint32_t AddrHighPart4;
+		}s1;
+		__uint64_t AddrBuffer4;
+		__uint64_t	word6;
+	}u7;
+
+    __uint64_t unused;
+
+} POSTALIGN(64) cmdDescType0_t;
+
+/* Note: sizeof(rcvDesc) should always be a mutliple of 2 */
+typedef struct rcvDesc
+{
+    __uint32_t	referenceHandle:16,
+				flags:16;
+    __uint32_t
+		/* allocated buffer length (usually 2K) */
+				bufferLength:32;
+	__uint64_t	AddrBuffer;
+}  rcvDesc_t;
+
+/* for status field in statusDesc_t */
+#define	STATUS_NEED_CKSUM		(1)
+#define	STATUS_CKSUM_OK			(2)
+#define	STATUS_CKSUM_NOT_OK		(3)
+
+/* owner bits of statusDesc_t */
+#define	STATUS_OWNER_HOST		(1ULL)
+#define	STATUS_OWNER_PHANTOM	(2ULL)
+#define	HOST_STATUS_DESC		((STATUS_OWNER_HOST) << 48)
+#define	PHANTOM_STATUS_DESC		((STATUS_OWNER_PHANTOM) << 48)
+
+#define	UNM_PROT_IP			(1)
+#define	UNM_PROT_UNKNOWN	(0)
+
+/* LRO specific bits of statusDesc_t */
+#define	LRO_LAST_FRAG			(1)
+#define	LRO_NORMAL_FRAG			(0)
+#define	LRO_LAST_FRAG_DESC		((LRO_LAST_FRAG)<<63)
+#define	LRO_NORMAL_FRAG_DESC	((LRO_NORMAL_FRAG)<<63)
+
+typedef struct PREALIGN(16) statusDesc {
+    union {
+		struct {
+					/* initially to be used but noe now */
+			__uint32_t	port:4,
+					/* completion status may not have use */
+						status:4,
+					/* type/index of descriptor ring */
+						type:4,
+					/* NIC mode...no use yet */
+						totalLength:16,
+					/* handle for the associated packet */
+						referenceHandle_lo:4;
+					/* handle for the associated packet */
+			__uint32_t	referenceHandle_hi:12,
+					/* Pkt protocol */
+						prot:4,
+						pkt_offset:5,
+/*
+ * This indicates the num of descriptors part of this descriptor chain.
+ */
+						descCnt:3,
+						owner:2,
+						opcode:6;
+
+			__uint32_t	HashValue;
+			__uint16_t	vlan;
+			__uint8_t	HashType;
+
+		union {
+			/*
+			 * For LRO count is set
+			 * Last LRO fragment is set when it is
+			 * the last frag as the name says.
+			 */
+			__uint8_t	lro_frag:7, last_lro_frag:1;
+
+			/*
+			 * Used to indicate direction in case
+			 * of captured packets. Egress will
+			 * contain EPG input, while ingress
+			 * contains an skb copy.
+			 */
+#define	NX_CAP_DIRN_OUT	1
+#define	NX_CAP_DIRN_IN	2
+			__uint8_t direction;
+
+			/*
+			 * Currently for Legacy this is 0.
+			 */
+			__uint8_t	nr_frags;
+		}u11;
+
+		}s1;
+		__uint64_t	 body[2];
+		}u1;
+
+} POSTALIGN(16) statusDesc_t;
+
+
+#define	STATUS_OWNER_NAME(sd) \
+	(((sd)->u1.s1.owner == STATUS_OWNER_HOST) ? "Host" : "Phantom")
+
+#ifdef	UNM_IPSECOFFLOAD
+
+#define	MAX_IPSEC_SAS			1024
+#define	RECEIVE_IPSEC_SA_BASE	0x8000
+
+/*
+ * IPSEC related structures and defines
+ */
+
+/* Values for DIrFlag in the ipsec_sa_t structure below: */
+#define	UNM_IPSEC_SA_DIR_INBOUND	1
+#define	UNM_IPSEC_SA_DIR_OUTBOUND	2
+
+/* Values for Operation Field below: */
+#define	UNM_IPSEC_SA_AUTHENTICATE	1
+#define	UNM_IPSEC_SA_ENDECRYPT		2
+
+/* COnfidential Algorithm Types: */
+#define	UNM_IPSEC_CONF_NONE			0    // NULL encryption?
+#define	UNM_IPSEC_CONF_DES			1
+#define	UNM_IPSEC_CONF_RESERVED		2
+#define	UNM_IPSEC_CONF_3DES			3
+
+/* Integrity algorithm (AH) types: */
+#define	UNM_IPSEC_INTEG_NONE	0
+#define	UNM_IPSEC_INTEG_MD5		1
+#define	UNM_IPSEC_INTEG_SHA1	2
+
+#define	UNM_PROTOCOL_OFFSET		0x9    // from ip header begin, in bytes
+#define	UNM_PKT_TYPE_AH			0x33
+#define	UNM_PKT_TYPE_ESP		0x32
+
+
+/* 96 bits of output for MD5/SHA1 algorithms */
+#define	UNM_AHOUTPUT_LENGTH		12
+/*
+ * 8 bytes (64 bits) of ICV value for each block of DES_CBC
+ * at the begin of ESP payload
+ */
+#define	UNM_DES_ICV_LENGTH		8
+
+#if UNM_CONF_PROCESSOR == UNM_CONF_X86
+
+typedef struct PREALIGN(512) s_ipsec_sa {
+    U32	SrcAddr;
+	U32	SrcMask;
+	U32	DestAddr;
+	U32	DestMask;
+	U32	Protocol:8,
+		DirFlag:4,
+		IntegCtxInit:2,
+		ConfCtxInit:2,
+		No_of_keys:8,
+		Operation:8;
+	U32	IntegAlg:8,
+		IntegKeyLen:8,
+		ConfAlg:8,
+		ConfAlgKeyLen:8;
+	U32	SAIndex;
+	U32	SPI_Id;
+	U64	Key1[124];
+} POSTALIGN(512) unm_ipsec_sa_t;
+
+#else
+
+typedef struct PREALIGN(512) s_ipsec_sa {
+	unm_halfmsgword_t	SrcAddr;
+	unm_halfmsgword_t	SrcMask;
+	unm_halfmsgword_t	DestAddr;
+	unm_halfmsgword_t	DestMask;
+	unm_halfmsgword_t	Protocol:8,
+						DirFlag:4,
+						IntegCtxInit:2,
+						ConfCtxInit:2,
+						No_of_keys:8,
+						Operation:8;
+	unm_halfmsgword_t	IntegAlg:8,
+						IntegKeyLen:8,
+						ConfAlg:8,
+						ConfAlgKeyLen:8;
+	unm_halfmsgword_t	SAIndex:32;
+	unm_halfmsgword_t	SPI_Id:32;
+	/* to round up to 1K of structure */
+	unm_msgword_t		Key1[124];
+} POSTALIGN(512) unm_ipsec_sa_t;
+
+#endif /* NOT-X86 */
+
+/* Other common header formats that may be needed */
+
+typedef struct _unm_ip_header_s {
+	U32	HdrVer:8,
+		diffser:8,
+		TotalLength:16;
+	U32	ipId:16,
+		flagfrag:16;
+	U32	TTL:8,
+		Protocol:8,
+		Chksum:16;
+	U32	srcaddr;
+	U32	destaddr;
+} unm_ip_header_t;
+
+typedef struct _unm_ah_header_s {
+	U32	NextProto:8,
+		length:8,
+		reserved:16;
+    U32    SPI;
+    U32    seqno;
+    U16    ICV;
+    U16    ICV1;
+    U16    ICV2;
+    U16    ICV3;
+    U16    ICV4;
+    U16    ICV5;
+} unm_ah_header_t;
+
+typedef struct _unm_esp_hdr_s {
+    U32 SPI;
+    U32 seqno;
+} unm_esp_hdr_t;
+
+#endif /* UNM_IPSECOFFLOAD */
+
+/*
+ * Defines for various loop counts. These determine the behaviour of the
+ * system. The classic tradeoff between latency and throughput.
+ */
+
+/*
+ * MAX_DMA_LOOPCOUNT : After how many interations do we start the dma for
+ * the status descriptors.
+ */
+#define	MAX_DMA_LOOPCOUNT    (32)
+
+/*
+ * MAX_TX_DMA_LOOP_COUNT : After how many interations do we start the dma for
+ * the command descriptors.
+ */
+#define	MAX_TX_DMA_LOOP_COUNT    1000
+
+/*
+ * MAX_RCV_BUFS : Max number Rx packets that can be buffered before DMA/INT
+ */
+#define	MAX_RCV_BUFS	(4096)
+
+/*
+ * XXX;shouldnt be exposed in nic_cmn.h
+ * DMA_MAX_RCV_BUFS : Max number Rx packets that can be buffered before DMA
+ */
+#define	DMA_MAX_RCV_BUFS	(4096)
+
+/*
+ * XXX;shouldnt be exposed in nic_cmn.h
+ * MAX_DMA_ENTRIES : Max number Rx dma entries can be in dma list
+ */
+#define	MAX_DMA_ENTRIES		(4096)
+
+
+/*
+ * MAX_INTR_LOOPCOUNT : After how many iterations do we interrupt the
+ * host ?
+ */
+#define	MAX_INTR_LOOPCOUNT		(1024)
+
+/*
+ * XMIT_LOOP_THRESHOLD : How many times do we spin before we process the
+ * transmit buffers.
+ */
+#define	XMIT_LOOP_THRESHOLD		0x20
+
+/*
+ * XMIT_DESC_THRESHOLD : How many descriptors pending before we process
+ * the descriptors.
+ */
+#define	XMIT_DESC_THRESHOLD		0x4
+
+/*
+ * TX_DMA_THRESHOLD : When do we start the dma of the command descriptors.
+ * We need these number of command descriptors, or we need to exceed the
+ * loop count.   P1 only.
+ */
+#define	TX_DMA_THRESHOLD		16
+
+#if defined(UNM_IP_FILTER)
+/*
+ * Commands. Must match the definitions in nic/Linux/include/unm_nic_ioctl.h
+ */
+enum {
+    UNM_IP_FILTER_CLEAR = 1,
+    UNM_IP_FILTER_ADD,
+    UNM_IP_FILTER_DEL,
+    UNM_IP_FILTER_SHOW
+};
+
+#define	MAX_FILTER_ENTRIES		16
+
+typedef struct {
+    __int32_t count;
+    __uint32_t ip_addr[15];
+} unm_ip_filter_t;
+#endif /* UNM_IP_FILTER */
+
+enum {
+    UNM_RCV_PEG_0 = 0,
+    UNM_RCV_PEG_1
+};
+
+#endif /* !UNM_NIC_CMN_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/nic_phan_reg.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,161 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef NIC_PHAN_REG_H
+#define	NIC_PHAN_REG_H
+
+#define	NIC_CRB_BASE				UNM_CAM_RAM(0x200)
+#define	NIC_CRB_BASE_2				UNM_CAM_RAM(0x700)
+#define	UNM_NIC_REG(X)				(NIC_CRB_BASE+(X))
+#define	UNM_NIC_REG_2(X)			(NIC_CRB_BASE_2+(X))
+
+#define	CRB_CUT_THRU_PAGE_SIZE		UNM_CAM_RAM(0x170)
+
+#define	CRB_CMD_PRODUCER_OFFSET		UNM_NIC_REG(0x08)
+#define	CRB_CMD_CONSUMER_OFFSET		UNM_NIC_REG(0x0c)
+/* C0 EPG BUG  */
+#define	CRB_PAUSE_ADDR_LO			UNM_NIC_REG(0x10)
+#define	CRB_PAUSE_ADDR_HI			UNM_NIC_REG(0x14)
+#define	NX_CDRP_CRB_OFFSET			UNM_NIC_REG(0x18)
+#define	NX_ARG1_CRB_OFFSET			UNM_NIC_REG(0x1c)
+#define	NX_ARG2_CRB_OFFSET			UNM_NIC_REG(0x20)
+#define	NX_ARG3_CRB_OFFSET			UNM_NIC_REG(0x24)
+#define	NX_SIGN_CRB_OFFSET			UNM_NIC_REG(0x28)
+#define	CRB_CMDPEG_CMDRING			UNM_NIC_REG(0x38)
+#define	CRB_HOST_DUMMY_BUF_ADDR_HI  UNM_NIC_REG(0x3c)
+#define	CRB_HOST_DUMMY_BUF_ADDR_LO  UNM_NIC_REG(0x40)
+#define	CRB_CMDPEG_STATE			UNM_NIC_REG(0x50)
+/* interrupt coalescing */
+#define	CRB_GLOBAL_INT_COAL			UNM_NIC_REG(0x64)
+#define	CRB_INT_COAL_MODE			UNM_NIC_REG(0x68)
+#define	CRB_MAX_RCV_BUFS			UNM_NIC_REG(0x6c)
+#define	CRB_TX_INT_THRESHOLD		UNM_NIC_REG(0x70)
+#define	CRB_RX_PKT_TIMER			UNM_NIC_REG(0x74)
+#define	CRB_TX_PKT_TIMER			UNM_NIC_REG(0x78)
+#define	CRB_RX_PKT_CNT				UNM_NIC_REG(0x7c)
+#define	CRB_RX_TMR_CNT				UNM_NIC_REG(0x80)
+#define	CRB_RCV_INTR_COUNT			UNM_NIC_REG(0x84)
+/* XG Link status */
+#define	CRB_XG_STATE				UNM_NIC_REG(0x94)
+/* XG PF Link status */
+#define	CRB_XG_STATE_P3				UNM_NIC_REG(0x98)
+/* Debug -performance */
+#define	CRB_TX_STATE				UNM_NIC_REG(0xac)
+#define	CRB_TX_COUNT				UNM_NIC_REG(0xb0)
+#define	CRB_RX_STATE				UNM_NIC_REG(0xb4)
+#define	CRB_RX_PERF_DEBUG_1			UNM_NIC_REG(0xb8)
+/* LRO On/OFF */
+#define	CRB_RX_LRO_CONTROL			UNM_NIC_REG(0xbc)
+/* Multiport Mode */
+#define	CRB_MPORT_MODE				UNM_NIC_REG(0xc4)
+#define	CRB_INT_VECTOR				UNM_NIC_REG(0xd4)
+#define	CRB_PF_LINK_SPEED_1			UNM_NIC_REG(0xe8)
+#define	CRB_PF_LINK_SPEED_2			UNM_NIC_REG(0xec)
+#define	CRB_HOST_DUMMY_BUF			UNM_NIC_REG(0xfc)
+
+#define	CRB_SCRATCHPAD_TEST			UNM_NIC_REG(0x280)
+
+#define	CRB_RCVPEG_STATE			UNM_NIC_REG(0x13c)
+
+/* 12 registers to store MAC addresses for 8 PCI functions */
+#define	CRB_MAC_BLOCK_START			UNM_CAM_RAM(0x1c0)
+
+#define	CRB_CMD_PRODUCER_OFFSET_1   UNM_NIC_REG(0x1ac)
+#define	CRB_CMD_CONSUMER_OFFSET_1   UNM_NIC_REG(0x1b0)
+#define	CRB_TEMP_STATE				UNM_NIC_REG(0x1b4)
+#define	CRB_CMD_PRODUCER_OFFSET_2	UNM_NIC_REG(0x1b8)
+#define	CRB_CMD_CONSUMER_OFFSET_2	UNM_NIC_REG(0x1bc)
+
+#define	CRB_CMD_PRODUCER_OFFSET_3	UNM_NIC_REG(0x1d0)
+#define	CRB_CMD_CONSUMER_OFFSET_3	UNM_NIC_REG(0x1d4)
+/*   sw int status/mask registers */
+#define	CRB_SW_INT_MASK_OFFSET_0   0x1d8
+#define	CRB_SW_INT_MASK_OFFSET_1   0x1e0
+#define	CRB_SW_INT_MASK_OFFSET_2   0x1e4
+#define	CRB_SW_INT_MASK_OFFSET_3   0x1e8
+#define	CRB_SW_INT_MASK_OFFSET_4   0x450
+#define	CRB_SW_INT_MASK_OFFSET_5   0x454
+#define	CRB_SW_INT_MASK_OFFSET_6   0x458
+#define	CRB_SW_INT_MASK_OFFSET_7   0x45c
+#define	CRB_SW_INT_MASK_0		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_0)
+#define	CRB_SW_INT_MASK_1		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_1)
+#define	CRB_SW_INT_MASK_2		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_2)
+#define	CRB_SW_INT_MASK_3		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_3)
+#define	CRB_SW_INT_MASK_4		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_4)
+#define	CRB_SW_INT_MASK_5		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_5)
+#define	CRB_SW_INT_MASK_6		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_6)
+#define	CRB_SW_INT_MASK_7		UNM_NIC_REG(CRB_SW_INT_MASK_OFFSET_7)
+
+#define	CRB_NIC_DEBUG_STRUCT_BASE	UNM_NIC_REG(0x288)
+
+/*
+ * capabilities register, can be used to selectively enable/disable features
+ * for backward compability
+ */
+#define	CRB_NIC_CAPABILITIES_HOST	UNM_NIC_REG(0x1a8)
+#define	CRB_NIC_MSI_MODE_HOST		UNM_NIC_REG(0x270)
+#define	INTR_SCHEME_PERPORT		0x1
+#define	MSI_MODE_MULTIFUNC		0x1
+
+#define	CRB_EPG_QUEUE_BUSY_COUNT    UNM_NIC_REG(0x200)
+
+#define	CRB_V2P_0					UNM_NIC_REG(0x290)
+#define	CRB_V2P_1					UNM_NIC_REG(0x294)
+#define	CRB_V2P_2					UNM_NIC_REG(0x298)
+#define	CRB_V2P_3					UNM_NIC_REG(0x29c)
+#define	CRB_V2P(port)				(CRB_V2P_0+((port)*4))
+#define	CRB_DRIVER_VERSION			UNM_NIC_REG(0x2a0)
+
+#define	CRB_CNT_DBG1				UNM_NIC_REG(0x2a4)
+#define	CRB_CNT_DBG2				UNM_NIC_REG(0x2a8)
+#define	CRB_CNT_DBG3				UNM_NIC_REG(0x2ac)
+
+	/*
+	 * Driver must set the version number register as follows:
+	 *	(major << 16) | (minor << 8) | (subminor)
+	 */
+
+/* last -> 0x2a0 */
+
+/* Upper 16 bits of CRB_TEMP_STATE:temperature value. Lower 16 bits: state */
+#define	nx_get_temp_val(x)				((x) >> 16)
+#define	nx_get_temp_state(x)			((x) & 0xffff)
+#define	nx_encode_temp(val, state)		(((val) << 16) | (state))
+
+#define	lower32(x)	((__uint32_t)((x) & 0xffffffff))
+#define	upper32(x)	((__uint32_t)(((unsigned long long)(x) >> 32) &	\
+			0xffffffff))
+
+/*
+ * Temperature control.
+ */
+enum {
+    NX_TEMP_NORMAL = 0x1,	/* Normal operating range */
+    NX_TEMP_WARN,		/* Sound alert, temperature getting high */
+    NX_TEMP_PANIC		/* Fatal error, hardware has shut down. */
+};
+
+#define	D3_CRB_REG_FUN2		(UNM_PCIX_PS_REG(0x2084))
+#define	D3_CRB_REG_FUN3		(UNM_PCIX_PS_REG(0x3084))
+#endif /* NIC_PHAN_REG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/niu.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,689 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/debug.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#include <sys/strlog.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/vtrace.h>
+#include <sys/dlpi.h>
+#include <sys/strsun.h>
+#include <sys/ethernet.h>
+#include <sys/modctl.h>
+#include <sys/errno.h>
+#include <sys/dditypes.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+
+#include <sys/pci.h>
+
+#include "unm_inc.h"
+#include "unm_nic.h"
+
+static long phy_lock_timeout = 100000000;
+
+static int phy_lock(struct unm_adapter_s *adapter)
+{
+	u32	done = 0;
+	int	timeout = 0;
+
+	while (!done) {
+		/* acquire semaphore3 from PCI HW block */
+		adapter->unm_nic_pci_read_immediate(adapter,
+		    UNM_PCIE_REG(PCIE_SEM3_LOCK), &done);
+		if (done == 1)
+			break;
+		if (timeout >= phy_lock_timeout)
+			return (-1);
+		timeout++;
+	}
+
+	adapter->unm_crb_writelit_adapter(adapter, UNM_PHY_LOCK_ID,
+	    PHY_LOCK_DRIVER);
+	return (0);
+}
+
+static void
+phy_unlock(struct unm_adapter_s *adapter)
+{
+	u32	val;
+
+	/* release semaphore3 */
+	adapter->unm_nic_pci_read_immediate(adapter,
+	    UNM_PCIE_REG(PCIE_SEM3_UNLOCK), &val);
+}
+
+/*
+ * unm_niu_gbe_phy_read - read a register from the GbE PHY via
+ * mii management interface.
+ *
+ * Note: The MII management interface goes through port 0.
+ *	   Individual phys are addressed as follows:
+ *	   [15:8]  phy id
+ *	   [7:0]   register number
+ *
+ * Returns:  0 success
+ *	  -1 error
+ *
+ */
+long
+unm_niu_gbe_phy_read(struct unm_adapter_s *adapter, long reg,
+    unm_crbword_t *readval)
+{
+	long phy = adapter->physical_port;
+	unm_niu_gb_mii_mgmt_address_t address;
+	unm_niu_gb_mii_mgmt_command_t command;
+	unm_niu_gb_mii_mgmt_indicators_t status;
+
+	long timeout = 0;
+	long result = 0;
+	long restore = 0;
+	unm_niu_gb_mac_config_0_t mac_cfg0;
+
+	if (phy_lock(adapter) != 0)
+		return (-1);
+
+	/*
+	 * MII mgmt all goes through port 0 MAC interface, so it cannot be
+	 * in reset
+	 */
+	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(0),
+	    &mac_cfg0, 4);
+	if (mac_cfg0.soft_reset) {
+		unm_niu_gb_mac_config_0_t temp;
+		*(unm_crbword_t *)&temp = 0;
+		temp.tx_reset_pb = 1;
+		temp.rx_reset_pb = 1;
+		temp.tx_reset_mac = 1;
+		temp.rx_reset_mac = 1;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    UNM_NIU_GB_MAC_CONFIG_0(0), &temp, 4);
+		restore = 1;
+	}
+
+	*(unm_crbword_t *)&address = 0;
+	address.reg_addr = (unm_crbword_t)reg;
+	address.phy_addr = (unm_crbword_t)phy;
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_ADDR(0),
+	    &address, 4);
+
+	*(unm_crbword_t *)&command = 0;	/* turn off any prior activity */
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_COMMAND(0),
+	    &command, 4);
+
+	/* send read command */
+	command.read_cycle = 1;
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_COMMAND(0),
+	    &command, 4);
+
+	*(unm_crbword_t *)&status = 0;
+	do {
+		adapter->unm_nic_hw_read_wx(adapter,
+		    UNM_NIU_GB_MII_MGMT_INDICATE(0), &status, 4);
+		timeout++;
+	} while ((status.busy || status.notvalid) &&
+	    (timeout++ < UNM_NIU_PHY_WAITMAX));
+
+	if (timeout < UNM_NIU_PHY_WAITMAX) {
+		adapter->unm_nic_hw_read_wx(adapter,
+		    UNM_NIU_GB_MII_MGMT_STATUS(0), readval, 4);
+		result = 0;
+	} else
+		result = -1;
+
+	if (restore)
+		adapter->unm_nic_hw_write_wx(adapter,
+		    UNM_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4);
+
+	phy_unlock(adapter);
+
+	return (result);
+}
+
+/*
+ * Return the current station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ */
+int
+unm_niu_macaddr_get(struct unm_adapter_s *adapter, unsigned char *addr)
+{
+	__uint64_t result;
+	int phy = adapter->physical_port;
+
+	if (addr == NULL)
+		return (-1);
+	if ((phy < 0) || (phy > 3))
+		return (-1);
+
+	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+	if (adapter->curr_window != 0) {
+		adapter->unm_nic_pci_change_crbwindow(adapter, 0);
+	}
+
+	result = UNM_NIC_PCI_READ_32((void *)pci_base_offset(adapter,
+	    UNM_NIU_GB_STATION_ADDR_1(phy))) >> 16;
+	result |= ((uint64_t)UNM_NIC_PCI_READ_32((void *)pci_base_offset(
+	    adapter, UNM_NIU_GB_STATION_ADDR_0(phy)))) << 16;
+
+	(void) memcpy(addr, &result, sizeof (unm_ethernet_macaddr_t));
+
+	adapter->unm_nic_pci_change_crbwindow(adapter, 1);
+
+	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+
+	return (0);
+}
+
+/*
+ * Set the station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ */
+int
+unm_niu_macaddr_set(struct unm_adapter_s *adapter, unm_ethernet_macaddr_t addr)
+{
+	unm_crbword_t temp = 0;
+	int phy = adapter->physical_port;
+
+	if ((phy < 0) || (phy > 3))
+		return (-1);
+
+	(void) memcpy(&temp, addr, 2);
+	temp <<= 16;
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_STATION_ADDR_1(phy),
+	    &temp, 4);
+	temp = 0;
+	(void) memcpy(&temp, ((__uint8_t *)addr)+2, sizeof (unm_crbword_t));
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_STATION_ADDR_0(phy),
+	    &temp, 4);
+	return (0);
+}
+
+/* Enable a GbE interface */
+/* ARGSUSED */
+native_t unm_niu_enable_gbe_port(struct unm_adapter_s *adapter,
+		unm_niu_gbe_ifmode_t mode_dont_care)
+{
+	unm_niu_gb_mac_config_0_t mac_cfg0;
+	unm_niu_gb_mac_config_1_t mac_cfg1;
+	unm_niu_gb_mii_mgmt_config_t mii_cfg;
+	native_t port = adapter->physical_port;
+	int zero = 0;
+	int one = 1;
+	u32 port_mode = 0;
+
+	mode_dont_care = 0;
+
+	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) {
+		return (-1);
+	}
+
+	if (adapter->link_speed != MBPS_10 &&
+	    adapter->link_speed != MBPS_100 &&
+	    adapter->link_speed != MBPS_1000) {
+
+		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+/*
+ * Do NOT fail this call because the cable is unplugged.
+ * Updated when the link comes up...
+ */
+		adapter->link_speed = MBPS_1000;
+		} else {
+			return (-1);
+		}
+	}
+
+	port_mode = adapter->unm_nic_pci_read_normalize(adapter,
+	    UNM_PORT_MODE_ADDR);
+	if (port_mode == UNM_PORT_MODE_802_3_AP) {
+		*(unm_crbword_t *)&mac_cfg0 = 0x0000003f;
+		*(unm_crbword_t *)&mac_cfg1 = 0x0000f2df;
+		unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_0(port), &mac_cfg0,
+		    adapter);
+		unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_1(port), &mac_cfg1,
+		    adapter);
+	} else {
+		*(unm_crbword_t *)&mac_cfg0 = 0;
+		mac_cfg0.soft_reset = 1;
+		unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0,
+		    adapter);
+
+		*(unm_crbword_t *)&mac_cfg0 = 0;
+		mac_cfg0.tx_enable = 1;
+		mac_cfg0.rx_enable = 1;
+		mac_cfg0.rx_flowctl = 0;
+		mac_cfg0.tx_reset_pb = 1;
+		mac_cfg0.rx_reset_pb = 1;
+		mac_cfg0.tx_reset_mac = 1;
+		mac_cfg0.rx_reset_mac = 1;
+
+		unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0,
+		    adapter);
+
+		*(unm_crbword_t *)&mac_cfg1 = 0;
+		mac_cfg1.preamblelen = 0xf;
+		mac_cfg1.duplex = 1;
+		mac_cfg1.crc_enable = 1;
+		mac_cfg1.padshort = 1;
+		mac_cfg1.checklength = 1;
+		mac_cfg1.hugeframes = 1;
+
+		switch (adapter->link_speed) {
+			case MBPS_10:
+			case MBPS_100: /* Fall Through */
+				mac_cfg1.intfmode = 1;
+				unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_1
+				    (port), &mac_cfg1, adapter);
+
+				/* set mii mode */
+				unm_crb_write_adapter(
+				    UNM_NIU_GB0_GMII_MODE+(port<<3),
+				    &zero, adapter);
+				unm_crb_write_adapter(
+				    UNM_NIU_GB0_MII_MODE+(port<< 3),
+				    &one, adapter);
+				break;
+
+			case MBPS_1000:
+				mac_cfg1.intfmode = 2;
+				unm_crb_write_adapter(
+				    UNM_NIU_GB_MAC_CONFIG_1(port),
+				    &mac_cfg1, adapter);
+
+				/* set gmii mode */
+				unm_crb_write_adapter(
+				    UNM_NIU_GB0_MII_MODE+(port << 3),
+				    &zero, adapter);
+				unm_crb_write_adapter(
+				    UNM_NIU_GB0_GMII_MODE+(port << 3),
+				    &one, adapter);
+				break;
+
+			default:
+				/* Will not happen */
+				break;
+		}
+
+		*(unm_crbword_t *)&mii_cfg = 0;
+		mii_cfg.clockselect = 7;
+		unm_crb_write_adapter(UNM_NIU_GB_MII_MGMT_CONFIG(port),
+		    &mii_cfg, adapter);
+
+		*(unm_crbword_t *)&mac_cfg0 = 0;
+		mac_cfg0.tx_enable = 1;
+		mac_cfg0.rx_enable = 1;
+		mac_cfg0.tx_flowctl = 0;
+		mac_cfg0.rx_flowctl = 0;
+		unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port),
+		    &mac_cfg0, adapter);
+	}
+
+	return (0);
+}
+
+/* Disable a GbE interface */
+native_t
+unm_niu_disable_gbe_port(struct unm_adapter_s *adapter)
+{
+	native_t			port = adapter->physical_port;
+	unm_niu_gb_mac_config_0_t	mac_cfg0;
+
+	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
+		return (-1);
+
+	*(unm_crbword_t *)&mac_cfg0 = 0;
+	mac_cfg0.soft_reset = 1;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		adapter->unm_nic_hw_write_wx(adapter,
+		    UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 0);
+	else
+		adapter->unm_nic_hw_write_wx(adapter,
+		    UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4);
+	return (0);
+}
+
+/* Disable an XG interface */
+native_t
+unm_niu_disable_xg_port(struct unm_adapter_s *adapter)
+{
+	native_t			port = adapter->physical_port;
+	unm_niu_xg_mac_config_0_t	mac_cfg;
+
+	*(unm_crbword_t *)&mac_cfg = 0;
+	mac_cfg.soft_reset = 1;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		if (port != 0)
+			return (-1);
+		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0,
+		    &mac_cfg, 4);
+	} else {
+		if ((port < 0) || (port >= UNM_NIU_MAX_XG_PORTS))
+			return (-1);
+		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
+		    (port * 0x10000), &mac_cfg, 4);
+	}
+	return (0);
+}
+
+
+/* Set promiscuous mode for a GbE interface */
+native_t
+unm_niu_set_promiscuous_mode(struct unm_adapter_s *adapter,
+    unm_niu_prom_mode_t mode)
+{
+	native_t port = adapter->physical_port;
+	unm_niu_gb_drop_crc_t reg;
+	unm_niu_gb_mac_config_0_t mac_cfg;
+	unm_crbword_t data;
+	int cnt = 0, ret = 0;
+	ulong_t val;
+
+	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
+		return (-1);
+
+	/* Turn off mac */
+	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
+	    &mac_cfg, 4);
+	mac_cfg.rx_enable = 0;
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
+	    &mac_cfg, 4);
+
+	/* wait until mac is drained by sre */
+	/* Port 0 rx fifo bit 5 */
+	val = (0x20 << port);
+	adapter->unm_crb_writelit_adapter(adapter, UNM_NIU_FRAME_COUNT_SELECT,
+	    val);
+
+	do {
+		adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_FRAME_COUNT,
+		    &val, 4);
+		cnt++;
+		if (cnt > 2000) {
+			ret = -1;
+			break;
+		}
+		drv_usecwait(10);
+	} while (val);
+
+	/* now set promiscuous mode */
+	if (ret != -1) {
+		if (mode == UNM_NIU_PROMISCOUS_MODE)
+			data = 0;
+		else
+			data = 1;
+
+		adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR,
+		    &reg, 4);
+		switch (port) {
+		case 0:
+			reg.drop_gb0 = data;
+			break;
+		case 1:
+			reg.drop_gb1 = data;
+			break;
+		case 2:
+			reg.drop_gb2 = data;
+			break;
+		case 3:
+			reg.drop_gb3 = data;
+			break;
+		default:
+			ret  = -1;
+			break;
+		}
+		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR,
+		    &reg, 4);
+	}
+
+	/* turn the mac on back */
+	mac_cfg.rx_enable = 1;
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
+	    &mac_cfg, 4);
+
+	return (ret);
+}
+
+/*
+ * Set the MAC address for an XG port
+ * Note that the passed-in value must already be in network byte order.
+ */
+int
+unm_niu_xg_macaddr_set(struct unm_adapter_s *adapter,
+		unm_ethernet_macaddr_t addr)
+{
+	int		phy = adapter->physical_port;
+	unm_crbword_t	temp = 0;
+	u32		port_mode = 0;
+
+	if ((phy < 0) || (phy > 3))
+		return (-1);
+
+	switch (phy) {
+	case 0:
+		(void) memcpy(&temp, addr, 2);
+		temp <<= 16;
+		port_mode = adapter->unm_nic_pci_read_normalize(adapter,
+		    UNM_PORT_MODE_ADDR);
+		if (port_mode == UNM_PORT_MODE_802_3_AP) {
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4);
+			temp = 0;
+			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
+			    sizeof (unm_crbword_t));
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4);
+		} else {
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4);
+			temp = 0;
+			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
+			    sizeof (unm_crbword_t));
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4);
+		}
+		break;
+
+	case 1:
+		(void) memcpy(&temp, addr, 2);
+		temp <<= 16;
+		port_mode = adapter->unm_nic_pci_read_normalize(adapter,
+		    UNM_PORT_MODE_ADDR);
+		if (port_mode == UNM_PORT_MODE_802_3_AP) {
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4);
+			temp = 0;
+			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
+			    sizeof (unm_crbword_t));
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4);
+		} else {
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4);
+			temp = 0;
+			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
+			    sizeof (unm_crbword_t));
+			adapter->unm_nic_hw_write_wx(adapter,
+			    UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4);
+		}
+		break;
+
+	default:
+		cmn_err(CE_WARN, "Unknown port %d\n", phy);
+		return (DDI_FAILURE);
+	}
+
+	return (0);
+}
+
+native_t
+unm_niu_xg_set_promiscuous_mode(struct unm_adapter_s *adapter,
+    unm_niu_prom_mode_t mode)
+{
+	long  reg;
+	unm_niu_xg_mac_config_0_t mac_cfg;
+	native_t port = adapter->physical_port;
+	int cnt = 0;
+	int result = 0;
+	u32 port_mode = 0;
+
+	if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS))
+		return (-1);
+
+	port_mode = adapter->unm_nic_pci_read_normalize(adapter,
+	    UNM_PORT_MODE_ADDR);
+
+	if (port_mode == UNM_PORT_MODE_802_3_AP) {
+		reg = 0;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    UNM_NIU_GB_DROP_WRONGADDR, (void*)&reg, 4);
+	} else {
+		/* Turn off mac */
+		adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
+		    (0x10000 * port), &mac_cfg, 4);
+		mac_cfg.rx_enable = 0;
+		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
+		    (0x10000 * port), &mac_cfg, 4);
+
+		/* wait until mac is drained by sre */
+		if ((adapter->ahw.boardcfg.board_type !=
+		    UNM_BRDTYPE_P2_SB31_10G_IMEZ) &&
+		    (adapter->ahw.boardcfg.board_type !=
+		    UNM_BRDTYPE_P2_SB31_10G_HMEZ)) {
+			/* single port case bit 9 */
+			reg = 0x0200;
+			adapter->unm_crb_writelit_adapter(adapter,
+			    UNM_NIU_FRAME_COUNT_SELECT, reg);
+		} else {
+			/* Port 0 rx fifo bit 5 */
+			reg = (0x20 << port);
+			adapter->unm_crb_writelit_adapter(adapter,
+			    UNM_NIU_FRAME_COUNT_SELECT, reg);
+		}
+		do {
+			adapter->unm_nic_hw_read_wx(adapter,
+			    UNM_NIU_FRAME_COUNT, &reg, 4);
+			cnt++;
+			if (cnt > 2000) {
+				result = -1;
+				break;
+			}
+			drv_usecwait(10);
+		} while (reg);
+
+		/* now set promiscuous mode */
+		if (result != -1) {
+			adapter->unm_nic_hw_read_wx(adapter,
+			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4);
+			if (mode == UNM_NIU_PROMISCOUS_MODE) {
+				reg = (reg | 0x2000UL);
+			} else { /* FIXME  use the correct mode value here */
+				reg = (reg & ~0x2000UL);
+			}
+			adapter->unm_crb_writelit_adapter(adapter,
+			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+		}
+
+		/* turn the mac back on */
+		mac_cfg.rx_enable = 1;
+		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
+		    (0x10000 * port), &mac_cfg, 4);
+	}
+
+	return (result);
+}
+
+int
+unm_niu_xg_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable)
+{
+	int port = adapter->physical_port;
+	unm_niu_xg_pause_ctl_t reg;
+
+	if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS))
+		return (-1);
+
+	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XG_PAUSE_CTL, &reg, 4);
+	if (port == 0)
+		reg.xg0_mask = !enable;
+	else
+		reg.xg1_mask = !enable;
+
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XG_PAUSE_CTL, &reg, 4);
+
+	return (0);
+}
+
+int
+unm_niu_gbe_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable)
+{
+	int port = adapter->physical_port;
+	unm_niu_gb_pause_ctl_t reg;
+
+	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
+		return (-1);
+
+	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_PAUSE_CTL, &reg, 4);
+	switch (port) {
+	case (0):
+		reg.gb0_mask = !enable;
+		break;
+	case (1):
+		reg.gb1_mask = !enable;
+		break;
+	case (2):
+		reg.gb2_mask = !enable;
+		break;
+	case (3):
+	default:
+		reg.gb3_mask = !enable;
+		break;
+	}
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_PAUSE_CTL, &reg, 4);
+
+	return (0);
+}
+
+int
+unm_niu_gbe_set_rx_flow_ctl(struct unm_adapter_s *adapter, int enable)
+{
+	int port = adapter->physical_port;
+	unm_niu_gb_mac_config_0_t reg;
+
+	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
+		return (-1);
+
+	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
+	    &reg, 4);
+	reg.rx_flowctl = enable;
+	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
+	    &reg, 4);
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/nx_errorcode.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,81 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Error codes for HAL - NIC interface.
+ *
+ */
+
+#ifndef _NX_ERRORCODE_H_
+#define	_NX_ERRORCODE_H_
+
+/*
+ *        Common Error Codes
+ */
+
+#define	NX_RCODE_SUCCESS			0
+/* Insuff. mem resource on host */
+#define	NX_RCODE_NO_HOST_MEM		1
+/* Insuff. misc. resources on host */
+#define	NX_RCODE_NO_HOST_RESOURCE	2
+/* Insuff. crb resources on card */
+#define	NX_RCODE_NO_CARD_CRB		3
+/* Insuff. mem resources on card */
+#define	NX_RCODE_NO_CARD_MEM		4
+/* Insuff. misc. resources on card */
+#define	NX_RCODE_NO_CARD_RESOURCE	5
+/* One or more args to routine were out-of-range */
+#define	NX_RCODE_INVALID_ARGS		6
+/* Requested action is invalid / in error */
+#define	NX_RCODE_INVALID_ACTION		7
+/* Requested RX/TX has invalid state */
+#define	NX_RCODE_INVALID_STATE		8
+/* Requested action is not supported */
+#define	NX_RCODE_NOT_SUPPORTED		9
+/* Requested action is not allowed */
+#define	NX_RCODE_NOT_PERMITTED		10
+/* System not ready for action */
+#define	NX_RCODE_NOT_READY			11
+/* Target of requested action does not exist */
+#define	NX_RCODE_DOES_NOT_EXIST		2
+/* Requested action already performed/complete */
+#define	NX_RCODE_ALREADY_EXISTSi	13
+/* Invalid signature provided */
+#define	NX_RCODE_BAD_SIGNATURE		14
+/* Valid command, not implemented */
+#define	NX_RCODE_CMD_NOT_IMPLi		15
+/* Invalid/Unknown command */
+#define	NX_RCODE_CMD_INVALID		16
+/* Timeout on polling rsp status  */
+#define	NX_RCODE_TIMEOUT			17
+#define	NX_RCODE_CMD_FAILED			18
+#define	NX_RCODE_MAX_EXCEEDED		19
+#define	NX_RCODE_MAX				20
+
+/*
+ *       Macros
+ */
+#define	NX_IS_RCODE_VALID(ERR)		(ERR >= NX_RCODE_MAX)
+
+#endif /* _NX_ERRORCODE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/nx_hw_pci_regs.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,168 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef __NX_HW_REGS_H
+#define	__NX_HW_REGS_H
+
+/*
+ *		PCI related defines.
+ */
+
+/*
+ * Interrupt related defines.
+ */
+#define	PCIX_TARGET_STATUS	(0x10118)
+#define	PCIX_TARGET_STATUS_F1	(0x10160)
+#define	PCIX_TARGET_STATUS_F2	(0x10164)
+#define	PCIX_TARGET_STATUS_F3	(0x10168)
+#define	PCIX_TARGET_STATUS_F4	(0x10360)
+#define	PCIX_TARGET_STATUS_F5	(0x10364)
+#define	PCIX_TARGET_STATUS_F6	(0x10368)
+#define	PCIX_TARGET_STATUS_F7	(0x1036c)
+
+#define	PCIX_TARGET_MASK	(0x10128)
+#define	PCIX_TARGET_MASK_F1	(0x10170)
+#define	PCIX_TARGET_MASK_F2	(0x10174)
+#define	PCIX_TARGET_MASK_F3	(0x10178)
+#define	PCIX_TARGET_MASK_F4	(0x10370)
+#define	PCIX_TARGET_MASK_F5	(0x10374)
+#define	PCIX_TARGET_MASK_F6	(0x10378)
+#define	PCIX_TARGET_MASK_F7	(0x1037c)
+
+/*
+ * Message Signaled Interrupts
+ */
+#define	PCIX_MSI_F0		(0x13000)
+#define	PCIX_MSI_F1		(0x13004)
+#define	PCIX_MSI_F2		(0x13008)
+#define	PCIX_MSI_F3		(0x1300c)
+#define	PCIX_MSI_F4		(0x13010)
+#define	PCIX_MSI_F5		(0x13014)
+#define	PCIX_MSI_F6		(0x13018)
+#define	PCIX_MSI_F7		(0x1301c)
+#define	PCIX_MSI_F(FUNC)	(0x13000 +((FUNC) * 4))
+
+/*
+ *
+ */
+#define	PCIX_INT_VECTOR		(0x10100)
+#define	PCIX_INT_MASK		(0x10104)
+
+/*
+ * Interrupt state machine and other bits.
+ */
+#define	PCIE_MISCCFG_RC		(0x1206c)
+
+
+#define	ISR_INT_TARGET_STATUS	  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS))
+#define	ISR_INT_TARGET_STATUS_F1  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS_F1))
+#define	ISR_INT_TARGET_STATUS_F2  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS_F2))
+#define	ISR_INT_TARGET_STATUS_F3  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS_F3))
+#define	ISR_INT_TARGET_STATUS_F4  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS_F4))
+#define	ISR_INT_TARGET_STATUS_F5  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS_F5))
+#define	ISR_INT_TARGET_STATUS_F6  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS_F6))
+#define	ISR_INT_TARGET_STATUS_F7  (UNM_PCIX_PS_REG(PCIX_TARGET_STATUS_F7))
+
+#define	ISR_INT_TARGET_MASK	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK))
+#define	ISR_INT_TARGET_MASK_F1	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK_F1))
+#define	ISR_INT_TARGET_MASK_F2	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK_F2))
+#define	ISR_INT_TARGET_MASK_F3	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK_F3))
+#define	ISR_INT_TARGET_MASK_F4	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK_F4))
+#define	ISR_INT_TARGET_MASK_F5	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK_F5))
+#define	ISR_INT_TARGET_MASK_F6	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK_F6))
+#define	ISR_INT_TARGET_MASK_F7	  (UNM_PCIX_PS_REG(PCIX_TARGET_MASK_F7))
+
+#define	ISR_INT_VECTOR		  (UNM_PCIX_PS_REG(PCIX_INT_VECTOR))
+#define	ISR_INT_MASK		  (UNM_PCIX_PS_REG(PCIX_INT_MASK))
+#define	ISR_INT_STATE_REG	  (UNM_PCIX_PS_REG(PCIE_MISCCFG_RC))
+
+#define	ISR_MSI_INT_TRIGGER(FUNC) (UNM_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
+
+
+#define	ISR_IS_LEGACY_INTR_IDLE(VAL)		(((VAL) & 0x300) == 0)
+#define	ISR_IS_LEGACY_INTR_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)
+
+/*
+ * PCI Interrupt Vector Values.
+ */
+#define	PCIX_INT_VECTOR_BIT_F0	0x0080
+#define	PCIX_INT_VECTOR_BIT_F1	0x0100
+#define	PCIX_INT_VECTOR_BIT_F2	0x0200
+#define	PCIX_INT_VECTOR_BIT_F3	0x0400
+#define	PCIX_INT_VECTOR_BIT_F4	0x0800
+#define	PCIX_INT_VECTOR_BIT_F5	0x1000
+#define	PCIX_INT_VECTOR_BIT_F6	0x2000
+#define	PCIX_INT_VECTOR_BIT_F7	0x4000
+
+struct nx_legacy_intr_set {
+	__uint32_t	int_vec_bit;
+	__uint32_t	tgt_status_reg;
+	__uint32_t	tgt_mask_reg;
+	__uint32_t	pci_int_reg;
+};
+
+#define	NX_LEGACY_INTR_CONFIG			\
+{						\
+	{	PCIX_INT_VECTOR_BIT_F0,		\
+		ISR_INT_TARGET_STATUS,		\
+		ISR_INT_TARGET_MASK,		\
+		ISR_MSI_INT_TRIGGER(0) },	\
+						\
+	{	PCIX_INT_VECTOR_BIT_F1,		\
+		ISR_INT_TARGET_STATUS_F1,	\
+		ISR_INT_TARGET_MASK_F1,		\
+		ISR_MSI_INT_TRIGGER(1) },	\
+						\
+	{	PCIX_INT_VECTOR_BIT_F2,		\
+		ISR_INT_TARGET_STATUS_F2,	\
+		ISR_INT_TARGET_MASK_F2,		\
+		ISR_MSI_INT_TRIGGER(2) },	\
+						\
+	{	PCIX_INT_VECTOR_BIT_F3,		\
+		ISR_INT_TARGET_STATUS_F3,	\
+		ISR_INT_TARGET_MASK_F3,		\
+		ISR_MSI_INT_TRIGGER(3) },	\
+						\
+	{	PCIX_INT_VECTOR_BIT_F4,		\
+		ISR_INT_TARGET_STATUS_F4,	\
+		ISR_INT_TARGET_MASK_F4,		\
+		ISR_MSI_INT_TRIGGER(4) },	\
+						\
+	{	PCIX_INT_VECTOR_BIT_F5,		\
+		ISR_INT_TARGET_STATUS_F5,	\
+		ISR_INT_TARGET_MASK_F5,		\
+		ISR_MSI_INT_TRIGGER(5) },	\
+						\
+	{	PCIX_INT_VECTOR_BIT_F6,		\
+		ISR_INT_TARGET_STATUS_F6,	\
+		ISR_INT_TARGET_MASK_F6,		\
+		ISR_MSI_INT_TRIGGER(6) },	\
+						\
+	{	PCIX_INT_VECTOR_BIT_F7,		\
+		ISR_INT_TARGET_STATUS_F7,	\
+		ISR_INT_TARGET_MASK_F7,		\
+		ISR_MSI_INT_TRIGGER(7) },	\
+}
+
+#endif /* __NX_HW_REGS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/nxhal_nic_interface.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,545 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Data types and structure for HAL - NIC interface.
+ *
+ */
+
+#ifndef _NXHAL_NIC_INTERFACE_H_
+#define	_NXHAL_NIC_INTERFACE_H_
+
+/*
+ *        Simple Types
+ */
+
+typedef	U32	nx_reg_addr_t;
+
+/*
+ *        Root crb-based firmware commands
+ */
+
+/*
+ * CRB Root Command
+ * A single set of crbs is used across all physical/virtual
+ * functions for capability queries, initialization, and
+ * context creation/destruction.
+ *
+ * There are 4 CRBS:
+ *					Command/Response CRB
+ *					Argument1 CRB
+ *					Argument2 CRB
+ *					Argument3 CRB
+ *					Signature CRB
+ *
+ * The cmd/rsp crb is always intiated by the host via
+ * a command code and always responded by the card with
+ * a response code. The cmd and rsp codes are disjoint.
+ * The sequence of use is always CMD, RSP, CLEAR CMD.
+ *
+ * The arguments are for passing in command specific
+ * and response specific parameters/data.
+ *
+ * The signature is composed of a magic value, the
+ * pci function id, and a command sequence id:
+ *		[7:0]  = pci function
+ *		[15:8]  = version
+ *		[31:16] = magic of 0xcafe
+ *
+ *	The pci function allows the card to take correct
+ *	action for the given particular commands.
+ *	The firmware will attempt to detect
+ *	an errant driver that has died while holding
+ *	the root crb hardware lock. Such an error condition
+ *	shows up as the cmd/rsp crb stuck in a non-clear state.
+ *
+ * Interface Sequence:
+ *	 Host always makes requests and firmware always responds.
+ *	 Note that data field is always set prior to command field.
+ *
+ *		[READ]             CMD/RSP CRB      ARGUMENT FIELD
+ *		Host grab lock
+ *		Host  ->           CMD              optional parameter
+ *		FW   <-  (Good)    RSP-OK           DATA
+ *		FW   <-  (Fail)    RSP-FAIL         optional failure code
+ *		Host ->            CLEAR
+ *		Host release lock
+ *
+ * [WRITE]            CMD/RSP CRB      ARGUMENT FIELD
+ * Host grab lock
+ * Host  ->           CMD              DATA
+ * FW   <-  (Good)    RSP-OK           optional write status
+ * FW   <-  (Write)   RSP-FAIL         optional failure code
+ * Host ->            CLEAR
+ * Host release lock
+ */
+
+
+/*
+ *        CMD/RSP
+ */
+
+#define	NX_CDRP_SIGNATURE_TO_PCIFN(sign)    ((sign) & 0xff)
+#define	NX_CDRP_SIGNATURE_TO_VERSION(sign)  (((sign)>>8) & 0xff)
+#define	NX_CDRP_SIGNATURE_TO_MAGIC(sign)    (((sign)>>16) & 0xffff)
+#define	NX_CDRP_SIGNATURE_VALID(sign)       \
+	(NX_CDRP_SIGNATURE_TO_MAGIC(sign) == 0xcafe && \
+	    NX_CDRP_SIGNATURE_TO_PCIFN(sign) < 8)
+#define	NX_CDRP_SIGNATURE_MAKE(pcifn, version) \
+	(((pcifn) & 0xff) |		      \
+	    (((version) & 0xff) << 8) |	      \
+	    ((u32)0xcafe << 16))
+
+#define	NX_CDRP_CLEAR			0x00000000
+#define	NX_CDRP_CMD_BIT			0x80000000
+
+/*
+ * All responses must have the NX_CDRP_CMD_BIT cleared
+ * in the crb NX_CDRP_CRB_OFFSET.
+ */
+
+#define	NX_CDRP_FORM_RSP(rsp)		(rsp)
+#define	NX_CDRP_IS_RSP(rsp)			(((rsp) & NX_CDRP_CMD_BIT) == 0)
+
+#define	NX_CDRP_RSP_OK				0x00000001
+#define	NX_CDRP_RSP_FAIL			0x00000002
+#define	NX_CDRP_RSP_TIMEOUT			0x00000003
+
+/*
+ * All commands must have the NX_CDRP_CMD_BIT set in
+ * the crb NX_CDRP_CRB_OFFSET.
+ * The macros below do not have it explicitly set to
+ * allow their use in lookup tables
+ */
+#define	NX_CDRP_FORM_CMD(cmd)	(NX_CDRP_CMD_BIT | (cmd))
+#define	NX_CDRP_IS_CMD(cmd)		(((cmd) & NX_CDRP_CMD_BIT) != 0)
+
+/* [CMD] Capability Vector [RSP] Capability Vector */
+#define	NX_CDRP_CMD_SUBMIT_CAPABILITIES		0x00000001
+
+/* [CMD] - [RSP] Query Value */
+#define	NX_CDRP_CMD_READ_MAX_RDS_PER_CTX    0x00000002
+
+/* [CMD] - [RSP] Query Value */
+#define	NX_CDRP_CMD_READ_MAX_SDS_PER_CTX    0x00000003
+
+/* [CMD] - [RSP] Query Value */
+#define	NX_CDRP_CMD_READ_MAX_RULES_PER_CTX  0x00000004
+
+/* [CMD] - [RSP] Query Value */
+#define	NX_CDRP_CMD_READ_MAX_RX_CTX			0x00000005
+
+/* [CMD] - [RSP] Query Value */
+#define	NX_CDRP_CMD_READ_MAX_TX_CTX			0x00000006
+
+/* [CMD] Rx Config DMA Addr [RSP] rcode */
+#define	NX_CDRP_CMD_CREATE_RX_CTX			0x00000007
+
+/* [CMD] Rx Context Handle, Reset Kind [RSP] rcode */
+#define	NX_CDRP_CMD_DESTROY_RX_CTX			0x00000008
+
+/* [CMD] Tx Config DMA Addr [RSP] rcode */
+#define	NX_CDRP_CMD_CREATE_TX_CTX			0x00000009
+
+/* [CMD] Tx Context Handle, Reset Kind [RSP] rcode */
+#define	NX_CDRP_CMD_DESTROY_TX_CTX			0x0000000a
+
+/* [CMD] Stat setup dma addr - [RSP] Handle, rcode */
+#define	NX_CDRP_CMD_SETUP_STATISTICS		0x0000000e
+
+/* [CMD] Handle - [RSP] rcode */
+#define	NX_CDRP_CMD_GET_STATISTICS			0x0000000f
+
+/* [CMD] Handle - [RSP] rcode */
+#define	NX_CDRP_CMD_DELETE_STATISTICS		0x00000010
+
+/* [CMD] - [RSP] rcode */
+#define	NX_CDRP_CMD_GEN_INT					0x00000011
+
+/* [CMD] MTU - [RSP] rcode */
+#define	NX_CDRP_CMD_SET_MTU					0x00000012
+
+#define	NX_CDRP_CMD_MAX						0x00000013
+
+/*
+ *        Capabilities
+ */
+
+#define	NX_CAP_BIT(class, bit)				(1 << bit)
+
+/* Class 0 (i.e. ARGS 1) */
+#define	NX_CAP0_LEGACY_CONTEXT			NX_CAP_BIT(0, 0)
+#define	NX_CAP0_MULTI_CONTEXT			NX_CAP_BIT(0, 1)
+#define	NX_CAP0_LEGACY_MN				NX_CAP_BIT(0, 2)
+#define	NX_CAP0_LEGACY_MS				NX_CAP_BIT(0, 3)
+#define	NX_CAP0_CUT_THROUGH				NX_CAP_BIT(0, 4)
+#define	NX_CAP0_LRO						NX_CAP_BIT(0, 5)
+#define	NX_CAP0_LSO						NX_CAP_BIT(0, 6)
+#define	NX_CAP0_JUMBO_CONTIGUOUS		NX_CAP_BIT(0, 7)
+#define	NX_CAP0_LRO_CONTIGUOUS		    NX_CAP_BIT(0, 8)
+
+/* Class 1 (i.e. ARGS 2) */
+#define	NX_CAP1_NIC						NX_CAP_BIT(1, 0)
+#define	NX_CAP1_PXE						NX_CAP_BIT(1, 1)
+#define	NX_CAP1_CHIMNEY					NX_CAP_BIT(1, 2)
+#define	NX_CAP1_LSA						NX_CAP_BIT(1, 3)
+#define	NX_CAP1_RDMA					NX_CAP_BIT(1, 4)
+#define	NX_CAP1_ISCSI					NX_CAP_BIT(1, 5)
+#define	NX_CAP1_FCOE					NX_CAP_BIT(1, 6)
+
+/* Class 2 (i.e. ARGS 3) */
+
+/*
+ *        Rules
+ */
+
+typedef	U32	nx_rx_rule_type_t;
+
+#define	NX_RX_RULETYPE_DEFAULT				0
+#define	NX_RX_RULETYPE_MAC					1
+#define	NX_RX_RULETYPE_MAC_VLAN				2
+#define	NX_RX_RULETYPE_MAC_RSS				3
+#define	NX_RX_RULETYPE_MAC_VLAN_RSS			4
+#define	NX_RX_RULETYPE_MAX					5
+
+typedef	U32	nx_rx_rule_cmd_t;
+
+#define	NX_RX_RULECMD_ADD					0
+#define	NX_RX_RULECMD_REMOVE				1
+#define	NX_RX_RULECMD_MAX					2
+
+typedef struct nx_rx_rule_arg_s {
+	union {
+		struct {
+			char mac[6];
+		} m;
+		struct {
+			char mac[6];
+			char vlan;
+		} mv;
+		struct {
+			char mac[6];
+		} mr;
+		struct {
+			char mac[6];
+			char vlan;
+		} mvr;
+	} s1;
+	/* will be union of all the different args for rules */
+	U64 data;
+} nx_rx_rule_arg_t;
+
+typedef struct nx_rx_rule_s {
+	U32 id;
+	U32 active;
+	nx_rx_rule_arg_t arg;
+	nx_rx_rule_type_t type;
+} nx_rx_rule_t;
+
+/* MSG - REQUIRES TX CONTEXT */
+
+/*
+ * The rules can be added/deleted from both the
+ *  host and card sides so rq/rsp are similar.
+ */
+typedef struct nx_hostmsg_rx_rule_s {
+	nx_rx_rule_cmd_t cmd;
+	nx_rx_rule_t rule;
+} nx_hostmsg_rx_rule_t;
+
+typedef struct nx_cardmsg_rx_rule_s {
+	nx_rcode_t rcode;
+	nx_rx_rule_cmd_t cmd;
+	nx_rx_rule_t rule;
+} nx_cardmsg_rx_rule_t;
+
+
+/*
+ *        Common to Rx/Tx contexts
+ */
+
+/*
+ * Context states
+ */
+
+typedef U32 nx_host_ctx_state_t;
+
+#define	NX_HOST_CTX_STATE_FREED		0 /* Invalid state */
+#define	NX_HOST_CTX_STATE_ALLOCATED	1 /* Not committed */
+/* The following states imply FW is aware of context */
+#define	NX_HOST_CTX_STATE_ACTIVE	2
+#define	NX_HOST_CTX_STATE_DISABLED	3
+#define	NX_HOST_CTX_STATE_QUIESCED	4
+#define	NX_HOST_CTX_STATE_MAX		5
+
+/*
+ * Interrupt mask crb use must be set identically on the Tx
+ * and Rx context configs across a pci function
+ */
+
+/* Rx and Tx have unique interrupt/crb */
+#define	NX_HOST_INT_CRB_MODE_UNIQUE		0
+/* Rx and Tx share a common interrupt/crb */
+#define	NX_HOST_INT_CRB_MODE_SHARED		1	/* <= LEGACY */
+/* Rx does not use a crb */
+#define	NX_HOST_INT_CRB_MODE_NORX		2
+/* Tx does not use a crb */
+#define	NX_HOST_INT_CRB_MODE_NOTX		3
+/* Neither Rx nor Tx use a crb */
+#define	NX_HOST_INT_CRB_MODE_NORXTX		4
+
+/*
+ * Destroy Rx/Tx
+ */
+
+#define	NX_DESTROY_CTX_RESET			0
+#define	NX_DESTROY_CTX_D3_RESET			1
+#define	NX_DESTROY_CTX_MAX				2
+
+
+/*
+ *        Tx
+ */
+
+/*
+ * Components of the host-request for Tx context creation.
+ * CRB - DOES NOT REQUIRE Rx/TX CONTEXT
+ */
+
+typedef struct nx_hostrq_cds_ring_s {
+	U64 host_phys_addr;	/* Ring base addr */
+	U32 ring_size;		/* Ring entries */
+	U32 rsvd;		/* Padding */
+} nx_hostrq_cds_ring_t;
+
+typedef struct nx_hostrq_tx_ctx_s {
+	U64 host_rsp_dma_addr;	/* Response dma'd here */
+	U64 cmd_cons_dma_addr;	/*  */
+	U64 dummy_dma_addr;	/*  */
+	U32 capabilities[4];	/* Flag bit vector */
+	U32 host_int_crb_mode;	/* Interrupt crb usage */
+	U32 rsvd1;		/* Padding */
+	U16 rsvd2;		/* Padding */
+	U16 interrupt_ctl;
+	U16 msi_index;
+	U16 rsvd3;		/* Padding */
+	nx_hostrq_cds_ring_t cds_ring;	/* Desc of cds ring */
+	U8  reserved[128];	/* future expansion */
+} nx_hostrq_tx_ctx_t;
+
+typedef struct nx_cardrsp_cds_ring_s {
+	U32 host_producer_crb;	/* Crb to use */
+	U32 interrupt_crb;	/* Crb to use */
+} nx_cardrsp_cds_ring_t;
+
+typedef struct nx_cardrsp_tx_ctx_s {
+	U32 host_ctx_state;	/* Starting state */
+	U16 context_id;		/* Handle for context */
+	U8  phys_port;		/* Physical id of port */
+	U8  virt_port;		/* Virtual/Logical id of port */
+	nx_cardrsp_cds_ring_t cds_ring;	/* Card cds settings */
+	U8  reserved[128];	/* future expansion */
+} nx_cardrsp_tx_ctx_t;
+
+#define	SIZEOF_HOSTRQ_TX(HOSTRQ_TX) 			\
+		(sizeof (HOSTRQ_TX))
+
+#define	SIZEOF_CARDRSP_TX(CARDRSP_TX) 			\
+		(sizeof (CARDRSP_TX))
+
+/*
+ *        Rx
+ */
+
+/*
+ * RDS ring mapping to producer crbs
+ */
+
+/* Each ring has a unique crb */
+#define	NX_HOST_RDS_CRB_MODE_UNIQUE    0	/* <= LEGACY */
+
+/*
+ * All configured RDS Rings share common crb:
+ *		1 Ring  - same as unique
+ *		2 Rings - 16, 16
+ *		3 Rings - 10, 10, 10
+ */
+#define	NX_HOST_RDS_CRB_MODE_SHARED    1
+
+/*
+ * Bit usage is specified per-ring using the
+ * ring's size. Sum of bit lengths must be <= 32.
+ * Packing is [Ring N] ... [Ring 1][Ring 0]
+ */
+#define	NX_HOST_RDS_CRB_MODE_CUSTOM		2
+#define	NX_HOST_RDS_CRB_MODE_MAX		3
+
+
+/*
+ * RDS Ting Types
+ */
+
+#define	NX_RDS_RING_TYPE_NORMAL		0
+#define	NX_RDS_RING_TYPE_JUMBO		1
+#define	NX_RDS_RING_TYPE_LRO		2
+#define	NX_RDS_RING_TYPE_MAX		3
+
+/*
+ * Components of the host-request for Rx context creation.
+ * CRB - DOES NOT REQUIRE Rx/TX CONTEXT
+ */
+
+typedef struct nx_hostrq_sds_ring_s {
+	U64 host_phys_addr;	/* Ring base addr */
+	U32 ring_size;		/* Ring entries */
+	U16 msi_index;
+	U16 rsvd;		/* Padding */
+} nx_hostrq_sds_ring_t;
+
+typedef struct nx_hostrq_rds_ring_s {
+	U64 host_phys_addr;	/* Ring base addr */
+	U64 buff_size;		/* Packet buffer size */
+	U32 ring_size;		/* Ring entries */
+	U32 ring_kind;		/* Class of ring */
+} nx_hostrq_rds_ring_t;
+
+typedef struct nx_hostrq_rx_ctx_s {
+	U64 host_rsp_dma_addr;	/* Response dma'd here */
+	U32 capabilities[4];	/* Flag bit vector */
+	U32 host_int_crb_mode;	/* Interrupt crb usage */
+	U32 host_rds_crb_mode;	/* RDS crb usage */
+	/* These ring offsets are relative to data[0] below */
+	U32 rds_ring_offset;	/* Offset to RDS config */
+	U32 sds_ring_offset;	/* Offset to SDS config */
+	U16 num_rds_rings;	/* Count of RDS rings */
+	U16 num_sds_rings;	/* Count of SDS rings */
+	U16 rsvd1;		/* Padding */
+	U16 rsvd2;		/* Padding */
+	U8  reserved[128]; 	/* reserve space for future expansion */
+	/*
+	 * MUST BE 64-bit aligned.
+	 * The following is packed:
+	 * - N hostrq_rds_rings
+	 * - N hostrq_sds_rings
+	 */
+	char data[];
+} nx_hostrq_rx_ctx_t;
+
+typedef struct nx_cardrsp_rds_ring_s {
+	U32 host_producer_crb;	/* Crb to use */
+	U32 rsvd1;		/* Padding */
+} nx_cardrsp_rds_ring_t;
+
+typedef struct nx_cardrsp_sds_ring_s {
+	U32 host_consumer_crb;	/* Crb to use */
+	U32 interrupt_crb;	/* Crb to use */
+} nx_cardrsp_sds_ring_t;
+
+typedef struct nx_cardrsp_rx_ctx_s {
+	/* These ring offsets are relative to data[0] below */
+	U32 rds_ring_offset;	/* Offset to RDS config */
+	U32 sds_ring_offset;	/* Offset to SDS config */
+	U32 host_ctx_state;	/* Starting State */
+	U32 num_fn_per_port;	/* How many PCI fn share the port */
+	U16 num_rds_rings;	/* Count of RDS rings */
+	U16 num_sds_rings;	/* Count of SDS rings */
+	U16 context_id;		/* Handle for context */
+	U8  phys_port;		/* Physical id of port */
+	U8  virt_port;		/* Virtual/Logical id of port */
+	U8  reserved[128];	/* save space for future expansion */
+	/*
+	 * MUST BE 64-bit aligned.
+	 * The following is packed:
+	 * - N cardrsp_rds_rings
+	 * - N cardrs_sds_rings
+	 */
+	char data[];
+} nx_cardrsp_rx_ctx_t;
+
+#define	SIZEOF_HOSTRQ_RX(HOSTRQ_RX, rds_rings, sds_rings)	\
+	(sizeof (HOSTRQ_RX) + 					\
+	(rds_rings)*(sizeof (nx_hostrq_rds_ring_t)) +		\
+	    (sds_rings)*(sizeof (nx_hostrq_sds_ring_t)))
+
+#define	SIZEOF_CARDRSP_RX(CARDRSP_RX, rds_rings, sds_rings) 	\
+	(sizeof (CARDRSP_RX) + 					\
+	(rds_rings)*(sizeof (nx_cardrsp_rds_ring_t)) + 		\
+	    (sds_rings)*(sizeof (nx_cardrsp_sds_ring_t)))
+
+
+/*
+ *        Statistics
+ */
+
+/*
+ * The model of statistics update to use
+ */
+
+#define	NX_STATISTICS_MODE_INVALID		0
+
+/*
+ * Permanent setup; Updates are only sent on explicit request
+ * NX_CDRP_CMD_GET_STATISTICS)
+ */
+#define	NX_STATISTICS_MODE_PULL			1
+
+/*
+ * Permanent setup; Updates are sent automatically and on
+ * explicit request (NX_CDRP_CMD_GET_STATISTICS)
+ */
+#define	NX_STATISTICS_MODE_PUSH			2
+
+/* One time stat update. */
+#define	NX_STATISTICS_MODE_SINGLE_SHOT	3
+
+#define	NX_STATISTICS_MODE_MAX			4
+
+/*
+ * What set of stats
+ */
+#define	NX_STATISTICS_TYPE_INVALID		0
+#define	NX_STATISTICS_TYPE_NIC_RX_CORE	1
+#define	NX_STATISTICS_TYPE_NIC_TX_CORE	2
+#define	NX_STATISTICS_TYPE_NIC_RX_ALL	3
+#define	NX_STATISTICS_TYPE_NIC_TX_ALL	4
+#define	NX_STATISTICS_TYPE_MAX			5
+
+
+/*
+ * Request to setup statistics gathering.
+ * CRB - DOES NOT REQUIRE Rx/TX CONTEXT
+ */
+
+typedef struct nx_hostrq_stat_setup_s {
+	U64 host_stat_buffer;	/* Where to dma stats */
+	U32 host_stat_size;	/* Size of stat buffer */
+	U16 context_id;		/* Which context */
+	U16 stat_type;		/* What class of stats */
+	U16 stat_mode;		/* When to update */
+	U16 stat_interval;	/* Frequency of update */
+} nx_hostrq_stat_setup_t;
+
+
+
+#endif /* _NXHAL_NIC_INTERFACE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_brdcfg.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,273 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef __UNM_BRDINFO_H
+#define	__UNM_BRDINFO_H
+
+/* The version of the main data structure */
+#define	UNM_BDINFO_VERSION 1
+
+/* Magic number to let user know flash is programmed */
+#define	UNM_BDINFO_MAGIC 0x12345678
+
+#define	P2_CHIP 2
+#define	P3_CHIP 3
+#define	NX_P2_C0		0x24
+#define	NX_P2_C1		0x25
+#define	NX_P3_A0		0x30
+#define	NX_P3_A2		0x32
+#define	NX_P3_B0		0x40
+#define	NX_P3_B1		0x41
+#define	NX_P3_B2		0x42
+
+#define	NX_IS_REVISION_P2(REVISION)	(REVISION <= NX_P2_C1)
+#define	NX_IS_REVISION_P3(REVISION)	(REVISION >= NX_P3_A0)
+
+typedef enum {
+    UNM_BRDTYPE_P1_BD   = 0x0000,
+    UNM_BRDTYPE_P1_SB   = 0x0001,
+    UNM_BRDTYPE_P1_SMAX = 0x0002,
+    UNM_BRDTYPE_P1_SOCK = 0x0003,
+
+    UNM_BRDTYPE_P2_SOCK_31  =  0x0008,
+    UNM_BRDTYPE_P2_SOCK_35  =  0x0009,
+    UNM_BRDTYPE_P2_SB35_4G  =  0x000a,
+    UNM_BRDTYPE_P2_SB31_10G =  0x000b,
+    UNM_BRDTYPE_P2_SB31_2G  =  0x000c,
+
+    UNM_BRDTYPE_P2_SB31_10G_IMEZ =  0x000d,
+    UNM_BRDTYPE_P2_SB31_10G_HMEZ =  0x000e,
+    UNM_BRDTYPE_P2_SB31_10G_CX4  =  0x000f,
+
+	/* Reference quad gig */
+	UNM_BRDTYPE_P3_REF_QG		=	0x0021,
+	UNM_BRDTYPE_P3_HMEZ			=	0x0022,
+	/* Dual CX4 - Low Profile - Red card */
+	UNM_BRDTYPE_P3_10G_CX4_LP	=  0x0023,
+	UNM_BRDTYPE_P3_4_GB			=	0x0024,
+	UNM_BRDTYPE_P3_IMEZ			=	0x0025,
+	UNM_BRDTYPE_P3_10G_SFP_PLUS	=	0x0026,
+	UNM_BRDTYPE_P3_10000_BASE_T	=	0x0027,
+	UNM_BRDTYPE_P3_XG_LOM		=	0x0028,
+
+	UNM_BRDTYPE_P3_4_GB_MM		=	0x0029,
+	UNM_BRDTYPE_P3_10G_CX4		=	0x0031, /* Reference CX4 */
+	UNM_BRDTYPE_P3_10G_XFP		=	0x0032, /* Reference XFP */
+
+    UNM_BRDTYPE_P3_10G_TRP	 =  0x0080,
+
+} unm_brdtype_t;
+
+typedef enum {
+	NX_UNKNOWN_TYPE_ROMIMAGE = 0,
+	NX_P2_MN_TYPE_ROMIMAGE = 1,
+	NX_P3_CT_TYPE_ROMIMAGE,
+	NX_P3_MN_TYPE_ROMIMAGE,
+	NX_P3_MS_TYPE_ROMIMAGE,
+	NX_UNKNOWN_TYPE_ROMIMAGE_LAST,
+} nx_fw_type_t;
+
+/* board type specific information */
+typedef struct {
+	unm_brdtype_t	brdtype; /* type of board */
+	long			ports; /* max no of physical ports */
+	nx_fw_type_t	fwtype; /* The FW Associated with board type */
+	char			*short_name;
+} unm_brdinfo_t;
+
+#define	NUM_SUPPORTED_BOARDS (sizeof (unm_boards)/sizeof (unm_brdinfo_t))
+
+#define	GET_BRD_NAME_BY_TYPE(type, name)            \
+{                                                   \
+	int i, found = 0;                               \
+	for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) {    \
+		if (unm_boards[i].brdtype == type) {        \
+			name = unm_boards[i].short_name;        \
+			found = 1;                              \
+			break;                                  \
+		}                                           \
+	}                                               \
+	if (!found)                                   \
+	name = "Unknown";                           \
+}
+
+typedef struct {
+    __uint32_t header_version;
+
+    __uint32_t board_mfg;
+    __uint32_t board_type;
+    __uint32_t board_num;
+    __uint32_t chip_id;
+    __uint32_t chip_minor;
+    __uint32_t chip_major;
+    __uint32_t chip_pkg;
+    __uint32_t chip_lot;
+
+
+	__uint32_t port_mask; /* available niu ports */
+	__uint32_t peg_mask; /* available pegs */
+	__uint32_t icache_ok; /* can we run with icache? */
+	__uint32_t dcache_ok; /* can we run with dcache? */
+	__uint32_t casper_ok;
+
+	/* unm_eth_addr_t  mac_address[MAX_PORTS]; */
+    __uint32_t mac_addr_lo_0;
+    __uint32_t mac_addr_lo_1;
+    __uint32_t mac_addr_lo_2;
+    __uint32_t mac_addr_lo_3;
+
+	/* MN-related config */
+    __uint32_t mn_sync_mode;    /* enable/ sync shift cclk/ sync shift mclk */
+    __uint32_t mn_sync_shift_cclk;
+    __uint32_t mn_sync_shift_mclk;
+    __uint32_t mn_wb_en;
+    __uint32_t mn_crystal_freq; /* in MHz */
+    __uint32_t mn_speed; /* in MHz */
+    __uint32_t mn_org;
+    __uint32_t mn_depth;
+    __uint32_t mn_ranks_0; /* ranks per slot */
+    __uint32_t mn_ranks_1; /* ranks per slot */
+    __uint32_t mn_rd_latency_0;
+    __uint32_t mn_rd_latency_1;
+    __uint32_t mn_rd_latency_2;
+    __uint32_t mn_rd_latency_3;
+    __uint32_t mn_rd_latency_4;
+    __uint32_t mn_rd_latency_5;
+    __uint32_t mn_rd_latency_6;
+    __uint32_t mn_rd_latency_7;
+    __uint32_t mn_rd_latency_8;
+    __uint32_t mn_dll_val[18];
+    __uint32_t mn_mode_reg; /* See MIU DDR Mode Register */
+    __uint32_t mn_ext_mode_reg; /* See MIU DDR Extended Mode Register */
+    __uint32_t mn_timing_0; /* See MIU Memory Control Timing Rgister */
+    __uint32_t mn_timing_1; /* See MIU Extended Memory Ctrl Timing Register */
+    __uint32_t mn_timing_2; /* See MIU Extended Memory Ctrl Timing2 Register */
+
+	/* SN-related config */
+    __uint32_t sn_sync_mode; /* enable/ sync shift cclk / sync shift mclk */
+    __uint32_t sn_pt_mode; /* pass through mode */
+    __uint32_t sn_ecc_en;
+    __uint32_t sn_wb_en;
+    __uint32_t sn_crystal_freq;
+    __uint32_t sn_speed;
+    __uint32_t sn_org;
+    __uint32_t sn_depth;
+    __uint32_t sn_dll_tap;
+    __uint32_t sn_rd_latency;
+
+    __uint32_t mac_addr_hi_0;
+    __uint32_t mac_addr_hi_1;
+    __uint32_t mac_addr_hi_2;
+    __uint32_t mac_addr_hi_3;
+
+    __uint32_t magic; /* indicates flash has been initialized */
+
+    __uint32_t mn_rdimm;
+    __uint32_t mn_dll_override;
+    __uint32_t coreclock_speed;
+}  unm_board_info_t;
+
+#define	FLASH_NUM_PORTS		4
+
+typedef struct {
+    __uint32_t flash_addr[32];
+} unm_flash_mac_addr_t;
+
+/* flash user area */
+typedef struct {
+    __uint8_t  flash_md5[16];
+    __uint8_t  crbinit_md5[16];
+    __uint8_t  brdcfg_md5[16];
+	/* bootloader */
+    __uint32_t bootld_version;
+    __uint32_t bootld_size;
+    __uint8_t  bootld_md5[16];
+	/* image */
+    __uint32_t image_version;
+    __uint32_t image_size;
+    __uint8_t  image_md5[16];
+	/* primary image status */
+    __uint32_t primary_status;
+    __uint32_t secondary_present;
+
+	/* MAC address , 4 ports */
+    unm_flash_mac_addr_t mac_addr[FLASH_NUM_PORTS];
+
+	/* Any user defined data */
+} unm_old_user_info_t;
+
+#define	FLASH_NUM_MAC_PER_PORT		32
+typedef struct {
+    __uint8_t  flash_md5[16 * 64];
+	// __uint8_t  crbinit_md5[16];
+	// __uint8_t  brdcfg_md5[16];
+	/* bootloader */
+    __uint32_t bootld_version;
+    __uint32_t bootld_size;
+	// __uint8_t  bootld_md5[16];
+	/* image */
+    __uint32_t image_version;
+    __uint32_t image_size;
+	// U8  image_md5[16];
+	/* primary image status */
+    __uint32_t primary_status;
+    __uint32_t secondary_present;
+
+	/* MAC address , 4 ports, 32 address per port */
+    __uint64_t mac_addr[FLASH_NUM_PORTS * FLASH_NUM_MAC_PER_PORT];
+    __uint32_t sub_sys_id;
+    __uint8_t  serial_num[32];
+	__uint32_t bios_version;
+    __uint32_t pxe_enable;  /* bitmask, per port */
+    __uint32_t vlan_tag[FLASH_NUM_PORTS];
+
+	/* Any user defined data */
+} unm_user_info_t;
+
+/* Flash memory map */
+typedef enum {
+    CRBINIT_START   = 0,		/* Crbinit section */
+    BRDCFG_START    = 0x4000,	/* board config */
+    INITCODE_START  = 0x6000,	/* pegtune code */
+    BOOTLD_START    = 0x10000,	/* bootld */
+    BOOTLD1_START   = 0x14000,	/* Start of booloader 1 */
+	IMAGE_START		= 0x43000,	/* compressed image */
+    SECONDARY_START = 0x200000,	/* backup images */
+    PXE_FIRST_STAGE_INTEL = 0x3C0000, /* Intel First Stage info */
+    PXE_FIRST_STAGE_PPC = 0x3C4000, /* PPC First Stage info */
+    PXE_SECOND_STAGE_INTEL = 0x3B0000, /* Intel Second Stage info */
+    PXE_SECOND_STAGE_PPC = 0x3A0000, /* Intel Second Stage info */
+//    LICENSE_TIME_START = 0x3C0000, /* license expiry time info */
+	PXE_START		= 0x3D0000,   /* PXE image area */
+    DEFAULT_DATA_START = 0x3e0000, /* where we place default factory data */
+	/* User defined region for new boards */
+	USER_START		= 0x3E8000,
+    VPD_START		= 0x3E8C00,   /* Vendor private data */
+    LICENSE_START	= 0x3E9000,   /* Firmware License */
+    FIXED_START		= 0x3F0000    /* backup of crbinit */
+} unm_flash_map_t;
+
+#define	USER_START_OLD		PXE_START /* for backward compatibility */
+
+#endif	/* !__UNM_BRDINFO_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_gem.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,1489 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/debug.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#include <sys/strlog.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/vtrace.h>
+#include <sys/dlpi.h>
+#include <sys/strsun.h>
+#include <sys/ethernet.h>
+#include <sys/modctl.h>
+#include <sys/errno.h>
+#include <sys/dditypes.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+#include <sys/pci.h>
+#include <sys/ddi_intr.h>
+
+#include "unm_nic.h"
+#include "unm_nic_hw.h"
+#include "unm_brdcfg.h"
+#include "nic_cmn.h"
+#include "nic_phan_reg.h"
+#include "unm_nic_ioctl.h"
+#include "nx_hw_pci_regs.h"
+
+char ident[] = "Netxen nic driver v" UNM_NIC_VERSIONID;
+char unm_nic_driver_name[] = "ntxn";
+int verbmsg = 0;
+
+static char txbcopythreshold_propname[] = "tx_bcopy_threshold";
+static char rxbcopythreshold_propname[] = "rx_bcopy_threshold";
+static char rxringsize_propname[] = "rx_ring_size";
+static char jumborxringsize_propname[] = "jumbo_rx_ring_size";
+static char txringsize_propname[] = "tx_ring_size";
+static char defaultmtu_propname[] = "default_mtu";
+static char dmesg_propname[] = "verbose_driver";
+
+#define	STRUCT_COPY(a, b)	bcopy(&(b), &(a), sizeof (a))
+
+extern int unm_register_mac(unm_adapter *adapter);
+extern void unm_fini_kstats(unm_adapter* adapter);
+extern void unm_nic_remove(unm_adapter *adapter);
+extern int unm_nic_suspend(unm_adapter *);
+extern uint_t unm_intr(caddr_t, caddr_t);
+
+/* Data access requirements. */
+static struct ddi_device_acc_attr unm_dev_attr = {
+	DDI_DEVICE_ATTR_V0,
+	DDI_STRUCTURE_LE_ACC,
+	DDI_STRICTORDER_ACC
+};
+
+static struct ddi_device_acc_attr unm_buf_attr = {
+	DDI_DEVICE_ATTR_V0,
+	DDI_NEVERSWAP_ACC,
+	DDI_STRICTORDER_ACC
+};
+
+static ddi_dma_attr_t unm_dma_attr_desc = {
+	DMA_ATTR_V0,		/* dma_attr_version */
+	0,			/* dma_attr_addr_lo */
+	0xffffffffull,		/* dma_attr_addr_hi */
+	0x000fffffull,		/* dma_attr_count_max */
+	4096,			/* dma_attr_align */
+	0x000fffffull,		/* dma_attr_burstsizes */
+	4,			/* dma_attr_minxfer */
+	0x003fffffull,		/* dma_attr_maxxfer */
+	0xffffffffull,		/* dma_attr_seg */
+	1,			/* dma_attr_sgllen */
+	1,			/* dma_attr_granular */
+	0			/* dma_attr_flags */
+};
+
+static ddi_dma_attr_t unm_dma_attr_rxbuf = {
+	DMA_ATTR_V0,		/* dma_attr_version */
+	0,			/* dma_attr_addr_lo */
+	0x7ffffffffULL,		/* dma_attr_addr_hi */
+	0xffffull,		/* dma_attr_count_max */
+	4096,			/* dma_attr_align */
+	0xfff8ull,		/* dma_attr_burstsizes */
+	1,			/* dma_attr_minxfer */
+	0xffffffffull,		/* dma_attr_maxxfer */
+	0xffffull,		/* dma_attr_seg */
+	1,			/* dma_attr_sgllen */
+	1,			/* dma_attr_granular */
+	0			/* dma_attr_flags */
+};
+
+static ddi_dma_attr_t unm_dma_attr_cmddesc = {
+	DMA_ATTR_V0,		/* dma_attr_version */
+	0,			/* dma_attr_addr_lo */
+	0x7ffffffffULL,		/* dma_attr_addr_hi */
+	0xffffull,		/* dma_attr_count_max */
+	1,			/* dma_attr_align */
+	0xfff8ull,		/* dma_attr_burstsizes */
+	1,			/* dma_attr_minxfer */
+	0xffff0ull,		/* dma_attr_maxxfer */
+	0xffffull,		/* dma_attr_seg */
+	16,			/* dma_attr_sgllen */
+	1,			/* dma_attr_granular */
+	0			/* dma_attr_flags */
+};
+
+static struct nx_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
+
+static int
+check_hw_init(struct unm_adapter_s *adapter)
+{
+	u32	val;
+	int	ret = 0;
+
+	adapter->unm_nic_hw_read_wx(adapter, UNM_CAM_RAM(0x1fc), &val, 4);
+	if (val == 0x55555555) {
+		/* This is the first boot after power up */
+		adapter->unm_nic_hw_read_wx(adapter, UNM_ROMUSB_GLB_SW_RESET,
+		    &val, 4);
+		if (val != 0x80000f)
+			ret = -1;
+
+		if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+			/* Start P2 boot loader */
+			adapter->unm_nic_pci_write_normalize(adapter,
+			    UNM_CAM_RAM(0x1fc), UNM_BDINFO_MAGIC);
+			adapter->unm_nic_pci_write_normalize(adapter,
+			    UNM_ROMUSB_GLB_PEGTUNE_DONE, 1);
+		}
+	}
+	return (ret);
+}
+
+
+static int
+unm_get_flash_block(unm_adapter *adapter, int base, int size, uint32_t *buf)
+{
+	int i, addr;
+	uint32_t *ptr32;
+
+	addr  = base;
+	ptr32 = buf;
+	for (i = 0; i < size / sizeof (uint32_t); i++) {
+		if (rom_fast_read(adapter, addr, (int *)ptr32) == -1)
+			return (-1);
+		ptr32++;
+		addr += sizeof (uint32_t);
+	}
+	if ((char *)buf + size > (char *)ptr32) {
+		int local;
+
+		if (rom_fast_read(adapter, addr, &local) == -1)
+			return (-1);
+		(void) memcpy(ptr32, &local,
+		    (uintptr_t)((char *)buf + size) - (uintptr_t)(char *)ptr32);
+	}
+
+	return (0);
+}
+
+
+static int
+get_flash_mac_addr(struct unm_adapter_s *adapter, u64 mac[])
+{
+	uint32_t *pmac = (uint32_t *)&mac[0];
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		uint32_t temp, crbaddr;
+		uint16_t *pmac16 = (uint16_t *)pmac;
+
+		// FOR P3, read from CAM RAM
+
+		int pci_func = adapter->ahw.pci_func;
+		pmac16 += (4*pci_func);
+		crbaddr = CRB_MAC_BLOCK_START + (4 * ((pci_func/2) * 3)) +
+		    (4 * (pci_func & 1));
+
+		adapter->unm_nic_hw_read_wx(adapter, crbaddr, &temp, 4);
+		if (pci_func & 1) {
+			*pmac16++ = (temp >> 16);
+			adapter->unm_nic_hw_read_wx(adapter, crbaddr+4,
+			    &temp, 4);
+			*pmac16++ = (temp & 0xffff);
+			*pmac16++ = (temp >> 16);
+			*pmac16 = 0;
+		} else {
+			*pmac16++ = (temp & 0xffff);
+			*pmac16++ = (temp >> 16);
+			adapter->unm_nic_hw_read_wx(adapter, crbaddr+4,
+			    &temp, 4);
+			*pmac16++ = (temp & 0xffff);
+			*pmac16 = 0;
+		}
+		return (0);
+	}
+
+
+	if (unm_get_flash_block(adapter, USER_START +
+	    offsetof(unm_user_info_t, mac_addr), FLASH_NUM_PORTS * sizeof (U64),
+	    pmac) == -1)
+		return (-1);
+
+	if (*mac == ~0ULL) {
+		if (unm_get_flash_block(adapter, USER_START_OLD +
+		    offsetof(unm_old_user_info_t, mac_addr),
+		    FLASH_NUM_PORTS * sizeof (U64), pmac) == -1)
+			return (-1);
+
+		if (*mac == ~0ULL)
+			return (-1);
+	}
+
+	return (0);
+}
+
+static int
+is_flash_supported(unm_adapter *adapter)
+{
+	int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 };
+	int addr, val01, val02, i, j;
+
+	/* if the flash size less than 4Mb, make huge war cry and die */
+	for (j = 1; j < 4; j++) {
+		addr = j * 0x100000;
+		for (i = 0; i < (sizeof (locs) / sizeof (locs[0])); i++) {
+			if (rom_fast_read(adapter, locs[i], &val01) == 0 &&
+			    rom_fast_read(adapter, (addr + locs[i]),
+			    &val02) == 0) {
+				if (val01 == val02)
+					return (-1);
+			} else {
+				return (-1);
+			}
+		}
+	}
+
+	return (0);
+}
+
+static int
+unm_initialize_dummy_dma(unm_adapter *adapter)
+{
+	uint32_t		hi, lo, temp;
+	ddi_dma_cookie_t	cookie;
+
+	if (unm_pci_alloc_consistent(adapter, UNM_HOST_DUMMY_DMA_SIZE,
+	    (caddr_t *)&adapter->dummy_dma.addr, &cookie,
+	    &adapter->dummy_dma.dma_handle,
+	    &adapter->dummy_dma.acc_handle) != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: Unable to alloc dummy dma buf\n",
+		    adapter->name, adapter->instance);
+		return (DDI_ENOMEM);
+	}
+
+	adapter->dummy_dma.phys_addr = cookie.dmac_laddress;
+
+	hi = (adapter->dummy_dma.phys_addr >> 32) & 0xffffffff;
+	lo = adapter->dummy_dma.phys_addr & 0xffffffff;
+
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI,
+	    &hi, 4);
+	adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO,
+	    &lo, 4);
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		temp = DUMMY_BUF_INIT;
+		adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF,
+		    &temp, 4);
+	}
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	return (DDI_SUCCESS);
+}
+
+void
+unm_free_dummy_dma(unm_adapter *adapter)
+{
+	if (adapter->dummy_dma.addr) {
+		unm_pci_free_consistent(&adapter->dummy_dma.dma_handle,
+		    &adapter->dummy_dma.acc_handle);
+		adapter->dummy_dma.addr = NULL;
+	}
+}
+
+static int
+unm_pci_cfg_init(unm_adapter *adapter)
+{
+	hardware_context *hwcontext;
+	ddi_acc_handle_t pci_cfg_hdl;
+	int *reg_options;
+	dev_info_t *dip;
+	uint_t noptions;
+	int ret;
+	uint16_t vendor_id, pci_cmd_word;
+	uint8_t	base_class, sub_class, prog_class;
+	uint32_t pexsizes;
+	struct nx_legacy_intr_set *legacy_intrp;
+
+	hwcontext = &adapter->ahw;
+	pci_cfg_hdl = adapter->pci_cfg_handle;
+	dip = adapter->dip;
+
+	vendor_id = pci_config_get16(pci_cfg_hdl, PCI_CONF_VENID);
+
+	if (vendor_id != 0x4040) {
+		cmn_err(CE_WARN, "%s%d: vendor id %x not 0x4040\n",
+		    adapter->name, adapter->instance, vendor_id);
+		return (DDI_FAILURE);
+	}
+
+	ret = ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
+	    dip, 0, "reg", &reg_options, &noptions);
+	if (ret != DDI_PROP_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: Could not determine reg property\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	hwcontext->pci_func = (reg_options[0] >> 8) & 0x7;
+	ddi_prop_free(reg_options);
+
+	base_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_BASCLASS);
+	sub_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_SUBCLASS);
+	prog_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_PROGCLASS);
+
+	/*
+	 * Need this check so that MEZZ card mgmt interface ntxn0 could fail
+	 * attach & return and proceed to next interfaces ntxn1 and ntxn2
+	 */
+	if ((base_class != 0x02) || (sub_class != 0) || (prog_class != 0)) {
+		cmn_err(CE_WARN, "%s%d: Base/sub/prog class problem %d/%d/%d\n",
+		    adapter->name, adapter->instance, base_class, sub_class,
+		    prog_class);
+		return (DDI_FAILURE);
+	}
+
+	hwcontext->revision_id = pci_config_get8(pci_cfg_hdl, PCI_CONF_REVID);
+
+	/*
+	 * Refuse to work with dubious P3 cards.
+	 */
+	if ((hwcontext->revision_id >= NX_P3_A0) &&
+	    (hwcontext->revision_id < NX_P3_B1)) {
+		cmn_err(CE_WARN, "%s%d: NetXen chip revs between 0x%x-0x%x "
+		    "is unsupported\n", adapter->name, adapter->instance,
+		    NX_P3_A0, NX_P3_B0);
+		return (DDI_FAILURE);
+	}
+
+	/*
+	 * Save error reporting settings; clear [19:16] error status bits.
+	 * Set max read request [14:12] to 0 for 128 bytes. Set max payload
+	 * size[7:5] to 0 for for 128 bytes.
+	 */
+	if (NX_IS_REVISION_P2(hwcontext->revision_id)) {
+		pexsizes = pci_config_get32(pci_cfg_hdl, 0xd8);
+		pexsizes &= 7;
+		pexsizes |= 0xF0000;
+		pci_config_put32(pci_cfg_hdl, 0xd8, pexsizes);
+	}
+
+	pci_cmd_word = pci_config_get16(pci_cfg_hdl, PCI_CONF_COMM);
+	pci_cmd_word |= (PCI_COMM_INTX_DISABLE | PCI_COMM_SERR_ENABLE);
+	pci_config_put16(pci_cfg_hdl, PCI_CONF_COMM, pci_cmd_word);
+
+	if (hwcontext->revision_id >= NX_P3_B0)
+		legacy_intrp = &legacy_intr[hwcontext->pci_func];
+	else
+		legacy_intrp = &legacy_intr[0];
+
+	adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
+	adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
+	adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
+	adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
+
+	return (DDI_SUCCESS);
+}
+
+void
+unm_free_tx_dmahdl(unm_adapter *adapter)
+{
+	int i;
+	unm_dmah_node_t	 *nodep;
+
+	mutex_enter(&adapter->tx_lock);
+	nodep = &adapter->tx_dma_hdls[0];
+
+	for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) {
+		if (nodep->dmahdl != NULL) {
+			ddi_dma_free_handle(&nodep->dmahdl);
+			nodep->dmahdl = NULL;
+		}
+		nodep->next = NULL;
+		nodep++;
+	}
+
+	adapter->dmahdl_pool = NULL;
+	adapter->freehdls = 0;
+	mutex_exit(&adapter->tx_lock);
+}
+
+static int
+unm_alloc_tx_dmahdl(unm_adapter *adapter)
+{
+	int		i;
+	unm_dmah_node_t	*nodep = &adapter->tx_dma_hdls[0];
+
+	mutex_enter(&adapter->tx_lock);
+	for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) {
+		if (ddi_dma_alloc_handle(adapter->dip, &unm_dma_attr_cmddesc,
+		    DDI_DMA_DONTWAIT, NULL, &nodep->dmahdl) != DDI_SUCCESS) {
+			mutex_exit(&adapter->tx_lock);
+			goto alloc_hdl_fail;
+		}
+
+		if (i > 0)
+			nodep->next = nodep - 1;
+		nodep++;
+	}
+
+	adapter->dmahdl_pool = nodep - 1;
+	adapter->freehdls = i;
+	mutex_exit(&adapter->tx_lock);
+
+	return (DDI_SUCCESS);
+
+alloc_hdl_fail:
+	unm_free_tx_dmahdl(adapter);
+	cmn_err(CE_WARN, "%s%d: Failed transmit ring dma handle allocation\n",
+	    adapter->name, adapter->instance);
+	return (DDI_FAILURE);
+}
+
+static void
+unm_free_dma_mem(dma_area_t *dma_p)
+{
+	if (dma_p->dma_hdl != NULL) {
+		if (dma_p->ncookies) {
+			(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
+			dma_p->ncookies = 0;
+		}
+	}
+	if (dma_p->acc_hdl != NULL) {
+		ddi_dma_mem_free(&dma_p->acc_hdl);
+		dma_p->acc_hdl = NULL;
+	}
+	if (dma_p->dma_hdl != NULL) {
+		ddi_dma_free_handle(&dma_p->dma_hdl);
+		dma_p->dma_hdl = NULL;
+	}
+}
+
+static int
+unm_alloc_dma_mem(unm_adapter *adapter, int size, uint_t dma_flag,
+	ddi_dma_attr_t *dma_attr_p, dma_area_t *dma_p)
+{
+	int ret;
+	caddr_t vaddr;
+	size_t actual_size;
+	ddi_dma_cookie_t	cookie;
+
+	ret = ddi_dma_alloc_handle(adapter->dip,
+	    dma_attr_p, DDI_DMA_DONTWAIT,
+	    NULL, &dma_p->dma_hdl);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: Failed ddi_dma_alloc_handle\n",
+		    adapter->name, adapter->instance);
+		goto dma_mem_fail;
+	}
+
+	ret = ddi_dma_mem_alloc(dma_p->dma_hdl,
+	    size, &adapter->gc_attr_desc,
+	    dma_flag & (DDI_DMA_STREAMING | DDI_DMA_CONSISTENT),
+	    DDI_DMA_DONTWAIT, NULL, &vaddr, &actual_size,
+	    &dma_p->acc_hdl);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() failed\n",
+		    adapter->name, adapter->instance);
+		goto dma_mem_fail;
+	}
+
+	if (actual_size < size) {
+		cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() allocated small\n",
+		    adapter->name, adapter->instance);
+		goto dma_mem_fail;
+	}
+
+	ret = ddi_dma_addr_bind_handle(dma_p->dma_hdl,
+	    NULL, vaddr, size, dma_flag, DDI_DMA_DONTWAIT,
+	    NULL, &cookie, &dma_p->ncookies);
+	if (ret != DDI_DMA_MAPPED || dma_p->ncookies != 1) {
+		cmn_err(CE_WARN, "%s%d: ddi_dma_addr_bind_handle() failed, "
+		    "%d, %d\n", adapter->name, adapter->instance, ret,
+		    dma_p->ncookies);
+		goto dma_mem_fail;
+	}
+
+	dma_p->dma_addr = cookie.dmac_laddress;
+	dma_p->vaddr = vaddr;
+	(void) memset(vaddr, 0, size);
+
+	return (DDI_SUCCESS);
+
+dma_mem_fail:
+	unm_free_dma_mem(dma_p);
+	return (DDI_FAILURE);
+}
+
+void
+unm_free_tx_buffers(unm_adapter *adapter)
+{
+	int i;
+	dma_area_t *dma_p;
+	struct unm_cmd_buffer *cmd_buf;
+	unm_dmah_node_t	 *nodep;
+
+	cmd_buf = &adapter->cmd_buf_arr[0];
+
+	for (i = 0; i < adapter->MaxTxDescCount; i++) {
+		dma_p = &cmd_buf->dma_area;
+		unm_free_dma_mem(dma_p);
+		nodep = cmd_buf->head;
+		while (nodep != NULL) {
+			(void) ddi_dma_unbind_handle(nodep->dmahdl);
+			nodep = nodep->next;
+		}
+		if (cmd_buf->msg != NULL)
+			freemsg(cmd_buf->msg);
+		cmd_buf++;
+	}
+	adapter->freecmds = 0;
+}
+
+static int
+unm_alloc_tx_buffers(unm_adapter *adapter)
+{
+	int i, ret, size, allocated = 0;
+	dma_area_t *dma_p;
+	struct unm_cmd_buffer *cmd_buf;
+
+	cmd_buf = &adapter->cmd_buf_arr[0];
+	size = adapter->maxmtu;
+
+	for (i = 0; i < adapter->MaxTxDescCount; i++) {
+		dma_p = &cmd_buf->dma_area;
+		ret = unm_alloc_dma_mem(adapter, size,
+		    DDI_DMA_WRITE | DDI_DMA_STREAMING,
+		    &unm_dma_attr_rxbuf, dma_p);
+		if (ret != DDI_SUCCESS)
+			goto alloc_tx_buffer_fail;
+
+		allocated++;
+		cmd_buf++;
+	}
+	adapter->freecmds = adapter->MaxTxDescCount;
+	return (DDI_SUCCESS);
+
+alloc_tx_buffer_fail:
+
+	cmd_buf = &adapter->cmd_buf_arr[0];
+	for (i = 0; i < allocated; i++) {
+		dma_p = &cmd_buf->dma_area;
+		unm_free_dma_mem(dma_p);
+		cmd_buf++;
+	}
+	cmn_err(CE_WARN, "%s%d: Failed transmit ring memory allocation\n",
+	    adapter->name, adapter->instance);
+	return (DDI_FAILURE);
+}
+
+/*
+ * Called by freemsg() to "free" the resource.
+ */
+static void
+unm_rx_buffer_recycle(char *arg)
+{
+	unm_rx_buffer_t *rx_buffer = (unm_rx_buffer_t *)(uintptr_t)arg;
+	unm_adapter *adapter = rx_buffer->adapter;
+	unm_rcv_desc_ctx_t *rcv_desc = rx_buffer->rcv_desc;
+
+	rx_buffer->mp = desballoc(rx_buffer->dma_info.vaddr,
+	    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
+
+	if (rx_buffer->mp == NULL)
+		adapter->stats.desballocfailed++;
+
+	mutex_enter(rcv_desc->recycle_lock);
+	rx_buffer->next = rcv_desc->recycle_list;
+	rcv_desc->recycle_list = rx_buffer;
+	rcv_desc->rx_buf_recycle++;
+	mutex_exit(rcv_desc->recycle_lock);
+}
+
+void
+unm_destroy_rx_ring(unm_rcv_desc_ctx_t *rcv_desc)
+{
+	uint32_t i, total_buf;
+	unm_rx_buffer_t *buf_pool;
+
+	total_buf = rcv_desc->rx_buf_total;
+	buf_pool = rcv_desc->rx_buf_pool;
+	for (i = 0; i < total_buf; i++) {
+		if (buf_pool->mp != NULL)
+			freemsg(buf_pool->mp);
+		unm_free_dma_mem(&buf_pool->dma_info);
+		buf_pool++;
+	}
+
+	kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf);
+	rcv_desc->rx_buf_pool = NULL;
+	rcv_desc->pool_list = NULL;
+	rcv_desc->recycle_list = NULL;
+	rcv_desc->rx_buf_free = 0;
+
+	mutex_destroy(rcv_desc->pool_lock);
+	mutex_destroy(rcv_desc->recycle_lock);
+}
+
+static int
+unm_create_rx_ring(unm_adapter *adapter, unm_rcv_desc_ctx_t *rcv_desc)
+{
+	int		i, ret, allocate = 0, sreoff;
+	uint32_t	total_buf;
+	dma_area_t	*dma_info;
+	unm_rx_buffer_t	*rx_buffer;
+
+	sreoff = adapter->ahw.cut_through ? 0 : IP_ALIGNMENT_BYTES;
+
+	/* temporarily set the total rx buffers two times of MaxRxDescCount */
+	total_buf = rcv_desc->rx_buf_total = rcv_desc->MaxRxDescCount * 2;
+
+	rcv_desc->rx_buf_pool = kmem_zalloc(sizeof (unm_rx_buffer_t) *
+	    total_buf, KM_SLEEP);
+	rx_buffer = rcv_desc->rx_buf_pool;
+	for (i = 0; i < total_buf; i++) {
+		dma_info = &rx_buffer->dma_info;
+		ret = unm_alloc_dma_mem(adapter, rcv_desc->buf_size,
+		    DDI_DMA_READ | DDI_DMA_STREAMING,
+		    &unm_dma_attr_rxbuf, dma_info);
+		if (ret != DDI_SUCCESS)
+			goto alloc_mem_failed;
+		else {
+			allocate++;
+			dma_info->vaddr = (void *) ((char *)dma_info->vaddr +
+			    sreoff);
+			dma_info->dma_addr += sreoff;
+			rx_buffer->rx_recycle.free_func =
+			    unm_rx_buffer_recycle;
+			rx_buffer->rx_recycle.free_arg = (caddr_t)rx_buffer;
+			rx_buffer->next = NULL;
+			rx_buffer->mp = desballoc(dma_info->vaddr,
+			    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
+			if (rx_buffer->mp == NULL)
+				adapter->stats.desballocfailed++;
+			rx_buffer->rcv_desc = rcv_desc;
+			rx_buffer->adapter = adapter;
+			rx_buffer++;
+		}
+	}
+
+	for (i = 0; i < (total_buf - 1); i++) {
+		rcv_desc->rx_buf_pool[i].next = &rcv_desc->rx_buf_pool[i + 1];
+	}
+
+	rcv_desc->pool_list = rcv_desc->rx_buf_pool;
+	rcv_desc->recycle_list = NULL;
+	rcv_desc->rx_buf_free = total_buf;
+
+	mutex_init(rcv_desc->pool_lock, NULL,
+	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
+	mutex_init(rcv_desc->recycle_lock, NULL,
+	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
+
+	return (DDI_SUCCESS);
+
+alloc_mem_failed:
+	rx_buffer = rcv_desc->rx_buf_pool;
+	for (i = 0; i < allocate; i++, rx_buffer++) {
+		dma_info = &rx_buffer->dma_info;
+		if (rx_buffer->mp != NULL)
+			freemsg(rx_buffer->mp);
+		unm_free_dma_mem(dma_info);
+	}
+
+	kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf);
+	rcv_desc->rx_buf_pool = NULL;
+
+	cmn_err(CE_WARN, "%s%d: Failed receive ring resource allocation\n",
+	    adapter->name, adapter->instance);
+	return (DDI_FAILURE);
+}
+
+static void
+unm_check_options(unm_adapter *adapter)
+{
+	int			i, ring, tx_desc, rx_desc, rx_jdesc;
+	unm_recv_context_t	*recv_ctx;
+	unm_rcv_desc_ctx_t	*rcv_desc;
+	uint8_t			revid = adapter->ahw.revision_id;
+	dev_info_t		*dip = adapter->dip;
+
+	verbmsg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+	    dmesg_propname, 0);
+
+	adapter->tx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY,
+	    dip, DDI_PROP_DONTPASS, txbcopythreshold_propname,
+	    UNM_TX_BCOPY_THRESHOLD);
+	adapter->rx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY,
+	    dip, DDI_PROP_DONTPASS, rxbcopythreshold_propname,
+	    UNM_RX_BCOPY_THRESHOLD);
+
+	tx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+	    txringsize_propname, MAX_CMD_DESCRIPTORS_HOST);
+	if (tx_desc >= 256 && tx_desc <= MAX_CMD_DESCRIPTORS &&
+	    !(tx_desc & (tx_desc - 1))) {
+		adapter->MaxTxDescCount = tx_desc;
+	} else {
+		cmn_err(CE_WARN, "%s%d: TxRingSize defaulting to %d, since "
+		    ".conf value is not 2 power aligned in range 256 - %d\n",
+		    adapter->name, adapter->instance, MAX_CMD_DESCRIPTORS_HOST,
+		    MAX_CMD_DESCRIPTORS);
+		adapter->MaxTxDescCount = MAX_CMD_DESCRIPTORS_HOST;
+	}
+
+	rx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+	    rxringsize_propname, MAX_RCV_DESCRIPTORS);
+	if (rx_desc >= NX_MIN_DRIVER_RDS_SIZE &&
+	    rx_desc <= NX_MAX_SUPPORTED_RDS_SIZE &&
+	    !(rx_desc & (rx_desc - 1))) {
+		adapter->MaxRxDescCount = rx_desc;
+	} else {
+		cmn_err(CE_WARN, "%s%d: RxRingSize defaulting to %d, since "
+		    ".conf value is not 2 power aligned in range %d - %d\n",
+		    adapter->name, adapter->instance, MAX_RCV_DESCRIPTORS,
+		    NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_RDS_SIZE);
+		adapter->MaxRxDescCount = MAX_RCV_DESCRIPTORS;
+	}
+
+	rx_jdesc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+	    jumborxringsize_propname, MAX_JUMBO_RCV_DESCRIPTORS);
+	if (rx_jdesc >= NX_MIN_DRIVER_RDS_SIZE &&
+	    rx_jdesc <= NX_MAX_SUPPORTED_JUMBO_RDS_SIZE &&
+	    !(rx_jdesc & (rx_jdesc - 1))) {
+		adapter->MaxJumboRxDescCount = rx_jdesc;
+	} else {
+		cmn_err(CE_WARN, "%s%d: JumboRingSize defaulting to %d, since "
+		    ".conf value is not 2 power aligned in range %d - %d\n",
+		    adapter->name, adapter->instance, MAX_JUMBO_RCV_DESCRIPTORS,
+		    NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_JUMBO_RDS_SIZE);
+		adapter->MaxJumboRxDescCount = MAX_JUMBO_RCV_DESCRIPTORS;
+	}
+
+	adapter->MaxLroRxDescCount = MAX_LRO_RCV_DESCRIPTORS;
+
+	adapter->mtu = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
+	    DDI_PROP_DONTPASS, defaultmtu_propname, MTU_SIZE);
+
+	if (adapter->mtu < MTU_SIZE) {
+		cmn_err(CE_WARN, "Raising mtu to %d\n", MTU_SIZE);
+		adapter->mtu = MTU_SIZE;
+	}
+	adapter->maxmtu = NX_IS_REVISION_P2(revid) ? P2_MAX_MTU : P3_MAX_MTU;
+	if (adapter->mtu > adapter->maxmtu) {
+		cmn_err(CE_WARN, "Lowering mtu to %d\n", adapter->maxmtu);
+		adapter->mtu = adapter->maxmtu;
+	}
+
+	adapter->maxmtu += NX_MAX_ETHERHDR;
+
+	for (i = 0; i < MAX_RCV_CTX; ++i) {
+		recv_ctx = &adapter->recv_ctx[i];
+
+		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+
+			switch (RCV_DESC_TYPE(ring)) {
+			case RCV_DESC_NORMAL:
+				rcv_desc->MaxRxDescCount =
+				    adapter->MaxRxDescCount;
+				if (adapter->ahw.cut_through) {
+					rcv_desc->dma_size =
+					    NX_CT_DEFAULT_RX_BUF_LEN;
+					rcv_desc->buf_size = rcv_desc->dma_size;
+				} else {
+					rcv_desc->dma_size =
+					    NX_RX_NORMAL_BUF_MAX_LEN;
+					rcv_desc->buf_size =
+					    rcv_desc->dma_size +
+					    IP_ALIGNMENT_BYTES;
+				}
+				break;
+
+			case RCV_DESC_JUMBO:
+				rcv_desc->MaxRxDescCount =
+				    adapter->MaxJumboRxDescCount;
+				if (adapter->ahw.cut_through) {
+					rcv_desc->dma_size =
+					    rcv_desc->buf_size =
+					    NX_P3_RX_JUMBO_BUF_MAX_LEN;
+				} else {
+					if (NX_IS_REVISION_P2(revid))
+						rcv_desc->dma_size =
+						    NX_P2_RX_JUMBO_BUF_MAX_LEN;
+					else
+						rcv_desc->dma_size =
+						    NX_P3_RX_JUMBO_BUF_MAX_LEN;
+					rcv_desc->buf_size =
+					    rcv_desc->dma_size +
+					    IP_ALIGNMENT_BYTES;
+				}
+				break;
+
+			case RCV_RING_LRO:
+				rcv_desc->MaxRxDescCount =
+				    adapter->MaxLroRxDescCount;
+				rcv_desc->buf_size = MAX_RX_LRO_BUFFER_LENGTH;
+				rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
+static void
+vector128M(unm_adapter *aptr)
+{
+	aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_128M;
+	aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_128M;
+	aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_128M;
+	aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_128M;
+	aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_ioctl_128M;
+	aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_ioctl_128M;
+	aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_128M;
+	aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_128M;
+	aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_128M;
+	aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_128M;
+	aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_128M;
+	aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_128M;
+	aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_128M;
+	aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_128M;
+	aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_128M;
+}
+
+static void
+vector2M(unm_adapter *aptr)
+{
+	aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_2M;
+	aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_2M;
+	aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_2M;
+	aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_2M;
+	aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_wx_2M;
+	aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_wx_2M;
+	aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_2M;
+	aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_2M;
+	aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_2M;
+	aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_2M;
+	aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_2M;
+	aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_2M;
+	aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_2M;
+	aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_2M;
+	aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_2M;
+}
+
+static int
+unm_pci_map_setup(unm_adapter *adapter)
+{
+	int ret;
+	caddr_t reg_base, db_base;
+	caddr_t mem_ptr0, mem_ptr1 = NULL, mem_ptr2 = NULL;
+	unsigned long pci_len0;
+	unsigned long first_page_group_start, first_page_group_end;
+
+	off_t regsize, dbsize = UNM_DB_MAPSIZE_BYTES;
+	dev_info_t *dip = adapter->dip;
+
+	adapter->ahw.qdr_sn_window = adapter->ahw.ddr_mn_window = -1;
+
+	/* map register space */
+
+	ret = ddi_dev_regsize(dip, 1, &regsize);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: failed to read reg size for bar0\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	ret = ddi_regs_map_setup(dip, 1, &reg_base, 0,
+	    regsize, &unm_dev_attr, &adapter->regs_handle);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: failed to map registers\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	mem_ptr0 = reg_base;
+
+	if (regsize == UNM_PCI_128MB_SIZE) {
+		pci_len0 = FIRST_PAGE_GROUP_SIZE;
+		mem_ptr1 = mem_ptr0 + SECOND_PAGE_GROUP_START;
+		mem_ptr2 = mem_ptr0 + THIRD_PAGE_GROUP_START;
+		first_page_group_start = FIRST_PAGE_GROUP_START;
+		first_page_group_end   = FIRST_PAGE_GROUP_END;
+		vector128M(adapter);
+	} else if (regsize == UNM_PCI_32MB_SIZE) {
+		pci_len0 = 0;
+		mem_ptr1 = mem_ptr0;
+		mem_ptr2 = mem_ptr0 +
+		    (THIRD_PAGE_GROUP_START - SECOND_PAGE_GROUP_START);
+		first_page_group_start = 0;
+		first_page_group_end   = 0;
+		vector128M(adapter);
+	} else if (regsize == UNM_PCI_2MB_SIZE) {
+		pci_len0 = UNM_PCI_2MB_SIZE;
+		first_page_group_start = 0;
+		first_page_group_end = 0;
+		adapter->ahw.ddr_mn_window = adapter->ahw.qdr_sn_window = 0;
+		adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
+		    (adapter->ahw.pci_func * 0x20);
+		if (adapter->ahw.pci_func < 4)
+			adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW +
+			    (adapter->ahw.pci_func * 0x20);
+		else
+			adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW +
+			    0xA0 + ((adapter->ahw.pci_func - 4) * 0x10);
+		vector2M(adapter);
+	} else {
+		cmn_err(CE_WARN, "%s%d: invalid pci regs map size %ld\n",
+		    adapter->name, adapter->instance, regsize);
+		ddi_regs_map_free(&adapter->regs_handle);
+		return (DDI_FAILURE);
+	}
+
+	adapter->ahw.pci_base0  = (unsigned long)mem_ptr0;
+	adapter->ahw.pci_len0   = pci_len0;
+	adapter->ahw.pci_base1  = (unsigned long)mem_ptr1;
+	adapter->ahw.pci_len1   = SECOND_PAGE_GROUP_SIZE;
+	adapter->ahw.pci_base2  = (unsigned long)mem_ptr2;
+	adapter->ahw.pci_len2   = THIRD_PAGE_GROUP_SIZE;
+	adapter->ahw.crb_base   =
+	    PCI_OFFSET_SECOND_RANGE(adapter, UNM_PCI_CRBSPACE);
+
+	adapter->ahw.first_page_group_start = first_page_group_start;
+	adapter->ahw.first_page_group_end   = first_page_group_end;
+
+	/* map doorbell */
+
+	ret = ddi_regs_map_setup(dip, 2, &db_base, 0,
+	    dbsize, &unm_dev_attr, &adapter->db_handle);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: failed to map doorbell\n",
+		    adapter->name, adapter->instance);
+		ddi_regs_map_free(&adapter->regs_handle);
+		return (DDI_FAILURE);
+	}
+
+	adapter->ahw.db_base   = (unsigned long)db_base;
+	adapter->ahw.db_len    = dbsize;
+
+	return (DDI_SUCCESS);
+}
+
+static int
+unm_initialize_intr(unm_adapter *adapter)
+{
+
+	int		ret;
+	int		type, count, avail, actual;
+
+	ret = ddi_intr_get_supported_types(adapter->dip, &type);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: ddi_intr_get_supported_types() "
+		    "failed\n", adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	type = DDI_INTR_TYPE_MSI;
+	ret = ddi_intr_get_nintrs(adapter->dip, type, &count);
+	if ((ret == DDI_SUCCESS) && (count > 0))
+		goto found_msi;
+
+	type = DDI_INTR_TYPE_FIXED;
+	ret = ddi_intr_get_nintrs(adapter->dip, type, &count);
+	if ((ret != DDI_SUCCESS) || (count == 0)) {
+		cmn_err(CE_WARN,
+		    "ddi_intr_get_nintrs() failure ret=%d\n", ret);
+		return (DDI_FAILURE);
+	}
+
+found_msi:
+	adapter->intr_type = type;
+	adapter->flags &= ~(UNM_NIC_MSI_ENABLED | UNM_NIC_MSIX_ENABLED);
+	if (type == DDI_INTR_TYPE_MSI)
+		adapter->flags |= UNM_NIC_MSI_ENABLED;
+
+	/* Get number of available interrupts */
+	ret = ddi_intr_get_navail(adapter->dip, type, &avail);
+	if ((ret != DDI_SUCCESS) || (avail == 0)) {
+		cmn_err(CE_WARN, "ddi_intr_get_navail() failure, ret=%d\n",
+		    ret);
+		return (DDI_FAILURE);
+	}
+
+	ret = ddi_intr_alloc(adapter->dip, &adapter->intr_handle,
+	    type, 0, 1, &actual, DDI_INTR_ALLOC_NORMAL);
+	if ((ret != DDI_SUCCESS) || (actual == 0)) {
+		cmn_err(CE_WARN, "ddi_intr_alloc() failure: %d\n", ret);
+		return (DDI_FAILURE);
+	}
+
+	ret = ddi_intr_get_pri(adapter->intr_handle, &adapter->intr_pri);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "ddi_intr_get_pri() failure: %d\n", ret);
+	}
+
+	/* Call ddi_intr_add_handler() */
+	ret = ddi_intr_add_handler(adapter->intr_handle, unm_intr,
+	    (caddr_t)adapter, NULL);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: ddi_intr_add_handler() failure\n",
+		    adapter->name, adapter->instance);
+		(void) ddi_intr_free(adapter->intr_handle);
+		return (DDI_FAILURE);
+	}
+
+	/* Add softintr if required */
+
+	return (DDI_SUCCESS);
+
+}
+
+void
+unm_destroy_intr(unm_adapter *adapter)
+{
+	/* disable interrupt */
+	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
+		(void) ddi_intr_block_disable(&adapter->intr_handle, 1);
+	else
+		(void) ddi_intr_disable(adapter->intr_handle);
+
+	(void) ddi_intr_remove_handler(adapter->intr_handle);
+	(void) ddi_intr_free(adapter->intr_handle);
+
+	/* Remove the software intr handler */
+}
+
+static void
+netxen_set_port_mode(unm_adapter *adapter)
+{
+	static int	wol_port_mode = UNM_PORT_MODE_AUTO_NEG_1G;
+	static int	port_mode = UNM_PORT_MODE_AUTO_NEG;
+	int		btype = adapter->ahw.boardcfg.board_type, data = 0;
+
+	if (btype == UNM_BRDTYPE_P3_HMEZ || btype == UNM_BRDTYPE_P3_XG_LOM) {
+		data = port_mode;	/* set to port_mode normally */
+		if ((port_mode != UNM_PORT_MODE_802_3_AP) &&
+		    (port_mode != UNM_PORT_MODE_XG) &&
+		    (port_mode != UNM_PORT_MODE_AUTO_NEG_1G) &&
+		    (port_mode != UNM_PORT_MODE_AUTO_NEG_XG))
+			data = UNM_PORT_MODE_AUTO_NEG;
+
+		adapter->unm_nic_hw_write_wx(adapter, UNM_PORT_MODE_ADDR,
+		    &data, 4);
+
+		if ((wol_port_mode != UNM_PORT_MODE_802_3_AP) &&
+		    (wol_port_mode != UNM_PORT_MODE_XG) &&
+		    (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_1G) &&
+		    (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_XG))
+			wol_port_mode = UNM_PORT_MODE_AUTO_NEG;
+
+		adapter->unm_nic_hw_write_wx(adapter, UNM_WOL_PORT_MODE,
+		    &wol_port_mode, 4);
+	}
+}
+
+static void
+netxen_pcie_strap_init(unm_adapter *adapter)
+{
+	ddi_acc_handle_t	pcihdl = adapter->pci_cfg_handle;
+	u32			chicken, control, c8c9value = 0xF1000;
+
+	adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3),
+	    &chicken, 4);
+
+	chicken &= 0xFCFFFFFF;		/* clear chicken3 25:24 */
+	control = pci_config_get32(pcihdl, 0xD0);
+	if ((control & 0x000F0000) != 0x00020000)	/* is it gen1? */
+		chicken |= 0x01000000;
+	adapter->unm_nic_hw_write_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3),
+	    &chicken, 4);
+	control = pci_config_get32(pcihdl, 0xC8);
+	control = pci_config_get32(pcihdl, 0xC8);
+	pci_config_put32(pcihdl, 0xC8, c8c9value);
+}
+
+static int
+netxen_read_mac_addr(unm_adapter *adapter)
+{
+	u64		mac_addr[FLASH_NUM_PORTS + 1];
+	unsigned char	*p;
+	int		i;
+
+	if (is_flash_supported(adapter) != 0)
+		return (-1);
+
+	if (get_flash_mac_addr(adapter, mac_addr) != 0)
+		return (-1);
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		p = (unsigned char *)&mac_addr[adapter->ahw.pci_func];
+	else
+		p = (unsigned char *)&mac_addr[adapter->portnum];
+
+	for (i = 0; i < 6; i++)
+		adapter->mac_addr[i] = p[5 - i];
+
+	if (unm_nic_macaddr_set(adapter, adapter->mac_addr) != 0)
+		return (-1);
+
+	return (0);
+}
+
+static int
+unmattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
+{
+	unm_adapter			*adapter;
+	unm_recv_context_t		*recv_ctx = NULL;
+	unm_rcv_desc_ctx_t		*rcv_desc = NULL;
+	int				i, first_driver = 0;
+	int				ret, ring, temp;
+
+	switch (cmd) {
+	case DDI_ATTACH:
+		break;
+	case DDI_RESUME:
+	case DDI_PM_RESUME:
+	default:
+		return (DDI_FAILURE);
+	}
+
+	adapter = kmem_zalloc(sizeof (unm_adapter), KM_SLEEP);
+	adapter->dip = dip;
+	ddi_set_driver_private(dip, adapter);
+	adapter->instance = ddi_get_instance(dip);
+
+	adapter->name = ddi_driver_name(dip);
+
+	ret = pci_config_setup(dip, &adapter->pci_cfg_handle);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: pci_config_setup failed\n",
+		    adapter->name, adapter->instance);
+		goto attach_setup_err;
+	}
+
+	ret = unm_pci_cfg_init(adapter);
+	if (ret != DDI_SUCCESS)
+		goto attach_err;
+
+	ret = unm_pci_map_setup(adapter);
+	if (ret != DDI_SUCCESS)
+		goto attach_err;
+
+	if (unm_initialize_intr(adapter) != DDI_SUCCESS)
+		goto attach_unmap_regs;
+
+	rw_init(&adapter->adapter_lock, NULL,
+	    RW_DRIVER, DDI_INTR_PRI(adapter->intr_pri));
+	mutex_init(&adapter->tx_lock, NULL,
+	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
+	mutex_init(&adapter->lock, NULL,
+	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
+
+	adapter->portnum = (int8_t)adapter->ahw.pci_func;
+
+	/*
+	 * Set the CRB window to invalid. If any register in window 0 is
+	 * accessed it should set window to 0 and then reset it to 1.
+	 */
+	adapter->curr_window = 255;
+
+	adapter->fw_major = adapter->unm_nic_pci_read_normalize(adapter,
+	    UNM_FW_VERSION_MAJOR);
+
+	if (adapter->fw_major < 4)
+		adapter->max_rds_rings = 3;
+	else
+		adapter->max_rds_rings = 2;
+
+	STRUCT_COPY(adapter->gc_dma_attr_desc, unm_dma_attr_desc);
+	STRUCT_COPY(adapter->gc_attr_desc, unm_buf_attr);
+
+	ret = unm_nic_get_board_info(adapter);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: error reading board config\n",
+		    adapter->name, adapter->instance);
+		goto attach_destroy_intr;
+	}
+
+	/* Mezz cards have PCI function 0, 2, 3 enabled */
+	switch (adapter->ahw.boardcfg.board_type) {
+	case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
+	case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
+		if (adapter->ahw.pci_func >= 2) {
+			adapter->portnum = adapter->ahw.pci_func - 2;
+		}
+	default:
+		break;
+	}
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		temp = UNM_CRB_READ_VAL_ADAPTER(UNM_MIU_MN_CONTROL, adapter);
+		adapter->ahw.cut_through = NX_IS_SYSTEM_CUT_THROUGH(temp);
+		if (adapter->ahw.pci_func == 0)
+			first_driver = 1;
+	} else {
+		if (adapter->portnum == 0)
+			first_driver = 1;
+	}
+
+	unm_check_options(adapter);
+
+	if (first_driver) {
+		int first_boot = adapter->unm_nic_pci_read_normalize(adapter,
+		    UNM_CAM_RAM(0x1fc));
+
+		if (check_hw_init(adapter) != 0) {
+			cmn_err(CE_WARN, "%s%d: Error in HW init sequence\n",
+			    adapter->name, adapter->instance);
+			goto attach_destroy_intr;
+		}
+
+		if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+			netxen_set_port_mode(adapter);
+
+		if (first_boot != 0x55555555) {
+			temp = 0;
+			adapter->unm_nic_hw_write_wx(adapter, CRB_CMDPEG_STATE,
+			    &temp, 4);
+			if (pinit_from_rom(adapter, 0) != 0)
+				goto attach_destroy_intr;
+
+			drv_usecwait(500);
+
+			ret = load_from_flash(adapter);
+			if (ret != DDI_SUCCESS)
+				goto attach_destroy_intr;
+		}
+
+		if (ret = unm_initialize_dummy_dma(adapter))
+			goto attach_destroy_intr;
+
+		/*
+		 * Tell the hardware our version number.
+		 */
+		i = (_UNM_NIC_MAJOR << 16) |
+		    ((_UNM_NIC_MINOR << 8)) | (_UNM_NIC_SUBVERSION);
+		adapter->unm_nic_hw_write_wx(adapter, CRB_DRIVER_VERSION,
+		    &i, 4);
+
+		/* Unlock the HW, prompting the boot sequence */
+		if ((first_boot == 0x55555555) &&
+		    (NX_IS_REVISION_P2(adapter->ahw.revision_id)))
+			adapter->unm_nic_pci_write_normalize(adapter,
+			    UNM_ROMUSB_GLB_PEGTUNE_DONE, 1);
+
+		/* Handshake with the card before we register the devices. */
+		if (phantom_init(adapter, 0) != DDI_SUCCESS)
+			goto attach_destroy_intr;
+	}
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		netxen_pcie_strap_init(adapter);
+
+	/*
+	 * See if the firmware gave us a virtual-physical port mapping.
+	 */
+	adapter->physical_port = adapter->portnum;
+	i = adapter->unm_nic_pci_read_normalize(adapter,
+	    CRB_V2P(adapter->portnum));
+	if (i != 0x55555555)
+		adapter->physical_port = (uint16_t)i;
+
+	adapter->cmd_buf_arr = (struct unm_cmd_buffer *)kmem_zalloc(
+	    sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount,
+	    KM_SLEEP);
+
+	for (i = 0; i < MAX_RCV_CTX; ++i) {
+		recv_ctx = &adapter->recv_ctx[i];
+
+		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			ret = unm_create_rx_ring(adapter, rcv_desc);
+			if (ret != DDI_SUCCESS)
+				goto attach_free_cmdbufs;
+		}
+	}
+
+	ret = unm_alloc_tx_dmahdl(adapter);
+	if (ret != DDI_SUCCESS)
+		goto attach_free_cmdbufs;
+
+	ret = unm_alloc_tx_buffers(adapter);
+	if (ret != DDI_SUCCESS)
+		goto attach_free_tx_dmahdl;
+
+	adapter->ahw.linkup = 0;
+
+	if (receive_peg_ready(adapter)) {
+		ret = -EIO;
+		goto attach_free_tx_buffers;
+	}
+
+	if (netxen_read_mac_addr(adapter))
+		cmn_err(CE_WARN, "%s%d: Failed to read MAC addr\n",
+		    adapter->name, adapter->instance);
+
+	unm_nic_flash_print(adapter);
+
+	if (verbmsg != 0) {
+		switch (adapter->ahw.board_type) {
+		case UNM_NIC_GBE:
+			cmn_err(CE_NOTE, "%s: QUAD GbE port %d initialized\n",
+			    unm_nic_driver_name, adapter->portnum);
+			break;
+
+		case UNM_NIC_XGBE:
+			cmn_err(CE_NOTE, "%s: XGbE port %d initialized\n",
+			    unm_nic_driver_name, adapter->portnum);
+			break;
+		}
+	}
+
+	ret = unm_register_mac(adapter);
+	if (ret != DDI_SUCCESS) {
+		cmn_err(CE_NOTE, "%s%d: Mac registration error\n",
+		    adapter->name, adapter->instance);
+		goto attach_free_tx_buffers;
+	}
+
+	return (DDI_SUCCESS);
+
+attach_free_tx_buffers:
+	unm_free_tx_buffers(adapter);
+attach_free_tx_dmahdl:
+	unm_free_tx_dmahdl(adapter);
+attach_free_cmdbufs:
+	kmem_free(adapter->cmd_buf_arr, sizeof (struct unm_cmd_buffer) *
+	    adapter->MaxTxDescCount);
+	for (i = 0; i < MAX_RCV_CTX; ++i) {
+		recv_ctx = &adapter->recv_ctx[i];
+
+		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			if (rcv_desc->rx_buf_pool != NULL)
+				unm_destroy_rx_ring(rcv_desc);
+		}
+	}
+
+	if (adapter->portnum == 0)
+		unm_free_dummy_dma(adapter);
+attach_destroy_intr:
+	unm_destroy_intr(adapter);
+attach_unmap_regs:
+	ddi_regs_map_free(&(adapter->regs_handle));
+	ddi_regs_map_free(&(adapter->db_handle));
+attach_err:
+	pci_config_teardown(&adapter->pci_cfg_handle);
+attach_setup_err:
+	kmem_free(adapter, sizeof (unm_adapter));
+	return (ret);
+}
+
+static int
+unmdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
+{
+	unm_adapter  *adapter = (unm_adapter *)ddi_get_driver_private(dip);
+
+	if (adapter == NULL)
+	return (DDI_FAILURE);
+
+	switch (cmd) {
+	case DDI_DETACH:
+
+		unm_fini_kstats(adapter);
+		adapter->kstats[0] = NULL;
+
+		if (adapter->pci_cfg_handle != NULL)
+		pci_config_teardown(&adapter->pci_cfg_handle);
+
+		unm_nd_cleanup(adapter);
+		unm_nic_remove(adapter);
+		return (DDI_SUCCESS);
+
+	case DDI_SUSPEND:
+		return (unm_nic_suspend(adapter));
+
+	default:
+		break;
+	}
+
+	return (DDI_FAILURE);
+}
+
+#ifdef SOLARIS11
+DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach,
+	nodev, NULL, D_MP, NULL, NULL);
+#else
+DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach,
+	nodev, NULL, D_MP, NULL);
+#endif
+
+static struct modldrv modldrv = {
+	&mod_driverops,	/* Type of module.  This one is a driver */
+	ident,
+	&unm_ops,	/* driver ops */
+};
+
+static struct modlinkage modlinkage = {
+	MODREV_1,
+	(&modldrv),
+	NULL
+};
+
+
+int
+_init(void)
+{
+	int ret;
+
+	unm_ops.devo_cb_ops->cb_str = NULL;
+	mac_init_ops(&unm_ops, "ntxn");
+
+	ret = mod_install(&modlinkage);
+	if (ret != DDI_SUCCESS) {
+		mac_fini_ops(&unm_ops);
+		cmn_err(CE_WARN, "ntxn: mod_install failed\n");
+	}
+
+	return (ret);
+}
+
+
+int
+_fini(void)
+{
+	int ret;
+
+	ret = mod_remove(&modlinkage);
+	if (ret == DDI_SUCCESS)
+		mac_fini_ops(&unm_ops);
+	return (ret);
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+	return (mod_info(&modlinkage, modinfop));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_inc.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,1777 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef __UNM_INC_H
+#define	__UNM_INC_H
+
+#include "nx_errorcode.h"
+
+#define	PREALIGN(x)
+#define	POSTALIGN(x)
+
+typedef char					__int8_t;
+typedef short					__int16_t;
+typedef int						__int32_t;
+typedef long long				__int64_t;
+typedef unsigned char			__uint8_t;
+typedef unsigned short			__uint16_t;
+typedef unsigned int			__uint32_t;
+typedef unsigned long long		__uint64_t;
+typedef __uint64_t				jiffies_t;
+
+typedef uint8_t			u8;
+typedef uint8_t			U8;
+typedef uint16_t		U16;
+typedef uint32_t		u32;
+typedef uint32_t		U32;
+typedef unsigned long long	u64;
+typedef unsigned long long	U64;
+
+#define	UNUSED __attribute__((unused))
+#define	NOINLINE __attribute__((noinline))
+
+#include "nx_hw_pci_regs.h"
+
+#define	UNM_CONF_X86		3
+
+#define	bzero(A, B)			memset((A), 0, (B))
+
+/*
+ * MAX_RCV_CTX : The number of receive contexts that are available on
+ * the phantom.
+ */
+#define	MAX_RCV_CTX			1
+
+/* ------------------------------------------------------------------------ */
+/*  CRB Hub and Agent addressing */
+/* ------------------------------------------------------------------------ */
+/*
+ *  WARNING:  pex_tgt_adr.v assumes if MSB of hub adr is set then it is an
+ *  ILLEGAL hub!!!!!
+ */
+#define	UNM_HW_H0_CH_HUB_ADR    0x05
+#define	UNM_HW_H1_CH_HUB_ADR    0x0E
+#define	UNM_HW_H2_CH_HUB_ADR    0x03
+#define	UNM_HW_H3_CH_HUB_ADR    0x01
+#define	UNM_HW_H4_CH_HUB_ADR    0x06
+#define	UNM_HW_H5_CH_HUB_ADR    0x07
+#define	UNM_HW_H6_CH_HUB_ADR    0x08
+/*
+ * WARNING:  pex_tgt_adr.v assumes if MSB of hub adr is set then it is an
+ * ILLEGAL hub!!!!!
+ */
+
+/*  Hub 0 */
+#define	UNM_HW_MN_CRB_AGT_ADR   0x15
+#define	UNM_HW_MS_CRB_AGT_ADR   0x25
+
+/*  Hub 1 */
+#define	UNM_HW_PS_CRB_AGT_ADR		0x73
+#define	UNM_HW_SS_CRB_AGT_ADR		0x20
+#define	UNM_HW_RPMX3_CRB_AGT_ADR	0x0b
+#define	UNM_HW_QMS_CRB_AGT_ADR		0x00
+#define	UNM_HW_SQGS0_CRB_AGT_ADR	0x01
+#define	UNM_HW_SQGS1_CRB_AGT_ADR	0x02
+#define	UNM_HW_SQGS2_CRB_AGT_ADR	0x03
+#define	UNM_HW_SQGS3_CRB_AGT_ADR	0x04
+#define	UNM_HW_C2C0_CRB_AGT_ADR		0x58
+#define	UNM_HW_C2C1_CRB_AGT_ADR		0x59
+#define	UNM_HW_C2C2_CRB_AGT_ADR		0x5a
+#define	UNM_HW_RPMX2_CRB_AGT_ADR	0x0a
+#define	UNM_HW_RPMX4_CRB_AGT_ADR	0x0c
+#define	UNM_HW_RPMX7_CRB_AGT_ADR	0x0f
+#define	UNM_HW_RPMX9_CRB_AGT_ADR	0x12
+#define	UNM_HW_SMB_CRB_AGT_ADR		0x18
+
+/*  Hub 2 */
+#define	UNM_HW_NIU_CRB_AGT_ADR		0x31
+#define	UNM_HW_I2C0_CRB_AGT_ADR		0x19
+#define	UNM_HW_I2C1_CRB_AGT_ADR		0x29
+
+#define	UNM_HW_SN_CRB_AGT_ADR		0x10
+#define	UNM_HW_I2Q_CRB_AGT_ADR		0x20
+#define	UNM_HW_LPC_CRB_AGT_ADR		0x22
+#define	UNM_HW_ROMUSB_CRB_AGT_ADR	0x21
+#define	UNM_HW_QM_CRB_AGT_ADR		0x66
+#define	UNM_HW_SQG0_CRB_AGT_ADR		0x60
+#define	UNM_HW_SQG1_CRB_AGT_ADR		0x61
+#define	UNM_HW_SQG2_CRB_AGT_ADR		0x62
+#define	UNM_HW_SQG3_CRB_AGT_ADR		0x63
+#define	UNM_HW_RPMX1_CRB_AGT_ADR	0x09
+#define	UNM_HW_RPMX5_CRB_AGT_ADR	0x0d
+#define	UNM_HW_RPMX6_CRB_AGT_ADR	0x0e
+#define	UNM_HW_RPMX8_CRB_AGT_ADR	0x11
+
+/*  Hub 3 */
+#define	UNM_HW_PH_CRB_AGT_ADR		0x1A
+#define	UNM_HW_SRE_CRB_AGT_ADR		0x50
+#define	UNM_HW_EG_CRB_AGT_ADR		0x51
+#define	UNM_HW_RPMX0_CRB_AGT_ADR	0x08
+
+/*  Hub 4 */
+#define	UNM_HW_PEGN0_CRB_AGT_ADR		0x40
+#define	UNM_HW_PEGN1_CRB_AGT_ADR		0x41
+#define	UNM_HW_PEGN2_CRB_AGT_ADR		0x42
+#define	UNM_HW_PEGN3_CRB_AGT_ADR		0x43
+#define	UNM_HW_PEGNI_CRB_AGT_ADR		0x44
+#define	UNM_HW_PEGND_CRB_AGT_ADR		0x45
+#define	UNM_HW_PEGNC_CRB_AGT_ADR		0x46
+#define	UNM_HW_PEGR0_CRB_AGT_ADR		0x47
+#define	UNM_HW_PEGR1_CRB_AGT_ADR		0x48
+#define	UNM_HW_PEGR2_CRB_AGT_ADR		0x49
+#define	UNM_HW_PEGR3_CRB_AGT_ADR		0x4a
+#define	UNM_HW_PEGN4_CRB_AGT_ADR		0x4b
+
+/*  Hub 5 */
+#define	UNM_HW_PEGS0_CRB_AGT_ADR		0x40
+#define	UNM_HW_PEGS1_CRB_AGT_ADR		0x41
+#define	UNM_HW_PEGS2_CRB_AGT_ADR		0x42
+#define	UNM_HW_PEGS3_CRB_AGT_ADR		0x43
+#define	UNM_HW_PEGSI_CRB_AGT_ADR		0x44
+#define	UNM_HW_PEGSD_CRB_AGT_ADR		0x45
+#define	UNM_HW_PEGSC_CRB_AGT_ADR		0x46
+
+/*  Hub 6 */
+#define	UNM_HW_CAS0_CRB_AGT_ADR 0x46
+#define	UNM_HW_CAS1_CRB_AGT_ADR 0x47
+#define	UNM_HW_CAS2_CRB_AGT_ADR 0x48
+#define	UNM_HW_CAS3_CRB_AGT_ADR 0x49
+#define	UNM_HW_NCM_CRB_AGT_ADR  0x16
+#define	UNM_HW_TMR_CRB_AGT_ADR  0x17
+#define	UNM_HW_XDMA_CRB_AGT_ADR 0x05
+#define	UNM_HW_OCM0_CRB_AGT_ADR 0x06
+#define	UNM_HW_OCM1_CRB_AGT_ADR 0x07
+
+/*  This field defines PCI/X adr [25:20] of agents on the CRB */
+/*  */
+#define	UNM_HW_PX_MAP_CRB_PH    0
+#define	UNM_HW_PX_MAP_CRB_PS    1
+#define	UNM_HW_PX_MAP_CRB_MN    2
+#define	UNM_HW_PX_MAP_CRB_MS    3
+#define	UNM_HW_PX_MAP_CRB_SRE   5
+#define	UNM_HW_PX_MAP_CRB_NIU   6
+#define	UNM_HW_PX_MAP_CRB_QMN   7
+#define	UNM_HW_PX_MAP_CRB_SQN0  8
+#define	UNM_HW_PX_MAP_CRB_SQN1  9
+#define	UNM_HW_PX_MAP_CRB_SQN2  10
+#define	UNM_HW_PX_MAP_CRB_SQN3  11
+#define	UNM_HW_PX_MAP_CRB_QMS   12
+#define	UNM_HW_PX_MAP_CRB_SQS0  13
+#define	UNM_HW_PX_MAP_CRB_SQS1  14
+#define	UNM_HW_PX_MAP_CRB_SQS2  15
+#define	UNM_HW_PX_MAP_CRB_SQS3  16
+#define	UNM_HW_PX_MAP_CRB_PGN0  17
+#define	UNM_HW_PX_MAP_CRB_PGN1  18
+#define	UNM_HW_PX_MAP_CRB_PGN2  19
+#define	UNM_HW_PX_MAP_CRB_PGN3  20
+#define	UNM_HW_PX_MAP_CRB_PGND  21
+#define	UNM_HW_PX_MAP_CRB_PGNI  22
+#define	UNM_HW_PX_MAP_CRB_PGS0  23
+#define	UNM_HW_PX_MAP_CRB_PGS1  24
+#define	UNM_HW_PX_MAP_CRB_PGS2  25
+#define	UNM_HW_PX_MAP_CRB_PGS3  26
+#define	UNM_HW_PX_MAP_CRB_PGSD  27
+#define	UNM_HW_PX_MAP_CRB_PGSI  28
+#define	UNM_HW_PX_MAP_CRB_SN    29
+#define	UNM_HW_PX_MAP_CRB_EG	31
+#define	UNM_HW_PX_MAP_CRB_PH2   32
+#define	UNM_HW_PX_MAP_CRB_PS2   33
+#define	UNM_HW_PX_MAP_CRB_CAM   34
+#define	UNM_HW_PX_MAP_CRB_CAS0  35
+#define	UNM_HW_PX_MAP_CRB_CAS1  36
+#define	UNM_HW_PX_MAP_CRB_CAS2  37
+#define	UNM_HW_PX_MAP_CRB_C2C0  38
+#define	UNM_HW_PX_MAP_CRB_C2C1  39
+#define	UNM_HW_PX_MAP_CRB_TIMR  40
+/* N/A: Not use in either Phantom1 or Phantom2 => use for TIMR */
+/* #define	PX_MAP_CRB_C2C2		40 */
+/* #define	PX_MAP_CRB_SS		41 */
+#define	UNM_HW_PX_MAP_CRB_RPMX1 42
+#define	UNM_HW_PX_MAP_CRB_RPMX2 43
+#define	UNM_HW_PX_MAP_CRB_RPMX3 44
+#define	UNM_HW_PX_MAP_CRB_RPMX4 45
+#define	UNM_HW_PX_MAP_CRB_RPMX5 46
+#define	UNM_HW_PX_MAP_CRB_RPMX6 47
+#define	UNM_HW_PX_MAP_CRB_RPMX7 48
+#define	UNM_HW_PX_MAP_CRB_XDMA  49
+#define	UNM_HW_PX_MAP_CRB_I2Q   50
+#define	UNM_HW_PX_MAP_CRB_ROMUSB	51
+#define	UNM_HW_PX_MAP_CRB_CAS3  52
+#define	UNM_HW_PX_MAP_CRB_RPMX0 53
+#define	UNM_HW_PX_MAP_CRB_RPMX8 54
+#define	UNM_HW_PX_MAP_CRB_RPMX9 55
+#define	UNM_HW_PX_MAP_CRB_OCM0  56
+#define	UNM_HW_PX_MAP_CRB_OCM1  57
+#define	UNM_HW_PX_MAP_CRB_SMB   58
+#define	UNM_HW_PX_MAP_CRB_I2C0  59
+#define	UNM_HW_PX_MAP_CRB_I2C1  60
+#define	UNM_HW_PX_MAP_CRB_LPC   61
+#define	UNM_HW_PX_MAP_CRB_PGNC  62
+#define	UNM_HW_PX_MAP_CRB_PGR0  63
+#define	UNM_HW_PX_MAP_CRB_PGR1  4
+#define	UNM_HW_PX_MAP_CRB_PGR2  30
+#define	UNM_HW_PX_MAP_CRB_PGR3  41
+
+/*  This field defines CRB adr [31:20] of the agents */
+/*  */
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_MN	((UNM_HW_H0_CH_HUB_ADR << 7)	\
+		| UNM_HW_MN_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PH	((UNM_HW_H0_CH_HUB_ADR << 7)	\
+		| UNM_HW_PH_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_MS	((UNM_HW_H0_CH_HUB_ADR << 7)	\
+		| UNM_HW_MS_CRB_AGT_ADR)
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_PS	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_PS_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SS	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_SS_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX3	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX3_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_QMS	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_QMS_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQS0	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQGS0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQS1	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQGS1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQS2	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQGS2_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQS3	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQGS3_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_C2C0	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_C2C0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_C2C1	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_C2C1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX2	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX2_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX4	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX4_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX7	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX7_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX9	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX9_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SMB	((UNM_HW_H1_CH_HUB_ADR << 7)	\
+		| UNM_HW_SMB_CRB_AGT_ADR)
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_NIU	((UNM_HW_H2_CH_HUB_ADR << 7)	\
+		| UNM_HW_NIU_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_I2C0	((UNM_HW_H2_CH_HUB_ADR << 7)	\
+		| UNM_HW_I2C0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_I2C1	((UNM_HW_H2_CH_HUB_ADR << 7)	\
+		| UNM_HW_I2C1_CRB_AGT_ADR)
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_SRE	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_SRE_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_EG	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_EG_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX0	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_QMN	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_QM_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQN0	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQG0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQN1	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQG1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQN2	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQG2_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SQN3	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_SQG3_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX1	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX5	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX5_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX6	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX6_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_RPMX8	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_RPMX8_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_CAS0	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_CAS0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_CAS1	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_CAS1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_CAS2	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_CAS2_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_CAS3	((UNM_HW_H3_CH_HUB_ADR << 7)	\
+		| UNM_HW_CAS3_CRB_AGT_ADR)
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGNI	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGNI_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGND	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGND_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGN0	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGN0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGN1	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGN1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGN2	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGN2_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGN3	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGN3_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGN4	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGN4_CRB_AGT_ADR)
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGNC	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGNC_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGR0	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGR0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGR1	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGR1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGR2	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+	| UNM_HW_PEGR2_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGR3	((UNM_HW_H4_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGR3_CRB_AGT_ADR)
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGSI	((UNM_HW_H5_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGSI_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGSD	((UNM_HW_H5_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGSD_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGS0	((UNM_HW_H5_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGS0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGS1	((UNM_HW_H5_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGS1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGS2	((UNM_HW_H5_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGS2_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGS3	((UNM_HW_H5_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGS3_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_PGSC	((UNM_HW_H5_CH_HUB_ADR << 7)	\
+		| UNM_HW_PEGSC_CRB_AGT_ADR)
+
+#define	UNM_HW_CRB_HUB_AGT_ADR_CAM	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_NCM_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_TIMR	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_TMR_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_XDMA	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_XDMA_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_SN	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+	| UNM_HW_SN_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_I2Q	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_I2Q_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_ROMUSB_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_OCM0	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_OCM0_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_OCM1	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_OCM1_CRB_AGT_ADR)
+#define	UNM_HW_CRB_HUB_AGT_ADR_LPC	((UNM_HW_H6_CH_HUB_ADR << 7)	\
+		| UNM_HW_LPC_CRB_AGT_ADR)
+
+/*
+ * ROM USB CRB space is divided into 4 regions depending on decode of
+ * address bits [19:16]
+ */
+#define	ROMUSB_GLB			(UNM_CRB_ROMUSB + 0x00000)
+#define	ROMUSB_ROM			(UNM_CRB_ROMUSB + 0x10000)
+#define	ROMUSB_USB			(UNM_CRB_ROMUSB + 0x20000)
+#define	ROMUSB_DIRECT_ROM	(UNM_CRB_ROMUSB + 0x30000)
+#define	ROMUSB_TAP			(UNM_CRB_ROMUSB + 0x40000)
+
+/*  ROMUSB  GLB register definitions */
+#define	UNM_ROMUSB_GLB_CONTROL		(ROMUSB_GLB + 0x0000)
+#define	UNM_ROMUSB_GLB_STATUS		(ROMUSB_GLB + 0x0004)
+#define	UNM_ROMUSB_GLB_SW_RESET		(ROMUSB_GLB + 0x0008)
+#define	UNM_ROMUSB_GLB_PAD_GPIO_I	(ROMUSB_GLB + 0x000c)
+#define	UNM_ROMUSB_GLB_RNG_PLL_CTL	(ROMUSB_GLB + 0x0010)
+#define	UNM_ROMUSB_GLB_TEST_MUX_O	(ROMUSB_GLB + 0x0014)
+#define	UNM_ROMUSB_GLB_PLL0_CTRL	(ROMUSB_GLB + 0x0018)
+#define	UNM_ROMUSB_GLB_PLL1_CTRL	(ROMUSB_GLB + 0x001c)
+#define	UNM_ROMUSB_GLB_PLL2_CTRL	(ROMUSB_GLB + 0x0020)
+#define	UNM_ROMUSB_GLB_PLL3_CTRL	(ROMUSB_GLB + 0x0024)
+#define	UNM_ROMUSB_GLB_PLL_LOCK		(ROMUSB_GLB + 0x0028)
+#define	UNM_ROMUSB_GLB_EXTERN_INT	(ROMUSB_GLB + 0x002c)
+#define	UNM_ROMUSB_GLB_PH_RST		(ROMUSB_GLB + 0x0030)
+#define	UNM_ROMUSB_GLB_PS_RST		(ROMUSB_GLB + 0x0034)
+#define	UNM_ROMUSB_GLB_CAS_RST		(ROMUSB_GLB + 0x0038)
+#define	UNM_ROMUSB_GLB_MIU_RST		(ROMUSB_GLB + 0x003c)
+#define	UNM_ROMUSB_GLB_CRB_RST		(ROMUSB_GLB + 0x0040)
+#define	UNM_ROMUSB_GLB_TEST_MUX_SEL	(ROMUSB_GLB + 0x0044)
+#define	UNM_ROMUSB_GLB_MN_COM_A2T	(ROMUSB_GLB + 0x0050)
+#define	UNM_ROMUSB_GLB_REV_ID		(ROMUSB_GLB + 0x0054)
+#define	UNM_ROMUSB_GLB_PEGTUNE_DONE	(ROMUSB_GLB + 0x005c)
+#define	UNM_ROMUSB_GLB_VENDOR_DEV_ID	(ROMUSB_GLB + 0x0058)
+#define	UNM_ROMUSB_GLB_CHIP_CLK_CTRL	(ROMUSB_GLB + 0x00a8)
+
+#define	UNM_ROMUSB_GPIO(n) ((n) <= 15 ? (ROMUSB_GLB + 0x60 + (4 * (n))): \
+				((n) <= 18)?(ROMUSB_GLB + 0x70 + (4 * (n))): \
+				(ROMUSB_GLB + 0x70 + (4 * (19))))
+
+#define	UNM_ROMUSB_ROM_CONTROL			(ROMUSB_ROM + 0x0000)
+#define	UNM_ROMUSB_ROM_INSTR_OPCODE		(ROMUSB_ROM + 0x0004)
+#define	UNM_ROMUSB_ROM_ADDRESS			(ROMUSB_ROM + 0x0008)
+#define	UNM_ROMUSB_ROM_WDATA			(ROMUSB_ROM + 0x000c)
+#define	UNM_ROMUSB_ROM_ABYTE_CNT		(ROMUSB_ROM + 0x0010)
+#define	UNM_ROMUSB_ROM_DUMMY_BYTE_CNT	(ROMUSB_ROM + 0x0014)
+#define	UNM_ROMUSB_ROM_RDATA			(ROMUSB_ROM + 0x0018)
+#define	UNM_ROMUSB_ROM_AGT_TAG			(ROMUSB_ROM + 0x001c)
+#define	UNM_ROMUSB_ROM_TIME_PARM		(ROMUSB_ROM + 0x0020)
+#define	UNM_ROMUSB_ROM_CLK_DIV			(ROMUSB_ROM + 0x0024)
+#define	UNM_ROMUSB_ROM_MISS_INSTR		(ROMUSB_ROM + 0x0028)
+
+/* Lock IDs for ROM lock */
+#define	ROM_LOCK_DRIVER					0x0d417340
+
+/* Lock IDs for PHY lock */
+#define	PHY_LOCK_DRIVER					0x44524956
+
+#define	UNM_PCI_CRB_WINDOWSIZE    0x00100000    /* all are 1MB windows */
+#define	UNM_PCI_CRB_WINDOW(A)    (UNM_PCI_CRBSPACE + (A)*UNM_PCI_CRB_WINDOWSIZE)
+#define	UNM_CRB_C2C_0		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_C2C0)
+#define	UNM_CRB_C2C_1		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_C2C1)
+#define	UNM_CRB_C2C_2		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_C2C2)
+#define	UNM_CRB_CAM		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_CAM)
+#define	UNM_CRB_CASPER		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_CAS)
+#define	UNM_CRB_CASPER_0	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_CAS0)
+#define	UNM_CRB_CASPER_1	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_CAS1)
+#define	UNM_CRB_CASPER_2	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_CAS2)
+#define	UNM_CRB_DDR_MD		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_MS)
+#define	UNM_CRB_DDR_NET		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_MN)
+#define	UNM_CRB_EPG			UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_EG)
+#define	UNM_CRB_I2Q		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_I2Q)
+#define	UNM_CRB_NIU		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_NIU)
+/* HACK upon HACK upon HACK (for PCIE builds) */
+#define	UNM_CRB_PCIX_HOST	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PH)
+#define	UNM_CRB_PCIX_HOST2	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PH2)
+#define	UNM_CRB_PCIX_MD		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PS)
+#define	UNM_CRB_PCIE		UNM_CRB_PCIX_MD
+// window 1 pcie slot
+#define	UNM_CRB_PCIE2		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PS2)
+
+#define	UNM_CRB_PEG_MD_0   UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGS0)
+#define	UNM_CRB_PEG_MD_1   UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGS1)
+#define	UNM_CRB_PEG_MD_2   UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGS2)
+#define	UNM_CRB_PEG_MD_3   UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGS3)
+#define	UNM_CRB_PEG_MD_D   UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGSD)
+#define	UNM_CRB_PEG_MD_I   UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGSI)
+#define	UNM_CRB_PEG_NET_0  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGN0)
+#define	UNM_CRB_PEG_NET_1  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGN1)
+#define	UNM_CRB_PEG_NET_2  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGN2)
+#define	UNM_CRB_PEG_NET_3  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGN3)
+#define	UNM_CRB_PEG_NET_D  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGND)
+#define	UNM_CRB_PEG_NET_I  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_PGNI)
+#define	UNM_CRB_PQM_MD		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_QMS)
+#define	UNM_CRB_PQM_NET		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_QMN)
+#define	UNM_CRB_QDR_MD		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SS)
+#define	UNM_CRB_QDR_NET		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SN)
+#define	UNM_CRB_ROMUSB		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_ROMUSB)
+#define	UNM_CRB_RPMX_0		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX0)
+#define	UNM_CRB_RPMX_1		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX1)
+#define	UNM_CRB_RPMX_2		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX2)
+#define	UNM_CRB_RPMX_3		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX3)
+#define	UNM_CRB_RPMX_4		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX4)
+#define	UNM_CRB_RPMX_5		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX5)
+#define	UNM_CRB_RPMX_6		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX6)
+#define	UNM_CRB_RPMX_7		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_RPMX7)
+#define	UNM_CRB_SQM_MD_0	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQS0)
+#define	UNM_CRB_SQM_MD_1	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQS1)
+#define	UNM_CRB_SQM_MD_2	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQS2)
+#define	UNM_CRB_SQM_MD_3	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQS3)
+#define	UNM_CRB_SQM_NET_0  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQN0)
+#define	UNM_CRB_SQM_NET_1  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQN1)
+#define	UNM_CRB_SQM_NET_2  UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQN2)
+#define	UNM_CRB_SQM_NET_3	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SQN3)
+#define	UNM_CRB_SRE		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SRE)
+#define	UNM_CRB_TIMER		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_TIMR)
+#define	UNM_CRB_XDMA		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_XDMA)
+#define	UNM_CRB_I2C0	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_I2C0)
+#define	UNM_CRB_I2C1	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_I2C1)
+#define	UNM_CRB_OCM0	UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_OCM0)
+#define	UNM_CRB_SMB		UNM_PCI_CRB_WINDOW(UNM_HW_PX_MAP_CRB_SMB)
+
+#define	UNM_CRB_MAX		UNM_PCI_CRB_WINDOW(64)
+
+/*
+ * ====================== BASE ADDRESSES ON-CHIP ======================
+ * Base addresses of major components on-chip.
+ * ====================== BASE ADDRESSES ON-CHIP ======================
+ */
+#define	UNM_ADDR_DDR_NET		(0x0000000000000000ULL)
+#define	UNM_ADDR_DDR_NET_MAX	(0x000000000fffffffULL)
+
+/*
+ * Imbus address bit used to indicate a host address. This bit is
+ * eliminated by the pcie bar and bar select before presentation
+ * over pcie.
+ */
+/* host memory via IMBUS */
+#define	NX_P2_ADDR_PCIE		(0x0000000800000000ULL)
+#define	NX_P3_ADDR_PCIE		(0x0000008000000000ULL)
+
+#define	UNM_ADDR_PCIE_MAX	(0x0000000FFFFFFFFFULL)
+#define	UNM_ADDR_OCM0		(0x0000000200000000ULL)
+#define	UNM_ADDR_OCM0_MAX	(0x00000002000fffffULL)
+#define	UNM_ADDR_OCM1		(0x0000000200400000ULL)
+#define	UNM_ADDR_OCM1_MAX    (0x00000002004fffffULL)
+#define	UNM_ADDR_QDR_NET	(0x0000000300000000ULL)
+
+#define	NX_P2_ADDR_QDR_NET_MAX	(0x00000003001fffffULL)
+#define	NX_P3_ADDR_QDR_NET_MAX	(0x0000000303ffffffULL)
+/*
+ * The ifdef at the bottom should go. All drivers should start using the
+ * above 2 defines.
+ */
+#ifdef P3
+#define	UNM_ADDR_QDR_NET_MAX	NX_P3_ADDR_QDR_NET_MAX
+#else
+#define	UNM_ADDR_QDR_NET_MAX	NX_P2_ADDR_QDR_NET_MAX
+#endif
+
+#define	D3_CRB_REG_FUN0			(UNM_PCIX_PS_REG(0x0084))
+#define	D3_CRB_REG_FUN1			(UNM_PCIX_PS_REG(0x1084))
+#define	D3_CRB_REG_FUN2			(UNM_PCIX_PS_REG(0x2084))
+#define	D3_CRB_REG_FUN3			(UNM_PCIX_PS_REG(0x3084))
+
+
+#define	ISR_I2Q_CLR_PCI_LO		(UNM_PCIX_PS_REG(UNM_I2Q_CLR_PCI_LO))
+#define	ISR_I2Q_CLR_PCI_HI		(UNM_PCIX_PS_REG(UNM_I2Q_CLR_PCI_HI))
+#define	UNM_PCI_ARCH_CRB_BASE   (UNM_PCI_DIRECT_CRB)
+
+/* we're mapping 128MB of mem on the PCI bus */
+#define	UNM_PCI_MAPSIZE			128
+#define	UNM_PCI_DDR_NET			(unsigned long)0x00000000
+#define	UNM_PCI_DDR_NET_MAX		(unsigned long)0x01ffffff
+#define	UNM_PCI_DDR_MD			(unsigned long)0x02000000
+#define	UNM_PCI_DDR_MD_MAX		(unsigned long)0x03ffffff
+#define	UNM_PCI_QDR_NET			(unsigned long)0x04000000
+#define	UNM_PCI_QDR_NET_MAX		(unsigned long)0x043fffff
+#define	UNM_PCI_DIRECT_CRB		(unsigned long)0x04400000
+#define	UNM_PCI_DIRECT_CRB_MAX	(unsigned long)0x047fffff
+#define	UNM_PCI_CAMQM			(unsigned long)0x04800000
+#define	UNM_PCI_CAMQM_MAX		(unsigned long)0x04ffffff
+#define	UNM_PCI_OCM0			(unsigned long)0x05000000
+#define	UNM_PCI_OCM0_MAX		(unsigned long)0x050fffff
+#define	UNM_PCI_OCM1			(unsigned long)0x05100000
+#define	UNM_PCI_OCM1_MAX		(unsigned long)0x051fffff
+#define	UNM_PCI_CRBSPACE		(unsigned long)0x06000000
+#define	UNM_PCI_CRBSPACE_MAX	(unsigned long)0x07ffffff
+#define	UNM_PCI_128MB_SIZE		(unsigned long)0x08000000
+#define	UNM_PCI_32MB_SIZE		(unsigned long)0x02000000
+#define	UNM_PCI_2MB_SIZE		(unsigned long)0x00200000
+
+/*
+ * The basic unit of access when reading/writing control registers.
+ */
+typedef	long		native_t; /* most efficient integer on h/w */
+typedef	__uint64_t	unm_dataword_t; /* single word in data space */
+typedef	__uint64_t	unm64ptr_t; /* a pointer that occupies 64 bits */
+#define	UNM64PTR(P)	((unm64ptr_t)((native_t)(P)))  /* convert for us */
+
+typedef	__uint32_t	unm_crbword_t; /* single word in CRB space */
+
+/*
+ * Definitions relating to access/control of the Network Interface Unit
+ * h/w block.
+ */
+/*
+ * Configuration registers.
+ */
+#define	UNM_NIU_MODE				(UNM_CRB_NIU + 0x00000)
+
+#define	UNM_NIU_XG_SINGLE_TERM		(UNM_CRB_NIU + 0x00004)
+#define	UNM_NIU_XG_DRIVE_HI			(UNM_CRB_NIU + 0x00008)
+#define	UNM_NIU_XG_DRIVE_LO			(UNM_CRB_NIU + 0x0000c)
+#define	UNM_NIU_XG_DTX				(UNM_CRB_NIU + 0x00010)
+#define	UNM_NIU_XG_DEQ				(UNM_CRB_NIU + 0x00014)
+#define	UNM_NIU_XG_WORD_ALIGN		(UNM_CRB_NIU + 0x00018)
+#define	UNM_NIU_XG_RESET			(UNM_CRB_NIU + 0x0001c)
+#define	UNM_NIU_XG_POWER_DOWN		(UNM_CRB_NIU + 0x00020)
+#define	UNM_NIU_XG_RESET_PLL		(UNM_CRB_NIU + 0x00024)
+#define	UNM_NIU_XG_SERDES_LOOPBACK	(UNM_CRB_NIU + 0x00028)
+#define	UNM_NIU_XG_DO_BYTE_ALIGN	(UNM_CRB_NIU + 0x0002c)
+#define	UNM_NIU_XG_TX_ENABLE		(UNM_CRB_NIU + 0x00030)
+#define	UNM_NIU_XG_RX_ENABLE		(UNM_CRB_NIU + 0x00034)
+#define	UNM_NIU_XG_STATUS			(UNM_CRB_NIU + 0x00038)
+#define	UNM_NIU_XG_PAUSE_THRESHOLD	(UNM_CRB_NIU + 0x0003c)
+#define	UNM_NIU_INT_MASK			(UNM_CRB_NIU + 0x00040)
+#define	UNM_NIU_ACTIVE_INT			(UNM_CRB_NIU + 0x00044)
+#define	UNM_NIU_MASKABLE_INT		(UNM_CRB_NIU + 0x00048)
+#define	UNM_NIU_TEST_MUX_CTL		(UNM_CRB_NIU + 0x00094)
+#define	UNM_NIU_XG_PAUSE_CTL		(UNM_CRB_NIU + 0x00098)
+#define	UNM_NIU_XG_PAUSE_LEVEL		(UNM_CRB_NIU + 0x000dc)
+#define	UNM_NIU_XG_SEL				(UNM_CRB_NIU + 0x00128)
+#define	UNM_NIU_GB_PAUSE_CTL		(UNM_CRB_NIU + 0x0030c)
+#define	UNM_NIU_FULL_LEVEL_XG		(UNM_CRB_NIU + 0x00450)
+
+
+#define	UNM_NIU_XG1_RESET			(UNM_CRB_NIU + 0x0011c)
+#define	UNM_NIU_XG1_POWER_DOWN		(UNM_CRB_NIU + 0x00120)
+#define	UNM_NIU_XG1_RESET_PLL		(UNM_CRB_NIU + 0x00124)
+
+#define	UNM_NIU_STRAP_VALUE_SAVE_HIGHER (UNM_CRB_NIU + 0x0004c)
+
+#define	UNM_NIU_GB_SERDES_RESET (UNM_CRB_NIU + 0x00050)
+#define	UNM_NIU_GB0_GMII_MODE   (UNM_CRB_NIU + 0x00054)
+#define	UNM_NIU_GB0_MII_MODE    (UNM_CRB_NIU + 0x00058)
+#define	UNM_NIU_GB1_GMII_MODE   (UNM_CRB_NIU + 0x0005c)
+#define	UNM_NIU_GB1_MII_MODE    (UNM_CRB_NIU + 0x00060)
+#define	UNM_NIU_GB2_GMII_MODE   (UNM_CRB_NIU + 0x00064)
+#define	UNM_NIU_GB2_MII_MODE    (UNM_CRB_NIU + 0x00068)
+#define	UNM_NIU_GB3_GMII_MODE   (UNM_CRB_NIU + 0x0006c)
+#define	UNM_NIU_GB3_MII_MODE    (UNM_CRB_NIU + 0x00070)
+#define	UNM_NIU_REMOTE_LOOPBACK (UNM_CRB_NIU + 0x00074)
+#define	UNM_NIU_GB0_HALF_DUPLEX (UNM_CRB_NIU + 0x00078)
+#define	UNM_NIU_GB1_HALF_DUPLEX (UNM_CRB_NIU + 0x0007c)
+#define	UNM_NIU_GB2_HALF_DUPLEX (UNM_CRB_NIU + 0x00080)
+#define	UNM_NIU_GB3_HALF_DUPLEX (UNM_CRB_NIU + 0x00084)
+#define	UNM_NIU_RESET_SYS_FIFOS (UNM_CRB_NIU + 0x00088)
+#define	UNM_NIU_GB_CRC_DROP		(UNM_CRB_NIU + 0x0008c)
+#define	UNM_NIU_GB_DROP_WRONGADDR  (UNM_CRB_NIU + 0x00090)
+#define	UNM_NIU_TEST_MUX_CTL    (UNM_CRB_NIU + 0x00094)
+#define	UNM_NIU_XG_PAUSE_CTL    (UNM_CRB_NIU + 0x00098)
+#define	UNM_NIU_GB0_PAUSE_LEVEL (UNM_CRB_NIU + 0x000cc)
+#define	UNM_NIU_GB1_PAUSE_LEVEL (UNM_CRB_NIU + 0x000d0)
+#define	UNM_NIU_GB2_PAUSE_LEVEL (UNM_CRB_NIU + 0x000d4)
+#define	UNM_NIU_GB3_PAUSE_LEVEL (UNM_CRB_NIU + 0x000d8)
+#define	UNM_NIU_XG_PAUSE_LEVEL  (UNM_CRB_NIU + 0x000dc)
+#define	UNM_NIU_FRAME_COUNT_SELECT  (UNM_CRB_NIU + 0x000ac)
+#define	UNM_NIU_FRAME_COUNT  (UNM_CRB_NIU + 0x000b0)
+#define	UNM_NIU_XG_SE			(UNM_CRB_NIU + 0x00128)
+#define	UNM_NIU_FULL_LEVEL_XG   (UNM_CRB_NIU + 0x00450)
+
+#define	UNM_NIU_FC_RX_STATUS(I)	(UNM_CRB_NIU + 0x10000 + (I)*0x10000)
+#define	UNM_NIU_FC_RX_COMMA_DETECT(I)   (UNM_CRB_NIU + 0x10004 + (I)*0x10000)
+#define	UNM_NIU_FC_LASER_UNSAFE(I)	(UNM_CRB_NIU + 0x10008 + (I)*0x10000)
+#define	UNM_NIU_FC_TX_CONTROL(I)	(UNM_CRB_NIU + 0x1000c + (I)*0x10000)
+#define	UNM_NIU_FC_ON_OFFLINE_CTL(I)    (UNM_CRB_NIU + 0x10010 + (I)*0x10000)
+#define	UNM_NIU_FC_PORT_ACTIVE_STAT(I)  (UNM_CRB_NIU + 0x10014 + (I)*0x10000)
+#define	UNM_NIU_FC_PORT_INACTIVE_STAT(I)(UNM_CRB_NIU + 0x10018 + (I)*0x10000)
+#define	UNM_NIU_FC_LINK_FAILURE_CNT(I)  (UNM_CRB_NIU + 0x1001c + (I)*0x10000)
+#define	UNM_NIU_FC_LOSS_SYNC_CNT(I)	(UNM_CRB_NIU + 0x10020 + (I)*0x10000)
+#define	UNM_NIU_FC_LOSS_SIGNAL_CNT(I)   (UNM_CRB_NIU + 0x10024 + (I)*0x10000)
+#define	UNM_NIU_FC_PRIM_SEQ_ERR_CNT(I)  (UNM_CRB_NIU + 0x10028 + (I)*0x10000)
+#define	UNM_NIU_FC_INVLD_TX_WORD_CNT(I) (UNM_CRB_NIU + 0x1002c + (I)*0x10000)
+#define	UNM_NIU_FC_INVLD_CRC_CNT(I)	(UNM_CRB_NIU + 0x10030 + (I)*0x10000)
+#define	UNM_NIU_FC_RX_CELL_CNT(I)	(UNM_CRB_NIU + 0x10034 + (I)*0x10000)
+#define	UNM_NIU_FC_TX_CELL_CNT(I)	(UNM_CRB_NIU + 0x10038 + (I)*0x10000)
+#define	UNM_NIU_FC_B2B_CREDIT(I)	(UNM_CRB_NIU + 0x1003c + (I)*0x10000)
+#define	UNM_NIU_FC_LOGIN_DONE(I)	(UNM_CRB_NIU + 0x10040 + (I)*0x10000)
+#define	UNM_NIU_FC_OPERATING_SPEED(I)	(UNM_CRB_NIU + 0x10044 + (I)*0x10000)
+
+#define	UNM_NIU_GB_MAC_CONFIG_0(I)	(UNM_CRB_NIU + 0x30000 + (I)*0x10000)
+#define	UNM_NIU_GB_MAC_CONFIG_1(I)	(UNM_CRB_NIU + 0x30004 + (I)*0x10000)
+#define	UNM_NIU_GB_MAC_IPG_IFG(I)	(UNM_CRB_NIU + 0x30008 + (I)*0x10000)
+#define	UNM_NIU_GB_HALF_DUPLEX_CTRL(I)	(UNM_CRB_NIU + 0x3000c + (I)*0x10000)
+#define	UNM_NIU_GB_MAX_FRAME_SIZE(I)    (UNM_CRB_NIU + 0x30010 + (I)*0x10000)
+#define	UNM_NIU_GB_TEST_REG(I)		(UNM_CRB_NIU + 0x3001c + (I)*0x10000)
+#define	UNM_NIU_GB_MII_MGMT_CONFIG(I)   (UNM_CRB_NIU + 0x30020 + (I)*0x10000)
+#define	UNM_NIU_GB_MII_MGMT_COMMAND(I)  (UNM_CRB_NIU + 0x30024 + (I)*0x10000)
+#define	UNM_NIU_GB_MII_MGMT_ADDR(I)	(UNM_CRB_NIU + 0x30028 + (I)*0x10000)
+#define	UNM_NIU_GB_MII_MGMT_CTRL(I)	(UNM_CRB_NIU + 0x3002c + (I)*0x10000)
+#define	UNM_NIU_GB_MII_MGMT_STATUS(I)   (UNM_CRB_NIU + 0x30030 + (I)*0x10000)
+#define	UNM_NIU_GB_MII_MGMT_INDICATE(I) (UNM_CRB_NIU + 0x30034 + (I)*0x10000)
+#define	UNM_NIU_GB_INTERFACE_CTRL(I)    (UNM_CRB_NIU + 0x30038 + (I)*0x10000)
+#define	UNM_NIU_GB_INTERFACE_STATUS(I)  (UNM_CRB_NIU + 0x3003c + (I)*0x10000)
+#define	UNM_NIU_GB_STATION_ADDR_0(I)    (UNM_CRB_NIU + 0x30040 + (I)*0x10000)
+#define	UNM_NIU_GB_STATION_ADDR_1(I)    (UNM_CRB_NIU + 0x30044 + (I)*0x10000)
+
+#define	UNM_NIU_XGE_CONFIG_0	(UNM_CRB_NIU + 0x70000)
+#define	UNM_NIU_XGE_CONFIG_1	(UNM_CRB_NIU + 0x70004)
+#define	UNM_NIU_XGE_IPG			(UNM_CRB_NIU + 0x70008)
+#define	UNM_NIU_XGE_STATION_ADDR_0_HI   (UNM_CRB_NIU + 0x7000c)
+#define	UNM_NIU_XGE_STATION_ADDR_0_1    (UNM_CRB_NIU + 0x70010)
+#define	UNM_NIU_XGE_STATION_ADDR_1_LO   (UNM_CRB_NIU + 0x70014)
+#define	UNM_NIU_XGE_STATUS		(UNM_CRB_NIU + 0x70018)
+#define	UNM_NIU_XGE_MAX_FRAME_SIZE	(UNM_CRB_NIU + 0x7001c)
+#define	UNM_NIU_XGE_PAUSE_FRAME_VALUE   (UNM_CRB_NIU + 0x70020)
+#define	UNM_NIU_XGE_TX_BYTE_CNT		(UNM_CRB_NIU + 0x70024)
+#define	UNM_NIU_XGE_TX_FRAME_CNT	(UNM_CRB_NIU + 0x70028)
+#define	UNM_NIU_XGE_RX_BYTE_CNT		(UNM_CRB_NIU + 0x7002c)
+#define	UNM_NIU_XGE_RX_FRAME_CNT	(UNM_CRB_NIU + 0x70030)
+#define	UNM_NIU_XGE_AGGR_ERROR_CNT	(UNM_CRB_NIU + 0x70034)
+#define	UNM_NIU_XGE_MULTICAST_FRAME_CNT (UNM_CRB_NIU + 0x70038)
+#define	UNM_NIU_XGE_UNICAST_FRAME_CNT   (UNM_CRB_NIU + 0x7003c)
+#define	UNM_NIU_XGE_CRC_ERROR_CNT	(UNM_CRB_NIU + 0x70040)
+#define	UNM_NIU_XGE_OVERSIZE_FRAME_ERR  (UNM_CRB_NIU + 0x70044)
+#define	UNM_NIU_XGE_UNDERSIZE_FRAME_ERR (UNM_CRB_NIU + 0x70048)
+#define	UNM_NIU_XGE_LOCAL_ERROR_CNT		(UNM_CRB_NIU + 0x7004c)
+#define	UNM_NIU_XGE_REMOTE_ERROR_CNT	(UNM_CRB_NIU + 0x70050)
+#define	UNM_NIU_XGE_CONTROL_CHAR_CNT    (UNM_CRB_NIU + 0x70054)
+#define	UNM_NIU_XGE_PAUSE_FRAME_CNT		(UNM_CRB_NIU + 0x70058)
+#define	UNM_NIU_XG1_CONFIG_0			(UNM_CRB_NIU + 0x80000)
+#define	UNM_NIU_XG1_CONFIG_1			(UNM_CRB_NIU + 0x80004)
+#define	UNM_NIU_XG1_IPG					(UNM_CRB_NIU + 0x80008)
+#define	UNM_NIU_XG1_STATION_ADDR_0_HI   (UNM_CRB_NIU + 0x8000c)
+#define	UNM_NIU_XG1_STATION_ADDR_0_1    (UNM_CRB_NIU + 0x80010)
+#define	UNM_NIU_XG1_STATION_ADDR_1_LO   (UNM_CRB_NIU + 0x80014)
+#define	UNM_NIU_XG1_STATUS				(UNM_CRB_NIU + 0x80018)
+#define	UNM_NIU_XG1_MAX_FRAME_SIZE		(UNM_CRB_NIU + 0x8001c)
+#define	UNM_NIU_XG1_PAUSE_FRAME_VALUE   (UNM_CRB_NIU + 0x80020)
+#define	UNM_NIU_XG1_TX_BYTE_CNT			(UNM_CRB_NIU + 0x80024)
+#define	UNM_NIU_XG1_TX_FRAME_CNT		(UNM_CRB_NIU + 0x80028)
+#define	UNM_NIU_XG1_RX_BYTE_CNT			(UNM_CRB_NIU + 0x8002c)
+#define	UNM_NIU_XG1_RX_FRAME_CNT		(UNM_CRB_NIU + 0x80030)
+#define	UNM_NIU_XG1_AGGR_ERROR_CNT		(UNM_CRB_NIU + 0x80034)
+#define	UNM_NIU_XG1_MULTICAST_FRAME_CNT	(UNM_CRB_NIU + 0x80038)
+#define	UNM_NIU_XG1_UNICAST_FRAME_CNT	(UNM_CRB_NIU + 0x8003c)
+#define	UNM_NIU_XG1_CRC_ERROR_CNT		(UNM_CRB_NIU + 0x80040)
+#define	UNM_NIU_XG1_OVERSIZE_FRAME_ERR  (UNM_CRB_NIU + 0x80044)
+#define	UNM_NIU_XG1_UNDERSIZE_FRAME_ERR (UNM_CRB_NIU + 0x80048)
+#define	UNM_NIU_XG1_LOCAL_ERROR_CNT		(UNM_CRB_NIU + 0x8004c)
+#define	UNM_NIU_XG1_REMOTE_ERROR_CNT	(UNM_CRB_NIU + 0x80050)
+#define	UNM_NIU_XG1_CONTROL_CHAR_CNT    (UNM_CRB_NIU + 0x80054)
+#define	UNM_NIU_XG1_PAUSE_FRAME_CNT		(UNM_CRB_NIU + 0x80058)
+
+#define	UNM_TIMER_GT_TICKCTL			(UNM_CRB_TIMER + 0x00200)
+#define	UNM_TIMER_GLOBAL_TIMESTAMP_LO   (UNM_CRB_TIMER + 0x00220)
+#define	UNM_TIMER_TIMESTAMP		(UNM_CRB_TIMER + 0x00208)
+
+#define	UNM_PEXQ_REQ_HDR_LO				(UNM_CRB_XDMA + 0x00110)
+#define	UNM_PEXQ_REQ_HDR_HI				(UNM_CRB_XDMA + 0x00114)
+
+/* P3 802.3ap */
+#define	UNM_NIU_AP_MAC_CONFIG_0(I)	(UNM_CRB_NIU + 0xa0000 + (I)*0x10000)
+#define	UNM_NIU_AP_MAC_CONFIG_1(I)	(UNM_CRB_NIU + 0xa0004 + (I)*0x10000)
+#define	UNM_NIU_AP_MAC_IPG_IFG(I)	(UNM_CRB_NIU + 0xa0008 + (I)*0x10000)
+#define	UNM_NIU_AP_HALF_DUPLEX_CTRL(I)  (UNM_CRB_NIU + 0xa000c + (I)*0x10000)
+#define	UNM_NIU_AP_MAX_FRAME_SIZE(I)    (UNM_CRB_NIU + 0xa0010 + (I)*0x10000)
+#define	UNM_NIU_AP_TEST_REG(I)		(UNM_CRB_NIU + 0xa001c + (I)*0x10000)
+#define	UNM_NIU_AP_MII_MGMT_CONFIG(I)   (UNM_CRB_NIU + 0xa0020 + (I)*0x10000)
+#define	UNM_NIU_AP_MII_MGMT_COMMAND(I)  (UNM_CRB_NIU + 0xa0024 + (I)*0x10000)
+#define	UNM_NIU_AP_MII_MGMT_ADDR(I)	(UNM_CRB_NIU + 0xa0028 + (I)*0x10000)
+#define	UNM_NIU_AP_MII_MGMT_CTRL(I)	(UNM_CRB_NIU + 0xa002c + (I)*0x10000)
+#define	UNM_NIU_AP_MII_MGMT_STATUS(I)   (UNM_CRB_NIU + 0xa0030 + (I)*0x10000)
+#define	UNM_NIU_AP_MII_MGMT_INDICATE(I) (UNM_CRB_NIU + 0xa0034 + (I)*0x10000)
+#define	UNM_NIU_AP_INTERFACE_CTRL(I)    (UNM_CRB_NIU + 0xa0038 + (I)*0x10000)
+#define	UNM_NIU_AP_INTERFACE_STATUS(I)  (UNM_CRB_NIU + 0xa003c + (I)*0x10000)
+#define	UNM_NIU_AP_STATION_ADDR_0(I)    (UNM_CRB_NIU + 0xa0040 + (I)*0x10000)
+#define	UNM_NIU_AP_STATION_ADDR_1(I)    (UNM_CRB_NIU + 0xa0044 + (I)*0x10000)
+
+/*
+ *   Register offsets for MN
+ */
+#define	MIU_CONTROL		(0x000)
+#define	MIU_TAG			(0x004)
+#define	MIU_TEST_AGT_CTRL		(0x090)
+#define	MIU_TEST_AGT_ADDR_LO	(0x094)
+#define	MIU_TEST_AGT_ADDR_HI	(0x098)
+#define	MIU_TEST_AGT_WRDATA_LO	(0x0a0)
+#define	MIU_TEST_AGT_WRDATA_HI	(0x0a4)
+#define	MIU_TEST_AGT_WRDATA(i)	(0x0a0+(4*(i)))
+#define	MIU_TEST_AGT_RDDATA_LO	(0x0a8)
+#define	MIU_TEST_AGT_RDDATA_HI	(0x0ac)
+#define	MIU_TEST_AGT_RDDATA(i)	(0x0a8+(4*(i)))
+#define	MIU_TEST_AGT_ADDR_MASK	0xfffffff8
+#define	MIU_TEST_AGT_UPPER_ADDR(off)	(0)
+
+/* MIU_TEST_AGT_CTRL flags. work for SIU as well */
+#define	MIU_TA_CTL_START		1
+#define	MIU_TA_CTL_ENABLE		2
+#define	MIU_TA_CTL_WRITE		4
+#define	MIU_TA_CTL_BUSY			8
+
+#define	SIU_TEST_AGT_CTRL		(0x060)
+#define	SIU_TEST_AGT_ADDR_LO	(0x064)
+#define	SIU_TEST_AGT_ADDR_HI	(0x078)
+#define	SIU_TEST_AGT_WRDATA_LO	(0x068)
+#define	SIU_TEST_AGT_WRDATA_HI	(0x06c)
+#define	SIU_TEST_AGT_WRDATA(i)	(0x068+(4*(i)))
+#define	SIU_TEST_AGT_RDDATA_LO	(0x070)
+#define	SIU_TEST_AGT_RDDATA_HI	(0x074)
+#define	SIU_TEST_AGT_RDDATA(i)	(0x070+(4*(i)))
+
+#define	SIU_TEST_AGT_ADDR_MASK	0x3ffff8
+#define	SIU_TEST_AGT_UPPER_ADDR(off)	((off)>>22)
+
+/* XG Link status */
+#define	XG_LINK_UP    0x10
+
+
+/* ======================  Configuration Constants ======================== */
+#define	UNM_NIU_PHY_WAITLEN    200000    /* 200ms delay in each loop */
+#define	UNM_NIU_PHY_WAITMAX    50    /* 10 seconds before we give up */
+#define	UNM_NIU_MAX_GBE_PORTS 4
+#define	UNM_NIU_MAX_XG_PORTS 2
+
+typedef __uint8_t unm_ethernet_macaddr_t[6];
+
+#define	MIN_CORE_CLK_SPEED 200
+#define	MAX_CORE_CLK_SPEED 400
+#define	ACCEPTABLE_CORE_CLK_RANGE(speed)	\
+	((speed >= MIN_CORE_CLK_SPEED) && (speed <= MAX_CORE_CLK_SPEED))
+
+#define	P2_TICKS_PER_SEC    2048
+#define	P2_MIN_TICKS_PER_SEC    (P2_TICKS_PER_SEC-10)
+#define	P2_MAX_TICKS_PER_SEC    (P2_TICKS_PER_SEC+10)
+#define	CHECK_TICKS_PER_SEC(ticks)	\
+	((ticks >= P2_MIN_TICKS_PER_SEC) && (ticks <= P2_MAX_TICKS_PER_SEC))
+
+/* =============================    1GbE    =============================== */
+/* Nibble or Byte mode for phy interface (GbE mode only) */
+typedef enum {
+    UNM_NIU_10_100_MB = 0,
+    UNM_NIU_1000_MB
+} unm_niu_gbe_ifmode_t;
+
+/* Promiscous mode options (GbE mode only) */
+typedef enum {
+    UNM_NIU_PROMISCOUS_MODE = 0,
+    UNM_NIU_NON_PROMISCOUS_MODE
+} unm_niu_prom_mode_t;
+
+/*
+ * NIU GB Drop CRC Register
+ */
+typedef struct {
+    unm_crbword_t
+		drop_gb0:1, /* 1:drop pkts with bad CRCs, 0:pass them on */
+		drop_gb1:1, /* 1:drop pkts with bad CRCs, 0:pass them on */
+		drop_gb2:1, /* 1:drop pkts with bad CRCs, 0:pass them on */
+		drop_gb3:1, /* 1:drop pkts with bad CRCs, 0:pass them on */
+		rsvd:28;
+} unm_niu_gb_drop_crc_t;
+
+/*
+ * NIU GB GMII Mode Register (applies to GB0, GB1, GB2, GB3)
+ * To change the mode, turn off the existing mode, then turn on the new mode.
+ */
+typedef struct {
+    unm_crbword_t
+		gmiimode:1, /* 1:GMII mode, 0:xmit clk taken from SERDES */
+		rsvd:29;
+} unm_niu_gb_gmii_mode_t;
+
+/*
+ * NIU GB MII Mode Register (applies to GB0, GB1, GB2, GB3)
+ * To change the mode, turn off the existing mode, then turn on the new mode.
+ */
+typedef struct {
+    unm_crbword_t
+		miimode:1, /* 1:MII mode, 0:xmit clk provided to SERDES */
+		rsvd:29;
+} unm_niu_gb_mii_mode_t;
+
+/*
+ * NIU GB MAC Config Register 0 (applies to GB0, GB1, GB2, GB3)
+ */
+typedef struct {
+    unm_crbword_t
+		tx_enable:1, /* 1:enable frame xmit, 0:disable */
+		tx_synched:1, /* R/O: xmit enable synched to xmit stream */
+		rx_enable:1, /* 1:enable frame recv, 0:disable */
+		rx_synched:1, /* R/O: recv enable synched to recv stream */
+		tx_flowctl:1, /* 1:enable pause frame generation, 0:disable */
+		rx_flowctl:1, /* 1:act on recv'd pause frames, 0:ignore */
+		rsvd1:2,
+		loopback:1, /* 1:loop MAC xmits to MAC recvs, 0:normal */
+		rsvd2:7,
+		tx_reset_pb:1, /* 1:reset frame xmit protocol blk, 0:no-op */
+		rx_reset_pb:1, /* 1:reset frame recv protocol blk, 0:no-op */
+		tx_reset_mac:1, /* 1:reset data/ctl multiplexer blk, 0:no-op */
+		rx_reset_mac:1, /* 1:reset ctl frames & timers blk, 0:no-op */
+		rsvd3:11,
+		soft_reset:1; /* 1:reset the MAC and the SERDES, 0:no-op */
+} unm_niu_gb_mac_config_0_t;
+
+/*
+ * NIU GB MAC Config Register 1 (applies to GB0, GB1, GB2, GB3)
+ */
+typedef struct {
+    unm_crbword_t
+		duplex:1, /* 1:full duplex mode, 0:half duplex */
+		crc_enable:1, /* 1:append CRC to xmit frames, 0:dont append */
+		padshort:1, /* 1:pad short frames and add CRC, 0:dont pad */
+		rsvd1:1,
+		checklength:1, /* 1:check framelen with actual, 0:dont check */
+		hugeframes:1, /* 1:allow oversize xmit frames, 0:dont allow */
+		rsvd2:2,
+		intfmode:2, /* 01:nibble (10/100), 10:byte (1000) */
+		rsvd3:2,
+		preamblelen:4, /* preamble field length in bytes, default 7 */
+		rsvd4:16;
+} unm_niu_gb_mac_config_1_t;
+
+/*
+ * NIU XG Pause Ctl Register
+ */
+typedef struct {
+    unm_crbword_t
+		xg0_mask:1, /* 1:disable tx pause frames */
+		xg0_request:1, /* request single pause frame */
+		xg0_on_off:1, /* 1:req is pause on, 0:off */
+		xg1_mask:1, /* 1:disable tx pause frames */
+		xg1_request:1, /* request single pause frame */
+		xg1_on_off:1, /* 1:req is pause on, 0:off */
+		rsvd:26;
+} unm_niu_xg_pause_ctl_t;
+
+/*
+ * NIU GBe Pause Ctl Register
+ */
+typedef struct {
+    unm_crbword_t
+		gb0_mask:1, /* 1:disable tx pause frames */
+		gb0_pause_req:1, /* 1: send pause on, 0: send pause off */
+		gb1_mask:1, /* 1:disable tx pause frames */
+		gb1_pause_req:1, /* 1: send pause on, 0: send pause off */
+		gb2_mask:1, /* 1:disable tx pause frames */
+		gb2_pause_req:1, /* 1: send pause on, 0: send pause off */
+		gb3_mask:1, /* 1:disable tx pause frames */
+		gb3_pause_req:1, /* 1: send pause on, 0: send pause off */
+		rsvd:24;
+} unm_niu_gb_pause_ctl_t;
+
+
+/*
+ * NIU XG MAC Config Register
+ */
+typedef struct {
+    unm_crbword_t
+		tx_enable:1, /* 1:enable frame xmit, 0:disable */
+		rsvd1:1,
+		rx_enable:1, /* 1:enable frame recv, 0:disable */
+		rsvd2:1,
+		soft_reset:1, /* 1:reset the MAC , 0:no-op */
+		rsvd3:22,
+		xaui_framer_reset:1,
+		xaui_rx_reset:1,
+		xaui_tx_reset:1,
+		xg_ingress_afifo_reset:1,
+		xg_egress_afifo_reset:1;
+} unm_niu_xg_mac_config_0_t;
+
+/*
+ * NIU GB MII Mgmt Config Register (applies to GB0, GB1, GB2, GB3)
+ */
+typedef struct {
+    unm_crbword_t
+		clockselect:3, /* 0:clk/4,  1:clk/4,  2:clk/6,  3:clk/8 */
+		/* 4:clk/10, 5:clk/14, 6:clk/20, 7:clk/28 */
+		rsvd1:1,
+		nopreamble:1, /* 1:suppress preamble generation, 0:normal */
+		scanauto:1, /* ???? */
+		rsvd2:25,
+		reset:1; /* 1:reset MII mgmt, 0:no-op */
+} unm_niu_gb_mii_mgmt_config_t;
+
+/*
+ * NIU GB MII Mgmt Command Register (applies to GB0, GB1, GB2, GB3)
+ */
+typedef struct {
+    unm_crbword_t
+		read_cycle:1, /* 1:perform single read cycle, 0:no-op */
+		scan_cycle:1, /* 1:perform continuous read cycles, 0:no-op */
+		rsvd:30;
+} unm_niu_gb_mii_mgmt_command_t;
+
+/*
+ * NIU GB MII Mgmt Address Register (applies to GB0, GB1, GB2, GB3)
+ */
+typedef struct {
+    unm_crbword_t
+		reg_addr:5, /* which mgmt register we want to talk to */
+		rsvd1:3,
+		phy_addr:5, /* which PHY to talk to (0 is reserved) */
+		rsvd:19;
+} unm_niu_gb_mii_mgmt_address_t;
+
+/*
+ * NIU GB MII Mgmt Indicators Register (applies to GB0, GB1, GB2, GB3)
+ * Read-only register.
+ */
+typedef struct {
+    unm_crbword_t
+		busy:1, /* 1:performing an MII mgmt cycle, 0:idle */
+		scanning:1, /* 1:scan operation in progress, 0:idle */
+		notvalid:1, /* 1:mgmt result data not yet valid, 0:idle */
+		rsvd:29;
+} unm_niu_gb_mii_mgmt_indicators_t;
+
+/*
+ * NIU GB Station Address High Register
+ * NOTE: this value is in network byte order.
+ */
+typedef struct {
+    unm_crbword_t
+		address:32; /* station address [47:16] */
+} unm_niu_gb_station_address_high_t;
+
+/*
+ * NIU GB Station Address Low Register
+ * NOTE: this value is in network byte order.
+ */
+typedef struct {
+    unm_crbword_t
+		rsvd:16,
+		address:16; /* station address [15:0] */
+} unm_niu_gb_station_address_low_t;
+
+/* ============================  PHY Definitions  ========================== */
+/*
+ * PHY-Specific MII control/status registers.
+ */
+typedef enum {
+    UNM_NIU_GB_MII_MGMT_ADDR_CONTROL = 0,
+    UNM_NIU_GB_MII_MGMT_ADDR_STATUS = 1,
+    UNM_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 = 2,
+    UNM_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 = 3,
+    UNM_NIU_GB_MII_MGMT_ADDR_AUTONEG = 4,
+    UNM_NIU_GB_MII_MGMT_ADDR_LNKPART = 5,
+    UNM_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE = 6,
+    UNM_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT = 7,
+    UNM_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE = 8,
+    UNM_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL = 9,
+    UNM_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS = 10,
+    UNM_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS = 15,
+    UNM_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL = 16,
+    UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS = 17,
+    UNM_NIU_GB_MII_MGMT_ADDR_INT_ENABLE = 18,
+    UNM_NIU_GB_MII_MGMT_ADDR_INT_STATUS = 19,
+    UNM_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE = 20,
+    UNM_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT = 21,
+    UNM_NIU_GB_MII_MGMT_ADDR_LED_CONTROL = 24,
+    UNM_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE = 25,
+    UNM_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET = 26,
+    UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE = 27
+} unm_niu_phy_register_t;
+
+/*
+ * PHY-Specific Status Register (reg 17).
+ */
+typedef struct {
+    unm_crbword_t
+		jabber:1, /* 1:jabber detected, 0:not */
+		polarity:1, /* 1:polarity reversed, 0:normal */
+		recvpause:1, /* 1:receive pause enabled, 0:disabled */
+		xmitpause:1, /* 1:transmit pause enabled, 0:disabled */
+		energydetect:1, /* 1:sleep, 0:active */
+		downshift:1, /* 1:downshift, 0:no downshift */
+		crossover:1, /* 1:MDIX (crossover), 0:MDI (no crossover) */
+		cablelen:3, /* not valid in 10Mb/s mode */
+		/* 0:<50m, 1:50-80m, 2:80-110m, 3:110-140m, 4:>140m */
+		link:1, /* 1:link up, 0:link down */
+		resolved:1, /* 1:speed and duplex resolved, 0:not yet */
+		pagercvd:1, /* 1:page received, 0:page not received */
+		duplex:1, /* 1:full duplex, 0:half duplex */
+		speed:2, /* 0:10Mb/s, 1:100Mb/s, 2:1000Mb/s, 3:rsvd */
+		rsvd:16;
+} unm_niu_phy_status_t;
+
+/*
+ * Interrupt Register definition
+ * This definition applies to registers 18 and 19 (int enable and int status).
+ */
+typedef struct {
+    unm_crbword_t
+		jabber:1,
+		polarity_changed:1,
+		reserved:2,
+		energy_detect:1,
+		downshift:1,
+		mdi_xover_changed:1,
+		fifo_over_underflow:1,
+		false_carrier:1,
+		symbol_error:1,
+		link_status_changed:1,
+		autoneg_completed:1,
+		page_received:1,
+		duplex_changed:1,
+		speed_changed:1,
+		autoneg_error:1,
+		rsvd:16;
+} unm_niu_phy_interrupt_t;
+
+/* =============================   10GbE    =============================== */
+/*
+ * NIU Mode Register.
+ */
+typedef struct {
+    unm_crbword_t
+		enable_fc:1, /* enable FibreChannel */
+		enable_ge:1, /* enable 10/100/1000 Ethernet */
+		enable_xgb:1, /* enable 10Gb Ethernet */
+		rsvd:29;
+} unm_niu_control_t;
+
+/* ==========================  Interface Functions  ======================= */
+
+/* Generic enable for GbE ports. Will detect the speed of the link. */
+long unm_niu_gbe_init_port(long port);
+
+/* XG Link status */
+#define	XG_LINK_UP    0x10
+#define	XG_LINK_DOWN  0x20
+
+#define	XG_LINK_UP_P3    0x1
+#define	XG_LINK_DOWN_P3  0x2
+#define	XG_LINK_UNKNOWN_P3  0
+
+#define	XG_LINK_STATE_P3_MASK 0xf
+#define	XG_LINK_STATE_P3(pcifn, val) \
+	(((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK)
+
+#define	MTU_MARGIN			100
+
+#define	PF_LINK_SPEED_MHZ 100
+#define	PF_LINK_SPEED_REG(pcifn)  (CRB_PF_LINK_SPEED_1 + (((pcifn)/4)* 4))
+#define	PF_LINK_SPEED_MASK 0xff
+#define	PF_LINK_SPEED_VAL(pcifn, reg) \
+		(((reg) >> (8 * ((pcifn) & 0x3))) & PF_LINK_SPEED_MASK)
+
+
+
+/*
+ * Definitions relating to access/control of the CAM RAM
+ */
+
+typedef union {
+    struct {
+					/*
+					 * =1 if watchdog is active.
+					 * =0 if watchdog is inactive
+					 *  This is read-only for anyone
+					 *  but the watchdog itself.
+					 */
+		unsigned int    enabled: 1,
+					/*
+					 * Set this to 1 to send disable
+					 * request to watchdog . Watchdog
+					 * will complete the shutdown
+					 * process and acknowledge it
+					 * by clearing this bit and the
+					 * "enable" bit.
+					 */
+						disable_request: 1,
+					/*
+					 * Set this to 1 to send enable
+					 * request to watchdog . Watchdog
+					 * will complete the enable
+					 * process and acknowledge it
+					 * by clearing this bit and
+					 * setting the "enable" bit.
+					 */
+						enable_request: 1,
+						unused: 29;
+	} s1;
+	unm_crbword_t word;
+} dma_watchdog_ctrl_t;
+
+#define	UNM_CAM_RAM_BASE		(UNM_CRB_CAM + 0x02000)
+#define	UNM_CAM_RAM(reg)		(UNM_CAM_RAM_BASE + (reg))
+
+#define	UNM_PORT_MODE_NONE			0
+#define	UNM_PORT_MODE_XG			1
+#define	UNM_PORT_MODE_GB			2
+#define	UNM_PORT_MODE_802_3_AP		3
+#define	UNM_PORT_MODE_AUTO_NEG		4
+#define	UNM_PORT_MODE_AUTO_NEG_1G	5
+#define	UNM_PORT_MODE_AUTO_NEG_XG	6
+#define	UNM_PORT_MODE_ADDR			(UNM_CAM_RAM(0x24))
+#define	UNM_WOL_PORT_MODE			(UNM_CAM_RAM(0x198))
+
+#define	UNM_ROM_LOCK_ID		(UNM_CAM_RAM(0x100))
+#define	UNM_I2C_ROM_LOCK_ID (UNM_CAM_RAM(0x104))
+#define	UNM_PHY_LOCK_ID		(UNM_CAM_RAM(0x120))
+#define	UNM_CRB_WIN_LOCK_ID (UNM_CAM_RAM(0x124))
+#define	CAM_RAM_DMA_WATCHDOG_CTRL	0x14 /* See dma_watchdog_ctrl_t */
+#define	UNM_EFUSE_CHIP_ID	(UNM_CAM_RAM(0x18))
+
+#define	UNM_FW_VERSION_MAJOR (UNM_CAM_RAM(0x150))
+#define	UNM_FW_VERSION_MINOR (UNM_CAM_RAM(0x154))
+#define	UNM_FW_VERSION_BUILD (UNM_CAM_RAM(0x168))
+#define	UNM_FW_VERSION_SUB   (UNM_CAM_RAM(0x158))
+#define	UNM_TCP_FW_VERSION_MAJOR_ADDR (UNM_CAM_RAM(0x15c))
+#define	UNM_TCP_FW_VERSION_MINOR_ADDR (UNM_CAM_RAM(0x160))
+#define	UNM_TCP_FW_VERSION_SUB_ADDR (UNM_CAM_RAM(0x164))
+#define	UNM_PCIE_REG(reg) (UNM_CRB_PCIE + (reg))
+
+#define	PCIE_DCR				(0x00d8)
+#define	PCIE_DB_DATA2			(0x10070)
+#define	PCIE_DB_CTRL			(0x100a0)
+#define	PCIE_DB_ADDR			(0x100a4)
+#define	PCIE_DB_DATA			(0x100a8)
+#define	PCIE_IMBUS_CONTROL		(0x101b8)
+#define	PCIE_SETUP_FUNCTION		(0x12040)
+#define	PCIE_SETUP_FUNCTION2	(0x12048)
+#define	PCIE_TGT_SPLIT_CHICKEN	(0x12080)
+#define	PCIE_CHICKEN3			(0x120c8)
+#define	PCIE_MAX_MASTER_SPLIT	(0x14048)
+#define	PCIE_MAX_DMA_XFER_SIZE	(0x1404c)
+
+#define	UNM_WOL_WAKE (UNM_CAM_RAM(0x180))
+#define	UNM_WOL_CONFIG_NV (UNM_CAM_RAM(0x184))
+#define	UNM_WOL_CONFIG (UNM_CAM_RAM(0x188))
+#define	UNM_PRE_WOL_RX_ENABLE (UNM_CAM_RAM(0x18c))
+
+/*
+ *  Following define address space withing PCIX CRB space to talk with
+ *  devices on the storage side PCI bus.
+ */
+#define	PCIX_PS_MEM_SPACE		(0x90000)
+
+#define	UNM_PCIX_PH_REG(reg)	(UNM_CRB_PCIE + (reg))
+
+/*
+ * Configuration registers. These are the same offsets on both host and
+ * storage side PCI blocks.
+ */
+/* Used for PS PCI Memory access */
+#define	PCIX_PS_OP_ADDR_LO		(0x10000)
+#define	PCIX_PS_OP_ADDR_HI		(0x10004)  /* via CRB  (PS side only) */
+
+#define	PCIX_MS_WINDOW			(0x10204)   /* UNUSED */
+
+#define	PCIX_CRB_WINDOW			(0x10210)
+#define	PCIX_CRB_WINDOW_F0		(0x10210)
+#define	PCIX_CRB_WINDOW_F1		(0x10230)
+#define	PCIX_CRB_WINDOW_F2		(0x10250)
+#define	PCIX_CRB_WINDOW_F3		(0x10270)
+#define	PCIX_CRB_WINDOW_F4		(0x102ac)
+#define	PCIX_CRB_WINDOW_F5		(0x102bc)
+#define	PCIX_CRB_WINDOW_F6		(0x102cc)
+#define	PCIX_CRB_WINDOW_F7		(0x102dc)
+#define	PCIE_CRB_WINDOW_REG(func) (((func) < 4) ? \
+		(PCIX_CRB_WINDOW_F0 + (0x20 * (func))) :\
+		(PCIX_CRB_WINDOW_F4 + (0x10 * ((func)-4))))
+
+#define	PCIX_MN_WINDOW			(0x10200)
+#define	PCIX_MN_WINDOW_F0		(0x10200)
+#define	PCIX_MN_WINDOW_F1		(0x10220)
+#define	PCIX_MN_WINDOW_F2		(0x10240)
+#define	PCIX_MN_WINDOW_F3		(0x10260)
+#define	PCIX_MN_WINDOW_F4		(0x102a0)
+#define	PCIX_MN_WINDOW_F5		(0x102b0)
+#define	PCIX_MN_WINDOW_F6		(0x102c0)
+#define	PCIX_MN_WINDOW_F7		(0x102d0)
+#define	PCIE_MN_WINDOW_REG(func) (((func) < 4) ? \
+		(PCIX_MN_WINDOW_F0 + (0x20 * (func))) :\
+		(PCIX_MN_WINDOW_F4 + (0x10 * ((func)-4))))
+
+#define	PCIX_SN_WINDOW			(0x10208)
+#define	PCIX_SN_WINDOW_F0		(0x10208)
+#define	PCIX_SN_WINDOW_F1		(0x10228)
+#define	PCIX_SN_WINDOW_F2		(0x10248)
+#define	PCIX_SN_WINDOW_F3		(0x10268)
+#define	PCIX_SN_WINDOW_F4		(0x102a8)
+#define	PCIX_SN_WINDOW_F5		(0x102b8)
+#define	PCIX_SN_WINDOW_F6		(0x102c8)
+#define	PCIX_SN_WINDOW_F7		(0x102d8)
+#define	PCIE_SN_WINDOW_REG(func) (((func) < 4) ? \
+		(PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\
+		(PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4))))
+
+#define	UNM_PCIX_PS_REG(reg) (UNM_CRB_PCIX_MD + (reg))
+#define	UNM_PCIX_PS2_REG(reg) (UNM_CRB_PCIE2 + (reg))
+#define	MANAGEMENT_COMMAND_REG	(UNM_CRB_PCIE + (4))
+
+#define	UNM_PH_INT_MASK		(UNM_CRB_PCIE + PCIX_INT_MASK)
+
+/*
+ * CRB window register.
+ */
+typedef struct {
+    unm_crbword_t	rsvd1:25,
+					addrbit:1, /* bit 25 of CRB address */
+					rsvd2:6;
+} unm_pcix_crb_window_t;
+
+/*
+ * Tell which interrupt source we want to operate on.
+ */
+typedef enum {
+    UNM_PCIX_INT_SRC_UNDEFINED = 0,
+	UNM_PCIX_INT_SRC_DMA0, /* DMA engine 0 */
+	UNM_PCIX_INT_SRC_DMA1, /* DMA engine 1 */
+	UNM_PCIX_INT_SRC_I2Q  /* I2Q block */
+} unm_pcix_int_source_t;
+
+typedef enum {
+    UNM_PCIX_INT_SRC_UNDEFINEDSTATE = 0,
+	UNM_PCIX_INT_SRC_ALLOW, /* Allow this src to int. the host */
+	UNM_PCIX_INT_SRC_MASK /* Mask this src */
+} unm_pcix_int_state_t;
+
+/*
+ * PCIX Interrupt Mask Register.
+ */
+typedef struct {
+					/* 0=DMA0 not masked, 1=masked */
+	unm_crbword_t	dma0:1,
+					/* 0=DMA1 not masked, 1=masked */
+					dma1:1,
+					/* 0=I2Q  not masked, 1=masked */
+					i2q:1,
+					dma0_err:1,
+					dma1_err:1,
+					target_status:1,
+					mega_err:1,
+					ps_serr_int:1,
+					split_discard:1,
+					io_write_func0:1,
+					io_write_func1:1,
+					io_write_func2:1,
+					io_write_func3:1,
+					msi_write_func0:1,
+					msi_write_func1:1,
+					msi_write_func2:1,
+					msi_write_func3:1,
+					rsvd:15;
+} unm_pcix_int_mask_t;
+
+int unm_pcix_int_control(unm_pcix_int_source_t src,
+    unm_pcix_int_state_t state);
+
+#define	UNM_SRE_INT_STATUS			(UNM_CRB_SRE + 0x00034)
+#define	UNM_SRE_BUF_CTL				(UNM_CRB_SRE + 0x01000)
+#define	UNM_SRE_PBI_ACTIVE_STATUS	(UNM_CRB_SRE + 0x01014)
+#define	UNM_SRE_SCRATCHPAD			(UNM_CRB_SRE + 0x01018)
+#define	UNM_SRE_L1RE_CTL			(UNM_CRB_SRE + 0x03000)
+#define	UNM_SRE_L2RE_CTL			(UNM_CRB_SRE + 0x05000)
+
+// These are offset to a particular Peg's CRB base address
+#define	CRB_REG_EX_PC		0x3c
+
+#define	PEG_NETWORK_BASE(N)	(UNM_CRB_PEG_NET_0 + (((N)&3) << 20))
+
+/*
+ * Definitions relating to enqueue/dequeue/control of the Queue Operations
+ * to either the Primary Queue Manager or the Secondary Queue Manager.
+ */
+
+/*
+ * General configuration constants.
+ */
+#define	UNM_QM_MAX_SIDE		1
+
+/*
+ * Data movement registers (differs based on processor).
+ */
+#define	UNM_QM_COMMAND (UNM_PCI_CAMQM + 0x00000)
+#define	UNM_QM_STATUS  (UNM_PCI_CAMQM + 0x00008)
+#define	UNM_QM_DATA(W, P) (UNM_PCI_CAMQM + 0x00010 +	\
+		(W)*sizeof (unm_dataword_t))
+#define	UNM_QM_REPLY(W, P)(UNM_PCI_CAMQM + 0x00050 +	\
+		(W)*sizeof (unm_dataword_t))
+
+/*
+ * Control commands to the QM block.
+ */
+#define	UNM_QM_CMD_READ		0x0  /* interpret "readop" field */
+
+/*
+ * Platform-specific fields in the queue command word
+ */
+#define	UNM_QM_CMD_SIDE  0
+/* Casper and Peg need this bit.  PCI interface does not */
+#define	UNM_QM_CMD_START 1
+
+
+/*
+ * Pegasus has two QM ports. This is the default one to use (unless
+ * QM async interface is called explicitly with other port).
+ */
+#define	UNM_QM_DEFAULT_PORT 0
+
+/*
+ * Status result returned to caller of unm_qm_request_status()
+ */
+typedef enum {
+	/* error in HW - most likely PCI bug. retry  */
+	unm_qm_status_unknown = 0,
+	unm_qm_status_done, /* done with last command */
+	unm_qm_status_busy, /* busy */
+	unm_qm_status_notfound, /* queue is empty to read or full to write */
+	unm_qm_status_error /* error (e.g. timeout) encountered */
+} unm_qm_result_t;
+
+/*
+ * Definitions relating to access/control of the I2Q h/w block.
+ */
+/*
+ * Configuration registers.
+ */
+#define	UNM_I2Q_CONFIG			(UNM_CRB_I2Q + 0x00000)
+#define	UNM_I2Q_ENA_PCI_LO		(UNM_CRB_I2Q + 0x00010)
+#define	UNM_I2Q_ENA_PCI_HI		(UNM_CRB_I2Q + 0x00014)
+#define	UNM_I2Q_ENA_CASPER_LO	(UNM_CRB_I2Q + 0x00018)
+#define	UNM_I2Q_ENA_CASPER_HI	(UNM_CRB_I2Q + 0x0001c)
+#define	UNM_I2Q_ENA_QM_LO		(UNM_CRB_I2Q + 0x00020)
+#define	UNM_I2Q_ENA_QM_HI		(UNM_CRB_I2Q + 0x00024)
+#define	UNM_I2Q_CLR_PCI_LO		(UNM_CRB_I2Q + 0x00030)
+#define	UNM_I2Q_CLR_PCI_HI		(UNM_CRB_I2Q + 0x00034)
+#define	UNM_I2Q_CLR_CASPER_LO	(UNM_CRB_I2Q + 0x00038)
+#define	UNM_I2Q_CLR_CASPER_HI	(UNM_CRB_I2Q + 0x0003c)
+#define	UNM_I2Q_MSG_HDR_LO(I)	(UNM_CRB_I2Q + 0x00100 + (I)*0x8)
+#define	UNM_I2Q_MSG_HDR_HI(I)	(UNM_CRB_I2Q + 0x00104 + (I)*0x8)
+
+/*
+ * List the bit positions in the registers of the interrupt sources.
+ */
+typedef	enum {
+	UNM_I2Q_SRC_PCI32		= 0, /* PCI32 block */
+	UNM_I2Q_SRC_PCIE		= 1, /* PCI-Express block */
+	UNM_I2Q_SRC_CASPER		= 2, /* Casper */
+	UNM_I2Q_SRC_CASPER_ERR	= 3, /* Casper error */
+	UNM_I2Q_SRC_PEG_0		= 4, /* Peg 0  */
+	UNM_I2Q_SRC_PEG_1		= 5, /* Peg 1 */
+	UNM_I2Q_SRC_PEG_2		= 6, /* Peg 2 */
+	UNM_I2Q_SRC_PEG_3		= 7, /* Peg 3 */
+	UNM_I2Q_SRC_PEG_DCACHE	= 8, /* Peg Data cache */
+	UNM_I2Q_SRC_PEG_ICACHE	= 9, /* Peg Instruction cache */
+	UNM_I2Q_SRC_DMA0		= 10, /* DMA engine 0 */
+	UNM_I2Q_SRC_DMA1		= 11, /* DMA engine 1 */
+	UNM_I2Q_SRC_DMA2		= 12, /* DMA engine 2 */
+	NM_I2Q_SRC_DMA3			= 13, /* DMA engine 3 */
+	UNM_I2Q_SRC_LPC			= 14, /*  */
+	UNM_I2Q_SRC_SMB			= 15, /*  */
+	UNM_I2Q_SRC_TIMER		= 16, /* One of the global timers */
+	UNM_I2Q_SRC_SQG0		= 17, /* SQM SQG0 empty->non-empty */
+	UNM_I2Q_SRC_SQG1		= 18, /* SQM SQG1 empty->non-empty */
+	UNM_I2Q_SRC_SQG2		= 19, /* SQM SQG2 empty->non-empty */
+	UNM_I2Q_SRC_SQG3		= 20, /* SQM SQG3 empty->non-empty */
+	UNM_I2Q_SRC_SQG0_LW		= 21, /* SQM SQG0 low on free buffers */
+	UNM_I2Q_SRC_SQG1_LW		= 22, /* SQM SQG1 low on free buffers */
+	UNM_I2Q_SRC_SQG2_LW		= 23, /* SQM SQG2 low on free buffers */
+	UNM_I2Q_SRC_SQG3_LW		= 24, /* SQM SQG3 low on free buffers */
+	UNM_I2Q_SRC_PQM_0		= 25, /* PQM group 0 */
+	UNM_I2Q_SRC_PQM_1		= 26, /* PQM group 1 */
+	UNM_I2Q_SRC_PQM_2		= 27, /* PQM group 2 */
+	UNM_I2Q_SRC_PQM_3		= 28, /* PQM group 3 */
+	/* [29:31] reserved */
+	UNM_I2Q_SRC_SW_0		= 32, /* SW INT 0 */
+	UNM_I2Q_SRC_SW_1		= 33, /* SW INT 1 */
+	UNM_I2Q_SRC_SW_2		= 34, /* SW INT 2 */
+	UNM_I2Q_SRC_SW_3		= 35, /* SW INT 3 */
+	UNM_I2Q_SRC_SW_4		= 36, /* SW INT 4 */
+	UNM_I2Q_SRC_SW_5		= 37, /* SW INT 5 */
+	UNM_I2Q_SRC_SW_6		= 38, /* SW INT 6 */
+	UNM_I2Q_SRC_SW_7		= 39, /* SW INT 7 */
+	UNM_I2Q_SRC_SRE_EPG		= 40, /* SRE/EPG aggregate interrupt */
+	UNM_I2Q_SRC_XDMA		= 41, /* XDMA engine */
+	UNM_I2Q_SRC_MN			= 42, /* DDR interface unit */
+	UNM_I2Q_SRC_NIU			= 43, /* Network interface unit */
+	UNM_I2Q_SRC_SN			= 44, /* QDR interface unit */
+	UNM_I2Q_SRC_CAM			= 45, /* CAM */
+	UNM_I2Q_SRC_EXT1		= 46, /* External 1 */
+	UNM_I2Q_SRC_EXT2		= 47, /* External 2 */
+	/* [48:63] reserved */
+	UNM_I2Q_SRC_MAX			= 47, /* max used interrupt line */
+	UNM_I2Q_SRC_MAX_LO		= 32, /* max bits in "lo" register */
+} unm_i2q_source_t;
+
+/*
+ * Interrupt Source Enable/Clear registers for the I2Q.
+ */
+typedef struct {
+    unm_crbword_t  source:32;    /* int enable/status bits */
+} unm_i2q_source_lo_t;
+
+typedef struct {
+	unm_crbword_t	source:16, /* int enable/status bits */
+					rsvd:16;
+} unm_i2q_source_hi_t;
+
+/*
+ * List the possible interrupt sources and the
+ * control operations to be performed for each.
+ */
+typedef	enum {
+	UNM_I2Q_CTL_SRCUNKNOWN = 0, /* undefined */
+	UNM_I2Q_CTL_PCI, /* PCI block */
+	UNM_I2Q_CTL_CASPER, /* Casper */
+	UNM_I2Q_CTL_QM /* Queue Manager */
+} unm_i2q_ctl_src_t;
+
+typedef	enum {
+	UNM_I2Q_CTL_OPUNKNOWN = 0, /* undefined */
+	UNM_I2Q_CTL_ADD, /* add int'ing for that source */
+	UNM_I2Q_CTL_DEL  /* stop int'ing for that source */
+} unm_i2q_ctl_op_t;
+
+/*
+ * Definitions relating to access/control of the Secondary Queue Manager
+ * h/w block.
+ */
+/*
+ * Configuration registers.
+ */
+#define	UNM_SQM_BASE(G)                                        	\
+	((G) == 0 ? UNM_CRB_SQM_NET_0 :                             \
+	((G) == 1 ? UNM_CRB_SQM_NET_1 :                         \
+	((G) == 2 ? UNM_CRB_SQM_NET_2 : UNM_CRB_SQM_NET_3)))
+
+#define	UNM_SQM_INT_ENABLE(G)		(UNM_SQM_BASE(G) + 0x00018)
+#define	UNM_SQM_INT_STATUS(G)		(UNM_SQM_BASE(G) + 0x0001c)
+#define	UNN_SQM_SCRATCHPAD(G)		(UNM_SQM_BASE(G) + 0x01000)
+
+#define	UNM_SQM_MAX_GRP			4  /* num groups per side */
+#define	UNM_SQM_MAX_SUBQ		16 /* num Q's per type-0 group */
+#define	UNM_SQM_MAX_SUBGRP		4  /* subgrps per type-1 group */
+
+#define	UNM_SQM_MAX_TYPE_1_NUM		(256*1024)
+
+/*
+ * Interrupt enables and interrupt status for all 16 queues in a group.
+ */
+typedef	struct {
+	unm_crbword_t	queues:16, /* enable/status: 0x1=Q0, 0x8000=Q15 */
+					rsvd:16;
+} unm_sqm_int_enstat_t;
+
+/*
+ * Control operation for an SQM Group interrupt.
+ */
+typedef	enum {
+	UNM_SQM_INTOP_OPUNKNOWN = 0, /* undefined */
+	UNM_SQM_INTOP_GET, /* return all bits for that group */
+	UNM_SQM_INTOP_SET, /* assign all bits for that group */
+	UNM_SQM_INTOP_ADD, /* set one bit for that group */
+	UNM_SQM_INTOP_DEL  /* clear one bit for that group */
+} unm_sqm_int_op_t;
+typedef enum {
+	UNM_SQM_INTARG_ARGUNKNOWN = 0, /* undefined */
+	UNM_SQM_INTARG_ENABLE, /* affect the 'enable' register */
+	UNM_SQM_INTARG_STATUS  /* affect the 'status' register */
+} unm_sqm_int_arg_t;
+
+int unm_sqm_int_control(unm_sqm_int_op_t op, unm_sqm_int_arg_t arg,
+    int side, int group, int queue, int *image);
+
+
+int unm_crb_read(unsigned long off, void *data);
+native_t unm_crb_read_val(unsigned long off);
+int unm_crb_write(unsigned long off, void *data);
+int unm_crb_writelit(unsigned long off, int data);
+int unm_imb_read(unsigned long off, void *data);
+int unm_imb_write(unsigned long off, void *data);
+int unm_imb_writelit64(unsigned long off, __uint64_t data);
+
+unsigned long unm_xport_lock(void);
+void unm_xport_unlock(unsigned long);
+
+#define	UNM_CRB_READ_VAL(ADDR) unm_crb_read_val((ADDR))
+#define	UNM_CRB_READ(ADDR, VALUE) unm_crb_read((ADDR), (unm_crbword_t *)(VALUE))
+#define	UNM_CRB_READ_CHECK(ADDR, VALUE)		\
+	do {								\
+		if (unm_crb_read(ADDR, VALUE))	\
+			return (-1);					\
+	} while (0)
+#define	UNM_CRB_WRITE_CHECK(ADDR, VALUE)		\
+	do {								\
+		if (unm_crb_write(ADDR, VALUE))			\
+			return (-1);			\
+	} while (0)
+#define	UNM_CRB_WRITELIT(ADDR, VALUE)			\
+	do {						\
+		unm_crb_writelit(ADDR, VALUE);			\
+	} while (0)
+#define	UNM_CRB_WRITE(ADDR, VALUE)				\
+	do {					\
+		unm_crb_write(ADDR, VALUE);				\
+	} while (0)
+#define	UNM_CRB_WRITELIT_CHECK(ADDR, VALUE)			\
+	do {								\
+		if (unm_crb_writelit(ADDR, VALUE))	\
+			return (-1);		\
+	} while (0)
+
+#define	UNM_IMB_READ_CHECK(ADDR, VALUE)				\
+	do {					\
+		if (unm_imb_read(ADDR, VALUE))		\
+			return (-1);		\
+	} while (0)
+#define	UNM_IMB_WRITE_CHECK(ADDR, VALUE)			\
+	do {						\
+		if (unm_imb_write(ADDR, VALUE))		\
+			return (-1);		\
+	} while (0)
+#define	UNM_IMB_WRITELIT_CHECK(ADDR, VALUE)			\
+	do {						\
+		if (unm_imb_writelit64(ADDR, VALUE))	\
+			return (-1);	\
+	} while (0)
+
+/*
+ * Configuration registers.
+ */
+#ifdef PCIX
+#define	UNM_DMA_BASE(U)    (UNM_CRB_PCIX_HOST + 0x20000 + ((U)<<16))
+#else
+#define	UNM_DMA_BASE(U)    (UNM_CRB_PCIX_MD + 0x20000 + ((U)<<16))
+#endif
+#define	UNM_DMA_COMMAND(U)    (UNM_DMA_BASE(U) + 0x00008)
+
+
+#define	PCIE_SEM2_LOCK		(0x1c010)  /* Flash lock  */
+#define	PCIE_SEM2_UNLOCK	(0x1c014)  /* Flash unlock */
+#define	PCIE_SEM3_LOCK		(0x1c018)  /* Phy lock */
+#define	PCIE_SEM3_UNLOCK	(0x1c01c)  /* Phy unlock */
+#define	PCIE_SEM4_LOCK		(0x1c020)  /* I2C lock */
+#define	PCIE_SEM4_UNLOCK	(0x1c024)  /* I2C unlock */
+#define	PCIE_SEM5_LOCK		(0x1c028)  /* API lock */
+#define	PCIE_SEM5_UNLOCK	(0x1c02c)  /* API unlock */
+#define	PCIE_SEM6_LOCK		(0x1c030)  /* sw lock */
+#define	PCIE_SEM6_UNLOCK	(0x1c034)  /* sw unlock */
+#define	PCIE_SEM7_LOCK		(0x1c038)  /* crb win lock */
+#define	PCIE_SEM7_UNLOCK	(0x1c03c)  /* crbwin unlock */
+
+
+#define	PCIE_PS_STRAP_RESET	(0x18000)
+
+#define	M25P_INSTR_WREN		0x06
+#define	M25P_INSTR_RDSR		0x05
+#define	M25P_INSTR_PP		0x02
+#define	M25P_INSTR_SE		0xd8
+#define	CAM_RAM_P2I_ENABLE	0xc
+#define	CAM_RAM_P2D_ENABLE	0x8
+#define	PCIX_IMBTAG			(0x18004)
+#define	UNM_MAC_ADDR_CNTL_REG	(UNM_CRB_NIU + 0x1000)
+
+#define	UNM_MULTICAST_ADDR_HI_0		(UNM_CRB_NIU + 0x1010)
+#define	UNM_MULTICAST_ADDR_HI_1		(UNM_CRB_NIU + 0x1014)
+#define	UNM_MULTICAST_ADDR_HI_2		(UNM_CRB_NIU + 0x1018)
+#define	UNM_MULTICAST_ADDR_HI_3		(UNM_CRB_NIU + 0x101c)
+
+#define	M_UNICAST_ADDR_BASE			(UNM_CRB_NIU + 0x1080)
+
+#define	UNM_UNICAST_ADDR_LO_0_0		(UNM_CRB_NIU + 0x1080) // port 0
+#define	UNM_UNICAST_ADDR_HI_0_0		(UNM_CRB_NIU + 0x1084)
+#define	UNM_UNICAST_ADDR_LO_0_1		(UNM_CRB_NIU + 0x1088)
+#define	UNM_UNICAST_ADDR_HI_0_1		(UNM_CRB_NIU + 0x108c)
+#define	UNM_UNICAST_ADDR_LO_0_2		(UNM_CRB_NIU + 0x1090)
+#define	UNM_UNICAST_ADDR_HI_0_2		(UNM_CRB_NIU + 0x1084)
+#define	UNM_UNICAST_ADDR_LO_0_3		(UNM_CRB_NIU + 0x1098)
+#define	UNM_UNICAST_ADDR_HI_0_3		(UNM_CRB_NIU + 0x109c)
+
+#define	UNM_UNICAST_ADDR_LO_1_0		(UNM_CRB_NIU + 0x10a0)
+#define	UNM_UNICAST_ADDR_HI_1_0		(UNM_CRB_NIU + 0x10a4)
+#define	UNM_UNICAST_ADDR_LO_1_1		(UNM_CRB_NIU + 0x10a8)
+#define	UNM_UNICAST_ADDR_HI_1_1		(UNM_CRB_NIU + 0x10ac)
+#define	UNM_UNICAST_ADDR_LO_1_2		(UNM_CRB_NIU + 0x10b0)
+#define	UNM_UNICAST_ADDR_HI_1_2		(UNM_CRB_NIU + 0x10b4)
+#define	UNM_UNICAST_ADDR_LO_1_3		(UNM_CRB_NIU + 0x10b8)
+#define	UNM_UNICAST_ADDR_HI_1_3		(UNM_CRB_NIU + 0x10bc)
+
+#define	UNM_UNICAST_ADDR_LO_2_0		(UNM_CRB_NIU + 0x10c0)
+#define	UNM_UNICAST_ADDR_HI_2_0		(UNM_CRB_NIU + 0x10c4)
+#define	UNM_UNICAST_ADDR_LO_2_1		(UNM_CRB_NIU + 0x10c8)
+#define	UNM_UNICAST_ADDR_HI_2_1		(UNM_CRB_NIU + 0x10cc)
+#define	UNM_UNICAST_ADDR_LO_2_2		(UNM_CRB_NIU + 0x10d0)
+#define	UNM_UNICAST_ADDR_HI_2_2		(UNM_CRB_NIU + 0x10d4)
+#define	UNM_UNICAST_ADDR_LO_2_3		(UNM_CRB_NIU + 0x10d8)
+#define	UNM_UNICAST_ADDR_HI_2_3		(UNM_CRB_NIU + 0x10dc)
+
+#define	UNM_UNICAST_ADDR_LO_3_0		(UNM_CRB_NIU + 0x10e0)
+#define	UNM_UNICAST_ADDR_HI_3_0		(UNM_CRB_NIU + 0x10e4)
+#define	UNM_UNICAST_ADDR_LO_3_1		(UNM_CRB_NIU + 0x10e8)
+#define	UNM_UNICAST_ADDR_HI_3_1		(UNM_CRB_NIU + 0x10ec)
+#define	UNM_UNICAST_ADDR_LO_3_2		(UNM_CRB_NIU + 0x10f0)
+#define	UNM_UNICAST_ADDR_HI_3_2		(UNM_CRB_NIU + 0x10f4)
+#define	UNM_UNICAST_ADDR_LO_3_3		(UNM_CRB_NIU + 0x10f8)
+#define	UNM_UNICAST_ADDR_HI_3_3		(UNM_CRB_NIU + 0x10fc)
+
+#define	UNM_MULTICAST_ADDR_BASE		(UNM_CRB_NIU + 0x1100)
+
+// BASE ADDRESS FOR POOL/PORT 0
+#define	UNM_MULTICAST_ADDR_LO_0		(UNM_CRB_NIU + 0x1100)
+// FOR PORT 1
+#define	UNM_MULTICAST_ADDR_LO_1		(UNM_CRB_NIU + 0x1180)
+// FOR PORT 2
+#define	UNM_MULTICAST_ADDR_LO_2		(UNM_CRB_NIU + 0x1200)
+// PORT 3
+#define	UNM_MULTICAST_ADDR_LO_3		(UNM_CRB_NIU + 0x1280)
+
+#define	PHAN_VENDOR_ID			0x4040
+
+#define	CAM_RAM_PEG_ENABLES  0x4
+
+/*
+ * The PCI VendorID and DeviceID for our board.
+ */
+#define	PCI_VENDOR_ID_NX			0x4040
+#define	PCI_DEVICE_ID_NX_XG			0x0001
+#define	PCI_DEVICE_ID_NX_CX4		0x0002
+#define	PCI_DEVICE_ID_NX_QG			0x0003
+#define	PCI_DEVICE_ID_NX_IMEZ		0x0004
+#define	PCI_DEVICE_ID_NX_HMEZ		0x0005
+#define	PCI_DEVICE_ID_NX_IMEZ_DUP	0x0024
+#define	PCI_DEVICE_ID_NX_HMEZ_DUP	0x0025
+#define	PCI_DEVICE_ID_NX_P3_XG		0x0100
+
+/*
+ * Time base tick control registers (global and per-flow).
+ */
+
+typedef struct {
+	/* half period of time cycle */
+	/* global: in units of core clock */
+	/* per-flow: in units of global ticks */
+    unm_crbword_t   count:16,
+					rsvd:15,
+					enable:1;   /* 0=disable, 1=enable */
+} unm_timer_tickctl_t;
+
+
+typedef struct
+{
+	unm_crbword_t
+	id_pool_0:2,
+	enable_xtnd_0:1,
+	rsvd1:1,
+	id_pool_1:2,
+	enable_xtnd_1:1,
+	rsvd2:1,
+	id_pool_2:2,
+	enable_xtnd_2:1,
+	rsvd3:1,
+	id_pool_3:2,
+	enable_xtnd_3:1,
+    rsvd4:9,
+	mode_select:2,
+	rsvd5:2,
+	enable_pool:4;
+} unm_mac_addr_cntl_t;
+
+typedef struct {
+    unm_crbword_t	start:1,
+					enable:1,
+					command:1,
+					busy:1,
+					rsvd:28;
+} unm_miu_test_agt_ctrl_t;
+
+#define	UNM_MIU_TEST_AGENT_CMD_READ 0
+#define	UNM_MIU_TEST_AGENT_CMD_WRITE 1
+#define	UNM_MIU_TEST_AGENT_BUSY 1
+#define	UNM_MIU_TEST_AGENT_ENABLE 1
+#define	UNM_MIU_TEST_AGENT_START 1
+
+#define	UNM_MIU_MN_CONTROL		(UNM_CRB_DDR_NET + MIU_CONTROL)
+#define	UNM_MIU_MN_TAG			(UNM_CRB_DDR_NET + MIU_TAG)
+#define	UNM_MIU_MN_TEST_AGT_ADDR_LO   (UNM_CRB_DDR_NET + MIU_TEST_AGT_ADDR_LO)
+#define	UNM_MIU_MN_TEST_AGT_ADDR_HI   (UNM_CRB_DDR_NET + MIU_TEST_AGT_ADDR_HI)
+#define	UNM_MIU_MN_TEST_AGT_WRDATA_LO (UNM_CRB_DDR_NET + MIU_TEST_AGT_WRDATA_LO)
+#define	UNM_MIU_MN_TEST_AGT_WRDATA_HI (UNM_CRB_DDR_NET + MIU_TEST_AGT_WRDATA_HI)
+#define	UNM_MIU_MN_TEST_AGT_CTRL	(UNM_CRB_DDR_NET + MIU_TEST_AGT_CTRL)
+#define	UNM_MIU_MN_TEST_AGT_RDDATA_LO (UNM_CRB_DDR_NET + MIU_TEST_AGT_RDDATA_LO)
+#define	UNM_MIU_MN_TEST_AGT_RDDATA_HI (UNM_CRB_DDR_NET + MIU_TEST_AGT_RDDATA_HI)
+
+#define	UNM_SIU_SN_TEST_AGT_ADDR_LO   (UNM_CRB_QDR_NET + SIU_TEST_AGT_ADDR_LO)
+#define	UNM_SIU_SN_TEST_AGT_ADDR_HI   (UNM_CRB_QDR_NET + SIU_TEST_AGT_ADDR_HI)
+#define	UNM_SIU_SN_TEST_AGT_WRDATA_LO (UNM_CRB_QDR_NET + SIU_TEST_AGT_WRDATA_LO)
+#define	UNM_SIU_SN_TEST_AGT_WRDATA_HI (UNM_CRB_QDR_NET + SIU_TEST_AGT_WRDATA_HI)
+#define	UNM_SIU_SN_TEST_AGT_CTRL	(UNM_CRB_QDR_NET + SIU_TEST_AGT_CTRL)
+#define	UNM_SIU_SN_TEST_AGT_RDDATA_LO (UNM_CRB_QDR_NET + SIU_TEST_AGT_RDDATA_LO)
+#define	UNM_SIU_SN_TEST_AGT_RDDATA_HI (UNM_CRB_QDR_NET + SIU_TEST_AGT_RDDATA_HI)
+
+#define	NX_IS_SYSTEM_CUT_THROUGH(MIU_CTRL)	(((MIU_CTRL) & 0x4) ? 1 : 0)
+#define	NX_SET_SYSTEM_LEGACY(MIU_CTRL)		{(MIU_CTRL) &= ~0x4; }
+#define	NX_SET_SYSTEM_CUT_THROUGH(MIU_CTRL)	{(MIU_CTRL) |= 0x4; }
+
+#endif /* __UNM_INC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_ndd.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,499 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include "unm_nic.h"
+
+static char transfer_speed_propname[] = "transfer-speed";
+static char speed_propname[] = "speed";
+static char duplex_propname[] = "full-duplex";
+
+/*
+ * Notes:
+ *	The first character of the <name> field encodes the read/write
+ *	status of the parameter:
+ *		'-' => read-only,
+ *		'+' => read/write,
+ *		'!' => invisible!
+ *
+ *	For writable parameters, we check for a driver property with the
+ *	same name; if found, and its value is in range, we initialise
+ *	the parameter from the property, overriding the default in the
+ *	table below.
+ *
+ *	A NULL in the <name> field terminates the array.
+ *
+ *	The <info> field is used here to provide the index of the
+ *	parameter to be initialised; thus it doesn't matter whether
+ *	this table is kept ordered or not.
+ *
+ *	The <info> field in the per-instance copy, on the other hand,
+ *	is used to count assignments so that we can tell when a magic
+ *	parameter has been set via ndd (see unm_param_set()).
+ */
+static const nd_param_t nd_template_10000[] = {
+/*	info		min	max	init	r/w+name		*/
+
+/* Our hardware capabilities */
+{ PARAM_AUTONEG_CAP,	    0,	  1,	1,	"-autoneg_cap"		},
+{ PARAM_PAUSE_CAP,	    0,	  1,	1,	"-pause_cap"		},
+{ PARAM_ASYM_PAUSE_CAP,	    0,	  1,	1,	"-asym_pause_cap"	},
+{ PARAM_10000FDX_CAP,	    0,	  1,	1,	"-10000fdx_cap"		},
+{ PARAM_1000FDX_CAP,	    0,	  1,	0,	"-1000fdx_cap"		},
+{ PARAM_1000HDX_CAP,	    0,	  1,	0,	"-1000hdx_cap"		},
+{ PARAM_100T4_CAP,	    0,	  1,	0,	"-100T4_cap"		},
+{ PARAM_100FDX_CAP,	    0,	  1,	0,	"-100fdx_cap"		},
+{ PARAM_100HDX_CAP,	    0,	  1,	0,	"-100hdx_cap"		},
+{ PARAM_10FDX_CAP,	    0,	  1,	0,	"-10fdx_cap"		},
+{ PARAM_10HDX_CAP,	    0,	  1,	0,	"-10hdx_cap"		},
+
+/* Our advertised capabilities */
+{ PARAM_ADV_AUTONEG_CAP,    0,	  1,	1,	"-adv_autoneg_cap"	},
+{ PARAM_ADV_PAUSE_CAP,	    0,	  1,	1,	"+adv_pause_cap"	},
+{ PARAM_ADV_ASYM_PAUSE_CAP, 0,	  1,	1,	"+adv_asym_pause_cap"	},
+{ PARAM_ADV_10000FDX_CAP,   0,	  1,	1,	"+adv_10000fdx_cap"	},
+{ PARAM_ADV_1000FDX_CAP,    0,	  1,	0,	"+adv_1000fdx_cap"	},
+{ PARAM_ADV_1000HDX_CAP,    0,	  1,	0,	"-adv_1000hdx_cap"	},
+{ PARAM_ADV_100T4_CAP,	    0,	  1,	0,	"-adv_100T4_cap"	},
+{ PARAM_ADV_100FDX_CAP,	    0,	  1,	0,	"+adv_100fdx_cap"	},
+{ PARAM_ADV_100HDX_CAP,	    0,	  1,	0,	"+adv_100hdx_cap"	},
+{ PARAM_ADV_10FDX_CAP,	    0,	  1,	0,	"+adv_10fdx_cap"	},
+{ PARAM_ADV_10HDX_CAP,	    0,	  1,	0,	"+adv_10hdx_cap"	},
+
+/* Current operating modes */
+{ PARAM_LINK_STATUS,	    0,	  1,	0,	"-link_status"		},
+{ PARAM_LINK_SPEED,	    0,    10000, 0,	"-link_speed"		},
+{ PARAM_LINK_DUPLEX,	    0,	  2,	0,	"-link_duplex"		},
+
+/* Loopback status */
+{ PARAM_LOOP_MODE,	    0,	  2,	0,	"-loop_mode"		},
+
+/* Terminator */
+{ PARAM_COUNT,		    0,	  0,	0,	NULL			}
+};
+
+static const nd_param_t nd_template_1000[] = {
+/*	info		min	max	init	r/w+name		*/
+
+/* Our hardware capabilities */
+{ PARAM_AUTONEG_CAP,	    0,	  1,	1,	"-autoneg_cap"		},
+{ PARAM_PAUSE_CAP,	    0,	  1,	1,	"-pause_cap"		},
+{ PARAM_ASYM_PAUSE_CAP,	    0,	  1,	1,	"-asym_pause_cap"	},
+{ PARAM_1000FDX_CAP,	    0,	  1,	1,	"-1000fdx_cap"		},
+{ PARAM_1000HDX_CAP,	    0,	  1,	0,	"-1000hdx_cap"		},
+{ PARAM_100T4_CAP,	    0,	  1,	0,	"-100T4_cap"		},
+{ PARAM_100FDX_CAP,	    0,	  1,	1,	"-100fdx_cap"		},
+{ PARAM_100HDX_CAP,	    0,	  1,	1,	"-100hdx_cap"		},
+{ PARAM_10FDX_CAP,	    0,	  1,	1,	"-10fdx_cap"		},
+{ PARAM_10HDX_CAP,	    0,	  1,	1,	"-10hdx_cap"		},
+
+/* Our advertised capabilities */
+{ PARAM_ADV_AUTONEG_CAP,    0,	  1,	1,	"-adv_autoneg_cap"	},
+{ PARAM_ADV_PAUSE_CAP,	    0,	  1,	1,	"+adv_pause_cap"	},
+{ PARAM_ADV_ASYM_PAUSE_CAP, 0,	  1,	1,	"+adv_asym_pause_cap"	},
+{ PARAM_ADV_1000FDX_CAP,    0,	  1,	1,	"+adv_1000fdx_cap"	},
+{ PARAM_ADV_1000HDX_CAP,    0,	  1,	0,	"-adv_1000hdx_cap"	},
+{ PARAM_ADV_100T4_CAP,	    0,	  1,	0,	"-adv_100T4_cap"	},
+{ PARAM_ADV_100FDX_CAP,	    0,	  1,	1,	"+adv_100fdx_cap"	},
+{ PARAM_ADV_100HDX_CAP,	    0,	  1,	1,	"+adv_100hdx_cap"	},
+{ PARAM_ADV_10FDX_CAP,	    0,	  1,	1,	"+adv_10fdx_cap"	},
+{ PARAM_ADV_10HDX_CAP,	    0,	  1,	1,	"+adv_10hdx_cap"	},
+
+/* Current operating modes */
+{ PARAM_LINK_STATUS,	    0,	  1,	0,	"-link_status"		},
+{ PARAM_LINK_SPEED,	    0,    1000,	0,	"-link_speed"		},
+{ PARAM_LINK_DUPLEX,	    0,	  2,	0,	"-link_duplex"		},
+
+/* Loopback status */
+{ PARAM_LOOP_MODE,	    0,	  2,	0,	"-loop_mode"		},
+
+/* Terminator */
+{ PARAM_COUNT,		    0,	  0,	0,	NULL			}
+};
+
+/*  ============== NDD Support Functions ===============  */
+
+/*
+ * Extracts the value from the unm parameter array and prints
+ * the parameter value. cp points to the required parameter.
+ */
+/* ARGSUSED */
+static int
+unm_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *credp)
+{
+	nd_param_t *ndp;
+
+	ndp = (nd_param_t *)(uintptr_t)cp;
+	(void) mi_mpprintf(mp, "%d", ndp->ndp_val);
+
+	return (0);
+}
+
+/*
+ * Validates the request to set a UNM parameter to a specific value.
+ * If the request is OK, the parameter is set.  Also the <info> field
+ * is incremented to show that the parameter was touched, even though
+ * it may have been set to the same value it already had.
+ */
+/* ARGSUSED */
+static int
+unm_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *credp)
+{
+	nd_param_t *ndp;
+	int new_value;
+	char *end;
+
+	ndp = (nd_param_t *)(uintptr_t)cp;
+	new_value = mi_strtol(value, &end, 10);
+	if (end == value)
+		return (EINVAL);
+	if (new_value < ndp->ndp_min || new_value > ndp->ndp_max)
+		return (EINVAL);
+
+	ndp->ndp_val = new_value;
+	ndp->ndp_info += 1;
+	return (0);
+}
+
+/*
+ * Initialise the per-instance parameter array from the global prototype,
+ * and register each element with the named dispatch handler using nd_load()
+ */
+static int
+unm_param_register(unm_adapter *adapter)
+{
+	const nd_param_t *tmplp;
+	dev_info_t *dip;
+	nd_param_t *ndp;
+	caddr_t *nddpp;
+	pfi_t setfn;
+	char *nm;
+	int pval;
+
+	dip = adapter->dip;
+	nddpp = &adapter->nd_data_p;
+	ASSERT(*nddpp == NULL);
+
+	if (adapter->ahw.board_type == UNM_NIC_XGBE)
+		tmplp = nd_template_10000;
+	else
+		tmplp = nd_template_1000;
+
+	for (; tmplp->ndp_name != NULL; ++tmplp) {
+		/*
+		 * Copy the template from nd_template[] into the
+		 * proper slot in the per-instance parameters,
+		 * then register the parameter with nd_load()
+		 */
+		ndp = &adapter->nd_params[tmplp->ndp_info];
+		*ndp = *tmplp;
+		nm = &ndp->ndp_name[0];
+		setfn = unm_param_set;
+
+		switch (*nm) {
+		default:
+		case '!':
+			continue;
+
+		case '+':
+			break;
+
+		case '-':
+			setfn = NULL;
+			break;
+		}
+
+		if (!nd_load(nddpp, ++nm, unm_param_get, setfn, (caddr_t)ndp))
+			goto nd_fail;
+
+		/*
+		 * If the parameter is writable, and there's a property
+		 * with the same name, and its value is in range, we use
+		 * it to initialise the parameter.  If it exists but is
+		 * out of range, it's ignored.
+		 */
+		if (setfn && UNM_PROP_EXISTS(dip, nm)) {
+			pval = UNM_PROP_GET_INT(dip, nm);
+			if (pval >= ndp->ndp_min && pval <= ndp->ndp_max)
+				ndp->ndp_val = pval;
+		}
+	}
+
+	DPRINTF(1, (CE_WARN, "unm_param_register: OK"));
+	return (DDI_SUCCESS);
+
+nd_fail:
+	if (adapter->ahw.board_type == UNM_NIC_XGBE) {
+		cmn_err(CE_WARN,
+		    "unm_param_register: FAILED at index %d [info %d]",
+		    (int)(tmplp-nd_template_10000), tmplp->ndp_info);
+	} else {
+		cmn_err(CE_WARN,
+		    "unm_param_register: FAILED at index %d [info %d]",
+		    (int)(tmplp-nd_template_1000), tmplp->ndp_info);
+	}
+	nd_free(nddpp);
+	return (DDI_FAILURE);
+}
+
+int
+unm_nd_init(unm_adapter *adapter)
+{
+	dev_info_t *dip;
+	int duplex;
+	int speed;
+
+	/*
+	 * Register all the per-instance properties, initialising
+	 * them from the table above or from driver properties set
+	 * in the .conf file
+	 */
+	if (unm_param_register(adapter) != DDI_SUCCESS)
+		return (-1);
+
+	/*
+	 * The link speed may be forced to 1000 or 10000 Mbps using
+	 * the property "transfer-speed". This may be done in OBP by
+	 * using the command "apply transfer-speed=<speed> <device>".
+	 * The speed may be 1000 or 10000 - any other value will be
+	 * ignored.  Note that this does *enables* autonegotiation, but
+	 * restricts it to the speed specified by the property.
+	 */
+	dip = adapter->dip;
+	if (UNM_PROP_EXISTS(dip, transfer_speed_propname)) {
+
+		speed = UNM_PROP_GET_INT(dip, transfer_speed_propname);
+
+		switch (speed) {
+		case 10000:
+			adapter->param_adv_autoneg = 1;
+			adapter->param_adv_10000fdx = 1;
+			adapter->param_adv_1000fdx = 0;
+			adapter->param_adv_1000hdx = 0;
+			adapter->param_adv_100fdx = 0;
+			adapter->param_adv_100hdx = 0;
+			adapter->param_adv_10fdx = 0;
+			adapter->param_adv_10hdx = 0;
+			break;
+
+		case 1000:
+			adapter->param_adv_autoneg = 1;
+			adapter->param_adv_1000fdx = 1;
+			adapter->param_adv_1000hdx = 1;
+			adapter->param_adv_100fdx = 0;
+			adapter->param_adv_100hdx = 0;
+			adapter->param_adv_10fdx = 0;
+			adapter->param_adv_10hdx = 0;
+			break;
+
+		case 100:
+			adapter->param_adv_autoneg = 1;
+			adapter->param_adv_1000fdx = 0;
+			adapter->param_adv_1000hdx = 0;
+			adapter->param_adv_100fdx = 1;
+			adapter->param_adv_100hdx = 1;
+			adapter->param_adv_10fdx = 0;
+			adapter->param_adv_10hdx = 0;
+			break;
+
+		case 10:
+			adapter->param_adv_autoneg = 1;
+			adapter->param_adv_1000fdx = 0;
+			adapter->param_adv_1000hdx = 0;
+			adapter->param_adv_100fdx = 0;
+			adapter->param_adv_100hdx = 0;
+			adapter->param_adv_10fdx = 1;
+			adapter->param_adv_10hdx = 1;
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * Also check the "speed" and "full-duplex" properties.  Setting
+	 * these properties will override all other settings and *disable*
+	 * autonegotiation, so both should be specified if either one is.
+	 * Otherwise, the unspecified parameter will be set to a default
+	 * value (10000Mb/s, full-duplex).
+	 */
+	if (UNM_PROP_EXISTS(dip, speed_propname) ||
+	    UNM_PROP_EXISTS(dip, duplex_propname)) {
+
+		adapter->param_adv_autoneg = 0;
+		adapter->param_adv_10000fdx = 1;
+		adapter->param_adv_1000fdx = 1;
+		adapter->param_adv_1000hdx = 1;
+		adapter->param_adv_100fdx = 1;
+		adapter->param_adv_100hdx = 1;
+		adapter->param_adv_10fdx = 1;
+		adapter->param_adv_10hdx = 1;
+
+		speed = UNM_PROP_GET_INT(dip, speed_propname);
+		duplex = UNM_PROP_GET_INT(dip, duplex_propname);
+
+		switch (speed) {
+		case 10000:
+		default:
+			adapter->param_adv_1000fdx = 0;
+			adapter->param_adv_1000hdx = 0;
+			adapter->param_adv_100fdx = 0;
+			adapter->param_adv_100hdx = 0;
+			adapter->param_adv_10fdx = 0;
+			adapter->param_adv_10hdx = 0;
+			break;
+
+		case 1000:
+			adapter->param_adv_10000fdx = 0;
+			adapter->param_adv_100fdx = 0;
+			adapter->param_adv_100hdx = 0;
+			adapter->param_adv_10fdx = 0;
+			adapter->param_adv_10hdx = 0;
+			break;
+
+		case 100:
+			adapter->param_adv_10000fdx = 0;
+			adapter->param_adv_1000fdx = 0;
+			adapter->param_adv_1000hdx = 0;
+			adapter->param_adv_10fdx = 0;
+			adapter->param_adv_10hdx = 0;
+			break;
+
+		case 10:
+			adapter->param_adv_10000fdx = 0;
+			adapter->param_adv_1000fdx = 0;
+			adapter->param_adv_1000hdx = 0;
+			adapter->param_adv_100fdx = 0;
+			adapter->param_adv_100hdx = 0;
+			break;
+		}
+
+		switch (duplex) {
+		default:
+		case 1:
+			adapter->param_adv_1000hdx = 0;
+			adapter->param_adv_100hdx = 0;
+			adapter->param_adv_10hdx = 0;
+			break;
+
+		case 0:
+			adapter->param_adv_10000fdx = 0;
+			adapter->param_adv_1000fdx = 0;
+			adapter->param_adv_100fdx = 0;
+			adapter->param_adv_10fdx = 0;
+			break;
+		}
+	}
+
+	DPRINTF(1, (CE_WARN, "unm_nd_init: autoneg %d"
+	    "pause %d asym_pause %d "
+	    "10000fdx %d "
+	    "1000fdx %d 1000hdx %d "
+	    "100fdx %d 100hdx %d "
+	    "10fdx %d 10hdx %d ",
+	    adapter->param_adv_autoneg,
+	    adapter->param_adv_pause, adapter->param_adv_asym_pause,
+	    adapter->param_adv_10000fdx,
+	    adapter->param_adv_1000fdx, adapter->param_adv_1000hdx,
+	    adapter->param_adv_100fdx, adapter->param_adv_100hdx,
+	    adapter->param_adv_10fdx, adapter->param_adv_10hdx));
+
+	return (0);
+}
+
+enum ioc_reply
+unm_nd_ioctl(unm_adapter *adapter, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
+{
+	boolean_t ok;
+	int cmd;
+
+	DPRINTF(1, (CE_WARN, "unm_nd_ioctl($%p, $%p, $%p, $%p)",
+	    (void *)adapter, (void *)wq, (void *)mp, (void *)iocp));
+
+	cmd = iocp->ioc_cmd;
+	switch (cmd) {
+	default:
+		/* NOTREACHED */
+		DPRINTF(-1, (CE_WARN, "unm_nd_ioctl: invalid cmd 0x%x", cmd));
+		return (IOC_INVAL);
+
+	case ND_GET:
+		/*
+		 * If nd_getset() returns B_FALSE, the command was
+		 * not valid (e.g. unknown name), so we just tell the
+		 * top-level ioctl code to send a NAK (with code EINVAL).
+		 *
+		 * Otherwise, nd_getset() will have built the reply to
+		 * be sent (but not actually sent it), so we tell the
+		 * caller to send the prepared reply.
+		 */
+		ok = nd_getset(wq, adapter->nd_data_p, mp);
+		DPRINTF(1, (CE_WARN, "unm_nd_ioctl: get %s", ok ? "OK" :
+		    "FAIL"));
+		return (ok ? IOC_REPLY : IOC_INVAL);
+
+	case ND_SET:
+		/*
+		 * All adv_* parameters are locked (read-only) while
+		 * the device is in any sort of loopback mode ...
+		 */
+		if (adapter->param_loop_mode != UNM_LOOP_NONE) {
+			iocp->ioc_error = EBUSY;
+			return (IOC_INVAL);
+		}
+
+		ok = nd_getset(wq, adapter->nd_data_p, mp);
+
+		/*
+		 * If nd_getset() returns B_FALSE, the command was
+		 * not valid (e.g. unknown name), so we just tell
+		 * the top-level ioctl code to send a NAK (with code
+		 * EINVAL by default).
+		 *
+		 * Otherwise, nd_getset() will have built the reply to
+		 * be sent - but that doesn't imply success!  In some
+		 * cases, the reply it's built will have a non-zero
+		 * error code in it (e.g. EPERM if not superuser).
+		 * So, we also drop out in that case ...
+		 */
+		DPRINTF(1, (CE_WARN,
+		    "unm_nd_ioctl: set %s err %d autoneg %d info %d",
+		    ok ? "OK" : "FAIL", iocp->ioc_error,
+		    adapter->nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val,
+		    adapter->nd_params[PARAM_ADV_AUTONEG_CAP].ndp_info));
+		if (!ok)
+			return (IOC_INVAL);
+		if (iocp->ioc_error)
+			return (IOC_REPLY);
+
+		return (IOC_RESTART_REPLY);
+	}
+}
+
+/* Free the Named Dispatch Table by calling nd_free */
+void
+unm_nd_cleanup(unm_adapter *adapter)
+{
+	nd_free(&adapter->nd_data_p);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,819 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _UNM_NIC_
+#define	_UNM_NIC_
+
+#include <sys/inttypes.h>
+#include <sys/rwlock.h>
+#include <sys/mutex.h>
+#include <sys/ddi.h>
+
+#include <sys/sunddi.h>
+#include <sys/types.h>
+#include <sys/stream.h>
+#include <sys/strsun.h>
+#include <sys/strsubr.h>
+#include <sys/dlpi.h>
+#include <sys/devops.h>
+#include <sys/stat.h>
+#include <sys/pci.h>
+#include <sys/note.h>
+#include <sys/modctl.h>
+#include <sys/kstat.h>
+#include <sys/ethernet.h>
+#include <sys/errno.h>
+#include <netinet/ip6.h>
+#include <inet/common.h>
+#include <sys/pattr.h>
+#include <inet/mi.h>
+#include <inet/nd.h>
+
+#include <sys/mac.h>
+#include <sys/mac_ether.h>
+#include <sys/miiregs.h> /* by fjlite out of intel */
+
+#include "unm_nic_hw.h"
+#include "nic_cmn.h"
+#include "unm_inc.h" /* For MAX_RCV_CTX */
+#include "unm_brdcfg.h"
+#include "unm_version.h"
+#include "nic_phan_reg.h"
+#include "unm_nic_ioctl.h"
+
+#define	MAX_ADDR_LEN	 6
+
+#define	ADDR_IN_WINDOW1(off)	\
+	((off > UNM_CRB_PCIX_HOST2) && (off < UNM_CRB_MAX)) ? 1 : 0
+
+typedef unsigned long uptr_t;
+
+#define	FIRST_PAGE_GROUP_START	0
+#define	FIRST_PAGE_GROUP_END	0x100000
+
+#define	SECOND_PAGE_GROUP_START	0x6000000
+#define	SECOND_PAGE_GROUP_END	0x68BC000
+
+#define	THIRD_PAGE_GROUP_START	0x70E4000
+#define	THIRD_PAGE_GROUP_END	0x8000000
+
+#define	FIRST_PAGE_GROUP_SIZE	FIRST_PAGE_GROUP_END - FIRST_PAGE_GROUP_START
+#define	SECOND_PAGE_GROUP_SIZE	SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START
+#define	THIRD_PAGE_GROUP_SIZE	THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START
+
+/*
+ * normalize a 64MB crb address to 32MB PCI window
+ * To use CRB_NORMALIZE, window _must_ be set to 1
+ */
+#define	CRB_NORMAL(reg)	\
+	(reg) - UNM_CRB_PCIX_HOST2 + UNM_CRB_PCIX_HOST
+#define	CRB_NORMALIZE(adapter, reg) \
+	(void *)(unsigned long)(pci_base_offset(adapter, CRB_NORMAL(reg)))
+
+#define	DB_NORMALIZE(adapter, off) \
+	(void *)((unsigned long)adapter->ahw.db_base + (off))
+
+#define	find_diff_among(a, b, range) \
+	((a) < (b)?((b)-(a)):((b)+(range)-(a)))
+
+#define	__FUNCTION__		__func__
+#define	nx_msleep(_msecs_)	delay(drv_usectohz(_msecs_ * 1000))
+
+#define	HOST_TO_LE_64			LE_64
+#define	HOST_TO_LE_32			LE_32
+#define	LE_TO_HOST_32			LE_32
+#define	HOST_TO_LE_16			LE_16
+#define	LE_TO_HOST_16			LE_16
+
+#define	dbwritel(DATA, ADDRESS) \
+	ddi_put32(adapter->db_handle, (uint32_t *)(ADDRESS), (DATA))
+
+/*
+ * Following macros require the mapped addresses to access
+ * the Phantom memory.
+ */
+#define	UNM_NIC_PCI_READ_8(ADDRESS) \
+	ddi_get8(adapter->regs_handle, (uint8_t *)(ADDRESS))
+#define	UNM_NIC_PCI_READ_16(ADDRESS) \
+	ddi_get16(adapter->regs_handle, (uint16_t *)(ADDRESS))
+#define	UNM_NIC_PCI_READ_32(ADDRESS) \
+	ddi_get32(adapter->regs_handle, (uint32_t *)(ADDRESS))
+#define	UNM_NIC_PCI_READ_64(ADDRESS) \
+	ddi_get64(adapter->regs_handle, (uint64_t *)(ADDRESS))
+
+#define	UNM_NIC_PCI_WRITE_8(DATA, ADDRESS) \
+	ddi_put8(adapter->regs_handle, (uint8_t *)(ADDRESS), (DATA))
+#define	UNM_NIC_PCI_WRITE_16(DATA, ADDRESS) \
+	ddi_put16(adapter->regs_handle, (uint16_t *)(ADDRESS), (DATA))
+#define	UNM_NIC_PCI_WRITE_32(DATA, ADDRESS) \
+	ddi_put32(adapter->regs_handle, (uint32_t *)(ADDRESS), (DATA))
+#define	UNM_NIC_PCI_WRITE_64(DATA, ADDRESS) \
+	ddi_put64(adapter->regs_handle, (uint64_t *)(ADDRESS), (DATA))
+
+#ifdef DEBUG_LEVEL
+#define	DPRINTF(n, args)	if (DEBUG_LEVEL > (n)) cmn_err args;
+#else
+#define	DPRINTF(n, args)
+#endif
+
+#define	UNM_SPIN_LOCK(_lp_)			mutex_enter((_lp_))
+#define	UNM_SPIN_UNLOCK(_lp_)			mutex_exit((_lp_))
+#define	UNM_SPIN_LOCK_ISR(_lp_)			mutex_enter((_lp_))
+#define	UNM_SPIN_UNLOCK_ISR(_lp_)		mutex_exit((_lp_))
+
+#define	UNM_WRITE_LOCK(_lp_)			rw_enter((_lp_), RW_WRITER)
+#define	UNM_WRITE_UNLOCK(_lp_)			rw_exit((_lp_))
+#define	UNM_READ_LOCK(_lp_)			rw_enter((_lp_), RW_READER)
+#define	UNM_READ_UNLOCK(_lp_)			rw_exit((_lp_))
+#define	UNM_WRITE_LOCK_IRQS(_lp_, _fl_)		rw_enter((_lp_), RW_WRITER)
+#define	UNM_WRITE_UNLOCK_IRQR(_lp_, _fl_)	rw_exit((_lp_))
+
+extern char unm_nic_driver_name[];
+extern int verbmsg;
+
+typedef struct unm_dmah_node {
+	struct unm_dmah_node *next;
+	ddi_dma_handle_t dmahdl;
+}unm_dmah_node_t;
+
+typedef struct dma_area {
+	ddi_acc_handle_t	acc_hdl;	/* handle for memory	*/
+	ddi_dma_handle_t	dma_hdl;	/* DMA handle		*/
+	uint32_t		ncookies;
+	u64			dma_addr;
+	void			*vaddr;
+} dma_area_t;
+
+struct unm_cmd_buffer {
+	dma_area_t	dma_area;
+	mblk_t		*msg;
+	unm_dmah_node_t	*head, *tail;
+};
+
+typedef struct pkt_info {
+	uint32_t	total_len;
+	uint16_t	mblk_no;
+	uint16_t	etype;
+	uint16_t	mac_hlen;
+	uint16_t	ip_hlen;
+	uint16_t	l4_proto;
+} pktinfo_t;
+
+typedef struct unm_rcv_desc_context_s unm_rcv_desc_ctx_t;
+typedef struct unm_adapter_s unm_adapter;
+
+typedef struct unm_rx_buffer {
+	struct unm_rx_buffer	*next;
+	dma_area_t		dma_info;
+	frtn_t			rx_recycle;	/* recycle function */
+	mblk_t			*mp;
+	unm_rcv_desc_ctx_t	*rcv_desc;
+	unm_adapter		*adapter;
+}unm_rx_buffer_t;
+
+/* Board types */
+#define	UNM_NIC_GBE		0x01
+#define	UNM_NIC_XGBE    0x02
+
+/*
+ * One hardware_context{} per adapter
+ * contains interrupt info as well shared hardware info.
+ */
+typedef	struct _hardware_context {
+	unsigned long	pci_base0;
+	unsigned long	pci_len0;
+	unsigned long	pci_base1;
+	unsigned long	pci_len1;
+	unsigned long	pci_base2;
+	unsigned long	pci_len2;
+	unsigned long	first_page_group_end;
+	unsigned long	first_page_group_start;
+	uint8_t			revision_id;
+	uint8_t			cut_through;
+	uint16_t		board_type;
+	int				pci_func;
+	uint16_t		max_ports;
+	unm_board_info_t	boardcfg;
+	uint32_t		linkup;
+
+	struct unm_adapter_s	*adapter;
+	cmdDescType0_t			*cmdDescHead;
+
+	uint32_t		cmdProducer;
+	uint32_t		cmdConsumer;
+	uint32_t		rcvFlag;
+	uint32_t		crb_base;
+	unsigned long	db_base;    /* base of mapped db memory */
+	unsigned long	db_len;    /* length of mapped db memory */
+
+
+	uint64_t		cmdDesc_physAddr;
+	int				qdr_sn_window, ddr_mn_window;
+	unsigned long	mn_win_crb, ms_win_crb;
+	ddi_dma_handle_t cmd_desc_dma_handle;
+	ddi_acc_handle_t cmd_desc_acc_handle;
+	ddi_dma_cookie_t cmd_desc_dma_cookie;
+} hardware_context, *phardware_context;
+
+#define	NX_CT_DEFAULT_RX_BUF_LEN	2048
+#define	MTU_SIZE			1500
+#define	MAX_COOKIES_PER_CMD		16
+#define	UNM_DB_MAPSIZE_BYTES		0x1000
+#define	EXTRA_HANDLES			512
+#define	UNM_TX_BCOPY_THRESHOLD		128
+#define	UNM_RX_BCOPY_THRESHOLD		128
+#define	NX_MIN_DRIVER_RDS_SIZE		64
+
+typedef struct unm_pauseparam {
+	uint16_t rx_pause;
+	uint16_t tx_pause;
+} unm_pauseparam_t;
+
+/*
+ * The driver supports the NDD ioctls ND_GET/ND_SET, and the loopback
+ * ioctls LB_GET_INFO_SIZE/LB_GET_INFO/LB_GET_MODE/LB_SET_MODE
+ *
+ * These are the values to use with LD_SET_MODE.
+ */
+#define	UNM_LOOP_NONE	   0
+#define	UNM_LOOP_INTERNAL_PHY   1
+#define	UNM_LOOP_INTERNAL_MAC   2
+
+/*
+ * Named Data (ND) Parameter Management Structure
+ */
+typedef	struct {
+	int			ndp_info;
+	int			ndp_min;
+	int			ndp_max;
+	int			ndp_val;
+	char		*ndp_name;
+} nd_param_t; /* 0x18 (24) bytes  */
+
+/*
+ * NDD parameter indexes, divided into:
+ *
+ *      read-only parameters describing the hardware's capabilities
+ *      read-write parameters controlling the advertised capabilities
+ *      read-only parameters describing the partner's capabilities
+ *      read-only parameters describing the link state
+ */
+enum {
+	PARAM_AUTONEG_CAP = 0,
+	PARAM_PAUSE_CAP,
+	PARAM_ASYM_PAUSE_CAP,
+	PARAM_10000FDX_CAP,
+	PARAM_1000FDX_CAP,
+	PARAM_1000HDX_CAP,
+	PARAM_100T4_CAP,
+	PARAM_100FDX_CAP,
+	PARAM_100HDX_CAP,
+	PARAM_10FDX_CAP,
+	PARAM_10HDX_CAP,
+
+	PARAM_ADV_AUTONEG_CAP,
+	PARAM_ADV_PAUSE_CAP,
+	PARAM_ADV_ASYM_PAUSE_CAP,
+	PARAM_ADV_10000FDX_CAP,
+	PARAM_ADV_1000FDX_CAP,
+	PARAM_ADV_1000HDX_CAP,
+	PARAM_ADV_100T4_CAP,
+	PARAM_ADV_100FDX_CAP,
+	PARAM_ADV_100HDX_CAP,
+	PARAM_ADV_10FDX_CAP,
+	PARAM_ADV_10HDX_CAP,
+
+	PARAM_LINK_STATUS,
+	PARAM_LINK_SPEED,
+	PARAM_LINK_DUPLEX,
+
+	PARAM_LOOP_MODE,
+
+	PARAM_COUNT
+};
+
+struct unm_adapter_stats {
+	uint64_t  rcvdbadmsg;
+	uint64_t  xmitcalled;
+	uint64_t  xmitedframes;
+	uint64_t  xmitfinished;
+	uint64_t  badmsglen;
+	uint64_t  nocmddescriptor;
+	uint64_t  polled;
+	uint64_t  uphappy;
+	uint64_t  updropped;
+	uint64_t  uplcong;
+	uint64_t  uphcong;
+	uint64_t  upmcong;
+	uint64_t  updunno;
+	uint64_t  msgfreed;
+	uint64_t  txdropped;
+	uint64_t  txnullmsg;
+	uint64_t  csummed;
+	uint64_t  no_rcv;
+	uint64_t  rxbytes;
+	uint64_t  txbytes;
+	uint64_t  ints;
+	uint64_t  desballocfailed;
+	uint64_t  txcopyed;
+	uint64_t  txmapped;
+	uint64_t  outoftxdmahdl;
+	uint64_t  outofcmddesc;
+	uint64_t  rxcopyed;
+	uint64_t  rxmapped;
+	uint64_t  outofrxbuf;
+	uint64_t  promiscmode;
+	uint64_t  rxbufshort;
+	uint64_t  allocbfailed;
+};
+
+/* descriptor types */
+#define	RCV_RING_STD		RCV_DESC_NORMAL
+#define	RCV_RING_JUMBO		RCV_DESC_JUMBO
+#define	RCV_RING_LRO		RCV_DESC_LRO
+
+/*
+ * Rcv Descriptor Context. One such per Rcv Descriptor. There may
+ * be one Rcv Descriptor for normal packets, one for jumbo,
+ * one for LRO and may be expanded.
+ */
+struct unm_rcv_desc_context_s {
+	uint32_t	producer;
+
+	uint64_t	phys_addr;
+	dev_info_t	*phys_pdev;
+	/* address of rx ring in Phantom */
+	rcvDesc_t	*desc_head;
+
+	uint32_t	MaxRxDescCount;
+	uint32_t	rx_desc_handled;
+	uint32_t	rx_buf_card;
+	uint32_t	rx_buf_total;
+	uint32_t	rx_buf_free;
+	uint32_t	rx_buf_recycle;
+	unm_rx_buffer_t *rx_buf_pool;
+	unm_rx_buffer_t *pool_list;
+	unm_rx_buffer_t *recycle_list;
+	kmutex_t	pool_lock[1];	/* buffer pool lock */
+	kmutex_t	recycle_lock[1]; /* buffer recycle lock */
+	/* size of the receive buf */
+	uint32_t	buf_size;
+	/* rx buffers for receive   */
+
+	ddi_dma_handle_t	rx_desc_dma_handle;
+	ddi_acc_handle_t 	rx_desc_acc_handle;
+	ddi_dma_cookie_t	rx_desc_dma_cookie;
+	uint32_t		host_rx_producer;
+	uint32_t		dma_size;
+};
+
+/*
+ * Receive context. There is one such structure per instance of the
+ * receive processing. Any state information that is relevant to
+ * the receive, and is must be in this structure. The global data may be
+ * present elsewhere.
+ */
+typedef struct unm_recv_context_s {
+	unm_rcv_desc_ctx_t 	rcv_desc[NUM_RCV_DESC_RINGS];
+
+	uint32_t			statusRxConsumer;
+
+	uint64_t			rcvStatusDesc_physAddr;
+	statusDesc_t 		*rcvStatusDescHead;
+
+	ddi_dma_handle_t	status_desc_dma_handle;
+	ddi_acc_handle_t	status_desc_acc_handle;
+	ddi_dma_cookie_t	status_desc_dma_cookie;
+
+	uint32_t		state, host_sds_consumer;
+	uint16_t		context_id, virt_port;
+} unm_recv_context_t;
+
+#define	UNM_NIC_MSI_ENABLED	0x02
+#define	UNM_NIC_MSIX_ENABLED	0x04
+#define	UNM_IS_MSI_FAMILY(ADAPTER)	\
+	((ADAPTER)->flags & (UNM_NIC_MSI_ENABLED | UNM_NIC_MSIX_ENABLED))
+
+#define	NX_USE_MSIX
+
+/* msix defines */
+#define	MSIX_ENTRIES_PER_ADAPTER	8
+#define	UNM_MSIX_TBL_SPACE		8192
+#define	UNM_PCI_REG_MSIX_TBL		0x44
+
+/*
+ * Bug: word or char write on MSI-X capcabilities register (0x40) in PCI config
+ * space has no effect on register values. Need to write dword.
+ */
+#define	UNM_HWBUG_8_WORKAROUND
+
+/*
+ * Bug: Can not reset bit 32 (msix enable bit) on MSI-X capcabilities
+ * register (0x40) independently.
+ * Need to write 0x0 (zero) to MSI-X capcabilities register in order to reset
+ * msix enable bit. On writing zero rest of the bits are not touched.
+ */
+#define	UNM_HWBUG_9_WORKAROUND
+
+#define	UNM_MC_COUNT    38	/* == ((UNM_ADDR_L2LU_COUNT-1)/4) -2 */
+
+/* Following structure is for specific port information */
+struct unm_adapter_s {
+	hardware_context	ahw;
+	uint8_t			id[32];
+	uint16_t		portnum;
+	uint16_t		physical_port;
+	uint16_t		link_speed;
+	uint16_t		link_duplex;
+
+	struct unm_adapter_stats stats;
+	int			rx_csum;
+	int			status;
+	kmutex_t    		stats_lock;
+	unsigned char		mac_addr[MAX_ADDR_LEN];
+	int			mtu;		/* active mtu */
+	int			maxmtu;		/* max possible mtu value */
+	uint32_t		promisc;
+
+	mac_resource_handle_t   mac_rx_ring_ha;
+	mac_handle_t	mach;
+	int				flags;
+
+	int		  instance;
+	dev_info_t	  *dip;
+	ddi_acc_handle_t  pci_cfg_handle;
+	ddi_acc_handle_t  regs_handle;
+	ddi_dma_attr_t    gc_dma_attr_desc;
+
+	struct ddi_device_acc_attr  gc_attr_desc;
+	ddi_iblock_cookie_t iblock_cookie;
+	const char *name;
+	ddi_acc_handle_t  db_handle;
+
+	ddi_intr_handle_t	intr_handle;
+	int			intr_type;
+	uint_t		intr_pri;
+	unm_dmah_node_t		*dmahdl_pool;
+	unm_dmah_node_t		tx_dma_hdls[MAX_CMD_DESCRIPTORS+EXTRA_HANDLES];
+	uint64_t		freehdls;
+	uint64_t		freecmds;
+	int			tx_bcopy_threshold;
+	kmutex_t		tx_lock;
+	krwlock_t		adapter_lock;
+	kmutex_t		lock;
+	struct nx_legacy_intr_set	legacy_intr;
+	timeout_id_t		watchdog_timer;
+	kstat_t			*kstats[1];
+
+	uint32_t		curr_window;
+	uint32_t		crb_win;
+	uint32_t		cmdProducer;
+	uint32_t		*cmdConsumer;
+
+	uint32_t		interrupt_crb;
+	uint32_t		fw_major;
+	uint32_t		crb_addr_cmd_producer;
+	uint32_t		crb_addr_cmd_consumer;
+	uint16_t		tx_context_id;
+	short			context_alloced;
+	int			max_rds_rings;
+
+	uint32_t		lastCmdConsumer;
+	/* Num of bufs posted in phantom */
+	uint32_t	pendingCmdCount;
+	uint32_t	MaxTxDescCount;
+	uint32_t	MaxRxDescCount;
+	uint32_t	MaxJumboRxDescCount;
+	uint32_t	MaxLroRxDescCount;
+	/* Num of instances active on cmd buffer ring */
+	int		resched_needed;
+
+	int			driver_mismatch;
+	uint32_t	temp;
+
+	struct unm_cmd_buffer *cmd_buf_arr;  /* Command buffers for xmit */
+	int		rx_bcopy_threshold;
+
+	/*
+	 * Receive instances. These can be either one per port,
+	 * or one per peg, etc.
+	 */
+	unm_recv_context_t	recv_ctx[MAX_RCV_CTX];
+	int		is_up;
+
+	/* context interface shared between card and host */
+	RingContext		*ctxDesc;
+	uint64_t		ctxDesc_physAddr;
+	ddi_dma_handle_t 	ctxDesc_dma_handle;
+	ddi_acc_handle_t 	ctxDesc_acc_handle;
+
+	struct {
+		void			*addr;
+		uint64_t		phys_addr;
+		ddi_dma_handle_t	dma_handle;
+		ddi_acc_handle_t	acc_handle;
+	} dummy_dma;
+
+	void	(*unm_nic_pci_change_crbwindow)(struct unm_adapter_s *,
+		    uint32_t);
+	int	(*unm_crb_writelit_adapter)(struct unm_adapter_s *,
+		    unsigned long, int);
+	unsigned long long
+		(*unm_nic_pci_set_window)(struct unm_adapter_s *,
+		    unsigned long long);
+	int	(*unm_nic_fill_statistics)(struct unm_adapter_s *,
+		    struct unm_statistics *);
+	int	(*unm_nic_clear_statistics)(struct unm_adapter_s *);
+	int	(*unm_nic_hw_write_wx)(struct unm_adapter_s *, u64,
+	    void *, int);
+	int	(*unm_nic_hw_read_wx)(struct unm_adapter_s *, u64, void *, int);
+	int	(*unm_nic_hw_write_ioctl)(struct unm_adapter_s *, u64, void *,
+		    int);
+	int	(*unm_nic_hw_read_ioctl)(struct unm_adapter_s *, u64, void *,
+		    int);
+	int	(*unm_nic_pci_mem_write)(struct unm_adapter_s *, u64, void *,
+		    int);
+	int	(*unm_nic_pci_mem_read)(struct unm_adapter_s *, u64, void *,
+		    int);
+	int	(*unm_nic_pci_write_immediate)(struct unm_adapter_s *, u64,
+		    u32 *);
+	int	(*unm_nic_pci_read_immediate)(struct unm_adapter_s *, u64,
+		    u32 *);
+	void	(*unm_nic_pci_write_normalize)(struct unm_adapter_s *, u64,
+		    u32);
+	u32	(*unm_nic_pci_read_normalize)(struct unm_adapter_s *, u64);
+
+	caddr_t			nd_data_p;
+	nd_param_t		nd_params[PARAM_COUNT];
+};  /* unm_adapter structure */
+
+#define	UNM_HOST_DUMMY_DMA_SIZE	 1024
+
+/* Following structure is for specific port information    */
+
+#define	PCI_OFFSET_FIRST_RANGE(adapter, off)	\
+	((adapter)->ahw.pci_base0 + off)
+#define	PCI_OFFSET_SECOND_RANGE(adapter, off)	\
+	((adapter)->ahw.pci_base1 + off - SECOND_PAGE_GROUP_START)
+#define	PCI_OFFSET_THIRD_RANGE(adapter, off)	\
+	((adapter)->ahw.pci_base2 + off - THIRD_PAGE_GROUP_START)
+
+#define	pci_base_offset(adapter, off)	\
+	((((off) < ((adapter)->ahw.first_page_group_end)) &&	\
+	    ((off) >= ((adapter)->ahw.first_page_group_start))) ?	\
+	    ((adapter)->ahw.pci_base0 + (off)) :	\
+	    ((((off) < SECOND_PAGE_GROUP_END) &&	\
+	    ((off) >= SECOND_PAGE_GROUP_START)) ?	\
+	    ((adapter)->ahw.pci_base1 +		\
+	    (off) - SECOND_PAGE_GROUP_START) :	\
+		((((off) < THIRD_PAGE_GROUP_END) &&	\
+	    ((off) >= THIRD_PAGE_GROUP_START)) ?	\
+	    ((adapter)->ahw.pci_base2 + (off) -	\
+	    THIRD_PAGE_GROUP_START) :		\
+	    0)))
+#define	unm_nic_reg_write(_adp_, _off_, _val_)			\
+	{							\
+		__uint32_t	_v1_ = (_val_);			\
+		((_adp_)->unm_nic_hw_write_wx((_adp_), (_off_),	\
+		    &_v1_, 4));					\
+	}
+
+#define	unm_nic_reg_read(_adp_, _off_, _ptr_)			\
+	((_adp_)->unm_nic_hw_read_wx((_adp_), (_off_), (_ptr_), 4))
+
+
+#define	unm_nic_write_w0(_adp_, _idx_, _val_)			\
+	((_adp_)->unm_nic_hw_write_wx((_adp_), (_idx_), &(_val_), 4))
+
+#define	unm_nic_read_w0(_adp_, _idx_, _val_)			\
+	((_adp_)->unm_nic_hw_read_wx((_adp_), (_idx_), (_val_), 4))
+
+/* Functions available from unm_nic_hw.c */
+int unm_nic_get_board_info(struct unm_adapter_s *adapter);
+void _unm_nic_write_crb(struct unm_adapter_s *adapter, uint32_t index,
+				uint32_t value);
+void  unm_nic_write_crb(struct unm_adapter_s *adapter, uint32_t index,
+				uint32_t value);
+void _unm_nic_read_crb(struct unm_adapter_s *adapter, uint32_t index,
+				uint32_t *value);
+void  unm_nic_read_crb(struct unm_adapter_s *adapter, uint32_t index,
+				uint32_t *value);
+// int   unm_nic_reg_read (unm_adapter *adapter, u64 off);
+int _unm_nic_hw_write(struct unm_adapter_s *adapter,
+				u64 off, void *data, int len);
+int  unm_nic_hw_write(struct unm_adapter_s *adapter,
+				u64 off, void *data, int len);
+int _unm_nic_hw_read(struct unm_adapter_s *adapter,
+				u64 off, void *data, int len);
+int  unm_nic_hw_read(struct unm_adapter_s *adapter,
+				u64 off, void *data, int len);
+void _unm_nic_hw_block_read(struct unm_adapter_s *adapter,
+				u64 off, void *data, int num_words);
+void  unm_nic_hw_block_read(struct unm_adapter_s *adapter,
+				u64 off, void *data, int num_words);
+void _unm_nic_hw_block_write(struct unm_adapter_s *adapter,
+				u64 off, void *data, int num_words);
+void unm_nic_hw_block_write(struct unm_adapter_s *adapter,
+				u64 off, void *data, int num_words);
+int  unm_nic_pci_mem_write(struct unm_adapter_s *adapter,
+				u64 off, void *data, int size);
+void unm_nic_mem_block_read(struct unm_adapter_s *adapter, u64 off,
+				void *data, int num_words);
+void unm_nic_mem_block_write(struct unm_adapter_s *adapter, u64 off,
+				void *data, int num_words);
+int unm_nic_hw_read_ioctl(unm_adapter *adapter, u64 off, void *data, int len);
+int unm_nic_hw_write_ioctl(unm_adapter *adapter, u64 off, void *data, int len);
+int  unm_nic_macaddr_set(struct unm_adapter_s *, __uint8_t *addr);
+void unm_tcl_resetall(struct unm_adapter_s *adapter);
+void unm_tcl_phaninit(struct unm_adapter_s *adapter);
+void unm_tcl_postimage(struct unm_adapter_s *adapter);
+int unm_nic_set_mtu(struct unm_adapter_s *adapter, int new_mtu);
+long unm_nic_phy_read(unm_adapter *adapter, long reg, __uint32_t *);
+long unm_nic_init_port(struct unm_adapter_s *adapter);
+void unm_crb_write_adapter(unsigned long off, void *data,
+		struct unm_adapter_s *adapter);
+int unm_crb_read_adapter(unsigned long off, void *data,
+		struct unm_adapter_s *adapter);
+int unm_crb_read_val_adapter(unsigned long off,
+		struct unm_adapter_s *adapter);
+void unm_nic_stop_port(struct unm_adapter_s *adapter);
+int unm_nic_set_promisc_mode(struct unm_adapter_s *adapter);
+int unm_nic_unset_promisc_mode(struct unm_adapter_s *adapter);
+
+/* unm_nic_hw.c */
+void unm_nic_pci_change_crbwindow_128M(unm_adapter *adapter, uint32_t wndw);
+int unm_crb_writelit_adapter_128M(struct unm_adapter_s *, unsigned long, int);
+int unm_nic_hw_write_wx_128M(unm_adapter *adapter, u64 off, void *data,
+    int len);
+int unm_nic_hw_read_wx_128M(unm_adapter *adapter, u64 off, void *data, int len);
+int unm_nic_hw_write_ioctl_128M(unm_adapter *adapter, u64 off, void *data,
+    int len);
+int unm_nic_hw_read_ioctl_128M(unm_adapter *adapter, u64 off, void *data,
+    int len);
+int unm_nic_pci_mem_write_128M(struct unm_adapter_s *adapter, u64 off,
+    void *data, int size);
+int unm_nic_pci_mem_read_128M(struct unm_adapter_s *adapter, u64 off,
+    void *data, int size);
+void unm_nic_pci_write_normalize_128M(unm_adapter *adapter, u64 off, u32 data);
+u32 unm_nic_pci_read_normalize_128M(unm_adapter *adapter, u64 off);
+int unm_nic_pci_write_immediate_128M(unm_adapter *adapter, u64 off, u32 *data);
+int unm_nic_pci_read_immediate_128M(unm_adapter *adapter, u64 off, u32 *data);
+unsigned long long unm_nic_pci_set_window_128M(unm_adapter *adapter,
+    unsigned long long addr);
+int unm_nic_clear_statistics_128M(struct unm_adapter_s *adapter);
+int unm_nic_fill_statistics_128M(struct unm_adapter_s *adapter,
+    struct unm_statistics *unm_stats);
+
+void unm_nic_pci_change_crbwindow_2M(unm_adapter *adapter, uint32_t wndw);
+int unm_crb_writelit_adapter_2M(struct unm_adapter_s *, unsigned long, int);
+int unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len);
+int unm_nic_pci_mem_write_2M(struct unm_adapter_s *adapter, u64 off,
+    void *data, int size);
+int unm_nic_pci_mem_read_2M(struct unm_adapter_s *adapter, u64 off,
+    void *data, int size);
+int unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len);
+void unm_nic_pci_write_normalize_2M(unm_adapter *adapter, u64 off, u32 data);
+u32 unm_nic_pci_read_normalize_2M(unm_adapter *adapter, u64 off);
+int unm_nic_pci_write_immediate_2M(unm_adapter *adapter, u64 off, u32 *data);
+int unm_nic_pci_read_immediate_2M(unm_adapter *adapter, u64 off, u32 *data);
+unsigned long long unm_nic_pci_set_window_2M(unm_adapter *adapter,
+    unsigned long long addr);
+int unm_nic_clear_statistics_2M(struct unm_adapter_s *adapter);
+int unm_nic_fill_statistics_2M(struct unm_adapter_s *adapter,
+    struct unm_statistics *unm_stats);
+void nx_p3_nic_set_multi(unm_adapter *adapter);
+
+/* unm_nic_init.c */
+int phantom_init(struct unm_adapter_s *adapter, int first_time);
+int load_from_flash(struct unm_adapter_s *adapter);
+int  pinit_from_rom(unm_adapter *adapter, int verbose);
+int  rom_fast_read(struct unm_adapter_s *adapter, int addr, int *valp);
+
+/* unm_nic_isr.c */
+void unm_nic_handle_phy_intr(unm_adapter *adapter);
+
+/* niu.c */
+native_t unm_niu_set_promiscuous_mode(struct unm_adapter_s *adapter,
+		unm_niu_prom_mode_t mode);
+native_t unm_niu_xg_set_promiscuous_mode(struct unm_adapter_s *adapter,
+		unm_niu_prom_mode_t mode);
+
+int unm_niu_xg_macaddr_set(struct unm_adapter_s *adapter,
+		unm_ethernet_macaddr_t addr);
+native_t unm_niu_disable_xg_port(struct unm_adapter_s *adapter);
+
+long unm_niu_gbe_init_port(long port);
+native_t unm_niu_enable_gbe_port(struct unm_adapter_s *adapter,
+    unm_niu_gbe_ifmode_t mode);
+native_t unm_niu_disable_gbe_port(struct unm_adapter_s *adapter);
+
+int unm_niu_macaddr_get(struct unm_adapter_s *adapter, unsigned char *addr);
+int unm_niu_macaddr_set(struct unm_adapter_s *adapter,
+		unm_ethernet_macaddr_t addr);
+
+int unm_niu_xg_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable);
+int unm_niu_gbe_set_rx_flow_ctl(struct unm_adapter_s *adapter, int enable);
+int unm_niu_gbe_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable);
+long unm_niu_gbe_disable_phy_interrupts(struct unm_adapter_s *);
+long unm_niu_gbe_phy_read(struct unm_adapter_s *,
+		long reg, unm_crbword_t *readval);
+
+/* unm_nic_ctx.c */
+int netxen_create_rxtx(struct unm_adapter_s *adapter);
+void netxen_destroy_rxtx(struct unm_adapter_s *adapter);
+int nx_fw_cmd_set_mtu(struct unm_adapter_s *adapter, int mtu);
+
+/* unm_nic_main.c */
+int receive_peg_ready(struct unm_adapter_s *adapter);
+void unm_nic_update_cmd_producer(struct unm_adapter_s *adapter,
+    uint32_t crb_producer);
+void unm_desc_dma_sync(ddi_dma_handle_t handle, uint_t start, uint_t count,
+    uint_t range, uint_t unit_size, uint_t direction);
+int unm_pci_alloc_consistent(unm_adapter *, int, caddr_t *,
+    ddi_dma_cookie_t *, ddi_dma_handle_t *, ddi_acc_handle_t *);
+void unm_pci_free_consistent(ddi_dma_handle_t *, ddi_acc_handle_t *);
+
+/* unm_ndd.c */
+int unm_nd_init(unm_adapter *adapter);
+enum ioc_reply unm_nd_ioctl(unm_adapter *adapter, queue_t *wq,
+		mblk_t *mp, struct iocblk *iocp);
+void unm_nd_cleanup(unm_adapter *adapter);
+
+/* unm_gem.c */
+void unm_destroy_intr(unm_adapter *adapter);
+void unm_free_dummy_dma(unm_adapter *adapter);
+
+/*
+ * (Internal) return values from ioctl subroutines
+ */
+enum ioc_reply {
+	IOC_INVAL = -1,	/* bad, NAK with EINVAL */
+	IOC_DONE, /* OK, reply sent  */
+	IOC_ACK, /* OK, just send ACK  */
+	IOC_REPLY, /* OK, just send reply */
+	IOC_RESTART_ACK, /* OK, restart & ACK */
+	IOC_RESTART_REPLY /* OK, restart & reply */
+};
+
+/*
+ * Shorthand for the NDD parameters
+ */
+#define	param_adv_autoneg	nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val
+#define	param_adv_pause		nd_params[PARAM_ADV_PAUSE_CAP].ndp_val
+#define	param_adv_asym_pause	nd_params[PARAM_ADV_ASYM_PAUSE_CAP].ndp_val
+#define	param_adv_10000fdx	nd_params[PARAM_ADV_10000FDX_CAP].ndp_val
+#define	param_adv_1000fdx	nd_params[PARAM_ADV_1000FDX_CAP].ndp_val
+#define	param_adv_1000hdx	nd_params[PARAM_ADV_1000HDX_CAP].ndp_val
+#define	param_adv_100fdx	nd_params[PARAM_ADV_100FDX_CAP].ndp_val
+#define	param_adv_100hdx	nd_params[PARAM_ADV_100HDX_CAP].ndp_val
+#define	param_adv_10fdx		nd_params[PARAM_ADV_10FDX_CAP].ndp_val
+#define	param_adv_10hdx		nd_params[PARAM_ADV_10HDX_CAP].ndp_val
+#define	param_link_up		nd_params[PARAM_LINK_STATUS].ndp_val
+#define	param_link_speed	nd_params[PARAM_LINK_SPEED].ndp_val
+#define	param_link_duplex	nd_params[PARAM_LINK_DUPLEX].ndp_val
+#define	param_loop_mode		nd_params[PARAM_LOOP_MODE].ndp_val
+
+/*
+ * Property lookups
+ */
+#define	UNM_PROP_EXISTS(d, n) \
+	ddi_prop_exists(DDI_DEV_T_ANY, (d), DDI_PROP_DONTPASS, (n))
+#define	UNM_PROP_GET_INT(d, n) \
+	ddi_prop_get_int(DDI_DEV_T_ANY, (d), DDI_PROP_DONTPASS, (n), -1)
+
+/*
+ * Bit flags in the 'debug' word ...
+ */
+#define	UNM_DBG_TRACE	0x00000002 /* general flow tracing */
+#define	UNM_DBG_NDD		0x20000000 /* NDD operations */
+
+#define	MBPS_10		10
+#define	MBPS_100	100
+#define	MBPS_1000	1000
+
+#endif	/* !_UNM_NIC_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic_ctx.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,655 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/debug.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#include <sys/strlog.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/vtrace.h>
+#include <sys/dlpi.h>
+#include <sys/strsun.h>
+#include <sys/ethernet.h>
+#include <sys/modctl.h>
+#include <sys/errno.h>
+#include <sys/dditypes.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+#include <sys/pci.h>
+
+#include "unm_nic_hw.h"
+#include "unm_nic.h"
+#include "nic_phan_reg.h"
+#include "nic_cmn.h"
+
+typedef unsigned int nx_rcode_t;
+
+#include "nx_errorcode.h"
+#include "nxhal_nic_interface.h"
+
+#define	NXHAL_VERSION	1
+
+#define	NX_OS_CRB_RETRY_COUNT	4000
+
+#define	NX_CDRP_CLEAR		0x00000000
+#define	NX_CDRP_CMD_BIT		0x80000000
+
+/*
+ * All responses must have the NX_CDRP_CMD_BIT cleared
+ * in the crb NX_CDRP_CRB_OFFSET.
+ */
+#define	NX_CDRP_FORM_RSP(rsp)	(rsp)
+#define	NX_CDRP_IS_RSP(rsp)	(((rsp) & NX_CDRP_CMD_BIT) == 0)
+
+#define	NX_CDRP_RSP_OK		0x00000001
+#define	NX_CDRP_RSP_FAIL	0x00000002
+#define	NX_CDRP_RSP_TIMEOUT	0x00000003
+
+/*
+ * All commands must have the NX_CDRP_CMD_BIT set in
+ * the crb NX_CDRP_CRB_OFFSET.
+ */
+#define	NX_CDRP_FORM_CMD(cmd)	(NX_CDRP_CMD_BIT | (cmd))
+#define	NX_CDRP_IS_CMD(cmd)	(((cmd) & NX_CDRP_CMD_BIT) != 0)
+
+#define	NX_CDRP_CMD_SUBMIT_CAPABILITIES		0x00000001
+#define	NX_CDRP_CMD_READ_MAX_RDS_PER_CTX    0x00000002
+#define	NX_CDRP_CMD_READ_MAX_SDS_PER_CTX    0x00000003
+#define	NX_CDRP_CMD_READ_MAX_RULES_PER_CTX  0x00000004
+#define	NX_CDRP_CMD_READ_MAX_RX_CTX			0x00000005
+#define	NX_CDRP_CMD_READ_MAX_TX_CTX			0x00000006
+#define	NX_CDRP_CMD_CREATE_RX_CTX			0x00000007
+#define	NX_CDRP_CMD_DESTROY_RX_CTX			0x00000008
+#define	NX_CDRP_CMD_CREATE_TX_CTX			0x00000009
+#define	NX_CDRP_CMD_DESTROY_TX_CTX			0x0000000a
+#define	NX_CDRP_CMD_SETUP_STATISTICS		0x0000000e
+#define	NX_CDRP_CMD_GET_STATISTICS			0x0000000f
+#define	NX_CDRP_CMD_DELETE_STATISTICS		0x00000010
+#define	NX_CDRP_CMD_SET_MTU					0x00000012
+#define	NX_CDRP_CMD_MAX						0x00000013
+
+#define	NX_DESTROY_CTX_RESET		0
+#define	NX_DESTROY_CTX_D3_RESET		1
+#define	NX_DESTROY_CTX_MAX		2
+
+/*
+ * Context state
+ */
+#define	NX_HOST_CTX_STATE_FREED		0
+#define	NX_HOST_CTX_STATE_ALLOCATED	1
+#define	NX_HOST_CTX_STATE_ACTIVE	2
+#define	NX_HOST_CTX_STATE_DISABLED	3
+#define	NX_HOST_CTX_STATE_QUIESCED	4
+#define	NX_HOST_CTX_STATE_MAX		5
+
+static int
+netxen_api_lock(struct unm_adapter_s *adapter)
+{
+	u32 done = 0, timeout = 0;
+
+	for (;;) {
+		/* Acquire PCIE HW semaphore5 */
+		unm_nic_read_w0(adapter,
+		    UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
+
+		if (done == 1)
+			break;
+
+		if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
+			cmn_err(CE_WARN, "%s: lock timeout.\n", __func__);
+			return (-1);
+		}
+
+		drv_usecwait(1000);
+	}
+
+#if 0
+	unm_nic_reg_write(adapter, NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
+#endif
+	return (0);
+}
+
+static void
+netxen_api_unlock(struct unm_adapter_s *adapter)
+{
+	u32 val;
+
+	/* Release PCIE HW semaphore5 */
+	unm_nic_read_w0(adapter,
+	    UNM_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
+}
+
+static u32
+netxen_poll_rsp(struct unm_adapter_s *adapter)
+{
+	u32 raw_rsp, rsp = NX_CDRP_RSP_OK;
+	int	timeout = 0;
+
+	do {
+		/* give atleast 1ms for firmware to respond */
+		drv_usecwait(1000);
+
+		if (++timeout > NX_OS_CRB_RETRY_COUNT)
+			return (NX_CDRP_RSP_TIMEOUT);
+
+		adapter->unm_nic_hw_read_wx(adapter, NX_CDRP_CRB_OFFSET,
+		    &raw_rsp, 4);
+
+		rsp = LE_TO_HOST_32(raw_rsp);
+	} while (!NX_CDRP_IS_RSP(rsp));
+
+	return (rsp);
+}
+
+static u32
+netxen_issue_cmd(struct unm_adapter_s *adapter,
+	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
+{
+	u32 rsp;
+	u32 signature = 0;
+	u32 rcode = NX_RCODE_SUCCESS;
+
+	signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);
+
+	/* Acquire semaphore before accessing CRB */
+	if (netxen_api_lock(adapter))
+		return (NX_RCODE_TIMEOUT);
+
+	unm_nic_reg_write(adapter, NX_SIGN_CRB_OFFSET,
+	    HOST_TO_LE_32(signature));
+
+	unm_nic_reg_write(adapter, NX_ARG1_CRB_OFFSET,
+	    HOST_TO_LE_32(arg1));
+
+	unm_nic_reg_write(adapter, NX_ARG2_CRB_OFFSET,
+	    HOST_TO_LE_32(arg2));
+
+	unm_nic_reg_write(adapter, NX_ARG3_CRB_OFFSET,
+	    HOST_TO_LE_32(arg3));
+
+	unm_nic_reg_write(adapter, NX_CDRP_CRB_OFFSET,
+	    HOST_TO_LE_32(NX_CDRP_FORM_CMD(cmd)));
+
+	rsp = netxen_poll_rsp(adapter);
+
+	if (rsp == NX_CDRP_RSP_TIMEOUT) {
+		cmn_err(CE_WARN, "%s: card response timeout.\n",
+		    unm_nic_driver_name);
+
+		rcode = NX_RCODE_TIMEOUT;
+	} else if (rsp == NX_CDRP_RSP_FAIL) {
+		adapter->unm_nic_hw_read_wx(adapter, NX_ARG1_CRB_OFFSET,
+		    &rcode, 4);
+		rcode = LE_TO_HOST_32(rcode);
+
+		cmn_err(CE_WARN, "%s: failed card response code:0x%x\n",
+		    unm_nic_driver_name, rcode);
+	}
+
+	/* Release semaphore */
+	netxen_api_unlock(adapter);
+
+	return (rcode);
+}
+
+int
+nx_fw_cmd_set_mtu(struct unm_adapter_s *adapter, int mtu)
+{
+	u32 rcode = NX_RCODE_SUCCESS;
+	struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0];
+
+	if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
+		rcode = netxen_issue_cmd(adapter,
+		    adapter->ahw.pci_func,
+		    NXHAL_VERSION,
+		    recv_ctx->context_id,
+		    mtu,
+		    0,
+		    NX_CDRP_CMD_SET_MTU);
+
+	if (rcode != NX_RCODE_SUCCESS)
+		return (-EIO);
+
+	return (0);
+}
+
+static int
+nx_fw_cmd_create_rx_ctx(struct unm_adapter_s *adapter)
+{
+	unm_recv_context_t	*recv_ctx = &adapter->recv_ctx[0];
+	nx_hostrq_rx_ctx_t	*prq;
+	nx_cardrsp_rx_ctx_t	*prsp;
+	nx_hostrq_rds_ring_t	*prq_rds;
+	nx_hostrq_sds_ring_t	*prq_sds;
+	nx_cardrsp_rds_ring_t	*prsp_rds;
+	nx_cardrsp_sds_ring_t	*prsp_sds;
+	unm_rcv_desc_ctx_t	*rcv_desc;
+	ddi_dma_cookie_t	cookie;
+	ddi_dma_handle_t	rqdhdl, rsdhdl;
+	ddi_acc_handle_t	rqahdl, rsahdl;
+	uint64_t		hostrq_phys_addr, cardrsp_phys_addr;
+	u64			phys_addr;
+	u32			cap, reg;
+	size_t			rq_size, rsp_size;
+	void			*addr;
+	int			i, nrds_rings, nsds_rings, err;
+
+	/* only one sds ring for now */
+	nrds_rings = adapter->max_rds_rings;
+	nsds_rings = 1;
+
+	rq_size =
+	    SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
+	rsp_size =
+	    SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings);
+
+	if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&addr,
+	    &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS)
+		return (-ENOMEM);
+	hostrq_phys_addr = cookie.dmac_laddress;
+	prq = (nx_hostrq_rx_ctx_t *)addr;
+
+	if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&addr,
+	    &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) {
+		err = -ENOMEM;
+		goto out_free_rq;
+	}
+	cardrsp_phys_addr = cookie.dmac_laddress;
+	prsp = (nx_cardrsp_rx_ctx_t *)addr;
+
+	prq->host_rsp_dma_addr = HOST_TO_LE_64(cardrsp_phys_addr);
+
+	cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
+	cap |= (NX_CAP0_JUMBO_CONTIGUOUS);
+
+	prq->capabilities[0] = HOST_TO_LE_32(cap);
+	prq->host_int_crb_mode =
+	    HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED);
+	prq->host_rds_crb_mode =
+	    HOST_TO_LE_32(NX_HOST_RDS_CRB_MODE_UNIQUE);
+
+	prq->num_rds_rings = HOST_TO_LE_16(nrds_rings);
+	prq->num_sds_rings = HOST_TO_LE_16(nsds_rings);
+	prq->rds_ring_offset = 0;
+	prq->sds_ring_offset = prq->rds_ring_offset +
+	    (sizeof (nx_hostrq_rds_ring_t) * nrds_rings);
+
+	prq_rds = (nx_hostrq_rds_ring_t *)(uintptr_t)(prq->data +
+	    prq->rds_ring_offset);
+
+	for (i = 0; i < nrds_rings; i++) {
+		rcv_desc = &recv_ctx->rcv_desc[i];
+
+		prq_rds[i].host_phys_addr = HOST_TO_LE_64(rcv_desc->phys_addr);
+		prq_rds[i].ring_size = HOST_TO_LE_32(rcv_desc->MaxRxDescCount);
+		prq_rds[i].ring_kind = HOST_TO_LE_32(i);
+		prq_rds[i].buff_size = HOST_TO_LE_64(rcv_desc->dma_size);
+	}
+
+	prq_sds = (nx_hostrq_sds_ring_t *)(uintptr_t)(prq->data +
+	    prq->sds_ring_offset);
+
+	prq_sds[0].host_phys_addr =
+	    HOST_TO_LE_64(recv_ctx->rcvStatusDesc_physAddr);
+	prq_sds[0].ring_size = HOST_TO_LE_32(adapter->MaxRxDescCount);
+	/* only one msix vector for now */
+	prq_sds[0].msi_index = HOST_TO_LE_32(0);
+
+	/* now byteswap offsets */
+	prq->rds_ring_offset = HOST_TO_LE_32(prq->rds_ring_offset);
+	prq->sds_ring_offset = HOST_TO_LE_32(prq->sds_ring_offset);
+
+	phys_addr = hostrq_phys_addr;
+	err = netxen_issue_cmd(adapter,
+	    adapter->ahw.pci_func,
+	    NXHAL_VERSION,
+	    (u32)(phys_addr >> 32),
+	    (u32)(phys_addr & 0xffffffff),
+	    rq_size,
+	    NX_CDRP_CMD_CREATE_RX_CTX);
+	if (err) {
+		cmn_err(CE_WARN, "Failed to create rx ctx in firmware%d\n",
+		    err);
+		goto out_free_rsp;
+	}
+
+
+	prsp_rds = ((nx_cardrsp_rds_ring_t *)(uintptr_t)
+	    &prsp->data[prsp->rds_ring_offset]);
+
+	for (i = 0; i < LE_TO_HOST_32(prsp->num_rds_rings); i++) {
+		rcv_desc = &recv_ctx->rcv_desc[i];
+
+		reg = LE_TO_HOST_32(prsp_rds[i].host_producer_crb);
+		rcv_desc->host_rx_producer = UNM_NIC_REG(reg - 0x200);
+	}
+
+	prsp_sds = ((nx_cardrsp_sds_ring_t *)(uintptr_t)
+	    &prsp->data[prsp->sds_ring_offset]);
+	reg = LE_TO_HOST_32(prsp_sds[0].host_consumer_crb);
+	recv_ctx->host_sds_consumer = UNM_NIC_REG(reg - 0x200);
+
+	reg = LE_TO_HOST_32(prsp_sds[0].interrupt_crb);
+	adapter->interrupt_crb = UNM_NIC_REG(reg - 0x200);
+
+	recv_ctx->state = LE_TO_HOST_32(prsp->host_ctx_state);
+	recv_ctx->context_id = LE_TO_HOST_16(prsp->context_id);
+	recv_ctx->virt_port = LE_TO_HOST_16(prsp->virt_port);
+
+out_free_rsp:
+	unm_pci_free_consistent(&rsdhdl, &rsahdl);
+out_free_rq:
+	unm_pci_free_consistent(&rqdhdl, &rqahdl);
+	return (err);
+}
+
+static void
+nx_fw_cmd_destroy_rx_ctx(struct unm_adapter_s *adapter)
+{
+	struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0];
+
+	if (netxen_issue_cmd(adapter,
+	    adapter->ahw.pci_func,
+	    NXHAL_VERSION,
+	    recv_ctx->context_id,
+	    NX_DESTROY_CTX_RESET,
+	    0,
+	    NX_CDRP_CMD_DESTROY_RX_CTX)) {
+
+		cmn_err(CE_WARN, "%s: Failed to destroy rx ctx in firmware\n",
+		    unm_nic_driver_name);
+	}
+}
+
+static int
+nx_fw_cmd_create_tx_ctx(struct unm_adapter_s *adapter)
+{
+	nx_hostrq_tx_ctx_t	*prq;
+	nx_hostrq_cds_ring_t	*prq_cds;
+	nx_cardrsp_tx_ctx_t	*prsp;
+	ddi_dma_cookie_t	cookie;
+	ddi_dma_handle_t	rqdhdl, rsdhdl;
+	ddi_acc_handle_t	rqahdl, rsahdl;
+	void			*rq_addr, *rsp_addr;
+	size_t			rq_size, rsp_size;
+	u32			temp;
+	int			err = 0;
+	u64			offset, phys_addr;
+	uint64_t		rq_phys_addr, rsp_phys_addr;
+
+	rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
+	if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&rq_addr,
+	    &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS)
+		return (-ENOMEM);
+	rq_phys_addr = cookie.dmac_laddress;
+
+	rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t);
+	if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&rsp_addr,
+	    &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) {
+		err = -ENOMEM;
+		goto out_free_rq;
+	}
+	rsp_phys_addr = cookie.dmac_laddress;
+
+	(void) memset(rq_addr, 0, rq_size);
+	prq = (nx_hostrq_tx_ctx_t *)rq_addr;
+
+	(void) memset(rsp_addr, 0, rsp_size);
+	prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr;
+
+	prq->host_rsp_dma_addr = HOST_TO_LE_64(rsp_phys_addr);
+
+	temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
+	prq->capabilities[0] = HOST_TO_LE_32(temp);
+
+	prq->host_int_crb_mode =
+	    HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED);
+
+	prq->interrupt_ctl = 0;
+	prq->msi_index = 0;
+
+	prq->dummy_dma_addr = HOST_TO_LE_64(adapter->dummy_dma.phys_addr);
+
+	offset = adapter->ctxDesc_physAddr + sizeof (RingContext);
+	prq->cmd_cons_dma_addr = HOST_TO_LE_64(offset);
+
+	prq_cds = &prq->cds_ring;
+
+	prq_cds->host_phys_addr =
+	    HOST_TO_LE_64(adapter->ahw.cmdDesc_physAddr);
+
+	prq_cds->ring_size = HOST_TO_LE_32(adapter->MaxTxDescCount);
+
+	phys_addr = rq_phys_addr;
+	err = netxen_issue_cmd(adapter,
+	    adapter->ahw.pci_func,
+	    NXHAL_VERSION,
+	    (u32)(phys_addr >> 32),
+	    ((u32)phys_addr & 0xffffffff),
+	    rq_size,
+	    NX_CDRP_CMD_CREATE_TX_CTX);
+
+	if (err == NX_RCODE_SUCCESS) {
+		temp = LE_TO_HOST_32(prsp->cds_ring.host_producer_crb);
+		adapter->crb_addr_cmd_producer =
+		    UNM_NIC_REG(temp - 0x200);
+#if 0
+		adapter->tx_state =
+		    LE_TO_HOST_32(prsp->host_ctx_state);
+#endif
+		adapter->tx_context_id =
+		    LE_TO_HOST_16(prsp->context_id);
+	} else {
+		cmn_err(CE_WARN, "Failed to create tx ctx in firmware%d\n",
+		    err);
+		err = -EIO;
+	}
+
+	unm_pci_free_consistent(&rsdhdl, &rsahdl);
+
+out_free_rq:
+	unm_pci_free_consistent(&rqdhdl, &rqahdl);
+
+	return (err);
+}
+
+static void
+nx_fw_cmd_destroy_tx_ctx(struct unm_adapter_s *adapter)
+{
+	if (netxen_issue_cmd(adapter,
+	    adapter->ahw.pci_func,
+	    NXHAL_VERSION,
+	    adapter->tx_context_id,
+	    NX_DESTROY_CTX_RESET,
+	    0,
+	    NX_CDRP_CMD_DESTROY_TX_CTX)) {
+
+		cmn_err(CE_WARN, "%s: Failed to destroy tx ctx in firmware\n",
+		    unm_nic_driver_name);
+	}
+}
+
+static u64 ctx_addr_sig_regs[][3] = {
+	{UNM_NIC_REG(0x188), UNM_NIC_REG(0x18c), UNM_NIC_REG(0x1c0)},
+	{UNM_NIC_REG(0x190), UNM_NIC_REG(0x194), UNM_NIC_REG(0x1c4)},
+	{UNM_NIC_REG(0x198), UNM_NIC_REG(0x19c), UNM_NIC_REG(0x1c8)},
+	{UNM_NIC_REG(0x1a0), UNM_NIC_REG(0x1a4), UNM_NIC_REG(0x1cc)}
+};
+
+#define	CRB_CTX_ADDR_REG_LO(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][0])
+#define	CRB_CTX_ADDR_REG_HI(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][2])
+#define	CRB_CTX_SIGNATURE_REG(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][1])
+
+struct netxen_recv_crb {
+	u32	crb_rcv_producer[NUM_RCV_DESC_RINGS];
+	u32	crb_sts_consumer;
+};
+
+static struct netxen_recv_crb recv_crb_registers[] = {
+	/* Instance 0 */
+	{
+		/* crb_rcv_producer: */
+		{
+			UNM_NIC_REG(0x100),
+			/* Jumbo frames */
+			UNM_NIC_REG(0x110),
+			/* LRO */
+			UNM_NIC_REG(0x120)
+		},
+		/* crb_sts_consumer: */
+		UNM_NIC_REG(0x138),
+	},
+	/* Instance 1 */
+	{
+		/* crb_rcv_producer: */
+		{
+			UNM_NIC_REG(0x144),
+			/* Jumbo frames */
+			UNM_NIC_REG(0x154),
+			/* LRO */
+			UNM_NIC_REG(0x164)
+		},
+		/* crb_sts_consumer: */
+		UNM_NIC_REG(0x17c),
+	},
+	/* Instance 2 */
+	{
+		/* crb_rcv_producer: */
+		{
+			UNM_NIC_REG(0x1d8),
+			/* Jumbo frames */
+			UNM_NIC_REG(0x1f8),
+			/* LRO */
+			UNM_NIC_REG(0x208)
+		},
+		/* crb_sts_consumer: */
+		UNM_NIC_REG(0x220),
+	},
+	/* Instance 3 */
+	{
+		/* crb_rcv_producer: */
+		{
+			UNM_NIC_REG(0x22c),
+			/* Jumbo frames */
+			UNM_NIC_REG(0x23c),
+			/* LRO */
+			UNM_NIC_REG(0x24c)
+		},
+		/* crb_sts_consumer: */
+		UNM_NIC_REG(0x264),
+	},
+};
+
+static uint32_t sw_int_mask[4] = {
+	CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
+	CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
+};
+
+static int
+netxen_init_old_ctx(struct unm_adapter_s *adapter)
+{
+	hardware_context		*hw = &adapter->ahw;
+	struct unm_recv_context_s	*recv_ctx;
+	unm_rcv_desc_ctx_t		*rcv_desc;
+	int				ctx, ring, func_id = adapter->portnum;
+	unsigned int			temp;
+
+	adapter->ctxDesc->CmdRingAddrLo = hw->cmdDesc_physAddr & 0xffffffffUL;
+	adapter->ctxDesc->CmdRingAddrHi = ((U64)hw->cmdDesc_physAddr >> 32);
+	adapter->ctxDesc->CmdRingSize = adapter->MaxTxDescCount;
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		recv_ctx = &adapter->recv_ctx[ctx];
+
+		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+
+			adapter->ctxDesc->RcvContext[ring].RcvRingAddrLo =
+			    rcv_desc->phys_addr & 0xffffffffUL;
+			adapter->ctxDesc->RcvContext[ring].RcvRingAddrHi =
+			    ((U64)rcv_desc->phys_addr>>32);
+			adapter->ctxDesc->RcvContext[ring].RcvRingSize =
+			    rcv_desc->MaxRxDescCount;
+
+			rcv_desc->host_rx_producer =
+			    recv_crb_registers[adapter->portnum].
+			    crb_rcv_producer[ring];
+		}
+
+		adapter->ctxDesc->StsRingAddrLo =
+		    recv_ctx->rcvStatusDesc_physAddr & 0xffffffff;
+		adapter->ctxDesc->StsRingAddrHi =
+		    recv_ctx->rcvStatusDesc_physAddr >> 32;
+		adapter->ctxDesc->StsRingSize = adapter->MaxRxDescCount;
+
+		recv_ctx->host_sds_consumer =
+		    recv_crb_registers[adapter->portnum].crb_sts_consumer;
+	}
+
+	adapter->interrupt_crb = sw_int_mask[adapter->portnum];
+
+	temp = lower32(adapter->ctxDesc_physAddr);
+	adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_LO(func_id),
+	    &temp, 4);
+	temp = upper32(adapter->ctxDesc_physAddr);
+	adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_HI(func_id),
+	    &temp, 4);
+	temp = UNM_CTX_SIGNATURE | func_id;
+	adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_SIGNATURE_REG(func_id),
+	    &temp, 4);
+
+	return (0);
+}
+
+void
+netxen_destroy_rxtx(struct unm_adapter_s *adapter)
+{
+	if (adapter->fw_major >= 4) {
+		nx_fw_cmd_destroy_tx_ctx(adapter);
+		nx_fw_cmd_destroy_rx_ctx(adapter);
+	}
+}
+
+int
+netxen_create_rxtx(struct unm_adapter_s *adapter)
+{
+	int	err;
+
+	if (adapter->fw_major >= 4) {
+		err = nx_fw_cmd_create_rx_ctx(adapter);
+		if (err)
+			return (err);
+		err = nx_fw_cmd_create_tx_ctx(adapter);
+		if (err)
+			nx_fw_cmd_destroy_rx_ctx(adapter);
+		return (err);
+	} else {
+		return (netxen_init_old_ctx(adapter));
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic_hw.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,2204 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/debug.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#include <sys/strlog.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/vtrace.h>
+#include <sys/dlpi.h>
+#include <sys/strsun.h>
+#include <sys/ethernet.h>
+#include <sys/modctl.h>
+#include <sys/errno.h>
+#include <sys/dditypes.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+
+#include <sys/pci.h>
+
+#include "unm_nic.h"
+#include "unm_nic_hw.h"
+#include "nic_cmn.h"
+#include "unm_brdcfg.h"
+#include "driver_info.h"
+
+long unm_niu_gbe_phy_read(struct unm_adapter_s *,
+		long reg, unm_crbword_t *readval);
+
+#define	MASK(n)			((1ULL<<(n))-1)
+#define	MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
+#define	OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) |	\
+		((addr >> 25) & 0x3ff)) // 64K?
+#define	MS_WIN(addr) (addr & 0x0ffc0000)
+#define	UNM_PCI_MN_2M   (0)
+#define	UNM_PCI_MS_2M   (0x80000)
+#define	UNM_PCI_OCM0_2M (0xc0000)
+#define	VALID_OCM_ADDR(addr) (((addr) & 0x3f800) != 0x3f800)
+#define	GET_MEM_OFFS_2M(addr) (addr & MASK(18))
+
+#define	CRB_BLK(off)	((off >> 20) & 0x3f)
+#define	CRB_SUBBLK(off)	((off >> 16) & 0xf)
+#define	CRB_WINDOW_2M	(0x130060)
+#define	UNM_PCI_CAMQM_2M_END	(0x04800800UL)
+#define	CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
+#define	UNM_PCI_CAMQM_2M_BASE	(0x000ff800UL)
+#define	CRB_INDIRECT_2M	(0x1e0000UL)
+
+static crb_128M_2M_block_map_t	crb_128M_2M_map[64] = {
+	    {{{0, 0, 0, 0}}}, /* 0: PCI */
+	    {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
+	    {1, 0x0110000, 0x0120000, 0x130000},
+	    {1, 0x0120000, 0x0122000, 0x124000},
+	    {1, 0x0130000, 0x0132000, 0x126000},
+	    {1, 0x0140000, 0x0142000, 0x128000},
+	    {1, 0x0150000, 0x0152000, 0x12a000},
+	    {1, 0x0160000, 0x0170000, 0x110000},
+	    {1, 0x0170000, 0x0172000, 0x12e000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {1, 0x01e0000, 0x01e0800, 0x122000},
+	    {0, 0x0000000, 0x0000000, 0x000000}}},
+	    {{{1, 0x0200000, 0x0210000, 0x180000}}}, /* 2: MN */
+	    {{{0, 0, 0, 0}}}, /* 3: */
+	    {{{1, 0x0400000, 0x0401000, 0x169000}}}, /* 4: P2NR1 */
+	    {{{1, 0x0500000, 0x0510000, 0x140000}}}, /* 5: SRE   */
+	    {{{1, 0x0600000, 0x0610000, 0x1c0000}}}, /* 6: NIU   */
+	    {{{1, 0x0700000, 0x0704000, 0x1b8000}}}, /* 7: QM    */
+	    {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0  */
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {1, 0x08f0000, 0x08f2000, 0x172000}}},
+	    {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1 */
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {1, 0x09f0000, 0x09f2000, 0x176000}}},
+	    {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2 */
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {1, 0x0af0000, 0x0af2000, 0x17a000}}},
+	    {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3 */
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
+	    {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}}, /* 12: I2Q */
+	    {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}}, /* 13: TMR */
+	    {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}}, /* 14: ROMUSB */
+	    {{{1, 0x0f00000, 0x0f01000, 0x164000}}}, /* 15: PEG4 */
+	    {{{0, 0x1000000, 0x1004000, 0x1a8000}}}, /* 16: XDMA */
+	    {{{1, 0x1100000, 0x1101000, 0x160000}}}, /* 17: PEG0 */
+	    {{{1, 0x1200000, 0x1201000, 0x161000}}}, /* 18: PEG1 */
+	    {{{1, 0x1300000, 0x1301000, 0x162000}}}, /* 19: PEG2 */
+	    {{{1, 0x1400000, 0x1401000, 0x163000}}}, /* 20: PEG3 */
+	    {{{1, 0x1500000, 0x1501000, 0x165000}}}, /* 21: P2ND */
+	    {{{1, 0x1600000, 0x1601000, 0x166000}}}, /* 22: P2NI */
+	    {{{0, 0, 0, 0}}}, /* 23: */
+	    {{{0, 0, 0, 0}}}, /* 24: */
+	    {{{0, 0, 0, 0}}}, /* 25: */
+	    {{{0, 0, 0, 0}}}, /* 26: */
+	    {{{0, 0, 0, 0}}}, /* 27: */
+	    {{{0, 0, 0, 0}}}, /* 28: */
+	    {{{1, 0x1d00000, 0x1d10000, 0x190000}}}, /* 29: MS */
+	    {{{1, 0x1e00000, 0x1e01000, 0x16a000}}}, /* 30: P2NR2 */
+	    {{{1, 0x1f00000, 0x1f10000, 0x150000}}}, /* 31: EPG */
+	    {{{0}}}, /* 32: PCI */
+	    {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */
+	    {1, 0x2110000, 0x2120000, 0x130000},
+	    {1, 0x2120000, 0x2122000, 0x124000},
+	    {1, 0x2130000, 0x2132000, 0x126000},
+	    {1, 0x2140000, 0x2142000, 0x128000},
+	    {1, 0x2150000, 0x2152000, 0x12a000},
+	    {1, 0x2160000, 0x2170000, 0x110000},
+	    {1, 0x2170000, 0x2172000, 0x12e000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000},
+	    {0, 0x0000000, 0x0000000, 0x000000}}},
+	    {{{1, 0x2200000, 0x2204000, 0x1b0000}}}, /* 34: CAM */
+	    {{{0}}}, /* 35: */
+	    {{{0}}}, /* 36: */
+	    {{{0}}}, /* 37: */
+	    {{{0}}}, /* 38: */
+	    {{{0}}}, /* 39: */
+	    {{{1, 0x2800000, 0x2804000, 0x1a4000}}}, /* 40: TMR */
+	    {{{1, 0x2900000, 0x2901000, 0x16b000}}}, /* 41: P2NR3 */
+	    {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}}, /* 42: RPMX1 */
+	    {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}}, /* 43: RPMX2 */
+	    {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}}, /* 44: RPMX3 */
+	    {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}}, /* 45: RPMX4 */
+	    {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}}, /* 46: RPMX5 */
+	    {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}}, /* 47: RPMX6 */
+	    {{{1, 0x3000000, 0x3000400, 0x1adc00}}}, /* 48: RPMX7 */
+	    {{{0, 0x3100000, 0x3104000, 0x1a8000}}}, /* 49: XDMA */
+	    {{{1, 0x3200000, 0x3204000, 0x1d4000}}}, /* 50: I2Q */
+	    {{{1, 0x3300000, 0x3304000, 0x1a0000}}}, /* 51: ROMUSB */
+	    {{{0}}}, /* 52: */
+	    {{{1, 0x3500000, 0x3500400, 0x1ac000}}}, /* 53: RPMX0 */
+	    {{{1, 0x3600000, 0x3600400, 0x1ae000}}}, /* 54: RPMX8 */
+	    {{{1, 0x3700000, 0x3700400, 0x1ae400}}}, /* 55: RPMX9 */
+	    {{{1, 0x3800000, 0x3804000, 0x1d0000}}}, /* 56: OCM0 */
+	    {{{1, 0x3900000, 0x3904000, 0x1b4000}}}, /* 57: CRYPTO */
+	    {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}}, /* 58: SMB */
+	    {{{0}}}, /* 59: I2C0 */
+	    {{{0}}}, /* 60: I2C1 */
+	    {{{1, 0x3d00000, 0x3d04000, 0x1d8000}}}, /* 61: LPC */
+	    {{{1, 0x3e00000, 0x3e01000, 0x167000}}}, /* 62: P2NC */
+	    {{{1, 0x3f00000, 0x3f01000, 0x168000}}} /* 63: P2NR0 */
+};
+
+/*
+ * top 12 bits of crb internal address (hub, agent)
+ */
+static unsigned crb_hub_agt[64] = {
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_PS,
+	UNM_HW_CRB_HUB_AGT_ADR_MN,
+	UNM_HW_CRB_HUB_AGT_ADR_MS,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_SRE,
+	UNM_HW_CRB_HUB_AGT_ADR_NIU,
+	UNM_HW_CRB_HUB_AGT_ADR_QMN,
+	UNM_HW_CRB_HUB_AGT_ADR_SQN0,
+	UNM_HW_CRB_HUB_AGT_ADR_SQN1,
+	UNM_HW_CRB_HUB_AGT_ADR_SQN2,
+	UNM_HW_CRB_HUB_AGT_ADR_SQN3,
+	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
+	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
+	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
+	UNM_HW_CRB_HUB_AGT_ADR_PGN4,
+	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
+	UNM_HW_CRB_HUB_AGT_ADR_PGN0,
+	UNM_HW_CRB_HUB_AGT_ADR_PGN1,
+	UNM_HW_CRB_HUB_AGT_ADR_PGN2,
+	UNM_HW_CRB_HUB_AGT_ADR_PGN3,
+	UNM_HW_CRB_HUB_AGT_ADR_PGND,
+	UNM_HW_CRB_HUB_AGT_ADR_PGNI,
+	UNM_HW_CRB_HUB_AGT_ADR_PGS0,
+	UNM_HW_CRB_HUB_AGT_ADR_PGS1,
+	UNM_HW_CRB_HUB_AGT_ADR_PGS2,
+	UNM_HW_CRB_HUB_AGT_ADR_PGS3,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_PGSI,
+	UNM_HW_CRB_HUB_AGT_ADR_SN,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_EG,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_PS,
+	UNM_HW_CRB_HUB_AGT_ADR_CAM,
+	0,
+	0,
+	0,
+	0,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
+	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
+	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
+	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
+	UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
+	UNM_HW_CRB_HUB_AGT_ADR_OCM0,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_SMB,
+	UNM_HW_CRB_HUB_AGT_ADR_I2C0,
+	UNM_HW_CRB_HUB_AGT_ADR_I2C1,
+	0,
+	UNM_HW_CRB_HUB_AGT_ADR_PGNC,
+	0,
+};
+
+#define	CRB_WIN_LOCK_TIMEOUT 100000000
+
+static void
+crb_win_lock(struct unm_adapter_s *adapter)
+{
+	int i;
+	int done = 0, timeout = 0;
+
+	while (!done) {
+		/* acquire semaphore3 from PCI HW block */
+		adapter->unm_nic_hw_read_wx(adapter,
+		    UNM_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
+		if (done == 1)
+			break;
+		if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
+			cmn_err(CE_WARN, "%s%d: crb_win_lock timed out\n",
+			    adapter->name, adapter->instance);
+			return;
+		}
+		timeout++;
+		/*
+		 *  Yield CPU
+		 */
+		for (i = 0; i < 20; i++);
+	}
+	adapter->unm_crb_writelit_adapter(adapter, UNM_CRB_WIN_LOCK_ID,
+	    adapter->portnum);
+}
+
+static void
+crb_win_unlock(struct unm_adapter_s *adapter)
+{
+	int	val;
+
+	adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_SEM7_UNLOCK),
+	    &val, 4);
+}
+
+/*
+ * Changes the CRB window to the specified window.
+ */
+void
+unm_nic_pci_change_crbwindow_128M(unm_adapter *adapter, uint32_t wndw)
+{
+	unm_pcix_crb_window_t	window;
+	unsigned long			offset;
+	uint32_t				tmp;
+
+	if (adapter->curr_window == wndw) {
+		return;
+	}
+
+	/*
+	 * Move the CRB window.
+	 * We need to write to the "direct access" region of PCI
+	 * to avoid a race condition where the window register has
+	 * not been successfully written across CRB before the target
+	 * register address is received by PCI. The direct region bypasses
+	 * the CRB bus.
+	 */
+	offset = PCI_OFFSET_SECOND_RANGE(adapter,
+	    UNM_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(adapter->ahw.pci_func)));
+
+	*(unm_crbword_t *)&window = 0;
+	window.addrbit = wndw;
+	UNM_NIC_PCI_WRITE_32(*(unsigned int *)&window, (void*) (offset));
+	/* MUST make sure window is set before we forge on... */
+	while ((tmp = UNM_NIC_PCI_READ_32((void*) offset)) !=
+	    *(uint32_t *)&window) {
+		cmn_err(CE_WARN, "%s: %s WARNING: CRB window value not "
+		    "registered properly: 0x%08x.\n",
+		    unm_nic_driver_name, __FUNCTION__, tmp);
+	}
+
+	adapter->curr_window = wndw;
+}
+
+
+/*
+ * Changes the CRB window to the specified window.
+ */
+/* ARGSUSED */
+void
+unm_nic_pci_change_crbwindow_2M(unm_adapter *adapter, uint32_t wndw)
+{
+}
+
+
+uint32_t
+unm_nic_get_crbwindow(unm_adapter *adapter)
+{
+	return (adapter->curr_window);
+}
+
+/*
+ * Return -1 if off is not valid,
+ *	 1 if window access is needed. 'off' is set to offset from
+ *	   CRB space in 128M pci map
+ *	 0 if no window access is needed. 'off' is set to 2M addr
+ * In: 'off' is offset from base in 128M pci map
+ */
+int
+unm_nic_pci_get_crb_addr_2M(unm_adapter *adapter, u64 *off, int len)
+{
+	unsigned long end = *off + len;
+	crb_128M_2M_sub_block_map_t *m;
+
+
+	if (*off >= UNM_CRB_MAX)
+		return (-1);
+
+	if (*off >= UNM_PCI_CAMQM && (end <= UNM_PCI_CAMQM_2M_END)) {
+		*off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
+		    adapter->ahw.pci_base0;
+		return (0);
+	}
+
+	if (*off < UNM_PCI_CRBSPACE)
+		return (-1);
+
+	*off -= UNM_PCI_CRBSPACE;
+	end = *off + len;
+	/*
+	 * Try direct map
+	 */
+
+	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
+
+	if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
+		*off = *off + m->start_2M - m->start_128M +
+		    adapter->ahw.pci_base0;
+		return (0);
+	}
+
+	/*
+	 * Not in direct map, use crb window
+	 */
+	return (1);
+}
+/*
+ * In: 'off' is offset from CRB space in 128M pci map
+ * Out: 'off' is 2M pci map addr
+ * side effect: lock crb window
+ */
+static void
+unm_nic_pci_set_crbwindow_2M(unm_adapter *adapter, u64 *off)
+{
+	u32 win_read;
+
+	adapter->crb_win = CRB_HI(*off);
+	UNM_NIC_PCI_WRITE_32(adapter->crb_win, (void *) (CRB_WINDOW_2M +
+	    adapter->ahw.pci_base0));
+	/*
+	 * Read back value to make sure write has gone through before trying
+	 * to use it.
+	 */
+	win_read = UNM_NIC_PCI_READ_32((void *)
+	    (CRB_WINDOW_2M + adapter->ahw.pci_base0));
+	if (win_read != adapter->crb_win) {
+		cmn_err(CE_WARN, "%s: Written crbwin (0x%x) != Read crbwin "
+		    "(0x%x), off=0x%llx\n", __FUNCTION__, adapter->crb_win,
+		    win_read, *off);
+	}
+	*off = (*off & MASK(16)) + CRB_INDIRECT_2M +
+	    adapter->ahw.pci_base0;
+}
+
+int
+unm_nic_hw_write_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
+{
+	void		*addr;
+	u64		offset = off;
+
+	if (ADDR_IN_WINDOW1(off)) { // Window 1
+		addr = CRB_NORMALIZE(adapter, off);
+		if (!addr) {
+			offset = CRB_NORMAL(off);
+			if (adapter->ahw.pci_len0 == 0)
+				offset -= UNM_PCI_CRBSPACE;
+			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
+			    offset);
+		}
+		UNM_READ_LOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
+		if (!addr) {
+			offset = off;
+			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
+			    offset);
+		}
+		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+		unm_nic_pci_change_crbwindow_128M(adapter, 0);
+	}
+
+	switch (len) {
+		case 1:
+			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
+			break;
+		case 2:
+			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
+			break;
+		case 4:
+			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
+			break;
+		case 8:
+			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
+			break;
+		default:
+#if !defined(NDEBUG)
+		if ((len & 0x7) != 0)
+			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
+			    unm_nic_driver_name, __FUNCTION__, len);
+#endif
+		UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
+		break;
+	}
+	if (ADDR_IN_WINDOW1(off)) {// Window 1
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		unm_nic_pci_change_crbwindow_128M(adapter, 1);
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	}
+
+	return (0);
+}
+
+/*
+ * Note : 'len' argument should be either 1, 2, 4, or a multiple of 8.
+ */
+int
+unm_nic_hw_write_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
+{
+	/*
+	 * This is modified from _unm_nic_hw_write().
+	 * unm_nic_hw_write does not exist now.
+	 */
+
+	void *addr;
+
+	if (ADDR_IN_WINDOW1(off)) {// Window 1
+		addr = CRB_NORMALIZE(adapter, off);
+		UNM_READ_LOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
+		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+		unm_nic_pci_change_crbwindow_128M(adapter, 0);
+	}
+
+
+	if (!addr) {
+		if (ADDR_IN_WINDOW1(off)) {// Window 1
+			UNM_READ_UNLOCK(&adapter->adapter_lock);
+		} else {// Window 0
+			unm_nic_pci_change_crbwindow_128M(adapter, 1);
+			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+		}
+		return (1);
+	}
+
+	switch (len) {
+		case 1:
+			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
+			break;
+		case 2:
+			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
+			break;
+		case 4:
+			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
+			break;
+		case 8:
+			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
+			break;
+		default:
+#if !defined(NDEBUG)
+			if ((len & 0x7) != 0)
+				cmn_err(CE_WARN,
+				    "%s: %s  len(%d) not multiple of 8.\n",
+				    unm_nic_driver_name, __FUNCTION__, len);
+#endif
+			UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
+			break;
+	}
+	if (ADDR_IN_WINDOW1(off)) {// Window 1
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		unm_nic_pci_change_crbwindow_128M(adapter, 1);
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	}
+
+	return (0);
+}
+
+/*
+ * Note : only 32-bit writes!
+ */
+void
+unm_nic_pci_write_normalize_128M(unm_adapter *adapter, u64 off, u32 data)
+{
+	UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
+}
+
+/*
+ * Note : only 32-bit reads!
+ */
+u32
+unm_nic_pci_read_normalize_128M(unm_adapter *adapter, u64 off)
+{
+	return (UNM_NIC_PCI_READ_32(CRB_NORMALIZE(adapter, off)));
+}
+
+/*
+ * Note : only 32-bit writes!
+ */
+int
+unm_nic_pci_write_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
+{
+	UNM_NIC_PCI_WRITE_32(*data,
+	    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
+	return (0);
+}
+
+/*
+ * Note : only 32-bit reads!
+ */
+int
+unm_nic_pci_read_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
+{
+	*data = UNM_NIC_PCI_READ_32((void *)
+	    (uptr_t)(pci_base_offset(adapter, off)));
+	return (0);
+}
+
+/*
+ * Note : only 32-bit writes!
+ */
+void
+unm_nic_pci_write_normalize_2M(unm_adapter *adapter, u64 off, u32 data)
+{
+	u32 temp = data;
+
+	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
+}
+
+/*
+ * Note : only 32-bit reads!
+ */
+u32
+unm_nic_pci_read_normalize_2M(unm_adapter *adapter, u64 off)
+{
+	u32 temp;
+
+	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
+
+	return (temp);
+}
+
+/*
+ * Note : only 32-bit writes!
+ */
+int
+unm_nic_pci_write_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
+{
+	u32 temp = *data;
+
+	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
+
+	return (0);
+}
+
+/*
+ * Note : only 32-bit reads!
+ */
+int
+unm_nic_pci_read_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
+{
+	u32 temp;
+
+	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
+
+	*data = temp;
+
+	return (0);
+}
+
+/*
+ * write cross hw window boundary is not supported
+ * 'len' should be either 1, 2, 4, or multiple of 8
+ */
+int
+unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
+{
+	int rv;
+
+	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
+
+	if (rv == -1) {
+		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
+		    __FUNCTION__, off);
+		return (-1);
+	}
+
+	if (rv == 1) {
+		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+		crb_win_lock(adapter);
+		unm_nic_pci_set_crbwindow_2M(adapter, &off);
+	}
+
+	switch (len) {
+	case 1:
+		UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
+		break;
+	case 2:
+		UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
+		break;
+	case 4:
+		UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
+		break;
+	case 8:
+		UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
+		break;
+	default:
+#if !defined(NDEBUG)
+		if ((len & 0x7) != 0)
+			cmn_err(CE_WARN, "%s: %s  len(%d) not multiple of 8.\n",
+			    unm_nic_driver_name, __FUNCTION__, len);
+#endif
+		UNM_NIC_HW_BLOCK_WRITE_64(data, (uptr_t)off, (len>>3));
+		break;
+	}
+	if (rv == 1) {
+		crb_win_unlock(adapter);
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	}
+
+	return (0);
+}
+
+int
+unm_nic_hw_read_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
+{
+	void		*addr;
+	u64		offset;
+
+	if (ADDR_IN_WINDOW1(off)) {// Window 1
+		addr = CRB_NORMALIZE(adapter, off);
+		if (!addr) {
+			offset = CRB_NORMAL(off);
+			if (adapter->ahw.pci_len0 == 0)
+				offset -= UNM_PCI_CRBSPACE;
+			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
+			    offset);
+		}
+		UNM_READ_LOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
+		if (!addr) {
+			offset = off;
+			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
+			    offset);
+		}
+		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+		unm_nic_pci_change_crbwindow_128M(adapter, 0);
+	}
+
+	switch (len) {
+	case 1:
+		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
+		break;
+	case 2:
+		*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
+		break;
+	case 4:
+		*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
+		break;
+	case 8:
+		*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
+		break;
+	default:
+#if !defined(NDEBUG)
+		if ((len & 0x7) != 0)
+			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
+			    unm_nic_driver_name, __FUNCTION__, len);
+#endif
+		UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
+		break;
+	}
+
+	if (ADDR_IN_WINDOW1(off)) {// Window 1
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		unm_nic_pci_change_crbwindow_128M(adapter, 1);
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	}
+
+	return (0);
+}
+
+int
+unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
+{
+	int rv;
+
+	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
+
+	if (rv == -1) {
+		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
+		    __FUNCTION__, off);
+		return (-1);
+	}
+
+	if (rv == 1) {
+		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+		crb_win_lock(adapter);
+		unm_nic_pci_set_crbwindow_2M(adapter, &off);
+	}
+
+	switch (len) {
+	case 1:
+		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
+		break;
+	case 2:
+		*(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
+		break;
+	case 4:
+		*(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
+		break;
+	case 8:
+		*(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
+		break;
+	default:
+#if !defined(NDEBUG)
+		if ((len & 0x7) != 0)
+			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
+			    unm_nic_driver_name, __FUNCTION__, len);
+#endif
+		UNM_NIC_HW_BLOCK_READ_64(data, (void *) (uptr_t)off, (len>>3));
+		break;
+	}
+
+	if (rv == 1) {
+		crb_win_unlock(adapter);
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	}
+
+	return (0);
+}
+
+int
+unm_nic_hw_read_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
+{
+	void *addr;
+
+	if (ADDR_IN_WINDOW1(off)) {
+		// Window 1
+		addr = CRB_NORMALIZE(adapter, off);
+		UNM_READ_LOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
+		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+		unm_nic_pci_change_crbwindow_128M(adapter, 0);
+	}
+
+	if (!addr) {
+		if (ADDR_IN_WINDOW1(off)) {// Window 1
+			UNM_READ_UNLOCK(&adapter->adapter_lock);
+		} else {// Window 0
+			unm_nic_pci_change_crbwindow_128M(adapter, 1);
+			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+		}
+		return (1);
+	}
+
+	switch (len) {
+		case 1:
+			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
+			break;
+		case 2:
+			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
+			break;
+		case 4:
+			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
+			break;
+		case 8:
+			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
+			break;
+		default:
+#if !defined(NDEBUG)
+			if ((len & 0x7) != 0)
+				cmn_err(CE_WARN,
+				    "%s: %s len(%d) not multiple of 8.\n",
+				    unm_nic_driver_name, __FUNCTION__, len);
+#endif
+			UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
+			break;
+	}
+
+	if (ADDR_IN_WINDOW1(off)) {// Window 1
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	} else {// Window 0
+		unm_nic_pci_change_crbwindow_128M(adapter, 1);
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	}
+
+	return (0);
+}
+
+/*  PCI Windowing for DDR regions.  */
+#define	ADDR_IN_RANGE(addr, low, high)	    \
+	(((addr) <= (high)) && ((low) ? ((addr) >= (low)) : 1))
+
+/*
+ * check memory access boundary.
+ * used by test agent. support ddr access only for now
+ */
+/* ARGSUSED */
+static unsigned long
+unm_nic_pci_mem_bound_check(struct unm_adapter_s *adapter,
+    unsigned long long addr, int size)
+{
+	if (!ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX) ||
+	    !ADDR_IN_RANGE(addr + size -1, UNM_ADDR_DDR_NET,
+	    UNM_ADDR_DDR_NET_MAX) || ((size != 1) && (size != 2) &&
+	    (size != 4) && (size != 8)))
+		return (0);
+
+	return (1);
+}
+
+int unm_pci_set_window_warning_count = 0;
+
+unsigned long long
+unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
+    unsigned long long addr)
+{
+	int		window;
+	unsigned long long	qdr_max;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
+	} else {
+		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
+	}
+
+	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
+		/* DDR network side */
+		/* MN access should never come here */
+		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
+		addr = -1ULL;
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
+		addr -= UNM_ADDR_OCM0;
+		addr += UNM_PCI_OCM0;
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
+		addr -= UNM_ADDR_OCM1;
+		addr += UNM_PCI_OCM1;
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
+		/* QDR network side */
+		addr -= UNM_ADDR_QDR_NET;
+		window = (addr >> 22) & 0x3f;
+		if (adapter->ahw.qdr_sn_window != window) {
+			adapter->ahw.qdr_sn_window = window;
+			UNM_NIC_PCI_WRITE_32((window << 22),
+			    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
+			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
+			    adapter->ahw.pci_func)))));
+			/* MUST make sure window is set before we forge on... */
+			(void) UNM_NIC_PCI_READ_32((void *)
+			    (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
+			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
+			    adapter->ahw.pci_func)))));
+		}
+		addr -= (window * 0x400000);
+		addr += UNM_PCI_QDR_NET;
+	} else {
+		/*
+		 * peg gdb frequently accesses memory that doesn't exist,
+		 * this limits the chit chat so debugging isn't slowed down.
+		 */
+		if ((unm_pci_set_window_warning_count++ < 8) ||
+		    (unm_pci_set_window_warning_count%64 == 0)) {
+			cmn_err(CE_WARN, "%s: Warning:unm_nic_pci_set_window() "
+			    "Unknown address range!\n", unm_nic_driver_name);
+		}
+		addr = -1ULL;
+	}
+	return (addr);
+}
+
+unsigned long long
+unm_nic_pci_set_window_2M(struct unm_adapter_s *adapter,
+    unsigned long long addr)
+{
+	int window;
+	u32 win_read;
+
+	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
+		/* DDR network side */
+		window = MN_WIN(addr);
+		adapter->ahw.ddr_mn_window = window;
+		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
+		    UNM_PCI_CRBSPACE, &window, 4);
+		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
+		    UNM_PCI_CRBSPACE, &win_read, 4);
+		if ((win_read << 17) != window) {
+			cmn_err(CE_WARN,
+			    "%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
+			    __FUNCTION__, window, win_read);
+		}
+		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
+		unsigned int temp1;
+// OCM: pci_addr[20:18] == 011 && pci_addr[17:11] != 7f
+		if ((addr & 0x00ff800) == 0xff800) {
+			// if bits 19:18&17:11 are on
+			cmn_err(CE_WARN, "%s: QM access not handled.\n",
+			    __FUNCTION__);
+			addr = -1ULL;
+		}
+
+		window = OCM_WIN(addr);
+		adapter->ahw.ddr_mn_window = window;
+		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
+		    UNM_PCI_CRBSPACE, &window, 4);
+		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
+		    UNM_PCI_CRBSPACE, &win_read, 4);
+		temp1 = ((window & 0x1FF) << 7) |
+		    ((window & 0x0FFFE0000) >> 17);
+		if (win_read != temp1) {
+			cmn_err(CE_WARN,
+			    "%s: Written OCMwin(0x%x) != Read OCMwin(0x%x)\n",
+			    __FUNCTION__, temp1, win_read);
+		}
+		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
+
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
+	    NX_P3_ADDR_QDR_NET_MAX)) {
+		/* QDR network side */
+		window = MS_WIN(addr);
+		adapter->ahw.qdr_sn_window = window;
+		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.ms_win_crb |
+		    UNM_PCI_CRBSPACE, &window, 4);
+		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.ms_win_crb |
+		    UNM_PCI_CRBSPACE, &win_read, 4);
+		if (win_read != window) {
+			cmn_err(CE_WARN,
+			    "%s: Written MSwin (0x%x) != Read MSwin (0x%x)\n",
+			    __FUNCTION__, window, win_read);
+		}
+		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
+
+	} else {
+		/*
+		 * peg gdb frequently accesses memory that doesn't exist,
+		 * this limits the chit chat so debugging isn't slowed down.
+		 */
+		if ((unm_pci_set_window_warning_count++ < 8) ||
+		    (unm_pci_set_window_warning_count%64 == 0)) {
+			cmn_err(CE_WARN, "%s%d: %s Unknown address range!\n",
+			    adapter->name, adapter->instance, __FUNCTION__);
+		}
+		addr = -1ULL;
+	}
+	return (addr);
+}
+
+/* check if address is in the same windows as the previous access */
+static unsigned long
+unm_nic_pci_is_same_window(struct unm_adapter_s *adapter,
+    unsigned long long addr)
+{
+	int			window;
+	unsigned long long	qdr_max;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
+	} else {
+		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
+	}
+
+	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
+		/* DDR network side */
+		/* MN access can not come here */
+		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
+#if 0
+		window = ((addr - UNM_ADDR_DDR_NET) >> 25) & 0x3ff;
+		if (adapter->ahw.ddr_mn_window == window) {
+			return (1);
+		}
+#endif
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
+		return (1);
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
+		return (1);
+	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
+		/* QDR network side */
+		window = ((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f;
+		if (adapter->ahw.qdr_sn_window == window) {
+			return (1);
+		}
+	}
+
+	return (0);
+}
+
+static int
+unm_nic_pci_mem_read_direct(struct unm_adapter_s *adapter,
+    u64 off, void *data, int size)
+{
+	void			*addr;
+	int				ret = 0;
+	u64				start;
+
+#if 0
+	/*
+	 * This check can not be currently executed, since phanmon findq
+	 * command breaks this check whereby 8 byte reads are being attempted
+	 * on "aligned-by-4" addresses on x86. Reason this works is our version
+	 * breaks up the access into 2 consecutive 4 byte writes; on other
+	 * architectures, this might require "aligned-by-8" addresses and we
+	 * will run into trouble.
+	 *
+	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
+	 * values will not trigger access.
+	 */
+	if ((off & (size - 1)) != 0)
+		return (-1);
+#endif
+
+	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+
+	/*
+	 * If attempting to access unknown address or straddle hw windows,
+	 * do not access.
+	 */
+	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
+	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+		cmn_err(CE_WARN, "%s out of bound pci memory access. "
+		    "offset is 0x%llx\n", unm_nic_driver_name, off);
+		return (-1);
+	}
+
+	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
+	if (!addr)
+		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
+
+	switch (size) {
+		case 1:
+			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
+			break;
+		case 2:
+			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
+			break;
+		case 4:
+			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
+			break;
+		case 8:
+			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
+			break;
+		default:
+			ret = -1;
+			break;
+	}
+
+	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	return (ret);
+}
+
+static int
+unm_nic_pci_mem_write_direct(struct unm_adapter_s *adapter, u64 off,
+    void *data, int size)
+{
+	void	*addr;
+	int		ret = 0;
+	u64		start;
+
+#if 0
+	/*
+	 * This check can not be currently executed, since firmware load
+	 * breaks this check whereby 8 byte writes are being attempted on
+	 * "aligned-by-4" addresses on x86. Reason this works is our version
+	 * breaks up the access into 2 consecutive 4 byte writes; on other
+	 * architectures, this might require "aligned-by-8" addresses and we
+	 * will run into trouble.
+	 *
+	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
+	 * values will not trigger access.
+	 */
+	if ((off & (size - 1)) != 0)
+		return (-1);
+#endif
+
+	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+
+	/*
+	 * If attempting to access unknown address or straddle hw windows,
+	 * do not access.
+	 */
+	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
+	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+		cmn_err(CE_WARN, "%s out of bound pci memory access. "
+		    "offset is 0x%llx\n", unm_nic_driver_name, off);
+		return (-1);
+	}
+
+	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
+	if (!addr)
+		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
+
+	switch (size) {
+		case 1:
+			UNM_NIC_PCI_WRITE_8(*(__uint8_t  *)data, addr);
+			break;
+		case 2:
+			UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, addr);
+			break;
+		case 4:
+			UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, addr);
+			break;
+		case 8:
+			UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, addr);
+			break;
+		default:
+			ret = -1;
+			break;
+	}
+	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	return (ret);
+}
+
+
+int
+unm_nic_pci_mem_write_128M(struct unm_adapter_s *adapter, u64 off, void *data,
+    int size)
+{
+	int		i, j, ret = 0, loop, sz[2], off0;
+	__uint32_t		temp;
+	__uint64_t		off8, mem_crb, tmpw, word[2] = {0, 0};
+#define	MAX_CTL_CHECK   1000
+
+	/*
+	 * If not MN, go check for MS or invalid.
+	 */
+	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
+		return (unm_nic_pci_mem_write_direct(adapter, off, data, size));
+
+	off8 = off & 0xfffffff8;
+	off0 = off & 0x7;
+	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
+	sz[1] = size - sz[0];
+	loop = ((off0 + size - 1) >> 3) + 1;
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
+
+	if ((size != 8) || (off0 != 0))  {
+		for (i = 0; i < loop; i++) {
+			if (adapter->unm_nic_pci_mem_read(adapter,
+			    off8 + (i << 3), &word[i], 8))
+				return (-1);
+		}
+	}
+
+	switch (size) {
+		case 1:
+			tmpw = *((__uint8_t *)data);
+			break;
+		case 2:
+			tmpw = *((__uint16_t *)data);
+			break;
+		case 4:
+			tmpw = *((__uint32_t *)data);
+			break;
+		case 8:
+		default:
+			tmpw = *((__uint64_t *)data);
+			break;
+	}
+	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
+	word[0] |= tmpw << (off0 * 8);
+
+	if (loop == 2) {
+		word[1] &= ~(~0ULL << (sz[1] * 8));
+		word[1] |= tmpw >> (sz[0] * 8);
+	}
+
+	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+	unm_nic_pci_change_crbwindow_128M(adapter, 0);
+
+	for (i = 0; i < loop; i++) {
+		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+		UNM_NIC_PCI_WRITE_32(0,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+		UNM_NIC_PCI_WRITE_32(word[i] & 0xffffffff,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
+		UNM_NIC_PCI_WRITE_32((word[i] >> 32) & 0xffffffff,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
+		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
+		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE |
+		    MIU_TA_CTL_WRITE,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			temp = UNM_NIC_PCI_READ_32((void *)
+			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
+			if ((temp & MIU_TA_CTL_BUSY) == 0) {
+				break;
+			}
+		}
+
+		if (j >= MAX_CTL_CHECK) {
+			cmn_err(CE_WARN, "%s: %s Fail to write thru agent\n",
+			    __FUNCTION__, unm_nic_driver_name);
+			ret = -1;
+			break;
+		}
+	}
+
+	unm_nic_pci_change_crbwindow_128M(adapter, 1);
+	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	return (ret);
+}
+
+int
+unm_nic_pci_mem_read_128M(struct unm_adapter_s *adapter, u64 off, void *data,
+    int size)
+{
+	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
+	__uint32_t		temp;
+	__uint64_t		off8, val, mem_crb, word[2] = {0, 0};
+#define	MAX_CTL_CHECK   1000
+
+	/*
+	 * If not MN, go check for MS or invalid.
+	 */
+	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
+		return (unm_nic_pci_mem_read_direct(adapter, off, data, size));
+
+	off8 = off & 0xfffffff8;
+	off0[0] = off & 0x7;
+	off0[1] = 0;
+	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
+	sz[1] = size - sz[0];
+	loop = ((off0[0] + size - 1) >> 3) + 1;
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
+
+	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+	unm_nic_pci_change_crbwindow_128M(adapter, 0);
+
+	for (i = 0; i < loop; i++) {
+		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+		UNM_NIC_PCI_WRITE_32(0,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
+		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
+		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			temp = UNM_NIC_PCI_READ_32((void *)
+			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
+			if ((temp & MIU_TA_CTL_BUSY) == 0) {
+				break;
+			}
+		}
+
+		if (j >= MAX_CTL_CHECK) {
+			cmn_err(CE_WARN, "%s: %s Fail to read through agent\n",
+			    __FUNCTION__, unm_nic_driver_name);
+			break;
+		}
+
+		start = off0[i] >> 2;
+		end   = (off0[i] + sz[i] - 1) >> 2;
+		word[i] = 0;
+		for (k = start; k <= end; k++) {
+			word[i] |= ((__uint64_t)UNM_NIC_PCI_READ_32(
+			    (void *) (uptr_t)(mem_crb +
+			    MIU_TEST_AGT_RDDATA(k))) << (32*k));
+		}
+	}
+
+	unm_nic_pci_change_crbwindow_128M(adapter, 1);
+	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+
+	if (j >= MAX_CTL_CHECK)
+		return (-1);
+
+	if (sz[0] == 8) {
+		val = word[0];
+	} else {
+		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
+		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
+	}
+
+	switch (size) {
+	case 1:
+		*(__uint8_t  *)data = val;
+		break;
+	case 2:
+		*(__uint16_t *)data = val;
+		break;
+	case 4:
+		*(__uint32_t *)data = val;
+		break;
+	case 8:
+		*(__uint64_t *)data = val;
+		break;
+	}
+	return (0);
+}
+
+
+
+int
+unm_nic_pci_mem_write_2M(struct unm_adapter_s *adapter, u64 off, void *data,
+    int size)
+{
+	int	i, j, ret = 0, loop, sz[2], off0;
+	__uint32_t	temp;
+	__uint64_t	off8, mem_crb, tmpw, word[2] = {0, 0};
+#define	MAX_CTL_CHECK   1000
+
+	/*
+	 * If not MN, go check for MS or invalid.
+	 */
+	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
+		mem_crb = UNM_CRB_QDR_NET;
+	} else {
+		mem_crb = UNM_CRB_DDR_NET;
+		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
+			return (unm_nic_pci_mem_write_direct(adapter,
+			    off, data, size));
+	}
+
+	off8 = off & 0xfffffff8;
+	off0 = off & 0x7;
+	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
+	sz[1] = size - sz[0];
+	loop = ((off0 + size - 1) >> 3) + 1;
+
+	if ((size != 8) || (off0 != 0)) {
+		for (i = 0; i < loop; i++) {
+			if (adapter->unm_nic_pci_mem_read(adapter,
+			    off8 + (i << 3), &word[i], 8))
+				return (-1);
+		}
+	}
+
+	switch (size) {
+		case 1:
+			tmpw = *((__uint8_t *)data);
+			break;
+		case 2:
+			tmpw = *((__uint16_t *)data);
+			break;
+		case 4:
+			tmpw = *((__uint32_t *)data);
+			break;
+		case 8:
+		default:
+			tmpw = *((__uint64_t *)data);
+			break;
+	}
+
+	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
+	word[0] |= tmpw << (off0 * 8);
+
+	if (loop == 2) {
+		word[1] &= ~(~0ULL << (sz[1] * 8));
+		word[1] |= tmpw >> (sz[0] * 8);
+	}
+
+// don't lock here - write_wx gets the lock if each time
+// UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+// unm_nic_pci_change_crbwindow_128M(adapter, 0);
+
+	for (i = 0; i < loop; i++) {
+		temp = off8 + (i << 3);
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
+		temp = 0;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
+		temp = word[i] & 0xffffffff;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
+		temp = (word[i] >> 32) & 0xffffffff;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
+		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			adapter->unm_nic_hw_read_wx(adapter,
+			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+			if ((temp & MIU_TA_CTL_BUSY) == 0) {
+				break;
+			}
+		}
+
+		if (j >= MAX_CTL_CHECK) {
+			cmn_err(CE_WARN, "%s: Fail to write through agent\n",
+			    unm_nic_driver_name);
+			ret = -1;
+			break;
+		}
+	}
+
+//  unm_nic_pci_change_crbwindow_128M(adapter, 1);
+//  UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	return (ret);
+}
+
+int
+unm_nic_pci_mem_read_2M(struct unm_adapter_s *adapter, u64 off, void *data,
+    int size)
+{
+// unsigned long   flags;
+	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
+	__uint32_t	temp;
+	__uint64_t	off8, val, mem_crb, word[2] = {0, 0};
+#define	MAX_CTL_CHECK   1000
+
+	/*
+	 * If not MN, go check for MS or invalid.
+	 */
+
+	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
+		mem_crb = UNM_CRB_QDR_NET;
+	} else {
+		mem_crb = UNM_CRB_DDR_NET;
+		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
+			return (unm_nic_pci_mem_read_direct(adapter,
+			    off, data, size));
+	}
+
+	off8 = off & 0xfffffff8;
+	off0[0] = off & 0x7;
+	off0[1] = 0;
+	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
+	sz[1] = size - sz[0];
+	loop = ((off0[0] + size - 1) >> 3) + 1;
+
+// don't get lock - write_wx will get it
+// UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+// unm_nic_pci_change_crbwindow_128M(adapter, 0);
+
+	for (i = 0; i < loop; i++) {
+		temp = off8 + (i << 3);
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
+		temp = 0;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
+		temp = MIU_TA_CTL_ENABLE;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			adapter->unm_nic_hw_read_wx(adapter,
+			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+			if ((temp & MIU_TA_CTL_BUSY) == 0) {
+				break;
+			}
+		}
+
+		if (j >= MAX_CTL_CHECK) {
+			cmn_err(CE_WARN, "%s: Fail to read through agent\n",
+			    unm_nic_driver_name);
+			break;
+		}
+
+		start = off0[i] >> 2;
+		end   = (off0[i] + sz[i] - 1) >> 2;
+		for (k = start; k <= end; k++) {
+			adapter->unm_nic_hw_read_wx(adapter,
+			    mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
+			word[i] |= ((__uint64_t)temp << (32 * k));
+		}
+	}
+
+// unm_nic_pci_change_crbwindow_128M(adapter, 1);
+// UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+
+	if (j >= MAX_CTL_CHECK)
+		return (-1);
+
+	if (sz[0] == 8) {
+		val = word[0];
+	} else {
+		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
+		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
+	}
+
+	switch (size) {
+		case 1:
+			*(__uint8_t  *)data = val;
+			break;
+		case 2:
+			*(__uint16_t *)data = val;
+			break;
+		case 4:
+			*(__uint32_t *)data = val;
+			break;
+		case 8:
+			*(__uint64_t *)data = val;
+			break;
+	}
+	return (0);
+}
+
+int
+unm_crb_writelit_adapter_2M(struct unm_adapter_s *adapter, unsigned long off,
+    int data)
+{
+	return (unm_nic_hw_write_wx_2M(adapter, off, &data, 4));
+}
+
+int
+unm_crb_writelit_adapter_128M(struct unm_adapter_s *adapter, unsigned long off,
+    int data)
+{
+	void *addr;
+
+	if (ADDR_IN_WINDOW1(off)) {
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	} else {
+		// unm_nic_write_w0 (adapter, off, data);
+		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
+		unm_nic_pci_change_crbwindow_128M(adapter, 0);
+		addr = (void *) (pci_base_offset(adapter, off));
+		UNM_NIC_PCI_WRITE_32(data, addr);
+		unm_nic_pci_change_crbwindow_128M(adapter, 1);
+		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
+	}
+
+	return (0);
+}
+
+int
+unm_nic_get_board_info(struct unm_adapter_s *adapter)
+{
+	int	rv = 0;
+	unm_board_info_t  *boardinfo;
+	int		i;
+	int		addr = BRDCFG_START;
+	uint32_t	  *ptr32;
+	uint32_t	gpioval;
+
+	boardinfo = &adapter->ahw.boardcfg;
+	ptr32 = (uint32_t *)boardinfo;
+
+	for (i = 0; i < sizeof (unm_board_info_t) / sizeof (uint32_t); i++) {
+		if (rom_fast_read(adapter, addr, (int *)ptr32) == -1) {
+			return (-1);
+		}
+		DPRINTF(1, (CE_WARN, "ROM(%d): %x\n", i, *ptr32));
+		ptr32++;
+		addr += sizeof (uint32_t);
+	}
+
+	if (boardinfo->magic != UNM_BDINFO_MAGIC) {
+		DPRINTF(1, (CE_WARN, "%s: ERROR reading board config."
+		    " Read %x, expected %x\n", unm_nic_driver_name,
+		    boardinfo->magic, UNM_BDINFO_MAGIC));
+		rv = -1;
+	}
+
+	if (boardinfo->header_version != UNM_BDINFO_VERSION) {
+		DPRINTF(1, (CE_WARN, "%s: Unknown board config version."
+		    " Read %x, expected %x\n", unm_nic_driver_name,
+		    boardinfo->header_version, UNM_BDINFO_VERSION));
+		rv = -1;
+	}
+
+	if (boardinfo->board_type == UNM_BRDTYPE_P3_4_GB_MM) {
+		gpioval = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_PAD_GPIO_I,
+		    adapter);
+		if ((gpioval & 0x8000) == 0)
+			boardinfo->board_type = UNM_BRDTYPE_P3_10G_TRP;
+	}
+
+	DPRINTF(0, (CE_WARN, "Discovered board type:0x%x  ",
+	    boardinfo->board_type));
+
+	switch ((unm_brdtype_t)boardinfo->board_type) {
+	case UNM_BRDTYPE_P2_SB35_4G:
+		adapter->ahw.board_type = UNM_NIC_GBE;
+		break;
+	case UNM_BRDTYPE_P2_SB31_10G:
+	case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
+	case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
+	case UNM_BRDTYPE_P2_SB31_10G_CX4:
+	case UNM_BRDTYPE_P3_HMEZ:
+	case UNM_BRDTYPE_P3_XG_LOM:
+	case UNM_BRDTYPE_P3_10G_CX4:
+	case UNM_BRDTYPE_P3_10G_CX4_LP:
+	case UNM_BRDTYPE_P3_IMEZ:
+	case UNM_BRDTYPE_P3_10G_SFP_PLUS:
+	case UNM_BRDTYPE_P3_10G_XFP:
+	case UNM_BRDTYPE_P3_10000_BASE_T:
+		adapter->ahw.board_type = UNM_NIC_XGBE;
+		break;
+	case UNM_BRDTYPE_P3_REF_QG:
+	case UNM_BRDTYPE_P3_4_GB:
+	case UNM_BRDTYPE_P3_4_GB_MM:
+		adapter->ahw.board_type = UNM_NIC_GBE;
+		break;
+	case UNM_BRDTYPE_P1_BD:
+	case UNM_BRDTYPE_P1_SB:
+	case UNM_BRDTYPE_P1_SMAX:
+	case UNM_BRDTYPE_P1_SOCK:
+		adapter->ahw.board_type = UNM_NIC_GBE;
+		break;
+	case UNM_BRDTYPE_P3_10G_TRP:
+		if (adapter->portnum < 2)
+			adapter->ahw.board_type = UNM_NIC_XGBE;
+		else
+			adapter->ahw.board_type = UNM_NIC_GBE;
+		break;
+	default:
+		DPRINTF(1, (CE_WARN, "%s: Unknown(%x)\n", unm_nic_driver_name,
+		    boardinfo->board_type));
+		break;
+	}
+
+	return (rv);
+}
+
+/* NIU access sections */
+
+int
+unm_nic_macaddr_set(struct unm_adapter_s *adapter, __uint8_t *addr)
+{
+	int		ret = 0, i, retry_count = 10;
+	unsigned char		mac_addr[MAX_ADDR_LEN];
+
+	/* For P3, we should not set MAC in HW any more */
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		return (0);
+
+	switch (adapter->ahw.board_type) {
+		case UNM_NIC_GBE:
+	/*
+	 * Flaky Mac address registers on qgig require several writes.
+	 */
+			for (i = 0; i < retry_count; ++i) {
+				if (unm_niu_macaddr_set(adapter, addr) != 0)
+					return (-1);
+
+				(void) unm_niu_macaddr_get(adapter,
+				    (unsigned char *)mac_addr);
+				if (memcmp(mac_addr, addr, 6) == 0)
+					return (0);
+			}
+			cmn_err(CE_WARN, "%s: Flaky MAC addr registers\n",
+			    unm_nic_driver_name);
+			break;
+
+		case UNM_NIC_XGBE:
+			ret = unm_niu_xg_macaddr_set(adapter, addr);
+			break;
+
+		default:
+			cmn_err(CE_WARN,  "\r\nUnknown board type encountered"
+			    " while setting the MAC address.\n");
+			return (-1);
+	}
+	return (ret);
+}
+
+#define	MTU_FUDGE_FACTOR 100
+int
+unm_nic_set_mtu(struct unm_adapter_s *adapter, int new_mtu)
+{
+	long		port = adapter->physical_port;
+	int			ret = 0;
+	u32			port_mode = 0;
+
+	if (adapter->ahw.revision_id >= NX_P3_A2)
+		return (nx_fw_cmd_set_mtu(adapter, new_mtu));
+
+	new_mtu += MTU_FUDGE_FACTOR; /* so that MAC accepts frames > MTU */
+	switch (adapter->ahw.board_type) {
+		case UNM_NIC_GBE:
+			unm_nic_write_w0(adapter,
+			    UNM_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
+			    new_mtu);
+
+			break;
+
+		case UNM_NIC_XGBE:
+			adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
+			    &port_mode, 4);
+			if (port_mode == UNM_PORT_MODE_802_3_AP) {
+				unm_nic_write_w0(adapter,
+				    UNM_NIU_AP_MAX_FRAME_SIZE(port), new_mtu);
+			} else {
+				if (adapter->physical_port == 0) {
+					unm_nic_write_w0(adapter,
+					    UNM_NIU_XGE_MAX_FRAME_SIZE,
+					    new_mtu);
+				} else {
+					unm_nic_write_w0(adapter,
+					    UNM_NIU_XG1_MAX_FRAME_SIZE,
+					    new_mtu);
+				}
+			}
+			break;
+
+		default:
+			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
+			    unm_nic_driver_name);
+	}
+
+	return (ret);
+}
+
+int
+unm_nic_set_promisc_mode(struct unm_adapter_s *adapter)
+{
+	int		ret;
+
+	if (adapter->promisc)
+		return (0);
+
+	switch (adapter->ahw.board_type) {
+		case UNM_NIC_GBE:
+			ret = unm_niu_set_promiscuous_mode(adapter,
+			    UNM_NIU_PROMISCOUS_MODE);
+			break;
+
+		case UNM_NIC_XGBE:
+			ret = unm_niu_xg_set_promiscuous_mode(adapter,
+			    UNM_NIU_PROMISCOUS_MODE);
+			break;
+
+		default:
+			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
+			    unm_nic_driver_name);
+			ret = -1;
+			break;
+	}
+
+if (!ret)
+	adapter->promisc = 1;
+
+		return (ret);
+}
+
+int
+unm_nic_unset_promisc_mode(struct unm_adapter_s *adapter)
+{
+	int	ret = 0;
+
+	/*
+	 * P3 does not unset promiscous mode. Why?
+	 */
+	if (adapter->ahw.revision_id >= NX_P3_A2) {
+		return (0);
+	}
+
+	if (!adapter->promisc)
+		return (0);
+
+	switch (adapter->ahw.board_type) {
+		case UNM_NIC_GBE:
+			ret = unm_niu_set_promiscuous_mode(adapter,
+			    UNM_NIU_NON_PROMISCOUS_MODE);
+			break;
+
+		case UNM_NIC_XGBE:
+			ret = unm_niu_xg_set_promiscuous_mode(adapter,
+			    UNM_NIU_NON_PROMISCOUS_MODE);
+			break;
+
+		default:
+			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
+			    unm_nic_driver_name);
+			ret = -1;
+			break;
+	}
+
+	if (!ret)
+		adapter->promisc = 0;
+
+	return (ret);
+}
+
+long
+unm_nic_phy_read(unm_adapter *adapter, long reg,
+		    __uint32_t *readval)
+{
+	long	ret = 0;
+
+	switch (adapter->ahw.board_type) {
+	case UNM_NIC_GBE:
+		ret = unm_niu_gbe_phy_read(adapter, reg, readval);
+		break;
+
+	case UNM_NIC_XGBE:
+		DPRINTF(1, (CE_WARN,
+		    "%s: Function %s is not implemented for XG\n",
+		    unm_nic_driver_name, __FUNCTION__));
+		break;
+
+	default:
+		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
+		    unm_nic_driver_name));
+	}
+
+	return (ret);
+}
+
+long
+unm_nic_init_port(struct unm_adapter_s *adapter)
+{
+	long	portnum = adapter->physical_port;
+	long	ret = 0;
+	long	reg = 0;
+	unm_niu_gbe_ifmode_t	mode_dont_care = 0;
+	u32			port_mode = 0;
+
+	unm_nic_set_link_parameters(adapter);
+
+	switch (adapter->ahw.board_type) {
+	case UNM_NIC_GBE:
+		ret = unm_niu_enable_gbe_port(adapter, mode_dont_care);
+		break;
+
+	case UNM_NIC_XGBE:
+		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
+		    &port_mode, 4);
+		if (port_mode == UNM_PORT_MODE_802_3_AP) {
+			ret = unm_niu_enable_gbe_port(adapter, mode_dont_care);
+		} else {
+			adapter->unm_crb_writelit_adapter(adapter,
+			    UNM_NIU_XGE_CONFIG_0 + (0x10000 * portnum), 0x5);
+			UNM_CRB_READ_CHECK_ADAPTER(UNM_NIU_XGE_CONFIG_1 +
+			    (0x10000 * portnum), &reg, adapter);
+			if (adapter->ahw.revision_id < NX_P3_A2)
+				reg = (reg & ~0x2000UL);
+			adapter->unm_crb_writelit_adapter(adapter,
+			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * portnum), reg);
+		}
+		break;
+
+	default:
+		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
+		    unm_nic_driver_name));
+	}
+
+	return (ret);
+}
+
+void
+unm_nic_stop_port(struct unm_adapter_s *adapter)
+{
+
+	mac_unregister(adapter->mach);
+
+	switch (adapter->ahw.board_type) {
+	case UNM_NIC_GBE:
+		(void) unm_niu_disable_gbe_port(adapter);
+		break;
+
+	case UNM_NIC_XGBE:
+		(void) unm_niu_disable_xg_port(adapter);
+		break;
+
+	default:
+		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
+		    unm_nic_driver_name));
+	}
+}
+
+void
+unm_crb_write_adapter(unsigned long off, void *data,
+    struct unm_adapter_s *adapter)
+{
+	(void) adapter->unm_nic_hw_write_wx(adapter, off, data, 4);
+}
+
+int
+unm_crb_read_adapter(unsigned long off, void *data,
+    struct unm_adapter_s *adapter)
+{
+	return (adapter->unm_nic_hw_read_wx(adapter, off, data, 4));
+}
+
+int
+unm_crb_read_val_adapter(unsigned long off, struct unm_adapter_s *adapter)
+{
+	int data;
+
+	adapter->unm_nic_hw_read_wx(adapter, off, &data, 4);
+	return (data);
+}
+
+void
+unm_nic_set_link_parameters(struct unm_adapter_s *adapter)
+{
+	unm_niu_phy_status_t status;
+	uint16_t defval = (uint16_t)-1;
+	unm_niu_control_t mode;
+	u32 port_mode = 0;
+
+	unm_nic_read_w0(adapter, UNM_NIU_MODE, (uint32_t *)&mode);
+	if (mode.enable_ge) { // Gb 10/100/1000 Mbps mode
+		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
+		    &port_mode, 4);
+		if (port_mode == UNM_PORT_MODE_802_3_AP) {
+			adapter->link_speed = MBPS_1000;
+			adapter->link_duplex = LINK_DUPLEX_FULL;
+		} else {
+		if (unm_nic_phy_read(adapter,
+		    UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+		    (unm_crbword_t *)&status) == 0) {
+			if (status.link) {
+				switch (status.speed) {
+				case 0: adapter->link_speed = MBPS_10;
+					break;
+				case 1: adapter->link_speed = MBPS_100;
+					break;
+				case 2: adapter->link_speed = MBPS_1000;
+					break;
+				default:
+					adapter->link_speed = defval;
+					break;
+				}
+				switch (status.duplex) {
+				case 0: adapter->link_duplex = LINK_DUPLEX_HALF;
+					break;
+				case 1: adapter->link_duplex = LINK_DUPLEX_FULL;
+					break;
+				default:
+					adapter->link_duplex = defval;
+					break;
+				}
+			} else {
+				adapter->link_speed = defval;
+				adapter->link_duplex = defval;
+			}
+		} else {
+			adapter->link_speed = defval;
+			adapter->link_duplex = defval;
+		}
+		}
+	}
+}
+
+void
+unm_nic_flash_print(struct unm_adapter_s *adapter)
+{
+	int valid = 1;
+	unm_board_info_t *board_info = &(adapter->ahw.boardcfg);
+
+	if (board_info->magic != UNM_BDINFO_MAGIC) {
+		cmn_err(CE_WARN, "%s UNM Unknown board config, Read 0x%x "
+		    "expected as 0x%x\n", unm_nic_driver_name,
+		    board_info->magic, UNM_BDINFO_MAGIC);
+		valid = 0;
+	}
+	if (board_info->header_version != UNM_BDINFO_VERSION) {
+		cmn_err(CE_WARN, "%s UNM Unknown board config version."
+		    " Read %x, expected %x\n", unm_nic_driver_name,
+		    board_info->header_version, UNM_BDINFO_VERSION);
+		valid = 0;
+	}
+	if (valid) {
+		unm_user_info_t  user_info;
+		int	i;
+		int	addr = USER_START;
+		int	*ptr32;
+
+		ptr32 = (int *)&user_info;
+		for (i = 0; i < sizeof (unm_user_info_t) / sizeof (uint32_t);
+		    i++) {
+			if (rom_fast_read(adapter, addr, ptr32) == -1) {
+				cmn_err(CE_WARN,
+				    "%s: ERROR reading %s board userarea.\n",
+				    unm_nic_driver_name, unm_nic_driver_name);
+				return;
+			}
+			ptr32++;
+			addr += sizeof (uint32_t);
+		}
+		if (verbmsg != 0) {
+			char	*brd_name;
+			GET_BRD_NAME_BY_TYPE(board_info->board_type, brd_name);
+			cmn_err(CE_NOTE, "%s %s Board S/N %s  Chip id 0x%x\n",
+			    unm_nic_driver_name, brd_name, user_info.serial_num,
+			    board_info->chip_id);
+		}
+	}
+}
+
+static int
+nx_nic_send_cmd_descs(unm_adapter *adapter, cmdDescType0_t *cmd_desc_arr,
+    int nr_elements)
+{
+	struct unm_cmd_buffer	*pbuf;
+	unsigned int		i = 0, producer;
+
+	/*
+	 * We need to check if space is available.
+	 */
+	UNM_SPIN_LOCK(&adapter->tx_lock);
+	producer = adapter->cmdProducer;
+
+	do {
+		pbuf = &adapter->cmd_buf_arr[producer];
+		pbuf->head = pbuf->tail = NULL;
+		pbuf->msg = NULL;
+		(void) memcpy(&adapter->ahw.cmdDescHead[producer],
+		    &cmd_desc_arr[i], sizeof (cmdDescType0_t));
+		unm_desc_dma_sync(adapter->ahw.cmd_desc_dma_handle, producer,
+		    1, adapter->MaxTxDescCount, sizeof (cmdDescType0_t),
+		    DDI_DMA_SYNC_FORDEV);
+		producer = get_next_index(producer, adapter->MaxTxDescCount);
+		i++;
+	} while (i != nr_elements);
+
+	adapter->cmdProducer = adapter->ahw.cmdProducer = producer;
+	adapter->freecmds -= i;
+
+	unm_nic_update_cmd_producer(adapter, producer);
+
+	UNM_SPIN_UNLOCK(&adapter->tx_lock);
+	return (0);
+}
+
+typedef struct {
+	u64	qhdr, req_hdr, words[6];
+} nx_nic_req_t;
+
+typedef struct {
+	u8	op, tag, mac_addr[6];
+} nx_mac_req_t;
+
+static void
+nx_p3_sre_macaddr_change(unm_adapter *adapter, u8 *addr, u8 op)
+{
+	nx_nic_req_t	req;
+	nx_mac_req_t	mac_req;
+	int		rv;
+
+	(void) memset(&req, 0, sizeof (nx_nic_req_t));
+	req.qhdr |= (NX_NIC_REQUEST << 23);
+	req.req_hdr |= NX_MAC_EVENT;
+	req.req_hdr |= ((u64)adapter->portnum << 16);
+	mac_req.op = op;
+	(void) memcpy(&mac_req.mac_addr, addr, 6);
+	req.words[0] = HOST_TO_LE_64(*(u64 *)(uintptr_t)&mac_req);
+
+	rv = nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1);
+	if (rv != 0)
+		cmn_err(CE_WARN, "%s%d: Could not send mac update\n",
+		    adapter->name, adapter->instance);
+}
+
+static int
+nx_p3_nic_set_promisc(unm_adapter *adapter, u32 mode)
+{
+	nx_nic_req_t	req;
+
+	(void) memset(&req, 0, sizeof (nx_nic_req_t));
+
+	req.qhdr |= (NX_HOST_REQUEST << 23);
+	req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
+	req.req_hdr |= ((u64)adapter->portnum << 16);
+	req.words[0] = HOST_TO_LE_64(mode);
+
+	return (nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1));
+}
+
+/*
+ * Currently only invoked at interface initialization time
+ */
+void
+nx_p3_nic_set_multi(unm_adapter *adapter)
+{
+	u8	bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	if (nx_p3_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL))
+		cmn_err(CE_WARN, "Could not set promisc mode\n");
+
+	nx_p3_sre_macaddr_change(adapter, adapter->mac_addr, NETXEN_MAC_ADD);
+	nx_p3_sre_macaddr_change(adapter, bcast_addr, NETXEN_MAC_ADD);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic_hw.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,107 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _UNM_NIC_HW_
+#define	_UNM_NIC_HW_
+
+#include "unm_inc.h"
+
+/* Hardware memory size of 128 meg */
+#define	BAR0_SIZE (128 * 1024 * 1024)
+/*
+ * It can be calculated by looking at the first 1 bit of the BAR0 addr after
+ * bit 4 For us lets assume that BAR0 is D8000008, then the size is 0x8000000,
+ * 8 represents first bit containing 1.   FSL temp notes....pg 162 of PCI
+ * systems arch...
+ */
+
+#define	UNM_NIC_HW_BLOCK_WRITE_64(DATA_PTR, ADDR, NUM_WORDS)        \
+{                                                           \
+	int i;                                              \
+	u64 *a = (u64 *) (DATA_PTR);                        \
+	u64 *b = (u64 *) (ADDR);                            \
+	u64 tmp;					    \
+	for (i = 0; i < (NUM_WORDS); i++, a++, b++) {       \
+		tmp = UNM_NIC_PCI_READ_64(a);		    \
+		UNM_NIC_PCI_WRITE_64(tmp, b);		    \
+	}						    \
+}
+
+#define	UNM_NIC_HW_BLOCK_READ_64(DATA_PTR, ADDR, NUM_WORDS)           \
+{                                                             \
+	int i;                                                \
+	u64 *a = (u64 *) (DATA_PTR);                          \
+	u64 *b = (u64 *) (ADDR);                              \
+	u64 tmp;					      \
+	for (i = 0; i < (NUM_WORDS); i++, a++, b++) {            \
+		tmp = UNM_NIC_PCI_READ_64(b);		      \
+		UNM_NIC_PCI_WRITE_64(tmp, a);		      \
+	}                                                     \
+}
+
+#define	UNM_PCI_MAPSIZE_BYTES  (UNM_PCI_MAPSIZE << 20)
+
+#define	UNM_NIC_LOCKED_READ_REG(X, Y)   \
+	addr = (void *)(pci_base_offset(adapter, (X)));     \
+	*(uint32_t *)(Y) = UNM_NIC_PCI_READ_32(addr);
+
+#define	UNM_NIC_LOCKED_WRITE_REG(X, Y)   \
+	addr = (void *)(pci_base_offset(adapter, (X))); \
+	UNM_NIC_PCI_WRITE_32(*(uint32_t *)(Y), addr);
+
+/* For Multicard support */
+#define	UNM_CRB_READ_VAL_ADAPTER(ADDR, ADAPTER) \
+	unm_crb_read_val_adapter((ADDR), (struct unm_adapter_s *)ADAPTER)
+
+#define	UNM_CRB_READ_CHECK_ADAPTER(ADDR, VALUE, ADAPTER)		\
+	{								\
+		if (unm_crb_read_adapter(ADDR, VALUE,			\
+		    (struct unm_adapter_s *)ADAPTER)) return -1;	\
+	}
+
+#define	UNM_CRB_WRITELIT_ADAPTER(ADDR, VALUE, ADAPTER)			\
+	{								\
+		adapter->unm_crb_writelit_adapter(			\
+		    (struct unm_adapter_s *)ADAPTER,			\
+		    (unsigned long)ADDR, (int)VALUE);			\
+	}
+
+struct unm_adapter_s;
+void unm_nic_set_link_parameters(struct unm_adapter_s *adapter);
+long xge_mdio_init(struct unm_adapter_s *adapter);
+void unm_nic_flash_print(struct unm_adapter_s *adapter);
+void unm_nic_get_serial_num(struct unm_adapter_s *adapter);
+
+typedef struct {
+	unsigned valid;
+	unsigned start_128M;
+	unsigned end_128M;
+	unsigned start_2M;
+} crb_128M_2M_sub_block_map_t;
+
+typedef struct {
+	crb_128M_2M_sub_block_map_t sub_block[16];
+} crb_128M_2M_block_map_t;
+
+#endif /* _UNM_NIC_HW_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic_init.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,512 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/debug.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#include <sys/strlog.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/vtrace.h>
+#include <sys/dlpi.h>
+#include <sys/strsun.h>
+#include <sys/ethernet.h>
+#include <sys/modctl.h>
+#include <sys/errno.h>
+#include <sys/dditypes.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+#include <sys/pci.h>
+
+#include "unm_nic.h"
+#include "unm_nic_hw.h"
+#include "nic_cmn.h"
+#include "unm_nic_ioctl.h"
+#include "nic_phan_reg.h"
+
+struct crb_addr_pair {
+	long	addr, data;
+};
+
+#define	MAX_CRB_XFORM	60
+#define	ADDR_ERROR	((unsigned long)0xffffffff)
+
+#define	crb_addr_transform(name)				\
+		crb_addr_xform[UNM_HW_PX_MAP_CRB_##name] =		\
+		UNM_HW_CRB_HUB_AGT_ADR_##name << 20
+
+static unsigned int crb_addr_xform[MAX_CRB_XFORM];
+
+static void
+crb_addr_transform_setup(void)
+{
+		crb_addr_transform(XDMA);
+		crb_addr_transform(TIMR);
+		crb_addr_transform(SRE);
+		crb_addr_transform(SQN3);
+		crb_addr_transform(SQN2);
+		crb_addr_transform(SQN1);
+		crb_addr_transform(SQN0);
+		crb_addr_transform(SQS3);
+		crb_addr_transform(SQS2);
+		crb_addr_transform(SQS1);
+		crb_addr_transform(SQS0);
+		crb_addr_transform(RPMX7);
+		crb_addr_transform(RPMX6);
+		crb_addr_transform(RPMX5);
+		crb_addr_transform(RPMX4);
+		crb_addr_transform(RPMX3);
+		crb_addr_transform(RPMX2);
+		crb_addr_transform(RPMX1);
+		crb_addr_transform(RPMX0);
+		crb_addr_transform(ROMUSB);
+		crb_addr_transform(SN);
+		crb_addr_transform(QMN);
+		crb_addr_transform(QMS);
+		crb_addr_transform(PGNI);
+		crb_addr_transform(PGND);
+		crb_addr_transform(PGN3);
+		crb_addr_transform(PGN2);
+		crb_addr_transform(PGN1);
+		crb_addr_transform(PGN0);
+		crb_addr_transform(PGSI);
+		crb_addr_transform(PGSD);
+		crb_addr_transform(PGS3);
+		crb_addr_transform(PGS2);
+		crb_addr_transform(PGS1);
+		crb_addr_transform(PGS0);
+		crb_addr_transform(PS);
+		crb_addr_transform(PH);
+		crb_addr_transform(NIU);
+		crb_addr_transform(I2Q);
+		crb_addr_transform(EG);
+		crb_addr_transform(MN);
+		crb_addr_transform(MS);
+		crb_addr_transform(CAS2);
+		crb_addr_transform(CAS1);
+		crb_addr_transform(CAS0);
+		crb_addr_transform(CAM);
+		crb_addr_transform(C2C1);
+		crb_addr_transform(C2C0);
+		crb_addr_transform(SMB);
+		crb_addr_transform(OCM0);
+
+	/*
+	 * Used only in P3 just define it for P2 also.
+	 */
+	crb_addr_transform(I2C0);
+}
+
+/*
+ * decode_crb_addr(0 - utility to translate from internal Phantom CRB address
+ * to external PCI CRB address.
+ */
+static unsigned long
+decode_crb_addr(unsigned long addr)
+{
+	int i;
+	unsigned long base_addr, offset, pci_base;
+
+	crb_addr_transform_setup();
+
+	pci_base = ADDR_ERROR;
+	base_addr = addr & 0xfff00000;
+	offset = addr & 0x000fffff;
+
+	for (i = 0; i < MAX_CRB_XFORM; i++) {
+		if (crb_addr_xform[i] == base_addr) {
+			pci_base = i << 20;
+			break;
+		}
+	}
+
+	if (pci_base == ADDR_ERROR) {
+		return (pci_base);
+	} else {
+		return (pci_base + offset);
+	}
+}
+
+static long rom_max_timeout = 100;
+static long rom_lock_timeout = 10000;
+
+static int
+rom_lock(unm_adapter *adapter)
+{
+	uint32_t done = 0;
+	long timeout = 0;
+
+	while (!done) {
+		/* acquire semaphore2 from PCI HW block */
+		unm_nic_read_w0(adapter, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
+		if (done == 1)
+			break;
+		if (timeout >= rom_lock_timeout) {
+			cmn_err(CE_WARN, "%s%d rom_lock timed out %d %ld\n",
+			    adapter->name, adapter->instance, done, timeout);
+			return (-1);
+		}
+		timeout++;
+	}
+	unm_nic_reg_write(adapter, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
+	return (0);
+}
+
+static void
+rom_unlock(unm_adapter *adapter)
+{
+	uint32_t val;
+
+	/* release semaphore2 */
+	unm_nic_read_w0(adapter, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
+}
+
+static int
+wait_rom_done(unm_adapter *adapter)
+{
+	long timeout = 0;
+	long done = 0;
+
+	while (done == 0) {
+		unm_nic_reg_read(adapter, UNM_ROMUSB_GLB_STATUS, &done);
+		done &= 2;
+		timeout++;
+		if (timeout >= rom_max_timeout) {
+			cmn_err(CE_WARN,
+			    "Timeout reached waiting for rom done");
+			return (-1);
+		}
+	}
+	return (0);
+}
+
+static int
+do_rom_fast_read(unm_adapter *adapter, int addr, int *valp)
+{
+	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ADDRESS, addr);
+	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
+	drv_usecwait(100);   /* prevent bursting on CRB */
+	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+	if (wait_rom_done(adapter) != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "Error waiting for rom done\n");
+		return (-1);
+	}
+
+	// reset abyte_cnt and dummy_byte_cnt
+	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
+	drv_usecwait(100);   /* prevent bursting on CRB */
+	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+
+	unm_nic_reg_read(adapter, UNM_ROMUSB_ROM_RDATA, valp);
+	return (0);
+}
+
+int
+rom_fast_read(struct unm_adapter_s *adapter, int addr, int *valp)
+{
+	int ret;
+
+	if (rom_lock(adapter) != 0) {
+		cmn_err(CE_WARN, "%s(%d)rom_lock failed\n",
+		    __FUNCTION__, __LINE__);
+		return (-1);
+	}
+
+	ret = do_rom_fast_read(adapter, addr, valp);
+	if (ret != 0) {
+		cmn_err(CE_WARN, "%s do_rom_fast_read returned: %d\n",
+		    __FUNCTION__, __LINE__);
+		return (-1);
+	}
+	rom_unlock(adapter);
+	return (ret);
+}
+
+int
+pinit_from_rom(struct unm_adapter_s *adapter, int verbose)
+{
+	int	addr, val, status, i, init_delay = 0, n;
+	struct crb_addr_pair	*buf;
+	unsigned long	off;
+	unsigned int	offset;
+
+	status = unm_nic_get_board_info(adapter);
+	if (status)
+		cmn_err(CE_WARN, "%s: pinit_from_rom: Error getting brdinfo\n",
+		    unm_nic_driver_name);
+
+	UNM_CRB_WRITELIT_ADAPTER(UNM_ROMUSB_GLB_SW_RESET, 0xffffffff, adapter);
+
+	if (verbose) {
+		int	val;
+		if (rom_fast_read(adapter, 0x4008, &val) == 0)
+			cmn_err(CE_WARN, "P2 ROM board type: 0x%08x\n", val);
+		else
+			cmn_err(CE_WARN, "Could not read board type\n");
+		if (rom_fast_read(adapter, 0x400c, &val) == 0)
+			cmn_err(CE_WARN, "ROM board  num: 0x%08x\n", val);
+		else
+			cmn_err(CE_WARN, "Could not read board number\n");
+		if (rom_fast_read(adapter, 0x4010, &val) == 0)
+			cmn_err(CE_WARN, "ROM chip   num: 0x%08x\n", val);
+		else
+			cmn_err(CE_WARN, "Could not read chip number\n");
+	}
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		if (rom_fast_read(adapter, 0, &n) != 0 ||
+		    (unsigned int)n != 0xcafecafe ||
+		    rom_fast_read(adapter, 4, &n) != 0) {
+			cmn_err(CE_WARN, "%s: ERROR Reading crb_init area: "
+			    "n: %08x\n", unm_nic_driver_name, n);
+			return (-1);
+		}
+
+		offset = n & 0xffffU;
+		n = (n >> 16) & 0xffffU;
+	} else {
+		if (rom_fast_read(adapter, 0, &n) != 0 ||
+		    !(n & 0x80000000)) {
+			cmn_err(CE_WARN, "%s: ERROR Reading crb_init area: "
+			    "n: %08x\n", unm_nic_driver_name, n);
+			return (-1);
+		}
+		offset = 1;
+		n &= ~0x80000000;
+	}
+
+	if (n  >= 1024) {
+		cmn_err(CE_WARN, "%s: %s:n=0x%x Card flash not initialized\n",
+		    unm_nic_driver_name, __FUNCTION__, n);
+		return (-1);
+	}
+
+	if (verbose)
+		cmn_err(CE_WARN, "%s: %d CRB init values found in ROM.\n",
+		    unm_nic_driver_name, n);
+
+	buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
+	if (buf == NULL) {
+		cmn_err(CE_WARN, "%s: pinit_from_rom: Unable to get memory\n",
+		    unm_nic_driver_name);
+		return (-1);
+	}
+
+	for (i = 0; i < n; i++) {
+		if (rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
+		    rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
+			kmem_free(buf, n * sizeof (struct crb_addr_pair));
+			return (-1);
+		}
+
+		buf[i].addr = addr;
+		buf[i].data = val;
+
+		if (verbose)
+			cmn_err(CE_WARN, "%s: PCI:     0x%08x == 0x%08x\n",
+			    unm_nic_driver_name,
+			    (unsigned int)decode_crb_addr(
+			    (unsigned long)addr), val);
+	}
+
+	for (i = 0; i < n; i++) {
+		off = decode_crb_addr((unsigned long)buf[i].addr) +
+		    UNM_PCI_CRBSPACE;
+		/* skipping cold reboot MAGIC */
+		if (off == UNM_CAM_RAM(0x1fc)) {
+			continue;
+		}
+
+		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+			/* do not reset PCI */
+			if (off == (ROMUSB_GLB + 0xbc)) {
+				continue;
+			}
+			if (off == (ROMUSB_GLB + 0xc8))	/* core clock */
+				continue;
+			if (off == (ROMUSB_GLB + 0x24))	/* MN clock */
+				continue;
+			if (off == (ROMUSB_GLB + 0x1c))	/* MS clock */
+				continue;
+			if (off == (UNM_CRB_PEG_NET_1 + 0x18)) {
+				buf[i].data = 0x1020;
+			}
+			/* skip the function enable register */
+			if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
+				continue;
+			}
+			if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
+				continue;
+			}
+
+			if ((off & 0x0ff00000) == UNM_CRB_SMB) {
+				continue;
+			}
+
+		}
+
+		if (off == ADDR_ERROR) {
+			cmn_err(CE_WARN, "%s: Err: Unknown addr: 0x%08lx\n",
+			    unm_nic_driver_name, buf[i].addr);
+			continue;
+		}
+
+		/* After writing this register, HW needs time for CRB */
+		/* to quiet down (else crb_window returns 0xffffffff) */
+		if (off == UNM_ROMUSB_GLB_SW_RESET) {
+			init_delay = 1;
+
+			if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+				/* hold xdma in reset also */
+				buf[i].data = 0x8000ff;
+			}
+		}
+
+		adapter->unm_nic_hw_write_wx(adapter, off, &buf[i].data, 4);
+
+		if (init_delay == 1) {
+			nx_msleep(1000);	/* Sleep 1000 msecs */
+			init_delay = 0;
+		}
+
+		nx_msleep(1);			/* Sleep 1 msec */
+	}
+
+	kmem_free(buf, n * sizeof (struct crb_addr_pair));
+
+	// disable_peg_cache_all
+	// unreset_net_cache
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		val = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_SW_RESET,
+		    adapter);
+		UNM_CRB_WRITELIT_ADAPTER(UNM_ROMUSB_GLB_SW_RESET,
+		    (val & 0xffffff0f), adapter);
+	}
+
+	// p2dn replyCount
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_D+0xec, 0x1e, adapter);
+	// disable_peg_cache 0
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_D+0x4c, 8, adapter);
+	// disable_peg_cache 1
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_I+0x4c, 8, adapter);
+
+	// peg_clr_all
+	// peg_clr 0
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_0+0x8, 0, adapter);
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_0+0xc, 0, adapter);
+	// peg_clr 1
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_1+0x8, 0, adapter);
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_1+0xc, 0, adapter);
+	// peg_clr 2
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_2+0x8, 0, adapter);
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_2+0xc, 0, adapter);
+	// peg_clr 3
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_3+0x8, 0, adapter);
+	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_3+0xc, 0, adapter);
+
+	return (0);
+}
+
+int
+phantom_init(struct unm_adapter_s *adapter, int pegtune_val)
+{
+	u32	val = 0;
+	int	retries = 120;
+
+	if (!pegtune_val) {
+		do {
+			val = adapter->unm_nic_pci_read_normalize(adapter,
+			    CRB_CMDPEG_STATE);
+
+			if ((val == PHAN_INITIALIZE_COMPLETE) ||
+			    (val == PHAN_INITIALIZE_ACK))
+				return (DDI_SUCCESS);
+
+			/* 500 msec wait */
+			drv_usecwait(500000);
+		} while (--retries > 0);
+
+		if (!retries) {
+			val = adapter->unm_nic_pci_read_normalize(adapter,
+			    UNM_ROMUSB_GLB_PEGTUNE_DONE);
+			cmn_err(CE_WARN, "WARNING: Initial boot wait loop"
+			    "failed...state:%d\n", val);
+			return (DDI_FAILURE);
+		}
+	}
+
+	return (DDI_SUCCESS);
+}
+
+int
+load_from_flash(struct unm_adapter_s *adapter)
+{
+	int  i;
+	long data, size = 0;
+	long flashaddr = BOOTLD_START, memaddr = BOOTLD_START;
+
+	size = (IMAGE_START - BOOTLD_START)/4;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		data = 1;
+		adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_CAS_RST,
+		    &data, 4);
+	}
+
+	for (i = 0; i < size; i++) {
+		if (rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
+			cmn_err(CE_WARN, "Error in rom_fast_read: "
+			    "Will skip loading flash image\n");
+			return (DDI_FAILURE);
+		}
+
+		adapter->unm_nic_pci_mem_write(adapter, memaddr, &data, 4);
+		flashaddr += 4;
+		memaddr += 4;
+	}
+
+	drv_usecwait(100);
+	UNM_READ_LOCK(&adapter->adapter_lock);
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		data = 0x80001d;
+		adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_SW_RESET,
+		    &data, 4);
+	} else {
+		data = 0x3fff;
+		adapter->unm_nic_hw_write_wx(adapter,
+		    UNM_ROMUSB_GLB_CHIP_CLK_CTRL, &data, 4);
+		data = 0;
+		adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_CAS_RST,
+		    &data, 4);
+	}
+
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+	return (DDI_SUCCESS);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic_ioctl.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,79 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef __UNM_NIC_IOCTL_H__
+#define	__UNM_NIC_IOCTL_H__
+
+/* ioctl's dealing with PCI read/writes */
+#define	UNM_CMD_START 0
+#define	UNM_NIC_CMD  (UNM_CMD_START + 1)
+#define	UNM_NIC_NAME (UNM_CMD_START + 2)
+
+typedef enum {
+		unm_nic_cmd_none = 0,
+		unm_nic_cmd_pci_read,
+		unm_nic_cmd_pci_write,
+		unm_nic_cmd_pci_mem_read,
+		unm_nic_cmd_pci_mem_write,
+		unm_nic_cmd_pci_config_read,
+		unm_nic_cmd_pci_config_write,
+		unm_nic_cmd_get_stats,
+		unm_nic_cmd_clear_stats,
+		unm_nic_cmd_get_version,
+		unm_nic_cmd_get_phy_type,
+		unm_nic_cmd_efuse_chip_id,
+
+		unm_nic_cmd_flash_read = 50,
+		unm_nic_cmd_flash_write,
+		unm_nic_cmd_flash_se
+} unm_nic_ioctl_cmd_t;
+
+#pragma pack(1)
+
+typedef struct {
+		__uint32_t cmd;
+		__uint32_t unused1;
+		__uint64_t off;
+		__uint32_t size;
+		__uint32_t rv;
+		char uabc[64];
+		void *ptr;
+} unm_nic_ioctl_data_t;
+
+struct unm_statistics {
+	__uint64_t rx_packets;
+	__uint64_t tx_packets;
+	__uint64_t rx_bytes;
+	__uint64_t rx_errors;
+	__uint64_t tx_bytes;
+	__uint64_t tx_errors;
+	__uint64_t rx_CRC_errors;
+	__uint64_t rx_short_length_error;
+	__uint64_t rx_long_length_error;
+	__uint64_t rx_MAC_errors;
+};
+
+#pragma pack()
+
+#endif /* !__UNM_NIC_IOCTL_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic_isr.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,127 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/debug.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#include <sys/strlog.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/vtrace.h>
+#include <sys/dlpi.h>
+#include <sys/strsun.h>
+#include <sys/ethernet.h>
+#include <sys/modctl.h>
+#include <sys/errno.h>
+#include <sys/dditypes.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+
+#include <sys/pci.h>
+
+#include "unm_nic.h"
+#include "unm_nic_hw.h"
+#include "nic_cmn.h"
+#include "nic_phan_reg.h"
+
+static void
+unm_nic_isr_other(struct unm_adapter_s *adapter)
+{
+	u32 portno = adapter->portnum;
+	u32 val, linkup, qg_linksup = adapter->ahw.linkup;
+
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	adapter->unm_nic_hw_read_wx(adapter, CRB_XG_STATE, &val, 4);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	linkup = 1 & (val >> adapter->physical_port);
+	adapter->ahw.linkup = linkup;
+
+	if (linkup != qg_linksup) {
+		cmn_err(CE_WARN, "%s: PORT %d link %s\n", unm_nic_driver_name,
+		    portno, ((linkup == 0) ? "down" : "up"));
+		mac_link_update(adapter->mach, linkup);
+		if (linkup)
+			unm_nic_set_link_parameters(adapter);
+	}
+}
+
+void
+unm_nic_handle_phy_intr(struct unm_adapter_s *adapter)
+{
+	uint32_t	val, val1, linkupval;
+
+	switch (adapter->ahw.board_type) {
+		case UNM_NIC_GBE:
+			if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+				unm_nic_isr_other(adapter);
+				break;
+			}
+		/* FALLTHROUGH */
+
+		case UNM_NIC_XGBE:
+			/* WINDOW = 1 */
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+			adapter->unm_nic_hw_read_wx(adapter, CRB_XG_STATE_P3,
+			    &val, 4);
+			val1 = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+			linkupval = XG_LINK_UP_P3;
+		} else {
+			adapter->unm_nic_hw_read_wx(adapter, CRB_XG_STATE,
+			    &val, 4);
+			val >>= (adapter->portnum * 8);
+			val1 = val & 0xff;
+			linkupval = XG_LINK_UP;
+		}
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+		if (adapter->ahw.linkup && (val1 != linkupval)) {
+			if (verbmsg != 0)
+				cmn_err(CE_NOTE, "%s%d: NIC Link is down\n",
+				    adapter->name, adapter->portnum);
+			mac_link_update(adapter->mach, LINK_STATE_DOWN);
+			adapter->ahw.linkup = 0;
+		} else if ((adapter->ahw.linkup == 0) && (val1 == linkupval)) {
+			if (verbmsg != 0)
+				cmn_err(CE_NOTE, "%s%d: NIC Link is up\n",
+				    adapter->name, adapter->portnum);
+			mac_link_update(adapter->mach, LINK_STATE_UP);
+			adapter->ahw.linkup = 1;
+
+			if (adapter->ahw.board_type == UNM_NIC_GBE)
+				unm_nic_set_link_parameters(adapter);
+		}
+
+		break;
+
+		default:
+		DPRINTF(0, (CE_WARN, "%s%d ISR: Unknown board type\n",
+		    unm_nic_driver_name, adapter->portnum));
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_nic_main.c	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,2599 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/debug.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#include <sys/strlog.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/vtrace.h>
+#include <sys/dlpi.h>
+#include <sys/strsun.h>
+#include <sys/ethernet.h>
+#include <sys/modctl.h>
+#include <sys/errno.h>
+#include <sys/dditypes.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+#include <sys/pci.h>
+
+#include <sys/gld.h>
+#include <netinet/in.h>
+#include <inet/ip.h>
+#include <inet/tcp.h>
+
+#include <sys/rwlock.h>
+#include <sys/mutex.h>
+#include <sys/pattr.h>
+#include <sys/strsubr.h>
+#include <sys/ddi_impldefs.h>
+#include<sys/task.h>
+
+#include "unm_nic_hw.h"
+#include "unm_nic.h"
+
+#include "nic_phan_reg.h"
+#include "unm_nic_ioctl.h"
+#include "nic_cmn.h"
+#include "unm_version.h"
+#include "unm_brdcfg.h"
+
+#if defined(lint)
+#undef MBLKL
+#define	MBLKL(_mp_)	((uintptr_t)(_mp_)->b_wptr - (uintptr_t)(_mp_)->b_rptr)
+#endif /* lint */
+
+#undef UNM_LOOPBACK
+#undef SINGLE_DMA_BUF
+
+#define	UNM_ADAPTER_UP_MAGIC	777
+#define	VLAN_TAGSZ		0x4
+
+#define	index2rxbuf(_rdp_, _idx_)	((_rdp_)->rx_buf_pool + (_idx_))
+#define	rxbuf2index(_rdp_, _bufp_)	((_bufp_) - (_rdp_)->rx_buf_pool)
+
+/*
+ * Receive ISR processes NX_RX_MAXBUFS incoming packets at most, then posts
+ * as many buffers as packets processed. This loop repeats as required to
+ * process all incoming packets delivered in a single interrupt. Higher
+ * value of NX_RX_MAXBUFS improves performance by posting rx buffers less
+ * frequently, but at the cost of not posting quickly enough when card is
+ * running out of rx buffers.
+ */
+#define	NX_RX_THRESHOLD		32
+#define	NX_RX_MAXBUFS		128
+#define	NX_MAX_TXCOMPS		256
+
+extern void unm_free_tx_buffers(unm_adapter *adapter);
+extern void unm_free_tx_dmahdl(unm_adapter *adapter);
+extern void unm_destroy_rx_ring(unm_rcv_desc_ctx_t *rcv_desc);
+
+static void unm_post_rx_buffers_nodb(struct unm_adapter_s *adapter,
+    uint32_t ringid);
+static mblk_t *unm_process_rcv(unm_adapter *adapter, statusDesc_t *desc);
+static int unm_process_rcv_ring(unm_adapter *, int);
+static int unm_process_cmd_ring(struct unm_adapter_s *adapter);
+
+static int unm_nic_do_ioctl(unm_adapter *adapter, queue_t *q, mblk_t *mp);
+static void unm_nic_ioctl(struct unm_adapter_s *adapter, int cmd, queue_t *q,
+    mblk_t *mp);
+
+/* GLDv3 interface functions */
+static int ntxn_m_start(void *);
+static void ntxn_m_stop(void *);
+static int ntxn_m_multicst(void *, boolean_t, const uint8_t *);
+static int ntxn_m_promisc(void *, boolean_t);
+static int ntxn_m_stat(void *arg, uint_t stat, uint64_t *val);
+static mblk_t *ntxn_m_tx(void *, mblk_t *);
+static void ntxn_m_ioctl(void *arg, queue_t *wq, mblk_t *mp);
+static boolean_t ntxn_m_getcapab(void *arg, mac_capab_t cap, void *cap_data);
+
+/*
+ * Allocates DMA handle, virtual memory and binds them
+ * returns size of actual memory binded and the physical address.
+ */
+int
+unm_pci_alloc_consistent(unm_adapter *adapter,
+		int size, caddr_t *address, ddi_dma_cookie_t *cookie,
+		ddi_dma_handle_t *dma_handle, ddi_acc_handle_t *handlep)
+{
+	int			err;
+	uint32_t		ncookies;
+	size_t			ring_len;
+	uint_t			dma_flags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT;
+
+	*dma_handle = NULL;
+
+	if (size <= 0)
+		return (DDI_ENOMEM);
+
+	err = ddi_dma_alloc_handle(adapter->dip,
+	    &adapter->gc_dma_attr_desc,
+	    DDI_DMA_DONTWAIT, NULL, dma_handle);
+	if (err != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "!%s: %s: ddi_dma_alloc_handle FAILED:"
+		    " %d", unm_nic_driver_name, __func__, err);
+		return (DDI_ENOMEM);
+	}
+
+	err = ddi_dma_mem_alloc(*dma_handle,
+	    size, &adapter->gc_attr_desc,
+	    dma_flags & (DDI_DMA_STREAMING | DDI_DMA_CONSISTENT),
+	    DDI_DMA_DONTWAIT, NULL, address, &ring_len,
+	    handlep);
+	if (err != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "!%s: %s: ddi_dma_mem_alloc failed:"
+		    "ret %d, request size: %d",
+		    unm_nic_driver_name, __func__, err, size);
+		ddi_dma_free_handle(dma_handle);
+		return (DDI_ENOMEM);
+	}
+
+	if (ring_len < size) {
+		cmn_err(CE_WARN, "%s: %s: could not allocate required "
+		    "memory :%d\n", unm_nic_driver_name,
+		    __func__, err);
+		ddi_dma_mem_free(handlep);
+		ddi_dma_free_handle(dma_handle);
+		return (DDI_FAILURE);
+	}
+
+	(void) memset(*address, 0, size);
+
+	if (((err = ddi_dma_addr_bind_handle(*dma_handle,
+	    NULL, *address, ring_len,
+	    dma_flags,
+	    DDI_DMA_DONTWAIT, NULL,
+	    cookie, &ncookies)) != DDI_DMA_MAPPED) ||
+	    (ncookies != 1)) {
+		cmn_err(CE_WARN,
+		    "!%s: %s: ddi_dma_addr_bind_handle FAILED: %d",
+		    unm_nic_driver_name, __func__, err);
+		ddi_dma_mem_free(handlep);
+		ddi_dma_free_handle(dma_handle);
+		return (DDI_FAILURE);
+	}
+
+	return (DDI_SUCCESS);
+}
+
+/*
+ * Unbinds the memory, frees the DMA handle and at the end, frees the memory
+ */
+void
+unm_pci_free_consistent(ddi_dma_handle_t *dma_handle,
+    ddi_acc_handle_t *acc_handle)
+{
+	int err;
+
+	err = ddi_dma_unbind_handle(*dma_handle);
+	if (err != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s: Error unbinding memory\n", __func__);
+		return;
+	}
+
+	ddi_dma_mem_free(acc_handle);
+	ddi_dma_free_handle(dma_handle);
+}
+
+static uint32_t msi_tgt_status[] = {
+    ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
+    ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
+    ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
+    ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
+};
+
+static void
+unm_nic_disable_int(unm_adapter *adapter)
+{
+	__uint32_t	temp = 0;
+
+	adapter->unm_nic_hw_write_wx(adapter, adapter->interrupt_crb,
+	    &temp, 4);
+}
+
+static inline int
+unm_nic_clear_int(unm_adapter *adapter)
+{
+	uint32_t	mask, temp, our_int, status;
+
+	UNM_READ_LOCK(&adapter->adapter_lock);
+
+	/* check whether it's our interrupt */
+	if (!UNM_IS_MSI_FAMILY(adapter)) {
+
+		/* Legacy Interrupt case */
+		adapter->unm_nic_pci_read_immediate(adapter, ISR_INT_VECTOR,
+		    &status);
+
+		if (!(status & adapter->legacy_intr.int_vec_bit)) {
+			UNM_READ_UNLOCK(&adapter->adapter_lock);
+			return (-1);
+		}
+
+		if (adapter->ahw.revision_id >= NX_P3_B1) {
+			adapter->unm_nic_pci_read_immediate(adapter,
+			    ISR_INT_STATE_REG, &temp);
+			if (!ISR_IS_LEGACY_INTR_TRIGGERED(temp)) {
+				UNM_READ_UNLOCK(&adapter->adapter_lock);
+				return (-1);
+			}
+		} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+			our_int = adapter->unm_nic_pci_read_normalize(adapter,
+			    CRB_INT_VECTOR);
+
+			/* FIXME: Assumes pci_func is same as ctx */
+			if ((our_int & (0x80 << adapter->portnum)) == 0) {
+				if (our_int != 0) {
+					/* not our interrupt */
+					UNM_READ_UNLOCK(&adapter->adapter_lock);
+					return (-1);
+				}
+			}
+			temp = our_int & ~((u32)(0x80 << adapter->portnum));
+			adapter->unm_nic_pci_write_normalize(adapter,
+			    CRB_INT_VECTOR, temp);
+		}
+
+		if (adapter->fw_major < 4)
+			unm_nic_disable_int(adapter);
+
+		/* claim interrupt */
+		temp = 0xffffffff;
+		adapter->unm_nic_pci_write_immediate(adapter,
+		    adapter->legacy_intr.tgt_status_reg, &temp);
+
+		adapter->unm_nic_pci_read_immediate(adapter, ISR_INT_VECTOR,
+		    &mask);
+
+		/*
+		 * Read again to make sure the legacy interrupt message got
+		 * flushed out
+		 */
+		adapter->unm_nic_pci_read_immediate(adapter, ISR_INT_VECTOR,
+		    &mask);
+	} else if (adapter->flags & UNM_NIC_MSI_ENABLED) {
+		/* clear interrupt */
+		temp = 0xffffffff;
+		adapter->unm_nic_pci_write_immediate(adapter,
+		    msi_tgt_status[adapter->ahw.pci_func], &temp);
+	}
+
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	return (0);
+}
+
+static void
+unm_nic_enable_int(unm_adapter *adapter)
+{
+	u32	temp = 1;
+
+	adapter->unm_nic_hw_write_wx(adapter, adapter->interrupt_crb,
+	    &temp, 4);
+
+	if (!UNM_IS_MSI_FAMILY(adapter)) {
+		u32	mask = 0xfbff;
+
+		adapter->unm_nic_pci_write_immediate(adapter,
+		    adapter->legacy_intr.tgt_mask_reg, &mask);
+	}
+}
+
+static void
+unm_free_hw_resources(unm_adapter *adapter)
+{
+	unm_recv_context_t *recv_ctx;
+	unm_rcv_desc_ctx_t *rcv_desc;
+	int ctx, ring;
+
+	if (adapter->context_alloced == 1) {
+		netxen_destroy_rxtx(adapter);
+		adapter->context_alloced = 0;
+	}
+
+	if (adapter->ctxDesc != NULL) {
+		unm_pci_free_consistent(&adapter->ctxDesc_dma_handle,
+		    &adapter->ctxDesc_acc_handle);
+		adapter->ctxDesc = NULL;
+	}
+
+	if (adapter->ahw.cmdDescHead != NULL) {
+		unm_pci_free_consistent(&adapter->ahw.cmd_desc_dma_handle,
+		    &adapter->ahw.cmd_desc_acc_handle);
+		adapter->ahw.cmdDesc_physAddr = NULL;
+		adapter->ahw.cmdDescHead = NULL;
+	}
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		recv_ctx = &adapter->recv_ctx[ctx];
+		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+
+			if (rcv_desc->desc_head != NULL) {
+				unm_pci_free_consistent(
+				    &rcv_desc->rx_desc_dma_handle,
+				    &rcv_desc->rx_desc_acc_handle);
+				rcv_desc->desc_head = NULL;
+				rcv_desc->phys_addr = NULL;
+			}
+		}
+
+		if (recv_ctx->rcvStatusDescHead != NULL) {
+			unm_pci_free_consistent(
+			    &recv_ctx->status_desc_dma_handle,
+			    &recv_ctx->status_desc_acc_handle);
+			recv_ctx->rcvStatusDesc_physAddr = NULL;
+			recv_ctx->rcvStatusDescHead = NULL;
+		}
+	}
+}
+
+static void
+cleanup_adapter(struct unm_adapter_s *adapter)
+{
+	if (adapter->cmd_buf_arr != NULL)
+		kmem_free(adapter->cmd_buf_arr,
+		    sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount);
+
+	ddi_regs_map_free(&(adapter->regs_handle));
+	ddi_regs_map_free(&(adapter->db_handle));
+	kmem_free(adapter, sizeof (unm_adapter));
+
+}
+
+void
+unm_nic_remove(unm_adapter *adapter)
+{
+	unm_recv_context_t *recv_ctx;
+	unm_rcv_desc_ctx_t	*rcv_desc;
+	int ctx, ring;
+
+	mac_link_update(adapter->mach, LINK_STATE_DOWN);
+	unm_nic_stop_port(adapter);
+
+	if (adapter->interrupt_crb) {
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		unm_nic_disable_int(adapter);
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	}
+	(void) untimeout(adapter->watchdog_timer);
+
+	unm_free_hw_resources(adapter);
+	unm_free_tx_buffers(adapter);
+	unm_free_tx_dmahdl(adapter);
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		recv_ctx = &adapter->recv_ctx[ctx];
+		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			if (rcv_desc->rx_buf_pool != NULL)
+				unm_destroy_rx_ring(rcv_desc);
+		}
+	}
+
+	if (adapter->portnum == 0)
+		unm_free_dummy_dma(adapter);
+
+	unm_destroy_intr(adapter);
+
+	ddi_set_driver_private(adapter->dip, NULL);
+	cleanup_adapter(adapter);
+}
+
+static int
+init_firmware(unm_adapter *adapter)
+{
+	uint32_t state = 0, loops = 0, tempout;
+
+	/* Window 1 call */
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	state = adapter->unm_nic_pci_read_normalize(adapter, CRB_CMDPEG_STATE);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	if (state == PHAN_INITIALIZE_ACK)
+		return (0);
+
+	while (state != PHAN_INITIALIZE_COMPLETE && loops < 200000) {
+		drv_usecwait(100);
+		/* Window 1 call */
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		state = adapter->unm_nic_pci_read_normalize(adapter,
+		    CRB_CMDPEG_STATE);
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+		loops++;
+	}
+
+	if (loops >= 200000) {
+		cmn_err(CE_WARN, "%s%d: CmdPeg init incomplete:%x\n",
+		    adapter->name, adapter->instance, state);
+		return (-EIO);
+	}
+
+	/* Window 1 call */
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	tempout = INTR_SCHEME_PERPORT;
+	adapter->unm_nic_hw_write_wx(adapter, CRB_NIC_CAPABILITIES_HOST,
+	    &tempout, 4);
+	tempout = MSI_MODE_MULTIFUNC;
+	adapter->unm_nic_hw_write_wx(adapter, CRB_NIC_MSI_MODE_HOST,
+	    &tempout, 4);
+	tempout = MPORT_MULTI_FUNCTION_MODE;
+	adapter->unm_nic_hw_write_wx(adapter, CRB_MPORT_MODE, &tempout, 4);
+	tempout = PHAN_INITIALIZE_ACK;
+	adapter->unm_nic_hw_write_wx(adapter, CRB_CMDPEG_STATE, &tempout, 4);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	return (0);
+}
+
+/*
+ * Utility to synchronize with receive peg.
+ *  Returns   0 on sucess
+ *         -EIO on error
+ */
+int
+receive_peg_ready(struct unm_adapter_s *adapter)
+{
+	uint32_t state = 0;
+	int loops = 0, err = 0;
+
+	/* Window 1 call */
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	state = adapter->unm_nic_pci_read_normalize(adapter, CRB_RCVPEG_STATE);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	while ((state != PHAN_PEG_RCV_INITIALIZED) && (loops < 20000)) {
+		drv_usecwait(100);
+		/* Window 1 call */
+
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		state = adapter->unm_nic_pci_read_normalize(adapter,
+		    CRB_RCVPEG_STATE);
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+		loops++;
+	}
+
+	if (loops >= 20000) {
+		cmn_err(CE_WARN, "Receive Peg initialization incomplete 0x%x\n",
+		    state);
+		err = -EIO;
+	}
+
+	return (err);
+}
+
+/*
+ * check if the firmware has been downloaded and ready to run  and
+ * setup the address for the descriptors in the adapter
+ */
+static int
+unm_nic_hw_resources(unm_adapter *adapter)
+{
+	hardware_context	*hw = &adapter->ahw;
+	void			*addr;
+	int			err;
+	int			ctx, ring;
+	unm_recv_context_t	*recv_ctx;
+	unm_rcv_desc_ctx_t	*rcv_desc;
+	ddi_dma_cookie_t	cookie;
+	int			size;
+
+	if (err = receive_peg_ready(adapter))
+		return (err);
+
+	size = (sizeof (RingContext) + sizeof (uint32_t));
+
+	err = unm_pci_alloc_consistent(adapter,
+	    size, (caddr_t *)&addr, &cookie,
+	    &adapter->ctxDesc_dma_handle,
+	    &adapter->ctxDesc_acc_handle);
+	if (err != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "Failed to allocate HW context\n");
+		return (err);
+	}
+
+	adapter->ctxDesc_physAddr = cookie.dmac_laddress;
+
+	(void) memset(addr, 0, sizeof (RingContext));
+
+	adapter->ctxDesc = (RingContext *) addr;
+	adapter->ctxDesc->CtxId = adapter->portnum;
+	adapter->ctxDesc->CMD_CONSUMER_OFFSET =
+	    adapter->ctxDesc_physAddr + sizeof (RingContext);
+	adapter->cmdConsumer =
+	    (uint32_t *)(uintptr_t)(((char *)addr) + sizeof (RingContext));
+
+	ASSERT(!((unsigned long)adapter->ctxDesc_physAddr & 0x3f));
+
+	/*
+	 * Allocate command descriptor ring.
+	 */
+	size = (sizeof (cmdDescType0_t) * adapter->MaxTxDescCount);
+	err = unm_pci_alloc_consistent(adapter,
+	    size, (caddr_t *)&addr, &cookie,
+	    &hw->cmd_desc_dma_handle,
+	    &hw->cmd_desc_acc_handle);
+	if (err != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "Failed to allocate cmd desc ring\n");
+		return (err);
+	}
+
+	hw->cmdDesc_physAddr = cookie.dmac_laddress;
+	hw->cmdDescHead = (cmdDescType0_t *)addr;
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		recv_ctx = &adapter->recv_ctx[ctx];
+
+		size = (sizeof (statusDesc_t)* adapter->MaxRxDescCount);
+		err = unm_pci_alloc_consistent(adapter,
+		    size, (caddr_t *)&addr,
+		    &recv_ctx->status_desc_dma_cookie,
+		    &recv_ctx->status_desc_dma_handle,
+		    &recv_ctx->status_desc_acc_handle);
+		if (err != DDI_SUCCESS) {
+			cmn_err(CE_WARN, "Failed to allocate sts desc ring\n");
+			goto free_cmd_desc;
+		}
+
+		(void) memset(addr, 0, size);
+		recv_ctx->rcvStatusDesc_physAddr =
+		    recv_ctx->status_desc_dma_cookie.dmac_laddress;
+		recv_ctx->rcvStatusDescHead = (statusDesc_t *)addr;
+
+		/* rds rings */
+		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+
+			size = (sizeof (rcvDesc_t) * adapter->MaxRxDescCount);
+			err = unm_pci_alloc_consistent(adapter,
+			    size, (caddr_t *)&addr,
+			    &rcv_desc->rx_desc_dma_cookie,
+			    &rcv_desc->rx_desc_dma_handle,
+			    &rcv_desc->rx_desc_acc_handle);
+			if (err != DDI_SUCCESS) {
+				cmn_err(CE_WARN, "Failed to allocate "
+				    "rx desc ring %d\n", ring);
+				goto free_status_desc;
+			}
+
+			rcv_desc->phys_addr =
+			    rcv_desc->rx_desc_dma_cookie.dmac_laddress;
+			rcv_desc->desc_head = (rcvDesc_t *)addr;
+		}
+	}
+
+	if (err = netxen_create_rxtx(adapter))
+		goto free_statusrx_desc;
+	adapter->context_alloced = 1;
+
+	return (DDI_SUCCESS);
+
+free_statusrx_desc:
+free_status_desc:
+free_cmd_desc:
+	unm_free_hw_resources(adapter);
+
+	return (err);
+}
+
+void unm_desc_dma_sync(ddi_dma_handle_t handle, uint_t start, uint_t count,
+    uint_t range, uint_t unit_size, uint_t direction)
+{
+	if ((start + count) < range) {
+		(void) ddi_dma_sync(handle, start * unit_size,
+		    count * unit_size, direction);
+	} else {
+		(void) ddi_dma_sync(handle, start * unit_size, 0, direction);
+		(void) ddi_dma_sync(handle, 0,
+		    (start + count - range) * unit_size, DDI_DMA_SYNC_FORCPU);
+	}
+}
+
+static uint32_t crb_cmd_producer[4] = { CRB_CMD_PRODUCER_OFFSET,
+    CRB_CMD_PRODUCER_OFFSET_1, CRB_CMD_PRODUCER_OFFSET_2,
+    CRB_CMD_PRODUCER_OFFSET_3 };
+
+static uint32_t crb_cmd_consumer[4] = { CRB_CMD_CONSUMER_OFFSET,
+    CRB_CMD_CONSUMER_OFFSET_1, CRB_CMD_CONSUMER_OFFSET_2,
+    CRB_CMD_CONSUMER_OFFSET_3 };
+
+void
+unm_nic_update_cmd_producer(struct unm_adapter_s *adapter,
+    uint32_t crb_producer)
+{
+	int data = crb_producer;
+
+	if (adapter->crb_addr_cmd_producer) {
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		adapter->unm_nic_hw_write_wx(adapter,
+		    adapter->crb_addr_cmd_producer, &data, 4);
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	}
+}
+
+static void
+unm_nic_update_cmd_consumer(struct unm_adapter_s *adapter,
+    uint32_t crb_producer)
+{
+	int data = crb_producer;
+
+	if (adapter->crb_addr_cmd_consumer)
+		adapter->unm_nic_hw_write_wx(adapter,
+		    adapter->crb_addr_cmd_consumer, &data, 4);
+}
+
+/*
+ * Looks for type of packet and sets opcode accordingly
+ * so that checksum offload can be used.
+ */
+static void
+unm_tx_csum(cmdDescType0_t *desc, mblk_t *mp, pktinfo_t *pktinfo)
+{
+	if (pktinfo->mac_hlen == sizeof (struct ether_vlan_header))
+		desc->u1.s1.flags = FLAGS_VLAN_TAGGED;
+
+	if (pktinfo->etype == htons(ETHERTYPE_IP)) {
+		uint32_t	start, flags;
+
+		hcksum_retrieve(mp, NULL, NULL, &start, NULL, NULL, NULL,
+		    &flags);
+		if ((flags & (HCK_FULLCKSUM | HCK_IPV4_HDRCKSUM)) == 0)
+			return;
+
+		/*
+		 * For TCP/UDP, ask hardware to do both IP header and
+		 * full checksum, even if stack has already done one or
+		 * the other. Hardware will always get it correct even
+		 * if stack has already done it.
+		 */
+		switch (pktinfo->l4_proto) {
+			case IPPROTO_TCP:
+				desc->u1.s1.opcode = TX_TCP_PKT;
+				break;
+			case IPPROTO_UDP:
+				desc->u1.s1.opcode = TX_UDP_PKT;
+				break;
+			default:
+				/* Must be here with HCK_IPV4_HDRCKSUM */
+				desc->u1.s1.opcode = TX_IP_PKT;
+				return;
+		}
+
+		desc->u1.s1.ipHdrOffset = pktinfo->mac_hlen;
+		desc->u1.s1.tcpHdrOffset = pktinfo->mac_hlen + pktinfo->ip_hlen;
+	}
+}
+
+/*
+ * For IP/UDP/TCP checksum offload, this checks for MAC+IP header in one
+ * contiguous block ending at 8 byte aligned address as required by hardware.
+ * Caller assumes pktinfo->total_len will be updated by this function and
+ * if pktinfo->etype is set to 0, it will need to linearize the mblk and
+ * invoke unm_update_pkt_info() to determine ethertype, IP header len and
+ * protocol.
+ */
+static boolean_t
+unm_get_pkt_info(mblk_t *mp, pktinfo_t *pktinfo)
+{
+	mblk_t		*bp;
+	ushort_t	type;
+
+	(void) memset(pktinfo, 0, sizeof (pktinfo_t));
+
+	for (bp = mp; bp != NULL; bp = bp->b_cont) {
+		if (MBLKL(bp) == 0)
+			continue;
+		pktinfo->mblk_no++;
+		pktinfo->total_len += MBLKL(bp);
+	}
+
+	if (MBLKL(mp) < (sizeof (struct ether_header) + sizeof (ipha_t)))
+		return (B_FALSE);
+
+	/*
+	 * We just need non 1 byte aligned address, since ether_type is
+	 * ushort.
+	 */
+	if ((uintptr_t)mp->b_rptr & 1)
+		return (B_FALSE);
+
+	type = ((struct ether_header *)(uintptr_t)mp->b_rptr)->ether_type;
+	if (type == htons(ETHERTYPE_VLAN)) {
+		if (MBLKL(mp) < (sizeof (struct ether_vlan_header) +
+		    sizeof (ipha_t)))
+			return (B_FALSE);
+		type = ((struct ether_vlan_header *) \
+		    (uintptr_t)mp->b_rptr)->ether_type;
+		pktinfo->mac_hlen = sizeof (struct ether_vlan_header);
+	} else {
+		pktinfo->mac_hlen = sizeof (struct ether_header);
+	}
+	pktinfo->etype = type;
+
+	if (pktinfo->etype == htons(ETHERTYPE_IP)) {
+		uchar_t *ip_off = mp->b_rptr + pktinfo->mac_hlen;
+
+		pktinfo->ip_hlen = IPH_HDR_LENGTH((uintptr_t)ip_off);
+		pktinfo->l4_proto =
+		    ((ipha_t *)(uintptr_t)ip_off)->ipha_protocol;
+
+		/* IP header not aligned to quadward boundary? */
+		if ((unsigned long)(ip_off + pktinfo->ip_hlen) % 8 != 0)
+			return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+static void
+unm_update_pkt_info(char *ptr, pktinfo_t *pktinfo)
+{
+	ushort_t	type;
+
+	type = ((struct ether_header *)(uintptr_t)ptr)->ether_type;
+	if (type == htons(ETHERTYPE_VLAN)) {
+		type = ((struct ether_vlan_header *)(uintptr_t)ptr)->ether_type;
+		pktinfo->mac_hlen = sizeof (struct ether_vlan_header);
+	} else {
+		pktinfo->mac_hlen = sizeof (struct ether_header);
+	}
+	pktinfo->etype = type;
+
+	if (pktinfo->etype == htons(ETHERTYPE_IP)) {
+		char *ipp = ptr + pktinfo->mac_hlen;
+
+		pktinfo->ip_hlen = IPH_HDR_LENGTH((uintptr_t)ipp);
+		pktinfo->l4_proto = ((ipha_t *)(uintptr_t)ipp)->ipha_protocol;
+	}
+}
+
+static boolean_t
+unm_send_copy(struct unm_adapter_s *adapter, mblk_t *mp, pktinfo_t *pktinfo)
+{
+	hardware_context *hw;
+	u32				producer = 0;
+	cmdDescType0_t			*hwdesc;
+	struct unm_cmd_buffer		*pbuf = NULL;
+	u32				mblen;
+	int				no_of_desc = 1;
+	int				MaxTxDescCount;
+	mblk_t				*bp;
+	char				*txb;
+
+	hw = &adapter->ahw;
+	MaxTxDescCount = adapter->MaxTxDescCount;
+
+	UNM_SPIN_LOCK(&adapter->tx_lock);
+	membar_enter();
+
+	if (find_diff_among(adapter->cmdProducer, adapter->lastCmdConsumer,
+	    MaxTxDescCount) <= 2) {
+		adapter->stats.outofcmddesc++;
+		adapter->resched_needed = 1;
+		membar_exit();
+		UNM_SPIN_UNLOCK(&adapter->tx_lock);
+		return (B_FALSE);
+	}
+	adapter->freecmds -= no_of_desc;
+
+	producer = adapter->cmdProducer;
+
+	adapter->cmdProducer = get_index_range(adapter->cmdProducer,
+	    MaxTxDescCount, no_of_desc);
+
+	hwdesc = &hw->cmdDescHead[producer];
+	(void) memset(hwdesc, 0, sizeof (cmdDescType0_t));
+	pbuf = &adapter->cmd_buf_arr[producer];
+
+	pbuf->msg = NULL;
+	pbuf->head = NULL;
+	pbuf->tail = NULL;
+
+	txb = pbuf->dma_area.vaddr;
+
+	for (bp = mp; bp != NULL; bp = bp->b_cont) {
+		if ((mblen = MBLKL(bp)) == 0)
+			continue;
+		bcopy(bp->b_rptr, txb, mblen);
+		txb += mblen;
+	}
+
+	/*
+	 * Determine metadata if not previously done due to fragmented mblk.
+	 */
+	if (pktinfo->etype == 0)
+		unm_update_pkt_info(pbuf->dma_area.vaddr, pktinfo);
+
+	(void) ddi_dma_sync(pbuf->dma_area.dma_hdl,
+	    0, pktinfo->total_len, DDI_DMA_SYNC_FORDEV);
+
+	/* hwdesc->u1.s1.tcpHdrOffset = 0; */
+	/* hwdesc->mss = 0; */
+	hwdesc->u1.s1.opcode = TX_ETHER_PKT;
+	hwdesc->u3.s1.port = adapter->portnum;
+	hwdesc->u3.s1.ctx_id = adapter->portnum;
+
+	hwdesc->u6.s1.buffer1Length = pktinfo->total_len;
+	hwdesc->u5.AddrBuffer1 = pbuf->dma_area.dma_addr;
+	hwdesc->u1.s1.numOfBuffers = 1;
+	hwdesc->u1.s1.totalLength = pktinfo->total_len;
+
+	unm_tx_csum(hwdesc, mp, pktinfo);
+
+	unm_desc_dma_sync(hw->cmd_desc_dma_handle,
+	    producer,
+	    no_of_desc,
+	    MaxTxDescCount,
+	    sizeof (cmdDescType0_t),
+	    DDI_DMA_SYNC_FORDEV);
+
+	hw->cmdProducer = adapter->cmdProducer;
+	unm_nic_update_cmd_producer(adapter, adapter->cmdProducer);
+
+	adapter->stats.txbytes += pktinfo->total_len;
+	adapter->stats.xmitfinished++;
+	adapter->stats.txcopyed++;
+	UNM_SPIN_UNLOCK(&adapter->tx_lock);
+
+	freemsg(mp);
+	return (B_TRUE);
+}
+
+/* Should be called with adapter->tx_lock held. */
+static void
+unm_return_dma_handle(unm_adapter *adapter, unm_dmah_node_t *head,
+    unm_dmah_node_t *tail, uint32_t num)
+{
+	ASSERT(tail != NULL);
+	tail->next = adapter->dmahdl_pool;
+	adapter->dmahdl_pool = head;
+	adapter->freehdls += num;
+}
+
+static unm_dmah_node_t *
+unm_reserve_dma_handle(unm_adapter* adapter)
+{
+	unm_dmah_node_t *dmah = NULL;
+
+	dmah = adapter->dmahdl_pool;
+	if (dmah != NULL) {
+		adapter->dmahdl_pool = dmah->next;
+		dmah->next = NULL;
+		adapter->freehdls--;
+		membar_exit();
+	}
+
+	return (dmah);
+}
+
+static boolean_t
+unm_send_mapped(struct unm_adapter_s *adapter, mblk_t *mp, pktinfo_t *pktinfo)
+{
+	hardware_context		*hw;
+	u32				producer = 0;
+	u32				saved_producer = 0;
+	cmdDescType0_t			*hwdesc;
+	struct unm_cmd_buffer		*pbuf = NULL;
+	int				no_of_desc;
+	int				k;
+	int				MaxTxDescCount;
+	mblk_t				*bp;
+
+	unm_dmah_node_t *dmah, *head = NULL, *tail = NULL, *hdlp;
+	ddi_dma_cookie_t cookie[MAX_COOKIES_PER_CMD + 1];
+	int ret, i;
+	uint32_t hdl_reserved = 0;
+	uint32_t mblen;
+	uint32_t ncookies, index = 0, total_cookies = 0;
+
+	MaxTxDescCount = adapter->MaxTxDescCount;
+
+	UNM_SPIN_LOCK(&adapter->tx_lock);
+
+	/* bind all the mblks of the packet first */
+	for (bp = mp; bp != NULL; bp = bp->b_cont) {
+		mblen = MBLKL(bp);
+		if (mblen == 0)
+			continue;
+
+		dmah = unm_reserve_dma_handle(adapter);
+		if (dmah == NULL) {
+			adapter->stats.outoftxdmahdl++;
+			goto err_map;
+		}
+
+		ret = ddi_dma_addr_bind_handle(dmah->dmahdl,
+		    NULL, (caddr_t)bp->b_rptr, mblen,
+		    DDI_DMA_STREAMING | DDI_DMA_WRITE,
+		    DDI_DMA_DONTWAIT, NULL, &cookie[index], &ncookies);
+
+		if (ret != DDI_DMA_MAPPED)
+			goto err_map;
+
+		if (tail == NULL) {
+			head = tail = dmah;
+		} else {
+			tail->next = dmah;
+			tail = dmah;
+		}
+		hdl_reserved++;
+
+		total_cookies += ncookies;
+		if (total_cookies > MAX_COOKIES_PER_CMD) {
+			dmah = NULL;
+			goto err_map;
+		}
+
+		if (index == 0) {
+			size_t	hsize = cookie[0].dmac_size;
+
+			/*
+			 * For TCP/UDP packets with checksum offload,
+			 * MAC/IP headers need to be contiguous. Otherwise,
+			 * there must be at least 16 bytes in the first
+			 * descriptor.
+			 */
+			if ((pktinfo->l4_proto == IPPROTO_TCP) ||
+			    (pktinfo->l4_proto == IPPROTO_UDP)) {
+				if (hsize < (pktinfo->mac_hlen +
+				    pktinfo->ip_hlen)) {
+					dmah = NULL;
+					goto err_map;
+				}
+			} else {
+				if (hsize < 16) {
+					dmah = NULL;
+					goto err_map;
+				}
+			}
+		}
+
+		index++;
+		ncookies--;
+		for (i = 0; i < ncookies; i++, index++)
+			ddi_dma_nextcookie(dmah->dmahdl, &cookie[index]);
+	}
+
+	dmah = NULL;
+	hw = &adapter->ahw;
+	no_of_desc = (total_cookies + 3) >> 2;
+
+	membar_enter();
+	if (find_diff_among(adapter->cmdProducer, adapter->lastCmdConsumer,
+	    MaxTxDescCount) < no_of_desc+2) {
+		/*
+		 * If we are going to be trying the copy path, no point
+		 * scheduling an upcall when Tx resources are freed.
+		 */
+		if (pktinfo->total_len > adapter->maxmtu) {
+			adapter->stats.outofcmddesc++;
+			adapter->resched_needed = 1;
+		}
+		membar_exit();
+		goto err_alloc_desc;
+	}
+	adapter->freecmds -= no_of_desc;
+
+	/* Copy the descriptors into the hardware    */
+	producer = adapter->cmdProducer;
+	saved_producer = producer;
+	hwdesc = &hw->cmdDescHead[producer];
+	(void) memset(hwdesc, 0, sizeof (cmdDescType0_t));
+	pbuf = &adapter->cmd_buf_arr[producer];
+
+	pbuf->msg = mp;
+	pbuf->head = head;
+	pbuf->tail = tail;
+
+	hwdesc->u1.s1.numOfBuffers = total_cookies;
+	hwdesc->u1.s1.opcode = TX_ETHER_PKT;
+	hwdesc->u3.s1.port = adapter->portnum;
+	/* hwdesc->u1.s1.tcpHdrOffset = 0; */
+	/* hwdesc->mss = 0; */
+	hwdesc->u3.s1.ctx_id = adapter->portnum;
+	hwdesc->u1.s1.totalLength = pktinfo->total_len;
+	unm_tx_csum(hwdesc, mp, pktinfo);
+
+	for (i = k = 0; i < total_cookies; i++) {
+		if (k == 4) {
+			/* Move to the next descriptor */
+			k = 0;
+			producer = get_next_index(producer, MaxTxDescCount);
+			hwdesc = &hw->cmdDescHead[producer];
+			(void) memset(hwdesc, 0, sizeof (cmdDescType0_t));
+		}
+
+		switch (k) {
+		case 0:
+			hwdesc->u6.s1.buffer1Length = cookie[i].dmac_size;
+			hwdesc->u5.AddrBuffer1 = cookie[i].dmac_laddress;
+			break;
+		case 1:
+			hwdesc->u6.s1.buffer2Length = cookie[i].dmac_size;
+			hwdesc->u2.AddrBuffer2 = cookie[i].dmac_laddress;
+			break;
+		case 2:
+			hwdesc->u6.s1.buffer3Length = cookie[i].dmac_size;
+			hwdesc->u4.AddrBuffer3 = cookie[i].dmac_laddress;
+			break;
+		case 3:
+			hwdesc->u6.s1.buffer4Length = cookie[i].dmac_size;
+			hwdesc->u7.AddrBuffer4 = cookie[i].dmac_laddress;
+			break;
+		}
+		k++;
+	}
+
+	unm_desc_dma_sync(hw->cmd_desc_dma_handle, saved_producer, no_of_desc,
+	    MaxTxDescCount, sizeof (cmdDescType0_t), DDI_DMA_SYNC_FORDEV);
+
+	adapter->cmdProducer = get_next_index(producer, MaxTxDescCount);
+	hw->cmdProducer = adapter->cmdProducer;
+	unm_nic_update_cmd_producer(adapter, adapter->cmdProducer);
+
+	adapter->stats.txbytes += pktinfo->total_len;
+	adapter->stats.xmitfinished++;
+	adapter->stats.txmapped++;
+	UNM_SPIN_UNLOCK(&adapter->tx_lock);
+	return (B_TRUE);
+
+err_alloc_desc:
+err_map:
+
+	hdlp = head;
+	while (hdlp != NULL) {
+		(void) ddi_dma_unbind_handle(hdlp->dmahdl);
+		hdlp = hdlp->next;
+	}
+
+	/*
+	 * add the reserved but bind failed one to the list to be returned
+	 */
+	if (dmah != NULL) {
+		if (tail == NULL)
+			head = tail = dmah;
+		else {
+			tail->next = dmah;
+			tail = dmah;
+		}
+		hdl_reserved++;
+	}
+
+	if (head != NULL)
+		unm_return_dma_handle(adapter, head, tail, hdl_reserved);
+
+	UNM_SPIN_UNLOCK(&adapter->tx_lock);
+	return (B_FALSE);
+}
+
+static boolean_t
+unm_nic_xmit_frame(unm_adapter *adapter, mblk_t *mp)
+{
+	pktinfo_t	pktinfo;
+	boolean_t	status = B_FALSE, send_mapped;
+
+	adapter->stats.xmitcalled++;
+
+	send_mapped = unm_get_pkt_info(mp, &pktinfo);
+
+	if (pktinfo.total_len <= adapter->tx_bcopy_threshold ||
+	    pktinfo.mblk_no >= MAX_BUFFERS_PER_CMD)
+		send_mapped = B_FALSE;
+
+	if (send_mapped == B_TRUE)
+		status = unm_send_mapped(adapter, mp, &pktinfo);
+
+	if (status != B_TRUE) {
+		if (pktinfo.total_len <= adapter->maxmtu)
+			return (unm_send_copy(adapter, mp, &pktinfo));
+
+		/* message too large */
+		freemsg(mp);
+		adapter->stats.txdropped++;
+		status = B_TRUE;
+	}
+
+	return (status);
+}
+
+static int
+unm_nic_check_temp(struct unm_adapter_s *adapter)
+{
+	uint32_t temp, temp_state, temp_val;
+	int rv = 0;
+
+	if ((adapter->ahw.revision_id == NX_P3_A2) ||
+	    (adapter->ahw.revision_id == NX_P3_A0))
+		return (0);
+
+	temp = adapter->unm_nic_pci_read_normalize(adapter, CRB_TEMP_STATE);
+
+	temp_state = nx_get_temp_state(temp);
+	temp_val = nx_get_temp_val(temp);
+
+	if (temp_state == NX_TEMP_PANIC) {
+		cmn_err(CE_WARN, "%s: Device temperature %d C exceeds "
+		    "maximum allowed, device has been shut down\n",
+		    unm_nic_driver_name, temp_val);
+		rv = 1;
+	} else if (temp_state == NX_TEMP_WARN) {
+		if (adapter->temp == NX_TEMP_NORMAL) {
+		cmn_err(CE_WARN, "%s: Device temperature %d C exceeds"
+		    "operating range. Immediate action needed.\n",
+		    unm_nic_driver_name, temp_val);
+		}
+	} else {
+		if (adapter->temp == NX_TEMP_WARN) {
+			cmn_err(CE_WARN, "%s: Device temperature is now %d "
+			    "degrees C in normal range.\n",
+			    unm_nic_driver_name, temp_val);
+		}
+	}
+
+	adapter->temp = temp_state;
+	return (rv);
+}
+
+static void
+unm_watchdog(unsigned long v)
+{
+	unm_adapter *adapter = (unm_adapter *)v;
+
+	if ((adapter->portnum == 0) && unm_nic_check_temp(adapter)) {
+		/*
+		 * We return without turning on the netdev queue as there
+		 * was an overheated device
+		 */
+		return;
+	}
+
+	unm_nic_handle_phy_intr(adapter);
+
+	/*
+	 * This function schedules a call for itself.
+	 */
+	adapter->watchdog_timer = timeout((void (*)(void *))&unm_watchdog,
+	    (void *)adapter, 2 * drv_usectohz(1000000));
+
+}
+
+static void unm_nic_clear_stats(unm_adapter *adapter)
+{
+	(void) memset(&adapter->stats, 0, sizeof (adapter->stats));
+}
+
+static void
+unm_nic_poll(unm_adapter *adapter)
+{
+	int	work_done, tx_complete;
+
+	adapter->stats.polled++;
+
+loop:
+	tx_complete = unm_process_cmd_ring(adapter);
+	work_done = unm_process_rcv_ring(adapter, NX_RX_MAXBUFS);
+	if ((!tx_complete) || (!(work_done < NX_RX_MAXBUFS)))
+		goto loop;
+
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	unm_nic_enable_int(adapter);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+}
+
+/* ARGSUSED */
+uint_t
+unm_intr(caddr_t data, caddr_t arg)
+{
+	unm_adapter	*adapter = (unm_adapter *)(uintptr_t)data;
+
+	if (unm_nic_clear_int(adapter))
+		return (DDI_INTR_UNCLAIMED);
+
+	unm_nic_poll(adapter);
+	return (DDI_INTR_CLAIMED);
+}
+
+/*
+ * This is invoked from receive isr. Due to the single threaded nature
+ * of the invocation, pool_lock acquisition is not neccesary to protect
+ * pool_list.
+ */
+static void
+unm_free_rx_buffer(unm_rcv_desc_ctx_t *rcv_desc, unm_rx_buffer_t *rx_buffer)
+{
+	/* mutex_enter(rcv_desc->pool_lock); */
+	rx_buffer->next = rcv_desc->pool_list;
+	rcv_desc->pool_list = rx_buffer;
+	rcv_desc->rx_buf_free++;
+	/* mutex_exit(rcv_desc->pool_lock); */
+}
+
+/*
+ * unm_process_rcv() send the received packet to the protocol stack.
+ */
+static mblk_t *
+unm_process_rcv(unm_adapter *adapter, statusDesc_t *desc)
+{
+	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
+	unm_rx_buffer_t		*rx_buffer;
+	mblk_t *mp;
+	u32			desc_ctx = desc->u1.s1.type;
+	unm_rcv_desc_ctx_t	*rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
+	u32			pkt_length = desc->u1.s1.totalLength;
+	int			poff = desc->u1.s1.pkt_offset;
+	int			index, cksum_flags, docopy;
+	int			index_lo = desc->u1.s1.referenceHandle_lo;
+	char			*vaddr;
+
+	index = ((desc->u1.s1.referenceHandle_hi << 4) | index_lo);
+
+	rx_buffer = index2rxbuf(rcv_desc, index);
+
+	if (rx_buffer == NULL) {
+		cmn_err(CE_WARN, "\r\nNULL rx_buffer idx=%d", index);
+		return (NULL);
+	}
+	vaddr = (char *)rx_buffer->dma_info.vaddr;
+	if (vaddr == NULL) {
+		cmn_err(CE_WARN, "\r\nNULL vaddr");
+		return (NULL);
+	}
+	rcv_desc->rx_desc_handled++;
+	rcv_desc->rx_buf_card--;
+
+	(void) ddi_dma_sync(rx_buffer->dma_info.dma_hdl, 0,
+	    pkt_length + poff + (adapter->ahw.cut_through ? 0 :
+	    IP_ALIGNMENT_BYTES), DDI_DMA_SYNC_FORCPU);
+
+	/*
+	 * Copy packet into new allocated message buffer, if pkt_length
+	 * is below copy threshold.
+	 */
+	docopy = (pkt_length <= adapter->rx_bcopy_threshold) ? 1 : 0;
+
+	/*
+	 * If card is running out of rx buffers, then attempt to allocate
+	 * new mblk so we can feed this rx buffer back to card (we
+	 * _could_ look at what's pending on free and recycle lists).
+	 */
+	if (rcv_desc->rx_buf_card < NX_RX_THRESHOLD) {
+		docopy = 1;
+		adapter->stats.rxbufshort++;
+	}
+
+	if (docopy == 1) {
+		if ((mp = allocb(pkt_length + IP_ALIGNMENT_BYTES, 0)) == NULL) {
+			adapter->stats.allocbfailed++;
+			goto freebuf;
+		}
+
+		mp->b_rptr += IP_ALIGNMENT_BYTES;
+		vaddr += poff;
+		bcopy(vaddr, mp->b_rptr, pkt_length);
+		adapter->stats.rxcopyed++;
+		unm_free_rx_buffer(rcv_desc, rx_buffer);
+	} else {
+		mp = (mblk_t *)rx_buffer->mp;
+		if (mp == NULL) {
+			mp = desballoc(rx_buffer->dma_info.vaddr,
+			    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
+			if (mp == NULL) {
+				adapter->stats.desballocfailed++;
+				goto freebuf;
+			}
+			rx_buffer->mp = mp;
+		}
+		mp->b_rptr += poff;
+		adapter->stats.rxmapped++;
+	}
+
+	mp->b_wptr = (uchar_t *)((unsigned long)mp->b_rptr + pkt_length);
+
+	if (desc->u1.s1.status == STATUS_CKSUM_OK) {
+		adapter->stats.csummed++;
+		cksum_flags =
+		    HCK_FULLCKSUM_OK | HCK_IPV4_HDRCKSUM | HCK_FULLCKSUM;
+	} else {
+		cksum_flags = 0;
+	}
+	(void) hcksum_assoc(mp, NULL, NULL, 0, 0, 0, 0, cksum_flags, 0);
+
+	adapter->stats.no_rcv++;
+	adapter->stats.rxbytes += pkt_length;
+	adapter->stats.uphappy++;
+
+	return (mp);
+
+freebuf:
+	unm_free_rx_buffer(rcv_desc, rx_buffer);
+	return (NULL);
+}
+
+/* Process Receive status ring */
+static int
+unm_process_rcv_ring(unm_adapter *adapter, int max)
+{
+	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
+	statusDesc_t		*desc_head = recv_ctx->rcvStatusDescHead;
+	statusDesc_t		*desc = NULL;
+	uint32_t		consumer, start;
+	int			count = 0, ring;
+	mblk_t *mp;
+
+	start = consumer = recv_ctx->statusRxConsumer;
+
+	unm_desc_dma_sync(recv_ctx->status_desc_dma_handle, start, max,
+	    adapter->MaxRxDescCount, sizeof (statusDesc_t),
+	    DDI_DMA_SYNC_FORCPU);
+
+	while (count < max) {
+		desc = &desc_head[consumer];
+		if (!(desc->u1.s1.owner & STATUS_OWNER_HOST))
+			break;
+
+		mp = unm_process_rcv(adapter, desc);
+		desc->u1.s1.owner = STATUS_OWNER_PHANTOM;
+
+		consumer = (consumer + 1) % adapter->MaxRxDescCount;
+		count++;
+		if (mp != NULL)
+			mac_rx(adapter->mach, NULL, mp);
+	}
+
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		if (recv_ctx->rcv_desc[ring].rx_desc_handled > 0)
+			unm_post_rx_buffers_nodb(adapter, ring);
+	}
+
+	if (count) {
+		unm_desc_dma_sync(recv_ctx->status_desc_dma_handle, start,
+		    count, adapter->MaxRxDescCount, sizeof (statusDesc_t),
+		    DDI_DMA_SYNC_FORDEV);
+
+		/* update the consumer index in phantom */
+		recv_ctx->statusRxConsumer = consumer;
+
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		adapter->unm_nic_hw_write_wx(adapter,
+		    recv_ctx->host_sds_consumer, &consumer, 4);
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	}
+
+	return (count);
+}
+
+/* Process Command status ring */
+static int
+unm_process_cmd_ring(struct unm_adapter_s *adapter)
+{
+	u32			last_consumer;
+	u32			consumer;
+	int			count = 0;
+	struct unm_cmd_buffer	*buffer;
+	int			done;
+	unm_dmah_node_t *dmah, *head = NULL, *tail = NULL;
+	uint32_t	free_hdls = 0;
+
+	(void) ddi_dma_sync(adapter->ctxDesc_dma_handle, sizeof (RingContext),
+	    sizeof (uint32_t), DDI_DMA_SYNC_FORCPU);
+
+	last_consumer = adapter->lastCmdConsumer;
+	consumer = *(adapter->cmdConsumer);
+
+	while (last_consumer != consumer) {
+		buffer = &adapter->cmd_buf_arr[last_consumer];
+		if (buffer->head != NULL) {
+			dmah = buffer->head;
+			while (dmah != NULL) {
+				(void) ddi_dma_unbind_handle(dmah->dmahdl);
+				dmah = dmah->next;
+				free_hdls++;
+			}
+
+			if (head == NULL) {
+				head = buffer->head;
+				tail = buffer->tail;
+			} else {
+				tail->next = buffer->head;
+				tail = buffer->tail;
+			}
+
+			buffer->head = NULL;
+			buffer->tail = NULL;
+
+			if (buffer->msg != NULL) {
+				freemsg(buffer->msg);
+				buffer->msg = NULL;
+			}
+		}
+
+		last_consumer = get_next_index(last_consumer,
+		    adapter->MaxTxDescCount);
+		if (++count > NX_MAX_TXCOMPS)
+			break;
+	}
+
+	if (count) {
+		int	doresched;
+
+		UNM_SPIN_LOCK(&adapter->tx_lock);
+		adapter->lastCmdConsumer = last_consumer;
+		adapter->freecmds += count;
+		membar_exit();
+
+		doresched = adapter->resched_needed;
+		if (doresched)
+			adapter->resched_needed = 0;
+
+		if (head != NULL)
+			unm_return_dma_handle(adapter, head, tail, free_hdls);
+
+		UNM_SPIN_UNLOCK(&adapter->tx_lock);
+
+		if (doresched)
+			mac_tx_update(adapter->mach);
+	}
+
+	(void) ddi_dma_sync(adapter->ctxDesc_dma_handle, sizeof (RingContext),
+	    sizeof (uint32_t), DDI_DMA_SYNC_FORCPU);
+
+	consumer = *(adapter->cmdConsumer);
+	done = (adapter->lastCmdConsumer == consumer);
+
+	return (done);
+}
+
+/*
+ * This is invoked from receive isr, and at initialization time when no
+ * rx buffers have been posted to card. Due to the single threaded nature
+ * of the invocation, pool_lock acquisition is not neccesary to protect
+ * pool_list.
+ */
+static unm_rx_buffer_t *
+unm_reserve_rx_buffer(unm_rcv_desc_ctx_t *rcv_desc)
+{
+	unm_rx_buffer_t *rx_buffer = NULL;
+
+	/* mutex_enter(rcv_desc->pool_lock); */
+	if (rcv_desc->rx_buf_free) {
+		rx_buffer = rcv_desc->pool_list;
+		rcv_desc->pool_list = rx_buffer->next;
+		rx_buffer->next = NULL;
+		rcv_desc->rx_buf_free--;
+	} else {
+		mutex_enter(rcv_desc->recycle_lock);
+
+		if (rcv_desc->rx_buf_recycle) {
+			rcv_desc->pool_list = rcv_desc->recycle_list;
+			rcv_desc->recycle_list = NULL;
+			rcv_desc->rx_buf_free += rcv_desc->rx_buf_recycle;
+			rcv_desc->rx_buf_recycle = 0;
+
+			rx_buffer = rcv_desc->pool_list;
+			rcv_desc->pool_list = rx_buffer->next;
+			rx_buffer->next = NULL;
+			rcv_desc->rx_buf_free--;
+		}
+
+		mutex_exit(rcv_desc->recycle_lock);
+	}
+
+	/* mutex_exit(rcv_desc->pool_lock); */
+	return (rx_buffer);
+}
+
+static void
+post_rx_doorbell(struct unm_adapter_s *adapter, uint32_t ringid, int count)
+{
+#define	UNM_RCV_PEG_DB_ID	2
+#define	UNM_RCV_PRODUCER_OFFSET	0
+	ctx_msg msg = {0};
+
+	/*
+	 * Write a doorbell msg to tell phanmon of change in
+	 * receive ring producer
+	 */
+	msg.PegId = UNM_RCV_PEG_DB_ID;
+	msg.privId = 1;
+	msg.Count = count;
+	msg.CtxId = adapter->portnum;
+	msg.Opcode = UNM_RCV_PRODUCER(ringid);
+	dbwritel(*((__uint32_t *)&msg),
+	    (void *)(DB_NORMALIZE(adapter, UNM_RCV_PRODUCER_OFFSET)));
+}
+
+static int
+unm_post_rx_buffers(struct unm_adapter_s *adapter, uint32_t ringid)
+{
+	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
+	unm_rcv_desc_ctx_t	*rcv_desc = &recv_ctx->rcv_desc[ringid];
+	unm_rx_buffer_t		*rx_buffer;
+	rcvDesc_t		*pdesc;
+	int			count;
+
+	for (count = 0; count < rcv_desc->MaxRxDescCount; count++) {
+		rx_buffer = unm_reserve_rx_buffer(rcv_desc);
+		if (rx_buffer != NULL) {
+			pdesc = &rcv_desc->desc_head[count];
+			pdesc->referenceHandle = rxbuf2index(rcv_desc,
+			    rx_buffer);
+			pdesc->flags = ringid;
+			pdesc->bufferLength = rcv_desc->dma_size;
+			pdesc->AddrBuffer = rx_buffer->dma_info.dma_addr;
+		}
+		else
+			return (DDI_FAILURE);
+	}
+
+	rcv_desc->producer = count % rcv_desc->MaxRxDescCount;
+	count--;
+	unm_desc_dma_sync(rcv_desc->rx_desc_dma_handle,
+	    0,		/* start */
+	    count,	/* count */
+	    count,	/* range */
+	    sizeof (rcvDesc_t),	/* unit_size */
+	    DDI_DMA_SYNC_FORDEV);	/* direction */
+
+	rcv_desc->rx_buf_card = rcv_desc->MaxRxDescCount;
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	adapter->unm_nic_hw_write_wx(adapter, rcv_desc->host_rx_producer,
+	    &count, 4);
+	if (adapter->fw_major < 4)
+		post_rx_doorbell(adapter, ringid, count);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	return (DDI_SUCCESS);
+}
+
+static void
+unm_post_rx_buffers_nodb(struct unm_adapter_s *adapter,
+    uint32_t ringid)
+{
+	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
+	unm_rcv_desc_ctx_t	*rcv_desc = &recv_ctx->rcv_desc[ringid];
+	struct unm_rx_buffer	*rx_buffer;
+	rcvDesc_t		*pdesc;
+	int 			count, producer = rcv_desc->producer;
+	int 			last_producer = producer;
+
+	for (count = 0; count < rcv_desc->rx_desc_handled; count++) {
+		rx_buffer = unm_reserve_rx_buffer(rcv_desc);
+		if (rx_buffer != NULL) {
+			pdesc = &rcv_desc->desc_head[producer];
+			pdesc->referenceHandle = rxbuf2index(rcv_desc,
+			    rx_buffer);
+			pdesc->flags = ringid;
+			pdesc->bufferLength = rcv_desc->dma_size;
+			pdesc->AddrBuffer = rx_buffer->dma_info.dma_addr;
+		} else {
+			adapter->stats.outofrxbuf++;
+			break;
+		}
+		producer = get_next_index(producer, rcv_desc->MaxRxDescCount);
+	}
+
+	/* if we did allocate buffers, then write the count to Phantom */
+	if (count) {
+		/* Sync rx ring, considering case for wrap around */
+		unm_desc_dma_sync(rcv_desc->rx_desc_dma_handle, last_producer,
+		    count, rcv_desc->MaxRxDescCount, sizeof (rcvDesc_t),
+		    DDI_DMA_SYNC_FORDEV);
+
+		rcv_desc->producer = producer;
+		rcv_desc->rx_desc_handled -= count;
+		rcv_desc->rx_buf_card += count;
+
+		producer = (producer - 1) % rcv_desc->MaxRxDescCount;
+		UNM_READ_LOCK(&adapter->adapter_lock);
+		adapter->unm_nic_hw_write_wx(adapter,
+		    rcv_desc->host_rx_producer, &producer, 4);
+		UNM_READ_UNLOCK(&adapter->adapter_lock);
+	}
+}
+
+int
+unm_nic_fill_statistics_128M(struct unm_adapter_s *adapter,
+			    struct unm_statistics *unm_stats)
+{
+	void *addr;
+	if (adapter->ahw.board_type == UNM_NIC_XGBE) {
+		UNM_WRITE_LOCK(&adapter->adapter_lock);
+		unm_nic_pci_change_crbwindow_128M(adapter, 0);
+
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_TX_BYTE_CNT,
+		    &(unm_stats->tx_bytes));
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_TX_FRAME_CNT,
+		    &(unm_stats->tx_packets));
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_RX_BYTE_CNT,
+		    &(unm_stats->rx_bytes));
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_RX_FRAME_CNT,
+		    &(unm_stats->rx_packets));
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_AGGR_ERROR_CNT,
+		    &(unm_stats->rx_errors));
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_CRC_ERROR_CNT,
+		    &(unm_stats->rx_CRC_errors));
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_OVERSIZE_FRAME_ERR,
+		    &(unm_stats->rx_long_length_error));
+		/* LINTED: E_FALSE_LOGICAL_EXPR */
+		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_UNDERSIZE_FRAME_ERR,
+		    &(unm_stats->rx_short_length_error));
+
+		/*
+		 * For reading rx_MAC_error bit different procedure
+		 * UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_TEST_MUX_CTL, 0x15);
+		 * UNM_NIC_LOCKED_READ_REG((UNM_CRB_NIU + 0xC0), &temp);
+		 * unm_stats->rx_MAC_errors = temp & 0xff;
+		 */
+
+		unm_nic_pci_change_crbwindow_128M(adapter, 1);
+		UNM_WRITE_UNLOCK(&adapter->adapter_lock);
+	} else {
+		UNM_SPIN_LOCK_ISR(&adapter->tx_lock);
+		unm_stats->tx_bytes = adapter->stats.txbytes;
+		unm_stats->tx_packets = adapter->stats.xmitedframes +
+		    adapter->stats.xmitfinished;
+		unm_stats->rx_bytes = adapter->stats.rxbytes;
+		unm_stats->rx_packets = adapter->stats.no_rcv;
+		unm_stats->rx_errors = adapter->stats.rcvdbadmsg;
+		unm_stats->tx_errors = adapter->stats.nocmddescriptor;
+		unm_stats->rx_short_length_error = adapter->stats.uplcong;
+		unm_stats->rx_long_length_error = adapter->stats.uphcong;
+		unm_stats->rx_CRC_errors = 0;
+		unm_stats->rx_MAC_errors = 0;
+		UNM_SPIN_UNLOCK_ISR(&adapter->tx_lock);
+	}
+	return (0);
+}
+
+int
+unm_nic_fill_statistics_2M(struct unm_adapter_s *adapter,
+    struct unm_statistics *unm_stats)
+{
+	if (adapter->ahw.board_type == UNM_NIC_XGBE) {
+		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_TX_BYTE_CNT,
+		    &(unm_stats->tx_bytes), 4);
+		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_TX_FRAME_CNT,
+		    &(unm_stats->tx_packets), 4);
+		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_RX_BYTE_CNT,
+		    &(unm_stats->rx_bytes), 4);
+		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_RX_FRAME_CNT,
+		    &(unm_stats->rx_packets), 4);
+		(void) unm_nic_hw_read_wx_2M(adapter,
+		    UNM_NIU_XGE_AGGR_ERROR_CNT, &(unm_stats->rx_errors), 4);
+		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_CRC_ERROR_CNT,
+		    &(unm_stats->rx_CRC_errors), 4);
+		(void) unm_nic_hw_read_wx_2M(adapter,
+		    UNM_NIU_XGE_OVERSIZE_FRAME_ERR,
+		    &(unm_stats->rx_long_length_error), 4);
+		(void) unm_nic_hw_read_wx_2M(adapter,
+		    UNM_NIU_XGE_UNDERSIZE_FRAME_ERR,
+		    &(unm_stats->rx_short_length_error), 4);
+	} else {
+		UNM_SPIN_LOCK_ISR(&adapter->tx_lock);
+		unm_stats->tx_bytes = adapter->stats.txbytes;
+		unm_stats->tx_packets = adapter->stats.xmitedframes +
+		    adapter->stats.xmitfinished;
+		unm_stats->rx_bytes = adapter->stats.rxbytes;
+		unm_stats->rx_packets = adapter->stats.no_rcv;
+		unm_stats->rx_errors = adapter->stats.rcvdbadmsg;
+		unm_stats->tx_errors = adapter->stats.nocmddescriptor;
+		unm_stats->rx_short_length_error = adapter->stats.uplcong;
+		unm_stats->rx_long_length_error = adapter->stats.uphcong;
+		unm_stats->rx_CRC_errors = 0;
+		unm_stats->rx_MAC_errors = 0;
+		UNM_SPIN_UNLOCK_ISR(&adapter->tx_lock);
+	}
+	return (0);
+}
+
+int
+unm_nic_clear_statistics_128M(struct unm_adapter_s *adapter)
+{
+	void *addr;
+	int data = 0;
+
+	UNM_WRITE_LOCK(&adapter->adapter_lock);
+	unm_nic_pci_change_crbwindow_128M(adapter, 0);
+
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_TX_BYTE_CNT, &data);
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_TX_FRAME_CNT, &data);
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_RX_BYTE_CNT, &data);
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_RX_FRAME_CNT, &data);
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_AGGR_ERROR_CNT, &data);
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_CRC_ERROR_CNT, &data);
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_OVERSIZE_FRAME_ERR, &data);
+	/* LINTED: E_FALSE_LOGICAL_EXPR */
+	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_UNDERSIZE_FRAME_ERR, &data);
+
+	unm_nic_pci_change_crbwindow_128M(adapter, 1);
+	UNM_WRITE_UNLOCK(&adapter->adapter_lock);
+	unm_nic_clear_stats(adapter);
+	return (0);
+}
+
+int
+unm_nic_clear_statistics_2M(struct unm_adapter_s *adapter)
+{
+	int data = 0;
+
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_TX_BYTE_CNT,
+	    &data, 4);
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_TX_FRAME_CNT,
+	    &data, 4);
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_RX_BYTE_CNT,
+	    &data, 4);
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_RX_FRAME_CNT,
+	    &data, 4);
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_AGGR_ERROR_CNT,
+	    &data, 4);
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_CRC_ERROR_CNT,
+	    &data, 4);
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_OVERSIZE_FRAME_ERR,
+	    &data, 4);
+	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_UNDERSIZE_FRAME_ERR,
+	    &data, 4);
+	unm_nic_clear_stats(adapter);
+	return (0);
+}
+
+/*
+ * unm_nic_ioctl ()    We provide the tcl/phanmon support
+ * through these ioctls.
+ */
+static void
+unm_nic_ioctl(struct unm_adapter_s *adapter, int cmd, queue_t *q, mblk_t *mp)
+{
+	void *ptr;
+
+	switch (cmd) {
+	case UNM_NIC_CMD:
+		(void) unm_nic_do_ioctl(adapter, q, mp);
+		break;
+
+	case UNM_NIC_NAME:
+		ptr = (void *) mp->b_cont->b_rptr;
+
+		/*
+		 * Phanmon checks for "UNM-UNM" string
+		 * Replace the hardcoded value with appropriate macro
+		 */
+		DPRINTF(-1, (CE_CONT, "UNM_NIC_NAME ioctl executed %d %d\n",
+		    cmd, __LINE__));
+		(void) memcpy(ptr, "UNM-UNM", 10);
+		miocack(q, mp, 10, 0);
+		break;
+
+	default:
+		cmn_err(CE_WARN, "Netxen ioctl cmd %x not supported\n", cmd);
+
+		miocnak(q, mp, 0, EINVAL);
+		break;
+	}
+}
+
+int
+unm_nic_resume(unm_adapter *adapter)
+{
+
+	adapter->watchdog_timer = timeout((void (*)(void *))&unm_watchdog,
+	    (void *) adapter, 50000);
+
+	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
+		(void) ddi_intr_block_enable(&adapter->intr_handle, 1);
+	else
+		(void) ddi_intr_enable(adapter->intr_handle);
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	unm_nic_enable_int(adapter);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+
+	mac_link_update(adapter->mach, LINK_STATE_UP);
+
+	return (DDI_SUCCESS);
+}
+
+int
+unm_nic_suspend(unm_adapter *adapter)
+{
+	mac_link_update(adapter->mach, LINK_STATE_DOWN);
+
+	(void) untimeout(adapter->watchdog_timer);
+
+	UNM_READ_LOCK(&adapter->adapter_lock);
+	unm_nic_disable_int(adapter);
+	UNM_READ_UNLOCK(&adapter->adapter_lock);
+	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
+		(void) ddi_intr_block_disable(&adapter->intr_handle, 1);
+	else
+		(void) ddi_intr_disable(adapter->intr_handle);
+
+	return (DDI_SUCCESS);
+}
+
+static int
+unm_nic_do_ioctl(unm_adapter *adapter, queue_t *wq, mblk_t *mp)
+{
+	unm_nic_ioctl_data_t		data;
+	struct unm_nic_ioctl_data	*up_data;
+	ddi_acc_handle_t		conf_handle;
+	int				retval = 0;
+	unsigned int			efuse_chip_id;
+	char				*ptr1;
+	short				*ptr2;
+	int				*ptr4;
+
+	up_data = (struct unm_nic_ioctl_data *)(mp->b_cont->b_rptr);
+	(void) memcpy(&data, (void **)(uintptr_t)(mp->b_cont->b_rptr),
+	    sizeof (data));
+
+	/* Shouldn't access beyond legal limits of  "char u[64];" member */
+	if (data.size > sizeof (data.uabc)) {
+		/* evil user tried to crash the kernel */
+		cmn_err(CE_WARN, "bad size: %d\n", data.size);
+		retval = GLD_BADARG;
+		goto error_out;
+	}
+
+	switch (data.cmd) {
+	case unm_nic_cmd_pci_read:
+
+		if ((retval = adapter->unm_nic_hw_read_ioctl(adapter,
+		    data.off, up_data, data.size))) {
+			DPRINTF(-1, (CE_WARN, "%s(%d) unm_nic_hw_read_wx "
+		    "returned %d\n", __FUNCTION__, __LINE__, retval));
+
+			retval = data.rv;
+			goto error_out;
+		}
+
+		data.rv = 0;
+		break;
+
+	case unm_nic_cmd_pci_write:
+		if ((data.rv = adapter->unm_nic_hw_write_ioctl(adapter,
+		    data.off, &(data.uabc), data.size))) {
+			DPRINTF(-1, (CE_WARN, "%s(%d) unm_nic_hw_write_wx "
+			    "returned %d\n", __FUNCTION__,
+			    __LINE__, data.rv));
+			retval = data.rv;
+			goto error_out;
+		}
+		data.size = 0;
+		break;
+
+	case unm_nic_cmd_pci_mem_read:
+		if ((data.rv = adapter->unm_nic_pci_mem_read(adapter,
+		    data.off, up_data, data.size))) {
+			DPRINTF(-1, (CE_WARN, "%s(%d) unm_nic_pci_mem_read "
+			    "returned %d\n", __FUNCTION__,
+			    __LINE__, data.rv));
+			retval = data.rv;
+			goto error_out;
+		}
+		data.rv = 0;
+		break;
+
+	case unm_nic_cmd_pci_mem_write:
+		if ((data.rv = adapter->unm_nic_pci_mem_write(adapter,
+		    data.off, &(data.uabc), data.size))) {
+			DPRINTF(-1, (CE_WARN,
+			    "%s(%d) unm_nic_cmd_pci_mem_write "
+			    "returned %d\n",
+			    __FUNCTION__, __LINE__, data.rv));
+			retval = data.rv;
+			goto error_out;
+		}
+
+		data.size = 0;
+		data.rv = 0;
+		break;
+
+	case unm_nic_cmd_pci_config_read:
+
+		if (adapter->pci_cfg_handle != NULL) {
+			conf_handle = adapter->pci_cfg_handle;
+
+		} else if ((retval = pci_config_setup(adapter->dip,
+		    &conf_handle)) != DDI_SUCCESS) {
+			DPRINTF(-1, (CE_WARN, "!%s: pci_config_setup failed"
+			    " error:%d\n", unm_nic_driver_name, retval));
+			goto error_out;
+
+		} else
+			adapter->pci_cfg_handle = conf_handle;
+
+		switch (data.size) {
+		case 1:
+			ptr1 = (char *)up_data;
+			*ptr1 = (char)pci_config_get8(conf_handle, data.off);
+			break;
+		case 2:
+			ptr2 = (short *)up_data;
+			*ptr2 = (short)pci_config_get16(conf_handle, data.off);
+			break;
+		case 4:
+			ptr4 = (int *)up_data;
+			*ptr4 = (int)pci_config_get32(conf_handle, data.off);
+			break;
+		}
+
+		break;
+
+	case unm_nic_cmd_pci_config_write:
+
+		if (adapter->pci_cfg_handle != NULL) {
+			conf_handle = adapter->pci_cfg_handle;
+		} else if ((retval = pci_config_setup(adapter->dip,
+		    &conf_handle)) != DDI_SUCCESS) {
+			DPRINTF(-1, (CE_WARN, "!%s: pci_config_setup failed"
+			    " error:%d\n", unm_nic_driver_name, retval));
+			goto error_out;
+		} else {
+			adapter->pci_cfg_handle = conf_handle;
+		}
+
+		switch (data.size) {
+		case 1:
+			pci_config_put8(conf_handle,
+			    data.off, *(char *)&(data.uabc));
+			break;
+		case 2:
+			pci_config_put16(conf_handle,
+			    data.off, *(short *)(uintptr_t)&(data.uabc));
+			break;
+		case 4:
+			pci_config_put32(conf_handle,
+			    data.off, *(u32 *)(uintptr_t)&(data.uabc));
+			break;
+		}
+		data.size = 0;
+		break;
+
+	case unm_nic_cmd_get_stats:
+		data.rv = adapter->unm_nic_fill_statistics(adapter,
+		    (struct unm_statistics *)up_data);
+		data.size = sizeof (struct unm_statistics);
+
+		break;
+
+	case unm_nic_cmd_clear_stats:
+		data.rv = adapter->unm_nic_clear_statistics(adapter);
+		break;
+
+	case unm_nic_cmd_get_version:
+		(void) memcpy(up_data, UNM_NIC_VERSIONID,
+		    sizeof (UNM_NIC_VERSIONID));
+		data.size = sizeof (UNM_NIC_VERSIONID);
+
+		break;
+
+	case unm_nic_cmd_get_phy_type:
+		cmn_err(CE_WARN, "unm_nic_cmd_get_phy_type unimplemented\n");
+		break;
+
+	case unm_nic_cmd_efuse_chip_id:
+		efuse_chip_id = adapter->unm_nic_pci_read_normalize(adapter,
+		    UNM_EFUSE_CHIP_ID);
+		(void) memcpy(up_data, &efuse_chip_id, sizeof (unsigned long));
+		data.rv = 0;
+		break;
+
+	default:
+		cmn_err(CE_WARN, "%s%d: bad command %d\n", adapter->name,
+		    adapter->instance, data.cmd);
+		data.rv = GLD_NOTSUPPORTED;
+		data.size = 0;
+		goto error_out;
+	}
+
+work_done:
+	miocack(wq, mp, data.size, data.rv);
+	return (DDI_SUCCESS);
+
+error_out:
+	cmn_err(CE_WARN, "%s(%d) ioctl error\n", __FUNCTION__, data.cmd);
+	miocnak(wq, mp, 0, EINVAL);
+	return (retval);
+}
+
+/*
+ * Local datatype for defining tables of (Offset, Name) pairs
+ */
+typedef struct {
+	offset_t	index;
+	char		*name;
+} unm_ksindex_t;
+
+static const unm_ksindex_t unm_kstat[] = {
+	{ 0,		"freehdls"		},
+	{ 1,		"freecmds"		},
+	{ 2,		"tx_bcopy_threshold"	},
+	{ 3,		"rx_bcopy_threshold"	},
+	{ 4,		"xmitcalled"		},
+	{ 5,		"xmitedframes"		},
+	{ 6,		"xmitfinished"		},
+	{ 7,		"txbytes"		},
+	{ 8,		"txcopyed"		},
+	{ 9,		"txmapped"		},
+	{ 10,		"outoftxdmahdl"		},
+	{ 11,		"outofcmddesc"		},
+	{ 12,		"txdropped"		},
+	{ 13,		"polled"		},
+	{ 14,		"uphappy"		},
+	{ 15,		"updropped"		},
+	{ 16,		"csummed"		},
+	{ 17,		"no_rcv"		},
+	{ 18,		"rxbytes"		},
+	{ 19,		"rxcopyed"		},
+	{ 20,		"rxmapped"		},
+	{ 21,		"desballocfailed"	},
+	{ 22,		"outofrxbuf"		},
+	{ 23,		"promiscmode"		},
+	{ 24,		"rxbufshort"		},
+	{ 25,		"allocbfailed"		},
+	{ -1,		NULL			}
+};
+
+static int
+unm_kstat_update(kstat_t *ksp, int flag)
+{
+	unm_adapter *adapter;
+	kstat_named_t *knp;
+
+	if (flag != KSTAT_READ)
+		return (EACCES);
+
+	adapter = ksp->ks_private;
+	knp = ksp->ks_data;
+
+	(knp++)->value.ui32 = adapter->freehdls;
+	(knp++)->value.ui64 = adapter->freecmds;
+	(knp++)->value.ui64 = adapter->tx_bcopy_threshold;
+	(knp++)->value.ui64 = adapter->rx_bcopy_threshold;
+
+	(knp++)->value.ui64 = adapter->stats.xmitcalled;
+	(knp++)->value.ui64 = adapter->stats.xmitedframes;
+	(knp++)->value.ui64 = adapter->stats.xmitfinished;
+	(knp++)->value.ui64 = adapter->stats.txbytes;
+	(knp++)->value.ui64 = adapter->stats.txcopyed;
+	(knp++)->value.ui64 = adapter->stats.txmapped;
+	(knp++)->value.ui64 = adapter->stats.outoftxdmahdl;
+	(knp++)->value.ui64 = adapter->stats.outofcmddesc;
+	(knp++)->value.ui64 = adapter->stats.txdropped;
+	(knp++)->value.ui64 = adapter->stats.polled;
+	(knp++)->value.ui64 = adapter->stats.uphappy;
+	(knp++)->value.ui64 = adapter->stats.updropped;
+	(knp++)->value.ui64 = adapter->stats.csummed;
+	(knp++)->value.ui64 = adapter->stats.no_rcv;
+	(knp++)->value.ui64 = adapter->stats.rxbytes;
+	(knp++)->value.ui64 = adapter->stats.rxcopyed;
+	(knp++)->value.ui64 = adapter->stats.rxmapped;
+	(knp++)->value.ui64 = adapter->stats.desballocfailed;
+	(knp++)->value.ui64 = adapter->stats.outofrxbuf;
+	(knp++)->value.ui64 = adapter->stats.promiscmode;
+	(knp++)->value.ui64 = adapter->stats.rxbufshort;
+	(knp++)->value.ui64 = adapter->stats.allocbfailed;
+
+	return (0);
+}
+
+static kstat_t *
+unm_setup_named_kstat(unm_adapter *adapter, int instance, char *name,
+	const unm_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
+{
+	kstat_t *ksp;
+	kstat_named_t *knp;
+	char *np;
+	int type;
+	int count = 0;
+
+	size /= sizeof (unm_ksindex_t);
+	ksp = kstat_create(unm_nic_driver_name, instance, name, "net",
+	    KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
+	if (ksp == NULL)
+		return (NULL);
+
+	ksp->ks_private = adapter;
+	ksp->ks_update = update;
+	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
+		count++;
+		switch (*np) {
+		default:
+			type = KSTAT_DATA_UINT64;
+			break;
+		case '%':
+			np += 1;
+			type = KSTAT_DATA_UINT32;
+			break;
+		case '$':
+			np += 1;
+			type = KSTAT_DATA_STRING;
+			break;
+		case '&':
+			np += 1;
+			type = KSTAT_DATA_CHAR;
+			break;
+		}
+		kstat_named_init(knp, np, type);
+	}
+	kstat_install(ksp);
+
+	return (ksp);
+}
+
+void
+unm_init_kstats(unm_adapter* adapter, int instance)
+{
+	adapter->kstats[0] = unm_setup_named_kstat(adapter,
+	    instance, "kstatinfo", unm_kstat,
+	    sizeof (unm_kstat), unm_kstat_update);
+}
+
+void
+unm_fini_kstats(unm_adapter* adapter)
+{
+
+	if (adapter->kstats[0] != NULL) {
+			kstat_delete(adapter->kstats[0]);
+			adapter->kstats[0] = NULL;
+		}
+}
+
+static int
+unm_nic_set_pauseparam(unm_adapter *adapter, unm_pauseparam_t *pause)
+{
+	int ret = 0;
+
+	if (adapter->ahw.board_type == UNM_NIC_GBE) {
+		if (unm_niu_gbe_set_rx_flow_ctl(adapter, pause->rx_pause))
+			ret = -EIO;
+
+		if (unm_niu_gbe_set_tx_flow_ctl(adapter, pause->tx_pause))
+			ret = -EIO;
+
+	} else if (adapter->ahw.board_type == UNM_NIC_XGBE) {
+		if (unm_niu_xg_set_tx_flow_ctl(adapter, pause->tx_pause))
+			ret =  -EIO;
+	} else
+		ret = -EIO;
+
+	return (ret);
+}
+
+/*
+ *
+ * GLD/MAC interfaces
+ *
+ */
+
+static int
+ntxn_m_start(void *arg)
+{
+	unm_adapter	*adapter = arg;
+	int		ring;
+
+	UNM_SPIN_LOCK(&adapter->lock);
+	if (adapter->is_up == UNM_ADAPTER_UP_MAGIC) {
+		UNM_SPIN_UNLOCK(&adapter->lock);
+		return (DDI_SUCCESS);
+	}
+
+	if (init_firmware(adapter) != DDI_SUCCESS) {
+		UNM_SPIN_UNLOCK(&adapter->lock);
+		cmn_err(CE_WARN, "%s%d: Failed to init firmware\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	unm_nic_clear_stats(adapter);
+
+	if (unm_nic_hw_resources(adapter) != 0) {
+		UNM_SPIN_UNLOCK(&adapter->lock);
+		cmn_err(CE_WARN, "%s%d: Error setting hw resources\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	if (adapter->fw_major < 4) {
+		adapter->crb_addr_cmd_producer =
+		    crb_cmd_producer[adapter->portnum];
+		adapter->crb_addr_cmd_consumer =
+		    crb_cmd_consumer[adapter->portnum];
+		unm_nic_update_cmd_producer(adapter, 0);
+		unm_nic_update_cmd_consumer(adapter, 0);
+	}
+
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		if (unm_post_rx_buffers(adapter, ring) != DDI_SUCCESS) {
+			/* TODO: clean up */
+			UNM_SPIN_UNLOCK(&adapter->lock);
+			return (DDI_FAILURE);
+		}
+	}
+
+	if (unm_nic_macaddr_set(adapter, adapter->mac_addr) != 0) {
+		UNM_SPIN_UNLOCK(&adapter->lock);
+		cmn_err(CE_WARN, "%s%d: Could not set mac address\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	if (unm_nic_init_port(adapter) != 0) {
+		UNM_SPIN_UNLOCK(&adapter->lock);
+		cmn_err(CE_WARN, "%s%d: Could not initialize port\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	unm_nic_set_link_parameters(adapter);
+
+	/*
+	 * P2 and P3 should be handled similarly.
+	 */
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		if (unm_nic_set_promisc_mode(adapter) != 0) {
+			UNM_SPIN_UNLOCK(&adapter->lock);
+			cmn_err(CE_WARN, "%s%d: Could not set promisc mode\n",
+			    adapter->name, adapter->instance);
+			return (DDI_FAILURE);
+		}
+	} else {
+		nx_p3_nic_set_multi(adapter);
+	}
+	adapter->stats.promiscmode = 1;
+
+	if (unm_nic_set_mtu(adapter, adapter->mtu) != 0) {
+		UNM_SPIN_UNLOCK(&adapter->lock);
+		cmn_err(CE_WARN, "%s%d: Could not set mtu\n",
+		    adapter->name, adapter->instance);
+		return (DDI_FAILURE);
+	}
+
+	adapter->watchdog_timer = timeout((void (*)(void *))&unm_watchdog,
+	    (void *)adapter, 0);
+
+	adapter->is_up = UNM_ADAPTER_UP_MAGIC;
+
+	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
+		(void) ddi_intr_block_enable(&adapter->intr_handle, 1);
+	else
+		(void) ddi_intr_enable(adapter->intr_handle);
+	unm_nic_enable_int(adapter);
+
+	UNM_SPIN_UNLOCK(&adapter->lock);
+	return (GLD_SUCCESS);
+}
+
+
+/*
+ * This code is kept here for reference so as to
+ * see if something different is required to be done
+ * in GLDV3. This will be deleted later.
+ */
+/* ARGSUSED */
+static void
+ntxn_m_stop(void *arg)
+{
+}
+
+/*ARGSUSED*/
+static int
+ntxn_m_multicst(void *arg, boolean_t add, const uint8_t *ep)
+{
+	/*
+	 * When we correctly implement this, invoke nx_p3_nic_set_multi()
+	 * or nx_p2_nic_set_multi() here.
+	 */
+	return (GLD_SUCCESS);
+}
+
+/*ARGSUSED*/
+static int
+ntxn_m_promisc(void *arg, boolean_t on)
+{
+#if 0
+	int err = 0;
+	struct unm_adapter_s *adapter = arg;
+
+	err = on ? unm_nic_set_promisc_mode(adapter) :
+	    unm_nic_unset_promisc_mode(adapter);
+
+	if (err)
+		return (GLD_FAILURE);
+#endif
+
+	return (GLD_SUCCESS);
+}
+
+static int
+ntxn_m_stat(void *arg, uint_t stat, uint64_t *val)
+{
+	struct unm_adapter_s		*adapter = arg;
+	struct unm_adapter_stats	*portstat = &adapter->stats;
+
+	switch (stat) {
+	case MAC_STAT_IFSPEED:
+		if (adapter->ahw.board_type == UNM_NIC_XGBE) {
+			/* 10 Gigs */
+			*val = 10000000000ULL;
+		} else {
+			/* 1 Gig */
+			*val = 1000000000;
+		}
+		break;
+
+	case MAC_STAT_MULTIRCV:
+		*val = 0;
+		break;
+
+	case MAC_STAT_BRDCSTRCV:
+	case MAC_STAT_BRDCSTXMT:
+		*val = 0;
+		break;
+
+	case MAC_STAT_NORCVBUF:
+		*val = portstat->updropped;
+		break;
+
+	case MAC_STAT_NOXMTBUF:
+		*val = portstat->txdropped;
+		break;
+
+	case MAC_STAT_RBYTES:
+		*val = portstat->rxbytes;
+		break;
+
+	case MAC_STAT_OBYTES:
+		*val = portstat->txbytes;
+		break;
+
+	case MAC_STAT_OPACKETS:
+		*val = portstat->xmitedframes;
+		break;
+
+	case MAC_STAT_IPACKETS:
+		*val = portstat->uphappy;
+		break;
+
+	case MAC_STAT_OERRORS:
+		*val = portstat->xmitcalled - portstat->xmitedframes;
+		break;
+
+	case ETHER_STAT_LINK_DUPLEX:
+		*val = LINK_DUPLEX_FULL;
+		break;
+
+	default:
+		/*
+		 * Shouldn't reach here...
+		 */
+		*val = 0;
+		DPRINTF(0, (CE_WARN, ": unrecognized parameter = %d, value "
+		    "returned 1\n", stat));
+
+	}
+
+	return (0);
+}
+
+static int
+ntxn_m_unicst(void *arg, const uint8_t *mac)
+{
+	struct unm_adapter_s *adapter = arg;
+
+	DPRINTF(-1, (CE_CONT, "%s: called\n", __func__));
+
+	if (unm_nic_macaddr_set(adapter, (uint8_t *)mac))
+		return (EAGAIN);
+	bcopy(mac, adapter->mac_addr, ETHERADDRL);
+
+	return (0);
+}
+
+static mblk_t *
+ntxn_m_tx(void *arg, mblk_t *mp)
+{
+	unm_adapter *adapter = arg;
+	mblk_t *next;
+
+	while (mp != NULL) {
+		next = mp->b_next;
+		mp->b_next = NULL;
+
+		if (unm_nic_xmit_frame(adapter, mp) != B_TRUE) {
+			mp->b_next = next;
+			break;
+		}
+		mp = next;
+		adapter->stats.xmitedframes++;
+	}
+
+	return (mp);
+}
+
+static void
+ntxn_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
+{
+	int		cmd;
+	struct iocblk   *iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
+	struct unm_adapter_s *adapter = (struct unm_adapter_s *)arg;
+	enum ioc_reply status = IOC_DONE;
+
+	iocp->ioc_error = 0;
+	cmd = iocp->ioc_cmd;
+
+	if (cmd == ND_GET || cmd == ND_SET) {
+		status = unm_nd_ioctl(adapter, wq, mp, iocp);
+		switch (status) {
+		default:
+		case IOC_INVAL:
+			miocnak(wq, mp, 0, iocp->ioc_error == 0 ?
+			    EINVAL : iocp->ioc_error);
+			break;
+
+		case IOC_DONE:
+			break;
+
+		case IOC_RESTART_ACK:
+		case IOC_ACK:
+			miocack(wq, mp, 0, 0);
+			break;
+
+		case IOC_RESTART_REPLY:
+		case IOC_REPLY:
+			mp->b_datap->db_type = iocp->ioc_error == 0 ?
+			    M_IOCACK : M_IOCNAK;
+			qreply(wq, mp);
+			break;
+		}
+	} else if (cmd <= UNM_NIC_NAME && cmd >= UNM_CMD_START) {
+		unm_nic_ioctl(adapter, cmd, wq, mp);
+		return;
+	} else {
+		miocnak(wq, mp, 0, EINVAL);
+		return;
+	}
+}
+
+/* ARGSUSED */
+static boolean_t
+ntxn_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
+{
+	switch (cap) {
+	case MAC_CAPAB_HCKSUM:
+		{
+			uint32_t *txflags = cap_data;
+
+			*txflags = (HCKSUM_ENABLE |
+			    HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM);
+		}
+		break;
+
+	case MAC_CAPAB_POLL:
+	case MAC_CAPAB_MULTIADDRESS:
+	default:
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+#define	NETXEN_M_CALLBACK_FLAGS	(MC_IOCTL | MC_GETCAPAB)
+
+static mac_callbacks_t ntxn_m_callbacks = {
+	NETXEN_M_CALLBACK_FLAGS,
+	ntxn_m_stat,
+	ntxn_m_start,
+	ntxn_m_stop,
+	ntxn_m_promisc,
+	ntxn_m_multicst,
+	ntxn_m_unicst,
+	ntxn_m_tx,
+	NULL,			/* mc_resources */
+	ntxn_m_ioctl,
+	ntxn_m_getcapab,
+	NULL,			/* mc_open */
+	NULL,			/* mc_close */
+	NULL,			/* mc_setprop */
+	NULL			/* mc_getprop */
+};
+
+int
+unm_register_mac(unm_adapter *adapter)
+{
+	int ret;
+	mac_register_t *macp;
+	unm_pauseparam_t pause;
+
+	dev_info_t *dip = adapter->dip;
+
+	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
+		cmn_err(CE_WARN, "Memory not available\n");
+		return (DDI_FAILURE);
+	}
+
+	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
+	macp->m_driver = adapter;
+	macp->m_dip = dip;
+	macp->m_instance = adapter->instance;
+	macp->m_src_addr = adapter->mac_addr;
+	macp->m_callbacks = &ntxn_m_callbacks;
+	macp->m_min_sdu = 0;
+	macp->m_max_sdu = adapter->mtu;
+#ifdef SOLARIS11
+	macp->m_margin = VLAN_TAGSZ;
+#endif /* SOLARIS11 */
+
+	ret = mac_register(macp, &adapter->mach);
+	mac_free(macp);
+	if (ret != 0) {
+		cmn_err(CE_WARN, "mac_register failed for port %d\n",
+		    adapter->portnum);
+		return (DDI_FAILURE);
+	}
+
+	unm_init_kstats(adapter, adapter->instance);
+
+	/* Register NDD-tweakable parameters */
+	if (unm_nd_init(adapter)) {
+		cmn_err(CE_WARN, "unm_nd_init() failed");
+		return (DDI_FAILURE);
+	}
+
+	pause.rx_pause = adapter->nd_params[PARAM_ADV_PAUSE_CAP].ndp_val;
+	pause.tx_pause = adapter->nd_params[PARAM_ADV_ASYM_PAUSE_CAP].ndp_val;
+
+	if (unm_nic_set_pauseparam(adapter, &pause)) {
+		cmn_err(CE_WARN, "\nBad Pause settings RX %d, Tx %d",
+		    pause.rx_pause, pause.tx_pause);
+	}
+	adapter->nd_params[PARAM_PAUSE_CAP].ndp_val = pause.rx_pause;
+	adapter->nd_params[PARAM_ASYM_PAUSE_CAP].ndp_val = pause.tx_pause;
+
+	return (DDI_SUCCESS);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/ntxn/unm_version.h	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,31 @@
+/*
+ * 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 2008 NetXen, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _UNM_VERSION_H
+#define	_UNM_VERSION_H
+#define	UNM_NIC_VERSIONID	"4.0.219"
+#define	_UNM_NIC_MAJOR		4
+#define	_UNM_NIC_MINOR		0
+#define	_UNM_NIC_SUBVERSION	219
+#endif /* !_UNM_VERSION_H */
--- a/usr/src/uts/intel/Makefile.intel.shared	Tue Oct 28 09:59:16 2008 +0800
+++ b/usr/src/uts/intel/Makefile.intel.shared	Tue Oct 28 10:06:13 2008 +0800
@@ -203,6 +203,7 @@
 DRV_KMODS	+= bscbus
 DRV_KMODS	+= bscv
 DRV_KMODS	+= chxge
+DRV_KMODS	+= ntxn
 DRV_KMODS	+= clone
 DRV_KMODS	+= cmdk
 DRV_KMODS	+= cn
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/ntxn/Makefile	Tue Oct 28 10:06:13 2008 +0800
@@ -0,0 +1,95 @@
+#
+# 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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+#	This makefile drives the production of the Neterion Xframe
+#	10G Ethernet (XGE) driver module in x86 systems
+#
+
+#
+#	Paths to the base of the uts directory trees
+#
+UTSBASE   = ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= ntxn
+OBJECTS		= $(NTXN_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(NTXN_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_DRV_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+
+
+CFLAGS		+=  -DSOLARIS11 -xO4
+CFLAGS64	+=  -DSOLARIS11 -xO -I./
+
+#
+#	Driver depends on MAC & IP
+#
+LDFLAGS		+=  -dy -N misc/mac -N drv/ip
+
+#	Lint flag
+#
+LINTFLAGS	+= $(NTXN_DFLAGS) $(NTXN_KFLAGS)
+LINTFLAGS	+= -DSOLARIS11
+
+#
+#
+#	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)/intel/Makefile.targ