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