Add support for the Intel 80003 Gigabit Ethernet controller (found e.g. in

newer server chipsets) to wm(4), from the FreeBSD em(4) driver.
While there, add a few other Intel Ethernet controller that should work as
is.
Properly update the RX error and TX collision counters.
Add ikphy(4), a driver for the Intel i82563 Kumeran 10/100/1000 Ethernet PHYs
This commit is contained in:
bouyer 2006-10-21 14:10:32 +00:00
parent 7bdd26b810
commit 154d613f0b
24 changed files with 1047 additions and 73 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.942 2006/10/15 22:42:03 christos Exp $
# $NetBSD: mi,v 1.943 2006/10/21 14:10:32 bouyer Exp $
./etc/mtree/set.man man-sys-root
./usr/share/info/am-utils.info man-amd-info info
./usr/share/info/as.info man-computil-info bfd,info
@ -973,6 +973,7 @@
./usr/share/man/cat4/ifpci.0 man-sys-catman .cat
./usr/share/man/cat4/igsfb.0 man-sys-catman .cat
./usr/share/man/cat4/iha.0 man-sys-catman .cat
./usr/share/man/cat4/ikphy.0 man-sys-catman .cat
./usr/share/man/cat4/imp.0 man-obsolete obsolete
./usr/share/man/cat4/inet.0 man-sys-catman .cat
./usr/share/man/cat4/inet6.0 man-sys-catman .cat
@ -3361,6 +3362,7 @@
./usr/share/man/man4/ifpci.4 man-sys-man .man
./usr/share/man/man4/igsfb.4 man-sys-man .man
./usr/share/man/man4/iha.4 man-sys-man .man
./usr/share/man/man4/ikphy.4 man-sys-man .man
./usr/share/man/man4/imp.4 man-obsolete obsolete
./usr/share/man/man4/inet.4 man-sys-man .man
./usr/share/man/man4/inet6.4 man-sys-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.408 2006/10/09 16:51:51 gdamore Exp $
# $NetBSD: Makefile,v 1.409 2006/10/21 14:10:33 bouyer Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \
@ -20,7 +20,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \
fpa.4 fms.4 fss.4 fxp.4 gem.4 gentbi.4 \
glxtphy.4 gpib.4 gpio.4 gre.4 gphyter.4 gsip.4 hifn.4 hme.4 \
hptide.4 icmp.4 icp.4 icsphy.4 ieee80211.4 ifmedia.4 \
igsfb.4 iha.4 inet.4 inphy.4 intersil7170.4 \
igsfb.4 iha.4 inet.4 ikphy.4 inphy.4 intersil7170.4 \
ioasic.4 ioat.4 iop.4 iophy.4 iopsp.4 ip.4 ipkdb.4 ipmi.4 ipw.4 \
iso.4 isp.4 it.4 iteide.4 iwi.4 ixpide.4 joy.4 kloader.4 kse.4 \
ksyms.4 kttcp.4 lc.4 ld.4 lkm.4 lo.4 lxtphy.4 mainbus.4 makphy.4 \

View File

@ -1,4 +1,4 @@
.\" $NetBSD: mii.4,v 1.20 2006/03/25 17:46:09 xtraeme Exp $
.\" $NetBSD: mii.4,v 1.21 2006/10/21 14:10:33 bouyer Exp $
.\"
.\" Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -35,7 +35,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd March 25, 2006
.Dd Oct 13, 2006
.Dt MII 4
.Os
.Sh NAME
@ -53,6 +53,7 @@
.Cd "glxtphy* at mii? phy ? # Level One LXT-1000 Gig-E PHYs"
.Cd "gphyter* at mii? phy ? # NatSemi DP83861 Gig-E PHYs"
.Cd "icsphy* at mii? phy ? # Integrated Circuit Systems ICS1890 PHYs"
.Cd "ikphy* at mii? phy ? # Intel 82563 PHYs"
.Cd "inphy* at mii? phy ? # Intel 82555 PHYs"
.Cd "iophy* at mii? phy ? # Intel 82553 PHYs"
.Cd "lxtphy* at mii? phy ? # Level One LXT-970 PHYs"

View File

@ -1,4 +1,4 @@
.\" $NetBSD: wm.4,v 1.14 2006/06/10 08:06:51 msaitoh Exp $
.\" $NetBSD: wm.4,v 1.15 2006/10/21 14:10:33 bouyer Exp $
.\"
.\" Copyright 2002, 2003 Wasabi Systems, Inc.
.\" All rights reserved.
@ -33,7 +33,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd March 19, 2005
.Dd Oct 13, 2006
.Dt WM 4
.Os
.Sh NAME
@ -116,6 +116,8 @@ Intel i82571 1000BASE-T Ethernet
Intel i82572 1000BASE-T Ethernet
.It
Intel i82573 1000BASE-T Ethernet
.It
Intel i80003 1000BASE-T Ethernet
.El
.Pp
In addition to Intel's own

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.111 2006/09/26 14:30:26 elad Exp $
# $NetBSD: GENERIC,v 1.112 2006/10/21 14:10:33 bouyer Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.111 $"
#ident "GENERIC-$Revision: 1.112 $"
maxusers 32 # estimated number of users
@ -594,6 +594,7 @@ glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: INSTALL,v 1.58 2006/10/15 14:41:49 xtraeme Exp $
# $NetBSD: INSTALL,v 1.59 2006/10/21 14:10:33 bouyer Exp $
#
# GENERIC machine description file
#
@ -20,7 +20,7 @@
include "arch/amd64/conf/std.amd64"
#ident "INSTALL-$Revision: 1.58 $"
#ident "INSTALL-$Revision: 1.59 $"
maxusers 32 # estimated number of users
@ -481,6 +481,7 @@ glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.70 2006/08/26 20:26:45 christos Exp $
# $NetBSD: GENERIC,v 1.71 2006/10/21 14:10:33 bouyer Exp $
#
# GENERIC machine description file
#
@ -23,7 +23,7 @@ include "arch/hp700/conf/std.hp700"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel
#ident "GENERIC-$Revision: 1.70 $"
#ident "GENERIC-$Revision: 1.71 $"
maxusers 32 # estimated number of users
@ -492,6 +492,7 @@ glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.67 2006/10/13 21:02:19 christos Exp $
# $NetBSD: ALL,v 1.68 2006/10/21 14:10:33 bouyer Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.67 $"
#ident "ALL-$Revision: 1.68 $"
maxusers 32 # estimated number of users
@ -949,6 +949,7 @@ glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp $
# $NetBSD: GENERIC,v 1.788 2006/10/21 14:10:33 bouyer Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.787 $"
#ident "GENERIC-$Revision: 1.788 $"
maxusers 32 # estimated number of users
@ -967,8 +967,10 @@ glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
ikphy* at mii? phy ? # Intel 82563 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs
makphy* at mii? phy ? # Marvell Semiconductor 88E1000 PHYs
nsphy* at mii? phy ? # NS83840 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC_LAPTOP,v 1.208 2006/10/01 09:53:08 itohy Exp $
# $NetBSD: GENERIC_LAPTOP,v 1.209 2006/10/21 14:10:33 bouyer Exp $
# From: NetBSD: GENERIC,v 1.414 2001/07/30 19:59:05 ad Exp
#
# GENERIC_LAPTOP -- GENERIC with cardbus and some USB devices enabled
@ -8,7 +8,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.208 $"
#ident "GENERIC-$Revision: 1.209 $"
maxusers 32 # estimated number of users
@ -647,6 +647,7 @@ dmphy* at mii? phy ? # Davicom DM9101 PHYs
exphy* at mii? phy ? # 3Com internal PHYs
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: INSTALL,v 1.290 2006/10/02 03:28:30 chs Exp $
# $NetBSD: INSTALL,v 1.291 2006/10/21 14:10:33 bouyer Exp $
#
# INSTALL - Installation kernel.
#
@ -616,6 +616,7 @@ glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: INSTALL_LAPTOP,v 1.103 2006/10/02 03:28:30 chs Exp $
# $NetBSD: INSTALL_LAPTOP,v 1.104 2006/10/21 14:10:33 bouyer Exp $
#
# INSTALL - Installation kernel.
#
@ -473,6 +473,7 @@ brgphy* at mii? phy ? # Broadcom BCM5400-family PHYs
exphy* at mii? phy ? # 3Com internal PHYs
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: XEN2_DOM0,v 1.12 2006/10/15 14:34:56 xtraeme Exp $
# $NetBSD: XEN2_DOM0,v 1.13 2006/10/21 14:10:33 bouyer Exp $
include "arch/xen/conf/std.xen"
@ -316,6 +316,7 @@ glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
igphy* at mii? phy ? # Intel IGP01E1000
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.240 2006/10/14 20:08:07 tsutsui Exp $
# $NetBSD: GENERIC,v 1.241 2006/10/21 14:10:33 bouyer Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/macppc/conf/std.macppc"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.240 $"
#ident "GENERIC-$Revision: 1.241 $"
maxusers 32
@ -303,6 +303,7 @@ exphy* at mii? phy ? # 3Com internal PHYs
glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: PMPPC,v 1.41 2006/09/27 21:42:06 manu Exp $
# $NetBSD: PMPPC,v 1.42 2006/10/21 14:10:33 bouyer Exp $
#
# PMPPC
#
@ -278,6 +278,7 @@ exphy* at mii? phy ? # 3Com internal PHYs
glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC32_IP3x,v 1.57 2006/10/20 15:48:37 tsutsui Exp $
# $NetBSD: GENERIC32_IP3x,v 1.58 2006/10/21 14:10:33 bouyer Exp $
#
# GENERIC32_IP3x machine description file
#
@ -28,7 +28,7 @@ makeoptions TEXTADDR="0x80069000" # entry point
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC32_IP3x-$Revision: 1.57 $"
#ident "GENERIC32_IP3x-$Revision: 1.58 $"
maxusers 32
@ -245,6 +245,7 @@ gentbi* at mii? phy ? # Generic Ten-Bit 1000BASE-[CLS]X PHYs
glxtphy* at mii? phy ? # Level One LXT-1000 PHYs
gphyter* at mii? phy ? # NS83861 Gig-E PHY
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
lxtphy* at mii? phy ? # Level One LXT-970 PHYs

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.71 2006/10/19 22:01:18 martin Exp $
# $NetBSD: GENERIC,v 1.72 2006/10/21 14:10:33 bouyer Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/sparc64/conf/std.sparc64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.71 $"
#ident "GENERIC-$Revision: 1.72 $"
maxusers 64
@ -511,6 +511,7 @@ acphy* at mii? phy ? # Altima AC101 and AMD Am79c874 PHYs
dmphy* at mii? phy ? # Davicom DM9101 PHYs
exphy* at mii? phy ? # 3Com internal PHYs
icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
igphy* at mii? phy ? # Intel IGP01E1000

View File

@ -1,4 +1,4 @@
# $NetBSD: files.mii,v 1.38 2006/01/04 21:52:17 xtraeme Exp $
# $NetBSD: files.mii,v 1.39 2006/10/21 14:10:33 bouyer Exp $
defflag opt_mii.h MIIVERBOSE
@ -86,6 +86,10 @@ device igphy: mii_phy
attach igphy at mii
file dev/mii/igphy.c igphy
device ikphy: mii_phy
attach ikphy at mii
file dev/mii/ikphy.c ikphy
device sqphy: mii_phy
attach sqphy at mii
file dev/mii/sqphy.c sqphy

361
sys/dev/mii/ikphy.c Normal file
View File

@ -0,0 +1,361 @@
/* $NetBSD: ikphy.c,v 1.1 2006/10/21 14:10:33 bouyer Exp $ */
/*******************************************************************************
Copyright (c) 2001-2005, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/*
* Copyright (c) 2006 Manuel Bouyer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Manuel Bouyer.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* driver for Intel's i82563 ethernet 10/100/1000 PHY
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ikphy.c,v 1.1 2006/10/21 14:10:33 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <net/if.h>
#include <net/if_media.h>
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
#include <dev/mii/miidevs.h>
#include <dev/mii/ikphyreg.h>
static int ikphymatch(struct device *, struct cfdata *, void *);
static void ikphyattach(struct device *, struct device *, void *);
CFATTACH_DECL(ikphy, sizeof(struct mii_softc),
ikphymatch, ikphyattach, mii_phy_detach, mii_phy_activate);
static int ikphy_service(struct mii_softc *, struct mii_data *, int);
static void ikphy_status(struct mii_softc *);
static void ikphy_setmedia(struct mii_softc *);
static const struct mii_phy_funcs ikphy_funcs = {
ikphy_service, ikphy_status, mii_phy_reset,
};
static const struct mii_phydesc ikphys[] = {
{ MII_OUI_xxMARVELL, MII_MODEL_xxMARVELL_I82563,
MII_STR_xxMARVELL_I82563 },
{ 0, 0,
NULL },
};
static int
ikphymatch(struct device *parent __unused, struct cfdata *match __unused,
void *aux)
{
struct mii_attach_args *ma = aux;
if (mii_phy_match(ma, ikphys) != NULL)
return (10);
return (0);
}
static void
ikphyattach(struct device *parent __unused, struct device *self, void *aux)
{
struct mii_softc *sc = device_private(self);
struct mii_attach_args *ma = aux;
struct mii_data *mii = ma->mii_data;
const struct mii_phydesc *mpd;
mpd = mii_phy_match(ma, ikphys);
aprint_naive(": Media interface\n");
aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
sc->mii_inst = mii->mii_instance;
sc->mii_phy = ma->mii_phyno;
sc->mii_funcs = &ikphy_funcs;
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
sc->mii_anegticks = 5;
PHY_RESET(sc);
sc->mii_capabilities =
PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
if (sc->mii_capabilities & BMSR_EXTSTAT)
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
aprint_normal("%s: ", sc->mii_dev.dv_xname);
if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 &&
(sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0)
aprint_error("no media present");
else
mii_phy_add_media(sc);
aprint_normal("\n");
}
static int
ikphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int reg;
if (!device_is_active(&sc->mii_dev))
return (ENXIO);
switch (cmd) {
case MII_POLLSTAT:
/*
* If we're not polling our PHY instance, just return.
*/
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
return (0);
break;
case MII_MEDIACHG:
/*
* If the media indicates a different PHY instance,
* isolate ourselves.
*/
if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
reg = PHY_READ(sc, MII_BMCR);
PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
return (0);
}
/*
* If the interface is not up, don't do anything.
*/
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
break;
ikphy_setmedia(sc);
break;
case MII_TICK:
/*
* If we're not currently selected, just return.
*/
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
return (0);
if (mii_phy_tick(sc) == EJUSTRETURN)
return (0);
break;
case MII_DOWN:
mii_phy_down(sc);
return (0);
}
/* Update the media status. */
mii_phy_status(sc);
/* Callback if something changed. */
mii_phy_update(sc, cmd);
return (0);
}
static void
ikphy_setmedia(struct mii_softc *sc)
{
uint16_t phy_data;
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
/* Enable CRS on TX for half-duplex operation. */
phy_data = PHY_READ(sc, GG82563_PHY_MAC_SPEC_CTRL);
phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
/* Use 25MHz for both link down and 1000BASE-T for Tx clock */
phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
PHY_WRITE(sc, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
/* set mdi/mid-x options */
phy_data = PHY_READ(sc, GG82563_PHY_SPEC_CTRL);
phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
else
phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
/* set polarity correction */
phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
PHY_WRITE(sc, GG82563_PHY_SPEC_CTRL, phy_data);
/* SW Reset the PHY so all changes take effect */
PHY_RESET(sc);
/* for the i80003 */
phy_data = PHY_READ(sc, GG82563_PHY_SPEC_CTRL_2);
phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
PHY_WRITE(sc, GG82563_PHY_SPEC_CTRL_2, phy_data);
/* Enable Electrical Idle on the PHY */
phy_data = PHY_READ(sc, GG82563_PHY_PWR_MGMT_CTRL);
phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
PHY_WRITE(sc, GG82563_PHY_PWR_MGMT_CTRL, phy_data);
phy_data = PHY_READ(sc, GG82563_PHY_KMRN_MODE_CTRL);
phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
PHY_WRITE(sc, GG82563_PHY_KMRN_MODE_CTRL, phy_data);
/*
* Workaround: Disable padding in Kumeran interface in the MAC
* and in the PHY to avoid CRC errors.
*/
phy_data = PHY_READ(sc, GG82563_PHY_INBAND_CTRL);
phy_data |= GG82563_ICR_DIS_PADDING;
PHY_WRITE(sc, GG82563_PHY_INBAND_CTRL, phy_data);
mii_phy_setmedia(sc);
if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
/*
* when not in auto mode, we need to restart nego
* anyway, or a switch from a fixed mode to another
* fixed mode may not be seen by the switch.
*/
PHY_WRITE(sc, MII_BMCR,
PHY_READ(sc, MII_BMCR) | BMCR_STARTNEG);
}
phy_data = PHY_READ(sc, GG82563_PHY_MAC_SPEC_CTRL);
phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
switch(IFM_SUBTYPE(ife->ifm_media)) {
case IFM_10_T:
phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ;
break;
case IFM_100_TX:
phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25MHZ;
break;
case IFM_1000_T:
phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
break;
}
phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
PHY_WRITE(sc, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
}
static void
ikphy_status(struct mii_softc *sc)
{
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int pssr, bmcr, gtsr, kmrn;
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
pssr = PHY_READ(sc, GG82563_PHY_SPEC_STATUS);
if (pssr & GG82563_PSSR_LINK)
mii->mii_media_status |= IFM_ACTIVE;
bmcr = PHY_READ(sc, MII_BMCR);
if (bmcr & BMCR_ISO) {
mii->mii_media_active |= IFM_NONE;
mii->mii_media_status = 0;
return;
}
if (bmcr & BMCR_LOOP)
mii->mii_media_active |= IFM_LOOP;
if (bmcr & BMCR_AUTOEN) {
/*
* The media status bits are only valid of autonegotiation
* has completed (or it's disabled).
*/
if ((pssr & GG82563_PSSR_SPEED_DUPLEX_RESOLVED) == 0) {
/* Erg, still trying, I guess... */
mii->mii_media_active |= IFM_NONE;
return;
}
switch (pssr & GG82563_PSSR_SPEED_MASK) {
case GG82563_PSSR_SPEED_1000MBPS:
mii->mii_media_active |= IFM_1000_T;
gtsr = PHY_READ(sc, MII_100T2SR);
if (gtsr & GTSR_MS_RES)
mii->mii_media_active |= IFM_ETH_MASTER;
break;
case GG82563_PSSR_SPEED_100MBPS:
mii->mii_media_active |= IFM_100_TX;
break;
case GG82563_PSSR_SPEED_10MBPS:
mii->mii_media_active |= IFM_10_T;
break;
default:
mii->mii_media_active |= IFM_NONE;
mii->mii_media_status = 0;
return;
}
if (pssr & GG82563_PSSR_DUPLEX)
mii->mii_media_active |=
IFM_FDX | mii_phy_flowstatus(sc);
} else
mii->mii_media_active = ife->ifm_media;
kmrn = PHY_READ(sc, GG82563_PHY_KMRN_MODE_CTRL);
if (mii->mii_media_active & IFM_FDX)
kmrn &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
else
kmrn |= GG82563_KMCR_PASS_FALSE_CARRIER;
PHY_WRITE(sc, GG82563_PHY_KMRN_MODE_CTRL, kmrn);
}

197
sys/dev/mii/ikphyreg.h Normal file
View File

@ -0,0 +1,197 @@
/* $NetBSD: ikphyreg.h,v 1.1 2006/10/21 14:10:33 bouyer Exp $ */
/*******************************************************************************
Copyright (c) 2001-2005, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/*
* Copied from the Intel code, and then modified to match NetBSD
* style for MII registers more.
*/
/* Bits...
* 15-5: page
* 4-0: register offset
*/
#define GG82563_PAGE_SHIFT 5
#define GG82563_REG(page, reg) \
(((page) << GG82563_PAGE_SHIFT) | ((reg) & GG82563_MAX_REG_ADDRESS))
#define GG82563_MIN_ALT_REG 30
#define GG82563_MAX_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
#define GG82563_MAX_MULTI_PAGE_REG 0xF /* Registers equal on all pages */
/* GG82563 Specific Registers */
#define GG82563_PHY_SPEC_CTRL GG82563_REG(0, 16) /* PHY Specific Control */
#define GG82563_PSCR_DISABLE_JABBER 0x0001 /* 1=Disable Jabber */
#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Polarity Reversal Disabled */
#define GG82563_PSCR_POWER_DOWN 0x0004 /* 1=Power Down */
#define GG82563_PSCR_COPPER_TRANSMITER_DISABLE 0x0008 /* 1=Transmitter Disabled */
#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060
#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI configuration */
#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX configuration */
#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Automatic crossover */
#define GG82563_PSCR_ENALBE_EXTENDED_DISTANCE 0x0080 /* 1=Enable Extended Distance */
#define GG82563_PSCR_ENERGY_DETECT_MASK 0x0300
#define GG82563_PSCR_ENERGY_DETECT_OFF 0x0000 /* 00,01=Off */
#define GG82563_PSCR_ENERGY_DETECT_RX 0x0200 /* 10=Sense on Rx only (Energy Detect) */
#define GG82563_PSCR_ENERGY_DETECT_RX_TM 0x0300 /* 11=Sense and Tx NLP */
#define GG82563_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force Link Good */
#define GG82563_PSCR_DOWNSHIFT_ENABLE 0x0800 /* 1=Enable Downshift */
#define GG82563_PSCR_DOWNSHIFT_COUNTER_MASK 0x7000
#define GG82563_PSCR_DOWNSHIFT_COUNTER_SHIFT 12
#define GG82563_PHY_SPEC_STATUS GG82563_REG(0, 17) /* PHY Specific Status */
#define GG82563_PSSR_JABBER 0x0001 /* 1=Jabber */
#define GG82563_PSSR_POLARITY 0x0002 /* 1=Polarity Reversed */
#define GG82563_PSSR_LINK 0x0008 /* 1=Link is Up */
#define GG82563_PSSR_ENERGY_DETECT 0x0010 /* 1=Sleep, 0=Active */
#define GG82563_PSSR_DOWNSHIFT 0x0020 /* 1=Downshift */
#define GG82563_PSSR_CROSSOVER_STATUS 0x0040 /* 1=MDIX, 0=MDI */
#define GG82563_PSSR_RX_PAUSE_ENABLED 0x0100 /* 1=Receive Pause Enabled */
#define GG82563_PSSR_TX_PAUSE_ENABLED 0x0200 /* 1=Transmit Pause Enabled */
#define GG82563_PSSR_LINK_UP 0x0400 /* 1=Link Up */
#define GG82563_PSSR_SPEED_DUPLEX_RESOLVED 0x0800 /* 1=Resolved */
#define GG82563_PSSR_PAGE_RECEIVED 0x1000 /* 1=Page Received */
#define GG82563_PSSR_DUPLEX 0x2000 /* 1-Full-Duplex */
#define GG82563_PSSR_SPEED_MASK 0xC000
#define GG82563_PSSR_SPEED_10MBPS 0x0000 /* 00=10Mbps */
#define GG82563_PSSR_SPEED_100MBPS 0x4000 /* 01=100Mbps */
#define GG82563_PSSR_SPEED_1000MBPS 0x8000 /* 10=1000Mbps */
#define GG82563_PHY_INT_ENABLE \
GG82563_REG(0, 18) /* Interrupt Enable */
#define GG82563_PHY_SPEC_STATUS_2 GG82563_REG(0, 19) /* PHY Specific Status 2 */
#define GG82563_PSSR2_JABBER 0x0001 /* 1=Jabber */
#define GG82563_PSSR2_POLARITY_CHANGED 0x0002 /* 1=Polarity Changed */
#define GG82563_PSSR2_ENERGY_DETECT_CHANGED 0x0010 /* 1=Energy Detect Changed */
#define GG82563_PSSR2_DOWNSHIFT_INTERRUPT 0x0020 /* 1=Downshift Detected */
#define GG82563_PSSR2_MDI_CROSSOVER_CHANGE 0x0040 /* 1=Crossover Changed */
#define GG82563_PSSR2_FALSE_CARRIER 0x0100 /* 1=False Carrier */
#define GG82563_PSSR2_SYMBOL_ERROR 0x0200 /* 1=Symbol Error */
#define GG82563_PSSR2_LINK_STATUS_CHANGED 0x0400 /* 1=Link Status Changed */
#define GG82563_PSSR2_AUTO_NEG_COMPLETED 0x0800 /* 1=Auto-Neg Completed */
#define GG82563_PSSR2_PAGE_RECEIVED 0x1000 /* 1=Page Received */
#define GG82563_PSSR2_DUPLEX_CHANGED 0x2000 /* 1=Duplex Changed */
#define GG82563_PSSR2_SPEED_CHANGED 0x4000 /* 1=Speed Changed */
#define GG82563_PSSR2_AUTO_NEG_ERROR 0x8000 /* 1=Auto-Neg Error */
#define GG82563_PHY_RX_ERR_CNTR GG82563_REG(0, 21) /* Receive Error Counter */
#define GG82563_PHY_PAGE_SELECT GG82563_REG(0, 22) /* Page Select */
#define GG82563_PHY_SPEC_CTRL_2 GG82563_REG(0, 26) /* PHY Specific Control 2 */
#define GG82563_PSCR2_10BT_POLARITY_FORCE 0x0002 /* 1=Force Negative Polarity */
#define GG82563_PSCR2_1000MB_TEST_SELECT_MASK 0x000C
#define GG82563_PSCR2_1000MB_TEST_SELECT_NORMAL 0x0000 /* 00,01=Normal Operation */
#define GG82563_PSCR2_1000MB_TEST_SELECT_112NS 0x0008 /* 10=Select 112ns Sequence */
#define GG82563_PSCR2_1000MB_TEST_SELECT_16NS 0x000C /* 11=Select 16ns Sequence */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Negotiation */
#define GG82563_PSCR2_1000BT_DISABLE 0x4000 /* 1=Disable 1000BASE-T */
#define GG82563_PSCR2_TRANSMITER_TYPE_MASK 0x8000
#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_B 0x0000 /* 0=Class B */
#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_A 0x8000 /* 1=Class A */
#define GG82563_PHY_PAGE_SELECT_ALT GG82563_REG(0, 29) /* Alternate Page Select */
#define GG82563_PHY_TEST_CLK_CTRL GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */
#define GG82563_PHY_MAC_SPEC_CTRL GG82563_REG(2, 21) /* MAC Specific Control Register */
/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
#define GG82563_MSCR_TX_CLK_MASK 0x0007
#define GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ 0x0004
#define GG82563_MSCR_TX_CLK_100MBPS_25MHZ 0x0005
#define GG82563_MSCR_TX_CLK_1000MBPS_2_5MHZ 0x0006
#define GG82563_MSCR_TX_CLK_1000MBPS_25MHZ 0x0007
#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */
#define GG82563_PHY_MAC_SPEC_CTRL_2 GG82563_REG(2, 26) /* MAC Specific Control 2 */
#define GG82563_PHY_DSP_DISTANCE GG82563_REG(5, 26) /* DSP Distance */
#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M;
1 = 50-80M;
2 = 80-110M;
3 = 110-140M;
4 = >140M */
/* Page 193 - Port Control Registers */
#define GG82563_PHY_KMRN_MODE_CTRL GG82563_REG(193, 16) /* Kumeran Mode Control */
#define GG82563_KMCR_PHY_LEDS_EN 0x0020 /* 1=PHY LEDs, 0=Kumeran Inband LEDs */
#define GG82563_KMCR_FORCE_LINK_UP 0x0040 /* 1=Force Link Up */
#define GG82563_KMCR_SUPPRESS_SGMII_EPD_EXT 0x0080
#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT_MASK 0x0400
#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT 0x0400 /* 1=6.25MHz, 0=0.8MHz */
#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800
#define GG82563_PHY_PORT_RESET GG82563_REG(193, 17) /* Port Reset */
#define GG82563_PHY_REVISION_ID GG82563_REG(193, 18) /* Revision ID */
#define GG82563_PHY_DEVICE_ID GG82563_REG(193, 19) /* Device ID */
#define GG82563_PHY_PWR_MGMT_CTRL GG82563_REG(193, 20) /* Power Management Control */
#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* 1=Enalbe SERDES Electrical Idle */
#define GG82563_PMCR_DISABLE_PORT 0x0002 /* 1=Disable Port */
#define GG82563_PMCR_DISABLE_SERDES 0x0004 /* 1=Disable SERDES */
#define GG82563_PMCR_REVERSE_AUTO_NEG 0x0008 /* 1=Enable Reverse Auto-Negotiation */
#define GG82563_PMCR_DISABLE_1000_NON_D0 0x0010 /* 1=Disable 1000Mbps Auto-Neg in non D0 */
#define GG82563_PMCR_DISABLE_1000 0x0020 /* 1=Disable 1000Mbps Auto-Neg Always */
#define GG82563_PMCR_REVERSE_AUTO_NEG_D0A 0x0040 /* 1=Enable D0a Reverse Auto-Negotiation */
#define GG82563_PMCR_FORCE_POWER_STATE 0x0080 /* 1=Force Power State */
#define GG82563_PMCR_PROGRAMMED_POWER_STATE_MASK 0x0300
#define GG82563_PMCR_PROGRAMMED_POWER_STATE_DR 0x0000 /* 00=Dr */
#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0U 0x0100 /* 01=D0u */
#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0A 0x0200 /* 10=D0a */
#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D3 0x0300 /* 11=D3 */
#define GG82563_PHY_RATE_ADAPT_CTRL GG82563_REG(193, 25) /* Rate Adaptation Control */
/* Page 194 - KMRN Registers */
#define GG82563_PHY_KMRN_FIFO_CTRL_STAT GG82563_REG(194, 16) /* FIFO's Control/Status */
#define GG82563_PHY_KMRN_CTRL GG82563_REG(194, 17) /* Control */
#define GG82563_PHY_INBAND_CTRL GG82563_REG(194, 18) /* Inband Control */
#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding Use */
#define GG82563_PHY_KMRN_DIAGNOSTIC GG82563_REG(194, 19) /* Diagnostic */
#define GG82563_PHY_ACK_TIMEOUTS GG82563_REG(194, 20) /* Acknowledge Timeouts */
#define GG82563_PHY_ADV_ABILITY GG82563_REG(194, 21) /* Advertised Ability */
#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY GG82563_REG(194, 23) /* Link Partner Advertised Ability */
#define GG82563_PHY_ADV_NEXT_PAGE GG82563_REG(194, 24) /* Advertised Next Page */
#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE GG82563_REG(194, 25) /* Link Partner Advertised Next page */
#define GG82563_PHY_KMRN_MISC GG82563_REG(194, 26) /* Misc. */

View File

@ -1,4 +1,4 @@
$NetBSD: miidevs,v 1.67 2006/09/27 21:50:00 cube Exp $
$NetBSD: miidevs,v 1.68 2006/10/21 14:10:33 bouyer Exp $
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -169,6 +169,7 @@ model yyINTEL I82562G 0x0031 i82562G 10/100 media interface
model yyINTEL I82562EM 0x0032 i82562EM 10/100 media interface
model yyINTEL I82562ET 0x0033 i82562ET 10/100 media interface
model yyINTEL I82553 0x0035 i82553 10/100 media interface
model xxMARVELL I82563 0x000a i82563 10/100/1000 media interface
model yyINTEL IGP01E1000 0x0038 Intel IGP01E1000 Gigabit PHY

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wm.c,v 1.126 2006/10/12 01:31:30 christos Exp $ */
/* $NetBSD: if_wm.c,v 1.127 2006/10/21 14:10:33 bouyer Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.126 2006/10/12 01:31:30 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.127 2006/10/21 14:10:33 bouyer Exp $");
#include "bpfilter.h"
#include "rnd.h"
@ -92,6 +92,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.126 2006/10/12 01:31:30 christos Exp $")
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
#include <dev/mii/mii_bitbang.h>
#include <dev/mii/ikphyreg.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@ -104,7 +105,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.126 2006/10/12 01:31:30 christos Exp $")
#define WM_DEBUG_TX 0x02
#define WM_DEBUG_RX 0x04
#define WM_DEBUG_GMII 0x08
int wm_debug = WM_DEBUG_TX|WM_DEBUG_RX|WM_DEBUG_LINK;
int wm_debug = WM_DEBUG_TX|WM_DEBUG_RX|WM_DEBUG_LINK|WM_DEBUG_GMII;
#define DPRINTF(x, y) if (wm_debug & (x)) printf y
#else
@ -216,6 +217,7 @@ typedef enum {
WM_T_82571, /* i82571 */
WM_T_82572, /* i82572 */
WM_T_82573, /* i82573 */
WM_T_80003, /* i80003 */
} wm_chip_type;
/*
@ -361,18 +363,19 @@ do { \
} while (/*CONSTCOND*/0)
/* sc_flags */
#define WM_F_HAS_MII 0x001 /* has MII */
#define WM_F_EEPROM_HANDSHAKE 0x002 /* requires EEPROM handshake */
#define WM_F_EEPROM_SEMAPHORE 0x004 /* EEPROM with semaphore */
#define WM_F_EEPROM_EERDEEWR 0x008 /* EEPROM access via EERD/EEWR */
#define WM_F_EEPROM_SPI 0x010 /* EEPROM is SPI */
#define WM_F_EEPROM_FLASH 0x020 /* EEPROM is FLASH */
#define WM_F_EEPROM_INVALID 0x040 /* EEPROM not present (bad checksum) */
#define WM_F_IOH_VALID 0x080 /* I/O handle is valid */
#define WM_F_BUS64 0x100 /* bus is 64-bit */
#define WM_F_PCIX 0x200 /* bus is PCI-X */
#define WM_F_CSA 0x400 /* bus is CSA */
#define WM_F_PCIE 0x800 /* bus is PCI-Express */
#define WM_F_HAS_MII 0x0001 /* has MII */
#define WM_F_EEPROM_HANDSHAKE 0x0002 /* requires EEPROM handshake */
#define WM_F_EEPROM_SEMAPHORE 0x0004 /* EEPROM with semaphore */
#define WM_F_EEPROM_EERDEEWR 0x0008 /* EEPROM access via EERD/EEWR */
#define WM_F_EEPROM_SPI 0x0010 /* EEPROM is SPI */
#define WM_F_EEPROM_FLASH 0x0020 /* EEPROM is FLASH */
#define WM_F_EEPROM_INVALID 0x0040 /* EEPROM not present (bad checksum) */
#define WM_F_IOH_VALID 0x0080 /* I/O handle is valid */
#define WM_F_BUS64 0x0100 /* bus is 64-bit */
#define WM_F_PCIX 0x0200 /* bus is PCI-X */
#define WM_F_CSA 0x0400 /* bus is CSA */
#define WM_F_PCIE 0x0800 /* bus is PCI-Express */
#define WM_F_SWFW_SYNC 0x1000 /* Software-Firmware synchronisation */
#ifdef WM_EVENT_COUNTERS
#define WM_EVCNT_INCR(ev) (ev)->ev_count++
@ -502,18 +505,26 @@ static void wm_gmii_i82543_writereg(struct device *, int, int, int);
static int wm_gmii_i82544_readreg(struct device *, int, int);
static void wm_gmii_i82544_writereg(struct device *, int, int, int);
static int wm_gmii_i80003_readreg(struct device *, int, int);
static void wm_gmii_i80003_writereg(struct device *, int, int, int);
static void wm_gmii_statchg(struct device *);
static void wm_gmii_mediainit(struct wm_softc *);
static int wm_gmii_mediachange(struct ifnet *);
static void wm_gmii_mediastatus(struct ifnet *, struct ifmediareq *);
static int wm_kmrn_i80003_readreg(struct wm_softc *, int);
static void wm_kmrn_i80003_writereg(struct wm_softc *, int, int);
static int wm_match(struct device *, struct cfdata *, void *);
static void wm_attach(struct device *, struct device *, void *);
static int wm_is_onboard_nvm_eeprom(struct wm_softc *);
static int wm_get_eeprom_semaphore(struct wm_softc *);
static void wm_put_eeprom_semaphore(struct wm_softc *);
static int wm_get_swsm_semaphore(struct wm_softc *);
static void wm_put_swsm_semaphore(struct wm_softc *);
static int wm_poll_eerd_eewr_done(struct wm_softc *, int);
static int wm_get_swfw_semaphore(struct wm_softc *, uint16_t);
static void wm_put_swfw_semaphore(struct wm_softc *, uint16_t);
CFATTACH_DECL(wm, sizeof(struct wm_softc),
wm_match, wm_attach, NULL, NULL);
@ -624,6 +635,14 @@ static const struct wm_product {
"Intel i82546GB Gigabit Ethernet (SERDES)",
WM_T_82546_3, WMP_F_SERDES },
#endif
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546GB_QUAD_COPPER,
"i82546GB quad-port Gigabit Ethernet",
WM_T_82546_3, WMP_F_1000T },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546GB_QUAD_COPPER_KSP3,
"i82546GB quad-port Gigabit Ethernet (KSP3)",
WM_T_82546_3, WMP_F_1000T },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546GB_PCIE,
"Intel PRO/1000MT (82546GB)",
WM_T_82546_3, WMP_F_1000T },
@ -680,6 +699,10 @@ static const struct wm_product {
"Intel PRO/1000 PB (82571EB)",
WM_T_82571, WMP_F_SERDES },
#endif
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82571EB_QUAD_COPPER,
"Intel PRO/1000 QT (82571EB)",
WM_T_82571, WMP_F_1000T },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82572EI_COPPER,
"Intel i82572EI 1000baseT Ethernet",
WM_T_82572, WMP_F_1000T },
@ -709,6 +732,28 @@ static const struct wm_product {
"Intel i82573L Gigabit Ethernet",
WM_T_82573, WMP_F_1000T },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80K3LAN_CPR_DPT,
"i80003 dual 1000baseT Ethernet",
WM_T_80003, WMP_F_1000T },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80K3LAN_FIB_DPT,
"i80003 dual 1000baseX Ethernet",
WM_T_80003, WMP_F_1000T },
#if 0
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80K3LAN_SDS_DPT,
"Intel i80003ES2 dual Gigabit Ethernet (SERDES)",
WM_T_80003, WMP_F_SERDES },
#endif
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80K3LAN_CPR_SPT,
"Intel i80003 1000baseT Ethernet",
WM_T_80003, WMP_F_1000T },
#if 0
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80K3LAN_SDS_SPT,
"Intel i80003 Gigabit Ethernet (SERDES)",
WM_T_80003, WMP_F_SERDES },
#endif
{ 0, 0,
NULL,
0, 0 },
@ -1102,6 +1147,10 @@ wm_attach(struct device *parent __unused, struct device *self, void *aux)
sc->sc_rxsoft[i].rxs_mbuf = NULL;
}
/* clear interesting stat counters */
CSR_READ(sc, WMREG_COLC);
CSR_READ(sc, WMREG_RXERRC);
/*
* Reset the chip to a known state.
*/
@ -1110,7 +1159,9 @@ wm_attach(struct device *parent __unused, struct device *self, void *aux)
/*
* Get some information about the EEPROM.
*/
if (sc->sc_type == WM_T_82573)
if (sc->sc_type == WM_T_80003)
sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_SWFW_SYNC;
else if (sc->sc_type == WM_T_82573)
sc->sc_flags |= WM_F_EEPROM_EERDEEWR;
else if (sc->sc_type > WM_T_82544)
sc->sc_flags |= WM_F_EEPROM_HANDSHAKE;
@ -1197,7 +1248,7 @@ wm_attach(struct device *parent __unused, struct device *self, void *aux)
* of the dual port controller.
*/
if (sc->sc_type == WM_T_82546 || sc->sc_type == WM_T_82546_3
|| sc->sc_type == WM_T_82571) {
|| sc->sc_type == WM_T_82571 || sc->sc_type == WM_T_80003) {
if ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1)
enaddr[5] ^= 1;
}
@ -2193,7 +2244,6 @@ wm_intr(void *arg)
icr = CSR_READ(sc, WMREG_ICR);
if ((icr & sc->sc_icr) == 0)
break;
#if 0 /*NRND > 0*/
if (RND_ENABLED(&sc->rnd_source))
rnd_add_uint32(&sc->rnd_source, icr);
@ -2614,6 +2664,7 @@ static void
wm_tick(void *arg)
{
struct wm_softc *sc = arg;
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
int s;
s = splnet();
@ -2626,6 +2677,10 @@ wm_tick(void *arg)
WM_EVCNT_ADD(&sc->sc_ev_rx_macctl, CSR_READ(sc, WMREG_FCRUC));
}
ifp->if_collisions += CSR_READ(sc, WMREG_COLC);
ifp->if_ierrors += CSR_READ(sc, WMREG_RXERRC);
if (sc->sc_flags & WM_F_HAS_MII)
mii_tick(&sc->sc_mii);
else
@ -2664,6 +2719,7 @@ wm_reset(struct wm_softc *sc)
break;
case WM_T_82571:
case WM_T_82572:
case WM_T_80003:
sc->sc_pba = PBA_32K;
break;
case WM_T_82573:
@ -2722,6 +2778,18 @@ wm_reset(struct wm_softc *sc)
if (CSR_READ(sc, WMREG_CTRL) & CTRL_RST)
log(LOG_ERR, "%s: reset failed to complete\n",
sc->sc_dev.dv_xname);
if (sc->sc_type == WM_T_80003) {
/* wait for eeprom to reload */
for (i = 1000; i > 0; i--) {
if (CSR_READ(sc, WMREG_EECD) & EECD_EE_AUTORD)
break;
}
if (i == 0) {
log(LOG_ERR, "%s: auto read from eeprom failed to "
"complete\n", sc->sc_dev.dv_xname);
}
}
}
/*
@ -2760,6 +2828,10 @@ wm_init(struct ifnet *ifp)
/* Cancel any pending I/O. */
wm_stop(ifp, 0);
/* update statistics before reset */
ifp->if_collisions += CSR_READ(sc, WMREG_COLC);
ifp->if_ierrors += CSR_READ(sc, WMREG_RXERRC);
/* Reset the chip to a known state. */
wm_reset(sc);
@ -2885,6 +2957,30 @@ wm_init(struct ifnet *ifp)
/* Write the control registers. */
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
if (sc->sc_type >= WM_T_80003 && (sc->sc_flags & WM_F_HAS_MII)) {
int val;
val = CSR_READ(sc, WMREG_CTRL_EXT);
val &= ~CTRL_EXT_LINK_MODE_MASK;
CSR_WRITE(sc, WMREG_CTRL_EXT, val);
/* Bypass RX and TX FIFO's */
wm_kmrn_i80003_writereg(sc, KUMCTRLSTA_OFFSET_FIFO_CTRL,
KUMCTRLSTA_FIFO_CTRL_RX_BYPASS |
KUMCTRLSTA_FIFO_CTRL_TX_BYPASS);
wm_kmrn_i80003_writereg(sc, KUMCTRLSTA_OFFSET_INB_CTRL,
KUMCTRLSTA_INB_CTRL_DIS_PADDING |
KUMCTRLSTA_INB_CTRL_LINK_TMOUT_DFLT);
/*
* Set the mac to wait the maximum time between each
* iteration and increase the max iterations when
* polling the phy; this fixes erroneous timeouts at 10Mbps.
*/
wm_kmrn_i80003_writereg(sc, KUMCTRLSTA_OFFSET_TIMEOUTS, 0xFFFF);
val = wm_kmrn_i80003_readreg(sc, KUMCTRLSTA_OFFSET_INB_PARAM);
val |= 0x3F;
wm_kmrn_i80003_writereg(sc, KUMCTRLSTA_OFFSET_INB_PARAM, val);
}
#if 0
CSR_WRITE(sc, WMREG_CTRL_EXT, sc->sc_ctrl_ext);
#endif
@ -2939,6 +3035,8 @@ wm_init(struct ifnet *ifp)
TCTL_COLD(TX_COLLISION_DISTANCE_FDX);
if (sc->sc_type >= WM_T_82571)
sc->sc_tctl |= TCTL_MULR;
if (sc->sc_type >= WM_T_80003)
sc->sc_tctl |= TCTL_RTLC;
CSR_WRITE(sc, WMREG_TCTL, sc->sc_tctl);
/* Set the media. */
@ -3085,12 +3183,20 @@ wm_acquire_eeprom(struct wm_softc *sc)
{
uint32_t reg;
int x;
int ret = 0;
/* always success */
if ((sc->sc_flags & WM_F_EEPROM_FLASH) != 0)
return 0;
if (wm_get_eeprom_semaphore(sc))
if (sc->sc_flags & WM_F_SWFW_SYNC) {
/* this will also do wm_get_swsm_semaphore() if needed */
ret = wm_get_swfw_semaphore(sc, SWFW_EEP_SM);
} else if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE) {
ret = wm_get_swsm_semaphore(sc);
}
if (ret)
return 1;
if (sc->sc_flags & WM_F_EEPROM_HANDSHAKE) {
@ -3112,7 +3218,10 @@ wm_acquire_eeprom(struct wm_softc *sc)
sc->sc_dev.dv_xname);
reg &= ~EECD_EE_REQ;
CSR_WRITE(sc, WMREG_EECD, reg);
wm_put_eeprom_semaphore(sc);
if (sc->sc_flags & WM_F_SWFW_SYNC)
wm_put_swfw_semaphore(sc, SWFW_EEP_SM);
else if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE)
wm_put_swsm_semaphore(sc);
return (1);
}
}
@ -3140,7 +3249,10 @@ wm_release_eeprom(struct wm_softc *sc)
CSR_WRITE(sc, WMREG_EECD, reg);
}
wm_put_eeprom_semaphore(sc);
if (sc->sc_flags & WM_F_SWFW_SYNC)
wm_put_swfw_semaphore(sc, SWFW_EEP_SM);
else if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE)
wm_put_swsm_semaphore(sc);
}
/*
@ -3815,7 +3927,14 @@ static void
wm_gmii_reset(struct wm_softc *sc)
{
uint32_t reg;
int func = 0; /* XXX gcc */
if (sc->sc_type >= WM_T_80003) {
func = (CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1;
if (wm_get_swfw_semaphore(sc,
func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
return;
}
if (sc->sc_type >= WM_T_82544) {
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET);
delay(20000);
@ -3841,6 +3960,8 @@ wm_gmii_reset(struct wm_softc *sc)
sc->sc_ctrl_ext = reg | CTRL_EXT_SWDPIN(4);
#endif
}
if (sc->sc_type >= WM_T_80003)
wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM);
}
/*
@ -3856,11 +3977,16 @@ wm_gmii_mediainit(struct wm_softc *sc)
/* We have MII. */
sc->sc_flags |= WM_F_HAS_MII;
sc->sc_tipg = TIPG_1000T_DFLT;
if (sc->sc_type >= WM_T_80003)
sc->sc_tipg = TIPG_1000T_80003_DFLT;
else
sc->sc_tipg = TIPG_1000T_DFLT;
/*
* Let the chip set speed/duplex on its own based on
* signals from the PHY.
* XXXbouyer - I'm not sure this is right for the 80003,
* the em driver only sets CTRL_SLU here - but it seems to work.
*/
sc->sc_ctrl |= CTRL_SLU | CTRL_ASDE;
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
@ -3868,7 +3994,10 @@ wm_gmii_mediainit(struct wm_softc *sc)
/* Initialize our media structures and probe the GMII. */
sc->sc_mii.mii_ifp = ifp;
if (sc->sc_type >= WM_T_82544) {
if (sc->sc_type >= WM_T_80003) {
sc->sc_mii.mii_readreg = wm_gmii_i80003_readreg;
sc->sc_mii.mii_writereg = wm_gmii_i80003_writereg;
} else if (sc->sc_type >= WM_T_82544) {
sc->sc_mii.mii_readreg = wm_gmii_i82544_readreg;
sc->sc_mii.mii_writereg = wm_gmii_i82544_writereg;
} else {
@ -3916,9 +4045,36 @@ static int
wm_gmii_mediachange(struct ifnet *ifp)
{
struct wm_softc *sc = ifp->if_softc;
struct ifmedia_entry *ife = sc->sc_mii.mii_media.ifm_cur;
if (ifp->if_flags & IFF_UP)
if (ifp->if_flags & IFF_UP) {
sc->sc_ctrl &= ~(CTRL_SPEED_MASK | CTRL_FD);
sc->sc_ctrl |= CTRL_SLU;
if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
sc->sc_ctrl |= CTRL_ASDE;
} else {
sc->sc_ctrl &= ~CTRL_ASDE;
sc->sc_ctrl |= CTRL_FRCSPD | CTRL_FRCFDX;
if (ife->ifm_media & IFM_FDX)
sc->sc_ctrl |= CTRL_FD;
switch(IFM_SUBTYPE(ife->ifm_media)) {
case IFM_10_T:
sc->sc_ctrl |= CTRL_SPEED_10;
break;
case IFM_100_TX:
sc->sc_ctrl |= CTRL_SPEED_100;
break;
case IFM_1000_T:
sc->sc_ctrl |= CTRL_SPEED_1000;
break;
default:
panic("wm_gmii_mediachange: bad media 0x%x",
ife->ifm_media);
}
}
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
mii_mediachg(&sc->sc_mii);
}
return (0);
}
@ -4041,7 +4197,7 @@ wm_gmii_i82544_readreg(struct device *self, int phy, int reg)
CSR_WRITE(sc, WMREG_MDIC, MDIC_OP_READ | MDIC_PHYADD(phy) |
MDIC_REGADD(reg));
for (i = 0; i < 100; i++) {
for (i = 0; i < 320; i++) {
mdic = CSR_READ(sc, WMREG_MDIC);
if (mdic & MDIC_READY)
break;
@ -4082,7 +4238,7 @@ wm_gmii_i82544_writereg(struct device *self, int phy, int reg, int val)
CSR_WRITE(sc, WMREG_MDIC, MDIC_OP_WRITE | MDIC_PHYADD(phy) |
MDIC_REGADD(reg) | MDIC_DATA(val));
for (i = 0; i < 100; i++) {
for (i = 0; i < 320; i++) {
mdic = CSR_READ(sc, WMREG_MDIC);
if (mdic & MDIC_READY)
break;
@ -4097,6 +4253,70 @@ wm_gmii_i82544_writereg(struct device *self, int phy, int reg, int val)
sc->sc_dev.dv_xname, phy, reg);
}
/*
* wm_gmii_i80003_readreg: [mii interface function]
*
* Read a PHY register on the kumeran
* This could be handled by the PHY layer if we didn't have to lock the
* ressource ...
*/
static int
wm_gmii_i80003_readreg(struct device *self, int phy, int reg)
{
struct wm_softc *sc = (void *) self;
int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1);
int rv;
if (phy != 1) /* only one PHY on kumeran bus */
return 0;
if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
return 0;
if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
reg >> GG82563_PAGE_SHIFT);
} else {
wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT_ALT,
reg >> GG82563_PAGE_SHIFT);
}
rv = wm_gmii_i82544_readreg(self, phy, reg & GG82563_MAX_REG_ADDRESS);
wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM);
return (rv);
}
/*
* wm_gmii_i80003_writereg: [mii interface function]
*
* Write a PHY register on the kumeran.
* This could be handled by the PHY layer if we didn't have to lock the
* ressource ...
*/
static void
wm_gmii_i80003_writereg(struct device *self, int phy, int reg, int val)
{
struct wm_softc *sc = (void *) self;
int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1);
if (phy != 1) /* only one PHY on kumeran bus */
return;
if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
return;
if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
reg >> GG82563_PAGE_SHIFT);
} else {
wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT_ALT,
reg >> GG82563_PAGE_SHIFT);
}
wm_gmii_i82544_writereg(self, phy, reg & GG82563_MAX_REG_ADDRESS, val);
wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM);
}
/*
* wm_gmii_statchg: [mii interface function]
*
@ -4144,6 +4364,64 @@ wm_gmii_statchg(struct device *self)
CSR_WRITE(sc, WMREG_TCTL, sc->sc_tctl);
CSR_WRITE(sc, (sc->sc_type < WM_T_82543) ? WMREG_OLD_FCRTL
: WMREG_FCRTL, sc->sc_fcrtl);
if (sc->sc_type >= WM_T_80003) {
switch(IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
case IFM_1000_T:
wm_kmrn_i80003_writereg(sc, KUMCTRLSTA_OFFSET_HD_CTRL,
KUMCTRLSTA_HD_CTRL_1000_DEFAULT);
sc->sc_tipg = TIPG_1000T_80003_DFLT;
break;
default:
wm_kmrn_i80003_writereg(sc, KUMCTRLSTA_OFFSET_HD_CTRL,
KUMCTRLSTA_HD_CTRL_10_100_DEFAULT);
sc->sc_tipg = TIPG_10_100_80003_DFLT;
break;
}
CSR_WRITE(sc, WMREG_TIPG, sc->sc_tipg);
}
}
/*
* wm_kmrn_i80003_readreg:
*
* Read a kumeran register
*/
static int
wm_kmrn_i80003_readreg(struct wm_softc *sc, int reg)
{
int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1);
int rv;
if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
return 0;
CSR_WRITE(sc, WMREG_KUMCTRLSTA,
((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) |
KUMCTRLSTA_REN);
delay(2);
rv = CSR_READ(sc, WMREG_KUMCTRLSTA) & KUMCTRLSTA_MASK;
wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM);
return (rv);
}
/*
* wm_kmrn_i80003_writereg:
*
* Write a kumeran register
*/
static void
wm_kmrn_i80003_writereg(struct wm_softc *sc, int reg, int val)
{
int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1);
if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
return;
CSR_WRITE(sc, WMREG_KUMCTRLSTA,
((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) |
(val & KUMCTRLSTA_MASK));
wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM);
}
static int
@ -4166,14 +4444,11 @@ wm_is_onboard_nvm_eeprom(struct wm_softc *sc)
}
static int
wm_get_eeprom_semaphore(struct wm_softc *sc)
wm_get_swsm_semaphore(struct wm_softc *sc)
{
int32_t timeout;
uint32_t swsm;
if ((sc->sc_flags & WM_F_EEPROM_SEMAPHORE) == 0)
return 0;
/* Get the FW semaphore. */
timeout = 1000 + 1; /* XXX */
while (timeout) {
@ -4190,23 +4465,65 @@ wm_get_eeprom_semaphore(struct wm_softc *sc)
}
if (timeout == 0) {
aprint_error("%s: could not acquire EEPROM GNT\n",
sc->sc_dev.dv_xname);
/* Release semaphores */
wm_put_eeprom_semaphore(sc);
wm_put_swsm_semaphore(sc);
return 1;
}
return 0;
}
static void
wm_put_eeprom_semaphore(struct wm_softc *sc)
wm_put_swsm_semaphore(struct wm_softc *sc)
{
uint32_t swsm;
if ((sc->sc_flags & WM_F_EEPROM_SEMAPHORE) == 0)
return;
swsm = CSR_READ(sc, WMREG_SWSM);
swsm &= ~(SWSM_SWESMBI);
CSR_WRITE(sc, WMREG_SWSM, swsm);
}
static int
wm_get_swfw_semaphore(struct wm_softc *sc, uint16_t mask) {
uint32_t swfw_sync;
uint32_t swmask = mask << SWFW_SOFT_SHIFT;
uint32_t fwmask = mask << SWFW_FIRM_SHIFT;
int timeout = 200;
for(timeout = 0; timeout < 200; timeout++) {
if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE) {
if (wm_get_swsm_semaphore(sc))
return 1;
}
swfw_sync = CSR_READ(sc, WMREG_SW_FW_SYNC);
if ((swfw_sync & (swmask | fwmask)) == 0) {
swfw_sync |= swmask;
CSR_WRITE(sc, WMREG_SW_FW_SYNC, swfw_sync);
if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE)
wm_put_swsm_semaphore(sc);
return 0;
}
if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE)
wm_put_swsm_semaphore(sc);
delay(5000);
}
printf("%s: failed to get swfw semaphore mask 0x%x swfw 0x%x\n",
sc->sc_dev.dv_xname, mask, swfw_sync);
return 1;
}
static void
wm_put_swfw_semaphore(struct wm_softc *sc, uint16_t mask) {
uint32_t swfw_sync;
if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE) {
while (wm_get_swsm_semaphore(sc) != 0)
continue;
}
swfw_sync = CSR_READ(sc, WMREG_SW_FW_SYNC);
swfw_sync &= ~(mask << SWFW_SOFT_SHIFT);
CSR_WRITE(sc, WMREG_SW_FW_SYNC, swfw_sync);
if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE)
wm_put_swsm_semaphore(sc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wmreg.h,v 1.19 2006/06/10 14:26:52 msaitoh Exp $ */
/* $NetBSD: if_wmreg.h,v 1.20 2006/10/21 14:10:33 bouyer Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -185,6 +185,10 @@ struct livengood_tcpip_ctxdesc {
#define CTRL_SPEED_MASK CTRL_SPEED(3)
#define CTRL_FRCSPD (1U << 11) /* force speed (Livengood) */
#define CTRL_FRCFDX (1U << 12) /* force full-duplex (Livengood) */
#define CTRL_D_UD_EN (1U << 13) /* Dock/Undock enable */
#define CTRL_D_UD_POL (1U << 14) /* Defined polarity of Dock/Undock indication in SDP[0] */
#define CTRL_F_PHY_R (1U << 15) /* Reset both PHY ports, through PHYRST_N pin */
#define CTRL_EXT_LINK_EN (1U << 16) /* enable link status from external LINK_0 and LINK_1 pins */
#define CTRL_SWDPINS_SHIFT 18
#define CTRL_SWDPINS_MASK 0x0f
#define CTRL_SWDPIN(x) (1U << (CTRL_SWDPINS_SHIFT + (x)))
@ -236,6 +240,7 @@ struct livengood_tcpip_ctxdesc {
#define EECD_EE_PRES (1U << 8) /* EEPROM present */
#define EECD_EE_SIZE (1U << 9) /* EEPROM size
(0 = 64 word, 1 = 256 word) */
#define EECD_EE_AUTORD (1U << 9) /* auto read done */
#define EECD_EE_ABITS (1U << 10) /* EEPROM address bits
(based on type) */
#define EECD_EE_TYPE (1U << 13) /* EEPROM type
@ -319,6 +324,12 @@ struct livengood_tcpip_ctxdesc {
#define CTRL_EXT_SPD_BYPS (1U << 15) /* speed select bypass */
#define CTRL_EXT_IPS1 (1U << 16) /* invert power state bit 1 */
#define CTRL_EXT_RO_DIS (1U << 17) /* relaxed ordering disabled */
#define CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define CTRL_EXT_LINK_MODE_GMII 0x00000000
#define CTRL_EXT_LINK_MODE_TBI 0x00C00000
#define CTRL_EXT_LINK_MODE_KMRN 0x00000000
#define CTRL_EXT_LINK_MODE_SERDES 0x00C00000
#define WMREG_MDIC 0x0020 /* MDI Control Register */
#define MDIC_DATA(x) ((x) & 0xffff)
@ -368,6 +379,7 @@ struct livengood_tcpip_ctxdesc {
#define ICR_MDAC (1U << 9) /* MDIO access complete */
#define ICR_RXCFG (1U << 10) /* Receiving /C/ */
#define ICR_GPI(x) (1U << (x)) /* general purpose interrupts */
#define ICR_INT (1U << 31) /* device generated an interrupt */
#define WMREG_ITR 0x00c4 /* Interrupt Throttling Register */
#define ITR_IVAL_MASK 0xffff /* Interval mask */
@ -492,6 +504,12 @@ struct livengood_tcpip_ctxdesc {
#define TX_COLLISION_DISTANCE_HDX 512
#define TX_COLLISION_DISTANCE_FDX 64
#define WMREG_TCTL_EXT 0x0404 /* Transmit Control Register */
#define TCTL_EXT_BST_MASK 0x000003FF /* Backoff Slot Time */
#define TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
#define DEFAULT_80003ES2LAN_TCTL_EXT_GCEX 0x00010000
#define WMREG_TQSA_LO 0x0408
#define WMREG_TQSA_HI 0x040c
@ -504,6 +522,10 @@ struct livengood_tcpip_ctxdesc {
#define TIPG_WM_DFLT (TIPG_IPGT(0x0a) | TIPG_IPGR1(0x02) | TIPG_IPGR2(0x0a))
#define TIPG_LG_DFLT (TIPG_IPGT(0x06) | TIPG_IPGR1(0x08) | TIPG_IPGR2(0x06))
#define TIPG_1000T_DFLT (TIPG_IPGT(0x08) | TIPG_IPGR1(0x08) | TIPG_IPGR2(0x06))
#define TIPG_1000T_80003_DFLT \
(TIPG_IPGT(0x08) | TIPG_IPGR1(0x02) | TIPG_IPGR2(0x07))
#define TIPG_10_100_80003_DFLT \
(TIPG_IPGT(0x09) | TIPG_IPGR1(0x02) | TIPG_IPGR2(0x07))
#define WMREG_TQC 0x0418
@ -584,14 +606,56 @@ struct livengood_tcpip_ctxdesc {
#define RXCSUM_IPOFL (1U << 8) /* IP checksum offload */
#define RXCSUM_TUOFL (1U << 9) /* TCP/UDP checksum offload */
#define WMREG_RXERRC 0x400C /* receive error Count - R/clr */
#define WMREG_COLC 0x4028 /* collision Count - R/clr */
#define WMREG_XONRXC 0x4048 /* XON Rx Count - R/clr */
#define WMREG_XONTXC 0x404c /* XON Tx Count - R/clr */
#define WMREG_XOFFRXC 0x4050 /* XOFF Rx Count - R/clr */
#define WMREG_XOFFTXC 0x4054 /* XOFF Tx Count - R/clr */
#define WMREG_FCRUC 0x4058 /* Flow Control Rx Unsupported Count - R/clr */
#define WMREG_KUMCTRLSTA 0x0034 /* MAC-PHY interface - RW */
#define KUMCTRLSTA_MASK 0x0000FFFF
#define KUMCTRLSTA_OFFSET 0x001F0000
#define KUMCTRLSTA_OFFSET_SHIFT 16
#define KUMCTRLSTA_REN 0x00200000
#define KUMCTRLSTA_OFFSET_FIFO_CTRL 0x00000000
#define KUMCTRLSTA_OFFSET_CTRL 0x00000001
#define KUMCTRLSTA_OFFSET_INB_CTRL 0x00000002
#define KUMCTRLSTA_OFFSET_DIAG 0x00000003
#define KUMCTRLSTA_OFFSET_TIMEOUTS 0x00000004
#define KUMCTRLSTA_OFFSET_INB_PARAM 0x00000009
#define KUMCTRLSTA_OFFSET_HD_CTRL 0x00000010
#define KUMCTRLSTA_OFFSET_M2P_SERDES 0x0000001E
#define KUMCTRLSTA_OFFSET_M2P_MODES 0x0000001F
/* FIFO Control */
#define KUMCTRLSTA_FIFO_CTRL_RX_BYPASS 0x00000008
#define KUMCTRLSTA_FIFO_CTRL_TX_BYPASS 0x00000800
/* In-Band Control */
#define KUMCTRLSTA_INB_CTRL_LINK_TMOUT_DFLT 0x00000500
#define KUMCTRLSTA_INB_CTRL_DIS_PADDING 0x00000010
/* Half-Duplex Control */
#define KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004
#define KUMCTRLSTA_HD_CTRL_1000_DEFAULT 0x00000000
#define WMREG_MDPHYA 0x003C /* PHY address - RW */
#define WMREG_MANC2H 0x5860 /* Managment Control To Host - RW */
#define WMREG_SWSM 0x5b50 /* SW Semaphore */
#define SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
#define SWSM_WMNG 0x00000004 /* Wake MNG Clock */
#define SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
#define WMREG_SW_FW_SYNC 0x5b5c /* software-firmware semaphore */
#define SWFW_EEP_SM 0x0001 /* eeprom access */
#define SWFW_PHY0_SM 0x0002 /* first ctrl phy access */
#define SWFW_PHY1_SM 0x0004 /* second ctrl phy access */
#define SWFW_MAC_CSR_SM 0x0008
#define SWFW_SOFT_SHIFT 0 /* software semaphores */
#define SWFW_FIRM_SHIFT 16 /* firmware semaphores */

View File

@ -1,4 +1,4 @@
$NetBSD: pcidevs,v 1.839 2006/10/09 20:31:03 cube Exp $
$NetBSD: pcidevs,v 1.840 2006/10/21 14:10:33 bouyer Exp $
/*
* Copyright (c) 1995, 1996 Christopher G. Demetriou
@ -1923,7 +1923,11 @@ product INTEL PRO_100_VE_4 0x103d PRO/100 VE (MOB) Network Controller
product INTEL PRO_100_VM_5 0x103e PRO/100 VM (MOB) Network Controller
product INTEL PRO_WL_2100 0x1043 PRO/Wireless LAN 2100 3B Mini-PCI Adapter
product INTEL 82597EX 0x1048 PRO/10GbE LR Server Adapter
product INTEL 82801H_M_AMT 0x1049 i82801H (M_AMT) LAN Controller
product INTEL 82801H_AMT 0x104a i82801H (AMT) LAN Controller
product INTEL 82801H_LAN 0x104b i82801H LAN Controller
product INTEL 82801H_IFE_LAN 0x104c i82801H (IFE) LAN Controller
product INTEL 82801H_M_LAN 0x104d i82801H (M) LAN Controller
product INTEL PRO_100_VM_6 0x1050 PRO/100 VM Network Controller with 82562ET/EZ PHY
product INTEL 82801EB_LAN 0x1051 82801EB/ER 10/100 Ethernet
product INTEL PRO_100_M 0x1059 PRO/100 M Network Controller
@ -1948,9 +1952,16 @@ product INTEL 82573E 0x108b i82573E Gigabit Ethernet
product INTEL 82573E_IAMT 0x108c i82573E Gigabit Ethernet
product INTEL PRO_100_VE_6 0x1092 PRO/100 VE Network Controller
product INTEL PRO_100_VE_7 0x1094 PRO/100 VE Network Controller with 82562G PHY
product INTEL 80K3LAN_CPR_DPT 0x1096 i80003 dual 1000baseT Ethernet
product INTEL 80K3LAN_FIB_DPT 0x1097 i80003 dual 1000baseX Ethernet
product INTEL 80K3LAN_SDS_DPT 0x1098 i80003 dual Gigabit Ethernet (SERDES)
product INTEL 82546GB_QUAD_COPPER 0x1099 i82546GB quad-port Gigabit Ethernet
product INTEL 82573L 0x109a i82573L Gigabit Ethernet
product INTEL 82546GB_QUAD_COPPER 0x1099 PRO/1000MT QP (82546GB)
product INTEL 82572EI 0x10b9 PRO/1000PT (82572EI)
product INTEL 82571EB_QUAD_COPPER 0x10a4 i82571EB quad-1000baseT Ethernet
product INTEL 82546GB_QUAD_COPPER_KSP3 0x10b5 i82546GB quad-port Gigabit Ethernet (KSP3)
product INTEL 82572EI 0x10b9 i82572EI 1000baseT Ethernet
product INTEL 80K3LAN_CPR_SPT 0x10ba i80003 1000baseT Ethernet
product INTEL 80K3LAN_SDS_SPT 0x10bb i80003 Gigabit Ethernet (SERDES)
product INTEL 82815_DC100_HUB 0x1100 82815 Hub
product INTEL 82815_DC100_AGP 0x1101 82815 AGP
product INTEL 82815_DC100_GRAPH 0x1102 82815 Graphics