/*
 * drivers/net/ibm_newemac/debug.c
 *
 * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
 *
 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
 *                <benh@kernel.crashing.org>
 *
 * Based on the arch/ppc version of the driver:
 *
 * Copyright (c) 2004, 2005 Zultys Technologies
 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 *
 * 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/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/sysrq.h>
#include <asm/io.h>

#include "core.h"

static DEFINE_SPINLOCK(emac_dbg_lock);

static void emac_desc_dump(struct emac_instance *p)
{
	int i;
	printk("** EMAC %s TX BDs **\n"
	       " tx_cnt = %d tx_slot = %d ack_slot = %d\n",
	       p->ofdev->node->full_name,
	       p->tx_cnt, p->tx_slot, p->ack_slot);
	for (i = 0; i < NUM_TX_BUFF / 2; ++i)
		printk
		    ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
		     i, p->tx_desc[i].data_ptr, p->tx_skb[i] ? 'V' : ' ',
		     p->tx_desc[i].ctrl, p->tx_desc[i].data_len,
		     NUM_TX_BUFF / 2 + i,
		     p->tx_desc[NUM_TX_BUFF / 2 + i].data_ptr,
		     p->tx_skb[NUM_TX_BUFF / 2 + i] ? 'V' : ' ',
		     p->tx_desc[NUM_TX_BUFF / 2 + i].ctrl,
		     p->tx_desc[NUM_TX_BUFF / 2 + i].data_len);

	printk("** EMAC %s RX BDs **\n"
	       " rx_slot = %d flags = 0x%lx rx_skb_size = %d rx_sync_size = %d\n"
	       " rx_sg_skb = 0x%p\n",
	       p->ofdev->node->full_name,
	       p->rx_slot, p->commac.flags, p->rx_skb_size,
	       p->rx_sync_size, p->rx_sg_skb);
	for (i = 0; i < NUM_RX_BUFF / 2; ++i)
		printk
		    ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
		     i, p->rx_desc[i].data_ptr, p->rx_skb[i] ? 'V' : ' ',
		     p->rx_desc[i].ctrl, p->rx_desc[i].data_len,
		     NUM_RX_BUFF / 2 + i,
		     p->rx_desc[NUM_RX_BUFF / 2 + i].data_ptr,
		     p->rx_skb[NUM_RX_BUFF / 2 + i] ? 'V' : ' ',
		     p->rx_desc[NUM_RX_BUFF / 2 + i].ctrl,
		     p->rx_desc[NUM_RX_BUFF / 2 + i].data_len);
}

static void emac_mac_dump(struct emac_instance *dev)
{
	struct emac_regs __iomem *p = dev->emacp;
	const int xaht_regs = EMAC_XAHT_REGS(dev);
	u32 *gaht_base = emac_gaht_base(dev);
	u32 *iaht_base = emac_iaht_base(dev);
	int emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC);
	int n;

	printk("** EMAC %s registers **\n"
	       "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
	       "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n",
	       dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1),
	       in_be32(&p->tmr0), in_be32(&p->tmr1),
	       in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
	       in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
	       in_be32(&p->vtci)
	       );

	if (emac4sync)
		printk("MAR = %04x%08x MMAR = %04x%08x\n",
		       in_be32(&p->u0.emac4sync.mahr),
		       in_be32(&p->u0.emac4sync.malr),
		       in_be32(&p->u0.emac4sync.mmahr),
		       in_be32(&p->u0.emac4sync.mmalr)
		       );

	for (n = 0; n < xaht_regs; n++)
		printk("IAHT%02d = 0x%08x\n", n + 1, in_be32(iaht_base + n));

	for (n = 0; n < xaht_regs; n++)
		printk("GAHT%02d = 0x%08x\n", n + 1, in_be32(gaht_base + n));

	printk("LSA = %04x%08x IPGVR = 0x%04x\n"
	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
	       "OCTX = 0x%08x OCRX = 0x%08x\n",
	       in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
	       in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
	       in_be32(&p->octx), in_be32(&p->ocrx)
	       );

	if (!emac4sync) {
		printk("IPCR = 0x%08x\n",
		       in_be32(&p->u1.emac4.ipcr)
		       );
	} else {
		printk("REVID = 0x%08x TPC = 0x%08x\n",
		       in_be32(&p->u1.emac4sync.revid),
		       in_be32(&p->u1.emac4sync.tpc)
		       );
	}

	emac_desc_dump(dev);
}

static void emac_mal_dump(struct mal_instance *mal)
{
	int i;

	printk("** MAL %s Registers **\n"
	       "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n"
	       "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n"
	       "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n",
	       mal->ofdev->node->full_name,
	       get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR),
	       get_mal_dcrn(mal, MAL_IER),
	       get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR),
	       get_mal_dcrn(mal, MAL_TXEOBISR), get_mal_dcrn(mal, MAL_TXDEIR),
	       get_mal_dcrn(mal, MAL_RXCASR), get_mal_dcrn(mal, MAL_RXCARR),
	       get_mal_dcrn(mal, MAL_RXEOBISR), get_mal_dcrn(mal, MAL_RXDEIR)
	    );

	printk("TX|");
	for (i = 0; i < mal->num_tx_chans; ++i) {
		if (i && !(i % 4))
			printk("\n   ");
		printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_TXCTPR(i)));
	}
	printk("\nRX|");
	for (i = 0; i < mal->num_rx_chans; ++i) {
		if (i && !(i % 4))
			printk("\n   ");
		printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_RXCTPR(i)));
	}
	printk("\n   ");
	for (i = 0; i < mal->num_rx_chans; ++i) {
		u32 r = get_mal_dcrn(mal, MAL_RCBS(i));
		if (i && !(i % 3))
			printk("\n   ");
		printk("RCBS%d = 0x%08x (%d) ", i, r, r * 16);
	}
	printk("\n");
}

static struct emac_instance *__emacs[4];
static struct mal_instance *__mals[1];

void emac_dbg_register(struct emac_instance *dev)
{
	unsigned long flags;
	int i;

	spin_lock_irqsave(&emac_dbg_lock, flags);
	for (i = 0; i < ARRAY_SIZE(__emacs); i++)
		if (__emacs[i] == NULL) {
			__emacs[i] = dev;
			break;
		}
	spin_unlock_irqrestore(&emac_dbg_lock, flags);
}

void emac_dbg_unregister(struct emac_instance *dev)
{
	unsigned long flags;
	int i;

	spin_lock_irqsave(&emac_dbg_lock, flags);
	for (i = 0; i < ARRAY_SIZE(__emacs); i++)
		if (__emacs[i] == dev) {
			__emacs[i] = NULL;
			break;
		}
	spin_unlock_irqrestore(&emac_dbg_lock, flags);
}

void mal_dbg_register(struct mal_instance *mal)
{
	unsigned long flags;
	int i;

	spin_lock_irqsave(&emac_dbg_lock, flags);
	for (i = 0; i < ARRAY_SIZE(__mals); i++)
		if (__mals[i] == NULL) {
			__mals[i] = mal;
			break;
		}
	spin_unlock_irqrestore(&emac_dbg_lock, flags);
}

void mal_dbg_unregister(struct mal_instance *mal)
{
	unsigned long flags;
	int i;

	spin_lock_irqsave(&emac_dbg_lock, flags);
	for (i = 0; i < ARRAY_SIZE(__mals); i++)
		if (__mals[i] == mal) {
			__mals[i] = NULL;
			break;
		}
	spin_unlock_irqrestore(&emac_dbg_lock, flags);
}

void emac_dbg_dump_all(void)
{
	unsigned int i;
	unsigned long flags;

	spin_lock_irqsave(&emac_dbg_lock, flags);

	for (i = 0; i < ARRAY_SIZE(__mals); ++i)
		if (__mals[i])
			emac_mal_dump(__mals[i]);

	for (i = 0; i < ARRAY_SIZE(__emacs); ++i)
		if (__emacs[i])
			emac_mac_dump(__emacs[i]);

	spin_unlock_irqrestore(&emac_dbg_lock, flags);
}

#if defined(CONFIG_MAGIC_SYSRQ)
static void emac_sysrq_handler(int key, struct tty_struct *tty)
{
	emac_dbg_dump_all();
}

static struct sysrq_key_op emac_sysrq_op = {
	.handler = emac_sysrq_handler,
	.help_msg = "emaC",
	.action_msg = "Show EMAC(s) status",
};

int __init emac_init_debug(void)
{
	return register_sysrq_key('c', &emac_sysrq_op);
}

void __exit emac_fini_debug(void)
{
	unregister_sysrq_key('c', &emac_sysrq_op);
}

#else
int __init emac_init_debug(void)
{
	return 0;
}
void __exit emac_fini_debug(void)
{
}
#endif				/* CONFIG_MAGIC_SYSRQ */
