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
This commit is contained in:
parent
85d77c281b
commit
328d303684
@ -662,5 +662,9 @@
|
||||
* net/uip: Correct UDP bind behavior. It should select a valid port number
|
||||
if it receives a port number of zero.
|
||||
* netutils/dhcpd: Corrrect for ZDS compiler. Fix issue with re-use of a
|
||||
port number. Fix a number of broadcast-related problems.
|
||||
port number. Fixed a number of broadcast-related problems.
|
||||
* eZ80Acclaim!: Add a tiny webserver configuration
|
||||
* eZ80Acclaim!: Fixed an important bug in the EMAC Tx timeout logic. It was
|
||||
always timing out when the load was heavy and worse, for some reason,
|
||||
resetting the Tx function caused unexpected registers to be reset in
|
||||
the Rcv function was well.
|
||||
|
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: March 21, 2009</p>
|
||||
<p>Last Updated: March 22, 2009</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -1353,8 +1353,12 @@ nuttx-0.4.4 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* net/uip: Correct UDP bind behavior. It should select a valid port number
|
||||
if it receives a port number of zero.
|
||||
* netutils/dhcpd: Corrrect for ZDS compiler. Fix issue with re-use of a
|
||||
port number. Fix a number of broadcast-related problems.
|
||||
port number. Fixed a number of broadcast-related problems.
|
||||
* eZ80Acclaim!: Add a tiny webserver configuration
|
||||
* eZ80Acclaim!: Fixed an important bug in the EMAC Tx timeout logic. It was
|
||||
always timing out when the load was heavy and worse, for some reason,
|
||||
resetting the Tx function caused unexpected registers to be reset in
|
||||
the Rcv function was well.
|
||||
|
||||
pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
@ -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,7 +1025,7 @@ 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",
|
||||
txnext, txnext->np, txnext->pktsize, txnext->stat,
|
||||
@ -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,31 +1340,23 @@ 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);
|
||||
/* Handle all packets in the list that are no longer owned by the hardware */
|
||||
|
||||
/* Check if the packet is still 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;
|
||||
}
|
||||
|
||||
/* Handle errors */
|
||||
|
||||
else if ((txdesc->stat & EMAC_TXDESC_ABORT) != 0)
|
||||
if ((txhead->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);
|
||||
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));
|
||||
|
||||
EMAC_STAT(priv, tx_errors);
|
||||
EMAC_STAT(priv, tx_abterrors);
|
||||
@ -1372,43 +1364,49 @@ static int ez80emac_txinterrupt(int irq, FAR void *context)
|
||||
|
||||
/* Get the address of the next Tx descriptor in the list (if any) */
|
||||
|
||||
priv->txhead = (FAR struct ez80emac_desc_s *)txdesc->np;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the new head. If it is NULL, then we have read all the way to
|
||||
* the terminating description with np==NULL.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user