Changeset b8ef198b in mainline


Ignore:
Timestamp:
2018-06-20T18:58:44Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9afd2a8
Parents:
3d135e9
Message:

Implement virtio-net interrupt handler

Location:
uspace
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/nic/virtio-net/virtio-net.c

    r3d135e9 rb8ef198b  
    6969};
    7070
    71 static void virtio_net_irq_handler(ipc_call_t *icall, ddf_dev_t *dev)
    72 {
    73         ddf_msg(LVL_NOTE, "Got interrupt");
    74 }
    75 
    7671static errno_t virtio_net_setup_bufs(unsigned int buffers, size_t size,
    7772    bool write, void *buf[], uintptr_t buf_p[])
     
    125120                *head = virtio_virtq_desc_get_next(vdev, num, descno);
    126121        return descno;
     122}
     123
     124static void virtio_net_free_buf(virtio_dev_t *vdev, uint16_t num,
     125    uint16_t *head, uint16_t descno)
     126{
     127        virtio_virtq_desc_set(vdev, num, descno, 0, 0, VIRTQ_DESC_F_NEXT,
     128            *head);
     129        *head = descno;
     130}
     131
     132static void virtio_net_irq_handler(ipc_call_t *icall, ddf_dev_t *dev)
     133{
     134        nic_t *nic = ddf_dev_data_get(dev);
     135        virtio_net_t *virtio_net = nic_get_specific(nic);
     136        virtio_dev_t *vdev = &virtio_net->virtio_dev;
     137
     138        uint16_t descno;
     139        uint32_t len;
     140        while (virtio_virtq_consume_used(vdev, RX_QUEUE_1, &descno, &len)) {
     141                virtio_net_hdr_t *hdr =
     142                    (virtio_net_hdr_t *) virtio_net->rx_buf[descno];
     143                if (len <= sizeof(*hdr)) {
     144                        ddf_msg(LVL_WARN,
     145                            "RX data length too short, packet dropped");
     146                        virtio_virtq_produce_available(vdev, RX_QUEUE_1,
     147                            descno);
     148                        continue;
     149                }
     150
     151                nic_frame_t *frame = nic_alloc_frame(nic, len - sizeof(*hdr));
     152                if (frame) {
     153                        memcpy(frame->data, &hdr[1], len - sizeof(*hdr));
     154                        nic_received_frame(nic, frame);
     155                } else {
     156                        ddf_msg(LVL_WARN,
     157                            "Cannot allocate RX frame, packet dropped");
     158                }
     159
     160                virtio_virtq_produce_available(vdev, RX_QUEUE_1, descno);
     161        }
     162
     163        while (virtio_virtq_consume_used(vdev, TX_QUEUE_1, &descno, &len)) {
     164                virtio_net_free_buf(vdev, TX_QUEUE_1, &virtio_net->tx_free_head,
     165                    descno);
     166        }
     167        while (virtio_virtq_consume_used(vdev, CT_QUEUE_1, &descno, &len)) {
     168                virtio_net_free_buf(vdev, CT_QUEUE_1, &virtio_net->ct_free_head,
     169                    descno);
     170        }
    127171}
    128172
     
    365409        hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
    366410
    367         /* Copy packet data into the buffer just past the header */ 
     411        /* Copy packet data into the buffer just past the header */
    368412        memcpy(&hdr[1], data, size);
    369413
  • uspace/lib/virtio/virtio-pci.h

    r3d135e9 rb8ef198b  
    143143        /** Virtual address of the used ring */
    144144        virtq_used_t *used;
     145        uint16_t used_last_idx;
    145146
    146147        /** Address of the queue's notification register */
     
    182183
    183184extern void virtio_virtq_produce_available(virtio_dev_t *, uint16_t, uint16_t);
     185extern bool virtio_virtq_consume_used(virtio_dev_t *, uint16_t, uint16_t *,
     186    uint32_t *);
    184187
    185188extern errno_t virtio_virtq_setup(virtio_dev_t *, uint16_t, uint16_t);
  • uspace/lib/virtio/virtio.c

    r3d135e9 rb8ef198b  
    7171}
    7272
     73bool virtio_virtq_consume_used(virtio_dev_t *vdev, uint16_t num,
     74    uint16_t *descno, uint32_t *len)
     75{
     76        virtq_t *q = &vdev->queues[num];
     77
     78        uint16_t last_idx = q->used_last_idx % q->queue_size;
     79        if (last_idx == (pio_read_le16(&q->used->idx) % q->queue_size))
     80                return false;
     81
     82        *descno = (uint16_t) pio_read_le32(&q->used->ring[last_idx].id);
     83        *len = pio_read_le32(&q->used->ring[last_idx].len);
     84
     85        q->used_last_idx++;
     86
     87        return true;
     88}
     89
    7390errno_t virtio_virtq_setup(virtio_dev_t *vdev, uint16_t num, uint16_t size)
    7491{
     
    120137        q->avail = q->virt + avail_offset;
    121138        q->used = q->virt + used_offset;
     139        q->used_last_idx = 0;
    122140
    123141        memset(q->virt, 0, q->size);
Note: See TracChangeset for help on using the changeset viewer.