diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-03-22 17:13:51 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-03-22 17:13:51 +0000 |
commit | 7ed74e1e25fee6c29061fe600f617cf432887c03 (patch) | |
tree | 5403656ae9cdf04f8241bd25ec6cbd4596b9112e /nuttx/arch/z80 | |
parent | 0554e0302db0094f60b7595ea7f8770f3a69bb27 (diff) | |
download | px4-nuttx-7ed74e1e25fee6c29061fe600f617cf432887c03.tar.gz px4-nuttx-7ed74e1e25fee6c29061fe600f617cf432887c03.tar.bz2 px4-nuttx-7ed74e1e25fee6c29061fe600f617cf432887c03.zip |
Fix an error that was causing Tx to timeout improperly
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1639 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/z80')
-rw-r--r-- | nuttx/arch/z80/src/ez80/ez80_emac.c | 84 |
1 files changed, 41 insertions, 43 deletions
diff --git a/nuttx/arch/z80/src/ez80/ez80_emac.c b/nuttx/arch/z80/src/ez80/ez80_emac.c index 817668595..df550b715 100644 --- a/nuttx/arch/z80/src/ez80/ez80_emac.c +++ b/nuttx/arch/z80/src/ez80/ez80_emac.c @@ -276,7 +276,7 @@ struct ez80emac_driver_s * Tx/Rx memory). * txhead: Points to the oldest Tx descriptor queued for output (but for * which output has not yet completed. Initialized to NULL; set - * by ez80emac_transmit() when Tx is started and by ez80emac_reclaimtxdesc() + * by ez80emac_transmit() when Tx is started and by ez80emac_txinterrupt() * when Tx processing completes. txhead == NULL is also a sure * indication that there is no Tx in progress. * txnext: Points to the next free Tx descriptor. Initialized to txstart; set @@ -946,7 +946,7 @@ static int ez80emac_transmit(struct ez80emac_driver_s *priv) * handler and, therefore, may be suspended when debug output is generated! */ - nllvdbg("ENTRY: txnext=%p {%06x, %u, %04x} trp=%02x%02x\n", + nllvdbg("txnext=%p {%06x, %u, %04x} trp=%02x%02x\n", priv->txnext, priv->txnext->np, priv->txnext->pktsize, priv->txnext->stat, inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); @@ -1025,11 +1025,11 @@ static int ez80emac_transmit(struct ez80emac_driver_s *priv) outp(EZ80_EMAC_PTMR, EMAC_PTMR); irqrestore(flags); - nllvdbg("EXIT: txdesc=%p {%06x, %u, %04x}\n", + nllvdbg("txdesc=%p {%06x, %u, %04x}\n", txdesc, txdesc->np, txdesc->pktsize, txdesc->stat); - nllvdbg(" txnext=%p {%06x, %u, %04x} trp=%02x%02x\n", + nllvdbg("txnext=%p {%06x, %u, %04x} trp=%02x%02x\n", txnext, txnext->np, txnext->pktsize, txnext->stat, - inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); /* Setup the TX timeout watchdog (perhaps restarting the timer) */ @@ -1323,7 +1323,7 @@ static int ez80emac_receive(struct ez80emac_driver_s *priv) static int ez80emac_txinterrupt(int irq, FAR void *context) { FAR struct ez80emac_driver_s *priv = &g_emac; - FAR struct ez80emac_desc_s *txdesc = priv->txhead; + FAR struct ez80emac_desc_s *txhead = priv->txhead; ubyte regval; ubyte istat; @@ -1340,74 +1340,72 @@ static int ez80emac_txinterrupt(int irq, FAR void *context) istat = inp(EZ80_EMAC_ISTAT) & EMAC_ISTAT_TXEVENTS; outp(EZ80_EMAC_ISTAT, istat); + EMAC_STAT(priv, tx_int); + /* All events are packet/control frame transmit complete events */ nvdbg("txhead=%p {%06x, %u, %04x} trp=%02x%02x istat=%02x\n", - txdesc, txdesc->np, txdesc->pktsize, txdesc->stat, + txhead, txhead->np, txhead->pktsize, txhead->stat, inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L), istat); - EMAC_STAT(priv, tx_int); - - /* Check if the packet is still owned by the hardware */ + /* Handle all packets in the list that are no longer owned by the hardware */ - if ((txdesc->stat & EMAC_TXDESC_OWNER) != 0) + while (txhead && (txhead->stat & EMAC_TXDESC_OWNER) == 0) { - ndbg("Descriptor %p still owned by H/W {%06x, %u, %04x} trp=%02x%02x istat=%02x\n", - txdesc, txdesc->np, txdesc->pktsize, txdesc->stat, - inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L), istat); - return OK; - } + if ((txhead->stat & EMAC_TXDESC_ABORT) != 0) + { + ndbg("Descriptor %p aborted {%06x, %u, %04x} trp=%02x%02x\n", + txhead, txhead->np, txhead->pktsize, txhead->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); - /* Handle errors */ + EMAC_STAT(priv, tx_errors); + EMAC_STAT(priv, tx_abterrors); + } - else if ((txdesc->stat & EMAC_TXDESC_ABORT) != 0) - { - ndbg("Descriptor %p aborted {%06x, %u, %04x} trp=%02x%02x istat=%02x\n", - txdesc, txdesc->np, txdesc->pktsize, txdesc->stat, - inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L), istat); + /* Get the address of the next Tx descriptor in the list (if any) */ - EMAC_STAT(priv, tx_errors); - EMAC_STAT(priv, tx_abterrors); + txhead = (FAR struct ez80emac_desc_s *)txhead->np; + if (txhead) + { + nvdbg("txhead=%p {%06x, %u, %04x} trp=%02x%02x\n", + txhead, txhead->np, txhead->pktsize, txhead->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + } } - /* Get the address of the next Tx descriptor in the list (if any) */ + /* Save the new head. If it is NULL, then we have read all the way to + * the terminating description with np==NULL. + */ - priv->txhead = (FAR struct ez80emac_desc_s *)txdesc->np; + priv->txhead = txhead; if (!priv->txhead) { - /* No pending TX -- This should never happen because there - * is always a dummy descriptor at the end of the list owned - * by the host. Reset to the beginining of the buffer - * and stop the poll timer + nvdbg("No pending Tx.. Stopping XMIT function.\n"); + + /* Stop the Tx poll timer. (It will get restarted when we have + * something to send */ outp(EZ80_EMAC_PTMR, 0); - priv->txnext = priv->txstart; /* Reset the transmit function. That should force the TRP to be - * the same as TDLP which is the set to txstart. + * the same as TDLP which is then set to txstart. */ +#if 0 // Seems to reset RWP as well ??? + priv->txnext = priv->txstart; + regval = inp(EZ80_EMAC_RST); regval |= EMAC_RST_HRTFN; outp(EZ80_EMAC_RST, regval); regval &= ~EMAC_RST_HRTFN; outp(EZ80_EMAC_RST, regval); +#endif - /* If no further xmits are pending, then cancel the TX timeout */ + /* Cancel any pending the TX timeout */ wd_cancel(priv->txtimeout); } - - /* Clean up the old Tx descriptor -- not really necessary */ - - txdesc->np = 0; - txdesc->pktsize = 0; - txdesc->stat = 0; - - nvdbg("New txhead=%p {%06x, %u, %04x} trp=%02x%02x istat=%02x\n", - priv->txhead, priv->txhead->np, priv->txhead->pktsize, priv->txhead->stat, - inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L), istat); return OK; } |