Have a function pointer to the routine to call for writing an mbuf

into the card's memory.

# this eliminates a more of the ifdef soup in if_ed and if_edvar

# I've fixed the cbus drivers, but can't test them all easily.

If I've broken anything, please let me know.
This commit is contained in:
Warner Losh 2006-01-27 19:10:13 +00:00
parent 4591afafab
commit 96ba6a6eb2
9 changed files with 109 additions and 100 deletions

View File

@ -87,8 +87,6 @@ static __inline void ed_rint(struct ed_softc *);
static __inline void ed_xmit(struct ed_softc *);
static __inline void ed_ring_copy(struct ed_softc *, bus_size_t, char *,
u_short);
static u_short ed_pio_write_mbufs(struct ed_softc *, struct mbuf *,
bus_size_t);
static void ed_setrcr(struct ed_softc *);
@ -276,7 +274,11 @@ ed_attach(device_t dev)
sc->readmem = ed_pio_readmem;
}
}
if (sc->sc_write_mbufs == NULL) {
device_printf(dev, "No write mbufs routine set\n");
return (ENXIO);
}
callout_init_mtx(&sc->tick_ch, ED_MUTEX(sc), 0);
/*
* Set interface to stopped condition (reset)
@ -711,77 +713,10 @@ outloop:
/* txb_new points to next open buffer slot */
buffer = sc->mem_start + (sc->txb_new * ED_TXBUF_SIZE * ED_PAGE_SIZE);
if (sc->mem_shared) {
/*
* Special case setup for 16 bit boards...
*/
if (sc->isa16bit) {
switch (sc->vendor) {
#ifdef ED_3C503
/*
* For 16bit 3Com boards (which have 16k of
* memory), we have the xmit buffers in a
* different page of memory ('page 0') - so
* change pages.
*/
case ED_VENDOR_3COM:
ed_asic_outb(sc, ED_3COM_GACFR,
ED_3COM_GACFR_RSEL);
break;
#endif
/*
* Enable 16bit access to shared memory on
* WD/SMC boards.
*
* XXX - same as ed_enable_16bit_access()
*/
case ED_VENDOR_WD_SMC:
ed_asic_outb(sc, ED_WD_LAAR,
sc->wd_laar_proto | ED_WD_LAAR_M16EN);
if (sc->chip_type == ED_CHIP_TYPE_WD790)
ed_asic_outb(sc, ED_WD_MSR, ED_WD_MSR_MENB);
break;
}
}
for (len = 0; m != 0; m = m->m_next) {
if (sc->isa16bit)
bus_space_write_region_2(sc->mem_bst,
sc->mem_bsh, buffer,
mtod(m, uint16_t *), (m->m_len + 1)/ 2);
else
bus_space_write_region_1(sc->mem_bst,
sc->mem_bsh, buffer,
mtod(m, uint8_t *), m->m_len);
buffer += m->m_len;
len += m->m_len;
}
/*
* Restore previous shared memory access
*/
if (sc->isa16bit) {
switch (sc->vendor) {
#ifdef ED_3C503
case ED_VENDOR_3COM:
ed_asic_outb(sc, ED_3COM_GACFR,
ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
break;
#endif
case ED_VENDOR_WD_SMC:
/* XXX - same as ed_disable_16bit_access() */
if (sc->chip_type == ED_CHIP_TYPE_WD790)
ed_asic_outb(sc, ED_WD_MSR, 0x00);
ed_asic_outb(sc, ED_WD_LAAR,
sc->wd_laar_proto & ~ED_WD_LAAR_M16EN);
break;
}
}
} else {
len = ed_pio_write_mbufs(sc, m, buffer);
if (len == 0) {
m_freem(m0);
goto outloop;
}
len = sc->sc_write_mbufs(sc, m, buffer);
if (len == 0) {
m_freem(m0);
goto outloop;
}
sc->txb_len[sc->txb_new] = max(len, (ETHER_MIN_LEN-ETHER_CRC_LEN));
@ -1457,7 +1392,7 @@ ed_pio_writemem(struct ed_softc *sc, uint8_t *src, uint16_t dst, uint16_t len)
* Write an mbuf chain to the destination NIC memory address using
* programmed I/O.
*/
static u_short
u_short
ed_pio_write_mbufs(struct ed_softc *sc, struct mbuf *m, bus_size_t dst)
{
struct ifnet *ifp = sc->ifp;
@ -1467,12 +1402,6 @@ ed_pio_write_mbufs(struct ed_softc *sc, struct mbuf *m, bus_size_t dst)
ED_ASSERT_LOCKED(sc);
#ifdef ED_HPP
/* HP PC Lan+ cards need special handling */
if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS)
return ed_hpp_write_mbufs(sc, m, dst);
#endif
/* Regular Novell cards */
/* First, count up the total number of bytes to copy */
for (total_len = 0, mp = m; mp; mp = mp->m_next)
@ -1708,3 +1637,74 @@ ed_clear_memory(device_t dev)
}
return (0);
}
u_short
ed_shmem_write_mbufs(struct ed_softc *sc, struct mbuf *m, bus_size_t dst)
{
u_short len;
/*
* Special case setup for 16 bit boards...
*/
if (sc->isa16bit) {
switch (sc->vendor) {
#ifdef ED_3C503
/*
* For 16bit 3Com boards (which have 16k of
* memory), we have the xmit buffers in a
* different page of memory ('page 0') - so
* change pages.
*/
case ED_VENDOR_3COM:
ed_asic_outb(sc, ED_3COM_GACFR, ED_3COM_GACFR_RSEL);
break;
#endif
/*
* Enable 16bit access to shared memory on
* WD/SMC boards.
*
* XXX - same as ed_enable_16bit_access()
*/
case ED_VENDOR_WD_SMC:
ed_asic_outb(sc, ED_WD_LAAR,
sc->wd_laar_proto | ED_WD_LAAR_M16EN);
if (sc->chip_type == ED_CHIP_TYPE_WD790)
ed_asic_outb(sc, ED_WD_MSR, ED_WD_MSR_MENB);
break;
}
}
for (len = 0; m != 0; m = m->m_next) {
if (sc->isa16bit)
bus_space_write_region_2(sc->mem_bst,
sc->mem_bsh, dst,
mtod(m, uint16_t *), (m->m_len + 1)/ 2);
else
bus_space_write_region_1(sc->mem_bst,
sc->mem_bsh, dst,
mtod(m, uint8_t *), m->m_len);
dst += m->m_len;
len += m->m_len;
}
/*
* Restore previous shared memory access
*/
if (sc->isa16bit) {
switch (sc->vendor) {
#ifdef ED_3C503
case ED_VENDOR_3COM:
ed_asic_outb(sc, ED_3COM_GACFR,
ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
break;
#endif
case ED_VENDOR_WD_SMC:
/* XXX - same as ed_disable_16bit_access() */
if (sc->chip_type == ED_CHIP_TYPE_WD790)
ed_asic_outb(sc, ED_WD_MSR, 0x00);
ed_asic_outb(sc, ED_WD_LAAR,
sc->wd_laar_proto & ~ED_WD_LAAR_M16EN);
break;
}
}
return (len);
}

View File

@ -325,7 +325,7 @@ ed_probe_3Com(device_t dev, int port_rid, int flags)
* mem.
*/
ed_asic_outb(sc, ED_3COM_GACFR, ED_3COM_GACFR_RSEL |
ED_3COM_GACFR_MBS0);
ED_3COM_GACFR_MBS0);
/*
* Initialize "Vector Pointer" registers. These gawd-awful things are
@ -338,8 +338,10 @@ ed_probe_3Com(device_t dev, int port_rid, int flags)
ed_asic_outb(sc, ED_3COM_VPTR0, 0x00);
error = ed_clear_memory(dev);
if (error == 0)
if (error == 0) {
sc->sc_mediachg = ed_3c503_mediachg;
sc->sc_write_mbufs = ed_shmem_write_mbufs;
}
return (error);
}

View File

@ -54,13 +54,13 @@
static int ed98_alloc_port(device_t, int);
static int ed98_alloc_memory(device_t, int);
static int ed_pio_testmem(struct ed_softc *, int, int, int);
static int ed_probe_SIC98(device_t, int, int);
static int ed_probe_CNET98(device_t, int, int);
static int ed_probe_CNET98EL(device_t, int, int);
static int ed_probe_EZ98(device_t, int, int);
static int ed_probe_NEC77(device_t, int, int);
static int ed_probe_NW98X(device_t, int, int);
static int ed_probe_SB98(device_t, int, int);
static int ed_probe_EZ98(device_t, int, int);
static int ed_probe_SIC98(device_t, int, int);
static int ed98_probe_Novell(device_t, int, int);
static int ed98_probe_generic8390(struct ed_softc *);
static void ed_reset_CNET98(struct ed_softc *, int);
@ -788,6 +788,7 @@ ed98_probe_Novell(device_t dev, int port_rid, int flags)
/* clear any pending interrupts that might have occurred above */
ed_nic_outb(sc, ED_P0_ISR, 0xff);
sc->sc_write_mbufs = ed_pio_write_mbufs;
return (0);
}
@ -888,6 +889,7 @@ ed_probe_SIC98(device_t dev, int port_rid, int flags)
sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
sc->sc_write_mbufs = ed_shmem_write_mbufs;
return (0);
}
@ -1137,6 +1139,7 @@ ed_probe_CNET98(device_t dev, int port_rid, int flags)
ed_asic_outb(sc, ED_CNET98_INT_MASK, 0x7e);
DELAY(1000);
sc->sc_write_mbufs = ed_shmem_write_mbufs;
return (0);
}
@ -1231,6 +1234,7 @@ ed_probe_CNET98EL(device_t dev, int port_rid, int flags)
/* clear any pending interrupts that might have occurred above */
ed_nic_outb(sc, ED_P0_ISR, 0xff);
sc->sc_write_mbufs = ed_pio_write_mbufs;
return (0);
}
@ -1498,9 +1502,8 @@ ed_probe_SB98(device_t dev, int port_rid, int flags)
/* Test memory via PIO */
sc->cr_proto = ED_CR_RD2;
if (!ed_pio_testmem(sc, 16384, 1, flags)) {
if (!ed_pio_testmem(sc, 16384, 1, flags))
return (ENXIO);
}
/* This looks like an SB9801 board. */
sc->type_str = "SB9801";
@ -1511,6 +1514,7 @@ ed_probe_SB98(device_t dev, int port_rid, int flags)
/* clear any pending interrupts that might have occurred above */
ed_nic_outb(sc, ED_P0_ISR, 0xff);
sc->sc_write_mbufs = ed_pio_write_mbufs;
return (0);
}

View File

@ -60,9 +60,13 @@ __FBSDID("$FreeBSD$");
#include <dev/ed/if_edreg.h>
#include <dev/ed/if_edvar.h>
static void ed_hpp_readmem(struct ed_softc *, bus_size_t, uint8_t *,
uint16_t);
static void ed_hpp_writemem(struct ed_softc *, uint8_t *, uint16_t,
uint16_t);
static void ed_hpp_set_physical_link(struct ed_softc *sc);
static u_short ed_hpp_write_mbufs(struct ed_softc *, struct mbuf *,
bus_size_t);
/*
* Interrupt conversion table for the HP PC LAN+
@ -357,6 +361,8 @@ ed_probe_HP_pclanp(device_t dev, int port_rid, int flags)
}
sc->sc_mediachg = ed_hpp_set_physical_link;
sc->sc_write_mbufs = ed_hpp_write_mbufs;
sc->readmem = ed_hpp_readmem;
return (0);
}
@ -411,7 +417,7 @@ ed_hpp_set_physical_link(struct ed_softc *sc)
* IO.
*/
void
static void
ed_hpp_readmem(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
uint16_t amount)
{
@ -547,8 +553,8 @@ ed_hpp_writemem(struct ed_softc *sc, uint8_t *src, uint16_t dst, uint16_t len)
* allows it.
*/
u_short
ed_hpp_write_mbufs(struct ed_softc *sc, struct mbuf *m, int dst)
static u_short
ed_hpp_write_mbufs(struct ed_softc *sc, struct mbuf *m, bus_size_t dst)
{
int len, wantbyte;
unsigned short total_len;

View File

@ -82,6 +82,7 @@ ed_isa_probe_Novell(device_t dev)
/*
* Final sanity check for Gateway Ethernet cards before
* believing that they really are Gateway AT.
* XXX I think this is stale.
*/
if ((ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) &&
(sc->enaddr[2] == 0x86)) {
@ -175,10 +176,6 @@ ed_isa_attach(device_t dev)
return (error);
}
#ifdef ED_HPP
if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS)
sc->readmem = ed_hpp_readmem;
#endif
return ed_attach(dev);
}

View File

@ -192,6 +192,7 @@ ed_probe_Novell_generic(device_t dev, int flags)
/* clear any pending interrupts that might have occurred above */
ed_nic_outb(sc, ED_P0_ISR, 0xff);
sc->sc_write_mbufs = ed_pio_write_mbufs;
return (0);
}

View File

@ -150,6 +150,7 @@ ed_probe_SIC(device_t dev, int port_rid, int flags)
sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
sc->sc_write_mbufs = ed_shmem_write_mbufs;
return (0);
}

View File

@ -428,6 +428,7 @@ ed_probe_WD80x3_generic(device_t dev, int flags, uint16_t *intr_vals[])
*/
error = ed_clear_memory(dev);
ed_disable_16bit_access(sc);
sc->sc_write_mbufs = ed_shmem_write_mbufs;
return (error);
}

View File

@ -71,6 +71,7 @@ struct ed_softc {
void (*sc_tick)(void *);
void (*readmem)(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
uint16_t amount);
u_short (*sc_write_mbufs)(struct ed_softc *, struct mbuf *, bus_size_t);
int nic_offset; /* NIC (DS8390) I/O bus address offset */
int asic_offset; /* ASIC I/O bus address offset */
@ -215,14 +216,10 @@ int ed_isa_mem_ok(device_t, u_long, u_int); /* XXX isa specific */
void ed_stop(struct ed_softc *);
void ed_shmem_readmem16(struct ed_softc *, bus_size_t, uint8_t *, uint16_t);
void ed_shmem_readmem8(struct ed_softc *, bus_size_t, uint8_t *, uint16_t);
u_short ed_shmem_write_mbufs(struct ed_softc *, struct mbuf *, bus_size_t);
void ed_pio_readmem(struct ed_softc *, bus_size_t, uint8_t *, uint16_t);
void ed_pio_writemem(struct ed_softc *, uint8_t *, uint16_t, uint16_t);
/* The following is unsatisfying XXX */
#ifdef ED_HPP
void ed_hpp_readmem(struct ed_softc *, bus_size_t, uint8_t *, uint16_t);
u_short ed_hpp_write_mbufs(struct ed_softc *, struct mbuf *, int);
#endif
u_short ed_pio_write_mbufs(struct ed_softc *, struct mbuf *, bus_size_t);
void ed_disable_16bit_access(struct ed_softc *);
void ed_enable_16bit_access(struct ed_softc *);