Mercurial > ecos
changeset 1392:47e26737c662
* src/if_dp83902a.c: Set STOP bit in CR after setting CURP
register; required for AX88796 chip. Fix handling of BNDRY
pointer w.r.t. ring buffer wrap-around. Add extra delays
ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA.
| author | asl |
|---|---|
| date | Mon, 24 Nov 2003 11:51:42 +0000 |
| parents | c1f61c891552 |
| children | bce4d2e47e78 |
| files | packages/devs/eth/ns/dp83902a/current/ChangeLog packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c |
| diffstat | 2 files changed, 26 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/eth/ns/dp83902a/current/ChangeLog +++ b/packages/devs/eth/ns/dp83902a/current/ChangeLog @@ -1,3 +1,10 @@ +2003-11-19 David Woodhouse <dwmw2@redhat.com> + + * src/if_dp83902a.c: Set STOP bit in CR after setting CURP + register; required for AX88796 chip. Fix handling of BNDRY + pointer w.r.t. ring buffer wrap-around. Add extra delays + ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA. + 2002-06-14 Gary Thomas <gary@chez-thomas.org> * src/if_dp83902a.c:
--- a/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c +++ b/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c @@ -244,7 +244,7 @@ dp83902a_start(struct eth_drv_sc *sc, un dp->rx_next = dp->rx_buf_start-1; DP_OUT(base, DP_ISR, 0xFF); // Clear any pending interrupts DP_OUT(base, DP_IMR, DP_IMR_All); // Enable all interrupts - DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); // Select page 1 + DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); // Select page 1 DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); // Current page - next free page for Rx for (i = 0; i < ETHER_ADDR_LEN; i++) { DP_OUT(base, DP_P1_PAR0+i, enaddr[i]); @@ -498,24 +498,33 @@ dp83902a_RxEvent(struct eth_drv_sc *sc) DP_IN(base, DP_P1_CURP, cur); DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); DP_IN(base, DP_BNDRY, pkt); + pkt += 1; + if (pkt == dp->rx_buf_end) + pkt = dp->rx_buf_start; + if (pkt == cur) { CR_DOWN(); break; } - if (pkt == dp->rx_buf_end) pkt = dp->rx_buf_start; DP_OUT(base, DP_RBCL, sizeof(rcv_hdr)); DP_OUT(base, DP_RBCH, 0); DP_OUT(base, DP_RSAL, 0); DP_OUT(base, DP_RSAH, pkt); if (dp->rx_next == pkt) { - DP_OUT(base, DP_BNDRY, cur-1); // Update pointer + if (cur == dp->rx_buf_start) + DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); + else + DP_OUT(base, DP_BNDRY, cur-1); // Update pointer CR_DOWN(); return; } dp->rx_next = pkt; DP_OUT(base, DP_ISR, DP_ISR_RDC); // Clear end of DMA DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); +#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA + CYGACC_CALL_IF_DELAY_US(10); +#endif for (i = 0; i < sizeof(rcv_hdr);) { #ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA @@ -535,7 +544,10 @@ dp83902a_RxEvent(struct eth_drv_sc *sc) #endif len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); (sc->funs->eth_drv->recv)(sc, len); - DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); // Update pointer + if (rcv_hdr[1] == dp->rx_buf_start) + DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); + else + DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); // Update pointer } } @@ -581,6 +593,9 @@ dp83902a_recv(struct eth_drv_sc *sc, str DP_OUT(base, DP_RSAH, dp->rx_next); DP_OUT(base, DP_ISR, DP_ISR_RDC); // Clear end of DMA DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); +#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA + CYGACC_CALL_IF_DELAY_US(10); +#endif saved = false; for (i = 0; i < sg_len; i++) {
