/* virtio-pci.c - virtio ring management
 *
 * (c) Copyright 2008 Bull S.A.S.
 *
 *  Author: Laurent Vivier <Laurent.Vivier@bull.net>
 *
 *  some parts from Linux Virtio Ring
 *
 *  Copyright Rusty Russell IBM Corporation 2007
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 *
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include "etherboot.h"
#include "ipxe/io.h"
#include "ipxe/virtio-pci.h"
#include "ipxe/virtio-ring.h"

#define BUG() do { \
   printf("BUG: failure at %s:%d/%s()!\n", \
          __FILE__, __LINE__, __FUNCTION__); \
   while(1); \
} while (0)
#define BUG_ON(condition) do { if (condition) BUG(); } while (0)

/*
 * vring_free
 *
 * put at the begin of the free list the current desc[head]
 */

void vring_detach(struct vring_virtqueue *vq, unsigned int head)
{
   struct vring *vr = &vq->vring;
   unsigned int i;

   /* find end of given descriptor */

   i = head;
   while (vr->desc[i].flags & VRING_DESC_F_NEXT)
           i = vr->desc[i].next;

   /* link it with free list and point to it */

   vr->desc[i].next = vq->free_head;
   wmb();
   vq->free_head = head;
}

/*
 * vring_get_buf
 *
 * get a buffer from the used list
 *
 */

void *vring_get_buf(struct vring_virtqueue *vq, unsigned int *len)
{
   struct vring *vr = &vq->vring;
   struct vring_used_elem *elem;
   u32 id;
   void *opaque;

   BUG_ON(!vring_more_used(vq));

   elem = &vr->used->ring[vq->last_used_idx % vr->num];
   wmb();
   id = elem->id;
   if (len != NULL)
           *len = elem->len;

   opaque = vq->vdata[id];

   vring_detach(vq, id);

   vq->last_used_idx++;

   return opaque;
}

void vring_add_buf(struct vring_virtqueue *vq,
		   struct vring_list list[],
		   unsigned int out, unsigned int in,
		   void *opaque, int num_added)
{
   struct vring *vr = &vq->vring;
   int i, avail, head, prev;

   BUG_ON(out + in == 0);

   prev = 0;
   head = vq->free_head;
   for (i = head; out; i = vr->desc[i].next, out--) {

           vr->desc[i].flags = VRING_DESC_F_NEXT;
           vr->desc[i].addr = list->addr;
           vr->desc[i].len = list->length;
           prev = i;
           list++;
   }
   for ( ; in; i = vr->desc[i].next, in--) {

           vr->desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
           vr->desc[i].addr = list->addr;
           vr->desc[i].len = list->length;
           prev = i;
           list++;
   }
   vr->desc[prev].flags &= ~VRING_DESC_F_NEXT;

   vq->free_head = i;

   vq->vdata[head] = opaque;

   avail = (vr->avail->idx + num_added) % vr->num;
   vr->avail->ring[avail] = head;
   wmb();
}

void vring_kick(struct virtio_pci_modern_device *vdev, unsigned int ioaddr,
                struct vring_virtqueue *vq, int num_added)
{
   struct vring *vr = &vq->vring;

   wmb();
   vr->avail->idx += num_added;

   mb();
   if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY)) {
           if (vdev) {
                   /* virtio 1.0 */
                   vpm_notify(vdev, vq);
           } else {
                   /* legacy virtio */
                   vp_notify(ioaddr, vq->queue_index);
           }
   }
}
