Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4349 → Rev 4350

/branches/network/uspace/srv/net/nil/eth/eth.c
66,14 → 66,36
#include "eth.h"
#include "eth_header.h"
 
/** Reserved packet prefix length.
*/
#define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t ))
 
/** Reserved packet suffix length.
*/
#define ETH_SUFFIX sizeof( eth_fcs_t )
 
/** Maximum packet content length.
*/
#define ETH_MAX_CONTENT 1500
 
/** Minimum packet content length.
*/
#define ETH_MIN_CONTENT 46
 
/** Maximum tagged packet content length.
*/
#define ETH_MAX_TAGGED_CONTENT( flags ) ( ETH_MAX_CONTENT - (( IS_8023_2_LSAP( flags ) || IS_8023_2_SNAP( flags )) ? sizeof( eth_header_lsap_t ) : 0 ) - ( IS_8023_2_SNAP( flags ) ? sizeof( eth_header_snap_t ) : 0 ))
 
/** Minimum tagged packet content length.
*/
#define ETH_MIN_TAGGED_CONTENT( flags ) ( ETH_MIN_CONTENT - (( IS_8023_2_LSAP( flags ) || IS_8023_2_SNAP( flags )) ? sizeof( eth_header_lsap_t ) : 0 ) - ( IS_8023_2_SNAP( flags ) ? sizeof( eth_header_snap_t ) : 0 ))
 
/** Dummy flag shift value.
*/
#define ETH_DUMMY_SHIFT 0
 
/** Mode flag shift value.
*/
#define ETH_MODE_SHIFT 1
 
/** Dummy device flag.
80,6 → 102,10
* Preamble and FCS are mandatory part of the packets.
*/
#define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT )
 
/** Returns the dummy flag.
* @see ETH_DUMMY
*/
#define IS_DUMMY( flags ) (( flags ) & ETH_DUMMY )
 
/** Device mode flags.
88,22 → 114,59
* @see ETH_8023_2_SNAP
*/
#define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT )
 
/** DIX Ethernet mode flag.
*/
#define ETH_DIX ( 1 << ETH_MODE_SHIFT )
 
/** Returns whether the DIX Ethernet mode flag is set.
* @param flags The ethernet flags. Input parameter.
* @see ETH_DIX
*/
#define IS_DIX( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_DIX )
 
/** 802.3 + 802.2 + LSAP mode flag.
*/
#define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT )
 
/** Returns whether the 802.3 + 802.2 + LSAP mode flag is set.
* @param flags The ethernet flags. Input parameter.
* @see ETH_8023_2_LSAP
*/
#define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP )
 
/** 802.3 + 802.2 + LSAP + SNAP mode flag.
*/
#define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT )
 
/** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
* @param flags The ethernet flags. Input parameter.
* @see ETH_8023_2_SNAP
*/
#define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP )
 
/** Type definition of the ethernet address type.
* @see eth_addr_type
*/
typedef enum eth_addr_type eth_addr_type_t;
 
/** Type definition of the ethernet address type pointer.
* @see eth_addr_type
*/
typedef eth_addr_type_t * eth_addr_type_ref;
 
/** Ethernet address type.
*/
enum eth_addr_type{
/** Local address.
*/
ETH_LOCAL_ADDR,
/** Broadcast address.
*/
ETH_BROADCAST_ADDR
};
 
/** Ethernet global data.
/** Ethernet module global data.
*/
eth_globals_t eth_globals;
 
113,19 → 176,92
*/
void eth_receiver( ipc_callid_t iid, ipc_call_t * icall );
 
DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t )
/** Registers new device or updates the MTU of an existing one.
* Determines the device local hardware address.
* @param device_id The new device identifier. Input parameter.
* @param service The device driver service. Input parameter.
* @param mtu The device maximum transmission unit. Input parameter.
* @returns EOK on success.
* @returns EEXIST if the device with the different service exists.
* @returns ENOMEM if there is not enough memory left.
* @returns Other error codes as defined for the net_get_device_conf_req() function.
* @returns Other error codes as defined for the netif_bind_service() function.
* @returns Other error codes as defined for the netif_get_addr() function.
*/
int eth_device_message( device_id_t device_id, services_t service, size_t mtu );
 
INT_MAP_IMPLEMENT( eth_protos, eth_proto_t )
/** Registers receiving module service.
* Passes received packets for this service.
* @param service The module service. Input parameter.
* @param phone The service phone. Input parameter.
* @returns EOK on success.
* @returns ENOENT if the service is not known.
* @returns ENOMEM if there is not enough memory left.
*/
int nil_register_message( services_t service, int phone );
 
int eth_device_message( device_id_t device_id, services_t service, size_t mtu );
int nil_receive_msg( int nil_phone, device_id_t device_id, packet_t packet );
int nil_register_message( services_t service, int phone );
/** Returns the device packet dimensions for sending.
* @param device_id The device identifier. Input parameter.
* @param addr_len The minimum reserved address length. Output parameter.
* @param prefix The minimum reserved prefix size. Output parameter.
* @param content The maximum content size. Output parameter.
* @param suffix The minimum reserved suffix size. Output parameter.
* @returns EOK on success.
* @returns EBADMEM if either one of the parameters is NULL.
* @returns ENOENT if there is no such device.
*/
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix );
 
/** Returns the device hardware address.
* @param device_id The device identifier. Input parameter.
* @param type Type of the desired address. Input parameter
* @param address The device hardware address. Output parameter.
* @returns EOK on success.
* @returns EBADMEM if the address parameter is NULL.
* @returns ENOENT if there no such device.
*/
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address );
 
/** Sends the packet queue.
* Sends only packet successfully processed by the eth_prepare_packet() function.
* @param device_id The device identifier. Input parameter.
* @param packet The packet queue. Input parameter.
* @param sender The sending module service. Input parameter.
* @returns EOK on success.
* @returns ENOENT if there no such device.
* @returns EINVAL if the service parameter is not known.
*/
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender );
 
/** Processes the received packet and chooses the target registered module.
* @param flags The device flags. Input parameter.
* @param packet The packet. Input parameter.
* @returns The target registered module.
* @returns NULL if the packet is not long enough.
* @returns NULL if the packet is too long.
* @returns NULL if the raw ethernet protocol is used.
* @returns NULL if the dummy device FCS checksum is invalid.
* @returns NULL if the packet address length is not big enough.
*/
eth_proto_ref eth_process_packet( int flags, packet_t packet );
 
/** Prepares the packet for sending.
* @param flags The device flags. Input parameter.
* @param packet The packet. Input parameter.
* @param src_addr The source hardware address. Input parameter.
* @param ethertype The ethernet protocol type. Input parameter.
* @param mtu The device maximum transmission unit. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet addresses length is not long enough.
* @returns EINVAL if the packet is bigger than the device MTU.
* @returns ENOMEM if there is not enough memory in the packet.
*/
int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype );
 
DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t )
 
INT_MAP_IMPLEMENT( eth_protos, eth_proto_t )
 
int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){
int index;
eth_proto_ref proto;
331,7 → 467,7
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){
eth_device_ref device;
 
if( !( addr_len && prefix && content && suffix )) return EINVAL;
if( !( addr_len && prefix && content && suffix )) return EBADMEM;
rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
349,7 → 485,7
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){
eth_device_ref device;
 
if( ! address ) return EINVAL;
if( ! address ) return EBADMEM;
if( type == ETH_BROADCAST_ADDR ){
* address = eth_globals.broadcast_addr;
}else{
414,6 → 550,7
if( length < 0 ) return length;
if( length < ETH_ADDR ) return EINVAL;
length = packet_get_data_length( packet );
//TODO smaller than MTU!
if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL;
if( length < ETH_MIN_TAGGED_CONTENT( flags )){
padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length );