summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--src/drivers/net/network.c8
-rw-r--r--src/drivers/net/network.h6
-rw-r--r--src/drivers/net/rtl8139.c38
-rw-r--r--src/drivers/net/rtl8139.h6
-rw-r--r--src/kernel/kernel.c18
-rw-r--r--src/net/ethernet.h7
7 files changed, 74 insertions, 11 deletions
diff --git a/README b/README
index 915ce8a..4ddff4c 100644
--- a/README
+++ b/README
@@ -64,7 +64,7 @@ set disassemble-next-line on
analyze network traffic:
-tcpdump -nr network.log
+tcpdump -enr network.log
links
-----
diff --git a/src/drivers/net/network.c b/src/drivers/net/network.c
index be8001d..8c2edc1 100644
--- a/src/drivers/net/network.c
+++ b/src/drivers/net/network.c
@@ -12,7 +12,8 @@ static network_vtable_t const network_vtable = {
driver_deinit,
driver_print_info
},
- network_register_handler
+ network_register_handler,
+ network_write
};
void network_init( network_t *network, interrupt_t *interrupt, void *context )
@@ -32,3 +33,8 @@ void network_register_handler( void *obj, network_event_handler_t handler )
network->handler = handler;
}
+
+void network_write( void *obj, network_buffer_t buf )
+{
+ kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
+}
diff --git a/src/drivers/net/network.h b/src/drivers/net/network.h
index 91dbf61..39ae627 100644
--- a/src/drivers/net/network.h
+++ b/src/drivers/net/network.h
@@ -11,6 +11,10 @@
typedef struct {
uint16_t length;
uint8_t *data;
+} network_buffer_t;
+
+typedef struct {
+ network_buffer_t buf;
} network_event_t;
typedef void (*network_event_handler_t)( network_event_t *event, void *context );
@@ -24,10 +28,12 @@ typedef struct {
typedef struct {
driver_vtable_t base;
void (*register_handler)( void *obj, network_event_handler_t handler );
+ void (*write)( void *obj, network_buffer_t buf );
} network_vtable_t;
void network_init( network_t *network, interrupt_t *interrupt, void *context );
void network_register_handler( void *obj, network_event_handler_t handler );
+void network_write( void *obj, network_buffer_t buf );
#endif // NETWORK_H
diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c
index 5b95042..ad6ccfe 100644
--- a/src/drivers/net/rtl8139.c
+++ b/src/drivers/net/rtl8139.c
@@ -15,12 +15,15 @@ static rtl8139_vtable_t const rtl8139_vtable = {
rtl8139_print_name,
rtl8139_print_info
},
- network_register_handler
+ network_register_handler,
+ rtl8139_write
}
};
// registers
#define REG_MAC0 0x00
+#define REG_TR_STATUS0 0x10
+#define REG_TR_ADDR0 0x20
#define REG_RBSTART 0x30
#define REG_CMD 0x37
#define REG_CAPR 0x38
@@ -86,8 +89,6 @@ static rtl8139_vtable_t const rtl8139_vtable = {
// header
#define PACKET_HEADER_ROK 0x0001
-#define ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 64
-
// receive buffer, set to 8k + header (16) + wrap (2k)
#define RECEIVE_BUFFER_SIZE 8192
#define RECEIVE_TOTAL_BUFFER_SIZE RECEIVE_BUFFER_SIZE + 16 + 2048
@@ -106,6 +107,11 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descrip
for( int i = 0; i < NOF_MAC_REGISTERS; i++ ) {
port8_init( &rtl8139->MAC_port[i], descriptor->port_base + REG_MAC0 + i );
}
+ for( int i = 0; i < NOF_TRANSMIT_BUFFERS; i++ ) {
+ port32_init( &rtl8139->TSD_port[i], descriptor->port_base + REG_TR_STATUS0 +i );
+ port32_init( &rtl8139->TSAD_port[i], descriptor->port_base + REG_TR_ADDR0 + i );
+ }
+
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 );
@@ -184,6 +190,14 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descrip
port32_write( &rtl8139->RBSTART_port, (uint32_t)rtl8139->receive_buffer );
rtl8139->receive_buffer_pos = 0;
+ // allocate transmit buffers and set index to first transmit buffer
+ for( int i = 0; i < NOF_TRANSMIT_BUFFERS; i++ ) {
+ rtl8139->transmit_buffer[i] = (uint8_t *)aligned_alloc( 16, ETHERNET_MAX_FRAME_SIZE_IEEE_802_3 );
+ memset( rtl8139->transmit_buffer[i], 0, ETHERNET_MAX_FRAME_SIZE_IEEE_802_3 );
+ port32_write( &rtl8139->TSAD_port[i], (uint32_t)rtl8139->transmit_buffer[i] );
+ }
+ rtl8139->transmit_buffer_idx = 0;
+
// reset missed packet counter
port32_write( &rtl8139->MPC_port, 0 );
@@ -279,9 +293,9 @@ static void handle_receive_packet( rtl8139_t *rtl8139 )
if( len >= ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 ) {
// copy data for the handler of the network event
- event.length = len;
- event.data = (uint8_t *)malloc( len );
- memcpy( event.data, buffer, len );
+ event.buf.length = len;
+ event.buf.data = (uint8_t *)malloc( len );
+ memcpy( event.buf.data, buffer, len );
memset( rtl8139->receive_buffer, 0, len + 2 * sizeof( uint16_t ) );
} else {
// make sure we don't have a runt package
@@ -353,3 +367,15 @@ void rtl8139_print_info( void *obj )
( rtl8139->model != NULL ) ? rtl8139->model : buf2,
rtl8139->pci_descriptor.port_base, rtl8139->pci_descriptor.interrupt, buf );
}
+
+void rtl8139_write( void *obj, network_buffer_t buf )
+{
+#ifdef DEBUG
+ printf( "rtl8139: sending data of length %d\n", buf.length );
+ printf( "rtl8139: " );
+ for( int i = 0; i < buf.length; i++ ) {
+ printf( "%X ", ((const uint8_t *)buf.data)[i] );
+ }
+ puts( "" );
+#endif
+}
diff --git a/src/drivers/net/rtl8139.h b/src/drivers/net/rtl8139.h
index 462526a..ec87d23 100644
--- a/src/drivers/net/rtl8139.h
+++ b/src/drivers/net/rtl8139.h
@@ -6,10 +6,13 @@
#include "port.h"
#define NOF_MAC_REGISTERS 6
+#define NOF_TRANSMIT_BUFFERS 4
typedef struct {
network_t base;
port8_t MAC_port[NOF_MAC_REGISTERS];
+ port32_t TSD_port[NOF_TRANSMIT_BUFFERS];
+ port32_t TSAD_port[NOF_TRANSMIT_BUFFERS];
port32_t RBSTART_port;
port8_t CMD_port;
port16_t CAPR_port;
@@ -24,6 +27,8 @@ typedef struct {
const char *model;
uint8_t *receive_buffer;
uint16_t receive_buffer_pos;
+ uint8_t *transmit_buffer[NOF_TRANSMIT_BUFFERS];
+ int transmit_buffer_idx;
interrupt_handler_t interrupt_handler;
} rtl8139_t;
@@ -37,6 +42,7 @@ void rtl8139_deactivate( void *obj );
void rtl8139_deinit( void *obj );
void rtl8139_print_name( void *obj );
void rtl8139_print_info( void *obj );
+void rtl8139_write( void *obj, network_buffer_t buf );
uint32_t rtl8139_handle_interrupt( interrupt_handler_t *handler, uint32_t esp );
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 460cb74..0b10f45 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -456,7 +456,8 @@ void __stack_chk_fail( void )
void handle_network_event( network_event_t *event, void *context )
{
- network_ethernet_packet_t *packet = (network_ethernet_packet_t *)event->data;
+ network_ethernet_packet_t *packet = (network_ethernet_packet_t *)event->buf.data;
+ network_t *network = (network_t *)context;
char src_mac_addr[NETWORK_ETHERNET_MAC_ADDR_STRING];
char dst_mac_addr[NETWORK_ETHERNET_MAC_ADDR_STRING];
@@ -464,7 +465,7 @@ void handle_network_event( network_event_t *event, void *context )
network_mac_address_to_string( packet->header.dst_addr, dst_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING );
printf( "NETWORK DATA: src: %s, dst: %s, len: %d, type: %X\n",
src_mac_addr, dst_mac_addr,
- event->length,
+ event->buf.length,
packet->header.type );
if( packet->header.type == NETWORK_ETHER_PROTOCOL_TYPE_ARP ) {
@@ -479,8 +480,19 @@ void handle_network_event( network_event_t *event, void *context )
printf( "ARP: hw src: %s, dst: %s, ip src: %s, dst: %s, oper: %d\n",
src_mac_addr, dst_mac_addr, src_ip, dst_ip, arp->operation );
+
+ // TODO: remember the address mapping
+
+ // send answer
+ packet->header.dst_addr = arp->source_hardware_address;
+ packet->header.src_addr = global_context.network->mac_address;
+ arp->operation = ARP_OPERATION_ANSWER;
+ arp->destination_hardware_address = arp->source_hardware_address;
+ arp->source_hardware_address = global_context.network->mac_address;
+
+ ((network_vtable_t *)( global_context.network->base.vtable ))->write( global_context.network, event->buf );
}
// we must free the data if we no longer need it
- free( event->data );
+ free( event->buf.data );
}
diff --git a/src/net/ethernet.h b/src/net/ethernet.h
index 9ebf58e..3af053d 100644
--- a/src/net/ethernet.h
+++ b/src/net/ethernet.h
@@ -4,8 +4,15 @@
#include "stdint.h"
#include "stddef.h"
+// length of a string representation of a MAC address
#define NETWORK_ETHERNET_MAC_ADDR_STRING 6 * 3 + 1
+// minimal size of an ethernet packet
+#define ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 64
+
+// maximal size of an ethernet packet
+#define ETHERNET_MAX_FRAME_SIZE_IEEE_802_3 1536
+
// hardware_address_len
#define NETWORK_HARDWARE_ETHERNET_ADDRESS_LENGTH 6