mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
- 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.
This commit is contained in:
parent
c772c98600
commit
0e93a9b535
9 changed files with 1712 additions and 527 deletions
|
|
@ -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;
|
||||
pdq_softc_t * sc;
|
||||
struct ifnet * ifp;
|
||||
int error;
|
||||
|
||||
rid = 0;
|
||||
io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
sc = device_get_softc(dev);
|
||||
ifp = &sc->arpcom.ac_if;
|
||||
|
||||
if (!io) {
|
||||
device_printf(dev, "No I/O space?!\n");
|
||||
goto bad;
|
||||
}
|
||||
sc->dev = dev;
|
||||
|
||||
rid = 0;
|
||||
mspace = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
|
||||
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;
|
||||
}
|
||||
sc->io_bsh = rman_get_bushandle(sc->io);
|
||||
sc->io_bst = rman_get_bustag(sc->io);
|
||||
|
||||
if (!mspace) {
|
||||
device_printf(dev, "No memory space?!\n");
|
||||
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;
|
||||
}
|
||||
|
||||
rid = 0;
|
||||
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
|
||||
if (!irq) {
|
||||
device_printf(dev, "No, irq?!\n");
|
||||
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);
|
||||
pdq_free(dev);
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
data = pci_read_config(dev, PCIR_LATTIMER, 1);
|
||||
if (data < DEFPA_LATENCY) {
|
||||
data = DEFPA_LATENCY;
|
||||
pci_write_config(dev, PCIR_LATTIMER, data, 1);
|
||||
sc->dev = dev;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
goto bad;
|
||||
if (bus_setup_intr(dev, irqres, INTR_TYPE_NET, pdq_pci_ifintr,
|
||||
(void *)dev, &ih))
|
||||
goto bad;
|
||||
return 0;
|
||||
command = pci_read_config(dev, PCIR_LATTIMER, 1);
|
||||
if (command < DEFPA_LATENCY) {
|
||||
command = DEFPA_LATENCY;
|
||||
pci_write_config(dev, PCIR_LATTIMER, command, 1);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
dbp = pdq->pdq_dbp;
|
||||
|
||||
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));
|
||||
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];
|
||||
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_bufstart;
|
||||
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];
|
||||
PDQ_OS_DESC_PRESYNC(pdq, dbp->pdqdb_command_requests,
|
||||
sizeof(dbp->pdqdb_command_requests));
|
||||
|
||||
rxd->rxd_pa_lo = pdq->pdq_command_info.ci_pa_bufstart;
|
||||
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]));
|
||||
|
|
|
|||
271
sys/dev/pdq/pdq_freebsd.h
Normal file
271
sys/dev/pdq/pdq_freebsd.h
Normal file
|
|
@ -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);
|
||||
|
|
@ -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)
|
||||
*/
|
||||
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#if defined(__bsdi__) || defined(__NetBSD__)
|
||||
#include <sys/device.h>
|
||||
#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
|
||||
|
||||
#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>
|
||||
|
||||
#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 */
|
||||
devclass_t pdq_devclass;
|
||||
|
||||
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
|
||||
|
||||
|
||||
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 (pdq_queue_transmit_data(sc->sc_pdq, m) == PDQ_FALSE) {
|
||||
ifp->if_flags |= IFF_OACTIVE;
|
||||
IF_PREPEND(ifq, m);
|
||||
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)
|
||||
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;
|
||||
|
||||
#if defined(SIOCSIFMTU)
|
||||
#if !defined(ifr_mtu)
|
||||
#define ifr_mtu ifr_metric
|
||||
#endif
|
||||
case SIOCSIFMTU: {
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
/*
|
||||
* Set the interface MTU.
|
||||
*/
|
||||
if (ifr->ifr_mtu > FDDIMTU) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
break;
|
||||
}
|
||||
#endif /* SIOCSIFMTU */
|
||||
|
||||
#if defined(IFM_FDDI) && defined(SIOCSIFMEDIA)
|
||||
case SIOCSIFMEDIA:
|
||||
case SIOCGIFMEDIA: {
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
|
||||
break;
|
||||
}
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
#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)
|
||||
#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)
|
||||
|
||||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue