Subversion Repositories HelenOS

Rev

Rev 4332 | Rev 4351 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4332 Rev 4350
Line 64... Line 64...
64
#include "../nil_module.h"
64
#include "../nil_module.h"
65
 
65
 
66
#include "eth.h"
66
#include "eth.h"
67
#include "eth_header.h"
67
#include "eth_header.h"
68
 
68
 
-
 
69
/** Reserved packet prefix length.
-
 
70
 */
69
#define ETH_PREFIX      ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t ))
71
#define ETH_PREFIX      ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t ))
-
 
72
 
-
 
73
/** Reserved packet suffix length.
-
 
74
 */
70
#define ETH_SUFFIX      sizeof( eth_fcs_t )
75
#define ETH_SUFFIX      sizeof( eth_fcs_t )
-
 
76
 
-
 
77
/** Maximum packet content length.
-
 
78
 */
71
#define ETH_MAX_CONTENT 1500
79
#define ETH_MAX_CONTENT 1500
-
 
80
 
-
 
81
/** Minimum packet content length.
-
 
82
 */
72
#define ETH_MIN_CONTENT 46
83
#define ETH_MIN_CONTENT 46
-
 
84
 
-
 
85
/** Maximum tagged packet content length.
-
 
86
 */
73
#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 ))
87
#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 ))
-
 
88
 
-
 
89
/** Minimum tagged packet content length.
-
 
90
 */
74
#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 ))
91
#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 ))
75
 
92
 
-
 
93
/** Dummy flag shift value.
-
 
94
 */
76
#define ETH_DUMMY_SHIFT 0
95
#define ETH_DUMMY_SHIFT 0
-
 
96
 
-
 
97
/** Mode flag shift value.
-
 
98
 */
77
#define ETH_MODE_SHIFT  1
99
#define ETH_MODE_SHIFT  1
78
 
100
 
79
/** Dummy device flag.
101
/** Dummy device flag.
80
 *  Preamble and FCS are mandatory part of the packets.
102
 *  Preamble and FCS are mandatory part of the packets.
81
 */
103
 */
82
#define ETH_DUMMY               ( 1 << ETH_DUMMY_SHIFT )
104
#define ETH_DUMMY               ( 1 << ETH_DUMMY_SHIFT )
-
 
105
 
-
 
106
/** Returns the dummy flag.
-
 
107
 *  @see ETH_DUMMY
-
 
108
 */
83
#define IS_DUMMY( flags )       (( flags ) & ETH_DUMMY )
109
#define IS_DUMMY( flags )       (( flags ) & ETH_DUMMY )
84
 
110
 
85
/** Device mode flags.
111
/** Device mode flags.
86
 *  @see ETH_DIX
112
 *  @see ETH_DIX
87
 *  @see ETH_8023_2_LSAP
113
 *  @see ETH_8023_2_LSAP
88
 *  @see ETH_8023_2_SNAP
114
 *  @see ETH_8023_2_SNAP
89
 */
115
 */
90
#define ETH_MODE_MASK           ( 3 << ETH_MODE_SHIFT )
116
#define ETH_MODE_MASK           ( 3 << ETH_MODE_SHIFT )
-
 
117
 
-
 
118
/** DIX Ethernet mode flag.
-
 
119
 */
91
#define ETH_DIX                 ( 1 << ETH_MODE_SHIFT )
120
#define ETH_DIX                 ( 1 << ETH_MODE_SHIFT )
-
 
121
 
-
 
122
/** Returns whether the DIX Ethernet mode flag is set.
-
 
123
 *  @param flags The ethernet flags. Input parameter.
-
 
124
 *  @see ETH_DIX
-
 
125
 */
92
#define IS_DIX( flags )         ((( flags ) & ETH_MODE_MASK ) == ETH_DIX )
126
#define IS_DIX( flags )         ((( flags ) & ETH_MODE_MASK ) == ETH_DIX )
-
 
127
 
-
 
128
/** 802.3 + 802.2 + LSAP mode flag.
-
 
129
 */
93
#define ETH_8023_2_LSAP         ( 2 << ETH_MODE_SHIFT )
130
#define ETH_8023_2_LSAP         ( 2 << ETH_MODE_SHIFT )
-
 
131
 
-
 
132
/** Returns whether the 802.3 + 802.2 + LSAP mode flag is set.
-
 
133
 *  @param flags The ethernet flags. Input parameter.
-
 
134
 *  @see ETH_8023_2_LSAP
-
 
135
 */
94
#define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP )
136
#define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP )
-
 
137
 
-
 
138
/** 802.3 + 802.2 + LSAP + SNAP mode flag.
-
 
139
 */
95
#define ETH_8023_2_SNAP         ( 3 << ETH_MODE_SHIFT )
140
#define ETH_8023_2_SNAP         ( 3 << ETH_MODE_SHIFT )
-
 
141
 
-
 
142
/** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
-
 
143
 *  @param flags The ethernet flags. Input parameter.
-
 
144
 *  @see ETH_8023_2_SNAP
-
 
145
 */
96
#define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP )
146
#define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP )
97
 
147
 
-
 
148
/** Type definition of the ethernet address type.
-
 
149
 *  @see eth_addr_type
-
 
150
 */
98
typedef enum eth_addr_type  eth_addr_type_t;
151
typedef enum eth_addr_type  eth_addr_type_t;
-
 
152
 
-
 
153
/** Type definition of the ethernet address type pointer.
-
 
154
 *  @see eth_addr_type
-
 
155
 */
99
typedef eth_addr_type_t *   eth_addr_type_ref;
156
typedef eth_addr_type_t *   eth_addr_type_ref;
100
 
157
 
-
 
158
/** Ethernet address type.
-
 
159
 */
101
enum eth_addr_type{
160
enum eth_addr_type{
-
 
161
    /** Local address.
-
 
162
     */
102
    ETH_LOCAL_ADDR,
163
    ETH_LOCAL_ADDR,
-
 
164
    /** Broadcast address.
-
 
165
     */
103
    ETH_BROADCAST_ADDR
166
    ETH_BROADCAST_ADDR
104
};
167
};
105
 
168
 
106
/** Ethernet global data.
169
/** Ethernet module global data.
107
 */
170
 */
108
eth_globals_t   eth_globals;
171
eth_globals_t   eth_globals;
109
 
172
 
110
/** Processes IPC messages from the registered device driver modules in an infinite loop.
173
/** Processes IPC messages from the registered device driver modules in an infinite loop.
111
 *  @param iid The message identifier. Input parameter.
174
 *  @param iid The message identifier. Input parameter.
112
 *  @param icall The message parameters. Input/output parameter.
175
 *  @param icall The message parameters. Input/output parameter.
113
 */
176
 */
114
void    eth_receiver( ipc_callid_t iid, ipc_call_t * icall );
177
void    eth_receiver( ipc_callid_t iid, ipc_call_t * icall );
115
 
178
 
-
 
179
/** Registers new device or updates the MTU of an existing one.
-
 
180
 *  Determines the device local hardware address.
-
 
181
 *  @param device_id The new device identifier. Input parameter.
-
 
182
 *  @param service The device driver service. Input parameter.
-
 
183
 *  @param mtu The device maximum transmission unit. Input parameter.
-
 
184
 *  @returns EOK on success.
116
DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t )
185
 *  @returns EEXIST if the device with the different service exists.
117
 
-
 
118
INT_MAP_IMPLEMENT( eth_protos, eth_proto_t )
186
 *  @returns ENOMEM if there is not enough memory left.
-
 
187
 *  @returns Other error codes as defined for the net_get_device_conf_req() function.
-
 
188
 *  @returns Other error codes as defined for the netif_bind_service() function.
-
 
189
 *  @returns Other error codes as defined for the netif_get_addr() function.
119
 
190
 */
120
int eth_device_message( device_id_t device_id, services_t service, size_t mtu );
191
int eth_device_message( device_id_t device_id, services_t service, size_t mtu );
-
 
192
 
-
 
193
/** Registers receiving module service.
-
 
194
 *  Passes received packets for this service.
121
int nil_receive_msg( int nil_phone, device_id_t device_id, packet_t packet );
195
 *  @param service The module service. Input parameter.
-
 
196
 *  @param phone The service phone. Input parameter.
-
 
197
 *  @returns EOK on success.
-
 
198
 *  @returns ENOENT if the service is not known.
-
 
199
 *  @returns ENOMEM if there is not enough memory left.
-
 
200
 */
122
int nil_register_message( services_t service, int phone );
201
int nil_register_message( services_t service, int phone );
-
 
202
 
-
 
203
/** Returns the device packet dimensions for sending.
-
 
204
 *  @param device_id The device identifier. Input parameter.
-
 
205
 *  @param addr_len The minimum reserved address length. Output parameter.
-
 
206
 *  @param prefix The minimum reserved prefix size. Output parameter.
-
 
207
 *  @param content The maximum content size. Output parameter.
-
 
208
 *  @param suffix The minimum reserved suffix size. Output parameter.
-
 
209
 *  @returns EOK on success.
-
 
210
 *  @returns EBADMEM if either one of the parameters is NULL.
-
 
211
 *  @returns ENOENT if there is no such device.
-
 
212
 */
123
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix );
213
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix );
-
 
214
 
-
 
215
/** Returns the device hardware address.
-
 
216
 *  @param device_id The device identifier. Input parameter.
-
 
217
 *  @param type Type of the desired address. Input parameter
-
 
218
 *  @param address The device hardware address. Output parameter.
-
 
219
 *  @returns EOK on success.
-
 
220
 *  @returns EBADMEM if the address parameter is NULL.
-
 
221
 *  @returns ENOENT if there no such device.
-
 
222
 */
124
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address );
223
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address );
-
 
224
 
-
 
225
/** Sends the packet queue.
-
 
226
 *  Sends only packet successfully processed by the eth_prepare_packet() function.
-
 
227
 *  @param device_id The device identifier. Input parameter.
-
 
228
 *  @param packet The packet queue. Input parameter.
-
 
229
 *  @param sender The sending module service. Input parameter.
-
 
230
 *  @returns EOK on success.
-
 
231
 *  @returns ENOENT if there no such device.
-
 
232
 *  @returns EINVAL if the service parameter is not known.
-
 
233
 */
125
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender );
234
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender );
-
 
235
 
-
 
236
/** Processes the received packet and chooses the target registered module.
-
 
237
 *  @param flags The device flags. Input parameter.
-
 
238
 *  @param packet The packet. Input parameter.
-
 
239
 *  @returns The target registered module.
-
 
240
 *  @returns NULL if the packet is not long enough.
-
 
241
 *  @returns NULL if the packet is too long.
-
 
242
 *  @returns NULL if the raw ethernet protocol is used.
-
 
243
 *  @returns NULL if the dummy device FCS checksum is invalid.
-
 
244
 *  @returns NULL if the packet address length is not big enough.
-
 
245
 */
126
eth_proto_ref   eth_process_packet( int flags, packet_t packet );
246
eth_proto_ref   eth_process_packet( int flags, packet_t packet );
-
 
247
 
-
 
248
/** Prepares the packet for sending.
-
 
249
 *  @param flags The device flags. Input parameter.
-
 
250
 *  @param packet The packet. Input parameter.
-
 
251
 *  @param src_addr The source hardware address. Input parameter.
-
 
252
 *  @param ethertype The ethernet protocol type. Input parameter.
-
 
253
 *  @param mtu The device maximum transmission unit. Input parameter.
-
 
254
 *  @returns EOK on success.
-
 
255
 *  @returns EINVAL if the packet addresses length is not long enough.
-
 
256
 *  @returns EINVAL if the packet is bigger than the device MTU.
-
 
257
 *  @returns ENOMEM if there is not enough memory in the packet.
-
 
258
 */
127
int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype );
259
int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype );
128
 
260
 
-
 
261
DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t )
-
 
262
 
-
 
263
INT_MAP_IMPLEMENT( eth_protos, eth_proto_t )
-
 
264
 
129
int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){
265
int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){
130
    int             index;
266
    int             index;
131
    eth_proto_ref   proto;
267
    eth_proto_ref   proto;
132
 
268
 
133
    //TODO clear device if off?
269
    //TODO clear device if off?
Line 329... Line 465...
329
}
465
}
330
 
466
 
331
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){
467
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){
332
    eth_device_ref  device;
468
    eth_device_ref  device;
333
 
469
 
334
    if( !( addr_len && prefix && content && suffix )) return EINVAL;
470
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
335
    rwlock_read_lock( & eth_globals.devices_lock );
471
    rwlock_read_lock( & eth_globals.devices_lock );
336
    device = eth_devices_find( & eth_globals.devices, device_id );
472
    device = eth_devices_find( & eth_globals.devices, device_id );
337
    if( ! device ){
473
    if( ! device ){
338
        rwlock_read_unlock( & eth_globals.devices_lock );
474
        rwlock_read_unlock( & eth_globals.devices_lock );
339
        return ENOENT;
475
        return ENOENT;
Line 347... Line 483...
347
}
483
}
348
 
484
 
349
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){
485
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){
350
    eth_device_ref  device;
486
    eth_device_ref  device;
351
 
487
 
352
    if( ! address ) return EINVAL;
488
    if( ! address ) return EBADMEM;
353
    if( type == ETH_BROADCAST_ADDR ){
489
    if( type == ETH_BROADCAST_ADDR ){
354
        * address = eth_globals.broadcast_addr;
490
        * address = eth_globals.broadcast_addr;
355
    }else{
491
    }else{
356
        rwlock_read_lock( & eth_globals.devices_lock );
492
        rwlock_read_lock( & eth_globals.devices_lock );
357
        device = eth_devices_find( & eth_globals.devices, device_id );
493
        device = eth_devices_find( & eth_globals.devices, device_id );
Line 412... Line 548...
412
 
548
 
413
    length = packet_get_addr( packet, & src, & dest );
549
    length = packet_get_addr( packet, & src, & dest );
414
    if( length < 0 ) return length;
550
    if( length < 0 ) return length;
415
    if( length < ETH_ADDR ) return EINVAL;
551
    if( length < ETH_ADDR ) return EINVAL;
416
    length = packet_get_data_length( packet );
552
    length = packet_get_data_length( packet );
-
 
553
    //TODO smaller than MTU!
417
    if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL;
554
    if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL;
418
    if( length < ETH_MIN_TAGGED_CONTENT( flags )){
555
    if( length < ETH_MIN_TAGGED_CONTENT( flags )){
419
        padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length );
556
        padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length );
420
        if( ! padding ) return ENOMEM;
557
        if( ! padding ) return ENOMEM;
421
        bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length );
558
        bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length );