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

View File

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