/*
 * drivers/net/netx-eth.c
 *
 * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>

#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/mii.h>

#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/arch/hardware.h>
#include <asm/arch/netx-regs.h>
#include <asm/arch/pfifo.h>
#include <asm/arch/xc.h>
#include <asm/arch/eth.h>

/* XC Fifo Offsets */
#define EMPTY_PTR_FIFO(xcno)    (0 + ((xcno) << 3))	/* Index of the empty pointer FIFO */
#define IND_FIFO_PORT_HI(xcno)  (1 + ((xcno) << 3))	/* Index of the FIFO where received */
							/* Data packages are indicated by XC */
#define IND_FIFO_PORT_LO(xcno)  (2 + ((xcno) << 3))	/* Index of the FIFO where received */
							/* Data packages are indicated by XC */
#define REQ_FIFO_PORT_HI(xcno)  (3 + ((xcno) << 3))	/* Index of the FIFO where Data packages */
							/* have to be indicated by ARM which */
							/* shall be sent */
#define REQ_FIFO_PORT_LO(xcno)  (4 + ((xcno) << 3))	/* Index of the FIFO where Data packages */
							/* have to be indicated by ARM which shall */
							/* be sent */
#define CON_FIFO_PORT_HI(xcno)  (5 + ((xcno) << 3))	/* Index of the FIFO where sent Data packages */
							/* are confirmed */
#define CON_FIFO_PORT_LO(xcno)  (6 + ((xcno) << 3))	/* Index of the FIFO where sent Data */
							/* packages are confirmed */
#define PFIFO_MASK(xcno)        (0x7f << (xcno*8))

#define FIFO_PTR_FRAMELEN_SHIFT 0
#define FIFO_PTR_FRAMELEN_MASK  (0x7ff << 0)
#define FIFO_PTR_FRAMELEN(len)  (((len) << 0) & FIFO_PTR_FRAMELEN_MASK)
#define FIFO_PTR_TIMETRIG       (1<<11)
#define FIFO_PTR_MULTI_REQ
#define FIFO_PTR_ORIGIN         (1<<14)
#define FIFO_PTR_VLAN           (1<<15)
#define FIFO_PTR_FRAMENO_SHIFT  16
#define FIFO_PTR_FRAMENO_MASK   (0x3f << 16)
#define FIFO_PTR_FRAMENO(no)    (((no) << 16) & FIFO_PTR_FRAMENO_MASK)
#define FIFO_PTR_SEGMENT_SHIFT  22
#define FIFO_PTR_SEGMENT_MASK   (0xf << 22)
#define FIFO_PTR_SEGMENT(seg)   (((seg) & 0xf) << 22)
#define FIFO_PTR_ERROR_SHIFT    28
#define FIFO_PTR_ERROR_MASK     (0xf << 28)

#define ISR_LINK_STATUS_CHANGE (1<<4)
#define ISR_IND_LO             (1<<3)
#define ISR_CON_LO             (1<<2)
#define ISR_IND_HI             (1<<1)
#define ISR_CON_HI             (1<<0)

#define ETH_MAC_LOCAL_CONFIG 0x1560
#define ETH_MAC_4321         0x1564
#define ETH_MAC_65           0x1568

#define MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT 16
#define MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK (0xf<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT)
#define MAC_TRAFFIC_CLASS_ARRANGEMENT(x) (((x)<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT) & MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK)
#define LOCAL_CONFIG_LINK_STATUS_IRQ_EN (1<<24)
#define LOCAL_CONFIG_CON_LO_IRQ_EN (1<<23)
#define LOCAL_CONFIG_CON_HI_IRQ_EN (1<<22)
#define LOCAL_CONFIG_IND_LO_IRQ_EN (1<<21)
#define LOCAL_CONFIG_IND_HI_IRQ_EN (1<<20)

#define CARDNAME "netx-eth"

/* LSB must be zero */
#define INTERNAL_PHY_ADR 0x1c

struct netx_eth_priv {
	void                    __iomem *sram_base, *xpec_base, *xmac_base;
	int                     id;
	struct net_device_stats stats;
	struct mii_if_info      mii;
	u32                     msg_enable;
	struct xc               *xc;
	spinlock_t              lock;
};

static void netx_eth_set_multicast_list(struct net_device *ndev)
{
	/* implement me */
}

static int
netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);
	unsigned char *buf = skb->data;
	unsigned int len = skb->len;

	spin_lock_irq(&priv->lock);
	memcpy_toio(priv->sram_base + 1560, (void *)buf, len);
	if (len < 60) {
		memset_io(priv->sram_base + 1560 + len, 0, 60 - len);
		len = 60;
	}

	pfifo_push(REQ_FIFO_PORT_LO(priv->id),
	           FIFO_PTR_SEGMENT(priv->id) |
	           FIFO_PTR_FRAMENO(1) |
	           FIFO_PTR_FRAMELEN(len));

	ndev->trans_start = jiffies;
	priv->stats.tx_packets++;
	priv->stats.tx_bytes += skb->len;

	netif_stop_queue(ndev);
	spin_unlock_irq(&priv->lock);
	dev_kfree_skb(skb);

	return 0;
}

static void netx_eth_receive(struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);
	unsigned int val, frameno, seg, len;
	unsigned char *data;
	struct sk_buff *skb;

	val = pfifo_pop(IND_FIFO_PORT_LO(priv->id));

	frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT;
	seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT;
	len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT;

	skb = dev_alloc_skb(len);
	if (unlikely(skb == NULL)) {
		printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
			ndev->name);
		priv->stats.rx_dropped++;
		return;
	}

	data = skb_put(skb, len);

	memcpy_fromio(data, priv->sram_base + frameno * 1560, len);

	pfifo_push(EMPTY_PTR_FIFO(priv->id),
		FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno));

	ndev->last_rx = jiffies;
	skb->protocol = eth_type_trans(skb, ndev);
	netif_rx(skb);
	priv->stats.rx_packets++;
	priv->stats.rx_bytes += len;
}

static irqreturn_t
netx_eth_interrupt(int irq, void *dev_id)
{
	struct net_device *ndev = dev_id;
	struct netx_eth_priv *priv = netdev_priv(ndev);
	int status;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
	while (status) {
		int fill_level;
		writel(status, NETX_PFIFO_XPEC_ISR(priv->id));

		if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
			printk("%s: unexpected status: 0x%08x\n",
			    __FUNCTION__, status);

		fill_level =
		    readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
		while (fill_level--)
			netx_eth_receive(ndev);

		if (status & ISR_CON_LO)
			netif_wake_queue(ndev);

		if (status & ISR_LINK_STATUS_CHANGE)
			mii_check_media(&priv->mii, netif_msg_link(priv), 1);

		status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
	}
	spin_unlock_irqrestore(&priv->lock, flags);
	return IRQ_HANDLED;
}

static struct net_device_stats *netx_eth_query_statistics(struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);
	return &priv->stats;
}

static int netx_eth_open(struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);

	if (request_irq
	    (ndev->irq, &netx_eth_interrupt, IRQF_SHARED, ndev->name, ndev))
		return -EAGAIN;

	writel(ndev->dev_addr[0] |
	       ndev->dev_addr[1]<<8 |
	       ndev->dev_addr[2]<<16 |
	       ndev->dev_addr[3]<<24,
	       priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
	writel(ndev->dev_addr[4] |
	       ndev->dev_addr[5]<<8,
	       priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_65);

	writel(LOCAL_CONFIG_LINK_STATUS_IRQ_EN |
		LOCAL_CONFIG_CON_LO_IRQ_EN |
		LOCAL_CONFIG_CON_HI_IRQ_EN |
		LOCAL_CONFIG_IND_LO_IRQ_EN |
		LOCAL_CONFIG_IND_HI_IRQ_EN,
		priv->xpec_base + NETX_XPEC_RAM_START_OFS +
		ETH_MAC_LOCAL_CONFIG);

	mii_check_media(&priv->mii, netif_msg_link(priv), 1);
	netif_start_queue(ndev);

	return 0;
}

static int netx_eth_close(struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);

	netif_stop_queue(ndev);

	writel(0,
	    priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_LOCAL_CONFIG);

	free_irq(ndev->irq, ndev);

	return 0;
}

static void netx_eth_timeout(struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);
	int i;

	printk(KERN_ERR "%s: transmit timed out, resetting\n", ndev->name);

	spin_lock_irq(&priv->lock);

	xc_reset(priv->xc);
	xc_start(priv->xc);

	for (i=2; i<=18; i++)
		pfifo_push(EMPTY_PTR_FIFO(priv->id),
			FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));

	spin_unlock_irq(&priv->lock);

	netif_wake_queue(ndev);
}

static int
netx_eth_phy_read(struct net_device *ndev, int phy_id, int reg)
{
	unsigned int val;

	val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
	      MIIMU_REGADDR(reg) | MIIMU_PHY_NRES;

	writel(val, NETX_MIIMU);
	while (readl(NETX_MIIMU) & MIIMU_SNRDY);

	return readl(NETX_MIIMU) >> 16;

}

static void
netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
{
	unsigned int val;

	val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
	      MIIMU_REGADDR(reg) | MIIMU_PHY_NRES | MIIMU_OPMODE_WRITE |
	      MIIMU_DATA(value);

	writel(val, NETX_MIIMU);
	while (readl(NETX_MIIMU) & MIIMU_SNRDY);
}

static int netx_eth_enable(struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);
	unsigned int mac4321, mac65;
	int running, i;

	ether_setup(ndev);

	ndev->open = netx_eth_open;
	ndev->stop = netx_eth_close;
	ndev->hard_start_xmit = netx_eth_hard_start_xmit;
	ndev->tx_timeout = netx_eth_timeout;
	ndev->watchdog_timeo = msecs_to_jiffies(5000);
	ndev->get_stats = netx_eth_query_statistics;
	ndev->set_multicast_list = netx_eth_set_multicast_list;

	priv->msg_enable       = NETIF_MSG_LINK;
	priv->mii.phy_id_mask  = 0x1f;
	priv->mii.reg_num_mask = 0x1f;
	priv->mii.force_media  = 0;
	priv->mii.full_duplex  = 0;
	priv->mii.dev	     = ndev;
	priv->mii.mdio_read    = netx_eth_phy_read;
	priv->mii.mdio_write   = netx_eth_phy_write;
	priv->mii.phy_id = INTERNAL_PHY_ADR + priv->id;

	running = xc_running(priv->xc);
	xc_stop(priv->xc);

	/* if the xc engine is already running, assume the bootloader has
	 * loaded the firmware for us
	 */
	if (running) {
		/* get Node Address from hardware */
		mac4321 = readl(priv->xpec_base +
			NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
		mac65 = readl(priv->xpec_base +
			NETX_XPEC_RAM_START_OFS + ETH_MAC_65);

		ndev->dev_addr[0] = mac4321 & 0xff;
		ndev->dev_addr[1] = (mac4321 >> 8) & 0xff;
		ndev->dev_addr[2] = (mac4321 >> 16) & 0xff;
		ndev->dev_addr[3] = (mac4321 >> 24) & 0xff;
		ndev->dev_addr[4] = mac65 & 0xff;
		ndev->dev_addr[5] = (mac65 >> 8) & 0xff;
	} else {
		if (xc_request_firmware(priv->xc)) {
			printk(CARDNAME ": requesting firmware failed\n");
			return -ENODEV;
		}
	}

	xc_reset(priv->xc);
	xc_start(priv->xc);

	if (!is_valid_ether_addr(ndev->dev_addr))
		printk("%s: Invalid ethernet MAC address.  Please "
		       "set using ifconfig\n", ndev->name);

	for (i=2; i<=18; i++)
		pfifo_push(EMPTY_PTR_FIFO(priv->id),
			FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));

	return register_netdev(ndev);

}

static int netx_eth_drv_probe(struct platform_device *pdev)
{
	struct netx_eth_priv *priv;
	struct net_device *ndev;
	struct netxeth_platform_data *pdata;
	int ret;

	ndev = alloc_etherdev(sizeof (struct netx_eth_priv));
	if (!ndev) {
		printk("%s: could not allocate device.\n", CARDNAME);
		ret = -ENOMEM;
		goto exit;
	}
	SET_NETDEV_DEV(ndev, &pdev->dev);

	platform_set_drvdata(pdev, ndev);

	priv = netdev_priv(ndev);

	pdata = (struct netxeth_platform_data *)pdev->dev.platform_data;
	priv->xc = request_xc(pdata->xcno, &pdev->dev);
	if (!priv->xc) {
		dev_err(&pdev->dev, "unable to request xc engine\n");
		ret = -ENODEV;
		goto exit_free_netdev;
	}

	ndev->irq = priv->xc->irq;
	priv->id = pdev->id;
	priv->xpec_base = priv->xc->xpec_base;
	priv->xmac_base = priv->xc->xmac_base;
	priv->sram_base = priv->xc->sram_base;

	ret = pfifo_request(PFIFO_MASK(priv->id));
	if (ret) {
		printk("unable to request PFIFO\n");
		goto exit_free_xc;
	}

	ret = netx_eth_enable(ndev);
	if (ret)
		goto exit_free_pfifo;

	return 0;
exit_free_pfifo:
	pfifo_free(PFIFO_MASK(priv->id));
exit_free_xc:
	free_xc(priv->xc);
exit_free_netdev:
	platform_set_drvdata(pdev, NULL);
	free_netdev(ndev);
exit:
	return ret;
}

static int netx_eth_drv_remove(struct platform_device *pdev)
{
	struct net_device *ndev = dev_get_drvdata(&pdev->dev);
	struct netx_eth_priv *priv = netdev_priv(ndev);

	platform_set_drvdata(pdev, NULL);

	unregister_netdev(ndev);
	xc_stop(priv->xc);
	free_xc(priv->xc);
	free_netdev(ndev);
	pfifo_free(PFIFO_MASK(priv->id));

	return 0;
}

static int netx_eth_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
	dev_err(&pdev->dev, "suspend not implemented\n");
	return 0;
}

static int netx_eth_drv_resume(struct platform_device *pdev)
{
	dev_err(&pdev->dev, "resume not implemented\n");
	return 0;
}

static struct platform_driver netx_eth_driver = {
	.probe		= netx_eth_drv_probe,
	.remove		= netx_eth_drv_remove,
	.suspend	= netx_eth_drv_suspend,
	.resume		= netx_eth_drv_resume,
	.driver		= {
		.name	= CARDNAME,
		.owner	= THIS_MODULE,
	},
};

static int __init netx_eth_init(void)
{
	unsigned int phy_control, val;

	printk("NetX Ethernet driver\n");

	phy_control = PHY_CONTROL_PHY_ADDRESS(INTERNAL_PHY_ADR>>1) |
		      PHY_CONTROL_PHY1_MODE(PHY_MODE_ALL) |
		      PHY_CONTROL_PHY1_AUTOMDIX |
		      PHY_CONTROL_PHY1_EN |
		      PHY_CONTROL_PHY0_MODE(PHY_MODE_ALL) |
		      PHY_CONTROL_PHY0_AUTOMDIX |
		      PHY_CONTROL_PHY0_EN |
		      PHY_CONTROL_CLK_XLATIN;

	val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
	writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);

	writel(phy_control | PHY_CONTROL_RESET, NETX_SYSTEM_PHY_CONTROL);
	udelay(100);

	val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
	writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);

	writel(phy_control, NETX_SYSTEM_PHY_CONTROL);

	return platform_driver_register(&netx_eth_driver);
}

static void __exit netx_eth_cleanup(void)
{
	platform_driver_unregister(&netx_eth_driver);
}

module_init(netx_eth_init);
module_exit(netx_eth_cleanup);

MODULE_AUTHOR("Sascha Hauer, Pengutronix");
MODULE_LICENSE("GPL");

