RTL8139: Difference between revisions

142 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(2 intermediate revisions by 2 users not shown)
Line 53:
this should essentially *power on* the device.
 
<sourcesyntaxhighlight lang="c">
outportb( ioaddr + 0x52, 0x0);
</syntaxhighlight>
</source>
 
==== Software Reset! ====
Line 71:
initialization procedure.
 
<sourcesyntaxhighlight lang="c">
outportb( ioaddr + 0x37, 0x10);
while( (inb(ioaddr + 0x37) & 0x10) != 0) { }
</syntaxhighlight>
</source>
 
==== Init Receive buffer ====
Line 82:
that variables memory location to the RBSTART register (0x30).
 
<sourcesyntaxhighlight lang="c">
//ioaddr is obtained from PCI configuration
outportd(ioaddr + 0x30, (uintptr_t)rx_buffer); // send uint32_t memory location to RBSTART (0x30)
</syntaxhighlight>
</source>
 
Note that 'rx_buffer' needs to be a pointer to a '''physical address'''. In this case a size of 8192 + 16 (8K + 16 bytes) is recommended, see below.
Line 100:
a TOK or ROK IRQ happens, it actually will go through and fire up an IRQ.
 
<sourcesyntaxhighlight lang="c">
outportw(ioaddr + 0x3C, 0x0005); // Sets the TOK and ROK bits high
</syntaxhighlight>
</source>
 
=== Configuring receive buffer (RCR) ===
Line 122:
You can also tell the size of your RX buffer here, however if you use a 8k + 16 buffer as described before, writing zeroes is enough. To use the WRAP=1 bit, an 8K buffer must in fact be 8k+16+1500 bytes.
 
<sourcesyntaxhighlight lang="c">
outportl(ioaddr + 0x44, 0xf | (1 << 7)); // (1 << 7) is the WRAP bit, 0xf is AB+AM+APM+AAP
</syntaxhighlight>
</source>
 
=== Enable Receive and Transmitter ===
Line 138:
Once this is completed, then the card will start allowing packets in and/or out.
 
<sourcesyntaxhighlight lang="c">
outportb(ioaddr + 0x37, 0x0C); // Sets the RE and TE bits high
</syntaxhighlight>
</source>
 
=== Transmitting Packets ===
Line 169:
When you handle an interrupt, you ''have'' to write the bit corresponding to the interrupt to reset it. The datasheet says reading the register is enough to reset the buffer to zero and writing has no effect. ''This is not the case on QEMU'', and probably on some/most hardware too.
 
'''Note that it is important you write to this register ''before you read any packets from your buffers'', or itthe willwrite eitherto the register will have no effect, and any other packets than the first will not be delivered to your ISR.'''
 
For example, this is tested and works on QEmu:
 
<sourcesyntaxhighlight lang="c">
void rtl8139_handler(uint8_t isr, uint64_t error, uint64_t irq) {
uint16_t status = inw(io_base + 0x3e);
Line 185:
}
}
</syntaxhighlight>
</source>
 
== Related Articles ==