Ignore:
File:
1 edited

Legend:

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

    rea788701 r6d8455d  
    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>
    5356#include <errno.h>
    5457
     
    6164
    6265/**
    63  * Initializes libraries required for NIC framework - logger
     66 * Initializes libraries required for NIC framework - logger, packet manager
    6467 *
    6568 * @param name  Name of the device/driver (used in logging)
     
    7679        snprintf(buffer, 256, "drv/" DEVICE_CATEGORY_NIC "/%s", name);
    7780       
    78         return EOK;
     81        /* Initialize packet manager */
     82        return pm_init();
    7983}
    8084
     
    158162
    159163/**
    160  * Setup send frame handler. This MUST be called in the add_device handler
     164 * Setup write packet handler. This MUST be called in the add_device handler
    161165 * if the nic_send_message_impl function is used for sending messages (filled
    162166 * as send_message member of the nic_iface_t structure). The function must not
     
    266270}
    267271
    268 /** Allocate frame
     272/**
     273 * Just a wrapper over the packet_get_1_remote function
     274 */
     275packet_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 */
     284void 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
    269290 *
    270291 *  @param nic_data     The NIC driver data
    271  *  @param size         Frame size in bytes
     292 *  @param packet_size  Size of packet
     293 *  @param offload_size Size of packet offload
    272294 *  @return pointer to allocated frame if success, NULL otherwise
    273295 */
    274 nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)
     296nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size)
    275297{
    276298        nic_frame_t *frame;
     
    291313        }
    292314
    293         frame->data = malloc(size);
    294         if (frame->data == NULL) {
     315        packet_t *packet = nic_alloc_packet(nic_data, packet_size);
     316        if (!packet) {
    295317                free(frame);
    296318                return NULL;
    297319        }
    298320
    299         frame->size = size;
     321        frame->packet = packet;
    300322        return frame;
    301323}
     
    310332        if (!frame)
    311333                return;
    312 
    313         if (frame->data != NULL) {
    314                 free(frame->data);
    315                 frame->data = NULL;
    316                 frame->size = 0;
    317         }
    318 
     334        if (frame->packet != NULL) {
     335                nic_release_packet(nic_data, frame->packet);
     336        }
    319337        fibril_mutex_lock(&nic_globals.lock);
    320338        if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) {
     
    586604
    587605/**
    588  * The busy flag can be set to 1 only in the send_frame handler, to 0 it can
     606 * The busy flag can be set to 1 only in the write_packet handler, to 0 it can
    589607 * be set anywhere.
    590608 *
     
    595613{
    596614        /*
    597          * When the function is called in send_frame handler the main lock is
     615         * When the function is called in write_packet handler the main lock is
    598616         * locked so no race can happen.
    599617         * Otherwise, when it is unexpectedly set to 0 (even with main lock held
     
    604622
    605623/**
    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
     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
    612630 */
    613631void nic_received_frame(nic_t *nic_data, nic_frame_t *frame)
    614632{
     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 */
     646void nic_received_packet(nic_t *nic_data, packet_t *packet)
     647{
    615648        /* Note: this function must not lock main lock, because loopback driver
    616          *               calls it inside send_frame handler (with locked main lock) */
     649         *               calls it inside write_packet handler (with locked main lock) */
     650        packet_id_t pid = packet_get_id(packet);
     651       
    617652        fibril_rwlock_read_lock(&nic_data->rxc_lock);
    618653        nic_frame_type_t frame_type;
    619         int check = nic_rxc_check(&nic_data->rx_control, frame->data,
    620             frame->size, &frame_type);
     654        int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type);
    621655        fibril_rwlock_read_unlock(&nic_data->rxc_lock);
    622656        /* Update statistics */
    623657        fibril_rwlock_write_lock(&nic_data->stats_lock);
    624 
     658        /* Both sending message up and releasing packet are atomic IPC calls */
    625659        if (nic_data->state == NIC_STATE_ACTIVE && check) {
    626660                nic_data->stats.receive_packets++;
    627                 nic_data->stats.receive_bytes += frame->size;
     661                nic_data->stats.receive_bytes += packet_get_data_length(packet);
    628662                switch (frame_type) {
    629663                case NIC_FRAME_MULTICAST:
     
    637671                }
    638672                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    639                 nil_received_msg(nic_data->nil_session, nic_data->device_id,
    640                     frame->data, frame->size);
     673                nil_received_msg(nic_data->nil_session, nic_data->device_id, pid);
    641674        } else {
    642675                switch (frame_type) {
     
    652685                }
    653686                fibril_rwlock_write_unlock(&nic_data->stats_lock);
    654         }
    655         nic_release_frame(nic_data, frame);
     687                nic_release_packet(nic_data, packet);
     688        }
    656689}
    657690
    658691/**
    659692 * This function is to be used only in the loopback driver. It's workaround
    660  * for the situation when the frame does not contain ethernet address.
     693 * for the situation when the packet does not contain ethernet address.
    661694 * The filtering is therefore not applied here.
    662695 *
    663696 * @param nic_data
    664  * @param data          Frame data
    665  * @param size          Frame size in bytes
    666  */
    667 void nic_received_noneth_frame(nic_t *nic_data, void *data, size_t size)
     697 * @param packet
     698 */
     699void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet)
    668700{
    669701        fibril_rwlock_write_lock(&nic_data->stats_lock);
    670702        nic_data->stats.receive_packets++;
    671         nic_data->stats.receive_bytes += size;
     703        nic_data->stats.receive_bytes += packet_get_data_length(packet);
    672704        fibril_rwlock_write_unlock(&nic_data->stats_lock);
    673705       
    674706        nil_received_msg(nic_data->nil_session, nic_data->device_id,
    675             data, size);
    676 }
    677 
    678 /**
    679  * Some NICs can receive multiple frames during single interrupt. These can
     707            packet_get_id(packet));
     708}
     709
     710/**
     711 * Some NICs can receive multiple packets during single interrupt. These can
    680712 * send them in whole list of frames (actually nic_frame_t structures), then
    681  * the list is deallocated and each frame is passed to the
     713 * the list is deallocated and each packet is passed to the
    682714 * nic_received_packet function.
    683715 *
     
    694726
    695727                list_remove(&frame->link);
    696                 nic_received_frame(nic_data, frame);
     728                nic_received_packet(nic_data, frame->packet);
     729                frame->packet = NULL;
     730                nic_release_frame(nic_data, frame);
    697731        }
    698732        nic_driver_release_frame_list(frames);
     
    12951329}
    12961330
     1331/** Lock packet for DMA usage
     1332 *
     1333 * @param packet
     1334 * @return physical address of packet
     1335 */
     1336int 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 */
     1345int nic_dma_unlock_packet(packet_t *packet, size_t size)
     1346{
     1347        return dmamem_unmap(packet, size);
     1348}
     1349
    12971350/** @}
    12981351 */
Note: See TracChangeset for help on using the changeset viewer.