i8254xGBe_defs.hh revision 4291
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;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Ali Saidi
29 */
30
31/* @file
32 * Register and structure descriptions for Intel's 8254x line of gigabit ethernet controllers.
33 */
34#include "base/bitfield.hh"
35
36namespace iGbReg {
37
38
39// Registers used by the Intel GbE NIC
40const uint32_t REG_CTRL     = 0x00000;
41const uint32_t REG_STATUS   = 0x00008;
42const uint32_t REG_EECD     = 0x00010;
43const uint32_t REG_EERD     = 0x00014;
44const uint32_t REG_CTRL_EXT = 0x00018;
45const uint32_t REG_MDIC     = 0x00020;
46const uint32_t REG_FCAL     = 0x00028;
47const uint32_t REG_FCAH     = 0x0002C;
48const uint32_t REG_FCT      = 0x00030;
49const uint32_t REG_VET      = 0x00038;
50const uint32_t REG_PBA      = 0x01000;
51const uint32_t REG_ICR      = 0x000C0;
52const uint32_t REG_ITR      = 0x000C4;
53const uint32_t REG_ICS      = 0x000C8;
54const uint32_t REG_IMS      = 0x000D0;
55const uint32_t REG_IMC      = 0x000D8;
56const uint32_t REG_IAM      = 0x000E0;
57const uint32_t REG_RCTL     = 0x00100;
58const uint32_t REG_FCTTV    = 0x00170;
59const uint32_t REG_TIPG     = 0x00410;
60const uint32_t REG_AIFS     = 0x00458;
61const uint32_t REG_LEDCTL   = 0x00e00;
62const uint32_t REG_FCRTL    = 0x02160;
63const uint32_t REG_FCRTH    = 0x02168;
64const uint32_t REG_RDBAL    = 0x02800;
65const uint32_t REG_RDBAH    = 0x02804;
66const uint32_t REG_RDLEN    = 0x02808;
67const uint32_t REG_RDH      = 0x02810;
68const uint32_t REG_RDT      = 0x02818;
69const uint32_t REG_RDTR     = 0x02820;
70const uint32_t REG_RXDCTL   = 0x02828;
71const uint32_t REG_RADV     = 0x0282C;
72const uint32_t REG_TCTL     = 0x00400;
73const uint32_t REG_TDBAL    = 0x03800;
74const uint32_t REG_TDBAH    = 0x03804;
75const uint32_t REG_TDLEN    = 0x03808;
76const uint32_t REG_TDH      = 0x03810;
77const uint32_t REG_TDT      = 0x03818;
78const uint32_t REG_TIDV     = 0x03820;
79const uint32_t REG_TXDCTL   = 0x03828;
80const uint32_t REG_TADV     = 0x0382C;
81const uint32_t REG_CRCERRS  = 0x04000;
82const uint32_t REG_RXCSUM   = 0x05000;
83const uint32_t REG_MTA      = 0x05200;
84const uint32_t REG_RAL      = 0x05400;
85const uint32_t REG_RAH      = 0x05404;
86const uint32_t REG_VFTA     = 0x05600;
87
88const uint32_t REG_WUC      = 0x05800;
89const uint32_t REG_MANC     = 0x05820;
90
91const uint8_t EEPROM_READ_OPCODE_SPI    = 0x03;
92const uint8_t EEPROM_RDSR_OPCODE_SPI    = 0x05;
93const uint8_t EEPROM_SIZE               = 64;
94const uint16_t EEPROM_CSUM              = 0xBABA;
95
96const uint8_t VLAN_FILTER_TABLE_SIZE    = 128;
97const uint8_t RCV_ADDRESS_TABLE_SIZE    = 16;
98const uint8_t MULTICAST_TABLE_SIZE      = 128;
99const uint32_t STATS_REGS_SIZE           = 0x124;
100
101
102// Registers in that are accessed in the PHY
103const uint8_t PHY_PSTATUS       = 0x1;
104const uint8_t PHY_PID           = 0x2;
105const uint8_t PHY_EPID          = 0x3;
106const uint8_t PHY_GSTATUS       = 10;
107const uint8_t PHY_EPSTATUS      = 15;
108const uint8_t PHY_AGC           = 18;
109
110// Receive Descriptor Status Flags
111const uint8_t RXDS_PIF         = 0x80;
112const uint8_t RXDS_IPCS        = 0x40;
113const uint8_t RXDS_TCPCS       = 0x20;
114const uint8_t RXDS_UDPCS       = 0x10;
115const uint8_t RXDS_VP          = 0x08;
116const uint8_t RXDS_IXSM        = 0x04;
117const uint8_t RXDS_EOP         = 0x02;
118const uint8_t RXDS_DD          = 0x01;
119
120// Receive Descriptor Error Flags
121const uint8_t RXDE_RXE         = 0x80;
122const uint8_t RXDE_IPE         = 0x40;
123const uint8_t RXDE_TCPE        = 0x20;
124const uint8_t RXDE_SEQ         = 0x04;
125const uint8_t RXDE_SE          = 0x02;
126const uint8_t RXDE_CE          = 0x01;
127
128// Interrupt types
129enum IntTypes
130{
131    IT_NONE    = 0x00000, //dummy value
132    IT_TXDW    = 0x00001,
133    IT_TXQE    = 0x00002,
134    IT_LSC     = 0x00004,
135    IT_RXSEQ   = 0x00008,
136    IT_RXDMT   = 0x00010,
137    IT_RXO     = 0x00040,
138    IT_RXT     = 0x00080,
139    IT_MADC    = 0x00200,
140    IT_RXCFG   = 0x00400,
141    IT_GPI0    = 0x02000,
142    IT_GPI1    = 0x04000,
143    IT_TXDLOW  = 0x08000,
144    IT_SRPD    = 0x10000,
145    IT_ACK     = 0x20000
146};
147
148// Receive Descriptor struct
149struct RxDesc {
150    Addr buf;
151    uint16_t len;
152    uint16_t csum;
153    uint8_t status;
154    uint8_t errors;
155    uint16_t vlan;
156};
157
158struct TxDesc {
159    uint64_t d1;
160    uint64_t d2;
161};
162
163namespace TxdOp {
164const uint8_t TXD_CNXT = 0x0;
165const uint8_t TXD_DATA = 0x1;
166
167bool isLegacy(TxDesc *d) { return !bits(d->d2,29,29); }
168uint8_t getType(TxDesc *d) { return bits(d->d2, 23,20); }
169bool isContext(TxDesc *d) { return !isLegacy(d) && getType(d) == TXD_CNXT; }
170bool isData(TxDesc *d) { return !isLegacy(d) && getType(d) == TXD_DATA; }
171
172Addr getBuf(TxDesc *d) { assert(isLegacy(d) || isData(d)); return d->d1; }
173Addr getLen(TxDesc *d) { if (isLegacy(d)) return bits(d->d2,15,0); else return bits(d->d2, 19,0); }
174void setDd(TxDesc *d)
175{
176    replaceBits(d->d2, 35, 32, ULL(1));
177}
178
179bool ide(TxDesc *d)  { return bits(d->d2, 31,31); }
180bool vle(TxDesc *d)  { assert(isLegacy(d) || isData(d)); return bits(d->d2, 30,30); }
181bool rs(TxDesc *d)   { return bits(d->d2, 27,27); }
182bool ic(TxDesc *d)   { assert(isLegacy(d) || isData(d)); return isLegacy(d) && bits(d->d2, 26,26); }
183bool tse(TxDesc *d)  { return (isData(d) || isContext(d)) && bits(d->d2, 26,26); }
184bool ifcs(TxDesc *d) { assert(isLegacy(d) || isData(d)); return bits(d->d2, 25,25); }
185bool eop(TxDesc *d)  { assert(isLegacy(d) || isData(d)); return bits(d->d2, 24,24); }
186bool ip(TxDesc *d)   { assert(isContext(d)); return bits(d->d2, 25,25); }
187bool tcp(TxDesc *d)  { assert(isContext(d)); return bits(d->d2, 24,24); }
188
189uint8_t getCso(TxDesc *d) { assert(isLegacy(d)); return bits(d->d2, 23,16); }
190uint8_t getCss(TxDesc *d) { assert(isLegacy(d)); return bits(d->d2, 47,40); }
191
192bool ixsm(TxDesc *d)  { return isData(d) && bits(d->d2, 40,40); }
193bool txsm(TxDesc *d)  { return isData(d) && bits(d->d2, 41,41); }
194
195int tucse(TxDesc *d) { assert(isContext(d)); return bits(d->d1,63,48); }
196int tucso(TxDesc *d) { assert(isContext(d)); return bits(d->d1,47,40); }
197int tucss(TxDesc *d) { assert(isContext(d)); return bits(d->d1,39,32); }
198int ipcse(TxDesc *d) { assert(isContext(d)); return bits(d->d1,31,16); }
199int ipcso(TxDesc *d) { assert(isContext(d)); return bits(d->d1,15,8); }
200int ipcss(TxDesc *d) { assert(isContext(d)); return bits(d->d1,7,0); }
201int mss(TxDesc *d) { assert(isContext(d)); return bits(d->d2,63,48); }
202int hdrlen(TxDesc *d) { assert(isContext(d)); return bits(d->d2,47,40); }
203} // namespace TxdOp
204
205
206#define ADD_FIELD32(NAME, OFFSET, BITS) \
207    inline uint32_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
208    inline void NAME(uint32_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
209
210#define ADD_FIELD64(NAME, OFFSET, BITS) \
211    inline uint64_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
212    inline void NAME(uint64_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
213
214struct Regs {
215    template<class T>
216    struct Reg {
217        T _data;
218        T operator()() { return _data; }
219        const Reg<T> &operator=(T d) { _data = d; return *this;}
220        bool operator==(T d) { return d == _data; }
221        void operator()(T d) { _data = d; }
222        Reg() { _data = 0; }
223    };
224
225    struct CTRL : public Reg<uint32_t> { // 0x0000 CTRL Register
226        using Reg<uint32_t>::operator=;
227        ADD_FIELD32(fd,0,1);       // full duplex
228        ADD_FIELD32(bem,1,1);      // big endian mode
229        ADD_FIELD32(pcipr,2,1);    // PCI priority
230        ADD_FIELD32(lrst,3,1);     // link reset
231        ADD_FIELD32(tme,4,1);      // test mode enable
232        ADD_FIELD32(asde,5,1);     // Auto-speed detection
233        ADD_FIELD32(slu,6,1);      // Set link up
234        ADD_FIELD32(ilos,7,1);     // invert los-of-signal
235        ADD_FIELD32(speed,8,2);    // speed selection bits
236        ADD_FIELD32(be32,10,1);    // big endian mode 32
237        ADD_FIELD32(frcspd,11,1);  // force speed
238        ADD_FIELD32(frcdpx,12,1);  // force duplex
239        ADD_FIELD32(duden,13,1);   // dock/undock enable
240        ADD_FIELD32(dudpol,14,1);  // dock/undock polarity
241        ADD_FIELD32(fphyrst,15,1); // force phy reset
242        ADD_FIELD32(extlen,16,1);  // external link status enable
243        ADD_FIELD32(rsvd,17,1);    // reserved
244        ADD_FIELD32(sdp0d,18,1);   // software controlled pin data
245        ADD_FIELD32(sdp1d,19,1);   // software controlled pin data
246        ADD_FIELD32(sdp2d,20,1);   // software controlled pin data
247        ADD_FIELD32(sdp3d,21,1);   // software controlled pin data
248        ADD_FIELD32(sdp0i,22,1);   // software controlled pin dir
249        ADD_FIELD32(sdp1i,23,1);   // software controlled pin dir
250        ADD_FIELD32(sdp2i,24,1);   // software controlled pin dir
251        ADD_FIELD32(sdp3i,25,1);   // software controlled pin dir
252        ADD_FIELD32(rst,26,1);     // reset
253        ADD_FIELD32(rfce,27,1);    // receive flow control enable
254        ADD_FIELD32(tfce,28,1);    // transmit flow control enable
255        ADD_FIELD32(rte,29,1);     // routing tag enable
256        ADD_FIELD32(vme,30,1);     // vlan enable
257        ADD_FIELD32(phyrst,31,1);  // phy reset
258    };
259    CTRL ctrl;
260
261    struct STATUS : public Reg<uint32_t> { // 0x0008 STATUS Register
262        using Reg<uint32_t>::operator=;
263        ADD_FIELD32(fd,0,1);       // full duplex
264        ADD_FIELD32(lu,1,1);       // link up
265        ADD_FIELD32(func,2,2);     // function id
266        ADD_FIELD32(txoff,4,1);    // transmission paused
267        ADD_FIELD32(tbimode,5,1);  // tbi mode
268        ADD_FIELD32(speed,6,2);    // link speed
269        ADD_FIELD32(asdv,8,2);     // auto speed detection value
270        ADD_FIELD32(mtxckok,10,1); // mtx clock running ok
271        ADD_FIELD32(pci66,11,1);   // In 66Mhz pci slot
272        ADD_FIELD32(bus64,12,1);   // in 64 bit slot
273        ADD_FIELD32(pcix,13,1);    // Pci mode
274        ADD_FIELD32(pcixspd,14,2); // pci x speed
275    };
276    STATUS sts;
277
278    struct EECD : public Reg<uint32_t> { // 0x0010 EECD Register
279        using Reg<uint32_t>::operator=;
280        ADD_FIELD32(sk,0,1);       // clack input to the eeprom
281        ADD_FIELD32(cs,1,1);       // chip select to eeprom
282        ADD_FIELD32(din,2,1);      // data input to eeprom
283        ADD_FIELD32(dout,3,1);     // data output bit
284        ADD_FIELD32(fwe,4,2);      // flash write enable
285        ADD_FIELD32(ee_req,6,1);   // request eeprom access
286        ADD_FIELD32(ee_gnt,7,1);   // grant eeprom access
287        ADD_FIELD32(ee_pres,8,1);  // eeprom present
288        ADD_FIELD32(ee_size,9,1);  // eeprom size
289        ADD_FIELD32(ee_sz1,10,1);  // eeprom size
290        ADD_FIELD32(rsvd,11,2);    // reserved
291        ADD_FIELD32(ee_type,13,1); // type of eeprom
292    } ;
293    EECD eecd;
294
295    struct EERD : public Reg<uint32_t> { // 0x0014 EERD Register
296        using Reg<uint32_t>::operator=;
297        ADD_FIELD32(start,0,1);  // start read
298        ADD_FIELD32(done,4,1);   // done read
299        ADD_FIELD32(addr,8,8);   // address
300        ADD_FIELD32(data,16,16); // data
301    };
302    EERD eerd;
303
304    struct CTRL_EXT : public Reg<uint32_t> { // 0x0018 CTRL_EXT Register
305        using Reg<uint32_t>::operator=;
306        ADD_FIELD32(gpi_en,0,4);      // enable interrupts from gpio
307        ADD_FIELD32(phyint,5,1);      // reads the phy internal int status
308        ADD_FIELD32(sdp2_data,6,1);   // data from gpio sdp
309        ADD_FIELD32(spd3_data,7,1);   // data frmo gpio sdp
310        ADD_FIELD32(spd2_iodir,10,1); // direction of sdp2
311        ADD_FIELD32(spd3_iodir,11,1); // direction of sdp2
312        ADD_FIELD32(asdchk,12,1);     // initiate auto-speed-detection
313        ADD_FIELD32(eerst,13,1);      // reset the eeprom
314        ADD_FIELD32(spd_byps,15,1);   // bypass speed select
315        ADD_FIELD32(ro_dis,17,1);     // disable relaxed memory ordering
316        ADD_FIELD32(vreg,21,1);       // power down the voltage regulator
317        ADD_FIELD32(link_mode,22,2);  // interface to talk to the link
318        ADD_FIELD32(iame, 27,1);      // interrupt acknowledge auto-mask ??
319        ADD_FIELD32(drv_loaded, 28,1);// driver is loaded and incharge of device
320        ADD_FIELD32(timer_clr, 29,1); // clear interrupt timers after IMS clear ??
321    };
322    CTRL_EXT ctrl_ext;
323
324    struct MDIC : public Reg<uint32_t> { // 0x0020 MDIC Register
325        using Reg<uint32_t>::operator=;
326        ADD_FIELD32(data,0,16);   // data
327        ADD_FIELD32(regadd,16,5); // register address
328        ADD_FIELD32(phyadd,21,5); // phy addresses
329        ADD_FIELD32(op,26,2);     // opcode
330        ADD_FIELD32(r,28,1);      // ready
331        ADD_FIELD32(i,29,1);      // interrupt
332        ADD_FIELD32(e,30,1);      // error
333    };
334    MDIC mdic;
335
336    struct ICR : public Reg<uint32_t> { // 0x00C0 ICR Register
337        using Reg<uint32_t>::operator=;
338        ADD_FIELD32(txdw,0,1)   // tx descr witten back
339        ADD_FIELD32(txqe,1,1)   // tx queue empty
340        ADD_FIELD32(lsc,2,1)    // link status change
341        ADD_FIELD32(rxseq,3,1)  // rcv sequence error
342        ADD_FIELD32(rxdmt0,4,1) // rcv descriptor min thresh
343        ADD_FIELD32(rsvd1,5,1)  // reserved
344        ADD_FIELD32(rxo,6,1)    // receive overrunn
345        ADD_FIELD32(rxt0,7,1)   // receiver timer interrupt
346        ADD_FIELD32(mdac,9,1)   // mdi/o access complete
347        ADD_FIELD32(rxcfg,10,1)  // recv /c/ ordered sets
348        ADD_FIELD32(phyint,12,1) // phy interrupt
349        ADD_FIELD32(gpi1,13,1)   // gpi int 1
350        ADD_FIELD32(gpi2,14,1)   // gpi int 2
351        ADD_FIELD32(txdlow,15,1) // transmit desc low thresh
352        ADD_FIELD32(srpd,16,1)   // small receive packet detected
353        ADD_FIELD32(ack,17,1);    // receive ack frame
354        ADD_FIELD32(int_assert, 31,1); // interrupt caused a system interrupt
355    };
356    ICR icr;
357
358    uint32_t imr; // register that contains the current interrupt mask
359
360    struct ITR : public Reg<uint32_t> { // 0x00C4 ITR Register
361        using Reg<uint32_t>::operator=;
362        ADD_FIELD32(interval, 0,16); // minimum inter-interrutp inteval
363                                     // specified in 256ns interrupts
364    };
365    ITR itr;
366
367    // When CTRL_EXT.IAME and the ICR.INT_ASSERT is 1 an ICR read or write
368    // causes the IAM register contents to be written into the IMC
369    // automatically clearing all interrupts that have a bit in the IAM set
370    uint32_t iam;
371
372    struct RCTL : public Reg<uint32_t> { // 0x0100 RCTL Register
373        using Reg<uint32_t>::operator=;
374        ADD_FIELD32(rst,0,1);   // Reset
375        ADD_FIELD32(en,1,1);    // Enable
376        ADD_FIELD32(sbp,2,1);   // Store bad packets
377        ADD_FIELD32(upe,3,1);   // Unicast Promiscuous enabled
378        ADD_FIELD32(mpe,4,1);   // Multicast promiscuous enabled
379        ADD_FIELD32(lpe,5,1);   // long packet reception enabled
380        ADD_FIELD32(lbm,6,2);   //
381        ADD_FIELD32(rdmts,8,2); //
382        ADD_FIELD32(mo,12,2);    //
383        ADD_FIELD32(mdr,14,1);   //
384        ADD_FIELD32(bam,15,1);   //
385        ADD_FIELD32(bsize,16,2); //
386        ADD_FIELD32(vfe,18,1);   //
387        ADD_FIELD32(cfien,19,1); //
388        ADD_FIELD32(cfi,20,1);   //
389        ADD_FIELD32(dpf,22,1);   // discard pause frames
390        ADD_FIELD32(pmcf,23,1);  // pass mac control  frames
391        ADD_FIELD32(bsex,25,1);  // buffer size extension
392        ADD_FIELD32(secrc,26,1); // strip ethernet crc from incoming packet
393        int descSize()
394        {
395            switch(bsize()) {
396                case 0: return bsex() == 0 ? 2048 : -1;
397                case 1: return bsex() == 0 ? 1024 : 16384;
398                case 2: return bsex() == 0 ? 512 : 8192;
399                case 3: return bsex() == 0 ? 256 : 4096;
400                default:
401                        return -1;
402            }
403        }
404    };
405    RCTL rctl;
406
407    struct FCTTV : public Reg<uint32_t> { // 0x0170 FCTTV
408        using Reg<uint32_t>::operator=;
409        ADD_FIELD32(ttv,0,16);    // Transmit Timer Value
410    };
411    FCTTV fcttv;
412
413    struct TCTL : public Reg<uint32_t> { // 0x0400 TCTL Register
414        using Reg<uint32_t>::operator=;
415        ADD_FIELD32(rst,0,1);    // Reset
416        ADD_FIELD32(en,1,1);     // Enable
417        ADD_FIELD32(bce,2,1);    // busy check enable
418        ADD_FIELD32(psp,3,1);    // pad short packets
419        ADD_FIELD32(ct,4,8);     // collision threshold
420        ADD_FIELD32(cold,12,10); // collision distance
421        ADD_FIELD32(swxoff,22,1); // software xoff transmission
422        ADD_FIELD32(pbe,23,1);    // packet burst enable
423        ADD_FIELD32(rtlc,24,1);   // retransmit late collisions
424        ADD_FIELD32(nrtu,25,1);   // on underrun no TX
425        ADD_FIELD32(mulr,26,1);   // multiple request
426    };
427    TCTL tctl;
428
429    struct PBA : public Reg<uint32_t> { // 0x1000 PBA Register
430        using Reg<uint32_t>::operator=;
431        ADD_FIELD32(rxa,0,16);
432        ADD_FIELD32(txa,16,16);
433    };
434    PBA pba;
435
436    struct FCRTL : public Reg<uint32_t> { // 0x2160 FCRTL Register
437        using Reg<uint32_t>::operator=;
438        ADD_FIELD32(rtl,3,28); // make this bigger than the spec so we can have
439                               // a larger buffer
440        ADD_FIELD32(xone, 31,1);
441    };
442    FCRTL fcrtl;
443
444    struct FCRTH : public Reg<uint32_t> { // 0x2168 FCRTL Register
445        using Reg<uint32_t>::operator=;
446        ADD_FIELD32(rth,3,13); // make this bigger than the spec so we can have
447                               //a larger buffer
448        ADD_FIELD32(xfce, 31,1);
449    };
450    FCRTH fcrth;
451
452    struct RDBA : public Reg<uint64_t> { // 0x2800 RDBA Register
453        using Reg<uint64_t>::operator=;
454        ADD_FIELD64(rdbal,0,32); // base address of rx descriptor ring
455        ADD_FIELD64(rdbah,32,32); // base address of rx descriptor ring
456    };
457    RDBA rdba;
458
459    struct RDLEN : public Reg<uint32_t> { // 0x2808 RDLEN Register
460        using Reg<uint32_t>::operator=;
461        ADD_FIELD32(len,7,13); // number of bytes in the descriptor buffer
462    };
463    RDLEN rdlen;
464
465    struct RDH : public Reg<uint32_t> { // 0x2810 RDH Register
466        using Reg<uint32_t>::operator=;
467        ADD_FIELD32(rdh,0,16); // head of the descriptor ring
468    };
469    RDH rdh;
470
471    struct RDT : public Reg<uint32_t> { // 0x2818 RDT Register
472        using Reg<uint32_t>::operator=;
473        ADD_FIELD32(rdt,0,16); // tail of the descriptor ring
474    };
475    RDT rdt;
476
477    struct RDTR : public Reg<uint32_t> { // 0x2820 RDTR Register
478        using Reg<uint32_t>::operator=;
479        ADD_FIELD32(delay,0,16); // receive delay timer
480        ADD_FIELD32(fpd, 31,1);   // flush partial descriptor block ??
481    };
482    RDTR rdtr;
483
484    struct RXDCTL : public Reg<uint32_t> { // 0x2828 RXDCTL Register
485        using Reg<uint32_t>::operator=;
486        ADD_FIELD32(pthresh,0,6);   // prefetch threshold, less that this
487                                    // consider prefetch
488        ADD_FIELD32(hthresh,8,6);   // number of descriptors in host mem to
489                                    // consider prefetch
490        ADD_FIELD32(wthresh,16,6);  // writeback threshold
491        ADD_FIELD32(gran,24,1);     // granularity 0 = desc, 1 = cacheline
492    };
493    RXDCTL rxdctl;
494
495    struct RADV : public Reg<uint32_t> { // 0x282C RADV Register
496        using Reg<uint32_t>::operator=;
497        ADD_FIELD32(idv,0,16); // absolute interrupt delay
498    };
499    RADV radv;
500
501    struct RSRPD : public Reg<uint32_t> { // 0x2C00 RSRPD Register
502        using Reg<uint32_t>::operator=;
503        ADD_FIELD32(idv,0,12); // size to interrutp on small packets
504    };
505    RSRPD rsrpd;
506
507    struct TDBA : public Reg<uint64_t> { // 0x3800 TDBAL Register
508        using Reg<uint64_t>::operator=;
509        ADD_FIELD64(tdbal,0,32); // base address of transmit descriptor ring
510        ADD_FIELD64(tdbah,32,32); // base address of transmit descriptor ring
511    };
512    TDBA tdba;
513
514    struct TDLEN : public Reg<uint32_t> { // 0x3808 TDLEN Register
515        using Reg<uint32_t>::operator=;
516        ADD_FIELD32(len,7,13); // number of bytes in the descriptor buffer
517    };
518    TDLEN tdlen;
519
520    struct TDH : public Reg<uint32_t> { // 0x3810 TDH Register
521        using Reg<uint32_t>::operator=;
522        ADD_FIELD32(tdh,0,16); // head of the descriptor ring
523    };
524    TDH tdh;
525
526    struct TDT : public Reg<uint32_t> { // 0x3818 TDT Register
527        using Reg<uint32_t>::operator=;
528        ADD_FIELD32(tdt,0,16); // tail of the descriptor ring
529    };
530    TDT tdt;
531
532    struct TIDV : public Reg<uint32_t> { // 0x3820 TIDV Register
533        using Reg<uint32_t>::operator=;
534        ADD_FIELD32(idv,0,16); // interrupt delay
535    };
536    TIDV tidv;
537
538    struct TXDCTL : public Reg<uint32_t> { // 0x3828 TXDCTL Register
539        using Reg<uint32_t>::operator=;
540        ADD_FIELD32(pthresh, 0,6);  // if number of descriptors control has is
541                                    // below this number, a prefetch is considered
542        ADD_FIELD32(hthresh,8,8);   // number of valid descriptors is host memory
543                                    // before a prefetch is considered
544        ADD_FIELD32(wthresh,16,6);  // number of descriptors to keep until
545                                    // writeback is considered
546        ADD_FIELD32(gran, 24,1);    // granulatiry of above values (0 = cacheline,
547                                    // 1 == desscriptor)
548        ADD_FIELD32(lwthresh,25,7); // xmit descriptor low thresh, interrupt
549                                    // below this level
550    };
551    TXDCTL txdctl;
552
553    struct TADV : public Reg<uint32_t> { // 0x382C TADV Register
554        using Reg<uint32_t>::operator=;
555        ADD_FIELD32(idv,0,16); // absolute interrupt delay
556    };
557    TADV tadv;
558
559    struct RXCSUM : public Reg<uint32_t> { // 0x5000 RXCSUM Register
560        using Reg<uint32_t>::operator=;
561        ADD_FIELD32(pcss,0,8);
562        ADD_FIELD32(ipofld,8,1);
563        ADD_FIELD32(tuofld,9,1);
564    };
565    RXCSUM rxcsum;
566
567    struct MANC : public Reg<uint32_t> { // 0x5820 MANC Register
568        using Reg<uint32_t>::operator=;
569        ADD_FIELD32(smbus,0,1);    // SMBus enabled #####
570        ADD_FIELD32(asf,1,1);      // ASF enabled #####
571        ADD_FIELD32(ronforce,2,1); // reset of force
572        ADD_FIELD32(rsvd,3,5);     // reserved
573        ADD_FIELD32(rmcp1,8,1);    // rcmp1 filtering
574        ADD_FIELD32(rmcp2,9,1);    // rcmp2 filtering
575        ADD_FIELD32(ipv4,10,1);     // enable ipv4
576        ADD_FIELD32(ipv6,11,1);     // enable ipv6
577        ADD_FIELD32(snap,12,1);     // accept snap
578        ADD_FIELD32(arp,13,1);      // filter arp #####
579        ADD_FIELD32(neighbor,14,1); // neighbor discovery
580        ADD_FIELD32(arp_resp,15,1); // arp response
581        ADD_FIELD32(tcorst,16,1);   // tco reset happened
582        ADD_FIELD32(rcvtco,17,1);   // receive tco enabled ######
583        ADD_FIELD32(blkphyrst,18,1);// block phy resets ########
584        ADD_FIELD32(rcvall,19,1);   // receive all
585        ADD_FIELD32(macaddrfltr,20,1); // mac address filtering ######
586        ADD_FIELD32(mng2host,21,1); // mng2 host packets #######
587        ADD_FIELD32(ipaddrfltr,22,1); // ip address filtering
588        ADD_FIELD32(xsumfilter,23,1); // checksum filtering
589        ADD_FIELD32(brfilter,24,1); // broadcast filtering
590        ADD_FIELD32(smbreq,25,1);   // smb request
591        ADD_FIELD32(smbgnt,26,1);   // smb grant
592        ADD_FIELD32(smbclkin,27,1); // smbclkin
593        ADD_FIELD32(smbdatain,28,1); // smbdatain
594        ADD_FIELD32(smbdataout,29,1); // smb data out
595        ADD_FIELD32(smbclkout,30,1); // smb clock out
596    };
597    MANC manc;
598};
599
600}; // iGbReg namespace
601