[U-Boot] NE2000 driver issues and extensions

Rutger Hofman uboot at rutgerhofman.nl
Thu Dec 3 17:22:10 CET 2009


On our new, custom BlackFin board (see http://www.rfidguardian.org) we 
have an Asix AX88796B Ethernet chip. This chip is NE2000-compatible 
according to the manufacturer.

When porting this driver to our board, and extending it for extra 
commands (DP_RESET in software and then some, attempt to read the MAC 
address from an EEPROM), I met a few issues with the ne2000 controller:

bug 1) when a corrupted packet arrives, the driver attempts to detect 
this by doing a sanity check on the packet length in 
uboot_push_packet_len(). If the length check fails, this function 
returns and the caller continues as if nothing happened, reading 
rcv_hdr[1] as the location for the next packet. But this header will 
probably also be corrupt, so the management of receive pages becomes 
nonsensical.

Proposed fix:
  a) check rcv_hdr[0], the receive status byte; if != 0x01, then the 
packet is corrupt;
  b) check the length; if it exceeds PKTSIZE_ALIGN, the packet is corrupt;
  c) if the packet is corrupt, advance the next-packet-pointer to the 
following location, irrespective of the pointer in the header. This will 
discard the corrupt packet and keep the received pages consistent

bug 2) dp83902a_RxEvent() caches a pointer to the next-page-to-be read, 
then calls uboot_push_packet_len(), which calls upper layers via 
NetReceive(). If the upper layers want, they can call dp83902a_start() 
-- which happens e.g. when a tftp-ed file doesn't exist. 
dp83902a_start() resets the receive page pointers to the initial state. 
But when NetReceive() returns, the modified pointers into the receive 
pages are ignored. The BNDRY pointer is set to the cached next pointer, 
which has no relation to the current state.

Proposed fix:
  a) dp83902a_start() sets a bit in the driver state. This bit cleared 
before the driver upcalls to NetReceive(); if the bit is set after
NetReceive() returned, the driver knows that the receive page pointers 
are reset. In that case, it doesn't touch the receive page pointers any 
more.

Another issue:
Extension 1) our chip has an x16 bus. I extended the driver to support 
16-bit data read/writes, following the implementation in eCos (where the 
ne2000 driver originates). Issue: the endianness in the eCos driver 
appears wrong to me -- NE2000 is little-endian itself, so the driver 
must convert between NE2000's little-endianness and the endianness of 
the host. The eCos driver appears to assume a big-endian host in all cases.

I plan to also report this on the eCos mailing lists.

Rutger


More information about the U-Boot mailing list