1
0
Fork 0

ADDED - Driver: function routines for using hardware checksum capabilities (enc28j60[conf].cpp/h, nic.h).

MODIF - ICMP: Switched to hardware checksum routines.
MODIF - Main: Better output of ip config when in debug mode.
ISSUE - Only the new checksum should be written back to the memory, not the whole packet.

git-svn-id: svn+ssh://oldsvn/home/mlalondesvn/svn/Ethduino@5 b05466c9-153a-0410-ad00-ea1d4d8a27b5
master
mlalondesvn 17 years ago
parent 27a2de3439
commit b004ac562d

@ -114,6 +114,15 @@ void nicReboot(void)
enc28j60Reboot(); enc28j60Reboot();
} }
uint16_t nicGetChecksum(uint8_t* packet, uint16_t len)
{
#ifdef ENC28J60_CHECKSUM_ENABLED
enc28j60getChecksum(packet, len);
#else
return 0x0000;
#endif
}
void enc28j60Reboot(void) void enc28j60Reboot(void)
{ {
#ifndef ENC28J60_HARD_RESET_DISABLED #ifndef ENC28J60_HARD_RESET_DISABLED
@ -215,6 +224,68 @@ void enc28j60ReadBuffer(uint16_t len, uint8_t* data)
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS); sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
} }
uint16_t enc28j60getChecksum(uint8_t* packet, uint16_t len)
//void enc28j60PacketSend(uint16_t len, uint8_t* packet)
{
// Errata workaround #10 Transmit Logic
if (enc28j60Read(EIR) & EIR_TXERIF)
{
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
}
// Set the write pointer to start of transmit buffer area
enc28j60Write(EWRPTL, TXSTART_INIT);
enc28j60Write(EWRPTH, TXSTART_INIT>>8);
// Set the TXND pointer to correspond to the packet size given
enc28j60Write(ETXNDL, (TXSTART_INIT+len));
enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);
// write per-packet control byte
enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
// copy the packet into the transmit buffer
enc28j60WriteBuffer(len, packet);
// return the calculated checksum
return enc28j60doHardwareChecksum(len);
}
uint16_t enc28j60doHardwareChecksum(uint16_t len)
{
// Set EDMASTL to the beggining of the used memory
enc28j60Write(EDMASTL, TXSTART_INIT);
enc28j60Write(EDMASTH, TXSTART_INIT>>8);
// Set EDMAND to the end of the memory used
enc28j60Write(EDMANDL, (TXSTART_INIT+len));
enc28j60Write(EDMANDH, (TXSTART_INIT+len)>>8);
// Set EDMADST to the beggining of the DMA buffer
enc28j60Write(EDMADSTL, TXSTART_INIT);
enc28j60Write(EDMADSTH, TXSTART_INIT>>8);
// Enable DMA copy mode
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
// Wait for the DMA copy to complete
while(!(enc28j60Read(EIR) & EIR_DMAIF));
// Start the checksum calculation
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_CSUMEN);
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
// Wait for the checksum calculation to complete
while(!(enc28j60Read(ECON1) & ~ECON1_DMAST && enc28j60Read(EIR) & EIR_DMAIF));
// Read back and return the calculated checksum
return (uint16_t)(enc28j60Read(EDMACSL) | (uint16_t)enc28j60Read(EDMACSH)<<8);
}
void enc28j60WriteBuffer(uint16_t len, uint8_t* data) void enc28j60WriteBuffer(uint16_t len, uint8_t* data)
{ {
// assert CS // assert CS

@ -301,6 +301,9 @@ uint16_t enc28j60PhyRead(uint8_t address);
//! write a PHY register //! write a PHY register
void enc28j60PhyWrite(uint8_t address, uint16_t data); void enc28j60PhyWrite(uint8_t address, uint16_t data);
uint16_t enc28j60doHardwareChecksum(uint16_t len);
uint16_t enc28j60getChecksum(uint8_t* packet, uint16_t len);
//! initialize the ethernet interface for transmit/receive //! initialize the ethernet interface for transmit/receive
/// \return -1 if there was a problem initializing the NIC, otherwise the value is undefined /// \return -1 if there was a problem initializing the NIC, otherwise the value is undefined
char enc28j60Init(void); char enc28j60Init(void);

@ -67,6 +67,9 @@
#define ENC28J60_PACKET_FILTER_ENABLED /* Unimplemented */ #define ENC28J60_PACKET_FILTER_ENABLED /* Unimplemented */
#define ENC28J60_LAMPS_MODE 0x3476 /* Default (with Errata #9 correction) applied if this is undefied */ #define ENC28J60_LAMPS_MODE 0x3476 /* Default (with Errata #9 correction) applied if this is undefied */
#define ENC28J60_CHECKSUM_ENABLED
/** /**
* Lamps reference * Lamps reference
* 0x3D56 # Default full duplex: LEDA: Display link status and transmit/receive activity LEDB: Display duplex status * 0x3D56 # Default full duplex: LEDA: Display link status and transmit/receive activity LEDB: Display duplex status

@ -26,6 +26,10 @@
#include "HardwareSerial.h" #include "HardwareSerial.h"
#endif #endif
#ifdef NET_CHECKSUM_DEBUG
#include "enc28j60.h"
#endif
// functions // functions
void icmpInit(void) void icmpInit(void)
{ {
@ -48,20 +52,19 @@ void icmpIpIn(icmpip_hdr* packet)
void icmpEchoRequest(icmpip_hdr* packet) void icmpEchoRequest(icmpip_hdr* packet)
{ {
uint32_t tempIp, tempId; uint32_t tempIp;
uint16_t tempId;
// change type to reply // change type to reply
packet->icmp.type = ICMP_TYPE_ECHOREPLY; packet->icmp.type = ICMP_TYPE_ECHOREPLY;
// recalculate checksum // recalculate checksum
packet->icmp.icmpchksum = 0x0000; packet->icmp.icmpchksum = 0x0000;
packet->icmp.icmpchksum = ipChecksum((netIpHeader*)&packet->icmp, htons(packet->ip.len)-sizeof(netIpHeader)); packet->icmp.icmpchksum = nicGetChecksum((uint8_t*)&packet->icmp, htons(packet->ip.len)-IP_HEADER_LEN);
#ifdef NET_CHECKSUM_DEBUG #ifdef NET_CHECKSUM_DEBUG
SPrintln(" "); SPrintln(" ");
SPrint("ICMP Checksum: 0x"); SPrint("Hardware Checksum: 0x");
Serial.print((uint16_t)htons(packet->icmp.icmpchksum), HEX);
SPrint(" 0x");
Serial.println((uint16_t)HTONS(packet->icmp.icmpchksum), HEX); Serial.println((uint16_t)HTONS(packet->icmp.icmpchksum), HEX);
#endif #endif
@ -70,14 +73,6 @@ void icmpEchoRequest(icmpip_hdr* packet)
packet->ip.destipaddr = packet->ip.srcipaddr; packet->ip.destipaddr = packet->ip.srcipaddr;
packet->ip.srcipaddr = tempIp; packet->ip.srcipaddr = tempIp;
// Set the proper transaction id
tempId = packet->ip.ipid;
packet->ip.ipid = tempId;
tempId = packet->icmp.id;
packet->icmp.id = tempId;
// add ethernet routing // add ethernet routing
arpIpOut((struct netEthIpHeader*)(((u08*)packet)-ETH_HEADER_LEN), 0); arpIpOut((struct netEthIpHeader*)(((u08*)packet)-ETH_HEADER_LEN), 0);
@ -88,7 +83,7 @@ void icmpEchoRequest(icmpip_hdr* packet)
#endif #endif
// send it (packet->ip.len+ETH_HEADER_LEN // send it (packet->ip.len+ETH_HEADER_LEN
nicSend(htons(packet->ip.len)+ETH_HEADER_LEN, (((u08*)packet)-ETH_HEADER_LEN)); nicSend(htons(packet->ip.len)+ETH_HEADER_LEN, (((uint8_t*)packet)-ETH_HEADER_LEN));
} }
#ifdef ICMP_DEBUG_PRINT #ifdef ICMP_DEBUG_PRINT

@ -31,7 +31,7 @@
#include "net.h" #include "net.h"
#define ICMP_DEBUG_PRINT // #define ICMP_DEBUG_PRINT
//! Initialize ICMP protocol library. //! Initialize ICMP protocol library.
void icmpInit(void); void icmpInit(void);

@ -5,7 +5,6 @@
**/ **/
#include "main.h" #include "main.h"
/** /**
* Network support * Network support
**/ **/
@ -21,6 +20,8 @@
#include "ip.h" #include "ip.h"
#include "icmp.h" #include "icmp.h"
#define PrintIP(ip) netPrintIPAddr(ip); SPrintln(" ")
struct netEthAddr myEthAddress; struct netEthAddr myEthAddress;
// prototypes // prototypes
@ -112,10 +113,12 @@ void serviceLocal(void)
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS); sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
break; break;
*/ */
#if defined(NET_DEBUG) || defined(NIC_DEBUG) #if defined(ARP_DEBUG_PRINT)
case 'a' : case 'a' :
arpPrintTable(); arpPrintTable();
break; break;
#endif
#if defined(NET_DEBUG) || defined(NIC_DEBUG)
case 'd': case 'd':
nicRegDump(); nicRegDump();
break; break;
@ -144,11 +147,13 @@ void serviceLocal(void)
case 'c': case 'c':
SPrintln("IP Configs"); SPrintln("IP Configs");
SPrint("IP:"); SPrint("IP:");
Serial.println(ipGetConfig()->ip); PrintIP(ipGetConfig()->ip);
SPrint("Gateway:"); SPrint("Gateway:");
Serial.println(ipGetConfig()->gateway); PrintIP(ipGetConfig()->gateway);
SPrint("Netmask:"); SPrint("Netmask:");
Serial.println(ipGetConfig()->netmask); PrintIP(ipGetConfig()->netmask);
//SPrint("MAC:");
//netPrintEthAddr(netEthAddr);
break; break;
/* /*
case 'x': case 'x':

@ -30,13 +30,18 @@ uint32_t htonl(uint32_t val)
return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16); return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16);
} }
static uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len) uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len)
{ {
uint16_t t; uint16_t t;
uint32_t *dataptr; uint32_t *dataptr;
uint32_t *last_byte; uint32_t *last_byte;
#ifdef NET_CHECKSUM_DEBUG
SPrint("Length for chksum func: ");
Serial.println((long int)len, HEX);
#endif
dataptr = (uint32_t *) data; dataptr = (uint32_t *) data;
last_byte = (uint32_t *) data + len - 1; last_byte = (uint32_t *) data + len - 1;

@ -198,7 +198,7 @@ uint16_t ipChecksum(netIpHeader *data, uint16_t len);
//! Calculate IP Header checksum from data. //! Calculate IP Header checksum from data.
uint16_t netChecksum(netIpHeader *data, uint16_t len); uint16_t netChecksum(netIpHeader *data, uint16_t len);
static uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len); uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len);
//! Print Ethernet address in XX:XX:XX:XX:XX:XX format. //! Print Ethernet address in XX:XX:XX:XX:XX:XX format.
void netPrintEthAddr(struct netEthAddr* ethaddr); void netPrintEthAddr(struct netEthAddr* ethaddr);

@ -27,6 +27,7 @@
#ifndef NIC_H #ifndef NIC_H
#define NIC_H #define NIC_H
#include "net.h"
// #define NIC_DEBUG // #define NIC_DEBUG
#include <inttypes.h> #include <inttypes.h>
@ -81,5 +82,8 @@ void nicSoftReset(void);
//! PHY Chip reboot //! PHY Chip reboot
void nicReboot(void); void nicReboot(void);
//! PHY Chip hardware checksum, if available
uint16_t nicGetChecksum(uint8_t* packet, uint16_t len);
#endif #endif
//@} //@}

Loading…
Cancel
Save