Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Driver for Davicom DM9000 ethernet chips.
details: https://anonhg.NetBSD.org/src/rev/6b739933430a
branches: trunk
changeset: 757631:6b739933430a
user: ahoka <ahoka%NetBSD.org@localhost>
date: Wed Sep 08 22:01:29 2010 +0000
description:
Driver for Davicom DM9000 ethernet chips.
Written by Paul Fleischer, minor modifications by me.
diffstat:
sys/dev/ic/dm9000.c | 843 +++++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/ic/dm9000reg.h | 202 +++++++++++
sys/dev/ic/dm9000var.h | 146 ++++++++
3 files changed, 1191 insertions(+), 0 deletions(-)
diffs (truncated from 1203 to 300 lines):
diff -r 3465b34967d0 -r 6b739933430a sys/dev/ic/dm9000.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/dm9000.c Wed Sep 08 22:01:29 2010 +0000
@@ -0,0 +1,843 @@
+/* $NetBSD: dm9000.c,v 1.1 2010/09/08 22:01:29 ahoka Exp $ */
+
+/*
+ * Copyright (c) 2009 Paul Fleischer
+ * All rights reserved.
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * 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 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.
+ */
+
+/* based on sys/dev/ic/cs89x0.c */
+/*
+ * Copyright (c) 2004 Christopher Gilbert
+ * All rights reserved.
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * 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 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 1997
+ * Digital Equipment Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and conditions.
+ * Subject to these conditions, you may download, copy, install,
+ * use, modify and distribute this software in source and/or binary
+ * form. No title or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions as
+ * they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of
+ * Digital Equipment Corporation. Neither the "Digital Equipment
+ * Corporation" name nor any trademark or logo of Digital Equipment
+ * Corporation may be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied
+ * warranties, including but not limited to, any implied warranties
+ * of merchantability, fitness for a particular purpose, or
+ * non-infringement are disclaimed. In no event shall DIGITAL be
+ * liable for any damages whatsoever, and in particular, DIGITAL
+ * shall not be liable for special, indirect, consequential, or
+ * incidental damages or damages for lost profits, loss of
+ * revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise,
+ * even if advised of the possibility of such damage.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.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_ether.h>
+#include <net/if_media.h>
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_inarp.h>
+#endif
+
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+
+#include <sys/bus.h>
+#include <sys/intr.h>
+
+#include <dev/ic/dm9000var.h>
+#include <dev/ic/dm9000reg.h>
+
+#if 1
+#undef DM9000_DEBUG
+#undef DM9000_TX_DEBUG
+#undef DM9000_TX_DATA_DEBUG
+#undef DM9000_RX_DEBUG
+#undef DM9000_RX_DATA_DEBUG
+#else
+#define DM9000_DEBUG
+#define DM9000_TX_DEBUG
+#define DM9000_TX_DATA_DEBUG
+#define DM9000_RX_DEBUG
+#define DM9000_RX_DATA_DEBUG
+#endif
+
+#ifdef DM9000_DEBUG
+#define DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
+#else
+#define DPRINTF(s) do {} while (/*CONSTCOND*/0)
+#endif
+
+#ifdef DM9000_TX_DEBUG
+#define TX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
+#else
+#define TX_DPRINTF(s) do {} while (/*CONSTCOND*/0)
+#endif
+
+#ifdef DM9000_RX_DEBUG
+#define RX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
+#else
+#define RX_DPRINTF(s) do {} while (/*CONSTCOND*/0)
+#endif
+
+#ifdef DM9000_RX_DATA_DEBUG
+#define RX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
+#else
+#define RX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0)
+#endif
+
+#ifdef DM9000_TX_DATA_DEBUG
+#define TX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
+#else
+#define TX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0)
+#endif
+
+
+uint16_t dme_phy_read(struct dme_softc *sc, int reg);
+void dme_phy_write(struct dme_softc *sc, int reg, uint16_t value);
+
+/*** Methods registered in struct ifnet ***/
+void dme_start_output(struct ifnet *ifp);
+int dme_init(struct ifnet *ifp);
+int dme_ioctl(struct ifnet *ifp, u_long cmd, void *data);
+void dme_stop(struct ifnet *ifp, int disable);
+
+int dme_mediachange(struct ifnet *ifp);
+void dme_mediastatus(struct ifnet *ufp, struct ifmediareq *ifmr);
+
+/*** Internal methods ***/
+
+/* Prepare data to be transmitted (i.e. dequeue and load it into the DM9000) */
+void dme_prepare(struct dme_softc *sc, struct ifnet *ifp);
+
+/* Transmit prepared data */
+void dme_transmit(struct dme_softc *sc);
+
+/* Receive data */
+void dme_receive(struct dme_softc *sc, struct ifnet *ifp);
+
+/* Software Initialize/Reset of the DM9000 */
+void dme_reset(struct dme_softc *sc);
+
+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);
+
+ /* XXX: The delay is probably not necessary as we just busy-waited */
+ delay(200);
+
+ /* 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);
+
+
+ /* XXX: The delay is probably not necessary as we just busy-waited */
+ delay(200);
+
+ /* Reset ERPRR-bit */
+ dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
+}
+
+int
+dme_attach(struct dme_softc *sc, uint8_t *enaddr)
+{
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ uint8_t b[2];
+
+ dme_read_c(sc, DM9000_VID0, b, 2);
+#if BYTE_ORDER == BIG_ENDIAN
+ sc->sc_vendor_id = (b[0] << 8) | b[1];
+#else
+ sc->sc_vendor_id = b[0] | (b[1] << 8);
+#endif
+ dme_read_c(sc, DM9000_PID0, b, 2);
+#if BYTE_ORDER == BIG_ENDIAN
+ sc->sc_product_id = (b[0] << 8) | b[1];
+#else
+ sc->sc_product_id = b[0] | (b[1] << 8);
+#endif
+ /* TODO: Check the vendor ID as well */
+ if (sc->sc_product_id != 0x9000) {
+ panic("dme_attach: product id mismatch (0x%hx != 0x9000)",
+ sc->sc_product_id);
+ }
+
+#if 0
+ {
+ /* Force 10Mbps to test dme_phy_write */
+ uint16_t bmcr;
+ bmcr = dme_phy_read(sc, DM9000_PHY_BMCR);
+ bmcr &= ~DM9000_PHY_BMCR_AUTO_NEG_EN;
+ bmcr &= ~DM9000_PHY_BMCR_SPEED_SELECT; /* select 100Mbps */
+ dme_phy_write(sc, DM9000_PHY_BMCR, bmcr);
+ }
+#endif
+ /* Initialize ifnet structure. */
+ strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
+ ifp->if_softc = sc;
+ ifp->if_start = dme_start_output;
+ ifp->if_init = dme_init;
+ ifp->if_ioctl = dme_ioctl;
+ ifp->if_stop = dme_stop;
+ ifp->if_watchdog = NULL; /* no watchdog at this stage */
+ ifp->if_flags = IFF_SIMPLEX | IFF_NOTRAILERS |
+ IFF_BROADCAST; /* No multicast support for now */
+ IFQ_SET_READY(&ifp->if_snd);
+
+ /* Initialize ifmedia structures. */
+ ifmedia_init(&sc->sc_media, 0, dme_mediachange, dme_mediastatus);
+ ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_T|IFM_100_TX, 0, NULL);
+ ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_T|IFM_100_TX);
+
+ if (enaddr != NULL)
+ memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr));
+
+ /* Configure DM9000 with the MAC address */
+ dme_write_c(sc, DM9000_PAB0, sc->sc_enaddr, 6);
+
+#ifdef DM9000_DEBUG
Home |
Main Index |
Thread Index |
Old Index