summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README3
-rw-r--r--doc/LINKS.TODO9
-rw-r--r--src/README2
-rw-r--r--src/drivers/net/network.h2
-rw-r--r--src/drivers/net/rtl8139.c117
-rw-r--r--src/drivers/net/rtl8139.h1
-rw-r--r--src/kernel/kernel.c2
7 files changed, 68 insertions, 68 deletions
diff --git a/README b/README
index f35750c..aa75fbd 100644
--- a/README
+++ b/README
@@ -98,3 +98,6 @@ https://code.google.com/archive/p/fpos/source/default/source, FreePascal
https://mirage.io/
http://www.jamesmolloy.co.uk/tutorial_html/
http://prettyos.de
+http://www.jbox.dk/sanos/index.htm
+https://github.com/omarrx024/xos/
+http://minirighi.sourceforge.net
diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO
index 557e598..4824e48 100644
--- a/doc/LINKS.TODO
+++ b/doc/LINKS.TODO
@@ -113,3 +113,12 @@ http://wiki.osdev.org/Detecting_Memory_(x86)
Networking:
http://wiki.osdev.org/RTL8139
http://lowlevel.eu/wiki/RTL8139
+https://gist.github.com/pdumais/f5a2aff025fc7a3fe6bc
+http://linuxgazette.net/156/jangir.html
+http://blog.elastocloud.org/2015/07/qemukvm-bridged-network-with-tap.html
+
+Ethernet:
+https://en.wikipedia.org/wiki/EtherType
+
+ARP:
+https://tools.ietf.org/html/rfc826
diff --git a/src/README b/src/README
index 957d477..c2e9065 100644
--- a/src/README
+++ b/src/README
@@ -51,6 +51,8 @@ Driver framework and specific drivers.
* hdi/ps2/ps2mouse.c - PS/2 mouse
* video/video.c - generic video interface
* video/vga.c - standard VGA video driver
+* net/network.c - generic network interface
+* net/rtl8139.c - driver for the RealTek8139 network card
gui
---
diff --git a/src/drivers/net/network.h b/src/drivers/net/network.h
index 751ca40..a4ffca0 100644
--- a/src/drivers/net/network.h
+++ b/src/drivers/net/network.h
@@ -11,6 +11,8 @@ typedef struct {
} network_mac_address_t;
typedef struct {
+ uint16_t length;
+ uint8_t *data;
} network_event_t;
typedef void (*network_event_handler_t)( network_event_t *event, void *context );
diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c
index 4f32815..34f273c 100644
--- a/src/drivers/net/rtl8139.c
+++ b/src/drivers/net/rtl8139.c
@@ -22,7 +22,6 @@ static rtl8139_vtable_t const rtl8139_vtable = {
// registers
#define REG_MAC0 0x00
#define REG_RBSTART 0x30
-#define REG_ERSR 0x36
#define REG_CMD 0x37
#define REG_CAPR 0x38
#define REG_IMR 0x3C
@@ -56,6 +55,7 @@ static rtl8139_vtable_t const rtl8139_vtable = {
// values for REG_TCR (transmit configuration register)
#define TCR_IFG_STANDARD 0x03000000
#define TCR_MXDMA_2048 0x00000700
+#define TCR_APPEND_CRC 0x00010000
// values for REG_RCR (receive configuration register)
#define RCR_MXDMA_UNLIMITED 0x00000700
@@ -87,7 +87,8 @@ static rtl8139_vtable_t const rtl8139_vtable = {
#define PACKET_HEADER_ROK 0x0001
// receive buffer, set to 8k + header (16) + wrap (2k)
-#define RECEIVE_BUFFER_SIZE 8192 + 16 + 2048
+#define RECEIVE_BUFFER_SIZE 8192
+#define RECEIVE_TOTAL_BUFFER_SIZE RECEIVE_BUFFER_SIZE + 16 + 2048
void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descriptor_t *descriptor, interrupt_t *interrupt, void *context )
{
@@ -106,7 +107,6 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descrip
port8_init( &rtl8139->CMD_port, descriptor->port_base + REG_CMD );
port16_init( &rtl8139->CAPR_port, descriptor->port_base + REG_CAPR );
port32_init( &rtl8139->RBSTART_port, descriptor->port_base + REG_RBSTART );
- port8_init( &rtl8139->ERSR_port, descriptor->port_base + REG_ERSR );
port16_init( &rtl8139->IMR_port, descriptor->port_base + REG_IMR );
port16_init( &rtl8139->ISR_port, descriptor->port_base + REG_ISR );
port32_init( &rtl8139->TCR_port, descriptor->port_base + REG_TCR );
@@ -171,14 +171,14 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descrip
}
// initialize TCR/RCR (take Lowlevel suggestions: TCR = 0x03000700, RCR = 0x0000070a)
- port32_write( &rtl8139->TCR_port, TCR_IFG_STANDARD | TCR_MXDMA_2048 );
+ port32_write( &rtl8139->TCR_port, TCR_IFG_STANDARD | TCR_APPEND_CRC | TCR_MXDMA_2048 );
port32_write( &rtl8139->RCR_port, RCR_MXDMA_UNLIMITED |
RCR_RECEIVE_BUFFER_8K_16 | RCR_WRAP |
RCR_ACCEPT_BROADCAST | RCR_ACCEPT_MULTICAST | RCR_ACCEPT_PHYS_MATCH );
// allocate receive buffer and register it
- rtl8139->receive_buffer = (uint8_t *)aligned_alloc( 16, RECEIVE_BUFFER_SIZE + 16 );
- memset( rtl8139->receive_buffer, 0xFE, RECEIVE_BUFFER_SIZE + 16 );
+ rtl8139->receive_buffer = (uint8_t *)aligned_alloc( 16, RECEIVE_TOTAL_BUFFER_SIZE );
+ memset( rtl8139->receive_buffer, 0, RECEIVE_TOTAL_BUFFER_SIZE );
port32_write( &rtl8139->RBSTART_port, (uint32_t)rtl8139->receive_buffer );
rtl8139->receive_buffer_pos = 0;
@@ -226,9 +226,6 @@ void rtl8139_deinit( void *obj )
static void handle_receive_packet( rtl8139_t *rtl8139 )
{
- network_event_t event;
- rtl8139->base.handler( &event, rtl8139 );
-
while( true ) {
uint8_t data = port8_read( &rtl8139->CMD_port );
@@ -238,31 +235,13 @@ static void handle_receive_packet( rtl8139_t *rtl8139 )
}
uint8_t *buffer = rtl8139->receive_buffer + rtl8139->receive_buffer_pos;
-
-#ifdef DEBUG
- uint16_t capr = port16_read( &rtl8139->CAPR_port );
- uint32_t rbstart = port32_read( &rtl8139->RBSTART_port );
- uint32_t mpc = port32_read( &rtl8139->MPC_port );
- uint8_t ersr = port8_read( &rtl8139->ERSR_port );
- printf( "rtl8139: ERSR: %X, RBSTART: %X, CAPR: %X, RBPOS: %X, MPC: %X\n",
- ersr, rbstart, capr, rtl8139->receive_buffer_pos, mpc );
- printf( "rtl8139: " );
- for( int i = 0; i < 80; i++ ) {
- printf( "%X ", rtl8139->receive_buffer[rtl8139->receive_buffer_pos+i] );
- }
- puts( "" );
-#endif
-
- // kprintf("%s: rtl8139_rx() status %4.4x, size %4.4x, cur %4.4x\n", dev->name, rx_status, rx_size, cur_rx);
- // kprintf("%s: Frame contents ", dev->name);
- // for (i = 0; i < 70; i++) kprintf(" %2.2x", rx_ring[ring_offset + i]);
-
// packet header
uint16_t header = *( (uint16_t *)buffer );
#ifdef DEBUG
printf( "rtl8139: rcv header %X\n", header );
#endif
+
if( ( header & PACKET_HEADER_ROK ) == 0 ) {
printf( "rtl8139: illegal packet header, no ROK\n", header );
break;
@@ -276,41 +255,46 @@ static void handle_receive_packet( rtl8139_t *rtl8139 )
printf( "rtl8139: rcv len: %d\n", len );
#endif
+#ifdef DEBUG
+ uint16_t capr = port16_read( &rtl8139->CAPR_port );
+ uint32_t rbstart = port32_read( &rtl8139->RBSTART_port );
+ uint32_t mpc = port32_read( &rtl8139->MPC_port );
+ printf( "rtl8139: RBSTART: %X, CAPR: %X, RBPOS: %X, MPC: %X\n",
+ rbstart, capr, rtl8139->receive_buffer_pos, mpc );
+ printf( "rtl8139: " );
for( int i = 0; i < len; i++ ) {
+ printf( "%X ", rtl8139->receive_buffer[rtl8139->receive_buffer_pos+i] );
+ }
+ puts( "" );
+#endif
+
+ // copy data for the handler of the network event
+ network_event_t event;
+ event.length = len;
+ event.data = (uint8_t *)malloc( len );
+ memcpy( event.data, buffer, len );
+ memset( rtl8139->receive_buffer, 0, len + 2 * sizeof( uint16_t ) );
+
+ // adjust buffer pos
+ rtl8139->receive_buffer_pos += 2 * sizeof( uint16_t );
+ rtl8139->receive_buffer_pos += len;
+ rtl8139->receive_buffer_pos = ( rtl8139->receive_buffer_pos + 3 ) & ~0x3;
+ if( rtl8139->receive_buffer_pos >= RECEIVE_TOTAL_BUFFER_SIZE ) {
+ rtl8139->receive_buffer_pos = 0;
}
+ // initial CAPS is set to FFF0, we deduce from this that we have
+ // to subtract 16 from the actual buffer offset (not mentioned in
+ // documentation of the card!)
+ port16_write( &rtl8139->CAPR_port, rtl8139->receive_buffer_pos - 16 );
+
+ rtl8139->base.handler( &event, rtl8139 );
}
#if 0
while (1)
{
-
- void* buffer = netcard->rx_buffer + netcard->rx_buffer_offset;
-
- uint16_t packet_header = *((uint16_t*) buffer);
- buffer += 2;
-
- if ((packet_header & 1) == 0) {
- DEBUG_MSG("Paketheader: Kein ROK.\n");
- break;
- }
-
- // Die L�nge enth�lt die CRC-Pr�fsumme, nicht aber den Paketheader
- uint16_t length = *((uint16_t*) buffer);
- buffer += 2;
-
- /*
- * RECEIVE_BUFFER_SIZE
- printf("Empfangen: %d Bytes\n", length);
- printf("netcard->rx_buffer_offset = %08x\n", netcard->rx_buffer_offset);
- */
- /*int i;
- for (i = 0; i < length; i++) {
- printf("%02x ", ((char*) buffer)[i]);
- }
- printf("\n");*/
-
netcard->rx_buffer_offset += 4;
if (length >= sizeof(struct eth_packet_header))
@@ -334,16 +318,18 @@ static void handle_receive_packet( rtl8139_t *rtl8139 )
length - 4);
}
- // Den aktuellen Offset im Lesepuffer anpassen. Jedes Paket ist
- // uint32_t-aligned, daher anschlie�end Aufrundung.
- netcard->rx_buffer_offset += length;
- netcard->rx_buffer_offset = (netcard->rx_buffer_offset + 3) & ~0x3;
+--
- // �berl�ufe abfangen
- netcard->rx_buffer_offset %= RX_BUFFER_SIZE;
+ // Den aktuellen Offset im Lesepuffer anpassen. Jedes Paket ist
+ // dword-aligned, daher anschließend Aufrundung.
+ netcard->rx_buffer_offset += length + 4;
+ netcard->rx_buffer_offset = (netcard->rx_buffer_offset + 3) & ~0x3;
- write_register_word(netcard, REG_CUR_READ_ADDR,
- netcard->rx_buffer_offset - 0x10);
+ // Überläufe abfangen
+ netcard->rx_buffer_offset %= 0x2000;
+
+ write_register_word(netcard, REG_CUR_READ_ADDR,
+ netcard->rx_buffer_offset - 0x10);
@@ -356,8 +342,9 @@ uint32_t rtl8139_handle_interrupt( interrupt_handler_t *handler, uint32_t esp )
rtl8139_t *rtl8139 = (rtl8139_t *)handler->driver;
uint16_t isr = port16_read( &rtl8139->ISR_port );
- //~ uint16_t reset_isr = 0;
+ uint16_t reset_isr = 0;
+ // TODO: early interrupt line cleaning or later?
port16_write( &rtl8139->ISR_port, isr );
#ifdef DEBUG
@@ -369,12 +356,10 @@ uint32_t rtl8139_handle_interrupt( interrupt_handler_t *handler, uint32_t esp )
// TODO: manual says, we should reset the ISR bit first,
// then go into a read loop?
handle_receive_packet( rtl8139 );
-
- //~ reset_isr |= ISR_RECEIVE_OK;
}
// reset interrupt lines when consumed
- //~ port16_write( &rtl8139->ISR_port, reset_isr );
+ //~ port16_write( &rtl8139->ISR_port, isr );
return esp;
}
diff --git a/src/drivers/net/rtl8139.h b/src/drivers/net/rtl8139.h
index 7419f65..462526a 100644
--- a/src/drivers/net/rtl8139.h
+++ b/src/drivers/net/rtl8139.h
@@ -11,7 +11,6 @@ typedef struct {
network_t base;
port8_t MAC_port[NOF_MAC_REGISTERS];
port32_t RBSTART_port;
- port8_t ERSR_port;
port8_t CMD_port;
port16_t CAPR_port;
port16_t IMR_port;
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 486e04f..23a8d72 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -452,5 +452,5 @@ void __stack_chk_fail( void )
void handle_network_event( network_event_t *event, void *context )
{
- puts( "NETWORK EVENT" );
+ printf( "NETWORK DATA: len: %d\n", event->length );
}