/*
 * drivers/net/ibm_emac/ibm_emac_mal.c
 *
 * Memory Access Layer (MAL) support
 * 
 * Copyright (c) 2004, 2005 Zultys Technologies.
 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 *
 * Based on original work by
 *      Benjamin Herrenschmidt <benh@kernel.crashing.org>,
 *      David Gibson <hermes@gibson.dropbear.id.au>,
 *
 *      Armin Kuster <akuster@mvista.com>
 *      Copyright 2002 MontaVista Softare Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>

#include <asm/ocp.h>

#include "ibm_emac_core.h"
#include "ibm_emac_mal.h"
#include "ibm_emac_debug.h"

int __init mal_register_commac(struct ibm_ocp_mal *mal,
			       struct mal_commac *commac)
{
	unsigned long flags;
	local_irq_save(flags);

	MAL_DBG("%d: reg(%08x, %08x)" NL, mal->def->index,
		commac->tx_chan_mask, commac->rx_chan_mask);

	/* Don't let multiple commacs claim the same channel(s) */
	if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
	    (mal->rx_chan_mask & commac->rx_chan_mask)) {
		local_irq_restore(flags);
		printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
		       mal->def->index);
		return -EBUSY;
	}

	mal->tx_chan_mask |= commac->tx_chan_mask;
	mal->rx_chan_mask |= commac->rx_chan_mask;
	list_add(&commac->list, &mal->list);

	local_irq_restore(flags);
	return 0;
}

void mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
{
	unsigned long flags;
	local_irq_save(flags);

	MAL_DBG("%d: unreg(%08x, %08x)" NL, mal->def->index,
		commac->tx_chan_mask, commac->rx_chan_mask);

	mal->tx_chan_mask &= ~commac->tx_chan_mask;
	mal->rx_chan_mask &= ~commac->rx_chan_mask;
	list_del_init(&commac->list);

	local_irq_restore(flags);
}

int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size)
{
	struct ocp_func_mal_data *maldata = mal->def->additions;
	BUG_ON(channel < 0 || channel >= maldata->num_rx_chans ||
	       size > MAL_MAX_RX_SIZE);

	MAL_DBG("%d: set_rbcs(%d, %lu)" NL, mal->def->index, channel, size);

	if (size & 0xf) {
		printk(KERN_WARNING
		       "mal%d: incorrect RX size %lu for the channel %d\n",
		       mal->def->index, size, channel);
		return -EINVAL;
	}

	set_mal_dcrn(mal, MAL_RCBS(channel), size >> 4);
	return 0;
}

int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel)
{
	struct ocp_func_mal_data *maldata = mal->def->additions;
	BUG_ON(channel < 0 || channel >= maldata->num_tx_chans);
	return channel * NUM_TX_BUFF;
}

int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel)
{
	struct ocp_func_mal_data *maldata = mal->def->additions;
	BUG_ON(channel < 0 || channel >= maldata->num_rx_chans);
	return maldata->num_tx_chans * NUM_TX_BUFF + channel * NUM_RX_BUFF;
}

void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel)
{
	local_bh_disable();
	MAL_DBG("%d: enable_tx(%d)" NL, mal->def->index, channel);
	set_mal_dcrn(mal, MAL_TXCASR,
		     get_mal_dcrn(mal, MAL_TXCASR) | MAL_CHAN_MASK(channel));
	local_bh_enable();
}

void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel)
{
	set_mal_dcrn(mal, MAL_TXCARR, MAL_CHAN_MASK(channel));
	MAL_DBG("%d: disable_tx(%d)" NL, mal->def->index, channel);
}

void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel)
{
	local_bh_disable();
	MAL_DBG("%d: enable_rx(%d)" NL, mal->def->index, channel);
	set_mal_dcrn(mal, MAL_RXCASR,
		     get_mal_dcrn(mal, MAL_RXCASR) | MAL_CHAN_MASK(channel));
	local_bh_enable();
}

void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel)
{
	set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel));
	MAL_DBG("%d: disable_rx(%d)" NL, mal->def->index, channel);
}

void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac)
{
	local_bh_disable();
	MAL_DBG("%d: poll_add(%p)" NL, mal->def->index, commac);
	list_add_tail(&commac->poll_list, &mal->poll_list);
	local_bh_enable();
}

void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac)
{
	local_bh_disable();
	MAL_DBG("%d: poll_del(%p)" NL, mal->def->index, commac);
	list_del(&commac->poll_list);
	local_bh_enable();
}

/* synchronized by mal_poll() */
static inline void mal_enable_eob_irq(struct ibm_ocp_mal *mal)
{
	MAL_DBG2("%d: enable_irq" NL, mal->def->index);
	set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
}

/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */
static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal)
{
	set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) & ~MAL_CFG_EOPIE);
	MAL_DBG2("%d: disable_irq" NL, mal->def->index);
}

static irqreturn_t mal_serr(int irq, void *dev_instance)
{
	struct ibm_ocp_mal *mal = dev_instance;
	u32 esr = get_mal_dcrn(mal, MAL_ESR);

	/* Clear the error status register */
	set_mal_dcrn(mal, MAL_ESR, esr);

	MAL_DBG("%d: SERR %08x" NL, mal->def->index, esr);

	if (esr & MAL_ESR_EVB) {
		if (esr & MAL_ESR_DE) {
			/* We ignore Descriptor error,
			 * TXDE or RXDE interrupt will be generated anyway.
			 */
			return IRQ_HANDLED;
		}

		if (esr & MAL_ESR_PEIN) {
			/* PLB error, it's probably buggy hardware or
			 * incorrect physical address in BD (i.e. bug)
			 */
			if (net_ratelimit())
				printk(KERN_ERR
				       "mal%d: system error, PLB (ESR = 0x%08x)\n",
				       mal->def->index, esr);
			return IRQ_HANDLED;
		}

		/* OPB error, it's probably buggy hardware or incorrect EBC setup */
		if (net_ratelimit())
			printk(KERN_ERR
			       "mal%d: system error, OPB (ESR = 0x%08x)\n",
			       mal->def->index, esr);
	}
	return IRQ_HANDLED;
}

static inline void mal_schedule_poll(struct ibm_ocp_mal *mal)
{
	if (likely(napi_schedule_prep(&mal->napi))) {
		MAL_DBG2("%d: schedule_poll" NL, mal->def->index);
		mal_disable_eob_irq(mal);
		__napi_schedule(&mal->napi);
	} else
		MAL_DBG2("%d: already in poll" NL, mal->def->index);
}

static irqreturn_t mal_txeob(int irq, void *dev_instance)
{
	struct ibm_ocp_mal *mal = dev_instance;
	u32 r = get_mal_dcrn(mal, MAL_TXEOBISR);
	MAL_DBG2("%d: txeob %08x" NL, mal->def->index, r);
	mal_schedule_poll(mal);
	set_mal_dcrn(mal, MAL_TXEOBISR, r);
	return IRQ_HANDLED;
}

static irqreturn_t mal_rxeob(int irq, void *dev_instance)
{
	struct ibm_ocp_mal *mal = dev_instance;
	u32 r = get_mal_dcrn(mal, MAL_RXEOBISR);
	MAL_DBG2("%d: rxeob %08x" NL, mal->def->index, r);
	mal_schedule_poll(mal);
	set_mal_dcrn(mal, MAL_RXEOBISR, r);
	return IRQ_HANDLED;
}

static irqreturn_t mal_txde(int irq, void *dev_instance)
{
	struct ibm_ocp_mal *mal = dev_instance;
	u32 deir = get_mal_dcrn(mal, MAL_TXDEIR);
	set_mal_dcrn(mal, MAL_TXDEIR, deir);

	MAL_DBG("%d: txde %08x" NL, mal->def->index, deir);

	if (net_ratelimit())
		printk(KERN_ERR
		       "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
		       mal->def->index, deir);

	return IRQ_HANDLED;
}

static irqreturn_t mal_rxde(int irq, void *dev_instance)
{
	struct ibm_ocp_mal *mal = dev_instance;
	struct list_head *l;
	u32 deir = get_mal_dcrn(mal, MAL_RXDEIR);

	MAL_DBG("%d: rxde %08x" NL, mal->def->index, deir);

	list_for_each(l, &mal->list) {
		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
		if (deir & mc->rx_chan_mask) {
			mc->rx_stopped = 1;
			mc->ops->rxde(mc->dev);
		}
	}

	mal_schedule_poll(mal);
	set_mal_dcrn(mal, MAL_RXDEIR, deir);

	return IRQ_HANDLED;
}

static int mal_poll(struct napi_struct *napi, int budget)
{
	struct ibm_ocp_mal *mal = container_of(napi, struct ibm_ocp_mal, napi);
	struct list_head *l;
	int received = 0;

	MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget,
		 rx_work_limit);
      again:
	/* Process TX skbs */
	list_for_each(l, &mal->poll_list) {
		struct mal_commac *mc =
		    list_entry(l, struct mal_commac, poll_list);
		mc->ops->poll_tx(mc->dev);
	}

	/* Process RX skbs.
	 * We _might_ need something more smart here to enforce polling fairness.
	 */
	list_for_each(l, &mal->poll_list) {
		struct mal_commac *mc =
		    list_entry(l, struct mal_commac, poll_list);
		int n = mc->ops->poll_rx(mc->dev, budget);
		if (n) {
			received += n;
			budget -= n;
			if (budget <= 0)
				goto more_work;	// XXX What if this is the last one ?
		}
	}

	/* We need to disable IRQs to protect from RXDE IRQ here */
	local_irq_disable();
	__napi_complete(napi);
	mal_enable_eob_irq(mal);
	local_irq_enable();

	/* Check for "rotting" packet(s) */
	list_for_each(l, &mal->poll_list) {
		struct mal_commac *mc =
		    list_entry(l, struct mal_commac, poll_list);
		if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) {
			MAL_DBG2("%d: rotting packet" NL, mal->def->index);
			if (napi_reschedule(napi))
				mal_disable_eob_irq(mal);
			else
				MAL_DBG2("%d: already in poll list" NL,
					 mal->def->index);

			if (budget > 0)
				goto again;
			else
				goto more_work;
		}
		mc->ops->poll_tx(mc->dev);
	}

      more_work:
	MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, budget, received);
	return received;
}

static void mal_reset(struct ibm_ocp_mal *mal)
{
	int n = 10;
	MAL_DBG("%d: reset" NL, mal->def->index);

	set_mal_dcrn(mal, MAL_CFG, MAL_CFG_SR);

	/* Wait for reset to complete (1 system clock) */
	while ((get_mal_dcrn(mal, MAL_CFG) & MAL_CFG_SR) && n)
		--n;

	if (unlikely(!n))
		printk(KERN_ERR "mal%d: reset timeout\n", mal->def->index);
}

int mal_get_regs_len(struct ibm_ocp_mal *mal)
{
	return sizeof(struct emac_ethtool_regs_subhdr) +
	    sizeof(struct ibm_mal_regs);
}

void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf)
{
	struct emac_ethtool_regs_subhdr *hdr = buf;
	struct ibm_mal_regs *regs = (struct ibm_mal_regs *)(hdr + 1);
	struct ocp_func_mal_data *maldata = mal->def->additions;
	int i;

	hdr->version = MAL_VERSION;
	hdr->index = mal->def->index;

	regs->tx_count = maldata->num_tx_chans;
	regs->rx_count = maldata->num_rx_chans;

	regs->cfg = get_mal_dcrn(mal, MAL_CFG);
	regs->esr = get_mal_dcrn(mal, MAL_ESR);
	regs->ier = get_mal_dcrn(mal, MAL_IER);
	regs->tx_casr = get_mal_dcrn(mal, MAL_TXCASR);
	regs->tx_carr = get_mal_dcrn(mal, MAL_TXCARR);
	regs->tx_eobisr = get_mal_dcrn(mal, MAL_TXEOBISR);
	regs->tx_deir = get_mal_dcrn(mal, MAL_TXDEIR);
	regs->rx_casr = get_mal_dcrn(mal, MAL_RXCASR);
	regs->rx_carr = get_mal_dcrn(mal, MAL_RXCARR);
	regs->rx_eobisr = get_mal_dcrn(mal, MAL_RXEOBISR);
	regs->rx_deir = get_mal_dcrn(mal, MAL_RXDEIR);

	for (i = 0; i < regs->tx_count; ++i)
		regs->tx_ctpr[i] = get_mal_dcrn(mal, MAL_TXCTPR(i));

	for (i = 0; i < regs->rx_count; ++i) {
		regs->rx_ctpr[i] = get_mal_dcrn(mal, MAL_RXCTPR(i));
		regs->rcbs[i] = get_mal_dcrn(mal, MAL_RCBS(i));
	}
	return regs + 1;
}

static int __init mal_probe(struct ocp_device *ocpdev)
{
	struct ibm_ocp_mal *mal;
	struct ocp_func_mal_data *maldata;
	int err = 0, i, bd_size;

	MAL_DBG("%d: probe" NL, ocpdev->def->index);

	maldata = ocpdev->def->additions;
	if (maldata == NULL) {
		printk(KERN_ERR "mal%d: missing additional data!\n",
		       ocpdev->def->index);
		return -ENODEV;
	}

	mal = kzalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
	if (!mal) {
		printk(KERN_ERR
		       "mal%d: out of memory allocating MAL structure!\n",
		       ocpdev->def->index);
		return -ENOMEM;
	}

	/* XXX This only works for native dcr for now */
	mal->dcrhost = dcr_map(NULL, maldata->dcr_base, 0);

	mal->def = ocpdev->def;

	INIT_LIST_HEAD(&mal->poll_list);
	mal->napi.weight = CONFIG_IBM_EMAC_POLL_WEIGHT;
	mal->napi.poll = mal_poll;

	INIT_LIST_HEAD(&mal->list);

	/* Load power-on reset defaults */
	mal_reset(mal);

	/* Set the MAL configuration register */
	set_mal_dcrn(mal, MAL_CFG, MAL_CFG_DEFAULT | MAL_CFG_PLBB |
		     MAL_CFG_OPBBL | MAL_CFG_LEA);

	mal_enable_eob_irq(mal);

	/* Allocate space for BD rings */
	BUG_ON(maldata->num_tx_chans <= 0 || maldata->num_tx_chans > 32);
	BUG_ON(maldata->num_rx_chans <= 0 || maldata->num_rx_chans > 32);
	bd_size = sizeof(struct mal_descriptor) *
	    (NUM_TX_BUFF * maldata->num_tx_chans +
	     NUM_RX_BUFF * maldata->num_rx_chans);
	mal->bd_virt =
	    dma_alloc_coherent(&ocpdev->dev, bd_size, &mal->bd_dma, GFP_KERNEL);

	if (!mal->bd_virt) {
		printk(KERN_ERR
		       "mal%d: out of memory allocating RX/TX descriptors!\n",
		       mal->def->index);
		err = -ENOMEM;
		goto fail;
	}
	memset(mal->bd_virt, 0, bd_size);

	for (i = 0; i < maldata->num_tx_chans; ++i)
		set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma +
			     sizeof(struct mal_descriptor) *
			     mal_tx_bd_offset(mal, i));

	for (i = 0; i < maldata->num_rx_chans; ++i)
		set_mal_dcrn(mal, MAL_RXCTPR(i), mal->bd_dma +
			     sizeof(struct mal_descriptor) *
			     mal_rx_bd_offset(mal, i));

	err = request_irq(maldata->serr_irq, mal_serr, 0, "MAL SERR", mal);
	if (err)
		goto fail2;
	err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE", mal);
	if (err)
		goto fail3;
	err = request_irq(maldata->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
	if (err)
		goto fail4;
	err = request_irq(maldata->rxde_irq, mal_rxde, 0, "MAL RX DE", mal);
	if (err)
		goto fail5;
	err = request_irq(maldata->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
	if (err)
		goto fail6;

	/* Enable all MAL SERR interrupt sources */
	set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS);

	/* Advertise this instance to the rest of the world */
	ocp_set_drvdata(ocpdev, mal);

	mal_dbg_register(mal->def->index, mal);

	printk(KERN_INFO "mal%d: initialized, %d TX channels, %d RX channels\n",
	       mal->def->index, maldata->num_tx_chans, maldata->num_rx_chans);
	return 0;

      fail6:
	free_irq(maldata->rxde_irq, mal);
      fail5:
	free_irq(maldata->txeob_irq, mal);
      fail4:
	free_irq(maldata->txde_irq, mal);
      fail3:
	free_irq(maldata->serr_irq, mal);
      fail2:
	dma_free_coherent(&ocpdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
      fail:
	kfree(mal);
	return err;
}

static void __exit mal_remove(struct ocp_device *ocpdev)
{
	struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev);
	struct ocp_func_mal_data *maldata = mal->def->additions;

	MAL_DBG("%d: remove" NL, mal->def->index);

	/* Synchronize with scheduled polling */
	napi_disable(&mal->napi);

	if (!list_empty(&mal->list)) {
		/* This is *very* bad */
		printk(KERN_EMERG
		       "mal%d: commac list is not empty on remove!\n",
		       mal->def->index);
	}

	ocp_set_drvdata(ocpdev, NULL);

	free_irq(maldata->serr_irq, mal);
	free_irq(maldata->txde_irq, mal);
	free_irq(maldata->txeob_irq, mal);
	free_irq(maldata->rxde_irq, mal);
	free_irq(maldata->rxeob_irq, mal);

	mal_reset(mal);

	mal_dbg_register(mal->def->index, NULL);

	dma_free_coherent(&ocpdev->dev,
			  sizeof(struct mal_descriptor) *
			  (NUM_TX_BUFF * maldata->num_tx_chans +
			   NUM_RX_BUFF * maldata->num_rx_chans), mal->bd_virt,
			  mal->bd_dma);

	kfree(mal);
}

/* Structure for a device driver */
static struct ocp_device_id mal_ids[] = {
	{ .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_MAL },
	{ .vendor = OCP_VENDOR_INVALID}
};

static struct ocp_driver mal_driver = {
	.name = "mal",
	.id_table = mal_ids,

	.probe = mal_probe,
	.remove = mal_remove,
};

int __init mal_init(void)
{
	MAL_DBG(": init" NL);
	return ocp_register_driver(&mal_driver);
}

void __exit mal_exit(void)
{
	MAL_DBG(": exit" NL);
	ocp_unregister_driver(&mal_driver);
}
