Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add support for KSZ80[0456]1, KSZ8721, KSZ9[01]31, KS8731 an...
details: https://anonhg.NetBSD.org/src/rev/9a3457000ccf
branches: trunk
changeset: 460868:9a3457000ccf
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Nov 06 16:02:53 2019 +0000
description:
Add support for KSZ80[0456]1, KSZ8721, KSZ9[01]31, KS8731 and KSZ9477.
It also supports LAN7430's internal PHY. First wrote by nisimura@ and added
some device support by me. Not tested well.
diffstat:
share/man/man4/micphy.4 | 10 +-
sys/dev/mii/micphy.c | 212 ++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 194 insertions(+), 28 deletions(-)
diffs (truncated from 324 to 300 lines):
diff -r d62abbcf09ac -r 9a3457000ccf share/man/man4/micphy.4
--- a/share/man/man4/micphy.4 Wed Nov 06 16:00:33 2019 +0000
+++ b/share/man/man4/micphy.4 Wed Nov 06 16:02:53 2019 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: micphy.4,v 1.2 2014/03/03 09:10:46 wiz Exp $
+.\" $NetBSD: micphy.4,v 1.3 2019/11/06 16:02:53 msaitoh Exp $
.\"
.\" Copyright (c) 2014 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -15,18 +15,20 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd March 3, 2014
+.Dd November 6, 2019
.Dt MICPHY 4
.Os
.Sh NAME
.Nm micphy
-.Nd Micrel KSZ9021 10/100/1000 PHY driver
+.Nd Micrel KSZ8xxx 10/100 and KSZ9xxx 10/100/1000 PHY driver
.Sh SYNOPSIS
.Cd "micphy* at mii? phy ?"
.Sh DESCRIPTION
The
.Nm
-driver currently supports only Micrel KSZ9021RN PHY.
+driver currently supports KSZ80[2345689]1, KSZ87[23]x, KSZ90[23]1, KSZ9131 and
+KSZ9477.
+It also supports LAN7430's internal PHY.
The driver has a fixup for
.Xr evbarm/cpsw 4
which requires Gig-E PHYs to adjust RGMII signal timing.
diff -r d62abbcf09ac -r 9a3457000ccf sys/dev/mii/micphy.c
--- a/sys/dev/mii/micphy.c Wed Nov 06 16:00:33 2019 +0000
+++ b/sys/dev/mii/micphy.c Wed Nov 06 16:02:53 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: micphy.c,v 1.8 2019/03/25 07:34:13 msaitoh Exp $ */
+/* $NetBSD: micphy.c,v 1.9 2019/11/06 16:02:53 msaitoh Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -55,11 +55,11 @@
*/
/*
- * Driver for Micrel KSZ9021RN PHYs
+ * Driver for Micrel KSZ8xxx 10/100 and KSZ9xxx 10/100/1000 PHY.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: micphy.c,v 1.8 2019/03/25 07:34:13 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: micphy.c,v 1.9 2019/11/06 16:02:53 msaitoh Exp $");
#include "opt_mii.h"
@@ -87,19 +87,98 @@
DVF_DETACH_SHUTDOWN);
static int micphy_service(struct mii_softc *, struct mii_data *, int);
+static void micphy_status(struct mii_softc *);
static void micphy_fixup(struct mii_softc *, int, int, device_t);
static const struct mii_phy_funcs micphy_funcs = {
- micphy_service, ukphy_status, micphy_reset,
+ micphy_service, micphy_status, micphy_reset,
+};
+
+struct micphy_softc {
+ struct mii_softc sc_mii;
+ uint32_t sc_lstype; /* Type of link status register */
};
static const struct mii_phydesc micphys[] = {
- MII_PHY_DESC(MICREL, KSZ8081),
- MII_PHY_DESC(MICREL, KSZ9021RNI),
+ MII_PHY_DESC(MICREL, KSZ8041),
+ MII_PHY_DESC(MICREL, KSZ8051), /* +8021,8031 */
+ MII_PHY_DESC(MICREL, KSZ8061),
+ MII_PHY_DESC(MICREL, KSZ8081), /* +8051,8091 */
+ MII_PHY_DESC(MICREL, KS8737),
+ MII_PHY_DESC(MICREL, KSZ9021_8001_8721),
+ MII_PHY_DESC(MICREL, KSZ9031),
+ MII_PHY_DESC(MICREL, KSZ9131),
+ MII_PHY_DESC(MICREL, KSZ9477), /* +LAN7430internal */
MII_PHY_END,
};
-#define MII_KSZ8081_PHYCTL2 0x1f
+/*
+ * Model Rev. Media LSTYPE Devices
+ *
+ * 0x11 100 1F_42 KSZ8041
+ * 0x13 100 1F_42? KSZ8041RNLI
+ * 0x15 ? 100 1E_20 KSZ8051
+ * 0x5 100 1E_20 KSZ8021
+ * 0x6 100 1E_20 KSZ8031
+ * 0x16 ? 100 1E_20 KSZ8081
+ * ? 100 1E_20 KSZ8091
+ * 0x17 100 1E_20 KSZ8061
+ * 0x21 0x0 giga GIGA KSZ9021
+ * 0x1 giga GIGA KSZ9021RLRN
+ * 0x9 100 1F_42 KSZ8721BL/SL
+ * 0x9 100 none? KSZ8721CL
+ * 0xa 100 1F_42 KSZ8001
+ * 0x22 giga GIGA KSZ9031
+ * 0x23 1? gigasw GIGA KSZ9477 (No master/slave bit)
+ * 5? giga GIGA LAN7430internal
+ * 0x24 giga GIGA KSZ9131
+ * 0x32 100 1F_42 KS8737
+ */
+
+/* Type of link status register */
+#define MICPHYF_LSTYPE_DEFAULT 0
+#define MICPHYF_LSTYPE_1F_42 1
+#define MICPHYF_LSTYPE_1E_20 2
+#define MICPHYF_LSTYPE_GIGA 3
+
+/* Return if the device is Gigabit (KSZ9021) */
+#define KSZ_MODEL21H_GIGA(rev) \
+ ((((rev) & 0x0e) == 0) ? true : false)
+
+#define KSZ_XREG_CONTROL 0x0b
+#define KSZ_XREG_WRITE 0x0c
+#define KSZ_XREG_READ 0x0d
+#define KSZ_XREG_CTL_SEL_READ 0x0000
+#define KSZ_XREG_CTL_SEL_WRITE 0x8000
+
+#define REG_RGMII_CLOCK_AND_CONTROL 0x104
+#define REG_RGMII_RX_DATA 0x105
+
+/* PHY control 1 register for 10/100 PHYs (KSZ80[235689]1) */
+#define KSZ8051_PHYCTL1 0x1e
+#define KSZ8051_PHY_LINK 0x0100
+#define KSZ8051_PHY_MDIX 0x0020
+#define KSZ8051_PHY_FDX 0x0004
+#define KSZ8051_PHY_SPD_MASK 0x0003
+#define KSZ8051_PHY_SPD_10T 0x0001
+#define KSZ8051_PHY_SPD_100TX 0x0002
+
+/* PHY control 2 register for 10/100 PHYs (KSZ8041, KSZ8721 and KSZ8001) */
+#define KSZ8041_PHYCTL2 0x1f
+#define KSZ8041_PHY_ACOMP 0x0080
+#define KSZ8041_PHY_SPD_MASK 0x001c
+#define KSZ8041_PHY_SPD_10T 0x0004
+#define KSZ8041_PHY_SPD_100TX 0x0008
+#define KSZ8041_PHY_FDX 0x0010
+#define KSZ8051_PHYCTL2 0x1f
+
+/* PHY control register for Gigabit PHYs */
+#define KSZ_GPHYCTL 0x1f
+#define KSZ_GPHY_SPD_1000T 0x0040
+#define KSZ_GPHY_SPD_100TX 0x0020
+#define KSZ_GPHY_SPD_10T 0x0010
+#define KSZ_GPHY_FDX 0x0008
+#define KSZ_GPHY_1000T_MS 0x0004
static int
micphymatch(device_t parent, cfdata_t match, void *aux)
@@ -115,7 +194,8 @@
static void
micphyattach(device_t parent, device_t self, void *aux)
{
- struct mii_softc *sc = device_private(self);
+ struct micphy_softc *msc = device_private(self);
+ struct mii_softc *sc = &msc->sc_mii;
struct mii_attach_args *ma = aux;
struct mii_data *mii = ma->mii_data;
int model = MII_MODEL(ma->mii_id2);
@@ -134,6 +214,25 @@
sc->mii_flags = ma->mii_flags;
sc->mii_anegticks = MII_ANEGTICKS;
+ if ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8041)
+ || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8041RNLI)
+ || (sc->mii_mpd_model == MII_MODEL_MICREL_KS8737)
+ || ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9021_8001_8721)
+ && !KSZ_MODEL21H_GIGA(sc->mii_mpd_rev))) {
+ msc->sc_lstype = MICPHYF_LSTYPE_1F_42;
+ } else if ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8051)
+ || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081)
+ || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8061)) {
+ msc->sc_lstype = MICPHYF_LSTYPE_1E_20;
+ } else if (((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9021_8001_8721)
+ && KSZ_MODEL21H_GIGA(sc->mii_mpd_rev))
+ || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031)
+ || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9477)
+ || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9131)) {
+ msc->sc_lstype = MICPHYF_LSTYPE_GIGA;
+ } else
+ msc->sc_lstype = MICPHYF_LSTYPE_DEFAULT;
+
PHY_RESET(sc);
micphy_fixup(sc, model, rev, parent);
@@ -164,10 +263,10 @@
* behavior).
*/
if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081)
- PHY_READ(sc, MII_KSZ8081_PHYCTL2, ®);
+ PHY_READ(sc, KSZ8051_PHYCTL2, ®);
mii_phy_reset(sc);
if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081)
- PHY_WRITE(sc, MII_KSZ8081_PHYCTL2, reg);
+ PHY_WRITE(sc, KSZ8051_PHYCTL2, reg);
}
static int
@@ -223,24 +322,15 @@
return 0;
}
-#define XREG_CONTROL 0x0b
-#define XREG_WRITE 0x0c
-#define XREG_READ 0x0d
-#define XREG_CTL_SEL_READ 0x0000
-#define XREG_CTL_SEL_WRITE 0x8000
-
-#define REG_RGMII_CLOCK_AND_CONTROL 0x104
-#define REG_RGMII_RX_DATA 0x105
-
static void
micphy_writexreg(struct mii_softc *sc, uint32_t reg, uint32_t wval)
{
uint16_t rval __debugused;
- PHY_WRITE(sc, XREG_CONTROL, XREG_CTL_SEL_WRITE | reg);
- PHY_WRITE(sc, XREG_WRITE, wval);
- PHY_WRITE(sc, XREG_CONTROL, XREG_CTL_SEL_READ | reg);
- PHY_READ(sc, XREG_READ, &rval);
+ PHY_WRITE(sc, KSZ_XREG_CONTROL, KSZ_XREG_CTL_SEL_WRITE | reg);
+ PHY_WRITE(sc, KSZ_XREG_WRITE, wval);
+ PHY_WRITE(sc, KSZ_XREG_CONTROL, KSZ_XREG_CTL_SEL_READ | reg);
+ PHY_READ(sc, KSZ_XREG_READ, &rval);
KDASSERT(wval == rval);
}
@@ -248,7 +338,7 @@
micphy_fixup(struct mii_softc *sc, int model, int rev, device_t parent)
{
switch (model) {
- case MII_MODEL_MICREL_KSZ9021RNI:
+ case MII_MODEL_MICREL_KSZ9021_8001_8721:
if (!device_is_a(parent, "cpsw"))
break;
@@ -268,3 +358,77 @@
return;
}
+
+static void
+micphy_status(struct mii_softc *sc)
+{
+ struct micphy_softc *msc = device_private(sc->mii_dev);
+ struct mii_data *mii = sc->mii_pdata;
+ uint16_t bmsr, bmcr, sr;
+
+ /* For unknown devices */
+ if (msc->sc_lstype == MICPHYF_LSTYPE_DEFAULT) {
+ ukphy_status(sc);
+ return;
+ }
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ PHY_READ(sc, MII_BMCR, &bmcr);
+
+ PHY_READ(sc, MII_BMSR, &bmsr);
+ PHY_READ(sc, MII_BMSR, &bmsr);
+ if (bmsr & BMSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ if (bmcr & BMCR_AUTOEN) {
+ if ((bmsr & BMSR_ACOMP) == 0) {
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+ }
+
+ if (msc->sc_lstype == MICPHYF_LSTYPE_1F_42) {
+ PHY_READ(sc, KSZ8041_PHYCTL2, &sr);
+ if ((sr & KSZ8041_PHY_SPD_MASK) == 0)
+ mii->mii_media_active |= IFM_NONE;
+ else if (sr & KSZ8041_PHY_SPD_100TX)
+ mii->mii_media_active |= IFM_100_TX;
+ else if (sr & KSZ8041_PHY_SPD_10T)
+ mii->mii_media_active |= IFM_10_T;
+ if (sr & KSZ8041_PHY_FDX)
+ mii->mii_media_active |= IFM_FDX
+ | mii_phy_flowstatus(sc);
+ } else if (msc->sc_lstype == MICPHYF_LSTYPE_1E_20) {
+ PHY_READ(sc, KSZ8051_PHYCTL1, &sr);
+ if ((sr & KSZ8051_PHY_SPD_MASK) == 0)
+ mii->mii_media_active |= IFM_NONE;
+ else if (sr & KSZ8051_PHY_SPD_100TX)
+ mii->mii_media_active |= IFM_100_TX;
+ else if (sr & KSZ8051_PHY_SPD_10T)
+ mii->mii_media_active |= IFM_10_T;
Home |
Main Index |
Thread Index |
Old Index