Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4191 → Rev 4192

/branches/network/kernel/generic/src/ipc/irq.c
77,6 → 77,8
#include <syscall/copy.h>
#include <console/console.h>
#include <print.h>
// explicitly enable irq
#include <arch/interrupt.h>
 
/** Free the top-half pseudocode.
*
194,6 → 196,11
spinlock_unlock(&irq_uspace_hash_table_lock);
 
interrupts_restore(ipl);
// explicitly enable irq
/* different byteorder?
* trap_virtual_enable_irqs( 1 << ( irq->inr - 1 ));
*/
trap_virtual_enable_irqs( 1 << ( irq->inr + 7 ));
return EOK;
}
 
/branches/network/uspace/srv/net/nil/eth/eth.c
37,8 → 37,8
 
#include <async.h>
#include <malloc.h>
#include <mem.h>
#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
76,9 → 76,11
*/
#define IPC_GET_PACKET( call ) ( packet_id_t ) IPC_GET_ARG2( * call )
 
#define IPC_GET_STATE( call ) ( device_state_t ) IPC_GET_ARG2( * call )
 
/** Returns the protocol service message parameter.
*/
#define IPC_GET_PROTO( call ) ( services_t ) IPC_GET_ARG1( * call )
#define IPC_GET_PROTO( call ) ( services_t ) IPC_GET_ARG2( * call )
 
/** Returns the device driver service message parameter.
*/
123,7 → 125,7
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender );
int eth_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
void eth_receiver( ipc_callid_t iid, ipc_call_t * icall );
eth_proto_ref eth_proccess_packet( int dummy, packet_t packet );
eth_proto_ref eth_process_packet( int dummy, packet_t packet );
int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype );
 
int eth_initialize( void ){
151,7 → 153,8
aid_t message;
ipc_call_t answer;
eth_device_ref device;
int result;
ipcarg_t result;
int index;
 
rwlock_write_lock( & eth_globals.devices_lock );
// an existing device?
190,7 → 193,7
async_wait_for( message, NULL );
return ERROR_CODE;
}
async_wait_for( message, ( ipcarg_t * ) & result );
async_wait_for( message, & result );
if( ERROR_OCCURRED( result )){
rwlock_write_unlock( & eth_globals.devices_lock );
free( device->addr );
199,12 → 202,13
return ERROR_CODE;
}
// add to the cache
if( ERROR_OCCURRED( eth_devices_add( & eth_globals.devices, device->device_id, device ))){
index = eth_devices_add( & eth_globals.devices, device->device_id, device );
if( index < 0 ){
rwlock_write_unlock( & eth_globals.devices_lock );
free( device->addr );
free( device->addr_data );
free( device );
return ERROR_CODE;
return index;
}
printf( "\nNew device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n\taddress\t= %X:%X:%X:%X:%X:%X", device->device_id, device->service, device->mtu, device->addr_data[ 0 ], device->addr_data[ 1 ], device->addr_data[ 2 ], device->addr_data[ 3 ], device->addr_data[ 4 ], device->addr_data[ 5 ] );
}
212,7 → 216,7
return EOK;
}
 
eth_proto_ref eth_proccess_packet( int dummy, packet_t packet ){
eth_proto_ref eth_process_packet( int dummy, packet_t packet ){
ERROR_DECLARE;
 
eth_header_ex_ref header;
286,12 → 290,12
rwlock_read_lock( & eth_globals.protos_lock );
do{
next = pq_detach( packet );
proto = eth_proccess_packet( dummy, packet );
proto = eth_process_packet( dummy, packet );
if( proto ){
async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ));
}else{
// drop invalid/unknown
packet_release( eth_globals.networking_phone, packet_get_id( packet ));
pq_release( eth_globals.networking_phone, packet_get_id( packet ));
}
packet = next;
}while( packet );
303,14 → 307,14
eth_device_ref device;
 
if( !( addr_len && prefix && content && suffix )) return EINVAL;
rwlock_write_lock( & eth_globals.devices_lock );
rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_write_unlock( & eth_globals.devices_lock );
rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
* content = ( ETH_MAX_CONTENT > device->mtu ) ? device->mtu : ETH_MAX_CONTENT;
rwlock_write_unlock( & eth_globals.devices_lock );
rwlock_read_unlock( & eth_globals.devices_lock );
* addr_len = ETH_ADDR;
* prefix = ETH_PREFIX;
* suffix = ETH_MIN_CONTENT + ETH_SUFFIX;
324,23 → 328,22
if( type == ETH_BROADCAST_ADDR ){
* address = eth_globals.broadcast_addr;
}else{
rwlock_write_lock( & eth_globals.devices_lock );
rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_write_unlock( & eth_globals.devices_lock );
rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
* address = device->addr;
rwlock_write_unlock( & eth_globals.devices_lock );
rwlock_read_unlock( & eth_globals.devices_lock );
}
return ( * address ) ? EOK : ENOENT;
}
 
int eth_register_message( services_t service, int phone ){
ERROR_DECLARE;
 
eth_proto_ref proto;
int protocol;
int index;
 
protocol = protocol_map( SERVICE_ETHERNET, service );
if( ! protocol ) return ENOENT;
359,13 → 362,14
proto->service = service;
proto->protocol = protocol;
proto->phone = phone;
if( ERROR_OCCURRED( eth_protos_add( & eth_globals.protos, protocol, proto ))){
index = eth_protos_add( & eth_globals.protos, protocol, proto );
if( index < 0 ){
rwlock_write_unlock( & eth_globals.protos_lock );
free( proto );
return ERROR_CODE;
return index;
}
}
printf( "\nNew protocol registered:\n\tprotocol\t= %d\n\tservice\t= %d\n\tphone\t= %d", proto->protocol, proto->service, proto->phone );
printf( "\nNew protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d", proto->protocol, proto->service, proto->phone );
rwlock_write_unlock( & eth_globals.protos_lock );
return EOK;
}
398,7 → 402,7
if( length < ETH_MIN_CONTENT ){
padding = packet_suffix( packet, ETH_MIN_CONTENT - length );
if( ! padding ) return ENOMEM;
memset( padding, 0, ETH_MIN_CONTENT - length );
bzero( padding, ETH_MIN_CONTENT - length );
}
header->header.ethertype = htons( length );
header->lsap.dsap = 0xAA;
424,7 → 428,7
 
ethertype = htons( protocol_map( SERVICE_ETHERNET, sender ));
if( ! ethertype ){
packet_release( eth_globals.networking_phone, packet_get_id( packet ));
pq_release( eth_globals.networking_phone, packet_get_id( packet ));
return EINVAL;
}
rwlock_read_lock( & eth_globals.devices_lock );
433,13 → 437,13
rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
// proccess packet queue
// process packet queue
next = packet;
do{
if( ERROR_OCCURRED( eth_prepare_packet( device->dummy, next, ( uint8_t * ) device->addr->value, ethertype ))){
// release invalid packet
tmp = pq_detach( next );
packet_release( eth_globals.networking_phone, packet_get_id( next ));
pq_release( eth_globals.networking_phone, packet_get_id( next ));
next = tmp;
}else{
next = pq_next( next );
471,18 → 475,11
* answer_count = 3;
return EOK;
case NET_NIL_ADDR:
rwlock_read_lock( & eth_globals.devices_lock );
if( ! ERROR_OCCURRED( eth_addr_message( IPC_GET_DEVICE( call ), ETH_LOCAL_ADDR, & address ))){
ERROR_CODE = measured_strings_reply( address, 1 );
}
rwlock_read_unlock( & eth_globals.devices_lock );
return ERROR_CODE;
ERROR_PROPAGATE( eth_addr_message( IPC_GET_DEVICE( call ), ETH_LOCAL_ADDR, & address ));
return measured_strings_reply( address, 1 );
case NET_NIL_BROADCAST_ADDR:
rwlock_read_lock( & eth_globals.devices_lock );
if( ! ERROR_OCCURRED( eth_addr_message( IPC_GET_DEVICE( call ), ETH_BROADCAST_ADDR, & address ))){
ERROR_CODE = measured_strings_reply( address, 1 );
}
rwlock_read_unlock( & eth_globals.devices_lock );
ERROR_PROPAGATE( eth_addr_message( IPC_GET_DEVICE( call ), ETH_BROADCAST_ADDR, & address ));
return measured_strings_reply( address, 1 );
return ERROR_CODE;
case IPC_M_CONNECT_TO_ME:
return eth_register_message( IPC_GET_PROTO( call ), IPC_GET_PHONE( call ));
494,11 → 491,20
ERROR_DECLARE;
 
packet_t packet;
int index;
eth_proto_ref proto;
 
while( true ){
switch( IPC_GET_METHOD( * icall )){
case NET_NIL_DEVICE_STATE:
//TODO clear device if off?
rwlock_read_lock( & eth_globals.protos_lock );
for( index = eth_protos_count( & eth_globals.protos ) - 1; index >= 0; -- index ){
proto = eth_protos_get_index( & eth_globals.protos, index );
if( proto && proto->phone ) async_msg_2( proto->phone, NET_IL_DEVICE_STATE, IPC_GET_DEVICE( icall ), IPC_GET_STATE( icall ));
}
rwlock_read_unlock( & eth_globals.protos_lock );
ipc_answer_0( iid, EOK );
break;
case NET_NIL_RECEIVED:
if( ! ERROR_OCCURRED( packet_translate( eth_globals.networking_phone, & packet, IPC_GET_PACKET( icall )))){
/branches/network/uspace/srv/net/structures/measured_strings.c
37,8 → 37,7
 
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <mem.h>
#include <unistd.h>
 
#include <ipc/ipc.h>
/branches/network/uspace/srv/net/structures/module_map.c
0,0 → 1,111
/*
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup netif
* @{
*/
 
/**
* @file
*/
 
#include <malloc.h>
#include <task.h>
#include <unistd.h>
 
#include <ipc/services.h>
 
#include "../err.h"
#include "../modules.h"
 
#include "generic_char_map.h"
#include "module_map.h"
 
GENERIC_CHAR_MAP_IMPLEMENT( modules, module_t )
 
int add_module( module_ref * module, modules_ref modules, char * name, char * filename, services_t service, task_id_t task_id ){
ERROR_DECLARE;
 
module_ref tmp_module;
 
tmp_module = ( module_ref ) malloc( sizeof( module_t ));
if( ! tmp_module ) return ENOMEM;
tmp_module->task_id = task_id;
tmp_module->phone = 0;
tmp_module->usage = 0;
tmp_module->name = name;
tmp_module->filename = filename;
tmp_module->service = service;
if( ERROR_OCCURRED( modules_add( modules, tmp_module->name, 0, tmp_module ))){
free( tmp_module );
return ERROR_CODE;
}
if( module ) * module = tmp_module;
return EOK;
}
 
module_ref get_running_module( modules_ref modules, char * name ){
module_ref module;
 
module = modules_find( modules, name, 0 );
// TODO register the unknown one?
if( ! module ) return NULL;
if( ! module->task_id ){
module->task_id = spawn( module->filename );
if( ! module->task_id ) return NULL;
}
if( ! module->phone ){
module->phone = connect_to_service( module->service );
}
return module;
}
 
task_id_t spawn( char * fname ){
char * argv[ 2 ];
// char * argv[ 4 ];
task_id_t res;
 
// printf( "Spawning %s\n", fname );
argv[ 0 ] = fname;
argv[ 1 ] = NULL;
res = task_spawn( fname, argv );
/* argv[ 0 ] = "/app/trace";
argv[ 1 ] = "+ti";
argv[ 2 ] = fname;
argv[ 3 ] = NULL;
res = task_spawn( "/app/trace", argv );
*/
if( res != 0 ){
/* Success */
usleep( 10000 );
}
return res;
}
 
/** @}
*/
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/branches/network/uspace/srv/net/structures/generic_field.h
38,7 → 38,7
 
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <mem.h>
#include <unistd.h>
 
#define GENERIC_FIELD_MAGIC_VALUE 0x55667788
/branches/network/uspace/srv/net/structures/packet/packet_client.c
36,9 → 36,9
 
#include <async.h>
#include <errno.h>
#include <mem.h>
#include <unistd.h>
//#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
#include <sys/mman.h>
122,15 → 122,15
padding = packet->addr_len - addr_len;
if( src ){
memcpy(( void * ) packet + packet->src_addr, src, addr_len );
memset(( void * ) packet + packet->src_addr + addr_len, 0, padding );
bzero(( void * ) packet + packet->src_addr + addr_len, padding );
}else{
memset(( void * ) packet + packet->src_addr + addr_len, 0, packet->addr_len );
bzero(( void * ) packet + packet->src_addr + addr_len, packet->addr_len );
}
if( dest ){
memcpy(( void * ) packet + packet->dest_addr, dest, addr_len );
memset(( void * ) packet + packet->dest_addr + addr_len, 0, padding );
bzero(( void * ) packet + packet->dest_addr + addr_len, padding );
}else{
memset(( void * ) packet + packet->dest_addr + addr_len, 0, packet->addr_len );
bzero(( void * ) packet + packet->dest_addr + addr_len, packet->addr_len );
}
return EOK;
}
194,7 → 194,7
return packet;
}
 
void packet_release( int phone, packet_id_t packet_id ){
void pq_release( int phone, packet_id_t packet_id ){
async_msg_1( phone, NET_PACKET_RELEASE, packet_id );
}
 
/branches/network/uspace/srv/net/structures/packet/packet.c
37,9 → 37,9
 
#include <errno.h>
#include <malloc.h>
#include <mem.h>
#include <rwlock.h>
//#include <stdio.h>
#include <string.h>
 
#include <sys/mman.h>
 
148,7 → 148,7
rwlock_write_unlock( & pm_globals.lock );
return ENOMEM;
}
memset( map, 0, sizeof( packet_map_t ));
bzero( map, sizeof( packet_map_t ));
if(( ERROR_CODE = gpm_add( & pm_globals.packet_map, map )) < 0 ){
rwlock_write_unlock( & pm_globals.lock );
free( map );
/branches/network/uspace/srv/net/structures/packet/packet_client.h
200,7 → 200,7
* @param phone The packet server module phone. Input parameter.
* @param packet_id The packet identifier. Input parameter.
*/
void packet_release( int phone, packet_id_t packet_id );
void pq_release( int phone, packet_id_t packet_id );
 
#endif
 
/branches/network/uspace/srv/net/structures/packet/packet_server.c
51,6 → 51,18
#include "packet_header.h"
#include "packet_server.h"
 
/** The default address length reserved for new packets.
*/
#define DEFAULT_ADDR_LEN 32
 
/** The default prefix reserved for new packets.
*/
#define DEFAULT_PREFIX 0
 
/** The default suffix reserved for new packets.
*/
#define DEFAULT_SUFFIX 0
 
/** Returns the packet identifier message parameter.
*/
#define IPC_GET_ID( call ) ( packet_id_t ) IPC_GET_ARG1( * call )
69,7 → 81,7
 
/** Returns the maximal suffix length message parameter.
*/
#define IPC_GET_SUFIX( call ) ( size_t ) IPC_GET_ARG4( * call )
#define IPC_GET_SUFFIX( call ) ( size_t ) IPC_GET_ARG4( * call )
 
#define FREE_QUEUES_COUNT 7
 
155,7 → 167,7
case IPC_M_PHONE_HUNGUP:
return EOK;
case NET_PACKET_CREATE_1:
packet = packet_get( 0, 0, IPC_GET_CONTENT( call ), 0 );
packet = packet_get( DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT( call ), DEFAULT_SUFFIX );
if( ! packet ) return ENOMEM;
* answer_count = 2;
IPC_SET_ARG1( * answer, packet->packet_id );
162,7 → 174,7
IPC_SET_ARG2( * answer, packet->length );
return EOK;
case NET_PACKET_CREATE_4:
packet = packet_get( IPC_GET_ADDR_LEN( call ), IPC_GET_PREFIX( call ), IPC_GET_CONTENT( call ), IPC_GET_SUFIX( call ));
packet = packet_get( IPC_GET_ADDR_LEN( call ), IPC_GET_PREFIX( call ), IPC_GET_CONTENT( call ), IPC_GET_SUFFIX( call ));
if( ! packet ) return ENOMEM;
* answer_count = 2;
IPC_SET_ARG1( * answer, packet->packet_id );
/branches/network/uspace/srv/net/structures/module_map.h
0,0 → 1,67
/*
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup netif
* @{
*/
 
/**
* @file
*/
 
#ifndef __NET_MODULES_MAP_H__
#define __NET_MODULES_MAP_H__
 
#include <task.h>
 
#include <ipc/services.h>
 
#include "generic_char_map.h"
 
typedef struct module_struct module_t;
typedef module_t * module_ref;
 
GENERIC_CHAR_MAP_DECLARE( modules, module_t )
 
struct module_struct{
task_id_t task_id;
services_t service;
int phone;
int usage;
char * name;
char * filename;
};
 
int add_module( module_ref * module, modules_ref modules, char * name, char * filename, services_t service, task_id_t task_id );
module_ref get_running_module( modules_ref modules, char * name );
task_id_t spawn( char * fname );
 
#endif
 
/** @}
*/
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/branches/network/uspace/srv/net/structures/char_map.c
37,8 → 37,8
 
#include <errno.h>
#include <malloc.h>
#include <mem.h>
#include <unistd.h>
#include <string.h>
 
#include "char_map.h"
 
/branches/network/uspace/srv/net/structures/int_map.h
38,7 → 38,7
 
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <mem.h>
 
#define INT_MAP_MAGIC_VALUE 0x11223344
#define INT_MAP_ITEM_MAGIC_VALUE 0x55667788
/branches/network/uspace/srv/net/networking/networking.c
39,8 → 39,6
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <task.h>
#include <unistd.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
53,6 → 51,7
#include "../structures/char_map.h"
#include "../structures/generic_char_map.h"
#include "../structures/measured_strings.h"
#include "../structures/module_map.h"
#include "../structures/packet/packet.h"
#include "../structures/packet/packet_server.h"
 
93,9 → 92,6
#define IPC_GET_DEVICE( call ) ( device_id_t ) IPC_GET_ARG1( * call )
#define IPC_GET_COUNT( call ) ( int ) IPC_GET_ARG2( * call )
 
typedef struct module_struct module_t;
typedef module_t * module_ref;
 
typedef struct netif netif_t;
typedef netif_t * netif_ref;
 
105,17 → 101,6
 
GENERIC_CHAR_MAP_DECLARE( measured_strings, measured_string_t )
 
GENERIC_CHAR_MAP_DECLARE( modules, module_t )
 
struct module_struct{
task_id_t task_id;
services_t service;
int phone;
int usage;
char * name;
char * filename;
};
 
/** A present network interface device.
*/
struct netif{
157,7 → 142,6
};
 
void networking_print_name( void );
int add_module( module_ref * module, modules_ref modules, char * name, char * filename, services_t service, task_id_t task_id );
measured_string_ref configuration_find( measured_strings_ref configuration, const char * name );
int networking_start_module( async_client_conn_t client_connection );
int networking_initialize( void );
166,7 → 150,8
//int parse_line( measured_strings_ref configuration, char * line );
int add_configuration( measured_strings_ref configuration, const char * name, const char * value );
int read_configuration( void );
task_id_t spawn( char * fname );
int read_netif_configuration( char * name, netif_ref netif );
int start_device( netif_ref netif );
int startup( void );
device_id_t generate_new_device_id( void );
 
176,33 → 161,10
 
GENERIC_CHAR_MAP_IMPLEMENT( measured_strings, measured_string_t )
 
GENERIC_CHAR_MAP_IMPLEMENT( modules, module_t )
 
void networking_print_name( void ){
printf( NAME );
}
 
int add_module( module_ref * module, modules_ref modules, char * name, char * filename, services_t service, task_id_t task_id ){
ERROR_DECLARE;
 
module_ref tmp_module;
 
tmp_module = ( module_ref ) malloc( sizeof( module_t ));
if( ! tmp_module ) return ENOMEM;
tmp_module->task_id = task_id;
tmp_module->phone = 0;
tmp_module->usage = 0;
tmp_module->name = name;
tmp_module->filename = filename;
tmp_module->service = service;
if( ERROR_OCCURRED( modules_add( modules, tmp_module->name, 0, tmp_module ))){
free( tmp_module );
return ERROR_CODE;
}
if( module ) * module = tmp_module;
return EOK;
}
 
int networking_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
#ifdef NETWORKING_module
//TODO map to *_message
447,166 → 409,83
int read_configuration( void ){
ERROR_DECLARE;
 
netif_ref netif;
// read general configuration
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "IPV", "4" ));
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "MTU", "1500" ));
return EOK;
}
 
int read_netif_configuration( char * name, netif_ref netif ){
ERROR_DECLARE;
 
if( strncmp( name, "lo", 2 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ));
}else if( strncmp( name, "ne2k", 4 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", "eth0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NIL", ETHERNET_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IRQ", "9" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IO", "300" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "10.0.2.5" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.255.255.0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "BROADCAST", "10.0.2.255" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "GATEWAY", "10.0.2.2" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "DNS1", "10.0.2.2" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "DNS2", "10.0.2.2" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "ARP", "arp" ));
}
return EOK;
}
 
int start_device( netif_ref netif ){
ERROR_DECLARE;
 
measured_string_ref setting;
services_t internet_service;
int index;
int irq;
int io;
int mtu;
 
// read general configuration
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "IPV", "4" ));
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "MTU", "1500" ));
 
// read network interfaces configuration
 
netif = ( netif_ref ) malloc( sizeof( netif_t ));
if( ! netif ) return ENOMEM;
netif->id = generate_new_device_id();
ERROR_PROPAGATE( measured_strings_initialize( & netif->configuration ));
if( ERROR_OCCURRED( add_configuration( & netif->configuration, "NAME", "eth0" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NIL", ETHERNET_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IL", IP_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IRQ", "9" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IO", "300" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_CONFIG", "STATIC" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_ADDR", "10.0.2.5" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETMASK", "255.255.255.0" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "BROADCAST", "10.0.2.255" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "GATEWAY", "10.0.2.2" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "DNS1", "10.0.2.2" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "DNS2", "10.0.2.2" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "ARP", "ARP" ))){
measured_strings_destroy( & netif->configuration );
free( netif );
return ERROR_CODE;
}
/* if( ERROR_OCCURRED( add_configuration( & netif->configuration, "NAME", LO_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETIF", LO_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IL", IP_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_CONFIG", "STATIC" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ))){
measured_strings_destroy( & netif->configuration );
free( netif );
return ERROR_CODE;
}
*/ // mandatory name
setting = measured_strings_find( & netif->configuration, CONF_NAME, 0 );
if( ! setting ){
printf( "\nThe name is missing" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->name = setting->value;
// mandatory netif
setting = measured_strings_find( & netif->configuration, CONF_NETIF, 0 );
if( ! setting ){
printf( "\nThe network interface driver is missing" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->driver = modules_find( & networking_globals.modules, setting->value, 0 );
netif->driver = get_running_module( & networking_globals.modules, setting->value );
if( ! netif->driver ){
printf( "\nThe network interface driver is unknown" );
// TODO register the unknown one
measured_strings_destroy( & netif->configuration );
free( netif );
printf( "\nFailed to start the network interface driver %s", setting->value );
return EINVAL;
}
if( ! netif->driver->task_id ){
netif->driver->task_id = spawn( netif->driver->filename );
if( ! netif->driver->task_id ){
printf( "\nFailed to start the network interface driver" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
}
// optional network interface layer
setting = measured_strings_find( & netif->configuration, CONF_NIL, 0 );
if( setting ){
netif->nil = modules_find( & networking_globals.modules, setting->value, 0 );
netif->nil = get_running_module( & networking_globals.modules, setting->value );
if( ! netif->nil ){
printf( "\nThe network interface layer is unknown" );
// TODO register the unknown one
-- netif->driver->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
printf( "\nFailed to start the network interface layer %s", setting->value );
return EINVAL;
}
if( ! netif->nil->task_id ){
netif->nil->task_id = spawn( netif->nil->filename );
if( ! netif->nil->task_id ){
printf( "\nFailed to start the network interface layer" );
-- netif->driver->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
}
}else{
netif->nil = NULL;
}
// mandatory internet layer
setting = measured_strings_find( & netif->configuration, CONF_IL, 0 );
if( ! setting ){
printf( "\nThe internet layer is missing" );
-- netif->driver->usage;
-- netif->nil->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->il = modules_find( & networking_globals.modules, setting->value, 0 );
netif->il = get_running_module( & networking_globals.modules, setting->value );
if( ! netif->il ){
printf( "\nThe internet layer is unknown" );
// TODO register the unknown one
-- netif->driver->usage;
-- netif->nil->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
printf( "\nFailed to start the internet layer %s", setting->value );
return EINVAL;
}
if( ! netif->il->task_id ){
netif->il->task_id = spawn( netif->il->filename );
if( ! netif->il->task_id ){
printf( "\nFailed to start the internet layer" );
-- netif->driver->usage;
-- netif->nil->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
}
index = netifs_add( & networking_globals.netifs, netif->id, netif );
if( index < 0 ){
free( netif );
return index;
}
if( ERROR_OCCURRED( char_map_add( & networking_globals.netif_names, netif->name, 0, index ))){
netifs_exclude_index( & networking_globals.netifs, index );
return ERROR_CODE;
}
// end of the static loopback initialization
// startup the loopback interface
if( ! netif->driver->phone ){
netif->driver->phone = connect_to_service( netif->driver->service );
}
setting = measured_strings_find( & netif->configuration, CONF_IRQ, 0 );
irq = setting ? strtol( setting->value, NULL, 10 ) : 0;
setting = measured_strings_find( & netif->configuration, CONF_IO, 0 );
io = setting ? strtol( setting->value, NULL, 16 ) : 0;
ERROR_PROPAGATE( async_req_3_0( netif->driver->phone, NET_NETIF_PROBE, netif->id, irq, io ));
++ netif->driver->usage;
if( netif->nil ){
if( ! netif->nil->phone ){
netif->nil->phone = connect_to_service( netif->nil->service );
}
setting = measured_strings_find( & netif->configuration, CONF_MTU, 0 );
if( ! setting ){
setting = measured_strings_find( & networking_globals.configuration, CONF_MTU, 0 );
613,53 → 492,72
}
mtu = setting ? strtol( setting->value, NULL, 10 ) : 0;
ERROR_PROPAGATE( async_req_3_0( netif->nil->phone, NET_NIL_DEVICE, netif->id, netif->driver->service, mtu ));
++ netif->nil->usage;
internet_service = netif->nil->service;
}else{
internet_service = netif->driver->service;
}
if( ! netif->il->phone ){
netif->il->phone = connect_to_service( netif->il->service );
}
// TODO IL_BUNDLE
ERROR_PROPAGATE( async_req_2_0( netif->il->phone, NET_IL_DEVICE, netif->id, internet_service ));
++ netif->il->usage;
// TODO startup?
ERROR_PROPAGATE( async_req_1_0( netif->driver->phone, NET_NETIF_START, netif->id ));
printf( "\nNew network interface started:\n\tname\t= %s\n\tid\t= %d\n\tdriver\t= %s\n\tnil\t= %s\n\til\t= %s", netif->name, netif->id, netif->driver->name, netif->nil ? netif->nil->name : NULL, netif->il->name );
return EOK;
}
 
task_id_t spawn( char * fname ){
char * argv[ 2 ];
// char * argv[ 4 ];
task_id_t res;
 
// printf( "Spawning %s\n", fname );
argv[ 0 ] = fname;
argv[ 1 ] = NULL;
res = task_spawn( fname, argv );
/* argv[ 0 ] = "/app/trace";
argv[ 1 ] = "+ti";
argv[ 2 ] = fname;
argv[ 3 ] = NULL;
res = task_spawn( "/app/trace", argv );
*/
if( res != 0 ){
/* Success */
usleep( 50000 );
}
return res;
}
 
int startup( void ){
ERROR_DECLARE;
 
// read configuration files
if( ERROR_OCCURRED( read_configuration())) return ERROR_CODE;
char * conf_files[] = { "lo", "ne2k" };
int count = sizeof( conf_files ) / sizeof( char * );
int index;
netif_ref netif;
int i;
measured_string_ref setting;
 
// start network interfaces and needed modules
// start_device( "/sbin/lo", "/sbin/dummy_link_layer" );
// TODO dynamic configuration
ERROR_PROPAGATE( read_configuration());
 
for( i = 0; i < count; ++ i ){
netif = ( netif_ref ) malloc( sizeof( netif_t ));
if( ! netif ) return ENOMEM;
 
netif->id = generate_new_device_id();
if( ! netif->id ) return EXDEV;
ERROR_PROPAGATE( measured_strings_initialize( & netif->configuration ));
// read configuration files
if( ERROR_OCCURRED( read_netif_configuration( conf_files[ i ], netif ))){
measured_strings_destroy( & netif->configuration );
free( netif );
return ERROR_CODE;
}
// mandatory name
setting = measured_strings_find( & netif->configuration, CONF_NAME, 0 );
if( ! setting ){
printf( "\nThe name is missing" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->name = setting->value;
// add to the netifs map
index = netifs_add( & networking_globals.netifs, netif->id, netif );
if( index < 0 ){
measured_strings_destroy( & netif->configuration );
free( netif );
return index;
}
// add to the netif names map
if( ERROR_OCCURRED( char_map_add( & networking_globals.netif_names, netif->name, 0, index ))
// start network interfaces and needed modules
|| ERROR_OCCURRED( start_device( netif ))){
measured_strings_destroy( & netif->configuration );
netifs_exclude_index( & networking_globals.netifs, index );
return ERROR_CODE;
}
// increment modules' usage
++ netif->driver->usage;
if( netif->nil ) ++ netif->nil->usage;
++ netif->il->usage;
printf( "\nNew network interface started:\n\tname\t= %s\n\tid\t= %d\n\tdriver\t= %s\n\tnil\t= %s\n\til\t= %s", netif->name, netif->id, netif->driver->name, netif->nil ? netif->nil->name : NULL, netif->il->name );
}
return EOK;
}
 
/branches/network/uspace/srv/net/networking/Makefile
43,6 → 43,7
$(NET_BASE)modules.c \
$(STRUCTURES)char_map.c \
$(STRUCTURES)measured_strings.c \
$(STRUCTURES)module_map.c \
$(STRUCTURES)packet/packet.c \
$(STRUCTURES)packet/packet_server.c
# $(NET_BASE)self_test.c
/branches/network/uspace/srv/net/il/arp/arp.c
37,9 → 37,9
 
#include <async.h>
#include <malloc.h>
#include <mem.h>
#include <rwlock.h>
#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
192,6 → 192,7
ipc_call_t answer;
ipcarg_t result;
arp_proto_ref proto;
int index;
 
rwlock_write_lock( & arp_globals.lock );
// an existing device?
213,14 → 214,17
rwlock_write_unlock( & arp_globals.lock );
return ERROR_CODE;
}
if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){
index = arp_protos_add( & device->protos, proto->service, proto );
if( index < 0 ){
rwlock_write_unlock( & arp_globals.lock );
free( proto );
return ERROR_CODE;
return result;
}
}
printf( "\nCache of the existing device %d cleaned", device->device_id );
}else{
index = protocol_map( service, protocol );
if( ! index ) return ENOENT;
// create a new device
device = ( arp_device_ref ) malloc( sizeof( arp_device_t ));
if( ! device ){
227,6 → 231,7
rwlock_write_unlock( & arp_globals.lock );
return ENOMEM;
}
device->hardware = index;
device->device_id = device_id;
if( ERROR_OCCURRED( arp_protos_initialize( & device->protos ))
|| ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
234,15 → 239,22
free( device );
return ERROR_CODE;
}
if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){
index = arp_protos_add( & device->protos, proto->service, proto );
if( index < 0 ){
rwlock_write_unlock( & arp_globals.lock );
arp_protos_destroy( & device->protos );
free( device );
return ERROR_CODE;
return index;
}
device->service = service;
// bind the new one
device->phone = bind_service( device->service, device->device_id, SERVICE_ARP, 0, arp_receiver );
if( device->phone < 0 ){
rwlock_write_unlock( & arp_globals.lock );
arp_protos_destroy( & device->protos );
free( device );
return EREFUSED;
}
// get packet dimensions
if( ERROR_OCCURRED( async_req_1_4( device->phone, NET_NIL_PACKET_SPACE, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){
rwlock_write_unlock( & arp_globals.lock );
292,7 → 304,7
free( device );
return ERROR_CODE;
}
printf( "\nNew device registered:\n\tid\t= %d\n\ttype\t= %x\n\tservice\t= %d", device->device_id, device->hardware, device->service );
printf( "\nNew device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d", device->device_id, device->hardware, device->service );
}
rwlock_write_unlock( & arp_globals.lock );
return EOK;
345,7 → 357,7
length += device->addr->length;
memcpy((( uint8_t * ) header ) + length, proto->addr->value, proto->addr->length );
length += proto->addr->length;
memset((( uint8_t * ) header ) + length, 0, device->addr->length );
bzero((( uint8_t * ) header ) + length, device->addr->length );
length += device->addr->length;
memcpy((( uint8_t * ) header ) + length, target->value, target->length );
packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length ));
428,7 → 440,7
rwlock_read_unlock( & arp_globals.lock );
}else{
rwlock_read_unlock( & arp_globals.lock );
packet_release( arp_globals.networking_phone, packet_get_id( packet ));
pq_release( arp_globals.networking_phone, packet_get_id( packet ));
}
}
return EOK;
453,13 → 465,13
int count;
arp_proto_ref proto;
 
count = arp_protos_count( & device->protos );
while( count > 0 ){
for( count = arp_protos_count( & device->protos ) - 1; count >= 0; -- count ){
proto = arp_protos_get_index( & device->protos, count );
if( proto->addr ) free( proto->addr );
if( proto->addr_data ) free( proto->addr_data );
arp_addr_destroy( & proto->addresses );
-- count;
if( proto ){
if( proto->addr ) free( proto->addr );
if( proto->addr_data ) free( proto->addr_data );
arp_addr_destroy( & proto->addresses );
}
}
arp_protos_clear( & device->protos );
}
469,8 → 481,7
arp_device_ref device;
 
rwlock_write_lock( & arp_globals.lock );
count = arp_cache_count( & arp_globals.cache );
while( count > 0 ){
for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){
device = arp_cache_get_index( & arp_globals.cache, count );
if( device ){
clear_device( device );
/branches/network/uspace/srv/net/il/ip/ip.c
48,6 → 48,7
#include "../../include/socket.h"
#include "../../netif/device.h"
#include "../../structures/measured_strings.h"
#include "../../structures/module_map.h"
#include "../../structures/packet/packet_client.h"
 
#include "ip.h"
56,6 → 57,9
 
#define DEFAULT_IPV 4
 
#define ARP_NAME "arp"
#define ARP_FILENAME "/srv/arp"
 
#define IPC_GET_DEVICE( call ) ( device_id_t ) IPC_GET_ARG1( * call )
#define IPC_GET_PACKET( call ) ( packet_id_t ) IPC_GET_ARG1( * call )
#define IPC_GET_PROTO( call ) ( int ) IPC_GET_ARG1( * call )
76,8 → 80,12
/** Initializes the module.
*/
int ip_initialize( void ){
ip_netifs_initialize( & ip_globals.netifs );
ip_protos_initialize( & ip_globals.protos );
ERROR_DECLARE;
 
ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, 0 ));
return EOK;
}
 
93,7 → 101,7
int ip_device_message( device_id_t device_id, services_t service ){
ERROR_DECLARE;
 
ip_netif_ref ip_netif;
ip_netif_ref ip_netif;
aid_t message;
ipc_call_t answer;
measured_string_t configuration[ 9 ] = {{ "IPV", 3 }, { "IP_CONFIG", 9 }, { "IP_ADDR", 7 }, { "NETMASK", 7 }, { "GATEWAY", 7 }, { "BROADCAST", 9 }, { "DNS1", 4 }, { "DNS2", 4 }, { "ARP", 3 }};
100,6 → 108,8
int count = 9;
measured_string_ref settings;
char * data;
ipcarg_t result;
int index;
 
ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
if( ! ip_netif ) return ENOMEM;
111,8 → 121,18
if( ERROR_OCCURRED( measured_strings_send( ip_globals.networking_phone, configuration, count ))
|| ERROR_OCCURRED( measured_strings_return( ip_globals.networking_phone, & settings, & data, count ))){
async_wait_for( message, NULL );
free( ip_netif );
return ERROR_CODE;
}
async_wait_for( message, & result );
if( ERROR_OCCURRED( result )){
if( settings ){
free( settings );
free( data );
};
free( ip_netif );
return ERROR_CODE;
}
if( settings ){
if( settings[ 0 ].value ){
ip_netif->ipv = strtol( settings[ 0 ].value, NULL, 0 );
119,9 → 139,11
}else{
ip_netif->ipv = DEFAULT_IPV;
}
ip_netif->dhcp = ! strcmp( settings[ 1 ].value, "DHCP" );
ip_netif->dhcp = ! strncmp( settings[ 1 ].value, "dhcp", 4 );
if( ip_netif->dhcp ){
// TODO dhcp
free( settings );
free( data );
free( ip_netif );
return ENOTSUP;
}else if( ip_netif->ipv == 4 ){
131,27 → 153,64
|| ( inet_pton( AF_INET, settings[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast ) == EINVAL )
|| ( inet_pton( AF_INET, settings[ 6 ].value, ( uint8_t * ) & ip_netif->dns1 ) == EINVAL )
|| ( inet_pton( AF_INET, settings[ 7 ].value, ( uint8_t * ) & ip_netif->dns2 ) == EINVAL )){
free( settings );
free( data );
free( ip_netif );
return EINVAL;
}
}else{
// TODO ipv6
free( settings );
free( data );
free( ip_netif );
return ENOTSUP;
}
// TODO ARP module
if( settings[ 8 ].value ){
ip_netif->arp = get_running_module( & ip_globals.modules, settings[ 8 ].value );
if( ! ip_netif->arp ){
printf( "\nFailed to start the arp %s", settings[ 8 ].value );
free( settings );
free( data );
free( ip_netif );
return EINVAL;
}
}else{
ip_netif->arp = NULL;
}
free( settings );
free( data );
}
// TODO arp module
// TODO register
free( settings );
free( data );
// end request
// TODO mapping
async_wait_for( message, NULL );
ip_netif->phone = bind_service( service, ip_netif->device_id, SERVICE_IP, 0, ip_driver_receiver );
if( ip_netif->phone < 0 ){
printf( "\nFailed to contact the nil service %d", service );
free( ip_netif );
return ip_netif->phone;
}
if( ip_netif->arp ){
message = async_send_3( ip_netif->arp->phone, NET_ARP_DEVICE, ip_netif->device_id, SERVICE_IP, service, & answer );
configuration[ 0 ].value = ( char * ) & ip_netif->address;
configuration[ 0 ].length = CONVERT_SIZE( in_addr_t, char, 1 );
if( ERROR_OCCURRED( measured_strings_send( ip_netif->arp->phone, & configuration[ 0 ], 1 ))){
free( ip_netif );
return ERROR_CODE;
}
async_wait_for( message, & result );
if( ERROR_OCCURRED( result )){
free( ip_netif );
return ERROR_CODE;
}
}
index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif );
if( index < 0 ){
free( ip_netif );
return index;
}
if( ip_netif->arp ) ++ ip_netif->arp->usage;
// print the settings
printf( "\nNew device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d", ip_netif->device_id, ip_netif->phone, ip_netif->ipv );
printf( "\n\tconfiguration\t= %s", ip_netif->dhcp ? "dhcp" : "static" );
// TODO ipv6
// TODO ipv6 addresses
data = malloc( INET_ADDRSTRLEN );
if( data ){
inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->address, data, INET_ADDRSTRLEN );
168,12 → 227,6
printf( "\n\tdns2\t= %s", data );
free( data );
}
// TODO mapping
ip_netif->phone = bind_service( service, ip_netif->device_id, SERVICE_IP, 0, ip_driver_receiver );
if( ERROR_OCCURRED( ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif ))){
free( ip_netif );
return ERROR_CODE;
}
return EOK;
}
 
229,17 → 282,17
}
 
int ip_register_message( int protocol, int phone ){
ERROR_DECLARE;
 
ip_proto_ref proto;
int index;
 
proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
if( ! proto ) return ENOMEM;
proto->protocol = protocol;
proto->phone = phone;
if( ERROR_OCCURRED( ip_protos_add( & ip_globals.protos, proto->protocol, proto ))){
index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
if( index < 0 ){
free( proto );
return ERROR_CODE;
return index;
}
printf( "\nNew protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d", proto->protocol, proto->phone );
return EOK;
248,7 → 301,7
int ip_send_message( device_id_t device_id, packet_t packet ){
// TODO send packet
printf( "Packet to send via %d: %s", device_id, packet_get_data( packet ));
packet_release( ip_globals.networking_phone, packet_get_id( packet ));
pq_release( ip_globals.networking_phone, packet_get_id( packet ));
return EOK;
}
 
269,10 → 322,7
case IPC_M_CONNECT_TO_ME:
return ip_register_message( IPC_GET_PROTO( call ), IPC_GET_PHONE( call ));
case NET_IP_SEND:
if( ERROR_OCCURRED( packet_translate( ip_globals.networking_phone, & packet, IPC_GET_PACKET( call )))){
printf( "\nIP send E %d", ERROR_CODE );
return ERROR_CODE;
}
ERROR_PROPAGATE( packet_translate( ip_globals.networking_phone, & packet, IPC_GET_PACKET( call )));
return ip_send_message( IPC_GET_DEVICE( call ), packet );
}
return ENOTSUP;
/branches/network/uspace/srv/net/il/ip/Makefile
37,7 → 37,9
$(NAME).c \
$(NET_BASE)module.c \
$(NET_BASE)modules.c \
$(STRUCTURES)char_map.c \
$(STRUCTURES)measured_strings.c \
$(STRUCTURES)module_map.c \
$(STRUCTURES)packet/packet.c \
$(STRUCTURES)packet/packet_client.c \
$(NET_BASE)sockaddr.c
/branches/network/uspace/srv/net/il/ip/ip.h
42,6 → 42,8
#include "../../include/sockaddr.h"
#include "../../netif/device.h"
 
#include "../../structures/module_map.h"
 
typedef struct ip_netif ip_netif_t;
typedef ip_netif_t * ip_netif_ref;
 
57,6 → 59,7
struct ip_netif{
device_id_t device_id;
int phone;
module_ref arp;
int ipv;
int dhcp;
in_addr_t address;
77,6 → 80,7
int networking_phone;
ip_netifs_t netifs;
ip_protos_t protos;
modules_t modules;
};
 
#endif
/branches/network/uspace/srv/net/netif/netif.c
35,11 → 35,11
 
#include <async.h>
#include <mem.h>
#include <rwlock.h>
#include <stdio.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
//#include <sys/mman.h>
 
#include "../err.h"
#include "../messages.h"
51,6 → 51,7
 
#include "device.h"
#include "netif.h"
#include "netif_interface.h"
 
#define IPC_GET_DEVICE( call ) ( device_id_t ) IPC_GET_ARG1( * call )
#define IPC_GET_PACKET( call ) ( packet_id_t ) IPC_GET_ARG2( * call )
60,22 → 61,12
 
extern netif_globals_t netif_globals;
 
extern int initialize( void );
extern int probe_auto_message( void );
extern int probe_message( device_id_t device_id, int irq, int io );
extern int send_message( device_id_t device_id, packet_t packet );
extern int start_message( device_id_t device_id );
extern int stop_message( device_id_t device_id );
extern measured_string_ref get_addr_message( device_id_t device_id );
 
DEVICE_MAP_IMPLEMENT( device_map, device_t )
 
int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
int netif_start_module( async_client_conn_t client_connection );
int register_message( device_id_t device_id, int phone );
int get_device_stats( device_id_t device_id, device_stats_ref * stats );
 
 
int find_device( device_id_t device_id, device_ref * device ){
if( ! device ) return EBADMEM;
* device = device_map_find( & netif_globals.device_map, device_id );
84,17 → 75,6
return EOK;
}
 
int get_device_stats( device_id_t device_id, device_stats_ref * stats ){
ERROR_DECLARE;
 
device_ref device;
 
if( ! stats ) return EBADMEM;
ERROR_PROPAGATE( find_device( device_id, & device ));
* stats = & device->stats;
return EOK;
}
 
void null_device_stats( device_stats_ref stats ){
bzero( stats, sizeof( device_stats_t ));
}
115,38 → 95,68
ERROR_DECLARE;
 
size_t length;
device_stats_ref stats;
device_stats_t stats;
packet_t packet;
measured_string_ref address;
measured_string_t address;
 
// printf( "\nNETIF message %d", method );
* answer_count = 0;
switch( IPC_GET_METHOD( * call )){
case IPC_M_PHONE_HUNGUP:
return EOK;
case NET_NETIF_PROBE_AUTO:
return probe_auto_message();
rwlock_write_lock( & netif_globals.lock );
ERROR_CODE = probe_auto_message();
rwlock_write_unlock( & netif_globals.lock );
return ERROR_CODE;
case NET_NETIF_PROBE:
return probe_message( IPC_GET_DEVICE( call ), IPC_GET_IRQ( call ), IPC_GET_IO( call ));
rwlock_write_lock( & netif_globals.lock );
ERROR_CODE = probe_message( IPC_GET_DEVICE( call ), IPC_GET_IRQ( call ), IPC_GET_IO( call ));
rwlock_write_unlock( & netif_globals.lock );
return ERROR_CODE;
case IPC_M_CONNECT_TO_ME:
return register_message( IPC_GET_DEVICE( call ), IPC_GET_PHONE( call ));
rwlock_write_lock( & netif_globals.lock );
ERROR_CODE = register_message( IPC_GET_DEVICE( call ), IPC_GET_PHONE( call ));
rwlock_write_unlock( & netif_globals.lock );
return ERROR_CODE;
case NET_NETIF_SEND:
ERROR_PROPAGATE( packet_translate( netif_globals.networking_phone, & packet, IPC_GET_PACKET( call )));
return send_message( IPC_GET_DEVICE( call ), packet );
rwlock_write_lock( & netif_globals.lock );
if( ! ERROR_OCCURRED( packet_translate( netif_globals.networking_phone, & packet, IPC_GET_PACKET( call )))){
ERROR_CODE = send_message( IPC_GET_DEVICE( call ), packet );
}
rwlock_write_unlock( & netif_globals.lock );
return ERROR_CODE;
case NET_NETIF_START:
return start_message( IPC_GET_DEVICE( call ));
rwlock_write_lock( & netif_globals.lock );
ERROR_CODE = start_message( IPC_GET_DEVICE( call ));
rwlock_write_unlock( & netif_globals.lock );
return ERROR_CODE;
case NET_NETIF_STATS:
ERROR_PROPAGATE( ipc_data_read_receive( & callid, & length ));
if( length < sizeof( device_stats_t )) return EOVERFLOW;
ERROR_PROPAGATE( get_device_stats( IPC_GET_DEVICE( call ), & stats ));
return ipc_data_read_finalize( callid, stats, sizeof( device_stats_t ));
rwlock_read_lock( & netif_globals.lock );
if( ! ERROR_OCCURRED( ipc_data_read_receive( & callid, & length ))){
if( length < sizeof( device_stats_t )){
ERROR_CODE = EOVERFLOW;
}else{
if( ! ERROR_OCCURRED( get_device_stats( IPC_GET_DEVICE( call ), & stats ))){
ERROR_CODE = ipc_data_read_finalize( callid, & stats, sizeof( device_stats_t ));
}
}
}
rwlock_read_unlock( & netif_globals.lock );
return ERROR_CODE;
case NET_NETIF_STOP:
return stop_message( IPC_GET_DEVICE( call ));
rwlock_write_lock( & netif_globals.lock );
ERROR_CODE = stop_message( IPC_GET_DEVICE( call ));
rwlock_write_unlock( & netif_globals.lock );
return ERROR_CODE;
case NET_NETIF_GET_ADDR:
address = get_addr_message( IPC_GET_DEVICE( call ));
return address ? measured_strings_reply( address, 1 ) : ENOENT;
rwlock_read_lock( & netif_globals.lock );
if( ! ERROR_OCCURRED( get_addr_message( IPC_GET_DEVICE( call ), & address ))){
ERROR_CODE = measured_strings_reply( & address, 1 );
}
rwlock_read_unlock( & netif_globals.lock );
return ERROR_CODE;
}
return ENOTSUP;
return specific_message( callid, call, answer, answer_count );
}
 
int netif_start_module( async_client_conn_t client_connection ){
156,6 → 166,7
netif_globals.networking_phone = connect_to_service( SERVICE_NETWORKING );
device_map_initialize( & netif_globals.device_map );
ERROR_PROPAGATE( pm_init());
rwlock_initialize( & netif_globals.lock );
if( ERROR_OCCURRED( initialize())){
pm_destroy();
return ERROR_CODE;
167,5 → 178,13
return EOK;
}
 
void netif_pq_release( packet_id_t packet_id ){
pq_release( netif_globals.networking_phone, packet_id );
}
 
packet_t netif_packet_get_1( size_t content ){
return packet_get_1( netif_globals.networking_phone, content );
}
 
/** @}
*/
/branches/network/uspace/srv/net/netif/dp8390/dp8390_port.h
34,6 → 34,7
#define __NET_NETIF_DP8390_PORT_H__
 
#include <errno.h>
#include <mem.h>
#include <stdio.h>
#include <libarch/ddi.h>
#include <sys/types.h>
45,31 → 46,21
typedef uint8_t u8_t;
typedef uint16_t u16_t;
 
static inline int memcmp( const void * first, const void * second, size_t length ){
uint8_t * f;
uint8_t * s;
#define memcmp( first, second, size ) bcmp(( char * ) ( first ), ( char * ) ( second ), ( size ))
 
if( ! first ){
return second ? 1 : 0;
}
if( ! second ) return -1;
f = ( uint8_t * ) first;
s = ( uint8_t * ) second;
while(( length > 0 ) && (( * f ) == ( * s ))){
-- length;
++ f;
++ s;
}
return length ? ((( * f ) < ( * s )) ? 1 : -1 ): 0;
}
 
#define inb( port ) pio_read_8(( ioport8_t * ) ( port ))
#define inw( port ) pio_read_16(( ioport16_t * ) ( port ))
#define outb( port, value ) pio_write_8(( ioport8_t * ) ( port ), ( value ))
#define outw( port, value ) pio_write_16(( ioport16_t * ) ( port ), ( value ))
 
#define panic( ... ) { printf( __VA_ARGS__ ); return; }
#define panic( ... ) printf( "%s%s%d", __VA_ARGS__ )
 
#define sys_vircopy( proc, src_s, src, me, dst_s, dst, bytes ) ({ memcpy(( void * )( dst ), ( void * )( src ), ( bytes )); EOK; })
#define do_vir_insb( port, proc, src, bytes ) insb(( port ), ( void * )( src ), ( bytes ))
#define do_vir_insw( port, proc, src, bytes ) insw(( port ), ( void * )( src ), ( bytes ))
#define do_vir_outsb( port, proc, src, bytes ) outsb(( port ), ( void * )( src ), ( bytes ))
#define do_vir_outsw( port, proc, src, bytes ) outsw(( port ), ( void * )( src ), ( bytes ))
 
/* com.h */
/* Bits in 'DL_MODE' field of DL requests. */
# define DL_NOMODE 0x0
83,7 → 74,8
#define NO_NUM 0x8000 /* used as numerical argument to panic() */
 
/* devio.h */
typedef u16_t port_t;
//typedef u16_t port_t;
typedef int port_t;
 
/* dl_eth.h */
typedef struct eth_stat
/branches/network/uspace/srv/net/netif/dp8390/dp8390_module.h
34,19 → 34,14
#define __NET_NETIF_DP8390_MODULE_H__
 
#include "../../structures/measured_strings.h"
#include "../../structures/packet/packet.h"
 
#include "dp8390.h"
 
#define DP8390_IO_SIZE 0x01f
 
typedef struct dp_device dp_device_t;
typedef dp_device_t * dp_device_ref;
int netif_send_packet( dpeth_t * dep, packet_t packet );
 
struct dp_device{
struct dpeth dep;
measured_string_ref addr;
};
 
#endif
 
/** @}
/branches/network/uspace/srv/net/netif/dp8390/dp8390.c
21,7 → 21,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes:
* 2009 Lukas Medjrech ported to HelenOS
* 2009 Lukas Mejdrech ported to HelenOS
*/
 
/** @addtogroup dp8390
29,12 → 29,17
*/
 
#include <assert.h>
 
#include <errno.h>
 
#include "../../include/byteorder.h"
 
#include "../../structures/packet/packet.h"
#include "../../structures/packet/packet_client.h"
 
#include "../netif.h"
 
#include "dp8390_drv.h"
#include "dp8390_module.h"
#include "dp8390_port.h"
 
/*
52,6 → 57,10
#include "local.h"
#include "dp8390.h"
 
int queue_packet( dpeth_t * dep, packet_t packet );
static void outsb( port_t port, void * buf, size_t size );
static void outsw( port_t port, void * buf, size_t size );
 
//static u16_t eth_ign_proto;
//static char *progname;
 
118,27 → 127,27
//_PROTOTYPE( static void dp8390_stop, (void) );
_PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
size_t offset, size_t size, void *dst) );
//_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
// size_t offset, size_t size, void *dst) );
//_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
// size_t offset, size_t size, void *dst) );
_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
size_t offset, size_t size, void *dst) );
_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
size_t offset, size_t size, void *dst) );
_PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
int length) );
//_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
// int length) );
//_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
// vir_bytes offset, int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
vir_bytes offset, int nic_addr, vir_bytes count) );
//_PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
// vir_bytes offset, int nic_addr, vir_bytes count) );
//_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
// iovec_dat_t *iovp, vir_bytes offset,
// int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
iovec_dat_t *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
//_PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
// iovec_dat_s_t *iovp, vir_bytes offset,
// int nic_addr, vir_bytes count) );
//_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
// iovec_dat_t *iovp, vir_bytes offset,
// int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
iovec_dat_t *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
//_PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
// iovec_dat_s_t *iovp, vir_bytes offset,
// int nic_addr, vir_bytes count) );
146,15 → 155,15
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
//_PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
// iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
//_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
// iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
//_PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
// iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
//_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
// iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
//_PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
// iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
//_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
//_PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp) );
_PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
//_PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
163,8 → 172,8
//_PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp) );
_PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) );
//_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
//_PROTOTYPE( static void get_userdata, (int user_proc,
// vir_bytes user_addr, vir_bytes count, void *loc_addr) );
_PROTOTYPE( static void get_userdata, (int user_proc,
vir_bytes user_addr, vir_bytes count, void *loc_addr) );
//_PROTOTYPE( static void get_userdata_s, (int user_proc,
// cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
// void *loc_addr) );
172,8 → 181,8
// vir_bytes user_addr, vir_bytes count, void *loc_addr) );
//_PROTOTYPE( static void put_userdata_s, (int user_proc,
// cp_grant_id_t grant, size_t count, void *loc_addr) );
//_PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
//_PROTOTYPE( static void insw, (port_t port, void *buf, size_t size) );
_PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
_PROTOTYPE( static void insw, (port_t port, void *buf, size_t size) );
//_PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
// vir_bytes buf, size_t size) );
//_PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
258,7 → 267,136
}
}
 
int queue_packet( dpeth_t * dep, packet_t packet ){
packet_t tmp;
 
if( dep->packet_count > 1 ){
if( ! pq_add( pq_previous( dep->packet_queue ), packet, 0, 0 )){
return EINVAL;
}
}else{
tmp = pq_add( dep->packet_queue, packet, 0, 0 );
if( ! tmp ) return EINVAL;
dep->packet_queue = tmp;
}
++ dep->packet_count;
return EBUSY;
}
 
/*===========================================================================*
* based on do_vwrite *
*===========================================================================*/
int do_pwrite( dpeth_t * dep, packet_t packet, int from_int )
{
// int port, count, size;
int size;
int sendq_head;
/* dpeth_t *dep;
 
port = mp->DL_PORT;
count = mp->DL_COUNT;
if (port < 0 || port >= DE_PORT_NR)
panic("", "dp8390: illegal port", port);
dep= &de_table[port];
dep->de_client= mp->DL_PROC;
*/
if (dep->de_mode == DEM_SINK)
{
assert(!from_int);
dep->de_flags |= DEF_PACK_SEND;
reply(dep, OK, FALSE);
// return;
return EOK;
}
assert(dep->de_mode == DEM_ENABLED);
assert(dep->de_flags & DEF_ENABLED);
if (dep->de_flags & DEF_SEND_AVAIL){
// panic("", "dp8390: send already in progress", NO_NUM);
return queue_packet( dep, packet );
}
 
sendq_head= dep->de_sendq_head;
if (dep->de_sendq[sendq_head].sq_filled)
{
if (from_int)
panic("", "dp8390: should not be sending\n", NO_NUM);
// dep->de_sendmsg= *mp;
dep->de_flags |= DEF_SEND_AVAIL;
reply(dep, OK, FALSE);
// return;
return queue_packet( dep, packet );
}
assert(!(dep->de_flags & DEF_PACK_SEND));
 
/* if (vectored)
{
get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
(count > IOVEC_NR ? IOVEC_NR : count) *
sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
dep->de_write_iovec.iod_iovec_s = count;
dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
 
dep->de_tmp_iovec = dep->de_write_iovec;
size = calc_iovec_size(&dep->de_tmp_iovec);
}
else
{
dep->de_write_iovec.iod_iovec[0].iov_addr =
(vir_bytes) mp->DL_ADDR;
dep->de_write_iovec.iod_iovec[0].iov_size =
mp->DL_COUNT;
dep->de_write_iovec.iod_iovec_s = 1;
dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
dep->de_write_iovec.iod_iovec_addr = 0;
size= mp->DL_COUNT;
}
*/
size = packet_get_data_length( packet );
dep->de_write_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_get_data( packet );
dep->de_write_iovec.iod_iovec[0].iov_size = size;
dep->de_write_iovec.iod_iovec_s = 1;
dep->de_write_iovec.iod_iovec_addr = NULL;
 
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
{
panic("", "dp8390: invalid packet size", size);
return EINVAL;
}
(dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
size);
dep->de_sendq[sendq_head].sq_filled= TRUE;
if (dep->de_sendq_tail == sendq_head)
{
outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
outb_reg0(dep, DP_TBCR1, size >> 8);
outb_reg0(dep, DP_TBCR0, size & 0xff);
outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
}
else
dep->de_sendq[sendq_head].sq_size= size;
if (++sendq_head == dep->de_sendq_nr)
sendq_head= 0;
assert(sendq_head < SENDQ_NR);
dep->de_sendq_head= sendq_head;
 
dep->de_flags |= DEF_PACK_SEND;
 
/* If the interrupt handler called, don't send a reply. The reply
* will be sent after all interrupts are handled.
*/
if (from_int)
return EOK;
reply(dep, OK, FALSE);
 
assert(dep->de_mode == DEM_ENABLED);
assert(dep->de_flags & DEF_ENABLED);
return EOK;
}
 
/*===========================================================================*
* dp_init *
*===========================================================================*/
void dp_init(dep)
353,30 → 491,30
dep->de_sendq[i].sq_filled= 0;
dep->de_sendq_head= 0;
dep->de_sendq_tail= 0;
// if (!dep->de_prog_IO)
// {
// dep->de_user2nicf= dp_user2nic;
if (!dep->de_prog_IO)
{
dep->de_user2nicf= dp_user2nic;
// dep->de_user2nicf_s= dp_user2nic_s;
dep->de_nic2userf= dp_nic2user;
// dep->de_nic2userf_s= dp_nic2user_s;
dep->de_getblockf= dp_getblock;
// }
// else if (dep->de_16bit)
// {
// dep->de_user2nicf= dp_pio16_user2nic;
}
else if (dep->de_16bit)
{
dep->de_user2nicf= dp_pio16_user2nic;
// dep->de_user2nicf_s= dp_pio16_user2nic_s;
// dep->de_nic2userf= dp_pio16_nic2user;
dep->de_nic2userf= dp_pio16_nic2user;
// dep->de_nic2userf_s= dp_pio16_nic2user_s;
// dep->de_getblockf= dp_pio16_getblock;
// }
// else
// {
// dep->de_user2nicf= dp_pio8_user2nic;
dep->de_getblockf= dp_pio16_getblock;
}
else
{
dep->de_user2nicf= dp_pio8_user2nic;
// dep->de_user2nicf_s= dp_pio8_user2nic_s;
// dep->de_nic2userf= dp_pio8_nic2user;
dep->de_nic2userf= dp_pio8_nic2user;
// dep->de_nic2userf_s= dp_pio8_nic2user_s;
// dep->de_getblockf= dp_pio8_getblock;
// }
dep->de_getblockf= dp_pio8_getblock;
}
 
/* Set the interrupt handler and policy. Do not automatically
* reenable interrupts. Return the IRQ line number on interrupts.
692,11 → 830,20
static void dp_send(dep)
dpeth_t *dep;
{
/* if (!(dep->de_flags & DEF_SEND_AVAIL))
packet_t packet;
 
if (!(dep->de_flags & DEF_SEND_AVAIL))
return;
 
dep->de_flags &= ~DEF_SEND_AVAIL;
switch(dep->de_sendmsg.m_type)
while( dep->packet_queue ){
packet = dep->packet_queue;
dep->packet_queue = pq_detach( packet );
do_pwrite( dep, packet, TRUE );
netif_pq_release( packet_get_id( packet ));
-- dep->packet_count;
}
/* switch(dep->de_sendmsg.m_type)
{
case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
726,6 → 873,47
}
 
/*===========================================================================*
* dp_pio8_getblock *
*===========================================================================*/
static void dp_pio8_getblock(dep, page, offset, size, dst)
dpeth_t *dep;
int page;
size_t offset;
size_t size;
void *dst;
{
offset = page * DP_PAGESIZE + offset;
outb_reg0(dep, DP_RBCR0, size & 0xFF);
outb_reg0(dep, DP_RBCR1, size >> 8);
outb_reg0(dep, DP_RSAR0, offset & 0xFF);
outb_reg0(dep, DP_RSAR1, offset >> 8);
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
 
insb(dep->de_data_port, dst, size);
}
 
/*===========================================================================*
* dp_pio16_getblock *
*===========================================================================*/
static void dp_pio16_getblock(dep, page, offset, size, dst)
dpeth_t *dep;
int page;
size_t offset;
size_t size;
void *dst;
{
offset = page * DP_PAGESIZE + offset;
outb_reg0(dep, DP_RBCR0, size & 0xFF);
outb_reg0(dep, DP_RBCR1, size >> 8);
outb_reg0(dep, DP_RSAR0, offset & 0xFF);
outb_reg0(dep, DP_RSAR1, offset >> 8);
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
 
assert (!(size & 1));
insw(dep->de_data_port, dst, size);
}
 
/*===========================================================================*
* dp_pkt2user *
*===========================================================================*/
static int dp_pkt2user(dep, page, length)
733,10 → 921,18
int page, length;
{
int last, count;
packet_t packet;
 
if (!(dep->de_flags & DEF_READING))
return EGENERIC;
 
packet = netif_packet_get_1( length );
if( ! packet ) return ENOMEM;
dep->de_read_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_suffix( packet, length );
dep->de_read_iovec.iod_iovec[0].iov_size = length;
dep->de_read_iovec.iod_iovec_s = 1;
dep->de_read_iovec.iod_iovec_addr = NULL;
 
last = page + (length - 1) / DP_PAGESIZE;
if (last >= dep->de_stoppage)
{
760,10 → 956,231
dep->de_flags |= DEF_PACK_RECV;
dep->de_flags &= ~DEF_READING;
 
if( netif_send_packet( dep, packet ) != EOK ){
netif_pq_release( packet_get_id( packet ));
}
return OK;
}
 
/*===========================================================================*
* dp_user2nic *
*===========================================================================*/
static void dp_user2nic(dep, iovp, offset, nic_addr, count)
dpeth_t *dep;
iovec_dat_t *iovp;
vir_bytes offset;
int nic_addr;
vir_bytes count;
{
vir_bytes vir_hw;//, vir_user;
int bytes, i, r;
 
vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
 
i= 0;
while (count > 0)
{
if (i >= IOVEC_NR)
{
dp_next_iovec(iovp);
i= 0;
continue;
}
assert(i < iovp->iod_iovec_s);
if (offset >= iovp->iod_iovec[i].iov_size)
{
offset -= iovp->iod_iovec[i].iov_size;
i++;
continue;
}
bytes = iovp->iod_iovec[i].iov_size - offset;
if (bytes > count)
bytes = count;
 
r= sys_vircopy(iovp->iod_proc_nr, D,
iovp->iod_iovec[i].iov_addr + offset,
SELF, D, vir_hw, bytes);
if (r != OK)
panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
 
count -= bytes;
vir_hw += bytes;
offset += bytes;
}
assert(count == 0);
}
 
/*===========================================================================*
* dp_pio8_user2nic *
*===========================================================================*/
static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
dpeth_t *dep;
iovec_dat_t *iovp;
vir_bytes offset;
int nic_addr;
vir_bytes count;
{
// phys_bytes phys_user;
int bytes, i;
 
outb_reg0(dep, DP_ISR, ISR_RDC);
 
outb_reg0(dep, DP_RBCR0, count & 0xFF);
outb_reg0(dep, DP_RBCR1, count >> 8);
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
 
i= 0;
while (count > 0)
{
if (i >= IOVEC_NR)
{
dp_next_iovec(iovp);
i= 0;
continue;
}
assert(i < iovp->iod_iovec_s);
if (offset >= iovp->iod_iovec[i].iov_size)
{
offset -= iovp->iod_iovec[i].iov_size;
i++;
continue;
}
bytes = iovp->iod_iovec[i].iov_size - offset;
if (bytes > count)
bytes = count;
 
do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
iovp->iod_iovec[i].iov_addr + offset, bytes);
count -= bytes;
offset += bytes;
}
assert(count == 0);
 
for (i= 0; i<100; i++)
{
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
break;
}
if (i == 100)
{
panic("", "dp8390: remote dma failed to complete", NO_NUM);
}
}
 
/*===========================================================================*
* dp_pio16_user2nic *
*===========================================================================*/
static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
dpeth_t *dep;
iovec_dat_t *iovp;
vir_bytes offset;
int nic_addr;
vir_bytes count;
{
vir_bytes vir_user;
vir_bytes ecount;
int i, r, bytes, user_proc;
u8_t two_bytes[2];
int odd_byte;
 
ecount= (count+1) & ~1;
odd_byte= 0;
 
outb_reg0(dep, DP_ISR, ISR_RDC);
outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
outb_reg0(dep, DP_RBCR1, ecount >> 8);
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
 
i= 0;
while (count > 0)
{
if (i >= IOVEC_NR)
{
dp_next_iovec(iovp);
i= 0;
continue;
}
assert(i < iovp->iod_iovec_s);
if (offset >= iovp->iod_iovec[i].iov_size)
{
offset -= iovp->iod_iovec[i].iov_size;
i++;
continue;
}
bytes = iovp->iod_iovec[i].iov_size - offset;
if (bytes > count)
bytes = count;
 
user_proc= iovp->iod_proc_nr;
vir_user= iovp->iod_iovec[i].iov_addr + offset;
if (odd_byte)
{
r= sys_vircopy(user_proc, D, vir_user,
SELF, D, (vir_bytes)&two_bytes[1], 1);
if (r != OK)
{
panic("DP8390",
"dp_pio16_user2nic: sys_vircopy failed",
r);
}
outw(dep->de_data_port, *(u16_t *)two_bytes);
count--;
offset++;
bytes--;
vir_user++;
odd_byte= 0;
if (!bytes)
continue;
}
ecount= bytes & ~1;
if (ecount != 0)
{
do_vir_outsw(dep->de_data_port, user_proc, vir_user,
ecount);
count -= ecount;
offset += ecount;
bytes -= ecount;
vir_user += ecount;
}
if (bytes)
{
assert(bytes == 1);
r= sys_vircopy(user_proc, D, vir_user,
SELF, D, (vir_bytes)&two_bytes[0], 1);
if (r != OK)
{
panic("DP8390",
"dp_pio16_user2nic: sys_vircopy failed",
r);
}
count--;
offset++;
bytes--;
vir_user++;
odd_byte= 1;
}
}
assert(count == 0);
 
if (odd_byte)
outw(dep->de_data_port, *(u16_t *)two_bytes);
 
for (i= 0; i<100; i++)
{
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
break;
}
if (i == 100)
{
panic("", "dp8390: remote dma failed to complete", NO_NUM);
}
}
 
/*===========================================================================*
* dp_nic2user *
*===========================================================================*/
static void dp_nic2user(dep, nic_addr, iovp, offset, count)
773,7 → 1190,7
vir_bytes offset;
vir_bytes count;
{
/* vir_bytes vir_hw, vir_user;
vir_bytes vir_hw;//, vir_user;
int bytes, i, r;
 
vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
809,11 → 1226,170
offset += bytes;
}
assert(count == 0);
*/
printf("n2u");
}
 
/*===========================================================================*
* dp_pio8_nic2user *
*===========================================================================*/
static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
dpeth_t *dep;
int nic_addr;
iovec_dat_t *iovp;
vir_bytes offset;
vir_bytes count;
{
// phys_bytes phys_user;
int bytes, i;
 
outb_reg0(dep, DP_RBCR0, count & 0xFF);
outb_reg0(dep, DP_RBCR1, count >> 8);
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
 
i= 0;
while (count > 0)
{
if (i >= IOVEC_NR)
{
dp_next_iovec(iovp);
i= 0;
continue;
}
assert(i < iovp->iod_iovec_s);
if (offset >= iovp->iod_iovec[i].iov_size)
{
offset -= iovp->iod_iovec[i].iov_size;
i++;
continue;
}
bytes = iovp->iod_iovec[i].iov_size - offset;
if (bytes > count)
bytes = count;
 
do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
iovp->iod_iovec[i].iov_addr + offset, bytes);
count -= bytes;
offset += bytes;
}
assert(count == 0);
}
 
/*===========================================================================*
* dp_pio16_nic2user *
*===========================================================================*/
static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
dpeth_t *dep;
int nic_addr;
iovec_dat_t *iovp;
vir_bytes offset;
vir_bytes count;
{
vir_bytes vir_user;
vir_bytes ecount;
int i, r, bytes, user_proc;
u8_t two_bytes[2];
int odd_byte;
 
ecount= (count+1) & ~1;
odd_byte= 0;
 
outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
outb_reg0(dep, DP_RBCR1, ecount >> 8);
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
 
i= 0;
while (count > 0)
{
if (i >= IOVEC_NR)
{
dp_next_iovec(iovp);
i= 0;
continue;
}
assert(i < iovp->iod_iovec_s);
if (offset >= iovp->iod_iovec[i].iov_size)
{
offset -= iovp->iod_iovec[i].iov_size;
i++;
continue;
}
bytes = iovp->iod_iovec[i].iov_size - offset;
if (bytes > count)
bytes = count;
 
user_proc= iovp->iod_proc_nr;
vir_user= iovp->iod_iovec[i].iov_addr + offset;
if (odd_byte)
{
r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
user_proc, D, vir_user, 1);
if (r != OK)
{
panic("DP8390",
"dp_pio16_nic2user: sys_vircopy failed",
r);
}
count--;
offset++;
bytes--;
vir_user++;
odd_byte= 0;
if (!bytes)
continue;
}
ecount= bytes & ~1;
if (ecount != 0)
{
do_vir_insw(dep->de_data_port, user_proc, vir_user,
ecount);
count -= ecount;
offset += ecount;
bytes -= ecount;
vir_user += ecount;
}
if (bytes)
{
assert(bytes == 1);
*(u16_t *)two_bytes= inw(dep->de_data_port);
r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
user_proc, D, vir_user, 1);
if (r != OK)
{
panic("DP8390",
"dp_pio16_nic2user: sys_vircopy failed",
r);
}
count--;
offset++;
bytes--;
vir_user++;
odd_byte= 1;
}
}
assert(count == 0);
}
 
/*===========================================================================*
* dp_next_iovec *
*===========================================================================*/
static void dp_next_iovec(iovp)
iovec_dat_t *iovp;
{
assert(iovp->iod_iovec_s > IOVEC_NR);
 
iovp->iod_iovec_s -= IOVEC_NR;
 
iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
 
get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
(iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
sizeof(iovec_t), iovp->iod_iovec);
}
 
/*===========================================================================*
* conf_hw *
*===========================================================================*/
static void conf_hw(dep)
859,14 → 1435,16
 
if (dep->de_prog_IO)
{
//#if 0
#if 0
if(debug){
printf(
"map_hw_buffer: programmed I/O, no need to map buffer\n");
}
//#endif
#endif
dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
return;
}else{
printf( "map_hw_buffer: no buffer!" );
}
 
// size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for
927,6 → 1505,59
*/ dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
}
 
/*===========================================================================*
* get_userdata *
*===========================================================================*/
static void get_userdata(user_proc, user_addr, count, loc_addr)
int user_proc;
vir_bytes user_addr;
vir_bytes count;
void *loc_addr;
{
int r;
 
r= sys_vircopy(user_proc, D, user_addr,
SELF, D, (vir_bytes)loc_addr, count);
if (r != OK)
panic("DP8390", "get_userdata: sys_vircopy failed", r);
}
 
static void insb(port_t port, void *buf, size_t size)
{
int i;
 
for( i = 0; i < size; ++ i ){
*(( uint8_t * )( buf + i )) = inb( port );
}
}
 
static void insw(port_t port, void *buf, size_t size)
{
int i;
 
for( i = 0; i < size; i += 2 ){
*(( uint16_t * )( buf + i )) = inw( port );
}
}
 
static void outsb(port_t port, void *buf, size_t size)
{
int i;
 
for( i = 0; i < size; ++ i ){
outb( port, *(( uint8_t * )( buf + i )));
}
}
 
static void outsw(port_t port, void *buf, size_t size)
{
int i;
 
for( i = 0; i < size; i += 2 ){
outw( port, *(( uint16_t * )( buf + i )));
}
}
 
/*
* $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
*/
/branches/network/uspace/srv/net/netif/dp8390/dp8390_drv.h
37,12 → 37,12
#define __NET_NETIF_DP8390_DRIVER_H__
 
#include "dp8390.h"
#include "dp8390_port.h"
 
_PROTOTYPE( int do_init, (dpeth_t *dep, int mode) );
_PROTOTYPE( void do_stop, (dpeth_t *dep) );
_PROTOTYPE( void dp_check_ints, (dpeth_t *dep) );
int do_probe( dpeth_t * dep );
int do_probe( dpeth_t * dep );
int do_pwrite( dpeth_t * dep, packet_t packet, int from_int );
 
#endif
 
/branches/network/uspace/srv/net/netif/dp8390/dp8390.h
35,6 → 35,8
#ifndef __NET_NETIF_DP8390_H__
#define __NET_NETIF_DP8390_H__
 
#include "../../structures/packet/packet.h"
 
#include "dp8390_port.h"
#include "local.h"
 
216,9 → 218,9
//struct iovec_dat_s;
_PROTOTYPE( typedef void (*dp_initf_t), (struct dpeth *dep) );
_PROTOTYPE( typedef void (*dp_stopf_t), (struct dpeth *dep) );
//_PROTOTYPE( typedef void (*dp_user2nicf_t), (struct dpeth *dep,
// struct iovec_dat *iovp, vir_bytes offset,
// int nic_addr, vir_bytes count) );
_PROTOTYPE( typedef void (*dp_user2nicf_t), (struct dpeth *dep,
struct iovec_dat *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
//_PROTOTYPE( typedef void (*dp_user2nicf_s_t), (struct dpeth *dep,
// struct iovec_dat_s *iovp, vir_bytes offset,
// int nic_addr, vir_bytes count) );
236,7 → 238,9
int page, size_t offset, size_t size, void *dst) );
 
/* iovectors are handled IOVEC_NR entries at a time. */
#define IOVEC_NR 16
//#define IOVEC_NR 16
// no vectors allowed
#define IOVEC_NR 1
 
/*
typedef int irq_hook_t;
245,6 → 249,7
{
iovec_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
// no direct process access
int iod_proc_nr;
vir_bytes iod_iovec_addr;
} iovec_dat_t;
263,6 → 268,14
 
typedef struct dpeth
{
/* Parent device structure.
*/
void * parent;
/* Packet send queue.
*/
packet_t packet_queue;
int packet_count;
 
/* The de_base_port field is the starting point of the probe.
* The conf routine also fills de_linmem and de_irq. If the probe
* routine knows the irq and/or memory address because they are
325,7 → 338,7
iovec_dat_t de_read_iovec;
// iovec_dat_s_t de_read_iovec_s;
// int de_safecopy_read;
// iovec_dat_t de_write_iovec;
iovec_dat_t de_write_iovec;
// iovec_dat_s_t de_write_iovec_s;
iovec_dat_t de_tmp_iovec;
// iovec_dat_s_t de_tmp_iovec_s;
332,7 → 345,7
vir_bytes de_read_s;
// int de_client;
// message de_sendmsg;
// dp_user2nicf_t de_user2nicf;
dp_user2nicf_t de_user2nicf;
// dp_user2nicf_s_t de_user2nicf_s;
dp_nic2userf_t de_nic2userf;
// dp_nic2userf_s_t de_nic2userf_s;
/branches/network/uspace/srv/net/netif/dp8390/dp8390_module.c
34,16 → 34,12
*/
 
#include <assert.h>
//#include <async.h>
#include <ddi.h>
#include <errno.h>
#include <malloc.h>
#include <mem.h>
//#include <stdio.h>
//#include <sysinfo.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
//#include <sys/types.h>
 
#include "../../err.h"
#include "../../messages.h"
52,19 → 48,18
#include "../../structures/packet/packet_client.h"
#include "../../structures/measured_strings.h"
 
#include "../device.h"
#include "../netif.h"
#include "../netif_interface.h"
 
#include "dp8390.h"
#include "dp8390_drv.h"
#include "dp8390_module.h"
#include "dp8390_port.h"
//#include "local.h"
#include "../device.h"
#include "../netif.h"
 
//TODO sync stats
 
#define NAME "dp8390 network interface"
 
#define IPC_GET_DEVICE( call ) ( device_id_t ) IPC_GET_ARG1( * call )
#define IPC_GET_DEVICE( call ) ( device_id_t ) IPC_GET_METHOD( * call )
#define IPC_GET_ISR( call ) ( int ) IPC_GET_ARG2( * call )
 
static irq_cmd_t dp8390_cmds[] = {
77,10 → 72,9
.value = 2,
.srcarg = 2
},
{//TODO remember device_id
.cmd = CMD_ACCEPT,
.value = 0,
.dstarg = 1,
{ .cmd = CMD_PIO_WRITE_8,
.addr = NULL,
.srcarg = 2
},
{
.cmd = CMD_ACCEPT
94,58 → 88,84
 
netif_globals_t netif_globals;
 
void netif_print_name( void );
int initialize( void );
int probe_auto_message( void );
int probe_message( device_id_t device_id, int irq, int io );
int send_message( device_id_t device_id, packet_t packet );
int start_message( device_id_t device_id );
int stop_message( device_id_t device_id );
measured_string_ref get_addr_message( device_id_t device_id );
void netif_print_name( void );
 
static void irq_handler( ipc_callid_t iid, ipc_call_t * call );
void irq_handler( ipc_callid_t iid, ipc_call_t * call );
void change_state( device_ref device, device_state_t state );
 
int specific_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
return ENOTSUP;
}
 
int get_device_stats( device_id_t device_id, device_stats_ref stats ){
ERROR_DECLARE;
 
device_ref device;
eth_stat_t * de_stat;
 
if( ! stats ) return EBADMEM;
ERROR_PROPAGATE( find_device( device_id, & device ));
de_stat = & (( dpeth_t * ) device->specific )->de_stat;
null_device_stats( stats );
stats->rx_errors = de_stat->ets_recvErr;
stats->tx_errors = de_stat->ets_sendErr;
stats->rx_crc_errors = de_stat->ets_CRCerr;
stats->rx_frame_errors = de_stat->ets_frameAll;
stats->rx_missed_errors = de_stat->ets_missedP;
stats->rx_packets = de_stat->ets_packetR;
stats->tx_packets = de_stat->ets_packetT;
stats->collisions = de_stat->ets_collision;
stats->tx_aborted_errors = de_stat->ets_transAb;
stats->tx_carrier_errors = de_stat->ets_carrSense;
stats->tx_heartbeat_errors = de_stat->ets_CDheartbeat;
stats->tx_window_errors = de_stat->ets_OWC;
return EOK;
}
 
void netif_print_name( void ){
printf( NAME );
}
 
measured_string_ref get_addr_message( device_id_t device_id ){
int get_addr_message( device_id_t device_id, measured_string_ref address ){
ERROR_DECLARE;
 
device_ref device;
 
if( ERROR_OCCURRED( find_device( device_id, & device ))) return NULL;
return (( dp_device_ref )( device->specific ))->addr;
if( ! address ) return EBADMEM;
ERROR_PROPAGATE( find_device( device_id, & device ));
address->value = ( char * ) ( & (( dpeth_t * ) device->specific )->de_address );
address->length = CONVERT_SIZE( ether_addr_t, char, 1 );
return EOK;
}
 
static void irq_handler( ipc_callid_t iid, ipc_call_t * call )
void irq_handler( ipc_callid_t iid, ipc_call_t * call )
{
// int irq;
device_ref device;
dpeth_t * dep;
 
if( find_device( IPC_GET_DEVICE( call ), & device ) == EOK ){
dep = & (( dp_device_ref ) device->specific )->dep;
printf( "\ndev %d, irq %x\n", device->device_id, IPC_GET_ISR( call ));
if ( dep->de_mode != DEM_ENABLED)
// continue;
return;
assert( dep->de_flags & DEF_ENABLED);
// irq= dep.de_irq;
// assert(irq >= 0 && irq < NR_IRQ_VECTORS);
if ( dep->de_int_pending || 1)
printf( "\ndevice %d - irq %x", IPC_GET_DEVICE( call ), IPC_GET_ISR( call ));
if( find_device( IPC_GET_DEVICE( call ), & device ) != EOK ) return;
dep = ( dpeth_t * ) device->specific;
printf( "\ndev %d, irq %x\n", device->device_id, IPC_GET_ISR( call ));
if ( dep->de_mode != DEM_ENABLED)
// continue;
return;
assert( dep->de_flags & DEF_ENABLED);
// irq= dep.de_irq;
// assert(irq >= 0 && irq < NR_IRQ_VECTORS);
// if ( dep->de_int_pending || 1)
// {
dep->de_int_pending= 0;
dp_check_ints( dep );
// do_int(dep);
/* r= sys_irqenable(&dep->de_hook);
if (r != OK)
{
dep->de_int_pending= 0;
dp_check_ints( dep );
// do_int(dep);
/* r= sys_irqenable(&dep->de_hook);
if (r != OK)
{
panic("DP8390",
"unable enable interrupts", r);
}
*/ }
}
panic("DP8390",
"unable enable interrupts", r);
}
*/// }
}
 
int probe_auto_message( void ){
155,42 → 175,35
int probe_message( device_id_t device_id, int irq, int io ){
ERROR_DECLARE;
 
device_ref device;
dp_device_ref dp_device;
device_ref device;
dpeth_t * dep;
 
printf( "\n" );
device = ( device_ref ) malloc( sizeof( device_t ));
if( ! device ) return ENOMEM;
dp_device = ( dp_device_ref ) malloc( sizeof( dp_device_t ));
if( ! dp_device ){
dep = ( dpeth_t * ) malloc( sizeof( dpeth_t ));
if( ! dep ){
free( device );
return ENOMEM;
}
bzero( device, sizeof( device_t ));
bzero( dp_device, sizeof( dp_device_t ));
bzero( dep, sizeof( dpeth_t ));
device->device_id = device_id;
device->nil_phone = -1;
device->specific = ( void * ) dp_device;
device->state = NETIF_ACTIVE;
dp_device->dep.de_irq = irq;
// dp_device->dep.de_base_port = io;
dp_device->dep.de_mode = DEM_DISABLED;
device->specific = ( void * ) dep;
device->state = NETIF_STOPPED;
dep->parent = device;
dep->de_irq = irq;
dep->de_mode = DEM_DISABLED;
//TODO address?
if( ERROR_OCCURRED( pio_enable(( void * ) io, DP8390_IO_SIZE, ( void ** ) & dp_device->dep.de_base_port ))
|| ERROR_OCCURRED( do_probe( & dp_device->dep ))){
free( dp_device );
if( ERROR_OCCURRED( pio_enable(( void * ) io, DP8390_IO_SIZE, ( void ** ) & dep->de_base_port ))
|| ERROR_OCCURRED( do_probe( dep ))){
free( dep );
free( device );
return ERROR_CODE;
}
dp_device->addr = measured_string_create_bulk(( char * ) & dp_device->dep.de_address, CONVERT_SIZE( ether_addr_t, char, 1 ));
if( ! dp_device->addr ){
free( dp_device );
free( device );
return ENOMEM;
}
if( ERROR_OCCURRED( device_map_add( & netif_globals.device_map, device->device_id, device ))){
free( dp_device->addr );
free( dp_device );
free( dep );
free( device );
return ERROR_CODE;
}
198,8 → 211,23
}
 
int send_message( device_id_t device_id, packet_t packet ){
// TODO send message
return ENOTSUP;
ERROR_DECLARE;
 
device_ref device;
dpeth_t * dep;
packet_t next;
 
ERROR_PROPAGATE( find_device( IPC_GET_DEVICE( call ), & device ));
dep = ( dpeth_t * ) device->specific;
// process packet queue
do{
next = pq_detach( packet );
if( do_pwrite( dep, packet, FALSE ) != EBUSY ){
netif_pq_release( packet_get_id( packet ));
}
packet = next;
}while( packet );
return EOK;
}
 
int start_message( device_id_t device_id ){
210,16 → 238,15
 
ERROR_PROPAGATE( find_device( device_id, & device ));
if( device->state != NETIF_ACTIVE ){
dep = & (( dp_device_ref ) device->specific )->dep;
dep = ( dpeth_t * ) device->specific;
dp8390_cmds[ 0 ].addr = ( void * ) ( uint32_t ) ( dep->de_dp8390_port + DP_ISR );
dp8390_cmds[ 2 ].value = device->device_id;
ERROR_PROPAGATE( ipc_register_irq( dep->de_irq, device->device_id, 0, & dp8390_code ));
dp8390_cmds[ 2 ].addr = dp8390_cmds[ 0 ].addr;
ERROR_PROPAGATE( ipc_register_irq( dep->de_irq, device->device_id, device->device_id, & dp8390_code ));
if( ERROR_OCCURRED( do_init( dep, DL_BROAD_REQ ))){
ipc_unregister_irq( dep->de_irq, device->device_id );
return ERROR_CODE;
}
device->state = NETIF_ACTIVE;
nil_message( device, NET_NIL_DEVICE_STATE, device->state, NULL );
change_state( device, NETIF_ACTIVE );
}
return EOK;
}
232,15 → 259,20
 
ERROR_PROPAGATE( find_device( device_id, & device ));
if( device->state != NETIF_STOPPED ){
dep = & (( dp_device_ref ) device->specific )->dep;
dep = ( dpeth_t * ) device->specific;
do_stop( dep );
ipc_unregister_irq( dep->de_irq, device->device_id );
device->state = NETIF_STOPPED;
nil_message( device, NET_NIL_DEVICE_STATE, device->state, NULL );
change_state( device, NETIF_STOPPED );
}
return EOK;
}
 
void change_state( device_ref device, device_state_t state ){
device->state = state;
nil_message( device, NET_NIL_DEVICE_STATE, device->state, NULL );
printf( "\nState changed to %s", ( state == NETIF_ACTIVE ) ? "ACTIVE" : "STOPPED" );
}
 
int initialize( void ){
ipcarg_t phonehash;
 
249,5 → 281,11
return REGISTER_ME( SERVICE_DP8390, & phonehash );
}
 
int netif_send_packet( dpeth_t * dep, packet_t packet ){
if( !( dep && dep->parent )) return EINVAL;
nil_message(( device_ref ) dep->parent, NET_NIL_RECEIVED, packet_get_id( packet ), 0 );
return EOK;
}
 
/** @}
*/
/branches/network/uspace/srv/net/netif/lo/lo.c
48,33 → 48,46
#include "../../structures/packet/packet_client.h"
 
#include "../netif.h"
#include "../netif_interface.h"
 
#define DEFAULT_MTU 1500
 
#define DEFAULT_ADDR "\0\0\0\0\0\0"
#define DEFAULT_ADDR_LEN ( sizeof( DEFAULT_ADDR ) / sizeof( char ))
 
#define NAME "lo - loopback interface"
 
netif_globals_t netif_globals;
 
static struct lo_globals{
measured_string_ref addr;
int mtu;
} lo_globals;
 
int change_state_message( device_id_t device_id, device_state_t state );
int create( device_id_t device_id, device_ref * device );
int initialize( void );
void netif_print_name( void );
int probe_auto_message( void );
int probe_message( device_id_t device_id, int irq, int io );
int send_message( device_id_t device_id, packet_t packet );
int start_message( device_id_t device_id );
int stop_message( device_id_t device_id );
measured_string_ref get_addr_message( device_id_t device_id );
 
measured_string_ref get_addr_message( device_id_t device_id ){
return lo_globals.addr;
int specific_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
return ENOTSUP;
}
 
int get_addr_message( device_id_t device_id, measured_string_ref address ){
if( ! address ) return EBADMEM;
address->value = DEFAULT_ADDR;
address->length = DEFAULT_ADDR_LEN;
}
 
int get_device_stats( device_id_t device_id, device_stats_ref stats ){
ERROR_DECLARE;
 
device_ref device;
 
if( ! stats ) return EBADMEM;
ERROR_PROPAGATE( find_device( device_id, & device ));
memcpy( stats, ( device_stats_ref ) device->specific, sizeof( device_stats_t ));
return EOK;
}
 
int change_state_message( device_id_t device_id, device_state_t state ){
ERROR_DECLARE;
 
90,7 → 103,7
}
 
int create( device_id_t device_id, device_ref * device ){
ERROR_DECLARE;
int index;
 
if( device_map_count( & netif_globals.device_map ) > 0 ){
return EXDEV;
97,15 → 110,21
}else{
* device = ( device_ref ) malloc( sizeof( device_t ));
if( !( * device )) return ENOMEM;
( ** device ).specific = malloc( sizeof( device_stats_t ));
if( ! ( ** device ).specific ){
free( * device );
return ENOMEM;
}
null_device_stats(( device_stats_ref )( ** device ).specific );
( ** device ).device_id = device_id;
( ** device ).nil_phone = -1;
( ** device ).specific = NULL;
null_device_stats( &(( ** device ).stats ));
( ** device ).state = NETIF_STOPPED;
if( ERROR_OCCURRED( device_map_add( & netif_globals.device_map, ( ** device ).device_id, * device ))){
index = device_map_add( & netif_globals.device_map, ( ** device ).device_id, * device );
if( index < 0 ){
free( * device );
free(( ** device ).specific );
* device = NULL;
return ERROR_CODE;
return index;
}
}
return EOK;
114,8 → 133,6
int initialize( void ){
ipcarg_t phonehash;
 
lo_globals.addr = measured_string_create_bulk( "\0\0\0\0\0\0", 0 );
if( ! lo_globals.addr ) return ENOMEM;
return REGISTER_ME( SERVICE_LO, & phonehash );
}
 
143,6 → 160,7
int count = 1;
measured_string_ref settings;
char * data;
ipcarg_t result;
 
// create a new device
ERROR_PROPAGATE( create( device_id, & device ));
154,16 → 172,23
async_wait_for( message, NULL );
return ERROR_CODE;
}
// end request
async_wait_for( message, & result );
if( ERROR_OCCURRED( result )){
if( settings ){
free( settings );
free( data );
}
return ERROR_CODE;
}
// MTU is the first one
if( settings && ( settings[ 0 ].value )){
lo_globals.mtu = strtoul( settings[ 0 ].value, NULL, 0 );
free( settings );
free( data );
}else{
lo_globals.mtu = DEFAULT_MTU;
}
free( settings );
free( data );
// end request
async_wait_for( message, NULL );
// print the settings
printf("\nNew device registered:\n\tid\t= %d\n\tMTU\t= %d", device->device_id, lo_globals.mtu );
return EOK;
180,11 → 205,11
if( device->state != NETIF_ACTIVE ) return EPERM;
next = packet;
do{
++ device->stats.tx_packets;
++ device->stats.rx_packets;
++ (( device_stats_ref ) device->specific )->tx_packets;
++ (( device_stats_ref ) device->specific )->rx_packets;
length = packet_get_data_length( next );
device->stats.tx_bytes += length;
device->stats.rx_bytes += length;
(( device_stats_ref ) device->specific )->tx_bytes += length;
(( device_stats_ref ) device->specific )->rx_bytes += length;
next = pq_next( next );
}while( next );
nil_message( device, NET_NIL_RECEIVED, packet_get_id( packet ), PACKET_SELF );
/branches/network/uspace/srv/net/netif/netif.h
37,6 → 37,8
#ifndef __NET_NETIF_H__
#define __NET_NETIF_H__
 
#include <rwlock.h>
 
#include "device.h"
 
/** Sends the notification message to the registered network interface layer module.
79,9 → 81,6
/** Receiving network interface layer phone.
*/
int nil_phone;
/** Usage statistics.
*/
device_stats_t stats;
/** Actual device state.
*/
device_state_t state;
99,6 → 98,9
/** Device map.
*/
device_map_t device_map;
/** Safety lock.
*/
rwlock_t lock;
};
 
/** Finds the device specific data.
115,6 → 117,15
*/
void null_device_stats( device_stats_ref stats );
 
// prepared for future optimalizations
/** \todo
*/
void netif_pq_release( packet_id_t packet );
 
/** \todo
*/
packet_t netif_packet_get_1( size_t content );
 
#endif
 
/** @}
/branches/network/uspace/srv/net/netif/netif_interface.h
0,0 → 1,56
/*
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup netif
* @{
*/
 
#ifndef __NET_NETIF_INTERFACE_H__
#define __NET_NETIF_INTERFACE_H__
 
#include <ipc/ipc.h>
 
#include "../structures/measured_strings.h"
#include "../structures/packet/packet.h"
 
#include "device.h"
 
int initialize( void );
int probe_auto_message( void );
int probe_message( device_id_t device_id, int irq, int io );
int send_message( device_id_t device_id, packet_t packet );
int start_message( device_id_t device_id );
int stop_message( device_id_t device_id );
int get_addr_message( device_id_t device_id, measured_string_ref address );
int specific_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
int get_device_stats( device_id_t device_id, device_stats_ref stats );
 
#endif
 
/** @}
*/
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/branches/network/uspace/srv/net/sockaddr.c
34,8 → 34,8
*
*/
 
#include <mem.h>
#include <stdio.h>
#include <string.h>
 
#include "include/sockaddr.h"
#include "include/socket.h"
68,7 → 68,7
return ENOTSUP;
}
if( ! address ){
memset( data, 0, count );
bzero( data, count );
return ENOENT;
}
next = address;
88,7 → 88,7
}while( shift -- );
index += bytes;
}else{
memset( data + index, 0, count - index );
bzero( data + index, count - index );
return EOK;
}
}while( index < count );
/branches/network/HelenOS.config
464,6 → 464,6
 
% Networking architecture
@ "modular" Modular
@ "module" One module
#@ "module" One module
! [PLATFORM=ia32] NETWORKING (choice)