[U-Boot] NE2000 driver issues and extensions

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
participants (1)
-
Rutger Hofman