diff options
author | Garrett D'Amore <gdamore@opensolaris.org> | 2010-01-07 17:13:33 -0800 |
---|---|---|
committer | Garrett D'Amore <gdamore@opensolaris.org> | 2010-01-07 17:13:33 -0800 |
commit | bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2eb (patch) | |
tree | 47073d015f4a6d1ec6d0893a8c3b1502f78ac422 /usr/src | |
parent | df8eb1c6f8abc69ad7de0e40e0ea573eb3000b0b (diff) | |
download | illumos-gate-bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2eb.tar.gz |
6848310 rtls modernization
6913614 remove rtls warning for pci1186,1300 (and support it properly)
6913806 rtls copyrights and licenses wrong
6914292 rtls does not check suspended flag in interrupt routine
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/pkgdefs/SUNWrtls/Makefile | 33 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWrtls/depend | 31 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWrtls/postinstall | 110 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWrtls/postinstall.tmpl (renamed from usr/src/uts/common/io/rtls/rtls.conf) | 17 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWrtls/postremove | 18 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWrtls/preremove.tmpl | 28 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWrtls/prototype_com | 27 | ||||
-rw-r--r-- | usr/src/uts/common/Makefile.files | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/mii/mii.c | 1 | ||||
-rw-r--r-- | usr/src/uts/common/io/mii/mii_realtek.c | 117 | ||||
-rw-r--r-- | usr/src/uts/common/io/mii/miipriv.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/rtls/rtls.c | 656 | ||||
-rw-r--r-- | usr/src/uts/common/io/rtls/rtls.h | 22 | ||||
-rw-r--r-- | usr/src/uts/intel/rtls/Makefile | 7 | ||||
-rw-r--r-- | usr/src/uts/sparc/rtls/Makefile | 7 |
15 files changed, 400 insertions, 681 deletions
diff --git a/usr/src/pkgdefs/SUNWrtls/Makefile b/usr/src/pkgdefs/SUNWrtls/Makefile index 84714a95de..20525a6e11 100644 --- a/usr/src/pkgdefs/SUNWrtls/Makefile +++ b/usr/src/pkgdefs/SUNWrtls/Makefile @@ -1,19 +1,36 @@ # -# Copyright 2008 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] # -# ident "%Z%%M% %I% %E% SMI" +# CDDL HEADER END +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # include ../Makefile.com -DATAFILES += i.preserve -LICENSEFILES += $(OSBL) -CDDL= - .KEEP_STATE: -all: $(FILES) depend postinstall postremove +TMPLFILES += postinstall preremove +DATAFILES += depend + +all: $(FILES) postinstall install: all pkg include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWrtls/depend b/usr/src/pkgdefs/SUNWrtls/depend deleted file mode 100644 index dd84c2cf31..0000000000 --- a/usr/src/pkgdefs/SUNWrtls/depend +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This package information file defines software dependencies associated -# with the pkg. You can define three types of pkg dependencies with this file: -# P indicates a prerequisite for installation -# I indicates an incompatible package -# R indicates a reverse dependency -# <pkg.abbr> see pkginfo(4), PKG parameter -# <name> see pkginfo(4), NAME parameter -# <version> see pkginfo(4), VERSION parameter -# <arch> see pkginfo(4), ARCH parameter -# <type> <pkg.abbr> <name> -# (<arch>)<version> -# (<arch>)<version> -# ... -# <type> <pkg.abbr> <name> -# ... - -P SUNWcar Core Architecture, (Root) -P SUNWcakr Core Solaris Kernel Architecture (Root) -P SUNWkvm Core Architecture, (Kvm) -P SUNWcsr Core Solaris, (Root) -P SUNWckr Core Solaris Kernel (Root) -P SUNWcnetr Core Solaris Network Infrastructure (Root) -P SUNWcsu Core Solaris, (Usr) -P SUNWcsd Core Solaris Devices -P SUNWcsl Core Solaris Libraries -P SUNWcslr Core Solaris Libraries (Root) diff --git a/usr/src/pkgdefs/SUNWrtls/postinstall b/usr/src/pkgdefs/SUNWrtls/postinstall deleted file mode 100644 index e7546f053d..0000000000 --- a/usr/src/pkgdefs/SUNWrtls/postinstall +++ /dev/null @@ -1,110 +0,0 @@ -#!/sbin/sh -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -# Function: check_add_drv() -# -# This function will check if the module has an entry in etc/name_to_major -# If not simply calls add_drv with the arguments given. If there is -# such an entry in name_to_major file, it adds entries in driver_aliases -# driver_classes and minor_perm if necessary. -# The syntax of this function is the same as add_drv. - -check_add_drv() -{ - if [ "$BASEDIR" = "" ] - then - BASEDIR=/ - fi - alias="" - class="" - ADD_ALIAS=0 - ADD_CLASS=0 - ADD_MINOR=0 - OPTIND=1 - IS_NET_DRIVER=0 - - cmd="add_drv" - - NO_CMD= - while getopts i:b:m:c:N opt - do - case $opt in - N ) NO_CMD=1;; - i ) ADD_ALIAS=1 - alias=$OPTARG - cmd=$cmd" -i '$alias'" - ;; - m ) ADD_MINOR=1 - minor=$OPTARG - cmd=$cmd" -m '$minor'" - ;; - c) ADD_CLASS=1 - class=$OPTARG - cmd=$cmd" -c $class" - ;; - b) BASEDIR=$OPTARG - cmd=$cmd" -b $BASEDIR" - ;; - \?) echo "check_add_drv can not handle this option" - return - ;; - esac - done - shift `/usr/bin/expr $OPTIND - 1` - - drvname=$1 - - cmd=$cmd" "$drvname - - drvname=`echo $drvname | /usr/bin/sed 's;.*/;;g'` - - /usr/bin/grep "^$drvname[ ]" $BASEDIR/etc/name_to_major > /dev/null 2>&1 - - if [ "$NO_CMD" = "" -a $? -ne 0 ] - then - eval $cmd - else - # entry already in name_to_major, add alias, class, minorperm - # if necessary - if [ $ADD_ALIAS = 1 ] - then - for i in $alias - do - /usr/bin/egrep "^$drvname[ ]+$i" $BASEDIR/etc/driver_aliases>/dev/null 2>&1 - if [ $? -ne 0 ] - then - echo "$drvname $i" >> $BASEDIR/etc/driver_aliases - fi - done - fi - - if [ $ADD_CLASS = 1 ] - then - /usr/bin/egrep "^$drvname[ ]+$class( | |$)" $BASEDIR/etc/driver_classes > /dev/null 2>&1 - if [ $? -ne 0 ] - then - echo "$drvname\t$class" >> $BASEDIR/etc/driver_classes - fi - fi - - if [ $ADD_MINOR = 1 ] - then - /usr/bin/grep "^$drvname:" $BASEDIR/etc/minor_perm > /dev/null 2>&1 - if [ $? -ne 0 ] - then - minorentry="$drvname:$minor" - echo $minorentry >> $BASEDIR/etc/minor_perm - fi - fi - - fi - - -} - -check_add_drv -i '"pci10ec,8139" "pci1186,1301" "pci1113,1211"' -b "$BASEDIR" rtls diff --git a/usr/src/uts/common/io/rtls/rtls.conf b/usr/src/pkgdefs/SUNWrtls/postinstall.tmpl index 1de90dd9c6..eec55acf6e 100644 --- a/usr/src/uts/common/io/rtls/rtls.conf +++ b/usr/src/pkgdefs/SUNWrtls/postinstall.tmpl @@ -1,3 +1,4 @@ +#!/sbin/sh # # CDDL HEADER START # @@ -18,17 +19,13 @@ # # CDDL HEADER END # -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Driver.conf file for the RealTek 8139 chip +include drv_utils + +pkg_drvadd -i \ + '"pci10ec,8139" "pci1186,1300" "pci1186,1301" "pci1113,1211"' \ + -m '* 0666 root sys' rtls || exit 1 -# ForceSpeedDuplex: set nic speed and duplex mode -# 5: auto-negotiate -# 4: 100 FDX -# 3: 100 HDX -# 2: 10 FDX -# 1: 10 HDX -ForceSpeedDuplex=5,5,5,5,5,5; diff --git a/usr/src/pkgdefs/SUNWrtls/postremove b/usr/src/pkgdefs/SUNWrtls/postremove deleted file mode 100644 index 1937710994..0000000000 --- a/usr/src/pkgdefs/SUNWrtls/postremove +++ /dev/null @@ -1,18 +0,0 @@ -#!/sbin/sh -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -BD=${BASEDIR:-/} -if grep -w rtls $BD/etc/name_to_major > /dev/null 2>&1 -then - rem_drv -b ${BD} rtls - if [ $? -ne 0 ] - then - exit 1 - fi -fi -exit 0 diff --git a/usr/src/pkgdefs/SUNWrtls/preremove.tmpl b/usr/src/pkgdefs/SUNWrtls/preremove.tmpl new file mode 100644 index 0000000000..d74fe7919c --- /dev/null +++ b/usr/src/pkgdefs/SUNWrtls/preremove.tmpl @@ -0,0 +1,28 @@ +#!/sbin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include drv_utils + +pkg_drvrem rtls || exit 1 diff --git a/usr/src/pkgdefs/SUNWrtls/prototype_com b/usr/src/pkgdefs/SUNWrtls/prototype_com index 6aed5a340d..4bc21ee64d 100644 --- a/usr/src/pkgdefs/SUNWrtls/prototype_com +++ b/usr/src/pkgdefs/SUNWrtls/prototype_com @@ -1,8 +1,25 @@ # -# 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. # -# ident "%Z%%M% %I% %E% SMI" +# 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 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # @@ -20,10 +37,8 @@ i pkginfo i copyright i depend i postinstall -i postremove -i i.preserve +i preremove # RTL fast NIC driver d none kernel 0755 root sys d none kernel/drv 0755 root sys -e preserve kernel/drv/rtls.conf 0644 root sys diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 974cec5d3f..2d3bc80003 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -20,7 +20,7 @@ # # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Makefile defines all file modules for the directory uts/common @@ -487,7 +487,7 @@ LX_PTM_OBJS += lx_ptm.o LX_AUDIO_OBJS += lx_audio.o MII_OBJS += mii.o mii_cicada.o mii_natsemi.o mii_intel.o mii_qualsemi.o \ - mii_marvell.o mii_other.o + mii_marvell.o mii_realtek.o mii_other.o PTS_OBJS += pts.o diff --git a/usr/src/uts/common/io/mii/mii.c b/usr/src/uts/common/io/mii/mii.c index bbb02e269f..2187553b40 100644 --- a/usr/src/uts/common/io/mii/mii.c +++ b/usr/src/uts/common/io/mii/mii.c @@ -208,6 +208,7 @@ phy_probe_t _phy_probes[] = { phy_qualsemi_probe, phy_cicada_probe, phy_marvell_probe, + phy_realtek_probe, phy_other_probe, NULL }; diff --git a/usr/src/uts/common/io/mii/mii_realtek.c b/usr/src/uts/common/io/mii/mii_realtek.c new file mode 100644 index 0000000000..5bc1353c1a --- /dev/null +++ b/usr/src/uts/common/io/mii/mii_realtek.c @@ -0,0 +1,117 @@ +/* + * 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 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * MII overrides for Cicada (now Vitesse) PHYs. + */ + +#include <sys/types.h> +#include <sys/ddi.h> +#include <sys/sunddi.h> +#include <sys/mii.h> +#include <sys/miiregs.h> +#include "miipriv.h" + + +/* + * The Realtek 10/100 PHYs are mostly standard compliant, but they + * lack a true vendor/device ID for the integrated PHY, and they don't + * report the "detected" non-Nway link speed in the appropriate + * registers. + */ +static int rtl8139_check(phy_handle_t *); +static int rtl8201_check(phy_handle_t *); + +boolean_t +phy_realtek_probe(phy_handle_t *ph) +{ + if ((ph->phy_id == 0) && + (strcmp(phy_get_driver(ph), "rtls") == 0)) { + ph->phy_vendor = "Realtek"; + ph->phy_model = "Internal RTL8139"; + ph->phy_check = rtl8139_check; + return (B_TRUE); + } else if (ph->phy_id == 0x8201) { + ph->phy_vendor = "Realtek"; + ph->phy_model = "RTL8201"; + ph->phy_check = rtl8201_check; + return (B_TRUE); + } else { + return (B_FALSE); + } +} + +static int +rtl8139_check(phy_handle_t *ph) +{ + int rv; + uint16_t s; + + rv = phy_check(ph); + + /* + * We possibly override settings, so that we can use the PHYs + * autodetected link speed if the partner isn't doing NWay. + */ + s = phy_read(ph, MII_VENDOR(0)); + if (s & (1 << 2)) { + ph->phy_link = LINK_STATE_DOWN; + } else { + ph->phy_link = LINK_STATE_UP; + if (s & (1 << 3)) { + ph->phy_speed = 10; + } else { + ph->phy_speed = 100; + } + } + + return (rv); +} + +static int +rtl8201_check(phy_handle_t *ph) +{ + int rv; + uint16_t s; + + rv = phy_check(ph); + + /* + * We possibly override settings, so that we can use the PHYs + * autodetected link speed if the partner isn't doing NWay. + */ + s = phy_read(ph, MII_VENDOR(9)); + if (s & (1 << 0)) { + ph->phy_link = LINK_STATE_UP; + ph->phy_speed = 100; + } else if (s & (1 << 1)) { + ph->phy_link = LINK_STATE_UP; + ph->phy_speed = 10; + } else { + ph->phy_link = LINK_STATE_DOWN; + } + + return (rv); +} diff --git a/usr/src/uts/common/io/mii/miipriv.h b/usr/src/uts/common/io/mii/miipriv.h index a7c20c515f..5052821abb 100644 --- a/usr/src/uts/common/io/mii/miipriv.h +++ b/usr/src/uts/common/io/mii/miipriv.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -214,6 +214,7 @@ boolean_t phy_natsemi_probe(phy_handle_t *); boolean_t phy_qualsemi_probe(phy_handle_t *); boolean_t phy_cicada_probe(phy_handle_t *); boolean_t phy_marvell_probe(phy_handle_t *); +boolean_t phy_realtek_probe(phy_handle_t *); boolean_t phy_other_probe(phy_handle_t *); #endif /* _MIIPRIV_H */ diff --git a/usr/src/uts/common/io/rtls/rtls.c b/usr/src/uts/common/io/rtls/rtls.c index 999f3f7d13..4a0f6fef9a 100644 --- a/usr/src/uts/common/io/rtls/rtls.c +++ b/usr/src/uts/common/io/rtls/rtls.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,6 +56,8 @@ #include <sys/strsun.h> #include <sys/pci.h> #include <sys/sunddi.h> +#include <sys/mii.h> +#include <sys/miiregs.h> #include <sys/mac_provider.h> #include <sys/mac_ether.h> @@ -91,10 +93,21 @@ static int rtls_m_multicst(void *, boolean_t, const uint8_t *); static int rtls_m_promisc(void *, boolean_t); static mblk_t *rtls_m_tx(void *, mblk_t *); static int rtls_m_stat(void *, uint_t, uint64_t *); +static int rtls_m_getprop(void *, const char *, mac_prop_id_t, uint_t, + uint_t, void *, uint_t *); +static int rtls_m_setprop(void *, const char *, mac_prop_id_t, uint_t, + const void *); static uint_t rtls_intr(caddr_t); /* + * MII entry points + */ +static uint16_t rtls_mii_read(void *, uint8_t, uint8_t); +static void rtls_mii_write(void *, uint8_t, uint8_t, uint16_t); +static void rtls_mii_notify(void *, link_state_t); + +/* * Internal functions used by the above entry points */ static int rtls_chip_reset(rtls_t *, boolean_t); @@ -107,10 +120,6 @@ static void rtls_set_mac_addr(rtls_t *, const uint8_t *); static uint_t rtls_hash_index(const uint8_t *); static boolean_t rtls_send(rtls_t *, mblk_t *); static void rtls_receive(rtls_t *); -static void rtls_periodic(void *); -static uint_t rtls_reschedule(caddr_t arg); -static uint_t rtls_events(caddr_t arg); -static void rtls_chip_force_speed_duplex(rtls_t *); /* * Buffer Management Routines @@ -168,7 +177,7 @@ uchar_t rtls_broadcastaddr[] = { }; static mac_callbacks_t rtls_m_callbacks = { - 0, + MC_SETPROP | MC_GETPROP, rtls_m_stat, rtls_m_start, rtls_m_stop, @@ -176,9 +185,20 @@ static mac_callbacks_t rtls_m_callbacks = { rtls_m_multicst, rtls_m_unicst, rtls_m_tx, - NULL, /* mc_resources */ NULL, /* mc_ioctl */ - NULL /* mc_getcapab */ + NULL, /* mc_getcapab */ + NULL, /* mc_open */ + NULL, /* mc_close */ + rtls_m_setprop, + rtls_m_getprop, +}; + +static mii_ops_t rtls_mii_ops = { + MII_OPS_VERSION, + rtls_mii_read, + rtls_mii_write, + rtls_mii_notify, /* notify */ + NULL, /* reset */ }; DDI_DEFINE_STREAM_OPS(rtls_dev_ops, nulldev, nulldev, rtls_attach, rtls_detach, @@ -197,10 +217,6 @@ static struct modlinkage modlinkage = { MODREV_1, { (void *)&rtls_modldrv, NULL } }; -/* Save ForceSpeedDuplex value for instances in rtls.conf file */ -#define RTLS_MAX_DEVICES 256 -static uint_t rtls_link_mode[RTLS_MAX_DEVICES]; - /* * ========== RealTek chip register access Routines ========== */ @@ -359,6 +375,8 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) mutex_exit(&rtlsp->rtls_rx_lock); mutex_exit(&rtlsp->rtls_io_lock); + mii_resume(rtlsp->mii); + mac_tx_update(rtlsp->mh); return (DDI_SUCCESS); default: @@ -369,8 +387,7 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) * we don't support high level interrupts in the driver */ if (ddi_intr_hilevel(devinfo, 0) != 0) { - cmn_err(CE_WARN, - "rtls_attach -- unsupported high level interrupt"); + cmn_err(CE_WARN, "unsupported high level interrupt"); return (DDI_FAILURE); } @@ -378,7 +395,7 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) * Get handle to access pci configuration space */ if (pci_config_setup(devinfo, &pci_handle) != DDI_SUCCESS) { - cmn_err(CE_WARN, "rtls_attach -- pci_config_setup fail."); + cmn_err(CE_WARN, "pci_config_setup fail."); return (DDI_FAILURE); } @@ -390,12 +407,6 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) device = vendorid; device = (device << 16) | deviceid; /* combine two id together */ -#ifdef RTLS_DEBUG - cmn_err(CE_NOTE, - "rtls_attach: vendorID = 0x%x, deviceID = 0x%x", - vendorid, deviceid); -#endif - /* * See if we support this device * We do not return for wrong device id. It's user risk. @@ -403,29 +414,17 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) switch (device) { default: cmn_err(CE_WARN, - "RTLS don't support this device: " + "RTLS doesn't support this device: " "vendorID = 0x%x, deviceID = 0x%x", vendorid, deviceid); break; case RTLS_SUPPORT_DEVICE_1: case RTLS_SUPPORT_DEVICE_2: case RTLS_SUPPORT_DEVICE_3: + case RTLS_SUPPORT_DEVICE_4: break; } -#ifdef RTLS_OEM - /* - * RealTek required macro - */ - if ((vendorid != RT_VENDOR_ID) || (deviceid != RT_DEVICE_8139)) { - cmn_err(CE_WARN, - "rtls_attach -- wrong OEM device: " - "vendorID = 0x%x, deviceID = 0x%x", - vendorid, deviceid); - pci_config_teardown(&pci_handle); - return (DDI_FAILURE); - } -#endif /* * Turn on Master Enable (DMA) and IO Enable bits. * Enable PCI Memory Space accesses @@ -442,10 +441,6 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) pci_config_teardown(&pci_handle); rtlsp = kmem_zalloc(sizeof (rtls_t), KM_SLEEP); - if (rtlsp == NULL) { - cmn_err(CE_WARN, "rtls_attach -- rtls_t alloc fail."); - return (DDI_FAILURE); - } ddi_set_driver_private(devinfo, rtlsp); rtlsp->devinfo = devinfo; @@ -458,7 +453,7 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) (offset_t)0, 0, &rtls_reg_accattr, &rtlsp->io_handle); if (err != DDI_SUCCESS) { kmem_free((caddr_t)rtlsp, sizeof (rtls_t)); - cmn_err(CE_WARN, "rtls_attach -- ddi_regs_map_setup fail."); + cmn_err(CE_WARN, "ddi_regs_map_setup fail."); return (DDI_FAILURE); } @@ -466,7 +461,7 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) * Allocate the TX and RX descriptors/buffers */ if (rtls_alloc_bufs(rtlsp) == DDI_FAILURE) { - cmn_err(CE_WARN, "rtls_attach -- DMA buffer allocation fail."); + cmn_err(CE_WARN, "DMA buffer allocation fail."); goto fail; } @@ -483,38 +478,6 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) rtls_get_mac_addr(rtlsp, rtlsp->netaddr); /* - * Add the softint handlers: - * - * Both of these handlers are used to avoid restrictions on the - * context and/or mutexes required for some operations. In - * particular, the hardware interrupt handler and its subfunctions - * can detect a number of conditions that we don't want to handle - * in that context or with that set of mutexes held. So, these - * softints are triggered instead: - * - * the <rtls_reschedule> softint is triggered if we have previously - * had to refuse to send a packet because of resource shortage - * (we've run out of transmit descriptors),Its only purpose is to - * call mac_tx_update() to retry the pending transmits (we're not - * allowed to hold driver-defined mutexes across mac_tx_update()). - * - * the <rtls_events> is triggered if the h/w interrupt handler - * sees the <link state changed>. - */ - if (ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &rtlsp->resched_id, - NULL, NULL, rtls_reschedule, (caddr_t)rtlsp) != DDI_SUCCESS) { - cmn_err(CE_WARN, "rtls_attach -- ddi_add_softintr 1 fail."); - goto fail; - } - - if (ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &rtlsp->events_id, - NULL, NULL, rtls_events, (caddr_t)rtlsp) != DDI_SUCCESS) { - cmn_err(CE_WARN, "rtls_attach -- ddi_add_softintr 2 fail."); - ddi_remove_softintr(rtlsp->resched_id); - goto fail; - } - - /* * Add the interrupt handler * * This will prevent receiving interrupts before device is ready, as @@ -526,12 +489,23 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) if (ddi_add_intr(devinfo, 0, &rtlsp->iblk, NULL, rtls_intr, (caddr_t)rtlsp) != DDI_SUCCESS) { - cmn_err(CE_WARN, "rtls_attach -- ddi_add_intr fail."); + cmn_err(CE_WARN, "ddi_add_intr fail."); + goto late_fail; + } + + if ((rtlsp->mii = mii_alloc(rtlsp, devinfo, &rtls_mii_ops)) == NULL) { + ddi_remove_intr(devinfo, 0, rtlsp->iblk); goto late_fail; } + /* + * Note: Some models of 8139 can support pause, but we have + * not implemented support for it at this time. This might be + * an interesting feature to add later. + */ + mii_set_pauseable(rtlsp->mii, B_FALSE, B_FALSE); if ((macp = mac_alloc(MAC_VERSION)) == NULL) { - cmn_err(CE_WARN, "rtls_attach - mac_alloc fail."); + cmn_err(CE_WARN, "mac_alloc fail."); ddi_remove_intr(devinfo, 0, rtlsp->iblk); goto late_fail; } @@ -566,24 +540,13 @@ rtls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) mac_free(macp); - /* - * Add the periodic timer to check link state. We do this - * once a second, in case the link interrupt is missed (or not - * delivered -- qemu emulated 8139 devices don't deliver the - * link change interrupt.) This can run in ordinary kernel - * context. - */ - rtlsp->periodic_id = ddi_periodic_add(rtls_periodic, rtlsp, - 1000000000U, 0); - ASSERT(rtlsp->periodic_id != NULL); /* API guarantee */ - return (DDI_SUCCESS); late_fail: if (macp) mac_free(macp); - ddi_remove_softintr(rtlsp->resched_id); - ddi_remove_softintr(rtlsp->events_id); + if (rtlsp->mii) + mii_free(rtlsp->mii); fail: ddi_regs_map_free(&rtlsp->io_handle); @@ -613,6 +576,8 @@ rtls_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) break; case DDI_SUSPEND: + mii_suspend(rtlsp->mii); + mutex_enter(&rtlsp->rtls_io_lock); mutex_enter(&rtlsp->rtls_rx_lock); mutex_enter(&rtlsp->rtls_tx_lock); @@ -634,11 +599,9 @@ rtls_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) return (DDI_FAILURE); } - ddi_periodic_delete(rtlsp->periodic_id); ddi_remove_intr(devinfo, 0, rtlsp->iblk); - ddi_remove_softintr(rtlsp->resched_id); - ddi_remove_softintr(rtlsp->events_id); + mii_free(rtlsp->mii); mutex_destroy(&rtlsp->rtls_io_lock); mutex_destroy(&rtlsp->rtls_tx_lock); @@ -700,6 +663,10 @@ rtls_m_start(void *arg) mutex_exit(&rtlsp->rtls_rx_lock); mutex_exit(&rtlsp->rtls_io_lock); + drv_usecwait(100); + + mii_start(rtlsp->mii); + return (0); } @@ -711,6 +678,8 @@ rtls_m_stop(void *arg) { rtls_t *rtlsp = (rtls_t *)arg; + mii_stop(rtlsp->mii); + mutex_enter(&rtlsp->rtls_io_lock); if (!rtlsp->rtls_suspended) @@ -754,13 +723,6 @@ rtls_m_multicst(void *arg, boolean_t enable, const uint8_t *mcast) index = rtls_hash_index(mcast); /* index value is between 0 and 63 */ -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_REGCFG) { - cmn_err(CE_NOTE, - "%s: rtls_m_multicst: enable = %d, multi(%s), index=%d", - rtlsp->ifname, enable, ether_sprintf((void *)mcast), index); - } -#endif if (enable) { if (rtlsp->multicast_cnt[index]++) { mutex_exit(&rtlsp->rtls_io_lock); @@ -783,19 +745,6 @@ rtls_m_multicst(void *arg, boolean_t enable, const uint8_t *mcast) rtls_reg_set32(rtlsp, MULTICAST_4_REG, hashp[1]); } -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_REGCFG) { - cmn_err(CE_NOTE, - "%s: rtls_m_multicst =>: hash0=0x%x, hash1=0x%x", - rtlsp->ifname, hashp[0], hashp[1]); - cmn_err(CE_NOTE, - "%s: rtls_m_multicst <=, hash0=0x%x, hash1=0x%x", - rtlsp->ifname, - rtls_reg_get32(rtlsp, MULTICAST_0_REG), - rtls_reg_get32(rtlsp, MULTICAST_4_REG)); - } -#endif - mutex_exit(&rtlsp->rtls_io_lock); return (0); @@ -842,12 +791,6 @@ rtls_m_promisc(void *arg, boolean_t on) { rtls_t *rtlsp = arg; -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_REGCFG) { - cmn_err(CE_NOTE, "%s: rtls_m_promisc: on=%d", - rtlsp->ifname, on); - } -#endif mutex_enter(&rtlsp->rtls_io_lock); rtlsp->promisc = on; @@ -878,24 +821,11 @@ rtls_m_stat(void *arg, uint_t stat, uint64_t *val) { rtls_t *rtlsp = arg; - uint16_t bmcr, bmsr, anar, anlpar, aner; - - mutex_enter(&rtlsp->rtls_io_lock); - if (!rtlsp->rtls_suspended) { - bmcr = rtls_reg_get16(rtlsp, BASIC_MODE_CONTROL_REG); - bmsr = rtls_reg_get16(rtlsp, BASIC_MODE_STATUS_REG); - anar = rtls_reg_get16(rtlsp, AUTO_NEGO_AD_REG); - anlpar = rtls_reg_get16(rtlsp, AUTO_NEGO_LP_REG); - aner = rtls_reg_get16(rtlsp, AUTO_NEGO_EXP_REG); - } else { - bmcr = bmsr = anar = anlpar = aner = 0; + if (mii_m_getstat(rtlsp->mii, stat, val) == 0) { + return (0); } - mutex_exit(&rtlsp->rtls_io_lock); switch (stat) { - case MAC_STAT_IFSPEED: - *val = rtlsp->stats.speed; - break; case MAC_STAT_IPACKETS: *val = rtlsp->stats.ipackets; break; @@ -938,9 +868,6 @@ rtls_m_stat(void *arg, uint_t stat, uint64_t *val) case MAC_STAT_COLLISIONS: *val = rtlsp->stats.collisions; break; - case ETHER_STAT_LINK_DUPLEX: - *val = rtlsp->stats.duplex; - break; case ETHER_STAT_FCS_ERRORS: *val = rtlsp->stats.crc_err; break; @@ -968,48 +895,6 @@ rtls_m_stat(void *arg, uint_t stat, uint64_t *val) case ETHER_STAT_MULTI_COLLISIONS: *val = rtlsp->stats.multicol; break; - case ETHER_STAT_CAP_100FDX: - case ETHER_STAT_CAP_100HDX: - case ETHER_STAT_CAP_10FDX: - case ETHER_STAT_CAP_10HDX: - case ETHER_STAT_CAP_AUTONEG: - *val = 1; /* these are all true by default */ - break; - case ETHER_STAT_ADV_CAP_100FDX: - *val = anar & AUTO_NEGO_100FULL ? 1 : 0; - break; - case ETHER_STAT_ADV_CAP_100HDX: - *val = anar & AUTO_NEGO_100HALF ? 1 : 0; - break; - case ETHER_STAT_ADV_CAP_10FDX: - *val = anar & AUTO_NEGO_10FULL ? 1 : 0; - break; - case ETHER_STAT_ADV_CAP_10HDX: - *val = anar & AUTO_NEGO_10HALF ? 1 : 0; - break; - case ETHER_STAT_ADV_CAP_AUTONEG: - *val = bmcr & BASIC_MODE_AUTONEGO ? 1 : 0; - break; - case ETHER_STAT_LP_CAP_100FDX: - *val = anlpar & AUTO_NEGO_100FULL ? 1 : 0; - break; - case ETHER_STAT_LP_CAP_100HDX: - *val = anlpar & AUTO_NEGO_100HALF ? 1 : 0; - break; - case ETHER_STAT_LP_CAP_10FDX: - *val = anlpar & AUTO_NEGO_10FULL ? 1 : 0; - break; - case ETHER_STAT_LP_CAP_10HDX: - *val = anlpar & AUTO_NEGO_10HALF ? 1 : 0; - break; - case ETHER_STAT_LP_CAP_AUTONEG: - *val = aner & AUTO_NEGO_EXP_LPCANAN ? 1 : 0; - break; - case ETHER_STAT_LINK_AUTONEG: - *val = ((aner & AUTO_NEGO_EXP_LPCANAN) && - (bmcr & BASIC_MODE_AUTONEGO) && - (bmsr & BASIC_MODE_STATUS_AUTONEGO_DONE)) ? 1 : 0; - break; default: return (ENOTSUP); } @@ -1027,6 +912,24 @@ rtls_m_stat(void *arg, uint_t stat, uint64_t *val) return (0); } +int +rtls_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t flags, + uint_t sz, void *val, uint_t *perm) +{ + rtls_t *rtlsp = arg; + + return (mii_m_getprop(rtlsp->mii, name, num, flags, sz, val, perm)); +} + +int +rtls_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz, + const void *val) +{ + rtls_t *rtlsp = arg; + + return (mii_m_setprop(rtlsp->mii, name, num, sz, val)); +} + /* * rtls_send() -- send a packet * @@ -1073,9 +976,12 @@ rtls_send(rtls_t *rtlsp, mblk_t *mp) } /* - * If chip link down ... + * If chip link down ... Note that experimentation shows that + * the device seems not to care about whether or not we have + * this check, but if we don't add the check here, it might + * not be properly reported as a carrier error. */ - if (rtlsp->link_state == LINK_STATE_DOWN) { + if (rtls_reg_get8(rtlsp, MEDIA_STATUS_REG) & MEDIA_STATUS_LINK) { #ifdef RTLS_DEBUG cmn_err(CE_WARN, "%s: send fail--LINK DOWN!", @@ -1477,11 +1383,14 @@ rtls_intr(caddr_t arg) { rtls_t *rtlsp = (void *)arg; uint32_t int_status; - uint8_t media_status; - int32_t link; uint32_t val32; + boolean_t resched = B_FALSE; mutex_enter(&rtlsp->rtls_io_lock); + if (rtlsp->rtls_suspended) { + mutex_exit(&rtlsp->rtls_io_lock); + return (DDI_INTR_UNCLAIMED); + } /* * Was this interrupt caused by our device... @@ -1525,29 +1434,11 @@ rtls_intr(caddr_t arg) } /* - * Cable link change interrupt - */ - if (int_status & LINK_CHANGE_INT) { - media_status = rtls_reg_get8(rtlsp, MEDIA_STATUS_REG); - link = (media_status & MEDIA_STATUS_LINK) ? - LINK_STATE_DOWN : LINK_STATE_UP; - - if (rtlsp->link_state != link) { - rtlsp->link_state = link; - rtlsp->link_change = B_TRUE; - /* - * Trigger rtls_events - */ - ddi_trigger_softintr(rtlsp->events_id); - } - } - - /* * Trigger mac_tx_update */ - if (rtlsp->need_sched && !rtlsp->sched_running) { - rtlsp->sched_running = B_TRUE; - ddi_trigger_softintr(rtlsp->resched_id); + if (rtlsp->need_sched) { + rtlsp->need_sched = B_FALSE; + resched = B_TRUE; } mutex_exit(&rtlsp->rtls_io_lock); @@ -1563,104 +1454,18 @@ rtls_intr(caddr_t arg) rtls_receive(rtlsp); } - return (DDI_INTR_CLAIMED); /* indicate it was our interrupt */ -} - -static void -rtls_periodic(void *arg) -{ - rtls_t *rtlsp = (void *)arg; - uint32_t link; - uint8_t media_status; - - mutex_enter(&rtlsp->rtls_io_lock); - - if (rtlsp->rtls_suspended) { - mutex_exit(&rtlsp->rtls_io_lock); - return; - } - - media_status = rtls_reg_get8(rtlsp, MEDIA_STATUS_REG); - link = (media_status & MEDIA_STATUS_LINK) ? - LINK_STATE_DOWN : LINK_STATE_UP; - - if (rtlsp->link_state != link) { - rtlsp->link_state = link; - rtlsp->link_change = B_TRUE; - /* - * Trigger rtls_events - */ - ddi_trigger_softintr(rtlsp->events_id); + /* + * Link change interrupt. + */ + if (int_status & LINK_CHANGE_INT) { + mii_check(rtlsp->mii); } - mutex_exit(&rtlsp->rtls_io_lock); -} -/* - * rtls_reschedule() -- soft interrupt handler - */ -static uint_t -rtls_reschedule(caddr_t arg) -{ - rtls_t *rtlsp = (void *)arg; - uint_t tmp; - - tmp = DDI_INTR_UNCLAIMED; - - if (rtlsp->need_sched && rtlsp->rtls_running) { -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_SEND) { - cmn_err(CE_NOTE, "%s: rtls_reschedule", rtlsp->ifname); - } -#endif - rtlsp->need_sched = B_FALSE; + if (resched) { mac_tx_update(rtlsp->mh); - rtlsp->sched_running = B_FALSE; - tmp = DDI_INTR_CLAIMED; - } - return (tmp); -} - -/* - * rtls_events() -- soft interrupt handler - * - * The rtls_events is woken up when there's something to do that we'd rather - * not do from inside a hardware interrupt handler. - * Its main task now is just: - * notice mac the link status changed - */ -static uint_t -rtls_events(caddr_t arg) -{ - rtls_t *rtlsp = (void *)arg; - uint_t tmp = DDI_INTR_UNCLAIMED; - uint8_t media_status; - uint16_t duplex_mode; - - /* - * If the link state changed, tell the world about it. - * Note: can't do this while still holding the mutex. - */ - if (rtlsp->link_change) { - rtlsp->link_change = B_FALSE; - - if (rtlsp->link_state == LINK_STATE_UP) { - media_status = - rtls_reg_get8(rtlsp, MEDIA_STATUS_REG); - rtlsp->stats.speed = - (media_status & MEDIA_STATUS_SPEED) ? - RTLS_SPEED_10M : RTLS_SPEED_100M; - duplex_mode = rtls_reg_get16(rtlsp, - BASIC_MODE_CONTROL_REG); - rtlsp->stats.duplex = - (duplex_mode & BASIC_MODE_DUPLEX) ? - LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; - } - mac_link_update(rtlsp->mh, rtlsp->link_state); - - tmp = DDI_INTR_CLAIMED; } - return (tmp); + return (DDI_INTR_CLAIMED); /* indicate it was our interrupt */ } /* @@ -1878,14 +1683,9 @@ rtls_chip_reset(rtls_t *rtlsp, boolean_t quiesce) static void rtls_chip_init(rtls_t *rtlsp) { - static boolean_t first_time = B_TRUE; - int *forced_speed_and_duplex; - uint_t item_num; uint32_t val32; uint16_t val16; uint8_t val8; - int err; - int i; /* * Initialize internal data structures @@ -1895,53 +1695,6 @@ rtls_chip_init(rtls_t *rtlsp) rtlsp->tx_first_loop = 0; /* - * Read ForceSpeedDuplex from rtls.conf file - */ - if (first_time) { - first_time = B_FALSE; - /* - * Set ForceSpeedDuplex array default value - * to 5:Anto-Negotiation - */ - for (i = 0; i < RTLS_MAX_DEVICES; i++) - rtls_link_mode[i] = FORCE_AUTO_NEGO; - - /* Read ForceSpeedDuplex value */ - err = ddi_prop_lookup_int_array( - DDI_DEV_T_ANY, - rtlsp->devinfo, - DDI_PROP_DONTPASS, - "ForceSpeedDuplex", - &forced_speed_and_duplex, - &item_num); - if (err == DDI_PROP_SUCCESS) { - for (i = 0; i <= item_num; i++) { - rtls_link_mode[i] = - forced_speed_and_duplex[i]; - } - ddi_prop_free(forced_speed_and_duplex); - } -#ifdef RTLS_DEBUG - if (err == DDI_PROP_SUCCESS) { - for (i = 0; i < item_num; i++) - cmn_err(CE_NOTE, - "rtls.conf: rtls%d, ForceSpeedDuplex = %d", - i, rtls_link_mode[i]); - } else { - cmn_err(CE_NOTE, - "rtls: read ForceSpeedDuplex in rtls.conf fail."); - } -#endif - } - rtlsp->force_speed_duplex = - rtls_link_mode[rtlsp->instance]; - - /* - * Set duplex and speed - */ - rtls_chip_force_speed_duplex(rtlsp); - - /* * Set DMA physical rx/tx buffer address to register */ rtls_reg_set32(rtlsp, RX_BUFF_ADDR_REG, @@ -2102,18 +1855,12 @@ rtls_set_mac_addr(rtls_t *rtlsp, const uint8_t *macaddr) uint32_t val32; uint8_t val8; -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_REGCFG) { - cmn_err(CE_NOTE, "%s:rtls_set_mac_addr(%s)", - rtlsp->ifname, ether_sprintf((void *)macaddr)); - } -#endif /* * Change to config register write enable mode */ - val8 = rtls_reg_get8(rtlsp, RT_93c46_COMMOND_REG); + val8 = rtls_reg_get8(rtlsp, RT_93c46_COMMAND_REG); val8 |= RT_93c46_MODE_CONFIG; - rtls_reg_set8(rtlsp, RT_93c46_COMMOND_REG, val8); + rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8); /* * Get first 4 bytes of mac address @@ -2131,15 +1878,6 @@ rtls_set_mac_addr(rtls_t *rtlsp, const uint8_t *macaddr) */ rtls_reg_set32(rtlsp, ID_0_REG, val32); -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_REGCFG) { - cmn_err(CE_NOTE, "%s: rtls_m_unicst 0 => 0x%x", - rtlsp->ifname, val32); - val32 = rtls_reg_get32(rtlsp, ID_0_REG); - cmn_err(CE_NOTE, "%s: rtls_m_unicst 0 <= 0x%x", - rtlsp->ifname, val32); - } -#endif /* * Get last 2 bytes of mac address */ @@ -2153,124 +1891,104 @@ rtls_set_mac_addr(rtls_t *rtlsp, const uint8_t *macaddr) val32 |= rtls_reg_get32(rtlsp, ID_4_REG) & ~0xffff; rtls_reg_set32(rtlsp, ID_4_REG, val32); -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_REGCFG) { - cmn_err(CE_NOTE, "%s: rtls_m_unicst 1 => 0x%x", - rtlsp->ifname, val32); - val32 = rtls_reg_get32(rtlsp, ID_4_REG); - cmn_err(CE_NOTE, "%s: rtls_m_unicst 1 <= 0x%x", - rtlsp->ifname, val32); - } -#endif /* * Return to normal network/host communication mode */ val8 &= ~RT_93c46_MODE_CONFIG; - rtls_reg_set8(rtlsp, RT_93c46_COMMOND_REG, val8); + rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8); } -/* - * rtls_chip_force_speed_duplex() -- set chip speed and duplex mode - */ -static void -rtls_chip_force_speed_duplex(rtls_t *rtlsp) +static uint16_t +rtls_mii_read(void *arg, uint8_t phy, uint8_t reg) { - uint16_t control; - uint16_t ad_mode; - uint8_t val8; - - control = rtls_reg_get16(rtlsp, BASIC_MODE_CONTROL_REG); - control &= ~BASIC_MODE_CONTROL_BITS; - ad_mode = rtls_reg_get16(rtlsp, AUTO_NEGO_AD_REG); - ad_mode &= ~AUTO_NEGO_MODE_BITS; + rtls_t *rtlsp = arg; + uint16_t val; -#ifdef RTLS_DEBUG - if (rtls_debug & RTLS_TRACE) { - cmn_err(CE_NOTE, "%s:rtls_chip_force_speed_duplex = %d", - rtlsp->ifname, rtlsp->force_speed_duplex); + if (phy != 1) { + return (0xffff); } -#endif - switch (rtlsp->force_speed_duplex) { - default: - cmn_err(CE_WARN, - "%s: Bad ForceSpeedDuplex = %d value, " - "will use its default value 5: Anto-Negotiation", - rtlsp->ifname, rtlsp->force_speed_duplex); - rtlsp->force_speed_duplex = FORCE_AUTO_NEGO; - control |= BASIC_MODE_AUTONEGO | BASIC_MODE_RESTAR_AUTONEGO; - ad_mode |= AUTO_NEGO_100FULL | AUTO_NEGO_100HALF | - AUTO_NEGO_10FULL | AUTO_NEGO_10HALF; - rtlsp->stats.speed = RTLS_SPEED_UNKNOWN; - rtlsp->stats.duplex = LINK_DUPLEX_UNKNOWN; + switch (reg) { + case MII_CONTROL: + val = rtls_reg_get16(rtlsp, BASIC_MODE_CONTROL_REG); break; - case FORCE_AUTO_NEGO: - control |= BASIC_MODE_AUTONEGO | BASIC_MODE_RESTAR_AUTONEGO; - ad_mode |= AUTO_NEGO_100FULL | AUTO_NEGO_100HALF | - AUTO_NEGO_10FULL | AUTO_NEGO_10HALF; - if (!rtlsp->chip_error) { - rtlsp->stats.speed = RTLS_SPEED_UNKNOWN; - rtlsp->stats.duplex = LINK_DUPLEX_UNKNOWN; - } + case MII_STATUS: + val = rtls_reg_get16(rtlsp, BASIC_MODE_STATUS_REG); break; - case FORCE_100_FDX: - /* - * RTL8139 can't establish link correctly on this force mode - * if the other side is not the same force mode. So We have to - * realize this force mode in auto-negotiation mode advertising - * 100M/Full ability only - */ - control |= BASIC_MODE_AUTONEGO | BASIC_MODE_RESTAR_AUTONEGO; - ad_mode |= AUTO_NEGO_100FULL; - rtlsp->stats.speed = RTLS_SPEED_100M; - rtlsp->stats.duplex = LINK_DUPLEX_FULL; + case MII_AN_ADVERT: + val = rtls_reg_get16(rtlsp, AUTO_NEGO_AD_REG); + break; + case MII_AN_LPABLE: + val = rtls_reg_get16(rtlsp, AUTO_NEGO_LP_REG); break; - case FORCE_100_HDX: - control |= BASIC_MODE_SPEED_100; - ad_mode |= AUTO_NEGO_100HALF; - rtlsp->stats.speed = RTLS_SPEED_100M; - rtlsp->stats.duplex = LINK_DUPLEX_HALF; + case MII_AN_EXPANSION: + val = rtls_reg_get16(rtlsp, AUTO_NEGO_EXP_REG); break; - case FORCE_10_FDX: + case MII_VENDOR(0): /* - * RTL8139 can't establish link correctly on this force mode - * if the other side is not the same force mode. So We have to - * realize this force mode in auto-negotiation mode advertising - * 10M/Full ability only + * We "simulate" a vendor private register so that the + * PHY layer can access it to determine detected link + * speed/duplex. */ - control |= BASIC_MODE_AUTONEGO | BASIC_MODE_RESTAR_AUTONEGO; - ad_mode |= AUTO_NEGO_10FULL; - rtlsp->stats.speed = RTLS_SPEED_10M; - rtlsp->stats.duplex = LINK_DUPLEX_FULL; + val = rtls_reg_get8(rtlsp, MEDIA_STATUS_REG); break; - case FORCE_10_HDX: - ad_mode |= AUTO_NEGO_10HALF; - rtlsp->stats.speed = RTLS_SPEED_10M; - rtlsp->stats.duplex = LINK_DUPLEX_HALF; + case MII_PHYIDH: + case MII_PHYIDL: + default: + val = 0; break; } + return (val); +} - /* - * Set auto-negotiation advertisement ability register - */ - rtls_reg_set16(rtlsp, AUTO_NEGO_AD_REG, ad_mode); +void +rtls_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val) +{ + rtls_t *rtlsp = arg; + uint8_t val8; - /* - * Change to config register write enable mode - */ - val8 = rtls_reg_get8(rtlsp, RT_93c46_COMMOND_REG); - val8 |= RT_93c46_MODE_CONFIG; - rtls_reg_set8(rtlsp, RT_93c46_COMMOND_REG, val8); + if (phy != 1) { + return; + } + switch (reg) { + case MII_CONTROL: + /* Enable writes to all bits of BMCR */ + val8 = rtls_reg_get8(rtlsp, RT_93c46_COMMAND_REG); + val8 |= RT_93c46_MODE_CONFIG; + rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8); + /* write out the value */ + rtls_reg_set16(rtlsp, BASIC_MODE_CONTROL_REG, val); + + /* Return to normal network/host communication mode */ + val8 &= ~RT_93c46_MODE_CONFIG; + rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8); + return; - /* - * Set MII control register - */ - rtls_reg_set16(rtlsp, BASIC_MODE_CONTROL_REG, control); + case MII_STATUS: + rtls_reg_set16(rtlsp, BASIC_MODE_STATUS_REG, val); + break; + case MII_AN_ADVERT: + rtls_reg_set16(rtlsp, AUTO_NEGO_AD_REG, val); + break; + case MII_AN_LPABLE: + rtls_reg_set16(rtlsp, AUTO_NEGO_LP_REG, val); + break; + case MII_AN_EXPANSION: + rtls_reg_set16(rtlsp, AUTO_NEGO_EXP_REG, val); + break; + case MII_PHYIDH: + case MII_PHYIDL: + default: + /* these are not writable */ + break; + } +} - /* - * Return to normal network/host communication mode - */ - val8 &= ~RT_93c46_MODE_CONFIG; - rtls_reg_set8(rtlsp, RT_93c46_COMMOND_REG, val8); +void +rtls_mii_notify(void *arg, link_state_t link) +{ + rtls_t *rtlsp = arg; + + mac_link_update(rtlsp->mh, link); } #ifdef RTLS_DEBUG @@ -2305,37 +2023,31 @@ rtls_reg_print(rtls_t *rtlsp) delay(drv_usectohz(1000)); val16 = rtls_reg_get16(rtlsp, TX_DESC_STAUS_REG); - cmn_err(CE_NOTE, - "%s: TX_DESC_STAUS_REG = 0x%x, cur_desc = %d", + cmn_err(CE_NOTE, "%s: TX_DESC_STAUS_REG = 0x%x, cur_desc = %d", rtlsp->ifname, val16, rtlsp->tx_current_desc); delay(drv_usectohz(1000)); val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC0_REG); - cmn_err(CE_NOTE, - "%s: TX_STATUS_DESC0_REG = 0x%x", + cmn_err(CE_NOTE, "%s: TX_STATUS_DESC0_REG = 0x%x", rtlsp->ifname, val32); delay(drv_usectohz(1000)); val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC1_REG); - cmn_err(CE_NOTE, - "%s: TX_STATUS_DESC1_REG = 0x%x", + cmn_err(CE_NOTE, "%s: TX_STATUS_DESC1_REG = 0x%x", rtlsp->ifname, val32); delay(drv_usectohz(1000)); val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC2_REG); - cmn_err(CE_NOTE, - "%s: TX_STATUS_DESC2_REG = 0x%x", + cmn_err(CE_NOTE, "%s: TX_STATUS_DESC2_REG = 0x%x", rtlsp->ifname, val32); delay(drv_usectohz(1000)); val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC3_REG); - cmn_err(CE_NOTE, - "%s: TX_STATUS_DESC3_REG = 0x%x", + cmn_err(CE_NOTE, "%s: TX_STATUS_DESC3_REG = 0x%x", rtlsp->ifname, val32); delay(drv_usectohz(1000)); - cmn_err(CE_NOTE, - "%s: in = %llu, multicast = %llu, broadcast = %llu", + cmn_err(CE_NOTE, "%s: in = %llu, multicast = %llu, broadcast = %llu", rtlsp->ifname, (unsigned long long)rtlsp->stats.ipackets, (unsigned long long)rtlsp->stats.multi_rcv, diff --git a/usr/src/uts/common/io/rtls/rtls.h b/usr/src/uts/common/io/rtls/rtls.h index b62232f487..3b60d3eca5 100644 --- a/usr/src/uts/common/io/rtls/rtls.h +++ b/usr/src/uts/common/io/rtls/rtls.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -73,6 +73,10 @@ extern "C" { #define RTLS_DEVICE_ID_3 0x1211 #define RTLS_SUPPORT_DEVICE_3 ((RTLS_VENDOR_ID_3 << 16) | RTLS_DEVICE_ID_3) +#define RTLS_VENDOR_ID_4 0x1186 /* D-link */ +#define RTLS_DEVICE_ID_4 0x1300 +#define RTLS_SUPPORT_DEVICE_4 ((RTLS_VENDOR_ID_4 << 16) | RTLS_DEVICE_ID_4) + /* * Driver tx/rx parameters */ @@ -139,12 +143,11 @@ typedef struct rtls_stats { uint32_t in_short; uint32_t too_long; uint32_t no_rcvbuf; /* ifInDiscards */ - uint32_t speed; /* ifSpeed */ - uint32_t duplex; /* Invented for GLD */ } rtls_stats_t; typedef struct rtls_instance { mac_handle_t mh; + mii_handle_t mii; dev_info_t *devinfo; /* device instance */ int32_t instance; @@ -190,14 +193,6 @@ typedef struct rtls_instance { /* send reschedule used */ boolean_t need_sched; - boolean_t sched_running; - ddi_softintr_t resched_id; /* reschedule callback */ - - /* events:link change used */ - boolean_t link_change; - int32_t link_state; - ddi_softintr_t events_id; /* events callback */ - ddi_periodic_t periodic_id; boolean_t chip_error; /* chip error flag */ @@ -205,9 +200,6 @@ typedef struct rtls_instance { boolean_t rtls_running; boolean_t rtls_suspended; - /* value of rtls.conf file, default 5:FORCE_AUTO_NEGO */ - uint_t force_speed_duplex; - /* rtls statistics */ rtls_stats_t stats; } rtls_t; @@ -444,7 +436,7 @@ typedef struct rtls_instance { /* * 93c46(93c56) commond register: */ -#define RT_93c46_COMMOND_REG 0x0050 +#define RT_93c46_COMMAND_REG 0x0050 #define RT_93c46_MODE_BITS 0xc0 #define RT_93c46_MODE_NORMAL 0x00 #define RT_93c46_MODE_AUTOLOAD 0x40 diff --git a/usr/src/uts/intel/rtls/Makefile b/usr/src/uts/intel/rtls/Makefile index 067fe90411..b412976238 100644 --- a/usr/src/uts/intel/rtls/Makefile +++ b/usr/src/uts/intel/rtls/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # @@ -39,7 +39,6 @@ MODULE = rtls OBJECTS = $(RTLS_OBJS:%=$(OBJS_DIR)/%) LINTS = $(RTLS_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/common/io/rtls # # Include common rules. @@ -51,7 +50,7 @@ include $(UTSBASE)/intel/Makefile.intel # ALL_TARGET = $(BINARY) LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # # Overrides @@ -60,7 +59,7 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) # # Driver depends on Mac # -LDFLAGS += -dy -N misc/mac +LDFLAGS += -dy -N misc/mac -N misc/mii # # Default build targets. diff --git a/usr/src/uts/sparc/rtls/Makefile b/usr/src/uts/sparc/rtls/Makefile index 58ca1be260..cda125df9e 100644 --- a/usr/src/uts/sparc/rtls/Makefile +++ b/usr/src/uts/sparc/rtls/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # @@ -39,7 +39,6 @@ MODULE = rtls OBJECTS = $(RTLS_OBJS:%=$(OBJS_DIR)/%) LINTS = $(RTLS_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/common/io/rtls # # Include common rules. @@ -51,7 +50,7 @@ include $(UTSBASE)/sparc/Makefile.sparc # ALL_TARGET = $(BINARY) LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # # Overrides @@ -60,7 +59,7 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) # # Driver depends on Mac # -LDFLAGS += -dy -N misc/mac +LDFLAGS += -dy -N misc/mac -N misc/mii # # Default build targets. |