using namespace iGbReg;
IGbE::IGbE(Params *p)
- : PciDev(p), etherInt(NULL)
+ : PciDev(p), etherInt(NULL), useFlowControl(p->use_flow_control)
{
// Initialized internal registers per Intel documentation
- regs.tctl.reg = 0;
- regs.rctl.reg = 0;
- regs.ctrl.reg = 0;
- regs.ctrl.fd = 1;
- regs.ctrl.lrst = 1;
- regs.ctrl.speed = 2;
- regs.ctrl.frcspd = 1;
- regs.sts.reg = 0;
- regs.eecd.reg = 0;
- regs.eecd.fwe = 1;
- regs.eecd.ee_type = 1;
- regs.eerd.reg = 0;
- regs.icd.reg = 0;
- regs.imc.reg = 0;
- regs.rctl.reg = 0;
- regs.tctl.reg = 0;
- regs.manc.reg = 0;
-
- regs.pba.rxa = 0x30;
- regs.pba.txa = 0x10;
+ regs.tctl(0);
+ regs.rctl(0);
+ regs.ctrl(0);
+ regs.ctrl.fd(1);
+ regs.ctrl.lrst(1);
+ regs.ctrl.speed(2);
+ regs.ctrl.frcspd(1);
+ regs.sts(0);
+ regs.sts.speed(3); // Say we're 1000Mbps
+ regs.sts.fd(1); // full duplex
+ regs.eecd(0);
+ regs.eecd.fwe(1);
+ regs.eecd.ee_type(1);
+ regs.eerd(0);
+ regs.icr(0);
+ regs.rctl(0);
+ regs.tctl(0);
+ regs.fcrtl(0);
+ regs.fcrth(1);
+ regs.manc(0);
+
+ regs.pba.rxa(0x30);
+ regs.pba.txa(0x10);
eeOpBits = 0;
eeAddrBits = 0;
// clear all 64 16 bit words of the eeprom
memset(&flash, 0, EEPROM_SIZE*2);
+ //We'll need to instert the MAC address into the flash
+ flash[0] = 0xA4A4;
+ flash[1] = 0xB6B6;
+ flash[2] = 0xC8C8;
+
+ uint16_t csum = 0;
+ for (int x = 0; x < EEPROM_SIZE; x++)
+ csum += flash[x];
+
// Magic happy checksum value
- flash[0] = 0xBABA;
+ flash[EEPROM_SIZE-1] = htobe((uint16_t)(EEPROM_CSUM - csum));
}
switch (daddr) {
- case CTRL:
- pkt->set<uint32_t>(regs.ctrl.reg);
- break;
- case STATUS:
- pkt->set<uint32_t>(regs.sts.reg);
- break;
- case EECD:
- pkt->set<uint32_t>(regs.eecd.reg);
- break;
- case EERD:
- pkt->set<uint32_t>(regs.eerd.reg);
- break;
- case ICR:
- pkt->set<uint32_t>(regs.icd.reg);
- break;
- case IMC:
- pkt->set<uint32_t>(regs.imc.reg);
- break;
- case RCTL:
- pkt->set<uint32_t>(regs.rctl.reg);
- break;
- case TCTL:
- pkt->set<uint32_t>(regs.tctl.reg);
- break;
- case PBA:
- pkt->set<uint32_t>(regs.pba.reg);
- break;
- case WUC:
- case LEDCTL:
- pkt->set<uint32_t>(0); // We don't care, so just return 0
- break;
- case MANC:
- pkt->set<uint32_t>(regs.manc.reg);
- break;
+ case REG_CTRL:
+ pkt->set<uint32_t>(regs.ctrl());
+ break;
+ case REG_STATUS:
+ pkt->set<uint32_t>(regs.sts());
+ break;
+ case REG_EECD:
+ pkt->set<uint32_t>(regs.eecd());
+ break;
+ case REG_EERD:
+ pkt->set<uint32_t>(regs.eerd());
+ break;
+ case REG_CTRL_EXT:
+ pkt->set<uint32_t>(regs.ctrl_ext());
+ break;
+ case REG_MDIC:
+ pkt->set<uint32_t>(regs.mdic());
+ break;
+ case REG_ICR:
+ pkt->set<uint32_t>(regs.icr());
+ // handle auto setting mask from IAM
+ break;
+ case REG_ITR:
+ pkt->set<uint32_t>(regs.itr());
+ break;
+ case REG_RCTL:
+ pkt->set<uint32_t>(regs.rctl());
+ break;
+ case REG_FCTTV:
+ pkt->set<uint32_t>(regs.fcttv());
+ break;
+ case REG_TCTL:
+ pkt->set<uint32_t>(regs.tctl());
+ break;
+ case REG_PBA:
+ pkt->set<uint32_t>(regs.pba());
+ break;
+ case REG_WUC:
+ case REG_LEDCTL:
+ pkt->set<uint32_t>(0); // We don't care, so just return 0
+ break;
+ case REG_FCRTL:
+ pkt->set<uint32_t>(regs.fcrtl());
+ break;
+ case REG_FCRTH:
+ pkt->set<uint32_t>(regs.fcrth());
+ break;
+ case REG_RDBAL:
+ pkt->set<uint32_t>(regs.rdba.rdbal());
+ break;
+ case REG_RDBAH:
+ pkt->set<uint32_t>(regs.rdba.rdbah());
+ break;
+ case REG_RDLEN:
+ pkt->set<uint32_t>(regs.rdlen());
+ break;
+ case REG_RDH:
+ pkt->set<uint32_t>(regs.rdh());
+ break;
+ case REG_RDT:
+ pkt->set<uint32_t>(regs.rdt());
+ break;
+ case REG_RDTR:
+ pkt->set<uint32_t>(regs.rdtr());
+ break;
+ case REG_RADV:
+ pkt->set<uint32_t>(regs.radv());
+ break;
+ case REG_TDBAL:
+ pkt->set<uint32_t>(regs.tdba.tdbal());
+ break;
+ case REG_TDBAH:
+ pkt->set<uint32_t>(regs.tdba.tdbah());
+ break;
+ case REG_TDLEN:
+ pkt->set<uint32_t>(regs.tdlen());
+ break;
+ case REG_TDH:
+ pkt->set<uint32_t>(regs.tdh());
+ break;
+ case REG_TDT:
+ pkt->set<uint32_t>(regs.tdt());
+ break;
+ case REG_TIDV:
+ pkt->set<uint32_t>(regs.tidv());
+ break;
+ case REG_TXDCTL:
+ pkt->set<uint32_t>(regs.txdctl());
+ break;
+ case REG_TADV:
+ pkt->set<uint32_t>(regs.tadv());
+ break;
+ case REG_RXCSUM:
+ pkt->set<uint32_t>(regs.rxcsum());
+ break;
+ case REG_MANC:
+ pkt->set<uint32_t>(regs.manc());
+ break;
default:
- if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) &&
- !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) &&
- !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4))
- pkt->set<uint32_t>(0);
- else
- panic("Read request to unknown register number: %#x\n", daddr);
+ if (!(daddr >= REG_VFTA && daddr < (REG_VFTA + VLAN_FILTER_TABLE_SIZE*4)) &&
+ !(daddr >= REG_RAL && daddr < (REG_RAL + RCV_ADDRESS_TABLE_SIZE*8)) &&
+ !(daddr >= REG_MTA && daddr < (REG_MTA + MULTICAST_TABLE_SIZE*4)) &&
+ !(daddr >= REG_CRCERRS && daddr < (REG_CRCERRS + STATS_REGS_SIZE)))
+ panic("Read request to unknown register number: %#x\n", daddr);
+ else
+ pkt->set<uint32_t>(0);
};
pkt->result = Packet::Success;
uint32_t val = pkt->get<uint32_t>();
switch (daddr) {
- case CTRL:
- regs.ctrl.reg = val;
- break;
- case STATUS:
- regs.sts.reg = val;
- break;
- case EECD:
- int oldClk;
- oldClk = regs.eecd.sk;
- regs.eecd.reg = val;
- // See if this is a eeprom access and emulate accordingly
- if (!oldClk && regs.eecd.sk) {
- if (eeOpBits < 8) {
- eeOpcode = eeOpcode << 1 | regs.eecd.din;
- eeOpBits++;
- } else if (eeAddrBits < 8 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
- eeAddr = eeAddr << 1 | regs.eecd.din;
- eeAddrBits++;
- } else if (eeDataBits < 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
- assert(eeAddr>>1 < EEPROM_SIZE);
- DPRINTF(EthernetEEPROM, "EEPROM bit read: %d word: %#X\n",
- flash[eeAddr>>1] >> eeDataBits & 0x1, flash[eeAddr>>1]);
- regs.eecd.dout = (flash[eeAddr>>1] >> (15-eeDataBits)) & 0x1;
- eeDataBits++;
- } else if (eeDataBits < 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI) {
- regs.eecd.dout = 0;
- eeDataBits++;
- } else
- panic("What's going on with eeprom interface? opcode:"
- " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)eeOpcode,
- (uint32_t)eeOpBits, (uint32_t)eeAddr,
- (uint32_t)eeAddrBits, (uint32_t)eeDataBits);
-
- // Reset everything for the next command
- if ((eeDataBits == 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) ||
+ case REG_CTRL:
+ regs.ctrl = val;
+ if (regs.ctrl.tfce())
+ warn("TX Flow control enabled, should implement\n");
+ if (regs.ctrl.rfce())
+ warn("RX Flow control enabled, should implement\n");
+ break;
+ case REG_CTRL_EXT:
+ regs.ctrl_ext = val;
+ break;
+ case REG_STATUS:
+ regs.sts = val;
+ break;
+ case REG_EECD:
+ int oldClk;
+ oldClk = regs.eecd.sk();
+ regs.eecd = val;
+ // See if this is a eeprom access and emulate accordingly
+ if (!oldClk && regs.eecd.sk()) {
+ if (eeOpBits < 8) {
+ eeOpcode = eeOpcode << 1 | regs.eecd.din();
+ eeOpBits++;
+ } else if (eeAddrBits < 8 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
+ eeAddr = eeAddr << 1 | regs.eecd.din();
+ eeAddrBits++;
+ } else if (eeDataBits < 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
+ assert(eeAddr>>1 < EEPROM_SIZE);
+ DPRINTF(EthernetEEPROM, "EEPROM bit read: %d word: %#X\n",
+ flash[eeAddr>>1] >> eeDataBits & 0x1, flash[eeAddr>>1]);
+ regs.eecd.dout((flash[eeAddr>>1] >> (15-eeDataBits)) & 0x1);
+ eeDataBits++;
+ } else if (eeDataBits < 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI) {
+ regs.eecd.dout(0);
+ eeDataBits++;
+ } else
+ panic("What's going on with eeprom interface? opcode:"
+ " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)eeOpcode,
+ (uint32_t)eeOpBits, (uint32_t)eeAddr,
+ (uint32_t)eeAddrBits, (uint32_t)eeDataBits);
+
+ // Reset everything for the next command
+ if ((eeDataBits == 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) ||
(eeDataBits == 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI)) {
- eeOpBits = 0;
- eeAddrBits = 0;
- eeDataBits = 0;
+ eeOpBits = 0;
+ eeAddrBits = 0;
+ eeDataBits = 0;
eeOpcode = 0;
- eeAddr = 0;
- }
+ eeAddr = 0;
+ }
DPRINTF(EthernetEEPROM, "EEPROM: opcode: %#X:%d addr: %#X:%d\n",
- (uint32_t)eeOpcode, (uint32_t) eeOpBits,
- (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits);
+ (uint32_t)eeOpcode, (uint32_t) eeOpBits,
+ (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits);
if (eeOpBits == 8 && !(eeOpcode == EEPROM_READ_OPCODE_SPI ||
- eeOpcode == EEPROM_RDSR_OPCODE_SPI ))
- panic("Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode,
- (uint32_t)eeOpBits);
-
-
- }
- // If driver requests eeprom access, immediately give it to it
- regs.eecd.ee_gnt = regs.eecd.ee_req;
- break;
- case EERD:
- regs.eerd.reg = val;
- break;
- case ICR:
- regs.icd.reg = val;
- break;
- case IMC:
- regs.imc.reg = val;
- break;
- case RCTL:
- regs.rctl.reg = val;
- break;
- case TCTL:
- regs.tctl.reg = val;
- break;
- case PBA:
- regs.pba.rxa = val;
- regs.pba.txa = 64 - regs.pba.rxa;
- break;
- case WUC:
- case LEDCTL:
- ; // We don't care, so don't store anything
- break;
- case MANC:
- regs.manc.reg = val;
- break;
+ eeOpcode == EEPROM_RDSR_OPCODE_SPI ))
+ panic("Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode,
+ (uint32_t)eeOpBits);
+
+
+ }
+ // If driver requests eeprom access, immediately give it to it
+ regs.eecd.ee_gnt(regs.eecd.ee_req());
+ break;
+ case REG_EERD:
+ regs.eerd = val;
+ break;
+ case REG_MDIC:
+ regs.mdic = val;
+ if (regs.mdic.i())
+ panic("No support for interrupt on mdic complete\n");
+ if (regs.mdic.phyadd() != 1)
+ panic("No support for reading anything but phy\n");
+ DPRINTF(Ethernet, "%s phy address %x\n", regs.mdic.op() == 1 ? "Writing"
+ : "Reading", regs.mdic.regadd());
+ switch (regs.mdic.regadd()) {
+ case PHY_PSTATUS:
+ regs.mdic.data(0x796D); // link up
+ break;
+ case PHY_PID:
+ regs.mdic.data(0x02A8);
+ break;
+ case PHY_EPID:
+ regs.mdic.data(0x0380);
+ break;
+ case PHY_GSTATUS:
+ regs.mdic.data(0x7C00);
+ break;
+ case PHY_EPSTATUS:
+ regs.mdic.data(0x3000);
+ break;
+ case PHY_AGC:
+ regs.mdic.data(0x180); // some random length
+ break;
+ default:
+ regs.mdic.data(0);
+ warn("Accessing unknown phy register %d\n", regs.mdic.regadd());
+ }
+ regs.mdic.r(1);
+ break;
+ case REG_ICR:
+ regs.icr = val;
+ // handle auto setting mask from IAM
+ break;
+ case REG_ITR:
+ regs.itr = val;
+ break;
+ case REG_ICS:
+ regs.icr = val | regs.icr();
+ // generate an interrupt if needed here
+ break;
+ case REG_IMS:
+ regs.imr |= val;
+ // handle interrupts if needed here
+ break;
+ case REG_IMC:
+ regs.imr |= ~val;
+ // handle interrupts if needed here
+ break;
+ case REG_IAM:
+ regs.iam = val;
+ break;
+ case REG_RCTL:
+ regs.rctl = val;
+ break;
+ case REG_FCTTV:
+ regs.fcttv = val;
+ break;
+ case REG_TCTL:
+ regs.tctl = val;
+ break;
+ case REG_PBA:
+ regs.pba.rxa(val);
+ regs.pba.txa(64 - regs.pba.rxa());
+ break;
+ case REG_WUC:
+ case REG_LEDCTL:
+ case REG_FCAL:
+ case REG_FCAH:
+ case REG_FCT:
+ case REG_VET:
+ case REG_AIFS:
+ case REG_TIPG:
+ ; // We don't care, so don't store anything
+ break;
+ case REG_FCRTL:
+ regs.fcrtl = val;
+ break;
+ case REG_FCRTH:
+ regs.fcrth = val;
+ break;
+ case REG_RDBAL:
+ regs.rdba.rdbal( val & ~mask(4));
+ break;
+ case REG_RDBAH:
+ regs.rdba.rdbah(val);
+ break;
+ case REG_RDLEN:
+ regs.rdlen = val & ~mask(7);
+ break;
+ case REG_RDH:
+ regs.rdh = val;
+ break;
+ case REG_RDT:
+ regs.rdt = val;
+ break;
+ case REG_RDTR:
+ regs.rdtr = val;
+ break;
+ case REG_RADV:
+ regs.radv = val;
+ break;
+ case REG_TDBAL:
+ regs.tdba.tdbal( val & ~mask(4));
+ break;
+ case REG_TDBAH:
+ regs.tdba.tdbah(val);
+ break;
+ case REG_TDLEN:
+ regs.tdlen = val & ~mask(7);
+ break;
+ case REG_TDH:
+ regs.tdh = val;
+ break;
+ case REG_TDT:
+ regs.tdt = val;
+ break;
+ case REG_TIDV:
+ regs.tidv = val;
+ break;
+ case REG_TXDCTL:
+ regs.txdctl = val;
+ break;
+ case REG_TADV:
+ regs.tadv = val;
+ break;
+ case REG_RXCSUM:
+ regs.rxcsum = val;
+ break;
+ case REG_MANC:
+ regs.manc = val;
+ break;
default:
- if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) &&
- !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) &&
- !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4))
+ if (!(daddr >= REG_VFTA && daddr < (REG_VFTA + VLAN_FILTER_TABLE_SIZE*4)) &&
+ !(daddr >= REG_RAL && daddr < (REG_RAL + RCV_ADDRESS_TABLE_SIZE*8)) &&
+ !(daddr >= REG_MTA && daddr < (REG_MTA + MULTICAST_TABLE_SIZE*4)))
panic("Write request to unknown register number: %#x\n", daddr);
};
/* @file
* Register and structure descriptions for Intel's 8254x line of gigabit ethernet controllers.
*/
+#include "base/bitfield.hh"
namespace iGbReg {
-const uint32_t CTRL = 0x00000; //*
-const uint32_t STATUS = 0x00008; //*
-const uint32_t EECD = 0x00010; //*
-const uint32_t EERD = 0x00014; //*
-const uint32_t CTRL_EXT = 0x00018;
-const uint32_t PBA = 0x01000;
-const uint32_t ICR = 0x000C0; //*
-const uint32_t ITR = 0x000C4;
-const uint32_t ICS = 0x000C8;
-const uint32_t IMS = 0x000D0;
-const uint32_t IMC = 0x000D8; //*
-const uint32_t RCTL = 0x00100; //*
-const uint32_t RDBAL = 0x02800;
-const uint32_t RDBAH = 0x02804;
-const uint32_t RDLEN = 0x02808;
-const uint32_t RDH = 0x02810;
-const uint32_t RDT = 0x02818;
-const uint32_t RDTR = 0x02820;
-const uint32_t RADV = 0x0282C;
-const uint32_t RSRPD = 0x02C00;
-const uint32_t TCTL = 0x00400; //*
-const uint32_t TDBAL = 0x03800;
-const uint32_t TDBAH = 0x03804;
-const uint32_t TDLEN = 0x03808;
-const uint32_t TDH = 0x03810;
-const uint32_t THT = 0x03818;
-const uint32_t TIDV = 0x03820;
-const uint32_t TXDMAC = 0x03000;
-const uint32_t TXDCTL = 0x03828;
-const uint32_t TADV = 0x0282C;
-const uint32_t TSPMT = 0x03830;
-const uint32_t RXDCTL = 0x02828;
-const uint32_t RXCSUM = 0x05000;
-const uint32_t MANC = 0x05820;//*
+const uint32_t REG_CTRL = 0x00000; //*
+const uint32_t REG_STATUS = 0x00008; //*
+const uint32_t REG_EECD = 0x00010; //*
+const uint32_t REG_EERD = 0x00014; //*
+const uint32_t REG_CTRL_EXT = 0x00018; //*-
+const uint32_t REG_MDIC = 0x00020; //*
+const uint32_t REG_FCAL = 0x00028; //*
+const uint32_t REG_FCAH = 0x0002C; //*
+const uint32_t REG_FCT = 0x00030; //*
+const uint32_t REG_VET = 0x00038; //*
+const uint32_t REG_PBA = 0x01000; //*
+const uint32_t REG_ICR = 0x000C0; //*
+const uint32_t REG_ITR = 0x000C4; //*
+const uint32_t REG_ICS = 0x000C8; //*
+const uint32_t REG_IMS = 0x000D0; //*
+const uint32_t REG_IMC = 0x000D8; //*
+const uint32_t REG_IAM = 0x000E0; //*
+const uint32_t REG_RCTL = 0x00100; //*
+const uint32_t REG_FCTTV = 0x00170; //*
+const uint32_t REG_TIPG = 0x00410; //*
+const uint32_t REG_AIFS = 0x00458; //*
+const uint32_t REG_LEDCTL = 0x00e00; //*
+const uint32_t REG_FCRTL = 0x02160; //*
+const uint32_t REG_FCRTH = 0x02168; //*
+const uint32_t REG_RDBAL = 0x02800; //*-
+const uint32_t REG_RDBAH = 0x02804; //*-
+const uint32_t REG_RDLEN = 0x02808; //*-
+const uint32_t REG_RDH = 0x02810; //*-
+const uint32_t REG_RDT = 0x02818; //*-
+const uint32_t REG_RDTR = 0x02820; //*-
+const uint32_t REG_RXDCTL = 0x02828; //*
+const uint32_t REG_RADV = 0x0282C; //*-
+const uint32_t REG_RSRPD = 0x02C00;
+const uint32_t REG_TCTL = 0x00400; //*
+const uint32_t REG_TDBAL = 0x03800; //*
+const uint32_t REG_TDBAH = 0x03804; //*
+const uint32_t REG_TDLEN = 0x03808; //*
+const uint32_t REG_TDH = 0x03810; //*
+const uint32_t REG_TDT = 0x03818; //*
+const uint32_t REG_TIDV = 0x03820; //*
+const uint32_t REG_TXDMAC = 0x03000;
+const uint32_t REG_TXDCTL = 0x03828; //*
+const uint32_t REG_TADV = 0x0382C; //*
+const uint32_t REG_TSPMT = 0x03830;
+const uint32_t REG_CRCERRS = 0x04000;
+const uint32_t REG_RXCSUM = 0x05000; //*-
+const uint32_t REG_MTA = 0x05200;
+const uint32_t REG_RAL = 0x05400;
+const uint32_t REG_RAH = 0x05404;
+const uint32_t REG_VFTA = 0x05600;
+
+const uint32_t REG_WUC = 0x05800;//*
+const uint32_t REG_MANC = 0x05820;//*
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 = 16;
+const uint8_t MULTICAST_TABLE_SIZE = 128;
+const uint32_t STATS_REGS_SIZE = 0x124;
+
+const uint8_t PHY_PSTATUS = 0x1;
+const uint8_t PHY_PID = 0x2;
+const uint8_t PHY_EPID = 0x3;
+const uint8_t PHY_GSTATUS = 10;
+const uint8_t PHY_EPSTATUS = 15;
+const uint8_t PHY_AGC = 18;
+
struct RxDesc {
Addr buf;
} type;
};
+#define ADD_FIELD32(NAME, OFFSET, BITS) \
+ inline uint32_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
+ inline void NAME(uint32_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
+
+#define ADD_FIELD64(NAME, OFFSET, BITS) \
+ inline uint64_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
+ inline void NAME(uint64_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
+
struct Regs {
- union { // 0x0000 CTRL Register
- uint32_t reg;
- struct {
- uint8_t fd:1; // full duplex
- uint8_t bem:1; // big endian mode
- uint8_t pcipr:1; // PCI priority
- uint8_t lrst:1; // link reset
- uint8_t tme:1; // test mode enable
- uint8_t asde:1; // Auto-speed detection
- uint8_t slu:1; // Set link up
- uint8_t ilos:1; // invert los-of-signal
- uint8_t speed:2; // speed selection bits
- uint8_t be32:1; // big endian mode 32
- uint8_t frcspd:1; // force speed
- uint8_t frcdpx:1; // force duplex
- uint8_t duden:1; // dock/undock enable
- uint8_t dudpol:1; // dock/undock polarity
- uint8_t fphyrst:1; // force phy reset
- uint8_t extlen:1; // external link status enable
- uint8_t rsvd:1; // reserved
- uint8_t sdp0d:1; // software controlled pin data
- uint8_t sdp1d:1; // software controlled pin data
- uint8_t sdp2d:1; // software controlled pin data
- uint8_t sdp3d:1; // software controlled pin data
- uint8_t sdp0i:1; // software controlled pin dir
- uint8_t sdp1i:1; // software controlled pin dir
- uint8_t sdp2i:1; // software controlled pin dir
- uint8_t sdp3i:1; // software controlled pin dir
- uint8_t rst:1; // reset
- uint8_t rfce:1; // receive flow control enable
- uint8_t tfce:1; // transmit flow control enable
- uint8_t rte:1; // routing tag enable
- uint8_t vme:1; // vlan enable
- uint8_t phyrst:1; // phy reset
- } ;
- } ctrl;
-
- union { // 0x0008 STATUS
- uint32_t reg;
- struct {
- uint8_t fd:1; // full duplex
- uint8_t lu:1; // link up
- uint8_t func:2; // function id
- uint8_t txoff:1; // transmission paused
- uint8_t tbimode:1; // tbi mode
- uint8_t speed:2; // link speed
- uint8_t asdv:2; // auto speed detection value
- uint8_t mtxckok:1; // mtx clock running ok
- uint8_t pci66:1; // In 66Mhz pci slot
- uint8_t bus64:1; // in 64 bit slot
- uint8_t pcix:1; // Pci mode
- uint8_t pcixspd:1; // pci x speed
- uint8_t reserved; // reserved
- } ;
- } sts;
-
- union { // 0x0010 EECD
- uint32_t reg;
- struct {
- uint8_t sk:1; // clack input to the eeprom
- uint8_t cs:1; // chip select to eeprom
- uint8_t din:1; // data input to eeprom
- uint8_t dout:1; // data output bit
- uint8_t fwe:2; // flash write enable
- uint8_t ee_req:1; // request eeprom access
- uint8_t ee_gnt:1; // grant eeprom access
- uint8_t ee_pres:1; // eeprom present
- uint8_t ee_size:1; // eeprom size
- uint8_t ee_sz1:1; // eeprom size
- uint8_t rsvd:2; // reserved
- uint8_t ee_type:1; // type of eeprom
- } ;
- } eecd;
-
- union { // 0x0014 EERD
- uint32_t reg;
- struct {
- uint8_t start:1; // start read
- uint8_t done:1; // done read
- uint16_t addr:14; // address
- uint16_t data; // data
- };
- } eerd;
+ template<class T>
+ struct Reg {
+ T _data;
+ T operator()() { return _data; }
+ const Reg<T> &operator=(T d) { _data = d; return *this;}
+ bool operator==(T d) { return d == _data; }
+ void operator()(T d) { _data = d; }
+ };
- union { // 0x00C0 ICR
- uint32_t reg;
- struct {
- uint8_t txdw:1; // tx descr witten back
- uint8_t txqe:1; // tx queue empty
- uint8_t lsc:1; // link status change
- uint8_t rxseq:1; // rcv sequence error
- uint8_t rxdmt0:1; // rcv descriptor min thresh
- uint8_t rsvd1:1; // reserved
- uint8_t rxo:1; // receive overrunn
- uint8_t rxt0:1; // receiver timer interrupt
- uint8_t rsvd2:1; // reserved
- uint8_t mdac:1; // mdi/o access complete
- uint8_t rxcfg:1; // recv /c/ ordered sets
- uint8_t rsvd3:1; // reserved
- uint8_t phyint:1; // phy interrupt
- uint8_t gpi1:1; // gpi int 1
- uint8_t gpi2:1; // gpi int 2
- uint8_t txdlow:1; // transmit desc low thresh
- uint8_t srpd:1; // small receive packet detected
- uint16_t rsvd4:15; // reserved
- } ;
- } icd;
-
- union { // 0x00C0 IMC
- uint32_t reg;
- struct {
- uint8_t txdw:1; // tx descr witten back
- uint8_t txqe:1; // tx queue empty
- uint8_t lsc:1; // link status change
- uint8_t rxseq:1; // rcv sequence error
- uint8_t rxdmt0:1; // rcv descriptor min thresh
- uint8_t rsvd1:1; // reserved
- uint8_t rxo:1; // receive overrunn
- uint8_t rxt0:1; // receiver timer interrupt
- uint8_t rsvd2:1; // reserved
- uint8_t mdac:1; // mdi/o access complete
- uint8_t rxcfg:1; // recv /c/ ordered sets
- uint8_t rsvd3:1; // reserved
- uint8_t phyint:1; // phy interrupt
- uint8_t gpi1:1; // gpi int 1
- uint8_t gpi2:1; // gpi int 2
- uint8_t txdlow:1; // transmit desc low thresh
- uint8_t srpd:1; // small receive packet detected
- uint16_t rsvd4:15; // reserved
- } ;
- } imc;
-
- union { // 0x0100 RCTL
- uint32_t reg;
- struct {
- uint8_t rst:1; // Reset
- uint8_t en:1; // Enable
- uint8_t sbp:1; // Store bad packets
- uint8_t upe:1; // Unicast Promiscuous enabled
- uint8_t mpe:1; // Multicast promiscuous enabled
- uint8_t lpe:1; // long packet reception enabled
- uint8_t lbm:2; //
- uint8_t rdmts:2; //
- uint8_t rsvd:2; //
- uint8_t mo:2; //
- uint8_t mdr:1; //
- uint8_t bam:1; //
- uint8_t bsize:2; //
- uint8_t vpe:1; //
- uint8_t cfien:1; //
- uint8_t cfi:1; //
- uint8_t rsvd2:1; //
- uint8_t dpf:1; // discard pause frames
- uint8_t pmcf:1; // pass mac control frames
- uint8_t rsvd3:1; // reserved
- uint8_t bsex:1; // buffer size extension
- uint8_t secrc:1; // strip ethernet crc from incoming packet
- uint8_t rsvd1:5; // reserved
- } ;
- } rctl;
-
- union { // 0x0400 TCTL
- uint32_t reg;
- struct {
- uint8_t rst:1; // Reset
- uint8_t en:1; // Enable
- uint8_t bce:1; // busy check enable
- uint8_t psp:1; // pad short packets
- uint8_t ct:8; // collision threshold
- uint16_t cold:10; // collision distance
- uint8_t swxoff:1; // software xoff transmission
- uint8_t pbe:1; // packet burst enable
- uint8_t rtlc:1; // retransmit late collisions
- uint8_t nrtu:1; // on underrun no TX
- uint8_t mulr:1; // multiple request
- uint8_t rsvd:5; // reserved
- } ;
- } tctl;
-
- union { // 0x5820 MANC
- uint32_t reg;
- struct {
- uint8_t smbus:1; // SMBus enabled #####
- uint8_t asf:1; // ASF enabled #####
- uint8_t ronforce:1; // reset of force
- uint8_t rsvd:5; // reserved
- uint8_t rmcp1:1; // rcmp1 filtering
- uint8_t rmcp2:1; // rcmp2 filtering
- uint8_t ipv4:1; // enable ipv4
- uint8_t ipv6:1; // enable ipv6
- uint8_t snap:1; // accept snap
- uint8_t arp:1; // filter arp #####
- uint8_t neighbor:1; // neighbor discovery
- uint8_t arp_resp:1; // arp response
- uint8_t tcorst:1; // tco reset happened
- uint8_t rcvtco:1; // receive tco enabled ######
- uint8_t blkphyrst:1;// block phy resets ########
- uint8_t rcvall:1; // receive all
- uint8_t macaddrfltr:1; // mac address filtering ######
- uint8_t mng2host:1; // mng2 host packets #######
- uint8_t ipaddrfltr:1; // ip address filtering
- uint8_t xsumfilter:1; // checksum filtering
- uint8_t brfilter:1; // broadcast filtering
- uint8_t smbreq:1; // smb request
- uint8_t smbgnt:1; // smb grant
- uint8_t smbclkin:1; // smbclkin
- uint8_t smbdatain:1; // smbdatain
- uint8_t smbdataout:1; // smb data out
- uint8_t smbclkout:1; // smb clock out
- uint8_t rsvd2:2;
- };
- } manc;
+ struct CTRL : public Reg<uint32_t> { // 0x0000 CTRL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(fd,0,1); // full duplex
+ ADD_FIELD32(bem,1,1); // big endian mode
+ ADD_FIELD32(pcipr,2,1); // PCI priority
+ ADD_FIELD32(lrst,3,1); // link reset
+ ADD_FIELD32(tme,4,1); // test mode enable
+ ADD_FIELD32(asde,5,1); // Auto-speed detection
+ ADD_FIELD32(slu,6,1); // Set link up
+ ADD_FIELD32(ilos,7,1); // invert los-of-signal
+ ADD_FIELD32(speed,8,2); // speed selection bits
+ ADD_FIELD32(be32,10,1); // big endian mode 32
+ ADD_FIELD32(frcspd,11,1); // force speed
+ ADD_FIELD32(frcdpx,12,1); // force duplex
+ ADD_FIELD32(duden,13,1); // dock/undock enable
+ ADD_FIELD32(dudpol,14,1); // dock/undock polarity
+ ADD_FIELD32(fphyrst,15,1); // force phy reset
+ ADD_FIELD32(extlen,16,1); // external link status enable
+ ADD_FIELD32(rsvd,17,1); // reserved
+ ADD_FIELD32(sdp0d,18,1); // software controlled pin data
+ ADD_FIELD32(sdp1d,19,1); // software controlled pin data
+ ADD_FIELD32(sdp2d,20,1); // software controlled pin data
+ ADD_FIELD32(sdp3d,21,1); // software controlled pin data
+ ADD_FIELD32(sdp0i,22,1); // software controlled pin dir
+ ADD_FIELD32(sdp1i,23,1); // software controlled pin dir
+ ADD_FIELD32(sdp2i,24,1); // software controlled pin dir
+ ADD_FIELD32(sdp3i,25,1); // software controlled pin dir
+ ADD_FIELD32(rst,26,1); // reset
+ ADD_FIELD32(rfce,27,1); // receive flow control enable
+ ADD_FIELD32(tfce,28,1); // transmit flow control enable
+ ADD_FIELD32(rte,29,1); // routing tag enable
+ ADD_FIELD32(vme,30,1); // vlan enable
+ ADD_FIELD32(phyrst,31,1); // phy reset
+ };
+ CTRL ctrl;
+
+ struct STATUS : public Reg<uint32_t> { // 0x0008 STATUS Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(fd,0,1); // full duplex
+ ADD_FIELD32(lu,1,1); // link up
+ ADD_FIELD32(func,2,2); // function id
+ ADD_FIELD32(txoff,4,1); // transmission paused
+ ADD_FIELD32(tbimode,5,1); // tbi mode
+ ADD_FIELD32(speed,6,2); // link speed
+ ADD_FIELD32(asdv,8,2); // auto speed detection value
+ ADD_FIELD32(mtxckok,10,1); // mtx clock running ok
+ ADD_FIELD32(pci66,11,1); // In 66Mhz pci slot
+ ADD_FIELD32(bus64,12,1); // in 64 bit slot
+ ADD_FIELD32(pcix,13,1); // Pci mode
+ ADD_FIELD32(pcixspd,14,2); // pci x speed
+ };
+ STATUS sts;
+
+ struct EECD : public Reg<uint32_t> { // 0x0010 EECD Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(sk,0,1); // clack input to the eeprom
+ ADD_FIELD32(cs,1,1); // chip select to eeprom
+ ADD_FIELD32(din,2,1); // data input to eeprom
+ ADD_FIELD32(dout,3,1); // data output bit
+ ADD_FIELD32(fwe,4,2); // flash write enable
+ ADD_FIELD32(ee_req,6,1); // request eeprom access
+ ADD_FIELD32(ee_gnt,7,1); // grant eeprom access
+ ADD_FIELD32(ee_pres,8,1); // eeprom present
+ ADD_FIELD32(ee_size,9,1); // eeprom size
+ ADD_FIELD32(ee_sz1,10,1); // eeprom size
+ ADD_FIELD32(rsvd,11,2); // reserved
+ ADD_FIELD32(ee_type,13,1); // type of eeprom
+ } ;
+ EECD eecd;
+
+ struct EERD : public Reg<uint32_t> { // 0x0014 EERD Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(start,0,1); // start read
+ ADD_FIELD32(done,4,1); // done read
+ ADD_FIELD32(addr,8,8); // address
+ ADD_FIELD32(data,16,16); // data
+ };
+ EERD eerd;
+
+ struct CTRL_EXT : public Reg<uint32_t> { // 0x0018 CTRL_EXT Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(gpi_en,0,4); // enable interrupts from gpio
+ ADD_FIELD32(phyint,5,1); // reads the phy internal int status
+ ADD_FIELD32(sdp2_data,6,1); // data from gpio sdp
+ ADD_FIELD32(spd3_data,7,1); // data frmo gpio sdp
+ ADD_FIELD32(spd2_iodir,10,1); // direction of sdp2
+ ADD_FIELD32(spd3_iodir,11,1); // direction of sdp2
+ ADD_FIELD32(asdchk,12,1); // initiate auto-speed-detection
+ ADD_FIELD32(eerst,13,1); // reset the eeprom
+ ADD_FIELD32(spd_byps,15,1); // bypass speed select
+ ADD_FIELD32(ro_dis,17,1); // disable relaxed memory ordering
+ ADD_FIELD32(vreg,21,1); // power down the voltage regulator
+ ADD_FIELD32(link_mode,22,2); // interface to talk to the link
+ ADD_FIELD32(iame, 27,1); // interrupt acknowledge auto-mask ??
+ ADD_FIELD32(drv_loaded, 28,1);// driver is loaded and incharge of device
+ ADD_FIELD32(timer_clr, 29,1); // clear interrupt timers after IMS clear ??
+ };
+ CTRL_EXT ctrl_ext;
+
+ struct MDIC : public Reg<uint32_t> { // 0x0020 MDIC Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(data,0,16); // data
+ ADD_FIELD32(regadd,16,5); // register address
+ ADD_FIELD32(phyadd,21,5); // phy addresses
+ ADD_FIELD32(op,26,2); // opcode
+ ADD_FIELD32(r,28,1); // ready
+ ADD_FIELD32(i,29,1); // interrupt
+ ADD_FIELD32(e,30,1); // error
+ };
+ MDIC mdic;
+
+ struct ICR : public Reg<uint32_t> { // 0x00C0 ICR Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(txdw,0,1) // tx descr witten back
+ ADD_FIELD32(txqe,1,1) // tx queue empty
+ ADD_FIELD32(lsc,2,1) // link status change
+ ADD_FIELD32(rxseq,3,1) // rcv sequence error
+ ADD_FIELD32(rxdmt0,4,1) // rcv descriptor min thresh
+ ADD_FIELD32(rsvd1,5,1) // reserved
+ ADD_FIELD32(rxo,6,1) // receive overrunn
+ ADD_FIELD32(rxt0,7,1) // receiver timer interrupt
+ ADD_FIELD32(mdac,9,1) // mdi/o access complete
+ ADD_FIELD32(rxcfg,10,1) // recv /c/ ordered sets
+ ADD_FIELD32(phyint,12,1) // phy interrupt
+ ADD_FIELD32(gpi1,13,1) // gpi int 1
+ ADD_FIELD32(gpi2,14,1) // gpi int 2
+ ADD_FIELD32(txdlow,15,1) // transmit desc low thresh
+ ADD_FIELD32(srpd,16,1) // small receive packet detected
+ ADD_FIELD32(ack,17,1); // receive ack frame
+ ADD_FIELD32(int_assert, 31,0); // interrupt caused a system interrupt
+ };
+ ICR icr;
+
+ uint32_t imr; // register that contains the current interrupt mask
+
+ struct ITR : public Reg<uint32_t> { // 0x00C4 ITR Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(interval, 0,16); // minimum inter-interrutp inteval
+ // specified in 256ns interrupts
+ };
+ ITR itr;
+
+ // When CTRL_EXT.IAME and the ICR.INT_ASSERT is 1 an ICR read or write
+ // causes the IAM register contents to be written into the IMC
+ // automatically clearing all interrupts that have a bit in the IAM set
+ uint32_t iam;
+
+ struct RCTL : public Reg<uint32_t> { // 0x0100 RCTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rst,0,1); // Reset
+ ADD_FIELD32(en,1,1); // Enable
+ ADD_FIELD32(sbp,2,1); // Store bad packets
+ ADD_FIELD32(upe,3,1); // Unicast Promiscuous enabled
+ ADD_FIELD32(mpe,4,1); // Multicast promiscuous enabled
+ ADD_FIELD32(lpe,5,1); // long packet reception enabled
+ ADD_FIELD32(lbm,6,2); //
+ ADD_FIELD32(rdmts,8,2); //
+ ADD_FIELD32(rsvd,10,2); //
+ ADD_FIELD32(mo,12,2); //
+ ADD_FIELD32(mdr,14,1); //
+ ADD_FIELD32(bam,15,1); //
+ ADD_FIELD32(bsize,16,2); //
+ ADD_FIELD32(vfe,18,1); //
+ ADD_FIELD32(cfien,19,1); //
+ ADD_FIELD32(cfi,20,1); //
+ ADD_FIELD32(rsvd2,21,1); //
+ ADD_FIELD32(dpf,22,1); // discard pause frames
+ ADD_FIELD32(pmcf,23,1); // pass mac control frames
+ ADD_FIELD32(bsex,25,1); // buffer size extension
+ ADD_FIELD32(secrc,26,1); // strip ethernet crc from incoming packet
+ };
+ RCTL rctl;
+
+ struct FCTTV : public Reg<uint32_t> { // 0x0170 FCTTV
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(ttv,0,16); // Transmit Timer Value
+ };
+ FCTTV fcttv;
+
+ struct TCTL : public Reg<uint32_t> { // 0x0400 TCTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rst,0,1); // Reset
+ ADD_FIELD32(en,1,1); // Enable
+ ADD_FIELD32(bce,2,1); // busy check enable
+ ADD_FIELD32(psp,3,1); // pad short packets
+ ADD_FIELD32(ct,4,8); // collision threshold
+ ADD_FIELD32(cold,12,10); // collision distance
+ ADD_FIELD32(swxoff,22,1); // software xoff transmission
+ ADD_FIELD32(pbe,23,1); // packet burst enable
+ ADD_FIELD32(rtlc,24,1); // retransmit late collisions
+ ADD_FIELD32(nrtu,25,1); // on underrun no TX
+ ADD_FIELD32(mulr,26,1); // multiple request
+ };
+ TCTL tctl;
+
+ struct PBA : public Reg<uint32_t> { // 0x1000 PBA Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rxa,0,16);
+ ADD_FIELD32(txa,16,16);
+ };
+ PBA pba;
+
+ struct FCRTL : public Reg<uint32_t> { // 0x2160 FCRTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rtl,3,28); // make this bigger than the spec so we can have
+ // a larger buffer
+ ADD_FIELD32(xone, 31,1);
+ };
+ FCRTL fcrtl;
+
+ struct FCRTH : public Reg<uint32_t> { // 0x2168 FCRTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rth,3,13); // make this bigger than the spec so we can have
+ //a larger buffer
+ ADD_FIELD32(xfce, 31,1);
+ };
+ FCRTH fcrth;
+
+ struct RDBA : public Reg<uint64_t> { // 0x2800 RDBA Register
+ using Reg<uint64_t>::operator=;
+ ADD_FIELD64(rdbal,4,28); // base address of rx descriptor ring
+ ADD_FIELD64(rdbah,32,32); // base address of rx descriptor ring
+ };
+ RDBA rdba;
+
+ struct RDLEN : public Reg<uint32_t> { // 0x2808 RDLEN Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(len,7,13); // number of bytes in the descriptor buffer
+ };
+ RDLEN rdlen;
+
+ struct RDH : public Reg<uint32_t> { // 0x2810 RDH Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rdh,0,16); // head of the descriptor ring
+ };
+ RDH rdh;
+
+ struct RDT : public Reg<uint32_t> { // 0x2818 RDT Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rdt,0,16); // tail of the descriptor ring
+ };
+ RDT rdt;
+
+ struct RDTR : public Reg<uint32_t> { // 0x2820 RDTR Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(delay,0,16); // receive delay timer
+ ADD_FIELD32(fpd, 31,); // flush partial descriptor block ??
+ };
+ RDTR rdtr;
+
+ struct RADV : public Reg<uint32_t> { // 0x282C RADV Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,16); // absolute interrupt delay
+ };
+ RADV radv;
+
+ struct RSRPD : public Reg<uint32_t> { // 0x2C00 RSRPD Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,12); // size to interrutp on small packets
+ };
+ RSRPD rsrpd;
+
+ struct TDBA : public Reg<uint64_t> { // 0x3800 TDBAL Register
+ using Reg<uint64_t>::operator=;
+ ADD_FIELD64(tdbal,4,28); // base address of transmit descriptor ring
+ ADD_FIELD64(tdbah,32,32); // base address of transmit descriptor ring
+ };
+ TDBA tdba;
+
+ struct TDLEN : public Reg<uint32_t> { // 0x3808 TDLEN Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(len,7,13); // number of bytes in the descriptor buffer
+ };
+ TDLEN tdlen;
+
+ struct TDH : public Reg<uint32_t> { // 0x3810 TDH Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(tdh,0,16); // head of the descriptor ring
+ };
+ TDH tdh;
+
+ struct TDT : public Reg<uint32_t> { // 0x3818 TDT Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(tdt,0,16); // tail of the descriptor ring
+ };
+ TDT tdt;
+
+ struct TIDV : public Reg<uint32_t> { // 0x3820 TIDV Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,16); // interrupt delay
+ };
+ TIDV tidv;
+
+ struct TXDCTL : public Reg<uint32_t> { // 0x3828 TXDCTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(pthresh, 0,6); // if number of descriptors control has is
+ // below this number, a prefetch is considered
+ ADD_FIELD32(hthresh,8,8); // number of valid descriptors is host memory
+ // before a prefetch is considered
+ ADD_FIELD32(wthresh,16,6); // number of descriptors to keep until
+ // writeback is considered
+ ADD_FIELD32(gran, 24,1); // granulatiry of above values (0 = cacheline,
+ // 1 == desscriptor)
+ ADD_FIELD32(lwthresh,25,7); // xmit descriptor low thresh, interrupt
+ // below this level
+ };
+ TXDCTL txdctl;
+
+ struct TADV : public Reg<uint32_t> { // 0x382C TADV Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,16); // absolute interrupt delay
+ };
+ TADV tadv;
+
+ struct RXCSUM : public Reg<uint32_t> { // 0x5000 RXCSUM Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(pcss,0,8);
+ ADD_FIELD32(ipofld,8,1);
+ ADD_FIELD32(tuofld,9,1);
+ };
+ RXCSUM rxcsum;
+
+ struct MANC : public Reg<uint32_t> { // 0x5820 MANC Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(smbus,0,1); // SMBus enabled #####
+ ADD_FIELD32(asf,1,1); // ASF enabled #####
+ ADD_FIELD32(ronforce,2,1); // reset of force
+ ADD_FIELD32(rsvd,3,5); // reserved
+ ADD_FIELD32(rmcp1,8,1); // rcmp1 filtering
+ ADD_FIELD32(rmcp2,9,1); // rcmp2 filtering
+ ADD_FIELD32(ipv4,10,1); // enable ipv4
+ ADD_FIELD32(ipv6,11,1); // enable ipv6
+ ADD_FIELD32(snap,12,1); // accept snap
+ ADD_FIELD32(arp,13,1); // filter arp #####
+ ADD_FIELD32(neighbor,14,1); // neighbor discovery
+ ADD_FIELD32(arp_resp,15,1); // arp response
+ ADD_FIELD32(tcorst,16,1); // tco reset happened
+ ADD_FIELD32(rcvtco,17,1); // receive tco enabled ######
+ ADD_FIELD32(blkphyrst,18,1);// block phy resets ########
+ ADD_FIELD32(rcvall,19,1); // receive all
+ ADD_FIELD32(macaddrfltr,20,1); // mac address filtering ######
+ ADD_FIELD32(mng2host,21,1); // mng2 host packets #######
+ ADD_FIELD32(ipaddrfltr,22,1); // ip address filtering
+ ADD_FIELD32(xsumfilter,23,1); // checksum filtering
+ ADD_FIELD32(brfilter,24,1); // broadcast filtering
+ ADD_FIELD32(smbreq,25,1); // smb request
+ ADD_FIELD32(smbgnt,26,1); // smb grant
+ ADD_FIELD32(smbclkin,27,1); // smbclkin
+ ADD_FIELD32(smbdatain,28,1); // smbdatain
+ ADD_FIELD32(smbdataout,29,1); // smb data out
+ ADD_FIELD32(smbclkout,30,1); // smb clock out
+ };
+ MANC manc;
};
}; // iGbReg namespace