47 #include "debug/Drain.hh"
48 #include "debug/EthernetAll.hh"
51 #include "params/IGbE.hh"
60 rxFifo(
p->rx_fifo_size), txFifo(
p->tx_fifo_size), inTick(false),
61 rxTick(false), txTick(false), txFifoTick(false), rxDmaPacket(false),
62 pktOffset(0), fetchDelay(
p->fetch_delay), wbDelay(
p->wb_delay),
63 fetchCompDelay(
p->fetch_comp_delay), wbCompDelay(
p->wb_comp_delay),
64 rxWriteDelay(
p->rx_write_delay), txReadDelay(
p->tx_read_delay),
66 radvEvent([
this]{ radvProcess(); },
name()),
67 tadvEvent([
this]{ tadvProcess(); },
name()),
68 tidvEvent([
this]{ tidvProcess(); },
name()),
69 tickEvent([
this]{ tick(); },
name()),
70 interEvent([
this]{ delayIntEvent(); },
name()),
71 rxDescCache(
this,
name()+
".RxDesc",
p->rx_desc_cache_size),
72 txDescCache(
this,
name()+
".TxDesc",
p->tx_desc_cache_size),
109 memcpy(
flash,
p->hardware_address.bytes(), ETH_ADDR_LEN);
110 for (
int x = 0;
x < ETH_ADDR_LEN/2;
x++)
142 if (if_name ==
"interface")
154 panic(
"Device specific PCI config space not implemented.\n");
164 #define IN_RANGE(val, base, len) (val >= base && val < (base + len))
173 panic(
"Invalid PCI memory access to unmapped memory.\n");
181 DPRINTF(Ethernet,
"Read device register %#X\n", daddr);
208 DPRINTF(Ethernet,
"Reading ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
222 pkt->
setLE<uint32_t>(0);
243 pkt->
setLE<uint32_t>(0);
274 "Posting interrupt because of RDTR.FPD write\n");
345 panic(
"Read request to unknown register number: %#x\n", daddr);
347 pkt->
setLE<uint32_t>(0);
362 panic(
"Invalid PCI memory access to unmapped memory.\n");
368 assert(pkt->
getSize() ==
sizeof(uint32_t));
370 DPRINTF(Ethernet,
"Wrote device register %#X value %#X\n",
371 daddr, pkt->
getLE<uint32_t>());
376 uint32_t
val = pkt->
getLE<uint32_t>();
385 warn(
"TX Flow control enabled, should implement\n");
387 warn(
"RX Flow control enabled, should implement\n");
409 DPRINTF(EthernetEEPROM,
"EEPROM bit read: %d word: %#X\n",
418 panic(
"What's going on with eeprom interface? opcode:"
419 " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)
eeOpcode,
433 DPRINTF(EthernetEEPROM,
"EEPROM: opcode: %#X:%d addr: %#X:%d\n",
453 DPRINTF(EthernetEEPROM,
"EEPROM: read addr: %#X data %#x\n",
460 panic(
"No support for interrupt on mdic complete\n");
462 panic(
"No support for reading anything but phy\n");
463 DPRINTF(Ethernet,
"%s phy address %x\n",
464 regs.
mdic.op() == 1 ?
"Writing" :
"Reading",
491 DPRINTF(Ethernet,
"Writing ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
502 DPRINTF(EthernetIntr,
"Posting interrupt because of ICS write\n");
521 DPRINTF(EthernetSM,
"RXS: Got RESET!\n");
539 if (
regs.
tctl.en() && !oldtctl.en()) {
560 warn(
"Writing to IVAR0, ignoring...\n");
589 DPRINTF(EthernetSM,
"RXS: RDT Updated.\n");
591 DPRINTF(EthernetSM,
"RXS: RDT Fetching Descriptors!\n");
594 DPRINTF(EthernetSM,
"RXS: RDT NOT Fetching Desc b/c draining!\n");
625 panic(
"No support for DCA\n");
629 DPRINTF(EthernetSM,
"TXS: TX Tail pointer updated\n");
631 DPRINTF(EthernetSM,
"TXS: TDT Fetching Descriptors!\n");
634 DPRINTF(EthernetSM,
"TXS: TDT NOT Fetching Desc b/c draining!\n");
667 panic(
"Extended RX descriptors not implemented\n");
684 panic(
"Write request to unknown register number: %#x\n", daddr);
704 "EINT: postInterrupt() curTick(): %d itr: %d interval: %d\n",
707 if (
regs.
itr.interval() == 0 || now ||
715 assert(int_time > 0);
716 DPRINTF(EthernetIntr,
"EINT: Scheduling timer interrupt for tick %d\n",
738 DPRINTF(Ethernet,
"Interrupt Masked. Not Posting\n");
742 DPRINTF(Ethernet,
"Posting Interrupt\n");
767 DPRINTF(EthernetIntr,
"EINT: Posting interrupt to CPU now. Vector %#x\n",
781 "EINT: Clearing interrupt to CPU now. Vector %#x\n",
790 DPRINTF(Ethernet,
"Checking interrupts icr: %#x imr: %#x\n",
regs.
icr(),
794 DPRINTF(Ethernet,
"Mask cleaned all interrupts\n");
800 DPRINTF(Ethernet,
"ITR = %#X itr.interval = %#X\n",
804 if (
regs.
itr.interval() == 0) {
808 "Possibly scheduling interrupt because of imr write\n");
811 DPRINTF(Ethernet,
"Scheduling for %d\n",
t);
823 : igbe(
i), _name(
n), cachePnt(0), size(
s), curFetching(0),
824 wbOut(0), moreToWb(false), wbAlignment(0), pktPtr(NULL),
825 wbDelayEvent([this]{ writeback1(); },
n),
826 fetchDelayEvent([
this]{ fetchDescriptors1(); },
n),
827 fetchEvent([
this]{ fetchComplete(); },
n),
828 wbEvent([
this]{ wbComplete(); },
n)
830 fetchBuf =
new T[size];
846 if (usedCache.size() > 0 || curFetching || wbOut)
847 panic(
"Descriptor Address, Length or Head changed. Bad\n");
856 int curHead = descHead();
857 int max_to_wb = usedCache.size();
862 if (aMask < wbAlignment) {
867 "Writing back already in process, returning\n");
875 DPRINTF(EthernetDesc,
"Writing back descriptors head: %d tail: "
876 "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
877 curHead, descTail(), descLen(), cachePnt, max_to_wb,
880 if (max_to_wb + curHead >= descLen()) {
881 max_to_wb = descLen() - curHead;
884 }
else if (wbAlignment != 0) {
886 max_to_wb = max_to_wb & ~wbAlignment;
889 DPRINTF(EthernetDesc,
"Writing back %d descriptors\n", max_to_wb);
896 assert(!wbDelayEvent.scheduled());
897 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
906 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
910 DPRINTF(EthernetDesc,
"Begining DMA of %d descriptors\n", wbOut);
912 for (
int x = 0;
x < wbOut;
x++) {
913 assert(usedCache.size());
914 memcpy(&wbBuf[
x], usedCache[
x],
sizeof(T));
919 igbe->dmaWrite(pciToDma(descBase() + descHead() *
sizeof(T)),
920 wbOut *
sizeof(T), &wbEvent, (uint8_t*)wbBuf,
932 "Currently fetching %d descriptors, returning\n",
937 if (descTail() >= cachePnt)
938 max_to_fetch = descTail() - cachePnt;
940 max_to_fetch = descLen() - cachePnt;
942 size_t free_cache = size - usedCache.size() - unusedCache.size();
944 max_to_fetch = std::min(max_to_fetch, free_cache);
947 DPRINTF(EthernetDesc,
"Fetching descriptors head: %d tail: "
948 "%d len: %d cachePnt: %d max_to_fetch: %d descleft: %d\n",
949 descHead(), descTail(), descLen(), cachePnt,
950 max_to_fetch, descLeft());
953 if (max_to_fetch == 0)
957 curFetching = max_to_fetch;
959 assert(!fetchDelayEvent.scheduled());
960 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
969 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
973 DPRINTF(EthernetDesc,
"Fetching descriptors at %#x (%#x), size: %#x\n",
974 descBase() + cachePnt *
sizeof(T),
975 pciToDma(descBase() + cachePnt *
sizeof(T)),
976 curFetching *
sizeof(T));
978 igbe->dmaRead(pciToDma(descBase() + cachePnt *
sizeof(T)),
979 curFetching *
sizeof(T), &fetchEvent, (uint8_t*)fetchBuf,
980 igbe->fetchCompDelay);
988 for (
int x = 0;
x < curFetching;
x++) {
990 memcpy(newDesc, &fetchBuf[
x],
sizeof(T));
991 unusedCache.push_back(newDesc);
996 int oldCp = cachePnt;
999 cachePnt += curFetching;
1000 assert(cachePnt <= descLen());
1001 if (cachePnt == descLen())
1006 DPRINTF(EthernetDesc,
"Fetching complete cachePnt %d -> %d\n",
1018 long curHead = descHead();
1020 long oldHead = curHead;
1023 for (
int x = 0;
x < wbOut;
x++) {
1024 assert(usedCache.size());
1025 delete usedCache[0];
1026 usedCache.pop_front();
1032 if (curHead >= descLen())
1033 curHead -= descLen();
1036 updateHead(curHead);
1038 DPRINTF(EthernetDesc,
"Writeback complete curHead %d -> %d\n",
1045 DPRINTF(EthernetDesc,
"Writeback has more todo\n");
1058 DPRINTF(EthernetDesc,
"Reseting descriptor cache\n");
1060 delete usedCache[
x];
1062 delete unusedCache[
x];
1065 unusedCache.clear();
1085 (uint8_t*)usedCache[
x],
sizeof(T));
1092 (uint8_t*)unusedCache[
x],
sizeof(T));
1095 Tick fetch_delay = 0, wb_delay = 0;
1096 if (fetchDelayEvent.scheduled())
1097 fetch_delay = fetchDelayEvent.when();
1099 if (wbDelayEvent.scheduled())
1100 wb_delay = wbDelayEvent.when();
1122 (uint8_t*)temp,
sizeof(T));
1123 usedCache.push_back(temp);
1131 (uint8_t*)temp,
sizeof(T));
1132 unusedCache.push_back(temp);
1134 Tick fetch_delay = 0, wb_delay = 0;
1138 igbe->schedule(fetchDelayEvent, fetch_delay);
1140 igbe->schedule(wbDelayEvent, wb_delay);
1150 pktHdrEvent([
this]{ pktSplitDone(); },
n),
1151 pktDataEvent([
this]{ pktSplitDone(); },
n)
1154 annSmFetch =
"RX Desc Fetch";
1155 annSmWb =
"RX Desc Writeback";
1156 annUnusedDescQ =
"RX Unused Descriptors";
1157 annUnusedCacheQ =
"RX Unused Descriptor Cache";
1158 annUsedCacheQ =
"RX Used Descriptor Cache";
1159 annUsedDescQ =
"RX Used Descriptors";
1160 annDescQ =
"RX Descriptors";
1168 "Part of split packet done: splitcount now %d\n", splitCount);
1169 assert(splitCount <= 2);
1170 if (splitCount != 2)
1174 "Part of split packet done: calling pktComplete()\n");
1181 assert(unusedCache.size());
1187 unsigned buf_len, hdr_len;
1189 RxDesc *desc = unusedCache.front();
1190 switch (igbe->regs.srrctl.desctype()) {
1192 assert(pkt_offset == 0);
1193 bytesCopied = packet->length;
1194 DPRINTF(EthernetDesc,
"Packet Length: %d Desc Size: %d\n",
1195 packet->length, igbe->regs.rctl.descSize());
1196 assert(packet->length < igbe->regs.rctl.descSize());
1198 packet->length, &pktEvent, packet->data,
1199 igbe->rxWriteDelay);
1202 assert(pkt_offset == 0);
1203 bytesCopied = packet->length;
1204 buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
1205 igbe->regs.rctl.descSize();
1206 DPRINTF(EthernetDesc,
"Packet Length: %d srrctl: %#x Desc Size: %d\n",
1207 packet->length, igbe->regs.srrctl(), buf_len);
1208 assert(packet->length < buf_len);
1210 packet->length, &pktEvent, packet->data,
1211 igbe->rxWriteDelay);
1214 desc->
adv_wb.pkt_len =
htole((uint16_t)(pktPtr->length));
1219 buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
1220 igbe->regs.rctl.descSize();
1221 hdr_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.hdrLen() : 0;
1223 "lpe: %d Packet Length: %d offset: %d srrctl: %#x "
1224 "hdr addr: %#x Hdr Size: %d desc addr: %#x Desc Size: %d\n",
1225 igbe->regs.rctl.lpe(), packet->length, pkt_offset,
1226 igbe->regs.srrctl(), desc->
adv_read.hdr, hdr_len,
1229 split_point =
hsplit(pktPtr);
1231 if (packet->length <= hdr_len) {
1232 bytesCopied = packet->length;
1233 assert(pkt_offset == 0);
1234 DPRINTF(EthernetDesc,
"Hdr split: Entire packet in header\n");
1236 packet->length, &pktEvent, packet->data,
1237 igbe->rxWriteDelay);
1238 desc->
adv_wb.header_len =
htole((uint16_t)packet->length);
1241 }
else if (split_point) {
1246 std::min(packet->length - pkt_offset, buf_len);
1247 bytesCopied += max_to_copy;
1249 "Hdr split: Continuing data buffer copy\n");
1251 max_to_copy, &pktEvent,
1252 packet->data + pkt_offset, igbe->rxWriteDelay);
1254 desc->
adv_wb.pkt_len =
htole((uint16_t)max_to_copy);
1258 std::min(packet->length - split_point, buf_len);
1259 bytesCopied += max_to_copy + split_point;
1261 DPRINTF(EthernetDesc,
"Hdr split: splitting at %d\n",
1264 split_point, &pktHdrEvent,
1265 packet->data, igbe->rxWriteDelay);
1267 max_to_copy, &pktDataEvent,
1268 packet->data + split_point, igbe->rxWriteDelay);
1271 desc->
adv_wb.pkt_len =
htole((uint16_t)(max_to_copy));
1274 panic(
"Header split not fitting within header buffer or "
1275 "undecodable packet not fitting in header unsupported\n");
1279 panic(
"Unimplemnted RX receive buffer type: %d\n",
1280 igbe->regs.srrctl.desctype());
1289 assert(unusedCache.size());
1291 desc = unusedCache.front();
1293 uint16_t crcfixup = igbe->regs.rctl.secrc() ? 0 : 4 ;
1294 DPRINTF(EthernetDesc,
"pktPtr->length: %d bytesCopied: %d "
1295 "stripcrc offset: %d value written: %d %d\n",
1296 pktPtr->length, bytesCopied, crcfixup,
1297 htole((uint16_t)(pktPtr->length + crcfixup)),
1298 (uint16_t)(pktPtr->length + crcfixup));
1301 assert(igbe->regs.rxcsum.pcss() == 0);
1303 DPRINTF(EthernetDesc,
"Packet written to memory updating Descriptor\n");
1307 uint16_t ext_err = 0;
1312 assert(bytesCopied <= pktPtr->
length);
1313 if (bytesCopied == pktPtr->length)
1321 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1329 if (
ip && igbe->regs.rxcsum.ipofld()) {
1330 DPRINTF(EthernetDesc,
"Checking IP checksum\n");
1333 igbe->rxIpChecksums++;
1337 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1341 if (
tcp && igbe->regs.rxcsum.tuofld()) {
1342 DPRINTF(EthernetDesc,
"Checking TCP checksum\n");
1346 igbe->rxTcpChecksums++;
1348 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1355 if (udp && igbe->regs.rxcsum.tuofld()) {
1356 DPRINTF(EthernetDesc,
"Checking UDP checksum\n");
1360 igbe->rxUdpChecksums++;
1361 if (
cksum(udp) != 0) {
1362 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1368 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1371 switch (igbe->regs.srrctl.desctype()) {
1373 desc->
legacy.len =
htole((uint16_t)(pktPtr->length + crcfixup));
1383 if (igbe->regs.rxcsum.pcsd()) {
1396 panic(
"Unimplemnted RX receive buffer type %d\n",
1397 igbe->regs.srrctl.desctype());
1400 DPRINTF(EthernetDesc,
"Descriptor complete w0: %#x w1: %#x\n",
1403 if (bytesCopied == pktPtr->length) {
1405 "Packet completely written to descriptor buffers\n");
1407 if (igbe->regs.rdtr.delay()) {
1408 Tick delay = igbe->regs.rdtr.delay() * igbe->intClock();
1409 DPRINTF(EthernetSM,
"RXS: Scheduling DTR for %d\n", delay);
1410 igbe->reschedule(igbe->rdtrEvent,
curTick() + delay);
1413 if (igbe->regs.radv.idv()) {
1414 Tick delay = igbe->regs.radv.idv() * igbe->intClock();
1415 DPRINTF(EthernetSM,
"RXS: Scheduling ADV for %d\n", delay);
1416 if (!igbe->radvEvent.scheduled()) {
1417 igbe->schedule(igbe->radvEvent,
curTick() + delay);
1422 if (!igbe->regs.rdtr.delay() && !igbe->regs.radv.idv()) {
1424 "RXS: Receive interrupt delay disabled, posting IT_RXT\n");
1425 igbe->postInterrupt(
IT_RXT);
1430 if (pktPtr->length <= igbe->regs.rsrpd.idv()) {
1432 "RXS: Posting IT_SRPD beacuse small packet received\n");
1443 DPRINTF(EthernetDesc,
"Processing of this descriptor complete\n");
1444 unusedCache.pop_front();
1445 usedCache.push_back(desc);
1452 igbe->rxTick =
true;
1453 igbe->restartClock();
1470 return pktEvent.scheduled() || wbEvent.scheduled() ||
1471 fetchEvent.scheduled() || pktHdrEvent.scheduled() ||
1472 pktDataEvent.scheduled();
1499 pktWaiting(false), pktMultiDesc(false),
1500 completionAddress(0), completionEnabled(false),
1501 useTso(false), tsoHeaderLen(0), tsoMss(0), tsoTotalLen(0), tsoUsedLen(0),
1502 tsoPrevSeq(0), tsoPktPayloadBytes(0), tsoLoadedHeader(false),
1503 tsoPktHasHeader(false), tsoDescBytesUsed(0), tsoCopyBytes(0), tsoPkts(0),
1505 headerEvent([
this]{ headerComplete(); },
n),
1506 nullEvent([
this]{ nullCallback(); },
n)
1508 annSmFetch =
"TX Desc Fetch";
1509 annSmWb =
"TX Desc Writeback";
1510 annUnusedDescQ =
"TX Unused Descriptors";
1511 annUnusedCacheQ =
"TX Unused Descriptor Cache";
1512 annUsedCacheQ =
"TX Used Descriptor Cache";
1513 annUsedDescQ =
"TX Used Descriptors";
1514 annDescQ =
"TX Descriptors";
1520 assert(unusedCache.size());
1523 DPRINTF(EthernetDesc,
"Checking and processing context descriptors\n");
1525 while (!useTso && unusedCache.size() &&
1527 DPRINTF(EthernetDesc,
"Got context descriptor type...\n");
1529 desc = unusedCache.front();
1530 DPRINTF(EthernetDesc,
"Descriptor upper: %#x lower: %#X\n",
1531 desc->
d1, desc->
d2);
1543 DPRINTF(EthernetDesc,
"TCP offload enabled for packet hdrlen: "
1548 tsoLoadedHeader =
false;
1549 tsoDescBytesUsed = 0;
1552 tsoPktHasHeader =
false;
1558 unusedCache.pop_front();
1559 usedCache.push_back(desc);
1562 if (!unusedCache.size())
1565 desc = unusedCache.front();
1568 DPRINTF(EthernetDesc,
"TCP offload(adv) enabled for packet "
1569 "hdrlen: %d mss: %d paylen %d\n",
1573 tsoLoadedHeader =
false;
1574 tsoDescBytesUsed = 0;
1577 tsoPktHasHeader =
false;
1581 if (useTso && !tsoLoadedHeader) {
1583 DPRINTF(EthernetDesc,
"Starting DMA of TSO header\n");
1586 assert(tsoHeaderLen <= 256);
1588 tsoHeaderLen, &headerEvent, tsoHeader, 0);
1595 DPRINTF(EthernetDesc,
"TSO: Fetching TSO header complete\n");
1598 assert(unusedCache.size());
1599 TxDesc *desc = unusedCache.front();
1600 DPRINTF(EthernetDesc,
"TSO: len: %d tsoHeaderLen: %d\n",
1604 tsoDescBytesUsed = 0;
1605 tsoLoadedHeader =
true;
1606 unusedCache.pop_front();
1607 usedCache.push_back(desc);
1609 DPRINTF(EthernetDesc,
"TSO: header part of larger payload\n");
1610 tsoDescBytesUsed = tsoHeaderLen;
1611 tsoLoadedHeader =
true;
1620 if (!unusedCache.size())
1623 DPRINTF(EthernetDesc,
"Starting processing of descriptor\n");
1625 assert(!useTso || tsoLoadedHeader);
1626 TxDesc *desc = unusedCache.front();
1629 DPRINTF(EthernetDesc,
"getPacket(): TxDescriptor data "
1630 "d1: %#llx d2: %#llx\n", desc->
d1, desc->
d2);
1631 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d "
1632 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1633 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1635 if (tsoPktHasHeader)
1636 tsoCopyBytes = std::min((tsoMss + tsoHeaderLen) -
p->length,
1639 tsoCopyBytes = std::min(tsoMss,
1642 tsoCopyBytes + (tsoPktHasHeader ? 0 : tsoHeaderLen);
1644 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d "
1645 "this descLen: %d\n",
1647 DPRINTF(EthernetDesc,
"TSO: pktHasHeader: %d\n", tsoPktHasHeader);
1648 DPRINTF(EthernetDesc,
"TSO: Next packet is %d bytes\n", pkt_size);
1652 DPRINTF(EthernetDesc,
"Next TX packet is %d bytes\n",
1660 assert(unusedCache.size());
1663 desc = unusedCache.front();
1665 DPRINTF(EthernetDesc,
"getPacketData(): TxDescriptor data "
1666 "d1: %#llx d2: %#llx\n", desc->
d1, desc->
d2);
1674 DPRINTF(EthernetDesc,
"Starting DMA of packet at offset %d\n",
p->length);
1677 assert(tsoLoadedHeader);
1678 if (!tsoPktHasHeader) {
1680 "Loading TSO header (%d bytes) into start of packet\n",
1682 memcpy(
p->data, &tsoHeader,tsoHeaderLen);
1683 p->length +=tsoHeaderLen;
1684 tsoPktHasHeader =
true;
1690 "Starting DMA of packet at offset %d length: %d\n",
1691 p->length, tsoCopyBytes);
1694 tsoCopyBytes, &pktEvent,
p->data +
p->length,
1696 tsoDescBytesUsed += tsoCopyBytes;
1710 assert(unusedCache.size());
1713 DPRINTF(EthernetDesc,
"DMA of packet complete\n");
1716 desc = unusedCache.front();
1720 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1721 desc->
d1, desc->
d2);
1725 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d "
1726 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1727 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1728 pktPtr->simLength += tsoCopyBytes;
1729 pktPtr->length += tsoCopyBytes;
1730 tsoUsedLen += tsoCopyBytes;
1731 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d\n",
1732 tsoDescBytesUsed, tsoCopyBytes);
1741 (pktPtr->length < ( tsoMss + tsoHeaderLen) &&
1742 tsoTotalLen != tsoUsedLen && useTso)) {
1743 assert(!useTso || (tsoDescBytesUsed ==
TxdOp::getLen(desc)));
1744 unusedCache.pop_front();
1745 usedCache.push_back(desc);
1747 tsoDescBytesUsed = 0;
1750 pktMultiDesc =
true;
1752 DPRINTF(EthernetDesc,
"Partial Packet Descriptor of %d bytes Done\n",
1762 pktMultiDesc =
false;
1774 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1775 desc->
d1, desc->
d2);
1781 DPRINTF(EthernetDesc,
"TSO: Modifying IP header. Id + %d\n",
1783 ip->id(
ip->id() + tsoPkts++);
1784 ip->len(pktPtr->length -
EthPtr(pktPtr)->size());
1787 ip6->plen(pktPtr->length -
EthPtr(pktPtr)->size());
1791 "TSO: Modifying TCP header. old seq %d + %d\n",
1792 tcp->seq(), tsoPrevSeq);
1793 tcp->seq(
tcp->seq() + tsoPrevSeq);
1794 if (tsoUsedLen != tsoTotalLen)
1795 tcp->flags(
tcp->flags() & ~9);
1799 DPRINTF(EthernetDesc,
"TSO: Modifying UDP header.\n");
1800 udp->
len(pktPtr->length -
EthPtr(pktPtr)->size());
1802 tsoPrevSeq = tsoUsedLen;
1805 if (
DTRACE(EthernetDesc)) {
1808 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1811 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1816 DPRINTF(EthernetDesc,
"Calculating checksums for packet\n");
1823 igbe->txIpChecksums++;
1824 DPRINTF(EthernetDesc,
"Calculated IP checksum\n");
1832 igbe->txTcpChecksums++;
1833 DPRINTF(EthernetDesc,
"Calculated TCP checksum\n");
1838 igbe->txUdpChecksums++;
1839 DPRINTF(EthernetDesc,
"Calculated UDP checksum\n");
1841 panic(
"Told to checksum, but don't know how\n");
1848 DPRINTF(EthernetDesc,
"Descriptor had IDE set\n");
1849 if (igbe->regs.tidv.idv()) {
1850 Tick delay = igbe->regs.tidv.idv() * igbe->intClock();
1851 DPRINTF(EthernetDesc,
"setting tidv\n");
1852 igbe->reschedule(igbe->tidvEvent,
curTick() + delay,
true);
1855 if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) {
1856 Tick delay = igbe->regs.tadv.idv() * igbe->intClock();
1857 DPRINTF(EthernetDesc,
"setting tadv\n");
1858 if (!igbe->tadvEvent.scheduled()) {
1859 igbe->schedule(igbe->tadvEvent,
curTick() + delay);
1866 DPRINTF(EthernetDesc,
"Descriptor Done\n");
1867 unusedCache.pop_front();
1868 usedCache.push_back(desc);
1869 tsoDescBytesUsed = 0;
1872 if (useTso && tsoUsedLen == tsoTotalLen)
1877 "------Packet of %d bytes ready for transmission-------\n",
1882 tsoPktHasHeader =
false;
1884 if (igbe->regs.txdctl.wthresh() == 0) {
1885 DPRINTF(EthernetDesc,
"WTHRESH == 0, writing back descriptor\n");
1887 }
else if (!igbe->regs.txdctl.gran() && igbe->regs.txdctl.wthresh() <=
1888 descInBlock(usedCache.size())) {
1889 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1890 writeback((igbe->cacheBlockSize()-1)>>4);
1891 }
else if (igbe->regs.txdctl.wthresh() <= usedCache.size()) {
1892 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1893 writeback((igbe->cacheBlockSize()-1)>>4);
1903 DPRINTF(EthernetDesc,
"actionAfterWb() completionEnabled: %d\n",
1906 if (completionEnabled) {
1907 descEnd = igbe->regs.tdh();
1909 "Completion writing back value: %d to addr: %#x\n", descEnd,
1912 sizeof(descEnd), &nullEvent, (uint8_t*)&descEnd, 0);
1988 igbe->txTick =
true;
1989 igbe->restartClock();
1996 return pktEvent.scheduled() || wbEvent.scheduled() ||
1997 fetchEvent.scheduled();
2014 unsigned int count(0);
2028 DPRINTF(Drain,
"IGbE not drained\n");
2044 DPRINTF(EthernetSM,
"resuming from drain");
2058 DPRINTF(Drain,
"IGbE done draining, processing drain event\n");
2068 DPRINTF(EthernetSM,
"TXS: TX disabled, stopping ticking\n");
2077 DPRINTF(EthernetSM,
"TXS: packet placed in TX FIFO\n");
2092 DPRINTF(EthernetSM,
"TXS: LWTHRESH caused posting of TXDLOW\n");
2097 txPacket = std::make_shared<EthPacketData>(16384);
2105 DPRINTF(EthernetSM,
"TXS: No descriptors left in ring, forcing "
2106 "writeback stopping ticking and posting TXQE\n");
2114 DPRINTF(EthernetSM,
"TXS: No descriptors available in cache, "
2115 "fetching and stopping ticking\n");
2124 "TXS: Fetching TSO header, stopping ticking\n");
2131 DPRINTF(EthernetSM,
"TXS: Reserving %d bytes in FIFO and "
2132 "beginning DMA of next packet\n", size);
2135 }
else if (size == 0) {
2136 DPRINTF(EthernetSM,
"TXS: getPacketSize returned: %d\n", size);
2138 "TXS: No packets to get, writing back used descriptors\n");
2141 DPRINTF(EthernetSM,
"TXS: FIFO full, stopping ticking until space "
2142 "available in FIFO\n");
2149 DPRINTF(EthernetSM,
"TXS: Nothing to do, stopping ticking\n");
2159 DPRINTF(Ethernet,
"RxFIFO: Receiving pcakte from wire\n");
2163 DPRINTF(Ethernet,
"RxFIFO: RX not enabled, dropping\n");
2171 "RXS: received packet into fifo, starting ticking\n");
2176 DPRINTF(Ethernet,
"RxFIFO: Packet won't fit in fifo... dropped\n");
2190 DPRINTF(EthernetSM,
"RXS: RX disabled, stopping ticking\n");
2197 DPRINTF(EthernetSM,
"RXS: Packet completed DMA to memory\n");
2199 DPRINTF(EthernetSM,
"RXS: descLeft: %d rdmts: %d rdlen: %d\n",
2205 DPRINTF(Ethernet,
"RXS: Interrupting (RXDMT) "
2206 "because of descriptors left\n");
2213 if (descLeft == 0) {
2215 DPRINTF(EthernetSM,
"RXS: No descriptors left in ring, forcing"
2216 " writeback and stopping ticking\n");
2225 "RXS: Writing back because WTHRESH >= descUsed\n");
2235 DPRINTF(EthernetSM,
"RXS: Fetching descriptors because "
2236 "descUnused < PTHRESH\n");
2242 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, "
2243 "fetching descriptors and stopping ticking\n");
2251 "RXS: stopping ticking until packet DMA completes\n");
2258 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, "
2259 "stopping ticking\n");
2261 DPRINTF(EthernetSM,
"RXS: No descriptors available, fetching\n");
2266 DPRINTF(EthernetSM,
"RXS: RxFIFO empty, stopping ticking\n");
2276 DPRINTF(EthernetSM,
"RXS: Writing packet into memory\n");
2278 DPRINTF(EthernetSM,
"RXS: Removing packet from FIFO\n");
2283 DPRINTF(EthernetSM,
"RXS: stopping ticking until packet DMA completes\n");
2298 if (
DTRACE(EthernetSM)) {
2301 DPRINTF(EthernetSM,
"Transmitting Ip packet with Id=%d\n",
2304 DPRINTF(EthernetSM,
"Transmitting Non-Ip packet\n");
2307 "TxFIFO: Successful transmit, bytes available in fifo: %d\n",
2320 DPRINTF(EthernetSM,
"IGbE: -------------- Cycle --------------\n");
2357 DPRINTF(EthernetSM,
"TxFIFO: Transmission complete\n");
2377 bool txPktExists =
txPacket !=
nullptr;
2382 Tick rdtr_time = 0, radv_time = 0, tidv_time = 0, tadv_time = 0,
2431 txPacket = std::make_shared<EthPacketData>(16384);
2439 Tick rdtr_time, radv_time, tidv_time, tadv_time, inter_time;
2468 IGbEParams::create()
2470 return new IGbE(
this);