diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-10-10 00:09:08 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-10-10 00:09:08 +0000 |
commit | dc8d0c42a03c25fdf64c58d17fc94f81dd2782d7 (patch) | |
tree | 7035711de4c06df38dee1f8dbe133b6798372b20 /sys/dev/ic/ne2000.c | |
parent | 883652ccedcb7255aa5d5ad9048216f16d568ac3 (diff) |
Add bus_space_barrier.
Add DELAY in some busy loops to allow the DMA engine to actually do something
(neccessary on fast processors).
From ws@ & mycroft@ NetBSD
Testing by deraadt@ nick@, ok deraadt@
Diffstat (limited to 'sys/dev/ic/ne2000.c')
-rw-r--r-- | sys/dev/ic/ne2000.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/sys/dev/ic/ne2000.c b/sys/dev/ic/ne2000.c index 33ad2aea13c..fd5a27195ea 100644 --- a/sys/dev/ic/ne2000.c +++ b/sys/dev/ic/ne2000.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ne2000.c,v 1.17 2006/07/29 11:31:20 miod Exp $ */ +/* $OpenBSD: ne2000.c,v 1.18 2006/10/10 00:09:07 brad Exp $ */ /* $NetBSD: ne2000.c,v 1.12 1998/06/10 01:15:50 thorpej Exp $ */ /*- @@ -98,6 +98,10 @@ void ne2000_writemem(bus_space_tag_t, bus_space_handle_t, void ne2000_readmem(bus_space_tag_t, bus_space_handle_t, bus_space_tag_t, bus_space_handle_t, int, u_int8_t *, size_t, int); +#define ASIC_BARRIER(asict, asich) \ + bus_space_barrier((asict), (asich), 0, 0x10, \ + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) + struct cfdriver ne_cd = { NULL, "ne", DV_IFNET }; @@ -250,10 +254,13 @@ ne2000_attach(nsc, myea) /* Read the station address. */ if (nsc->sc_type == NE2000_TYPE_AX88190) { /* Select page 0 registers. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA); + NIC_BARRIER(nict, nich); /* Select word transfer. */ bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_WTS); + NIC_BARRIER(nict, nich); ne2000_readmem(nict, nich, asict, asich, NE2000_AX88190_NODEID_OFFSET, dsc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN, useword); @@ -273,7 +280,9 @@ ne2000_attach(nsc, myea) bcopy(myea, dsc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); /* Clear any pending interrupts that might have occurred above. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_ISR, 0xff); + NIC_BARRIER(nict, nich); if (dsc->sc_media_init == NULL) dsc->sc_media_init = dp8390_media_init; @@ -315,9 +324,11 @@ ne2000_detect(nsc) /* Reset the board. */ #ifdef GWETHER bus_space_write_1(asict, asich, NE2000_ASIC_RESET, 0); + ASIC_BARRIER(asict, asich); delay(200); #endif /* GWETHER */ tmp = bus_space_read_1(asict, asich, NE2000_ASIC_RESET); + ASIC_BARRIER(asict, asich); delay(10000); /* @@ -329,6 +340,7 @@ ne2000_detect(nsc) * the invasive thing for now. Yuck.] */ bus_space_write_1(asict, asich, NE2000_ASIC_RESET, tmp); + ASIC_BARRIER(asict, asich); delay(5000); /* @@ -339,6 +351,7 @@ ne2000_detect(nsc) */ bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP); + NIC_BARRIER(nict, nich); delay(5000); @@ -374,12 +387,14 @@ ne2000_detect(nsc) bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA); + NIC_BARRIER(nict, nich); for (i = 0; i < 100; i++) { if ((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RST) == ED_ISR_RST) { /* Ack the reset bit. */ bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RST); + NIC_BARRIER(nict, nich); break; } delay(100); @@ -401,6 +416,7 @@ ne2000_detect(nsc) * the readmem routine turns on the start bit in the CR. */ bus_space_write_1(nict, nich, ED_P0_RCR, ED_RCR_MON); + NIC_BARRIER(nict, nich); /* Temporarily initialize DCR for byte operations. */ bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); @@ -446,6 +462,7 @@ ne2000_detect(nsc) } /* Clear any pending interrupts that might have occurred above. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_ISR, 0xff); out: @@ -475,11 +492,14 @@ ne2000_write_mbuf(sc, m, buf) savelen = m->m_pkthdr.len; /* Select page 0 registers. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA); + NIC_BARRIER(nict, nich); /* Reset remote DMA complete flag. */ bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC); + NIC_BARRIER(nict, nich); /* Set up DMA byte count. */ bus_space_write_1(nict, nich, ED_P0_RBCR0, savelen); @@ -490,8 +510,10 @@ ne2000_write_mbuf(sc, m, buf) bus_space_write_1(nict, nich, ED_P0_RSAR1, buf >> 8); /* Set remote DMA write. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA); + NIC_BARRIER(nict, nich); /* * Transfer the mbuf chain to the NIC memory. NE2000 cards @@ -596,6 +618,7 @@ ne2000_write_mbuf(sc, m, buf) #endif } } + NIC_BARRIER(nict, nich); /* * Wait for remote DMA to complete. This is necessary because on the @@ -605,7 +628,12 @@ ne2000_write_mbuf(sc, m, buf) * the bus. */ while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) != - ED_ISR_RDC) && --maxwait); + ED_ISR_RDC) && --maxwait) { + bus_space_read_1(nict, nich, ED_P0_CRDA1); + bus_space_read_1(nict, nich, ED_P0_CRDA0); + NIC_BARRIER(nict, nich); + DELAY(1); + } if (maxwait == 0) { log(LOG_WARNING, @@ -699,8 +727,10 @@ ne2000_readmem(nict, nich, asict, asich, src, dst, amount, useword) { /* Select page 0 registers. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA); + NIC_BARRIER(nict, nich); /* Round up to a word. */ if (amount & 1) @@ -714,9 +744,11 @@ ne2000_readmem(nict, nich, asict, asich, src, dst, amount, useword) bus_space_write_1(nict, nich, ED_P0_RSAR0, src); bus_space_write_1(nict, nich, ED_P0_RSAR1, src >> 8); + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA); + ASIC_BARRIER(asict, asich); if (useword) #ifdef __NetBSD__ bus_space_read_multi_stream_2(asict, asich, NE2000_ASIC_DATA, @@ -748,11 +780,14 @@ ne2000_writemem(nict, nich, asict, asich, src, dst, len, useword) int maxwait = 100; /* about 120us */ /* Select page 0 registers. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA); + NIC_BARRIER(nict, nich); /* Reset remote DMA complete flag. */ bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC); + NIC_BARRIER(nict, nich); /* Set up DMA byte count. */ bus_space_write_1(nict, nich, ED_P0_RBCR0, len); @@ -763,9 +798,12 @@ ne2000_writemem(nict, nich, asict, asich, src, dst, len, useword) bus_space_write_1(nict, nich, ED_P0_RSAR1, dst >> 8); /* Set remote DMA write. */ + NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA); + NIC_BARRIER(nict, nich); + ASIC_BARRIER(asict, asich); if (useword) #ifdef __NetBSD__ bus_space_write_multi_stream_2(asict, asich, NE2000_ASIC_DATA, @@ -777,6 +815,7 @@ ne2000_writemem(nict, nich, asict, asich, src, dst, len, useword) else bus_space_write_multi_1(asict, asich, NE2000_ASIC_DATA, src, len); + ASIC_BARRIER(asict, asich); /* * Wait for remote DMA to complete. This is necessary because on the @@ -786,7 +825,8 @@ ne2000_writemem(nict, nich, asict, asich, src, dst, len, useword) * the bus. */ while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) != - ED_ISR_RDC) && --maxwait); + ED_ISR_RDC) && --maxwait) + DELAY(1); } int |