add all the registers we'll need to support for the Intel GbE device and support enough functionality make the driver think

the device is there, and in good working order.

src/dev/SConscript:
    add intel gbe to the dev SCons file
src/dev/i8254xGBe.cc:
src/dev/i8254xGBe.hh:
src/dev/i8254xGBe_defs.hh:
    use new manner of registers and implement all device registers that are touched through boot and ifup

--HG--
extra : convert_revision : b1a1767f0fd31cd371e432cb48ac9a2e9f9291b5
This commit is contained in:
Ali Saidi 2007-03-15 15:16:23 -04:00
parent c6188a2264
commit 3a5a20769b
4 changed files with 768 additions and 378 deletions

View file

@ -40,7 +40,7 @@ if env['FULL_SYSTEM']:
Source('etherlink.cc')
Source('etherpkt.cc')
Source('ethertap.cc')
#Source('i8254xGBe.cc')
Source('i8254xGBe.cc')
Source('ide_ctrl.cc')
Source('ide_disk.cc')
Source('io_device.cc')

View file

@ -46,29 +46,32 @@
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.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;
regs.pba.rxa(0x30);
regs.pba.txa(0x10);
eeOpBits = 0;
eeAddrBits = 0;
@ -78,8 +81,17 @@ IGbE::IGbE(Params *p)
// 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));
}
@ -124,47 +136,112 @@ IGbE::read(PacketPtr pkt)
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;
@ -195,92 +272,211 @@ IGbE::write(PacketPtr pkt)
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);
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) ||
// 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);
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;
}
// 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);
};

View file

@ -54,13 +54,15 @@ class IGbE : public PciDev
int eeOpBits, eeAddrBits, eeDataBits;
uint8_t eeOpcode, eeAddr;
bool useFlowControl;
uint16_t flash[iGbReg::EEPROM_SIZE];
public:
struct Params : public PciDev::Params
{
;
bool use_flow_control;
};
IGbE(Params *params);

View file

@ -31,47 +31,81 @@
/* @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;
@ -245,219 +279,377 @@ union TxDesc {
} 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;
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 { // 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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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