/* This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file. */

/* Network driver stub for bxe */

#include <vfs.h>
#include <kfs.h>
#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <arch/pci.h>
#include <ip.h>
#include <ns.h>
#include "bxe.h"
/* We're required to print out stats at some point.  Here are a couple from
 * igbe, as an example. */

static char *statistics[Nstatistics] = {
	"CRC Error",
	"Alignment Error",
};

static long bxeifstat(struct ether *edev, void *a, long n, uint32_t offset)
{
	struct bxe_adapter *ctlr;
	char *p, *s;
	int i, l, r;
	uint64_t tuvl, ruvl;

	ctlr = edev->ctlr;
	qlock(&ctlr->slock);
	p = kzmalloc(READSTR, 0);
	if (p == NULL) {
		qunlock(&ctlr->slock);
		error(Enomem);
	}
	l = 0;
	for (i = 0; i < Nstatistics; i++) {
		/* somehow read the device's HW stats */
		//r = csr32r(ctlr, Statistics + i * 4);
		r = 3;	/* TODO: this is the value for the statistic */
		if ((s = statistics[i]) == NULL)
			continue;
		/* based on the stat, spit out a string */
		switch (i) {
			default:
				ctlr->statistics[i] += r;
				if (ctlr->statistics[i] == 0)
					continue;
				l += snprintf(p + l, READSTR - l, "%s: %ud %ud\n",
							  s, ctlr->statistics[i], r);
				break;
		}
	}

	/* TODO: then print out the software-only (ctlr) stats */
//	l += snprintf(p + l, READSTR - l, "lintr: %ud %ud\n",
//				  ctlr->lintr, ctlr->lsleep);
	n = readstr(offset, a, n, p);
	kfree(p);
	qunlock(&ctlr->slock);

	return n;
}

static long bxectl(struct ether *edev, void *buf, long n)
{
	ERRSTACK(1);
	int v;
	char *p;
	struct bxe_adapter *ctlr;
	struct cmdbuf *cb;
	struct cmdtab *ct;

	if ((ctlr = edev->ctlr) == NULL)
		error(Enonexist);
	cb = parsecmd(buf, n);
	if (waserror()) {
		kfree(cb);
		nexterror();
	}

	/* TODO: handle ctl command somehow.  igbe did the following: */
	//ct = lookupcmd(cb, igbectlmsg, ARRAY_SIZE(igbectlmsg));
	
	kfree(cb);
	poperror();
	return n;
}

static void bxepromiscuous(void *arg, int on)
{
	int rctl;
	struct bxe_adapter *ctlr;
	struct ether *edev;

	edev = arg;
	ctlr = edev->ctlr;
	/* TODO: set promisc on/off */
}

static void bxemulticast(void *arg, uint8_t * addr, int add)
{
	int bit, x;
	struct bxe_adapter *ctlr;
	struct ether *edev;

	edev = arg;
	ctlr = edev->ctlr;
	/* TODO: add or remove a multicast addr */
}

/* Transmit initialization.  Not mandatory for 9ns, but a good idea */
static void bxetxinit(struct bxe_adapter *ctlr)
{
}

static void bxetransmit(struct ether *edev)
{
	struct block *bp;
	struct bxe_adapter *ctlr;

	ctlr = edev->ctlr;

	/* Don't forget to spin_lock_irqsave */

	/* TODO: Free any completed packets */

	/* Try to fill the ring back up.  While there is space, yank from the output
	 * queue (oq) and put them in the Tx desc. */
	while (1) {
	//while (NEXT_RING(tdt, ctlr->ntd) != tdh) {
		if ((bp = qget(edev->oq)) == NULL)
			break;
		//td = &ctlr->tdba[tdt];
		//td->addr[0] = paddr_low32(bp->rp);
		//td->addr[1] = paddr_high32(bp->rp);
		/* if we're breaking out, make sure to set the IRQ mask */
		//if (NEXT_RING(tdt, ctlr->ntd) == tdh) {
		//	// other stuff removed
		//	csr32w(ctlr, Tdt, tdt);
		//	igbeim(ctlr, Txdw);
		//	break;
		//}
	}
}

/* Not mandatory.  Called to make sure there are free blocks available for
 * incoming packets */
static void bxereplenish(struct bxe_adapter *ctlr)
{
	struct block *bp;

	while (1) {
	//while (NEXT_RING(rdt, ctlr->nrd) != ctlr->rdh) {
		//if we want a new block
		{
			bp = iallocb(64); // TODO: use your block size, e.g. Rbsz
			if (bp == NULL) {
				/* needs to be a safe print for interrupt level */
				printk("#l%d bxereplenish: no available buffers\n",
					   ctlr->edev->ctlrno);
				break;
			}
			//ctlr->rb[rdt] = bp;
			//rd->addr[0] = paddr_low32(bp->rp);
			//rd->addr[1] = paddr_high32(bp->rp);
		}
		wmb();	/* ensure prev rd writes come before status = 0. */
		//rd->status = 0;
	}
}

/* Not mandatory.  Device init. */
static void bxerxinit(struct bxe_adapter *ctlr)
{
	bxereplenish(ctlr);
}

static int bxerim(void* ctlr)
{
	//return ((struct bxe_adapter*)ctlr)->rim != 0;
	return 1;
}

/* Do we want a receive proc?  It is similar to softirq.  Or we can do the work
 * in hard IRQ ctx. */
static void bxerproc(void *arg)
{
	struct block *bp;
	struct bxe_adapter *ctlr;
	struct ether *edev;

	edev = arg;
	ctlr = edev->ctlr;

	bxerxinit(ctlr);
	/* TODO: one time RX init */


	for (;;) {
		/* TODO: set up, once per sleep.  make sure we'll wake up */
		rendez_sleep(&ctlr->rrendez, bxerim, ctlr);

		for (;;) {
			/* if we can get a block, here's how to ram it up the stack */

			if (1) {
				bp = (void*)0xdeadbeef;
				//bp = ctlr->rb[rdh];
				//bp->wp += rd->length;
				//bp->next = NULL;
				/* conditionally, set block flags */
					//bp->flag |= Bipck; /* IP checksum done in HW */
					//bp->flag |= Btcpck | Budpck;
					//bp->checksum = rd->checksum;
					//bp->flag |= Bpktck;	/* Packet checksum? */
				etheriq(edev, bp, 1);
			} else {
				//freeb(ctlr->rb[rdh]);
			}

		}
		// optionally
			bxereplenish(ctlr);
	}
}

static void bxeattach(struct ether *edev)
{
	ERRSTACK(1);
	struct block *bp;
	struct bxe_adapter *ctlr;
	char *name;

	ctlr = edev->ctlr;
	ctlr->edev = edev;	/* point back to Ether* */

	/* not sure if we'll need/want any of the 9ns stuff */
	return;

	qlock(&ctlr->alock);
	/* TODO: make sure we haven't attached already.  If so, just return */

	/* Alloc all your ctrl crap. */

	/* the ktasks should free these names, if they ever exit */
	name = kmalloc(KNAMELEN, KMALLOC_WAIT);
	snprintf(name, KNAMELEN, "#l%d-bxerproc", edev->ctlrno);
	ktask(name, bxerproc, edev);

	bxetxinit(ctlr);

	qunlock(&ctlr->alock);
}

/* Hard IRQ */
static void bxeinterrupt(struct hw_trapframe *hw_tf, void *arg)
{
	struct bxe_adapter *ctlr;
	struct ether *edev;
	int icr, im, txdw;

	edev = arg;
	ctlr = edev->ctlr;

			/* At some point, wake up the rproc */
			rendez_wakeup(&ctlr->rrendez);

	/* optionally, might need to transmit (not sure if this is a good idea in
	 * hard irq or not) */
	bxetransmit(edev);
}

static void bxeshutdown(struct ether *ether)
{
	/*
	 * Perform a device reset to get the chip back to the
	 * power-on state, followed by an EEPROM reset to read
	 * the defaults for some internal registers.
	 */
	/* igbe did: */
	//igbedetach(ether->ctlr);
}

/* "reset", getting it back to the basic power-on state.  9ns drivers call this
 * during the initial setup (from the PCI func) */
static int bxereset(struct bxe_adapter *ctlr)
{
	int ctrl, i, pause, r, swdpio, txcw;

	/* despite the name, we attach at reset time.  BXE attach has a lot of
	 * mmio mappings that have to happen at boot (in akaros), instead of during
	 * devether's attach (at runtime) */
extern int bxe_attach(struct bxe_adapter *sc);
	bxe_attach(ctlr);

//	if (igbedetach(ctlr))
//		return -1;

	return 0;
}

static void bxepci(void)
{
	int cls, id;
	struct pci_device *pcidev;
	struct bxe_adapter *ctlr;

	STAILQ_FOREACH(pcidev, &pci_devices, all_dev) {
		/* This checks that pcidev is a Network Controller for Ethernet */
		if (pcidev->class != 0x02 || pcidev->subclass != 0x00)
			continue;
		id = pcidev->dev_id << 16 | pcidev->ven_id;

		extern int bxe_probe(struct pci_device *dev);
		if (bxe_probe(pcidev))
			continue;

		printk("bxe driver found 0x%04x:%04x at %02x:%02x.%x\n",
			   pcidev->ven_id, pcidev->dev_id,
			   pcidev->bus, pcidev->dev, pcidev->func);

		/* MMIO, pci_bus_master, etc, are all done in bxe_attach */

		cls = pcidev_read8(pcidev, PCI_CLSZ_REG);
		switch (cls) {
			default:
				printd("bxe: unexpected CLS - %d\n", cls * 4);
				break;
			case 0x00:
			case 0xFF:
				/* bogus value; use a sane default.  cls is set in DWORD (u32)
				 * units. */
				cls = ARCH_CL_SIZE / sizeof(long);
				pcidev_write8(pcidev, PCI_CLSZ_REG, cls);
				break;
			case 0x08:
			case 0x10:
				break;
		}

		ctlr = kzmalloc(sizeof(struct bxe_adapter), 0);
		if (ctlr == NULL)
			error(Enomem);

		/* TODO: Remove me */
		ctlr->debug = 0xFFFFFFFF; /* flying monkeys     */

		spinlock_init_irqsave(&ctlr->imlock);
		spinlock_init_irqsave(&ctlr->tlock);
		qlock_init(&ctlr->alock);
		qlock_init(&ctlr->slock);
		rendez_init(&ctlr->rrendez);

		ctlr->pcidev = pcidev;
		
		if (bxereset(ctlr)) {
			kfree(ctlr);
			continue;
		}

		/* BSD used mutexes for this list for other reasons */
		qlock(&bxe_prev_mtx);
		LIST_INSERT_HEAD(&bxe_prev_list, ctlr, node);
		qunlock(&bxe_prev_mtx);
	}
}

/* Called by devether's probe routines.  Return -1 if the edev does not match
 * any of your ctlrs. */
static int bxepnp(struct ether *edev)
{
	struct bxe_adapter *ctlr;

	run_once(qlock_init(&bxe_prev_mtx));
	/* Allocs ctlrs for all PCI devices matching our IDs, does various PCI and
	 * MMIO/port setup */
	run_once(bxepci());

	qlock(&bxe_prev_mtx);
	LIST_FOREACH(ctlr, &bxe_prev_list, node) {
		/* just take the first inactive ctlr on the list */
		if (ctlr->active)
			continue;
		ctlr->active = 1;
		break;
	}
	qunlock(&bxe_prev_mtx);
	if (ctlr == NULL)
		return -1;

	edev->ctlr = ctlr;
	//edev->port = ctlr->port;	/* might just remove this from devether */
	edev->irq = ctlr->pcidev->irqline;
	edev->tbdf = MKBUS(BusPCI, ctlr->pcidev->bus, ctlr->pcidev->dev,
	                   ctlr->pcidev->func);
	edev->netif.mbps = 1000;
	memmove(edev->ea, ctlr->link_params.mac_addr, Eaddrlen);
	
	/*
	 * Linkage to the generic ethernet driver.
	 */
	edev->attach = bxeattach;
	edev->transmit = bxetransmit;
	edev->ifstat = bxeifstat;
	edev->ctl = bxectl;
	edev->shutdown = bxeshutdown;

	edev->netif.arg = edev;
	edev->netif.promiscuous = bxepromiscuous;
	edev->netif.multicast = bxemulticast;

	register_irq(edev->irq, bxeinterrupt, edev, edev->tbdf);
	return 0;
}

linker_func_3(etherbxelink)
{
	addethercard("bxe", bxepnp);
}
