git: 69759b0c695d - main - Remove dme(4).
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 31 Jan 2023 16:39:57 UTC
The branch main has been updated by jhibbits:
URL: https://cgit.FreeBSD.org/src/commit/?id=69759b0c695da15a3379ca01335ab314897d8594
commit 69759b0c695da15a3379ca01335ab314897d8594
Author: Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2023-01-31 16:32:52 +0000
Commit: Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2023-01-31 16:39:48 +0000
Remove dme(4).
This was used only on an Ingenic MIPS SoC.
---
sys/dev/dme/if_dme.c | 1060 -----------------------------------------------
sys/dev/dme/if_dmereg.h | 137 ------
sys/dev/dme/if_dmevar.h | 39 --
3 files changed, 1236 deletions(-)
diff --git a/sys/dev/dme/if_dme.c b/sys/dev/dme/if_dme.c
deleted file mode 100644
index c518fa98af0f..000000000000
--- a/sys/dev/dme/if_dme.c
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- * Copyright (C) 2015 Alexander Kabaev
- * Copyright (C) 2010 Andrew Turner
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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.
- */
-
-/* A driver for the Davicom DM9000 MAC. */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/mbuf.h>
-#include <sys/mutex.h>
-#include <sys/rman.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/gpio.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-#include <net/ethernet.h>
-#include <net/bpf.h>
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-#include <dev/dme/if_dmereg.h>
-#include <dev/dme/if_dmevar.h>
-
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#include <dev/extres/regulator/regulator.h>
-#include <dev/gpio/gpiobusvar.h>
-
-#include "miibus_if.h"
-
-struct dme_softc {
- struct ifnet *dme_ifp;
- device_t dme_dev;
- device_t dme_miibus;
- bus_space_handle_t dme_handle;
- bus_space_tag_t dme_tag;
- int dme_rev;
- int dme_bits;
- struct resource *dme_res;
- struct resource *dme_irq;
- void *dme_intrhand;
- struct mtx dme_mtx;
- struct callout dme_tick_ch;
- struct gpiobus_pin *gpio_rset;
- uint32_t dme_ticks;
- uint8_t dme_macaddr[ETHER_ADDR_LEN];
- regulator_t dme_vcc_regulator;
- uint8_t dme_txbusy: 1;
- uint8_t dme_txready: 1;
- uint16_t dme_txlen;
-};
-
-#define DME_CHIP_DM9000 0x00
-#define DME_CHIP_DM9000A 0x19
-#define DME_CHIP_DM9000B 0x1a
-
-#define DME_INT_PHY 1
-
-static int dme_probe(device_t);
-static int dme_attach(device_t);
-static int dme_detach(device_t);
-
-static void dme_intr(void *arg);
-static void dme_init_locked(struct dme_softc *);
-
-static void dme_prepare(struct dme_softc *);
-static void dme_transmit(struct dme_softc *);
-
-static int dme_miibus_writereg(device_t dev, int phy, int reg, int data);
-static int dme_miibus_readreg(device_t dev, int phy, int reg);
-
-/* The bit on the address bus attached to the CMD pin */
-#define BASE_ADDR 0x000
-#define CMD_ADDR BASE_ADDR
-#define DATA_BIT 1
-#define DATA_ADDR 0x002
-
-#undef DME_TRACE
-
-#ifdef DME_TRACE
-#define DTR3 TR3
-#define DTR4 TR4
-#else
-#define NOTR(args...) (void)0
-#define DTR3 NOTR
-#define DTR4 NOTR
-#endif
-
-static uint8_t
-dme_read_reg(struct dme_softc *sc, uint8_t reg)
-{
-
- /* Send the register to read from */
- bus_space_write_1(sc->dme_tag, sc->dme_handle, CMD_ADDR, reg);
- bus_space_barrier(sc->dme_tag, sc->dme_handle, CMD_ADDR, 1,
- BUS_SPACE_BARRIER_WRITE);
-
- /* Get the value of the register */
- return bus_space_read_1(sc->dme_tag, sc->dme_handle, DATA_ADDR);
-}
-
-static void
-dme_write_reg(struct dme_softc *sc, uint8_t reg, uint8_t value)
-{
-
- /* Send the register to write to */
- bus_space_write_1(sc->dme_tag, sc->dme_handle, CMD_ADDR, reg);
- bus_space_barrier(sc->dme_tag, sc->dme_handle, CMD_ADDR, 1,
- BUS_SPACE_BARRIER_WRITE);
-
- /* Write the value to the register */
- bus_space_write_1(sc->dme_tag, sc->dme_handle, DATA_ADDR, value);
- bus_space_barrier(sc->dme_tag, sc->dme_handle, DATA_ADDR, 1,
- BUS_SPACE_BARRIER_WRITE);
-}
-
-static void
-dme_reset(struct dme_softc *sc)
-{
- u_int ncr;
-
- /* Send a soft reset #1 */
- dme_write_reg(sc, DME_NCR, NCR_RST | NCR_LBK_MAC);
- DELAY(100); /* Wait for the MAC to reset */
- ncr = dme_read_reg(sc, DME_NCR);
- if (ncr & NCR_RST)
- device_printf(sc->dme_dev, "device did not complete first reset\n");
-
- /* Send a soft reset #2 per Application Notes v1.22 */
- dme_write_reg(sc, DME_NCR, 0);
- dme_write_reg(sc, DME_NCR, NCR_RST | NCR_LBK_MAC);
- DELAY(100); /* Wait for the MAC to reset */
- ncr = dme_read_reg(sc, DME_NCR);
- if (ncr & NCR_RST)
- device_printf(sc->dme_dev, "device did not complete second reset\n");
-
- /* Reset trasmit state */
- sc->dme_txbusy = 0;
- sc->dme_txready = 0;
-
- DTR3("dme_reset, flags %#x busy %d ready %d",
- sc->dme_ifp ? sc->dme_ifp->if_drv_flags : 0,
- sc->dme_txbusy, sc->dme_txready);
-}
-
-/*
- * Parse string MAC address into usable form
- */
-static int
-dme_parse_macaddr(const char *str, uint8_t *mac)
-{
- int count, i;
- unsigned int amac[ETHER_ADDR_LEN]; /* Aligned version */
-
- count = sscanf(str, "%x%*c%x%*c%x%*c%x%*c%x%*c%x",
- &amac[0], &amac[1], &amac[2],
- &amac[3], &amac[4], &amac[5]);
- if (count < ETHER_ADDR_LEN) {
- memset(mac, 0, ETHER_ADDR_LEN);
- return (1);
- }
-
- /* Copy aligned to result */
- for (i = 0; i < ETHER_ADDR_LEN; i ++)
- mac[i] = (amac[i] & 0xff);
-
- return (0);
-}
-
-/*
- * Try to determine our own MAC address
- */
-static void
-dme_get_macaddr(struct dme_softc *sc)
-{
- char devid_str[32];
- char *var;
- int i;
-
- /* Cannot use resource_string_value with static hints mode */
- snprintf(devid_str, 32, "hint.%s.%d.macaddr",
- device_get_name(sc->dme_dev),
- device_get_unit(sc->dme_dev));
-
- /* Try resource hints */
- if ((var = kern_getenv(devid_str)) != NULL) {
- if (!dme_parse_macaddr(var, sc->dme_macaddr)) {
- device_printf(sc->dme_dev, "MAC address: %s (hints)\n", var);
- return;
- }
- }
-
- /*
- * Try to read MAC address from the device, in case U-Boot has
- * pre-programmed one for us.
- */
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- sc->dme_macaddr[i] = dme_read_reg(sc, DME_PAR(i));
-
- device_printf(sc->dme_dev, "MAC address %6D (existing)\n",
- sc->dme_macaddr, ":");
-}
-
-static void
-dme_config(struct dme_softc *sc)
-{
- int i;
-
- /* Mask all interrupts and reset receive pointer */
- dme_write_reg(sc, DME_IMR, IMR_PAR);
-
- /* Disable GPIO0 to enable the internal PHY */
- dme_write_reg(sc, DME_GPCR, 1);
- dme_write_reg(sc, DME_GPR, 0);
-
-#if 0
- /*
- * Supposedly requires special initialization for DSP PHYs
- * used by DM9000B. Maybe belongs in dedicated PHY driver?
- */
- if (sc->dme_rev == DME_CHIP_DM9000B) {
- dme_miibus_writereg(sc->dme_dev, DME_INT_PHY, MII_BMCR,
- BMCR_RESET);
- dme_miibus_writereg(sc->dme_dev, DME_INT_PHY, MII_DME_DSPCR,
- DSPCR_INIT);
- /* Wait 100ms for it to complete. */
- for (i = 0; i < 100; i++) {
- int reg;
-
- reg = dme_miibus_readreg(sc->dme_dev, DME_INT_PHY, MII_BMCR);
- if ((reg & BMCR_RESET) == 0)
- break;
- DELAY(1000);
- }
- }
-#endif
-
- /* Select the internal PHY and normal loopback */
- dme_write_reg(sc, DME_NCR, NCR_LBK_NORMAL);
- /* Clear any TX requests */
- dme_write_reg(sc, DME_TCR, 0);
- /* Setup backpressure thresholds to 4k and 600us */
- dme_write_reg(sc, DME_BPTR, BPTR_BPHW(3) | BPTR_JPT(0x0f));
- /* Setup flow control */
- dme_write_reg(sc, DME_FCTR, FCTR_HWOT(0x3) | FCTR_LWOT(0x08));
- /* Enable flow control */
- dme_write_reg(sc, DME_FCR, 0xff);
- /* Clear special modes */
- dme_write_reg(sc, DME_SMCR, 0);
- /* Clear TX status */
- dme_write_reg(sc, DME_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
- /* Clear interrrupts */
- dme_write_reg(sc, DME_ISR, 0xff);
- /* Set multicast address filter */
- for (i = 0; i < 8; i++)
- dme_write_reg(sc, DME_MAR(i), 0xff);
- /* Set the MAC address */
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- dme_write_reg(sc, DME_PAR(i), sc->dme_macaddr[i]);
- /* Enable the RX buffer */
- dme_write_reg(sc, DME_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
-
- /* Enable interrupts we care about */
- dme_write_reg(sc, DME_IMR, IMR_PAR | IMR_PRI | IMR_PTI);
-}
-
-void
-dme_prepare(struct dme_softc *sc)
-{
- struct ifnet *ifp;
- struct mbuf *m, *mp;
- uint16_t total_len, len;
-
- DME_ASSERT_LOCKED(sc);
-
- KASSERT(sc->dme_txready == 0,
- ("dme_prepare: called with txready set\n"));
-
- ifp = sc->dme_ifp;
- IFQ_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- DTR3("dme_prepare none, flags %#x busy %d ready %d",
- sc->dme_ifp->if_drv_flags, sc->dme_txbusy, sc->dme_txready);
- return; /* Nothing to transmit */
- }
-
- /* Element has now been removed from the queue, so we better send it */
- BPF_MTAP(ifp, m);
-
- /* Setup the controller to accept the writes */
- bus_space_write_1(sc->dme_tag, sc->dme_handle, CMD_ADDR, DME_MWCMD);
-
- /*
- * TODO: Fix the case where an mbuf is
- * not a multiple of the write size.
- */
- total_len = 0;
- for (mp = m; mp != NULL; mp = mp->m_next) {
- len = mp->m_len;
-
- /* Ignore empty parts */
- if (len == 0)
- continue;
-
- total_len += len;
-
-#if 0
- bus_space_write_multi_2(sc->dme_tag, sc->dme_handle,
- DATA_ADDR, mtod(mp, uint16_t *), (len + 1) / 2);
-#else
- bus_space_write_multi_1(sc->dme_tag, sc->dme_handle,
- DATA_ADDR, mtod(mp, uint8_t *), len);
-#endif
- }
-
- if (total_len % (sc->dme_bits >> 3) != 0)
- panic("dme_prepare: length is not compatible with IO_MODE");
-
- sc->dme_txlen = total_len;
- sc->dme_txready = 1;
- DTR3("dme_prepare done, flags %#x busy %d ready %d",
- sc->dme_ifp->if_drv_flags, sc->dme_txbusy, sc->dme_txready);
-
- m_freem(m);
-}
-
-void
-dme_transmit(struct dme_softc *sc)
-{
-
- DME_ASSERT_LOCKED(sc);
- KASSERT(sc->dme_txready, ("transmit without txready"));
-
- dme_write_reg(sc, DME_TXPLL, sc->dme_txlen & 0xff);
- dme_write_reg(sc, DME_TXPLH, (sc->dme_txlen >> 8) & 0xff );
-
- /* Request to send the packet */
- dme_read_reg(sc, DME_ISR);
-
- dme_write_reg(sc, DME_TCR, TCR_TXREQ);
-
- sc->dme_txready = 0;
- sc->dme_txbusy = 1;
- DTR3("dme_transmit done, flags %#x busy %d ready %d",
- sc->dme_ifp->if_drv_flags, sc->dme_txbusy, sc->dme_txready);
-}
-
-
-static void
-dme_start_locked(struct ifnet *ifp)
-{
- struct dme_softc *sc;
-
- sc = ifp->if_softc;
- DME_ASSERT_LOCKED(sc);
-
- if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING)
- return;
-
- DTR3("dme_start, flags %#x busy %d ready %d",
- sc->dme_ifp->if_drv_flags, sc->dme_txbusy, sc->dme_txready);
- KASSERT(sc->dme_txbusy == 0 || sc->dme_txready == 0,
- ("dme: send without empty queue\n"));
-
- dme_prepare(sc);
-
- if (sc->dme_txbusy == 0) {
- /* We are ready to transmit right away */
- dme_transmit(sc);
- dme_prepare(sc); /* Prepare next one */
- }
- /*
- * We need to wait until the current packet has
- * been transmitted.
- */
- if (sc->dme_txready != 0)
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-}
-
-static void
-dme_start(struct ifnet *ifp)
-{
- struct dme_softc *sc;
-
- sc = ifp->if_softc;
- DME_LOCK(sc);
- dme_start_locked(ifp);
- DME_UNLOCK(sc);
-}
-
-static void
-dme_stop(struct dme_softc *sc)
-{
- struct ifnet *ifp;
-
- DME_ASSERT_LOCKED(sc);
- /* Disable receiver */
- dme_write_reg(sc, DME_RCR, 0x00);
- /* Mask interrupts */
- dme_write_reg(sc, DME_IMR, 0x00);
- /* Stop poll */
- callout_stop(&sc->dme_tick_ch);
-
- ifp = sc->dme_ifp;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- DTR3("dme_stop, flags %#x busy %d ready %d",
- sc->dme_ifp->if_drv_flags, sc->dme_txbusy, sc->dme_txready);
- sc->dme_txbusy = 0;
- sc->dme_txready = 0;
-}
-
-static int
-dme_rxeof(struct dme_softc *sc)
-{
- struct ifnet *ifp;
- struct mbuf *m;
- int len, i;
-
- DME_ASSERT_LOCKED(sc);
-
- ifp = sc->dme_ifp;
-
- /* Read the first byte to check it correct */
- (void)dme_read_reg(sc, DME_MRCMDX);
- i = bus_space_read_1(sc->dme_tag, sc->dme_handle, DATA_ADDR);
- switch(bus_space_read_1(sc->dme_tag, sc->dme_handle, DATA_ADDR)) {
- case 1:
- /* Correct value */
- break;
- case 0:
- return 1;
- default:
- /* Error */
- return -1;
- }
-
- i = dme_read_reg(sc, DME_MRRL);
- i |= dme_read_reg(sc, DME_MRRH) << 8;
-
- len = dme_read_reg(sc, DME_ROCR);
-
- bus_space_write_1(sc->dme_tag, sc->dme_handle, CMD_ADDR, DME_MRCMD);
- len = 0;
- switch(sc->dme_bits) {
- case 8:
- i = bus_space_read_1(sc->dme_tag, sc->dme_handle, DATA_ADDR);
- i <<= 8;
- i |= bus_space_read_1(sc->dme_tag, sc->dme_handle, DATA_ADDR);
-
- len = bus_space_read_1(sc->dme_tag, sc->dme_handle, DATA_ADDR);
- len |= bus_space_read_1(sc->dme_tag, sc->dme_handle,
- DATA_ADDR) << 8;
- break;
- case 16:
- bus_space_read_2(sc->dme_tag, sc->dme_handle, DATA_ADDR);
- len = bus_space_read_2(sc->dme_tag, sc->dme_handle, DATA_ADDR);
- break;
- case 32:
- {
- uint32_t reg;
-
- reg = bus_space_read_4(sc->dme_tag, sc->dme_handle, DATA_ADDR);
- len = reg & 0xFFFF;
- break;
- }
- }
-
- MGETHDR(m, M_NOWAIT, MT_DATA);
- if (m == NULL)
- return -1;
-
- if (len > MHLEN - ETHER_ALIGN) {
- MCLGET(m, M_NOWAIT);
- if (!(m->m_flags & M_EXT)) {
- m_freem(m);
- return -1;
- }
- }
-
- m->m_pkthdr.rcvif = ifp;
- m->m_len = m->m_pkthdr.len = len;
- m_adj(m, ETHER_ALIGN);
-
- /* Read the data */
-#if 0
- bus_space_read_multi_2(sc->dme_tag, sc->dme_handle, DATA_ADDR,
- mtod(m, uint16_t *), (len + 1) / 2);
-#else
- bus_space_read_multi_1(sc->dme_tag, sc->dme_handle, DATA_ADDR,
- mtod(m, uint8_t *), len);
-#endif
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
- DME_UNLOCK(sc);
- (*ifp->if_input)(ifp, m);
- DME_LOCK(sc);
-
- return 0;
-}
-
-static void
-dme_tick(void *arg)
-{
- struct dme_softc *sc;
- struct mii_data *mii;
-
- sc = (struct dme_softc *)arg;
-
- /* Probably too frequent? */
- mii = device_get_softc(sc->dme_miibus);
- mii_tick(mii);
-
- callout_reset(&sc->dme_tick_ch, hz, dme_tick, sc);
-}
-
-static void
-dme_intr(void *arg)
-{
- struct dme_softc *sc;
- uint32_t intr_status;
-
- sc = (struct dme_softc *)arg;
-
- DME_LOCK(sc);
-
- intr_status = dme_read_reg(sc, DME_ISR);
- dme_write_reg(sc, DME_ISR, intr_status);
-
- DTR4("dme_intr flags %#x busy %d ready %d intr %#x",
- sc->dme_ifp->if_drv_flags, sc->dme_txbusy,
- sc->dme_txready, intr_status);
-
- if (intr_status & ISR_PT) {
- uint8_t nsr, tx_status;
-
- sc->dme_txbusy = 0;
-
- nsr = dme_read_reg(sc, DME_NSR);
-
- if (nsr & NSR_TX1END)
- tx_status = dme_read_reg(sc, DME_TSR1);
- else if (nsr & NSR_TX2END)
- tx_status = dme_read_reg(sc, DME_TSR2);
- else
- tx_status = 1;
-
- DTR4("dme_intr flags %#x busy %d ready %d nsr %#x",
- sc->dme_ifp->if_drv_flags, sc->dme_txbusy,
- sc->dme_txready, nsr);
-
- /* Prepare packet to send if none is currently pending */
- if (sc->dme_txready == 0)
- dme_prepare(sc);
- /* Send the packet out of one is waiting for transmit */
- if (sc->dme_txready != 0) {
- /* Initiate transmission of the prepared packet */
- dme_transmit(sc);
- /* Prepare next packet to send */
- dme_prepare(sc);
- /*
- * We need to wait until the current packet has
- * been transmitted.
- */
- if (sc->dme_txready != 0)
- sc->dme_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
- }
-
- if (intr_status & ISR_PR) {
- /* Read the packets off the device */
- while (dme_rxeof(sc) == 0)
- continue;
- }
- DME_UNLOCK(sc);
-}
-
-static void
-dme_setmode(struct dme_softc *sc)
-{
-}
-
-static int
-dme_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct dme_softc *sc;
- struct mii_data *mii;
- struct ifreq *ifr;
- int error = 0;
-
- sc = ifp->if_softc;
- ifr = (struct ifreq *)data;
-
- switch (command) {
- case SIOCSIFFLAGS:
- /*
- * Switch interface state between "running" and
- * "stopped", reflecting the UP flag.
- */
- DME_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- dme_init_locked(sc);
- }
- } else {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
- dme_stop(sc);
- }
- }
- dme_setmode(sc);
- DME_UNLOCK(sc);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- mii = device_get_softc(sc->dme_miibus);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
- break;
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
- return (error);
-}
-
-static void dme_init_locked(struct dme_softc *sc)
-{
- struct ifnet *ifp = sc->dme_ifp;
-
- DME_ASSERT_LOCKED(sc);
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
- return;
-
- dme_reset(sc);
- dme_config(sc);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- callout_reset(&sc->dme_tick_ch, hz, dme_tick, sc);
-}
-
-static void
-dme_init(void *xcs)
-{
- struct dme_softc *sc = xcs;
-
- DME_LOCK(sc);
- dme_init_locked(sc);
- DME_UNLOCK(sc);
-}
-
-static int
-dme_ifmedia_upd(struct ifnet *ifp)
-{
- struct dme_softc *sc;
- struct mii_data *mii;
-
- sc = ifp->if_softc;
- mii = device_get_softc(sc->dme_miibus);
-
- DME_LOCK(sc);
- mii_mediachg(mii);
- DME_UNLOCK(sc);
-
- return (0);
-}
-
-static void
-dme_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct dme_softc *sc;
- struct mii_data *mii;
-
- sc = ifp->if_softc;
- mii = device_get_softc(sc->dme_miibus);
-
- DME_LOCK(sc);
- mii_pollstat(mii);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
- DME_UNLOCK(sc);
-}
-
-static struct ofw_compat_data compat_data[] = {
- { "davicom,dm9000", true },
- { NULL, false }
-};
-
-static int
-dme_probe(device_t dev)
-{
- if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
- return (ENXIO);
- device_set_desc(dev, "Davicom DM9000");
- return (0);
-}
-
-static int
-dme_attach(device_t dev)
-{
- struct dme_softc *sc;
- struct ifnet *ifp;
- int error, rid;
- uint32_t data;
-
- sc = device_get_softc(dev);
- sc->dme_dev = dev;
-
- error = 0;
-
- mtx_init(&sc->dme_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
- MTX_DEF);
- callout_init_mtx(&sc->dme_tick_ch, &sc->dme_mtx, 0);
-
- rid = 0;
- sc->dme_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (sc->dme_res == NULL) {
- device_printf(dev, "unable to map memory\n");
- error = ENXIO;
- goto fail;
- }
-
- rid = 0;
- sc->dme_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (sc->dme_irq == NULL) {
- device_printf(dev, "unable to map memory\n");
- error = ENXIO;
- goto fail;
- }
- /*
- * Power the chip up, if necessary
- */
- error = regulator_get_by_ofw_property(dev, 0, "vcc-supply", &sc->dme_vcc_regulator);
- if (error == 0) {
- error = regulator_enable(sc->dme_vcc_regulator);
- if (error != 0) {
- device_printf(dev, "unable to enable power supply\n");
- error = ENXIO;
- goto fail;
- }
- }
-
- /*
- * Delay a little. This seems required on rev-1 boards (green.)
- */
- DELAY(100000);
-
- /* Bring controller out of reset */
- error = ofw_gpiobus_parse_gpios(dev, "reset-gpios", &sc->gpio_rset);
- if (error > 1) {
- device_printf(dev, "too many reset gpios\n");
- sc->gpio_rset = NULL;
- error = ENXIO;
- goto fail;
- }
-
- if (sc->gpio_rset != NULL) {
- error = GPIO_PIN_SET(sc->gpio_rset->dev, sc->gpio_rset->pin, 0);
- if (error != 0) {
- device_printf(dev, "Cannot configure GPIO pin %d on %s\n",
- sc->gpio_rset->pin, device_get_nameunit(sc->gpio_rset->dev));
- goto fail;
- }
-
- error = GPIO_PIN_SETFLAGS(sc->gpio_rset->dev, sc->gpio_rset->pin,
- GPIO_PIN_OUTPUT);
- if (error != 0) {
- device_printf(dev, "Cannot configure GPIO pin %d on %s\n",
- sc->gpio_rset->pin, device_get_nameunit(sc->gpio_rset->dev));
- goto fail;
- }
-
- DELAY(2000);
-
- error = GPIO_PIN_SET(sc->gpio_rset->dev, sc->gpio_rset->pin, 1);
- if (error != 0) {
- device_printf(dev, "Cannot configure GPIO pin %d on %s\n",
- sc->gpio_rset->pin, device_get_nameunit(sc->gpio_rset->dev));
- goto fail;
- }
-
- DELAY(4000);
- } else
- device_printf(dev, "Unable to find reset GPIO\n");
-
- sc->dme_tag = rman_get_bustag(sc->dme_res);
- sc->dme_handle = rman_get_bushandle(sc->dme_res);
-
- /* Reset the chip as soon as possible */
- dme_reset(sc);
-
- /* Figure IO mode */
- switch((dme_read_reg(sc, DME_ISR) >> 6) & 0x03) {
- case 0:
- /* 16 bit */
- sc->dme_bits = 16;
- break;
- case 1:
- /* 32 bit */
- sc->dme_bits = 32;
- break;
- case 2:
- /* 8 bit */
- sc->dme_bits = 8;
- break;
- default:
- /* reserved */
- device_printf(dev, "Unable to determine device mode\n");
- error = ENXIO;
- goto fail;
- }
-
- DELAY(100000);
-
- /* Read vendor and device id's */
- data = dme_read_reg(sc, DME_VIDH) << 8;
- data |= dme_read_reg(sc, DME_VIDL);
- device_printf(dev, "Vendor ID: 0x%04x\n", data);
-
- /* Read vendor and device id's */
- data = dme_read_reg(sc, DME_PIDH) << 8;
- data |= dme_read_reg(sc, DME_PIDL);
- device_printf(dev, "Product ID: 0x%04x\n", data);
-
- /* Chip revision */
- data = dme_read_reg(sc, DME_CHIPR);
- device_printf(dev, "Revision: 0x%04x\n", data);
- if (data != DME_CHIP_DM9000A && data != DME_CHIP_DM9000B)
- data = DME_CHIP_DM9000;
- sc->dme_rev = data;
-
- device_printf(dev, "using %d-bit IO mode\n", sc->dme_bits);
- KASSERT(sc->dme_bits == 8, ("wrong io mode"));
-
- /* Try to figure our mac address */
- dme_get_macaddr(sc);
-
- /* Configure chip after reset */
- dme_config(sc);
-
- ifp = sc->dme_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(dev, "unable to allocate ifp\n");
- error = ENOSPC;
- goto fail;
- }
- ifp->if_softc = sc;
-
- /* Setup MII */
- error = mii_attach(dev, &sc->dme_miibus, ifp, dme_ifmedia_upd,
- dme_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
- /* This should never happen as the DM9000 contains it's own PHY */
- if (error != 0) {
- device_printf(dev, "PHY probe failed\n");
- goto fail;
- }
-
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_start = dme_start;
- ifp->if_ioctl = dme_ioctl;
- ifp->if_init = dme_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
-
- ether_ifattach(ifp, sc->dme_macaddr);
-
- error = bus_setup_intr(dev, sc->dme_irq, INTR_TYPE_NET | INTR_MPSAFE,
- NULL, dme_intr, sc, &sc->dme_intrhand);
- if (error) {
- device_printf(dev, "couldn't set up irq\n");
- ether_ifdetach(ifp);
- goto fail;
- }
-
-fail:
- if (error != 0)
- dme_detach(dev);
- return (error);
-}
-
-static int
-dme_detach(device_t dev)
-{
- struct dme_softc *sc;
- struct ifnet *ifp;
-
- sc = device_get_softc(dev);
- KASSERT(mtx_initialized(&sc->dme_mtx), ("dme mutex not initialized"));
-
- ifp = sc->dme_ifp;
-
- if (device_is_attached(dev)) {
- DME_LOCK(sc);
- dme_stop(sc);
- DME_UNLOCK(sc);
- ether_ifdetach(ifp);
- callout_drain(&sc->dme_tick_ch);
- }
-
- if (sc->dme_miibus)
- device_delete_child(dev, sc->dme_miibus);
- bus_generic_detach(dev);
-
- if (sc->dme_vcc_regulator != 0)
- regulator_release(sc->dme_vcc_regulator);
- if (sc->dme_intrhand)
- bus_teardown_intr(dev, sc->dme_irq, sc->dme_intrhand);
- if (sc->dme_irq)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dme_irq);
- if (sc->dme_res)
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->dme_res);
-
- if (ifp != NULL)
- if_free(ifp);
-
- mtx_destroy(&sc->dme_mtx);
-
- return (0);
*** 286 LINES SKIPPED ***