Use MII device layer.
XXX still 100Mbps receive side is very slow...
This commit is contained in:
parent
492bfe70f3
commit
6b26a49ee9
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.macppc,v 1.25 1999/10/15 07:16:16 tsubai Exp $
|
||||
# $NetBSD: files.macppc,v 1.26 2000/01/25 14:38:39 tsubai Exp $
|
||||
#
|
||||
# macppc-specific configuration info
|
||||
|
||||
|
@ -100,7 +100,7 @@ attach mc at obio
|
|||
file arch/macppc/dev/if_mc.c mc
|
||||
file arch/macppc/dev/am79c950.c mc
|
||||
|
||||
device bm: ifnet, ether, arp
|
||||
device bm: ifnet, ether, arp, mii, mii_bitbang
|
||||
attach bm at obio
|
||||
file arch/macppc/dev/if_bm.c bm
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: if_bm.c,v 1.3 1999/06/20 05:34:59 tsubai Exp $ */
|
||||
/* $NetBSD: if_bm.c,v 1.4 2000/01/25 14:38:50 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1998, 1999 Tsubai Masanari. All rights reserved.
|
||||
* Copyright (C) 1998, 1999, 2000 Tsubai Masanari. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -33,23 +33,32 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_ether.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
#if NBPFILTER > 0
|
||||
#include <net/bpf.h>
|
||||
#include <net/bpfdesc.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h>
|
||||
#ifdef INET
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_inarp.h>
|
||||
#endif
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
#include <dev/mii/mii_bitbang.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
|
@ -64,7 +73,6 @@ struct bmac_softc {
|
|||
struct device sc_dev;
|
||||
struct ethercom sc_ethercom;
|
||||
#define sc_if sc_ethercom.ec_if
|
||||
struct ifmedia sc_media;
|
||||
vaddr_t sc_regs;
|
||||
dbdma_regmap_t *sc_txdma;
|
||||
dbdma_regmap_t *sc_rxdma;
|
||||
|
@ -74,11 +82,12 @@ struct bmac_softc {
|
|||
caddr_t sc_rxbuf;
|
||||
int sc_rxlast;
|
||||
int sc_flags;
|
||||
int sc_debug;
|
||||
struct mii_data sc_mii;
|
||||
u_char sc_enaddr[6];
|
||||
};
|
||||
|
||||
#define BMAC_BMACPLUS 0x01
|
||||
#define BMAC_DEBUGFLAG 0x02
|
||||
|
||||
extern u_int *heathrow_FCR;
|
||||
|
||||
|
@ -87,29 +96,41 @@ static __inline void bmac_write_reg __P((struct bmac_softc *, int, int));
|
|||
static __inline void bmac_set_bits __P((struct bmac_softc *, int, int));
|
||||
static __inline void bmac_reset_bits __P((struct bmac_softc *, int, int));
|
||||
|
||||
static int bmac_match __P((struct device *, struct cfdata *, void *));
|
||||
static void bmac_attach __P((struct device *, struct device *, void *));
|
||||
static void bmac_reset_chip __P((struct bmac_softc *));
|
||||
static void bmac_init __P((struct bmac_softc *));
|
||||
static void bmac_init_dma __P((struct bmac_softc *));
|
||||
static int bmac_intr __P((void *));
|
||||
static int bmac_rint __P((void *));
|
||||
static void bmac_reset __P((struct bmac_softc *));
|
||||
static void bmac_stop __P((struct bmac_softc *));
|
||||
static void bmac_start __P((struct ifnet *));
|
||||
static void bmac_transmit_packet __P((struct bmac_softc *, void *, int));
|
||||
static int bmac_put __P((struct bmac_softc *, caddr_t, struct mbuf *));
|
||||
static struct mbuf *bmac_get __P((struct bmac_softc *, caddr_t, int));
|
||||
static void bmac_watchdog __P((struct ifnet *));
|
||||
static int bmac_ioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
static int bmac_mediachange __P((struct ifnet *));
|
||||
static void bmac_mediastatus __P((struct ifnet *, struct ifmediareq *));
|
||||
static void bmac_setladrf __P((struct bmac_softc *));
|
||||
int bmac_match __P((struct device *, struct cfdata *, void *));
|
||||
void bmac_attach __P((struct device *, struct device *, void *));
|
||||
void bmac_reset_chip __P((struct bmac_softc *));
|
||||
void bmac_init __P((struct bmac_softc *));
|
||||
void bmac_init_dma __P((struct bmac_softc *));
|
||||
int bmac_intr __P((void *));
|
||||
int bmac_rint __P((void *));
|
||||
void bmac_reset __P((struct bmac_softc *));
|
||||
void bmac_stop __P((struct bmac_softc *));
|
||||
void bmac_start __P((struct ifnet *));
|
||||
void bmac_transmit_packet __P((struct bmac_softc *, void *, int));
|
||||
int bmac_put __P((struct bmac_softc *, caddr_t, struct mbuf *));
|
||||
struct mbuf *bmac_get __P((struct bmac_softc *, caddr_t, int));
|
||||
void bmac_watchdog __P((struct ifnet *));
|
||||
int bmac_ioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
int bmac_mediachange __P((struct ifnet *));
|
||||
void bmac_mediastatus __P((struct ifnet *, struct ifmediareq *));
|
||||
void bmac_setladrf __P((struct bmac_softc *));
|
||||
|
||||
int bmac_mii_readreg __P((struct device *, int, int));
|
||||
void bmac_mii_writereg __P((struct device *, int, int, int));
|
||||
void bmac_mii_statchg __P((struct device *));
|
||||
void bmac_mii_tick __P((void *));
|
||||
u_int32_t bmac_mbo_read __P((struct device *));
|
||||
void bmac_mbo_write __P((struct device *, u_int32_t));
|
||||
|
||||
struct cfattach bm_ca = {
|
||||
sizeof(struct bmac_softc), bmac_match, bmac_attach
|
||||
};
|
||||
|
||||
struct mii_bitbang_ops bmac_mbo = {
|
||||
bmac_mbo_read, bmac_mbo_write,
|
||||
{ MIFDO, MIFDI, MIFDC, MIFDIR, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
bmac_read_reg(sc, off)
|
||||
struct bmac_softc *sc;
|
||||
|
@ -170,8 +191,8 @@ bmac_attach(parent, self, aux)
|
|||
struct confargs *ca = aux;
|
||||
struct bmac_softc *sc = (void *)self;
|
||||
struct ifnet *ifp = &sc->sc_if;
|
||||
struct mii_data *mii = &sc->sc_mii;
|
||||
u_char laddr[6];
|
||||
int i;
|
||||
|
||||
sc->sc_flags =0;
|
||||
if (strcmp(ca->ca_name, "ethernet") == 0) {
|
||||
|
@ -224,9 +245,21 @@ bmac_attach(parent, self, aux)
|
|||
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
|
||||
ifp->if_watchdog = bmac_watchdog;
|
||||
|
||||
ifmedia_init(&sc->sc_media, 0, bmac_mediachange, bmac_mediastatus);
|
||||
ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_T, 0, NULL);
|
||||
ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_T);
|
||||
mii->mii_ifp = ifp;
|
||||
mii->mii_readreg = bmac_mii_readreg;
|
||||
mii->mii_writereg = bmac_mii_writereg;
|
||||
mii->mii_statchg = bmac_mii_statchg;
|
||||
|
||||
ifmedia_init(&mii->mii_media, 0, bmac_mediachange, bmac_mediastatus);
|
||||
mii_phy_probe(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
|
||||
MII_OFFSET_ANY);
|
||||
|
||||
/* Choose a default media. */
|
||||
if (LIST_FIRST(&mii->mii_phys) == NULL) {
|
||||
ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_10_T, 0, NULL);
|
||||
ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_10_T);
|
||||
} else
|
||||
ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO);
|
||||
|
||||
bmac_reset_chip(sc);
|
||||
|
||||
|
@ -274,16 +307,27 @@ bmac_init(sc)
|
|||
struct ifnet *ifp = &sc->sc_if;
|
||||
struct ether_header *eh;
|
||||
caddr_t data;
|
||||
int i, tb;
|
||||
int i, tb, bmcr;
|
||||
u_short *p;
|
||||
|
||||
bmac_reset_chip(sc);
|
||||
|
||||
/* XXX */
|
||||
bmcr = bmac_mii_readreg((struct device *)sc, 0, MII_BMCR);
|
||||
bmcr &= ~BMCR_ISO;
|
||||
bmac_mii_writereg((struct device *)sc, 0, MII_BMCR, bmcr);
|
||||
|
||||
bmac_write_reg(sc, RXRST, RxResetValue);
|
||||
bmac_write_reg(sc, TXRST, TxResetBit);
|
||||
|
||||
/* Wait for reset completion. */
|
||||
while (bmac_read_reg(sc, TXRST) & TxResetBit);
|
||||
for (i = 1000; i > 0; i -= 10) {
|
||||
if ((bmac_read_reg(sc, TXRST) & TxResetBit) == 0)
|
||||
break;
|
||||
delay(10);
|
||||
}
|
||||
if (i <= 0)
|
||||
printf("%s: reset timeout\n", ifp->if_xname);
|
||||
|
||||
if (! (sc->sc_flags & BMAC_BMACPLUS))
|
||||
bmac_set_bits(sc, XCVRIF, ClkBit|SerialMode|COLActiveLow);
|
||||
|
@ -355,6 +399,9 @@ bmac_init(sc)
|
|||
bmac_transmit_packet(sc, data, sizeof(eh) + ETHERMIN);
|
||||
|
||||
bmac_start(ifp);
|
||||
|
||||
untimeout(bmac_mii_tick, sc);
|
||||
timeout(bmac_mii_tick, sc, hz);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -499,6 +546,9 @@ bmac_stop(sc)
|
|||
|
||||
s = splnet();
|
||||
|
||||
untimeout(bmac_mii_tick, sc);
|
||||
mii_down(&sc->sc_mii);
|
||||
|
||||
/* Disable TX/RX. */
|
||||
bmac_reset_bits(sc, TXCFG, TxMACEnable);
|
||||
bmac_reset_bits(sc, RXCFG, RxMACEnable);
|
||||
|
@ -675,7 +725,6 @@ bmac_ioctl(ifp, cmd, data)
|
|||
struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
int temp;
|
||||
|
||||
s = splnet();
|
||||
|
||||
|
@ -741,9 +790,7 @@ bmac_ioctl(ifp, cmd, data)
|
|||
}
|
||||
#ifdef BMAC_DEBUG
|
||||
if (ifp->if_flags & IFF_DEBUG)
|
||||
sc->sc_debug = 1;
|
||||
else
|
||||
sc->sc_debug = 0;
|
||||
sc->sc_flags |= BMAC_DEBUGFLAG;
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -766,7 +813,7 @@ bmac_ioctl(ifp, cmd, data)
|
|||
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -781,7 +828,9 @@ int
|
|||
bmac_mediachange(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
return EINVAL;
|
||||
struct bmac_softc *sc = ifp->if_softc;
|
||||
|
||||
return mii_mediachg(&sc->sc_mii);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -789,11 +838,12 @@ bmac_mediastatus(ifp, ifmr)
|
|||
struct ifnet *ifp;
|
||||
struct ifmediareq *ifmr;
|
||||
{
|
||||
if ((ifp->if_flags & IFF_UP) == 0)
|
||||
return;
|
||||
struct bmac_softc *sc = ifp->if_softc;
|
||||
|
||||
ifmr->ifm_status = IFM_AVALID;
|
||||
ifmr->ifm_status |= IFM_ACTIVE;
|
||||
mii_pollstat(&sc->sc_mii);
|
||||
|
||||
ifmr->ifm_status = sc->sc_mii.mii_media_status;
|
||||
ifmr->ifm_active = sc->sc_mii.mii_media_active;
|
||||
}
|
||||
|
||||
#define MC_POLY_BE 0x04c11db7UL /* mcast crc, big endian */
|
||||
|
@ -882,3 +932,73 @@ allmulti:
|
|||
bmac_write_reg(sc, HASH1, 0xffff);
|
||||
bmac_write_reg(sc, HASH0, 0xffff);
|
||||
}
|
||||
|
||||
int
|
||||
bmac_mii_readreg(dev, phy, reg)
|
||||
struct device *dev;
|
||||
int phy, reg;
|
||||
{
|
||||
return mii_bitbang_readreg(dev, &bmac_mbo, phy, reg);
|
||||
}
|
||||
|
||||
void
|
||||
bmac_mii_writereg(dev, phy, reg, val)
|
||||
struct device *dev;
|
||||
int phy, reg, val;
|
||||
{
|
||||
mii_bitbang_writereg(dev, &bmac_mbo, phy, reg, val);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
bmac_mbo_read(dev)
|
||||
struct device *dev;
|
||||
{
|
||||
struct bmac_softc *sc = (void *)dev;
|
||||
|
||||
return bmac_read_reg(sc, MIFCSR);
|
||||
}
|
||||
|
||||
void
|
||||
bmac_mbo_write(dev, val)
|
||||
struct device *dev;
|
||||
u_int32_t val;
|
||||
{
|
||||
struct bmac_softc *sc = (void *)dev;
|
||||
|
||||
bmac_write_reg(sc, MIFCSR, val);
|
||||
}
|
||||
|
||||
void
|
||||
bmac_mii_statchg(dev)
|
||||
struct device *dev;
|
||||
{
|
||||
struct bmac_softc *sc = (void *)dev;
|
||||
int x;
|
||||
|
||||
/* Update duplex mode in TX configuration */
|
||||
x = bmac_read_reg(sc, TXCFG);
|
||||
if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0)
|
||||
x |= TxFullDuplex;
|
||||
else
|
||||
x &= ~TxFullDuplex;
|
||||
bmac_write_reg(sc, TXCFG, x);
|
||||
|
||||
#ifdef BMAC_DEBUG
|
||||
printf("bmac_mii_statchg 0x%x\n",
|
||||
IFM_OPTIONS(sc->sc_mii.mii_media_active));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
bmac_mii_tick(v)
|
||||
void *v;
|
||||
{
|
||||
struct bmac_softc *sc = v;
|
||||
int s;
|
||||
|
||||
s = splnet();
|
||||
mii_tick(&sc->sc_mii);
|
||||
splx(s);
|
||||
|
||||
timeout(bmac_mii_tick, sc, hz);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_bmreg.h,v 1.1 1999/01/01 01:27:52 tsubai Exp $ */
|
||||
/* $NetBSD: if_bmreg.h,v 1.2 2000/01/25 14:38:50 tsubai Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1991-1998 by Open Software Foundation, Inc.
|
||||
|
@ -52,6 +52,10 @@
|
|||
#define ClkBit 0x0008
|
||||
#define CHIPID 0x0170
|
||||
#define MIFCSR 0x0180
|
||||
#define MIFDC 0x0001 /* MII clock */
|
||||
#define MIFDO 0x0002 /* MII data out */
|
||||
#define MIFDIR 0x0004 /* MII direction (1: write) */
|
||||
#define MIFDI 0x0008 /* MII data in */
|
||||
#define SROMCSR 0x0190
|
||||
#define TXPNTR 0x01A0
|
||||
#define RXPNTR 0x01B0
|
||||
|
@ -82,6 +86,7 @@
|
|||
#define TXCFG 0x0430
|
||||
#define TxMACEnable 0x0001
|
||||
#define TxThreshold 0x0004
|
||||
#define TxFullDuplex 0x0200
|
||||
#define IPG1 0x0440
|
||||
#define IPG2 0x0450
|
||||
#define ALIMIT 0x0460
|
||||
|
|
Loading…
Reference in New Issue