i8254xGBe.cc (11263:8dcc6b40f164) i8254xGBe.cc (11320:42ecb523c64a)
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 47 unchanged lines hidden (view full) ---

56
57using namespace iGbReg;
58using namespace Net;
59
60IGbE::IGbE(const Params *p)
61 : EtherDevice(p), etherInt(NULL), cpa(NULL),
62 rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false),
63 txTick(false), txFifoTick(false), rxDmaPacket(false), pktOffset(0),
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 47 unchanged lines hidden (view full) ---

56
57using namespace iGbReg;
58using namespace Net;
59
60IGbE::IGbE(const Params *p)
61 : EtherDevice(p), etherInt(NULL), cpa(NULL),
62 rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false),
63 txTick(false), txFifoTick(false), rxDmaPacket(false), pktOffset(0),
64 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),
64 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),
67 rdtrEvent(this), radvEvent(this),
68 tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this),
69 rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size),
70 txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size),
71 lastInterrupt(0)
72{
73 etherInt = new IGbEInt(name() + ".int", this);
74

--- 787 unchanged lines hidden (view full) ---

862 }
863 DPRINTF(EthernetDesc,
864 "Writing back already in process, returning\n");
865 return;
866 }
867
868 moreToWb = false;
869 wbAlignment = aMask;
67 rdtrEvent(this), radvEvent(this),
68 tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this),
69 rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size),
70 txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size),
71 lastInterrupt(0)
72{
73 etherInt = new IGbEInt(name() + ".int", this);
74

--- 787 unchanged lines hidden (view full) ---

862 }
863 DPRINTF(EthernetDesc,
864 "Writing back already in process, returning\n");
865 return;
866 }
867
868 moreToWb = false;
869 wbAlignment = aMask;
870
871
870
871
872 DPRINTF(EthernetDesc, "Writing back descriptors head: %d tail: "
873 "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
874 curHead, descTail(), descLen(), cachePnt, max_to_wb,
875 descLeft());
876
877 if (max_to_wb + curHead >= descLen()) {
878 max_to_wb = descLen() - curHead;
879 moreToWb = true;

--- 10 unchanged lines hidden (view full) ---

890 igbe->anBegin(annSmWb, "Wait Alignment", CPA::FL_WAIT);
891 else
892 igbe->anWe(annSmWb, annUsedCacheQ);
893 return;
894 }
895
896 wbOut = max_to_wb;
897
872 DPRINTF(EthernetDesc, "Writing back descriptors head: %d tail: "
873 "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
874 curHead, descTail(), descLen(), cachePnt, max_to_wb,
875 descLeft());
876
877 if (max_to_wb + curHead >= descLen()) {
878 max_to_wb = descLen() - curHead;
879 moreToWb = true;

--- 10 unchanged lines hidden (view full) ---

890 igbe->anBegin(annSmWb, "Wait Alignment", CPA::FL_WAIT);
891 else
892 igbe->anWe(annSmWb, annUsedCacheQ);
893 return;
894 }
895
896 wbOut = max_to_wb;
897
898 assert(!wbDelayEvent.scheduled());
898 assert(!wbDelayEvent.scheduled());
899 igbe->schedule(wbDelayEvent, curTick() + igbe->wbDelay);
900 igbe->anBegin(annSmWb, "Prepare Writeback Desc");
901}
899 igbe->schedule(wbDelayEvent, curTick() + igbe->wbDelay);
900 igbe->anBegin(annSmWb, "Prepare Writeback Desc");
901}
902
902
903template<class T>
904void
905IGbE::DescCache<T>::writeback1()
906{
907 // If we're draining delay issuing this DMA
908 if (igbe->drainState() != DrainState::Running) {
909 igbe->schedule(wbDelayEvent, curTick() + igbe->wbDelay);
910 return;
911 }
912
913 DPRINTF(EthernetDesc, "Begining DMA of %d descriptors\n", wbOut);
903template<class T>
904void
905IGbE::DescCache<T>::writeback1()
906{
907 // If we're draining delay issuing this DMA
908 if (igbe->drainState() != DrainState::Running) {
909 igbe->schedule(wbDelayEvent, curTick() + igbe->wbDelay);
910 return;
911 }
912
913 DPRINTF(EthernetDesc, "Begining DMA of %d descriptors\n", wbOut);
914
914
915 for (int x = 0; x < wbOut; x++) {
916 assert(usedCache.size());
917 memcpy(&wbBuf[x], usedCache[x], sizeof(T));
918 igbe->anPq(annSmWb, annUsedCacheQ);
919 igbe->anPq(annSmWb, annDescQ);
920 igbe->anQ(annSmWb, annUsedDescQ);
921 }
922
915 for (int x = 0; x < wbOut; x++) {
916 assert(usedCache.size());
917 memcpy(&wbBuf[x], usedCache[x], sizeof(T));
918 igbe->anPq(annSmWb, annUsedCacheQ);
919 igbe->anPq(annSmWb, annDescQ);
920 igbe->anQ(annSmWb, annUsedDescQ);
921 }
922
923
923
924 igbe->anBegin(annSmWb, "Writeback Desc DMA");
925
926 assert(wbOut);
927 igbe->dmaWrite(pciToDma(descBase() + descHead() * sizeof(T)),
928 wbOut * sizeof(T), &wbEvent, (uint8_t*)wbBuf,
929 igbe->wbCompDelay);
930}
931

--- 25 unchanged lines hidden (view full) ---

957 if (max_to_fetch) {
958 if (!free_cache)
959 igbe->anWf(annSmFetch, annDescQ);
960 else
961 igbe->anRq(annSmFetch, annDescQ, free_cache);
962 }
963
964 max_to_fetch = std::min(max_to_fetch, free_cache);
924 igbe->anBegin(annSmWb, "Writeback Desc DMA");
925
926 assert(wbOut);
927 igbe->dmaWrite(pciToDma(descBase() + descHead() * sizeof(T)),
928 wbOut * sizeof(T), &wbEvent, (uint8_t*)wbBuf,
929 igbe->wbCompDelay);
930}
931

--- 25 unchanged lines hidden (view full) ---

957 if (max_to_fetch) {
958 if (!free_cache)
959 igbe->anWf(annSmFetch, annDescQ);
960 else
961 igbe->anRq(annSmFetch, annDescQ, free_cache);
962 }
963
964 max_to_fetch = std::min(max_to_fetch, free_cache);
965
966
965
966
967 DPRINTF(EthernetDesc, "Fetching descriptors head: %d tail: "
968 "%d len: %d cachePnt: %d max_to_fetch: %d descleft: %d\n",
969 descHead(), descTail(), descLen(), cachePnt,
970 max_to_fetch, descLeft());
971
972 // Nothing to do
973 if (max_to_fetch == 0)
974 return;
967 DPRINTF(EthernetDesc, "Fetching descriptors head: %d tail: "
968 "%d len: %d cachePnt: %d max_to_fetch: %d descleft: %d\n",
969 descHead(), descTail(), descLen(), cachePnt,
970 max_to_fetch, descLeft());
971
972 // Nothing to do
973 if (max_to_fetch == 0)
974 return;
975
975
976 // So we don't have two descriptor fetches going on at once
977 curFetching = max_to_fetch;
978
979 assert(!fetchDelayEvent.scheduled());
980 igbe->schedule(fetchDelayEvent, curTick() + igbe->fetchDelay);
981 igbe->anBegin(annSmFetch, "Prepare Fetch Desc");
982}
983

--- 69 unchanged lines hidden (view full) ---

1053{
1054
1055 igbe->anBegin(annSmWb, "Finish Writeback");
1056
1057 long curHead = descHead();
1058#ifndef NDEBUG
1059 long oldHead = curHead;
1060#endif
976 // So we don't have two descriptor fetches going on at once
977 curFetching = max_to_fetch;
978
979 assert(!fetchDelayEvent.scheduled());
980 igbe->schedule(fetchDelayEvent, curTick() + igbe->fetchDelay);
981 igbe->anBegin(annSmFetch, "Prepare Fetch Desc");
982}
983

--- 69 unchanged lines hidden (view full) ---

1053{
1054
1055 igbe->anBegin(annSmWb, "Finish Writeback");
1056
1057 long curHead = descHead();
1058#ifndef NDEBUG
1059 long oldHead = curHead;
1060#endif
1061
1061
1062 for (int x = 0; x < wbOut; x++) {
1063 assert(usedCache.size());
1064 delete usedCache[0];
1065 usedCache.pop_front();
1066
1067 igbe->anDq(annSmWb, annUsedCacheQ);
1068 igbe->anDq(annSmWb, annDescQ);
1069 }

--- 117 unchanged lines hidden (view full) ---

1187 igbe->schedule(wbDelayEvent, wb_delay);
1188
1189
1190}
1191
1192///////////////////////////// IGbE::RxDescCache //////////////////////////////
1193
1194IGbE::RxDescCache::RxDescCache(IGbE *i, const std::string n, int s)
1062 for (int x = 0; x < wbOut; x++) {
1063 assert(usedCache.size());
1064 delete usedCache[0];
1065 usedCache.pop_front();
1066
1067 igbe->anDq(annSmWb, annUsedCacheQ);
1068 igbe->anDq(annSmWb, annDescQ);
1069 }

--- 117 unchanged lines hidden (view full) ---

1187 igbe->schedule(wbDelayEvent, wb_delay);
1188
1189
1190}
1191
1192///////////////////////////// IGbE::RxDescCache //////////////////////////////
1193
1194IGbE::RxDescCache::RxDescCache(IGbE *i, const std::string n, int s)
1195 : DescCache<RxDesc>(i, n, s), pktDone(false), splitCount(0),
1195 : DescCache(i, n, s), pktDone(false), splitCount(0),
1196 pktEvent(this), pktHdrEvent(this), pktDataEvent(this)
1197
1198{
1199 annSmFetch = "RX Desc Fetch";
1200 annSmWb = "RX Desc Writeback";
1201 annUnusedDescQ = "RX Unused Descriptors";
1202 annUnusedCacheQ = "RX Unused Descriptor Cache";
1203 annUsedCacheQ = "RX Used Descriptor Cache";

--- 51 unchanged lines hidden (view full) ---

1255 packet->length, &pktEvent, packet->data,
1256 igbe->rxWriteDelay);
1257 desc->adv_wb.header_len = htole(0);
1258 desc->adv_wb.sph = htole(0);
1259 desc->adv_wb.pkt_len = htole((uint16_t)(pktPtr->length));
1260 break;
1261 case RXDT_ADV_SPLIT_A:
1262 int split_point;
1196 pktEvent(this), pktHdrEvent(this), pktDataEvent(this)
1197
1198{
1199 annSmFetch = "RX Desc Fetch";
1200 annSmWb = "RX Desc Writeback";
1201 annUnusedDescQ = "RX Unused Descriptors";
1202 annUnusedCacheQ = "RX Unused Descriptor Cache";
1203 annUsedCacheQ = "RX Used Descriptor Cache";

--- 51 unchanged lines hidden (view full) ---

1255 packet->length, &pktEvent, packet->data,
1256 igbe->rxWriteDelay);
1257 desc->adv_wb.header_len = htole(0);
1258 desc->adv_wb.sph = htole(0);
1259 desc->adv_wb.pkt_len = htole((uint16_t)(pktPtr->length));
1260 break;
1261 case RXDT_ADV_SPLIT_A:
1262 int split_point;
1263
1263
1264 buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
1265 igbe->regs.rctl.descSize();
1264 buf_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.bufLen() :
1265 igbe->regs.rctl.descSize();
1266 hdr_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.hdrLen() : 0;
1266 hdr_len = igbe->regs.rctl.lpe() ? igbe->regs.srrctl.hdrLen() : 0;
1267 DPRINTF(EthernetDesc,
1268 "lpe: %d Packet Length: %d offset: %d srrctl: %#x "
1269 "hdr addr: %#x Hdr Size: %d desc addr: %#x Desc Size: %d\n",
1270 igbe->regs.rctl.lpe(), packet->length, pkt_offset,
1271 igbe->regs.srrctl(), desc->adv_read.hdr, hdr_len,
1272 desc->adv_read.pkt, buf_len);
1273
1274 split_point = hsplit(pktPtr);

--- 22 unchanged lines hidden (view full) ---

1297 packet->data + pkt_offset, igbe->rxWriteDelay);
1298 desc->adv_wb.header_len = htole(0);
1299 desc->adv_wb.pkt_len = htole((uint16_t)max_to_copy);
1300 desc->adv_wb.sph = htole(0);
1301 } else {
1302 int max_to_copy =
1303 std::min(packet->length - split_point, buf_len);
1304 bytesCopied += max_to_copy + split_point;
1267 DPRINTF(EthernetDesc,
1268 "lpe: %d Packet Length: %d offset: %d srrctl: %#x "
1269 "hdr addr: %#x Hdr Size: %d desc addr: %#x Desc Size: %d\n",
1270 igbe->regs.rctl.lpe(), packet->length, pkt_offset,
1271 igbe->regs.srrctl(), desc->adv_read.hdr, hdr_len,
1272 desc->adv_read.pkt, buf_len);
1273
1274 split_point = hsplit(pktPtr);

--- 22 unchanged lines hidden (view full) ---

1297 packet->data + pkt_offset, igbe->rxWriteDelay);
1298 desc->adv_wb.header_len = htole(0);
1299 desc->adv_wb.pkt_len = htole((uint16_t)max_to_copy);
1300 desc->adv_wb.sph = htole(0);
1301 } else {
1302 int max_to_copy =
1303 std::min(packet->length - split_point, buf_len);
1304 bytesCopied += max_to_copy + split_point;
1305
1305
1306 DPRINTF(EthernetDesc, "Hdr split: splitting at %d\n",
1307 split_point);
1308 igbe->dmaWrite(pciToDma(desc->adv_read.hdr),
1309 split_point, &pktHdrEvent,
1310 packet->data, igbe->rxWriteDelay);
1311 igbe->dmaWrite(pciToDma(desc->adv_read.pkt),
1312 max_to_copy, &pktDataEvent,
1313 packet->data + split_point, igbe->rxWriteDelay);

--- 112 unchanged lines hidden (view full) ---

1426 desc->adv_wb.rss_hash = htole(0);
1427 } else {
1428 desc->adv_wb.id = htole(ip_id);
1429 desc->adv_wb.csum = htole(csum);
1430 }
1431 desc->adv_wb.status = htole(status);
1432 desc->adv_wb.errors = htole(ext_err);
1433 // no vlan support
1306 DPRINTF(EthernetDesc, "Hdr split: splitting at %d\n",
1307 split_point);
1308 igbe->dmaWrite(pciToDma(desc->adv_read.hdr),
1309 split_point, &pktHdrEvent,
1310 packet->data, igbe->rxWriteDelay);
1311 igbe->dmaWrite(pciToDma(desc->adv_read.pkt),
1312 max_to_copy, &pktDataEvent,
1313 packet->data + split_point, igbe->rxWriteDelay);

--- 112 unchanged lines hidden (view full) ---

1426 desc->adv_wb.rss_hash = htole(0);
1427 } else {
1428 desc->adv_wb.id = htole(ip_id);
1429 desc->adv_wb.csum = htole(csum);
1430 }
1431 desc->adv_wb.status = htole(status);
1432 desc->adv_wb.errors = htole(ext_err);
1433 // no vlan support
1434 desc->adv_wb.vlan_tag = htole(0);
1434 desc->adv_wb.vlan_tag = htole(0);
1435 break;
1436 default:
1437 panic("Unimplemnted RX receive buffer type %d\n",
1438 igbe->regs.srrctl.desctype());
1439 }
1440
1441 DPRINTF(EthernetDesc, "Descriptor complete w0: %#x w1: %#x\n",
1442 desc->adv_read.pkt, desc->adv_read.hdr);

--- 66 unchanged lines hidden (view full) ---

1509}
1510
1511bool
1512IGbE::RxDescCache::hasOutstandingEvents()
1513{
1514 return pktEvent.scheduled() || wbEvent.scheduled() ||
1515 fetchEvent.scheduled() || pktHdrEvent.scheduled() ||
1516 pktDataEvent.scheduled();
1435 break;
1436 default:
1437 panic("Unimplemnted RX receive buffer type %d\n",
1438 igbe->regs.srrctl.desctype());
1439 }
1440
1441 DPRINTF(EthernetDesc, "Descriptor complete w0: %#x w1: %#x\n",
1442 desc->adv_read.pkt, desc->adv_read.hdr);

--- 66 unchanged lines hidden (view full) ---

1509}
1510
1511bool
1512IGbE::RxDescCache::hasOutstandingEvents()
1513{
1514 return pktEvent.scheduled() || wbEvent.scheduled() ||
1515 fetchEvent.scheduled() || pktHdrEvent.scheduled() ||
1516 pktDataEvent.scheduled();
1517
1517
1518}
1519
1520void
1521IGbE::RxDescCache::serialize(CheckpointOut &cp) const
1522{
1523 DescCache<RxDesc>::serialize(cp);
1524 SERIALIZE_SCALAR(pktDone);
1525 SERIALIZE_SCALAR(splitCount);

--- 30 unchanged lines hidden (view full) ---

1556 annDescQ = "TX Descriptors";
1557}
1558
1559void
1560IGbE::TxDescCache::processContextDesc()
1561{
1562 assert(unusedCache.size());
1563 TxDesc *desc;
1518}
1519
1520void
1521IGbE::RxDescCache::serialize(CheckpointOut &cp) const
1522{
1523 DescCache<RxDesc>::serialize(cp);
1524 SERIALIZE_SCALAR(pktDone);
1525 SERIALIZE_SCALAR(splitCount);

--- 30 unchanged lines hidden (view full) ---

1556 annDescQ = "TX Descriptors";
1557}
1558
1559void
1560IGbE::TxDescCache::processContextDesc()
1561{
1562 assert(unusedCache.size());
1563 TxDesc *desc;
1564
1564
1565 DPRINTF(EthernetDesc, "Checking and processing context descriptors\n");
1566
1567 while (!useTso && unusedCache.size() &&
1568 TxdOp::isContext(unusedCache.front())) {
1569 DPRINTF(EthernetDesc, "Got context descriptor type...\n");
1570
1571 desc = unusedCache.front();
1565 DPRINTF(EthernetDesc, "Checking and processing context descriptors\n");
1566
1567 while (!useTso && unusedCache.size() &&
1568 TxdOp::isContext(unusedCache.front())) {
1569 DPRINTF(EthernetDesc, "Got context descriptor type...\n");
1570
1571 desc = unusedCache.front();
1572 DPRINTF(EthernetDesc, "Descriptor upper: %#x lower: %#X\n",
1572 DPRINTF(EthernetDesc, "Descriptor upper: %#x lower: %#X\n",
1573 desc->d1, desc->d2);
1574
1573 desc->d1, desc->d2);
1574
1575
1575
1576 // is this going to be a tcp or udp packet?
1577 isTcp = TxdOp::tcp(desc) ? true : false;
1578
1576 // is this going to be a tcp or udp packet?
1577 isTcp = TxdOp::tcp(desc) ? true : false;
1578
1579 // setup all the TSO variables, they'll be ignored if we don't use
1579 // setup all the TSO variables, they'll be ignored if we don't use
1580 // tso for this connection
1581 tsoHeaderLen = TxdOp::hdrlen(desc);
1582 tsoMss = TxdOp::mss(desc);
1583
1584 if (TxdOp::isType(desc, TxdOp::TXD_CNXT) && TxdOp::tse(desc)) {
1585 DPRINTF(EthernetDesc, "TCP offload enabled for packet hdrlen: "
1586 "%d mss: %d paylen %d\n", TxdOp::hdrlen(desc),
1587 TxdOp::mss(desc), TxdOp::getLen(desc));

--- 14 unchanged lines hidden (view full) ---

1602 usedCache.push_back(desc);
1603 igbe->anQ("TXS", annUsedCacheQ);
1604 }
1605
1606 if (!unusedCache.size())
1607 return;
1608
1609 desc = unusedCache.front();
1580 // tso for this connection
1581 tsoHeaderLen = TxdOp::hdrlen(desc);
1582 tsoMss = TxdOp::mss(desc);
1583
1584 if (TxdOp::isType(desc, TxdOp::TXD_CNXT) && TxdOp::tse(desc)) {
1585 DPRINTF(EthernetDesc, "TCP offload enabled for packet hdrlen: "
1586 "%d mss: %d paylen %d\n", TxdOp::hdrlen(desc),
1587 TxdOp::mss(desc), TxdOp::getLen(desc));

--- 14 unchanged lines hidden (view full) ---

1602 usedCache.push_back(desc);
1603 igbe->anQ("TXS", annUsedCacheQ);
1604 }
1605
1606 if (!unusedCache.size())
1607 return;
1608
1609 desc = unusedCache.front();
1610 if (!useTso && TxdOp::isType(desc, TxdOp::TXD_ADVDATA) &&
1610 if (!useTso && TxdOp::isType(desc, TxdOp::TXD_ADVDATA) &&
1611 TxdOp::tse(desc)) {
1612 DPRINTF(EthernetDesc, "TCP offload(adv) enabled for packet "
1611 TxdOp::tse(desc)) {
1612 DPRINTF(EthernetDesc, "TCP offload(adv) enabled for packet "
1613 "hdrlen: %d mss: %d paylen %d\n",
1613 "hdrlen: %d mss: %d paylen %d\n",
1614 tsoHeaderLen, tsoMss, TxdOp::getTsoLen(desc));
1615 useTso = true;
1616 tsoTotalLen = TxdOp::getTsoLen(desc);
1617 tsoLoadedHeader = false;
1618 tsoDescBytesUsed = 0;
1619 tsoUsedLen = 0;
1620 tsoPrevSeq = 0;
1621 tsoPktHasHeader = false;

--- 36 unchanged lines hidden (view full) ---

1658 igbe->checkDrain();
1659}
1660
1661unsigned
1662IGbE::TxDescCache::getPacketSize(EthPacketPtr p)
1663{
1664 if (!unusedCache.size())
1665 return 0;
1614 tsoHeaderLen, tsoMss, TxdOp::getTsoLen(desc));
1615 useTso = true;
1616 tsoTotalLen = TxdOp::getTsoLen(desc);
1617 tsoLoadedHeader = false;
1618 tsoDescBytesUsed = 0;
1619 tsoUsedLen = 0;
1620 tsoPrevSeq = 0;
1621 tsoPktHasHeader = false;

--- 36 unchanged lines hidden (view full) ---

1658 igbe->checkDrain();
1659}
1660
1661unsigned
1662IGbE::TxDescCache::getPacketSize(EthPacketPtr p)
1663{
1664 if (!unusedCache.size())
1665 return 0;
1666
1666
1667 DPRINTF(EthernetDesc, "Starting processing of descriptor\n");
1668
1669 assert(!useTso || tsoLoadedHeader);
1670 TxDesc *desc = unusedCache.front();
1671
1672 if (useTso) {
1673 DPRINTF(EthernetDesc, "getPacket(): TxDescriptor data "
1674 "d1: %#llx d2: %#llx\n", desc->d1, desc->d2);
1675 DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d "
1676 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1677 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1678
1667 DPRINTF(EthernetDesc, "Starting processing of descriptor\n");
1668
1669 assert(!useTso || tsoLoadedHeader);
1670 TxDesc *desc = unusedCache.front();
1671
1672 if (useTso) {
1673 DPRINTF(EthernetDesc, "getPacket(): TxDescriptor data "
1674 "d1: %#llx d2: %#llx\n", desc->d1, desc->d2);
1675 DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d "
1676 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1677 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1678
1679 if (tsoPktHasHeader)
1679 if (tsoPktHasHeader)
1680 tsoCopyBytes = std::min((tsoMss + tsoHeaderLen) - p->length,
1681 TxdOp::getLen(desc) - tsoDescBytesUsed);
1682 else
1683 tsoCopyBytes = std::min(tsoMss,
1680 tsoCopyBytes = std::min((tsoMss + tsoHeaderLen) - p->length,
1681 TxdOp::getLen(desc) - tsoDescBytesUsed);
1682 else
1683 tsoCopyBytes = std::min(tsoMss,
1684 TxdOp::getLen(desc) - tsoDescBytesUsed);
1684 TxdOp::getLen(desc) - tsoDescBytesUsed);
1685 unsigned pkt_size =
1685 unsigned pkt_size =
1686 tsoCopyBytes + (tsoPktHasHeader ? 0 : tsoHeaderLen);
1686 tsoCopyBytes + (tsoPktHasHeader ? 0 : tsoHeaderLen);
1687
1688 DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d "
1689 "this descLen: %d\n",
1690 tsoDescBytesUsed, tsoCopyBytes, TxdOp::getLen(desc));
1691 DPRINTF(EthernetDesc, "TSO: pktHasHeader: %d\n", tsoPktHasHeader);
1692 DPRINTF(EthernetDesc, "TSO: Next packet is %d bytes\n", pkt_size);
1693 return pkt_size;
1694 }

--- 16 unchanged lines hidden (view full) ---

1711 assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) &&
1712 TxdOp::getLen(desc));
1713
1714 pktPtr = p;
1715
1716 pktWaiting = true;
1717
1718 DPRINTF(EthernetDesc, "Starting DMA of packet at offset %d\n", p->length);
1687
1688 DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d "
1689 "this descLen: %d\n",
1690 tsoDescBytesUsed, tsoCopyBytes, TxdOp::getLen(desc));
1691 DPRINTF(EthernetDesc, "TSO: pktHasHeader: %d\n", tsoPktHasHeader);
1692 DPRINTF(EthernetDesc, "TSO: Next packet is %d bytes\n", pkt_size);
1693 return pkt_size;
1694 }

--- 16 unchanged lines hidden (view full) ---

1711 assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) &&
1712 TxdOp::getLen(desc));
1713
1714 pktPtr = p;
1715
1716 pktWaiting = true;
1717
1718 DPRINTF(EthernetDesc, "Starting DMA of packet at offset %d\n", p->length);
1719
1719
1720 if (useTso) {
1721 assert(tsoLoadedHeader);
1722 if (!tsoPktHasHeader) {
1723 DPRINTF(EthernetDesc,
1724 "Loading TSO header (%d bytes) into start of packet\n",
1725 tsoHeaderLen);
1726 memcpy(p->data, &tsoHeader,tsoHeaderLen);
1727 p->length +=tsoHeaderLen;
1728 tsoPktHasHeader = true;
1729 }
1730 }
1720 if (useTso) {
1721 assert(tsoLoadedHeader);
1722 if (!tsoPktHasHeader) {
1723 DPRINTF(EthernetDesc,
1724 "Loading TSO header (%d bytes) into start of packet\n",
1725 tsoHeaderLen);
1726 memcpy(p->data, &tsoHeader,tsoHeaderLen);
1727 p->length +=tsoHeaderLen;
1728 tsoPktHasHeader = true;
1729 }
1730 }
1731
1731
1732 if (useTso) {
1733 DPRINTF(EthernetDesc,
1734 "Starting DMA of packet at offset %d length: %d\n",
1735 p->length, tsoCopyBytes);
1736 igbe->dmaRead(pciToDma(TxdOp::getBuf(desc))
1737 + tsoDescBytesUsed,
1738 tsoCopyBytes, &pktEvent, p->data + p->length,
1739 igbe->txReadDelay);

--- 32 unchanged lines hidden (view full) ---

1772 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1773 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1774 pktPtr->length += tsoCopyBytes;
1775 tsoUsedLen += tsoCopyBytes;
1776 DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d\n",
1777 tsoDescBytesUsed, tsoCopyBytes);
1778 } else
1779 pktPtr->length += TxdOp::getLen(desc);
1732 if (useTso) {
1733 DPRINTF(EthernetDesc,
1734 "Starting DMA of packet at offset %d length: %d\n",
1735 p->length, tsoCopyBytes);
1736 igbe->dmaRead(pciToDma(TxdOp::getBuf(desc))
1737 + tsoDescBytesUsed,
1738 tsoCopyBytes, &pktEvent, p->data + p->length,
1739 igbe->txReadDelay);

--- 32 unchanged lines hidden (view full) ---

1772 "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
1773 tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
1774 pktPtr->length += tsoCopyBytes;
1775 tsoUsedLen += tsoCopyBytes;
1776 DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d\n",
1777 tsoDescBytesUsed, tsoCopyBytes);
1778 } else
1779 pktPtr->length += TxdOp::getLen(desc);
1780
1781
1782
1780
1781
1783 if ((!TxdOp::eop(desc) && !useTso) ||
1782
1783 if ((!TxdOp::eop(desc) && !useTso) ||
1784 (pktPtr->length < ( tsoMss + tsoHeaderLen) &&
1785 tsoTotalLen != tsoUsedLen && useTso)) {
1786 assert(!useTso || (tsoDescBytesUsed == TxdOp::getLen(desc)));
1787 igbe->anDq("TXS", annUnusedCacheQ);
1788 unusedCache.pop_front();
1789 igbe->anQ("TXS", annUsedCacheQ);
1790 usedCache.push_back(desc);
1791

--- 28 unchanged lines hidden (view full) ---

1820 desc->d1, desc->d2);
1821
1822 if (useTso) {
1823 IpPtr ip(pktPtr);
1824 if (ip) {
1825 DPRINTF(EthernetDesc, "TSO: Modifying IP header. Id + %d\n",
1826 tsoPkts);
1827 ip->id(ip->id() + tsoPkts++);
1784 (pktPtr->length < ( tsoMss + tsoHeaderLen) &&
1785 tsoTotalLen != tsoUsedLen && useTso)) {
1786 assert(!useTso || (tsoDescBytesUsed == TxdOp::getLen(desc)));
1787 igbe->anDq("TXS", annUnusedCacheQ);
1788 unusedCache.pop_front();
1789 igbe->anQ("TXS", annUsedCacheQ);
1790 usedCache.push_back(desc);
1791

--- 28 unchanged lines hidden (view full) ---

1820 desc->d1, desc->d2);
1821
1822 if (useTso) {
1823 IpPtr ip(pktPtr);
1824 if (ip) {
1825 DPRINTF(EthernetDesc, "TSO: Modifying IP header. Id + %d\n",
1826 tsoPkts);
1827 ip->id(ip->id() + tsoPkts++);
1828 ip->len(pktPtr->length - EthPtr(pktPtr)->size());
1829
1828 ip->len(pktPtr->length - EthPtr(pktPtr)->size());
1829
1830 TcpPtr tcp(ip);
1831 if (tcp) {
1832 DPRINTF(EthernetDesc,
1833 "TSO: Modifying TCP header. old seq %d + %d\n",
1834 tcp->seq(), tsoPrevSeq);
1835 tcp->seq(tcp->seq() + tsoPrevSeq);
1836 if (tsoUsedLen != tsoTotalLen)
1837 tcp->flags(tcp->flags() & ~9); // clear fin & psh

--- 102 unchanged lines hidden (view full) ---

1940 writeback((igbe->cacheBlockSize()-1)>>4);
1941 }
1942
1943 enableSm();
1944 igbe->checkDrain();
1945}
1946
1947void
1830 TcpPtr tcp(ip);
1831 if (tcp) {
1832 DPRINTF(EthernetDesc,
1833 "TSO: Modifying TCP header. old seq %d + %d\n",
1834 tcp->seq(), tsoPrevSeq);
1835 tcp->seq(tcp->seq() + tsoPrevSeq);
1836 if (tsoUsedLen != tsoTotalLen)
1837 tcp->flags(tcp->flags() & ~9); // clear fin & psh

--- 102 unchanged lines hidden (view full) ---

1940 writeback((igbe->cacheBlockSize()-1)>>4);
1941 }
1942
1943 enableSm();
1944 igbe->checkDrain();
1945}
1946
1947void
1948IGbE::TxDescCache::actionAfterWb()
1948IGbE::TxDescCache::actionAfterWb()
1949{
1950 DPRINTF(EthernetDesc, "actionAfterWb() completionEnabled: %d\n",
1951 completionEnabled);
1952 igbe->postInterrupt(iGbReg::IT_TXDW);
1949{
1950 DPRINTF(EthernetDesc, "actionAfterWb() completionEnabled: %d\n",
1951 completionEnabled);
1952 igbe->postInterrupt(iGbReg::IT_TXDW);
1953 if (completionEnabled) {
1953 if (completionEnabled) {
1954 descEnd = igbe->regs.tdh();
1955 DPRINTF(EthernetDesc,
1956 "Completion writing back value: %d to addr: %#x\n", descEnd,
1957 completionAddress);
1958 igbe->dmaWrite(pciToDma(mbits(completionAddress, 63, 2)),
1959 sizeof(descEnd), &nullEvent, (uint8_t*)&descEnd, 0);
1960 }
1961}

--- 601 unchanged lines hidden ---
1954 descEnd = igbe->regs.tdh();
1955 DPRINTF(EthernetDesc,
1956 "Completion writing back value: %d to addr: %#x\n", descEnd,
1957 completionAddress);
1958 igbe->dmaWrite(pciToDma(mbits(completionAddress, 63, 2)),
1959 sizeof(descEnd), &nullEvent, (uint8_t*)&descEnd, 0);
1960 }
1961}

--- 601 unchanged lines hidden ---