milkymist network driver bug
Till Straumann
strauman at slac.stanford.edu
Thu Feb 24 00:18:26 UTC 2011
Today I started playing with the milkymist BSP in HEAD.
After some hacking I got some life out of lm32-qemu and this
BSP but I'm not sure it has reached production quality quite yet.
When sending a packet, minimac_sendpacket() copies the
entire mbuf chain holding the packet into a driver-buffer
(struct mm_packet) which is much smaller than the interface
MTU and which is allocated *on*the*stack* and then handed
(by reference) to the chip (for DMA, I guess).
Any packet that is larger than 128 bytes overruns the stack
and since it is very likely that the packet buffer is popped
before the hardware is done reading it from memory it may
very well be corrupted.
Other peculiarities include not declaring memory-mapped
registers as 'volatile' (in the network- and other drivers).
-- T.
PS: Here's a snippet of that code
static void minimac_sendpacket(struct ifnet *ifp, struct mbuf *m)
{
struct mbuf *nm = m;
struct minimac_softc *sc = &minimac_softc;
unsigned int len = 0;
struct mm_packet p;
unsigned int crc;
uint8_t i;
for (i = 0 ; i < 7 ; i++) // Preamble
p.preamble[i] = 0x55;
p.preamble[7] = 0xd5;
do
{
unsigned int mlen;
mlen = nm->m_len;
if (nm->m_len > 0) {
m_copydata(nm, 0, mlen, p.raw_data + len);
len += nm->m_len;
} while ( (nm = nm->m_next) != 0 );
for ( ; len < 60 ; len++)
p.raw_data[len] = 0x00; // Padding
crc = mm_ether_crc32((uint8_t *)p.raw_data, len); // CRC32
p.raw_data[len] = crc & 0xff;
p.raw_data[len+1] = (crc & 0xff00) >> 8;
p.raw_data[len+2] = (crc & 0xff0000) >> 16;
p.raw_data[len+3] = crc >> 24;
len += 4; // We add 4 bytes of CRC32
if (len + 8 < 64) {
printk("[minimac] Packet is too small !\n");
sc->txErrors++; // update stats
return;
}
minimac_write(MM_MINIMAC_TXADR, (unsigned int)&p);
minimac_write(MM_MINIMAC_TXREMAINING, (unsigned int)(len + 8));
}
where struct mm_packet is
struct mm_packet {
unsigned char preamble[8];
char raw_data[MLEN]; /* MLEN == 128 bytes! */
} __attribute__((aligned(4), packed));
More information about the users
mailing list