summaryrefslogtreecommitdiff
path: root/sys/arch/armv7
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-09-22 12:43:23 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-09-22 12:43:23 +0000
commitee79cc51762dffca44ed2c99ac0bf859e9a866e2 (patch)
tree283a483ebd5dab7a0ba6bbd0390051c839059035 /sys/arch/armv7
parent751841d21f413ac3a66a9cc1e03342a715f889d1 (diff)
Periodically call mii_tick() like all our other ethernet drivers that use
mii(4). Should fix the link negotiation issues that people have been seeing. ok jsg@, mikeb@, guenther@
Diffstat (limited to 'sys/arch/armv7')
-rw-r--r--sys/arch/armv7/imx/if_fec.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sys/arch/armv7/imx/if_fec.c b/sys/arch/armv7/imx/if_fec.c
index 22034c869e4..38be655ef7b 100644
--- a/sys/arch/armv7/imx/if_fec.c
+++ b/sys/arch/armv7/imx/if_fec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_fec.c,v 1.17 2016/09/21 10:28:47 kettenis Exp $ */
+/* $OpenBSD: if_fec.c,v 1.18 2016/09/22 12:43:22 kettenis Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
*
@@ -231,6 +231,7 @@ struct fec_softc {
struct fec_buffer *rx_buffer_base;
int cur_tx;
int cur_rx;
+ struct timeout sc_tick;
};
struct fec_softc *fec_sc;
@@ -249,6 +250,7 @@ void fec_iff(struct fec_softc *);
struct mbuf * fec_newbuf(void);
int fec_intr(void *);
void fec_recv(struct fec_softc *);
+void fec_tick(void *);
int fec_miibus_readreg(struct device *, int, int);
void fec_miibus_writereg(struct device *, int, int, int);
void fec_miibus_statchg(struct device *);
@@ -430,6 +432,8 @@ fec_attach(struct device *parent, struct device *self, void *aux)
ether_ifattach(ifp);
splx(s);
+ timeout_set(&sc->sc_tick, fec_tick, sc);
+
fec_sc = sc;
return;
@@ -672,6 +676,8 @@ fec_init(struct fec_softc *sc)
/* program promiscuous mode and multicast filters */
fec_iff(sc);
+ timeout_add_sec(&sc->sc_tick, 1);
+
/* Indicate we are up and running. */
ifp->if_flags |= IFF_RUNNING;
ifq_clr_oactive(&ifp->if_snd);
@@ -694,6 +700,8 @@ fec_stop(struct fec_softc *sc)
ifp->if_timer = 0;
ifq_clr_oactive(&ifp->if_snd);
+ timeout_del(&sc->sc_tick);
+
/* reset the controller */
HSET4(sc, ENET_ECR, ENET_ECR_RESET);
while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET);
@@ -968,6 +976,19 @@ done:
if_input(ifp, &ml);
}
+void
+fec_tick(void *arg)
+{
+ struct fec_softc *sc = arg;
+ int s;
+
+ s = splnet();
+ mii_tick(&sc->sc_mii);
+ splx(s);
+
+ timeout_add_sec(&sc->sc_tick, 1);
+}
+
/*
* MII
* Interrupts need ENET_ECR_ETHEREN to be set,