Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/nic/src/nic_driver.c

    r49bd793b r77ad86c  
    4646#include <ipc/irc.h>
    4747#include <sysinfo.h>
    48 
     48#include <as.h>
    4949#include <devman.h>
    5050#include <ddf/interrupt.h>
    51 #include <net_interface.h>
    5251#include <ops/nic.h>
    53 #include <packet_client.h>
    54 #include <packet_remote.h>
    55 #include <net/packet_header.h>
    5652#include <errno.h>
    5753
    5854#include "nic_driver.h"
     55#include "nic_ev.h"
    5956#include "nic_impl.h"
    6057
     
    6461
    6562/**
    66  * Initializes libraries required for NIC framework - logger, packet manager
     63 * Initializes libraries required for NIC framework - logger
    6764 *
    6865 * @param name  Name of the device/driver (used in logging)
     
    7976        snprintf(buffer, 256, "drv/" DEVICE_CATEGORY_NIC "/%s", name);
    8077       
    81         /* Initialize packet manager */
    82         return pm_init();
    83 }
    84 
    85 /**
    86  * Fill in the default implementations for device options and NIC interface.
     78        return EOK;
     79}
     80
     81/** Fill in the default implementations for device options and NIC interface.
    8782 *
    8883 * @param driver_ops
     
    9388    nic_iface_t *iface)
    9489{
    95         if (driver_ops) {
    96                 if (!driver_ops->device_added)
    97                         driver_ops->device_added = nic_device_added_impl;
    98         }
    99 
    10090        if (dev_ops) {
    10191                if (!dev_ops->open)
     
    114104                if (!iface->set_state)
    115105                        iface->set_state = nic_set_state_impl;
    116                 if (!iface->send_message)
    117                         iface->send_message = nic_send_message_impl;
    118                 if (!iface->connect_to_nil)
    119                         iface->connect_to_nil = nic_connect_to_nil_impl;
     106                if (!iface->send_frame)
     107                        iface->send_frame = nic_send_frame_impl;
     108                if (!iface->callback_create)
     109                        iface->callback_create = nic_callback_create_impl;
    120110                if (!iface->get_address)
    121111                        iface->get_address = nic_get_address_impl;
     
    162152
    163153/**
    164  * Setup write packet handler. This MUST be called in the add_device handler
     154 * Setup send frame handler. This MUST be called in the add_device handler
    165155 * if the nic_send_message_impl function is used for sending messages (filled
    166156 * as send_message member of the nic_iface_t structure). The function must not
     
    168158 *
    169159 * @param nic_data
    170  * @param wpfunc                Function handling the write_packet request
    171  */
    172 void nic_set_write_packet_handler(nic_t *nic_data, write_packet_handler wpfunc)
    173 {
    174         nic_data->write_packet = wpfunc;
     160 * @param sffunc        Function handling the send_frame request
     161 */
     162void nic_set_send_frame_handler(nic_t *nic_data, send_frame_handler sffunc)
     163{
     164        nic_data->send_frame = sffunc;
    175165}
    176166
     
    270260}
    271261
    272 /**
    273  * Just a wrapper over the packet_get_1_remote function
    274  */
    275 packet_t *nic_alloc_packet(nic_t *nic_data, size_t data_size)
    276 {
    277         return packet_get_1_remote(nic_data->net_session, data_size);
    278 }
    279 
    280 
    281 /**
    282  * Just a wrapper over the pq_release_remote function
    283  */
    284 void nic_release_packet(nic_t *nic_data, packet_t *packet)
    285 {
    286         pq_release_remote(nic_data->net_session, packet_get_id(packet));
    287 }
    288 
    289 /** Allocate frame and packet
     262/** Allocate frame
    290263 *
    291264 *  @param nic_data     The NIC driver data
    292  *  @param packet_size  Size of packet
    293  *  @param offload_size Size of packet offload
     265 *  @param size         Frame size in bytes
    294266 *  @return pointer to allocated frame if success, NULL otherwise
    295267 */
    296 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size)
     268nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)
    297269{
    298270        nic_frame_t *frame;
     
    313285        }
    314286
    315         packet_t *packet = nic_alloc_packet(nic_data, packet_size);
    316         if (!packet) {
     287        frame->data = malloc(size);
     288        if (frame->data == NULL) {
    317289                free(frame);
    318290                return NULL;
    319291        }
    320292
    321         frame->packet = packet;
     293        frame->size = size;
    322294        return frame;
    323295}
     
    332304        if (!frame)
    333305                return;
    334         if (frame->packet != NULL) {
    335                 nic_release_packet(nic_data, frame->packet);
    336         }
     306
     307        if (frame->data != NULL) {
     308                free(frame->data);
     309                frame->data = NULL;
     310                frame->size = 0;
     311        }
     312
    337313        fibril_mutex_lock(&nic_globals.lock);
    338314        if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) {
     
    447423
    448424/**
    449  * Connect to the NET and IRQ services. This function should be called only from
     425 * Connect to IRC service. This function should be called only from
    450426 * the add_device handler, thus no locking is required.
    451427 *
     
    454430 * @return EOK          If connection was successful.
    455431 * @return EINVAL       If the IRC service cannot be determined.
    456  * @return EREFUSED     If NET or IRC service cannot be connected.
     432 * @return EREFUSED     If IRC service cannot be connected.
    457433 */
    458434int nic_connect_to_services(nic_t *nic_data)
    459435{
    460         /* NET service */
    461         nic_data->net_session = service_connect_blocking(EXCHANGE_SERIALIZE,
    462                 SERVICE_NETWORKING, 0, 0);
    463         if (nic_data->net_session == NULL)
    464                 return errno;
    465        
    466436        /* IRC service */
    467437        sysarg_t apic;
     
    480450       
    481451        return EOK;
    482 }
    483 
    484 /** Notify the NET service that the device is ready
    485  *
    486  * @param nic NICF structure
    487  *
    488  * @return EOK on success
    489  *
    490  */
    491 int nic_ready(nic_t *nic)
    492 {
    493         fibril_rwlock_read_lock(&nic->main_lock);
    494        
    495         async_sess_t *session = nic->net_session;
    496         devman_handle_t handle = nic->dev->handle;
    497        
    498         fibril_rwlock_read_unlock(&nic->main_lock);
    499        
    500         if (session == NULL)
    501                 return EINVAL;
    502        
    503         return net_driver_ready(session, handle);
    504452}
    505453
     
    546494       
    547495        /* Notify NIL layer (and uppper) if bound - not in add_device */
    548         if (nic_data->nil_session != NULL) {
    549                 int rc = nil_addr_changed_msg(nic_data->nil_session,
    550                     nic_data->device_id, address);
     496        if (nic_data->client_session != NULL) {
     497                int rc = nic_ev_addr_changed(nic_data->client_session,
     498                    address);
    551499                if (rc != EOK) {
    552500                        fibril_rwlock_write_unlock(&nic_data->main_lock);
     
    604552
    605553/**
    606  * The busy flag can be set to 1 only in the write_packet handler, to 0 it can
     554 * The busy flag can be set to 1 only in the send_frame handler, to 0 it can
    607555 * be set anywhere.
    608556 *
     
    613561{
    614562        /*
    615          * When the function is called in write_packet handler the main lock is
     563         * When the function is called in send_frame handler the main lock is
    616564         * locked so no race can happen.
    617565         * Otherwise, when it is unexpectedly set to 0 (even with main lock held
     
    622570
    623571/**
    624  * Provided for correct naming conventions.
    625  * The packet is checked by filters and then sent up to the NIL layer or
    626  * discarded, the frame is released.
    627  *
    628  * @param nic_data
    629  * @param frame         The frame containing received packet
     572 * This is the function that the driver should call when it receives a frame.
     573 * The frame is checked by filters and then sent up to the NIL layer or
     574 * discarded. The frame is released.
     575 *
     576 * @param nic_data
     577 * @param frame         The received frame
    630578 */
    631579void nic_received_frame(nic_t *nic_data, nic_frame_t *frame)
    632580{
    633         nic_received_packet(nic_data, frame->packet);
    634         frame->packet = NULL;
    635         nic_release_frame(nic_data, frame);
    636 }
    637 
    638 /**
    639  * This is the function that the driver should call when it receives a packet.
    640  * The packet is checked by filters and then sent up to the NIL layer or
    641  * discarded.
    642  *
    643  * @param nic_data
    644  * @param packet                The received packet
    645  */
    646 void nic_received_packet(nic_t *nic_data, packet_t *packet)
    647 {
    648581        /* Note: this function must not lock main lock, because loopback driver
    649          *               calls it inside write_packet handler (with locked main lock) */
    650         packet_id_t pid = packet_get_id(packet);
    651        
     582         *               calls it inside send_frame handler (with locked main lock) */
    652583        fibril_rwlock_read_lock(&nic_data->rxc_lock);
    653584        nic_frame_type_t frame_type;
    654         int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type);
     585        int check = nic_rxc_check(&nic_data->rx_control, frame->data,
     586            frame->size, &frame_type);
    655587        fibril_rwlock_read_unlock(&nic_data->rxc_lock);
    656588        /* Update statistics */
    657589        fibril_rwlock_write_lock(&nic_data->stats_lock);
    658         /* Both sending message up and releasing packet are atomic IPC calls */
     590
    659591        if (nic_data->state == NIC_STATE_ACTIVE && check) {
    660592                nic_data->stats.receive_packets++;
    661                 nic_data->stats.receive_bytes += packet_get_data_length(packet);
     593                nic_data->stats.receive_bytes += frame->size;
    662594                switch (frame_type) {
    663595                case NIC_FRAME_MULTICAST:
     
    671603                }
    672604                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    673                 nil_received_msg(nic_data->nil_session, nic_data->device_id, pid);
     605                nic_ev_received(nic_data->client_session, frame->data,
     606                    frame->size);
    674607        } else {
    675608                switch (frame_type) {
     
    685618                }
    686619                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    687                 nic_release_packet(nic_data, packet);
    688         }
    689 }
    690 
    691 /**
    692  * This function is to be used only in the loopback driver. It's workaround
    693  * for the situation when the packet does not contain ethernet address.
    694  * The filtering is therefore not applied here.
    695  *
    696  * @param nic_data
    697  * @param packet
    698  */
    699 void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet)
    700 {
    701         fibril_rwlock_write_lock(&nic_data->stats_lock);
    702         nic_data->stats.receive_packets++;
    703         nic_data->stats.receive_bytes += packet_get_data_length(packet);
    704         fibril_rwlock_write_unlock(&nic_data->stats_lock);
    705        
    706         nil_received_msg(nic_data->nil_session, nic_data->device_id,
    707             packet_get_id(packet));
    708 }
    709 
    710 /**
    711  * Some NICs can receive multiple packets during single interrupt. These can
     620        }
     621        nic_release_frame(nic_data, frame);
     622}
     623
     624/**
     625 * Some NICs can receive multiple frames during single interrupt. These can
    712626 * send them in whole list of frames (actually nic_frame_t structures), then
    713  * the list is deallocated and each packet is passed to the
     627 * the list is deallocated and each frame is passed to the
    714628 * nic_received_packet function.
    715629 *
     
    726640
    727641                list_remove(&frame->link);
    728                 nic_received_packet(nic_data, frame->packet);
    729                 frame->packet = NULL;
    730                 nic_release_frame(nic_data, frame);
     642                nic_received_frame(nic_data, frame);
    731643        }
    732644        nic_driver_release_frame_list(frames);
     
    758670        nic_data->dev = NULL;
    759671        nic_data->fun = NULL;
    760         nic_data->device_id = NIC_DEVICE_INVALID_ID;
    761672        nic_data->state = NIC_STATE_STOPPED;
    762         nic_data->net_session = NULL;
    763         nic_data->nil_session = NULL;
     673        nic_data->client_session = NULL;
    764674        nic_data->irc_session = NULL;
    765675        nic_data->poll_mode = NIC_POLL_IMMEDIATE;
    766676        nic_data->default_poll_mode = NIC_POLL_IMMEDIATE;
    767         nic_data->write_packet = NULL;
     677        nic_data->send_frame = NULL;
    768678        nic_data->on_activating = NULL;
    769679        nic_data->on_going_down = NULL;
     
    815725 */
    816726static void nic_destroy(nic_t *nic_data) {
    817         if (nic_data->net_session != NULL) {
    818                 async_hangup(nic_data->net_session);
    819         }
    820 
    821         if (nic_data->nil_session != NULL) {
    822                 async_hangup(nic_data->nil_session);
     727        if (nic_data->client_session != NULL) {
     728                async_hangup(nic_data->client_session);
    823729        }
    824730
     
    846752
    847753/**
    848  * Creates an exposed DDF function for the device, named "port0".
    849  * Device options are set as this function's options. The function is bound
    850  * (see ddf_fun_bind) and then registered to the DEVICE_CATEGORY_NIC class.
    851  * Note: this function should be called only from add_device handler, therefore
    852  * we don't need to use locks.
    853  *
    854  * @param nic_data      The NIC structure
    855  * @param ops           Device options for the DDF function.
    856  */
    857 int nic_register_as_ddf_fun(nic_t *nic_data, ddf_dev_ops_t *ops)
    858 {
    859         int rc;
    860         assert(nic_data);
    861 
    862         nic_data->fun = ddf_fun_create(nic_data->dev, fun_exposed, "port0");
    863         if (nic_data->fun == NULL)
    864                 return ENOMEM;
    865        
    866         nic_data->fun->ops = ops;
    867         nic_data->fun->driver_data = nic_data;
    868 
    869         rc = ddf_fun_bind(nic_data->fun);
    870         if (rc != EOK) {
    871                 ddf_fun_destroy(nic_data->fun);
    872                 return rc;
    873         }
    874 
    875         rc = ddf_fun_add_to_category(nic_data->fun, DEVICE_CATEGORY_NIC);
    876         if (rc != EOK) {
    877                 ddf_fun_destroy(nic_data->fun);
    878                 return rc;
    879         }
    880        
    881         return EOK;
    882 }
    883 
    884 /**
    885754 * Set information about current HW filtering.
    886755 *  1 ...       Only those frames we want to receive are passed through HW
     
    1097966{
    1098967        return nic_data->fun;
     968}
     969
     970/**
     971 * @param nic_data
     972 * @param fun
     973 */
     974void nic_set_ddf_fun(nic_t *nic_data, ddf_fun_t *fun)
     975{
     976        nic_data->fun = fun;
    1099977}
    1100978
     
    13291207}
    13301208
    1331 // FIXME: Later
    1332 #if 0
    1333 
    1334 /** Lock packet for DMA usage
    1335  *
    1336  * @param packet
    1337  * @return physical address of packet
    1338  */
    1339 void *nic_dma_lock_packet(packet_t *packet)
    1340 {
    1341         void *phys_addr;
    1342         size_t locked;
    1343         int rc = dma_lock(packet, &phys_addr, 1, &locked);
    1344         if (rc != EOK)
    1345                 return NULL;
    1346        
    1347         assert(locked == 1);
    1348         return phys_addr;
    1349 }
    1350 
    1351 /** Unlock packet after DMA usage
    1352  *
    1353  * @param packet
    1354  */
    1355 void nic_dma_unlock_packet(packet_t *packet)
    1356 {
    1357         size_t unlocked;
    1358         int rc = dma_unlock(packet, 1, &unlocked);
    1359         if (rc != EOK)
    1360                 return;
    1361        
    1362         assert(unlocked == 1);
    1363 }
    1364 
    1365 #endif
    1366 
    13671209/** @}
    13681210 */
Note: See TracChangeset for help on using the changeset viewer.