Can send and receive packets but fails when TDA wraps. There appears

to be a problem with overwriting the TX descriptors during an RX.
This commit is contained in:
Joel Sherrill
1999-01-31 20:46:52 +00:00
parent 07d880f4bc
commit 7dbab7204f
2 changed files with 113 additions and 45 deletions

View File

@@ -63,13 +63,31 @@ void break_when_you_get_here();
#define SONIC_DEBUG_CAM 0x0008
#define SONIC_DEBUG_DESCRIPTORS 0x0010
#define SONIC_DEBUG_ERRORS 0x0020
#define SONIC_DEBUG_DUMP_TX_MBUFS 0x0040
#define SONIC_DEBUG_DUMP_RX_MBUFS 0x0080
#define SONIC_DEBUG (SONIC_DEBUG_ERRORS)
#define SONIC_DEBUG_DUMP_MBUFS \
(SONIC_DEBUG_DUMP_TX_MBUFS|SONIC_DEBUG_DUMP_RX_MBUFS)
#define SONIC_DEBUG_MEDIUM \
((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_PRINT_REGISTERS|SONIC_DEBUG_DUMP_MBUFS))
/*
((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_DUMP_MBUFS))
*/
#define SONIC_DEBUG SONIC_DEBUG_ALL
/* ((SONIC_DEBUG_ALL) & ~SONIC_DEBUG_PRINT_REGISTERS) */
/* (SONIC_DEBUG_ALL) */
/* (SONIC_DEBUG_ALL) */
/* (SONIC_DEBUG_ERRORS) */
/* (SONIC_DEBUG_MEMORY|SONIC_DEBUG_DESCRIPTORS) */
/* SONIC_DEBUG_ALL */
#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_MBUFS)
#include <rtems/dumpbuf.h>
#endif
/*
* XXX
@@ -139,7 +157,7 @@ void break_when_you_get_here();
* Default sizes of transmit and receive descriptor areas
*/
#define RDA_COUNT 20
#define TDA_COUNT 100
#define TDA_COUNT 10
/*
*
@@ -196,6 +214,13 @@ struct sonic_softc {
*/
void *sonic;
/*
* Tables to map the mbufs from chip to stack
*/
struct mbuf **rxMbuf;
struct mbuf **txMbuf;
/*
* Interrupt vector
*/
@@ -305,9 +330,9 @@ SONIC_STATIC void * sonic_allocate(unsigned int nbytes)
* Change malloc to malloc_noncacheable_guarded.
*/
p = malloc( nbytes, M_MBUF, M_NOWAIT );
memset (p, '\0', nbytes);
if (p == NULL)
rtems_panic ("No memory!");
memset (p, '\0', nbytes);
a1 = (unsigned long)p;
a2 = a1 + nbytes - 1;
if ((a1 >> 16) == (a2 >> 16))
@@ -372,6 +397,7 @@ SONIC_STATIC void sonic_stats (struct sonic_softc *sc)
SONIC_STATIC rtems_isr sonic_interrupt_handler (rtems_vector_number v)
{
struct sonic_softc *sc = sonic_softc;
unsigned32 isr, imr;
void *rp;
#if (NSONIC > 1)
@@ -393,16 +419,15 @@ SONIC_STATIC rtems_isr sonic_interrupt_handler (rtems_vector_number v)
sc->Interrupts++;
isr = sonic_read_register( rp, SONIC_REG_ISR );
imr = sonic_read_register( rp, SONIC_REG_IMR );
/*
* Packet received or receive buffer area exceeded?
*/
if ((sonic_read_register( rp, SONIC_REG_IMR ) & (IMR_PRXEN | IMR_RBAEEN)) &&
(sonic_read_register( rp, SONIC_REG_ISR ) & (ISR_PKTRX | ISR_RBAE))) {
sonic_write_register(
rp,
SONIC_REG_IMR,
sonic_read_register( rp, SONIC_REG_IMR) & ~(IMR_PRXEN | IMR_RBAEEN)
);
if ((imr & (IMR_PRXEN | IMR_RBAEEN)) &&
(isr & (ISR_PKTRX | ISR_RBAE))) {
imr &= ~(IMR_PRXEN | IMR_RBAEEN);
sc->rxInterrupts++;
rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
}
@@ -410,17 +435,14 @@ SONIC_STATIC rtems_isr sonic_interrupt_handler (rtems_vector_number v)
/*
* Packet started, transmitter done or transmitter error?
*/
if ((sonic_read_register( rp, SONIC_REG_IMR ) & (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN))
&& (sonic_read_register( rp, SONIC_REG_ISR ) & (ISR_PINT | ISR_TXDN | ISR_TXER))) {
sonic_write_register(
rp,
SONIC_REG_IMR,
sonic_read_register( rp, SONIC_REG_IMR) &
~(IMR_PINTEN | IMR_PTXEN | IMR_TXEREN)
);
if ((imr & (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN)) &&
(isr & (ISR_PINT | ISR_TXDN | ISR_TXER))) {
imr &= ~(IMR_PINTEN | IMR_PTXEN | IMR_TXEREN);
sc->txInterrupts++;
rtems_event_send (sc->txDaemonTid, INTERRUPT_EVENT);
}
sonic_write_register( rp, SONIC_REG_IMR, imr );
}
/*
@@ -601,12 +623,18 @@ SONIC_STATIC void sonic_sendpacket (struct ifnet *ifp, struct mbuf *m)
fp->frag_msw = MSW(p);
fp->frag_size = m->m_len;
packetSize += m->m_len;
#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
printf( "fp %p 0x%04x%04x %d=%d .. %d\n",
fp, fp->frag_msw, fp->frag_lsw, fp->frag_size, m->m_len, packetSize );
#endif
#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_TX_MBUFS)
Dump_Buffer(
p,
(fp->frag_size > MAXIMUM_FRAME_SIZE) ? MAXIMUM_FRAME_SIZE : fp->frag_size
);
#endif
l = m;
m = m->m_next;
#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
printf( "fp %p 0x%04x%04x %d\n",
fp, fp->frag_msw, fp->frag_lsw, fp->frag_size );
#endif
}
else {
struct mbuf *n;
@@ -657,7 +685,8 @@ SONIC_STATIC void sonic_sendpacket (struct ifnet *ifp, struct mbuf *m)
sc->tdaActiveCount++;
sc->tdaHead = tdp;
sonic_enable_interrupts( rp, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
/* XXX */
/* sonic_enable_interrupts( rp, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) ); */
sonic_write_register( rp, SONIC_REG_CR, CR_TXP );
}
@@ -858,6 +887,7 @@ SONIC_STATIC void sonic_rxDaemon (void *arg)
ReceiveDescriptorPointer_t rdp;
ReceiveResourcePointer_t rwp, rea;
rtems_unsigned16 newMissedTally, oldMissedTally;
unsigned32 rxMbufIndex;
rwp = sc->rsa;
rea = sc->rea;
@@ -867,12 +897,11 @@ SONIC_STATIC void sonic_rxDaemon (void *arg)
* Start the receiver
*/
oldMissedTally = sonic_read_register( rp, SONIC_REG_MPT );
sonic_write_register( rp, SONIC_REG_CR, CR_RRRA );
sonic_write_register( rp, SONIC_REG_CR, CR_RXEN );
/*
* Input packet handling loop
*/
rxMbufIndex = 0;
for (;;) {
/*
* Wait till SONIC supplies a Receive Descriptor.
@@ -890,17 +919,9 @@ SONIC_STATIC void sonic_rxDaemon (void *arg)
*/
status = rdp->status;
if (status & RDA_STATUS_PRX) {
struct mbuf **mp;
struct ether_header *eh;
void *p;
/*
* Get the mbuf pointer
*/
p = PTR(rdp->pkt_msw, rdp->pkt_lsw);
mp = (struct mbuf **)p - 1;
m = *mp;
/*
* Pass the packet up the chain.
* The mbuf count is reduced to remove
@@ -909,11 +930,18 @@ SONIC_STATIC void sonic_rxDaemon (void *arg)
* ===CACHE===
* Invalidate cache entries for this memory.
*/
m = rdp->mbufp;
m->m_len = m->m_pkthdr.len = rdp->byte_count -
sizeof(rtems_unsigned32) -
sizeof(struct ether_header);
eh = mtod (m, struct ether_header *);
m->m_data += sizeof(struct ether_header);
#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_RX_MBUFS)
Dump_Buffer( (void *) eh, sizeof(struct ether_header) );
Dump_Buffer( (void *) m, 96 /* m->m_len*/ );
#endif
ether_input (ifp, eh, m);
/*
@@ -933,20 +961,24 @@ SONIC_STATIC void sonic_rxDaemon (void *arg)
/*
* Allocate a new mbuf.
*/
m= (void *)0xA0000000; /* hope for a fault :) */
MGETHDR (m, M_WAIT, MT_DATA);
MCLGET (m, M_WAIT);
m->m_pkthdr.rcvif = ifp;
mp = mtod (m, struct mbuf **);
m->m_data += sizeof *mp;
*mp = m;
rdp->mbufp = m;
p = mtod (m, void *);
/*
* Reuse Receive Resource.
*/
rwp->buff_ptr_lsw = LSW(p);
rwp->buff_ptr_msw = MSW(p);
rwp->buff_wc_lsw = RBUF_WC;
rwp->buff_wc_msw = 0;
rwp++;
if (rwp == rea) {
#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
printf( "Wrapping RWP from %p to %p\n", rwp, sc->rsa );
@@ -982,9 +1014,11 @@ SONIC_STATIC void sonic_rxDaemon (void *arg)
/*
* Move to next receive descriptor
*/
rdp->in_use = RDA_FREE;
rdp = rdp->next;
rdp->link &= ~RDA_LINK_EOL;
}
}
@@ -1024,6 +1058,19 @@ SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
rtems_fatal_error_occurred( 0x0BADF00D ); /* don't eat this part :) */
}
/*
* Allocate memory so we can figure out from the descriptor which
* mbuf to send to the stack.
*/
sc->txMbuf = malloc (sc->tdaCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
if (!sc->txMbuf)
rtems_panic ("No memory for TX mbuf pointers");
sc->rxMbuf = malloc (sc->rdaCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
if (!sc->rxMbuf)
rtems_panic ("No memory for RX mbuf pointers");
/*
* Set up circular linked list in Transmit Descriptor Area.
* Use the PINT bit in the transmit configuration field to
@@ -1039,6 +1086,11 @@ SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
#endif
tdp = sc->tdaTail;
for (i = 0 ; i < sc->tdaCount ; i++) {
/*
* Start off with the table of outstanding mbuf's
*/
sc->txMbuf[i] = NULL;
/*
* status, pkt_config, pkt_size, and all fragment fields
* are set to zero by sonic_allocate.
@@ -1119,7 +1171,6 @@ SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
rwp = sc->rsa;
for (i = 0 ; i < (sc->rdaCount + RRA_EXTRA_COUNT) ; i++, rwp++) {
struct mbuf **mp;
/*
* Allocate memory for buffer.
@@ -1131,10 +1182,9 @@ SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
MGETHDR (m, M_WAIT, MT_DATA);
MCLGET (m, M_WAIT);
m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
mp = mtod (m, struct mbuf **);
sc->rxMbuf[i] = m;
sc->rda[i].mbufp = m;
m->m_data += sizeof *mp;
*mp = m;
p = mtod (m, void *);
/*
@@ -1167,7 +1217,7 @@ SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
/*
* Mask all interrupts
*/
sonic_write_register( rp, SONIC_REG_IMR, 0x3fff );
sonic_write_register( rp, SONIC_REG_IMR, 0x0 ); /* XXX was backwards */
/*
* Clear outstanding interrupts.
@@ -1292,12 +1342,14 @@ SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
rtems_panic ("SONIC LCAM");
}
sonic_write_register(rp, SONIC_REG_CR, CR_TXP | CR_RXEN | CR_STP);
sonic_write_register(rp, SONIC_REG_CR, /* CR_TXP | */CR_RXEN | CR_STP);
/*
* Attach SONIC interrupt handler
*/
/* XXX
sonic_write_register( rp, SONIC_REG_IMR, 0 );
*/
old_handler = set_vector(sonic_interrupt_handler, sc->vector, 0);
/*
@@ -1361,7 +1413,10 @@ SONIC_STATIC void sonic_init (void *arg)
/*
* Enable receiver and transmitter
*/
sonic_write_register(rp, SONIC_REG_CR, CR_TXP | CR_RXEN);
/* sonic_write_register( rp, SONIC_REG_IMR, 0 ); */
sonic_enable_interrupts( rp, (IMR_PRXEN | IMR_RBAEEN) );
sonic_write_register(rp, SONIC_REG_CR, /* CR_TXP | */ CR_RXEN);
}
/*
@@ -1472,6 +1527,9 @@ rtems_sonic_driver_attach (struct rtems_bsdnet_ifconfig *config)
sc->tdaCount = TDA_COUNT;
sc->acceptBroadcast = !config->ignore_broadcast;
sc->sonic = (void *) SONIC_BASE_ADDRESS;
sc->vector = SONIC_VECTOR;
/*
* Set up network interface values
*/
@@ -1572,6 +1630,10 @@ void sonic_write_register(
)
{
volatile unsigned32 *p = base;
{
volatile unsigned32 *C = (void *)0x34CDF0;
if ( *C ) printf( "W. *C = 0x%x\n", *C );
}
#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
printf( "%p Write 0x%04x to %s (0x%02x)\n",
@@ -1589,6 +1651,11 @@ unsigned32 sonic_read_register(
volatile unsigned32 *p = base;
unsigned32 value;
{
volatile unsigned32 *C = (void *)0x34CDF0;
if ( *C ) printf( "R. *C = 0x%x\n", *C );
}
value = p[regno];
#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
printf( "%p Read 0x%04x from %s (0x%02x)\n",

View File

@@ -329,6 +329,7 @@ struct ReceiveDescriptor {
* Extra RTEMS stuff
*/
volatile struct ReceiveDescriptor *next; /* Circularly-linked list */
struct mbuf *mbufp; /* First mbuf in packet */
};
typedef struct ReceiveDescriptor ReceiveDescriptor_t;
typedef volatile ReceiveDescriptor_t *ReceiveDescriptorPointer_t;