Changeset cfb79747 in mainline for uspace/lib/nic/src/nic_driver.c


Ignore:
Timestamp:
2012-02-14T22:06:15Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a31aad1
Parents:
199112e4 (diff), e10d41a (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/lib/nic/src/nic_driver.c

    r199112e4 rcfb79747  
    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();
     78        return EOK;
    8379}
    8480
     
    9389    nic_iface_t *iface)
    9490{
    95         if (driver_ops) {
    96                 if (!driver_ops->device_added)
    97                         driver_ops->device_added = nic_device_added_impl;
    98         }
    99 
    10091        if (dev_ops) {
    10192                if (!dev_ops->open)
     
    116107                if (!iface->send_frame)
    117108                        iface->send_frame = nic_send_frame_impl;
    118                 if (!iface->connect_to_nil)
    119                         iface->connect_to_nil = nic_connect_to_nil_impl;
     109                if (!iface->callback_create)
     110                        iface->callback_create = nic_callback_create_impl;
    120111                if (!iface->get_address)
    121112                        iface->get_address = nic_get_address_impl;
     
    162153
    163154/**
    164  * Setup write packet handler. This MUST be called in the add_device handler
     155 * Setup send frame handler. This MUST be called in the add_device handler
    165156 * if the nic_send_message_impl function is used for sending messages (filled
    166157 * as send_message member of the nic_iface_t structure). The function must not
     
    270261}
    271262
    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
     263/** Allocate frame
    290264 *
    291265 *  @param nic_data     The NIC driver data
    292  *  @param packet_size  Size of packet
    293  *  @param offload_size Size of packet offload
     266 *  @param size         Frame size in bytes
    294267 *  @return pointer to allocated frame if success, NULL otherwise
    295268 */
    296 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size)
     269nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)
    297270{
    298271        nic_frame_t *frame;
     
    313286        }
    314287
    315         packet_t *packet = nic_alloc_packet(nic_data, packet_size);
    316         if (!packet) {
     288        frame->data = malloc(size);
     289        if (frame->data == NULL) {
    317290                free(frame);
    318291                return NULL;
    319292        }
    320293
    321         frame->packet = packet;
     294        frame->size = size;
    322295        return frame;
    323296}
     
    332305        if (!frame)
    333306                return;
    334         if (frame->packet != NULL) {
    335                 nic_release_packet(nic_data, frame->packet);
    336         }
     307
     308        if (frame->data != NULL) {
     309                free(frame->data);
     310                frame->data = NULL;
     311                frame->size = 0;
     312        }
     313
    337314        fibril_mutex_lock(&nic_globals.lock);
    338315        if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) {
     
    447424
    448425/**
    449  * Connect to the NET and IRQ services. This function should be called only from
     426 * Connect to IRC service. This function should be called only from
    450427 * the add_device handler, thus no locking is required.
    451428 *
     
    454431 * @return EOK          If connection was successful.
    455432 * @return EINVAL       If the IRC service cannot be determined.
    456  * @return EREFUSED     If NET or IRC service cannot be connected.
     433 * @return EREFUSED     If IRC service cannot be connected.
    457434 */
    458435int nic_connect_to_services(nic_t *nic_data)
    459436{
    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        
    466437        /* IRC service */
    467438        sysarg_t apic;
     
    480451       
    481452        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);
    504453}
    505454
     
    546495       
    547496        /* 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);
     497        if (nic_data->client_session != NULL) {
     498                int rc = nic_ev_addr_changed(nic_data->client_session,
     499                    address);
    551500                if (rc != EOK) {
    552501                        fibril_rwlock_write_unlock(&nic_data->main_lock);
     
    604553
    605554/**
    606  * The busy flag can be set to 1 only in the write_packet handler, to 0 it can
     555 * The busy flag can be set to 1 only in the send_frame handler, to 0 it can
    607556 * be set anywhere.
    608557 *
     
    613562{
    614563        /*
    615          * When the function is called in write_packet handler the main lock is
     564         * When the function is called in send_frame handler the main lock is
    616565         * locked so no race can happen.
    617566         * Otherwise, when it is unexpectedly set to 0 (even with main lock held
     
    622571
    623572/**
    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
     573 * This is the function that the driver should call when it receives a frame.
     574 * The frame is checked by filters and then sent up to the NIL layer or
     575 * discarded. The frame is released.
     576 *
     577 * @param nic_data
     578 * @param frame         The received frame
    630579 */
    631580void nic_received_frame(nic_t *nic_data, nic_frame_t *frame)
    632581{
    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 {
    648582        /* 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        
     583         *               calls it inside send_frame handler (with locked main lock) */
    652584        fibril_rwlock_read_lock(&nic_data->rxc_lock);
    653585        nic_frame_type_t frame_type;
    654         int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type);
     586        int check = nic_rxc_check(&nic_data->rx_control, frame->data,
     587            frame->size, &frame_type);
    655588        fibril_rwlock_read_unlock(&nic_data->rxc_lock);
    656589        /* Update statistics */
    657590        fibril_rwlock_write_lock(&nic_data->stats_lock);
    658         /* Both sending message up and releasing packet are atomic IPC calls */
     591
    659592        if (nic_data->state == NIC_STATE_ACTIVE && check) {
    660593                nic_data->stats.receive_packets++;
    661                 nic_data->stats.receive_bytes += packet_get_data_length(packet);
     594                nic_data->stats.receive_bytes += frame->size;
    662595                switch (frame_type) {
    663596                case NIC_FRAME_MULTICAST:
     
    671604                }
    672605                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    673                 nil_received_msg(nic_data->nil_session, nic_data->device_id, pid);
     606                nic_ev_received(nic_data->client_session, frame->data,
     607                    frame->size);
    674608        } else {
    675609                switch (frame_type) {
     
    685619                }
    686620                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    687                 nic_release_packet(nic_data, packet);
    688         }
     621        }
     622        nic_release_frame(nic_data, frame);
    689623}
    690624
    691625/**
    692626 * 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.
     627 * for the situation when the frame does not contain ethernet address.
    694628 * The filtering is therefore not applied here.
    695629 *
    696630 * @param nic_data
    697  * @param packet
    698  */
    699 void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet)
     631 * @param data          Frame data
     632 * @param size          Frame size in bytes
     633 */
     634void nic_received_noneth_frame(nic_t *nic_data, void *data, size_t size)
    700635{
    701636        fibril_rwlock_write_lock(&nic_data->stats_lock);
    702637        nic_data->stats.receive_packets++;
    703         nic_data->stats.receive_bytes += packet_get_data_length(packet);
     638        nic_data->stats.receive_bytes += size;
    704639        fibril_rwlock_write_unlock(&nic_data->stats_lock);
    705640       
    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
     641        nic_ev_received(nic_data->client_session, data, size);
     642}
     643
     644/**
     645 * Some NICs can receive multiple frames during single interrupt. These can
    712646 * 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
     647 * the list is deallocated and each frame is passed to the
    714648 * nic_received_packet function.
    715649 *
     
    726660
    727661                list_remove(&frame->link);
    728                 nic_received_packet(nic_data, frame->packet);
    729                 frame->packet = NULL;
    730                 nic_release_frame(nic_data, frame);
     662                nic_received_frame(nic_data, frame);
    731663        }
    732664        nic_driver_release_frame_list(frames);
     
    758690        nic_data->dev = NULL;
    759691        nic_data->fun = NULL;
    760         nic_data->device_id = NIC_DEVICE_INVALID_ID;
    761692        nic_data->state = NIC_STATE_STOPPED;
    762         nic_data->net_session = NULL;
    763         nic_data->nil_session = NULL;
     693        nic_data->client_session = NULL;
    764694        nic_data->irc_session = NULL;
    765695        nic_data->poll_mode = NIC_POLL_IMMEDIATE;
     
    815745 */
    816746static 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);
     747        if (nic_data->client_session != NULL) {
     748                async_hangup(nic_data->client_session);
    823749        }
    824750
     
    846772
    847773/**
    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 /**
    885774 * Set information about current HW filtering.
    886775 *  1 ...       Only those frames we want to receive are passed through HW
     
    1097986{
    1098987        return nic_data->fun;
     988}
     989
     990/**
     991 * @param nic_data
     992 * @param fun
     993 */
     994void nic_set_ddf_fun(nic_t *nic_data, ddf_fun_t *fun)
     995{
     996        nic_data->fun = fun;
    1099997}
    1100998
     
    13291227}
    13301228
    1331 /** Lock packet for DMA usage
    1332  *
    1333  * @param packet
    1334  * @return physical address of packet
    1335  */
    1336 int nic_dma_lock_packet(packet_t *packet, size_t size, void **phys)
    1337 {
    1338         return dmamem_map(packet, SIZE2PAGES(size), 0, 0, phys);
    1339 }
    1340 
    1341 /** Unlock packet after DMA usage
    1342  *
    1343  * @param packet
    1344  */
    1345 int nic_dma_unlock_packet(packet_t *packet, size_t size)
    1346 {
    1347         return dmamem_unmap(packet, size);
    1348 }
    1349 
    13501229/** @}
    13511230 */
Note: See TracChangeset for help on using the changeset viewer.