MPC8xx Network Driver Bug
Steven King
sking at zetron.com
Tue Jan 2 22:49:23 UTC 2007
Hi All,
A bug has been found in the network driver for the Power PC MPC8xx BSPs. It
can be reproduced by sending network traffic to the device before the
FEC/SCC initialisation is complete.
The bug is caused by the following lines in the network driver (file:
c/src/lib/libbsp/powerpc/-project-/network/network.c in the function
'fec_rxDaemon' or 'scc_rxDaemon'):
for (rxBdIndex = 0 ; ;) {
rxBd = sc->rxBdBase + rxBdIndex;
MGETHDR (m, M_WAIT, MT_DATA);
MCLGET (m, M_WAIT);
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->buffer = mtod (m, void *);
rxBd->status = M8xx_BD_EMPTY;
m8xx.fec.r_des_active = 0x1000000;
if (++rxBdIndex == sc->rxBdCount) {
rxBd->status |= M8xx_BD_WRAP;
break;
}
}
Due to optimisation, some of the code can be shifted around so that the
buffer descriptors have not been assigned the cluster buffer before they are
set to empty. During this stage the FEC is actually active and can start
writing incoming packets to these unassigned locations. I was seeing it as
corrupted MBUF clusters, once the network driver allocated the corrupted
cluster it would raise an invalid address exception.
We seemed to get correct object code by changing the definition of the
buffer descriptor struct in mpc8xx.h:
typedef struct m8xxBufferDescriptor_
{
volatile rtems_unsigned16 status;
volatile rtems_unsigned16 length;
volatile void* volatile buffer;
} m8xxBufferDescriptor_t;
This should fix the FEC and the SCC Ethernet drivers.
Declaring the buffer descriptor variable (rxBd) as volatile did not seem to
gaurantee correctness in the compiled code (may be a good idea to declare
them as volatile in network.c to make it obvious).
Steven King
More information about the users
mailing list