Changeset 89c57b6 in mainline for uspace/srv/net/nil/eth/eth.c


Ignore:
Timestamp:
2011-04-13T14:45:41Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
88634420
Parents:
cefb126 (diff), 17279ead (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/nil/eth/eth.c

    rcefb126 r89c57b6  
    4040#include <mem.h>
    4141#include <stdio.h>
     42#include <byteorder.h>
    4243#include <str.h>
    43 
    44 #include <ipc/ipc.h>
     44#include <errno.h>
     45#include <ipc/nil.h>
     46#include <ipc/net.h>
    4547#include <ipc/services.h>
    46 
    47 #include <net_err.h>
    48 #include <net_messages.h>
    49 #include <net_modules.h>
    50 #include <net_byteorder.h>
     48#include <net/modules.h>
    5149#include <net_checksum.h>
    5250#include <ethernet_lsap.h>
    5351#include <ethernet_protocols.h>
    5452#include <protocol_map.h>
    55 #include <net_device.h>
    56 #include <netif_interface.h>
     53#include <net/device.h>
     54#include <netif_remote.h>
    5755#include <net_interface.h>
    58 #include <nil_interface.h>
    59 #include <il_interface.h>
     56#include <il_remote.h>
    6057#include <adt/measured_strings.h>
    61 #include <packet/packet_client.h>
     58#include <packet_client.h>
    6259#include <packet_remote.h>
    63 #include <nil_local.h>
     60#include <nil_skel.h>
    6461
    6562#include "eth.h"
    66 #include "eth_header.h"
    67 
    68 /** The module name.
    69  */
     63
     64/** The module name. */
    7065#define NAME  "eth"
    7166
    72 /** Reserved packet prefix length.
    73  */
    74 #define ETH_PREFIX              (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t))
    75 
    76 /** Reserved packet suffix length.
    77  */
    78 #define ETH_SUFFIX              sizeof(eth_fcs_t)
    79 
    80 /** Maximum packet content length.
    81  */
    82 #define ETH_MAX_CONTENT 1500u
    83 
    84 /** Minimum packet content length.
    85  */
    86 #define ETH_MIN_CONTENT 46u
    87 
    88 /** Maximum tagged packet content length.
    89  */
    90 #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))
    91 
    92 /** Minimum tagged packet content length.
    93  */
    94 #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))
    95 
    96 /** Dummy flag shift value.
    97  */
    98 #define ETH_DUMMY_SHIFT 0
    99 
    100 /** Mode flag shift value.
    101  */
    102 #define ETH_MODE_SHIFT  1
     67/** Reserved packet prefix length. */
     68#define ETH_PREFIX \
     69        (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \
     70            sizeof(eth_header_snap_t))
     71
     72/** Reserved packet suffix length. */
     73#define ETH_SUFFIX  (sizeof(eth_fcs_t))
     74
     75/** Maximum packet content length. */
     76#define ETH_MAX_CONTENT  1500u
     77
     78/** Minimum packet content length. */
     79#define ETH_MIN_CONTENT  46u
     80
     81/** Maximum tagged packet content length. */
     82#define ETH_MAX_TAGGED_CONTENT(flags) \
     83        (ETH_MAX_CONTENT - \
     84            ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
     85            sizeof(eth_header_lsap_t) : 0) - \
     86            (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
     87
     88/** Minimum tagged packet content length. */
     89#define ETH_MIN_TAGGED_CONTENT(flags) \
     90        (ETH_MIN_CONTENT - \
     91            ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
     92            sizeof(eth_header_lsap_t) : 0) - \
     93            (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
     94
     95/** Dummy flag shift value. */
     96#define ETH_DUMMY_SHIFT  0
     97
     98/** Mode flag shift value. */
     99#define ETH_MODE_SHIFT  1
    103100
    104101/** Dummy device flag.
    105  *  Preamble and FCS are mandatory part of the packets.
    106  */
    107 #define ETH_DUMMY                               (1 << ETH_DUMMY_SHIFT)
     102 * Preamble and FCS are mandatory part of the packets.
     103 */
     104#define ETH_DUMMY  (1 << ETH_DUMMY_SHIFT)
    108105
    109106/** Returns the dummy flag.
    110  *  @see ETH_DUMMY
    111  */
    112 #define IS_DUMMY(flags)         ((flags) &ETH_DUMMY)
     107 * @see ETH_DUMMY
     108 */
     109#define IS_DUMMY(flags)  ((flags) & ETH_DUMMY)
    113110
    114111/** Device mode flags.
    115  *  @see ETH_DIX
    116  *  @see ETH_8023_2_LSAP
    117  *  @see ETH_8023_2_SNAP
    118  */
    119 #define ETH_MODE_MASK                   (3 << ETH_MODE_SHIFT)
    120 
    121 /** DIX Ethernet mode flag.
    122  */
    123 #define ETH_DIX                                 (1 << ETH_MODE_SHIFT)
    124 
    125 /** Returns whether the DIX Ethernet mode flag is set.
    126  *  @param[in] flags The ethernet flags.
    127  *  @see ETH_DIX
    128  */
    129 #define IS_DIX(flags)                   (((flags) &ETH_MODE_MASK) == ETH_DIX)
    130 
    131 /** 802.3 + 802.2 + LSAP mode flag.
    132  */
    133 #define ETH_8023_2_LSAP                 (2 << ETH_MODE_SHIFT)
    134 
    135 /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set.
    136  *  @param[in] flags The ethernet flags.
    137  *  @see ETH_8023_2_LSAP
    138  */
    139 #define IS_8023_2_LSAP(flags)   (((flags) &ETH_MODE_MASK) == ETH_8023_2_LSAP)
    140 
    141 /** 802.3 + 802.2 + LSAP + SNAP mode flag.
    142  */
    143 #define ETH_8023_2_SNAP                 (3 << ETH_MODE_SHIFT)
    144 
    145 /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
    146  *  @param[in] flags The ethernet flags.
    147  *  @see ETH_8023_2_SNAP
    148  */
    149 #define IS_8023_2_SNAP(flags)   (((flags) &ETH_MODE_MASK) == ETH_8023_2_SNAP)
     112 * @see ETH_DIX
     113 * @see ETH_8023_2_LSAP
     114 * @see ETH_8023_2_SNAP
     115 */
     116#define ETH_MODE_MASK  (3 << ETH_MODE_SHIFT)
     117
     118/** DIX Ethernet mode flag. */
     119#define ETH_DIX  (1 << ETH_MODE_SHIFT)
     120
     121/** Return whether the DIX Ethernet mode flag is set.
     122 *
     123 * @param[in] flags Ethernet flags.
     124 * @see ETH_DIX
     125 *
     126 */
     127#define IS_DIX(flags)  (((flags) & ETH_MODE_MASK) == ETH_DIX)
     128
     129/** 802.3 + 802.2 + LSAP mode flag. */
     130#define ETH_8023_2_LSAP  (2 << ETH_MODE_SHIFT)
     131
     132/** Return whether the 802.3 + 802.2 + LSAP mode flag is set.
     133 *
     134 * @param[in] flags Ethernet flags.
     135 * @see ETH_8023_2_LSAP
     136 *
     137 */
     138#define IS_8023_2_LSAP(flags)  (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP)
     139
     140/** 802.3 + 802.2 + LSAP + SNAP mode flag. */
     141#define ETH_8023_2_SNAP  (3 << ETH_MODE_SHIFT)
     142
     143/** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
     144 *
     145 * @param[in] flags Ethernet flags.
     146 * @see ETH_8023_2_SNAP
     147 *
     148 */
     149#define IS_8023_2_SNAP(flags)  (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP)
    150150
    151151/** Type definition of the ethernet address type.
    152  *  @see eth_addr_type
    153  */
    154 typedef enum eth_addr_type      eth_addr_type_t;
    155 
    156 /** Type definition of the ethernet address type pointer.
    157  *  @see eth_addr_type
    158  */
    159 typedef eth_addr_type_t *       eth_addr_type_ref;
    160 
    161 /** Ethernet address type.
    162  */
    163 enum eth_addr_type{
    164         /** Local address.
    165          */
     152 * @see eth_addr_type
     153 */
     154typedef enum eth_addr_type eth_addr_type_t;
     155
     156/** Ethernet address type. */
     157enum eth_addr_type {
     158        /** Local address. */
    166159        ETH_LOCAL_ADDR,
    167         /** Broadcast address.
    168          */
     160        /** Broadcast address. */
    169161        ETH_BROADCAST_ADDR
    170162};
    171163
    172 /** Ethernet module global data.
    173  */
    174 eth_globals_t   eth_globals;
    175 
    176 /** @name Message processing functions
    177  */
    178 /*@{*/
    179 
    180 /** Processes IPC messages from the registered device driver modules in an infinite loop.
    181  *  @param[in] iid The message identifier.
    182  *  @param[in,out] icall The message parameters.
    183  */
    184 void eth_receiver(ipc_callid_t iid, ipc_call_t * icall);
    185 
    186 /** Registers new device or updates the MTU of an existing one.
    187  *  Determines the device local hardware address.
    188  *  @param[in] device_id The new device identifier.
    189  *  @param[in] service The device driver service.
    190  *  @param[in] mtu The device maximum transmission unit.
    191  *  @returns EOK on success.
    192  *  @returns EEXIST if the device with the different service exists.
    193  *  @returns ENOMEM if there is not enough memory left.
    194  *  @returns Other error codes as defined for the net_get_device_conf_req() function.
    195  *  @returns Other error codes as defined for the netif_bind_service() function.
    196  *  @returns Other error codes as defined for the netif_get_addr_req() function.
    197  */
    198 int eth_device_message(device_id_t device_id, services_t service, size_t mtu);
    199 
    200 /** Registers receiving module service.
    201  *  Passes received packets for this service.
    202  *  @param[in] service The module service.
    203  *  @param[in] phone The service phone.
    204  *  @returns EOK on success.
    205  *  @returns ENOENT if the service is not known.
    206  *  @returns ENOMEM if there is not enough memory left.
    207  */
    208 int eth_register_message(services_t service, int phone);
    209 
    210 /** Returns the device packet dimensions for sending.
    211  *  @param[in] device_id The device identifier.
    212  *  @param[out] addr_len The minimum reserved address length.
    213  *  @param[out] prefix The minimum reserved prefix size.
    214  *  @param[out] content The maximum content size.
    215  *  @param[out] suffix The minimum reserved suffix size.
    216  *  @returns EOK on success.
    217  *  @returns EBADMEM if either one of the parameters is NULL.
    218  *  @returns ENOENT if there is no such device.
    219  */
    220 int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix);
    221 
    222 /** Returns the device hardware address.
    223  *  @param[in] device_id The device identifier.
    224  *  @param[in] type Type of the desired address.
    225  *  @param[out] address The device hardware address.
    226  *  @returns EOK on success.
    227  *  @returns EBADMEM if the address parameter is NULL.
    228  *  @returns ENOENT if there no such device.
    229  */
    230 int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address);
    231 
    232 /** Sends the packet queue.
    233  *  Sends only packet successfully processed by the eth_prepare_packet() function.
    234  *  @param[in] device_id The device identifier.
    235  *  @param[in] packet The packet queue.
    236  *  @param[in] sender The sending module service.
    237  *  @returns EOK on success.
    238  *  @returns ENOENT if there no such device.
    239  *  @returns EINVAL if the service parameter is not known.
    240  */
    241 int eth_send_message(device_id_t device_id, packet_t packet, services_t sender);
    242 
    243 /*@}*/
    244 
    245 /** Processes the received packet and chooses the target registered module.
    246  *  @param[in] flags The device flags.
    247  *  @param[in] packet The packet.
    248  *  @returns The target registered module.
    249  *  @returns NULL if the packet is not long enough.
    250  *  @returns NULL if the packet is too long.
    251  *  @returns NULL if the raw ethernet protocol is used.
    252  *  @returns NULL if the dummy device FCS checksum is invalid.
    253  *  @returns NULL if the packet address length is not big enough.
    254  */
    255 eth_proto_ref eth_process_packet(int flags, packet_t packet);
    256 
    257 /** Prepares the packet for sending.
    258  *  @param[in] flags The device flags.
    259  *  @param[in] packet The packet.
    260  *  @param[in] src_addr The source hardware address.
    261  *  @param[in] ethertype The ethernet protocol type.
    262  *  @param[in] mtu The device maximum transmission unit.
    263  *  @returns EOK on success.
    264  *  @returns EINVAL if the packet addresses length is not long enough.
    265  *  @returns EINVAL if the packet is bigger than the device MTU.
    266  *  @returns ENOMEM if there is not enough memory in the packet.
    267  */
    268 int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu);
    269 
    270 DEVICE_MAP_IMPLEMENT(eth_devices, eth_device_t)
    271 
    272 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t)
    273 
    274 int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state){
     164/** Ethernet module global data. */
     165eth_globals_t eth_globals;
     166
     167DEVICE_MAP_IMPLEMENT(eth_devices, eth_device_t);
     168INT_MAP_IMPLEMENT(eth_protos, eth_proto_t);
     169
     170int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state)
     171{
    275172        int index;
    276         eth_proto_ref proto;
     173        eth_proto_t *proto;
    277174
    278175        fibril_rwlock_read_lock(&eth_globals.protos_lock);
    279         for(index = eth_protos_count(&eth_globals.protos) - 1; index >= 0; -- index){
     176        for (index = eth_protos_count(&eth_globals.protos) - 1; index >= 0;
     177            index--) {
    280178                proto = eth_protos_get_index(&eth_globals.protos, index);
    281                 if(proto && proto->phone){
    282                         il_device_state_msg(proto->phone, device_id, state, proto->service);
     179                if (proto && proto->phone) {
     180                        il_device_state_msg(proto->phone, device_id, state,
     181                            proto->service);
    283182                }
    284183        }
    285184        fibril_rwlock_read_unlock(&eth_globals.protos_lock);
     185       
    286186        return EOK;
    287187}
    288188
    289 int nil_initialize(int net_phone){
    290         ERROR_DECLARE;
     189int nil_initialize(int net_phone)
     190{
     191        int rc;
    291192
    292193        fibril_rwlock_initialize(&eth_globals.devices_lock);
    293194        fibril_rwlock_initialize(&eth_globals.protos_lock);
     195       
    294196        fibril_rwlock_write_lock(&eth_globals.devices_lock);
    295197        fibril_rwlock_write_lock(&eth_globals.protos_lock);
    296198        eth_globals.net_phone = net_phone;
    297         eth_globals.broadcast_addr = measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF", CONVERT_SIZE(uint8_t, char, ETH_ADDR));
    298         if(! eth_globals.broadcast_addr){
    299                 return ENOMEM;
    300         }
    301         ERROR_PROPAGATE(eth_devices_initialize(&eth_globals.devices));
    302         if(ERROR_OCCURRED(eth_protos_initialize(&eth_globals.protos))){
    303                 eth_devices_destroy(&eth_globals.devices);
    304                 return ERROR_CODE;
    305         }
     199
     200        eth_globals.broadcast_addr =
     201            measured_string_create_bulk((uint8_t *) "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ADDR);
     202        if (!eth_globals.broadcast_addr) {
     203                rc = ENOMEM;
     204                goto out;
     205        }
     206
     207        rc = eth_devices_initialize(&eth_globals.devices);
     208        if (rc != EOK) {
     209                free(eth_globals.broadcast_addr);
     210                goto out;
     211        }
     212
     213        rc = eth_protos_initialize(&eth_globals.protos);
     214        if (rc != EOK) {
     215                free(eth_globals.broadcast_addr);
     216                eth_devices_destroy(&eth_globals.devices, free);
     217        }
     218out:
    306219        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    307220        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    308         return EOK;
    309 }
    310 
    311 int eth_device_message(device_id_t device_id, services_t service, size_t mtu){
    312         ERROR_DECLARE;
    313 
    314         eth_device_ref device;
     221       
     222        return rc;
     223}
     224
     225/** Processes IPC messages from the registered device driver modules in an
     226 * infinite loop.
     227 *
     228 * @param[in] iid       The message identifier.
     229 * @param[in,out] icall The message parameters.
     230 */
     231static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall)
     232{
     233        packet_t *packet;
     234        int rc;
     235
     236        while (true) {
     237                switch (IPC_GET_IMETHOD(*icall)) {
     238                case NET_NIL_DEVICE_STATE:
     239                        nil_device_state_msg_local(0, IPC_GET_DEVICE(*icall),
     240                            IPC_GET_STATE(*icall));
     241                        async_answer_0(iid, EOK);
     242                        break;
     243                case NET_NIL_RECEIVED:
     244                        rc = packet_translate_remote(eth_globals.net_phone,
     245                            &packet, IPC_GET_PACKET(*icall));
     246                        if (rc == EOK)
     247                                rc = nil_received_msg_local(0,
     248                                    IPC_GET_DEVICE(*icall), packet, 0);
     249                       
     250                        async_answer_0(iid, (sysarg_t) rc);
     251                        break;
     252                default:
     253                        async_answer_0(iid, (sysarg_t) ENOTSUP);
     254                }
     255               
     256                iid = async_get_call(icall);
     257        }
     258}
     259
     260/** Registers new device or updates the MTU of an existing one.
     261 *
     262 * Determines the device local hardware address.
     263 *
     264 * @param[in] device_id The new device identifier.
     265 * @param[in] service   The device driver service.
     266 * @param[in] mtu       The device maximum transmission unit.
     267 * @return              EOK on success.
     268 * @return              EEXIST if the device with the different service exists.
     269 * @return              ENOMEM if there is not enough memory left.
     270 * @return              Other error codes as defined for the
     271 *                      net_get_device_conf_req() function.
     272 * @return              Other error codes as defined for the
     273 *                      netif_bind_service() function.
     274 * @return              Other error codes as defined for the
     275 *                      netif_get_addr_req() function.
     276 */
     277static int eth_device_message(device_id_t device_id, services_t service,
     278    size_t mtu)
     279{
     280        eth_device_t *device;
    315281        int index;
    316         measured_string_t names[2] = {{str_dup("ETH_MODE"), 8}, {str_dup("ETH_DUMMY"), 9}};
    317         measured_string_ref configuration;
     282        measured_string_t names[2] = {
     283                {
     284                        (uint8_t *) "ETH_MODE",
     285                        8
     286                },
     287                {
     288                        (uint8_t *) "ETH_DUMMY",
     289                        9
     290                }
     291        };
     292        measured_string_t *configuration;
    318293        size_t count = sizeof(names) / sizeof(measured_string_t);
    319         char * data;
    320         eth_proto_ref proto;
     294        uint8_t *data;
     295        eth_proto_t *proto;
     296        int rc;
    321297
    322298        fibril_rwlock_write_lock(&eth_globals.devices_lock);
    323         // an existing device?
     299        /* An existing device? */
    324300        device = eth_devices_find(&eth_globals.devices, device_id);
    325         if(device){
    326                 if(device->service != service){
     301        if (device) {
     302                if (device->service != service) {
    327303                        printf("Device %d already exists\n", device->device_id);
    328304                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    329305                        return EEXIST;
    330                 }else{
    331                         // update mtu
    332                         if((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){
    333                                 device->mtu = mtu;
    334                         }else{
    335                                  device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
     306                }
     307               
     308                /* Update mtu */
     309                if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags)))
     310                        device->mtu = mtu;
     311                else
     312                        device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
     313               
     314                printf("Device %d already exists:\tMTU\t= %zu\n",
     315                    device->device_id, device->mtu);
     316                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     317               
     318                /* Notify all upper layer modules */
     319                fibril_rwlock_read_lock(&eth_globals.protos_lock);
     320                for (index = 0; index < eth_protos_count(&eth_globals.protos);
     321                    index++) {
     322                        proto = eth_protos_get_index(&eth_globals.protos,
     323                            index);
     324                        if (proto->phone) {
     325                                il_mtu_changed_msg(proto->phone,
     326                                    device->device_id, device->mtu,
     327                                    proto->service);
    336328                        }
    337                         printf("Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu);
    338                         fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    339                         // notify all upper layer modules
    340                         fibril_rwlock_read_lock(&eth_globals.protos_lock);
    341                         for(index = 0; index < eth_protos_count(&eth_globals.protos); ++ index){
    342                                 proto = eth_protos_get_index(&eth_globals.protos, index);
    343                                 if (proto->phone){
    344                                         il_mtu_changed_msg(proto->phone, device->device_id, device->mtu, proto->service);
    345                                 }
    346                         }
    347                         fibril_rwlock_read_unlock(&eth_globals.protos_lock);
    348                         return EOK;
    349                 }
    350         }else{
    351                 // create a new device
    352                 device = (eth_device_ref) malloc(sizeof(eth_device_t));
    353                 if(! device){
    354                         return ENOMEM;
    355                 }
    356                 device->device_id = device_id;
    357                 device->service = service;
    358                 device->flags = 0;
    359                 if((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){
    360                         device->mtu = mtu;
    361                 }else{
    362                          device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
    363                 }
    364                 configuration = &names[0];
    365                 if(ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, device->device_id, &configuration, count, &data))){
    366                         fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    367                         free(device);
    368                         return ERROR_CODE;
    369                 }
    370                 if(configuration){
    371                         if(! str_lcmp(configuration[0].value, "DIX", configuration[0].length)){
    372                                 device->flags |= ETH_DIX;
    373                         }else if(! str_lcmp(configuration[0].value, "8023_2_LSAP", configuration[0].length)){
    374                                 device->flags |= ETH_8023_2_LSAP;
    375                         }else device->flags |= ETH_8023_2_SNAP;
    376                         if((configuration[1].value) && (configuration[1].value[0] == 'y')){
    377                                 device->flags |= ETH_DUMMY;
    378                         }
    379                         net_free_settings(configuration, data);
    380                 }else{
     329                }
     330
     331                fibril_rwlock_read_unlock(&eth_globals.protos_lock);
     332                return EOK;
     333        }
     334       
     335        /* Create a new device */
     336        device = (eth_device_t *) malloc(sizeof(eth_device_t));
     337        if (!device)
     338                return ENOMEM;
     339
     340        device->device_id = device_id;
     341        device->service = service;
     342        device->flags = 0;
     343        if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags)))
     344                device->mtu = mtu;
     345        else
     346                device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
     347
     348        configuration = &names[0];
     349        rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id,
     350            &configuration, count, &data);
     351        if (rc != EOK) {
     352                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     353                free(device);
     354                return rc;
     355        }
     356
     357        if (configuration) {
     358                if (!str_lcmp((char *) configuration[0].value, "DIX",
     359                    configuration[0].length)) {
     360                        device->flags |= ETH_DIX;
     361                } else if(!str_lcmp((char *) configuration[0].value, "8023_2_LSAP",
     362                    configuration[0].length)) {
     363                        device->flags |= ETH_8023_2_LSAP;
     364                } else {
    381365                        device->flags |= ETH_8023_2_SNAP;
    382366                }
    383                 // bind the device driver
    384                 device->phone = netif_bind_service(device->service, device->device_id, SERVICE_ETHERNET, eth_receiver);
    385                 if(device->phone < 0){
    386                         fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    387                         free(device);
    388                         return device->phone;
    389                 }
    390                 // get hardware address
    391                 if(ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, &device->addr, &device->addr_data))){
    392                         fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    393                         free(device);
    394                         return ERROR_CODE;
    395                 }
    396                 // add to the cache
    397                 index = eth_devices_add(&eth_globals.devices, device->device_id, device);
    398                 if(index < 0){
    399                         fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    400                         free(device->addr);
    401                         free(device->addr_data);
    402                         free(device);
    403                         return index;
    404                 }
    405                 printf("%s: Device registered (id: %d, service: %d: mtu: %d, "
    406                     "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n",
    407                     NAME, device->device_id, device->service, device->mtu,
    408                     device->addr_data[0], device->addr_data[1],
    409                     device->addr_data[2], device->addr_data[3],
    410                     device->addr_data[4], device->addr_data[5], device->flags);
    411         }
     367               
     368                if (configuration[1].value &&
     369                    (configuration[1].value[0] == 'y')) {
     370                        device->flags |= ETH_DUMMY;
     371                }
     372                net_free_settings(configuration, data);
     373        } else {
     374                device->flags |= ETH_8023_2_SNAP;
     375        }
     376       
     377        /* Bind the device driver */
     378        device->phone = netif_bind_service(device->service, device->device_id,
     379            SERVICE_ETHERNET, eth_receiver);
     380        if (device->phone < 0) {
     381                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     382                free(device);
     383                return device->phone;
     384        }
     385       
     386        /* Get hardware address */
     387        rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
     388            &device->addr_data);
     389        if (rc != EOK) {
     390                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     391                free(device);
     392                return rc;
     393        }
     394       
     395        /* Add to the cache */
     396        index = eth_devices_add(&eth_globals.devices, device->device_id,
     397            device);
     398        if (index < 0) {
     399                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     400                free(device->addr);
     401                free(device->addr_data);
     402                free(device);
     403                return index;
     404        }
     405       
     406        printf("%s: Device registered (id: %d, service: %d: mtu: %zu, "
     407            "mac: %02x:%02x:%02x:%02x:%02x:%02x, flags: 0x%x)\n",
     408            NAME, device->device_id, device->service, device->mtu,
     409            device->addr_data[0], device->addr_data[1],
     410            device->addr_data[2], device->addr_data[3],
     411            device->addr_data[4], device->addr_data[5], device->flags);
     412
    412413        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    413414        return EOK;
    414415}
    415416
    416 eth_proto_ref eth_process_packet(int flags, packet_t packet){
    417         ERROR_DECLARE;
    418 
    419         eth_header_snap_ref header;
     417/** Processes the received packet and chooses the target registered module.
     418 *
     419 * @param[in] flags     The device flags.
     420 * @param[in] packet    The packet.
     421 * @return              The target registered module.
     422 * @return              NULL if the packet is not long enough.
     423 * @return              NULL if the packet is too long.
     424 * @return              NULL if the raw ethernet protocol is used.
     425 * @return              NULL if the dummy device FCS checksum is invalid.
     426 * @return              NULL if the packet address length is not big enough.
     427 */
     428static eth_proto_t *eth_process_packet(int flags, packet_t *packet)
     429{
     430        eth_header_snap_t *header;
    420431        size_t length;
    421432        eth_type_t type;
    422433        size_t prefix;
    423434        size_t suffix;
    424         eth_fcs_ref fcs;
    425         uint8_t * data;
     435        eth_fcs_t *fcs;
     436        uint8_t *data;
     437        int rc;
    426438
    427439        length = packet_get_data_length(packet);
    428         if(IS_DUMMY(flags)){
     440       
     441        if (IS_DUMMY(flags))
    429442                packet_trim(packet, sizeof(eth_preamble_t), 0);
    430         }
    431         if(length < sizeof(eth_header_t) + ETH_MIN_CONTENT + (IS_DUMMY(flags) ? ETH_SUFFIX : 0)) return NULL;
     443        if (length < sizeof(eth_header_t) + ETH_MIN_CONTENT +
     444            (IS_DUMMY(flags) ? ETH_SUFFIX : 0))
     445                return NULL;
     446       
    432447        data = packet_get_data(packet);
    433         header = (eth_header_snap_ref) data;
     448        header = (eth_header_snap_t *) data;
    434449        type = ntohs(header->header.ethertype);
    435         if(type >= ETH_MIN_PROTO){
    436                 // DIX Ethernet
     450       
     451        if (type >= ETH_MIN_PROTO) {
     452                /* DIX Ethernet */
    437453                prefix = sizeof(eth_header_t);
    438454                suffix = 0;
    439                 fcs = (eth_fcs_ref) data + length - sizeof(eth_fcs_t);
     455                fcs = (eth_fcs_t *) data + length - sizeof(eth_fcs_t);
    440456                length -= sizeof(eth_fcs_t);
    441         }else if(type <= ETH_MAX_CONTENT){
    442                 // translate "LSAP" values
    443                 if((header->lsap.dsap == ETH_LSAP_GLSAP) && (header->lsap.ssap == ETH_LSAP_GLSAP)){
    444                         // raw packet
    445                         // discard
     457        } else if(type <= ETH_MAX_CONTENT) {
     458                /* Translate "LSAP" values */
     459                if ((header->lsap.dsap == ETH_LSAP_GLSAP) &&
     460                    (header->lsap.ssap == ETH_LSAP_GLSAP)) {
     461                        /* Raw packet -- discard */
    446462                        return NULL;
    447                 }else if((header->lsap.dsap == ETH_LSAP_SNAP) && (header->lsap.ssap == ETH_LSAP_SNAP)){
    448                         // IEEE 802.3 + 802.2 + LSAP + SNAP
    449                         // organization code not supported
     463                } else if((header->lsap.dsap == ETH_LSAP_SNAP) &&
     464                    (header->lsap.ssap == ETH_LSAP_SNAP)) {
     465                        /*
     466                         * IEEE 802.3 + 802.2 + LSAP + SNAP
     467                         * organization code not supported
     468                         */
    450469                        type = ntohs(header->snap.ethertype);
    451                         prefix = sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t);
    452                 }else{
    453                         // IEEE 802.3 + 802.2 LSAP
     470                        prefix = sizeof(eth_header_t) +
     471                            sizeof(eth_header_lsap_t) +
     472                            sizeof(eth_header_snap_t);
     473                } else {
     474                        /* IEEE 802.3 + 802.2 LSAP */
    454475                        type = lsap_map(header->lsap.dsap);
    455                         prefix = sizeof(eth_header_t) + sizeof(eth_header_lsap_t);
    456                 }
    457                 suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0u;
    458                 fcs = (eth_fcs_ref) data + prefix + type + suffix;
     476                        prefix = sizeof(eth_header_t) +
     477                            sizeof(eth_header_lsap_t);
     478                }
     479
     480                suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0U;
     481                fcs = (eth_fcs_t *) data + prefix + type + suffix;
    459482                suffix += length - prefix - type;
    460483                length = prefix + type + suffix;
    461         }else{
    462                 // invalid length/type, should not occurr
     484        } else {
     485                /* Invalid length/type, should not occur */
    463486                return NULL;
    464487        }
    465         if(IS_DUMMY(flags)){
    466                 if((~ compute_crc32(~ 0u, data, length * 8)) != ntohl(*fcs)){
     488       
     489        if (IS_DUMMY(flags)) {
     490                if (~compute_crc32(~0U, data, length * 8) != ntohl(*fcs))
    467491                        return NULL;
    468                 }
    469492                suffix += sizeof(eth_fcs_t);
    470493        }
    471         if(ERROR_OCCURRED(packet_set_addr(packet, header->header.source_address, header->header.destination_address, ETH_ADDR))
    472                 || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))){
     494       
     495        rc = packet_set_addr(packet, header->header.source_address,
     496            header->header.destination_address, ETH_ADDR);
     497        if (rc != EOK)
    473498                return NULL;
    474         }
     499
     500        rc = packet_trim(packet, prefix, suffix);
     501        if (rc != EOK)
     502                return NULL;
     503       
    475504        return eth_protos_find(&eth_globals.protos, type);
    476505}
    477506
    478 int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
    479         eth_proto_ref proto;
    480         packet_t next;
    481         eth_device_ref device;
     507int nil_received_msg_local(int nil_phone, device_id_t device_id,
     508    packet_t *packet, services_t target)
     509{
     510        eth_proto_t *proto;
     511        packet_t *next;
     512        eth_device_t *device;
    482513        int flags;
    483514
    484515        fibril_rwlock_read_lock(&eth_globals.devices_lock);
    485516        device = eth_devices_find(&eth_globals.devices, device_id);
    486         if(! device){
     517        if (!device) {
    487518                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    488519                return ENOENT;
    489520        }
     521
    490522        flags = device->flags;
    491523        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
     524       
    492525        fibril_rwlock_read_lock(&eth_globals.protos_lock);
    493         do{
     526        do {
    494527                next = pq_detach(packet);
    495528                proto = eth_process_packet(flags, packet);
    496                 if(proto){
    497                         il_received_msg(proto->phone, device_id, packet, proto->service);
    498                 }else{
    499                         // drop invalid/unknown
    500                         pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
     529                if (proto) {
     530                        il_received_msg(proto->phone, device_id, packet,
     531                            proto->service);
     532                } else {
     533                        /* Drop invalid/unknown */
     534                        pq_release_remote(eth_globals.net_phone,
     535                            packet_get_id(packet));
    501536                }
    502537                packet = next;
    503         }while(packet);
     538        } while(packet);
     539
    504540        fibril_rwlock_read_unlock(&eth_globals.protos_lock);
    505541        return EOK;
    506542}
    507543
    508 int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){
    509         eth_device_ref device;
    510 
    511         if(!(addr_len && prefix && content && suffix)){
     544/** Returns the device packet dimensions for sending.
     545 *
     546 * @param[in] device_id The device identifier.
     547 * @param[out] addr_len The minimum reserved address length.
     548 * @param[out] prefix   The minimum reserved prefix size.
     549 * @param[out] content  The maximum content size.
     550 * @param[out] suffix   The minimum reserved suffix size.
     551 * @return              EOK on success.
     552 * @return              EBADMEM if either one of the parameters is NULL.
     553 * @return              ENOENT if there is no such device.
     554 */
     555static int eth_packet_space_message(device_id_t device_id, size_t *addr_len,
     556    size_t *prefix, size_t *content, size_t *suffix)
     557{
     558        eth_device_t *device;
     559
     560        if (!addr_len || !prefix || !content || !suffix)
    512561                return EBADMEM;
    513         }
     562       
    514563        fibril_rwlock_read_lock(&eth_globals.devices_lock);
    515564        device = eth_devices_find(&eth_globals.devices, device_id);
    516         if(! device){
     565        if (!device) {
    517566                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    518567                return ENOENT;
    519568        }
     569
    520570        *content = device->mtu;
    521571        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
     572       
    522573        *addr_len = ETH_ADDR;
    523574        *prefix = ETH_PREFIX;
    524575        *suffix = ETH_MIN_CONTENT + ETH_SUFFIX;
     576
    525577        return EOK;
    526578}
    527579
    528 int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address){
    529         eth_device_ref device;
    530 
    531         if(! address){
     580/** Returns the device hardware address.
     581 *
     582 * @param[in] device_id The device identifier.
     583 * @param[in] type      Type of the desired address.
     584 * @param[out] address  The device hardware address.
     585 * @return              EOK on success.
     586 * @return              EBADMEM if the address parameter is NULL.
     587 * @return              ENOENT if there no such device.
     588 */
     589static int eth_addr_message(device_id_t device_id, eth_addr_type_t type,
     590    measured_string_t **address)
     591{
     592        eth_device_t *device;
     593
     594        if (!address)
    532595                return EBADMEM;
    533         }
    534         if(type == ETH_BROADCAST_ADDR){
     596
     597        if (type == ETH_BROADCAST_ADDR) {
    535598                *address = eth_globals.broadcast_addr;
    536         }else{
     599        } else {
    537600                fibril_rwlock_read_lock(&eth_globals.devices_lock);
    538601                device = eth_devices_find(&eth_globals.devices, device_id);
    539                 if(! device){
     602                if (!device) {
    540603                        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    541604                        return ENOENT;
     
    544607                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    545608        }
     609       
    546610        return (*address) ? EOK : ENOENT;
    547611}
    548612
    549 int eth_register_message(services_t service, int phone){
    550         eth_proto_ref proto;
     613/** Registers receiving module service.
     614 *
     615 * Passes received packets for this service.
     616 *
     617 * @param[in] service   The module service.
     618 * @param[in] phone     The service phone.
     619 * @return              EOK on success.
     620 * @return              ENOENT if the service is not known.
     621 * @return              ENOMEM if there is not enough memory left.
     622 */
     623static int eth_register_message(services_t service, int phone)
     624{
     625        eth_proto_t *proto;
    551626        int protocol;
    552627        int index;
    553628
    554629        protocol = protocol_map(SERVICE_ETHERNET, service);
    555         if(! protocol){
     630        if (!protocol)
    556631                return ENOENT;
    557         }
     632
    558633        fibril_rwlock_write_lock(&eth_globals.protos_lock);
    559634        proto = eth_protos_find(&eth_globals.protos, protocol);
    560         if(proto){
     635        if (proto) {
    561636                proto->phone = phone;
    562637                fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    563638                return EOK;
    564         }else{
    565                 proto = (eth_proto_ref) malloc(sizeof(eth_proto_t));
    566                 if(! proto){
     639        } else {
     640                proto = (eth_proto_t *) malloc(sizeof(eth_proto_t));
     641                if (!proto) {
    567642                        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    568643                        return ENOMEM;
    569644                }
     645
    570646                proto->service = service;
    571647                proto->protocol = protocol;
    572648                proto->phone = phone;
     649
    573650                index = eth_protos_add(&eth_globals.protos, protocol, proto);
    574                 if(index < 0){
     651                if (index < 0) {
    575652                        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    576653                        free(proto);
     
    579656        }
    580657       
    581         printf("%s: Protocol registered (protocol: %d, service: %d, phone: %d)\n",
    582             NAME, proto->protocol, proto->service, proto->phone);
     658        printf("%s: Protocol registered (protocol: %d, service: %d, phone: "
     659            "%d)\n", NAME, proto->protocol, proto->service, proto->phone);
    583660       
    584661        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
     
    586663}
    587664
    588 int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu){
    589         eth_header_snap_ref header;
    590         eth_header_lsap_ref header_lsap;
    591         eth_header_ref header_dix;
    592         eth_fcs_ref fcs;
    593         uint8_t * src;
    594         uint8_t * dest;
     665/** Prepares the packet for sending.
     666 *
     667 * @param[in] flags     The device flags.
     668 * @param[in] packet    The packet.
     669 * @param[in] src_addr  The source hardware address.
     670 * @param[in] ethertype The ethernet protocol type.
     671 * @param[in] mtu       The device maximum transmission unit.
     672 * @return              EOK on success.
     673 * @return              EINVAL if the packet addresses length is not long
     674 *                      enough.
     675 * @return              EINVAL if the packet is bigger than the device MTU.
     676 * @return              ENOMEM if there is not enough memory in the packet.
     677 */
     678static int
     679eth_prepare_packet(int flags, packet_t *packet, uint8_t *src_addr, int ethertype,
     680    size_t mtu)
     681{
     682        eth_header_snap_t *header;
     683        eth_header_lsap_t *header_lsap;
     684        eth_header_t *header_dix;
     685        eth_fcs_t *fcs;
     686        uint8_t *src;
     687        uint8_t *dest;
    595688        size_t length;
    596689        int i;
    597         void * padding;
    598         eth_preamble_ref preamble;
     690        void *padding;
     691        eth_preamble_t *preamble;
    599692
    600693        i = packet_get_addr(packet, &src, &dest);
    601         if(i < 0){
     694        if (i < 0)
    602695                return i;
    603         }
    604         if(i != ETH_ADDR){
     696        if (i != ETH_ADDR)
    605697                return EINVAL;
    606         }
     698
    607699        length = packet_get_data_length(packet);
    608         if(length > mtu){
     700        if (length > mtu)
    609701                return EINVAL;
    610         }
    611         if(length < ETH_MIN_TAGGED_CONTENT(flags)){
    612                 padding = packet_suffix(packet, ETH_MIN_TAGGED_CONTENT(flags) - length);
    613                 if(! padding){
     702       
     703        if (length < ETH_MIN_TAGGED_CONTENT(flags)) {
     704                padding = packet_suffix(packet,
     705                    ETH_MIN_TAGGED_CONTENT(flags) - length);
     706                if (!padding)
    614707                        return ENOMEM;
    615                 }
     708
    616709                bzero(padding, ETH_MIN_TAGGED_CONTENT(flags) - length);
    617710        }
    618         if(IS_DIX(flags)){
     711       
     712        if (IS_DIX(flags)) {
    619713                header_dix = PACKET_PREFIX(packet, eth_header_t);
    620                 if(! header_dix){
     714                if (!header_dix)
    621715                        return ENOMEM;
    622                 }
     716               
    623717                header_dix->ethertype = (uint16_t) ethertype;
    624718                memcpy(header_dix->source_address, src_addr, ETH_ADDR);
    625719                memcpy(header_dix->destination_address, dest, ETH_ADDR);
    626720                src = &header_dix->destination_address[0];
    627         }else if(IS_8023_2_LSAP(flags)){
     721        } else if(IS_8023_2_LSAP(flags)) {
    628722                header_lsap = PACKET_PREFIX(packet, eth_header_lsap_t);
    629                 if(! header_lsap){
     723                if (!header_lsap)
    630724                        return ENOMEM;
    631                 }
    632                 header_lsap->header.ethertype = htons(length + sizeof(eth_header_lsap_t));
     725               
     726                header_lsap->header.ethertype = htons(length +
     727                    sizeof(eth_header_lsap_t));
    633728                header_lsap->lsap.dsap = lsap_unmap(ntohs(ethertype));
    634729                header_lsap->lsap.ssap = header_lsap->lsap.dsap;
     
    637732                memcpy(header_lsap->header.destination_address, dest, ETH_ADDR);
    638733                src = &header_lsap->header.destination_address[0];
    639         }else if(IS_8023_2_SNAP(flags)){
     734        } else if(IS_8023_2_SNAP(flags)) {
    640735                header = PACKET_PREFIX(packet, eth_header_snap_t);
    641                 if(! header){
     736                if (!header)
    642737                        return ENOMEM;
    643                 }
    644                 header->header.ethertype = htons(length + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t));
     738               
     739                header->header.ethertype = htons(length +
     740                    sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t));
    645741                header->lsap.dsap = (uint16_t) ETH_LSAP_SNAP;
    646742                header->lsap.ssap = header->lsap.dsap;
    647743                header->lsap.ctrl = IEEE_8023_2_UI;
    648                 for(i = 0; i < 3; ++ i){
     744               
     745                for (i = 0; i < 3; ++ i)
    649746                        header->snap.protocol[i] = 0;
    650                 }
     747               
    651748                header->snap.ethertype = (uint16_t) ethertype;
    652749                memcpy(header->header.source_address, src_addr, ETH_ADDR);
     
    654751                src = &header->header.destination_address[0];
    655752        }
    656         if(IS_DUMMY(flags)){
     753       
     754        if (IS_DUMMY(flags)) {
    657755                preamble = PACKET_PREFIX(packet, eth_preamble_t);
    658                 if(! preamble){
     756                if (!preamble)
    659757                        return ENOMEM;
    660                 }
    661                 for(i = 0; i < 7; ++ i){
     758               
     759                for (i = 0; i < 7; ++ i)
    662760                        preamble->preamble[i] = ETH_PREAMBLE;
    663                 }
     761               
    664762                preamble->sfd = ETH_SFD;
     763               
    665764                fcs = PACKET_SUFFIX(packet, eth_fcs_t);
    666                 if(! fcs){
     765                if (!fcs)
    667766                        return ENOMEM;
    668                 }
    669                 *fcs = htonl(~ compute_crc32(~ 0u, src, length * 8));
    670         }
     767
     768                *fcs = htonl(~compute_crc32(~0U, src, length * 8));
     769        }
     770       
    671771        return EOK;
    672772}
    673773
    674 int eth_send_message(device_id_t device_id, packet_t packet, services_t sender){
    675         ERROR_DECLARE;
    676 
    677         eth_device_ref device;
    678         packet_t next;
    679         packet_t tmp;
     774/** Sends the packet queue.
     775 *
     776 * Sends only packet successfully processed by the eth_prepare_packet()
     777 * function.
     778 *
     779 * @param[in] device_id The device identifier.
     780 * @param[in] packet    The packet queue.
     781 * @param[in] sender    The sending module service.
     782 * @return              EOK on success.
     783 * @return              ENOENT if there no such device.
     784 * @return              EINVAL if the service parameter is not known.
     785 */
     786static int eth_send_message(device_id_t device_id, packet_t *packet,
     787    services_t sender)
     788{
     789        eth_device_t *device;
     790        packet_t *next;
     791        packet_t *tmp;
    680792        int ethertype;
     793        int rc;
    681794
    682795        ethertype = htons(protocol_map(SERVICE_ETHERNET, sender));
    683         if(! ethertype){
     796        if (!ethertype) {
    684797                pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
    685798                return EINVAL;
    686799        }
     800       
    687801        fibril_rwlock_read_lock(&eth_globals.devices_lock);
    688802        device = eth_devices_find(&eth_globals.devices, device_id);
    689         if(! device){
     803        if (!device) {
    690804                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    691805                return ENOENT;
    692806        }
    693         // process packet queue
     807       
     808        /* Process packet queue */
    694809        next = packet;
    695         do{
    696                 if(ERROR_OCCURRED(eth_prepare_packet(device->flags, next, (uint8_t *) device->addr->value, ethertype, device->mtu))){
    697                         // release invalid packet
     810        do {
     811                rc = eth_prepare_packet(device->flags, next,
     812                    (uint8_t *) device->addr->value, ethertype, device->mtu);
     813                if (rc != EOK) {
     814                        /* Release invalid packet */
    698815                        tmp = pq_detach(next);
    699                         if(next == packet){
     816                        if (next == packet)
    700817                                packet = tmp;
    701                         }
    702                         pq_release_remote(eth_globals.net_phone, packet_get_id(next));
     818                        pq_release_remote(eth_globals.net_phone,
     819                            packet_get_id(next));
    703820                        next = tmp;
    704                 }else{
     821                } else {
    705822                        next = pq_next(next);
    706823                }
    707         }while(next);
    708         // send packet queue
    709         if(packet){
    710                 netif_send_msg(device->phone, device_id, packet, SERVICE_ETHERNET);
    711         }
     824        } while(next);
     825       
     826        /* Send packet queue */
     827        if (packet) {
     828                netif_send_msg(device->phone, device_id, packet,
     829                    SERVICE_ETHERNET);
     830        }
     831
    712832        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    713833        return EOK;
    714834}
    715835
    716 int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
    717     ipc_call_t *answer, int *answer_count)
    718 {
    719         ERROR_DECLARE;
    720        
    721         measured_string_ref address;
    722         packet_t packet;
     836int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
     837    ipc_call_t *answer, size_t *answer_count)
     838{
     839        measured_string_t *address;
     840        packet_t *packet;
    723841        size_t addrlen;
    724842        size_t prefix;
    725843        size_t suffix;
    726844        size_t content;
     845        int rc;
    727846       
    728847        *answer_count = 0;
    729         switch (IPC_GET_METHOD(*call)) {
    730                 case IPC_M_PHONE_HUNGUP:
     848        switch (IPC_GET_IMETHOD(*call)) {
     849        case IPC_M_PHONE_HUNGUP:
     850                return EOK;
     851       
     852        case NET_NIL_DEVICE:
     853                return eth_device_message(IPC_GET_DEVICE(*call),
     854                    IPC_GET_SERVICE(*call), IPC_GET_MTU(*call));
     855        case NET_NIL_SEND:
     856                rc = packet_translate_remote(eth_globals.net_phone, &packet,
     857                    IPC_GET_PACKET(*call));
     858                if (rc != EOK)
     859                        return rc;
     860                return eth_send_message(IPC_GET_DEVICE(*call), packet,
     861                    IPC_GET_SERVICE(*call));
     862        case NET_NIL_PACKET_SPACE:
     863                rc = eth_packet_space_message(IPC_GET_DEVICE(*call), &addrlen,
     864                    &prefix, &content, &suffix);
     865                if (rc != EOK)
     866                        return rc;
     867                IPC_SET_ADDR(*answer, addrlen);
     868                IPC_SET_PREFIX(*answer, prefix);
     869                IPC_SET_CONTENT(*answer, content);
     870                IPC_SET_SUFFIX(*answer, suffix);
     871                *answer_count = 4;
     872                return EOK;
     873        case NET_NIL_ADDR:
     874                rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_LOCAL_ADDR,
     875                    &address);
     876                if (rc != EOK)
     877                        return rc;
     878                return measured_strings_reply(address, 1);
     879        case NET_NIL_BROADCAST_ADDR:
     880                rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_BROADCAST_ADDR,
     881                    &address);
     882                if (rc != EOK)
    731883                        return EOK;
    732                 case NET_NIL_DEVICE:
    733                         return eth_device_message(IPC_GET_DEVICE(call),
    734                             IPC_GET_SERVICE(call), IPC_GET_MTU(call));
    735                 case NET_NIL_SEND:
    736                         ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone, &packet,
    737                             IPC_GET_PACKET(call)));
    738                         return eth_send_message(IPC_GET_DEVICE(call), packet,
    739                             IPC_GET_SERVICE(call));
    740                 case NET_NIL_PACKET_SPACE:
    741                         ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call),
    742                             &addrlen, &prefix, &content, &suffix));
    743                         IPC_SET_ADDR(answer, addrlen);
    744                         IPC_SET_PREFIX(answer, prefix);
    745                         IPC_SET_CONTENT(answer, content);
    746                         IPC_SET_SUFFIX(answer, suffix);
    747                         *answer_count = 4;
    748                         return EOK;
    749                 case NET_NIL_ADDR:
    750                         ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
    751                             ETH_LOCAL_ADDR, &address));
    752                         return measured_strings_reply(address, 1);
    753                 case NET_NIL_BROADCAST_ADDR:
    754                         ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
    755                             ETH_BROADCAST_ADDR, &address));
    756                         return measured_strings_reply(address, 1);
    757                 case IPC_M_CONNECT_TO_ME:
    758                         return eth_register_message(NIL_GET_PROTO(call),
    759                             IPC_GET_PHONE(call));
     884                return measured_strings_reply(address, 1);
     885        case IPC_M_CONNECT_TO_ME:
     886                return eth_register_message(NIL_GET_PROTO(*call),
     887                    IPC_GET_PHONE(*call));
    760888        }
    761889       
     
    763891}
    764892
    765 void eth_receiver(ipc_callid_t iid, ipc_call_t * icall){
    766         ERROR_DECLARE;
    767 
    768         packet_t packet;
    769 
    770         while(true){
    771 //              printf("message %d - %d\n", IPC_GET_METHOD(*icall), NET_NIL_FIRST);
    772                 switch(IPC_GET_METHOD(*icall)){
    773                         case NET_NIL_DEVICE_STATE:
    774                                 nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
    775                                 ipc_answer_0(iid, EOK);
    776                                 break;
    777                         case NET_NIL_RECEIVED:
    778                                 if(! ERROR_OCCURRED(packet_translate_remote(eth_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){
    779                                         ERROR_CODE = nil_received_msg_local(0, IPC_GET_DEVICE(icall), packet, 0);
    780                                 }
    781                                 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
    782                                 break;
    783                         default:
    784                                 ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
    785                 }
    786                 iid = async_get_call(icall);
    787         }
    788 }
    789 
    790 #ifndef CONFIG_NETIF_NIL_BUNDLE
    791 
    792 /** Default thread for new connections.
    793  *
    794  * @param[in] iid The initial message identifier.
    795  * @param[in] icall The initial message call structure.
    796  *
    797  */
    798 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    799 {
    800         /*
    801          * Accept the connection
    802          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    803          */
    804         ipc_answer_0(iid, EOK);
    805        
    806         while(true) {
    807                 ipc_call_t answer;
    808                 int answer_count;
    809                
    810                 /* Clear the answer structure */
    811                 refresh_answer(&answer, &answer_count);
    812                
    813                 /* Fetch the next message */
    814                 ipc_call_t call;
    815                 ipc_callid_t callid = async_get_call(&call);
    816                
    817                 /* Process the message */
    818                 int res = nil_module_message_standalone(NAME, callid, &call, &answer,
    819                     &answer_count);
    820                
    821                 /* End if said to either by the message or the processing result */
    822                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
    823                         return;
    824                
    825                 /* Answer the message */
    826                 answer_call(callid, res, &answer, answer_count);
    827         }
    828 }
    829 
    830893int main(int argc, char *argv[])
    831894{
    832         ERROR_DECLARE;
    833        
    834895        /* Start the module */
    835         if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
    836                 return ERROR_CODE;
    837        
    838         return EOK;
    839 }
    840 
    841 #endif /* CONFIG_NETIF_NIL_BUNDLE */
     896        return nil_module_start(SERVICE_ETHERNET);
     897}
    842898
    843899/** @}
Note: See TracChangeset for help on using the changeset viewer.