/*
 * Copyright (c) 2009 The Regents of the University of California
 * See LICENSE for details.
 */

#ifdef __SHARC__
#pragma nosharc
#endif

#include <arch/mmu.h>
#include <arch/x86.h>
#include <arch/smp.h>
#include <arch/apic.h>
#include <arch/pci.h>
#include "ne2k.h"

#include <ros/memlayout.h>

#include <atomic.h>
#include <stdio.h>
#include <string.h>
#include <trap.h>
#include <kmalloc.h>

#include <pmap.h>
#include <time.h>

/** @file
 * @brief NE2K Driver Sketch
 *
 * EXPERIMENTAL.
 *
 * Rough driver. Appears to work in QEMU. Probably completely broken under heavy load.
 *
 * @author Paul Pearce <pearce@eecs.berkeley.edu>
 *
 * @todo Everything
 */

#define NE2K_RESET_R_ADDR 0x1f
#define NE2K_PG0_RW_CR	0x00
#define NE2K_PG0_RW_ISR 0x07
#define NE2K_PG0_W_IMR	0x0F
#define NE2K_PG0_W_PSTRT 0x1
#define NE2K_PG0_W_PSTP 0x2
#define NE2K_PG0_W_RCR 0xC
#define NE2K_PG0_R_RSR 0xC
#define NE2K_PG0_R_TSR 0x4
#define NE2K_PG0_W_TCR 0xD
#define NE2K_PG1_RW_PAR 0x1
#define NE2K_PG0_W_RSAR0 0x08
#define NE2K_PG0_W_RSAR1 0x09
#define NE2K_PG0_W_RBCR0 0x0A
#define NE2K_PG0_W_RBCR1 0x0B
#define NE2K_PG0_W_TBCR0 0x05
#define NE2K_PG0_W_TBCR1 0x06
#define NE2K_PG0_W_TPSR  0x04
#define NE2K_PG0_W_DCR 0x0E
#define NE2K_PG1_RW_CURR 0x07
#define NE2K_PG0_RW_BNRY 0x03

#define NE2K_PAGE_SIZE 256

#define NE2K_PMEM_START   (16*1024)
#define NE2K_PMEM_SIZE	  (32*1024)
#define NE2K_NUM_PAGES 		((NE2K_PMEM_SIZE - NE2K_PMEM_START) / NE2K_PAGE_SIZE)
#define NE2K_NUM_RECV_PAGES 	(NE2K_NUM_PAGES / 2)
#define NE2K_NUM_SEND_PAGES	(NE2K_NUM_PAGES / 2)
#define NE2K_FIRST_RECV_PAGE	(NE2K_PMEM_START / NE2K_PAGE_SIZE)
#define NE2K_LAST_RECV_PAGE	NE2K_FIRST_RECV_PAGE + NE2K_NUM_RECV_PAGES
#define NE2K_FIRST_SEND_PAGE	NE2K_LAST_RECV_PAGE + 1


#define SET_PAGE_0() (inb(ne2k_io_base_addr + NE2K_PG0_RW_CR) & 0x3F)

static uint32_t ne2k_irq;      // Fix this
static uint32_t ne2k_io_base_addr;

static void *base_page;
static uint32_t num_pages = 0;

void ne2k_init() {
	
	if (ne2k_scan_pci() < 0) return;
	ne2k_mem_alloc();
	ne2k_configure_nic();
	ne2k_read_mac();
	printk("Network Card MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", 
	   device_mac[0],device_mac[1],device_mac[2],
	   device_mac[3],device_mac[4],device_mac[5]);
	//ne2k_test_interrupts();
	send_frame = &ne2k_send_frame;

	ne2k_setup_interrupts();

	eth_up = 1;

	return;
}


int ne2k_scan_pci() {
	struct pci_device *pcidev;
	uint32_t result;
	printk("Searching for NE2000 Network device...");
	STAILQ_FOREACH(pcidev, &pci_devices, all_dev) {
		/* Ignore non NE2K Devices */
		if ((pcidev->ven_id != NE2K_VENDOR_ID) ||
		   (pcidev->dev_id != NE2K_DEV_ID))
			continue;
		printk(" found on BUS %x DEV %x\n", pcidev->bus, pcidev->dev);
		/* Find the IRQ */
		ne2k_irq = pcidev->irqline;
		ne2k_debug("-->IRQ: %u\n", ne2k_irq);
		/* Loop over the BARs */
		for (int k = 0; k <= 5; k++) {
			int reg = 4 + k;
	        result = pcidev_read32(pcidev, reg << 2);	// SHAME!
			if (result == 0) // (0 denotes no valid data)
				continue;
			// Read the bottom bit of the BAR. 
			if (result & PCI_BAR_IO) {
				result = result & PCI_BAR_IO_MASK;
				ne2k_debug("-->BAR%u: %s --> %x\n", k, "IO", result);
			} else {
				result = result & PCI_BAR_MEM_MASK;
				ne2k_debug("-->BAR%u: %s --> %x\n", k, "MEM", result);
			}
			// TODO Switch to memory mapped instead of IO?
			if (k == 0) // BAR0 denotes the IO Addr for the device
				ne2k_io_base_addr = result;						
		}
		return 0;
	}
	printk(" not found. No device configured.\n");
	return -1;
}

void ne2k_configure_nic() {
	
	ne2k_debug("-->Configuring Device.\n");
	
	// Reset. Yes reading from this addr resets it
	inb(ne2k_io_base_addr + NE2K_RESET_R_ADDR);

	// Configure
	outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x22);
	outb(ne2k_io_base_addr + NE2K_PG0_W_PSTRT,  NE2K_FIRST_RECV_PAGE);
        outb(ne2k_io_base_addr + NE2K_PG0_RW_BNRY, NE2K_FIRST_RECV_PAGE + 1);

        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, (0x22 & 0x3F) | 0x40);
	outb(ne2k_io_base_addr + NE2K_PG1_RW_CURR, NE2K_FIRST_RECV_PAGE + 2);
	outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, 0x22);
	outb(ne2k_io_base_addr + NE2K_PG0_W_PSTP, NE2K_LAST_RECV_PAGE);
	outb(ne2k_io_base_addr + NE2K_PG0_W_DCR, 0x94);	
	outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x22);
	
	outb(ne2k_io_base_addr + NE2K_PG0_W_RCR,  0xDF);
	outb(ne2k_io_base_addr + NE2K_PG0_W_TCR,  0xE0);
	

	//uint8_t isr = inb(ne2k_io_base_addr + NE2K_PG0_RW_ISR);
	//cprintf("isr: %x\n", isr);

	
	return;
}

void ne2k_setup_interrupts() {
	
	ne2k_debug("-->Setting interrupts.\n");
	
	// Kernel based interrupt stuff
	register_dev_irq(ne2k_irq, ne2k_interrupt_handler, 0);
	
	SET_PAGE_0();

        outb(ne2k_io_base_addr + NE2K_PG0_W_IMR,  0xBF);

	outb(ne2k_io_base_addr + NE2K_PG0_RW_ISR, 0xFF);
	return;
}

void ne2k_mem_alloc() {
	
	num_pages = ROUNDUP(NE2K_NUM_PAGES * NE2K_PAGE_SIZE, PGSIZE) / PGSIZE;
	base_page = get_cont_pages(LOG2_UP(num_pages), 0);	
}

void ne2k_read_mac() {

	uint8_t cr = inb(ne2k_io_base_addr + NE2K_PG0_RW_CR);
	
	// Set correct bits
	outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, 0xA);
	outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR0, 0x0);
        outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR1, 0x0);
        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR0, 0x6);
        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR1, 0x0);


	for (int i = 0; i < 6; i++)
		device_mac[i] = inb(ne2k_io_base_addr + 0x10) & inb(ne2k_io_base_addr + 0x10);

	// Set page 1
        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, (cr & 0x3F) | 0x40);

	for (int i = 0; i < 6; i++) 
           outb(ne2k_io_base_addr + NE2K_PG1_RW_PAR + i, device_mac[i]);

	
	ne2k_debug("-->DEVICE MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & device_mac[0], 0xFF & device_mac[1],	
	                                                            0xFF & device_mac[2], 0xFF & device_mac[3],	
                                                                0xFF & device_mac[4], 0xFF & device_mac[5]);
	// Restore old setting.
	outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, cr);
	return;
}

void ne2k_test_interrupts() {
	
	cprintf("Generating Interrupt...\n");
	outb(ne2k_io_base_addr + 0x0A, 0x00);
	outb(ne2k_io_base_addr + 0x0B, 0x00);
	outb(ne2k_io_base_addr + 0x00, 0x0A);
	udelay(10000000);

	cprintf("Generating Interrupt again...\n");
	outb(ne2k_io_base_addr + 0x0A, 0x00);
	outb(ne2k_io_base_addr + 0x0B, 0x00);
	outb(ne2k_io_base_addr + 0x00, 0x0A);
	udelay(10000000);
	
}

// We need to evaluate this routine in terms of concurrency.
// We also need to figure out whats up with different core interrupts
void ne2k_interrupt_handler(struct hw_trapframe *hw_tf, void *data)
{
	
	ne2k_interrupt_debug("\nNE2K interrupt on core %u!\n", lapic_get_id());

	SET_PAGE_0();

	uint8_t isr= inb(ne2k_io_base_addr + NE2K_PG0_RW_ISR);
	ne2k_interrupt_debug("isr: %x\n", isr);
	
	while (isr != 0x0) {

		// TODO: Other interrupt cases.

		if (isr & 0x1) {
			ne2k_interrupt_debug("-->Packet received.\n");
			ne2k_handle_rx_packet();
		}
		
		SET_PAGE_0();

		// Clear interrupts
		isr = inb(ne2k_io_base_addr + NE2K_PG0_RW_ISR);
		outb(ne2k_io_base_addr + NE2K_PG0_RW_ISR, isr);

	}

	ne2k_handle_rx_packet();
	
	return;				
}

// @TODO: Is this broken? Didn't change it after kmalloc changed
void ne2k_handle_rx_packet() {
	
	SET_PAGE_0();

        uint8_t bound = inb(ne2k_io_base_addr + NE2K_PG0_RW_BNRY);

        uint8_t cr = inb(ne2k_io_base_addr + NE2K_PG0_RW_CR);
        
	// Set page 1
        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, (cr & 0x3F) | 0x40);

	uint8_t next = inb(ne2k_io_base_addr + NE2K_PG1_RW_CURR);

	// Restore old setting.
        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, cr);

        uint8_t start = NE2K_FIRST_RECV_PAGE;
        uint8_t stop = NE2K_LAST_RECV_PAGE;

	// Broken mult packets?
	if (((bound + 1) == next) || (((bound + 1) == stop) && (start == next))) {
		ne2k_debug("NO PACKET TO PROCESS\n");
		return;
	}

	uint32_t kmalloc_size;

	if (MAX_FRAME_SIZE % NE2K_PAGE_SIZE) {
		kmalloc_size = ((MAX_FRAME_SIZE / NE2K_PAGE_SIZE) + 1) * NE2K_PAGE_SIZE;
	} else {
		kmalloc_size = MAX_FRAME_SIZE;
	}
	
	char *rx_buffer = kmalloc(kmalloc_size, 0);
	
	if (rx_buffer == NULL) panic ("Can't allocate page for incoming packet.");

        uint8_t curr = bound + 1;

	uint8_t header[4];
	uint16_t packet_len = 0xFFFF;
	uint16_t page_count = 0;
	for (int i = 0, n = 0; i < (MAX_FRAME_SIZE / NE2K_PAGE_SIZE); i++) {
		if (curr == stop)
			curr = start;			

		outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR0, 0x0);
		outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR1, curr);


		// Fix this. Its hard coded to 256
        	outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR0, 0);
        	outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR1, 0x1);
	
		outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, 0x0A);

		for (int j = 0; j < NE2K_PAGE_SIZE; j++) {
			uint8_t val = inb(ne2k_io_base_addr + 0x10);
			if ((i == 0) && (j < 4)) {
				header[j] = val;
			} else { 
				rx_buffer[n++] = val;
			}
		}

		if (i == 0) {
			packet_len = ((uint16_t)header[3] << 8) | (uint16_t)header[2];
			if (packet_len % NE2K_PAGE_SIZE) {
				page_count = (packet_len / NE2K_PAGE_SIZE) + 1;
			} else {
				page_count = (packet_len / NE2K_PAGE_SIZE);
			}
		}
		
		if ((i + 1) == page_count)
			break;

		curr++;
	
	}
	outb(ne2k_io_base_addr + NE2K_PG0_RW_BNRY, curr);

	if (packet_len == 0) {
		ne2k_debug("Triggered on an empty packet.\n");
		return;
	}

#ifdef CONFIG_APPSERVER
	// Treat as a syscall frontend response packet if eth_type says so
	// Will eventually go away, so not too worried about elegance here...
	#include <frontend.h>
	#include <arch/frontend.h>
	uint16_t eth_type = htons(*(uint16_t*)(rx_buffer + 12));
	if(eth_type == APPSERVER_ETH_TYPE) {
		handle_appserver_packet(rx_buffer, packet_len);
		kfree(rx_buffer);
		return;
	}
#endif

	spin_lock(&packet_buffers_lock);

	if (num_packet_buffers >= MAX_PACKET_BUFFERS) {
		printk("WARNING: DROPPING PACKET!\n");
		spin_unlock(&packet_buffers_lock);
		kfree(rx_buffer);
		return;
	}

	packet_buffers[packet_buffers_tail] = rx_buffer;
	packet_buffers_sizes[packet_buffers_tail] = packet_len;

	packet_buffers_tail = (packet_buffers_tail + 1) % MAX_PACKET_BUFFERS;
	num_packet_buffers++;

	spin_unlock(&packet_buffers_lock);
	
	return;
}

// Main routine to send a frame. May be completely broken.
int ne2k_send_frame(const char *data, size_t len) {

	if (data == NULL)
		return -1;
	if (len == 0)
		return 0;


	if (len > MAX_FRAME_SIZE) {
		ne2k_frame_debug("-->Frame Too Large!\n");
		return -1;
	}

        outb(ne2k_io_base_addr + NE2K_PG0_W_IMR,  0x00);


	// The TPSR takes a page #
	// The RSAR takes a byte offset, but since a page is 256 bits
	// and we are writing on page boundries, the low bits are 0, and
	// the high bits are a page #
	outb(ne2k_io_base_addr + NE2K_PG0_W_TPSR, NE2K_FIRST_SEND_PAGE);
        outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR0, 0x0);
        outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR1, NE2K_FIRST_SEND_PAGE);

	
	outb(ne2k_io_base_addr + NE2K_PG0_W_TBCR0, len & 0xFF);
        outb(ne2k_io_base_addr + NE2K_PG0_W_TBCR1, len >> 8);

        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR0, len & 0xFF);
        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR1, len >> 8);

	
	outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x12);
	

	for (int i = 0; i<len; i = i + 1) {
		outb(ne2k_io_base_addr + 0x10, *(uint8_t*)(data + i));
		//ne2k_debug("sent: %x\n", *(uint8_t*)(data + i));
	}
	
	while(( inb(ne2k_io_base_addr + NE2K_PG0_RW_ISR) & 0x40) == 0);

        outb(ne2k_io_base_addr + NE2K_PG0_RW_ISR,  0x40);

        outb(ne2k_io_base_addr + NE2K_PG0_W_IMR,  0xBF);

        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x1E);
	
	
	return len;
}

