From d9638539eb82b74d9efc7abb0d71b2deb68a2547 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 10 Aug 2017 12:34:23 +0200 Subject: some renamed in ethernet/rtl8139 don't try tp play with the ethernet CRCs, they belong to layer 2 OSI, the firmware of the network card rtl8139: computing packet size correctly (sizeof uint32_t of the CRC was part of the payload len) --- BUGS | 4 ++++ doc/LINKS.TODO | 1 + src/drivers/net/rtl8139.c | 22 +++++++++++++--------- src/drivers/net/rtl8139.h | 1 + src/kernel/kernel.c | 11 +++++++---- src/net/ethernet.c | 3 +-- src/net/ethernet.h | 2 +- 7 files changed, 28 insertions(+), 16 deletions(-) diff --git a/BUGS b/BUGS index 73e2525..d2a7dcc 100644 --- a/BUGS +++ b/BUGS @@ -28,3 +28,7 @@ - also the PS/2 devices are on a serio bus - there are ISA/AGP/I2C/USB buses which are also dynamic - we could have multiple registered handlers for some devices +- rtl8139 driver: + - can only transmit one packet in parallel currently (transmitting + boolean flag. Taken from Tyndur. No queueing currently and + postponing of sending of packets) diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO index fff3859..d9b081b 100644 --- a/doc/LINKS.TODO +++ b/doc/LINKS.TODO @@ -120,6 +120,7 @@ http://blog.elastocloud.org/2015/07/qemukvm-bridged-network-with-tap.html Ethernet: https://en.wikipedia.org/wiki/Ethernet_frame https://en.wikipedia.org/wiki/EtherType +http://www.hackersdelight.org/hdcodetxt/crc.c.txt ARP: https://tools.ietf.org/html/rfc826 diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index 7731475..3dafaef 100644 --- a/src/drivers/net/rtl8139.c +++ b/src/drivers/net/rtl8139.c @@ -197,6 +197,7 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descrip port32_write( &rtl8139->TSAD_port[i], (uint32_t)rtl8139->transmit_buffer[i] ); } rtl8139->transmit_buffer_idx = 0; + rtl8139->transmitting = false; // reset missed packet counter port32_write( &rtl8139->MPC_port, 0 ); @@ -282,20 +283,16 @@ static void handle_receive_packet( rtl8139_t *rtl8139 ) printf( "%X ", rtl8139->receive_buffer[rtl8139->receive_buffer_pos+i] ); } puts( "" ); - printf( "rtl8139: CRC: " ); - for( int i = len; i < len + 4; i++ ) { - printf( "%X ", rtl8139->receive_buffer[rtl8139->receive_buffer_pos+i] ); - } - puts( "" ); #endif network_event_t event; if( len >= ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 ) { + // remove CRC (which is part of len) // copy data for the handler of the network event - event.buf.length = len; - event.buf.data = (uint8_t *)malloc( len ); - memcpy( event.buf.data, buffer, len ); + event.buf.length = len - sizeof( uint32_t ); + event.buf.data = (uint8_t *)malloc( event.buf.length ); + memcpy( event.buf.data, buffer, event.buf.length ); memset( rtl8139->receive_buffer, 0, len + 2 * sizeof( uint16_t ) ); } else { // make sure we don't have a runt package @@ -339,6 +336,8 @@ 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 ); + } else if( isr & ISR_TRANSMIT_OK ) { + rtl8139->transmitting = false; } // reset interrupt lines when consumed @@ -361,7 +360,7 @@ void rtl8139_print_info( void *obj ) if( rtl8139->model == NULL ) { snprintf( buf2, 30, "unknown submodel 0x%X", rtl8139->model_id ); } - network_mac_address_to_string( rtl8139->base.mac_address, buf, 20 ); + ethernet_mac_address_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, rtl8139->pci_descriptor.port_base, rtl8139->pci_descriptor.interrupt, buf ); @@ -371,6 +370,11 @@ void rtl8139_write( void *obj, network_buffer_t buf ) { rtl8139_t *rtl8139 = (rtl8139_t *)obj; + if( rtl8139->transmitting ) { + puts( "rtl8139: currently transmitting, buffer overrun" ); + return; + } + #ifdef DEBUG printf( "rtl8139: sending data of length %d\n", buf.length ); printf( "rtl8139: " ); diff --git a/src/drivers/net/rtl8139.h b/src/drivers/net/rtl8139.h index ec87d23..4222b6d 100644 --- a/src/drivers/net/rtl8139.h +++ b/src/drivers/net/rtl8139.h @@ -27,6 +27,7 @@ typedef struct { const char *model; uint8_t *receive_buffer; uint16_t receive_buffer_pos; + bool transmitting; uint8_t *transmit_buffer[NOF_TRANSMIT_BUFFERS]; int transmit_buffer_idx; interrupt_handler_t interrupt_handler; diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 0b10f45..d91c5d6 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -461,8 +461,8 @@ void handle_network_event( network_event_t *event, void *context ) char src_mac_addr[NETWORK_ETHERNET_MAC_ADDR_STRING]; char dst_mac_addr[NETWORK_ETHERNET_MAC_ADDR_STRING]; - network_mac_address_to_string( packet->header.src_addr, src_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); - network_mac_address_to_string( packet->header.dst_addr, dst_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); + ethernet_mac_address_to_string( packet->header.src_addr, src_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); + ethernet_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->buf.length, @@ -473,8 +473,8 @@ void handle_network_event( network_event_t *event, void *context ) char src_ip[NETWORK_PROTOCOL_IPV4_ADDR_STRING]; char dst_ip[NETWORK_PROTOCOL_IPV4_ADDR_STRING]; - network_mac_address_to_string( arp->source_hardware_address, src_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); - network_mac_address_to_string( arp->destination_hardware_address, dst_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); + ethernet_mac_address_to_string( arp->source_hardware_address, src_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); + ethernet_mac_address_to_string( arp->destination_hardware_address, dst_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); network_ipv4_address_to_string( arp->source_protocol_address, src_ip, NETWORK_PROTOCOL_IPV4_ADDR_STRING ); network_ipv4_address_to_string( arp->destination_protocol_address, dst_ip, NETWORK_PROTOCOL_IPV4_ADDR_STRING ); @@ -489,6 +489,9 @@ void handle_network_event( network_event_t *event, void *context ) arp->operation = ARP_OPERATION_ANSWER; arp->destination_hardware_address = arp->source_hardware_address; arp->source_hardware_address = global_context.network->mac_address; + network_ipv4_address_t tmp = arp->destination_protocol_address; + arp->destination_protocol_address = arp->source_protocol_address; + arp->source_protocol_address = tmp; ((network_vtable_t *)( global_context.network->base.vtable ))->write( global_context.network, event->buf ); } diff --git a/src/net/ethernet.c b/src/net/ethernet.c index bf8bb93..539764b 100644 --- a/src/net/ethernet.c +++ b/src/net/ethernet.c @@ -2,7 +2,7 @@ #include "stdio.h" -char *network_mac_address_to_string( network_mac_address_t mac, char *buf, size_t buflen ) +char *ethernet_mac_address_to_string( network_mac_address_t mac, char *buf, size_t buflen ) { snprintf( buf, buflen, "%X:%X:%X:%X:%X:%X", mac.byte[0], mac.byte[1], mac.byte[2], @@ -10,4 +10,3 @@ char *network_mac_address_to_string( network_mac_address_t mac, char *buf, size_ return buf; } - diff --git a/src/net/ethernet.h b/src/net/ethernet.h index 3af053d..2731041 100644 --- a/src/net/ethernet.h +++ b/src/net/ethernet.h @@ -45,6 +45,6 @@ typedef struct { #pragma pack() #endif -char *network_mac_address_to_string( network_mac_address_t mac, char *buf, size_t buflen ); +char *ethernet_mac_address_to_string( network_mac_address_t mac, char *buf, size_t buflen ); #endif // ETHERNET_H -- cgit v1.2.3-54-g00ecf