summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers')
-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
4 files changed, 51 insertions, 7 deletions
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 );