Clean up network header stuff and make it more generic. Use
libdnet when we can instead of our own home grown stuff.
SConscript:
separate the crc code into its own file
base/inet.cc:
move the crc stuff to crc.cc
add generic code for calculating ip/tcp/udp checksums
base/inet.hh:
- move crc stuff to crc.hh
- #include all of the libdnet stuff. (this makes base/inet.hh the
only file you need to include if you want to use this kind of stuff.)
- Wrap some of the libdnet structs to get easier access to structure
members. These wrappers will automatically deal with masking/shifting/
byte-swapping.
base/refcnt.hh:
If one derives from RefCountingPtr, they should have access to
the internal data pointer.
build/SConstruct:
make #include of dnet stuff work
dev/etherlink.cc:
dev/ethertap.cc:
dev/ethertap.hh:
EtherPacket -> PacketData
dev/etherpkt.cc:
EtherPacket -> PacketData
add a function for populating extra info about a packet.
Basically just gives pointers to ethernet/ip/tcp/udp headers
if they exist.
dev/etherpkt.hh:
EtherPacket -> PacketData
remove most of the packet header stuff from teh PacketData
class and just add a few generic functions for grabbing various
headers that may exist in the packet. The old functionality is
contained in the headers.
dev/ns_gige.cc:
- IP -> Ip, UDP -> Udp, TCP ->Tcp when used in variable names
- get rid of our own byte swapping functions.
- whack checksum code and use libdnet version.
- Get pointers to the various packet headers and grab info from
those headers. (The byte swapping in the headers now.)
- Add stats for Udp Checksums
dev/ns_gige.hh:
use libdnet for checksum code.
IP -> Ip, TCP -> Tcp in variable names
add stats for UDP checksums
--HG--
extra : convert_revision : 96c4160e1967b7c0090acd456df4a76e1f3aab53
This commit is contained in:
@@ -41,8 +41,9 @@
|
||||
#include "dev/etherlink.hh"
|
||||
#include "dev/etherpkt.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/universe.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/system.hh"
|
||||
#include "sim/universe.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -196,7 +197,7 @@ EtherLink::Link::unserialize(Checkpoint *cp, const string §ion)
|
||||
bool packet_exists;
|
||||
UNSERIALIZE_SCALAR(packet_exists);
|
||||
if (packet_exists) {
|
||||
packet = new EtherPacket;
|
||||
packet = new PacketData;
|
||||
packet->unserialize(cp, csprintf("%s.packet", section));
|
||||
}
|
||||
|
||||
@@ -246,7 +247,7 @@ void
|
||||
LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion)
|
||||
{
|
||||
Event::unserialize(cp, section);
|
||||
packet = new EtherPacket;
|
||||
packet = new PacketData;
|
||||
packet->unserialize(cp, csprintf("%s.packet", section));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,17 +34,39 @@
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
EtherPacket::serialize(ostream &os)
|
||||
PacketData::doext()
|
||||
{
|
||||
_eth = 0;
|
||||
_ip = 0;
|
||||
_tcp = 0;
|
||||
_udp = 0;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
_eth = data;
|
||||
if (eth()->type() == ETH_TYPE_IP) {
|
||||
_ip = eth()->payload();
|
||||
|
||||
if (ip()->proto() == IP_PROTO_TCP)
|
||||
_tcp = ip()->payload();
|
||||
|
||||
if (ip()->proto() == IP_PROTO_UDP)
|
||||
_udp = ip()->payload();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PacketData::serialize(ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(length);
|
||||
SERIALIZE_ARRAY(data, length);
|
||||
}
|
||||
|
||||
void
|
||||
EtherPacket::unserialize(Checkpoint *cp, const string §ion)
|
||||
PacketData::unserialize(Checkpoint *cp, const string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(length);
|
||||
data = new uint8_t[length];
|
||||
UNSERIALIZE_ARRAY(data, length);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,70 +37,50 @@
|
||||
#include <memory>
|
||||
#include <assert.h>
|
||||
|
||||
#include "sim/host.hh"
|
||||
#include "base/refcnt.hh"
|
||||
#include "base/inet_hdrs.hh"
|
||||
#include "base/inet.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
class Checkpoint;
|
||||
/*
|
||||
* Reference counted class containing ethernet packet data
|
||||
*/
|
||||
class EtherPacket : public RefCounted
|
||||
class Checkpoint;
|
||||
class PacketData : public RefCounted
|
||||
{
|
||||
public:
|
||||
uint8_t *data;
|
||||
int length;
|
||||
|
||||
public:
|
||||
EtherPacket() : data(NULL), length(0) {}
|
||||
EtherPacket(std::auto_ptr<uint8_t> d, int l)
|
||||
: data(d.release()), length(l) {}
|
||||
~EtherPacket() { if (data) delete [] data; }
|
||||
protected:
|
||||
uint8_t *_eth;
|
||||
uint8_t *_ip;
|
||||
uint8_t *_tcp;
|
||||
uint8_t *_udp;
|
||||
|
||||
void doext();
|
||||
void ext()
|
||||
{
|
||||
if (_eth != data)
|
||||
doext();
|
||||
}
|
||||
|
||||
public:
|
||||
bool IsUnicast() { return data[0] == 0x00; }
|
||||
bool IsMulticast() { return data[0] == 0x01; }
|
||||
bool IsBroadcast() { return data[0] == 0xff; }
|
||||
PacketData() : data(NULL), length(0) { doext(); }
|
||||
PacketData(std::auto_ptr<uint8_t> d, int l)
|
||||
: data(d.release()), length(l) { doext(); }
|
||||
~PacketData() { if (data) delete [] data; }
|
||||
|
||||
bool isIpPkt() {
|
||||
eth_header *eth = (eth_header *) data;
|
||||
return (eth->type == 0x8);
|
||||
}
|
||||
bool isTcpPkt(ip_header *ip) {
|
||||
return (ip->protocol == 0x6);
|
||||
}
|
||||
bool isTcpPkt() {
|
||||
ip_header *ip = getIpHdr();
|
||||
return (ip->protocol == 0x6);
|
||||
}
|
||||
bool isUdpPkt(ip_header *ip) {
|
||||
return (ip->protocol == 17);
|
||||
}
|
||||
bool isUdpPkt() {
|
||||
ip_header *ip = getIpHdr();
|
||||
return (ip->protocol == 17);
|
||||
}
|
||||
|
||||
ip_header *getIpHdr() {
|
||||
assert(isIpPkt());
|
||||
return (ip_header *) (data + sizeof(eth_header));
|
||||
}
|
||||
|
||||
tcp_header *getTcpHdr(ip_header *ip) {
|
||||
assert(isTcpPkt(ip));
|
||||
return (tcp_header *) ((uint8_t *) ip + (ip->vers_len & 0xf)*4);
|
||||
}
|
||||
|
||||
udp_header *getUdpHdr(ip_header *ip) {
|
||||
assert(isUdpPkt(ip));
|
||||
return (udp_header *) ((uint8_t *) ip + (ip->vers_len & 0xf)*4);
|
||||
}
|
||||
typedef RefCountingPtr<EtherPacket> PacketPtr;
|
||||
public:
|
||||
EthHdr *eth() { ext(); return (EthHdr *)_eth; }
|
||||
IpHdr *ip() { ext(); return (IpHdr *)_ip; }
|
||||
TcpHdr *tcp() { ext(); return (TcpHdr *)_tcp; }
|
||||
UdpHdr *udp() { ext(); return (UdpHdr *)_udp; }
|
||||
|
||||
public:
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
typedef RefCountingPtr<EtherPacket> PacketPtr;
|
||||
typedef RefCountingPtr<PacketData> PacketPtr;
|
||||
|
||||
#endif // __ETHERPKT_HH__
|
||||
|
||||
@@ -219,7 +219,7 @@ EtherTap::process(int revent)
|
||||
|
||||
while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) {
|
||||
PacketPtr packet;
|
||||
packet = new EtherPacket;
|
||||
packet = new PacketData;
|
||||
packet->data = new uint8_t[data_len];
|
||||
packet->length = data_len;
|
||||
memcpy(packet->data, data, data_len);
|
||||
|
||||
@@ -70,7 +70,7 @@ class EtherTap : public EtherInt
|
||||
std::queue<PacketPtr> packetBuffer;
|
||||
|
||||
void process(int revent);
|
||||
void enqueue(EtherPacket *packet);
|
||||
void enqueue(PacketData *packet);
|
||||
void retransmit();
|
||||
|
||||
/*
|
||||
|
||||
270
dev/ns_gige.cc
270
dev/ns_gige.cc
@@ -87,11 +87,6 @@ const char *NsDmaState[] =
|
||||
|
||||
using namespace std;
|
||||
|
||||
// helper function declarations
|
||||
// These functions reverse Endianness so we can evaluate network data
|
||||
// correctly
|
||||
uint16_t reverseEnd16(uint16_t);
|
||||
uint32_t reverseEnd32(uint32_t);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -194,34 +189,48 @@ NSGigE::regStats()
|
||||
.prereq(rxBytes)
|
||||
;
|
||||
|
||||
txIPChecksums
|
||||
.name(name() + ".txIPChecksums")
|
||||
txIpChecksums
|
||||
.name(name() + ".txIpChecksums")
|
||||
.desc("Number of tx IP Checksums done by device")
|
||||
.precision(0)
|
||||
.prereq(txBytes)
|
||||
;
|
||||
|
||||
rxIPChecksums
|
||||
.name(name() + ".rxIPChecksums")
|
||||
rxIpChecksums
|
||||
.name(name() + ".rxIpChecksums")
|
||||
.desc("Number of rx IP Checksums done by device")
|
||||
.precision(0)
|
||||
.prereq(rxBytes)
|
||||
;
|
||||
|
||||
txTCPChecksums
|
||||
.name(name() + ".txTCPChecksums")
|
||||
txTcpChecksums
|
||||
.name(name() + ".txTcpChecksums")
|
||||
.desc("Number of tx TCP Checksums done by device")
|
||||
.precision(0)
|
||||
.prereq(txBytes)
|
||||
;
|
||||
|
||||
rxTCPChecksums
|
||||
.name(name() + ".rxTCPChecksums")
|
||||
rxTcpChecksums
|
||||
.name(name() + ".rxTcpChecksums")
|
||||
.desc("Number of rx TCP Checksums done by device")
|
||||
.precision(0)
|
||||
.prereq(rxBytes)
|
||||
;
|
||||
|
||||
txUdpChecksums
|
||||
.name(name() + ".txUdpChecksums")
|
||||
.desc("Number of tx UDP Checksums done by device")
|
||||
.precision(0)
|
||||
.prereq(txBytes)
|
||||
;
|
||||
|
||||
rxUdpChecksums
|
||||
.name(name() + ".rxUdpChecksums")
|
||||
.desc("Number of rx UDP Checksums done by device")
|
||||
.precision(0)
|
||||
.prereq(rxBytes)
|
||||
;
|
||||
|
||||
descDmaReads
|
||||
.name(name() + ".descDMAReads")
|
||||
.desc("Number of descriptors the device read w/ DMA")
|
||||
@@ -1332,14 +1341,13 @@ NSGigE::rxKick()
|
||||
|
||||
#if TRACING_ON
|
||||
if (DTRACE(Ethernet)) {
|
||||
if (rxPacket->isIpPkt()) {
|
||||
ip_header *ip = rxPacket->getIpHdr();
|
||||
DPRINTF(Ethernet, "ID is %d\n", reverseEnd16(ip->ID));
|
||||
if (rxPacket->isTcpPkt()) {
|
||||
tcp_header *tcp = rxPacket->getTcpHdr(ip);
|
||||
const IpHdr *ip = rxPacket->ip();
|
||||
if (ip) {
|
||||
DPRINTF(Ethernet, "ID is %d\n", ip->id());
|
||||
const TcpHdr *tcp = rxPacket->tcp();
|
||||
if (tcp) {
|
||||
DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n",
|
||||
reverseEnd16(tcp->src_port_num),
|
||||
reverseEnd16(tcp->dest_port_num));
|
||||
tcp->sport(), tcp->dport());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1395,33 +1403,36 @@ NSGigE::rxKick()
|
||||
*/
|
||||
if (rxFilterEnable) {
|
||||
rxDescCache.cmdsts &= ~CMDSTS_DEST_MASK;
|
||||
if (rxFifo.front()->IsUnicast())
|
||||
EthHdr *eth = rxFifoFront()->eth();
|
||||
if (eth->unicast())
|
||||
rxDescCache.cmdsts |= CMDSTS_DEST_SELF;
|
||||
if (rxFifo.front()->IsMulticast())
|
||||
if (eth->multicast())
|
||||
rxDescCache.cmdsts |= CMDSTS_DEST_MULTI;
|
||||
if (rxFifo.front()->IsBroadcast())
|
||||
if (eth->broadcast())
|
||||
rxDescCache.cmdsts |= CMDSTS_DEST_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rxPacket->isIpPkt() && extstsEnable) {
|
||||
if (extstsEnable && rxPacket->ip()) {
|
||||
rxDescCache.extsts |= EXTSTS_IPPKT;
|
||||
rxIPChecksums++;
|
||||
if (!ipChecksum(rxPacket, false)) {
|
||||
rxIpChecksums++;
|
||||
IpHdr *ip = rxPacket->ip();
|
||||
if (ip->ip_cksum() != 0) {
|
||||
DPRINTF(EthernetCksum, "Rx IP Checksum Error\n");
|
||||
rxDescCache.extsts |= EXTSTS_IPERR;
|
||||
}
|
||||
if (rxPacket->isTcpPkt()) {
|
||||
if (rxPacket->tcp()) {
|
||||
rxDescCache.extsts |= EXTSTS_TCPPKT;
|
||||
rxTCPChecksums++;
|
||||
if (!tcpChecksum(rxPacket, false)) {
|
||||
rxTcpChecksums++;
|
||||
if (ip->tu_cksum() != 0) {
|
||||
DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n");
|
||||
rxDescCache.extsts |= EXTSTS_TCPERR;
|
||||
|
||||
}
|
||||
} else if (rxPacket->isUdpPkt()) {
|
||||
} else if (rxPacket->udp()) {
|
||||
rxDescCache.extsts |= EXTSTS_UDPPKT;
|
||||
if (!udpChecksum(rxPacket, false)) {
|
||||
rxUdpChecksums++;
|
||||
if (ip->tu_cksum() != 0) {
|
||||
DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n");
|
||||
rxDescCache.extsts |= EXTSTS_UDPERR;
|
||||
}
|
||||
@@ -1539,14 +1550,13 @@ NSGigE::transmit()
|
||||
if (interface->sendPacket(txFifo.front())) {
|
||||
#if TRACING_ON
|
||||
if (DTRACE(Ethernet)) {
|
||||
if (txFifo.front()->isIpPkt()) {
|
||||
ip_header *ip = txFifo.front()->getIpHdr();
|
||||
DPRINTF(Ethernet, "ID is %d\n", reverseEnd16(ip->ID));
|
||||
if (txFifo.front()->isTcpPkt()) {
|
||||
tcp_header *tcp = txFifo.front()->getTcpHdr(ip);
|
||||
const IpHdr *ip = txFifo.front()->ip();
|
||||
if (ip) {
|
||||
DPRINTF(Ethernet, "ID is %d\n", ip->id());
|
||||
const TcpHdr *tcp = txFifo.front()->tcp();
|
||||
if (tcp) {
|
||||
DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n",
|
||||
reverseEnd16(tcp->src_port_num),
|
||||
reverseEnd16(tcp->dest_port_num));
|
||||
tcp->sport(), tcp->dport());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1780,7 +1790,7 @@ NSGigE::txKick()
|
||||
case txFifoBlock:
|
||||
if (!txPacket) {
|
||||
DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
|
||||
txPacket = new EtherPacket;
|
||||
txPacket = new PacketData;
|
||||
txPacket->data = new uint8_t[16384];
|
||||
txPacketBufPtr = txPacket->data;
|
||||
}
|
||||
@@ -1806,15 +1816,22 @@ NSGigE::txKick()
|
||||
DPRINTF(EthernetSM, "This packet is done, let's wrap it up\n");
|
||||
/* deal with the the packet that just finished */
|
||||
if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) {
|
||||
IpHdr *ip = txPacket->ip();
|
||||
if (txDescCache.extsts & EXTSTS_UDPPKT) {
|
||||
udpChecksum(txPacket, true);
|
||||
UdpHdr *udp = txPacket->udp();
|
||||
udp->sum(0);
|
||||
udp->sum(ip->tu_cksum());
|
||||
txUdpChecksums++;
|
||||
} else if (txDescCache.extsts & EXTSTS_TCPPKT) {
|
||||
tcpChecksum(txPacket, true);
|
||||
txTCPChecksums++;
|
||||
TcpHdr *tcp = txPacket->tcp();
|
||||
tcp->sum(0);
|
||||
tcp->sum(ip->tu_cksum());
|
||||
txTcpChecksums++;
|
||||
}
|
||||
if (txDescCache.extsts & EXTSTS_IPPKT) {
|
||||
ipChecksum(txPacket, true);
|
||||
txIPChecksums++;
|
||||
ip->sum(0);
|
||||
ip->sum(ip->ip_cksum());
|
||||
txIpChecksums++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1977,9 +1994,8 @@ NSGigE::rxFilter(PacketPtr packet)
|
||||
bool drop = true;
|
||||
string type;
|
||||
|
||||
if (packet->IsUnicast()) {
|
||||
type = "unicast";
|
||||
|
||||
EthHdr *eth = packet->eth();
|
||||
if (eth->unicast()) {
|
||||
// If we're accepting all unicast addresses
|
||||
if (acceptUnicast)
|
||||
drop = false;
|
||||
@@ -1989,28 +2005,19 @@ NSGigE::rxFilter(PacketPtr packet)
|
||||
memcmp(rom.perfectMatch, packet->data, EADDR_LEN) == 0)
|
||||
drop = false;
|
||||
|
||||
eth_header *eth = (eth_header *) packet->data;
|
||||
if ((acceptArp) && (eth->type == 0x608))
|
||||
if (acceptArp && eth->type() == ETH_TYPE_ARP)
|
||||
drop = false;
|
||||
|
||||
} else if (packet->IsBroadcast()) {
|
||||
type = "broadcast";
|
||||
|
||||
} else if (eth->broadcast()) {
|
||||
// if we're accepting broadcasts
|
||||
if (acceptBroadcast)
|
||||
drop = false;
|
||||
|
||||
} else if (packet->IsMulticast()) {
|
||||
type = "multicast";
|
||||
|
||||
} else if (eth->multicast()) {
|
||||
// if we're accepting all multicasts
|
||||
if (acceptMulticast)
|
||||
drop = false;
|
||||
|
||||
} else {
|
||||
type = "unknown";
|
||||
|
||||
// oh well, punt on this one
|
||||
}
|
||||
|
||||
if (drop) {
|
||||
@@ -2058,121 +2065,6 @@ NSGigE::recvPacket(PacketPtr packet)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* does a udp checksum. if gen is true, then it generates it and puts
|
||||
* it in the right place else, it just checks what it calculates
|
||||
* against the value in the header in packet
|
||||
*/
|
||||
bool
|
||||
NSGigE::udpChecksum(PacketPtr packet, bool gen)
|
||||
{
|
||||
ip_header *ip = packet->getIpHdr();
|
||||
udp_header *hdr = packet->getUdpHdr(ip);
|
||||
|
||||
pseudo_header *pseudo = new pseudo_header;
|
||||
|
||||
pseudo->src_ip_addr = ip->src_ip_addr;
|
||||
pseudo->dest_ip_addr = ip->dest_ip_addr;
|
||||
pseudo->protocol = ip->protocol;
|
||||
pseudo->len = hdr->len;
|
||||
|
||||
uint16_t cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
|
||||
(uint32_t) hdr->len);
|
||||
|
||||
delete pseudo;
|
||||
if (gen)
|
||||
hdr->chksum = cksum;
|
||||
else
|
||||
if (cksum != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NSGigE::tcpChecksum(PacketPtr packet, bool gen)
|
||||
{
|
||||
ip_header *ip = packet->getIpHdr();
|
||||
tcp_header *hdr = packet->getTcpHdr(ip);
|
||||
|
||||
uint16_t cksum;
|
||||
pseudo_header *pseudo = new pseudo_header;
|
||||
if (!gen) {
|
||||
pseudo->src_ip_addr = ip->src_ip_addr;
|
||||
pseudo->dest_ip_addr = ip->dest_ip_addr;
|
||||
pseudo->protocol = reverseEnd16(ip->protocol);
|
||||
pseudo->len = reverseEnd16(reverseEnd16(ip->dgram_len) -
|
||||
(ip->vers_len & 0xf)*4);
|
||||
|
||||
cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
|
||||
(uint32_t) reverseEnd16(pseudo->len));
|
||||
} else {
|
||||
pseudo->src_ip_addr = 0;
|
||||
pseudo->dest_ip_addr = 0;
|
||||
pseudo->protocol = hdr->chksum;
|
||||
pseudo->len = 0;
|
||||
hdr->chksum = 0;
|
||||
cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
|
||||
(uint32_t) (reverseEnd16(ip->dgram_len) -
|
||||
(ip->vers_len & 0xf)*4));
|
||||
}
|
||||
|
||||
delete pseudo;
|
||||
if (gen)
|
||||
hdr->chksum = cksum;
|
||||
else
|
||||
if (cksum != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NSGigE::ipChecksum(PacketPtr packet, bool gen)
|
||||
{
|
||||
ip_header *hdr = packet->getIpHdr();
|
||||
|
||||
uint16_t cksum = checksumCalc(NULL, (uint16_t *) hdr,
|
||||
(hdr->vers_len & 0xf)*4);
|
||||
|
||||
if (gen) {
|
||||
DPRINTF(EthernetCksum, "generated checksum: %#x\n", cksum);
|
||||
hdr->hdr_chksum = cksum;
|
||||
}
|
||||
else
|
||||
if (cksum != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
NSGigE::checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
|
||||
uint16_t last_pad = 0;
|
||||
if (len & 1) {
|
||||
last_pad = buf[len/2] & 0xff;
|
||||
len--;
|
||||
sum += last_pad;
|
||||
}
|
||||
|
||||
if (pseudo) {
|
||||
sum = pseudo[0] + pseudo[1] + pseudo[2] +
|
||||
pseudo[3] + pseudo[4] + pseudo[5];
|
||||
}
|
||||
|
||||
for (int i=0; i < (len/2); ++i) {
|
||||
sum += buf[i];
|
||||
}
|
||||
|
||||
while (sum >> 16)
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
|
||||
return ~sum;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//
|
||||
//
|
||||
@@ -2398,7 +2290,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
UNSERIALIZE_SCALAR(txNumPkts);
|
||||
int i;
|
||||
for (i = 0; i < txNumPkts; ++i) {
|
||||
PacketPtr p = new EtherPacket;
|
||||
PacketPtr p = new PacketData;
|
||||
p->unserialize(cp, csprintf("%s.rxFifo%d", section, i));
|
||||
txFifo.push_back(p);
|
||||
}
|
||||
@@ -2406,7 +2298,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
int rxNumPkts;
|
||||
UNSERIALIZE_SCALAR(rxNumPkts);
|
||||
for (i = 0; i < rxNumPkts; ++i) {
|
||||
PacketPtr p = new EtherPacket;
|
||||
PacketPtr p = new PacketData;
|
||||
p->unserialize(cp, csprintf("%s.rxFifo%d", section, i));
|
||||
rxFifo.push_back(p);
|
||||
}
|
||||
@@ -2417,7 +2309,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
bool txPacketExists;
|
||||
UNSERIALIZE_SCALAR(txPacketExists);
|
||||
if (txPacketExists) {
|
||||
txPacket = new EtherPacket;
|
||||
txPacket = new PacketData;
|
||||
txPacket->unserialize(cp, csprintf("%s.txPacket", section));
|
||||
uint32_t txPktBufPtr;
|
||||
UNSERIALIZE_SCALAR(txPktBufPtr);
|
||||
@@ -2429,7 +2321,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
UNSERIALIZE_SCALAR(rxPacketExists);
|
||||
rxPacket = 0;
|
||||
if (rxPacketExists) {
|
||||
rxPacket = new EtherPacket;
|
||||
rxPacket = new PacketData;
|
||||
rxPacket->unserialize(cp, csprintf("%s.rxPacket", section));
|
||||
uint32_t rxPktBufPtr;
|
||||
UNSERIALIZE_SCALAR(rxPktBufPtr);
|
||||
@@ -2530,28 +2422,6 @@ NSGigE::cacheAccess(MemReqPtr &req)
|
||||
req->paddr, req->paddr - addr);
|
||||
return curTick + pioLatency;
|
||||
}
|
||||
//=====================================================================
|
||||
|
||||
|
||||
//********** helper functions******************************************
|
||||
|
||||
uint16_t reverseEnd16(uint16_t num)
|
||||
{
|
||||
uint16_t reverse = (num & 0xff)<<8;
|
||||
reverse += ((num & 0xff00) >> 8);
|
||||
return reverse;
|
||||
}
|
||||
|
||||
uint32_t reverseEnd32(uint32_t num)
|
||||
{
|
||||
uint32_t reverse = (reverseEnd16(num & 0xffff)) << 16;
|
||||
reverse += reverseEnd16((uint16_t) ((num & 0xffff0000) >> 8));
|
||||
return reverse;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=====================================================================
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt)
|
||||
|
||||
|
||||
@@ -329,15 +329,6 @@ class NSGigE : public PciDev
|
||||
typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
|
||||
friend class IntrEvent;
|
||||
IntrEvent *intrEvent;
|
||||
|
||||
/**
|
||||
* Hardware checksum support
|
||||
*/
|
||||
bool udpChecksum(PacketPtr packet, bool gen);
|
||||
bool tcpChecksum(PacketPtr packet, bool gen);
|
||||
bool ipChecksum(PacketPtr packet, bool gen);
|
||||
uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len);
|
||||
|
||||
NSGigEInt *interface;
|
||||
|
||||
public:
|
||||
@@ -377,10 +368,12 @@ class NSGigE : public PciDev
|
||||
Stats::Scalar<> rxBytes;
|
||||
Stats::Scalar<> txPackets;
|
||||
Stats::Scalar<> rxPackets;
|
||||
Stats::Scalar<> txIPChecksums;
|
||||
Stats::Scalar<> rxIPChecksums;
|
||||
Stats::Scalar<> txTCPChecksums;
|
||||
Stats::Scalar<> rxTCPChecksums;
|
||||
Stats::Scalar<> txIpChecksums;
|
||||
Stats::Scalar<> rxIpChecksums;
|
||||
Stats::Scalar<> txTcpChecksums;
|
||||
Stats::Scalar<> rxTcpChecksums;
|
||||
Stats::Scalar<> txUdpChecksums;
|
||||
Stats::Scalar<> rxUdpChecksums;
|
||||
Stats::Scalar<> descDmaReads;
|
||||
Stats::Scalar<> descDmaWrites;
|
||||
Stats::Scalar<> descDmaRdBytes;
|
||||
|
||||
Reference in New Issue
Block a user