summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormdodd <mdodd@FreeBSD.org>2002-03-29 11:22:22 +0000
committermdodd <mdodd@FreeBSD.org>2002-03-29 11:22:22 +0000
commit84c21f1d8ff69f47f8e2bef01392d5b39cf9ce02 (patch)
treeacee2dafe452f857b35aa52d9223075e812b1e18 /sys
parentfdbdd2f5af8ced636e98ffa82c0898512b04bfba (diff)
downloadFreeBSD-src-84c21f1d8ff69f47f8e2bef01392d5b39cf9ce02.zip
FreeBSD-src-84c21f1d8ff69f47f8e2bef01392d5b39cf9ce02.tar.gz
- Merge the pdq driver (if_fpa and if_fea) from NetBSD.
Among other things this gets us ifmedia support. - Update fddi_ifattach() to take an additional argument.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pdq/if_fea.c180
-rw-r--r--sys/dev/pdq/if_fpa.c172
-rw-r--r--sys/dev/pdq/pdq.c504
-rw-r--r--sys/dev/pdq/pdq_freebsd.h271
-rw-r--r--sys/dev/pdq/pdq_ifsubr.c670
-rw-r--r--sys/dev/pdq/pdqreg.h168
-rw-r--r--sys/dev/pdq/pdqvar.h247
-rw-r--r--sys/net/fddi.h4
-rw-r--r--sys/net/if_fddisubr.c13
9 files changed, 1707 insertions, 522 deletions
diff --git a/sys/dev/pdq/if_fea.c b/sys/dev/pdq/if_fea.c
index ee4fba3..3348550 100644
--- a/sys/dev/pdq/if_fea.c
+++ b/sys/dev/pdq/if_fea.c
@@ -35,25 +35,32 @@
#include <sys/kernel.h>
#include <sys/socket.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-
#include <sys/module.h>
#include <sys/bus.h>
+
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_media.h>
+#include <net/fddi.h>
+
#include <dev/eisa/eisaconf.h>
-#include <dev/pdq/pdqvar.h>
+
+#include <dev/pdq/pdq_freebsd.h>
#include <dev/pdq/pdqreg.h>
static void pdq_eisa_subprobe (pdq_bus_t, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *);
static void pdq_eisa_devinit (pdq_softc_t *);
static const char * pdq_eisa_match (eisa_id_t);
+
static int pdq_eisa_probe (device_t);
static int pdq_eisa_attach (device_t);
-void pdq_eisa_intr (void *);
+static int pdq_eisa_detach (device_t);
static int pdq_eisa_shutdown (device_t);
+static void pdq_eisa_ifintr (void *);
#define DEFEA_IRQS 0x0000FBA9U
@@ -91,18 +98,18 @@ pdq_eisa_devinit (sc)
/*
* Do the standard initialization for the DEFEA registers.
*/
- PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_FUNCTION_CTRL, 0x23);
- PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CMP_1_1, (sc->sc_iobase >> 8) & 0xF0);
- PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CMP_0_1, (sc->sc_iobase >> 8) & 0xF0);
- PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_SLOT_CTRL, 0x01);
- data = PDQ_OS_IORD_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF);
+ PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_FUNCTION_CTRL, 0x23);
+ PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CMP_1_1, (sc->io_bsh >> 8) & 0xF0);
+ PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CMP_0_1, (sc->io_bsh >> 8) & 0xF0);
+ PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_SLOT_CTRL, 0x01);
+ data = PDQ_OS_IORD_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF);
#if defined(PDQ_IOMAPPED)
- PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data & ~1);
+ PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF, data & ~1);
#else
- PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data | 1);
+ PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF, data | 1);
#endif
- data = PDQ_OS_IORD_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0);
- PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0, data | DEFEA_INTRENABLE);
+ data = PDQ_OS_IORD_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CONFIG_STAT_0);
+ PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CONFIG_STAT_0, data | DEFEA_INTRENABLE);
return;
}
@@ -144,7 +151,7 @@ pdq_eisa_probe (dev)
device_set_desc(dev, desc);
iobase = eisa_get_slot(dev) * EISA_SLOT_SIZE;
- pdq_eisa_subprobe(PDQ_BUS_EISA, iobase, &maddr, &msize, &irq);
+ pdq_eisa_subprobe(SYS_RES_IOPORT, iobase, &maddr, &msize, &irq);
eisa_add_iospace(dev, iobase, 0x200, RESVADDR_NONE);
eisa_add_mspace(dev, maddr, msize, RESVADDR_NONE);
@@ -153,99 +160,119 @@ pdq_eisa_probe (dev)
return (0);
}
-void
-pdq_eisa_intr(xdev)
- void *xdev;
+static void
+pdq_eisa_ifintr(arg)
+ void * arg;
{
- device_t dev = (device_t) xdev;
- pdq_softc_t *sc = device_get_softc(dev);
+ device_t dev;
+ pdq_softc_t * sc;
+
+ dev = (device_t)arg;
+ sc = device_get_softc(dev);
+
+ PDQ_LOCK(sc);
(void) pdq_interrupt(sc->sc_pdq);
+ PDQ_LOCK(sc);
return;
}
static int
pdq_eisa_attach (dev)
- device_t dev;
+ device_t dev;
{
- pdq_softc_t *sc = device_get_softc(dev);
- struct resource *io = 0;
- struct resource *irq = 0;
- struct resource *mspace = 0;
- int rid;
- void *ih;
- u_int32_t m_addr, m_size;
-
- rid = 0;
- io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
- 0, ~0, 1, RF_ACTIVE);
-
- if (!io) {
- device_printf(dev, "No I/O space?!\n");
- goto bad;
- }
+ pdq_softc_t * sc;
+ struct ifnet * ifp;
+ int error;
- rid = 0;
- mspace = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
- 0, ~0, 1, RF_ACTIVE);
+ sc = device_get_softc(dev);
+ ifp = &sc->arpcom.ac_if;
- if (!mspace) {
- device_printf(dev, "No memory space?!\n");
+ sc->dev = dev;
+
+ sc->io_rid = 0;
+ sc->io_type = SYS_RES_IOPORT;
+ sc->io = bus_alloc_resource(dev, sc->io_type, &sc->io_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!sc->io) {
+ device_printf(dev, "Unable to allocate I/O space resource.\n");
+ error = ENXIO;
goto bad;
}
-
- rid = 0;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
- 0, ~0, 1, RF_ACTIVE);
-
- if (!irq) {
- device_printf(dev, "No, irq?!\n");
+ sc->io_bsh = rman_get_bushandle(sc->io);
+ sc->io_bst = rman_get_bustag(sc->io);
+
+ sc->mem_rid = 0;
+ sc->mem_type = SYS_RES_MEMORY;
+ sc->mem = bus_alloc_resource(dev, sc->mem_type, &sc->mem_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!sc->mem) {
+ device_printf(dev, "Unable to allocate memory resource.\n");
+ error = ENXIO;
+ goto bad;
+ }
+ sc->mem_bsh = rman_get_bushandle(sc->mem);
+ sc->mem_bst = rman_get_bustag(sc->mem);
+
+ sc->irq_rid = 0;
+ sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
+ 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
+ if (!sc->irq) {
+ device_printf(dev, "Unable to allocate interrupt resource.\n");
+ error = ENXIO;
goto bad;
}
- m_addr = rman_get_start(mspace);
- m_size = rman_get_size(mspace);
-
- sc->sc_iobase = (pdq_bus_ioport_t) rman_get_start(io);
- sc->sc_membase = (pdq_bus_memaddr_t) pmap_mapdev(m_addr, m_size);
- sc->sc_if.if_name = "fea";
- sc->sc_if.if_unit = device_get_unit(dev);
+ ifp->if_name = "fea";
+ ifp->if_unit = device_get_unit(dev);
pdq_eisa_devinit(sc);
- sc->sc_pdq = pdq_initialize(PDQ_BUS_EISA, sc->sc_membase,
- sc->sc_if.if_name, sc->sc_if.if_unit,
- (void *) sc, PDQ_DEFEA);
+ sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh,
+ ifp->if_name, ifp->if_unit,
+ (void *)sc, PDQ_DEFEA);
if (sc->sc_pdq == NULL) {
- device_printf(dev, "initialization failed\n");
+ device_printf(dev, "Initialization failed.\n");
+ error = ENXIO;
goto bad;
}
- if (bus_setup_intr(dev, irq, INTR_TYPE_NET, pdq_eisa_intr, dev, &ih)) {
+ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
+ pdq_eisa_ifintr, dev, &sc->irq_ih);
+ if (error) {
+ device_printf(dev, "Failed to setup interrupt handler.\n");
+ error = ENXIO;
goto bad;
}
- bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
- pdq_ifattach(sc, NULL);
+ bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes,
+ (caddr_t) sc->arpcom.ac_enaddr, FDDI_ADDR_LEN);
+ pdq_ifattach(sc);
return (0);
-
bad:
- if (io)
- bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
- if (irq)
- bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
- if (mspace)
- bus_release_resource(dev, SYS_RES_MEMORY, 0, mspace);
-
- return (-1);
+ pdq_free(dev);
+ return (error);
+}
+
+static int
+pdq_eisa_detach (dev)
+ device_t dev;
+{
+ pdq_softc_t * sc;
+
+ sc = device_get_softc(dev);
+ pdq_ifdetach(sc);
+
+ return (0);
}
static int
pdq_eisa_shutdown(dev)
device_t dev;
{
- pdq_softc_t *sc = device_get_softc(dev);
+ pdq_softc_t * sc;
+ sc = device_get_softc(dev);
pdq_hwreset(sc->sc_pdq);
return (0);
@@ -254,6 +281,7 @@ pdq_eisa_shutdown(dev)
static device_method_t pdq_eisa_methods[] = {
DEVMETHOD(device_probe, pdq_eisa_probe),
DEVMETHOD(device_attach, pdq_eisa_attach),
+ DEVMETHOD(device_attach, pdq_eisa_detach),
DEVMETHOD(device_shutdown, pdq_eisa_shutdown),
{ 0, 0 }
@@ -265,6 +293,6 @@ static driver_t pdq_eisa_driver = {
sizeof(pdq_softc_t),
};
-static devclass_t pdq_devclass;
-
-DRIVER_MODULE(pdq, eisa, pdq_eisa_driver, pdq_devclass, 0, 0);
+DRIVER_MODULE(if_fea, eisa, pdq_eisa_driver, pdq_devclass, 0, 0);
+/* MODULE_DEPEND(if_fea, eisa, 1, 1, 1); */
+MODULE_DEPEND(if_fea, fddi, 1, 1, 1);
diff --git a/sys/dev/pdq/if_fpa.c b/sys/dev/pdq/if_fpa.c
index 9eb3f50..c01b8ad 100644
--- a/sys/dev/pdq/if_fpa.c
+++ b/sys/dev/pdq/if_fpa.c
@@ -32,22 +32,29 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
-#include <net/if.h>
+#include <sys/module.h>
+#include <sys/bus.h>
-#include <net/ethernet.h>
-#include <net/if_arp.h>
-#include <dev/pdq/pdqvar.h>
-#include <dev/pdq/pdqreg.h>
+#include <machine/bus_memio.h>
+#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/resource.h>
-#include <sys/bus.h>
-#include <sys/rman.h>
-#include <pci/pcivar.h>
-#include <pci/pcireg.h>
+#include <sys/rman.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_media.h>
+#include <net/fddi.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/pdq/pdq_freebsd.h>
+#include <dev/pdq/pdqreg.h>
#define DEC_VENDORID 0x1011
#define DEFPA_CHIPID 0x000F
@@ -58,13 +65,26 @@
#define PCI_CBMA 0x10 /* Configuration Base Memory Address */
#define PCI_CBIO 0x14 /* Configuration Base I/O Address */
+static int pdq_pci_probe (device_t);
+static int pdq_pci_attach (device_t);
+static int pdq_pci_detach (device_t);
+static void pdq_pci_shutdown (device_t);
+static void pdq_pci_ifintr (void *);
+
static void
pdq_pci_ifintr(void *arg)
{
+ device_t dev;
pdq_softc_t *sc;
- sc = device_get_softc(arg);
+ dev = (device_t)arg;
+ sc = device_get_softc(dev);
+
+ PDQ_LOCK(sc);
(void) pdq_interrupt(sc->sc_pdq);
+ PDQ_UNLOCK(sc);
+
+ return;
}
/*
@@ -76,61 +96,112 @@ pdq_pci_probe(device_t dev)
if (pci_get_vendor(dev) == DEC_VENDORID &&
pci_get_device(dev) == DEFPA_CHIPID) {
device_set_desc(dev, "Digital DEFPA PCI FDDI Controller");
- return 0;
+ return (0);
}
- return ENXIO;
+
+ return (ENXIO);
}
static int
pdq_pci_attach(device_t dev)
{
pdq_softc_t *sc;
- int data;
- struct resource *memres, *irqres;
- int rid;
- void *ih;
+ struct ifnet *ifp;
+ u_int32_t command;
+ int error;
- memres = NULL;
- irqres = NULL;
sc = device_get_softc(dev);
+ ifp = &sc->arpcom.ac_if;
+
+ sc->dev = dev;
- data = pci_read_config(dev, PCIR_LATTIMER, 1);
- if (data < DEFPA_LATENCY) {
- data = DEFPA_LATENCY;
- pci_write_config(dev, PCIR_LATTIMER, data, 1);
+ /*
+ * Map control/status registers.
+ */
+ pci_enable_busmaster(dev);
+ pci_enable_io(dev, SYS_RES_IOPORT);
+ pci_enable_io(dev, SYS_RES_MEMORY);
+ command = pci_read_config(dev, PCIR_COMMAND, 4);
+
+ if (!(command & PCIM_CMD_PORTEN)) {
+ device_printf(dev, "Failed to enable PCI I/O ports.\n");
+ error = ENXIO;
+ goto bad;
}
- rid = PCI_CBMA;
- memres = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!memres)
+ if (!(command & PCIM_CMD_MEMEN)) {
+ device_printf(dev, "Failed to enable PCI memory mapping.\n");
+ error = ENXIO;
goto bad;
+ }
+
+ command = pci_read_config(dev, PCIR_LATTIMER, 1);
+ if (command < DEFPA_LATENCY) {
+ command = DEFPA_LATENCY;
+ pci_write_config(dev, PCIR_LATTIMER, command, 1);
+ }
- sc->sc_if.if_name = "fpa";
- sc->sc_if.if_unit = device_get_unit(dev);
- sc->sc_membase = (pdq_bus_memaddr_t) rman_get_virtual(memres);
- sc->sc_pdq = pdq_initialize(PDQ_BUS_PCI, sc->sc_membase,
- sc->sc_if.if_name, sc->sc_if.if_unit,
- (void *) sc, PDQ_DEFPA);
- if (sc->sc_pdq == NULL)
+ sc->mem_rid = PCI_CBMA;
+ sc->mem_type = SYS_RES_MEMORY;
+ sc->mem = bus_alloc_resource(dev, sc->mem_type, &sc->mem_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!sc->mem) {
+ device_printf(dev, "Unable to allocate I/O space resource.\n");
+ error = ENXIO;
goto bad;
- bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
- pdq_ifattach(sc, NULL);
- rid = 0;
- irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE);
- if (!irqres)
+ }
+ sc->mem_bsh = rman_get_bushandle(sc->mem);
+ sc->mem_bst = rman_get_bustag(sc->mem);
+
+ sc->irq_rid = 0;
+ sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
+ 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
+ if (!sc->irq) {
+ device_printf(dev, "Unable to allocate interrupt resource.\n");
+ error = ENXIO;
goto bad;
- if (bus_setup_intr(dev, irqres, INTR_TYPE_NET, pdq_pci_ifintr,
- (void *)dev, &ih))
+ }
+
+ ifp->if_name = "fpa";
+ ifp->if_unit = device_get_unit(dev);
+
+ sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh,
+ ifp->if_name, ifp->if_unit,
+ (void *)sc, PDQ_DEFPA);
+ if (sc->sc_pdq == NULL) {
+ device_printf(dev, "Initialization failed.\n");
+ error = ENXIO;
goto bad;
- return 0;
+ }
+ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
+ pdq_pci_ifintr, dev, &sc->irq_ih);
+ if (error) {
+ device_printf(dev, "Failed to setup interrupt handler.\n");
+ error = ENXIO;
+ goto bad;
+ }
+
+ bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes,
+ (caddr_t) sc->arpcom.ac_enaddr, FDDI_ADDR_LEN);
+ pdq_ifattach(sc);
+
+ return (0);
bad:
- if (memres)
- bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, memres);
- if (irqres)
- bus_release_resource(dev, SYS_RES_IRQ, 0, irqres);
- return ENXIO;
+ pdq_free(dev);
+ return (error);
+}
+
+static int
+pdq_pci_detach (dev)
+ device_t dev;
+{
+ pdq_softc_t *sc;
+
+ sc = device_get_softc(dev);
+ pdq_ifdetach(sc);
+
+ return (0);
}
static void
@@ -140,19 +211,26 @@ pdq_pci_shutdown(device_t dev)
sc = device_get_softc(dev);
pdq_hwreset(sc->sc_pdq);
+
+ return;
}
static device_method_t pdq_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pdq_pci_probe),
DEVMETHOD(device_attach, pdq_pci_attach),
+ DEVMETHOD(device_detach, pdq_pci_detach),
DEVMETHOD(device_shutdown, pdq_pci_shutdown),
+
{ 0, 0 }
};
+
static driver_t pdq_pci_driver = {
"fpa",
pdq_pci_methods,
sizeof(pdq_softc_t),
};
-static devclass_t pdq_devclass;
+
DRIVER_MODULE(if_fpa, pci, pdq_pci_driver, pdq_devclass, 0, 0);
+/* MODULE_DEPEND(if_fpa, pci, 1, 1, 1); */
+MODULE_DEPEND(if_fpa, fddi, 1, 1, 1);
diff --git a/sys/dev/pdq/pdq.c b/sys/dev/pdq/pdq.c
index 055bdc2..fd9aa00 100644
--- a/sys/dev/pdq/pdq.c
+++ b/sys/dev/pdq/pdq.c
@@ -1,3 +1,5 @@
+/* $NetBSD: pdq.c,v 1.33 2001/11/13 13:14:43 lukem Exp $ */
+
/*-
* Copyright (c) 1995,1996 Matt Thomas <matt@3am-software.com>
* All rights reserved.
@@ -8,7 +10,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * 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
@@ -21,6 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
+ * Id: pdq.c,v 1.32 1997/06/05 01:56:35 thomas Exp
* $FreeBSD$
*
*/
@@ -28,7 +31,7 @@
/*
* DEC PDQ FDDI Controller O/S independent code
*
- * This module should work any PDQ based board. Note that changes for
+ * This module should work any on PDQ based board. Note that changes for
* MIPS and Alpha architectures (or any other architecture which requires
* a flushing of memory or write buffers and/or has incoherent caches)
* have yet to be made.
@@ -37,10 +40,18 @@
* flushing of the write buffers.
*/
+#ifdef __NetBSD__
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: pdq.c,v 1.33 2001/11/13 13:14:43 lukem Exp $");
+#endif
+
#define PDQ_HWSUPPORT /* for pdq.h */
#if defined(__FreeBSD__)
-#include <dev/pdq/pdqvar.h>
+/*
+ * What a botch having to specific includes for FreeBSD!
+ */
+#include <dev/pdq/pdq_freebsd.h>
#include <dev/pdq/pdqreg.h>
#else
#include "pdqvar.h"
@@ -76,6 +87,7 @@ static const char * const pdq_entities[] = {
};
static const char * const pdq_station_events[] = {
+ "Unknown Event #0",
"Trace Received"
};
@@ -218,6 +230,8 @@ pdq_print_fddi_chars(
pdq_pmd_types[rsp->status_chars_get.pmd_type[1] / 100][rsp->status_chars_get.pmd_type[1] % 100]);
printf("\n");
+
+ pdq_os_update_status(pdq, rsp);
}
static void
@@ -261,6 +275,7 @@ pdq_init_pci_csrs(
static void
pdq_flush_databuf_queue(
+ pdq_t *pdq,
pdq_databuf_queue_t *q)
{
PDQ_OS_DATABUF_T *pdu;
@@ -268,7 +283,7 @@ pdq_flush_databuf_queue(
PDQ_OS_DATABUF_DEQUEUE(q, pdu);
if (pdu == NULL)
return;
- PDQ_OS_DATABUF_FREE(pdu);
+ PDQ_OS_DATABUF_FREE(pdq, pdu);
}
}
@@ -409,7 +424,6 @@ static const struct {
sizeof(pdq_response_addr_filter_get_t),
"Addr Filter Get"
},
-#if 0
{ sizeof(pdq_cmd_generic_t), /* 9 - PDQC_ERROR_LOG_CLEAR */
sizeof(pdq_response_generic_t),
"Error Log Clear"
@@ -443,7 +457,7 @@ static const struct {
sizeof(pdq_response_generic_t),
"SMT MIB Set",
},
-#endif
+ { 0, 0, "Bogus CMD" },
};
static void
@@ -453,6 +467,7 @@ pdq_queue_commands(
const pdq_csrs_t * const csrs = &pdq->pdq_csrs;
pdq_command_info_t * const ci = &pdq->pdq_command_info;
pdq_descriptor_block_t * const dbp = pdq->pdq_dbp;
+ pdq_txdesc_t * const txd = &dbp->pdqdb_command_requests[ci->ci_request_producer];
pdq_cmd_code_t op;
pdq_uint32_t cmdlen, rsplen, mask;
@@ -487,23 +502,19 @@ pdq_queue_commands(
* Obtain and fill in the descriptor for the command (descriptor is
* pre-initialized)
*/
- dbp->pdqdb_command_requests[ci->ci_request_producer].txd_seg_len = cmdlen;
- PDQ_ADVANCE(ci->ci_request_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_requests));
-
- /*
- * Obtain and fill in the descriptor for the response (descriptor is
- * pre-initialized)
- */
- dbp->pdqdb_command_responses[ci->ci_response_producer].rxd_seg_len_hi = cmdlen / 16;
- PDQ_ADVANCE(ci->ci_response_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_responses));
+ txd->txd_seg_len = cmdlen;
/*
* Clear the command area, set the opcode, and the command from the pending
* mask.
*/
- PDQ_OS_MEMZERO(ci->ci_bufstart, cmdlen);
- *(pdq_cmd_code_t *) ci->ci_bufstart = op;
+ ci->ci_queued_commands[ci->ci_request_producer] = op;
+#if defined(PDQVERBOSE)
+ ((pdq_response_generic_t *) ci->ci_response_bufstart)->generic_op = PDQC_BOGUS_CMD;
+#endif
+ PDQ_OS_MEMZERO(ci->ci_request_bufstart, cmdlen);
+ *(pdq_cmd_code_t *) ci->ci_request_bufstart = op;
ci->ci_pending_commands &= ~mask;
/*
@@ -511,7 +522,7 @@ pdq_queue_commands(
*/
switch (op) {
case PDQC_FILTER_SET: {
- pdq_cmd_filter_set_t *filter_set = (pdq_cmd_filter_set_t *) ci->ci_bufstart;
+ pdq_cmd_filter_set_t *filter_set = (pdq_cmd_filter_set_t *) ci->ci_request_bufstart;
unsigned idx = 0;
filter_set->filter_set_items[idx].item_code = PDQI_IND_GROUP_PROM;
filter_set->filter_set_items[idx].filter_state = (pdq->pdq_flags & PDQ_PROMISC ? PDQ_FILTER_PASS : PDQ_FILTER_BLOCK);
@@ -529,7 +540,7 @@ pdq_queue_commands(
break;
}
case PDQC_ADDR_FILTER_SET: {
- pdq_cmd_addr_filter_set_t *addr_filter_set = (pdq_cmd_addr_filter_set_t *) ci->ci_bufstart;
+ pdq_cmd_addr_filter_set_t *addr_filter_set = (pdq_cmd_addr_filter_set_t *) ci->ci_request_bufstart;
pdq_lanaddr_t *addr = addr_filter_set->addr_filter_set_addresses;
addr->lanaddr_bytes[0] = 0xFF;
addr->lanaddr_bytes[1] = 0xFF;
@@ -541,10 +552,36 @@ pdq_queue_commands(
pdq_os_addr_fill(pdq, addr, 61);
break;
}
+ case PDQC_SNMP_SET: {
+ pdq_cmd_snmp_set_t *snmp_set = (pdq_cmd_snmp_set_t *) ci->ci_request_bufstart;
+ unsigned idx = 0;
+ snmp_set->snmp_set_items[idx].item_code = PDQSNMP_FULL_DUPLEX_ENABLE;
+ snmp_set->snmp_set_items[idx].item_value = (pdq->pdq_flags & PDQ_WANT_FDX ? 1 : 2);
+ snmp_set->snmp_set_items[idx].item_port = 0;
+ idx++;
+ snmp_set->snmp_set_items[idx].item_code = PDQSNMP_EOL;
+ break;
+ }
default: { /* to make gcc happy */
break;
}
}
+
+
+ /*
+ * Sync the command request buffer and descriptor, then advance
+ * the request producer index.
+ */
+ PDQ_OS_CMDRQST_PRESYNC(pdq, txd->txd_seg_len);
+ PDQ_OS_DESC_PRESYNC(pdq, txd, sizeof(pdq_txdesc_t));
+ PDQ_ADVANCE(ci->ci_request_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_requests));
+
+ /*
+ * Sync the command response buffer and advance the response
+ * producer index (descriptor is already pre-initialized)
+ */
+ PDQ_OS_CMDRSP_PRESYNC(pdq, PDQ_SIZE_COMMAND_RESPONSE);
+ PDQ_ADVANCE(ci->ci_response_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_responses));
/*
* At this point the command is done. All that needs to be done is to
* produce it to the PDQ.
@@ -578,15 +615,21 @@ pdq_process_command_responses(
PDQ_ASSERT(cbp->pdqcb_command_request != ci->ci_request_completion);
- rspgen = (const pdq_response_generic_t *) ci->ci_bufstart;
+ PDQ_OS_CMDRSP_POSTSYNC(pdq, PDQ_SIZE_COMMAND_RESPONSE);
+ rspgen = (const pdq_response_generic_t *) ci->ci_response_bufstart;
+ PDQ_ASSERT(rspgen->generic_op == ci->ci_queued_commands[ci->ci_request_completion]);
PDQ_ASSERT(rspgen->generic_status == PDQR_SUCCESS);
- PDQ_PRINTF(("PDQ Process Command Response: %s completed (status=%d)\n",
+ PDQ_PRINTF(("PDQ Process Command Response: %s completed (status=%d [0x%x])\n",
pdq_cmd_info[rspgen->generic_op].cmd_name,
- rspgen->generic_status));
+ rspgen->generic_status, rspgen->generic_status));
if (rspgen->generic_op == PDQC_STATUS_CHARS_GET && (pdq->pdq_flags & PDQ_PRINTCHARS)) {
pdq->pdq_flags &= ~PDQ_PRINTCHARS;
pdq_print_fddi_chars(pdq, (const pdq_response_status_chars_get_t *) rspgen);
+ } else if (rspgen->generic_op == PDQC_DEC_EXT_MIB_GET) {
+ pdq->pdq_flags &= ~PDQ_IS_FDX;
+ if (((const pdq_response_dec_ext_mib_get_t *)rspgen)->dec_ext_mib_get.fdx_operational)
+ pdq->pdq_flags |= PDQ_IS_FDX;
}
PDQ_ADVANCE(ci->ci_request_completion, 1, PDQ_RING_MASK(dbp->pdqdb_command_requests));
@@ -617,19 +660,40 @@ pdq_process_unsolicited_events(
pdq_unsolicited_info_t *ui = &pdq->pdq_unsolicited_info;
volatile const pdq_consumer_block_t *cbp = pdq->pdq_cbp;
pdq_descriptor_block_t *dbp = pdq->pdq_dbp;
- const pdq_unsolicited_event_t *event;
- pdq_rxdesc_t *rxd;
/*
* Process each unsolicited event (if any).
*/
while (cbp->pdqcb_unsolicited_event != ui->ui_completion) {
- rxd = &dbp->pdqdb_unsolicited_events[ui->ui_completion];
+ const pdq_unsolicited_event_t *event;
event = &ui->ui_events[ui->ui_completion & (PDQ_NUM_UNSOLICITED_EVENTS-1)];
+ PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, event);
switch (event->event_type) {
case PDQ_UNSOLICITED_EVENT: {
+ int bad_event = 0;
+ switch (event->event_entity) {
+ case PDQ_ENTITY_STATION: {
+ bad_event = event->event_code.value >= PDQ_STATION_EVENT_MAX;
+ break;
+ }
+ case PDQ_ENTITY_LINK: {
+ bad_event = event->event_code.value >= PDQ_LINK_EVENT_MAX;
+ break;
+ }
+ case PDQ_ENTITY_PHY_PORT: {
+ bad_event = event->event_code.value >= PDQ_PHY_EVENT_MAX;
+ break;
+ }
+ default: {
+ bad_event = 1;
+ break;
+ }
+ }
+ if (bad_event) {
+ break;
+ }
printf(PDQ_OS_PREFIX "Unsolicited Event: %s: %s",
PDQ_OS_PREFIX_ARGS,
pdq_entities[event->event_entity],
@@ -643,6 +707,7 @@ pdq_process_unsolicited_events(
break;
}
}
+ PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, event);
PDQ_ADVANCE(ui->ui_completion, 1, PDQ_RING_MASK(dbp->pdqdb_unsolicited_events));
ui->ui_free++;
}
@@ -679,11 +744,13 @@ pdq_process_received_data(
fpdu = lpdu = buffers[completion];
PDQ_ASSERT(fpdu != NULL);
-
+ PDQ_OS_RXPDU_POSTSYNC(pdq, fpdu, 0, sizeof(u_int32_t));
dataptr = PDQ_OS_DATABUF_PTR(fpdu);
status = *(pdq_rxstatus_t *) dataptr;
- if ((status.rxs_status & 0x200000) == 0) {
- datalen = status.rxs_status & 0x1FFF;
+ if (status.rxs_rcc_badpdu == 0) {
+ datalen = status.rxs_len;
+ PDQ_OS_RXPDU_POSTSYNC(pdq, fpdu, sizeof(u_int32_t),
+ PDQ_RX_FC_OFFSET + 1 - sizeof(u_int32_t));
fc = dataptr[PDQ_RX_FC_OFFSET];
switch (fc & (PDQ_FDDIFC_C|PDQ_FDDIFC_L|PDQ_FDDIFC_F)) {
case PDQ_FDDI_LLC_ASYNC:
@@ -710,19 +777,19 @@ pdq_process_received_data(
* Update the lengths of the data buffers now that we know
* the real length.
*/
- pdulen = datalen - 4 /* CRC */;
- segcnt = (pdulen + PDQ_RX_FC_OFFSET + PDQ_OS_DATABUF_SIZE - 1) / PDQ_OS_DATABUF_SIZE;
- PDQ_OS_DATABUF_ALLOC(npdu);
+ pdulen = datalen + (PDQ_RX_FC_OFFSET - PDQ_OS_HDR_OFFSET) - 4 /* CRC */;
+ segcnt = (pdulen + PDQ_OS_HDR_OFFSET + PDQ_OS_DATABUF_SIZE - 1) / PDQ_OS_DATABUF_SIZE;
+ PDQ_OS_DATABUF_ALLOC(pdq, npdu);
if (npdu == NULL) {
PDQ_PRINTF(("discard: no databuf #0\n"));
goto discard_frame;
}
buffers[completion] = npdu;
for (idx = 1; idx < segcnt; idx++) {
- PDQ_OS_DATABUF_ALLOC(npdu);
+ PDQ_OS_DATABUF_ALLOC(pdq, npdu);
if (npdu == NULL) {
PDQ_OS_DATABUF_NEXT_SET(lpdu, NULL);
- PDQ_OS_DATABUF_FREE(fpdu);
+ PDQ_OS_DATABUF_FREE(pdq, fpdu);
goto discard_frame;
}
PDQ_OS_DATABUF_NEXT_SET(lpdu, buffers[(completion + idx) & ring_mask]);
@@ -735,13 +802,17 @@ pdq_process_received_data(
buffers[(completion + idx) & ring_mask];
buffers[(completion + idx) & ring_mask] = NULL;
}
- PDQ_OS_DATABUF_ADJ(fpdu, PDQ_RX_FC_OFFSET);
+ PDQ_OS_DATABUF_ADJ(fpdu, PDQ_OS_HDR_OFFSET);
if (segcnt == 1) {
PDQ_OS_DATABUF_LEN_SET(fpdu, pdulen);
} else {
- PDQ_OS_DATABUF_LEN_SET(lpdu, pdulen + PDQ_RX_FC_OFFSET - (segcnt - 1) * PDQ_OS_DATABUF_SIZE);
+ PDQ_OS_DATABUF_LEN_SET(lpdu, pdulen + PDQ_OS_HDR_OFFSET - (segcnt - 1) * PDQ_OS_DATABUF_SIZE);
}
- pdq_os_receive_pdu(pdq, fpdu, pdulen);
+ /*
+ * Do not pass to protocol if packet was received promiscuously
+ */
+ pdq_os_receive_pdu(pdq, fpdu, pdulen,
+ status.rxs_rcc_dd < PDQ_RXS_RCC_DD_CAM_MATCH);
rx->rx_free += PDQ_RX_SEGCNT;
PDQ_ADVANCE(producer, PDQ_RX_SEGCNT, ring_mask);
PDQ_ADVANCE(completion, PDQ_RX_SEGCNT, ring_mask);
@@ -754,21 +825,21 @@ pdq_process_received_data(
goto discard_frame;
if (status.rxs_rcc_reason != 0) {
/* hardware fault */
- }
- if (status.rxs_rcc_badcrc) {
- printf(PDQ_OS_PREFIX " MAC CRC error (source=%x-%x-%x-%x-%x-%x)\n",
- PDQ_OS_PREFIX_ARGS,
- dataptr[PDQ_RX_FC_OFFSET+1],
- dataptr[PDQ_RX_FC_OFFSET+2],
- dataptr[PDQ_RX_FC_OFFSET+3],
- dataptr[PDQ_RX_FC_OFFSET+4],
- dataptr[PDQ_RX_FC_OFFSET+5],
- dataptr[PDQ_RX_FC_OFFSET+6]);
- /* rx->rx_badcrc++; */
- } else if (status.rxs_fsc == 0 || status.rxs_fsb_e == 1) {
- /* rx->rx_frame_status_errors++; */
- } else {
- /* hardware fault */
+ if (status.rxs_rcc_badcrc) {
+ printf(PDQ_OS_PREFIX " MAC CRC error (source=%x-%x-%x-%x-%x-%x)\n",
+ PDQ_OS_PREFIX_ARGS,
+ dataptr[PDQ_RX_FC_OFFSET+1],
+ dataptr[PDQ_RX_FC_OFFSET+2],
+ dataptr[PDQ_RX_FC_OFFSET+3],
+ dataptr[PDQ_RX_FC_OFFSET+4],
+ dataptr[PDQ_RX_FC_OFFSET+5],
+ dataptr[PDQ_RX_FC_OFFSET+6]);
+ /* rx->rx_badcrc++; */
+ } else if (status.rxs_fsc == 0 || status.rxs_fsb_e == 1) {
+ /* rx->rx_frame_status_errors++; */
+ } else {
+ /* hardware fault */
+ }
}
}
discard_frame:
@@ -787,7 +858,9 @@ pdq_process_received_data(
}
rxd->rxd_pa_hi = 0;
rxd->rxd_seg_len_hi = PDQ_OS_DATABUF_SIZE / 16;
- rxd->rxd_pa_lo = PDQ_OS_VA_TO_PA(pdq, PDQ_OS_DATABUF_PTR(buffers[rx->rx_producer]));
+ rxd->rxd_pa_lo = PDQ_OS_DATABUF_BUSPA(pdq, buffers[rx->rx_producer]);
+ PDQ_OS_RXPDU_PRESYNC(pdq, buffers[rx->rx_producer], 0, PDQ_OS_DATABUF_SIZE);
+ PDQ_OS_DESC_PRESYNC(pdq, rxd, sizeof(*rxd));
PDQ_ADVANCE(rx->rx_producer, 1, ring_mask);
PDQ_ADVANCE(producer, 1, ring_mask);
PDQ_ADVANCE(completion, 1, ring_mask);
@@ -804,7 +877,7 @@ pdq_process_received_data(
*/
for (idx = 0; idx < PDQ_RX_SEGCNT; idx++) {
if ((pdu = buffers[(rx->rx_producer + idx) & ring_mask]) == NULL) {
- PDQ_OS_DATABUF_ALLOC(pdu);
+ PDQ_OS_DATABUF_ALLOC(pdq, pdu);
if (pdu == NULL)
break;
buffers[(rx->rx_producer + idx) & ring_mask] = pdu;
@@ -817,7 +890,9 @@ pdq_process_received_data(
}
rxd->rxd_pa_hi = 0;
rxd->rxd_seg_len_hi = PDQ_OS_DATABUF_SIZE / 16;
- rxd->rxd_pa_lo = PDQ_OS_VA_TO_PA(pdq, PDQ_OS_DATABUF_PTR(pdu));
+ rxd->rxd_pa_lo = PDQ_OS_DATABUF_BUSPA(pdq, pdu);
+ PDQ_OS_RXPDU_PRESYNC(pdq, pdu, 0, PDQ_OS_DATABUF_SIZE);
+ PDQ_OS_DESC_PRESYNC(pdq, rxd, sizeof(*rxd));
}
if (idx < PDQ_RX_SEGCNT) {
/*
@@ -832,24 +907,65 @@ pdq_process_received_data(
}
}
+static void pdq_process_transmitted_data(pdq_t *pdq);
+
pdq_boolean_t
pdq_queue_transmit_data(
pdq_t *pdq,
PDQ_OS_DATABUF_T *pdu)
{
- pdq_tx_info_t *tx = &pdq->pdq_tx_info;
- pdq_descriptor_block_t *dbp = pdq->pdq_dbp;
+ pdq_tx_info_t * const tx = &pdq->pdq_tx_info;
+ pdq_descriptor_block_t * const dbp = pdq->pdq_dbp;
pdq_uint32_t producer = tx->tx_producer;
pdq_txdesc_t *eop = NULL;
PDQ_OS_DATABUF_T *pdu0;
pdq_uint32_t freecnt;
+#if defined(PDQ_BUS_DMA)
+ bus_dmamap_t map;
+#endif
- if (tx->tx_free < 1)
+ again:
+ if (PDQ_RX_FC_OFFSET == PDQ_OS_HDR_OFFSET) {
+ freecnt = tx->tx_free - 1;
+ } else {
+ freecnt = tx->tx_free;
+ }
+ /*
+ * Need 2 or more descriptors to be able to send.
+ */
+ if (freecnt == 0) {
+ pdq->pdq_intrmask |= PDQ_HOST_INT_TX_ENABLE;
+ PDQ_CSR_WRITE(&pdq->pdq_csrs, csr_host_int_enable, pdq->pdq_intrmask);
return PDQ_FALSE;
+ }
- dbp->pdqdb_transmits[producer] = tx->tx_hdrdesc;
- PDQ_ADVANCE(producer, 1, PDQ_RING_MASK(dbp->pdqdb_transmits));
+ if (PDQ_RX_FC_OFFSET == PDQ_OS_HDR_OFFSET) {
+ dbp->pdqdb_transmits[producer] = tx->tx_hdrdesc;
+ PDQ_OS_DESC_PRESYNC(pdq, &dbp->pdqdb_transmits[producer], sizeof(pdq_txdesc_t));
+ PDQ_ADVANCE(producer, 1, PDQ_RING_MASK(dbp->pdqdb_transmits));
+ }
+#if defined(PDQ_BUS_DMA)
+ map = M_GETCTX(pdu, bus_dmamap_t);
+ if (freecnt >= map->dm_nsegs) {
+ int idx;
+ for (idx = 0; idx < map->dm_nsegs; idx++) {
+ /*
+ * Initialize the transmit descriptor
+ */
+ eop = &dbp->pdqdb_transmits[producer];
+ eop->txd_seg_len = map->dm_segs[idx].ds_len;
+ eop->txd_pa_lo = map->dm_segs[idx].ds_addr;
+ eop->txd_sop = eop->txd_eop = eop->txd_pa_hi = 0;
+ PDQ_OS_DESC_PRESYNC(pdq, eop, sizeof(pdq_txdesc_t));
+ freecnt--;
+ PDQ_ADVANCE(producer, 1, PDQ_RING_MASK(dbp->pdqdb_transmits));
+ }
+ pdu0 = NULL;
+ } else {
+ pdu0 = pdu;
+ }
+#else
for (freecnt = tx->tx_free - 1, pdu0 = pdu; pdu0 != NULL && freecnt > 0;) {
pdq_uint32_t fraglen, datalen = PDQ_OS_DATABUF_LEN(pdu0);
const pdq_uint8_t *dataptr = PDQ_OS_DATABUF_PTR(pdu0);
@@ -868,9 +984,9 @@ pdq_queue_transmit_data(
*/
eop = &dbp->pdqdb_transmits[producer];
eop->txd_seg_len = seglen;
- eop->txd_pa_lo = PDQ_OS_VA_TO_PA(pdq, dataptr);
+ eop->txd_pa_lo = PDQ_OS_VA_TO_BUSPA(pdq, dataptr);
eop->txd_sop = eop->txd_eop = eop->txd_pa_hi = 0;
-
+ PDQ_OS_DESC_PRESYNC(pdq, eop, sizeof(pdq_txdesc_t));
datalen -= seglen;
dataptr += seglen;
fraglen = PDQ_OS_PAGESIZE;
@@ -879,20 +995,37 @@ pdq_queue_transmit_data(
}
pdu0 = PDQ_OS_DATABUF_NEXT(pdu0);
}
+#endif /* defined(PDQ_BUS_DMA) */
if (pdu0 != NULL) {
+ unsigned completion = tx->tx_completion;
PDQ_ASSERT(freecnt == 0);
+ PDQ_OS_CONSUMER_POSTSYNC(pdq);
+ pdq_process_transmitted_data(pdq);
+ if (completion != tx->tx_completion) {
+ producer = tx->tx_producer;
+ eop = NULL;
+ goto again;
+ }
/*
* If we still have data to process then the ring was too full
* to store the PDU. Return FALSE so the caller will requeue
* the PDU for later.
*/
+ pdq->pdq_intrmask |= PDQ_HOST_INT_TX_ENABLE;
+ PDQ_CSR_WRITE(&pdq->pdq_csrs, csr_host_int_enable, pdq->pdq_intrmask);
return PDQ_FALSE;
}
/*
* Everything went fine. Finish it up.
*/
tx->tx_descriptor_count[tx->tx_producer] = tx->tx_free - freecnt;
+ if (PDQ_RX_FC_OFFSET != PDQ_OS_HDR_OFFSET) {
+ dbp->pdqdb_transmits[tx->tx_producer].txd_sop = 1;
+ PDQ_OS_DESC_PRESYNC(pdq, &dbp->pdqdb_transmits[tx->tx_producer],
+ sizeof(pdq_txdesc_t));
+ }
eop->txd_eop = 1;
+ PDQ_OS_DESC_PRESYNC(pdq, eop, sizeof(pdq_txdesc_t));
PDQ_OS_DATABUF_ENQUEUE(&tx->tx_txq, pdu);
tx->tx_producer = producer;
tx->tx_free = freecnt;
@@ -908,6 +1041,7 @@ pdq_process_transmitted_data(
volatile const pdq_consumer_block_t *cbp = pdq->pdq_cbp;
pdq_descriptor_block_t *dbp = pdq->pdq_dbp;
pdq_uint32_t completion = tx->tx_completion;
+ int reclaimed = 0;
while (completion != cbp->pdqcb_transmits) {
PDQ_OS_DATABUF_T *pdu;
@@ -917,14 +1051,17 @@ pdq_process_transmitted_data(
PDQ_OS_DATABUF_DEQUEUE(&tx->tx_txq, pdu);
pdq_os_transmit_done(pdq, pdu);
tx->tx_free += descriptor_count;
-
+ reclaimed = 1;
PDQ_ADVANCE(completion, descriptor_count, PDQ_RING_MASK(dbp->pdqdb_transmits));
}
if (tx->tx_completion != completion) {
tx->tx_completion = completion;
+ pdq->pdq_intrmask &= ~PDQ_HOST_INT_TX_ENABLE;
+ PDQ_CSR_WRITE(&pdq->pdq_csrs, csr_host_int_enable, pdq->pdq_intrmask);
pdq_os_restart_transmitter(pdq);
}
- PDQ_DO_TYPE2_PRODUCER(pdq);
+ if (reclaimed)
+ PDQ_DO_TYPE2_PRODUCER(pdq);
}
void
@@ -943,11 +1080,12 @@ pdq_flush_transmitter(
* Don't call transmit done since the packet never made it
* out on the wire.
*/
- PDQ_OS_DATABUF_FREE(pdu);
+ PDQ_OS_DATABUF_FREE(pdq, pdu);
}
tx->tx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_transmits);
- tx->tx_completion = cbp->pdqcb_transmits = tx->tx_producer;
+ cbp->pdqcb_transmits = tx->tx_completion = tx->tx_producer;
+ PDQ_OS_CONSUMER_PRESYNC(pdq);
PDQ_DO_TYPE2_PRODUCER(pdq);
}
@@ -964,17 +1102,17 @@ pdq_hwreset(
if (state == PDQS_DMA_UNAVAILABLE)
return;
PDQ_CSR_WRITE(csrs, csr_port_data_a,
- (state == PDQS_HALTED) ? 0 : PDQ_PRESET_SKIP_SELFTEST);
+ (state == PDQS_HALTED && pdq->pdq_type != PDQ_DEFTA) ? 0 : PDQ_PRESET_SKIP_SELFTEST);
PDQ_CSR_WRITE(csrs, csr_port_reset, 1);
PDQ_OS_USEC_DELAY(100);
PDQ_CSR_WRITE(csrs, csr_port_reset, 0);
- for (cnt = 45000;;cnt--) {
+ for (cnt = 100000;;cnt--) {
PDQ_OS_USEC_DELAY(1000);
state = PDQ_PSTS_ADAPTER_STATE(PDQ_CSR_READ(csrs, csr_port_status));
if (state == PDQS_DMA_UNAVAILABLE || cnt == 0)
break;
}
- PDQ_PRINTF(("PDQ Reset spun %d cycles\n", 45000 - cnt));
+ PDQ_PRINTF(("PDQ Reset spun %d cycles\n", 100000 - cnt));
PDQ_OS_USEC_DELAY(10000);
state = PDQ_PSTS_ADAPTER_STATE(PDQ_CSR_READ(csrs, csr_port_status));
PDQ_ASSERT(state == PDQS_DMA_UNAVAILABLE);
@@ -1050,12 +1188,12 @@ pdq_stop(
/*
* Flush all the databuf queues.
*/
- pdq_flush_databuf_queue(&pdq->pdq_tx_info.tx_txq);
- pdq->pdq_flags &= ~PDQ_TXOK;
+ pdq_flush_databuf_queue(pdq, &pdq->pdq_tx_info.tx_txq);
+ pdq->pdq_flags &= ~(PDQ_TXOK|PDQ_IS_ONRING|PDQ_IS_FDX);
buffers = (PDQ_OS_DATABUF_T **) pdq->pdq_rx_info.rx_buffers;
for (idx = 0; idx < PDQ_RING_SIZE(pdq->pdq_dbp->pdqdb_receives); idx++) {
if (buffers[idx] != NULL) {
- PDQ_OS_DATABUF_FREE(buffers[idx]);
+ PDQ_OS_DATABUF_FREE(pdq, buffers[idx]);
buffers[idx] = NULL;
}
}
@@ -1063,7 +1201,7 @@ pdq_stop(
buffers = (PDQ_OS_DATABUF_T **) pdq->pdq_host_smt_info.rx_buffers;
for (idx = 0; idx < PDQ_RING_SIZE(pdq->pdq_dbp->pdqdb_host_smt); idx++) {
if (buffers[idx] != NULL) {
- PDQ_OS_DATABUF_FREE(buffers[idx]);
+ PDQ_OS_DATABUF_FREE(pdq, buffers[idx]);
buffers[idx] = NULL;
}
}
@@ -1078,6 +1216,7 @@ pdq_stop(
pdq->pdq_cbp->pdqcb_unsolicited_event = 0;
pdq->pdq_cbp->pdqcb_command_response = 0;
pdq->pdq_cbp->pdqcb_command_request = 0;
+ PDQ_OS_CONSUMER_PRESYNC(pdq);
/*
* Reset the producer and completion indexes to 0.
@@ -1119,20 +1258,30 @@ pdq_stop(
*/
pdq_process_unsolicited_events(pdq);
- if (pdq->pdq_type == PDQ_DEFEA && pdq->pdq_chip_rev == PDQ_CHIP_REV_E)
+ if ((pdq->pdq_type == PDQ_DEFEA && pdq->pdq_chip_rev == PDQ_CHIP_REV_E)
+ || pdq->pdq_type == PDQ_DEFTA)
PDQ_CSR_WRITE(csrs, csr_port_data_b, PDQ_DMA_BURST_16LW);
else
PDQ_CSR_WRITE(csrs, csr_port_data_b, PDQ_DMA_BURST_8LW);
PDQ_CSR_WRITE(csrs, csr_port_data_a, PDQ_SUB_CMD_DMA_BURST_SIZE_SET);
pdq_do_port_control(csrs, PDQ_PCTL_SUB_CMD);
+ /*
+ * Make sure there isn't stale information in the caches before
+ * tell the adapter about the blocks it's going to use.
+ */
+ PDQ_OS_CONSUMER_PRESYNC(pdq);
+
PDQ_CSR_WRITE(csrs, csr_port_data_b, 0);
- PDQ_CSR_WRITE(csrs, csr_port_data_a, PDQ_OS_VA_TO_PA(pdq, pdq->pdq_cbp));
+ PDQ_CSR_WRITE(csrs, csr_port_data_a, pdq->pdq_pa_consumer_block);
pdq_do_port_control(csrs, PDQ_PCTL_CONSUMER_BLOCK);
PDQ_CSR_WRITE(csrs, csr_port_data_b, 0);
- PDQ_CSR_WRITE(csrs, csr_port_data_a,
- PDQ_OS_VA_TO_PA(pdq, pdq->pdq_dbp) | PDQ_DMA_INIT_LW_BSWAP_DATA);
+#if !defined(BYTE_ORDER) || BYTE_ORDER == LITTLE_ENDIAN
+ PDQ_CSR_WRITE(csrs, csr_port_data_a, pdq->pdq_pa_descriptor_block | PDQ_DMA_INIT_LW_BSWAP_DATA);
+#else
+ PDQ_CSR_WRITE(csrs, csr_port_data_a, pdq->pdq_pa_descriptor_block | PDQ_DMA_INIT_LW_BSWAP_DATA | PDQ_DMA_INIT_LW_BSWAP_LITERAL);
+#endif
pdq_do_port_control(csrs, PDQ_PCTL_DMA_INIT);
for (cnt = 0; cnt < 1000; cnt++) {
@@ -1152,9 +1301,11 @@ pdq_stop(
PDQ_ASSERT(state == PDQS_DMA_AVAILABLE);
PDQ_CSR_WRITE(csrs, csr_host_int_type_0, 0xFF);
- PDQ_CSR_WRITE(csrs, csr_host_int_enable, 0) /* PDQ_HOST_INT_STATE_CHANGE
+ pdq->pdq_intrmask = 0;
+ /* PDQ_HOST_INT_STATE_CHANGE
|PDQ_HOST_INT_FATAL_ERROR|PDQ_HOST_INT_CMD_RSP_ENABLE
|PDQ_HOST_INT_UNSOL_ENABLE */;
+ PDQ_CSR_WRITE(csrs, csr_host_int_enable, pdq->pdq_intrmask);
/*
* Any other command but START should be valid.
@@ -1169,6 +1320,7 @@ pdq_stop(
* Now wait (up to 100ms) for the command(s) to finish.
*/
for (cnt = 0; cnt < 1000; cnt++) {
+ PDQ_OS_CONSUMER_POSTSYNC(pdq);
pdq_process_command_responses(pdq);
if (pdq->pdq_command_info.ci_response_producer == pdq->pdq_command_info.ci_response_completion)
break;
@@ -1201,9 +1353,11 @@ pdq_run(
* ones will get through.
*/
PDQ_CSR_WRITE(csrs, csr_host_int_type_0, 0xFF);
- PDQ_CSR_WRITE(csrs, csr_host_int_enable, PDQ_HOST_INT_STATE_CHANGE|PDQ_HOST_INT_XMT_DATA_FLUSH
- |PDQ_HOST_INT_FATAL_ERROR|PDQ_HOST_INT_CMD_RSP_ENABLE|PDQ_HOST_INT_UNSOL_ENABLE
- |PDQ_HOST_INT_RX_ENABLE|PDQ_HOST_INT_TX_ENABLE|PDQ_HOST_INT_HOST_SMT_ENABLE);
+ pdq->pdq_intrmask = PDQ_HOST_INT_STATE_CHANGE
+ |PDQ_HOST_INT_XMT_DATA_FLUSH|PDQ_HOST_INT_FATAL_ERROR
+ |PDQ_HOST_INT_CMD_RSP_ENABLE|PDQ_HOST_INT_UNSOL_ENABLE
+ |PDQ_HOST_INT_RX_ENABLE|PDQ_HOST_INT_HOST_SMT_ENABLE;
+ PDQ_CSR_WRITE(csrs, csr_host_int_enable, pdq->pdq_intrmask);
/*
* Set the MAC and address filters and start up the PDQ.
*/
@@ -1223,7 +1377,9 @@ pdq_run(
| (pdq->pdq_host_smt_info.rx_completion << 8));
}
pdq->pdq_command_info.ci_pending_commands = PDQ_BITMASK(PDQC_FILTER_SET)
- | PDQ_BITMASK(PDQC_ADDR_FILTER_SET) | PDQ_BITMASK(PDQC_START);
+ | PDQ_BITMASK(PDQC_ADDR_FILTER_SET)
+ | PDQ_BITMASK(PDQC_SNMP_SET)
+ | PDQ_BITMASK(PDQC_START);
if (pdq->pdq_flags & PDQ_PRINTCHARS)
pdq->pdq_command_info.ci_pending_commands |= PDQ_BITMASK(PDQC_STATUS_CHARS_GET);
pdq_queue_commands(pdq);
@@ -1232,7 +1388,8 @@ pdq_run(
case PDQS_LINK_UNAVAILABLE:
case PDQS_LINK_AVAILABLE: {
pdq->pdq_command_info.ci_pending_commands = PDQ_BITMASK(PDQC_FILTER_SET)
- | PDQ_BITMASK(PDQC_ADDR_FILTER_SET);
+ | PDQ_BITMASK(PDQC_ADDR_FILTER_SET)
+ | PDQ_BITMASK(PDQC_SNMP_SET);
if (pdq->pdq_flags & PDQ_PRINTCHARS)
pdq->pdq_command_info.ci_pending_commands |= PDQ_BITMASK(PDQC_STATUS_CHARS_GET);
if (pdq->pdq_flags & PDQ_PASS_SMT) {
@@ -1270,6 +1427,7 @@ pdq_interrupt(
while ((data = PDQ_CSR_READ(csrs, csr_port_status)) & PDQ_PSTS_INTR_PENDING) {
progress = 1;
PDQ_PRINTF(("PDQ Interrupt: Status = 0x%08x\n", data));
+ PDQ_OS_CONSUMER_POSTSYNC(pdq);
if (data & PDQ_PSTS_RCV_DATA_PENDING) {
pdq_process_received_data(pdq, &pdq->pdq_rx_info,
pdq->pdq_dbp->pdqdb_receives,
@@ -1284,7 +1442,7 @@ pdq_interrupt(
PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt));
PDQ_DO_HOST_SMT_PRODUCER(pdq);
}
- if (data & PDQ_PSTS_XMT_DATA_PENDING)
+ /* if (data & PDQ_PSTS_XMT_DATA_PENDING) */
pdq_process_transmitted_data(pdq);
if (data & PDQ_PSTS_UNSOL_PENDING)
pdq_process_unsolicited_events(pdq);
@@ -1296,9 +1454,13 @@ pdq_interrupt(
pdq_state_t state = PDQ_PSTS_ADAPTER_STATE(PDQ_CSR_READ(csrs, csr_port_status));
printf(PDQ_OS_PREFIX "%s", PDQ_OS_PREFIX_ARGS, pdq_adapter_states[state]);
if (state == PDQS_LINK_UNAVAILABLE) {
- pdq->pdq_flags &= ~PDQ_TXOK;
+ pdq->pdq_flags &= ~(PDQ_TXOK|PDQ_IS_ONRING|PDQ_IS_FDX);
} else if (state == PDQS_LINK_AVAILABLE) {
- pdq->pdq_flags |= PDQ_TXOK;
+ if (pdq->pdq_flags & PDQ_WANT_FDX) {
+ pdq->pdq_command_info.ci_pending_commands |= PDQ_BITMASK(PDQC_DEC_EXT_MIB_GET);
+ pdq_queue_commands(pdq);
+ }
+ pdq->pdq_flags |= PDQ_TXOK|PDQ_IS_ONRING;
pdq_os_restart_transmitter(pdq);
} else if (state == PDQS_HALTED) {
pdq_response_error_log_get_t log_entry;
@@ -1310,7 +1472,28 @@ pdq_interrupt(
PDQ_CSR_READ(&pdq->pdq_pci_csrs, csr_pfi_status),
data & PDQ_HOST_INT_FATAL_ERROR));
}
- pdq_read_error_log(pdq, &log_entry);
+ PDQ_OS_MEMZERO(&log_entry, sizeof(log_entry));
+ if (pdq_read_error_log(pdq, &log_entry)) {
+ PDQ_PRINTF((" Error log Entry:\n"));
+ PDQ_PRINTF((" CMD Status = %d (0x%x)\n",
+ log_entry.error_log_get_status,
+ log_entry.error_log_get_status));
+ PDQ_PRINTF((" Event Status = %d (0x%x)\n",
+ log_entry.error_log_get_event_status,
+ log_entry.error_log_get_event_status));
+ PDQ_PRINTF((" Caller Id = %d (0x%x)\n",
+ log_entry.error_log_get_caller_id,
+ log_entry.error_log_get_caller_id));
+ PDQ_PRINTF((" Write Count = %d (0x%x)\n",
+ log_entry.error_log_get_write_count,
+ log_entry.error_log_get_write_count));
+ PDQ_PRINTF((" FRU Implication Mask = %d (0x%x)\n",
+ log_entry.error_log_get_fru_implication_mask,
+ log_entry.error_log_get_fru_implication_mask));
+ PDQ_PRINTF((" Test ID = %d (0x%x)\n",
+ log_entry.error_log_get_test_id,
+ log_entry.error_log_get_test_id));
+ }
pdq_stop(pdq);
if (pdq->pdq_flags & PDQ_RUNNING)
pdq_run(pdq);
@@ -1350,8 +1533,11 @@ pdq_initialize(
{
pdq_t *pdq;
pdq_state_t state;
+ pdq_descriptor_block_t *dbp;
+#if !defined(PDQ_BUS_DMA)
const pdq_uint32_t contig_bytes = (sizeof(pdq_descriptor_block_t) * 2) - PDQ_OS_PAGESIZE;
pdq_uint8_t *p;
+#endif
int idx;
PDQ_ASSERT(sizeof(pdq_descriptor_block_t) == 8192);
@@ -1387,32 +1573,46 @@ pdq_initialize(
* buffers (though on machines with 8KB pages we will to allocate
* them separately since there will be nothing left overs.)
*/
+#if defined(PDQ_OS_MEMALLOC_CONTIG)
p = (pdq_uint8_t *) PDQ_OS_MEMALLOC_CONTIG(contig_bytes);
+
+if (p == NULL)
+ printf("%s() - PDQ_OS_MEMALLOC_CONTIG() failed!\n", __FUNCTION__);
+
if (p != NULL) {
- pdq_physaddr_t physaddr = PDQ_OS_VA_TO_PA(pdq, p);
+ pdq_physaddr_t physaddr = PDQ_OS_VA_TO_BUSPA(pdq, p);
/*
* Assert that we really got contiguous memory. This isn't really
* needed on systems that actually have physical contiguous allocation
* routines, but on those systems that don't ...
*/
for (idx = PDQ_OS_PAGESIZE; idx < 0x2000; idx += PDQ_OS_PAGESIZE) {
- if (PDQ_OS_VA_TO_PA(pdq, p + idx) - physaddr != idx)
+ if (PDQ_OS_VA_TO_BUSPA(pdq, p + idx) - physaddr != idx)
goto cleanup_and_return;
}
- physaddr &= 0x1FFF;
- if (physaddr) {
+ if (physaddr & 0x1FFF) {
pdq->pdq_unsolicited_info.ui_events = (pdq_unsolicited_event_t *) p;
- pdq->pdq_dbp = (pdq_descriptor_block_t *) &p[0x2000 - physaddr];
+ pdq->pdq_unsolicited_info.ui_pa_bufstart = physaddr;
+ pdq->pdq_dbp = (pdq_descriptor_block_t *) &p[0x2000 - (physaddr & 0x1FFF)];
+ pdq->pdq_pa_descriptor_block = physaddr & ~0x1FFFUL;
} else {
pdq->pdq_dbp = (pdq_descriptor_block_t *) p;
+ pdq->pdq_pa_descriptor_block = physaddr;
pdq->pdq_unsolicited_info.ui_events = (pdq_unsolicited_event_t *) &p[0x2000];
+ pdq->pdq_unsolicited_info.ui_pa_bufstart = physaddr + 0x2000;
}
}
+ pdq->pdq_cbp = (volatile pdq_consumer_block_t *) &pdq->pdq_dbp->pdqdb_consumer;
+ pdq->pdq_pa_consumer_block = PDQ_DB_BUSPA(pdq, pdq->pdq_cbp);
if (contig_bytes == sizeof(pdq_descriptor_block_t)) {
pdq->pdq_unsolicited_info.ui_events =
(pdq_unsolicited_event_t *) PDQ_OS_MEMALLOC(
PDQ_NUM_UNSOLICITED_EVENTS * sizeof(pdq_unsolicited_event_t));
}
+#else
+ if (pdq_os_memalloc_contig(pdq))
+ goto cleanup_and_return;
+#endif
/*
* Make sure everything got allocated. If not, free what did
@@ -1420,27 +1620,24 @@ pdq_initialize(
*/
if (pdq->pdq_dbp == NULL || pdq->pdq_unsolicited_info.ui_events == NULL) {
cleanup_and_return:
+#ifdef PDQ_OS_MEMFREE_CONTIG
if (p /* pdq->pdq_dbp */ != NULL)
PDQ_OS_MEMFREE_CONTIG(p /* pdq->pdq_dbp */, contig_bytes);
if (contig_bytes == sizeof(pdq_descriptor_block_t) && pdq->pdq_unsolicited_info.ui_events != NULL)
PDQ_OS_MEMFREE(pdq->pdq_unsolicited_info.ui_events,
PDQ_NUM_UNSOLICITED_EVENTS * sizeof(pdq_unsolicited_event_t));
+#endif
PDQ_OS_MEMFREE(pdq, sizeof(pdq_t));
return NULL;
}
-
- pdq->pdq_cbp = (volatile pdq_consumer_block_t *) &pdq->pdq_dbp->pdqdb_consumer;
- pdq->pdq_command_info.ci_bufstart = (pdq_uint8_t *) pdq->pdq_dbp->pdqdb_command_pool;
- pdq->pdq_rx_info.rx_buffers = (void *) pdq->pdq_dbp->pdqdb_receive_buffers;
-
- pdq->pdq_host_smt_info.rx_buffers = (void *) pdq->pdq_dbp->pdqdb_host_smt_buffers;
-
- PDQ_PRINTF(("\nPDQ Descriptor Block = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp));
- PDQ_PRINTF((" Recieve Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_receives));
- PDQ_PRINTF((" Transmit Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_transmits));
- PDQ_PRINTF((" Host SMT Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_host_smt));
- PDQ_PRINTF((" Command Response Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_command_responses));
- PDQ_PRINTF((" Command Request Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_command_requests));
+ dbp = pdq->pdq_dbp;
+
+ PDQ_PRINTF(("\nPDQ Descriptor Block = " PDQ_OS_PTR_FMT " (PA = 0x%x)\n", dbp, pdq->pdq_pa_descriptor_block));
+ PDQ_PRINTF((" Receive Queue = " PDQ_OS_PTR_FMT "\n", dbp->pdqdb_receives));
+ PDQ_PRINTF((" Transmit Queue = " PDQ_OS_PTR_FMT "\n", dbp->pdqdb_transmits));
+ PDQ_PRINTF((" Host SMT Queue = " PDQ_OS_PTR_FMT "\n", dbp->pdqdb_host_smt));
+ PDQ_PRINTF((" Command Response Queue = " PDQ_OS_PTR_FMT "\n", dbp->pdqdb_command_responses));
+ PDQ_PRINTF((" Command Request Queue = " PDQ_OS_PTR_FMT "\n", dbp->pdqdb_command_requests));
PDQ_PRINTF(("PDQ Consumer Block = " PDQ_OS_PTR_FMT "\n", pdq->pdq_cbp));
/*
@@ -1449,7 +1646,7 @@ pdq_initialize(
* block, command pool, and buffer pointers for the receive
* host_smt rings.
*/
- PDQ_OS_MEMZERO(pdq->pdq_dbp, sizeof(*pdq->pdq_dbp));
+ PDQ_OS_MEMZERO(dbp, sizeof(*dbp));
/*
* Initialize the CSR references.
@@ -1459,61 +1656,81 @@ pdq_initialize(
if (pdq->pdq_type == PDQ_DEFPA)
pdq_init_pci_csrs(&pdq->pdq_pci_csrs, bus, csr_base, 1);
- PDQ_PRINTF(("PDQ CSRs: BASE = " PDQ_OS_PTR_FMT "\n", pdq->pdq_csrs.csr_base));
- PDQ_PRINTF((" Port Reset = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF(("PDQ CSRs: BASE = " PDQ_OS_CSR_FMT "\n", pdq->pdq_csrs.csr_base));
+ PDQ_PRINTF((" Port Reset = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_port_reset, PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_reset)));
- PDQ_PRINTF((" Host Data = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Host Data = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_host_data, PDQ_CSR_READ(&pdq->pdq_csrs, csr_host_data)));
- PDQ_PRINTF((" Port Control = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Port Control = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_port_control, PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_control)));
- PDQ_PRINTF((" Port Data A = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Port Data A = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_port_data_a, PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_data_a)));
- PDQ_PRINTF((" Port Data B = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Port Data B = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_port_data_b, PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_data_b)));
- PDQ_PRINTF((" Port Status = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Port Status = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_port_status, PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_status)));
- PDQ_PRINTF((" Host Int Type 0 = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Host Int Type 0 = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_host_int_type_0, PDQ_CSR_READ(&pdq->pdq_csrs, csr_host_int_type_0)));
- PDQ_PRINTF((" Host Int Enable = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Host Int Enable = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_host_int_enable, PDQ_CSR_READ(&pdq->pdq_csrs, csr_host_int_enable)));
- PDQ_PRINTF((" Type 2 Producer = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Type 2 Producer = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_type_2_producer, PDQ_CSR_READ(&pdq->pdq_csrs, csr_type_2_producer)));
- PDQ_PRINTF((" Command Response Producer = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Command Response Producer = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_cmd_response_producer, PDQ_CSR_READ(&pdq->pdq_csrs, csr_cmd_response_producer)));
- PDQ_PRINTF((" Command Request Producer = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Command Request Producer = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_cmd_request_producer, PDQ_CSR_READ(&pdq->pdq_csrs, csr_cmd_request_producer)));
- PDQ_PRINTF((" Host SMT Producer = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Host SMT Producer = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_host_smt_producer, PDQ_CSR_READ(&pdq->pdq_csrs, csr_host_smt_producer)));
- PDQ_PRINTF((" Unsolicited Producer = " PDQ_OS_PTR_FMT " [0x%08x]\n",
+ PDQ_PRINTF((" Unsolicited Producer = " PDQ_OS_CSR_FMT " [0x%08x]\n",
pdq->pdq_csrs.csr_unsolicited_producer, PDQ_CSR_READ(&pdq->pdq_csrs, csr_unsolicited_producer)));
/*
* Initialize the command information block
*/
- pdq->pdq_command_info.ci_pa_bufstart = PDQ_OS_VA_TO_PA(pdq, pdq->pdq_command_info.ci_bufstart);
- for (idx = 0; idx < sizeof(pdq->pdq_dbp->pdqdb_command_requests)/sizeof(pdq->pdq_dbp->pdqdb_command_requests[0]); idx++) {
- pdq_txdesc_t *txd = &pdq->pdq_dbp->pdqdb_command_requests[idx];
-
- txd->txd_pa_lo = pdq->pdq_command_info.ci_pa_bufstart;
+ pdq->pdq_command_info.ci_request_bufstart = dbp->pdqdb_cmd_request_buf;
+ pdq->pdq_command_info.ci_pa_request_bufstart = PDQ_DB_BUSPA(pdq, pdq->pdq_command_info.ci_request_bufstart);
+ pdq->pdq_command_info.ci_pa_request_descriptors = PDQ_DB_BUSPA(pdq, dbp->pdqdb_command_requests);
+ PDQ_PRINTF(("PDQ Command Request Buffer = " PDQ_OS_PTR_FMT " (PA=0x%x)\n",
+ pdq->pdq_command_info.ci_request_bufstart,
+ pdq->pdq_command_info.ci_pa_request_bufstart));
+ for (idx = 0; idx < sizeof(dbp->pdqdb_command_requests)/sizeof(dbp->pdqdb_command_requests[0]); idx++) {
+ pdq_txdesc_t *txd = &dbp->pdqdb_command_requests[idx];
+
+ txd->txd_pa_lo = pdq->pdq_command_info.ci_pa_request_bufstart;
txd->txd_eop = txd->txd_sop = 1;
txd->txd_pa_hi = 0;
}
- for (idx = 0; idx < sizeof(pdq->pdq_dbp->pdqdb_command_responses)/sizeof(pdq->pdq_dbp->pdqdb_command_responses[0]); idx++) {
- pdq_rxdesc_t *rxd = &pdq->pdq_dbp->pdqdb_command_responses[idx];
-
- rxd->rxd_pa_lo = pdq->pdq_command_info.ci_pa_bufstart;
+ PDQ_OS_DESC_PRESYNC(pdq, dbp->pdqdb_command_requests,
+ sizeof(dbp->pdqdb_command_requests));
+
+ pdq->pdq_command_info.ci_response_bufstart = dbp->pdqdb_cmd_response_buf;
+ pdq->pdq_command_info.ci_pa_response_bufstart = PDQ_DB_BUSPA(pdq, pdq->pdq_command_info.ci_response_bufstart);
+ pdq->pdq_command_info.ci_pa_response_descriptors = PDQ_DB_BUSPA(pdq, dbp->pdqdb_command_responses);
+ PDQ_PRINTF(("PDQ Command Response Buffer = " PDQ_OS_PTR_FMT " (PA=0x%x)\n",
+ pdq->pdq_command_info.ci_response_bufstart,
+ pdq->pdq_command_info.ci_pa_response_bufstart));
+ for (idx = 0; idx < sizeof(dbp->pdqdb_command_responses)/sizeof(dbp->pdqdb_command_responses[0]); idx++) {
+ pdq_rxdesc_t *rxd = &dbp->pdqdb_command_responses[idx];
+
+ rxd->rxd_pa_lo = pdq->pdq_command_info.ci_pa_response_bufstart;
rxd->rxd_sop = 1;
rxd->rxd_seg_cnt = 0;
rxd->rxd_seg_len_lo = 0;
+ rxd->rxd_seg_len_hi = PDQ_SIZE_COMMAND_RESPONSE / 16;
}
+ PDQ_OS_DESC_PRESYNC(pdq, dbp->pdqdb_command_responses,
+ sizeof(dbp->pdqdb_command_responses));
/*
* Initialize the unsolicited event information block
*/
pdq->pdq_unsolicited_info.ui_free = PDQ_NUM_UNSOLICITED_EVENTS;
- pdq->pdq_unsolicited_info.ui_pa_bufstart = PDQ_OS_VA_TO_PA(pdq, pdq->pdq_unsolicited_info.ui_events);
- for (idx = 0; idx < sizeof(pdq->pdq_dbp->pdqdb_unsolicited_events)/sizeof(pdq->pdq_dbp->pdqdb_unsolicited_events[0]); idx++) {
- pdq_rxdesc_t *rxd = &pdq->pdq_dbp->pdqdb_unsolicited_events[idx];
+ pdq->pdq_unsolicited_info.ui_pa_descriptors = PDQ_DB_BUSPA(pdq, dbp->pdqdb_unsolicited_events);
+ PDQ_PRINTF(("PDQ Unsolicit Event Buffer = " PDQ_OS_PTR_FMT " (PA=0x%x)\n",
+ pdq->pdq_unsolicited_info.ui_events,
+ pdq->pdq_unsolicited_info.ui_pa_bufstart));
+ for (idx = 0; idx < sizeof(dbp->pdqdb_unsolicited_events)/sizeof(dbp->pdqdb_unsolicited_events[0]); idx++) {
+ pdq_rxdesc_t *rxd = &dbp->pdqdb_unsolicited_events[idx];
pdq_unsolicited_event_t *event = &pdq->pdq_unsolicited_info.ui_events[idx & (PDQ_NUM_UNSOLICITED_EVENTS-1)];
rxd->rxd_sop = 1;
@@ -1522,26 +1739,35 @@ pdq_initialize(
rxd->rxd_pa_lo = pdq->pdq_unsolicited_info.ui_pa_bufstart + (const pdq_uint8_t *) event
- (const pdq_uint8_t *) pdq->pdq_unsolicited_info.ui_events;
rxd->rxd_pa_hi = 0;
+ PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, event);
}
+ PDQ_OS_DESC_PRESYNC(pdq, dbp->pdqdb_unsolicited_events,
+ sizeof(dbp->pdqdb_unsolicited_events));
+
/*
* Initialize the receive information blocks (normal and SMT).
*/
- pdq->pdq_rx_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_receives);
+ pdq->pdq_rx_info.rx_buffers = pdq->pdq_receive_buffers;
+ pdq->pdq_rx_info.rx_free = PDQ_RING_MASK(dbp->pdqdb_receives);
pdq->pdq_rx_info.rx_target = pdq->pdq_rx_info.rx_free - PDQ_RX_SEGCNT * 8;
+ pdq->pdq_rx_info.rx_pa_descriptors = PDQ_DB_BUSPA(pdq, dbp->pdqdb_receives);
- pdq->pdq_host_smt_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt);
+ pdq->pdq_host_smt_info.rx_buffers = pdq->pdq_host_smt_buffers;
+ pdq->pdq_host_smt_info.rx_free = PDQ_RING_MASK(dbp->pdqdb_host_smt);
pdq->pdq_host_smt_info.rx_target = pdq->pdq_host_smt_info.rx_free - PDQ_RX_SEGCNT * 3;
+ pdq->pdq_host_smt_info.rx_pa_descriptors = PDQ_DB_BUSPA(pdq, dbp->pdqdb_host_smt);
/*
* Initialize the transmit information block.
*/
- pdq->pdq_tx_hdr[0] = PDQ_FDDI_PH0;
- pdq->pdq_tx_hdr[1] = PDQ_FDDI_PH1;
- pdq->pdq_tx_hdr[2] = PDQ_FDDI_PH2;
- pdq->pdq_tx_info.tx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_transmits);
- pdq->pdq_tx_info.tx_hdrdesc.txd_seg_len = sizeof(pdq->pdq_tx_hdr);
+ dbp->pdqdb_tx_hdr[0] = PDQ_FDDI_PH0;
+ dbp->pdqdb_tx_hdr[1] = PDQ_FDDI_PH1;
+ dbp->pdqdb_tx_hdr[2] = PDQ_FDDI_PH2;
+ pdq->pdq_tx_info.tx_free = PDQ_RING_MASK(dbp->pdqdb_transmits);
+ pdq->pdq_tx_info.tx_hdrdesc.txd_seg_len = 3;
pdq->pdq_tx_info.tx_hdrdesc.txd_sop = 1;
- pdq->pdq_tx_info.tx_hdrdesc.txd_pa_lo = PDQ_OS_VA_TO_PA(pdq, pdq->pdq_tx_hdr);
+ pdq->pdq_tx_info.tx_hdrdesc.txd_pa_lo = PDQ_DB_BUSPA(pdq, dbp->pdqdb_tx_hdr);
+ pdq->pdq_tx_info.tx_pa_descriptors = PDQ_DB_BUSPA(pdq, dbp->pdqdb_transmits);
state = PDQ_PSTS_ADAPTER_STATE(PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_status));
PDQ_PRINTF(("PDQ Adapter State = %s\n", pdq_adapter_states[state]));
diff --git a/sys/dev/pdq/pdq_freebsd.h b/sys/dev/pdq/pdq_freebsd.h
new file mode 100644
index 0000000..fd556b9
--- /dev/null
+++ b/sys/dev/pdq/pdq_freebsd.h
@@ -0,0 +1,271 @@
+/* $NetBSD: pdqvar.h,v 1.27 2000/05/03 19:17:54 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough 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 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.
+ *
+ * Id: pdqvar.h,v 1.21 1997/03/21 21:16:04 thomas Exp
+ * $FreeBSD$
+ *
+ */
+
+/*
+ * DEC PDQ FDDI Controller; PDQ O/S dependent definitions
+ *
+ * Written by Matt Thomas
+ *
+ */
+
+#if defined(PDQ_HWSUPPORT)
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/bus_memio.h>
+#include <machine/bus_pio.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/fddi.h>
+
+#include <net/bpf.h>
+
+#include <vm/vm.h> /* for vtophys */
+#include <vm/pmap.h> /* for vtophys */
+#include <machine/clock.h> /* for DELAY */
+
+#endif /* PDQ_HWSUPPORT */
+
+typedef struct _pdq_t pdq_t;
+typedef struct _pdq_csrs_t pdq_csrs_t;
+typedef struct _pdq_pci_csrs_t pdq_pci_csrs_t;
+typedef struct _pdq_lanaddr_t pdq_lanaddr_t;
+typedef unsigned int pdq_uint32_t;
+typedef unsigned short pdq_uint16_t;
+typedef unsigned char pdq_uint8_t;
+typedef enum _pdq_boolean_t pdq_boolean_t;
+typedef enum _pdq_type_t pdq_type_t;
+typedef enum _pdq_state_t pdq_state_t;
+typedef struct mbuf PDQ_OS_DATABUF_T;
+
+typedef bus_space_tag_t pdq_bus_t;
+typedef bus_space_handle_t pdq_bus_memaddr_t;
+typedef pdq_bus_memaddr_t pdq_bus_memoffset_t;
+
+extern devclass_t pdq_devclass;
+
+enum _pdq_type_t {
+ PDQ_DEFPA, /* PCI-bus */
+ PDQ_DEFEA, /* EISA-bus */
+ PDQ_DEFTA, /* TurboChannel */
+ PDQ_DEFAA, /* FutureBus+ */
+ PDQ_DEFQA /* Q-bus */
+};
+
+#define sc_ifmedia ifmedia
+#define sc_if arpcom.ac_if
+#define sc_bpf sc_if.if_bpf
+#define IFQ_DEQUEUE IF_DEQUEUE
+#define IFQ_IS_EMPTY(q) ((q)->ifq_len == 0)
+
+typedef struct _pdq_os_ctx_t {
+ struct arpcom arpcom;
+ struct ifmedia ifmedia;
+ device_t dev;
+ int debug;
+
+ pdq_t * sc_pdq;
+ int sc_flags;
+#define PDQIF_DOWNCALL 0x0001 /* active calling from if to pdq */
+
+ struct resource * io;
+ int io_rid;
+ int io_type;
+ bus_space_handle_t io_bsh;
+ bus_space_tag_t io_bst;
+
+ struct resource * mem;
+ int mem_rid;
+ int mem_type;
+ bus_space_handle_t mem_bsh;
+ bus_space_tag_t mem_bst;
+
+ struct resource * irq;
+ int irq_rid;
+ void * irq_ih;
+
+ struct mtx mtx;
+} pdq_softc_t;
+
+#define PDQ_LOCK(_sc) mtx_lock(&(_sc)->mtx)
+#define PDQ_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
+
+#define PDQ_OS_HDR_OFFSET PDQ_RX_FC_OFFSET
+
+#define PDQ_OS_PAGESIZE PAGE_SIZE
+#define PDQ_OS_TX_TRANSMIT 5
+
+#define PDQ_OS_IORD_32(bt, bh, off) bus_space_read_4(bt, bh, off)
+#define PDQ_OS_IOWR_32(bt, bh, off, data) bus_space_write_4(bt, bh, off, data)
+#define PDQ_OS_IORD_8(bt, bh, off) bus_space_read_1(bt, bh, off)
+#define PDQ_OS_IOWR_8(bt, bh, off, data) bus_space_write_1(bt, bh, off, data)
+
+#define PDQ_CSR_OFFSET(base, offset) (0 + (offset)*sizeof(pdq_uint32_t))
+#define PDQ_CSR_WRITE(csr, name, data) PDQ_OS_IOWR_32((csr)->csr_bus, (csr)->csr_base, (csr)->name, data)
+#define PDQ_CSR_READ(csr, name) PDQ_OS_IORD_32((csr)->csr_bus, (csr)->csr_base, (csr)->name)
+
+#define PDQ_OS_DATABUF_FREE(pdq, b) (m_freem(b))
+
+#if defined(PDQ_OSSUPPORT)
+#define PDQ_OS_TX_TIMEOUT 5 /* seconds */
+
+#define PDQ_OS_IFP_TO_SOFTC(ifp) ((pdq_softc_t *) (ifp)->if_softc)
+#define PDQ_BPF_MTAP(sc, m) bpf_mtap(&(sc)->arpcom.ac_if, m)
+
+#endif /* PDQ_OSSUPPORT */
+
+#if defined(PDQ_HWSUPPORT)
+
+#define PDQ_OS_PREFIX "%s%d: "
+#define PDQ_OS_PREFIX_ARGS pdq->pdq_os_name, pdq->pdq_unit
+
+#define PDQ_OS_PTR_FMT "%p"
+#define PDQ_OS_CSR_FMT "0x%x"
+
+#define PDQ_OS_USEC_DELAY(n) DELAY(n)
+#define PDQ_OS_VA_TO_BUSPA(pdq, p) vtophys(p)
+
+#define PDQ_OS_MEMALLOC(n) malloc(n, M_DEVBUF, M_NOWAIT)
+#define PDQ_OS_MEMFREE(p, n) free((void *) p, M_DEVBUF)
+#define PDQ_OS_MEMZERO(p, n) bzero((caddr_t)(p), (n))
+#define PDQ_OS_MEMALLOC_CONTIG(n) contigmalloc(n, M_DEVBUF, M_NOWAIT, 0x800000, ~0, PAGE_SIZE, 0)
+#define PDQ_OS_MEMFREE_CONTIG(p, n) contigfree(p, n, M_DEVBUF)
+
+#define PDQ_OS_DATABUF_SIZE (MCLBYTES)
+#define PDQ_OS_DATABUF_NEXT(b) ((b)->m_next)
+#define PDQ_OS_DATABUF_NEXT_SET(b, b1) ((b)->m_next = (b1))
+#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->m_nextpkt)
+#define PDQ_OS_DATABUF_NEXTPKT_SET(b, b1) ((b)->m_nextpkt = (b1))
+#define PDQ_OS_DATABUF_LEN(b) ((b)->m_len)
+#define PDQ_OS_DATABUF_LEN_SET(b, n) ((b)->m_len = (n))
+/* #define PDQ_OS_DATABUF_LEN_ADJ(b, n) ((b)->m_len += (n)) */
+#define PDQ_OS_DATABUF_PTR(b) (mtod((b), pdq_uint8_t *))
+#define PDQ_OS_DATABUF_ADJ(b, n) ((b)->m_data += (n), (b)->m_len -= (n))
+
+#define PDQ_OS_DATABUF_ALLOC(pdq, b) do { \
+ PDQ_OS_DATABUF_T *x_m0; \
+ MGETHDR(x_m0, M_DONTWAIT, MT_DATA); \
+ if (x_m0 != NULL) { \
+ MCLGET(x_m0, M_DONTWAIT); \
+ if ((x_m0->m_flags & M_EXT) == 0) { \
+ m_free(x_m0); \
+ (b) = NULL; \
+ } else { \
+ (b) = x_m0; \
+ x_m0->m_len = PDQ_OS_DATABUF_SIZE; \
+ } \
+ } else { \
+ (b) = NULL; \
+ } \
+} while (0)
+
+#define PDQ_OS_DATABUF_RESET(b) ((b)->m_data = (b)->m_ext.ext_buf, (b)->m_len = MCLBYTES)
+
+#define PDQ_OS_DATABUF_ENQUEUE(q, b) do { \
+ PDQ_OS_DATABUF_NEXTPKT_SET(b, NULL); \
+ if ((q)->q_tail == NULL) \
+ (q)->q_head = (b); \
+ else \
+ PDQ_OS_DATABUF_NEXTPKT_SET(((PDQ_OS_DATABUF_T *)(q)->q_tail), b); \
+ (q)->q_tail = (b); \
+} while (0)
+
+#define PDQ_OS_DATABUF_DEQUEUE(q, b) do { \
+ if (((b) = (PDQ_OS_DATABUF_T *) (q)->q_head) != NULL) { \
+ if (((q)->q_head = PDQ_OS_DATABUF_NEXTPKT(b)) == NULL) \
+ (q)->q_tail = NULL; \
+ PDQ_OS_DATABUF_NEXTPKT_SET(b, NULL); \
+ } \
+} while (0)
+
+#define PDQ_OS_DATABUF_BUSPA(pdq, b) PDQ_OS_VA_TO_BUSPA(pdq, PDQ_OS_DATABUF_PTR(b))
+
+#define PDQ_OS_CONSUMER_PRESYNC(pdq) do { } while(0)
+#define PDQ_OS_CONSUMER_POSTSYNC(pdq) do { } while(0)
+#define PDQ_OS_DESC_PRESYNC(pdq, d, s) do { } while(0)
+#define PDQ_OS_DESC_POSTSYNC(pdq, d, s) do { } while(0)
+#define PDQ_OS_CMDRQST_PRESYNC(pdq, s) do { } while(0)
+#define PDQ_OS_CMDRQST_POSTSYNC(pdq, s) do { } while(0)
+#define PDQ_OS_CMDRSP_PRESYNC(pdq, s) do { } while(0)
+#define PDQ_OS_CMDRSP_POSTSYNC(pdq, s) do { } while(0)
+#define PDQ_OS_RXPDU_PRESYNC(pdq, b, o, l) do { } while(0)
+#define PDQ_OS_RXPDU_POSTSYNC(pdq, b, o, l) do { } while(0)
+#define PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, e) do { } while(0)
+#define PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, e) do { } while(0)
+
+#endif /* PDQ_HWSUPPORT */
+
+/*
+ * OS dependent functions provided by pdq_ifsubr.c to pdq.c
+ */
+void pdq_os_addr_fill (pdq_t *pdq, pdq_lanaddr_t *addrs, size_t numaddrs);
+void pdq_os_receive_pdu (pdq_t *, PDQ_OS_DATABUF_T *, size_t, int);
+void pdq_os_restart_transmitter (pdq_t *pdq);
+void pdq_os_transmit_done (pdq_t *, PDQ_OS_DATABUF_T *);
+void pdq_os_update_status (pdq_t *, const void *);
+
+/*
+ * Driver interfaces functions provided by pdq.c to pdq_ifsubr.c
+ */
+pdq_boolean_t pdq_queue_transmit_data (pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
+void pdq_run (pdq_t *pdq);
+pdq_state_t pdq_stop (pdq_t *pdq);
+
+/*
+ * OS dependent functions provided by
+ * pdq_ifsubr.c or pdq.c to the bus front ends
+ */
+void pdq_ifattach (pdq_softc_t *);
+void pdq_ifdetach (pdq_softc_t *);
+void pdq_free (device_t);
+int pdq_interrupt (pdq_t *pdq);
+void pdq_hwreset (pdq_t *pdq);
+pdq_t * pdq_initialize (pdq_bus_t bus, pdq_bus_memaddr_t csr_va,
+ const char *name, int unit,
+ void *ctx, pdq_type_t type);
+/*
+ * Misc prototypes.
+ */
+void pdq_flush_transmitter(pdq_t *pdq);
diff --git a/sys/dev/pdq/pdq_ifsubr.c b/sys/dev/pdq/pdq_ifsubr.c
index ad8e02a..5a9a4a1 100644
--- a/sys/dev/pdq/pdq_ifsubr.c
+++ b/sys/dev/pdq/pdq_ifsubr.c
@@ -1,3 +1,5 @@
+/* $NetBSD: pdq_ifsubr.c,v 1.38 2001/12/21 23:21:47 matt Exp $ */
+
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
* All rights reserved.
@@ -8,7 +10,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * 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
@@ -21,8 +23,8 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
+ * $NetBSD: pdq_ifsubr.c,v 1.12 1997/06/05 01:56:35 thomas Exp$
* $FreeBSD$
- *
*/
/*
@@ -32,65 +34,45 @@
* (ie. it provides an ifnet interface to the rest of the system)
*/
+#ifdef __NetBSD__
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: pdq_ifsubr.c,v 1.38 2001/12/21 23:21:47 matt Exp $");
+#endif
-#include "opt_inet.h"
+#define PDQ_OSSUPPORT
#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/malloc.h>
#include <sys/socket.h>
#include <sys/sockio.h>
-#if defined(__bsdi__) || defined(__NetBSD__)
-#include <sys/device.h>
-#endif
+
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/bus_memio.h>
+#include <machine/bus_pio.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
#include <net/if.h>
+#include <net/if_arp.h>
#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/fddi.h>
#include <net/bpf.h>
-#if defined(__FreeBSD__)
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#endif
-#include <netinet/if_fddi.h>
-#else
-#include <net/if_fddi.h>
-#endif
-
-#if defined(__bsdi__)
-#include <i386/isa/isavar.h>
-#endif
-
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-
-#if defined(__FreeBSD__)
-#include <dev/pdq/pdqvar.h>
+#include <dev/pdq/pdq_freebsd.h>
#include <dev/pdq/pdqreg.h>
-#else
-#include "pdqvar.h"
-#include "pdqreg.h"
-#endif
-#if defined(__bsdi__) && _BSDI_VERSION < 199506 /* XXX */
-static void
-arp_ifinit(
- struct arpcom *ac,
- struct ifaddr *ifa)
-{
- sc->sc_ac.ac_ipaddr = IA_SIN(ifa)->sin_addr;
- arpwhohas(&sc->sc_ac, &IA_SIN(ifa)->sin_addr);
-#if _BSDI_VERSION >= 199401
- ifa->ifa_rtrequest = arp_rtrequest;
- ifa->ifa_flags |= RTF_CLONING;
-#endif
-}
-#endif
+devclass_t pdq_devclass;
-
-void
+static void
pdq_ifinit(
pdq_softc_t *sc)
{
@@ -101,11 +83,6 @@ pdq_ifinit(
} else {
sc->sc_pdq->pdq_flags &= ~PDQ_PROMISC;
}
- if (sc->sc_if.if_flags & IFF_ALLMULTI) {
- sc->sc_pdq->pdq_flags |= PDQ_ALLMULTI;
- } else {
- sc->sc_pdq->pdq_flags &= ~PDQ_ALLMULTI;
- }
if (sc->sc_if.if_flags & IFF_LINK1) {
sc->sc_pdq->pdq_flags |= PDQ_PASS_SMT;
} else {
@@ -120,7 +97,7 @@ pdq_ifinit(
}
}
-void
+static void
pdq_ifwatchdog(
struct ifnet *ifp)
{
@@ -131,15 +108,20 @@ pdq_ifwatchdog(
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_timer = 0;
- IF_DRAIN(&ifp->if_snd);
+ for (;;) {
+ struct mbuf *m;
+ IFQ_DEQUEUE(&ifp->if_snd, m);
+ if (m == NULL)
+ return;
+ PDQ_OS_DATABUF_FREE(PDQ_OS_IFP_TO_SOFTC(ifp)->sc_pdq, m);
+ }
}
-ifnet_ret_t
+static void
pdq_ifstart(
struct ifnet *ifp)
{
- pdq_softc_t *sc = (pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_ac.ac_if));
- struct ifqueue *ifq = &ifp->if_snd;
+ pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
struct mbuf *m;
int tx = 0;
@@ -153,41 +135,95 @@ pdq_ifstart(
sc->sc_if.if_flags |= IFF_OACTIVE;
return;
}
+ sc->sc_flags |= PDQIF_DOWNCALL;
for (;; tx = 1) {
- IF_DEQUEUE(ifq, m);
+ IF_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
break;
+#if defined(PDQ_BUS_DMA) && !defined(PDQ_BUS_DMA_NOTX)
+ if ((m->m_flags & M_HASTXDMAMAP) == 0) {
+ bus_dmamap_t map;
+ if (PDQ_OS_HDR_OFFSET != PDQ_RX_FC_OFFSET) {
+ m->m_data[0] = PDQ_FDDI_PH0;
+ m->m_data[1] = PDQ_FDDI_PH1;
+ m->m_data[2] = PDQ_FDDI_PH2;
+ }
+ if (!bus_dmamap_create(sc->sc_dmatag, m->m_pkthdr.len, 255,
+ m->m_pkthdr.len, 0, BUS_DMA_NOWAIT, &map)) {
+ if (!bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,
+ BUS_DMA_WRITE|BUS_DMA_NOWAIT)) {
+ bus_dmamap_sync(sc->sc_dmatag, map, 0, m->m_pkthdr.len,
+ BUS_DMASYNC_PREWRITE);
+ M_SETCTX(m, map);
+ m->m_flags |= M_HASTXDMAMAP;
+ }
+ }
+ if ((m->m_flags & M_HASTXDMAMAP) == 0)
+ break;
+ }
+#else
+ if (PDQ_OS_HDR_OFFSET != PDQ_RX_FC_OFFSET) {
+ m->m_data[0] = PDQ_FDDI_PH0;
+ m->m_data[1] = PDQ_FDDI_PH1;
+ m->m_data[2] = PDQ_FDDI_PH2;
+ }
+#endif
- if (pdq_queue_transmit_data(sc->sc_pdq, m) == PDQ_FALSE) {
- ifp->if_flags |= IFF_OACTIVE;
- IF_PREPEND(ifq, m);
+ if (pdq_queue_transmit_data(sc->sc_pdq, m) == PDQ_FALSE)
break;
- }
+ }
+ if (m != NULL) {
+ ifp->if_flags |= IFF_OACTIVE;
+ IF_PREPEND(&ifp->if_snd, m);
}
if (tx)
PDQ_DO_TYPE2_PRODUCER(sc->sc_pdq);
+ sc->sc_flags &= ~PDQIF_DOWNCALL;
}
void
pdq_os_receive_pdu(
pdq_t *pdq,
struct mbuf *m,
- size_t pktlen)
+ size_t pktlen,
+ int drop)
{
- pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
- struct fddi_header *fh = mtod(m, struct fddi_header *);
+ pdq_softc_t *sc = pdq->pdq_os_ctx;
+ struct fddi_header *fh;
sc->sc_if.if_ipackets++;
+#if defined(PDQ_BUS_DMA)
+ {
+ /*
+ * Even though the first mbuf start at the first fddi header octet,
+ * the dmamap starts PDQ_OS_HDR_OFFSET octets earlier. Any additional
+ * mbufs will start normally.
+ */
+ int offset = PDQ_OS_HDR_OFFSET;
+ struct mbuf *m0;
+ for (m0 = m; m0 != NULL; m0 = m0->m_next, offset = 0) {
+ pdq_os_databuf_sync(sc, m0, offset, m0->m_len, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->sc_dmatag, M_GETCTX(m0, bus_dmamap_t));
+ bus_dmamap_destroy(sc->sc_dmatag, M_GETCTX(m0, bus_dmamap_t));
+ m0->m_flags &= ~M_HASRXDMAMAP;
+ M_SETCTX(m0, NULL);
+ }
+ }
+#endif
+ m->m_pkthdr.len = pktlen;
+#if NBPFILTER > 0
if (sc->sc_bpf != NULL)
PDQ_BPF_MTAP(sc, m);
- if ((fh->fddi_fc & (FDDIFC_L|FDDIFC_F)) != FDDIFC_LLC_ASYNC) {
- m_freem(m);
+#endif
+ fh = mtod(m, struct fddi_header *);
+ if (drop || (fh->fddi_fc & (FDDIFC_L|FDDIFC_F)) != FDDIFC_LLC_ASYNC) {
+ sc->sc_if.if_iqdrops++;
+ sc->sc_if.if_ierrors++;
+ PDQ_OS_DATABUF_FREE(pdq, m);
return;
}
- m->m_data += sizeof(struct fddi_header);
- m->m_len -= sizeof(struct fddi_header);
- m->m_pkthdr.len = pktlen - sizeof(struct fddi_header);
+ m_adj(m, FDDI_HDR_LEN);
m->m_pkthdr.rcvif = &sc->sc_if;
fddi_input(&sc->sc_if, fh, m);
}
@@ -196,11 +232,12 @@ void
pdq_os_restart_transmitter(
pdq_t *pdq)
{
- pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
+ pdq_softc_t *sc = pdq->pdq_os_ctx;
sc->sc_if.if_flags &= ~IFF_OACTIVE;
- if (sc->sc_if.if_snd.ifq_head != NULL) {
+ if (IFQ_IS_EMPTY(&sc->sc_if.if_snd) == 0) {
sc->sc_if.if_timer = PDQ_OS_TX_TIMEOUT;
- pdq_ifstart(&sc->sc_if);
+ if ((sc->sc_flags & PDQIF_DOWNCALL) == 0)
+ pdq_ifstart(&sc->sc_if);
} else {
sc->sc_if.if_timer = 0;
}
@@ -211,10 +248,12 @@ pdq_os_transmit_done(
pdq_t *pdq,
struct mbuf *m)
{
- pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
+ pdq_softc_t *sc = pdq->pdq_os_ctx;
+#if NBPFILTER > 0
if (sc->sc_bpf != NULL)
PDQ_BPF_MTAP(sc, m);
- m_freem(m);
+#endif
+ PDQ_OS_DATABUF_FREE(pdq, m);
sc->sc_if.if_opackets++;
}
@@ -224,9 +263,23 @@ pdq_os_addr_fill(
pdq_lanaddr_t *addr,
size_t num_addrs)
{
- pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
+ pdq_softc_t *sc = pdq->pdq_os_ctx;
+ struct ifnet *ifp;
struct ifmultiaddr *ifma;
+ ifp = &sc->arpcom.ac_if;
+
+ /*
+ * ADDR_FILTER_SET is always issued before FILTER_SET so
+ * we can play with PDQ_ALLMULTI and not worry about
+ * queueing a FILTER_SET ourselves.
+ */
+
+ pdq->pdq_flags &= ~PDQ_ALLMULTI;
+#if defined(IFF_ALLMULTI)
+ sc->sc_if.if_flags &= ~IFF_ALLMULTI;
+#endif
+
for (ifma = TAILQ_FIRST(&sc->sc_if.if_multiaddrs); ifma && num_addrs > 0;
ifma = TAILQ_NEXT(ifma, ifma_link)) {
char *mcaddr;
@@ -239,66 +292,95 @@ pdq_os_addr_fill(
addr++;
num_addrs--;
}
+ /*
+ * If not all the address fit into the CAM, turn on all-multicast mode.
+ */
+ if (ifma != NULL) {
+ pdq->pdq_flags |= PDQ_ALLMULTI;
+#if defined(IFF_ALLMULTI)
+ sc->sc_if.if_flags |= IFF_ALLMULTI;
+#endif
+ }
}
-int
+#if defined(IFM_FDDI)
+static int
+pdq_ifmedia_change(
+ struct ifnet *ifp)
+{
+ pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
+
+ if (sc->sc_ifmedia.ifm_media & IFM_FDX) {
+ if ((sc->sc_pdq->pdq_flags & PDQ_WANT_FDX) == 0) {
+ sc->sc_pdq->pdq_flags |= PDQ_WANT_FDX;
+ if (sc->sc_pdq->pdq_flags & PDQ_RUNNING)
+ pdq_run(sc->sc_pdq);
+ }
+ } else if (sc->sc_pdq->pdq_flags & PDQ_WANT_FDX) {
+ sc->sc_pdq->pdq_flags &= ~PDQ_WANT_FDX;
+ if (sc->sc_pdq->pdq_flags & PDQ_RUNNING)
+ pdq_run(sc->sc_pdq);
+ }
+
+ return 0;
+}
+
+static void
+pdq_ifmedia_status(
+ struct ifnet *ifp,
+ struct ifmediareq *ifmr)
+{
+ pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
+
+ ifmr->ifm_status = IFM_AVALID;
+ if (sc->sc_pdq->pdq_flags & PDQ_IS_ONRING)
+ ifmr->ifm_status |= IFM_ACTIVE;
+
+ ifmr->ifm_active = (ifmr->ifm_current & ~IFM_FDX);
+ if (sc->sc_pdq->pdq_flags & PDQ_IS_FDX)
+ ifmr->ifm_active |= IFM_FDX;
+}
+
+void
+pdq_os_update_status(
+ pdq_t *pdq,
+ const void *arg)
+{
+ pdq_softc_t * const sc = pdq->pdq_os_ctx;
+ const pdq_response_status_chars_get_t *rsp = arg;
+ int media = 0;
+
+ switch (rsp->status_chars_get.pmd_type[0]) {
+ case PDQ_PMD_TYPE_ANSI_MUTLI_MODE: media = IFM_FDDI_MMF; break;
+ case PDQ_PMD_TYPE_ANSI_SINGLE_MODE_TYPE_1: media = IFM_FDDI_SMF; break;
+ case PDQ_PMD_TYPE_ANSI_SIGNLE_MODE_TYPE_2: media = IFM_FDDI_SMF; break;
+ case PDQ_PMD_TYPE_UNSHIELDED_TWISTED_PAIR: media = IFM_FDDI_UTP; break;
+ default: media |= IFM_MANUAL;
+ }
+
+ if (rsp->status_chars_get.station_type == PDQ_STATION_TYPE_DAS)
+ media |= IFM_FDDI_DA;
+
+ sc->sc_ifmedia.ifm_media = media | IFM_FDDI;
+}
+#endif /* defined(IFM_FDDI) */
+
+static int
pdq_ifioctl(
struct ifnet *ifp,
- ioctl_cmd_t cmd,
+ u_long cmd,
caddr_t data)
{
- pdq_softc_t *sc = (pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_ac.ac_if));
- int s, error = 0;
+ pdq_softc_t *sc = PDQ_OS_IFP_TO_SOFTC(ifp);
+ int error = 0;
- s = splimp();
+ PDQ_LOCK(sc);
switch (cmd) {
+ case SIOCSIFMTU:
+ case SIOCGIFADDR:
case SIOCSIFADDR: {
- struct ifaddr *ifa = (struct ifaddr *)data;
-
- ifp->if_flags |= IFF_UP;
- switch(ifa->ifa_addr->sa_family) {
-#if defined(INET)
- case AF_INET: {
- pdq_ifinit(sc);
- arp_ifinit(&sc->sc_ac.ac_if, ifa);
- break;
- }
-#endif /* INET */
-
-#if defined(NS)
- /* This magic copied from if_is.c; I don't use XNS,
- * so I have no way of telling if this actually
- * works or not.
- */
- case AF_NS: {
- struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
- if (ns_nullhost(*ina)) {
- ina->x_host = *(union ns_host *)(sc->sc_ac.ac_enaddr);
- } else {
- ifp->if_flags &= ~IFF_RUNNING;
- bcopy((caddr_t)ina->x_host.c_host,
- (caddr_t)sc->sc_ac.ac_enaddr,
- sizeof sc->sc_ac.ac_enaddr);
- }
-
- pdq_ifinit(sc);
- break;
- }
-#endif /* NS */
-
- default: {
- pdq_ifinit(sc);
- break;
- }
- }
- break;
- }
- case SIOCGIFADDR: {
- struct ifreq *ifr = (struct ifreq *)data;
- bcopy((caddr_t) sc->sc_ac.ac_enaddr,
- (caddr_t) ((struct sockaddr *)&ifr->ifr_data)->sa_data,
- 6);
+ error = fddi_ioctl(ifp, cmd, data);
break;
}
@@ -308,32 +390,22 @@ pdq_ifioctl(
}
case SIOCADDMULTI:
- case SIOCDELMULTI:
- /*
- * Update multicast listeners
- */
- if (sc->sc_if.if_flags & IFF_RUNNING)
- pdq_run(sc->sc_pdq);
+ case SIOCDELMULTI: {
+ if (sc->sc_if.if_flags & IFF_RUNNING) {
+ pdq_run(sc->sc_pdq);
error = 0;
- break;
+ }
+ break;
+ }
-#if defined(SIOCSIFMTU)
-#if !defined(ifr_mtu)
-#define ifr_mtu ifr_metric
-#endif
- case SIOCSIFMTU: {
+#if defined(IFM_FDDI) && defined(SIOCSIFMEDIA)
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA: {
struct ifreq *ifr = (struct ifreq *)data;
- /*
- * Set the interface MTU.
- */
- if (ifr->ifr_mtu > FDDIMTU) {
- error = EINVAL;
- break;
- }
- ifp->if_mtu = ifr->ifr_mtu;
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
break;
}
-#endif /* SIOCSIFMTU */
+#endif
default: {
error = EINVAL;
@@ -341,7 +413,7 @@ pdq_ifioctl(
}
}
- splx(s);
+ PDQ_UNLOCK(sc);
return error;
}
@@ -350,12 +422,15 @@ pdq_ifioctl(
#endif
void
-pdq_ifattach(
- pdq_softc_t *sc,
- ifnet_ret_t (*ifwatchdog)(int unit))
+pdq_ifattach(pdq_softc_t *sc)
{
struct ifnet *ifp = &sc->sc_if;
+ mtx_init(&sc->mtx, device_get_nameunit(sc->dev), MTX_DEF | MTX_RECURSE);
+
+ ifp->if_softc = sc;
+ ifp->if_init = (if_init_f_t *)pdq_ifinit;
+ ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
#if (defined(__FreeBSD__) && BSD >= 199506) || defined(__NetBSD__)
@@ -365,13 +440,296 @@ pdq_ifattach(
#endif
ifp->if_ioctl = pdq_ifioctl;
+#if !defined(__NetBSD__) && !defined(__FreeBSD__)
ifp->if_output = fddi_output;
+#endif
ifp->if_start = pdq_ifstart;
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-#warning "Implement fddi_resolvemulti!"
-/* ifp->if_resolvemulti = ether_resolvemulti; XXX */
+
+#if defined(IFM_FDDI)
+ {
+ const int media = sc->sc_ifmedia.ifm_media;
+ ifmedia_init(&sc->sc_ifmedia, IFM_FDX,
+ pdq_ifmedia_change, pdq_ifmedia_status);
+ ifmedia_add(&sc->sc_ifmedia, media, 0, 0);
+ ifmedia_set(&sc->sc_ifmedia, media);
+ }
+#endif
if_attach(ifp);
- fddi_ifattach(ifp);
- PDQ_BPFATTACH(sc, DLT_FDDI, sizeof(struct fddi_header));
+#if defined(__NetBSD__)
+ fddi_ifattach(ifp, (caddr_t)&sc->sc_pdq->pdq_hwaddr);
+#else
+ fddi_ifattach(ifp, FDDI_BPF_SUPPORTED);
+#endif
+}
+
+void
+pdq_ifdetach (pdq_softc_t *sc)
+{
+ struct ifnet *ifp;
+
+ ifp = &sc->arpcom.ac_if;
+
+ fddi_ifdetach(ifp, FDDI_BPF_SUPPORTED);
+ pdq_stop(sc->sc_pdq);
+ pdq_free(sc->dev);
+
+ return;
+}
+
+void
+pdq_free (device_t dev)
+{
+ pdq_softc_t *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->io)
+ bus_release_resource(dev, sc->io_type, sc->io_rid, sc->io);
+ if (sc->mem)
+ bus_release_resource(dev, sc->mem_type, sc->mem_rid, sc->mem);
+ if (sc->irq_ih)
+ bus_teardown_intr(dev, sc->irq, sc->irq_ih);
+ if (sc->irq)
+ bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
+
+ /*
+ * Destroy the mutex.
+ */
+ if (mtx_initialized(&sc->mtx) != 0) {
+ mtx_destroy(&sc->mtx);
+ }
+
+ return;
+}
+
+#if defined(PDQ_BUS_DMA)
+int
+pdq_os_memalloc_contig(
+ pdq_t *pdq)
+{
+ pdq_softc_t * const sc = pdq->pdq_os_ctx;
+ bus_dma_segment_t db_segs[1], ui_segs[1], cb_segs[1];
+ int db_nsegs = 0, ui_nsegs = 0;
+ int steps = 0;
+ int not_ok;
+
+ not_ok = bus_dmamem_alloc(sc->sc_dmatag,
+ sizeof(*pdq->pdq_dbp), sizeof(*pdq->pdq_dbp),
+ sizeof(*pdq->pdq_dbp), db_segs, 1, &db_nsegs,
+ BUS_DMA_NOWAIT);
+ if (!not_ok) {
+ steps = 1;
+ not_ok = bus_dmamem_map(sc->sc_dmatag, db_segs, db_nsegs,
+ sizeof(*pdq->pdq_dbp), (caddr_t *) &pdq->pdq_dbp,
+ BUS_DMA_NOWAIT);
+ }
+ if (!not_ok) {
+ steps = 2;
+ not_ok = bus_dmamap_create(sc->sc_dmatag, db_segs[0].ds_len, 1,
+ 0x2000, 0, BUS_DMA_NOWAIT, &sc->sc_dbmap);
+ }
+ if (!not_ok) {
+ steps = 3;
+ not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_dbmap,
+ pdq->pdq_dbp, sizeof(*pdq->pdq_dbp),
+ NULL, BUS_DMA_NOWAIT);
+ }
+ if (!not_ok) {
+ steps = 4;
+ pdq->pdq_pa_descriptor_block = sc->sc_dbmap->dm_segs[0].ds_addr;
+ not_ok = bus_dmamem_alloc(sc->sc_dmatag,
+ PDQ_OS_PAGESIZE, PDQ_OS_PAGESIZE, PDQ_OS_PAGESIZE,
+ ui_segs, 1, &ui_nsegs, BUS_DMA_NOWAIT);
+ }
+ if (!not_ok) {
+ steps = 5;
+ not_ok = bus_dmamem_map(sc->sc_dmatag, ui_segs, ui_nsegs,
+ PDQ_OS_PAGESIZE,
+ (caddr_t *) &pdq->pdq_unsolicited_info.ui_events,
+ BUS_DMA_NOWAIT);
+ }
+ if (!not_ok) {
+ steps = 6;
+ not_ok = bus_dmamap_create(sc->sc_dmatag, ui_segs[0].ds_len, 1,
+ PDQ_OS_PAGESIZE, 0, BUS_DMA_NOWAIT,
+ &sc->sc_uimap);
+ }
+ if (!not_ok) {
+ steps = 7;
+ not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_uimap,
+ pdq->pdq_unsolicited_info.ui_events,
+ PDQ_OS_PAGESIZE, NULL, BUS_DMA_NOWAIT);
+ }
+ if (!not_ok) {
+ steps = 8;
+ pdq->pdq_unsolicited_info.ui_pa_bufstart = sc->sc_uimap->dm_segs[0].ds_addr;
+ cb_segs[0] = db_segs[0];
+ cb_segs[0].ds_addr += offsetof(pdq_descriptor_block_t, pdqdb_consumer);
+ cb_segs[0].ds_len = sizeof(pdq_consumer_block_t);
+ not_ok = bus_dmamem_map(sc->sc_dmatag, cb_segs, 1,
+ sizeof(*pdq->pdq_cbp), (caddr_t *) &pdq->pdq_cbp,
+ BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
+ }
+ if (!not_ok) {
+ steps = 9;
+ not_ok = bus_dmamap_create(sc->sc_dmatag, cb_segs[0].ds_len, 1,
+ 0x2000, 0, BUS_DMA_NOWAIT, &sc->sc_cbmap);
+ }
+ if (!not_ok) {
+ steps = 10;
+ not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_cbmap,
+ (caddr_t) pdq->pdq_cbp, sizeof(*pdq->pdq_cbp),
+ NULL, BUS_DMA_NOWAIT);
+ }
+ if (!not_ok) {
+ pdq->pdq_pa_consumer_block = sc->sc_cbmap->dm_segs[0].ds_addr;
+ return not_ok;
+ }
+
+ switch (steps) {
+ case 11: {
+ bus_dmamap_unload(sc->sc_dmatag, sc->sc_cbmap);
+ /* FALL THROUGH */
+ }
+ case 10: {
+ bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cbmap);
+ /* FALL THROUGH */
+ }
+ case 9: {
+ bus_dmamem_unmap(sc->sc_dmatag,
+ (caddr_t) pdq->pdq_cbp, sizeof(*pdq->pdq_cbp));
+ /* FALL THROUGH */
+ }
+ case 8: {
+ bus_dmamap_unload(sc->sc_dmatag, sc->sc_uimap);
+ /* FALL THROUGH */
+ }
+ case 7: {
+ bus_dmamap_destroy(sc->sc_dmatag, sc->sc_uimap);
+ /* FALL THROUGH */
+ }
+ case 6: {
+ bus_dmamem_unmap(sc->sc_dmatag,
+ (caddr_t) pdq->pdq_unsolicited_info.ui_events,
+ PDQ_OS_PAGESIZE);
+ /* FALL THROUGH */
+ }
+ case 5: {
+ bus_dmamem_free(sc->sc_dmatag, ui_segs, ui_nsegs);
+ /* FALL THROUGH */
+ }
+ case 4: {
+ bus_dmamap_unload(sc->sc_dmatag, sc->sc_dbmap);
+ /* FALL THROUGH */
+ }
+ case 3: {
+ bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dbmap);
+ /* FALL THROUGH */
+ }
+ case 2: {
+ bus_dmamem_unmap(sc->sc_dmatag,
+ (caddr_t) pdq->pdq_dbp,
+ sizeof(*pdq->pdq_dbp));
+ /* FALL THROUGH */
+ }
+ case 1: {
+ bus_dmamem_free(sc->sc_dmatag, db_segs, db_nsegs);
+ /* FALL THROUGH */
+ }
+ }
+
+ return not_ok;
+}
+
+extern void
+pdq_os_descriptor_block_sync(
+ pdq_os_ctx_t *sc,
+ size_t offset,
+ size_t length,
+ int ops)
+{
+ bus_dmamap_sync(sc->sc_dmatag, sc->sc_dbmap, offset, length, ops);
}
+
+extern void
+pdq_os_consumer_block_sync(
+ pdq_os_ctx_t *sc,
+ int ops)
+{
+ bus_dmamap_sync(sc->sc_dmatag, sc->sc_cbmap, 0, sizeof(pdq_consumer_block_t), ops);
+}
+
+extern void
+pdq_os_unsolicited_event_sync(
+ pdq_os_ctx_t *sc,
+ size_t offset,
+ size_t length,
+ int ops)
+{
+ bus_dmamap_sync(sc->sc_dmatag, sc->sc_uimap, offset, length, ops);
+}
+
+extern void
+pdq_os_databuf_sync(
+ pdq_os_ctx_t *sc,
+ struct mbuf *m,
+ size_t offset,
+ size_t length,
+ int ops)
+{
+ bus_dmamap_sync(sc->sc_dmatag, M_GETCTX(m, bus_dmamap_t), offset, length, ops);
+}
+
+extern void
+pdq_os_databuf_free(
+ pdq_os_ctx_t *sc,
+ struct mbuf *m)
+{
+ if (m->m_flags & (M_HASRXDMAMAP|M_HASTXDMAMAP)) {
+ bus_dmamap_t map = M_GETCTX(m, bus_dmamap_t);
+ bus_dmamap_unload(sc->sc_dmatag, map);
+ bus_dmamap_destroy(sc->sc_dmatag, map);
+ m->m_flags &= ~(M_HASRXDMAMAP|M_HASTXDMAMAP);
+ }
+ m_freem(m);
+}
+
+extern struct mbuf *
+pdq_os_databuf_alloc(
+ pdq_os_ctx_t *sc)
+{
+ struct mbuf *m;
+ bus_dmamap_t map;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ printf("%s: can't alloc small buf\n", sc->sc_dev.dv_xname);
+ return NULL;
+ }
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ printf("%s: can't alloc cluster\n", sc->sc_dev.dv_xname);
+ m_free(m);
+ return NULL;
+ }
+ m->m_pkthdr.len = m->m_len = PDQ_OS_DATABUF_SIZE;
+
+ if (bus_dmamap_create(sc->sc_dmatag, PDQ_OS_DATABUF_SIZE,
+ 1, PDQ_OS_DATABUF_SIZE, 0, BUS_DMA_NOWAIT, &map)) {
+ printf("%s: can't create dmamap\n", sc->sc_dev.dv_xname);
+ m_free(m);
+ return NULL;
+ }
+ if (bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,
+ BUS_DMA_READ|BUS_DMA_NOWAIT)) {
+ printf("%s: can't load dmamap\n", sc->sc_dev.dv_xname);
+ bus_dmamap_destroy(sc->sc_dmatag, map);
+ m_free(m);
+ return NULL;
+ }
+ m->m_flags |= M_HASRXDMAMAP;
+ M_SETCTX(m, map);
+ return m;
+}
+#endif
diff --git a/sys/dev/pdq/pdqreg.h b/sys/dev/pdq/pdqreg.h
index 26ddab1..9578195 100644
--- a/sys/dev/pdq/pdqreg.h
+++ b/sys/dev/pdq/pdqreg.h
@@ -1,3 +1,5 @@
+/* $NetBSD: pdqreg.h,v 1.14 2001/06/13 10:46:03 wiz Exp $ */
+
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
* All rights reserved.
@@ -8,7 +10,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * 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
@@ -21,6 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
+ * Id: pdqreg.h,v 1.11 1997/03/21 21:16:04 thomas Exp
* $FreeBSD$
*
*/
@@ -33,6 +36,11 @@
#ifndef _PDQREG_H
#define _PDQREG_H
+#if !defined(KERNEL) && !defined(_KERNEL)
+#include <stddef.h>
+#elif !defined(offsetof)
+#define offsetof(t, m) ((char *) (&((t *)0L)->m) - (char *) 0L)
+#endif
#if defined(PDQTEST) && !defined(PDQ_NDEBUG)
#include <assert.h>
#define PDQ_ASSERT assert
@@ -303,19 +311,36 @@ typedef struct {
typedef union {
pdq_uint32_t rxs_status;
- pdq_uint32_t PDQ_BITFIELD12(rxs_len : 13,
- rxs_rcc_ss : 2,
- rxs_rcc_dd : 2,
- rxs_rcc_reason : 3,
- rxs_rcc_badcrc : 1,
- rxs_rcc_badpdu : 1,
- rxs_fsb__reserved : 2,
- rxs_fsb_c : 1,
- rxs_fsb_a : 1,
- rxs_fsb_e : 1,
- rxs_fsc : 3,
- rxs__reserved : 2);
+ struct {
+ pdq_uint32_t PDQ_BITFIELD12(st_len : 13,
+ st_rcc_ss : 2,
+ st_rcc_dd : 2,
+ st_rcc_reason : 3,
+ st_rcc_badcrc : 1,
+ st_rcc_badpdu : 1,
+ st_fsb__reserved : 2,
+ st_fsb_c : 1,
+ st_fsb_a : 1,
+ st_fsb_e : 1,
+ st_fsc : 3,
+ st__reserved : 2);
+ } rxs_st;
} pdq_rxstatus_t;
+#define rxs_len rxs_st.st_len
+#define rxs_rcc_ss rxs_st.st_rcc_ss
+#define rxs_rcc_dd rxs_st.st_rcc_dd
+#define rxs_rcc_reason rxs_st.st_rcc_reason
+#define rxs_rcc_badcrc rxs_st.st_rcc_badcrc
+#define rxs_rcc_badpdu rxs_st.st_rcc_badpdu
+#define rxs_fsb_c rxs_st.st_fsb_c
+#define rxs_fsb_a rxs_st.st_fsb_a
+#define rxs_fsb_e rxs_st.st_fsb_e
+#define rxs_fsc rxs_st.st_fsc
+
+#define PDQ_RXS_RCC_DD_NO_MATCH 0x00
+#define PDQ_RXS_RCC_DD_PROMISC_MATCH 0x01
+#define PDQ_RXS_RCC_DD_CAM_MATCH 0x02
+#define PDQ_RXS_RCC_DD_MLA_MATCH 0x03
typedef struct {
pdq_uint32_t PDQ_BITFIELD5(txd_pa_hi : 16,
@@ -337,27 +362,52 @@ typedef struct {
* The rest of the descriptor block is unused.
* As such we could use it for other things.
*/
- pdq_consumer_block_t pdqdb_consumer; /* 64; 0x1380..0x13BF */
- void *pdqdb_receive_buffers[256]; /* 1024/2048; 0x13C0..0x17BF 0x13C0..0x1BBF */
- void *pdqdb_host_smt_buffers[64]; /* 256/ 512; 0x17C0..0x18BF 0x1BC0..0x1DBF */
+ pdq_uint32_t pdqdb__filler1[16]; /* 64; 0x1380..0x13BF */
+ pdq_consumer_block_t pdqdb_consumer; /* 64; 0x13C0..0x13FF */
/*
* The maximum command size is 512 so as long as thes
* command is at least that long all will be fine.
*/
-#if defined(__alpha) || defined(__alpha__)
- pdq_uint32_t pdqdb_command_pool[144];
-#else
- pdq_uint32_t pdqdb_command_pool[464];
-#endif
+ pdq_uint32_t pdqdb__filler2[64]; /* 256; 0x1400..0x14FF */
+ pdq_uint8_t pdqdb_cmd_request_buf[1024]; /* 1024; 0x1500..0x18FF */
+ pdq_uint8_t pdqdb_cmd_response_buf[1024]; /* 1024; 0x1900..0x1CFF */
+ pdq_uint32_t pdqdb__filler3[128]; /* 512; 0x1D00..0x1EFF */
+ pdq_uint8_t pdqdb_tx_hdr[4]; /* 4; 0x1F00..0x1F03 */
+ pdq_uint32_t pdqdb__filler4[63]; /* 252; 0x1F04..0x1FFF */
} pdq_descriptor_block_t;
+#define PDQ_SIZE_COMMAND_RESPONSE 512
+
+typedef enum {
+ PDQC_START=0,
+ PDQC_FILTER_SET=1,
+ PDQC_FILTER_GET=2,
+ PDQC_CHARS_SET=3,
+ PDQC_STATUS_CHARS_GET=4,
+ PDQC_COUNTERS_GET=5,
+ PDQC_COUNTERS_SET=6,
+ PDQC_ADDR_FILTER_SET=7,
+ PDQC_ADDR_FILTER_GET=8,
+ PDQC_ERROR_LOG_CLEAR=9,
+ PDQC_ERROR_LOG_GET=10,
+ PDQC_FDDI_MIB_GET=11,
+ PDQC_DEC_EXT_MIB_GET=12,
+ PDQC_DEV_SPECIFIC_GET=13,
+ PDQC_SNMP_SET=14,
+ PDQC_SMT_MIB_GET=16,
+ PDQC_SMT_MIB_SET=17,
+ PDQC_BOGUS_CMD=18
+} pdq_cmd_code_t;
+
typedef struct {
/*
* These value manage the available space in command/response
* buffer area.
*/
- pdq_physaddr_t ci_pa_bufstart;
- pdq_uint8_t *ci_bufstart;
+ pdq_physaddr_t ci_pa_request_bufstart;
+ pdq_uint8_t *ci_request_bufstart;
+ pdq_physaddr_t ci_pa_response_bufstart;
+ pdq_uint8_t *ci_response_bufstart;
/*
* Bitmask of commands to sent to the PDQ
*/
@@ -370,6 +420,13 @@ typedef struct {
pdq_uint32_t ci_response_producer;
pdq_uint32_t ci_request_completion;
pdq_uint32_t ci_response_completion;
+ /*
+ *
+ */
+ pdq_physaddr_t ci_pa_request_descriptors;
+ pdq_physaddr_t ci_pa_response_descriptors;
+
+ pdq_cmd_code_t ci_queued_commands[16];
} pdq_command_info_t;
#define PDQ_SIZE_UNSOLICITED_EVENT 512
@@ -379,6 +436,7 @@ typedef struct _pdq_unsolicited_event_t pdq_unsolicited_event_t;
typedef struct {
pdq_physaddr_t ui_pa_bufstart;
+ pdq_physaddr_t ui_pa_descriptors;
pdq_unsolicited_event_t *ui_events;
pdq_uint32_t ui_free;
@@ -409,6 +467,7 @@ typedef struct {
typedef struct {
void *rx_buffers;
+ pdq_physaddr_t rx_pa_descriptors;
pdq_uint32_t rx_target;
pdq_uint32_t rx_free;
@@ -420,12 +479,14 @@ typedef struct {
pdq_databuf_queue_t tx_txq;
pdq_txdesc_t tx_hdrdesc;
pdq_uint8_t tx_descriptor_count[256];
+ pdq_physaddr_t tx_pa_descriptors;
pdq_uint32_t tx_free;
pdq_uint32_t tx_producer;
pdq_uint32_t tx_completion;
} pdq_tx_info_t;
+typedef struct _pdq_os_ctx_t pdq_os_ctx_t;
struct _pdq_t {
pdq_csrs_t pdq_csrs;
pdq_pci_csrs_t pdq_pci_csrs;
@@ -435,6 +496,7 @@ struct _pdq_t {
pdq_fwrev_t pdq_fwrev;
pdq_descriptor_block_t *pdq_dbp;
volatile pdq_consumer_block_t *pdq_cbp;
+ pdq_uint32_t pdq_intrmask;
pdq_uint32_t pdq_flags;
#define PDQ_PROMISC 0x0001
#define PDQ_ALLMULTI 0x0002
@@ -442,36 +504,27 @@ struct _pdq_t {
#define PDQ_RUNNING 0x0008
#define PDQ_PRINTCHARS 0x0010
#define PDQ_TXOK 0x0020
+#define PDQ_WANT_FDX 0x0040
+#define PDQ_IS_FDX 0x0080
+#define PDQ_IS_ONRING 0x0100
const char *pdq_os_name;
- void *pdq_os_ctx;
+ pdq_os_ctx_t *pdq_os_ctx;
pdq_uint32_t pdq_unit;
pdq_command_info_t pdq_command_info;
pdq_unsolicited_info_t pdq_unsolicited_info;
pdq_tx_info_t pdq_tx_info;
pdq_rx_info_t pdq_rx_info;
pdq_rx_info_t pdq_host_smt_info;
- pdq_uint8_t pdq_tx_hdr[3];
+ void *pdq_receive_buffers[256];
+ void *pdq_host_smt_buffers[64];
+ pdq_physaddr_t pdq_pa_consumer_block;
+ pdq_physaddr_t pdq_pa_descriptor_block;
};
-typedef enum {
- PDQC_START=0,
- PDQC_FILTER_SET=1,
- PDQC_FILTER_GET=2,
- PDQC_CHARS_SET=3,
- PDQC_STATUS_CHARS_GET=4,
- PDQC_COUNTERS_GET=5,
- PDQC_COUNTERS_SET=6,
- PDQC_ADDR_FILTER_SET=7,
- PDQC_ADDR_FILTER_GET=8,
- PDQC_ERROR_LOG_CLEAR=9,
- PDQC_ERROR_LOG_GET=10,
- PDQC_FDDI_MIB_GET=11,
- PDQC_DEC_EXT_MIB_GET=12,
- PDQC_DEV_SPECIFIC_GET=13,
- PDQC_SNMP_SET=14,
- PDQC_SMT_MIB_GET=16,
- PDQC_SMT_MIB_SET=17
-} pdq_cmd_code_t;
+#define PDQ_DB_BUSPA(pdq, m) \
+ ((pdq)->pdq_pa_descriptor_block + \
+ ((u_int8_t *) (m) - (u_int8_t *) (pdq)->pdq_dbp))
+
typedef enum {
PDQR_SUCCESS=0,
@@ -556,6 +609,11 @@ typedef enum {
PDQI_FULL_DUPLEX_ENABLE=44
} pdq_item_code_t;
+typedef enum {
+ PDQSNMP_EOL=0,
+ PDQSNMP_FULL_DUPLEX_ENABLE=0x2F11
+} pdq_snmp_item_code_t;
+
enum _pdq_boolean_t {
PDQ_FALSE=0,
PDQ_TRUE=1
@@ -956,6 +1014,16 @@ typedef struct {
#define PDQ_SIZE_RESPONSE_DEC_EXT_MIB_GET 0x50
+typedef struct {
+ pdq_cmd_code_t snmp_set_op;
+ struct {
+ pdq_item_code_t item_code;
+ pdq_uint32_t item_value;
+ pdq_port_type_t item_port;
+ } snmp_set_items[7];
+ pdq_item_code_t snmp_set_eol_item_code;
+} pdq_cmd_snmp_set_t;
+
typedef enum {
PDQ_CALLER_ID_NONE=0,
PDQ_CALLER_ID_SELFTEST=1,
@@ -994,11 +1062,13 @@ typedef enum {
typedef enum {
PDQ_ENTITY_STATION=0,
PDQ_ENTITY_LINK=1,
- PDQ_ENTITY_PHY_PORT=2
+ PDQ_ENTITY_PHY_PORT=2,
+ PDQ_ENTITY_MAX=3
} pdq_entity_t;
typedef enum {
- PDQ_STATION_EVENT_TRACE_RECEIVED=1
+ PDQ_STATION_EVENT_TRACE_RECEIVED=1,
+ PDQ_STATION_EVENT_MAX=2
} pdq_station_event_t;
typedef enum {
@@ -1022,7 +1092,8 @@ typedef enum {
PDQ_LINK_EVENT_RING_PURGE_ERROR=15,
PDQ_LINK_EVENT_FCI_STRIP_ERROR=16,
PDQ_LINK_EVENT_TRACE_INITIATED=17,
- PDQ_LINK_EVENT_DIRECTED_BEACON_RECEIVED=18
+ PDQ_LINK_EVENT_DIRECTED_BEACON_RECEIVED=18,
+ PDQ_LINK_EVENT_MAX=19
} pdq_link_event_t;
typedef enum {
@@ -1036,7 +1107,8 @@ typedef enum {
typedef enum {
PDQ_PHY_EVENT_LEM_ERROR_MONITOR_REJECT=0,
PDQ_PHY_EVENT_ELASTICITY_BUFFER_ERROR=1,
- PDQ_PHY_EVENT_LINK_CONFIDENCE_TEST_REJECT=2
+ PDQ_PHY_EVENT_LINK_CONFIDENCE_TEST_REJECT=2,
+ PDQ_PHY_EVENT_MAX=3
} pdq_phy_event_t;
typedef enum {
diff --git a/sys/dev/pdq/pdqvar.h b/sys/dev/pdq/pdqvar.h
index 5828047..dc25da5 100644
--- a/sys/dev/pdq/pdqvar.h
+++ b/sys/dev/pdq/pdqvar.h
@@ -1,3 +1,5 @@
+/* $NetBSD: pdqvar.h,v 1.27 2000/05/03 19:17:54 thorpej Exp $ */
+
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
* All rights reserved.
@@ -21,6 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
+ * Id: pdqvar.h,v 1.21 1997/03/21 21:16:04 thomas Exp
* $FreeBSD$
*
*/
@@ -62,13 +65,10 @@ enum _pdq_type_t {
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/lock.h>
#ifndef M_MCAST
#include <sys/mbuf.h>
#endif /* M_CAST */
#include <sys/malloc.h>
-#include <sys/mutex.h>
-
#include <vm/vm.h>
#include <vm/vm_kern.h>
@@ -87,31 +87,31 @@ enum _pdq_type_t {
#endif
#define PDQ_OS_USEC_DELAY(n) DELAY(n)
#define PDQ_OS_MEMZERO(p, n) bzero((caddr_t)(p), (n))
-#if defined(__NetBSD__) && defined(__alpha__)
-#define PDQ_OS_VA_TO_PA(pdq, p) (vtophys((vm_offset_t)p) | (pdq->pdq_type == PDQ_DEFTA ? 0 : 0x40000000))
-#elif defined(__FreeBSD__) && defined(__alpha__)
-#define PDQ_OS_VA_TO_PA(pdq, p) (vtophys((vm_offset_t)p) | (pdq->pdq_type == PDQ_DEFTA ? 0 : alpha_XXX_dmamap_or))
-#else
-#define PDQ_OS_VA_TO_PA(pdq, p) vtophys(p)
+#if defined(__NetBSD__) && !defined(PDQ_NO_BUS_DMA)
+#define PDQ_BUS_DMA
+#endif
+#if !defined(PDQ_BUS_DMA)
+#define PDQ_OS_VA_TO_BUSPA(pdq, p) vtophys(p)
#endif
#define PDQ_OS_MEMALLOC(n) malloc(n, M_DEVBUF, M_NOWAIT)
#define PDQ_OS_MEMFREE(p, n) free((void *) p, M_DEVBUF)
#ifdef __FreeBSD__
#define PDQ_OS_MEMALLOC_CONTIG(n) vm_page_alloc_contig(n, 0, 0xffffffff, PAGE_SIZE)
-#define PDQ_OS_MEMFREE_CONTIG(p, n) kmem_free(kernel_map, (vm_offset_t) p, n)
+#define PDQ_OS_MEMFREE_CONTIG(p, n) kmem_free(kernel_map, (vaddr_t) p, n)
#else
-#define PDQ_OS_MEMALLOC_CONTIG(n) kmem_alloc(kernel_map, round_page(n))
-#define PDQ_OS_MEMFREE_CONTIG(p, n) kmem_free(kernel_map, (vm_offset_t) p, n)
+#if !defined(PDQ_BUS_DMA)
+#define PDQ_OS_MEMALLOC_CONTIG(n) uvm_km_alloc(kernel_map, round_page(n))
+#define PDQ_OS_MEMFREE_CONTIG(p, n) uvm_km_free(kernel_map, (vaddr_t) p, n)
+#endif
#endif /* __FreeBSD__ */
#if defined(__FreeBSD__)
#include <vm/pmap.h>
#include <vm/vm_extern.h>
-#include <machine/bus.h>
#include <machine/cpufunc.h>
#include <machine/clock.h>
-typedef void ifnet_ret_t;
-typedef u_long ioctl_cmd_t;
+#define ifnet_ret_t void
+typedef int ioctl_cmd_t;
typedef enum { PDQ_BUS_EISA, PDQ_BUS_PCI } pdq_bus_t;
typedef u_int16_t pdq_bus_ioport_t;
typedef volatile pdq_uint32_t *pdq_bus_memaddr_t;
@@ -121,10 +121,14 @@ typedef pdq_bus_memaddr_t pdq_bus_memoffset_t;
#define PDQ_BPFATTACH(sc, t, s) bpfattach(&(sc)->sc_if, t, s)
#endif
+#define pdq_os_update_status(a, b) ((void) 0)
#elif defined(__bsdi__)
+#if !defined(PDQ_HWSUPPORT) && (_BSDI_VERSION >= 199701)
+#include <net/if_media.h>
+#endif
#include <machine/inline.h>
-typedef int ifnet_ret_t;
+#define ifnet_ret_t int
typedef int ioctl_cmd_t;
typedef enum { PDQ_BUS_EISA, PDQ_BUS_PCI } pdq_bus_t;
typedef u_int16_t pdq_bus_ioport_t;
@@ -133,36 +137,100 @@ typedef pdq_bus_memaddr_t pdq_bus_memoffset_t;
#elif defined(__NetBSD__)
+#if !defined(PDQ_HWSUPPORT)
+#include <net/if_media.h>
+#endif
#include <machine/bus.h>
#include <machine/intr.h>
+#define PDQ_OS_HDR_OFFSET (PDQ_RX_FC_OFFSET-3)
#define PDQ_OS_PTR_FMT "%p"
-typedef void ifnet_ret_t;
+#define PDQ_OS_CSR_FMT "0x%lx"
+#define ifnet_ret_t void
typedef u_long ioctl_cmd_t;
-typedef bus_chipset_tag_t pdq_bus_t;
-typedef bus_io_handle_t pdq_bus_ioport_t;
-#if defined(PDQ_IOMAPPED)
-typedef bus_io_handle_t pdq_bus_memaddr_t;
-#else
-typedef bus_mem_handle_t pdq_bus_memaddr_t;
-#endif
-typedef pdq_uint32_t pdq_bus_memoffset_t;
+typedef bus_space_tag_t pdq_bus_t;
+typedef bus_space_handle_t pdq_bus_ioport_t;
+typedef bus_space_handle_t pdq_bus_memaddr_t;
+typedef bus_addr_t pdq_bus_memoffset_t;
+#define PDQ_OS_SPL_RAISE() splnet()
#define PDQ_OS_IOMEM
-#define PDQ_OS_IORD_32(t, base, offset) bus_io_read_4 (t, base, offset)
-#define PDQ_OS_IOWR_32(t, base, offset, data) bus_io_write_4 (t, base, offset, data)
-#define PDQ_OS_IORD_8(t, base, offset) bus_io_read_1 (t, base, offset)
-#define PDQ_OS_IOWR_8(t, base, offset, data) bus_io_write_1 (t, base, offset, data)
-#define PDQ_OS_MEMRD_32(t, base, offset) bus_mem_read_4(t, base, offset)
-#define PDQ_OS_MEMWR_32(t, base, offset, data) bus_mem_write_4(t, base, offset, data)
+#define PDQ_OS_IORD_32(t, base, offset) bus_space_read_4 (t, base, offset)
+#define PDQ_OS_IOWR_32(t, base, offset, data) bus_space_write_4 (t, base, offset, data)
+#define PDQ_OS_IORD_8(t, base, offset) bus_space_read_1 (t, base, offset)
+#define PDQ_OS_IOWR_8(t, base, offset, data) bus_space_write_1 (t, base, offset, data)
#define PDQ_CSR_OFFSET(base, offset) (0 + (offset)*sizeof(pdq_uint32_t))
-#if defined(PDQ_IOMAPPED)
+#ifdef PDQ_BUS_DMA
+#define PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, event) \
+ pdq_os_unsolicited_event_sync((pdq)->pdq_os_ctx, \
+ (u_int8_t *) (event) - \
+ (u_int8_t *) (pdq)->pdq_unsolicited_info.ui_events, \
+ sizeof(*event), BUS_DMASYNC_PREREAD)
+#define PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, event) \
+ pdq_os_unsolicited_event_sync((pdq)->pdq_os_ctx, \
+ (u_int8_t *) (event) - \
+ (u_int8_t *) (pdq)->pdq_unsolicited_info.ui_events, \
+ sizeof(*event), BUS_DMASYNC_POSTREAD)
+#define PDQ_OS_DESCBLOCK_SYNC(pdq, what, length, why) \
+ pdq_os_descriptor_block_sync((pdq)->pdq_os_ctx, \
+ (u_int8_t *) (what) - (u_int8_t *) (pdq)->pdq_dbp, \
+ (length), (why))
+#define PDQ_OS_CONSUMER_PRESYNC(pdq) \
+ pdq_os_consumer_block_sync((pdq)->pdq_os_ctx, \
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
+#define PDQ_OS_CONSUMER_POSTSYNC(pdq) \
+ pdq_os_consumer_block_sync((pdq)->pdq_os_ctx, \
+ BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
+#define PDQ_OS_DESC_PRESYNC(pdq, d, s) \
+ PDQ_OS_DESCBLOCK_SYNC((pdq), (d), (s), BUS_DMASYNC_PREWRITE)
+#define PDQ_OS_DESC_POSTSYNC(pdq, d, s) \
+ PDQ_OS_DESCBLOCK_SYNC((pdq), (d), (s), BUS_DMASYNC_POSTWRITE)
+#define PDQ_OS_CMDRQST_PRESYNC(pdq, s) \
+ PDQ_OS_DESCBLOCK_SYNC((pdq), \
+ (pdq)->pdq_command_info.ci_request_bufstart, \
+ (s), BUS_DMASYNC_PREWRITE)
+#define PDQ_OS_CMDRSP_PRESYNC(pdq, s) \
+ PDQ_OS_DESCBLOCK_SYNC((pdq), \
+ (pdq)->pdq_command_info.ci_response_bufstart, \
+ (s), BUS_DMASYNC_PREREAD)
+#define PDQ_OS_CMDRQST_POSTSYNC(pdq, s) \
+ PDQ_OS_DESCBLOCK_SYNC((pdq), \
+ (pdq)->pdq_command_info.ci_request_bufstart, \
+ (s), BUS_DMASYNC_POSTWRITE)
+#define PDQ_OS_CMDRSP_POSTSYNC(pdq, s) \
+ PDQ_OS_DESCBLOCK_SYNC((pdq), \
+ (pdq)->pdq_command_info.ci_response_bufstart, \
+ (s), BUS_DMASYNC_POSTREAD)
+#define PDQ_OS_RXPDU_PRESYNC(pdq, b, o, l) \
+ pdq_os_databuf_sync((pdq)->pdq_os_ctx, (b), (o), (l), \
+ BUS_DMASYNC_PREREAD)
+#define PDQ_OS_RXPDU_POSTSYNC(pdq, b, o, l) \
+ pdq_os_databuf_sync((pdq)->pdq_os_ctx, (b), (o), (l), \
+ BUS_DMASYNC_POSTREAD)
+#define PDQ_OS_DATABUF_ALLOC(pdq, b) ((void)((b) = pdq_os_databuf_alloc((pdq)->pdq_os_ctx)))
+#define PDQ_OS_DATABUF_FREE(pdq, b) pdq_os_databuf_free((pdq)->pdq_os_ctx, (b))
+#define PDQ_OS_DATABUF_BUSPA(pdq, b) (M_GETCTX((b), bus_dmamap_t)->dm_segs[0].ds_addr + 0)
+struct _pdq_os_ctx_t;
+extern void pdq_os_descriptor_block_sync(struct _pdq_os_ctx_t *osctx, size_t offset,
+ size_t length, int ops);
+extern void pdq_os_consumer_block_sync(struct _pdq_os_ctx_t *osctx, int ops);
+extern void pdq_os_unsolicited_event_sync(struct _pdq_os_ctx_t *osctx, size_t offset,
+ size_t length, int ops);
+extern struct mbuf *pdq_os_databuf_alloc(struct _pdq_os_ctx_t *osctx);
+extern void pdq_os_databuf_sync(struct _pdq_os_ctx_t *osctx, struct mbuf *b,
+ size_t offset, size_t length, int ops);
+extern void pdq_os_databuf_free(struct _pdq_os_ctx_t *osctx, struct mbuf *m);
+#define M_HASTXDMAMAP M_LINK1
+#define M_HASRXDMAMAP M_LINK2
+#endif
+
#define PDQ_CSR_WRITE(csr, name, data) PDQ_OS_IOWR_32((csr)->csr_bus, (csr)->csr_base, (csr)->name, data)
#define PDQ_CSR_READ(csr, name) PDQ_OS_IORD_32((csr)->csr_bus, (csr)->csr_base, (csr)->name)
-#else
-#define PDQ_CSR_WRITE(csr, name, data) PDQ_OS_MEMWR_32((csr)->csr_bus, (csr)->csr_base, (csr)->name, data)
-#define PDQ_CSR_READ(csr, name) PDQ_OS_MEMRD_32((csr)->csr_bus, (csr)->csr_base, (csr)->name)
-#endif
+#define PDQ_OS_IFP_TO_SOFTC(ifp) ((pdq_softc_t *) (ifp)->if_softc)
+#define PDQ_ARP_IFINIT(sc, ifa) arp_ifinit(&(sc)->sc_if, (ifa))
+#define PDQ_FDDICOM(sc) (&(sc)->sc_ec)
+#define PDQ_LANADDR(sc) LLADDR((sc)->sc_if.if_sadl)
+#define PDQ_LANADDR_SIZE(sc) ((sc)->sc_if.if_sadl->sdl_alen)
#endif
#if !defined(PDQ_BPF_MTAP)
@@ -173,17 +241,42 @@ typedef pdq_uint32_t pdq_bus_memoffset_t;
#define PDQ_BPFATTACH(sc, t, s) bpfattach(&(sc)->sc_bpf, &(sc)->sc_if, t, s)
#endif
+#if !defined(PDQ_OS_SPL_RAISE)
+#define PDQ_OS_SPL_RAISE() splimp()
+#endif
+
+#if !defined(PDQ_OS_SPL_LOWER)
+#define PDQ_OS_SPL_LOWER(s) splx(s)
+#endif
+
+#if !defined(PDQ_FDDICOM)
+#define PDQ_FDDICOM(sc) (&(sc)->sc_ac)
+#endif
+
+#if !defined(PDQ_ARP_IFINIT)
+#define PDQ_ARP_IFINIT(sc, ifa) arp_ifinit(&(sc)->sc_ac, (ifa))
+#endif
+
#if !defined(PDQ_OS_PTR_FMT)
#define PDQ_OS_PTR_FMT "0x%x"
#endif
+#if !defined(PDQ_OS_CSR_FMT)
+#define PDQ_OS_CSR_FMT "0x%x"
+#endif
+
+#if !defined(PDQ_LANADDR)
+#define PDQ_LANADDR(sc) ((sc)->sc_ac.ac_enaddr)
+#define PDQ_LANADDR_SIZE(sc) (sizeof((sc)->sc_ac.ac_enaddr))
+#endif
+
#if !defined(PDQ_OS_IOMEM)
#define PDQ_OS_IORD_32(t, base, offset) inl((base) + (offset))
#define PDQ_OS_IOWR_32(t, base, offset, data) outl((base) + (offset), data)
#define PDQ_OS_IORD_8(t, base, offset) inb((base) + (offset))
#define PDQ_OS_IOWR_8(t, base, offset, data) outb((base) + (offset), data)
-#define PDQ_OS_MEMRD_32(t, base, offset) readl((base) + (offset))
-#define PDQ_OS_MEMWR_32(t, base, offset, data) writel((base) + (offset), data)
+#define PDQ_OS_MEMRD_32(t, base, offset) (0 + *((base) + (offset)))
+#define PDQ_OS_MEMWR_32(t, base, offset, data) do *((base) + (offset)) = (data); while (0)
#endif
#ifndef PDQ_CSR_OFFSET
#define PDQ_CSR_OFFSET(base, offset) (0 + (base) + (offset))
@@ -194,38 +287,60 @@ typedef pdq_uint32_t pdq_bus_memoffset_t;
#define PDQ_CSR_READ(csr, name) PDQ_OS_MEMRD_32((csr)->csr_bus, (csr)->name, 0)
#endif
+#ifndef PDQ_OS_IFP_TO_SOFTC
+#define PDQ_OS_IFP_TO_SOFTC(ifp) ((pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_ac.ac_if)))
+#endif
+
+
#if !defined(PDQ_HWSUPPORT)
-typedef struct {
+typedef struct _pdq_os_ctx_t {
#if defined(__bsdi__)
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
struct intrhand sc_ih; /* interrupt vectoring */
struct atshutdown sc_ats; /* shutdown routine */
+ struct arpcom sc_ac;
+#define sc_if sc_ac.ac_if
#elif defined(__NetBSD__)
struct device sc_dev; /* base device */
void *sc_ih; /* interrupt vectoring */
void *sc_ats; /* shutdown hook */
+ struct ethercom sc_ec;
+ bus_dma_tag_t sc_dmatag;
+#define sc_if sc_ec.ec_if
#elif defined(__FreeBSD__)
struct kern_devconf *sc_kdc; /* freebsd cruft */
-#endif
struct arpcom sc_ac;
#define sc_if sc_ac.ac_if
+#endif
+#if defined(IFM_FDDI)
+ struct ifmedia sc_ifmedia;
+#endif
pdq_t *sc_pdq;
#if defined(__alpha__) || defined(__i386__)
pdq_bus_ioport_t sc_iobase;
#endif
-#ifdef PDQ_IOMAPPED
+#if defined(PDQ_IOMAPPED) && !defined(__NetBSD__)
#define sc_membase sc_iobase
#else
pdq_bus_memaddr_t sc_membase;
#endif
- pdq_bus_t sc_bc;
+ pdq_bus_t sc_iotag;
+ pdq_bus_t sc_csrtag;
#if !defined(__bsdi__) || _BSDI_VERSION >= 199401
#define sc_bpf sc_if.if_bpf
#else
caddr_t sc_bpf;
#endif
+#if defined(PDQ_BUS_DMA)
+#if !defined(__NetBSD__)
+ bus_dma_tag_t sc_dmatag;
+#endif
+ bus_dmamap_t sc_dbmap; /* DMA map for descriptor block */
+ bus_dmamap_t sc_uimap; /* DMA map for unsolicited events */
+ bus_dmamap_t sc_cbmap; /* DMA map for consumer block */
+#endif
} pdq_softc_t;
@@ -251,7 +366,7 @@ extern void pdq_ifattach(pdq_softc_t *sc, ifnet_ret_t (*ifwatchdog)(int unit));
#define PDQ_OS_PAGESIZE PAGESIZE
#define PDQ_OS_USEC_DELAY(n) drv_usecwait(n)
#define PDQ_OS_MEMZERO(p, n) bzero((caddr_t)(p), (n))
-#define PDQ_OS_VA_TO_PA(pdq, p) vtop((caddr_t)p, NULL)
+#define PDQ_OS_VA_TO_BUSPA(pdq, p) vtop((caddr_t)p, NULL)
#define PDQ_OS_MEMALLOC(n) kmem_zalloc(n, KM_NOSLEEP)
#define PDQ_OS_MEMFREE(p, n) kmem_free((caddr_t) p, n)
#define PDQ_OS_MEMALLOC_CONTIG(n) kmem_zalloc_physreq(n, decfddiphysreq_db, KM_NOSLEEP)
@@ -260,7 +375,7 @@ extern void pdq_ifattach(pdq_softc_t *sc, ifnet_ret_t (*ifwatchdog)(int unit));
extern physreq_t *decfddiphysreq_db;
extern physreq_t *decfddiphysreq_mblk;
-#define PDQ_OS_DATABUF_ALLOC(b) ((void) (((b) = allocb_physreq(PDQ_OS_DATABUF_SIZE, BPRI_MED, decfddiphysreq_mblk)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
+#define PDQ_OS_DATABUF_ALLOC(pdq, b) ((void) (((b) = allocb_physreq(PDQ_OS_DATABUF_SIZE, BPRI_MED, decfddiphysreq_mblk)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
#define PDQ_OS_IORD_8(port) inb(port)
#define PDQ_OS_IOWR_8(port, data) outb(port, data)
@@ -269,7 +384,9 @@ extern physreq_t *decfddiphysreq_mblk;
#ifdef PDQ_USE_MBUFS
#define PDQ_OS_DATABUF_SIZE (MCLBYTES)
-#define PDQ_OS_DATABUF_FREE(b) (m_freem(b))
+#ifndef PDQ_OS_DATABUF_FREE
+#define PDQ_OS_DATABUF_FREE(pdq, b) (m_freem(b))
+#endif
#define PDQ_OS_DATABUF_NEXT(b) ((b)->m_next)
#define PDQ_OS_DATABUF_NEXT_SET(b, b1) ((b)->m_next = (b1))
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->m_nextpkt)
@@ -281,7 +398,8 @@ extern physreq_t *decfddiphysreq_mblk;
#define PDQ_OS_DATABUF_ADJ(b, n) ((b)->m_data += (n), (b)->m_len -= (n))
typedef struct mbuf PDQ_OS_DATABUF_T;
-#define PDQ_OS_DATABUF_ALLOC(b) do { \
+#ifndef PDQ_OS_DATABUF_ALLOC
+#define PDQ_OS_DATABUF_ALLOC(pdq, b) do { \
PDQ_OS_DATABUF_T *x_m0; \
MGETHDR(x_m0, M_DONTWAIT, MT_DATA); \
if (x_m0 != NULL) { \
@@ -297,12 +415,13 @@ typedef struct mbuf PDQ_OS_DATABUF_T;
(b) = NULL; \
} \
} while (0)
+#endif
#define PDQ_OS_DATABUF_RESET(b) ((b)->m_data = (b)->m_ext.ext_buf, (b)->m_len = MCLBYTES)
#endif /* PDQ_USE_MBUFS */
#ifdef PDQ_USE_STREAMS
#define PDQ_OS_DATABUF_SIZE (2048)
-#define PDQ_OS_DATABUF_FREE(b) (freemsg(b))
+#define PDQ_OS_DATABUF_FREE(pdq, b) (freemsg(b))
#define PDQ_OS_DATABUF_NEXT(b) ((b)->b_cont)
#define PDQ_OS_DATABUF_NEXT_SET(b, b1) ((b)->b_cont = (b1))
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->b_next)
@@ -315,7 +434,7 @@ typedef struct mbuf PDQ_OS_DATABUF_T;
typedef mblk_t PDQ_OS_DATABUF_T;
#ifndef PDQ_OS_DATABUF_ALLOC
-#define PDQ_OS_DATABUF_ALLOC(b) ((void) (((b) = allocb(PDQ_OS_DATABUF_SIZE, BPRI_MED)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
+#define PDQ_OS_DATABUF_ALLOC(pdq, b) ((void) (((b) = allocb(PDQ_OS_DATABUF_SIZE, BPRI_MED)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
#endif /* PDQ_OS_DATABUF_ALLOC */
#endif /* PDQ_USE_STREAMS */
@@ -338,11 +457,39 @@ typedef mblk_t PDQ_OS_DATABUF_T;
} \
} while (0)
+#if !defined(PDQ_OS_CONSUMER_PRESYNC)
+#define PDQ_OS_CONSUMER_PRESYNC(pdq) do { } while(0)
+#define PDQ_OS_CONSUMER_POSTSYNC(pdq) do { } while(0)
+#define PDQ_OS_DESC_PRESYNC(pdq, d, s) do { } while(0)
+#define PDQ_OS_DESC_POSTSYNC(pdq, d, s) do { } while(0)
+#define PDQ_OS_CMDRQST_PRESYNC(pdq, s) do { } while(0)
+#define PDQ_OS_CMDRQST_POSTSYNC(pdq, s) do { } while(0)
+#define PDQ_OS_CMDRSP_PRESYNC(pdq, s) do { } while(0)
+#define PDQ_OS_CMDRSP_POSTSYNC(pdq, s) do { } while(0)
+#define PDQ_OS_RXPDU_PRESYNC(pdq, b, o, l) do { } while(0)
+#define PDQ_OS_RXPDU_POSTSYNC(pdq, b, o, l) do { } while(0)
+#define PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, e) do { } while(0)
+#define PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, e) do { } while(0)
+#endif
+
+#ifndef PDQ_OS_DATABUF_BUSPA
+#define PDQ_OS_DATABUF_BUSPA(pdq, b) PDQ_OS_VA_TO_BUSPA(pdq, PDQ_OS_DATABUF_PTR(b))
+#endif
+
+#ifndef PDQ_OS_HDR_OFFSET
+#define PDQ_OS_HDR_OFFSET PDQ_RX_FC_OFFSET
+#endif
+
extern void pdq_os_addr_fill(pdq_t *pdq, pdq_lanaddr_t *addrs, size_t numaddrs);
-extern void pdq_os_receive_pdu(pdq_t *, PDQ_OS_DATABUF_T *pdu, size_t pdulen);
+extern void pdq_os_receive_pdu(pdq_t *, PDQ_OS_DATABUF_T *pdu, size_t pdulen, int drop);
extern void pdq_os_restart_transmitter(pdq_t *pdq);
extern void pdq_os_transmit_done(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
-
+#if !defined(pdq_os_update_status)
+extern void pdq_os_update_status(pdq_t *pdq, const void *rsp);
+#endif
+#if !defined(PDQ_OS_MEMALLOC_CONTIG)
+extern int pdq_os_memalloc_contig(pdq_t *pdq);
+#endif
extern pdq_boolean_t pdq_queue_transmit_data(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
extern void pdq_flush_transmitter(pdq_t *pdq);
diff --git a/sys/net/fddi.h b/sys/net/fddi.h
index 7d69ce7..82c1a13 100644
--- a/sys/net/fddi.h
+++ b/sys/net/fddi.h
@@ -97,11 +97,9 @@ struct fddi_header {
#define FDDI_BPF_UNSUPPORTED 0
#define FDDI_BPF_SUPPORTED 1
-void fddi_ifattach(struct ifnet *);
+void fddi_ifattach(struct ifnet *, int);
void fddi_ifdetach(struct ifnet *, int);
void fddi_input(struct ifnet *, struct fddi_header *, struct mbuf *);
-int fddi_output(struct ifnet *, struct mbuf *, struct sockaddr *,
- struct rtentry *);
int fddi_ioctl(struct ifnet *, int, caddr_t);
#endif /* _KERNEL */
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index 642e625..126cf92 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -94,8 +94,11 @@ extern u_char aarp_org_code[ 3 ];
static u_char fddibroadcastaddr[FDDI_ADDR_LEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-static int fddi_resolvemulti(struct ifnet *, struct sockaddr **,
+static int fddi_resolvemulti(struct ifnet *, struct sockaddr **,
struct sockaddr *);
+static int fddi_output(struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *);
+
#define IFP2AC(IFP) ((struct arpcom *)IFP)
#define senderr(e) { error = (e); goto bad; }
@@ -107,7 +110,7 @@ static int fddi_resolvemulti(struct ifnet *, struct sockaddr **,
* packet leaves a multiple of 512 bytes of data in remainder.
* Assumes that ifp is actually pointer to arpcom structure.
*/
-int
+static int
fddi_output(ifp, m, dst, rt0)
struct ifnet *ifp;
struct mbuf *m;
@@ -519,8 +522,9 @@ dropanyway:
* Perform common duties while attaching to interface list
*/
void
-fddi_ifattach(ifp)
+fddi_ifattach(ifp, bpf)
struct ifnet *ifp;
+ int bpf;
{
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
@@ -551,6 +555,9 @@ fddi_ifattach(ifp)
sdl->sdl_alen = ifp->if_addrlen;
bcopy(IFP2AC(ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
+ if (bpf)
+ bpfattach(ifp, DLT_FDDI, FDDI_HDR_LEN);
+
return;
}
OpenPOWER on IntegriCloud