diff -r 346acd1ed26c -r 652a69d5c5ee src/dev/i8254xGBe.cc --- a/src/dev/i8254xGBe.cc Mon Feb 13 17:42:50 2012 -0600 +++ b/src/dev/i8254xGBe.cc Mon Feb 13 17:43:17 2012 -0600 @@ -90,6 +90,7 @@ regs.tdwba = 0; regs.rlpml = 0; regs.sw_fw_sync = 0; + regs.gcr.timeout(0xf); regs.pba.rxa(0x30); regs.pba.txa(0x10); @@ -245,6 +246,10 @@ case REG_FCRTH: pkt->set(regs.fcrth()); break; + case REG_RXPBS: + // Constant for max receive size (64K) + pkt->set(0x40); + break; case REG_RDBAL: pkt->set(regs.rdba.rdbal()); break; @@ -324,6 +329,9 @@ case REG_MANC: pkt->set(regs.manc()); break; + case REG_GCR: + pkt->set(regs.gcr()); + break; case REG_SWSM: pkt->set(regs.swsm()); regs.swsm.smbi(1); @@ -334,14 +342,40 @@ case REG_SWFWSYNC: pkt->set(regs.sw_fw_sync); break; + case REG_SYSTIML: + case REG_SYSTIMH: + case REG_TIMINCA: + warn_once("IGbE hardware timer not supported\n"); + break; + case REG_VMOLR: + case REG_DTXCTL: + case REG_DTXSWC: + case REG_RPLOLR: + case REG_VT_CTL: + case REG_MRQC: + case REG_IVAR0: + case REG_RQDPC: + case REG_EITR: + pkt->set(0); + break; default: - if (!IN_RANGE(daddr, REG_VFTA, VLAN_FILTER_TABLE_SIZE*4) && - !IN_RANGE(daddr, REG_RAL, RCV_ADDRESS_TABLE_SIZE*8) && - !IN_RANGE(daddr, REG_MTA, MULTICAST_TABLE_SIZE*4) && - !IN_RANGE(daddr, REG_CRCERRS, STATS_REGS_SIZE)) + Addr a; + if (IN_RANGE(daddr, REG_RAL, RCV_ADDRESS_TABLE_SIZE * 4)) { + a = daddr - REG_RAL; + pkt->set(regs.rcvAddrTable[a >> 2]); + } else if (IN_RANGE(daddr, REG_RA2, RA2_TABLE_SIZE * 4)) { + a = daddr - REG_RA2; + pkt->set(regs.ra2[a >> 2]); + } else if (IN_RANGE(daddr, REG_MTA, MULTICAST_TABLE_SIZE * 4)) { + a = daddr - REG_MTA; + pkt->set(regs.mta[a >> 2]); + } else if (!IN_RANGE(daddr, REG_VFTA, VLAN_FILTER_TABLE_SIZE * 4) && + !IN_RANGE(daddr, REG_CRCERRS, STATS_REGS_SIZE) && + !IN_RANGE(daddr, REG_RSSRK, RSSRK_TABLE_SIZE * 4)) { panic("Read request to unknown register number: %#x\n", daddr); - else + } else { pkt->set(0); + } }; pkt->makeAtomicResponse(); @@ -664,6 +698,9 @@ case REG_MANC: regs.manc = val; break; + case REG_GCR: + regs.gcr = val; + break; case REG_SWSM: regs.swsm = val; if (regs.fwsm.eep_fw_semaphore()) @@ -672,11 +709,35 @@ case REG_SWFWSYNC: regs.sw_fw_sync = val; break; + case REG_SYSTIML: + case REG_SYSTIMH: + case REG_TIMINCA: + warn_once("IGbE hardware timer not supported\n"); + break; + case REG_VMOLR: + case REG_RPLOLR: + case REG_DTXCTL: + case REG_VT_CTL: + case REG_DTXSWC: + case REG_MRQC: + case REG_EITR: + break; default: - if (!IN_RANGE(daddr, REG_VFTA, VLAN_FILTER_TABLE_SIZE*4) && - !IN_RANGE(daddr, REG_RAL, RCV_ADDRESS_TABLE_SIZE*8) && - !IN_RANGE(daddr, REG_MTA, MULTICAST_TABLE_SIZE*4)) + Addr a; + if (IN_RANGE(daddr, REG_RAL, RCV_ADDRESS_TABLE_SIZE * 4)) { + a = daddr - REG_RAL; + regs.rcvAddrTable[a >> 2] = val; + } else if (IN_RANGE(daddr, REG_RA2, RA2_TABLE_SIZE * 4)) { + a = daddr - REG_RA2; + regs.ra2[a >> 2] = val; + } else if (IN_RANGE(daddr, REG_MTA, MULTICAST_TABLE_SIZE * 4)) { + a = daddr - REG_MTA; + regs.mta[a >> 2] = val; + } else if (!IN_RANGE(daddr, REG_VFTA, VLAN_FILTER_TABLE_SIZE * 4) && + !IN_RANGE(daddr, REG_RSSRK, RSSRK_TABLE_SIZE * 4) && + !IN_RANGE(daddr, REG_RETA, RETA_TABLE_SIZE * 4)) { panic("Write request to unknown register number: %#x\n", daddr); + } }; pkt->makeAtomicResponse(); diff -r 346acd1ed26c -r 652a69d5c5ee src/dev/i8254xGBe_defs.hh --- a/src/dev/i8254xGBe_defs.hh Mon Feb 13 17:42:50 2012 -0600 +++ b/src/dev/i8254xGBe_defs.hh Mon Feb 13 17:43:17 2012 -0600 @@ -60,9 +60,11 @@ const uint32_t REG_AIFS = 0x00458; const uint32_t REG_LEDCTL = 0x00e00; const uint32_t REG_EICR = 0x01580; +const uint32_t REG_EITR = 0x01680; const uint32_t REG_IVAR0 = 0x01700; const uint32_t REG_FCRTL = 0x02160; const uint32_t REG_FCRTH = 0x02168; +const uint32_t REG_RXPBS = 0x02404; const uint32_t REG_RDBAL = 0x02800; const uint32_t REG_RDBAH = 0x02804; const uint32_t REG_RDLEN = 0x02808; @@ -73,6 +75,8 @@ const uint32_t REG_RXDCTL = 0x02828; const uint32_t REG_RADV = 0x0282C; const uint32_t REG_TCTL = 0x00400; +const uint32_t REG_DTXSWC = 0x03500; +const uint32_t REG_DTXCTL = 0x03590; const uint32_t REG_TDBAL = 0x03800; const uint32_t REG_TDBAH = 0x03804; const uint32_t REG_TDLEN = 0x03808; @@ -91,24 +95,40 @@ const uint32_t REG_MTA = 0x05200; const uint32_t REG_RAL = 0x05400; const uint32_t REG_RAH = 0x05404; +const uint32_t REG_RA2 = 0x054E0; const uint32_t REG_VFTA = 0x05600; const uint32_t REG_WUC = 0x05800; +const uint32_t REG_MRQC = 0x05818; +const uint32_t REG_VT_CTL = 0x0581C; const uint32_t REG_MANC = 0x05820; +const uint32_t REG_VMOLR = 0x05AD0; +const uint32_t REG_RPLOLR = 0x05AF0; +const uint32_t REG_GCR = 0x05B00; const uint32_t REG_SWSM = 0x05B50; const uint32_t REG_FWSM = 0x05B54; const uint32_t REG_SWFWSYNC = 0x05B5C; +const uint32_t REG_RETA = 0x05C00; +const uint32_t REG_RSSRK = 0x05C80; + +const uint32_t REG_SYSTIML = 0x0B600; +const uint32_t REG_SYSTIMH = 0x0B604; +const uint32_t REG_TIMINCA = 0x0B608; + +const uint32_t REG_RQDPC = 0x0C030; const uint8_t EEPROM_READ_OPCODE_SPI = 0x03; const uint8_t EEPROM_RDSR_OPCODE_SPI = 0x05; const uint8_t EEPROM_SIZE = 64; const uint16_t EEPROM_CSUM = 0xBABA; -const uint8_t VLAN_FILTER_TABLE_SIZE = 128; -const uint8_t RCV_ADDRESS_TABLE_SIZE = 24; -const uint8_t MULTICAST_TABLE_SIZE = 128; -const uint32_t STATS_REGS_SIZE = 0x228; - +const uint32_t VLAN_FILTER_TABLE_SIZE = 128; +const uint32_t RCV_ADDRESS_TABLE_SIZE = 48; +const uint32_t MULTICAST_TABLE_SIZE = 128; +const uint32_t RA2_TABLE_SIZE = 64; +const uint32_t STATS_REGS_SIZE = 0x228; +const uint32_t RSSRK_TABLE_SIZE = 10; +const uint32_t RETA_TABLE_SIZE = 32; // Registers in that are accessed in the PHY const uint8_t PHY_PSTATUS = 0x1; @@ -733,6 +753,12 @@ }; MANC manc; + struct GCR : public Reg { // 0x5B00 GCR register + using Reg::operator=; + ADD_FIELD32(timeout, 23, 4); + }; + GCR gcr; + struct SWSM : public Reg { // 0x5B50 SWSM register using Reg::operator=; ADD_FIELD32(smbi,0,1); // Semaphone bit @@ -759,6 +785,10 @@ uint32_t sw_fw_sync; + uint32_t rcvAddrTable[RCV_ADDRESS_TABLE_SIZE]; + uint32_t ra2[RA2_TABLE_SIZE]; + uint32_t mta[MULTICAST_TABLE_SIZE]; + void serialize(std::ostream &os) { paramOut(os, "ctrl", ctrl._data); @@ -800,9 +830,13 @@ SERIALIZE_SCALAR(rlpml); paramOut(os, "rfctl", rfctl._data); paramOut(os, "manc", manc._data); + paramOut(os, "gcr", gcr._data); paramOut(os, "swsm", swsm._data); paramOut(os, "fwsm", fwsm._data); SERIALIZE_SCALAR(sw_fw_sync); + SERIALIZE_ARRAY(rcvAddrTable, RCV_ADDRESS_TABLE_SIZE); + SERIALIZE_ARRAY(ra2, RA2_TABLE_SIZE); + SERIALIZE_ARRAY(mta, MULTICAST_TABLE_SIZE); } void unserialize(Checkpoint *cp, const std::string §ion) @@ -846,9 +880,13 @@ UNSERIALIZE_SCALAR(rlpml); paramIn(cp, section, "rfctl", rfctl._data); paramIn(cp, section, "manc", manc._data); + paramIn(cp, section, "gcr", gcr._data); paramIn(cp, section, "swsm", swsm._data); paramIn(cp, section, "fwsm", fwsm._data); UNSERIALIZE_SCALAR(sw_fw_sync); + UNSERIALIZE_ARRAY(rcvAddrTable, RCV_ADDRESS_TABLE_SIZE); + UNSERIALIZE_ARRAY(ra2, RA2_TABLE_SIZE); + UNSERIALIZE_ARRAY(mta, MULTICAST_TABLE_SIZE); } }; } // namespace iGbReg