/*
 * Copyright (c) 2014 Brian Swetland
 * Copyright (c) 2014-2015 Christopher Anderson
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <assert.h>
#include <debug.h>
#include <trace.h>
#include <printf.h>
#include <string.h>
#include <malloc.h>

#include <kernel/thread.h>
#include <kernel/semaphore.h>
#include <kernel/spinlock.h>
#include <lib/pktbuf.h>
#include <lib/pool.h>
#include <lk/init.h>

#if WITH_KERNEL_VM
#include <kernel/vm.h>
#endif

#define LOCAL_TRACE 0

static pool_t pktbuf_pool;
static semaphore_t pktbuf_sem;
static spin_lock_t lock;


/* Take an object from the pool of pktbuf objects to act as a header or buffer.  */
static void *get_pool_object(void) {
	pool_t *entry;
	spin_lock_saved_state_t state;

	sem_wait(&pktbuf_sem);
	spin_lock_irqsave(&lock, state);
	entry = pool_alloc(&pktbuf_pool);
	spin_unlock_irqrestore(&lock, state);

	return (pktbuf_pool_object_t *) entry;

}

/* Return an object to thje pktbuf object pool. */
static void free_pool_object(pktbuf_pool_object_t *entry, bool reschedule) {
	DEBUG_ASSERT(entry);
	spin_lock_saved_state_t state;

	spin_lock_irqsave(&lock, state);
	pool_free(&pktbuf_pool, entry);
	spin_unlock_irqrestore(&lock, state);
	sem_post(&pktbuf_sem, reschedule);
}

/* Callback used internally to place a pktbuf_pool_object back in the pool after
 * it was used as a buffer for another pktbuf
 */
static void free_pktbuf_buf_cb(void *buf, void *arg) {
	free_pool_object((pktbuf_pool_object_t *)buf, true);
}

/* Add a buffer to a pktbuf. Header space for prepending data is adjusted based on
 * header_sz. cb is called when the pktbuf is freed / released by the driver level
 * and should handle proper management / freeing of the buffer pointed to by the iovec.
 *
 * It's important to note that there is a flag to note that the buffer is cached and should
 * be properly handled via the appropriate driver when it's time to deal with buffer
 * descriptiors.
 */
void pktbuf_add_buffer(pktbuf_t *p, u8 *buf, u32 len, uint32_t header_sz, uint32_t flags,
					   pktbuf_free_callback cb, void *cb_args) {
	DEBUG_ASSERT(p);
	DEBUG_ASSERT(buf);
	DEBUG_ASSERT(header_sz < len);

	p->buffer = buf;
	p->blen = len;
	p->data = p->buffer + header_sz;
	p->dlen = 0;
	p->flags = PKTBUF_FLAG_EOF | flags;
	p->cb = cb;
	p->cb_args = cb_args;

	/* If we're using a VM then this may be a virtual address, look up to see
	 * if there is an associated physical address we can store. If not, then
	 * stick with the address as presented to us.
	 */
#if WITH_KERNEL_VM
	p->phys_base = kvaddr_to_paddr(buf) | (uintptr_t) buf % PAGE_SIZE;
#else
	p->phys_base = (uintptr_t) buf;
#endif
}

pktbuf_t *pktbuf_alloc(void) {
	pktbuf_t *p = NULL;
	void *buf = NULL;

	p = get_pool_object();
	if (!p) {
		return NULL;
	}

	buf = get_pool_object();
	if (!buf) {
		free_pool_object((pktbuf_pool_object_t *)p, false);
		return NULL;
	}

	memset(p, 0, sizeof(pktbuf_t));
	pktbuf_add_buffer(p, buf, PKTBUF_SIZE, PKTBUF_MAX_HDR, 0, free_pktbuf_buf_cb, NULL);
	return p;
}

pktbuf_t *pktbuf_alloc_empty(void) {
	pktbuf_t *p = (pktbuf_t *) get_pool_object();

	p->flags = PKTBUF_FLAG_EOF;
	return p;
}

int pktbuf_free(pktbuf_t *p, bool reschedule) {
	DEBUG_ASSERT(p);

	if (p->cb) {
		p->cb(p->buffer, p->cb_args);
	}
	free_pool_object((pktbuf_pool_object_t *)p, false);

	return 1;
}

void pktbuf_append_data(pktbuf_t *p, const void *data, size_t sz) {
	if (pktbuf_avail_tail(p) < sz) {
		panic("pktbuf_append_data: overflow");
	}

	memcpy(p->data + p->dlen, data, sz);
	p->dlen += sz;
}

void *pktbuf_append(pktbuf_t *p, size_t sz) {
	if (pktbuf_avail_tail(p) < sz) {
		panic("pktbuf_append: overflow");
	}

	void *data = p->data + p->dlen;
	p->dlen += sz;

	return data;
}

void *pktbuf_prepend(pktbuf_t *p, size_t sz) {
	if (pktbuf_avail_head(p) < sz) {
		panic("pktbuf_prepend: not enough space");
	}

	p->dlen += sz;
	p->data -= sz;

	return p->data;
}

void *pktbuf_consume(pktbuf_t *p, size_t sz) {
	void *data = p->data;

	if (sz > p->dlen) {
		return NULL;
	}

	p->data += sz;
	p->dlen -= sz;

	return data;
}

void pktbuf_consume_tail(pktbuf_t *p, size_t sz) {
	if (sz > p->dlen) {
		p->dlen = 0;
		return;
	}

	p->dlen -= sz;
}

void pktbuf_dump(pktbuf_t *p) {
	printf("pktbuf data %p, buffer %p, dlen %u, data offset %lu, phys_base %p\n",
			p->data, p->buffer, p->dlen, (uintptr_t) p->data - (uintptr_t) p->buffer,
			(void *)p->phys_base);
}

static void pktbuf_init(uint level)
{
	void *slab;

#if LK_DEBUGLEVEL > 0
	printf("pktbuf: creating %u pktbuf entries of size %zu (total %zu)\n",
		PKTBUF_POOL_SIZE, sizeof(struct pktbuf_pool_object),
		PKTBUF_POOL_SIZE * sizeof(struct pktbuf_pool_object));
#endif

#if WITH_KERNEL_VM
	if (vmm_alloc_contiguous(vmm_get_kernel_aspace(), "pktbuf",
			PKTBUF_POOL_SIZE * sizeof(struct pktbuf_pool_object), 
			&slab, 0, 0, ARCH_MMU_FLAG_CACHED) < 0) {
		printf("Failed to initialize pktbuf hdr slab\n");
		return;
	}
#else
	slab = memalign(CACHE_LINE, PKTBUF_POOL_SIZE * sizeof(pktbuf_pool_object_t));
#endif

	pool_init(&pktbuf_pool, sizeof(struct pktbuf_pool_object), CACHE_LINE, PKTBUF_POOL_SIZE, slab);
	sem_init(&pktbuf_sem, PKTBUF_POOL_SIZE);
}

LK_INIT_HOOK(pktbuf, pktbuf_init, LK_INIT_LEVEL_THREADING);

// vim: set noexpandtab:
