Finish conversion to bus space and make ed MP safe.
o Lock ed o Fix extra newline in probe messages o Eliminate gone. o Make detach less-racy. o Eliminate spl* o Switch from timeout/untimeout to callout interface. o Read/write card memory using bus_space calls. o generalize readmem so that we don't need ifs in the code. o Fix memory stuff to be consistant. o Remove OLDCARD compat stuff. o Mark interrupt as MPSAFE. # sic, hpp not tested at all # ISA and PCI attachments lightly tested
This commit is contained in:
parent
3041058fad
commit
0a15fd3fab
@ -28,6 +28,11 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* o lock MII
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
|
||||
* adapters. By David Greenman, 29-April-1993
|
||||
@ -71,12 +76,15 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/ed/if_edreg.h>
|
||||
#include <dev/ed/if_edvar.h>
|
||||
#include <sys/kdb.h>
|
||||
|
||||
devclass_t ed_devclass;
|
||||
|
||||
static void ed_init(void *);
|
||||
static void ed_init_locked(struct ed_softc *);
|
||||
static int ed_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static void ed_start(struct ifnet *);
|
||||
static void ed_start_locked(struct ifnet *);
|
||||
static void ed_reset(struct ifnet *);
|
||||
static void ed_watchdog(struct ifnet *);
|
||||
#ifndef ED_NO_MIIBUS
|
||||
@ -85,12 +93,15 @@ static void ed_tick(void *);
|
||||
|
||||
static void ed_ds_getmcaf(struct ed_softc *, uint32_t *);
|
||||
|
||||
static void ed_get_packet(struct ed_softc *, char *, u_short);
|
||||
static void ed_get_packet(struct ed_softc *, bus_size_t, u_short);
|
||||
static void ed_stop_hw(struct ed_softc *sc);
|
||||
|
||||
static __inline void ed_rint(struct ed_softc *);
|
||||
static __inline void ed_xmit(struct ed_softc *);
|
||||
static __inline char *ed_ring_copy(struct ed_softc *, char *, char *, u_short);
|
||||
static u_short ed_pio_write_mbufs(struct ed_softc *, struct mbuf *, long);
|
||||
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 *);
|
||||
|
||||
@ -257,17 +268,31 @@ ed_attach(device_t dev)
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc->dev = dev;
|
||||
ED_LOCK_INIT(sc);
|
||||
ifp = sc->ifp = if_alloc(IFT_ETHER);
|
||||
if (ifp == NULL) {
|
||||
device_printf(dev, "can not if_alloc()\n");
|
||||
ED_LOCK_DESTROY(sc);
|
||||
return (ENOSPC);
|
||||
}
|
||||
|
||||
callout_handle_init(&sc->tick_ch);
|
||||
if (sc->readmem == NULL) {
|
||||
if (sc->mem_shared) {
|
||||
if (sc->isa16bit)
|
||||
sc->readmem = ed_shmem_readmem16;
|
||||
else
|
||||
sc->readmem = ed_shmem_readmem8;
|
||||
} else {
|
||||
sc->readmem = ed_pio_readmem;
|
||||
}
|
||||
}
|
||||
|
||||
callout_init_mtx(&sc->tick_ch, ED_MUTEX(sc), 0);
|
||||
/*
|
||||
* Set interface to stopped condition (reset)
|
||||
*/
|
||||
ed_stop(sc);
|
||||
ed_stop_hw(sc);
|
||||
|
||||
/*
|
||||
* Initialize ifnet structure
|
||||
@ -298,15 +323,11 @@ ed_attach(device_t dev)
|
||||
|
||||
/*
|
||||
* Set default state for ALTPHYS flag (used to disable the
|
||||
* tranceiver for AUI operation), based on compile-time
|
||||
* config option.
|
||||
* tranceiver for AUI operation), based on config option.
|
||||
*/
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
if (device_get_flags(dev) & ED_FLAGS_DISABLE_TRANCEIVER)
|
||||
ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX |
|
||||
IFF_MULTICAST | IFF_ALTPHYS | IFF_NEEDSGIANT);
|
||||
else
|
||||
ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX |
|
||||
IFF_MULTICAST | IFF_NEEDSGIANT);
|
||||
ifp->if_flags |= IFF_ALTPHYS;
|
||||
|
||||
/*
|
||||
* Attach the interface
|
||||
@ -331,7 +352,7 @@ ed_attach(device_t dev)
|
||||
printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)");
|
||||
|
||||
#if defined(ED_HPP) || defined(ED_3C503)
|
||||
printf("%s\n", (((sc->vendor == ED_VENDOR_3COM) ||
|
||||
printf("%s", (((sc->vendor == ED_VENDOR_3COM) ||
|
||||
(sc->vendor == ED_VENDOR_HP)) &&
|
||||
(ifp->if_flags & IFF_ALTPHYS)) ?
|
||||
" tranceiver disabled" : "");
|
||||
@ -350,15 +371,18 @@ ed_detach(device_t dev)
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
|
||||
if (sc->gone)
|
||||
return (0);
|
||||
ed_stop(sc);
|
||||
ED_ASSERT_UNLOCKED(sc);
|
||||
ED_LOCK(sc);
|
||||
if (bus_child_present(dev))
|
||||
ed_stop(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
ED_UNLOCK(sc);
|
||||
callout_drain(&sc->tick_ch);
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
sc->gone = 1;
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
|
||||
ed_release_resources(dev);
|
||||
ED_LOCK_DESTROY(sc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -369,35 +393,20 @@ static void
|
||||
ed_reset(struct ifnet *ifp)
|
||||
{
|
||||
struct ed_softc *sc = ifp->if_softc;
|
||||
int s;
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
s = splimp();
|
||||
|
||||
ED_ASSERT_LOCKED(sc);
|
||||
/*
|
||||
* Stop interface and re-initialize.
|
||||
*/
|
||||
ed_stop(sc);
|
||||
ed_init(sc);
|
||||
|
||||
(void) splx(s);
|
||||
ed_init_locked(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take interface offline.
|
||||
*/
|
||||
void
|
||||
ed_stop(struct ed_softc *sc)
|
||||
static void
|
||||
ed_stop_hw(struct ed_softc *sc)
|
||||
{
|
||||
int n = 5000;
|
||||
|
||||
#ifndef ED_NO_MIIBUS
|
||||
untimeout(ed_tick, sc, sc->tick_ch);
|
||||
callout_handle_init(&sc->tick_ch);
|
||||
#endif
|
||||
if (sc->gone)
|
||||
return;
|
||||
/*
|
||||
* Stop everything on the interface, and select page 0 registers.
|
||||
*/
|
||||
@ -413,6 +422,19 @@ ed_stop(struct ed_softc *sc)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Take interface offline.
|
||||
*/
|
||||
void
|
||||
ed_stop(struct ed_softc *sc)
|
||||
{
|
||||
ED_ASSERT_LOCKED(sc);
|
||||
#ifndef ED_NO_MIIBUS
|
||||
callout_stop(&sc->tick_ch);
|
||||
#endif
|
||||
ed_stop_hw(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Device timeout/watchdog routine. Entered if the device neglects to
|
||||
* generate an interrupt after a transmit has been started on it.
|
||||
@ -422,12 +444,12 @@ ed_watchdog(struct ifnet *ifp)
|
||||
{
|
||||
struct ed_softc *sc = ifp->if_softc;
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
|
||||
ifp->if_oerrors++;
|
||||
|
||||
ED_LOCK(sc);
|
||||
ed_reset(ifp);
|
||||
ED_UNLOCK(sc);
|
||||
}
|
||||
|
||||
#ifndef ED_NO_MIIBUS
|
||||
@ -436,19 +458,13 @@ ed_tick(void *arg)
|
||||
{
|
||||
struct ed_softc *sc = arg;
|
||||
struct mii_data *mii;
|
||||
int s;
|
||||
|
||||
if (sc->gone) {
|
||||
callout_handle_init(&sc->tick_ch);
|
||||
return;
|
||||
}
|
||||
s = splimp();
|
||||
ED_ASSERT_LOCKED(sc);
|
||||
if (sc->miibus != NULL) {
|
||||
mii = device_get_softc(sc->miibus);
|
||||
mii_tick(mii);
|
||||
}
|
||||
sc->tick_ch = timeout(ed_tick, sc, hz);
|
||||
splx(s);
|
||||
callout_reset(&sc->tick_ch, hz, ed_tick, sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -459,18 +475,26 @@ static void
|
||||
ed_init(void *xsc)
|
||||
{
|
||||
struct ed_softc *sc = xsc;
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
int i, s;
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
ED_ASSERT_UNLOCKED(sc);
|
||||
ED_LOCK(sc);
|
||||
ed_init_locked(sc);
|
||||
ED_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
ed_init_locked(struct ed_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
int i;
|
||||
|
||||
ED_ASSERT_LOCKED(sc);
|
||||
|
||||
/*
|
||||
* Initialize the NIC in the exact order outlined in the NS manual.
|
||||
* This init procedure is "mandatory"...don't change what or when
|
||||
* things happen.
|
||||
*/
|
||||
s = splimp();
|
||||
|
||||
/* reset transmitter flags */
|
||||
sc->xmit_busy = 0;
|
||||
@ -601,13 +625,11 @@ ed_init(void *xsc)
|
||||
/*
|
||||
* ...and attempt to start output
|
||||
*/
|
||||
ed_start(ifp);
|
||||
ed_start_locked(ifp);
|
||||
|
||||
#ifndef ED_NO_MIIBUS
|
||||
untimeout(ed_tick, sc, sc->tick_ch);
|
||||
sc->tick_ch = timeout(ed_tick, sc, hz);
|
||||
callout_reset(&sc->tick_ch, hz, ed_tick, sc);
|
||||
#endif
|
||||
(void) splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -619,8 +641,6 @@ ed_xmit(struct ed_softc *sc)
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
unsigned short len;
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
len = sc->txb_len[sc->txb_next_tx];
|
||||
|
||||
/*
|
||||
@ -670,16 +690,24 @@ ed_xmit(struct ed_softc *sc)
|
||||
*/
|
||||
static void
|
||||
ed_start(struct ifnet *ifp)
|
||||
{
|
||||
struct ed_softc *sc = ifp->if_softc;
|
||||
|
||||
ED_ASSERT_UNLOCKED(sc);
|
||||
ED_LOCK(sc);
|
||||
ed_start_locked(ifp);
|
||||
ED_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
ed_start_locked(struct ifnet *ifp)
|
||||
{
|
||||
struct ed_softc *sc = ifp->if_softc;
|
||||
struct mbuf *m0, *m;
|
||||
caddr_t buffer;
|
||||
bus_size_t buffer;
|
||||
int len;
|
||||
|
||||
if (sc->gone) {
|
||||
printf("ed_start(%p) GONE\n",ifp);
|
||||
return;
|
||||
}
|
||||
ED_ASSERT_LOCKED(sc);
|
||||
outloop:
|
||||
|
||||
/*
|
||||
@ -719,7 +747,6 @@ ed_start(struct ifnet *ifp)
|
||||
/*
|
||||
* Copy the mbuf chain into the transmit buffer
|
||||
*/
|
||||
|
||||
m0 = m;
|
||||
|
||||
/* txb_new points to next open buffer slot */
|
||||
@ -758,11 +785,14 @@ ed_start(struct ifnet *ifp)
|
||||
}
|
||||
}
|
||||
for (len = 0; m != 0; m = m->m_next) {
|
||||
/* XXX
|
||||
* I'm not sure that this bcopy does only 16bit
|
||||
* access
|
||||
*/
|
||||
bcopy(mtod(m, caddr_t), buffer, m->m_len);
|
||||
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;
|
||||
}
|
||||
@ -788,7 +818,7 @@ ed_start(struct ifnet *ifp)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
len = ed_pio_write_mbufs(sc, m, (uintptr_t)buffer);
|
||||
len = ed_pio_write_mbufs(sc, m, buffer);
|
||||
if (len == 0) {
|
||||
m_freem(m0);
|
||||
goto outloop;
|
||||
@ -832,10 +862,9 @@ ed_rint(struct ed_softc *sc)
|
||||
u_char boundry;
|
||||
u_short len;
|
||||
struct ed_ring packet_hdr;
|
||||
char *packet_ptr;
|
||||
bus_size_t packet_ptr;
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
ED_ASSERT_LOCKED(sc);
|
||||
|
||||
/*
|
||||
* Set NIC to page 1 registers to get 'current' pointer
|
||||
@ -860,11 +889,8 @@ ed_rint(struct ed_softc *sc)
|
||||
* The byte count includes a 4 byte header that was added by
|
||||
* the NIC.
|
||||
*/
|
||||
if (sc->mem_shared)
|
||||
packet_hdr = *(struct ed_ring *) packet_ptr;
|
||||
else
|
||||
ed_pio_readmem(sc, (uintptr_t)packet_ptr,
|
||||
(char *) &packet_hdr, sizeof(packet_hdr));
|
||||
sc->readmem(sc, packet_ptr, (char *) &packet_hdr,
|
||||
sizeof(packet_hdr));
|
||||
len = packet_hdr.count;
|
||||
if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring)) ||
|
||||
len < (ETHER_MIN_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring))) {
|
||||
@ -968,8 +994,13 @@ edintr(void *arg)
|
||||
u_char isr;
|
||||
int count;
|
||||
|
||||
if (sc->gone)
|
||||
ED_LOCK(sc);
|
||||
#if 0
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
ED_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Set NIC to page 0 registers
|
||||
*/
|
||||
@ -1181,7 +1212,7 @@ edintr(void *arg)
|
||||
* after handling the receiver to give the receiver priority.
|
||||
*/
|
||||
if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0)
|
||||
ed_start(ifp);
|
||||
ed_start_locked(ifp);
|
||||
|
||||
/*
|
||||
* return NIC CR to standard state: page 0, remote DMA
|
||||
@ -1202,6 +1233,7 @@ edintr(void *arg)
|
||||
(void) ed_nic_inb(sc, ED_P0_CNTR2);
|
||||
}
|
||||
}
|
||||
ED_UNLOCK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1215,24 +1247,26 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
struct mii_data *mii;
|
||||
#endif
|
||||
int s, error = 0;
|
||||
int error = 0;
|
||||
|
||||
if (sc == NULL || sc->gone) {
|
||||
/*
|
||||
* XXX really needed?
|
||||
*/
|
||||
if (sc == NULL) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
return ENXIO;
|
||||
return (ENXIO);
|
||||
}
|
||||
s = splimp();
|
||||
|
||||
switch (command) {
|
||||
case SIOCSIFFLAGS:
|
||||
|
||||
/*
|
||||
* If the interface is marked up and stopped, then start it.
|
||||
* If it is marked down and running, then stop it.
|
||||
*/
|
||||
ED_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
ed_init(sc);
|
||||
ed_init_locked(sc);
|
||||
} else {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
ed_stop(sc);
|
||||
@ -1264,6 +1298,7 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
if (sc->vendor == ED_VENDOR_HP)
|
||||
ed_hpp_set_physical_link(sc);
|
||||
#endif
|
||||
ED_UNLOCK(sc);
|
||||
break;
|
||||
|
||||
case SIOCADDMULTI:
|
||||
@ -1272,7 +1307,9 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
* Multicast list has changed; set the hardware filter
|
||||
* accordingly.
|
||||
*/
|
||||
ED_LOCK(sc);
|
||||
ed_setrcr(sc);
|
||||
ED_UNLOCK(sc);
|
||||
error = 0;
|
||||
break;
|
||||
|
||||
@ -1290,8 +1327,8 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
|
||||
default:
|
||||
error = ether_ioctl(ifp, command, data);
|
||||
break;
|
||||
}
|
||||
(void) splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1300,34 +1337,21 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
* the ring buffer into a linear destination buffer. Takes into account
|
||||
* ring-wrap.
|
||||
*/
|
||||
static __inline char *
|
||||
ed_ring_copy(struct ed_softc *sc, char *src, char *dst, u_short amount)
|
||||
static __inline void
|
||||
ed_ring_copy(struct ed_softc *sc, bus_size_t src, char *dst, u_short amount)
|
||||
{
|
||||
u_short tmp_amount;
|
||||
|
||||
/* does copy wrap to lower addr in ring buffer? */
|
||||
if (src + amount > sc->mem_end) {
|
||||
tmp_amount = sc->mem_end - src;
|
||||
|
||||
/* XXX
|
||||
* I'm not sure that this bcopy does only 16bit access
|
||||
*/
|
||||
/* copy amount up to end of NIC memory */
|
||||
if (sc->mem_shared)
|
||||
bcopy(src, dst, tmp_amount);
|
||||
else
|
||||
ed_pio_readmem(sc, (uintptr_t)src, dst, tmp_amount);
|
||||
|
||||
sc->readmem(sc, src, dst, tmp_amount);
|
||||
amount -= tmp_amount;
|
||||
src = sc->mem_ring;
|
||||
dst += tmp_amount;
|
||||
}
|
||||
if (sc->mem_shared)
|
||||
bcopy(src, dst, amount);
|
||||
else
|
||||
ed_pio_readmem(sc, (uintptr_t)src, dst, amount);
|
||||
|
||||
return (src + amount);
|
||||
sc->readmem(sc, src, dst, amount);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1335,7 +1359,7 @@ ed_ring_copy(struct ed_softc *sc, char *src, char *dst, u_short amount)
|
||||
* ether_input().
|
||||
*/
|
||||
static void
|
||||
ed_get_packet(struct ed_softc *sc, char *buf, u_short len)
|
||||
ed_get_packet(struct ed_softc *sc, bus_size_t buf, u_short len)
|
||||
{
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
struct ether_header *eh;
|
||||
@ -1379,13 +1403,42 @@ ed_get_packet(struct ed_softc *sc, char *buf, u_short len)
|
||||
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
|
||||
ED_UNLOCK(sc);
|
||||
(*ifp->if_input)(ifp, m);
|
||||
ED_LOCK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Supporting routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Given a NIC memory source address and a host memory destination
|
||||
* address, copy 'amount' from NIC to host using shared memory.
|
||||
* The 'amount' is rounded up to a word - okay as long as mbufs
|
||||
* are word sized. That's what the +1 is below.
|
||||
* This routine accesses things as 16 bit quantities.
|
||||
*/
|
||||
void
|
||||
ed_shmem_readmem16(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
|
||||
uint16_t amount)
|
||||
{
|
||||
bus_space_read_region_2(sc->mem_bst, sc->mem_bsh, src, (uint16_t *)dst,
|
||||
amount + 1 / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a NIC memory source address and a host memory destination
|
||||
* address, copy 'amount' from NIC to host using shared memory.
|
||||
* This routine accesses things as 8 bit quantities.
|
||||
*/
|
||||
void
|
||||
ed_shmem_readmem8(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
|
||||
uint16_t amount)
|
||||
{
|
||||
bus_space_read_region_1(sc->mem_bst, sc->mem_bsh, src, dst, amount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a NIC memory source address and a host memory destination
|
||||
* address, copy 'amount' from NIC to host using Programmed I/O.
|
||||
@ -1394,16 +1447,9 @@ ed_get_packet(struct ed_softc *sc, char *buf, u_short len)
|
||||
* This routine is currently Novell-specific.
|
||||
*/
|
||||
void
|
||||
ed_pio_readmem(struct ed_softc *sc, long src, uint8_t *dst, uint16_t amount)
|
||||
ed_pio_readmem(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
|
||||
uint16_t amount)
|
||||
{
|
||||
#ifdef ED_HPP
|
||||
/* HP PC Lan+ cards need special handling */
|
||||
if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) {
|
||||
ed_hpp_readmem(sc, src, dst, amount);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Regular Novell cards */
|
||||
/* select page 0 registers */
|
||||
ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
|
||||
@ -1477,13 +1523,15 @@ ed_pio_writemem(struct ed_softc *sc, uint8_t *src, uint16_t dst, uint16_t len)
|
||||
* programmed I/O.
|
||||
*/
|
||||
static u_short
|
||||
ed_pio_write_mbufs(struct ed_softc *sc, struct mbuf *m, long dst)
|
||||
ed_pio_write_mbufs(struct ed_softc *sc, struct mbuf *m, bus_size_t dst)
|
||||
{
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
unsigned short total_len, dma_len;
|
||||
struct mbuf *mp;
|
||||
int maxwait = 200; /* about 240us */
|
||||
|
||||
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)
|
||||
@ -1599,15 +1647,12 @@ int
|
||||
ed_miibus_readreg(device_t dev, int phy, int reg)
|
||||
{
|
||||
struct ed_softc *sc;
|
||||
int failed, s, val;
|
||||
int failed, val;
|
||||
|
||||
s = splimp();
|
||||
sc = device_get_softc(dev);
|
||||
if (sc->gone) {
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* XXX is this right? */
|
||||
ED_LOCK(sc);
|
||||
(*sc->mii_writebits)(sc, 0xffffffff, 32);
|
||||
(*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS);
|
||||
(*sc->mii_writebits)(sc, ED_MII_READOP, ED_MII_OP_BITS);
|
||||
@ -1617,8 +1662,8 @@ ed_miibus_readreg(device_t dev, int phy, int reg)
|
||||
failed = (*sc->mii_readbits)(sc, ED_MII_ACK_BITS);
|
||||
val = (*sc->mii_readbits)(sc, ED_MII_DATA_BITS);
|
||||
(*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS);
|
||||
|
||||
splx(s);
|
||||
/* XXX is this right? */
|
||||
ED_UNLOCK(sc);
|
||||
return (failed ? 0 : val);
|
||||
}
|
||||
|
||||
@ -1626,15 +1671,11 @@ void
|
||||
ed_miibus_writereg(device_t dev, int phy, int reg, int data)
|
||||
{
|
||||
struct ed_softc *sc;
|
||||
int s;
|
||||
|
||||
s = splimp();
|
||||
sc = device_get_softc(dev);
|
||||
if (sc->gone) {
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX is this right? */
|
||||
ED_LOCK(sc);
|
||||
(*sc->mii_writebits)(sc, 0xffffffff, 32);
|
||||
(*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS);
|
||||
(*sc->mii_writebits)(sc, ED_MII_WRITEOP, ED_MII_OP_BITS);
|
||||
@ -1643,8 +1684,8 @@ ed_miibus_writereg(device_t dev, int phy, int reg, int data)
|
||||
(*sc->mii_writebits)(sc, ED_MII_TURNAROUND, ED_MII_TURNAROUND_BITS);
|
||||
(*sc->mii_writebits)(sc, data, ED_MII_DATA_BITS);
|
||||
(*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS);
|
||||
|
||||
splx(s);
|
||||
/* XXX is this right? */
|
||||
ED_UNLOCK(sc);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1654,7 +1695,7 @@ ed_ifmedia_upd(struct ifnet *ifp)
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
if (sc->gone || sc->miibus == NULL)
|
||||
if (sc->miibus == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
mii = device_get_softc(sc->miibus);
|
||||
@ -1668,7 +1709,7 @@ ed_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
if (sc->gone || sc->miibus == NULL)
|
||||
if (sc->miibus == NULL)
|
||||
return;
|
||||
|
||||
mii = device_get_softc(sc->miibus);
|
||||
@ -1695,6 +1736,8 @@ ed_setrcr(struct ed_softc *sc)
|
||||
int i;
|
||||
u_char reg1;
|
||||
|
||||
ED_ASSERT_LOCKED(sc);
|
||||
|
||||
/* Bit 6 in AX88190 RCR register must be set. */
|
||||
if (sc->chip_type == ED_CHIP_TYPE_AX88190)
|
||||
reg1 = ED_RCR_INTT;
|
||||
@ -1804,17 +1847,14 @@ int
|
||||
ed_clear_memory(device_t dev)
|
||||
{
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
int i;
|
||||
bus_size_t i;
|
||||
|
||||
/*
|
||||
* Now zero memory and verify that it is clear
|
||||
* XXX restricted to 16-bit writes? Do we need to
|
||||
* XXX enable 16-bit access?
|
||||
*/
|
||||
bzero(sc->mem_start, sc->mem_size);
|
||||
bus_space_set_region_1(sc->mem_bst, sc->mem_bsh, sc->mem_start,
|
||||
0, sc->mem_size);
|
||||
|
||||
for (i = 0; i < sc->mem_size; ++i) {
|
||||
if (sc->mem_start[i]) {
|
||||
for (i = 0; i < sc->mem_size; i++) {
|
||||
if (bus_space_read_1(sc->mem_bst, sc->mem_bsh,
|
||||
sc->mem_start + i)) {
|
||||
device_printf(dev, "failed to clear shared memory at "
|
||||
"0x%jx - check configuration\n",
|
||||
(uintmax_t)rman_get_start(sc->mem_res) + i);
|
||||
|
@ -249,7 +249,7 @@ ed_probe_3Com(device_t dev, int port_rid, int flags)
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res);
|
||||
sc->mem_start = 0;
|
||||
sc->mem_size = memsize;
|
||||
sc->mem_end = sc->mem_start + memsize;
|
||||
|
||||
|
@ -242,7 +242,7 @@ ed_cbus_attach(dev)
|
||||
|
||||
ed_alloc_irq(dev, sc->irq_rid, 0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
|
||||
edintr, sc, &sc->irq_handle);
|
||||
if (error) {
|
||||
ed_release_resources(dev);
|
||||
@ -616,7 +616,7 @@ ed98_alloc_memory(dev, rid)
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res);
|
||||
sc->mem_start = 0;
|
||||
sc->mem_size = conf_msize;
|
||||
|
||||
return (0);
|
||||
@ -839,9 +839,10 @@ ed_probe_SIC98(device_t dev, int port_rid, int flags)
|
||||
* type code and ethernet address check out, then we know we have
|
||||
* an SIC card.
|
||||
*/
|
||||
sum = sc->mem_start[6 * 2];
|
||||
sum = bus_space_read_1(sc->mem_bst, sc->mem_bsh, 6 * 2);
|
||||
for (i = 0; i < ETHER_ADDR_LEN; i++)
|
||||
sum ^= (sc->enaddr[i] = sc->mem_start[i * 2]);
|
||||
sum ^= (sc->enaddr[i] =
|
||||
bus_space_read_1(sc->mem_bst, sc->mem_bsh, i * 2));
|
||||
#ifdef ED_DEBUG
|
||||
device_printf(dev, "ed_probe_sic98: got address %6D\n",
|
||||
sc->enaddr, ":");
|
||||
@ -1064,7 +1065,8 @@ ed_probe_CNET98(device_t dev, int port_rid, int flags)
|
||||
/*
|
||||
* Get station address from on-board ROM
|
||||
*/
|
||||
bcopy(sc->mem_start, sc->enaddr, ETHER_ADDR_LEN);
|
||||
bus_space_read_region_1(sc->mem_bst, sc->mem_bsh, sc->mem_start,
|
||||
sc->enaddr, ETHER_ADDR_LEN);
|
||||
|
||||
sc->vendor = ED_VENDOR_MISC;
|
||||
sc->type_str = "CNET98";
|
||||
@ -1577,7 +1579,7 @@ ed_pio_testmem(struct ed_softc *sc, int page_offset, int isa16bit, int flags)
|
||||
}
|
||||
#endif
|
||||
sc->mem_size = memsize;
|
||||
sc->mem_start = (char *) page_offset;
|
||||
sc->mem_start = page_offset;
|
||||
sc->mem_end = sc->mem_start + memsize;
|
||||
sc->tx_page_start = page_offset / ED_PAGE_SIZE;
|
||||
|
||||
|
@ -410,7 +410,8 @@ ed_hpp_set_physical_link(struct ed_softc *sc)
|
||||
*/
|
||||
|
||||
void
|
||||
ed_hpp_readmem(struct ed_softc *sc, long src, uint8_t *dst, uint16_t amount)
|
||||
ed_hpp_readmem(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
|
||||
uint16_t amount)
|
||||
{
|
||||
int use_32bit_access = !(sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS);
|
||||
|
||||
@ -434,10 +435,10 @@ ed_hpp_readmem(struct ed_softc *sc, long src, uint8_t *dst, uint16_t amount)
|
||||
(uint32_t *) sc->hpp_mem_start;
|
||||
uint32_t *const fence = dl + (amount >> 2);
|
||||
|
||||
/* Copy out NIC data. We could probably write this
|
||||
as a `movsl'. The currently generated code is lousy.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copy out NIC data. We could probably write this
|
||||
* as a `movsl'. The currently generated code is lousy.
|
||||
*/
|
||||
while (dl < fence)
|
||||
*dl++ = *sl;
|
||||
|
||||
|
@ -43,11 +43,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_mib.h>
|
||||
|
||||
#include <isa/isavar.h>
|
||||
|
||||
#include <dev/ed/if_edvar.h>
|
||||
#include <dev/ed/if_edreg.h>
|
||||
|
||||
static int ed_isa_probe(device_t);
|
||||
static int ed_isa_attach(device_t);
|
||||
@ -157,13 +159,17 @@ ed_isa_attach(device_t dev)
|
||||
|
||||
ed_alloc_irq(dev, sc->irq_rid, 0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
|
||||
edintr, sc, &sc->irq_handle);
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
|
||||
edintr, sc, &sc->irq_handle);
|
||||
if (error) {
|
||||
ed_release_resources(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);
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ ed_probe_Novell_generic(device_t dev, int flags)
|
||||
|
||||
/* NIC memory doesn't start at zero on an NE board */
|
||||
/* The start address is tied to the bus width */
|
||||
sc->mem_start = (char *) 8192 + sc->isa16bit * 8192;
|
||||
sc->mem_start = 8192 + sc->isa16bit * 8192;
|
||||
sc->mem_end = sc->mem_start + memsize;
|
||||
sc->tx_page_start = memsize / ED_PAGE_SIZE;
|
||||
|
||||
@ -218,7 +218,7 @@ static int
|
||||
ed_probe_gwether(device_t dev)
|
||||
{
|
||||
int x, i, msize = 0;
|
||||
long mstart = 0;
|
||||
bus_size_t mstart = 0;
|
||||
char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE];
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
|
||||
@ -269,14 +269,17 @@ ed_probe_gwether(device_t dev)
|
||||
|
||||
if (msize == 0) {
|
||||
device_printf(dev,
|
||||
"Cannot find any RAM, start : %ld, x = %d.\n", mstart, x);
|
||||
"Cannot find any RAM, start : %d, x = %d.\n",
|
||||
(int)mstart, x);
|
||||
return (ENXIO);
|
||||
}
|
||||
device_printf(dev, "RAM start at %ld, size : %d.\n", mstart, msize);
|
||||
if (bootverbose)
|
||||
device_printf(dev,
|
||||
"RAM start at %d, size : %d.\n", (int)mstart, msize);
|
||||
|
||||
sc->mem_size = msize;
|
||||
sc->mem_start = (caddr_t)(uintptr_t) mstart;
|
||||
sc->mem_end = (caddr_t)(uintptr_t) (msize + mstart);
|
||||
sc->mem_start = mstart;
|
||||
sc->mem_end = msize + mstart;
|
||||
sc->tx_page_start = mstart / ED_PAGE_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
@ -80,9 +80,8 @@ MODULE_DEPEND(ed, ether, 1, 1, 1);
|
||||
#define ED_DEFAULT_MAC_OFFSET 0xff0
|
||||
|
||||
/*
|
||||
* PC-Card (PCMCIA) specific code.
|
||||
* PC Card (PCMCIA) specific code.
|
||||
*/
|
||||
static int ed_pccard_match(device_t);
|
||||
static int ed_pccard_probe(device_t);
|
||||
static int ed_pccard_attach(device_t);
|
||||
|
||||
@ -198,7 +197,7 @@ static const struct ed_product {
|
||||
};
|
||||
|
||||
static int
|
||||
ed_pccard_match(device_t dev)
|
||||
ed_pccard_probe(device_t dev)
|
||||
{
|
||||
const struct ed_product *pp;
|
||||
int error;
|
||||
@ -226,45 +225,6 @@ ed_pccard_match(device_t dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe framework for pccards. Replicates the standard framework,
|
||||
* minus the pccard driver registration and ignores the ether address
|
||||
* supplied (from the CIS), relying on the probe to find it instead.
|
||||
*/
|
||||
static int
|
||||
ed_pccard_probe(device_t dev)
|
||||
{
|
||||
const struct ed_product *pp;
|
||||
int error;
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
|
||||
if ((pp = (const struct ed_product *) pccard_product_lookup(dev,
|
||||
(const struct pccard_product *) ed_pccard_products,
|
||||
sizeof(ed_pccard_products[0]), NULL)) == NULL)
|
||||
return (ENXIO);
|
||||
sc->port_rid = pp->edrid;
|
||||
if (pp->flags & NE2000DVF_DL100XX) {
|
||||
error = ed_probe_Novell(dev, sc->port_rid, 0);
|
||||
if (error == 0)
|
||||
error = ed_pccard_Linksys(dev);
|
||||
ed_release_resources(dev);
|
||||
if (error == 0)
|
||||
goto end2;
|
||||
}
|
||||
if (pp->flags & NE2000DVF_AX88X90) {
|
||||
error = ed_pccard_ax88x90(dev);
|
||||
if (error == 0)
|
||||
goto end2;
|
||||
}
|
||||
error = ed_probe_Novell(dev, sc->port_rid, 0);
|
||||
end2:
|
||||
if (error == 0)
|
||||
error = ed_alloc_irq(dev, 0, 0);
|
||||
|
||||
ed_release_resources(dev);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ed_pccard_rom_mac(device_t dev, uint8_t *enaddr)
|
||||
{
|
||||
@ -300,25 +260,44 @@ ed_pccard_add_modem(device_t dev, int rid)
|
||||
static int
|
||||
ed_pccard_attach(device_t dev)
|
||||
{
|
||||
int error, i;
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
u_char sum;
|
||||
u_char enaddr[ETHER_ADDR_LEN];
|
||||
const struct ed_product *pp;
|
||||
|
||||
int error, i;
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
|
||||
if ((pp = (const struct ed_product *) pccard_product_lookup(dev,
|
||||
(const struct pccard_product *) ed_pccard_products,
|
||||
sizeof(ed_pccard_products[0]), NULL)) == NULL)
|
||||
return (ENXIO);
|
||||
sc->port_rid = pp->edrid;
|
||||
if (sc->port_used > 0)
|
||||
ed_alloc_port(dev, sc->port_rid, sc->port_used);
|
||||
if (sc->mem_used)
|
||||
ed_alloc_memory(dev, sc->mem_rid, sc->mem_used);
|
||||
ed_alloc_irq(dev, sc->irq_rid, 0);
|
||||
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, edintr, sc,
|
||||
&sc->irq_handle);
|
||||
if (pp->flags & NE2000DVF_DL100XX) {
|
||||
error = ed_probe_Novell(dev, sc->port_rid, 0);
|
||||
if (error == 0)
|
||||
error = ed_pccard_Linksys(dev);
|
||||
ed_release_resources(dev);
|
||||
if (error == 0)
|
||||
goto end2;
|
||||
}
|
||||
if (pp->flags & NE2000DVF_AX88X90) {
|
||||
error = ed_pccard_ax88x90(dev);
|
||||
if (error == 0)
|
||||
goto end2;
|
||||
}
|
||||
error = ed_probe_Novell(dev, sc->port_rid, 0);
|
||||
end2:
|
||||
if (error) {
|
||||
ed_release_resources(dev);
|
||||
return (error);
|
||||
}
|
||||
error = ed_alloc_irq(dev, 0, 0);
|
||||
if (error) {
|
||||
ed_release_resources(dev);
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
|
||||
edintr, sc, &sc->irq_handle);
|
||||
if (error) {
|
||||
device_printf(dev, "setup intr failed %d \n", error);
|
||||
ed_release_resources(dev);
|
||||
@ -376,9 +355,13 @@ ed_pccard_attach(device_t dev)
|
||||
}
|
||||
|
||||
error = ed_attach(dev);
|
||||
if (error) {
|
||||
ed_release_resources(dev);
|
||||
return (error);
|
||||
}
|
||||
#ifndef ED_NO_MIIBUS
|
||||
if (error == 0 && (sc->chip_type == ED_CHIP_TYPE_DL10019 ||
|
||||
sc->chip_type == ED_CHIP_TYPE_DL10022)) {
|
||||
if (sc->chip_type == ED_CHIP_TYPE_DL10019 ||
|
||||
sc->chip_type == ED_CHIP_TYPE_DL10022) {
|
||||
/* Probe for an MII bus, but ignore errors. */
|
||||
ed_pccard_dlink_mii_reset(sc);
|
||||
sc->mii_readbits = ed_pccard_dlink_mii_readbits;
|
||||
@ -389,7 +372,7 @@ ed_pccard_attach(device_t dev)
|
||||
#endif
|
||||
if (pp->flags & NE2000DVF_MODEM)
|
||||
ed_pccard_add_modem(dev, pp->siorid);
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -650,8 +633,8 @@ ed_pccard_dlink_mii_readbits(sc, nbits)
|
||||
|
||||
static device_method_t ed_pccard_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, pccard_compat_probe),
|
||||
DEVMETHOD(device_attach, pccard_compat_attach),
|
||||
DEVMETHOD(device_probe, ed_pccard_probe),
|
||||
DEVMETHOD(device_attach, ed_pccard_attach),
|
||||
DEVMETHOD(device_detach, ed_detach),
|
||||
|
||||
#ifndef ED_NO_MIIBUS
|
||||
@ -663,10 +646,6 @@ static device_method_t ed_pccard_methods[] = {
|
||||
DEVMETHOD(miibus_writereg, ed_miibus_writereg),
|
||||
#endif
|
||||
|
||||
/* Card interface */
|
||||
DEVMETHOD(card_compat_match, ed_pccard_match),
|
||||
DEVMETHOD(card_compat_probe, ed_pccard_probe),
|
||||
DEVMETHOD(card_compat_attach, ed_pccard_attach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_mib.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
@ -94,7 +95,7 @@ ed_pci_attach(device_t dev)
|
||||
ed_release_resources(dev);
|
||||
return (error);
|
||||
}
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
|
||||
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
|
||||
edintr, sc, &sc->irq_handle);
|
||||
if (error) {
|
||||
ed_release_resources(dev);
|
||||
|
@ -85,7 +85,7 @@ ed_probe_SIC(device_t dev, int port_rid, int flags)
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res);
|
||||
sc->mem_start = 0;
|
||||
sc->mem_size = memsize;
|
||||
|
||||
pmem = rman_get_start(sc->mem_res);
|
||||
@ -105,9 +105,10 @@ ed_probe_SIC(device_t dev, int port_rid, int flags)
|
||||
ed_asic_outb(sc, 0, 0x81);
|
||||
DELAY(100);
|
||||
|
||||
sum = sc->mem_start[6];
|
||||
sum = bus_space_read_1(sc->mem_bst, sc->mem_bsh, 6);
|
||||
for (i = 0; i < ETHER_ADDR_LEN; i++)
|
||||
sum ^= (sc->enaddr[i] = sc->mem_start[i]);
|
||||
sum ^= (sc->enaddr[i] =
|
||||
bus_space_read_1(sc->mem_bst, sc->mem_bsh, i));
|
||||
#ifdef ED_DEBUG
|
||||
device_printf(dev, "ed_probe_sic: got address %6D\n",
|
||||
sc->enaddr, ":");
|
||||
|
@ -258,7 +258,7 @@ ed_probe_WD80x3_generic(device_t dev, int flags, uint16_t *intr_vals[])
|
||||
error = ed_alloc_memory(dev, 0, memsize);
|
||||
if (error)
|
||||
return (error);
|
||||
sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res);
|
||||
sc->mem_start = 0;
|
||||
|
||||
#ifdef ED_DEBUG
|
||||
printf("type = %x type_str=%s isa16bit=%d memsize=%d id_msize=%lu\n",
|
||||
|
@ -34,12 +34,14 @@
|
||||
*/
|
||||
struct ed_softc {
|
||||
struct ifnet *ifp;
|
||||
struct ifmedia ifmedia; /* Media info */
|
||||
device_t dev;
|
||||
struct mtx sc_mtx;
|
||||
|
||||
char *type_str; /* pointer to type string */
|
||||
u_char vendor; /* interface vendor */
|
||||
u_char type; /* interface type code */
|
||||
u_char chip_type; /* the type of chip (one of ED_CHIP_TYPE_*) */
|
||||
u_char gone; /* HW missing, presumed having a good time */
|
||||
u_char isa16bit; /* width of access to card 0=8 or 1=16 */
|
||||
u_char mem_shared; /* NIC memory is shared with host */
|
||||
u_char xmit_busy; /* transmitter is busy */
|
||||
@ -61,7 +63,9 @@ struct ed_softc {
|
||||
device_t miibus; /* MII bus for cards with MII. */
|
||||
void (*mii_writebits)(struct ed_softc *, u_int, int);
|
||||
u_int (*mii_readbits)(struct ed_softc *, int);
|
||||
struct callout_handle tick_ch; /* Callout handle for ed_tick */
|
||||
struct callout tick_ch;
|
||||
void (*readmem)(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
|
||||
uint16_t amount);
|
||||
|
||||
int nic_offset; /* NIC (DS8390) I/O bus address offset */
|
||||
int asic_offset; /* ASIC I/O bus address offset */
|
||||
@ -81,10 +85,10 @@ struct ed_softc {
|
||||
u_short hpp_id; /* software revision and other fields */
|
||||
caddr_t hpp_mem_start; /* Memory-mapped IO register address */
|
||||
|
||||
caddr_t mem_start; /* NIC memory start address */
|
||||
caddr_t mem_end; /* NIC memory end address */
|
||||
bus_size_t mem_start; /* NIC memory start address */
|
||||
bus_size_t mem_end; /* NIC memory end address */
|
||||
uint32_t mem_size; /* total NIC memory size */
|
||||
caddr_t mem_ring; /* start of RX ring-buffer (in NIC mem) */
|
||||
bus_size_t mem_ring; /* start of RX ring-buffer (in NIC mem) */
|
||||
|
||||
u_char txb_cnt; /* number of transmit buffers */
|
||||
u_char txb_inuse; /* number of TX buffers currently in-use */
|
||||
@ -202,7 +206,9 @@ int ed_detach(device_t);
|
||||
int ed_clear_memory(device_t);
|
||||
int ed_isa_mem_ok(device_t, u_long, u_int); /* XXX isa specific */
|
||||
void ed_stop(struct ed_softc *);
|
||||
void ed_pio_readmem(struct ed_softc *, long, uint8_t *, uint16_t);
|
||||
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);
|
||||
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);
|
||||
#ifndef ED_NO_MIIBUS
|
||||
int ed_miibus_readreg(device_t, int, int);
|
||||
@ -215,7 +221,7 @@ void ed_child_detached(device_t, device_t);
|
||||
/* The following is unsatisfying XXX */
|
||||
#ifdef ED_HPP
|
||||
void ed_hpp_set_physical_link(struct ed_softc *);
|
||||
void ed_hpp_readmem(struct ed_softc *, long, uint8_t *, uint16_t);
|
||||
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
|
||||
|
||||
@ -272,4 +278,14 @@ extern devclass_t ed_devclass;
|
||||
|
||||
#define ED_FLAGS_GETTYPE(flg) ((flg) & 0xff0000)
|
||||
|
||||
#define ED_MUTEX(_sc) (&(_sc)->sc_mtx)
|
||||
#define ED_LOCK(_sc) mtx_lock(ED_MUTEX(_sc))
|
||||
#define ED_UNLOCK(_sc) mtx_unlock(ED_MUTEX(_sc))
|
||||
#define ED_LOCK_INIT(_sc) \
|
||||
mtx_init(ED_MUTEX(_sc), device_get_nameunit(_sc->dev), \
|
||||
MTX_NETWORK_LOCK, MTX_DEF)
|
||||
#define ED_LOCK_DESTROY(_sc) mtx_destroy(ED_MUTEX(_sc));
|
||||
#define ED_ASSERT_LOCKED(_sc) mtx_assert(ED_MUTEX(_sc), MA_OWNED);
|
||||
#define ED_ASSERT_UNLOCKED(_sc) mtx_assert(ED_MUTEX(_sc), MA_NOTOWNED);
|
||||
|
||||
#endif /* SYS_DEV_ED_IF_EDVAR_H */
|
||||
|
Loading…
Reference in New Issue
Block a user