47 #include "debug/Drain.hh"
48 #include "debug/EthernetAll.hh"
51 #include "params/IGbE.hh"
58 using namespace igbreg;
59 using namespace networking;
63 rxFifo(
p.rx_fifo_size), txFifo(
p.tx_fifo_size), inTick(false),
64 rxTick(false), txTick(false), txFifoTick(false), rxDmaPacket(false),
65 pktOffset(0), fetchDelay(
p.fetch_delay), wbDelay(
p.wb_delay),
66 fetchCompDelay(
p.fetch_comp_delay), wbCompDelay(
p.wb_comp_delay),
67 rxWriteDelay(
p.rx_write_delay), txReadDelay(
p.tx_read_delay),
69 radvEvent([
this]{ radvProcess(); },
name()),
70 tadvEvent([
this]{ tadvProcess(); },
name()),
71 tidvEvent([
this]{ tidvProcess(); },
name()),
72 tickEvent([
this]{ tick(); },
name()),
73 interEvent([
this]{ delayIntEvent(); },
name()),
74 rxDescCache(
this,
name()+
".RxDesc",
p.rx_desc_cache_size),
75 txDescCache(
this,
name()+
".TxDesc",
p.tx_desc_cache_size),
112 memcpy(
flash,
p.hardware_address.bytes(), ETH_ADDR_LEN);
113 for (
int x = 0;
x < ETH_ADDR_LEN / 2;
x++)
145 if (if_name ==
"interface")
157 panic(
"Device specific PCI config space not implemented.\n");
167 #define IN_RANGE(val, base, len) (val >= base && val < (base + len))
176 panic(
"Invalid PCI memory access to unmapped memory.\n");
184 DPRINTF(Ethernet,
"Read device register %#X\n", daddr);
211 DPRINTF(Ethernet,
"Reading ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
225 pkt->
setLE<uint32_t>(0);
246 pkt->
setLE<uint32_t>(0);
277 "Posting interrupt because of RDTR.FPD write\n");
348 panic(
"Read request to unknown register number: %#x\n", daddr);
350 pkt->
setLE<uint32_t>(0);
365 panic(
"Invalid PCI memory access to unmapped memory.\n");
371 assert(pkt->
getSize() ==
sizeof(uint32_t));
373 DPRINTF(Ethernet,
"Wrote device register %#X value %#X\n",
374 daddr, pkt->
getLE<uint32_t>());
379 uint32_t
val = pkt->
getLE<uint32_t>();
388 warn(
"TX Flow control enabled, should implement\n");
390 warn(
"RX Flow control enabled, should implement\n");
412 DPRINTF(EthernetEEPROM,
"EEPROM bit read: %d word: %#X\n",
422 panic(
"What's going on with eeprom interface? opcode:"
423 " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)
eeOpcode,
437 DPRINTF(EthernetEEPROM,
"EEPROM: opcode: %#X:%d addr: %#X:%d\n",
457 DPRINTF(EthernetEEPROM,
"EEPROM: read addr: %#X data %#x\n",
464 panic(
"No support for interrupt on mdic complete\n");
466 panic(
"No support for reading anything but phy\n");
467 DPRINTF(Ethernet,
"%s phy address %x\n",
468 regs.
mdic.op() == 1 ?
"Writing" :
"Reading",
495 DPRINTF(Ethernet,
"Writing ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
506 DPRINTF(EthernetIntr,
"Posting interrupt because of ICS write\n");
525 DPRINTF(EthernetSM,
"RXS: Got RESET!\n");
543 if (
regs.
tctl.en() && !oldtctl.en()) {
564 warn(
"Writing to IVAR0, ignoring...\n");
593 DPRINTF(EthernetSM,
"RXS: RDT Updated.\n");
595 DPRINTF(EthernetSM,
"RXS: RDT Fetching Descriptors!\n");
598 DPRINTF(EthernetSM,
"RXS: RDT NOT Fetching Desc b/c draining!\n");
629 panic(
"No support for DCA\n");
633 DPRINTF(EthernetSM,
"TXS: TX Tail pointer updated\n");
635 DPRINTF(EthernetSM,
"TXS: TDT Fetching Descriptors!\n");
638 DPRINTF(EthernetSM,
"TXS: TDT NOT Fetching Desc b/c draining!\n");
671 panic(
"Extended RX descriptors not implemented\n");
688 panic(
"Write request to unknown register number: %#x\n", daddr);
708 "EINT: postInterrupt() curTick(): %d itr: %d interval: %d\n",
711 if (
regs.
itr.interval() == 0 || now ||
719 assert(int_time > 0);
720 DPRINTF(EthernetIntr,
"EINT: Scheduling timer interrupt for tick %d\n",
742 DPRINTF(Ethernet,
"Interrupt Masked. Not Posting\n");
746 DPRINTF(Ethernet,
"Posting Interrupt\n");
771 DPRINTF(EthernetIntr,
"EINT: Posting interrupt to CPU now. Vector %#x\n",
785 "EINT: Clearing interrupt to CPU now. Vector %#x\n",
794 DPRINTF(Ethernet,
"Checking interrupts icr: %#x imr: %#x\n",
regs.
icr(),
798 DPRINTF(Ethernet,
"Mask cleaned all interrupts\n");
804 DPRINTF(Ethernet,
"ITR = %#X itr.interval = %#X\n",
808 if (
regs.
itr.interval() == 0) {
812 "Possibly scheduling interrupt because of imr write\n");
816 DPRINTF(Ethernet,
"Scheduling for %d\n",
t);
828 : igbe(
i), _name(
n), cachePnt(0), size(
s), curFetching(0),
829 wbOut(0), moreToWb(false), wbAlignment(0), pktPtr(NULL),
830 wbDelayEvent([this]{ writeback1(); },
n),
831 fetchDelayEvent([
this]{ fetchDescriptors1(); },
n),
832 fetchEvent([
this]{ fetchComplete(); },
n),
833 wbEvent([
this]{ wbComplete(); },
n)
835 fetchBuf =
new T[size];
851 if (usedCache.size() > 0 || curFetching || wbOut)
852 panic(
"Descriptor Address, Length or Head changed. Bad\n");
861 int curHead = descHead();
862 int max_to_wb = usedCache.size();
867 if (aMask < wbAlignment) {
872 "Writing back already in process, returning\n");
880 DPRINTF(EthernetDesc,
"Writing back descriptors head: %d tail: "
881 "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
882 curHead, descTail(), descLen(), cachePnt, max_to_wb,
885 if (max_to_wb + curHead >= descLen()) {
886 max_to_wb = descLen() - curHead;
889 }
else if (wbAlignment != 0) {
891 max_to_wb = max_to_wb & ~wbAlignment;
894 DPRINTF(EthernetDesc,
"Writing back %d descriptors\n", max_to_wb);
901 assert(!wbDelayEvent.scheduled());
902 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
910 if (igbe->drainState() != DrainState::Running) {
911 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
915 DPRINTF(EthernetDesc,
"Begining DMA of %d descriptors\n", wbOut);
917 for (
int x = 0;
x < wbOut;
x++) {
918 assert(usedCache.size());
919 memcpy(&wbBuf[
x], usedCache[
x],
sizeof(T));
924 igbe->dmaWrite(pciToDma(descBase() + descHead() *
sizeof(T)),
925 wbOut *
sizeof(T), &wbEvent, (uint8_t *)wbBuf,
937 "Currently fetching %d descriptors, returning\n",
942 if (descTail() >= cachePnt)
943 max_to_fetch = descTail() - cachePnt;
945 max_to_fetch = descLen() - cachePnt;
947 size_t free_cache = size - usedCache.size() - unusedCache.size();
949 max_to_fetch = std::min(max_to_fetch, free_cache);
952 DPRINTF(EthernetDesc,
"Fetching descriptors head: %d tail: "
953 "%d len: %d cachePnt: %d max_to_fetch: %d descleft: %d\n",
954 descHead(), descTail(), descLen(), cachePnt,
955 max_to_fetch, descLeft());
958 if (max_to_fetch == 0)
962 curFetching = max_to_fetch;
964 assert(!fetchDelayEvent.scheduled());
965 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
973 if (igbe->drainState() != DrainState::Running) {
974 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
978 DPRINTF(EthernetDesc,
"Fetching descriptors at %#x (%#x), size: %#x\n",
979 descBase() + cachePnt *
sizeof(T),
980 pciToDma(descBase() + cachePnt *
sizeof(T)),
981 curFetching *
sizeof(T));
983 igbe->dmaRead(pciToDma(descBase() + cachePnt *
sizeof(T)),
984 curFetching *
sizeof(T), &fetchEvent, (uint8_t *)fetchBuf,
985 igbe->fetchCompDelay);
993 for (
int x = 0;
x < curFetching;
x++) {
995 memcpy(newDesc, &fetchBuf[
x],
sizeof(T));
996 unusedCache.push_back(newDesc);
1000 int oldCp = cachePnt;
1002 cachePnt += curFetching;
1003 assert(cachePnt <= descLen());
1004 if (cachePnt == descLen())
1009 DPRINTF(EthernetDesc,
"Fetching complete cachePnt %d -> %d\n",
1021 long curHead = descHead();
1022 long oldHead = curHead;
1024 for (
int x = 0;
x < wbOut;
x++) {
1025 assert(usedCache.size());
1026 delete usedCache[0];
1027 usedCache.pop_front();
1033 if (curHead >= descLen())
1034 curHead -= descLen();
1037 updateHead(curHead);
1039 DPRINTF(EthernetDesc,
"Writeback complete curHead %d -> %d\n",
1046 DPRINTF(EthernetDesc,
"Writeback has more todo\n");
1059 DPRINTF(EthernetDesc,
"Reseting descriptor cache\n");
1061 delete usedCache[
x];
1063 delete unusedCache[
x];
1066 unusedCache.clear();
1086 (uint8_t *)usedCache[
x],
sizeof(T));
1093 (uint8_t *)unusedCache[
x],
sizeof(T));
1096 Tick fetch_delay = 0, wb_delay = 0;
1097 if (fetchDelayEvent.scheduled())
1098 fetch_delay = fetchDelayEvent.when();
1100 if (wbDelayEvent.scheduled())
1101 wb_delay = wbDelayEvent.when();
1123 (uint8_t *)temp,
sizeof(T));
1124 usedCache.push_back(temp);
1132 (uint8_t *)temp,
sizeof(T));
1133 unusedCache.push_back(temp);
1135 Tick fetch_delay = 0, wb_delay = 0;
1139 igbe->schedule(fetchDelayEvent, fetch_delay);
1141 igbe->schedule(wbDelayEvent, wb_delay);
1148 IGbE::RxDescCache::RxDescCache(
IGbE *
i,
const std::string
n,
int s)
1151 pktHdrEvent([
this]{ pktSplitDone(); },
n),
1152 pktDataEvent([
this]{ pktSplitDone(); },
n)
1155 annSmFetch =
"RX Desc Fetch";
1156 annSmWb =
"RX Desc Writeback";
1157 annUnusedDescQ =
"RX Unused Descriptors";
1158 annUnusedCacheQ =
"RX Unused Descriptor Cache";
1159 annUsedCacheQ =
"RX Used Descriptor Cache";
1160 annUsedDescQ =
"RX Used Descriptors";
1161 annDescQ =
"RX Descriptors";
1169 "Part of split packet done: splitcount now %d\n", splitCount);
1170 assert(splitCount <= 2);
1171 if (splitCount != 2)
1175 "Part of split packet done: calling pktComplete()\n");
1182 assert(unusedCache.size());
1188 unsigned buf_len, hdr_len;
1190 RxDesc *desc = unusedCache.front();
1191 switch (igbe->regs.srrctl.desctype()) {
1193 assert(pkt_offset == 0);
1194 bytesCopied = packet->length;
1195 DPRINTF(EthernetDesc,
"Packet Length: %d Desc Size: %d\n",
1196 packet->length, igbe->regs.rctl.descSize());
1197 assert(packet->length < igbe->regs.rctl.descSize());
1199 packet->length, &pktEvent, packet->data,
1200 igbe->rxWriteDelay);
1203 assert(pkt_offset == 0);
1204 bytesCopied = packet->length;
1205 buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
1206 igbe->regs.rctl.descSize();
1207 DPRINTF(EthernetDesc,
"Packet Length: %d srrctl: %#x Desc Size: %d\n",
1208 packet->length, igbe->regs.srrctl(), buf_len);
1209 assert(packet->length < buf_len);
1211 packet->length, &pktEvent, packet->data,
1212 igbe->rxWriteDelay);
1215 desc->
adv_wb.pkt_len =
htole((uint16_t)(pktPtr->length));
1220 buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
1221 igbe->regs.rctl.descSize();
1222 hdr_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.hdrLen() : 0;
1224 "lpe: %d Packet Length: %d offset: %d srrctl: %#x "
1225 "hdr addr: %#x Hdr Size: %d desc addr: %#x Desc Size: %d\n",
1226 igbe->regs.rctl.lpe(), packet->length, pkt_offset,
1227 igbe->regs.srrctl(), desc->
adv_read.hdr, hdr_len,
1230 split_point =
hsplit(pktPtr);
1232 if (packet->length <= hdr_len) {
1233 bytesCopied = packet->length;
1234 assert(pkt_offset == 0);
1235 DPRINTF(EthernetDesc,
"Hdr split: Entire packet in header\n");
1237 packet->length, &pktEvent, packet->data,
1238 igbe->rxWriteDelay);
1239 desc->
adv_wb.header_len =
htole((uint16_t)packet->length);
1242 }
else if (split_point) {
1247 std::min(packet->length - pkt_offset, buf_len);
1248 bytesCopied += max_to_copy;
1250 "Hdr split: Continuing data buffer copy\n");
1252 max_to_copy, &pktEvent,
1253 packet->data + pkt_offset, igbe->rxWriteDelay);
1255 desc->
adv_wb.pkt_len =
htole((uint16_t)max_to_copy);
1259 std::min(packet->length - split_point, buf_len);
1260 bytesCopied += max_to_copy + split_point;
1262 DPRINTF(EthernetDesc,
"Hdr split: splitting at %d\n",
1265 split_point, &pktHdrEvent,
1266 packet->data, igbe->rxWriteDelay);
1268 max_to_copy, &pktDataEvent,
1269 packet->data + split_point, igbe->rxWriteDelay);
1272 desc->
adv_wb.pkt_len =
htole((uint16_t)(max_to_copy));
1275 panic(
"Header split not fitting within header buffer or "
1276 "undecodable packet not fitting in header unsupported\n");
1280 panic(
"Unimplemnted RX receive buffer type: %d\n",
1281 igbe->regs.srrctl.desctype());
1290 assert(unusedCache.size());
1292 desc = unusedCache.front();
1294 uint16_t crcfixup = igbe->regs.rctl.secrc() ? 0 : 4 ;
1295 DPRINTF(EthernetDesc,
"pktPtr->length: %d bytesCopied: %d "
1296 "stripcrc offset: %d value written: %d %d\n",
1297 pktPtr->length, bytesCopied, crcfixup,
1298 htole((uint16_t)(pktPtr->length + crcfixup)),
1299 (uint16_t)(pktPtr->length + crcfixup));
1302 assert(igbe->regs.rxcsum.pcss() == 0);
1304 DPRINTF(EthernetDesc,
"Packet written to memory updating Descriptor\n");
1308 uint16_t ext_err = 0;
1313 assert(bytesCopied <= pktPtr->length);
1314 if (bytesCopied == pktPtr->length)
1322 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1330 if (
ip && igbe->regs.rxcsum.ipofld()) {
1331 DPRINTF(EthernetDesc,
"Checking IP checksum\n");
1334 igbe->etherDeviceStats.rxIpChecksums++;
1338 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1342 if (
tcp && igbe->regs.rxcsum.tuofld()) {
1343 DPRINTF(EthernetDesc,
"Checking TCP checksum\n");
1347 igbe->etherDeviceStats.rxTcpChecksums++;
1349 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1356 if (udp && igbe->regs.rxcsum.tuofld()) {
1357 DPRINTF(EthernetDesc,
"Checking UDP checksum\n");
1361 igbe->etherDeviceStats.rxUdpChecksums++;
1362 if (
cksum(udp) != 0) {
1363 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1369 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1372 switch (igbe->regs.srrctl.desctype()) {
1374 desc->
legacy.len =
htole((uint16_t)(pktPtr->length + crcfixup));
1384 if (igbe->regs.rxcsum.pcsd()) {
1397 panic(
"Unimplemnted RX receive buffer type %d\n",
1398 igbe->regs.srrctl.desctype());
1401 DPRINTF(EthernetDesc,
"Descriptor complete w0: %#x w1: %#x\n",
1404 if (bytesCopied == pktPtr->length) {
1406 "Packet completely written to descriptor buffers\n");
1408 if (igbe->regs.rdtr.delay()) {
1409 Tick delay = igbe->regs.rdtr.delay() * igbe->intClock();
1410 DPRINTF(EthernetSM,
"RXS: Scheduling DTR for %d\n", delay);
1411 igbe->reschedule(igbe->rdtrEvent,
curTick() + delay);
1414 if (igbe->regs.radv.idv()) {
1415 Tick delay = igbe->regs.radv.idv() * igbe->intClock();
1416 DPRINTF(EthernetSM,
"RXS: Scheduling ADV for %d\n", delay);
1417 if (!igbe->radvEvent.scheduled()) {
1418 igbe->schedule(igbe->radvEvent,
curTick() + delay);
1423 if (!igbe->regs.rdtr.delay() && !igbe->regs.radv.idv()) {
1425 "RXS: Receive interrupt delay disabled, posting IT_RXT\n");
1426 igbe->postInterrupt(
IT_RXT);
1431 if (pktPtr->length <= igbe->regs.rsrpd.idv()) {
1433 "RXS: Posting IT_SRPD beacuse small packet received\n");
1444 DPRINTF(EthernetDesc,
"Processing of this descriptor complete\n");
1445 unusedCache.pop_front();
1446 usedCache.push_back(desc);
1453 igbe->rxTick =
true;
1454 igbe->restartClock();
1471 return pktEvent.scheduled() || wbEvent.scheduled() ||
1472 fetchEvent.scheduled() || pktHdrEvent.scheduled() ||
1473 pktDataEvent.scheduled();
1500 pktWaiting(false), pktMultiDesc(false),
1501 completionAddress(0), completionEnabled(false),
1502 useTso(false), tsoHeaderLen(0), tsoMss(0), tsoTotalLen(0), tsoUsedLen(0),
1503 tsoPrevSeq(0), tsoPktPayloadBytes(0), tsoLoadedHeader(false),
1504 tsoPktHasHeader(false), tsoDescBytesUsed(0), tsoCopyBytes(0), tsoPkts(0),
1506 headerEvent([
this]{ headerComplete(); },
n),
1507 nullEvent([
this]{ nullCallback(); },
n)
1509 annSmFetch =
"TX Desc Fetch";
1510 annSmWb =
"TX Desc Writeback";
1511 annUnusedDescQ =
"TX Unused Descriptors";
1512 annUnusedCacheQ =
"TX Unused Descriptor Cache";
1513 annUsedCacheQ =
"TX Used Descriptor Cache";
1514 annUsedDescQ =
"TX Used Descriptors";
1515 annDescQ =
"TX Descriptors";
1521 assert(unusedCache.size());
1524 DPRINTF(EthernetDesc,
"Checking and processing context descriptors\n");
1526 while (!useTso && unusedCache.size() &&
1528 DPRINTF(EthernetDesc,
"Got context descriptor type...\n");
1530 desc = unusedCache.front();
1531 DPRINTF(EthernetDesc,
"Descriptor upper: %#x lower: %#X\n",
1532 desc->
d1, desc->
d2);
1544 DPRINTF(EthernetDesc,
"TCP offload enabled for packet hdrlen: "
1549 tsoLoadedHeader =
false;
1550 tsoDescBytesUsed = 0;
1553 tsoPktHasHeader =
false;
1559 unusedCache.pop_front();
1560 usedCache.push_back(desc);
1563 if (!unusedCache.size())
1566 desc = unusedCache.front();
1569 DPRINTF(EthernetDesc,
"TCP offload(adv) enabled for packet "
1570 "hdrlen: %d mss: %d paylen %d\n",
1574 tsoLoadedHeader =
false;
1575 tsoDescBytesUsed = 0;
1578 tsoPktHasHeader =
false;
1582 if (useTso && !tsoLoadedHeader) {
1584 DPRINTF(EthernetDesc,
"Starting DMA of TSO header\n");
1587 assert(tsoHeaderLen <= 256);
1589 tsoHeaderLen, &headerEvent, tsoHeader, 0);
1596 DPRINTF(EthernetDesc,
"TSO: Fetching TSO header complete\n");
1599 assert(unusedCache.size());
1600 TxDesc *desc = unusedCache.front();
1601 DPRINTF(EthernetDesc,
"TSO: len: %d tsoHeaderLen: %d\n",
1605 tsoDescBytesUsed = 0;
1606 tsoLoadedHeader =
true;
1607 unusedCache.pop_front();
1608 usedCache.push_back(desc);
1610 DPRINTF(EthernetDesc,
"TSO: header part of larger payload\n");
1611 tsoDescBytesUsed = tsoHeaderLen;
1612 tsoLoadedHeader =
true;
1621 if (!unusedCache.size())
1624 DPRINTF(EthernetDesc,
"Starting processing of descriptor\n");
1626 assert(!useTso || tsoLoadedHeader);
1627 TxDesc *desc = unusedCache.front();
1630 DPRINTF(EthernetDesc,
"getPacket(): TxDescriptor data "
1631 "d1: %#llx d2: %#llx\n", desc->
d1, desc->
d2);
1632 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d "
1633 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1634 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1636 if (tsoPktHasHeader)
1637 tsoCopyBytes = std::min((tsoMss + tsoHeaderLen) -
p->length,
1640 tsoCopyBytes = std::min(tsoMss,
1643 tsoCopyBytes + (tsoPktHasHeader ? 0 : tsoHeaderLen);
1645 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d "
1646 "this descLen: %d\n",
1648 DPRINTF(EthernetDesc,
"TSO: pktHasHeader: %d\n", tsoPktHasHeader);
1649 DPRINTF(EthernetDesc,
"TSO: Next packet is %d bytes\n", pkt_size);
1653 DPRINTF(EthernetDesc,
"Next TX packet is %d bytes\n",
1661 assert(unusedCache.size());
1664 desc = unusedCache.front();
1666 DPRINTF(EthernetDesc,
"getPacketData(): TxDescriptor data "
1667 "d1: %#llx d2: %#llx\n", desc->
d1, desc->
d2);
1675 DPRINTF(EthernetDesc,
"Starting DMA of packet at offset %d\n",
p->length);
1678 assert(tsoLoadedHeader);
1679 if (!tsoPktHasHeader) {
1681 "Loading TSO header (%d bytes) into start of packet\n",
1683 memcpy(
p->data, &tsoHeader, tsoHeaderLen);
1684 p->length +=tsoHeaderLen;
1685 tsoPktHasHeader =
true;
1691 "Starting DMA of packet at offset %d length: %d\n",
1692 p->length, tsoCopyBytes);
1695 tsoCopyBytes, &pktEvent,
p->data +
p->length,
1697 tsoDescBytesUsed += tsoCopyBytes;
1711 assert(unusedCache.size());
1714 DPRINTF(EthernetDesc,
"DMA of packet complete\n");
1717 desc = unusedCache.front();
1721 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1722 desc->
d1, desc->
d2);
1726 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d "
1727 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1728 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1729 pktPtr->simLength += tsoCopyBytes;
1730 pktPtr->length += tsoCopyBytes;
1731 tsoUsedLen += tsoCopyBytes;
1732 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d\n",
1733 tsoDescBytesUsed, tsoCopyBytes);
1742 (pktPtr->length < (tsoMss + tsoHeaderLen) &&
1743 tsoTotalLen != tsoUsedLen && useTso)) {
1745 unusedCache.pop_front();
1746 usedCache.push_back(desc);
1748 tsoDescBytesUsed = 0;
1751 pktMultiDesc =
true;
1753 DPRINTF(EthernetDesc,
"Partial Packet Descriptor of %d bytes Done\n",
1763 pktMultiDesc =
false;
1775 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1776 desc->
d1, desc->
d2);
1782 DPRINTF(EthernetDesc,
"TSO: Modifying IP header. Id + %d\n",
1784 ip->id(
ip->id() + tsoPkts++);
1785 ip->len(pktPtr->length -
EthPtr(pktPtr)->size());
1788 ip6->plen(pktPtr->length -
EthPtr(pktPtr)->size());
1792 "TSO: Modifying TCP header. old seq %d + %d\n",
1793 tcp->seq(), tsoPrevSeq);
1794 tcp->seq(
tcp->seq() + tsoPrevSeq);
1795 if (tsoUsedLen != tsoTotalLen)
1796 tcp->flags(
tcp->flags() & ~9);
1800 DPRINTF(EthernetDesc,
"TSO: Modifying UDP header.\n");
1801 udp->
len(pktPtr->length -
EthPtr(pktPtr)->size());
1803 tsoPrevSeq = tsoUsedLen;
1806 if (debug::EthernetDesc) {
1809 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1812 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1817 DPRINTF(EthernetDesc,
"Calculating checksums for packet\n");
1824 igbe->etherDeviceStats.txIpChecksums++;
1825 DPRINTF(EthernetDesc,
"Calculated IP checksum\n");
1833 igbe->etherDeviceStats.txTcpChecksums++;
1834 DPRINTF(EthernetDesc,
"Calculated TCP checksum\n");
1839 igbe->etherDeviceStats.txUdpChecksums++;
1840 DPRINTF(EthernetDesc,
"Calculated UDP checksum\n");
1842 panic(
"Told to checksum, but don't know how\n");
1849 DPRINTF(EthernetDesc,
"Descriptor had IDE set\n");
1850 if (igbe->regs.tidv.idv()) {
1851 Tick delay = igbe->regs.tidv.idv() * igbe->intClock();
1852 DPRINTF(EthernetDesc,
"setting tidv\n");
1853 igbe->reschedule(igbe->tidvEvent,
curTick() + delay,
true);
1856 if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) {
1857 Tick delay = igbe->regs.tadv.idv() * igbe->intClock();
1858 DPRINTF(EthernetDesc,
"setting tadv\n");
1859 if (!igbe->tadvEvent.scheduled()) {
1860 igbe->schedule(igbe->tadvEvent,
curTick() + delay);
1867 DPRINTF(EthernetDesc,
"Descriptor Done\n");
1868 unusedCache.pop_front();
1869 usedCache.push_back(desc);
1870 tsoDescBytesUsed = 0;
1873 if (useTso && tsoUsedLen == tsoTotalLen)
1878 "------Packet of %d bytes ready for transmission-------\n",
1883 tsoPktHasHeader =
false;
1885 if (igbe->regs.txdctl.wthresh() == 0) {
1886 DPRINTF(EthernetDesc,
"WTHRESH == 0, writing back descriptor\n");
1888 }
else if (!igbe->regs.txdctl.gran() && igbe->regs.txdctl.wthresh() <=
1889 descInBlock(usedCache.size())) {
1890 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1891 writeback((igbe->cacheBlockSize()-1)>>4);
1892 }
else if (igbe->regs.txdctl.wthresh() <= usedCache.size()) {
1893 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1894 writeback((igbe->cacheBlockSize()-1)>>4);
1904 DPRINTF(EthernetDesc,
"actionAfterWb() completionEnabled: %d\n",
1907 if (completionEnabled) {
1908 descEnd = igbe->regs.tdh();
1910 "Completion writing back value: %d to addr: %#x\n", descEnd,
1913 sizeof(descEnd), &nullEvent, (uint8_t *)&descEnd, 0);
1989 igbe->txTick =
true;
1990 igbe->restartClock();
1997 return pktEvent.scheduled() || wbEvent.scheduled() ||
1998 fetchEvent.scheduled();
2015 unsigned int count(0);
2029 DPRINTF(Drain,
"IGbE not drained\n");
2045 DPRINTF(EthernetSM,
"resuming from drain");
2059 DPRINTF(Drain,
"IGbE done draining, processing drain event\n");
2069 DPRINTF(EthernetSM,
"TXS: TX disabled, stopping ticking\n");
2078 DPRINTF(EthernetSM,
"TXS: packet placed in TX FIFO\n");
2093 DPRINTF(EthernetSM,
"TXS: LWTHRESH caused posting of TXDLOW\n");
2098 txPacket = std::make_shared<EthPacketData>(16384);
2106 DPRINTF(EthernetSM,
"TXS: No descriptors left in ring, forcing "
2107 "writeback stopping ticking and posting TXQE\n");
2115 DPRINTF(EthernetSM,
"TXS: No descriptors available in cache, "
2116 "fetching and stopping ticking\n");
2125 "TXS: Fetching TSO header, stopping ticking\n");
2132 DPRINTF(EthernetSM,
"TXS: Reserving %d bytes in FIFO and "
2133 "beginning DMA of next packet\n", size);
2136 }
else if (size == 0) {
2137 DPRINTF(EthernetSM,
"TXS: getPacketSize returned: %d\n", size);
2139 "TXS: No packets to get, writing back used descriptors\n");
2142 DPRINTF(EthernetSM,
"TXS: FIFO full, stopping ticking until space "
2143 "available in FIFO\n");
2150 DPRINTF(EthernetSM,
"TXS: Nothing to do, stopping ticking\n");
2160 DPRINTF(Ethernet,
"RxFIFO: Receiving pcakte from wire\n");
2164 DPRINTF(Ethernet,
"RxFIFO: RX not enabled, dropping\n");
2172 "RXS: received packet into fifo, starting ticking\n");
2177 DPRINTF(Ethernet,
"RxFIFO: Packet won't fit in fifo... dropped\n");
2191 DPRINTF(EthernetSM,
"RXS: RX disabled, stopping ticking\n");
2198 DPRINTF(EthernetSM,
"RXS: Packet completed DMA to memory\n");
2200 DPRINTF(EthernetSM,
"RXS: descLeft: %d rdmts: %d rdlen: %d\n",
2204 int ratio = (1ULL << (
regs.
rctl.rdmts() + 1));
2206 DPRINTF(Ethernet,
"RXS: Interrupting (RXDMT) "
2207 "because of descriptors left\n");
2214 if (descLeft == 0) {
2216 DPRINTF(EthernetSM,
"RXS: No descriptors left in ring, forcing"
2217 " writeback and stopping ticking\n");
2226 "RXS: Writing back because WTHRESH >= descUsed\n");
2236 DPRINTF(EthernetSM,
"RXS: Fetching descriptors because "
2237 "descUnused < PTHRESH\n");
2243 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, "
2244 "fetching descriptors and stopping ticking\n");
2252 "RXS: stopping ticking until packet DMA completes\n");
2259 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, "
2260 "stopping ticking\n");
2262 DPRINTF(EthernetSM,
"RXS: No descriptors available, fetching\n");
2267 DPRINTF(EthernetSM,
"RXS: RxFIFO empty, stopping ticking\n");
2277 DPRINTF(EthernetSM,
"RXS: Writing packet into memory\n");
2279 DPRINTF(EthernetSM,
"RXS: Removing packet from FIFO\n");
2284 DPRINTF(EthernetSM,
"RXS: stopping ticking until packet DMA completes\n");
2299 if (debug::EthernetSM) {
2302 DPRINTF(EthernetSM,
"Transmitting Ip packet with Id=%d\n",
2305 DPRINTF(EthernetSM,
"Transmitting Non-Ip packet\n");
2308 "TxFIFO: Successful transmit, bytes available in fifo: %d\n",
2321 DPRINTF(EthernetSM,
"IGbE: -------------- Cycle --------------\n");
2358 DPRINTF(EthernetSM,
"TxFIFO: Transmission complete\n");
2378 bool txPktExists =
txPacket !=
nullptr;
2381 txPacket->serialize(
"txpacket", cp);
2383 Tick rdtr_time = 0, radv_time = 0, tidv_time = 0, tadv_time = 0,
2432 txPacket = std::make_shared<EthPacketData>(16384);
2433 txPacket->unserialize(
"txpacket", cp);
2440 Tick rdtr_time, radv_time, tidv_time, tadv_time, inter_time;