diff options
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | doc/LINKS.TODO | 9 | ||||
-rw-r--r-- | src/README | 2 | ||||
-rw-r--r-- | src/drivers/net/network.h | 2 | ||||
-rw-r--r-- | src/drivers/net/rtl8139.c | 117 | ||||
-rw-r--r-- | src/drivers/net/rtl8139.h | 1 | ||||
-rw-r--r-- | src/kernel/kernel.c | 2 |
7 files changed, 68 insertions, 68 deletions
@@ -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 @@ -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 ); } |