#include "rtl8139.h" #include "string.h" #include "stdio.h" #define DEBUG /* Offset (from IO base) Size Name 0x08 8 MAR0-7 0x30 4 RBSTART 0x37 1 CMD 0x3C 2 IMR 0x3E 2 ISR */ static rtl8139_vtable_t const rtl8139_vtable = { { rtl8139_activate, rtl8139_deactivate, rtl8139_deinit, rtl8139_print_info } }; // registers #define REG_MAC0 0x00 #define REG_CMD 0x37 #define REG_TCR 0x40 #define REG_RCR 0x44 // commands for REG_CMD register #define CMD_RESET 0x10 #define CMD_RECEIVER_ENABLE 0x08 #define CMD_TRANSMITTER_ENABLE 0x04 #define TCR_MODEL_VERSION_AM 0x7C000000 #define TCR_MODEL_VERSION_BM 0x00C00000 #define TCR_MODEL_VERSION_RTL8139 0x60000000 #define TCR_MODEL_VERSION_RTL8139A 0x70000000 #define TCR_MODEL_VERSION_RTL8139B 0x78000000 #define TCR_MODEL_VERSION_RTL8130 0x78000000 #define TCR_MODEL_VERSION_RTL8139AG 0x74000000 #define TCR_MODEL_VERSION_RTL8139C 0x74000000 #define TCR_MODEL_VERSION_RTL8100 0x78800000 #define TCR_MODEL_VERSION_RTL8100B 0x74400000 #define TCR_MODEL_VERSION_RTL8139CP 0x74800000 #define TCR_MODEL_VERSION_RTL8101 0x74C00000 #define TCR_IFG_STANDARD 0x03000000 /* #define TCR_IFG_STANDARD (3 << 24) #define TCR_MXDMA_512 (5 << 8) #define TCR_MXDMA_1024 (6 << 8) #define TCR_MXDMA_2048 (7 << 8) #define RCR_MXDMA_512 (5 << 8) #define RCR_MXDMA_1024 (6 << 8) #define RCR_MXDMA_UNLIMITED (7 << 8) #define RCR_ACCEPT_BROADCAST (1 << 3) #define RCR_ACCEPT_MULTICAST (1 << 2) #define RCR_ACCEPT_PHYS_MATCH (1 << 1) */ void rtl8139_init( rtl8139_t *rtl8139, pci_device_descriptor_t *descriptor, interrupt_t *interrupt, void *context ) { memset( rtl8139, 0, sizeof( rtl8139_t ) ); network_init( (network_t *)rtl8139, interrupt, context ); puts( "Initializing driver for Realtek 8139 network card.." ); for( int i = 0; i < NOF_MAC_REGISTERS; i++ ) { port8_init( &rtl8139->MAC_port[i], descriptor->port_base + REG_MAC0 + i ); } port8_init( &rtl8139->CMD_port, descriptor->port_base + REG_CMD ); port32_init( &rtl8139->TCR_port, descriptor->port_base + REG_TCR ); port32_init( &rtl8139->RCR_port, descriptor->port_base + REG_RCR ); // software reset, the CR_RESET bit remains high till the // reset is finished port8_write( &rtl8139->CMD_port, CMD_RESET ); while( ( port8_read( &rtl8139->CMD_port ) & CMD_RESET ) == CMD_RESET ); // get MAC for( int i = 0; i < NOF_MAC_REGISTERS; i++ ) { rtl8139->base.mac_address.byte[i] = port8_read( &rtl8139->MAC_port[i] ); } // enable receiver and transmitter early port8_write( &rtl8139->CMD_port, CMD_RECEIVER_ENABLE | CMD_TRANSMITTER_ENABLE ); // get model uint32_t model_id = port32_read( &rtl8139->TCR_port ) & ( TCR_MODEL_VERSION_AM | TCR_MODEL_VERSION_BM ); switch( model_id ) { case TCR_MODEL_VERSION_RTL8139: rtl8139->model = "RTL8139"; break; case TCR_MODEL_VERSION_RTL8139A: rtl8139->model = "RTL8139A"; break; //case TCR_MODEL_VERSION_RTL8139B: case TCR_MODEL_VERSION_RTL8130: rtl8139->model = "RTL8130/RTL8130B"; break; // case TCR_MODEL_VERSION_RTL8139AG: case TCR_MODEL_VERSION_RTL8139C: rtl8139->model = "RTL8139A-G/RTL8139C"; break; case TCR_MODEL_VERSION_RTL8100: rtl8139->model = "RTL8100"; break; case TCR_MODEL_VERSION_RTL8100B: rtl8139->model = "RTL8100B"; break; case TCR_MODEL_VERSION_RTL8139CP: rtl8139->model = "RTL8139C+"; break; case TCR_MODEL_VERSION_RTL8101: rtl8139->model = "RTL8101"; break; default: rtl8139->model = NULL; break; } /* TODO: port32_write( &rtl8139->TCR_port, TCR_IFG_STANDARD ); port32_write( &rtl8139->RCR_port, ); TCR RCR DEBUG_MSG("Inititalisiere RCR/TCR"); write_register_dword(netcard, REG_RECEIVE_CONFIGURATION, RCR_MXDMA_UNLIMITED | RCR_ACCEPT_BROADCAST | RCR_ACCEPT_PHYS_MATCH); // DMA burst, 2k is max, what are other operating systems doing? write_register_dword(netcard, REG_TRANSMIT_CONFIGURATION, TCR_IFG_STANDARD | TCR_MXDMA_2048); */ #ifdef DEBUG char buf[20]; char buf2[30]; snprintf( buf2, 30, "unknown submodel 0x%X", model_id ); network_mac_to_string( rtl8139->base.mac_address, buf, 20 ); printf( "rtl8139 NIC type %s\n at I/O base 0x%X, interrupt 0x%X, MAC: %s\n", ( rtl8139->model != NULL ) ? rtl8139->model : buf2, descriptor->port_base, descriptor->interrupt, buf ); #endif interrupt_handler_init( &rtl8139->interrupt_handler, IRQ_BASE + descriptor->interrupt, interrupt, rtl8139_handle_interrupt, rtl8139 ); interrupts_register_interrupt_handler( rtl8139->interrupt_handler ); ((driver_t *)rtl8139)->vtable = (driver_vtable_t *)&rtl8139_vtable; } void rtl8139_activate( void *obj ) { puts( "Activating driver for Realtek 8139 network card.." ); rtl8139_t *rtl8139 = obj; } void rtl8139_deactivate( void *obj ) { puts( "Dectivating driver for Realtek 8139 network card.." ); rtl8139_t *rtl8139 = obj; } void rtl8139_deinit( void *obj ) { // nothing to do } uint32_t rtl8139_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) { rtl8139_t *rtl8139 = (rtl8139_t *)handler->driver; #ifdef DEBUG printf( "RTL INTERRUPT\n" ); #endif return esp; } void rtl8139_print_info( void *obj ) { puts( "Realtek 8139 network card driver" ); }