/* 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 bnx2x_ */

#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 <net/ip.h>
#include <ns.h>
#include "bnx2x.h"

/* TODO: Cheap externs */
extern int __init bnx2x_init(void);
extern bool is_bnx2x_dev(struct pci_device *dev);
extern const struct pci_device_id *
                    srch_bnx2x_pci_tbl(struct pci_device *needle);
extern int bnx2x_init_one(struct ether *dev, struct bnx2x *bp,
                          struct pci_device *pdev,
                          const struct pci_device_id *ent);
extern int bnx2x_open(struct ether *dev);
extern void bnx2x_set_rx_mode(struct ether *dev);
extern netdev_tx_t bnx2x_start_xmit(struct block *block,
                                    struct bnx2x_fp_txdata *txdata);

spinlock_t bnx2x_tq_lock = SPINLOCK_INITIALIZER;
TAILQ_HEAD(bnx2x_tq, bnx2x);
struct bnx2x_tq bnx2x_tq = TAILQ_HEAD_INITIALIZER(bnx2x_tq);

/* 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 bnx2x_ifstat(struct ether *edev, void *a, long n, uint32_t offset)
{
	struct bnx2x *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, ERROR_FIXME);
	}
	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 bnx2x_ctl(struct ether *edev, void *buf, long n)
{
	ERRSTACK(1);
	int v;
	char *p;
	struct bnx2x *ctlr;
	struct cmdbuf *cb;
	struct cmdtab *ct;

	if ((ctlr = edev->ctlr) == NULL)
		error(ENODEV, ERROR_FIXME);
	cb = parsecmd(buf, n);
	if (waserror()) {
		kfree(cb);
		nexterror();
	}
	if (cb->nf < 1)
		error(EFAIL, "short control request");

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

	kfree(cb);
	poperror();
	return n;
}

/* The poke function: we are guaranteed that only one copy of this func runs
 * per poke tracker (per queue).  Both transmit and tx_int will poke, and after
 * any pokes, the func will run at least once.
 *
 * Some notes for optimizing and synchronization:
 *
 * If we want a flag or something to keep us from checking the oq and attempting
 * the xmit, all that will do is speed up xmit when the tx rings are full.
 * You'd need to be careful.  The post/poke makes sure that this'll run after
 * work was posted, but if this function sets an abort flag and later checks it,
 * you need to check tx_avail *after* setting the flag (check, signal, check
 * again).  Consider this:
 *
 * this func:
 * 		calls start_xmit, fails with BUSY.  wants to set ABORT flag
 *
 *      PAUSE - meanwhile:
 *
 * tx_int clears the ABORT flag, then pokes:
 * 		drain so there is room;
 * 		clear flag (combo of these is "post work");
 * 		poke;.  guaranteed that poke will happen after we cleared flag.
 * 		        but it is concurrent with this function
 *
 * 		RESUME this func:
 *
 * 		sets ABORT flag
 * 		returns.
 * 		tx_int's poke ensures we run again
 * 		we run again and see ABORT, then return
 * 		never try again til the next tx_int, if ever
 *
 * Instead, in this func, we must set ABORT flag, then check tx_avail.  Or
 * have two flags, one set by us, another set by tx_int, where this func only
 * clears the tx_int flag when it will attempt a start_xmit.
 *
 * It's probably easier to just check tx_avail before entering the while loop,
 * if you're really concerned.  If you want to do the flag thing, probably use
 * two flags (atomically), and be careful. */
void __bnx2x_tx_queue(void *txdata_arg)
{
	struct bnx2x_fp_txdata *txdata = txdata_arg;
	struct block *block;
	struct queue *oq = txdata->oq;

	/* TODO: avoid bugs til multi-queue is working */
	assert(oq);
	assert(txdata->txq_index == 0);

	while ((block = qget(oq))) {
		if ((bnx2x_start_xmit(block, txdata) != NETDEV_TX_OK)) {
			/* all queue readers are sync'd by the poke, so we can putback
			 * without fear of going out of order. */

			/* TODO: q code has methods that should be called with the spinlock
			 * held, but no methods to do the locking... */
			//spin_unlock_irqsave(&oq->lock);
			qputback(oq, block);
			//spin_lock_irqsave(&oq->lock);

			/* device can't handle any more, we're done for now.  tx_int will
			 * poke when space frees up.  it may be poking concurrently, and in
			 * which case, we'll run again immediately. */
			break;
		}
	}
}

static void bnx2x_transmit(struct ether *edev)
{
	struct bnx2x *ctlr = edev->ctlr;
	struct bnx2x_fp_txdata *txdata;
	/* TODO: determine the tx queue we're supposed to work on */
	int txq_index = 0;

	txdata = &ctlr->bnx2x_txq[txq_index];
	poke(&txdata->poker, txdata);
}

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

	while (1) {
	//while (NEXT_RING(rdt, ctlr->nrd) != ctlr->rdh) {
		//if we want a new block
		{
			// TODO: use your block size, e.g. Rbsz
			bp = block_alloc(64, MEM_ATOMIC);
			if (bp == NULL) {
				/* needs to be a safe print for interrupt level */
				printk("#l%d bnx2x_replenish: 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 bnx2x_rxinit(struct bnx2x *ctlr)
{
	bnx2x_replenish(ctlr);
}

static int bnx2x_rim(void* ctlr)
{
	//return ((struct bnx2x*)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 bnx2x_rproc(void *arg)
{
	struct block *bp;
	struct bnx2x *ctlr;
	struct ether *edev;

	edev = arg;
	ctlr = edev->ctlr;

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


	for (;;) {
		/* TODO: set up, once per sleep.  make sure we'll wake up */
		rendez_sleep(&ctlr->rrendez, bnx2x_rim, 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
			bnx2x_replenish(ctlr);
	}
}

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

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

	qlock(&ctlr->alock);
	if (ctlr->attached) {
		qunlock(&ctlr->alock);
		return;
	}

	bnx2x_open(ctlr->edev);
	bnx2x_set_rx_mode(edev);

	ctlr->attached = TRUE;
	qunlock(&ctlr->alock);
	/* not sure if we'll need/want any of the other 9ns stuff */
	return;

	/* Alloc all your ctrl crap. */

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

	qunlock(&ctlr->alock);
}

/* Hard IRQ */
static void bnx2x_interrupt(struct hw_trapframe *hw_tf, void *arg)
{
	struct bnx2x *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) */
	bnx2x_transmit(edev);
}

static void bnx2x_shutdown(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 bnx2x_reset(struct bnx2x *ctlr)
{
	int ctrl, i, pause, r, swdpio, txcw;

	bnx2x_init_one(ctlr->edev, ctlr, ctlr->pcidev, ctlr->pci_id);
	return 0;
}

static void bnx2x_pci(void)
{
	int id;
	struct pci_device *pcidev;
	struct bnx2x *ctlr;
	const struct pci_device_id *pci_id;

	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;

		pci_id = srch_bnx2x_pci_tbl(pcidev);
		if (!pci_id)
			continue;

		/* only run bnx2x's __init method once we know we have one */
		run_once(bnx2x_init());

		printk("bnx2x 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 bnx2x_attach */

		pci_set_cacheline_size(pcidev);

		ctlr = kzmalloc(sizeof(struct bnx2x), 0);
		if (ctlr == NULL)
			error(ENOMEM, ERROR_FIXME);

		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;
		ctlr->pci_id = pci_id;

		spin_lock(&bnx2x_tq_lock);
		TAILQ_INSERT_TAIL(&bnx2x_tq, ctlr, link9ns);
		spin_unlock(&bnx2x_tq_lock);
	}
}

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

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

	spin_lock(&bnx2x_tq_lock);
	TAILQ_FOREACH(ctlr, &bnx2x_tq, link9ns) {
		/* just take the first inactive ctlr on the list */
		if (ctlr->active)
			continue;
		ctlr->active = 1;
		break;
	}
	spin_unlock(&bnx2x_tq_lock);
	if (ctlr == NULL)
		return -1;

	edev->ctlr = ctlr;
	ctlr->edev = edev;
	strlcpy(edev->drv_name, "bnx2x", KNAMELEN);

	//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->mbps = 1000;
	memmove(edev->ea, ctlr->link_params.mac_addr, Eaddrlen);

	/*
	 * Linkage to the generic ethernet driver.
	 */
	edev->attach = bnx2x_attach;
	edev->transmit = bnx2x_transmit;
	edev->ifstat = bnx2x_ifstat;
	edev->ctl = bnx2x_ctl;
	edev->shutdown = bnx2x_shutdown;

	edev->arg = edev;
	edev->promiscuous = NULL;
	edev->multicast = NULL;

	bnx2x_reset(ctlr);

	return 0;
}

linker_func_3(etherbnx2x_link)
{
	addethercard("bnx2x", bnx2x_pnp);
}
