/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,39 → 95,69 |
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 ); |
} |
return ENOTSUP; |
rwlock_read_unlock( & netif_globals.lock ); |
return ERROR_CODE; |
} |
return specific_message( callid, call, answer, answer_count ); |
} |
int netif_start_module( async_client_conn_t client_connection ){ |
ERROR_DECLARE; |
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_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 |
95,37 → 89,64 |
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 ); |
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( "\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; |
133,8 → 154,8 |
assert( dep->de_flags & DEF_ENABLED); |
// irq= dep.de_irq; |
// assert(irq >= 0 && irq < NR_IRQ_VECTORS); |
if ( dep->de_int_pending || 1) |
{ |
// if ( dep->de_int_pending || 1) |
// { |
dep->de_int_pending= 0; |
dp_check_ints( dep ); |
// do_int(dep); |
144,9 → 165,8 |
panic("DP8390", |
"unable enable interrupts", r); |
} |
*/ } |
*/// } |
} |
} |
int probe_auto_message( void ){ |
return ENOTSUP; |
156,41 → 176,34 |
ERROR_DECLARE; |
device_ref device; |
dp_device_ref dp_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,9 → 211,24 |
} |
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 ){ |
ERROR_DECLARE; |
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 |