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),
109 memcpy(
flash,
p->hardware_address.bytes(), ETH_ADDR_LEN);
110 for (
int x = 0;
x < ETH_ADDR_LEN/2;
x++)
143 if (if_name ==
"interface")
155 panic(
"Device specific PCI config space not implemented.\n");
165 #define IN_RANGE(val, base, len) (val >= base && val < (base + len)) 174 panic(
"Invalid PCI memory access to unmapped memory.\n");
182 DPRINTF(Ethernet,
"Read device register %#X\n", daddr);
209 DPRINTF(Ethernet,
"Reading ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
223 pkt->
setLE<uint32_t>(0);
244 pkt->
setLE<uint32_t>(0);
275 "Posting interrupt because of RDTR.FPD write\n");
346 panic(
"Read request to unknown register number: %#x\n", daddr);
348 pkt->
setLE<uint32_t>(0);
363 panic(
"Invalid PCI memory access to unmapped memory.\n");
369 assert(pkt->
getSize() ==
sizeof(uint32_t));
371 DPRINTF(Ethernet,
"Wrote device register %#X value %#X\n",
372 daddr, pkt->
getLE<uint32_t>());
377 uint32_t
val = pkt->
getLE<uint32_t>();
386 warn(
"TX Flow control enabled, should implement\n");
388 warn(
"RX Flow control enabled, should implement\n");
410 DPRINTF(EthernetEEPROM,
"EEPROM bit read: %d word: %#X\n",
419 panic(
"What's going on with eeprom interface? opcode:" 420 " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)
eeOpcode,
434 DPRINTF(EthernetEEPROM,
"EEPROM: opcode: %#X:%d addr: %#X:%d\n",
435 (uint32_t)eeOpcode, (uint32_t) eeOpBits,
436 (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits);
439 panic(
"Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode,
454 DPRINTF(EthernetEEPROM,
"EEPROM: read addr: %#X data %#x\n",
461 panic(
"No support for interrupt on mdic complete\n");
463 panic(
"No support for reading anything but phy\n");
464 DPRINTF(Ethernet,
"%s phy address %x\n",
465 regs.
mdic.op() == 1 ?
"Writing" :
"Reading",
492 DPRINTF(Ethernet,
"Writing ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
503 DPRINTF(EthernetIntr,
"Posting interrupt because of ICS write\n");
522 DPRINTF(EthernetSM,
"RXS: Got RESET!\n");
540 if (
regs.
tctl.en() && !oldtctl.en()) {
561 warn(
"Writing to IVAR0, ignoring...\n");
590 DPRINTF(EthernetSM,
"RXS: RDT Updated.\n");
592 DPRINTF(EthernetSM,
"RXS: RDT Fetching Descriptors!\n");
595 DPRINTF(EthernetSM,
"RXS: RDT NOT Fetching Desc b/c draining!\n");
626 panic(
"No support for DCA\n");
630 DPRINTF(EthernetSM,
"TXS: TX Tail pointer updated\n");
632 DPRINTF(EthernetSM,
"TXS: TDT Fetching Descriptors!\n");
635 DPRINTF(EthernetSM,
"TXS: TDT NOT Fetching Desc b/c draining!\n");
668 panic(
"Extended RX descriptors not implemented\n");
685 panic(
"Write request to unknown register number: %#x\n", daddr);
705 "EINT: postInterrupt() curTick(): %d itr: %d interval: %d\n",
708 if (
regs.
itr.interval() == 0 || now ||
716 assert(int_time > 0);
717 DPRINTF(EthernetIntr,
"EINT: Scheduling timer interrupt for tick %d\n",
739 DPRINTF(Ethernet,
"Interrupt Masked. Not Posting\n");
743 DPRINTF(Ethernet,
"Posting Interrupt\n");
768 DPRINTF(EthernetIntr,
"EINT: Posting interrupt to CPU now. Vector %#x\n",
782 "EINT: Clearing interrupt to CPU now. Vector %#x\n",
791 DPRINTF(Ethernet,
"Checking interrupts icr: %#x imr: %#x\n",
regs.
icr(),
795 DPRINTF(Ethernet,
"Mask cleaned all interrupts\n");
801 DPRINTF(Ethernet,
"ITR = %#X itr.interval = %#X\n",
805 if (
regs.
itr.interval() == 0) {
809 "Possibly scheduling interrupt because of imr write\n");
812 DPRINTF(Ethernet,
"Scheduling for %d\n", t);
824 : igbe(i), _name(n), cachePnt(0), size(s), curFetching(0),
825 wbOut(0), moreToWb(false), wbAlignment(0), pktPtr(NULL),
826 wbDelayEvent([this]{ writeback1(); },
n),
827 fetchDelayEvent([
this]{ fetchDescriptors1(); },
n),
828 fetchEvent([
this]{ fetchComplete(); },
n),
829 wbEvent([
this]{ wbComplete(); },
n)
831 fetchBuf =
new T[size];
847 if (usedCache.size() > 0 || curFetching || wbOut)
848 panic(
"Descriptor Address, Length or Head changed. Bad\n");
857 int curHead = descHead();
858 int max_to_wb = usedCache.size();
863 if (aMask < wbAlignment) {
868 "Writing back already in process, returning\n");
876 DPRINTF(EthernetDesc,
"Writing back descriptors head: %d tail: " 877 "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
878 curHead, descTail(), descLen(), cachePnt, max_to_wb,
881 if (max_to_wb + curHead >= descLen()) {
882 max_to_wb = descLen() - curHead;
885 }
else if (wbAlignment != 0) {
887 max_to_wb = max_to_wb & ~wbAlignment;
890 DPRINTF(EthernetDesc,
"Writing back %d descriptors\n", max_to_wb);
892 if (max_to_wb <= 0) {
893 if (usedCache.size())
896 igbe->anWe(annSmWb, annUsedCacheQ);
902 assert(!wbDelayEvent.scheduled());
903 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
904 igbe->anBegin(annSmWb,
"Prepare Writeback Desc");
913 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
917 DPRINTF(EthernetDesc,
"Begining DMA of %d descriptors\n", wbOut);
919 for (
int x = 0;
x < wbOut;
x++) {
920 assert(usedCache.size());
921 memcpy(&wbBuf[
x], usedCache[x],
sizeof(T));
922 igbe->anPq(annSmWb, annUsedCacheQ);
923 igbe->anPq(annSmWb, annDescQ);
924 igbe->anQ(annSmWb, annUsedDescQ);
928 igbe->anBegin(annSmWb,
"Writeback Desc DMA");
931 igbe->dmaWrite(pciToDma(descBase() + descHead() *
sizeof(T)),
932 wbOut *
sizeof(T), &wbEvent, (uint8_t*)wbBuf,
944 "Currently fetching %d descriptors, returning\n",
949 if (descTail() >= cachePnt)
950 max_to_fetch = descTail() - cachePnt;
952 max_to_fetch = descLen() - cachePnt;
954 size_t free_cache = size - usedCache.size() - unusedCache.size();
957 igbe->anWe(annSmFetch, annUnusedDescQ);
959 igbe->anPq(annSmFetch, annUnusedDescQ, max_to_fetch);
963 igbe->anWf(annSmFetch, annDescQ);
965 igbe->anRq(annSmFetch, annDescQ, free_cache);
968 max_to_fetch = std::min(max_to_fetch, free_cache);
971 DPRINTF(EthernetDesc,
"Fetching descriptors head: %d tail: " 972 "%d len: %d cachePnt: %d max_to_fetch: %d descleft: %d\n",
973 descHead(), descTail(), descLen(), cachePnt,
974 max_to_fetch, descLeft());
977 if (max_to_fetch == 0)
981 curFetching = max_to_fetch;
983 assert(!fetchDelayEvent.scheduled());
984 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
985 igbe->anBegin(annSmFetch,
"Prepare Fetch Desc");
994 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
998 igbe->anBegin(annSmFetch,
"Fetch Desc");
1000 DPRINTF(EthernetDesc,
"Fetching descriptors at %#x (%#x), size: %#x\n",
1001 descBase() + cachePnt *
sizeof(T),
1002 pciToDma(descBase() + cachePnt *
sizeof(T)),
1003 curFetching *
sizeof(T));
1004 assert(curFetching);
1005 igbe->dmaRead(pciToDma(descBase() + cachePnt *
sizeof(T)),
1006 curFetching *
sizeof(T), &fetchEvent, (uint8_t*)fetchBuf,
1007 igbe->fetchCompDelay);
1015 igbe->anBegin(annSmFetch,
"Fetch Complete");
1016 for (
int x = 0;
x < curFetching;
x++) {
1018 memcpy(newDesc, &fetchBuf[
x],
sizeof(T));
1019 unusedCache.push_back(newDesc);
1020 igbe->anDq(annSmFetch, annUnusedDescQ);
1021 igbe->anQ(annSmFetch, annUnusedCacheQ);
1022 igbe->anQ(annSmFetch, annDescQ);
1027 int oldCp = cachePnt;
1030 cachePnt += curFetching;
1031 assert(cachePnt <= descLen());
1032 if (cachePnt == descLen())
1037 DPRINTF(EthernetDesc,
"Fetching complete cachePnt %d -> %d\n",
1040 if ((descTail() >= cachePnt ? (descTail() - cachePnt) : (descLen() -
1043 igbe->anWe(annSmFetch, annUnusedDescQ);
1044 }
else if (!(size - usedCache.size() - unusedCache.size())) {
1045 igbe->anWf(annSmFetch, annDescQ);
1059 igbe->anBegin(annSmWb,
"Finish Writeback");
1061 long curHead = descHead();
1063 long oldHead = curHead;
1066 for (
int x = 0;
x < wbOut;
x++) {
1067 assert(usedCache.size());
1068 delete usedCache[0];
1069 usedCache.pop_front();
1071 igbe->anDq(annSmWb, annUsedCacheQ);
1072 igbe->anDq(annSmWb, annDescQ);
1078 if (curHead >= descLen())
1079 curHead -= descLen();
1082 updateHead(curHead);
1084 DPRINTF(EthernetDesc,
"Writeback complete curHead %d -> %d\n",
1091 DPRINTF(EthernetDesc,
"Writeback has more todo\n");
1097 if (usedCache.size())
1100 igbe->anWe(annSmWb, annUsedCacheQ);
1109 DPRINTF(EthernetDesc,
"Reseting descriptor cache\n");
1111 delete usedCache[
x];
1113 delete unusedCache[
x];
1116 unusedCache.clear();
1136 (uint8_t*)usedCache[
x],
sizeof(T));
1143 (uint8_t*)unusedCache[
x],
sizeof(T));
1146 Tick fetch_delay = 0, wb_delay = 0;
1147 if (fetchDelayEvent.scheduled())
1148 fetch_delay = fetchDelayEvent.when();
1150 if (wbDelayEvent.scheduled())
1151 wb_delay = wbDelayEvent.when();
1173 (uint8_t*)temp,
sizeof(T));
1174 usedCache.push_back(temp);
1182 (uint8_t*)temp,
sizeof(T));
1183 unusedCache.push_back(temp);
1185 Tick fetch_delay = 0, wb_delay = 0;
1189 igbe->schedule(fetchDelayEvent, fetch_delay);
1191 igbe->schedule(wbDelayEvent, wb_delay);
1206 annSmWb =
"RX Desc Writeback";
1219 "Part of split packet done: splitcount now %d\n",
splitCount);
1225 "Part of split packet done: calling pktComplete()\n");
1238 unsigned buf_len, hdr_len;
1243 assert(pkt_offset == 0);
1245 DPRINTF(EthernetDesc,
"Packet Length: %d Desc Size: %d\n",
1249 packet->length, &
pktEvent, packet->data,
1253 assert(pkt_offset == 0);
1257 DPRINTF(EthernetDesc,
"Packet Length: %d srrctl: %#x Desc Size: %d\n",
1259 assert(packet->length < buf_len);
1261 packet->length, &
pktEvent, packet->data,
1265 desc->
adv_wb.pkt_len =
htole((uint16_t)(pktPtr->length));
1274 "lpe: %d Packet Length: %d offset: %d srrctl: %#x " 1275 "hdr addr: %#x Hdr Size: %d desc addr: %#x Desc Size: %d\n",
1280 split_point =
hsplit(pktPtr);
1282 if (packet->length <= hdr_len) {
1284 assert(pkt_offset == 0);
1285 DPRINTF(EthernetDesc,
"Hdr split: Entire packet in header\n");
1287 packet->length, &
pktEvent, packet->data,
1289 desc->
adv_wb.header_len =
htole((uint16_t)packet->length);
1292 }
else if (split_point) {
1297 std::min(packet->length - pkt_offset, buf_len);
1300 "Hdr split: Continuing data buffer copy\n");
1305 desc->
adv_wb.pkt_len =
htole((uint16_t)max_to_copy);
1309 std::min(packet->length - split_point, buf_len);
1312 DPRINTF(EthernetDesc,
"Hdr split: splitting at %d\n",
1322 desc->
adv_wb.pkt_len =
htole((uint16_t)(max_to_copy));
1325 panic(
"Header split not fitting within header buffer or " 1326 "undecodable packet not fitting in header unsupported\n");
1330 panic(
"Unimplemnted RX receive buffer type: %d\n",
1347 DPRINTF(EthernetDesc,
"pktPtr->length: %d bytesCopied: %d " 1348 "stripcrc offset: %d value written: %d %d\n",
1351 (uint16_t)(
pktPtr->length + crcfixup));
1356 DPRINTF(EthernetDesc,
"Packet written to memory updating Descriptor\n");
1360 uint16_t ext_err = 0;
1365 assert(bytesCopied <= pktPtr->
length);
1374 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1383 DPRINTF(EthernetDesc,
"Checking IP checksum\n");
1387 if (
cksum(ip) != 0) {
1390 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1395 DPRINTF(EthernetDesc,
"Checking TCP checksum\n");
1400 if (
cksum(tcp) != 0) {
1401 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1409 DPRINTF(EthernetDesc,
"Checking UDP checksum\n");
1414 if (
cksum(udp) != 0) {
1415 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1421 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1426 desc->legacy.len =
htole((uint16_t)(
pktPtr->length + crcfixup));
1427 desc->legacy.status =
htole(status);
1428 desc->legacy.errors =
htole(err);
1430 desc->legacy.vlan = 0;
1434 desc->adv_wb.rss_type =
htole(0);
1435 desc->adv_wb.pkt_type =
htole(ptype);
1438 desc->adv_wb.rss_hash =
htole(0);
1440 desc->adv_wb.id =
htole(ip_id);
1441 desc->adv_wb.csum =
htole(csum);
1443 desc->adv_wb.status =
htole(status);
1444 desc->adv_wb.errors =
htole(ext_err);
1446 desc->adv_wb.vlan_tag =
htole(0);
1449 panic(
"Unimplemnted RX receive buffer type %d\n",
1453 DPRINTF(EthernetDesc,
"Descriptor complete w0: %#x w1: %#x\n",
1454 desc->adv_read.pkt, desc->adv_read.hdr);
1458 "Packet completely written to descriptor buffers\n");
1462 DPRINTF(EthernetSM,
"RXS: Scheduling DTR for %d\n", delay);
1468 DPRINTF(EthernetSM,
"RXS: Scheduling ADV for %d\n", delay);
1477 "RXS: Receive interrupt delay disabled, posting IT_RXT\n");
1485 "RXS: Posting IT_SRPD beacuse small packet received\n");
1497 DPRINTF(EthernetDesc,
"Processing of this descriptor complete\n");
1555 pktWaiting(false), pktMultiDesc(false),
1556 completionAddress(0), completionEnabled(false),
1557 useTso(false), tsoHeaderLen(0), tsoMss(0), tsoTotalLen(0), tsoUsedLen(0),
1558 tsoPrevSeq(0), tsoPktPayloadBytes(0), tsoLoadedHeader(false),
1559 tsoPktHasHeader(false), tsoDescBytesUsed(0), tsoCopyBytes(0), tsoPkts(0),
1565 annSmWb =
"TX Desc Writeback";
1579 DPRINTF(EthernetDesc,
"Checking and processing context descriptors\n");
1583 DPRINTF(EthernetDesc,
"Got context descriptor type...\n");
1586 DPRINTF(EthernetDesc,
"Descriptor upper: %#x lower: %#X\n",
1587 desc->d1, desc->d2);
1599 DPRINTF(EthernetDesc,
"TCP offload enabled for packet hdrlen: " 1626 DPRINTF(EthernetDesc,
"TCP offload(adv) enabled for packet " 1627 "hdrlen: %d mss: %d paylen %d\n",
1641 DPRINTF(EthernetDesc,
"Starting DMA of TSO header\n");
1653 DPRINTF(EthernetDesc,
"TSO: Fetching TSO header complete\n");
1658 DPRINTF(EthernetDesc,
"TSO: len: %d tsoHeaderLen: %d\n",
1667 DPRINTF(EthernetDesc,
"TSO: header part of larger payload\n");
1681 DPRINTF(EthernetDesc,
"Starting processing of descriptor\n");
1687 DPRINTF(EthernetDesc,
"getPacket(): TxDescriptor data " 1688 "d1: %#llx d2: %#llx\n", desc->
d1, desc->
d2);
1689 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d " 1702 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d " 1703 "this descLen: %d\n",
1706 DPRINTF(EthernetDesc,
"TSO: Next packet is %d bytes\n", pkt_size);
1710 DPRINTF(EthernetDesc,
"Next TX packet is %d bytes\n",
1723 DPRINTF(EthernetDesc,
"getPacketData(): TxDescriptor data " 1724 "d1: %#llx d2: %#llx\n", desc->d1, desc->d2);
1732 DPRINTF(EthernetDesc,
"Starting DMA of packet at offset %d\n", p->length);
1738 "Loading TSO header (%d bytes) into start of packet\n",
1748 "Starting DMA of packet at offset %d length: %d\n",
1773 DPRINTF(EthernetDesc,
"DMA of packet complete\n");
1780 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1781 desc->
d1, desc->
d2);
1785 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d " 1791 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d\n",
1814 DPRINTF(EthernetDesc,
"Partial Packet Descriptor of %d bytes Done\n",
1836 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1837 desc->
d1, desc->
d2);
1843 DPRINTF(EthernetDesc,
"TSO: Modifying IP header. Id + %d\n",
1853 "TSO: Modifying TCP header. old seq %d + %d\n",
1861 DPRINTF(EthernetDesc,
"TSO: Modifying UDP header.\n");
1867 if (
DTRACE(EthernetDesc)) {
1870 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1873 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1878 DPRINTF(EthernetDesc,
"Calculating checksums for packet\n");
1886 DPRINTF(EthernetDesc,
"Calculated IP checksum\n");
1895 DPRINTF(EthernetDesc,
"Calculated TCP checksum\n");
1901 DPRINTF(EthernetDesc,
"Calculated UDP checksum\n");
1903 panic(
"Told to checksum, but don't know how\n");
1910 DPRINTF(EthernetDesc,
"Descriptor had IDE set\n");
1913 DPRINTF(EthernetDesc,
"setting tidv\n");
1919 DPRINTF(EthernetDesc,
"setting tadv\n");
1928 DPRINTF(EthernetDesc,
"Descriptor Done\n");
1941 "------Packet of %d bytes ready for transmission-------\n",
1950 DPRINTF(EthernetDesc,
"WTHRESH == 0, writing back descriptor\n");
1954 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1958 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1970 DPRINTF(EthernetDesc,
"actionAfterWb() completionEnabled: %d\n",
1976 "Completion writing back value: %d to addr: %#x\n",
descEnd,
2081 unsigned int count(0);
2095 DPRINTF(Drain,
"IGbE not drained\n");
2111 DPRINTF(EthernetSM,
"resuming from drain");
2125 DPRINTF(Drain,
"IGbE done draining, processing drain event\n");
2135 DPRINTF(EthernetSM,
"TXS: TX disabled, stopping ticking\n");
2144 anQ(
"TXS",
"TX FIFO Q");
2145 DPRINTF(EthernetSM,
"TXS: packet placed in TX FIFO\n");
2153 anBegin(
"TXS",
"Desc Writeback");
2161 DPRINTF(EthernetSM,
"TXS: LWTHRESH caused posting of TXDLOW\n");
2166 txPacket = std::make_shared<EthPacketData>(16384);
2172 anBegin(
"TXS",
"Desc Writeback");
2177 DPRINTF(EthernetSM,
"TXS: No descriptors left in ring, forcing " 2178 "writeback stopping ticking and posting TXQE\n");
2188 DPRINTF(EthernetSM,
"TXS: No descriptors available in cache, " 2189 "fetching and stopping ticking\n");
2199 "TXS: Fetching TSO header, stopping ticking\n");
2206 anRq(
"TXS",
"TX FIFO Q");
2208 DPRINTF(EthernetSM,
"TXS: Reserving %d bytes in FIFO and " 2209 "beginning DMA of next packet\n", size);
2212 }
else if (size == 0) {
2213 DPRINTF(EthernetSM,
"TXS: getPacketSize returned: %d\n", size);
2215 "TXS: No packets to get, writing back used descriptors\n");
2216 anBegin(
"TXS",
"Desc Writeback");
2219 anWf(
"TXS",
"TX FIFO Q");
2220 DPRINTF(EthernetSM,
"TXS: FIFO full, stopping ticking until space " 2221 "available in FIFO\n");
2228 DPRINTF(EthernetSM,
"TXS: Nothing to do, stopping ticking\n");
2238 DPRINTF(Ethernet,
"RxFIFO: Receiving pcakte from wire\n");
2243 DPRINTF(Ethernet,
"RxFIFO: RX not enabled, dropping\n");
2252 "RXS: received packet into fifo, starting ticking\n");
2257 DPRINTF(Ethernet,
"RxFIFO: Packet won't fit in fifo... dropped\n");
2272 anQ(
"RXQ",
"RX FIFO Q");
2285 DPRINTF(EthernetSM,
"RXS: RX disabled, stopping ticking\n");
2292 DPRINTF(EthernetSM,
"RXS: Packet completed DMA to memory\n");
2294 DPRINTF(EthernetSM,
"RXS: descLeft: %d rdmts: %d rdlen: %d\n",
2300 DPRINTF(Ethernet,
"RXS: Interrupting (RXDMT) " 2301 "because of descriptors left\n");
2308 if (descLeft == 0) {
2309 anBegin(
"RXS",
"Writeback Descriptors");
2311 DPRINTF(EthernetSM,
"RXS: No descriptors left in ring, forcing" 2312 " writeback and stopping ticking\n");
2321 "RXS: Writing back because WTHRESH >= descUsed\n");
2322 anBegin(
"RXS",
"Writeback Descriptors");
2332 DPRINTF(EthernetSM,
"RXS: Fetching descriptors because " 2333 "descUnused < PTHRESH\n");
2334 anBegin(
"RXS",
"Fetch Descriptors");
2339 anBegin(
"RXS",
"Fetch Descriptors");
2342 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, " 2343 "fetching descriptors and stopping ticking\n");
2351 "RXS: stopping ticking until packet DMA completes\n");
2357 anBegin(
"RXS",
"Fetch Descriptors");
2360 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, " 2361 "stopping ticking\n");
2363 DPRINTF(EthernetSM,
"RXS: No descriptors available, fetching\n");
2369 anWe(
"RXS",
"RX FIFO Q");
2370 DPRINTF(EthernetSM,
"RXS: RxFIFO empty, stopping ticking\n");
2374 anPq(
"RXS",
"RX FIFO Q");
2382 DPRINTF(EthernetSM,
"RXS: Writing packet into memory\n");
2384 anBegin(
"RXS",
"FIFO Dequeue");
2385 DPRINTF(EthernetSM,
"RXS: Removing packet from FIFO\n");
2387 anDq(
"RXS",
"RX FIFO Q");
2391 DPRINTF(EthernetSM,
"RXS: stopping ticking until packet DMA completes\n");
2403 anWe(
"TXQ",
"TX FIFO Q");
2408 anPq(
"TXQ",
"TX FIFO Q");
2410 anQ(
"TXQ",
"WireQ");
2411 if (
DTRACE(EthernetSM)) {
2414 DPRINTF(EthernetSM,
"Transmitting Ip packet with Id=%d\n",
2417 DPRINTF(EthernetSM,
"Transmitting Non-Ip packet\n");
2419 anDq(
"TXQ",
"TX FIFO Q");
2422 "TxFIFO: Successful transmit, bytes available in fifo: %d\n",
2435 DPRINTF(EthernetSM,
"IGbE: -------------- Cycle --------------\n");
2473 DPRINTF(EthernetSM,
"TxFIFO: Transmission complete\n");
2493 bool txPktExists =
txPacket !=
nullptr;
2496 txPacket->serialize(
"txpacket", cp);
2498 Tick rdtr_time = 0, radv_time = 0, tidv_time = 0, tadv_time = 0,
2547 txPacket = std::make_shared<EthPacketData>(16384);
2548 txPacket->unserialize(
"txpacket", cp);
2555 Tick rdtr_time, radv_time, tidv_time, tadv_time, inter_time;
2584 IGbEParams::create()
2586 return new IGbE(
this);
EventFunctionWrapper interEvent
#define panic(...)
This implements a cprintf based panic() function.
const uint8_t MULTICAST_TABLE_SIZE
void anQ(std::string sm, std::string q)
EventFunctionWrapper pktHdrEvent
Ports are used to interface objects to each other.
void hwDq(flags f, System *sys, uint64_t frame, std::string sm, std::string q, uint64_t qid, System *q_sys=NULL, int32_t count=1)
void processContextDesc()
const uint16_t RXDEE_TCPE
void pktComplete()
Called by event when dma to write packet is completed.
const uint32_t REG_CRCERRS
const uint8_t RCV_ADDRESS_TABLE_SIZE
unsigned descUnused() const
Cycles is a wrapper class for representing cycle counts, i.e.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
virtual void drainResume()
Resume execution after a successful drain.
void unserialize(const std::string &base, CheckpointIn &cp)
const uint8_t PHY_GSTATUS
unsigned descInBlock(unsigned num_desc)
Return the number of dsecriptors in a cache block for threshold operations.
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
void chkInterrupt()
Check and see if changes to the mask register have caused an interrupt to need to be sent or perhaps ...
const uint8_t PHY_EPSTATUS
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
const uint32_t REG_RXCSUM
void serialize(CheckpointOut &cp) const override
Serialize an object.
uint16_t cksum(const IpPtr &ptr)
void serialize(CheckpointOut &cp) const override
Serialize an object.
EventFunctionWrapper tickEvent
TxDescCache(IGbE *i, std::string n, int s)
int hsplit(const EthPacketPtr &ptr)
EventFunctionWrapper pktEvent
unsigned bytesCopied
Bytes of packet that have been copied, so we know when to set EOP.
Stats::Scalar rxIpChecksums
const uint32_t REG_SRRCTL
unsigned descLeft() const
Stats::Scalar rxUdpChecksums
const uint8_t EEPROM_READ_OPCODE_SPI
void unserialize(CheckpointIn &cp) override
Unserialize an object.
const uint32_t REG_CTRL_EXT
bool isType(TxDesc *d, uint8_t type)
void restartClock()
This function is used to restart the clock so it can handle things like draining and resume in one pl...
EventFunctionWrapper radvEvent
Stats::Scalar rxTcpChecksums
void hwWe(flags f, System *sys, uint64_t frame, std::string sm, std::string q, uint64_t qid, System *q_sys=NULL, int32_t count=1)
DescCache(IGbE *i, const std::string n, int s)
bool packetDone()
Check if the dma on the packet has completed and RX state machine can continue.
void writeback(Addr aMask)
const uint8_t RXDT_ADV_SPLIT_A
EventFunctionWrapper wbEvent
struct iGbReg::RxDesc::@84::@87 adv_read
DrainState
Object drain/handover states.
std::string annSmFetch
Annotate sm.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
void setLE(T v)
Set the value in the data pointer to v as little endian.
unsigned getPacketSize(EthPacketPtr p)
Tell the cache to DMA a packet from main memory into its buffer and return the size the of the packet...
void wbComplete()
Called by event when dma to writeback descriptors is completed.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
const uint32_t STATS_REGS_SIZE
DrainState drainState() const
Return the current drain state of an object.
void anRq(std::string sm, std::string q, int num=1)
void delayIntEvent()
Send an interrupt to the cpu.
const uint32_t REG_RXDCTL
void serialize(CheckpointOut &cp) const override
Serialize an object.
EventFunctionWrapper pktEvent
#define UNSERIALIZE_SCALAR(scalar)
void drainResume() override
Resume execution after a successful drain.
void anWf(std::string sm, std::string q)
Draining buffers pending serialization/handover.
Tick curTick()
The current simulated tick.
void postInterrupt(iGbReg::IntTypes t, bool now=false)
Write an interrupt into the interrupt pending register and check mask and interrupt limit timer befor...
void anWe(std::string sm, std::string q)
std::string csprintf(const char *format, const Args &...args)
const uint16_t RXDS_UDPCS
const uint32_t REG_LEDCTL
unsigned descUsed() const
const uint32_t REG_STATUS
struct iGbReg::RxDesc::@84::@88 adv_wb
void makeAtomicResponse()
uint64_t Tick
Tick count type.
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
const uint8_t RXDT_LEGACY
bool packetWaiting()
Ask if we are still waiting for the packet to be transfered.
const uint8_t EEPROM_SIZE
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
void checkDrain()
Check if all the draining things that need to occur have occured and handle the drain event if so...
std::string annUnusedDescQ
void anBegin(std::string sm, std::string st, int flags=CPA::FL_NONE)
void deschedule(Event &event)
const uint32_t REG_TDWBAL
const uint32_t REG_SWFWSYNC
Stats::Scalar txIpChecksums
std::shared_ptr< EthPacketData > EthPacketPtr
void pktComplete()
Called by event when dma to write packet is completed.
void schedule(Event &event, Tick when)
int getBAR(Addr addr)
Which base address register (if any) maps the given address?
EventFunctionWrapper fetchEvent
#define PCI_DEVICE_SPECIFIC
unsigned reserve(unsigned len=0)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > ¶m)
void reschedule(Event &event, Tick when, bool always=false)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool isContext(TxDesc *d)
const uint16_t EEPROM_CSUM
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define ULL(N)
uint64_t constant
EventFunctionWrapper pktDataEvent
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
void areaChanged()
If the address/len/head change when we've got descriptors that are dirty that is very bad...
#define SERIALIZE_ARRAY(member, size)
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
RxDescCache(IGbE *i, std::string n, int s)
struct iGbReg::RxDesc::@84::@86 legacy
const Params * params() const
void serialize(CheckpointOut &cp) const override
Serialize an object.
DrainState drain() override
Notify an object that it needs to drain its state.
bool ethRxPkt(EthPacketPtr packet)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
#define SERIALIZE_SCALAR(scalar)
const uint8_t PHY_PSTATUS
Addr pciToDma(Addr a)
Shortcut for DMA address translation.
IGbE(const Params *params)
const uint8_t EEPROM_RDSR_OPCODE_SPI
bool scheduled() const
Determine if the current event is scheduled.
EventFunctionWrapper headerEvent
bool sendPacket(EthPacketPtr packet)
bool hasOutstandingEvents() override
Stats::Scalar txUdpChecksums
void actionAfterWb() override
virtual const std::string name() const
#define UNSERIALIZE_ARRAY(member, size)
void completionWriteback(Addr a, bool enabled)
Declaration of the Packet class.
std::ostream CheckpointOut
static int numSystemsRunning
unsigned int cacheBlockSize() const
void anDq(std::string sm, std::string q)
int writePacket(EthPacketPtr packet, int pkt_offset)
Write the given packet into the buffer(s) pointed to by the descriptor and update the book keeping...
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void signalDrainDone() const
Signal that an object is drained.
void anPq(std::string sm, std::string q, int num=1)
std::string annUsedCacheQ
EventFunctionWrapper tadvEvent
const uint16_t RXDS_TCPCS
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
EventFunctionWrapper tidvEvent
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > ¶m)
const uint8_t EEPROM_SIZE
void fetchDescriptors()
Fetch a chunk of descriptors into the descriptor cache.
void fetchComplete()
Called by event when dma to read descriptors is completed.
const uint32_t REG_TXDCA_CTL
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
#define IN_RANGE(val, base, len)
const uint8_t VLAN_FILTER_TABLE_SIZE
bool packetMultiDesc()
Ask if this packet is composed of multiple descriptors so even if we've got data, we need to wait for...
EventFunctionWrapper rdtrEvent
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
void cpuClearInt()
Clear the interupt line to the cpu.
uint16_t flash[iGbReg::EEPROM_SIZE]
bool push(EthPacketPtr ptr)
EthPacketPtr pktPtr
The packet that is currently being dmad to memory if any.
void serialize(const std::string &base, CheckpointOut &cp) const
Serialization stuff.
Stats::Scalar postedInterrupts
bool packetAvailable()
Ask if the packet has been transfered so the state machine can give it to the fifo.
Tick when() const
Get the time that the event is scheduled.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
EventFunctionWrapper nullEvent
void getPacketData(EthPacketPtr p)
const uint8_t TXD_ADVDATA
const uint32_t REG_TXDCTL
int splitCount
Variable to head with header/data completion events.
std::string annUnusedCacheQ
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
bool hasOutstandingEvents() override
void serialize(CheckpointOut &cp) const override
Serialize an object.
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Stats::Scalar txTcpChecksums
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
const uint8_t RXDT_ADV_ONEBUF
const uint32_t REG_TDWBAH
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
static std::vector< System * > systemList
void unserialize(CheckpointIn &cp) override
Unserialize an object.