Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic - reorgazine the entire structure to utilise ifme...



details:   https://anonhg.NetBSD.org/src/rev/851c58573bd5
branches:  trunk
changeset: 1008684:851c58573bd5
user:      nisimura <nisimura%NetBSD.org@localhost>
date:      Tue Mar 31 02:32:25 2020 +0000

description:
- reorgazine the entire structure to utilise ifmedia(4)/mii(4) and
  redefine starting point of debug.
- nuke duplicated standard MII register definition.  Davicom PHY extension
  is defined in dev/mii/dmphyreg.h

diffstat:

 sys/dev/ic/dm9000.c    |  1324 ++++++++++++++++++++++-------------------------
 sys/dev/ic/dm9000reg.h |    63 +-
 sys/dev/ic/dm9000var.h |    21 +-
 3 files changed, 637 insertions(+), 771 deletions(-)

diffs (truncated from 1729 to 300 lines):

diff -r 071d11546a2a -r 851c58573bd5 sys/dev/ic/dm9000.c
--- a/sys/dev/ic/dm9000.c       Tue Mar 31 01:02:18 2020 +0000
+++ b/sys/dev/ic/dm9000.c       Tue Mar 31 02:32:25 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dm9000.c,v 1.23 2020/03/29 23:16:52 nisimura Exp $     */
+/*     $NetBSD: dm9000.c,v 1.24 2020/03/31 02:32:25 nisimura Exp $     */
 
 /*
  * Copyright (c) 2009 Paul Fleischer
@@ -89,29 +89,26 @@
 #include <sys/cdefs.h>
 
 #include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/intr.h>
+#include <sys/device.h>
+#include <sys/mbuf.h>
+#include <sys/sockio.h>
+#include <sys/malloc.h>
+#include <sys/errno.h>
+#include <sys/cprng.h>
+#include <sys/rndsource.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/syslog.h>
-#include <sys/socket.h>
-#include <sys/device.h>
-#include <sys/malloc.h>
-#include <sys/ioctl.h>
-#include <sys/errno.h>
 
 #include <net/if.h>
+#include <net/if_dl.h>
 #include <net/if_ether.h>
 #include <net/if_media.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
 #include <net/bpf.h>
 
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/if_inarp.h>
-#endif
-
-#include <sys/bus.h>
-#include <sys/intr.h>
-
 #include <dev/ic/dm9000var.h>
 #include <dev/ic/dm9000reg.h>
 
@@ -159,705 +156,207 @@
 #define TX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0)
 #endif
 
-/*** Internal PHY functions ***/
-uint16_t dme_phy_read(struct dme_softc *, int );
-void   dme_phy_write(struct dme_softc *, int, uint16_t);
-void   dme_phy_init(struct dme_softc *);
-void   dme_phy_reset(struct dme_softc *);
-void   dme_phy_update_media(struct dme_softc *);
-void   dme_phy_check_link(void *);
-
-/*** Methods registered in struct ifnet ***/
-void   dme_start_output(struct ifnet *);
-int    dme_init(struct ifnet *);
-int    dme_ioctl(struct ifnet *, u_long, void *);
-void   dme_stop(struct ifnet *, int);
-
-int    dme_mediachange(struct ifnet *);
-void   dme_mediastatus(struct ifnet *, struct ifmediareq *);
-
-/*** Internal methods ***/
-
-/* Prepare data to be transmitted (i.e. dequeue and load it into the DM9000) */
-void   dme_prepare(struct dme_softc *, struct ifnet *);
-
-/* Transmit prepared data */
-void   dme_transmit(struct dme_softc *);
-
-/* Receive data */
-void   dme_receive(struct dme_softc *, struct ifnet *);
-
-/* Software Initialize/Reset of the DM9000 */
-void   dme_reset(struct dme_softc *);
-
-/* Configure multicast filter */
-void   dme_set_addr_filter(struct dme_softc *);
-
-/* Set media */
-int    dme_set_media(struct dme_softc *, int );
-
-/* Read/write packet data from/to DM9000 IC in various transfer sizes */
-int    dme_pkt_read_2(struct dme_softc *, struct ifnet *, struct mbuf **);
-int    dme_pkt_write_2(struct dme_softc *, struct mbuf *);
-int    dme_pkt_read_1(struct dme_softc *, struct ifnet *, struct mbuf **);
-int    dme_pkt_write_1(struct dme_softc *, struct mbuf *);
-/* TODO: Implement 32 bit read/write functions */
+static void dme_reset(struct dme_softc *);
+static int dme_init(struct ifnet *);
+static void dme_stop(struct ifnet *, int);
+static void dme_start(struct ifnet *);
+static int dme_ioctl(struct ifnet *, u_long, void *);
 
-uint16_t
-dme_phy_read(struct dme_softc *sc, int reg)
-{
-       uint16_t val;
-       /* Select Register to read*/
-       dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY +
-           (reg & DM9000_EPAR_EROA_MASK));
-       /* Select read operation (DM9000_EPCR_ERPRR) from the PHY */
-       dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRR + DM9000_EPCR_EPOS_PHY);
-
-       /* Wait until access to PHY has completed */
-       while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE)
-               ;
-
-       /* Reset ERPRR-bit */
-       dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
-
-       val = dme_read(sc, DM9000_EPDRL);
-       val += dme_read(sc, DM9000_EPDRH) << 8;
-
-       return val;
-}
-
-void
-dme_phy_write(struct dme_softc *sc, int reg, uint16_t value)
-{
-       /* Select Register to write*/
-       dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY +
-           (reg & DM9000_EPAR_EROA_MASK));
-
-       /* Write data to the two data registers */
-       dme_write(sc, DM9000_EPDRL, value & 0xFF);
-       dme_write(sc, DM9000_EPDRH, (value >> 8) & 0xFF);
-
-       /* Select write operation (DM9000_EPCR_ERPRW) from the PHY */
-       dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRW + DM9000_EPCR_EPOS_PHY);
-
-       /* Wait until access to PHY has completed */
-       while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE)
-               ;
-
-       /* Reset ERPRR-bit */
-       dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
-}
-
-void
-dme_phy_init(struct dme_softc *sc)
-{
-       u_int ifm_media = sc->sc_media.ifm_media;
-       uint32_t bmcr, anar;
-
-       bmcr = dme_phy_read(sc, DM9000_PHY_BMCR);
-       anar = dme_phy_read(sc, DM9000_PHY_ANAR);
-
-       anar = anar & ~DM9000_PHY_ANAR_10_HDX
-               & ~DM9000_PHY_ANAR_10_FDX
-               & ~DM9000_PHY_ANAR_TX_HDX
-               & ~DM9000_PHY_ANAR_TX_FDX;
+static void dme_set_rcvfilt(struct dme_softc *);
+static void mii_statchg(struct ifnet *);
+static void lnkchg(struct dme_softc *);
+static void phy_tick(void *);
+static int mii_readreg(device_t, int, int, uint16_t *);
+static int mii_writereg(device_t, int, int, uint16_t);
 
-       switch (IFM_SUBTYPE(ifm_media)) {
-       case IFM_AUTO:
-               bmcr |= DM9000_PHY_BMCR_AUTO_NEG_EN;
-               anar |= DM9000_PHY_ANAR_10_HDX |
-                       DM9000_PHY_ANAR_10_FDX |
-                       DM9000_PHY_ANAR_TX_HDX |
-                       DM9000_PHY_ANAR_TX_FDX;
-               break;
-       case IFM_10_T:
-               //bmcr &= ~DM9000_PHY_BMCR_AUTO_NEG_EN;
-               bmcr &= ~DM9000_PHY_BMCR_SPEED_SELECT;
-               if (ifm_media & IFM_FDX)
-                       anar |= DM9000_PHY_ANAR_10_FDX;
-               else
-                       anar |= DM9000_PHY_ANAR_10_HDX;
-               break;
-       case IFM_100_TX:
-               //bmcr &= ~DM9000_PHY_BMCR_AUTO_NEG_EN;
-               bmcr |= DM9000_PHY_BMCR_SPEED_SELECT;
-               if (ifm_media & IFM_FDX)
-                       anar |= DM9000_PHY_ANAR_TX_FDX;
-               else
-                       anar |= DM9000_PHY_ANAR_TX_HDX;
-
-               break;
-       }
-
-       if (ifm_media & IFM_FDX)
-               bmcr |= DM9000_PHY_BMCR_DUPLEX_MODE;
-       else
-               bmcr &= ~DM9000_PHY_BMCR_DUPLEX_MODE;
-
-       dme_phy_write(sc, DM9000_PHY_BMCR, bmcr);
-       dme_phy_write(sc, DM9000_PHY_ANAR, anar);
-}
-
-void
-dme_phy_reset(struct dme_softc *sc)
-{
-       uint32_t reg;
-
-       /* PHY Reset */
-       dme_phy_write(sc, DM9000_PHY_BMCR, DM9000_PHY_BMCR_RESET);
-
-       reg = dme_read(sc, DM9000_GPCR);
-       dme_write(sc, DM9000_GPCR, reg & ~DM9000_GPCR_GPIO0_OUT);
-       reg = dme_read(sc, DM9000_GPR);
-       dme_write(sc, DM9000_GPR, reg | DM9000_GPR_PHY_PWROFF);
-
-       dme_phy_init(sc);
-
-       reg = dme_read(sc, DM9000_GPR);
-       dme_write(sc, DM9000_GPR, reg & ~DM9000_GPR_PHY_PWROFF);
-       reg = dme_read(sc, DM9000_GPCR);
-       dme_write(sc, DM9000_GPCR, reg | DM9000_GPCR_GPIO0_OUT);
-
-       dme_phy_update_media(sc);
-}
+static void dme_prepare(struct ifnet *);
+static void dme_transmit(struct ifnet *);
+static void dme_receive(struct ifnet *);
 
-void
-dme_phy_update_media(struct dme_softc *sc)
-{
-       u_int ifm_media = sc->sc_media.ifm_media;
-       uint32_t reg;
-
-       if (IFM_SUBTYPE(ifm_media) == IFM_AUTO) {
-               /* If auto-negotiation is used, ensures that it is completed
-                before trying to extract any media information. */
-               reg = dme_phy_read(sc, DM9000_PHY_BMSR);
-               if ((reg & DM9000_PHY_BMSR_AUTO_NEG_AB) == 0) {
-                       /* Auto-negotation not possible, therefore there is no
-                          reason to try obtain any media information. */
-                       return;
-               }
-
-               /* Then loop until the negotiation is completed. */
-               while ((reg & DM9000_PHY_BMSR_AUTO_NEG_COM) == 0) {
-                       /* TODO: Bail out after a finite number of attempts
-                        in case something goes wrong. */
-                       preempt();
-                       reg = dme_phy_read(sc, DM9000_PHY_BMSR);
-               }
-       }
-
-
-       sc->sc_media_active = IFM_ETHER;
-       reg = dme_phy_read(sc, DM9000_PHY_BMCR);
+static int pkt_read_2(struct dme_softc *, struct mbuf **);
+static int pkt_write_2(struct dme_softc *, struct mbuf *);
+static int pkt_read_1(struct dme_softc *, struct mbuf **);
+static int pkt_write_1(struct dme_softc *, struct mbuf *);
+#define PKT_READ(ii,m) (*(ii)->sc_pkt_read)((ii),(m))
+#define PKT_WRITE(ii,m) (*(ii)->sc_pkt_write)((ii),(m))
 
-       if (reg & DM9000_PHY_BMCR_SPEED_SELECT)
-               sc->sc_media_active |= IFM_100_TX;
-       else
-               sc->sc_media_active |= IFM_10_T;
-
-       if (reg & DM9000_PHY_BMCR_DUPLEX_MODE)
-               sc->sc_media_active |= IFM_FDX;
-}
-
-void
-dme_phy_check_link(void *arg)
-{
-       struct dme_softc *sc = arg;
-       uint32_t reg;
-       int s;
-
-       s = splnet();
-
-       reg = dme_read(sc, DM9000_NSR) & DM9000_NSR_LINKST;
-
-       if (reg)
-               reg = IFM_ETHER | IFM_AVALID | IFM_ACTIVE;
-       else {
-               reg = IFM_ETHER | IFM_AVALID;
-               sc->sc_media_active = IFM_NONE;
-       }
-
-       if ((sc->sc_media_status != reg) && (reg & IFM_ACTIVE))
-               dme_phy_reset(sc);
-
-       sc->sc_media_status = reg;
-
-       callout_schedule(&sc->sc_link_callout, mstohz(2000));
-       splx(s);



Home | Main Index | Thread Index | Old Index