Clean up transmit buffer realignment.

Many thanks to Mr. Kolja Waschk for identifying the problem.
This commit is contained in:
Eric Norum
2005-06-20 20:48:48 +00:00
parent 3f0bb34c6e
commit f077cc96df
3 changed files with 85 additions and 75 deletions

View File

@@ -1,3 +1,8 @@
2005-06-20 Eric Norum <norume@aps.anl.gov>
* network/network.c: Clean up transmit buffer realignment. Many thanks to
Mr. Kolja Waschk for identifying the problem.
2005-05-26 Ralf Corsepius <ralf.corsepius@rtems.org> 2005-05-26 Ralf Corsepius <ralf.corsepius@rtems.org>
* include/bsp.h: New header guard. * include/bsp.h: New header guard.

View File

@@ -87,7 +87,7 @@ port into RAM then executed or programmed into flash memory.
4) Run 'tftp' on your host machine: 4) Run 'tftp' on your host machine:
tftp> binary tftp> binary
tftp> connect www.xxx.yyy.zzz (Your ucDIMM's address) tftp> connect www.xxx.yyy.zzz (Your ucDIMM's address)
tftp> put someFile.exe tftp> put someFile.exe (someFile.boot for the EPICS build system)
5) When the file has downloaded press the <ESC> key to terminate 5) When the file has downloaded press the <ESC> key to terminate
the uCDIMM tftp command. the uCDIMM tftp command.

View File

@@ -1,10 +1,5 @@
/* /*
* RTEMS/TCPIP driver for MCF5282 Fast Ethernet Controller * RTEMS/TCPIP driver for MCF5282 Fast Ethernet Controller
*
* TO DO: Check network stack code -- Is it possible force longword alignment
* of all tx mbufs? If so, the stupid
* realignment code in the output routine
* could be removed.
*/ */
#include <bsp.h> #include <bsp.h>
@@ -103,7 +98,7 @@ struct mcf5282_enet_struct {
unsigned long txInterrupts; unsigned long txInterrupts;
unsigned long txRawWait; unsigned long txRawWait;
unsigned long txRealign; unsigned long txRealign;
unsigned long txRealignBytes; unsigned long txRealignDrop;
}; };
static struct mcf5282_enet_struct enet_driver[NIFACES]; static struct mcf5282_enet_struct enet_driver[NIFACES];
@@ -320,11 +315,14 @@ static void
fec_retire_tx_bd(volatile struct mcf5282_enet_struct *sc ) fec_retire_tx_bd(volatile struct mcf5282_enet_struct *sc )
{ {
struct mbuf *m, *n; struct mbuf *m, *n;
uint16_t status;
while ((sc->txBdActiveCount != 0) while ((sc->txBdActiveCount != 0)
&& ((sc->txBdBase[sc->txBdTail].status & MCF5282_FEC_TxBD_R) == 0)) { && (((status = sc->txBdBase[sc->txBdTail].status) & MCF5282_FEC_TxBD_R) == 0)) {
if ((status & MCF5282_FEC_TxBD_TO1) == 0) {
m = sc->txMbuf[sc->txBdTail]; m = sc->txMbuf[sc->txBdTail];
MFREE(m, n); MFREE(m, n);
}
if (++sc->txBdTail == sc->txBdCount) if (++sc->txBdTail == sc->txBdCount)
sc->txBdTail = 0; sc->txBdTail = 0;
sc->txBdActiveCount--; sc->txBdActiveCount--;
@@ -337,7 +335,7 @@ fec_rxDaemon (void *arg)
volatile struct mcf5282_enet_struct *sc = (volatile struct mcf5282_enet_struct *)arg; volatile struct mcf5282_enet_struct *sc = (volatile struct mcf5282_enet_struct *)arg;
struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if; struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if;
struct mbuf *m; struct mbuf *m;
volatile uint16_t status; uint16_t status;
volatile mcf5282BufferDescriptor_t *rxBd; volatile mcf5282BufferDescriptor_t *rxBd;
int rxBdIndex; int rxBdIndex;
@@ -454,6 +452,7 @@ fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
struct mcf5282_enet_struct *sc = ifp->if_softc; struct mcf5282_enet_struct *sc = ifp->if_softc;
volatile mcf5282BufferDescriptor_t *firstTxBd, *txBd; volatile mcf5282BufferDescriptor_t *firstTxBd, *txBd;
uint16_t status; uint16_t status;
int offset;
int nAdded; int nAdded;
/* /*
@@ -471,7 +470,7 @@ fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
nAdded = 0; nAdded = 0;
firstTxBd = sc->txBdBase + sc->txBdHead; firstTxBd = sc->txBdBase + sc->txBdHead;
for (;;) { while (m != NULL) {
/* /*
* Wait for buffer descriptor to become available * Wait for buffer descriptor to become available
*/ */
@@ -517,43 +516,53 @@ fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
txBd = sc->txBdBase + sc->txBdHead; txBd = sc->txBdBase + sc->txBdHead;
if (m->m_len) { if (m->m_len) {
char *p = mtod(m, char *); char *p = mtod(m, char *);
/* if ((offset = (int)p & 0x3) == 0) {
* Stupid FEC can't handle misaligned data!
* Given the way that mbuf's are layed out it should be
* safe to shuffle the data down like this.....
* Perhaps this code could be improved with a "Duff's Device".
*/
if ((int)p & 0x3) {
int l = m->m_len;
char *dest = p - ((int)p & 0x3);
uint16_t *o = (uint16_t *)dest, *i = (uint16_t *)p;
while (l > 0) {
*o++ = *i++;
l -= sizeof(uint16_t);
}
p = dest;
sc->txRealign++;
sc->txRealignBytes += m->m_len;
}
txBd->buffer = p; txBd->buffer = p;
txBd->length = m->m_len; txBd->length = m->m_len;
sc->txMbuf[sc->txBdHead] = m; sc->txMbuf[sc->txBdHead] = m;
m = m->m_next;
}
else {
/*
* Stupid FEC can't handle misaligned data!
* Move offending bytes to a local buffer.
* Use buffer descriptor TO1 bit to indicate this.
*/
int nmove = 4 - offset;
char *d = (char *)&sc->txMbuf[sc->txBdHead];
status |= MCF5282_FEC_TxBD_TO1;
sc->txRealign++;
if (nmove > m->m_len)
nmove = m->m_len;
m->m_data += nmove;
m->m_len -= nmove;
txBd->buffer = d;
txBd->length = nmove;
while (nmove--)
*d++ = *p++;
if (m->m_len == 0) {
struct mbuf *n;
sc->txRealignDrop++;
MFREE(m, n);
m = n;
}
}
nAdded++; nAdded++;
if (++sc->txBdHead == sc->txBdCount) { if (++sc->txBdHead == sc->txBdCount) {
status |= MCF5282_FEC_TxBD_W; status |= MCF5282_FEC_TxBD_W;
sc->txBdHead = 0; sc->txBdHead = 0;
} }
m = m->m_next; txBd->status = status;
} }
else { else {
/* /*
* Just toss empty mbufs * Toss empty mbufs.
*/ */
struct mbuf *n; struct mbuf *n;
MFREE(m, n); MFREE(m, n);
m = n; m = n;
} }
if (m == NULL) { }
if (nAdded) { if (nAdded) {
txBd->status = status | MCF5282_FEC_TxBD_R txBd->status = status | MCF5282_FEC_TxBD_R
| MCF5282_FEC_TxBD_L | MCF5282_FEC_TxBD_L
@@ -563,10 +572,6 @@ fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
MCF5282_FEC_TDAR = 0; MCF5282_FEC_TDAR = 0;
sc->txBdActiveCount += nAdded; sc->txBdActiveCount += nAdded;
} }
break;
}
txBd->status = status;
}
} }
void void
@@ -699,8 +704,8 @@ enet_stats(struct mcf5282_enet_struct *sc)
printf(" Rx Octets OK:%-10lu\n", MCF5282_FEC_IEEE_R_OCTETS_OK); printf(" Rx Octets OK:%-10lu\n", MCF5282_FEC_IEEE_R_OCTETS_OK);
printf(" Tx Interrupts:%-10lu", sc->txInterrupts); printf(" Tx Interrupts:%-10lu", sc->txInterrupts);
printf("Tx Output Waits:%-10lu", sc->txRawWait); printf("Tx Output Waits:%-10lu", sc->txRawWait);
printf("Tx Realignments:%-10lu\n", sc->txRealign); printf("Tx mbuf realign:%-10lu\n", sc->txRealign);
printf(" Tx RealignByte:%-10lu", sc->txRealignBytes); printf("Tx realign drop:%-10lu", sc->txRealignDrop);
printf(" Tx Unaccounted:%-10lu", MCF5282_FEC_RMON_T_DROP); printf(" Tx Unaccounted:%-10lu", MCF5282_FEC_RMON_T_DROP);
printf("Tx Packet Count:%-10lu\n", MCF5282_FEC_RMON_T_PACKETS); printf("Tx Packet Count:%-10lu\n", MCF5282_FEC_RMON_T_PACKETS);
printf(" Tx Broadcast:%-10lu", MCF5282_FEC_RMON_T_BC_PKT); printf(" Tx Broadcast:%-10lu", MCF5282_FEC_RMON_T_BC_PKT);
@@ -746,7 +751,7 @@ enet_stats(struct mcf5282_enet_struct *sc)
* Yes, there are races here with adding and retiring descriptors, * Yes, there are races here with adding and retiring descriptors,
* but this diagnostic is more for when things have backed up. * but this diagnostic is more for when things have backed up.
*/ */
printf("Transmit Buffer Descriptors (Tail %d, Head %d, Active %d):\n", printf("Transmit Buffer Descriptors (Tail %d, Head %d, Unretired %d):\n",
sc->txBdTail, sc->txBdTail,
sc->txBdHead, sc->txBdHead,
sc->txBdActiveCount); sc->txBdActiveCount);