Add support IC Plus IP1000* PHYs. PR/kern 42314 first reported by

Tomokazu HARADA and patch provided by Andrius V.
This commit is contained in:
msaitoh 2019-10-07 11:53:40 +00:00
parent dd2790e42c
commit d3ce678f8d
15 changed files with 693 additions and 143 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1655 2019/09/21 14:04:12 jmcneill Exp $
# $NetBSD: mi,v 1.1656 2019/10/07 11:53:40 msaitoh Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -1336,6 +1336,7 @@
./usr/share/man/cat4/ip6.0 man-sys-catman .cat
./usr/share/man/cat4/ipf.0 man-ipf-catman ipfilter,.cat
./usr/share/man/cat4/ipfilter.0 man-ipf-catman ipfilter,.cat
./usr/share/man/cat4/ipgphy.0 man-sys-catman .cat
./usr/share/man/cat4/ipip.0 man-obsolete obsolete
./usr/share/man/cat4/ipkdb.0 man-obsolete obsolete
./usr/share/man/cat4/ipl.0 man-ipf-catman ipfilter,.cat
@ -4477,6 +4478,7 @@
./usr/share/man/html4/ip6.html man-sys-htmlman html
./usr/share/man/html4/ipf.html man-ipf-htmlman ipfilter,html
./usr/share/man/html4/ipfilter.html man-ipf-htmlman ipfilter,html
./usr/share/man/html4/ipgphy.html man-sys-htmlman html
./usr/share/man/html4/ipkdb.html man-obsolete obsolete
./usr/share/man/html4/ipl.html man-ipf-htmlman ipfilter,html
./usr/share/man/html4/ipmi.html man-sys-htmlman html
@ -7454,6 +7456,7 @@
./usr/share/man/man4/ip6.4 man-sys-man .man
./usr/share/man/man4/ipf.4 man-sys-man ipfilter,.man
./usr/share/man/man4/ipfilter.4 man-sys-man ipfilter,.man
./usr/share/man/man4/ipgphy.4 man-sys-man .man
./usr/share/man/man4/ipip.4 man-obsolete obsolete
./usr/share/man/man4/ipkdb.4 man-obsolete obsolete
./usr/share/man/man4/ipl.4 man-sys-man ipfilter,.man

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.683 2019/09/21 14:04:12 jmcneill Exp $
# $NetBSD: Makefile,v 1.684 2019/10/07 11:53:40 msaitoh Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@ -32,7 +32,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
ibmcd.4 ibmhawk.4 ichsmb.4 icmp.4 icp.4 icsphy.4 iee.4 ieee80211.4 \
ifmedia.4 igmafb.4 igphy.4 igsfb.4 iha.4 ihidev.4 ihphy.4 iic.4 ims.4 \
inet.4 ikphy.4 inphy.4 intersil7170.4 intro.4 \
ioasic.4 ioat.4 iop.4 iophy.4 iopsp.4 ip.4 ipmi.4 ipw.4 \
ioasic.4 ioat.4 iop.4 iophy.4 iopsp.4 ip.4 ipgphy.4 ipmi.4 ipw.4 \
irmce.4 isp.4 ismt.4 isv.4 itesio.4 iteide.4 iwi.4 iwm.4 iwn.4 ixg.4 \
ixpide.4 ixv.4 \
jme.4 jmide.4 joy.4 \

34
share/man/man4/ipgphy.4 Normal file
View File

@ -0,0 +1,34 @@
.\" $OpenBSD: ipgphy.4,v 1.5 2009/08/08 17:12:40 naddy Exp $
.\"
.\" Copyright (c) 2006 Brad Smith <brad@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: August 8 2009 $
.Dt IPGPHY 4
.Os
.Sh NAME
.Nm ipgphy
.Nd IC Plus IP1000A/IP1001 10/100/Gigabit Ethernet PHY
.Sh SYNOPSIS
.Cd "ipgphy* at mii?"
.Sh DESCRIPTION
The
.Nm
driver supports the IC Plus IP1000A/IP1001 10/100/Gigabit Ethernet PHY
interface.
.Sh SEE ALSO
.Xr ifmedia 4 ,
.Xr intro 4 ,
.Xr mii 4 ,
.Xr ifconfig 8

View File

@ -1,4 +1,4 @@
.\" $NetBSD: mii.4,v 1.27 2014/03/03 09:10:00 wiz Exp $
.\" $NetBSD: mii.4,v 1.28 2019/10/07 11:53:40 msaitoh Exp $
.\"
.\" Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -49,6 +49,7 @@
.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 "ipgphy* at mii? phy ? # IC PLUS IP1000A/IP1001 PHYs"
.Cd "lxtphy* at mii? phy ? # Level One LXT-970 PHYs"
.Cd "makphy* at mii? phy ? # Marvel 88E1000 Gig-E PHYs"
.Cd "micphy* at mii? phy ? # Micrel KSZ9021 Gig-E PHYs"

View File

@ -1,4 +1,4 @@
.\" $NetBSD: vge.4,v 1.7 2014/03/18 18:20:39 riastradh Exp $
.\" $NetBSD: vge.4,v 1.8 2019/10/07 11:53:40 msaitoh Exp $
.\"
.\" Copyright (c) 2004
.\" Bill Paul <wpaul@windriver.com>. All rights reserved.
@ -180,6 +180,7 @@ the network connection (cable). Driver resets the device.
.Sh SEE ALSO
.Xr arp 4 ,
.Xr ciphy 4 ,
.Xr ipgphy 4 ,
.Xr mii 4 ,
.Xr netintro 4 ,
.Xr ukphy 4 ,

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.123 2019/10/03 19:01:13 tnn Exp $
# $NetBSD: ALL,v 1.124 2019/10/07 11:53:40 msaitoh 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/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.123 $"
#ident "ALL-$Revision: 1.124 $"
maxusers 64 # estimated number of users
@ -1105,6 +1105,7 @@ ihphy* at mii? phy ? # Intel 82577 PHYs
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
ipgphy* at mii? phy ? # IC PLUS IP1000A/IP1001 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,v 1.536 2019/10/03 18:57:38 tnn Exp $
# $NetBSD: GENERIC,v 1.537 2019/10/07 11:53:40 msaitoh 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.536 $"
#ident "GENERIC-$Revision: 1.537 $"
maxusers 64 # estimated number of users
@ -874,6 +874,7 @@ ihphy* at mii? phy ? # Intel 82577 PHYs
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
ipgphy* at mii? phy ? # IC PLUS IP1000A/IP1001 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: ALL,v 1.470 2019/08/19 03:25:40 ozaki-r Exp $
# $NetBSD: ALL,v 1.471 2019/10/07 11:53:40 msaitoh 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.470 $"
#ident "ALL-$Revision: 1.471 $"
maxusers 64 # estimated number of users
@ -1209,6 +1209,7 @@ ihphy* at mii? phy ? # Intel 82577 PHYs
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
ipgphy* at mii? phy ? # IC PLUS IP1000A/IP1001 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,v 1.1210 2019/08/09 08:01:06 rin Exp $
# $NetBSD: GENERIC,v 1.1211 2019/10/07 11:53:40 msaitoh 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.1210 $"
#ident "GENERIC-$Revision: 1.1211 $"
maxusers 64 # estimated number of users
@ -1120,6 +1120,7 @@ ihphy* at mii? phy ? # Intel 82577 PHYs
ikphy* at mii? phy ? # Intel 82563 PHYs
inphy* at mii? phy ? # Intel 82555 PHYs
iophy* at mii? phy ? # Intel 82553 PHYs
ipgphy* at mii? phy ? # IC PLUS IP1000A/IP1001 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: DEVNAMES,v 1.321 2019/05/08 13:40:17 isaki Exp $
# $NetBSD: DEVNAMES,v 1.322 2019/10/07 11:53:40 msaitoh Exp $
#
# This file contains all used device names and defined attributes in
# alphabetical order. New devices added to the system somewhere should first
@ -659,6 +659,7 @@ iopsp MI
ipaqbus hpcarm
ipaqlcd hpcarm
ipaqpcic hpcarm
ipgphy MI
ipmi amd64
ipmi i386
ipmi xen

View File

@ -1,4 +1,4 @@
# $NetBSD: files.mii,v 1.50 2014/11/15 19:18:18 christos Exp $
# $NetBSD: files.mii,v 1.51 2019/10/07 11:53:40 msaitoh Exp $
defflag opt_mii.h MIIVERBOSE
@ -99,6 +99,10 @@ device ikphy: mii_phy
attach ikphy at mii
file dev/mii/ikphy.c ikphy
device ipgphy: mii_phy
attach ipgphy at mii
file dev/mii/ipgphy.c ipgphy
device sqphy: mii_phy
attach sqphy at mii
file dev/mii/sqphy.c sqphy

415
sys/dev/mii/ipgphy.c Normal file
View File

@ -0,0 +1,415 @@
/* $OpenBSD: ipgphy.c,v 1.19 2015/07/19 06:28:12 yuo Exp $ */
/*-
* Copyright (c) 2006, Pyun YongHyeon <yongari@FreeBSD.org>
* 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 unmodified, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
*/
/*
* Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ipgphy.c,v 1.1 2019/10/07 11:53:40 msaitoh 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/ipgphyreg.h>
#include <dev/pci/if_stgereg.h>
static int ipgphy_match(device_t, cfdata_t, void *);
static void ipgphy_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(ipgphy, sizeof(struct mii_softc),
ipgphy_match, ipgphy_attach, mii_phy_detach, mii_phy_activate);
static int ipgphy_service(struct mii_softc *, struct mii_data *, int);
static void ipgphy_status(struct mii_softc *);
static int ipgphy_mii_phy_auto(struct mii_softc *);
static void ipgphy_load_dspcode(struct mii_softc *);
static void ipgphy_reset(struct mii_softc *);
static const struct mii_phy_funcs ipgphy_funcs = {
ipgphy_service, ipgphy_status, ipgphy_reset,
};
static const struct mii_phydesc ipgphys[] = {
MII_PHY_DESC(xxICPLUS, IP1000A),
MII_PHY_DESC(xxICPLUS, IP1001),
MII_PHY_END,
};
static int
ipgphy_match(device_t parent, cfdata_t match, void *aux)
{
struct mii_attach_args *ma = aux;
if (mii_phy_match(ma, ipgphys) != NULL) {
return 10;
}
return 0;
}
static void
ipgphy_attach(device_t parent, device_t 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, ipgphys);
aprint_naive(": Media interface\n");
aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
sc->mii_dev = self;
sc->mii_inst = mii->mii_instance;
sc->mii_phy = ma->mii_phyno;
sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
sc->mii_mpd_model = MII_MODEL(ma->mii_id2);
sc->mii_mpd_rev = MII_REV(ma->mii_id2);
sc->mii_funcs = &ipgphy_funcs;
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
sc->mii_flags |= MIIF_NOISOLATE;
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
//sc->mii_capabilities &= ~BMSR_ANEG;
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_phy_add_media(sc);
aprint_normal("\n");
}
static int
ipgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t gig, reg, speed;
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) {
PHY_READ(sc, MII_BMCR, &reg);
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;
PHY_RESET(sc);
switch (IFM_SUBTYPE(ife->ifm_media)) {
case IFM_AUTO:
(void)ipgphy_mii_phy_auto(sc);
goto done;
break;
case IFM_1000_T:
/*
* XXX
* Manual 1000baseT setting doesn't seem to work.
*/
speed = BMCR_S1000;
break;
case IFM_100_TX:
speed = BMCR_S100;
break;
case IFM_10_T:
speed = BMCR_S10;
break;
default:
return EINVAL;
}
if (((ife->ifm_media & IFM_GMASK) & IFM_FDX) != 0) {
speed |= BMCR_FDX;
gig = GTCR_ADV_1000TFDX;
} else
gig = GTCR_ADV_1000THDX;
PHY_WRITE(sc, MII_100T2CR, 0);
PHY_WRITE(sc, MII_BMCR, speed);
if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T)
break;
PHY_WRITE(sc, MII_100T2CR, gig);
PHY_WRITE(sc, MII_BMCR, speed);
if (mii->mii_media.ifm_media & IFM_ETH_MASTER)
gig |= GTCR_MAN_MS | GTCR_ADV_MS;
PHY_WRITE(sc, MII_100T2CR, gig);
done:
break;
case MII_TICK:
/*
* If we're not currently selected, just return.
*/
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
return 0;
/*
* Is the interface even up?
*/
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
return 0;
/*
* Only used for autonegotiation.
*/
if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
sc->mii_ticks = 0;
break;
}
/*
* Check to see if we have link. If we do, we don't
* need to restart the autonegotiation process. Read
* the BMSR twice in case it's latched.
*/
PHY_READ(sc, MII_BMSR, &reg);
PHY_READ(sc, MII_BMSR, &reg);
if (reg & BMSR_LINK) {
/*
* Reset autonegotiation timer to 0 in case the link
* goes down in the next tick.
*/
sc->mii_ticks = 0;
/* See above. */
break;
}
/* Announce link loss right after it happens */
if (sc->mii_ticks++ == 0)
break;
/*
* Only retry autonegotiation every mii_anegticks seconds.
*/
if (sc->mii_ticks <= sc->mii_anegticks)
break;
sc->mii_ticks = 0;
ipgphy_mii_phy_auto(sc);
break;
}
/* Update the media status. */
ipgphy_status(sc);
/* Callback if something changed. */
mii_phy_update(sc, cmd);
return 0;
}
static void
ipgphy_status(struct mii_softc *sc)
{
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, stat, gtsr;
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
PHY_READ(sc, MII_BMSR, &bmsr);
PHY_READ(sc, MII_BMSR, &bmsr);
if (bmsr & BMSR_LINK)
mii->mii_media_status |= IFM_ACTIVE;
PHY_READ(sc, MII_BMCR, &bmcr);
if (bmcr & BMCR_LOOP)
mii->mii_media_active |= IFM_LOOP;
if (bmcr & BMCR_AUTOEN) {
if ((bmsr & BMSR_ACOMP) == 0) {
/* Erg, still trying, I guess... */
mii->mii_media_active |= IFM_NONE;
return;
}
if (sc->mii_mpd_model == MII_MODEL_xxICPLUS_IP1001) {
PHY_READ(sc, IPGPHY_LSR, &stat);
switch (stat & IPGPHY_LSR_SPEED_MASK) {
case IPGPHY_LSR_SPEED_10:
mii->mii_media_active |= IFM_10_T;
break;
case IPGPHY_LSR_SPEED_100:
mii->mii_media_active |= IFM_100_TX;
break;
case IPGPHY_LSR_SPEED_1000:
mii->mii_media_active |= IFM_1000_T;
break;
default:
mii->mii_media_active |= IFM_NONE;
return;
}
if (stat & IPGPHY_LSR_FULL_DUPLEX)
mii->mii_media_active |= IFM_FDX;
else
mii->mii_media_active |= IFM_HDX;
} else {
PHY_READ(sc, STGE_PhyCtrl, &stat);
switch (PC_LinkSpeed(stat)) {
case PC_LinkSpeed_Down:
mii->mii_media_active |= IFM_NONE;
return;
case PC_LinkSpeed_10:
mii->mii_media_active |= IFM_10_T;
break;
case PC_LinkSpeed_100:
mii->mii_media_active |= IFM_100_TX;
break;
case PC_LinkSpeed_1000:
mii->mii_media_active |= IFM_1000_T;
break;
default:
mii->mii_media_active |= IFM_NONE;
return;
}
if (stat & PC_PhyDuplexStatus)
mii->mii_media_active |= IFM_FDX;
else
mii->mii_media_active |= IFM_HDX;
}
if (mii->mii_media_active & IFM_FDX)
mii->mii_media_active |= mii_phy_flowstatus(sc);
if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
PHY_READ(sc, MII_100T2SR, &gtsr);
if (gtsr & GTSR_MS_RES)
mii->mii_media_active |= IFM_ETH_MASTER;
}
} else
mii->mii_media_active = ife->ifm_media;
}
static int
ipgphy_mii_phy_auto(struct mii_softc *sc)
{
uint16_t reg = 0;
if (sc->mii_mpd_model == MII_MODEL_xxICPLUS_IP1001) {
PHY_READ(sc, MII_ANAR, &reg);
reg &= ~(ANAR_PAUSE_SYM | ANAR_PAUSE_ASYM);
reg |= ANAR_NP;
}
reg |= ANAR_10 | ANAR_10_FD | ANAR_TX | ANAR_TX_FD;
if (sc->mii_flags & MIIF_DOPAUSE)
reg |= ANAR_PAUSE_SYM | ANAR_PAUSE_ASYM;
PHY_WRITE(sc, MII_ANAR, reg | ANAR_CSMA);
reg = GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX;
if (sc->mii_mpd_model != MII_MODEL_xxICPLUS_IP1001)
reg |= GTCR_ADV_MS;
PHY_WRITE(sc, MII_100T2CR, reg);
PHY_WRITE(sc, MII_BMCR, BMCR_FDX | BMCR_AUTOEN | BMCR_STARTNEG);
return EJUSTRETURN;
}
static void
ipgphy_load_dspcode(struct mii_softc *sc)
{
PHY_WRITE(sc, 31, 0x0001);
PHY_WRITE(sc, 27, 0x01e0);
PHY_WRITE(sc, 31, 0x0002);
PHY_WRITE(sc, 27, 0xeb8e);
PHY_WRITE(sc, 31, 0x0000);
PHY_WRITE(sc, 30, 0x005e);
PHY_WRITE(sc, 9, 0x0700);
DELAY(50);
}
static void
ipgphy_reset(struct mii_softc *sc)
{
struct ifnet *ifp = sc->mii_pdata->mii_ifp;
uint16_t reg;
mii_phy_reset(sc);
/* clear autoneg/full-duplex as we don't want it after reset */
PHY_READ(sc, MII_BMCR, &reg);
reg &= ~(BMCR_AUTOEN | BMCR_FDX);
PHY_WRITE(sc, MII_BMCR, reg);
if (sc->mii_mpd_model == MII_MODEL_xxICPLUS_IP1000A &&
strcmp(ifp->if_xname, "stge") == 0) {
struct stge_softc *stge_sc = ifp->if_softc;
if (stge_sc->sc_rev >= 0x40 && stge_sc->sc_rev <= 0x4e)
ipgphy_load_dspcode(sc);
}
}

83
sys/dev/mii/ipgphyreg.h Normal file
View File

@ -0,0 +1,83 @@
/* $OpenBSD: ipgphyreg.h,v 1.3 2015/07/19 06:28:12 yuo Exp $ */
/*-
* Copyright (c) 2006, Pyun YongHyeon
* 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 unmodified, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
*/
#ifndef _DEV_MII_IPGPHYREG_H_
#define _DEV_MII_IPGPHYREG_H_
/*
* Registers for the IC Plus IPGA internal PHY.
*/
/* PHY specific control & status register. IP1001 only. */
#define IPGPHY_SCSR 0x10
#define IPGPHY_SCSR_RXPHASE_SEL 0x0001
#define IPGPHY_SCSR_TXPHASE_SEL 0x0002
#define IPGPHY_SCSR_REPEATOR_MODE 0x0004
#define IPGPHY_SCSR_RESERVED1_DEF 0x0008
#define IPGPHY_SCSR_RXCLK_DRV_MASK 0x0060
#define IPGPHY_SCSR_RXCLK_DRV_DEF 0x0040
#define IPGPHY_SCSR_RXD_DRV_MASK 0x0180
#define IPGPHY_SCSR_RXD_DRV_DEF 0x0100
#define IPGPHY_SCSR_JABBER_ENB 0x0200
#define IPGPHY_SCSR_HEART_BEAT_ENB 0x0400
#define IPGPHY_SCSR_DOWNSHIFT_ENB 0x0800
#define IPGPHY_SCSR_RESERVED2_DEF 0x1000
#define IPGPHY_SCSR_LED_DRV_4MA 0x0000
#define IPGPHY_SCSR_LED_DRV_8MA 0x2000
#define IPGPHY_SCSR_LED_MODE_MASK 0xC000
#define IPGPHY_SCSR_LED_MODE_DEF 0x0000
/* PHY link status register. IP1001 only. */
#define IPGPHY_LSR 0x11
#define IPGPHY_LSR_JABBER_DET 0x0200
#define IPGPHY_LSR_APS_SLEEP 0x0400
#define IPGPHY_LSR_MDIX 0x0800
#define IPGPHY_LSR_FULL_DUPLEX 0x1000
#define IPGPHY_LSR_SPEED_10 0x0000
#define IPGPHY_LSR_SPEED_100 0x2000
#define IPGPHY_LSR_SPEED_1000 0x4000
#define IPGPHY_LSR_SPEED_MASK 0x6000
#define IPGPHY_LSR_LINKUP 0x8000
/* PHY specific control register 2. IP1001 only. */
#define IPGPHY_SCR
#define IPGPHY_SCR_SEW_RATE_MASK 0x0003
#define IPGPHY_SCR_SEW_RATE_DEF 0x0003
#define IPGPHY_SCR_AUTO_XOVER 0x0004
#define IPGPHY_SCR_SPEED_10_100_ENB 0x0040
#define IPGPHY_SCR_FIFO_LATENCY_2 0x0000
#define IPGPHY_SCR_FIFO_LATENCY_3 0x0080
#define IPGPHY_SCR_FIFO_LATENCY_4 0x0100
#define IPGPHY_SCR_FIFO_LATENCY_5 0x0180
#define IPGPHY_SCR_MDIX_ENB 0x0200
#define IPGPHY_SCR_RESERVED_DEF 0x0400
#define IPGPHY_SCR_APS_ON 0x0800
#endif /* _DEV_MII_IPGPHYREG_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_stge.c,v 1.70 2019/07/09 08:46:59 msaitoh Exp $ */
/* $NetBSD: if_stge.c,v 1.71 2019/10/07 11:53:40 msaitoh Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_stge.c,v 1.70 2019/07/09 08:46:59 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_stge.c,v 1.71 2019/10/07 11:53:40 msaitoh Exp $");
#include <sys/param.h>
@ -76,135 +76,10 @@ __KERNEL_RCSID(0, "$NetBSD: if_stge.c,v 1.70 2019/07/09 08:46:59 msaitoh Exp $")
#define STGE_VLAN_UNTAG 1
/* #define STGE_VLAN_CFI 1 */
/*
* Transmit descriptor list size.
*/
#define STGE_NTXDESC 256
#define STGE_NTXDESC_MASK (STGE_NTXDESC - 1)
#define STGE_NEXTTX(x) (((x) + 1) & STGE_NTXDESC_MASK)
/*
* Receive descriptor list size.
*/
#define STGE_NRXDESC 256
#define STGE_NRXDESC_MASK (STGE_NRXDESC - 1)
#define STGE_NEXTRX(x) (((x) + 1) & STGE_NRXDESC_MASK)
/*
* Only interrupt every N frames. Must be a power-of-two.
*/
#define STGE_TXINTR_SPACING 16
#define STGE_TXINTR_SPACING_MASK (STGE_TXINTR_SPACING - 1)
/*
* Control structures are DMA'd to the TC9021 chip. We allocate them in
* a single clump that maps to a single DMA segment to make several things
* easier.
*/
struct stge_control_data {
/*
* The transmit descriptors.
*/
struct stge_tfd scd_txdescs[STGE_NTXDESC];
/*
* The receive descriptors.
*/
struct stge_rfd scd_rxdescs[STGE_NRXDESC];
};
#define STGE_CDOFF(x) offsetof(struct stge_control_data, x)
#define STGE_CDTXOFF(x) STGE_CDOFF(scd_txdescs[(x)])
#define STGE_CDRXOFF(x) STGE_CDOFF(scd_rxdescs[(x)])
/*
* Software state for transmit and receive jobs.
*/
struct stge_descsoft {
struct mbuf *ds_mbuf; /* head of our mbuf chain */
bus_dmamap_t ds_dmamap; /* our DMA map */
};
/*
* Software state per device.
*/
struct stge_softc {
device_t sc_dev; /* generic device information */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
struct ethercom sc_ethercom; /* ethernet common data */
int sc_rev; /* silicon revision */
void *sc_ih; /* interrupt cookie */
struct mii_data sc_mii; /* MII/media information */
callout_t sc_tick_ch; /* tick callout */
bus_dmamap_t sc_cddmamap; /* control data DMA map */
#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
/*
* Software state for transmit and receive descriptors.
*/
struct stge_descsoft sc_txsoft[STGE_NTXDESC];
struct stge_descsoft sc_rxsoft[STGE_NRXDESC];
/*
* Control data structures.
*/
struct stge_control_data *sc_control_data;
#define sc_txdescs sc_control_data->scd_txdescs
#define sc_rxdescs sc_control_data->scd_rxdescs
#ifdef STGE_EVENT_COUNTERS
/*
* Event counters.
*/
struct evcnt sc_ev_txstall; /* Tx stalled */
struct evcnt sc_ev_txdmaintr; /* Tx DMA interrupts */
struct evcnt sc_ev_txindintr; /* Tx Indicate interrupts */
struct evcnt sc_ev_rxintr; /* Rx interrupts */
struct evcnt sc_ev_txseg1; /* Tx packets w/ 1 segment */
struct evcnt sc_ev_txseg2; /* Tx packets w/ 2 segments */
struct evcnt sc_ev_txseg3; /* Tx packets w/ 3 segments */
struct evcnt sc_ev_txseg4; /* Tx packets w/ 4 segments */
struct evcnt sc_ev_txseg5; /* Tx packets w/ 5 segments */
struct evcnt sc_ev_txsegmore; /* Tx packets w/ more than 5 segments */
struct evcnt sc_ev_txcopy; /* Tx packets that we had to copy */
struct evcnt sc_ev_rxipsum; /* IP checksums checked in-bound */
struct evcnt sc_ev_rxtcpsum; /* TCP checksums checked in-bound */
struct evcnt sc_ev_rxudpsum; /* UDP checksums checked in-bound */
struct evcnt sc_ev_txipsum; /* IP checksums comp. out-bound */
struct evcnt sc_ev_txtcpsum; /* TCP checksums comp. out-bound */
struct evcnt sc_ev_txudpsum; /* UDP checksums comp. out-bound */
#endif /* STGE_EVENT_COUNTERS */
int sc_txpending; /* number of Tx requests pending */
int sc_txdirty; /* first dirty Tx descriptor */
int sc_txlast; /* last used Tx descriptor */
int sc_rxptr; /* next ready Rx descriptor/descsoft */
int sc_rxdiscard;
int sc_rxlen;
struct mbuf *sc_rxhead;
struct mbuf *sc_rxtail;
struct mbuf **sc_rxtailp;
int sc_txthresh; /* Tx threshold */
uint32_t sc_usefiber:1; /* if we're fiber */
uint32_t sc_stge1023:1; /* are we a 1023 */
uint32_t sc_DMACtrl; /* prototype DMACtrl register */
uint32_t sc_MACCtrl; /* prototype MacCtrl register */
uint16_t sc_IntEnable; /* prototype IntEnable register */
uint16_t sc_ReceiveMode; /* prototype ReceiveMode register */
uint8_t sc_PhyCtrl; /* prototype PhyCtrl register */
};
#define STGE_RXCHAIN_RESET(sc) \
do { \
(sc)->sc_rxtailp = &(sc)->sc_rxhead; \

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_stgereg.h,v 1.5 2008/04/28 20:23:55 martin Exp $ */
/* $NetBSD: if_stgereg.h,v 1.6 2019/10/07 11:53:40 msaitoh Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -32,6 +32,10 @@
#ifndef _DEV_PCI_IF_STGEREG_H_
#define _DEV_PCI_IF_STGEREG_H_
#include <net/if_ether.h>
#include <sys/bus.h>
/*
* Register description for the Sundance Tech. TC9021 10/100/1000
* Ethernet controller.
@ -449,4 +453,129 @@ struct stge_rfd {
#define STGE_EtherStatsPkts1024to1518Octets 0x150
/*
* Transmit descriptor list size.
*/
#define STGE_NTXDESC 256
#define STGE_NTXDESC_MASK (STGE_NTXDESC - 1)
#define STGE_NEXTTX(x) (((x) + 1) & STGE_NTXDESC_MASK)
/*
* Receive descriptor list size.
*/
#define STGE_NRXDESC 256
#define STGE_NRXDESC_MASK (STGE_NRXDESC - 1)
#define STGE_NEXTRX(x) (((x) + 1) & STGE_NRXDESC_MASK)
/*
* Only interrupt every N frames. Must be a power-of-two.
*/
#define STGE_TXINTR_SPACING 16
#define STGE_TXINTR_SPACING_MASK (STGE_TXINTR_SPACING - 1)
/*
* Control structures are DMA'd to the TC9021 chip. We allocate them in
* a single clump that maps to a single DMA segment to make several things
* easier.
*/
struct stge_control_data {
/*
* The transmit descriptors.
*/
struct stge_tfd scd_txdescs[STGE_NTXDESC];
/*
* The receive descriptors.
*/
struct stge_rfd scd_rxdescs[STGE_NRXDESC];
};
/*
* Software state for transmit and receive jobs.
*/
struct stge_descsoft {
struct mbuf *ds_mbuf; /* head of our mbuf chain */
bus_dmamap_t ds_dmamap; /* our DMA map */
};
/*
* Software state per device.
*/
struct stge_softc {
device_t sc_dev; /* generic device information */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
struct ethercom sc_ethercom; /* ethernet common data */
int sc_rev; /* silicon revision */
void *sc_ih; /* interrupt cookie */
struct mii_data sc_mii; /* MII/media information */
callout_t sc_tick_ch; /* tick callout */
bus_dmamap_t sc_cddmamap; /* control data DMA map */
#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
/*
* Software state for transmit and receive descriptors.
*/
struct stge_descsoft sc_txsoft[STGE_NTXDESC];
struct stge_descsoft sc_rxsoft[STGE_NRXDESC];
/*
* Control data structures.
*/
struct stge_control_data *sc_control_data;
#define sc_txdescs sc_control_data->scd_txdescs
#define sc_rxdescs sc_control_data->scd_rxdescs
#ifdef STGE_EVENT_COUNTERS
/*
* Event counters.
*/
struct evcnt sc_ev_txstall; /* Tx stalled */
struct evcnt sc_ev_txdmaintr; /* Tx DMA interrupts */
struct evcnt sc_ev_txindintr; /* Tx Indicate interrupts */
struct evcnt sc_ev_rxintr; /* Rx interrupts */
struct evcnt sc_ev_txseg1; /* Tx packets w/ 1 segment */
struct evcnt sc_ev_txseg2; /* Tx packets w/ 2 segments */
struct evcnt sc_ev_txseg3; /* Tx packets w/ 3 segments */
struct evcnt sc_ev_txseg4; /* Tx packets w/ 4 segments */
struct evcnt sc_ev_txseg5; /* Tx packets w/ 5 segments */
struct evcnt sc_ev_txsegmore; /* Tx packets w/ more than 5 segments */
struct evcnt sc_ev_txcopy; /* Tx packets that we had to copy */
struct evcnt sc_ev_rxipsum; /* IP checksums checked in-bound */
struct evcnt sc_ev_rxtcpsum; /* TCP checksums checked in-bound */
struct evcnt sc_ev_rxudpsum; /* UDP checksums checked in-bound */
struct evcnt sc_ev_txipsum; /* IP checksums comp. out-bound */
struct evcnt sc_ev_txtcpsum; /* TCP checksums comp. out-bound */
struct evcnt sc_ev_txudpsum; /* UDP checksums comp. out-bound */
#endif /* STGE_EVENT_COUNTERS */
int sc_txpending; /* number of Tx requests pending */
int sc_txdirty; /* first dirty Tx descriptor */
int sc_txlast; /* last used Tx descriptor */
int sc_rxptr; /* next ready Rx descriptor/descsoft */
int sc_rxdiscard;
int sc_rxlen;
struct mbuf *sc_rxhead;
struct mbuf *sc_rxtail;
struct mbuf **sc_rxtailp;
int sc_txthresh; /* Tx threshold */
uint32_t sc_usefiber:1; /* if we're fiber */
uint32_t sc_stge1023:1; /* are we a 1023 */
uint32_t sc_DMACtrl; /* prototype DMACtrl register */
uint32_t sc_MACCtrl; /* prototype MacCtrl register */
uint16_t sc_IntEnable; /* prototype IntEnable register */
uint16_t sc_ReceiveMode; /* prototype ReceiveMode register */
uint8_t sc_PhyCtrl; /* prototype PhyCtrl register */
};
#endif /* _DEV_PCI_IF_STGEREG_H_ */