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
|
* net/uip: Correct UDP bind behavior. It should select a valid port number
|
||||||
if it receives a port number of zero.
|
if it receives a port number of zero.
|
||||||
* netutils/dhcpd: Corrrect for ZDS compiler. Fix issue with re-use of a
|
* 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!: 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">
|
<tr align="center" bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</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
|
* net/uip: Correct UDP bind behavior. It should select a valid port number
|
||||||
if it receives a port number of zero.
|
if it receives a port number of zero.
|
||||||
* netutils/dhcpd: Corrrect for ZDS compiler. Fix issue with re-use of a
|
* 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!: 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>
|
pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ struct ez80emac_driver_s
|
|||||||
* Tx/Rx memory).
|
* Tx/Rx memory).
|
||||||
* txhead: Points to the oldest Tx descriptor queued for output (but for
|
* txhead: Points to the oldest Tx descriptor queued for output (but for
|
||||||
* which output has not yet completed. Initialized to NULL; set
|
* 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
|
* when Tx processing completes. txhead == NULL is also a sure
|
||||||
* indication that there is no Tx in progress.
|
* indication that there is no Tx in progress.
|
||||||
* txnext: Points to the next free Tx descriptor. Initialized to txstart; set
|
* 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!
|
* 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,
|
priv->txnext, priv->txnext->np, priv->txnext->pktsize, priv->txnext->stat,
|
||||||
inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L));
|
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);
|
outp(EZ80_EMAC_PTMR, EMAC_PTMR);
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
|
|
||||||
nllvdbg("EXIT: txdesc=%p {%06x, %u, %04x}\n",
|
nllvdbg("txdesc=%p {%06x, %u, %04x}\n",
|
||||||
txdesc, txdesc->np, txdesc->pktsize, txdesc->stat);
|
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,
|
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)
|
static int ez80emac_txinterrupt(int irq, FAR void *context)
|
||||||
{
|
{
|
||||||
FAR struct ez80emac_driver_s *priv = &g_emac;
|
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 regval;
|
||||||
ubyte istat;
|
ubyte istat;
|
||||||
|
|
||||||
@ -1340,31 +1340,23 @@ static int ez80emac_txinterrupt(int irq, FAR void *context)
|
|||||||
istat = inp(EZ80_EMAC_ISTAT) & EMAC_ISTAT_TXEVENTS;
|
istat = inp(EZ80_EMAC_ISTAT) & EMAC_ISTAT_TXEVENTS;
|
||||||
outp(EZ80_EMAC_ISTAT, istat);
|
outp(EZ80_EMAC_ISTAT, istat);
|
||||||
|
|
||||||
|
EMAC_STAT(priv, tx_int);
|
||||||
|
|
||||||
/* All events are packet/control frame transmit complete events */
|
/* All events are packet/control frame transmit complete events */
|
||||||
|
|
||||||
nvdbg("txhead=%p {%06x, %u, %04x} trp=%02x%02x istat=%02x\n",
|
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);
|
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 */
|
while (txhead && (txhead->stat & EMAC_TXDESC_OWNER) == 0)
|
||||||
|
|
||||||
if ((txdesc->stat & EMAC_TXDESC_OWNER) != 0)
|
|
||||||
{
|
{
|
||||||
ndbg("Descriptor %p still owned by H/W {%06x, %u, %04x} trp=%02x%02x istat=%02x\n",
|
if ((txhead->stat & EMAC_TXDESC_ABORT) != 0)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
ndbg("Descriptor %p aborted {%06x, %u, %04x} trp=%02x%02x istat=%02x\n",
|
ndbg("Descriptor %p aborted {%06x, %u, %04x} trp=%02x%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);
|
inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L));
|
||||||
|
|
||||||
EMAC_STAT(priv, tx_errors);
|
EMAC_STAT(priv, tx_errors);
|
||||||
EMAC_STAT(priv, tx_abterrors);
|
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) */
|
/* 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)
|
if (!priv->txhead)
|
||||||
{
|
{
|
||||||
/* No pending TX -- This should never happen because there
|
nvdbg("No pending Tx.. Stopping XMIT function.\n");
|
||||||
* is always a dummy descriptor at the end of the list owned
|
|
||||||
* by the host. Reset to the beginining of the buffer
|
/* Stop the Tx poll timer. (It will get restarted when we have
|
||||||
* and stop the poll timer
|
* something to send
|
||||||
*/
|
*/
|
||||||
|
|
||||||
outp(EZ80_EMAC_PTMR, 0);
|
outp(EZ80_EMAC_PTMR, 0);
|
||||||
priv->txnext = priv->txstart;
|
|
||||||
|
|
||||||
/* Reset the transmit function. That should force the TRP to be
|
/* 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 = inp(EZ80_EMAC_RST);
|
||||||
regval |= EMAC_RST_HRTFN;
|
regval |= EMAC_RST_HRTFN;
|
||||||
outp(EZ80_EMAC_RST, regval);
|
outp(EZ80_EMAC_RST, regval);
|
||||||
regval &= ~EMAC_RST_HRTFN;
|
regval &= ~EMAC_RST_HRTFN;
|
||||||
outp(EZ80_EMAC_RST, regval);
|
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);
|
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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user