diff options
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. |