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


Ignore:
Timestamp:
2012-01-21T12:57:55Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
eaa0c3f
Parents:
47a89fe (diff), e86b8f0 (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 with mainline

File:
1 edited

Legend:

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

    r47a89fe r86c71de  
    5151#include <net_interface.h>
    5252#include <ops/nic.h>
    53 #include <packet_client.h>
    54 #include <packet_remote.h>
    55 #include <net/packet_header.h>
    5653#include <errno.h>
    5754
     
    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
     
    162158
    163159/**
    164  * Setup write packet handler. This MUST be called in the add_device handler
     160 * Setup send frame handler. This MUST be called in the add_device handler
    165161 * if the nic_send_message_impl function is used for sending messages (filled
    166162 * as send_message member of the nic_iface_t structure). The function must not
     
    270266}
    271267
    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
     268/** Allocate frame
    290269 *
    291270 *  @param nic_data     The NIC driver data
    292  *  @param packet_size  Size of packet
    293  *  @param offload_size Size of packet offload
     271 *  @param size         Frame size in bytes
    294272 *  @return pointer to allocated frame if success, NULL otherwise
    295273 */
    296 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size)
     274nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)
    297275{
    298276        nic_frame_t *frame;
     
    313291        }
    314292
    315         packet_t *packet = nic_alloc_packet(nic_data, packet_size);
    316         if (!packet) {
     293        frame->data = malloc(size);
     294        if (frame->data == NULL) {
    317295                free(frame);
    318296                return NULL;
    319297        }
    320298
    321         frame->packet = packet;
     299        frame->size = size;
    322300        return frame;
    323301}
     
    332310        if (!frame)
    333311                return;
    334         if (frame->packet != NULL) {
    335                 nic_release_packet(nic_data, frame->packet);
    336         }
     312
     313        if (frame->data != NULL) {
     314                free(frame->data);
     315                frame->data = NULL;
     316                frame->size = 0;
     317        }
     318
    337319        fibril_mutex_lock(&nic_globals.lock);
    338320        if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) {
     
    604586
    605587/**
    606  * The busy flag can be set to 1 only in the write_packet handler, to 0 it can
     588 * The busy flag can be set to 1 only in the send_frame handler, to 0 it can
    607589 * be set anywhere.
    608590 *
     
    613595{
    614596        /*
    615          * When the function is called in write_packet handler the main lock is
     597         * When the function is called in send_frame handler the main lock is
    616598         * locked so no race can happen.
    617599         * Otherwise, when it is unexpectedly set to 0 (even with main lock held
     
    622604
    623605/**
    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
     606 * This is the function that the driver should call when it receives a frame.
     607 * The frame is checked by filters and then sent up to the NIL layer or
     608 * discarded. The frame is released.
     609 *
     610 * @param nic_data
     611 * @param frame         The received frame
    630612 */
    631613void nic_received_frame(nic_t *nic_data, nic_frame_t *frame)
    632614{
    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 {
    648615        /* 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        
     616         *               calls it inside send_frame handler (with locked main lock) */
    652617        fibril_rwlock_read_lock(&nic_data->rxc_lock);
    653618        nic_frame_type_t frame_type;
    654         int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type);
     619        int check = nic_rxc_check(&nic_data->rx_control, frame->data,
     620            frame->size, &frame_type);
    655621        fibril_rwlock_read_unlock(&nic_data->rxc_lock);
    656622        /* Update statistics */
    657623        fibril_rwlock_write_lock(&nic_data->stats_lock);
    658         /* Both sending message up and releasing packet are atomic IPC calls */
     624
    659625        if (nic_data->state == NIC_STATE_ACTIVE && check) {
    660626                nic_data->stats.receive_packets++;
    661                 nic_data->stats.receive_bytes += packet_get_data_length(packet);
     627                nic_data->stats.receive_bytes += frame->size;
    662628                switch (frame_type) {
    663629                case NIC_FRAME_MULTICAST:
     
    671637                }
    672638                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    673                 nil_received_msg(nic_data->nil_session, nic_data->device_id, pid);
     639                nil_received_msg(nic_data->nil_session, nic_data->device_id,
     640                    frame->data, frame->size);
    674641        } else {
    675642                switch (frame_type) {
     
    685652                }
    686653                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    687                 nic_release_packet(nic_data, packet);
    688         }
     654        }
     655        nic_release_frame(nic_data, frame);
    689656}
    690657
    691658/**
    692659 * 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.
     660 * for the situation when the frame does not contain ethernet address.
    694661 * The filtering is therefore not applied here.
    695662 *
    696663 * @param nic_data
    697  * @param packet
    698  */
    699 void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet)
     664 * @param data          Frame data
     665 * @param size          Frame size in bytes
     666 */
     667void nic_received_noneth_frame(nic_t *nic_data, void *data, size_t size)
    700668{
    701669        fibril_rwlock_write_lock(&nic_data->stats_lock);
    702670        nic_data->stats.receive_packets++;
    703         nic_data->stats.receive_bytes += packet_get_data_length(packet);
     671        nic_data->stats.receive_bytes += size;
    704672        fibril_rwlock_write_unlock(&nic_data->stats_lock);
    705673       
    706674        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
     675            data, size);
     676}
     677
     678/**
     679 * Some NICs can receive multiple frames during single interrupt. These can
    712680 * 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
     681 * the list is deallocated and each frame is passed to the
    714682 * nic_received_packet function.
    715683 *
     
    726694
    727695                list_remove(&frame->link);
    728                 nic_received_packet(nic_data, frame->packet);
    729                 frame->packet = NULL;
    730                 nic_release_frame(nic_data, frame);
     696                nic_received_frame(nic_data, frame);
    731697        }
    732698        nic_driver_release_frame_list(frames);
     
    846812
    847813/**
    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 /**
    885814 * Set information about current HW filtering.
    886815 *  1 ...       Only those frames we want to receive are passed through HW
     
    10971026{
    10981027        return nic_data->fun;
     1028}
     1029
     1030/**
     1031 * @param nic_data
     1032 * @param fun
     1033 */
     1034void nic_set_ddf_fun(nic_t *nic_data, ddf_fun_t *fun)
     1035{
     1036        nic_data->fun = fun;
    10991037}
    11001038
     
    13291267}
    13301268
    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 
    13501269/** @}
    13511270 */
Note: See TracChangeset for help on using the changeset viewer.