49 #include "debug/Drain.hh" 50 #include "debug/EthernetAll.hh" 53 #include "params/IGbE.hh" 62 rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), inTick(false),
63 rxTick(false), txTick(false), txFifoTick(false), rxDmaPacket(false),
64 pktOffset(0), fetchDelay(p->fetch_delay), wbDelay(p->wb_delay),
65 fetchCompDelay(p->fetch_comp_delay), wbCompDelay(p->wb_comp_delay),
66 rxWriteDelay(p->rx_write_delay), txReadDelay(p->tx_read_delay),
111 memcpy(
flash,
p->hardware_address.bytes(), ETH_ADDR_LEN);
112 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",
421 panic(
"What's going on with eeprom interface? opcode:" 422 " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)
eeOpcode,
436 DPRINTF(EthernetEEPROM,
"EEPROM: opcode: %#X:%d addr: %#X:%d\n",
437 (uint32_t)eeOpcode, (uint32_t) eeOpBits,
438 (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits);
441 panic(
"Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode,
456 DPRINTF(EthernetEEPROM,
"EEPROM: read addr: %#X data %#x\n",
463 panic(
"No support for interrupt on mdic complete\n");
465 panic(
"No support for reading anything but phy\n");
466 DPRINTF(Ethernet,
"%s phy address %x\n",
467 regs.
mdic.op() == 1 ?
"Writing" :
"Reading",
494 DPRINTF(Ethernet,
"Writing ICR. ICR=%#x IMR=%#x IAM=%#x IAME=%d\n",
505 DPRINTF(EthernetIntr,
"Posting interrupt because of ICS write\n");
524 DPRINTF(EthernetSM,
"RXS: Got RESET!\n");
542 if (
regs.
tctl.en() && !oldtctl.en()) {
563 warn(
"Writing to IVAR0, ignoring...\n");
592 DPRINTF(EthernetSM,
"RXS: RDT Updated.\n");
594 DPRINTF(EthernetSM,
"RXS: RDT Fetching Descriptors!\n");
597 DPRINTF(EthernetSM,
"RXS: RDT NOT Fetching Desc b/c draining!\n");
628 panic(
"No support for DCA\n");
632 DPRINTF(EthernetSM,
"TXS: TX Tail pointer updated\n");
634 DPRINTF(EthernetSM,
"TXS: TDT Fetching Descriptors!\n");
637 DPRINTF(EthernetSM,
"TXS: TDT NOT Fetching Desc b/c draining!\n");
670 panic(
"Extended RX descriptors not implemented\n");
687 panic(
"Write request to unknown register number: %#x\n", daddr);
707 "EINT: postInterrupt() curTick(): %d itr: %d interval: %d\n",
710 if (
regs.
itr.interval() == 0 || now ||
718 assert(int_time > 0);
719 DPRINTF(EthernetIntr,
"EINT: Scheduling timer interrupt for tick %d\n",
741 DPRINTF(Ethernet,
"Interrupt Masked. Not Posting\n");
745 DPRINTF(Ethernet,
"Posting Interrupt\n");
770 DPRINTF(EthernetIntr,
"EINT: Posting interrupt to CPU now. Vector %#x\n",
784 "EINT: Clearing interrupt to CPU now. Vector %#x\n",
793 DPRINTF(Ethernet,
"Checking interrupts icr: %#x imr: %#x\n",
regs.
icr(),
797 DPRINTF(Ethernet,
"Mask cleaned all interrupts\n");
803 DPRINTF(Ethernet,
"ITR = %#X itr.interval = %#X\n",
807 if (
regs.
itr.interval() == 0) {
811 "Possibly scheduling interrupt because of imr write\n");
814 DPRINTF(Ethernet,
"Scheduling for %d\n", t);
826 : igbe(i), _name(n), cachePnt(0), size(s), curFetching(0),
827 wbOut(0), moreToWb(false), wbAlignment(0), pktPtr(NULL),
828 wbDelayEvent([this]{ writeback1(); },
n),
829 fetchDelayEvent([
this]{ fetchDescriptors1(); },
n),
830 fetchEvent([
this]{ fetchComplete(); },
n),
831 wbEvent([
this]{ wbComplete(); },
n)
833 fetchBuf =
new T[size];
849 if (usedCache.size() > 0 || curFetching || wbOut)
850 panic(
"Descriptor Address, Length or Head changed. Bad\n");
859 int curHead = descHead();
860 int max_to_wb = usedCache.size();
865 if (aMask < wbAlignment) {
870 "Writing back already in process, returning\n");
878 DPRINTF(EthernetDesc,
"Writing back descriptors head: %d tail: " 879 "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
880 curHead, descTail(), descLen(), cachePnt, max_to_wb,
883 if (max_to_wb + curHead >= descLen()) {
884 max_to_wb = descLen() - curHead;
887 }
else if (wbAlignment != 0) {
889 max_to_wb = max_to_wb & ~wbAlignment;
892 DPRINTF(EthernetDesc,
"Writing back %d descriptors\n", max_to_wb);
894 if (max_to_wb <= 0) {
895 if (usedCache.size())
898 igbe->anWe(annSmWb, annUsedCacheQ);
904 assert(!wbDelayEvent.scheduled());
905 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
906 igbe->anBegin(annSmWb,
"Prepare Writeback Desc");
915 igbe->schedule(wbDelayEvent,
curTick() + igbe->wbDelay);
919 DPRINTF(EthernetDesc,
"Begining DMA of %d descriptors\n", wbOut);
921 for (
int x = 0;
x < wbOut;
x++) {
922 assert(usedCache.size());
923 memcpy(&wbBuf[
x], usedCache[x],
sizeof(T));
924 igbe->anPq(annSmWb, annUsedCacheQ);
925 igbe->anPq(annSmWb, annDescQ);
926 igbe->anQ(annSmWb, annUsedDescQ);
930 igbe->anBegin(annSmWb,
"Writeback Desc DMA");
933 igbe->dmaWrite(pciToDma(descBase() + descHead() *
sizeof(T)),
934 wbOut *
sizeof(T), &wbEvent, (uint8_t*)wbBuf,
946 "Currently fetching %d descriptors, returning\n",
951 if (descTail() >= cachePnt)
952 max_to_fetch = descTail() - cachePnt;
954 max_to_fetch = descLen() - cachePnt;
956 size_t free_cache = size - usedCache.size() - unusedCache.size();
959 igbe->anWe(annSmFetch, annUnusedDescQ);
961 igbe->anPq(annSmFetch, annUnusedDescQ, max_to_fetch);
965 igbe->anWf(annSmFetch, annDescQ);
967 igbe->anRq(annSmFetch, annDescQ, free_cache);
970 max_to_fetch = std::min(max_to_fetch, free_cache);
973 DPRINTF(EthernetDesc,
"Fetching descriptors head: %d tail: " 974 "%d len: %d cachePnt: %d max_to_fetch: %d descleft: %d\n",
975 descHead(), descTail(), descLen(), cachePnt,
976 max_to_fetch, descLeft());
979 if (max_to_fetch == 0)
983 curFetching = max_to_fetch;
985 assert(!fetchDelayEvent.scheduled());
986 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
987 igbe->anBegin(annSmFetch,
"Prepare Fetch Desc");
996 igbe->schedule(fetchDelayEvent,
curTick() + igbe->fetchDelay);
1000 igbe->anBegin(annSmFetch,
"Fetch Desc");
1002 DPRINTF(EthernetDesc,
"Fetching descriptors at %#x (%#x), size: %#x\n",
1003 descBase() + cachePnt *
sizeof(T),
1004 pciToDma(descBase() + cachePnt *
sizeof(T)),
1005 curFetching *
sizeof(T));
1006 assert(curFetching);
1007 igbe->dmaRead(pciToDma(descBase() + cachePnt *
sizeof(T)),
1008 curFetching *
sizeof(T), &fetchEvent, (uint8_t*)fetchBuf,
1009 igbe->fetchCompDelay);
1017 igbe->anBegin(annSmFetch,
"Fetch Complete");
1018 for (
int x = 0;
x < curFetching;
x++) {
1020 memcpy(newDesc, &fetchBuf[
x],
sizeof(T));
1021 unusedCache.push_back(newDesc);
1022 igbe->anDq(annSmFetch, annUnusedDescQ);
1023 igbe->anQ(annSmFetch, annUnusedCacheQ);
1024 igbe->anQ(annSmFetch, annDescQ);
1029 int oldCp = cachePnt;
1032 cachePnt += curFetching;
1033 assert(cachePnt <= descLen());
1034 if (cachePnt == descLen())
1039 DPRINTF(EthernetDesc,
"Fetching complete cachePnt %d -> %d\n",
1042 if ((descTail() >= cachePnt ? (descTail() - cachePnt) : (descLen() -
1045 igbe->anWe(annSmFetch, annUnusedDescQ);
1046 }
else if (!(size - usedCache.size() - unusedCache.size())) {
1047 igbe->anWf(annSmFetch, annDescQ);
1061 igbe->anBegin(annSmWb,
"Finish Writeback");
1063 long curHead = descHead();
1065 long oldHead = curHead;
1068 for (
int x = 0;
x < wbOut;
x++) {
1069 assert(usedCache.size());
1070 delete usedCache[0];
1071 usedCache.pop_front();
1073 igbe->anDq(annSmWb, annUsedCacheQ);
1074 igbe->anDq(annSmWb, annDescQ);
1080 if (curHead >= descLen())
1081 curHead -= descLen();
1084 updateHead(curHead);
1086 DPRINTF(EthernetDesc,
"Writeback complete curHead %d -> %d\n",
1093 DPRINTF(EthernetDesc,
"Writeback has more todo\n");
1099 if (usedCache.size())
1102 igbe->anWe(annSmWb, annUsedCacheQ);
1111 DPRINTF(EthernetDesc,
"Reseting descriptor cache\n");
1113 delete usedCache[
x];
1115 delete unusedCache[
x];
1118 unusedCache.clear();
1138 (uint8_t*)usedCache[
x],
sizeof(T));
1145 (uint8_t*)unusedCache[
x],
sizeof(T));
1148 Tick fetch_delay = 0, wb_delay = 0;
1149 if (fetchDelayEvent.scheduled())
1150 fetch_delay = fetchDelayEvent.when();
1152 if (wbDelayEvent.scheduled())
1153 wb_delay = wbDelayEvent.when();
1175 (uint8_t*)temp,
sizeof(T));
1176 usedCache.push_back(temp);
1184 (uint8_t*)temp,
sizeof(T));
1185 unusedCache.push_back(temp);
1187 Tick fetch_delay = 0, wb_delay = 0;
1191 igbe->schedule(fetchDelayEvent, fetch_delay);
1193 igbe->schedule(wbDelayEvent, wb_delay);
1208 annSmWb =
"RX Desc Writeback";
1221 "Part of split packet done: splitcount now %d\n",
splitCount);
1227 "Part of split packet done: calling pktComplete()\n");
1240 unsigned buf_len, hdr_len;
1245 assert(pkt_offset == 0);
1247 DPRINTF(EthernetDesc,
"Packet Length: %d Desc Size: %d\n",
1251 packet->length, &
pktEvent, packet->data,
1255 assert(pkt_offset == 0);
1259 DPRINTF(EthernetDesc,
"Packet Length: %d srrctl: %#x Desc Size: %d\n",
1261 assert(packet->length < buf_len);
1263 packet->length, &
pktEvent, packet->data,
1267 desc->
adv_wb.pkt_len =
htole((uint16_t)(pktPtr->length));
1276 "lpe: %d Packet Length: %d offset: %d srrctl: %#x " 1277 "hdr addr: %#x Hdr Size: %d desc addr: %#x Desc Size: %d\n",
1282 split_point =
hsplit(pktPtr);
1284 if (packet->length <= hdr_len) {
1286 assert(pkt_offset == 0);
1287 DPRINTF(EthernetDesc,
"Hdr split: Entire packet in header\n");
1289 packet->length, &
pktEvent, packet->data,
1291 desc->
adv_wb.header_len =
htole((uint16_t)packet->length);
1294 }
else if (split_point) {
1299 std::min(packet->length - pkt_offset, buf_len);
1302 "Hdr split: Continuing data buffer copy\n");
1307 desc->
adv_wb.pkt_len =
htole((uint16_t)max_to_copy);
1311 std::min(packet->length - split_point, buf_len);
1314 DPRINTF(EthernetDesc,
"Hdr split: splitting at %d\n",
1324 desc->
adv_wb.pkt_len =
htole((uint16_t)(max_to_copy));
1327 panic(
"Header split not fitting within header buffer or " 1328 "undecodable packet not fitting in header unsupported\n");
1332 panic(
"Unimplemnted RX receive buffer type: %d\n",
1349 DPRINTF(EthernetDesc,
"pktPtr->length: %d bytesCopied: %d " 1350 "stripcrc offset: %d value written: %d %d\n",
1353 (uint16_t)(
pktPtr->length + crcfixup));
1358 DPRINTF(EthernetDesc,
"Packet written to memory updating Descriptor\n");
1362 uint16_t ext_err = 0;
1367 assert(bytesCopied <= pktPtr->
length);
1376 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1385 DPRINTF(EthernetDesc,
"Checking IP checksum\n");
1389 if (
cksum(ip) != 0) {
1392 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1397 DPRINTF(EthernetDesc,
"Checking TCP checksum\n");
1402 if (
cksum(tcp) != 0) {
1403 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1411 DPRINTF(EthernetDesc,
"Checking UDP checksum\n");
1416 if (
cksum(udp) != 0) {
1417 DPRINTF(EthernetDesc,
"Checksum is bad!!\n");
1423 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1428 desc->legacy.len =
htole((uint16_t)(
pktPtr->length + crcfixup));
1429 desc->legacy.status =
htole(status);
1430 desc->legacy.errors =
htole(err);
1432 desc->legacy.vlan = 0;
1436 desc->adv_wb.rss_type =
htole(0);
1437 desc->adv_wb.pkt_type =
htole(ptype);
1440 desc->adv_wb.rss_hash =
htole(0);
1442 desc->adv_wb.id =
htole(ip_id);
1443 desc->adv_wb.csum =
htole(csum);
1445 desc->adv_wb.status =
htole(status);
1446 desc->adv_wb.errors =
htole(ext_err);
1448 desc->adv_wb.vlan_tag =
htole(0);
1451 panic(
"Unimplemnted RX receive buffer type %d\n",
1455 DPRINTF(EthernetDesc,
"Descriptor complete w0: %#x w1: %#x\n",
1456 desc->adv_read.pkt, desc->adv_read.hdr);
1460 "Packet completely written to descriptor buffers\n");
1464 DPRINTF(EthernetSM,
"RXS: Scheduling DTR for %d\n", delay);
1470 DPRINTF(EthernetSM,
"RXS: Scheduling ADV for %d\n", delay);
1479 "RXS: Receive interrupt delay disabled, posting IT_RXT\n");
1487 "RXS: Posting IT_SRPD beacuse small packet received\n");
1499 DPRINTF(EthernetDesc,
"Processing of this descriptor complete\n");
1557 pktWaiting(false), pktMultiDesc(false),
1558 completionAddress(0), completionEnabled(false),
1559 useTso(false), tsoHeaderLen(0), tsoMss(0), tsoTotalLen(0), tsoUsedLen(0),
1560 tsoPrevSeq(0), tsoPktPayloadBytes(0), tsoLoadedHeader(false),
1561 tsoPktHasHeader(false), tsoDescBytesUsed(0), tsoCopyBytes(0), tsoPkts(0),
1567 annSmWb =
"TX Desc Writeback";
1581 DPRINTF(EthernetDesc,
"Checking and processing context descriptors\n");
1585 DPRINTF(EthernetDesc,
"Got context descriptor type...\n");
1588 DPRINTF(EthernetDesc,
"Descriptor upper: %#x lower: %#X\n",
1589 desc->d1, desc->d2);
1601 DPRINTF(EthernetDesc,
"TCP offload enabled for packet hdrlen: " 1628 DPRINTF(EthernetDesc,
"TCP offload(adv) enabled for packet " 1629 "hdrlen: %d mss: %d paylen %d\n",
1643 DPRINTF(EthernetDesc,
"Starting DMA of TSO header\n");
1655 DPRINTF(EthernetDesc,
"TSO: Fetching TSO header complete\n");
1660 DPRINTF(EthernetDesc,
"TSO: len: %d tsoHeaderLen: %d\n",
1669 DPRINTF(EthernetDesc,
"TSO: header part of larger payload\n");
1683 DPRINTF(EthernetDesc,
"Starting processing of descriptor\n");
1689 DPRINTF(EthernetDesc,
"getPacket(): TxDescriptor data " 1690 "d1: %#llx d2: %#llx\n", desc->
d1, desc->
d2);
1691 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d " 1704 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d " 1705 "this descLen: %d\n",
1708 DPRINTF(EthernetDesc,
"TSO: Next packet is %d bytes\n", pkt_size);
1712 DPRINTF(EthernetDesc,
"Next TX packet is %d bytes\n",
1725 DPRINTF(EthernetDesc,
"getPacketData(): TxDescriptor data " 1726 "d1: %#llx d2: %#llx\n", desc->d1, desc->d2);
1734 DPRINTF(EthernetDesc,
"Starting DMA of packet at offset %d\n", p->length);
1740 "Loading TSO header (%d bytes) into start of packet\n",
1750 "Starting DMA of packet at offset %d length: %d\n",
1775 DPRINTF(EthernetDesc,
"DMA of packet complete\n");
1782 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1783 desc->
d1, desc->
d2);
1787 DPRINTF(EthernetDesc,
"TSO: use: %d hdrlen: %d mss: %d total: %d " 1793 DPRINTF(EthernetDesc,
"TSO: descBytesUsed: %d copyBytes: %d\n",
1816 DPRINTF(EthernetDesc,
"Partial Packet Descriptor of %d bytes Done\n",
1838 DPRINTF(EthernetDesc,
"TxDescriptor data d1: %#llx d2: %#llx\n",
1839 desc->
d1, desc->
d2);
1845 DPRINTF(EthernetDesc,
"TSO: Modifying IP header. Id + %d\n",
1855 "TSO: Modifying TCP header. old seq %d + %d\n",
1863 DPRINTF(EthernetDesc,
"TSO: Modifying UDP header.\n");
1869 if (
DTRACE(EthernetDesc)) {
1872 DPRINTF(EthernetDesc,
"Proccesing Ip packet with Id=%d\n",
1875 DPRINTF(EthernetSM,
"Proccesing Non-Ip packet\n");
1880 DPRINTF(EthernetDesc,
"Calculating checksums for packet\n");
1888 DPRINTF(EthernetDesc,
"Calculated IP checksum\n");
1897 DPRINTF(EthernetDesc,
"Calculated TCP checksum\n");
1903 DPRINTF(EthernetDesc,
"Calculated UDP checksum\n");
1905 panic(
"Told to checksum, but don't know how\n");
1912 DPRINTF(EthernetDesc,
"Descriptor had IDE set\n");
1915 DPRINTF(EthernetDesc,
"setting tidv\n");
1921 DPRINTF(EthernetDesc,
"setting tadv\n");
1930 DPRINTF(EthernetDesc,
"Descriptor Done\n");
1943 "------Packet of %d bytes ready for transmission-------\n",
1952 DPRINTF(EthernetDesc,
"WTHRESH == 0, writing back descriptor\n");
1956 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1960 DPRINTF(EthernetDesc,
"used > WTHRESH, writing back descriptor\n");
1972 DPRINTF(EthernetDesc,
"actionAfterWb() completionEnabled: %d\n",
1978 "Completion writing back value: %d to addr: %#x\n",
descEnd,
2083 unsigned int count(0);
2097 DPRINTF(Drain,
"IGbE not drained\n");
2113 DPRINTF(EthernetSM,
"resuming from drain");
2127 DPRINTF(Drain,
"IGbE done draining, processing drain event\n");
2137 DPRINTF(EthernetSM,
"TXS: TX disabled, stopping ticking\n");
2146 anQ(
"TXS",
"TX FIFO Q");
2147 DPRINTF(EthernetSM,
"TXS: packet placed in TX FIFO\n");
2155 anBegin(
"TXS",
"Desc Writeback");
2163 DPRINTF(EthernetSM,
"TXS: LWTHRESH caused posting of TXDLOW\n");
2168 txPacket = std::make_shared<EthPacketData>(16384);
2174 anBegin(
"TXS",
"Desc Writeback");
2179 DPRINTF(EthernetSM,
"TXS: No descriptors left in ring, forcing " 2180 "writeback stopping ticking and posting TXQE\n");
2190 DPRINTF(EthernetSM,
"TXS: No descriptors available in cache, " 2191 "fetching and stopping ticking\n");
2201 "TXS: Fetching TSO header, stopping ticking\n");
2208 anRq(
"TXS",
"TX FIFO Q");
2210 DPRINTF(EthernetSM,
"TXS: Reserving %d bytes in FIFO and " 2211 "beginning DMA of next packet\n", size);
2214 }
else if (size == 0) {
2215 DPRINTF(EthernetSM,
"TXS: getPacketSize returned: %d\n", size);
2217 "TXS: No packets to get, writing back used descriptors\n");
2218 anBegin(
"TXS",
"Desc Writeback");
2221 anWf(
"TXS",
"TX FIFO Q");
2222 DPRINTF(EthernetSM,
"TXS: FIFO full, stopping ticking until space " 2223 "available in FIFO\n");
2230 DPRINTF(EthernetSM,
"TXS: Nothing to do, stopping ticking\n");
2240 DPRINTF(Ethernet,
"RxFIFO: Receiving pcakte from wire\n");
2245 DPRINTF(Ethernet,
"RxFIFO: RX not enabled, dropping\n");
2254 "RXS: received packet into fifo, starting ticking\n");
2259 DPRINTF(Ethernet,
"RxFIFO: Packet won't fit in fifo... dropped\n");
2274 anQ(
"RXQ",
"RX FIFO Q");
2287 DPRINTF(EthernetSM,
"RXS: RX disabled, stopping ticking\n");
2294 DPRINTF(EthernetSM,
"RXS: Packet completed DMA to memory\n");
2296 DPRINTF(EthernetSM,
"RXS: descLeft: %d rdmts: %d rdlen: %d\n",
2302 DPRINTF(Ethernet,
"RXS: Interrupting (RXDMT) " 2303 "because of descriptors left\n");
2310 if (descLeft == 0) {
2311 anBegin(
"RXS",
"Writeback Descriptors");
2313 DPRINTF(EthernetSM,
"RXS: No descriptors left in ring, forcing" 2314 " writeback and stopping ticking\n");
2323 "RXS: Writing back because WTHRESH >= descUsed\n");
2324 anBegin(
"RXS",
"Writeback Descriptors");
2334 DPRINTF(EthernetSM,
"RXS: Fetching descriptors because " 2335 "descUnused < PTHRESH\n");
2336 anBegin(
"RXS",
"Fetch Descriptors");
2341 anBegin(
"RXS",
"Fetch Descriptors");
2344 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, " 2345 "fetching descriptors and stopping ticking\n");
2353 "RXS: stopping ticking until packet DMA completes\n");
2359 anBegin(
"RXS",
"Fetch Descriptors");
2362 DPRINTF(EthernetSM,
"RXS: No descriptors available in cache, " 2363 "stopping ticking\n");
2365 DPRINTF(EthernetSM,
"RXS: No descriptors available, fetching\n");
2371 anWe(
"RXS",
"RX FIFO Q");
2372 DPRINTF(EthernetSM,
"RXS: RxFIFO empty, stopping ticking\n");
2376 anPq(
"RXS",
"RX FIFO Q");
2384 DPRINTF(EthernetSM,
"RXS: Writing packet into memory\n");
2386 anBegin(
"RXS",
"FIFO Dequeue");
2387 DPRINTF(EthernetSM,
"RXS: Removing packet from FIFO\n");
2389 anDq(
"RXS",
"RX FIFO Q");
2393 DPRINTF(EthernetSM,
"RXS: stopping ticking until packet DMA completes\n");
2405 anWe(
"TXQ",
"TX FIFO Q");
2410 anPq(
"TXQ",
"TX FIFO Q");
2412 anQ(
"TXQ",
"WireQ");
2413 if (
DTRACE(EthernetSM)) {
2416 DPRINTF(EthernetSM,
"Transmitting Ip packet with Id=%d\n",
2419 DPRINTF(EthernetSM,
"Transmitting Non-Ip packet\n");
2421 anDq(
"TXQ",
"TX FIFO Q");
2424 "TxFIFO: Successful transmit, bytes available in fifo: %d\n",
2437 DPRINTF(EthernetSM,
"IGbE: -------------- Cycle --------------\n");
2475 DPRINTF(EthernetSM,
"TxFIFO: Transmission complete\n");
2495 bool txPktExists =
txPacket !=
nullptr;
2498 txPacket->serialize(
"txpacket", cp);
2500 Tick rdtr_time = 0, radv_time = 0, tidv_time = 0, tadv_time = 0,
2549 txPacket = std::make_shared<EthPacketData>(16384);
2550 txPacket->unserialize(
"txpacket", cp);
2557 Tick rdtr_time, radv_time, tidv_time, tadv_time, inter_time;
2586 IGbEParams::create()
2588 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.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
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.
DrainState
Object drain/handover states.
Tick when() const
Get the time that the event is scheduled.
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 unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
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
struct iGbReg::RxDesc::@85::@89 adv_wb
DrainState drainState() const
Return the current drain state of an object.
const uint8_t EEPROM_READ_OPCODE_SPI
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void signalDrainDone() const
Signal that an object is drained.
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
std::string annSmFetch
Annotate sm.
void deschedule(Event &event)
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
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)
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
bool scheduled() const
Determine if the current event is scheduled.
unsigned descUsed() const
const uint32_t REG_STATUS
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)
#define SERIALIZE_ARRAY(member, size)
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.
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)
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.
Draining buffers pending serialization/handover.
#define ULL(N)
uint64_t constant
virtual const std::string name() const
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...
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)
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
#define UNSERIALIZE_ARRAY(member, size)
EventFunctionWrapper headerEvent
bool sendPacket(EthPacketPtr packet)
bool hasOutstandingEvents() override
void reschedule(Event &event, Tick when, bool always=false)
Stats::Scalar txUdpChecksums
void actionAfterWb() override
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)
virtual void drainResume()
Resume execution after a successful drain.
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 anPq(std::string sm, std::string q, int num=1)
std::string annUsedCacheQ
void schedule(Event &event, Tick when)
EventFunctionWrapper tadvEvent
struct iGbReg::RxDesc::@85::@87 legacy
struct iGbReg::RxDesc::@85::@88 adv_read
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.
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
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.