summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/pkgdefs/SUNWrtls/Makefile33
-rw-r--r--usr/src/pkgdefs/SUNWrtls/depend31
-rw-r--r--usr/src/pkgdefs/SUNWrtls/postinstall110
-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/postremove18
-rw-r--r--usr/src/pkgdefs/SUNWrtls/preremove.tmpl28
-rw-r--r--usr/src/pkgdefs/SUNWrtls/prototype_com27
-rw-r--r--usr/src/uts/common/Makefile.files4
-rw-r--r--usr/src/uts/common/io/mii/mii.c1
-rw-r--r--usr/src/uts/common/io/mii/mii_realtek.c117
-rw-r--r--usr/src/uts/common/io/mii/miipriv.h3
-rw-r--r--usr/src/uts/common/io/rtls/rtls.c656
-rw-r--r--usr/src/uts/common/io/rtls/rtls.h22
-rw-r--r--usr/src/uts/intel/rtls/Makefile7
-rw-r--r--usr/src/uts/sparc/rtls/Makefile7
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.