ZealOS/docs/Home/Net/Drivers/E1000.CC.html
TomAwezome 1b75d91002 Fix Mount AHCI Port selection.
Add arg to SATARep to specify drive types to show.
Add checks in AHCIPortInit to verify port signatures, add helper method to get signatures from port.
2021-08-02 16:40:05 -04:00

670 lines
63 KiB
HTML
Executable file

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<meta name="generator" content="ZealOS V0.13">
<style type="text/css">
body {background-color:#fef1f0;}
.cF0{color:#000000;background-color:#fef1f0;}
.cF1{color:#0148a4;background-color:#fef1f0;}
.cF2{color:#3b7901;background-color:#fef1f0;}
.cF3{color:#057c7e;background-color:#fef1f0;}
.cF4{color:#bb2020;background-color:#fef1f0;}
.cF5{color:#9e42ae;background-color:#fef1f0;}
.cF6{color:#b57901;background-color:#fef1f0;}
.cF7{color:#b2b6af;background-color:#fef1f0;}
.cF8{color:#555753;background-color:#fef1f0;}
.cF9{color:#678fbb;background-color:#fef1f0;}
.cFA{color:#82bc49;background-color:#fef1f0;}
.cFB{color:#0097a2;background-color:#fef1f0;}
.cFC{color:#e26a6a;background-color:#fef1f0;}
.cFD{color:#c671bc;background-color:#fef1f0;}
.cFE{color:#c7ab00;background-color:#fef1f0;}
.cFF{color:#fef1f0;background-color:#fef1f0;}
</style>
</head>
<body>
<pre style="font-family:monospace;font-size:12pt">
<a name="l1"></a><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Intel(R) E1000 Driver</span><span class=cF0>
<a name="l2"></a> </span><span class=cF2>Author: TomAwezome</span><span class=cF0>
<a name="l3"></a>
<a name="l4"></a> </span><span class=cF2>Driver is based on:</span><span class=cF0>
<a name="l5"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>01000101's example i825xx driver</span><span class=cF0>
<a name="l6"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>OSDev Intel(R) 8254x documentation</span><span class=cF0>
<a name="l7"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>Intel(R) PCI/PCI-X Family of Gigabit Ethernet Controllers Software Developer's Manual</span><span class=cF0>
<a name="l8"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>Linux E1000 driver</span><span class=cF0>
<a name="l9"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>any other useful sources.</span><span class=cF0>
<a name="l10"></a>
<a name="l11"></a> </span><span class=cF2>Guidelines:</span><span class=cF0>
<a name="l12"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>Magic numbers are bad. #defines are good.</span><span class=cF0>
<a name="l13"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>Understandability over LOC.</span><span class=cF0>
<a name="l14"></a> </span><span class=cF2>-</span><span class=cF0> </span><span class=cF2>Clear documentation.</span><span class=cF0>
<a name="l15"></a></span><span class=cF2>*/</span><span class=cF0>
<a name="l16"></a>
<a name="l17"></a></span><span class=cF2>// TODO: clean up entire driver</span><span class=cF0>
<a name="l18"></a>
<a name="l19"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_CTRL </span><span class=cFE>0x0000</span><span class=cF0>
<a name="l20"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_EERD </span><span class=cFE>0x0014</span><span class=cF0> </span><span class=cF2>// EEPROM Read</span><span class=cF0>
<a name="l21"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_ICR </span><span class=cFE>0x00C0</span><span class=cF0> </span><span class=cF2>// Interrupt Cause Read</span><span class=cF0>
<a name="l22"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_IMS </span><span class=cFE>0x00D0</span><span class=cF0>
<a name="l23"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_RCTL </span><span class=cFE>0x0100</span><span class=cF0>
<a name="l24"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_TCTL </span><span class=cFE>0x0400</span><span class=cF0>
<a name="l25"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_RDBAL </span><span class=cFE>0x2800</span><span class=cF0>
<a name="l26"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_RDBAH </span><span class=cFE>0x2804</span><span class=cF0>
<a name="l27"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_RDLEN </span><span class=cFE>0x2808</span><span class=cF0>
<a name="l28"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_RDH </span><span class=cFE>0x2810</span><span class=cF0>
<a name="l29"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_RDT </span><span class=cFE>0x2818</span><span class=cF0>
<a name="l30"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_TDBAL </span><span class=cFE>0x3800</span><span class=cF0>
<a name="l31"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_TDBAH </span><span class=cFE>0x3804</span><span class=cF0>
<a name="l32"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_TDLEN </span><span class=cFE>0x3808</span><span class=cF0>
<a name="l33"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_TDH </span><span class=cFE>0x3810</span><span class=cF0>
<a name="l34"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_TDT </span><span class=cFE>0x3818</span><span class=cF0>
<a name="l35"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_REG_MTA </span><span class=cFE>0x5200</span><span class=cF0> </span><span class=cF2>// Multicast Table Array</span><span class=cF0>
<a name="l36"></a>
<a name="l37"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_CTRLf_SLU </span><span class=cFE>6</span><span class=cF0> </span><span class=cF2>// Set Link Up ?</span><span class=cF0>
<a name="l38"></a>
<a name="l39"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_CTRLF_SLU (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_CTRLf_SLU) </span><span class=cF2>// Set Link Up ?</span><span class=cF0>
<a name="l40"></a>
<a name="l41"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_EN </span><span class=cFE>1</span><span class=cF0>
<a name="l42"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_SBP </span><span class=cFE>2</span><span class=cF0>
<a name="l43"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_UPE </span><span class=cFE>3</span><span class=cF0>
<a name="l44"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_MPE </span><span class=cFE>4</span><span class=cF0>
<a name="l45"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_LPE </span><span class=cFE>5</span><span class=cF0>
<a name="l46"></a></span><span class=cF2>//#define E1000_RCTLf_RDMTS_HALF</span><span class=cF0>
<a name="l47"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_RDMTS_QUARTER </span><span class=cFE>8</span><span class=cF0>
<a name="l48"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_RDMTS_EIGHTH </span><span class=cFE>9</span><span class=cF0>
<a name="l49"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_BAM </span><span class=cFE>15</span><span class=cF0>
<a name="l50"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_BSIZE_1024 </span><span class=cFE>16</span><span class=cF0>
<a name="l51"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_BSIZE_512 </span><span class=cFE>17</span><span class=cF0>
<a name="l52"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_BSIZE_256 </span><span class=cFE>18</span><span class=cF0>
<a name="l53"></a></span><span class=cF2>//#define E1000_RCTLf_BSIZE_2048</span><span class=cF0>
<a name="l54"></a></span><span class=cF2>//#define E1000_RCTLf_BSIZE_4096</span><span class=cF0>
<a name="l55"></a></span><span class=cF2>//#define E1000_RCTLf_BSIZE_8192</span><span class=cF0>
<a name="l56"></a></span><span class=cF2>//#define E1000_RCTLf_BSIZE_16384</span><span class=cF0>
<a name="l57"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLf_SECRC </span><span class=cFE>26</span><span class=cF0>
<a name="l58"></a>
<a name="l59"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_EN (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_EN)
<a name="l60"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_SBP (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_SBP)
<a name="l61"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_UPE (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_UPE)
<a name="l62"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_MPE (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_MPE)
<a name="l63"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_LPE (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_LPE)
<a name="l64"></a></span><span class=cF2>//#define E1000_RCTLF_RDMTS_HALF</span><span class=cF0>
<a name="l65"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_RDMTS_QUARTER (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_RDMTS_QUARTER)
<a name="l66"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_RDMTS_EIGHTH (</span><span class=cFE>2</span><span class=cF0> &lt;&lt; E1000_RCTLf_RDMTS_QUARTER)
<a name="l67"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_BAM (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_BAM)
<a name="l68"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_BSIZE_1024 (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_BSIZE_1024)
<a name="l69"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_BSIZE_512 (</span><span class=cFE>2</span><span class=cF0> &lt;&lt; E1000_RCTLf_BSIZE_1024)
<a name="l70"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_BSIZE_256 (</span><span class=cFE>3</span><span class=cF0> &lt;&lt; E1000_RCTLf_BSIZE_1024)
<a name="l71"></a></span><span class=cF2>//#define E1000_RCTLF_BSIZE_2048</span><span class=cF0>
<a name="l72"></a></span><span class=cF2>//#define E1000_RCTLF_BSIZE_4096</span><span class=cF0>
<a name="l73"></a></span><span class=cF2>//#define E1000_RCTLF_BSIZE_8192</span><span class=cF0>
<a name="l74"></a></span><span class=cF2>//#define E1000_RCTLF_BSIZE_16384</span><span class=cF0>
<a name="l75"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RCTLF_SECRC (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RCTLf_SECRC)
<a name="l76"></a>
<a name="l77"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TCTLf_EN </span><span class=cFE>1</span><span class=cF0>
<a name="l78"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TCTLf_PSP </span><span class=cFE>3</span><span class=cF0>
<a name="l79"></a>
<a name="l80"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TCTLF_EN (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TCTLf_EN)
<a name="l81"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TCTLF_PSP (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TCTLf_PSP)
<a name="l82"></a>
<a name="l83"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RDESC_STATUSf_EOP </span><span class=cFE>1</span><span class=cF0> </span><span class=cF2>// End of Packet: Last Descriptor for an incoming packet</span><span class=cF0>
<a name="l84"></a>
<a name="l85"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RDESC_STATUSF_EOP (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_RDESC_STATUSf_EOP)
<a name="l86"></a>
<a name="l87"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_EERDf_DONE </span><span class=cFE>4</span><span class=cF0>
<a name="l88"></a>
<a name="l89"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_EERDF_DONE (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_EERDf_DONE)
<a name="l90"></a>
<a name="l91"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_CMDf_EOP </span><span class=cFE>0</span><span class=cF0> </span><span class=cF2>// End of Packet: Last Descriptor making up the packet</span><span class=cF0>
<a name="l92"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_CMDf_IFCS </span><span class=cFE>1</span><span class=cF0> </span><span class=cF2>// Insert FCS/CRC field in Ethernet packets</span><span class=cF0>
<a name="l93"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_CMDf_RS </span><span class=cFE>3</span><span class=cF0> </span><span class=cF2>// Report Status: Ethernet controller needs to report status info</span><span class=cF0>
<a name="l94"></a>
<a name="l95"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_CMDF_EOP (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TDESC_CMDf_EOP)
<a name="l96"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_CMDF_IFCS (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TDESC_CMDf_IFCS)
<a name="l97"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_CMDF_RS (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TDESC_CMDf_RS)
<a name="l98"></a>
<a name="l99"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSf_DD </span><span class=cFE>0</span><span class=cF0> </span><span class=cF2>// Descriptor Done: descriptor is finished and written-back</span><span class=cF0>
<a name="l100"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSf_EC </span><span class=cFE>1</span><span class=cF0> </span><span class=cF2>// Excess Collisions: packet hit too many collisions; not transmitted.</span><span class=cF0>
<a name="l101"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSf_LC </span><span class=cFE>2</span><span class=cF0> </span><span class=cF2>// Late Collision: late collision occurred (only for half-duplex mode)</span><span class=cF0>
<a name="l102"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSf_TU </span><span class=cFE>3</span><span class=cF0> </span><span class=cF2>// Transmit Underrun</span><span class=cF0>
<a name="l103"></a>
<a name="l104"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSF_DD (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TDESC_STATUSf_DD)
<a name="l105"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSF_EC (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TDESC_STATUSf_EC)
<a name="l106"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSF_LC (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TDESC_STATUSf_LC)
<a name="l107"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TDESC_STATUSF_TU (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_TDESC_STATUSf_TU)
<a name="l108"></a>
<a name="l109"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRf_TXDW </span><span class=cFE>0</span><span class=cF0> </span><span class=cF2>// Transmit Descriptor Written Back</span><span class=cF0>
<a name="l110"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRf_TXQE </span><span class=cFE>1</span><span class=cF0> </span><span class=cF2>// Transmit Queue Empty</span><span class=cF0>
<a name="l111"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRf_LSC </span><span class=cFE>2</span><span class=cF0> </span><span class=cF2>// Link Status Change</span><span class=cF0>
<a name="l112"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRf_RXDMT </span><span class=cFE>4</span><span class=cF0> </span><span class=cF2>// Receive Descriptor Minimum Threshold Reached</span><span class=cF0>
<a name="l113"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRf_RXO </span><span class=cFE>6</span><span class=cF0> </span><span class=cF2>// Receive Data FIFO Overrun</span><span class=cF0>
<a name="l114"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRf_RXT </span><span class=cFE>7</span><span class=cF0> </span><span class=cF2>// Receive Timer Interrupt</span><span class=cF0>
<a name="l115"></a>
<a name="l116"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRF_TXDW (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_ICRf_TXDW)
<a name="l117"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRF_TXQE (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_ICRf_TXQE)
<a name="l118"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRF_LSC (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_ICRf_LSC)
<a name="l119"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRF_RXDMT (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_ICRf_RXDMT)
<a name="l120"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRF_RXO (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_ICRf_RXO)
<a name="l121"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_ICRF_RXT (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_ICRf_RXT)
<a name="l122"></a>
<a name="l123"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_TXDW </span><span class=cFE>0</span><span class=cF0>
<a name="l124"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_TXQE </span><span class=cFE>1</span><span class=cF0>
<a name="l125"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_LSC </span><span class=cFE>2</span><span class=cF0>
<a name="l126"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_RXSEQ </span><span class=cFE>3</span><span class=cF0>
<a name="l127"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_RXDMT </span><span class=cFE>4</span><span class=cF0>
<a name="l128"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_RXO </span><span class=cFE>6</span><span class=cF0>
<a name="l129"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_RXT </span><span class=cFE>7</span><span class=cF0>
<a name="l130"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_MDAC </span><span class=cFE>9</span><span class=cF0>
<a name="l131"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_RXCFG </span><span class=cFE>10</span><span class=cF0>
<a name="l132"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_PHYINT </span><span class=cFE>12</span><span class=cF0>
<a name="l133"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_GPI </span><span class=cFE>13</span><span class=cF0> </span><span class=cF2>// 13-14</span><span class=cF0>
<a name="l134"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_TXDLOW </span><span class=cFE>15</span><span class=cF0>
<a name="l135"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSf_SRPD </span><span class=cFE>16</span><span class=cF0>
<a name="l136"></a>
<a name="l137"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_TXDW (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_TXDW)
<a name="l138"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_TXQE (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_TXQE)
<a name="l139"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_LSC (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_LSC)
<a name="l140"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_RXSEQ (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_RXSEQ)
<a name="l141"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_RXDMT (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_RXDMT)
<a name="l142"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_RXO (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_RXO)
<a name="l143"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_RXT (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_RXT)
<a name="l144"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_MDAC (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_MDAC)
<a name="l145"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_RXCFG (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_RXCFG)
<a name="l146"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_PHYINT (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_PHYINT)
<a name="l147"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_GPI (</span><span class=cFE>2</span><span class=cF0> &lt;&lt; E1000_IMSf_GPI) </span><span class=cF2>// flag sets both bits</span><span class=cF0>
<a name="l148"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_TXDLOW (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_TXDLOW)
<a name="l149"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_IMSF_SRPD (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; E1000_IMSf_SRPD)
<a name="l150"></a>
<a name="l151"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_RX_BUFF_COUNT </span><span class=cFE>32</span><span class=cF0> </span><span class=cF2>// 01000101's driver uses 768 for each of these...</span><span class=cF0>
<a name="l152"></a>#</span><span class=cF1>define</span><span class=cF0> E1000_TX_BUFF_COUNT </span><span class=cFE>8</span><span class=cF0>
<a name="l153"></a>
<a name="l154"></a></span><span class=cF1>class</span><span class=cF0> CE1000DescriptorEntryRX
<a name="l155"></a>{
<a name="l156"></a> </span><span class=cF9>U64</span><span class=cF0> address;
<a name="l157"></a> </span><span class=cF9>U16</span><span class=cF0> length;
<a name="l158"></a> </span><span class=cF9>U16</span><span class=cF0> checksum;
<a name="l159"></a> </span><span class=cF1>U8</span><span class=cF0> status;
<a name="l160"></a> </span><span class=cF1>U8</span><span class=cF0> errors;
<a name="l161"></a> </span><span class=cF9>U16</span><span class=cF0> special;
<a name="l162"></a>};
<a name="l163"></a>
<a name="l164"></a></span><span class=cF1>class</span><span class=cF0> CE1000DescriptorEntryTX
<a name="l165"></a>{
<a name="l166"></a> </span><span class=cF9>U64</span><span class=cF0> address;
<a name="l167"></a> </span><span class=cF9>U16</span><span class=cF0> length;
<a name="l168"></a> </span><span class=cF1>U8</span><span class=cF0> cso;
<a name="l169"></a> </span><span class=cF1>U8</span><span class=cF0> cmd;
<a name="l170"></a> </span><span class=cF1>U8</span><span class=cF0> sta;
<a name="l171"></a> </span><span class=cF1>U8</span><span class=cF0> css;
<a name="l172"></a> </span><span class=cF9>U16</span><span class=cF0> special;
<a name="l173"></a>};
<a name="l174"></a>
<a name="l175"></a></span><span class=cF1>class</span><span class=cF0> CE1000
<a name="l176"></a>{
<a name="l177"></a> </span><span class=cF9>CPCIDev</span><span class=cF0> *pci;
<a name="l178"></a>
<a name="l179"></a> </span><span class=cF1>U8</span><span class=cF0> mac_address[</span><span class=cFE>6</span><span class=cF0>];
<a name="l180"></a> </span><span class=cF9>U64</span><span class=cF0> mmio_address;
<a name="l181"></a>
<a name="l182"></a> </span><span class=cF9>I64</span><span class=cF0> current_rx_de_index; </span><span class=cF2>// Current Receive DE being processed. Gets incremented, wrapped to 0 at max of E1000_RX_BUFF_COUNT.</span><span class=cF0>
<a name="l183"></a> </span><span class=cF9>I64</span><span class=cF0> current_tx_de_index; </span><span class=cF2>// Current Transmit DE being processed. Gets incremented, wrapped to 0 at max of E1000_TX_BUFF_COUNT.</span><span class=cF0>
<a name="l184"></a>
<a name="l185"></a> </span><span class=cF1>U8</span><span class=cF0> *rx_de_buffer; </span><span class=cF2>// Uncached-alias of pointer to the buffer of RX Descriptor Entries.</span><span class=cF0>
<a name="l186"></a> </span><span class=cF1>U8</span><span class=cF0> *tx_de_buffer; </span><span class=cF2>// Uncached-alias of pointer to the buffer of TX Descriptor Entries.</span><span class=cF0>
<a name="l187"></a> </span><span class=cF1>U8</span><span class=cF0> *rx_de_buffer_phys; </span><span class=cF2>// Pointer to the buffer of RX Descriptor Entries. (Code Heap, lower 2Gb)</span><span class=cF0>
<a name="l188"></a> </span><span class=cF1>U8</span><span class=cF0> *tx_de_buffer_phys; </span><span class=cF2>// Pointer to the buffer of TX Descriptor Entries. (Code Heap, lower 2Gb)</span><span class=cF0>
<a name="l189"></a>
<a name="l190"></a> </span><span class=cF9>U64</span><span class=cF0> rx_buffer_addr; </span><span class=cF2>// Uncached-alias of address of receive buffers.</span><span class=cF0>
<a name="l191"></a> </span><span class=cF9>U64</span><span class=cF0> tx_buffer_addr; </span><span class=cF2>// Uncached-alias of address of transmit buffers.</span><span class=cF0>
<a name="l192"></a> </span><span class=cF9>U64</span><span class=cF0> rx_buffer_addr_phys; </span><span class=cF2>// Physical address of actual receive buffers (&lt; 4 Gb)</span><span class=cF0>
<a name="l193"></a> </span><span class=cF9>U64</span><span class=cF0> tx_buffer_addr_phys; </span><span class=cF2>// Physical address of actual transmit buffers (&lt; 4 Gb)</span><span class=cF0>
<a name="l194"></a>
<a name="l195"></a>
<a name="l196"></a>} e1000; </span><span class=cF2>// e1000 is the global variable we store all of this into.</span><span class=cF0>
<a name="l197"></a>
<a name="l198"></a></span><span class=cF9>CPCIDev</span><span class=cF0> *E1000PCIDevFind()
<a name="l199"></a>{</span><span class=cF2>// Find and return E1000 card as a CPCIDev pointer.</span><span class=cF0>
<a name="l200"></a>
<a name="l201"></a> </span><span class=cF9>CPCIDev</span><span class=cF0> *pci = </span><span class=cF5>PCIDevFind</span><span class=cF0>(</span><span class=cF3>PCIC_NETWORK</span><span class=cF0>,, PCIV_E1000);
<a name="l202"></a>
<a name="l203"></a> </span><span class=cF1>if</span><span class=cF0> (!pci)
<a name="l204"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>NULL</span><span class=cF0>;
<a name="l205"></a>
<a name="l206"></a> </span><span class=cF5>ClassRep</span><span class=cF0>(pci);
<a name="l207"></a>
<a name="l208"></a> </span><span class=cF1>switch</span><span class=cF0> (pci-&gt;device_id)
<a name="l209"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l210"></a> </span><span class=cF1>case</span><span class=cF0> PCID_82545EM:
<a name="l211"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l212"></a>
<a name="l213"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l214"></a> pci = </span><span class=cF3>NULL</span><span class=cF0>;
<a name="l215"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l216"></a>
<a name="l217"></a> </span><span class=cF1>return</span><span class=cF0> pci;
<a name="l218"></a>}
<a name="l219"></a>
<a name="l220"></a></span><span class=cF9>U32</span><span class=cF0> E1000MMIORead(</span><span class=cF9>U32</span><span class=cF0> </span><span class=cF1>offset</span><span class=cF0>)
<a name="l221"></a>{
<a name="l222"></a> </span><span class=cF9>U32</span><span class=cF0> *val = e1000.mmio_address + </span><span class=cF1>offset</span><span class=cF0>;
<a name="l223"></a>
<a name="l224"></a> </span><span class=cF1>return</span><span class=cF0> *val;
<a name="l225"></a>}
<a name="l226"></a>
<a name="l227"></a></span><span class=cF1>U0</span><span class=cF0> E1000MMIOWrite(</span><span class=cF9>U32</span><span class=cF0> </span><span class=cF1>offset</span><span class=cF0>, </span><span class=cF9>U32</span><span class=cF0> val)
<a name="l228"></a>{
<a name="l229"></a> </span><span class=cF9>U32</span><span class=cF0> *addr = e1000.mmio_address + </span><span class=cF1>offset</span><span class=cF0>;
<a name="l230"></a>
<a name="l231"></a> *addr = val;
<a name="l232"></a>}
<a name="l233"></a>
<a name="l234"></a></span><span class=cF9>U16</span><span class=cF0> E1000EEPROMRead(</span><span class=cF1>U8</span><span class=cF0> word)
<a name="l235"></a>{ </span><span class=cF2>// word arg is which U16 to read</span><span class=cF0>
<a name="l236"></a> </span><span class=cF9>U16</span><span class=cF0> data;
<a name="l237"></a> </span><span class=cF9>U32</span><span class=cF0> temp;
<a name="l238"></a>
<a name="l239"></a> E1000MMIOWrite(E1000_REG_EERD, </span><span class=cFE>1</span><span class=cF0> | word &lt;&lt; </span><span class=cFE>8</span><span class=cF0>);
<a name="l240"></a>
<a name="l241"></a> temp = E1000MMIORead(E1000_REG_EERD);
<a name="l242"></a> </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&amp;temp, E1000_EERDf_DONE</span><span class=cF7>)</span><span class=cF0>)
<a name="l243"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l244"></a> </span><span class=cF5>Sleep</span><span class=cF0>(</span><span class=cFE>1</span><span class=cF0>);
<a name="l245"></a> temp = E1000MMIORead(E1000_REG_EERD);
<a name="l246"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l247"></a>
<a name="l248"></a> data = temp.u16[</span><span class=cFE>1</span><span class=cF0>];
<a name="l249"></a> </span><span class=cF1>return</span><span class=cF0> data;
<a name="l250"></a>}
<a name="l251"></a>
<a name="l252"></a></span><span class=cF1>U0</span><span class=cF0> E1000MACGet()
<a name="l253"></a>{
<a name="l254"></a> </span><span class=cF9>I64</span><span class=cF0> i;
<a name="l255"></a> </span><span class=cF9>U16</span><span class=cF0> mac;
<a name="l256"></a>
<a name="l257"></a> NetLog(</span><span class=cF6>&quot;E1000 MAC GET: Getting MAC Address.&quot;</span><span class=cF0>);
<a name="l258"></a>
<a name="l259"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>3</span><span class=cF0>; i++)
<a name="l260"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l261"></a> mac = E1000EEPROMRead(i);
<a name="l262"></a> e1000.mac_address[</span><span class=cFE>2</span><span class=cF0>*i] = mac.u8[</span><span class=cFE>0</span><span class=cF0>];
<a name="l263"></a> e1000.mac_address[</span><span class=cFE>2</span><span class=cF0>*i+</span><span class=cFE>1</span><span class=cF0>] = mac.u8[</span><span class=cFE>1</span><span class=cF0>];
<a name="l264"></a> NetLog(</span><span class=cF6>&quot; %02X %02X&quot;</span><span class=cF0>, mac.u8[</span><span class=cFE>0</span><span class=cF0>], mac.u8[</span><span class=cFE>1</span><span class=cF0>]);
<a name="l265"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l266"></a>
<a name="l267"></a>}
<a name="l268"></a>
<a name="l269"></a></span><span class=cF9>I64</span><span class=cF0> E1000PacketReceive(</span><span class=cF1>U8</span><span class=cF0> **packet_buffer_out, </span><span class=cF9>U16</span><span class=cF0> *packet_length_out)
<a name="l270"></a>{
<a name="l271"></a> </span><span class=cF9>I64</span><span class=cF0> de_index = e1000.current_rx_de_index;
<a name="l272"></a> CE1000DescriptorEntryRX *entry = &amp;e1000.rx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryRX)];
<a name="l273"></a> </span><span class=cF1>Bool</span><span class=cF0> drop = </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l274"></a>
<a name="l275"></a> </span><span class=cF1>if</span><span class=cF0> (entry-&gt;length &lt; </span><span class=cFE>60</span><span class=cF0>)
<a name="l276"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l277"></a> NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: Short Packet&quot;</span><span class=cF0>);
<a name="l278"></a> drop = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l279"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l280"></a>
<a name="l281"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&amp;entry-&gt;status, E1000_RDESC_STATUSf_EOP</span><span class=cF7>)</span><span class=cF0>)
<a name="l282"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l283"></a> NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: No EOP Set&quot;</span><span class=cF0>);
<a name="l284"></a> drop = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l285"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l286"></a>
<a name="l287"></a> </span><span class=cF1>if</span><span class=cF0> (entry-&gt;errors)
<a name="l288"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l289"></a> NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: RX DE Error Bits Set&quot;</span><span class=cF0>);
<a name="l290"></a> drop = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l291"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l292"></a>
<a name="l293"></a> e1000.current_rx_de_index = (e1000.current_rx_de_index + </span><span class=cFE>1</span><span class=cF0>) &amp; (E1000_RX_BUFF_COUNT - </span><span class=cFE>1</span><span class=cF0>);
<a name="l294"></a>
<a name="l295"></a> </span><span class=cF1>if</span><span class=cF0> (!drop)
<a name="l296"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l297"></a> *packet_buffer_out = entry-&gt;address;
<a name="l298"></a> *packet_length_out = entry-&gt;length;
<a name="l299"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l300"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l301"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l302"></a> NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: Dropping packet.&quot;</span><span class=cF0>);
<a name="l303"></a> de_index = -</span><span class=cFE>1</span><span class=cF0>;
<a name="l304"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l305"></a>
<a name="l306"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
<a name="l307"></a>}
<a name="l308"></a>
<a name="l309"></a></span><span class=cF1>U0</span><span class=cF0> E1000ReceivePacketRelease(</span><span class=cF9>I64</span><span class=cF0> de_index)
<a name="l310"></a>{
<a name="l311"></a> CE1000DescriptorEntryRX *entry = &amp;e1000.rx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryRX)];
<a name="l312"></a> entry-&gt;status = </span><span class=cFE>0</span><span class=cF0>;
<a name="l313"></a>
<a name="l314"></a> E1000MMIOWrite(E1000_REG_RDT, e1000.current_rx_de_index);
<a name="l315"></a>}
<a name="l316"></a>
<a name="l317"></a></span><span class=cF1>Bool</span><span class=cF0> E1000DriverOwnsRX(CE1000DescriptorEntryRX *entry)
<a name="l318"></a>{
<a name="l319"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF5>Bt</span><span class=cF0>(&amp;entry-&gt;status, </span><span class=cFE>0</span><span class=cF0>); </span><span class=cF2>// ?? TODO #define</span><span class=cF0>
<a name="l320"></a>}
<a name="l321"></a>
<a name="l322"></a></span><span class=cF9>I64</span><span class=cF0> E1000TransmitPacketAllocate(</span><span class=cF1>U8</span><span class=cF0> **packet_buffer_out, </span><span class=cF9>I64</span><span class=cF0> length)
<a name="l323"></a>{ </span><span class=cF9>I64</span><span class=cF0> de_index = e1000.current_tx_de_index;
<a name="l324"></a>
<a name="l325"></a> CE1000DescriptorEntryTX *entry = &amp;e1000.tx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryTX)];
<a name="l326"></a>
<a name="l327"></a> *packet_buffer_out = e1000.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE;
<a name="l328"></a>
<a name="l329"></a> </span><span class=cF5>MemSet</span><span class=cF0>(*packet_buffer_out, </span><span class=cFE>0</span><span class=cF0>, ETHERNET_FRAME_SIZE); </span><span class=cF2>// Clear buffer contents in advance.</span><span class=cF0>
<a name="l330"></a>
<a name="l331"></a> entry-&gt;address = *packet_buffer_out;
<a name="l332"></a> entry-&gt;length = length;
<a name="l333"></a> </span><span class=cF5>Bts</span><span class=cF0>(&amp;entry-&gt;cmd, E1000_TDESC_CMDf_EOP);
<a name="l334"></a> </span><span class=cF5>Bts</span><span class=cF0>(&amp;entry-&gt;cmd, E1000_TDESC_CMDf_IFCS);
<a name="l335"></a> </span><span class=cF5>Bts</span><span class=cF0>(&amp;entry-&gt;cmd, E1000_TDESC_CMDf_RS);
<a name="l336"></a>
<a name="l337"></a> NetLog(</span><span class=cF6>&quot;E1000 ALLOCATE TX PACKET: de_index: %X.&quot;</span><span class=cF0>, de_index);
<a name="l338"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
<a name="l339"></a>}
<a name="l340"></a>
<a name="l341"></a></span><span class=cF1>U0</span><span class=cF0> E1000TransmitPacketFinish(</span><span class=cF9>I64</span><span class=cF0> de_index)
<a name="l342"></a>{
<a name="l343"></a> CE1000DescriptorEntryTX *entry = &amp;e1000.tx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryTX)];
<a name="l344"></a>
<a name="l345"></a> e1000.current_tx_de_index = (e1000.current_tx_de_index + </span><span class=cFE>1</span><span class=cF0>) &amp; (E1000_TX_BUFF_COUNT - </span><span class=cFE>1</span><span class=cF0>);
<a name="l346"></a> E1000MMIOWrite(E1000_REG_TDT, e1000.current_tx_de_index);
<a name="l347"></a>
<a name="l348"></a> </span><span class=cF5>ClassRep</span><span class=cF0>(entry);
<a name="l349"></a>
<a name="l350"></a> </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>entry-&gt;sta &amp; (E1000_TDESC_STATUSF_DD | E1000_TDESC_STATUSF_EC |
<a name="l351"></a> E1000_TDESC_STATUSF_LC | E1000_TDESC_STATUSF_TU)</span><span class=cF7>)</span><span class=cF0>)
<a name="l352"></a> </span><span class=cF5>Yield</span><span class=cF0>;
<a name="l353"></a>
<a name="l354"></a> NetLog(</span><span class=cF6>&quot;E1000 FINISH TX PACKET: TX DE index: %X.&quot;</span><span class=cF0>, de_index);
<a name="l355"></a>}
<a name="l356"></a>
<a name="l357"></a></span><span class=cF1>U0</span><span class=cF0> EthernetFrameFinish(</span><span class=cF9>I64</span><span class=cF0> de_index)
<a name="l358"></a>{</span><span class=cF2>//Alias for driver Finish TX function.</span><span class=cF0>
<a name="l359"></a> E1000TransmitPacketFinish(de_index);
<a name="l360"></a>}
<a name="l361"></a>
<a name="l362"></a></span><span class=cF1>interrupt</span><span class=cF0> </span><span class=cF1>U0</span><span class=cF0> E1000IRQ()
<a name="l363"></a>{ </span><span class=cF2>// TODO need #defines</span><span class=cF0>
<a name="l364"></a> </span><span class=cF9>U32</span><span class=cF0> icr = E1000MMIORead(E1000_REG_ICR);
<a name="l365"></a> </span><span class=cF1>Bool</span><span class=cF0> poll = </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l366"></a> CE1000DescriptorEntryRX *entry = e1000.rx_de_buffer;
<a name="l367"></a> </span><span class=cF1>U8</span><span class=cF0> *packet_buffer;
<a name="l368"></a> </span><span class=cF9>U16</span><span class=cF0> packet_length;
<a name="l369"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
<a name="l370"></a>
<a name="l371"></a> icr &amp;= ~(E1000_ICRF_TXDW | E1000_ICRF_TXQE);
<a name="l372"></a>
<a name="l373"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&amp;icr, E1000_ICRf_LSC</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// 'link status change' ?</span><span class=cF0>
<a name="l374"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l375"></a> </span><span class=cF5>Btr</span><span class=cF0>(&amp;icr, E1000_ICRf_LSC);
<a name="l376"></a> E1000MMIOWrite(E1000_REG_CTRL, E1000MMIORead</span><span class=cF7>(</span><span class=cF0>E1000_REG_CTRL</span><span class=cF7>)</span><span class=cF0> | E1000_CTRLF_SLU);
<a name="l377"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l378"></a>
<a name="l379"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&amp;icr, E1000_ICRf_RXO</span><span class=cF7>)</span><span class=cF0> || </span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&amp;icr, E1000_ICRf_RXDMT</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// 'rx underrun / min threshold' ?</span><span class=cF0>
<a name="l380"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l381"></a> </span><span class=cF5>Btr</span><span class=cF0>(&amp;icr, E1000_ICRf_RXO);
<a name="l382"></a> </span><span class=cF5>Btr</span><span class=cF0>(&amp;icr, E1000_ICRf_RXDMT);
<a name="l383"></a>
<a name="l384"></a> poll = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l385"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l386"></a>
<a name="l387"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&amp;icr, E1000_ICRf_RXT</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// 'packet pending' ?</span><span class=cF0>
<a name="l388"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l389"></a> </span><span class=cF5>Btr</span><span class=cF0>(&amp;icr, E1000_ICRf_RXT);
<a name="l390"></a>
<a name="l391"></a> poll = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l392"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l393"></a>
<a name="l394"></a> </span><span class=cF1>if</span><span class=cF0> (poll)
<a name="l395"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l396"></a> </span><span class=cF1>while</span><span class=cF0> (E1000DriverOwnsRX</span><span class=cF7>(</span><span class=cF0>&amp;entry[e1000.current_rx_de_index]</span><span class=cF7>)</span><span class=cF0>)
<a name="l397"></a> {
<a name="l398"></a> NetLog(</span><span class=cF6>&quot;$BG,LTCYAN$$FG,WHITE$&quot;</span><span class=cF0>
<a name="l399"></a> </span><span class=cF6>&quot;==== E1000 IRQ ====&quot;</span><span class=cF0>
<a name="l400"></a> </span><span class=cF6>&quot;$BG$$FG$&quot;</span><span class=cF0>);
<a name="l401"></a>
<a name="l402"></a> NetLog(</span><span class=cF6>&quot;$BD,CYAN$$FD,WHITE$&quot;</span><span class=cF0>
<a name="l403"></a> </span><span class=cF6>&quot;E1000 IRQ: Saw owned RX DE index %d.&quot;</span><span class=cF0>, e1000.current_rx_de_index);
<a name="l404"></a>
<a name="l405"></a> de_index = E1000PacketReceive(&amp;packet_buffer, &amp;packet_length);
<a name="l406"></a>
<a name="l407"></a> </span><span class=cF1>if</span><span class=cF0> (de_index &gt;= </span><span class=cFE>0</span><span class=cF0>)
<a name="l408"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l409"></a> NetLog(</span><span class=cF6>&quot;E1000 IRQ: Pushing copy into Net Queue, releasing receive packet.&quot;</span><span class=cF0>);
<a name="l410"></a> NetQueuePush(packet_buffer, packet_length);
<a name="l411"></a> E1000ReceivePacketRelease(de_index);
<a name="l412"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l413"></a>
<a name="l414"></a> NetLog(</span><span class=cF6>&quot;E1000 IRQ: Exiting.\n&quot;</span><span class=cF0>
<a name="l415"></a> </span><span class=cF6>&quot;$BD,WHITE$$FD,LTGRAY$&quot;</span><span class=cF0>
<a name="l416"></a> </span><span class=cF6>&quot;$BG,LTCYAN$$FG,WHITE$&quot;</span><span class=cF0>
<a name="l417"></a> </span><span class=cF6>&quot;===================&quot;</span><span class=cF0>
<a name="l418"></a> </span><span class=cF6>&quot;$BG$$FG$&quot;</span><span class=cF0>);
<a name="l419"></a> }
<a name="l420"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l421"></a>
<a name="l422"></a> E1000MMIORead(E1000_REG_ICR); </span><span class=cF2>// clear pending interrupts?</span><span class=cF0>
<a name="l423"></a>
<a name="l424"></a> *(</span><span class=cFB>dev</span><span class=cF0>.uncached_alias + </span><span class=cF3>LAPIC_EOI</span><span class=cF0>)(</span><span class=cF9>U32</span><span class=cF0>*) = </span><span class=cFE>0</span><span class=cF0>;
<a name="l425"></a>}
<a name="l426"></a>
<a name="l427"></a></span><span class=cF1>U0</span><span class=cF0> PCIInterruptsReroute(</span><span class=cF9>I64</span><span class=cF0> base)
<a name="l428"></a>{ </span><span class=cF2>// todo: comments explaining process, maybe better var names</span><span class=cF0>
<a name="l429"></a> </span><span class=cF9>I64</span><span class=cF0> i;
<a name="l430"></a> </span><span class=cF1>U8</span><span class=cF0> *da = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + </span><span class=cF3>IOAPIC_REG</span><span class=cF0>;
<a name="l431"></a> </span><span class=cF9>U32</span><span class=cF0> *_d = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + </span><span class=cF3>IOAPIC_DATA</span><span class=cF0>;
<a name="l432"></a>
<a name="l433"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>4</span><span class=cF0>; i++)
<a name="l434"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l435"></a> *da = </span><span class=cF3>IOREDTAB</span><span class=cF0> + i * </span><span class=cFE>2</span><span class=cF0> + </span><span class=cFE>1</span><span class=cF0>;
<a name="l436"></a> *_d = </span><span class=cFB>dev</span><span class=cF0>.mp_apic_ids[INT_DEST_CPU] &lt;&lt; </span><span class=cFE>24</span><span class=cF0>;
<a name="l437"></a> *da = </span><span class=cF3>IOREDTAB</span><span class=cF0> + i * </span><span class=cFE>2</span><span class=cF0>;
<a name="l438"></a> *_d = </span><span class=cFE>0x4000</span><span class=cF0> + base + i;
<a name="l439"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l440"></a>}
<a name="l441"></a>
<a name="l442"></a>
<a name="l443"></a></span><span class=cF1>U0</span><span class=cF0> E1000InterruptsSetup()
<a name="l444"></a>{ </span><span class=cF2>// .. ?</span><span class=cF0>
<a name="l445"></a></span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>IntEntrySet(I_E1000_0, &amp;E1000IRQ);</span><span class=cF0>
<a name="l446"></a> </span><span class=cF2>IntEntrySet(I_E1000_1, &amp;E1000IRQ);</span><span class=cF0>
<a name="l447"></a> </span><span class=cF2>IntEntrySet(I_E1000_2, &amp;E1000IRQ);</span><span class=cF0>
<a name="l448"></a> </span><span class=cF2>IntEntrySet(I_E1000_3, &amp;E1000IRQ);</span><span class=cF0>
<a name="l449"></a> </span><span class=cF2>PCIInterruptsReroute(I_E1000_0);*/</span><span class=cF0>
<a name="l450"></a> </span><span class=cF9>I64</span><span class=cF0> irq, i;
<a name="l451"></a>
<a name="l452"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>4</span><span class=cF0>; i++)
<a name="l453"></a> </span><span class=cF5>IntEntrySet</span><span class=cF0>(</span><span class=cF7>(</span><span class=cF0>irq = </span><span class=cF5>IntEntryAlloc</span><span class=cF7>)</span><span class=cF0>, &amp;E1000IRQ);
<a name="l454"></a>
<a name="l455"></a> PCIInterruptsReroute(irq);
<a name="l456"></a>}
<a name="l457"></a>
<a name="l458"></a></span><span class=cF1>U0</span><span class=cF0> E1000InitRX()
<a name="l459"></a>{
<a name="l460"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
<a name="l461"></a>
<a name="l462"></a> e1000.rx_de_buffer_phys = </span><span class=cF5>CAllocAligned</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000DescriptorEntryRX</span><span class=cF7>)</span><span class=cF0> * E1000_RX_BUFF_COUNT,
<a name="l463"></a> </span><span class=cFE>16</span><span class=cF0>,
<a name="l464"></a> </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
<a name="l465"></a>
<a name="l466"></a> e1000.rx_de_buffer = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.rx_de_buffer_phys;
<a name="l467"></a>
<a name="l468"></a> e1000.rx_buffer_addr_phys = </span><span class=cF5>CAlloc</span><span class=cF0>(ETHERNET_FRAME_SIZE * E1000_RX_BUFF_COUNT, </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
<a name="l469"></a>
<a name="l470"></a> e1000.rx_buffer_addr = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.rx_buffer_addr_phys;
<a name="l471"></a>
<a name="l472"></a> </span><span class=cF2>// iterate de's and make packet buffers for each</span><span class=cF0>
<a name="l473"></a> CE1000DescriptorEntryRX *entry = e1000.rx_de_buffer;
<a name="l474"></a> </span><span class=cF1>for</span><span class=cF0> (de_index = </span><span class=cFE>0</span><span class=cF0>; de_index &lt; E1000_RX_BUFF_COUNT; de_index++)
<a name="l475"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l476"></a> entry-&gt;address = e1000.rx_buffer_addr + de_index * ETHERNET_FRAME_SIZE; </span><span class=cF2>// is this right? might need to change ?..</span><span class=cF0>
<a name="l477"></a> </span><span class=cF2>// 01000101 MAlloc's 8208 for each DE</span><span class=cF0>
<a name="l478"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l479"></a>
<a name="l480"></a> </span><span class=cF2>// setup rx de ring buffer</span><span class=cF0>
<a name="l481"></a> E1000MMIOWrite(E1000_REG_RDBAH, e1000.rx_de_buffer &gt;&gt; </span><span class=cFE>32</span><span class=cF0>); </span><span class=cF2>// should we be using uncached addr here ?</span><span class=cF0>
<a name="l482"></a> E1000MMIOWrite(E1000_REG_RDBAL, e1000.rx_de_buffer &amp; </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>);
<a name="l483"></a>
<a name="l484"></a> </span><span class=cF2>// set receive buffer length</span><span class=cF0>
<a name="l485"></a> E1000MMIOWrite(E1000_REG_RDLEN, E1000_RX_BUFF_COUNT * </span><span class=cFE>16</span><span class=cF0>);
<a name="l486"></a>
<a name="l487"></a> </span><span class=cF2>// set head tail pointers</span><span class=cF0>
<a name="l488"></a> E1000MMIOWrite(E1000_REG_RDH, </span><span class=cFE>0</span><span class=cF0>);
<a name="l489"></a> E1000MMIOWrite(E1000_REG_RDT, E1000_RX_BUFF_COUNT);
<a name="l490"></a>
<a name="l491"></a> </span><span class=cF2>// set receive control reg</span><span class=cF0>
<a name="l492"></a> E1000MMIOWrite(E1000_REG_RCTL, E1000_RCTLF_SBP |
<a name="l493"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>E1000_RCTLF_UPE</span><span class=cF0> </span><span class=cF2>|</span><span class=cF0>
<a name="l494"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>E1000_RCTLF_RDMTS_HALF</span><span class=cF0> </span><span class=cF2>|</span><span class=cF0>
<a name="l495"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>E1000_RCTLF_BSIZE_2048</span><span class=cF0> </span><span class=cF2>|</span><span class=cF0>
<a name="l496"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>E1000_RCTLF_MPE</span><span class=cF0> </span><span class=cF2>|</span><span class=cF0>
<a name="l497"></a> E1000_RCTLF_SECRC |
<a name="l498"></a> E1000_RCTLF_LPE |
<a name="l499"></a> E1000_RCTLF_BAM);
<a name="l500"></a>}
<a name="l501"></a>
<a name="l502"></a></span><span class=cF1>U0</span><span class=cF0> E1000InitTX()
<a name="l503"></a>{
<a name="l504"></a> e1000.tx_de_buffer_phys = </span><span class=cF5>CAllocAligned</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000DescriptorEntryTX</span><span class=cF7>)</span><span class=cF0> * E1000_TX_BUFF_COUNT,
<a name="l505"></a> </span><span class=cFE>16</span><span class=cF0>,
<a name="l506"></a> </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
<a name="l507"></a>
<a name="l508"></a> e1000.tx_de_buffer = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.tx_de_buffer_phys;
<a name="l509"></a>
<a name="l510"></a> e1000.tx_buffer_addr_phys = </span><span class=cF5>CAlloc</span><span class=cF0>(ETHERNET_FRAME_SIZE * E1000_TX_BUFF_COUNT, </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
<a name="l511"></a>
<a name="l512"></a> e1000.tx_buffer_addr = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.tx_buffer_addr_phys;
<a name="l513"></a>
<a name="l514"></a> </span><span class=cF2>// setup tx de ring buffer</span><span class=cF0>
<a name="l515"></a> E1000MMIOWrite(E1000_REG_TDBAH, e1000.tx_de_buffer &gt;&gt; </span><span class=cFE>32</span><span class=cF0>); </span><span class=cF2>// should we be using uncached addr here ?</span><span class=cF0>
<a name="l516"></a> E1000MMIOWrite(E1000_REG_TDBAL, e1000.tx_de_buffer &amp; </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>);
<a name="l517"></a>
<a name="l518"></a> </span><span class=cF2>// set tx buffer length</span><span class=cF0>
<a name="l519"></a> E1000MMIOWrite(E1000_REG_TDLEN, E1000_TX_BUFF_COUNT * </span><span class=cFE>16</span><span class=cF0>);
<a name="l520"></a>
<a name="l521"></a> </span><span class=cF2>// set head tail pointers</span><span class=cF0>
<a name="l522"></a> E1000MMIOWrite(E1000_REG_TDH, </span><span class=cFE>0</span><span class=cF0>);
<a name="l523"></a> E1000MMIOWrite(E1000_REG_TDT, E1000_RX_BUFF_COUNT);
<a name="l524"></a>
<a name="l525"></a> </span><span class=cF2>// set transmit control reg</span><span class=cF0>
<a name="l526"></a> E1000MMIOWrite(E1000_REG_TCTL, E1000_TCTLF_EN | E1000_TCTLF_PSP);
<a name="l527"></a>
<a name="l528"></a>}
<a name="l529"></a>
<a name="l530"></a>
<a name="l531"></a></span><span class=cF1>U0</span><span class=cF0> E1000Init()
<a name="l532"></a>{
<a name="l533"></a> </span><span class=cF9>I64</span><span class=cF0> i;
<a name="l534"></a>
<a name="l535"></a> </span><span class=cF5>MemSet</span><span class=cF0>(&amp;e1000, </span><span class=cFE>0</span><span class=cF0>, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000</span><span class=cF7>)</span><span class=cF0>); </span><span class=cF2>// e1000 global var will hold member data the driver uses often.</span><span class=cF0>
<a name="l536"></a> </span><span class=cF6>&quot;\nE1000 driver WIP\n\n&quot;</span><span class=cF0>;
<a name="l537"></a>
<a name="l538"></a> e1000.pci = E1000PCIDevFind;
<a name="l539"></a> </span><span class=cF1>if</span><span class=cF0> (!e1000.pci)
<a name="l540"></a> </span><span class=cF1>return</span><span class=cF0>; </span><span class=cF2>// if we don't find the card, quit.</span><span class=cF0>
<a name="l541"></a>
<a name="l542"></a>
<a name="l543"></a> e1000.mmio_address = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.pci-&gt;base[</span><span class=cFE>0</span><span class=cF0>] &amp; ~</span><span class=cFE>0xF</span><span class=cF0>;
<a name="l544"></a> </span><span class=cF2>// Assuming card supports MMIO... lower 4 bits are hardwired zero (?)</span><span class=cF0>
<a name="l545"></a>
<a name="l546"></a> </span><span class=cF6>&quot;\nMMIO address: 0x%0X\n&quot;</span><span class=cF0>, e1000.mmio_address;
<a name="l547"></a>
<a name="l548"></a> </span><span class=cF2>// init rx/tx addrs? (linux)</span><span class=cF0>
<a name="l549"></a>
<a name="l550"></a> </span><span class=cF2>// eeprom? MAC ?</span><span class=cF0>
<a name="l551"></a> E1000MACGet;
<a name="l552"></a>
<a name="l553"></a> </span><span class=cF2>// setup link? (01000101's driver)</span><span class=cF0>
<a name="l554"></a> E1000MMIOWrite(E1000_REG_CTRL, E1000MMIORead</span><span class=cF7>(</span><span class=cF0>E1000_REG_CTRL</span><span class=cF7>)</span><span class=cF0> | E1000_CTRLF_SLU);
<a name="l555"></a>
<a name="l556"></a> </span><span class=cF2>// zero out multicast hash? (linux)</span><span class=cF0>
<a name="l557"></a> </span><span class=cF2>// zero out multicast table array (01000101's driver)</span><span class=cF0>
<a name="l558"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>128</span><span class=cF0>; i++)
<a name="l559"></a> E1000MMIOWrite(E1000_REG_MTA + i*</span><span class=cFE>4</span><span class=cF0>, </span><span class=cFE>0</span><span class=cF0>);
<a name="l560"></a>
<a name="l561"></a> </span><span class=cF2>// setup link? (linux)</span><span class=cF0>
<a name="l562"></a>
<a name="l563"></a> </span><span class=cF2>// clear all statistics regs after link establish attempt (linux)</span><span class=cF0>
<a name="l564"></a>
<a name="l565"></a> </span><span class=cF2>// enable &amp; clear existing interupts (01000101's driver)</span><span class=cF0>
<a name="l566"></a> E1000MMIOWrite(E1000_REG_IMS, E1000_IMSF_LSC |
<a name="l567"></a> E1000_IMSF_RXSEQ |
<a name="l568"></a> E1000_IMSF_RXDMT |
<a name="l569"></a> E1000_IMSF_RXO |
<a name="l570"></a> E1000_IMSF_RXT |
<a name="l571"></a> E1000_IMSF_MDAC |
<a name="l572"></a> E1000_IMSF_RXCFG |
<a name="l573"></a> E1000_IMSF_PHYINT |
<a name="l574"></a> E1000_IMSF_GPI |
<a name="l575"></a> E1000_IMSF_TXDLOW |
<a name="l576"></a> E1000_IMSF_SRPD);
<a name="l577"></a>
<a name="l578"></a> E1000MMIORead(E1000_REG_ICR); </span><span class=cF2>// clear pending interrupts ?</span><span class=cF0>
<a name="l579"></a>
<a name="l580"></a> </span><span class=cF2>// start rx tx?</span><span class=cF0>
<a name="l581"></a> E1000InitRX;
<a name="l582"></a> E1000InitTX;
<a name="l583"></a>
<a name="l584"></a> E1000InterruptsSetup;
<a name="l585"></a>
<a name="l586"></a>
<a name="l587"></a> NetErr(</span><span class=cF6>&quot;TODO E1000&quot;</span><span class=cF0>);
<a name="l588"></a> </span><span class=cF6>&quot;\n&quot;</span><span class=cF0>;
<a name="l589"></a> </span><span class=cF5>ClassRep</span><span class=cF0>(&amp;e1000);
<a name="l590"></a>}
<a name="l591"></a>
<a name="l592"></a></span><span class=cF9>I64</span><span class=cF0> EthernetFrameAllocate(</span><span class=cF1>U8</span><span class=cF0> **packet_buffer_out,
<a name="l593"></a> </span><span class=cF1>U8</span><span class=cF0> *source_address,
<a name="l594"></a> </span><span class=cF1>U8</span><span class=cF0> *destination_address,
<a name="l595"></a> </span><span class=cF9>U16</span><span class=cF0> ethertype,
<a name="l596"></a> </span><span class=cF9>I64</span><span class=cF0> packet_length)
<a name="l597"></a>{
<a name="l598"></a> </span><span class=cF1>U8</span><span class=cF0> *ethernet_frame;
<a name="l599"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
<a name="l600"></a>
<a name="l601"></a> </span><span class=cF1>if</span><span class=cF0> (packet_length &lt; ETHERNET_MIN_FRAME_SIZE)
<a name="l602"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l603"></a> NetWarn(</span><span class=cF6>&quot;ETHERNET FRAME ALLOCATE: Truncating length&quot;</span><span class=cF0>);
<a name="l604"></a> packet_length = ETHERNET_MIN_FRAME_SIZE;
<a name="l605"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l606"></a>
<a name="l607"></a> de_index = E1000TransmitPacketAllocate(&amp;ethernet_frame, ETHERNET_MAC_HEADER_LENGTH + packet_length);
<a name="l608"></a>
<a name="l609"></a> </span><span class=cF1>if</span><span class=cF0> (de_index &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l610"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l611"></a> NetErr(</span><span class=cF6>&quot;ETHERNET FRAME ALLOCATE: Failure&quot;</span><span class=cF0>);
<a name="l612"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>; </span><span class=cF2>// Positive value expected. Functions calling this must factor this in.</span><span class=cF0>
<a name="l613"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l614"></a>
<a name="l615"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(ethernet_frame, destination_address, MAC_ADDRESS_LENGTH);
<a name="l616"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(ethernet_frame + MAC_ADDRESS_LENGTH, source_address, MAC_ADDRESS_LENGTH);
<a name="l617"></a>
<a name="l618"></a> ethernet_frame[ETHERNET_ETHERTYPE_OFFSET] = ethertype &gt;&gt; </span><span class=cFE>8</span><span class=cF0>;
<a name="l619"></a> ethernet_frame[ETHERNET_ETHERTYPE_OFFSET + </span><span class=cFE>1</span><span class=cF0>] = ethertype &amp; </span><span class=cFE>0xFF</span><span class=cF0>;
<a name="l620"></a>
<a name="l621"></a> *packet_buffer_out = ethernet_frame + ETHERNET_MAC_HEADER_LENGTH;
<a name="l622"></a>
<a name="l623"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
<a name="l624"></a>
<a name="l625"></a>}
<a name="l626"></a>
<a name="l627"></a></span><span class=cF1>U8</span><span class=cF0> *EthernetMACGet()
<a name="l628"></a>{
<a name="l629"></a> </span><span class=cF1>return</span><span class=cF0> e1000.mac_address;
<a name="l630"></a>}
<a name="l631"></a>
<a name="l632"></a></span><span class=cF1>U0</span><span class=cF0> NetStop()
<a name="l633"></a>{
<a name="l634"></a>
<a name="l635"></a>}
<a name="l636"></a>
<a name="l637"></a></span><span class=cF1>U0</span><span class=cF0> NetStart()
<a name="l638"></a>{
<a name="l639"></a>
<a name="l640"></a>}
<a name="l641"></a>
<a name="l642"></a>E1000Init;</span></pre></body>
</html>