Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4191 → Rev 4192

/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