Misc receive improvements
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3125 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
29595f874a
commit
e1c4208b12
@ -896,16 +896,19 @@ static void lpc17_rxdone(struct lpc17_driver_s *priv)
|
|||||||
|
|
||||||
EMAC_STAT(priv, rx_packets);
|
EMAC_STAT(priv, rx_packets);
|
||||||
|
|
||||||
/* Get the Rx status and packet length */
|
/* Get the Rx status and packet length (-4+1) */
|
||||||
|
|
||||||
rxstat = (uint32_t*)(LPC17_RXSTAT_BASE + (considx << 3));
|
rxstat = (uint32_t*)(LPC17_RXSTAT_BASE + (considx << 3));
|
||||||
pktlen = (*rxstat & RXSTAT_INFO_RXSIZE_MASK) + 1;
|
pktlen = (*rxstat & RXSTAT_INFO_RXSIZE_MASK) - 3;
|
||||||
|
|
||||||
/* Check for errors */
|
/* Check for errors. NOTE: The DMA engine reports bogus length errors,
|
||||||
|
* making this a pretty useless check.
|
||||||
|
*/
|
||||||
|
|
||||||
if ((*rxstat & RXSTAT_INFO_ERROR) != 0)
|
if ((*rxstat & RXSTAT_INFO_ERROR) != 0)
|
||||||
{
|
{
|
||||||
nlldbg("Error. rxstat: %08x\n", *rxstat);
|
nlldbg("Error. considx: %08x prodidx: %08x rxstat: %08x\n",
|
||||||
|
considx, prodidx, *rxstat);
|
||||||
EMAC_STAT(priv, rx_pkterr);
|
EMAC_STAT(priv, rx_pkterr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -915,20 +918,23 @@ static void lpc17_rxdone(struct lpc17_driver_s *priv)
|
|||||||
* imply that the packet is too big.
|
* imply that the packet is too big.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if (pktlen > CONFIG_NET_BUFSIZE+2)
|
/* else */ if (pktlen > CONFIG_NET_BUFSIZE+2)
|
||||||
{
|
{
|
||||||
nlldbg("Too big. pktlen: %d rxstat: %08x\n", pktlen, *rxstat);
|
nlldbg("Too big. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n",
|
||||||
|
considx, prodidx, pktlen, *rxstat);
|
||||||
EMAC_STAT(priv, rx_pktsize);
|
EMAC_STAT(priv, rx_pktsize);
|
||||||
}
|
}
|
||||||
else if ((*rxstat & RXSTAT_INFO_LASTFLAG) == 0)
|
else if ((*rxstat & RXSTAT_INFO_LASTFLAG) == 0)
|
||||||
{
|
{
|
||||||
nlldbg("Fragment. rxstat: %08x\n", pktlen, *rxstat);
|
nlldbg("Fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n",
|
||||||
|
considx, prodidx, pktlen, *rxstat);
|
||||||
EMAC_STAT(priv, rx_fragment);
|
EMAC_STAT(priv, rx_fragment);
|
||||||
fragment = true;
|
fragment = true;
|
||||||
}
|
}
|
||||||
else if (fragment)
|
else if (fragment)
|
||||||
{
|
{
|
||||||
nlldbg("Last fragment. rxstat: %08x\n", pktlen, *rxstat);
|
nlldbg("Last fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n",
|
||||||
|
considx, prodidx, pktlen, *rxstat);
|
||||||
EMAC_STAT(priv, rx_fragment);
|
EMAC_STAT(priv, rx_fragment);
|
||||||
fragment = false;
|
fragment = false;
|
||||||
}
|
}
|
||||||
@ -1115,13 +1121,16 @@ static int lpc17_interrupt(int irq, void *context)
|
|||||||
status = lpc17_getreg(LPC17_ETH_INTST);
|
status = lpc17_getreg(LPC17_ETH_INTST);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
|
/* Clear all pending interrupts */
|
||||||
|
|
||||||
|
lpc17_putreg(status, LPC17_ETH_INTCLR);
|
||||||
|
|
||||||
/* Handle each pending interrupt **************************************/
|
/* Handle each pending interrupt **************************************/
|
||||||
/* Check for Wake-Up on Lan *******************************************/
|
/* Check for Wake-Up on Lan *******************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_WOL
|
#ifdef CONFIG_NET_WOL
|
||||||
if ((status & ETH_INT_WKUP) != 0)
|
if ((status & ETH_INT_WKUP) != 0)
|
||||||
{
|
{
|
||||||
lpc17_putreg(ETH_INT_WKUP, LPC17_ETH_INTCLR);
|
|
||||||
EMAC_STAT(priv, wol);
|
EMAC_STAT(priv, wol);
|
||||||
# warning "Missing logic"
|
# warning "Missing logic"
|
||||||
}
|
}
|
||||||
@ -1142,13 +1151,13 @@ static int lpc17_interrupt(int irq, void *context)
|
|||||||
{
|
{
|
||||||
if ((status & ETH_INT_RXOVR) != 0)
|
if ((status & ETH_INT_RXOVR) != 0)
|
||||||
{
|
{
|
||||||
lpc17_putreg(ETH_INT_RXOVR, LPC17_ETH_INTCLR);
|
nlldbg("RX Overrun. status: %08x\n", status);
|
||||||
EMAC_STAT(priv, rx_ovrerrors);
|
EMAC_STAT(priv, rx_ovrerrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status & ETH_INT_TXUNR) != 0)
|
if ((status & ETH_INT_TXUNR) != 0)
|
||||||
{
|
{
|
||||||
lpc17_putreg(ETH_INT_TXUNR, LPC17_ETH_INTCLR);
|
nlldbg("TX Underrun. status: %08x\n", status);
|
||||||
EMAC_STAT(priv, tx_underrun);
|
EMAC_STAT(priv, tx_underrun);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1160,82 +1169,79 @@ static int lpc17_interrupt(int irq, void *context)
|
|||||||
{
|
{
|
||||||
/* Check for receive events ***************************************/
|
/* Check for receive events ***************************************/
|
||||||
/* RX ERROR -- Triggered on receive errors: AlignmentError,
|
/* RX ERROR -- Triggered on receive errors: AlignmentError,
|
||||||
* RangeError, LengthError, SymbolError, CRCError or
|
* RangeError, LengthError, SymbolError, CRCError or NoDescriptor
|
||||||
* NoDescriptor or Overrun.
|
* or Overrun. NOTE: (1) We will still need to call lpc17_rxdone
|
||||||
|
* on RX errors to bump the considx over the bad packet. (2) The
|
||||||
|
* DMA engine reports bogus length errors, making this a pretty
|
||||||
|
* useless check anyway.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((status & ETH_INT_RXERR) != 0)
|
if ((status & ETH_INT_RXERR) != 0)
|
||||||
{
|
{
|
||||||
lpc17_putreg(ETH_INT_RXERR, LPC17_ETH_INTCLR);
|
nlldbg("RX Error. status: %08x\n", status);
|
||||||
EMAC_STAT(priv, rx_errors);
|
EMAC_STAT(priv, rx_errors);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* RX FINISHED -- Triggered when all receive descriptors have
|
||||||
|
* been processed i.e. on the transition to the situation
|
||||||
|
* where ProduceIndex == ConsumeIndex.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((status & ETH_INT_RXFIN) != 0)
|
||||||
{
|
{
|
||||||
/* RX FINISHED -- Triggered when all receive descriptors have
|
EMAC_STAT(priv, rx_finished);
|
||||||
* been processed i.e. on the transition to the situation
|
DEBUGASSERT(lpc17_getreg(LPC17_ETH_RXPRODIDX) == lpc17_getreg(LPC17_ETH_RXCONSIDX));
|
||||||
* where ProduceIndex == ConsumeIndex.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((status & ETH_INT_RXFIN) != 0)
|
|
||||||
{
|
|
||||||
lpc17_putreg(ETH_INT_RXFIN, LPC17_ETH_INTCLR);
|
|
||||||
EMAC_STAT(priv, rx_finished);
|
|
||||||
DEBUGASSERT(lpc17_getreg(LPC17_ETH_RXPRODIDX) == lpc17_getreg(LPC17_ETH_RXCONSIDX));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RX DONE -- Triggered when a receive descriptor has been
|
|
||||||
* processed while the Interrupt bit in the Control field of
|
|
||||||
* the descriptor was set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((status & ETH_INT_RXDONE) != 0)
|
|
||||||
{
|
|
||||||
lpc17_putreg(ETH_INT_RXDONE, LPC17_ETH_INTCLR);
|
|
||||||
EMAC_STAT(priv, rx_done);
|
|
||||||
|
|
||||||
/* We have received at least one new incoming packet. */
|
|
||||||
|
|
||||||
lpc17_rxdone(priv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RX DONE -- Triggered when a receive descriptor has been
|
||||||
|
* processed while the Interrupt bit in the Control field of
|
||||||
|
* the descriptor was set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((status & ETH_INT_RXDONE) != 0)
|
||||||
|
{
|
||||||
|
EMAC_STAT(priv, rx_done);
|
||||||
|
|
||||||
|
/* We have received at least one new incoming packet. */
|
||||||
|
|
||||||
|
lpc17_rxdone(priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for Tx events ********************************************/
|
/* Check for Tx events ********************************************/
|
||||||
/* TX ERROR -- Triggered on transmit errors: LateCollision,
|
/* TX ERROR -- Triggered on transmit errors: LateCollision,
|
||||||
* ExcessiveCollision and ExcessiveDefer, NoDescriptor or Underrun.
|
* ExcessiveCollision and ExcessiveDefer, NoDescriptor or Underrun.
|
||||||
|
* NOTE: We will still need to call lpc17_txdone() in order to
|
||||||
|
* clean up after the failed transmit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((status & ETH_INT_TXERR) != 0)
|
if ((status & ETH_INT_TXERR) != 0)
|
||||||
{
|
{
|
||||||
lpc17_putreg(ETH_INT_TXERR, LPC17_ETH_INTCLR);
|
nlldbg("TX Error. status: %08x\n", status);
|
||||||
EMAC_STAT(priv, tx_errors);
|
EMAC_STAT(priv, tx_errors);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* TX FINISHED -- Triggered when all transmit descriptors have
|
||||||
|
* been processed i.e. on the transition to the situation
|
||||||
|
* where ProduceIndex == ConsumeIndex.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((status & ETH_INT_TXFIN) != 0)
|
||||||
{
|
{
|
||||||
/* TX FINISHED -- Triggered when all transmit descriptors have
|
EMAC_STAT(priv, tx_finished);
|
||||||
* been processed i.e. on the transition to the situation
|
}
|
||||||
* where ProduceIndex == ConsumeIndex.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((status & ETH_INT_TXFIN) != 0)
|
/* TX DONE -- Triggered when a descriptor has been transmitted
|
||||||
{
|
* while the Interrupt bit in the Control field of the
|
||||||
lpc17_putreg(ETH_INT_TXFIN, LPC17_ETH_INTCLR);
|
* descriptor was set.
|
||||||
EMAC_STAT(priv, tx_finished);
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
/* TX DONE -- Triggered when a descriptor has been transmitted
|
if ((status & ETH_INT_TXDONE) != 0)
|
||||||
* while the Interrupt bit in the Control field of the
|
{
|
||||||
* descriptor was set.
|
EMAC_STAT(priv, tx_done);
|
||||||
*/
|
|
||||||
|
|
||||||
if ((status & ETH_INT_TXDONE) != 0)
|
/* A packet transmission just completed */
|
||||||
{
|
|
||||||
lpc17_putreg(ETH_INT_TXDONE, LPC17_ETH_INTCLR);
|
|
||||||
EMAC_STAT(priv, tx_done);
|
|
||||||
|
|
||||||
/* A packet transmission just completed */
|
lpc17_txdone(priv);
|
||||||
|
|
||||||
lpc17_txdone(priv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user