tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
(Ab?)use of MII
Hi,
so I've got NetBSD running on my Banana Pi BPi-R1.
With this board, the gigabit net interface on the processor chip is
connected via mii to a switch chip (BCM 53125). The 5 external ports
of this chip all have their own phys and are brought out for external
connection.
With an unmodified BPI kernel, the mii attach code finds all of those
phys via the mii bus of the processor's ethernet interface and then
enables only one of those. In order to allow for a more appropriate
handling of the configuration, I added a flag to the mii_flags, to be
set by a phy driver to indicate that it wants to be the only phy to be
matched during the mii bus scan. The driver for the broadcom chip sets
this flag, and on attachment sets things up so that the box emulates
the processor ethernet interface being connected to an unmanaged switch.
Would this be an acceptable modification to the mii code?
For now, I'm ignoring the capabilities of the 53125's onboard processor
which can implement some managed switch options as well.
Note that while it was quite easy to obtain a datasheet for the 53125,
for some reason that datasheet lacks the description of the register
which needs to be set for reverse mii operation in order to be able
to transfer packets from the processor to the 53125 and back. So I
had to steal the relevant definition from the linux driver.
Attached are the diffs to the tree needed for this plus the driver
for the 53125.
BTW, does anyone know why cvs -N doesn't handle the new file as one
would expect?
Ciao,
Wolfgang
--
Wolfgang%Solfrank.net@localhost Wolfgang Solfrank
? sys/dev/mii/bswphy.c
Index: sys/arch/evbarm/conf/BPI
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/conf/BPI,v
retrieving revision 1.13
diff -u -r1.13 BPI
--- sys/arch/evbarm/conf/BPI 23 Nov 2014 20:02:37 -0000 1.13
+++ sys/arch/evbarm/conf/BPI 4 Apr 2015 11:46:54 -0000
@@ -312,6 +312,7 @@
midi* at midibus?
+bswphy* at mii? phy ?
rlphy* at mii? phy ?
rgephy* at mii? phy ?
ukphy* at mii? phy ?
Index: sys/dev/mii/files.mii
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/files.mii,v
retrieving revision 1.50
diff -u -r1.50 files.mii
--- sys/dev/mii/files.mii 15 Nov 2014 19:18:18 -0000 1.50
+++ sys/dev/mii/files.mii 4 Apr 2015 11:47:01 -0000
@@ -33,6 +33,10 @@
attach brgphy at mii
file dev/mii/brgphy.c brgphy
+device bswphy: mii_phy
+attach bswphy at mii
+file dev/mii/bswphy.c bswphy
+
device tlphy: mii_phy
attach tlphy at mii
file dev/mii/tlphy.c tlphy
Index: sys/dev/mii/mii.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/mii.c,v
retrieving revision 1.50
diff -u -r1.50 mii.c
--- sys/dev/mii/mii.c 4 Dec 2009 22:37:35 -0000 1.50
+++ sys/dev/mii/mii.c 4 Apr 2015 11:47:01 -0000
@@ -145,6 +145,11 @@
LIST_INSERT_HEAD(&mii->mii_phys, child, mii_list);
child->mii_offset = offset;
mii->mii_instance++;
+ if (child->mii_flags & MIIF_SINGLE) {
+ if (LIST_NEXT(child, mii_list))
+ panic("mii_attach: multiple PHYs with MIIF_SINGLE");
+ break;
+ }
}
offset++;
}
Index: sys/dev/mii/miidevs
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/miidevs,v
retrieving revision 1.122
diff -u -r1.122 miidevs
--- sys/dev/mii/miidevs 9 Nov 2014 17:53:37 -0000 1.122
+++ sys/dev/mii/miidevs 4 Apr 2015 11:47:01 -0000
@@ -189,6 +189,7 @@
model BROADCOM3 BCM5717C 0x0020 BCM5717C 1000BASE-T media interface
model BROADCOM3 BCM5719C 0x0022 BCM5719C 1000BASE-T media interface
model BROADCOM3 BCM57765 0x0024 BCM57765 1000BASE-T media interface
+model BROADCOM3 BCM53125 0x0032 BCM53125 1000BASE-T integrated PHY
model BROADCOM3 BCM5720C 0x0036 BCM5720C 1000BASE-T media interface
model xxBROADCOM_ALT1 BCM5906 0x0004 BCM5906 10/100baseTX media interface
Index: sys/dev/mii/miidevs.h
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/miidevs.h,v
retrieving revision 1.125
diff -u -r1.125 miidevs.h
--- sys/dev/mii/miidevs.h 9 Nov 2014 18:40:19 -0000 1.125
+++ sys/dev/mii/miidevs.h 4 Apr 2015 11:47:01 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: miidevs.h,v 1.125 2014/11/09 18:40:19 riz Exp $ */
+/* $NetBSD$ */
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
@@ -257,6 +257,8 @@
#define MII_STR_BROADCOM3_BCM5719C "BCM5719C 1000BASE-T media interface"
#define MII_MODEL_BROADCOM3_BCM57765 0x0024
#define MII_STR_BROADCOM3_BCM57765 "BCM57765 1000BASE-T media interface"
+#define MII_MODEL_BROADCOM3_BCM53125 0x0032
+#define MII_STR_BROADCOM3_BCM53125 "BCM53125 1000BASE-T integrated PHY"
#define MII_MODEL_BROADCOM3_BCM5720C 0x0036
#define MII_STR_BROADCOM3_BCM5720C "BCM5720C 1000BASE-T media interface"
#define MII_MODEL_xxBROADCOM_ALT1_BCM5906 0x0004
Index: sys/dev/mii/miidevs_data.h
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/miidevs_data.h,v
retrieving revision 1.113
diff -u -r1.113 miidevs_data.h
--- sys/dev/mii/miidevs_data.h 9 Nov 2014 17:54:02 -0000 1.113
+++ sys/dev/mii/miidevs_data.h 4 Apr 2015 11:47:01 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: miidevs_data.h,v 1.113 2014/11/09 17:54:02 nonaka Exp $ */
+/* $NetBSD$ */
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
@@ -98,6 +98,7 @@
{ MII_OUI_BROADCOM3, MII_MODEL_BROADCOM3_BCM5717C, MII_STR_BROADCOM3_BCM5717C },
{ MII_OUI_BROADCOM3, MII_MODEL_BROADCOM3_BCM5719C, MII_STR_BROADCOM3_BCM5719C },
{ MII_OUI_BROADCOM3, MII_MODEL_BROADCOM3_BCM57765, MII_STR_BROADCOM3_BCM57765 },
+ { MII_OUI_BROADCOM3, MII_MODEL_BROADCOM3_BCM53125, MII_STR_BROADCOM3_BCM53125 },
{ MII_OUI_BROADCOM3, MII_MODEL_BROADCOM3_BCM5720C, MII_STR_BROADCOM3_BCM5720C },
{ MII_OUI_xxBROADCOM_ALT1, MII_MODEL_xxBROADCOM_ALT1_BCM5906, MII_STR_xxBROADCOM_ALT1_BCM5906 },
{ MII_OUI_CICADA, MII_MODEL_CICADA_CS8201, MII_STR_CICADA_CS8201 },
Index: sys/dev/mii/miivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/miivar.h,v
retrieving revision 1.62
diff -u -r1.62 miivar.h
--- sys/dev/mii/miivar.h 28 May 2014 09:49:55 -0000 1.62
+++ sys/dev/mii/miivar.h 4 Apr 2015 11:47:01 -0000
@@ -154,6 +154,7 @@
#define MIIF_DOPAUSE 0x0100 /* advertise PAUSE capability */
#define MIIF_IS_HPNA 0x0200 /* is a HomePNA device */
#define MIIF_FORCEANEG 0x0400 /* force auto-negotiation */
+#define MIIF_SINGLE 0x8000 /* Known to be the only PHY here */
#define MIIF_INHERIT_MASK (MIIF_NOISOLATE|MIIF_NOLOOP|MIIF_AUTOTSLEEP)
/* $NetBSD */
/*-
* Copyright (c) 2015 Wolfgang Solfrank.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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) 1998, 1999, 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center, and by Frank van der Linden.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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) 1997 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.
*
* 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 BCM53125 switch PHY.
* We pretend to be connected to an unmanaged switch via an
* unchangeable 1000T-FDX interface.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD $");
#include "opt_mii.h"
#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>
static int bswphymatch(device_t, cfdata_t, void *);
static void bswphyattach(device_t, device_t, void *);
CFATTACH_DECL3_NEW(bswphy, sizeof(struct mii_softc),
bswphymatch, bswphyattach, mii_phy_detach, mii_phy_activate, NULL, NULL,
DVF_DETACH_SHUTDOWN);
static int bswphy_service(struct mii_softc *, struct mii_data *, int);
static void bswphy_status(struct mii_softc *);
static void bswphy_reset(struct mii_softc *);
static const struct mii_phy_funcs bswphy_funcs = {
bswphy_service, bswphy_status, bswphy_reset,
};
/* Access any PHY on the 53125. */
#define BSWPHY_READ(p, phy, r) \
((uint64_t)(*(p)->mii_pdata->mii_readreg)(device_parent((p)->mii_dev), \
(phy), (r)))
#define BSWPHY_WRITE(p, phy, r, v) \
(*(p)->mii_pdata->mii_writereg)(device_parent((p)->mii_dev), \
(phy), (r), (v))
#define PSD_PHY 30 /* Pseudo-PHY within 53125 */
#define PSD_PG 16 /* Page register */
#define PSD_PAGE(pg) \
(((pg) << 8) | 1)
#define PSD_ADDR 17 /* Register address */
#define PSD_OP 3 /* Type of operation */
#define PSD_READ(reg) \
(((reg) << 8) | 2)
#define PSD_WRITE(reg) \
(((reg) << 8) | 1)
#define PSD_0_15 24 /* Bits 0:15 */
#define PSD_16_31 25 /* Bits 16:31 */
#define PSD_32_47 26 /* Bits 32:47 */
#define PSD_48_63 27 /* Bits 48:63 */
#define PSD_CTL_PG 0 /* Control Registers */
/*
* Note that the following register is not described in the
* BCM53125 manual. The definitions used here are extracted
* from the Linux driver.
*/
#define PSD_CTL_POVER 0x0e /* Port override register */
#define PSD_POVER_LINK 0x01
#define PSD_POVER_USE 0x80
#define PSD_CTL_RST 0x79 /* Software Reset Control Register */
#define PSD_SW_RST 0x80
#define PSD_EN_SW_RST 0x10
#define PSD_MGMI_PG 2 /* Managament/Mirroring Registers */
#define PSD_DEVID 0x30 /* Device ID Register */
#define DEV_BCM53125 0x53125
static uint64_t bswphy_pseudoread(struct mii_softc *, int, int);
static void bswphy_pseudowrite(struct mii_softc *, int, int, uint64_t);
static const struct mii_phydesc bswphys[] = {
{ MII_OUI_BROADCOM3, MII_MODEL_BROADCOM3_BCM53125,
MII_STR_BROADCOM3_BCM53125 },
{ 0, 0,
NULL }
};
static int
bswphymatch(device_t parent, cfdata_t match, void *aux)
{
if (mii_phy_match(aux, bswphys) != NULL)
/*
* Should we check the device id from the pseudo phy here?
*/
return 10;
return 0;
}
static void
bswphyattach(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;
int oui = MII_OUI(ma->mii_id1, ma->mii_id2);
int model = MII_MODEL(ma->mii_id2);
int rev = MII_REV(ma->mii_id2);
const char *descr;
uint64_t devid, override;
if ((descr = mii_get_descr(oui, model)) != NULL)
aprint_normal(": %s (OUI 0x%06x, model 0x%04x), rev. %d\n",
descr, oui, model, rev);
else
aprint_normal(": OUI 0x%06x, model 0x%04x, rev. %d\n",
oui, model, rev);
aprint_naive(": Media interface\n");
sc->mii_dev = self;
sc->mii_inst = mii->mii_instance;
sc->mii_phy = ma->mii_phyno; /* PSD_PHY? */
sc->mii_funcs = &bswphy_funcs;
sc->mii_pdata = mii;
sc->mii_flags = (ma->mii_flags & ~MIIF_DOPAUSE)
| MIIF_NOISOLATE | MIIF_SINGLE;
sc->mii_anegticks = MII_ANEGTICKS;
/* Do a soft reset of the device to a known good state */
bswphy_pseudowrite(sc, PSD_CTL_PG, PSD_CTL_RST,
PSD_SW_RST | PSD_EN_SW_RST);
/* Check whether we are really a BCM54125 */
devid = bswphy_pseudoread(sc, PSD_MGMI_PG, PSD_DEVID);
if (devid != DEV_BCM53125)
panic("bswphy: unknown device id %llx", devid);
/*
* Enable reverse MII.
*/
override = bswphy_pseudoread(sc, PSD_CTL_PG, PSD_CTL_POVER)
| PSD_POVER_LINK | PSD_POVER_USE;
bswphy_pseudowrite(sc, PSD_CTL_PG, PSD_CTL_POVER, override);
sc->mii_capabilities = BMSR_EXTSTAT | BMSR_MFPS
| BMSR_ACOMP | BMSR_EXTCAP;
sc->mii_extcapabilities = EXTSR_1000TFDX;
aprint_normal_dev(self, "");
mii_phy_add_media(sc);
aprint_normal("\n");
}
static int
bswphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
switch (cmd) {
case MII_POLLSTAT:
break;
case MII_MEDIACHG:
break;
case MII_TICK:
sc->mii_ticks = 0;
break;
case MII_DOWN:
mii_phy_down(sc);
break;
}
mii_phy_status(sc);
mii_phy_update(sc, cmd);
return 0;
}
static void
bswphy_status(struct mii_softc *phy)
{
struct mii_data *mii = phy->mii_pdata;
/* For now, pretend to be connected vit 1000T Duplex */
mii->mii_media_status = IFM_AVALID | IFM_ACTIVE;
mii->mii_media_active = IFM_ETHER | IFM_1000_T | IFM_FDX;
}
static void
bswphy_reset(struct mii_softc *sc)
{
/* Ignore */
}
static uint64_t
bswphy_pseudoread(struct mii_softc *phy, int page, int reg)
{
uint64_t ret;
BSWPHY_WRITE(phy, PSD_PHY, PSD_PG, PSD_PAGE(page));
BSWPHY_WRITE(phy, PSD_PHY, PSD_ADDR, PSD_READ(reg));
while (BSWPHY_READ(phy, PSD_PHY, PSD_ADDR) & PSD_OP);
ret = BSWPHY_READ(phy, PSD_PHY, PSD_0_15) & 0xffff;
ret |= (BSWPHY_READ(phy, PSD_PHY, PSD_16_31) & 0xffff) << 16;
ret |= (BSWPHY_READ(phy, PSD_PHY, PSD_32_47) & 0xffff) << 32;
ret |= (BSWPHY_READ(phy, PSD_PHY, PSD_48_63) & 0xffff) << 48;
return ret;
}
static void
bswphy_pseudowrite(struct mii_softc *phy, int page, int reg, uint64_t val)
{
BSWPHY_WRITE(phy, PSD_PHY, PSD_PG, PSD_PAGE(page));
BSWPHY_WRITE(phy, PSD_PHY, PSD_0_15, val & 0xffff);
BSWPHY_WRITE(phy, PSD_PHY, PSD_16_31, (val >> 16) & 0xffff);
BSWPHY_WRITE(phy, PSD_PHY, PSD_32_47, (val >> 24) & 0xffff);
BSWPHY_WRITE(phy, PSD_PHY, PSD_48_63, (val >> 32) & 0xffff);
BSWPHY_WRITE(phy, PSD_PHY, PSD_ADDR, PSD_WRITE(reg));
while (BSWPHY_READ(phy, PSD_PHY, PSD_ADDR) & PSD_OP);
}
Home |
Main Index |
Thread Index |
Old Index