OFDPE handle_received_frame( const switch_port *port, buffer *frame ) { assert( port != NULL ); assert( frame != NULL ); debug( "Handling received frame ( port_no = %u, frame = %p, user_data = %p ).", port->port_no, frame, frame->user_data ); if ( frame->user_data == NULL ) { bool ret = parse_packet( frame ); if ( !ret ) { warn( "Failed to parse a received frame ( port_no = %u, frame = %p ).", port->port_no, frame ); return OFDPE_FAILED; } } assert( frame->user_data != NULL ); ( ( packet_info * ) frame->user_data )->eth_in_port = port->port_no; ( ( packet_info * ) frame->user_data )->eth_in_phy_port = port->port_no; if ( !trylock_pipeline() ) { return ERROR_LOCK; } process_received_frame( port, frame ); if ( !unlock_pipeline() ) { return ERROR_UNLOCK; } return OFDPE_SUCCESS; }
int main ( void ) { int_init(); // This is specific for OpenRISC, you may need to call some other routine here // in order to initialise interrupt support and so on. // We use a serial port console to display informational messages. init_uart( UART1_BASE_ADDR ); uart_print( UART1_BASE_ADDR, "This is the Ethernet example program." EOL ); init_ethernet(); int_add( ETH_IRQ, ð_interrupt, NULL ); // Use an Ethernet sniffer like Wireshark in order to see the test frame sent. uart_print( UART1_BASE_ADDR, "Sending the first test frame (which has invalid protocol contents)..." EOL ); int pos = 0; write_broadcast_mac_addr( ð_tx_packet[ pos ] ); pos += MAC_ADDR_LEN; write_own_mac_addr( ð_tx_packet[ pos ] ); pos += MAC_ADDR_LEN; eth_tx_packet[ pos + 0 ] = 0x10; eth_tx_packet[ pos + 1 ] = 0x20; eth_tx_packet[ pos + 2 ] = 0x30; eth_tx_packet[ pos + 3 ] = 0x40; eth_tx_packet[ pos + 4 ] = 0x50; eth_tx_packet[ pos + 5 ] = 0x60; pos += 6; int fill_to_end = 0; if ( fill_to_end ) { while ( pos < MAX_FRAME_LEN ) { eth_tx_packet[ pos ] = (unsigned char) pos; ++pos; } } start_ethernet_send( pos ); wait_until_frame_was_sent(); uart_print( UART1_BASE_ADDR, "Sending the second test frame (which has invalid protocol contents)..." EOL ); pos = 0; write_broadcast_mac_addr( ð_tx_packet[ pos ] ); pos += MAC_ADDR_LEN; write_own_mac_addr( ð_tx_packet[ pos ] ); pos += MAC_ADDR_LEN; eth_tx_packet[ pos + 0 ] = 0x11; eth_tx_packet[ pos + 1 ] = 0x22; eth_tx_packet[ pos + 2 ] = 0x33; eth_tx_packet[ pos + 3 ] = 0x44; eth_tx_packet[ pos + 4 ] = 0x55; eth_tx_packet[ pos + 5 ] = 0x66; pos += 6; start_ethernet_send( pos ); wait_until_frame_was_sent(); const int dump_all_register_values = 0; if ( dump_all_register_values ) { register_read_test(); } // Main infinite loop. // // Wait for incoming frames, dump their contents and reply to a single type of ARP request. // See the README file for an example on how to generate the right type of APR request with arping. for ( ; ; ) { uart_print( UART1_BASE_ADDR, "Waiting for a frame to be received..." EOL ); REG32( get_bd_ptr_addr( s_current_rx_bd_index ) ) = (unsigned long) eth_rx_packet; uint32_t receive_flags = ETH_RXBD_EMPTY | ETH_RXBD_IRQ; if ( s_current_rx_bd_index == BUFFER_DESCRIPTOR_COUNT - 1 ) receive_flags += ETH_RXBD_WRAP; REG32( get_bd_status_addr( s_current_rx_bd_index ) ) = receive_flags; uint32_t status; for ( ; ; ) { status = REG32( get_bd_status_addr( s_current_rx_bd_index ) ); if ( 0 == ( status & ETH_RXBD_EMPTY ) ) { uart_print( UART1_BASE_ADDR, "Frame received." EOL ); break; } } if ( status & ( ETH_RXBD_OR | ETH_RXBD_IS | ETH_RXBD_DN | ETH_RXBD_TL | ETH_RXBD_SF | ETH_RXBD_CRC | ETH_RXBD_LC ) ) { uart_print( UART1_BASE_ADDR, "Error receiving frame, rx status is: " ); uart_print_hex( UART1_BASE_ADDR, status, 8 ); uart_print( UART1_BASE_ADDR, EOL ); } else { const int eth_rx_len = ( status >> 16 ); const int should_dump_frame_contents = 0; if ( should_dump_frame_contents ) { uart_print( UART1_BASE_ADDR, "Received length: " ); uart_print_int( UART1_BASE_ADDR, eth_rx_len ); uart_print( UART1_BASE_ADDR, EOL ); uart_print( UART1_BASE_ADDR, "Frame data: " ); int i; for ( i = 0; i < eth_rx_len; i++ ) { uart_print_hex( UART1_BASE_ADDR, eth_rx_packet[i], 2 ); uart_print( UART1_BASE_ADDR," " ); } uart_print( UART1_BASE_ADDR, EOL "End of received data." EOL ); } if ( ! process_received_frame( eth_rx_len ) ) { uart_print( UART1_BASE_ADDR, "The received frame has been ignored." EOL ); } } ++s_current_rx_bd_index; if ( s_current_rx_bd_index == BUFFER_DESCRIPTOR_COUNT ) s_current_rx_bd_index = TX_BD_COUNT; } }