Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-9]: src/sys/dev/pci Pull up following revision(s) (requested by n...
details: https://anonhg.NetBSD.org/src/rev/519c6311d9e2
branches: netbsd-9
changeset: 460926:519c6311d9e2
user: martin <martin%NetBSD.org@localhost>
date: Sun Nov 10 13:05:15 2019 +0000
description:
Pull up following revision(s) (requested by nisimura in ticket #406):
sys/dev/pci/if_kse.c: revision 1.40
sys/dev/pci/if_kse.c: revision 1.41
sys/dev/pci/if_kse.c: revision 1.39
comment touchup
-
clarify 8842 MAC behaves 100FDX only has no alternative media selection
possible.
-
major rework to fix link control breakage
diffstat:
sys/dev/pci/if_kse.c | 231 +++++++++++++++++++++++++-------------------------
1 files changed, 114 insertions(+), 117 deletions(-)
diffs (truncated from 342 to 300 lines):
diff -r 3c648db1d23e -r 519c6311d9e2 sys/dev/pci/if_kse.c
--- a/sys/dev/pci/if_kse.c Sun Nov 10 12:58:29 2019 +0000
+++ b/sys/dev/pci/if_kse.c Sun Nov 10 13:05:15 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_kse.c,v 1.38 2019/05/29 10:07:29 msaitoh Exp $ */
+/* $NetBSD: if_kse.c,v 1.38.2.1 2019/11/10 13:05:15 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -29,9 +29,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * Micrel 8841/8842 10/100 ethernet driver
+ */
+
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_kse.c,v 1.38 2019/05/29 10:07:29 msaitoh Exp $");
-
+__KERNEL_RCSID(0, "$NetBSD: if_kse.c,v 1.38.2.1 2019/11/10 13:05:15 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -58,6 +61,8 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
+#define KSE_LINKDEBUG 0
+
#define CSR_READ_4(sc, off) \
bus_space_read_4(sc->sc_st, sc->sc_sh, off)
#define CSR_WRITE_4(sc, off, val) \
@@ -93,6 +98,17 @@
#define P1SR 0x514 /* port 1 status */
#define P2CR4 0x532 /* port 2 control 4 */
#define P2SR 0x534 /* port 2 status */
+#define PxCR_STARTNEG (1U << 9) /* restart auto negotiation */
+#define PxCR_AUTOEN (1U << 7) /* auto negotiation enable */
+#define PxCR_SPD100 (1U << 6) /* force speed 100 */
+#define PxCR_USEFDX (1U << 5) /* force full duplex */
+#define PxCR_USEFC (1U << 4) /* advertise pause flow control */
+#define PxSR_ACOMP (1U << 6) /* auto negotiation completed */
+#define PxSR_SPD100 (1U << 10) /* speed is 100Mbps */
+#define PxSR_FDX (1U << 9) /* full duplex */
+#define PxSR_LINKUP (1U << 5) /* link is good */
+#define PxSR_RXFLOW (1U << 12) /* receive flow control active */
+#define PxSR_TXFLOW (1U << 11) /* transmit flow control active */
#define TXC_BS_MSK 0x3f000000 /* burst size */
#define TXC_BS_SFT (24) /* 1,2,4,8,16,32 or 0 for unlimited */
@@ -207,8 +223,8 @@
void *sc_ih; /* interrupt cookie */
struct ifmedia sc_media; /* ifmedia information */
- int sc_media_status; /* PHY */
- int sc_media_active; /* PHY */
+ int sc_linkstatus; /* last P1SR register value */
+
callout_t sc_callout; /* MII tick callout */
callout_t sc_stat_ch; /* statistics counter callout */
@@ -313,11 +329,10 @@
static void rxintr(struct kse_softc *);
static void txreap(struct kse_softc *);
static void lnkchg(struct kse_softc *);
-static int ifmedia_upd(struct ifnet *);
-static void ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static int ksephy_change(struct ifnet *);
+static void ksephy_status(struct ifnet *, struct ifmediareq *);
+static void nopifm_status(struct ifnet *, struct ifmediareq *);
static void phy_tick(void *);
-static int ifmedia2_upd(struct ifnet *);
-static void ifmedia2_sts(struct ifnet *, struct ifmediareq *);
#ifdef KSE_EVENT_COUNTERS
static void stat_tick(void *);
static void zerostats(struct kse_softc *);
@@ -493,8 +508,9 @@
/* Initialize ifmedia structures. */
ifm = &sc->sc_media;
sc->sc_ethercom.ec_ifmedia = ifm;
+ sc->sc_linkstatus = 0;
if (sc->sc_chip == 0x8841) {
- ifmedia_init(ifm, 0, ifmedia_upd, ifmedia_sts);
+ ifmedia_init(ifm, 0, ksephy_change, ksephy_status);
ifmedia_add(ifm, IFM_ETHER | IFM_10_T, 0, NULL);
ifmedia_add(ifm, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
ifmedia_add(ifm, IFM_ETHER | IFM_100_TX, 0, NULL);
@@ -502,9 +518,18 @@
ifmedia_add(ifm, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(ifm, IFM_ETHER | IFM_AUTO);
} else {
- ifmedia_init(ifm, 0, ifmedia2_upd, ifmedia2_sts);
- ifmedia_add(ifm, IFM_ETHER | IFM_AUTO, 0, NULL);
- ifmedia_set(ifm, IFM_ETHER | IFM_AUTO);
+ /*
+ * pretend 100FDX w/ no alternative media selection.
+ * 8842 MAC is tied with a builtin 3 port switch.
+ * It can do rate control over either of tx / rx direction
+ * respectively, tough, this driver leaves the rate unlimited
+ * intending 100Mbps maximum.
+ * 2 ports behave in AN mode and this driver provides no mean
+ * to see the exact details.
+ */
+ ifmedia_init(ifm, 0, NULL, nopifm_status);
+ ifmedia_add(ifm, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
+ ifmedia_set(ifm, IFM_ETHER | IFM_100_TX | IFM_FDX);
}
printf("%s: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto\n",
@@ -522,7 +547,7 @@
IFQ_SET_READY(&ifp->if_snd);
/*
- * KSZ8842 can handle 802.1Q VLAN-sized frames,
+ * capable of 802.1Q VLAN-sized frames,
* can do IPv4, TCPv4, and UDPv4 checksums in hardware.
*/
sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
@@ -766,7 +791,8 @@
kse_set_filter(sc);
/* set current media */
- (void)ifmedia_upd(ifp);
+ if (sc->sc_chip == 0x8841)
+ (void)ksephy_change(ifp);
/* enable transmitter and receiver */
CSR_WRITE_4(sc, MDTXC, sc->sc_txc);
@@ -1257,92 +1283,92 @@
{
struct ifmediareq ifmr;
-#if 0 /* rambling link status */
- printf("%s: link %s\n", device_xname(sc->sc_dev),
- (CSR_READ_2(sc, P1SR) & (1U << 5)) ? "up" : "down");
+#if KSE_LINKDEBUG > 0
+printf("link change detected\n");
#endif
- ifmedia_sts(&sc->sc_ethercom.ec_if, &ifmr);
+ ksephy_status(&sc->sc_ethercom.ec_if, &ifmr);
}
static int
-ifmedia_upd(struct ifnet *ifp)
+ksephy_change(struct ifnet *ifp)
{
struct kse_softc *sc = ifp->if_softc;
struct ifmedia *ifm = &sc->sc_media;
- uint16_t ctl;
-
- ctl = 0;
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) {
- ctl |= (1U << 13); /* Restart AN */
- ctl |= (1U << 7); /* Enable AN */
- ctl |= (1U << 4); /* Advertise flow control pause */
- ctl |= (1U << 3) | (1U << 2) | (1U << 1) | (1U << 0);
+ uint16_t p1cr4;
+#if KSE_LINKDEBUG > 0
+printf("ifm_media: %x\n", ifm->ifm_cur->ifm_media);
+#endif
+ p1cr4 = 0;
+ if (IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_AUTO) {
+ p1cr4 |= PxCR_STARTNEG; /* restart AN */
+ p1cr4 |= PxCR_AUTOEN; /* enable AN */
+ p1cr4 |= PxCR_USEFC; /* advertise flow control pause */
+ p1cr4 |= 0xf; /* advertise 100-FDX,100-HDX,10-FDX,10-HDX */
+ } else {
+ if (IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_100_TX)
+ p1cr4 |= PxCR_SPD100;
+ if (ifm->ifm_media & IFM_FDX)
+ p1cr4 |= PxCR_USEFDX;
}
- else {
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX)
- ctl |= (1U << 6);
- if (ifm->ifm_media & IFM_FDX)
- ctl |= (1U << 5);
- }
- CSR_WRITE_2(sc, P1CR4, ctl);
-
- sc->sc_media_active = IFM_NONE;
- sc->sc_media_status = IFM_AVALID;
-
+ CSR_WRITE_2(sc, P1CR4, p1cr4);
+#if KSE_LINKDEBUG > 0
+printf("P1CR4: %04x\n", p1cr4);
+#endif
return 0;
}
static void
-ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+ksephy_status(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct kse_softc *sc = ifp->if_softc;
+ int media_status;
+ u_int media_active;
+ uint16_t p1cr4, p1sr;
+
+ media_status = IFM_AVALID;
+ media_active = IFM_ETHER;
+
+ p1cr4 = CSR_READ_2(sc, P1CR4);
+ p1sr = CSR_READ_2(sc, P1SR);
+#if KSE_LINKDEBUG > 0
+printf("P1SR: %04x link %s\n", p1sr, (p1sr & PxSR_LINKUP) ? "up" : "down");
+#endif
+ sc->sc_linkstatus = p1sr;
+ if (p1sr & PxSR_LINKUP)
+ media_status |= IFM_ACTIVE;
+
+ if (p1cr4 & PxCR_AUTOEN) {
+ if ((p1sr & PxSR_ACOMP) == 0) {
+ media_active |= IFM_NONE;
+ goto out; /* Negotiation in progress */
+ }
+ }
+
+ media_active |= (p1sr & PxSR_SPD100) ? IFM_100_TX : IFM_10_T;
+ if (p1sr & PxSR_FDX)
+ media_active |= IFM_FDX;
+ if (p1sr & PxSR_RXFLOW)
+ media_active |= IFM_FLOW | IFM_ETH_RXPAUSE;
+ if (p1sr & PxSR_TXFLOW)
+ media_active |= IFM_FLOW | IFM_ETH_TXPAUSE;
+ out:
+ ifmr->ifm_active = media_active;
+ ifmr->ifm_status = media_status;
+}
+
+static void
+nopifm_status(struct ifnet *ifp, struct ifmediareq *ifmr)
{
struct kse_softc *sc = ifp->if_softc;
struct ifmedia *ifm = &sc->sc_media;
- uint16_t ctl, sts, result;
-
- ifmr->ifm_status = IFM_AVALID;
- ifmr->ifm_active = IFM_ETHER;
- ctl = CSR_READ_2(sc, P1CR4);
- sts = CSR_READ_2(sc, P1SR);
- if ((sts & (1U << 5)) == 0) {
- ifmr->ifm_active |= IFM_NONE;
- goto out; /* Link is down */
- }
- ifmr->ifm_status |= IFM_ACTIVE;
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) {
- if ((sts & (1U << 6)) == 0) {
- ifmr->ifm_active |= IFM_NONE;
- goto out; /* Negotiation in progress */
- }
- result = ctl & sts & 017;
- if (result & (1U << 3))
- ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
- else if (result & (1U << 2))
- ifmr->ifm_active |= IFM_100_TX | IFM_HDX;
- else if (result & (1U << 1))
- ifmr->ifm_active |= IFM_10_T | IFM_FDX;
- else if (result & (1U << 0))
- ifmr->ifm_active |= IFM_10_T | IFM_HDX;
- else
- ifmr->ifm_active |= IFM_NONE;
- if (ctl & (1U << 4))
- ifmr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE;
- if (sts & (1U << 4))
- ifmr->ifm_active |= IFM_FLOW | IFM_ETH_TXPAUSE;
- }
- else {
- ifmr->ifm_active |= (sts & (1U << 10)) ? IFM_100_TX : IFM_10_T;
- if (sts & (1U << 9))
- ifmr->ifm_active |= IFM_FDX;
- if (sts & (1U << 12))
- ifmr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE;
- if (sts & (1U << 11))
- ifmr->ifm_active |= IFM_FLOW | IFM_ETH_TXPAUSE;
- }
+#if KSE_LINKDEBUG > 1
+printf("p1sr: %04x, p2sr: %04x\n", CSR_READ_2(sc, P1SR), CSR_READ_2(sc, P2SR));
+#endif
- out:
- sc->sc_media_status = ifmr->ifm_status;
- sc->sc_media_active = ifmr->ifm_active;
+ /* 8842 MAC pretends 100FDX all the time */
+ ifmr->ifm_active = ifm->ifm_cur->ifm_media;
+ ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
}
static void
@@ -1351,46 +1377,17 @@
struct kse_softc *sc = arg;
struct ifmediareq ifmr;
int s;
+ uint16_t p1sr;
s = splnet();
- ifmedia_sts(&sc->sc_ethercom.ec_if, &ifmr);
+ p1sr = CSR_READ_2(sc, P1SR);
Home |
Main Index |
Thread Index |
Old Index