/*
 * Ethernet driver for the Atmel AT91RM9200 (Thunder)
 *
 *  Copyright (C) 2003 SAN People (Pty) Ltd
 *
 * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
 * Initial version by Rick Bronson 01/11/2003
 *
 * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker
 *   (Polaroid Corporation)
 *
 * Realtek RTL8201(B)L PHY support by Roman Avramenko <roman@imsystems.ru>
 *
 * 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/init.h>
#include <linux/mii.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/dma-mapping.h>
#include <linux/ethtool.h>
#include <linux/platform_device.h>
#include <linux/clk.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/mach-types.h>

#include <mach/at91rm9200_emac.h>
#include <mach/gpio.h>
#include <mach/board.h>

#include "at91_ether.h"

#define DRV_NAME	"at91_ether"
#define DRV_VERSION	"1.0"

#define LINK_POLL_INTERVAL	(HZ)

/* ..................................................................... */

/*
 * Read from a EMAC register.
 */
static inline unsigned long at91_emac_read(unsigned int reg)
{
	void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC;

	return __raw_readl(emac_base + reg);
}

/*
 * Write to a EMAC register.
 */
static inline void at91_emac_write(unsigned int reg, unsigned long value)
{
	void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC;

	__raw_writel(value, emac_base + reg);
}

/* ........................... PHY INTERFACE ........................... */

/*
 * Enable the MDIO bit in MAC control register
 * When not called from an interrupt-handler, access to the PHY must be
 *  protected by a spinlock.
 */
static void enable_mdi(void)
{
	unsigned long ctl;

	ctl = at91_emac_read(AT91_EMAC_CTL);
	at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_MPE);	/* enable management port */
}

/*
 * Disable the MDIO bit in the MAC control register
 */
static void disable_mdi(void)
{
	unsigned long ctl;

	ctl = at91_emac_read(AT91_EMAC_CTL);
	at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_MPE);	/* disable management port */
}

/*
 * Wait until the PHY operation is complete.
 */
static inline void at91_phy_wait(void) {
	unsigned long timeout = jiffies + 2;

	while (!(at91_emac_read(AT91_EMAC_SR) & AT91_EMAC_SR_IDLE)) {
		if (time_after(jiffies, timeout)) {
			printk("at91_ether: MIO timeout\n");
			break;
		}
		cpu_relax();
	}
}

/*
 * Write value to the a PHY register
 * Note: MDI interface is assumed to already have been enabled.
 */
static void write_phy(unsigned char phy_addr, unsigned char address, unsigned int value)
{
	at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_W
		| ((phy_addr & 0x1f) << 23) | (address << 18) | (value & AT91_EMAC_DATA));

	/* Wait until IDLE bit in Network Status register is cleared */
	at91_phy_wait();
}

/*
 * Read value stored in a PHY register.
 * Note: MDI interface is assumed to already have been enabled.
 */
static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int *value)
{
	at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_R
		| ((phy_addr & 0x1f) << 23) | (address << 18));

	/* Wait until IDLE bit in Network Status register is cleared */
	at91_phy_wait();

	*value = at91_emac_read(AT91_EMAC_MAN) & AT91_EMAC_DATA;
}

/* ........................... PHY MANAGEMENT .......................... */

/*
 * Access the PHY to determine the current link speed and mode, and update the
 * MAC accordingly.
 * If no link or auto-negotiation is busy, then no changes are made.
 */
static void update_linkspeed(struct net_device *dev, int silent)
{
	struct at91_private *lp = netdev_priv(dev);
	unsigned int bmsr, bmcr, lpa, mac_cfg;
	unsigned int speed, duplex;

	if (!mii_link_ok(&lp->mii)) {		/* no link */
		netif_carrier_off(dev);
		if (!silent)
			printk(KERN_INFO "%s: Link down.\n", dev->name);
		return;
	}

	/* Link up, or auto-negotiation still in progress */
	read_phy(lp->phy_address, MII_BMSR, &bmsr);
	read_phy(lp->phy_address, MII_BMCR, &bmcr);
	if (bmcr & BMCR_ANENABLE) {				/* AutoNegotiation is enabled */
		if (!(bmsr & BMSR_ANEGCOMPLETE))
			return;			/* Do nothing - another interrupt generated when negotiation complete */

		read_phy(lp->phy_address, MII_LPA, &lpa);
		if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100;
		else speed = SPEED_10;
		if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL;
		else duplex = DUPLEX_HALF;
	} else {
		speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
		duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
	}

	/* Update the MAC */
	mac_cfg = at91_emac_read(AT91_EMAC_CFG) & ~(AT91_EMAC_SPD | AT91_EMAC_FD);
	if (speed == SPEED_100) {
		if (duplex == DUPLEX_FULL)		/* 100 Full Duplex */
			mac_cfg |= AT91_EMAC_SPD | AT91_EMAC_FD;
		else					/* 100 Half Duplex */
			mac_cfg |= AT91_EMAC_SPD;
	} else {
		if (duplex == DUPLEX_FULL)		/* 10 Full Duplex */
			mac_cfg |= AT91_EMAC_FD;
		else {}					/* 10 Half Duplex */
	}
	at91_emac_write(AT91_EMAC_CFG, mac_cfg);

	if (!silent)
		printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
	netif_carrier_on(dev);
}

/*
 * Handle interrupts from the PHY
 */
static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = (struct net_device *) dev_id;
	struct at91_private *lp = netdev_priv(dev);
	unsigned int phy;

	/*
	 * This hander is triggered on both edges, but the PHY chips expect
	 * level-triggering.  We therefore have to check if the PHY actually has
	 * an IRQ pending.
	 */
	enable_mdi();
	if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {
		read_phy(lp->phy_address, MII_DSINTR_REG, &phy);	/* ack interrupt in Davicom PHY */
		if (!(phy & (1 << 0)))
			goto done;
	}
	else if (lp->phy_type == MII_LXT971A_ID) {
		read_phy(lp->phy_address, MII_ISINTS_REG, &phy);	/* ack interrupt in Intel PHY */
		if (!(phy & (1 << 2)))
			goto done;
	}
	else if (lp->phy_type == MII_BCM5221_ID) {
		read_phy(lp->phy_address, MII_BCMINTR_REG, &phy);	/* ack interrupt in Broadcom PHY */
		if (!(phy & (1 << 0)))
			goto done;
	}
	else if (lp->phy_type == MII_KS8721_ID) {
		read_phy(lp->phy_address, MII_TPISTATUS, &phy);		/* ack interrupt in Micrel PHY */
		if (!(phy & ((1 << 2) | 1)))
			goto done;
	}
	else if (lp->phy_type == MII_T78Q21x3_ID) {			/* ack interrupt in Teridian PHY */
		read_phy(lp->phy_address, MII_T78Q21INT_REG, &phy);
		if (!(phy & ((1 << 2) | 1)))
			goto done;
	}
	else if (lp->phy_type == MII_DP83848_ID) {
		read_phy(lp->phy_address, MII_DPPHYSTS_REG, &phy);	/* ack interrupt in DP83848 PHY */
		if (!(phy & (1 << 7)))
			goto done;
	}

	update_linkspeed(dev, 0);

done:
	disable_mdi();

	return IRQ_HANDLED;
}

/*
 * Initialize and enable the PHY interrupt for link-state changes
 */
static void enable_phyirq(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	unsigned int dsintr, irq_number;
	int status;

	irq_number = lp->board_data.phy_irq_pin;
	if (!irq_number) {
		/*
		 * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L),
		 * or board does not have it connected.
		 */
		mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL);
		return;
	}

	status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev);
	if (status) {
		printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status);
		return;
	}

	spin_lock_irq(&lp->lock);
	enable_mdi();

	if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {	/* for Davicom PHY */
		read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr);
		dsintr = dsintr & ~0xf00;		/* clear bits 8..11 */
		write_phy(lp->phy_address, MII_DSINTR_REG, dsintr);
	}
	else if (lp->phy_type == MII_LXT971A_ID) {	/* for Intel PHY */
		read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr);
		dsintr = dsintr | 0xf2;			/* set bits 1, 4..7 */
		write_phy(lp->phy_address, MII_ISINTE_REG, dsintr);
	}
	else if (lp->phy_type == MII_BCM5221_ID) {	/* for Broadcom PHY */
		dsintr = (1 << 15) | ( 1 << 14);
		write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr);
	}
	else if (lp->phy_type == MII_KS8721_ID) {	/* for Micrel PHY */
		dsintr = (1 << 10) | ( 1 << 8);
		write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
	}
	else if (lp->phy_type == MII_T78Q21x3_ID) {	/* for Teridian PHY */
		read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
		dsintr = dsintr | 0x500;		/* set bits 8, 10 */
		write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
	}
	else if (lp->phy_type == MII_DP83848_ID) {	/* National Semiconductor DP83848 PHY */
		read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
		dsintr = dsintr | 0x3c;			/* set bits 2..5 */
		write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
		read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
		dsintr = dsintr | 0x3;			/* set bits 0,1 */
		write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
	}

	disable_mdi();
	spin_unlock_irq(&lp->lock);
}

/*
 * Disable the PHY interrupt
 */
static void disable_phyirq(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	unsigned int dsintr;
	unsigned int irq_number;

	irq_number = lp->board_data.phy_irq_pin;
	if (!irq_number) {
		del_timer_sync(&lp->check_timer);
		return;
	}

	spin_lock_irq(&lp->lock);
	enable_mdi();

	if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {	/* for Davicom PHY */
		read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr);
		dsintr = dsintr | 0xf00;			/* set bits 8..11 */
		write_phy(lp->phy_address, MII_DSINTR_REG, dsintr);
	}
	else if (lp->phy_type == MII_LXT971A_ID) {	/* for Intel PHY */
		read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr);
		dsintr = dsintr & ~0xf2;			/* clear bits 1, 4..7 */
		write_phy(lp->phy_address, MII_ISINTE_REG, dsintr);
	}
	else if (lp->phy_type == MII_BCM5221_ID) {	/* for Broadcom PHY */
		read_phy(lp->phy_address, MII_BCMINTR_REG, &dsintr);
		dsintr = ~(1 << 14);
		write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr);
	}
	else if (lp->phy_type == MII_KS8721_ID) {	/* for Micrel PHY */
		read_phy(lp->phy_address, MII_TPISTATUS, &dsintr);
		dsintr = ~((1 << 10) | (1 << 8));
		write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
	}
	else if (lp->phy_type == MII_T78Q21x3_ID) {	/* for Teridian PHY */
		read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
		dsintr = dsintr & ~0x500;			/* clear bits 8, 10 */
		write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
	}
	else if (lp->phy_type == MII_DP83848_ID) {	/* National Semiconductor DP83848 PHY */
		read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
		dsintr = dsintr & ~0x3;				/* clear bits 0, 1 */
		write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
		read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
		dsintr = dsintr & ~0x3c;			/* clear bits 2..5 */
		write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
	}

	disable_mdi();
	spin_unlock_irq(&lp->lock);

	free_irq(irq_number, dev);			/* Free interrupt handler */
}

/*
 * Perform a software reset of the PHY.
 */
#if 0
static void reset_phy(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	unsigned int bmcr;

	spin_lock_irq(&lp->lock);
	enable_mdi();

	/* Perform PHY reset */
	write_phy(lp->phy_address, MII_BMCR, BMCR_RESET);

	/* Wait until PHY reset is complete */
	do {
		read_phy(lp->phy_address, MII_BMCR, &bmcr);
	} while (!(bmcr & BMCR_RESET));

	disable_mdi();
	spin_unlock_irq(&lp->lock);
}
#endif

static void at91ether_check_link(unsigned long dev_id)
{
	struct net_device *dev = (struct net_device *) dev_id;
	struct at91_private *lp = netdev_priv(dev);

	enable_mdi();
	update_linkspeed(dev, 1);
	disable_mdi();

	mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL);
}

/* ......................... ADDRESS MANAGEMENT ........................ */

/*
 * NOTE: Your bootloader must always set the MAC address correctly before
 * booting into Linux.
 *
 * - It must always set the MAC address after reset, even if it doesn't
 *   happen to access the Ethernet while it's booting.  Some versions of
 *   U-Boot on the AT91RM9200-DK do not do this.
 *
 * - Likewise it must store the addresses in the correct byte order.
 *   MicroMonitor (uMon) on the CSB337 does this incorrectly (and
 *   continues to do so, for bug-compatibility).
 */

static short __init unpack_mac_address(struct net_device *dev, unsigned int hi, unsigned int lo)
{
	char addr[6];

	if (machine_is_csb337()) {
		addr[5] = (lo & 0xff);			/* The CSB337 bootloader stores the MAC the wrong-way around */
		addr[4] = (lo & 0xff00) >> 8;
		addr[3] = (lo & 0xff0000) >> 16;
		addr[2] = (lo & 0xff000000) >> 24;
		addr[1] = (hi & 0xff);
		addr[0] = (hi & 0xff00) >> 8;
	}
	else {
		addr[0] = (lo & 0xff);
		addr[1] = (lo & 0xff00) >> 8;
		addr[2] = (lo & 0xff0000) >> 16;
		addr[3] = (lo & 0xff000000) >> 24;
		addr[4] = (hi & 0xff);
		addr[5] = (hi & 0xff00) >> 8;
	}

	if (is_valid_ether_addr(addr)) {
		memcpy(dev->dev_addr, &addr, 6);
		return 1;
	}
	return 0;
}

/*
 * Set the ethernet MAC address in dev->dev_addr
 */
static void __init get_mac_address(struct net_device *dev)
{
	/* Check Specific-Address 1 */
	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA1H), at91_emac_read(AT91_EMAC_SA1L)))
		return;
	/* Check Specific-Address 2 */
	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA2H), at91_emac_read(AT91_EMAC_SA2L)))
		return;
	/* Check Specific-Address 3 */
	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA3H), at91_emac_read(AT91_EMAC_SA3L)))
		return;
	/* Check Specific-Address 4 */
	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA4H), at91_emac_read(AT91_EMAC_SA4L)))
		return;

	printk(KERN_ERR "at91_ether: Your bootloader did not configure a MAC address.\n");
}

/*
 * Program the hardware MAC address from dev->dev_addr.
 */
static void update_mac_address(struct net_device *dev)
{
	at91_emac_write(AT91_EMAC_SA1L, (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) | (dev->dev_addr[1] << 8) | (dev->dev_addr[0]));
	at91_emac_write(AT91_EMAC_SA1H, (dev->dev_addr[5] << 8) | (dev->dev_addr[4]));

	at91_emac_write(AT91_EMAC_SA2L, 0);
	at91_emac_write(AT91_EMAC_SA2H, 0);
}

/*
 * Store the new hardware address in dev->dev_addr, and update the MAC.
 */
static int set_mac_address(struct net_device *dev, void* addr)
{
	struct sockaddr *address = addr;

	if (!is_valid_ether_addr(address->sa_data))
		return -EADDRNOTAVAIL;

	memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
	update_mac_address(dev);

	printk("%s: Setting MAC address to %pM\n", dev->name,
	       dev->dev_addr);

	return 0;
}

static int inline hash_bit_value(int bitnr, __u8 *addr)
{
	if (addr[bitnr / 8] & (1 << (bitnr % 8)))
		return 1;
	return 0;
}

/*
 * The hash address register is 64 bits long and takes up two locations in the memory map.
 * The least significant bits are stored in EMAC_HSL and the most significant
 * bits in EMAC_HSH.
 *
 * The unicast hash enable and the multicast hash enable bits in the network configuration
 *  register enable the reception of hash matched frames. The destination address is
 *  reduced to a 6 bit index into the 64 bit hash register using the following hash function.
 * The hash function is an exclusive or of every sixth bit of the destination address.
 *   hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
 *   hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
 *   hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
 *   hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
 *   hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
 *   hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
 * da[0] represents the least significant bit of the first byte received, that is, the multicast/
 *  unicast indicator, and da[47] represents the most significant bit of the last byte
 *  received.
 * If the hash index points to a bit that is set in the hash register then the frame will be
 *  matched according to whether the frame is multicast or unicast.
 * A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and
 *  the hash index points to a bit set in the hash register.
 * A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the
 *  hash index points to a bit set in the hash register.
 * To receive all multicast frames, the hash register should be set with all ones and the
 *  multicast hash enable bit should be set in the network configuration register.
 */

/*
 * Return the hash index value for the specified address.
 */
static int hash_get_index(__u8 *addr)
{
	int i, j, bitval;
	int hash_index = 0;

	for (j = 0; j < 6; j++) {
		for (i = 0, bitval = 0; i < 8; i++)
			bitval ^= hash_bit_value(i*6 + j, addr);

		hash_index |= (bitval << j);
	}

	return hash_index;
}

/*
 * Add multicast addresses to the internal multicast-hash table.
 */
static void at91ether_sethashtable(struct net_device *dev)
{
	struct dev_mc_list *curr;
	unsigned long mc_filter[2];
	unsigned int i, bitnr;

	mc_filter[0] = mc_filter[1] = 0;

	curr = dev->mc_list;
	for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
		if (!curr) break;	/* unexpected end of list */

		bitnr = hash_get_index(curr->dmi_addr);
		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
	}

	at91_emac_write(AT91_EMAC_HSL, mc_filter[0]);
	at91_emac_write(AT91_EMAC_HSH, mc_filter[1]);
}

/*
 * Enable/Disable promiscuous and multicast modes.
 */
static void at91ether_set_rx_mode(struct net_device *dev)
{
	unsigned long cfg;

	cfg = at91_emac_read(AT91_EMAC_CFG);

	if (dev->flags & IFF_PROMISC)			/* Enable promiscuous mode */
		cfg |= AT91_EMAC_CAF;
	else if (dev->flags & (~IFF_PROMISC))		/* Disable promiscuous mode */
		cfg &= ~AT91_EMAC_CAF;

	if (dev->flags & IFF_ALLMULTI) {		/* Enable all multicast mode */
		at91_emac_write(AT91_EMAC_HSH, -1);
		at91_emac_write(AT91_EMAC_HSL, -1);
		cfg |= AT91_EMAC_MTI;
	} else if (dev->mc_count > 0) {			/* Enable specific multicasts */
		at91ether_sethashtable(dev);
		cfg |= AT91_EMAC_MTI;
	} else if (dev->flags & (~IFF_ALLMULTI)) {	/* Disable all multicast mode */
		at91_emac_write(AT91_EMAC_HSH, 0);
		at91_emac_write(AT91_EMAC_HSL, 0);
		cfg &= ~AT91_EMAC_MTI;
	}

	at91_emac_write(AT91_EMAC_CFG, cfg);
}

/* ......................... ETHTOOL SUPPORT ........................... */

static int mdio_read(struct net_device *dev, int phy_id, int location)
{
	unsigned int value;

	read_phy(phy_id, location, &value);
	return value;
}

static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
	write_phy(phy_id, location, value);
}

static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct at91_private *lp = netdev_priv(dev);
	int ret;

	spin_lock_irq(&lp->lock);
	enable_mdi();

	ret = mii_ethtool_gset(&lp->mii, cmd);

	disable_mdi();
	spin_unlock_irq(&lp->lock);

	if (lp->phy_media == PORT_FIBRE) {		/* override media type since mii.c doesn't know */
		cmd->supported = SUPPORTED_FIBRE;
		cmd->port = PORT_FIBRE;
	}

	return ret;
}

static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct at91_private *lp = netdev_priv(dev);
	int ret;

	spin_lock_irq(&lp->lock);
	enable_mdi();

	ret = mii_ethtool_sset(&lp->mii, cmd);

	disable_mdi();
	spin_unlock_irq(&lp->lock);

	return ret;
}

static int at91ether_nwayreset(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	int ret;

	spin_lock_irq(&lp->lock);
	enable_mdi();

	ret = mii_nway_restart(&lp->mii);

	disable_mdi();
	spin_unlock_irq(&lp->lock);

	return ret;
}

static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
	strlcpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}

static const struct ethtool_ops at91ether_ethtool_ops = {
	.get_settings	= at91ether_get_settings,
	.set_settings	= at91ether_set_settings,
	.get_drvinfo	= at91ether_get_drvinfo,
	.nway_reset	= at91ether_nwayreset,
	.get_link	= ethtool_op_get_link,
};

static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
	struct at91_private *lp = netdev_priv(dev);
	int res;

	if (!netif_running(dev))
		return -EINVAL;

	spin_lock_irq(&lp->lock);
	enable_mdi();
	res = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL);
	disable_mdi();
	spin_unlock_irq(&lp->lock);

	return res;
}

/* ................................ MAC ................................ */

/*
 * Initialize and start the Receiver and Transmit subsystems
 */
static void at91ether_start(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	struct recv_desc_bufs *dlist, *dlist_phys;
	int i;
	unsigned long ctl;

	dlist = lp->dlist;
	dlist_phys = lp->dlist_phys;

	for (i = 0; i < MAX_RX_DESCR; i++) {
		dlist->descriptors[i].addr = (unsigned int) &dlist_phys->recv_buf[i][0];
		dlist->descriptors[i].size = 0;
	}

	/* Set the Wrap bit on the last descriptor */
	dlist->descriptors[i-1].addr |= EMAC_DESC_WRAP;

	/* Reset buffer index */
	lp->rxBuffIndex = 0;

	/* Program address of descriptor list in Rx Buffer Queue register */
	at91_emac_write(AT91_EMAC_RBQP, (unsigned long) dlist_phys);

	/* Enable Receive and Transmit */
	ctl = at91_emac_read(AT91_EMAC_CTL);
	at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE | AT91_EMAC_TE);
}

/*
 * Open the ethernet interface
 */
static int at91ether_open(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	unsigned long ctl;

	if (!is_valid_ether_addr(dev->dev_addr))
		return -EADDRNOTAVAIL;

	clk_enable(lp->ether_clk);		/* Re-enable Peripheral clock */

	/* Clear internal statistics */
	ctl = at91_emac_read(AT91_EMAC_CTL);
	at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_CSR);

	/* Update the MAC address (incase user has changed it) */
	update_mac_address(dev);

	/* Enable PHY interrupt */
	enable_phyirq(dev);

	/* Enable MAC interrupts */
	at91_emac_write(AT91_EMAC_IER, AT91_EMAC_RCOM | AT91_EMAC_RBNA
				| AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM
				| AT91_EMAC_ROVR | AT91_EMAC_ABT);

	/* Determine current link speed */
	spin_lock_irq(&lp->lock);
	enable_mdi();
	update_linkspeed(dev, 0);
	disable_mdi();
	spin_unlock_irq(&lp->lock);

	at91ether_start(dev);
	netif_start_queue(dev);
	return 0;
}

/*
 * Close the interface
 */
static int at91ether_close(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	unsigned long ctl;

	/* Disable Receiver and Transmitter */
	ctl = at91_emac_read(AT91_EMAC_CTL);
	at91_emac_write(AT91_EMAC_CTL, ctl & ~(AT91_EMAC_TE | AT91_EMAC_RE));

	/* Disable PHY interrupt */
	disable_phyirq(dev);

	/* Disable MAC interrupts */
	at91_emac_write(AT91_EMAC_IDR, AT91_EMAC_RCOM | AT91_EMAC_RBNA
				| AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM
				| AT91_EMAC_ROVR | AT91_EMAC_ABT);

	netif_stop_queue(dev);

	clk_disable(lp->ether_clk);		/* Disable Peripheral clock */

	return 0;
}

/*
 * Transmit packet.
 */
static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);

	if (at91_emac_read(AT91_EMAC_TSR) & AT91_EMAC_TSR_BNQ) {
		netif_stop_queue(dev);

		/* Store packet information (to free when Tx completed) */
		lp->skb = skb;
		lp->skb_length = skb->len;
		lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
		dev->stats.tx_bytes += skb->len;

		/* Set address of the data in the Transmit Address register */
		at91_emac_write(AT91_EMAC_TAR, lp->skb_physaddr);
		/* Set length of the packet in the Transmit Control register */
		at91_emac_write(AT91_EMAC_TCR, skb->len);

		dev->trans_start = jiffies;
	} else {
		printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n");
		return 1;	/* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
				on this skb, he also reports -ENETDOWN and printk's, so either
				we free and return(0) or don't free and return 1 */
	}

	return 0;
}

/*
 * Update the current statistics from the internal statistics registers.
 */
static struct net_device_stats *at91ether_stats(struct net_device *dev)
{
	int ale, lenerr, seqe, lcol, ecol;

	if (netif_running(dev)) {
		dev->stats.rx_packets += at91_emac_read(AT91_EMAC_OK);		/* Good frames received */
		ale = at91_emac_read(AT91_EMAC_ALE);
		dev->stats.rx_frame_errors += ale;				/* Alignment errors */
		lenerr = at91_emac_read(AT91_EMAC_ELR) + at91_emac_read(AT91_EMAC_USF);
		dev->stats.rx_length_errors += lenerr;				/* Excessive Length or Undersize Frame error */
		seqe = at91_emac_read(AT91_EMAC_SEQE);
		dev->stats.rx_crc_errors += seqe;				/* CRC error */
		dev->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC);	/* Receive buffer not available */
		dev->stats.rx_errors += (ale + lenerr + seqe
			+ at91_emac_read(AT91_EMAC_CDE) + at91_emac_read(AT91_EMAC_RJB));

		dev->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA);		/* Frames successfully transmitted */
		dev->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE);	/* Transmit FIFO underruns */
		dev->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE);	/* Carrier Sense errors */
		dev->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */

		lcol = at91_emac_read(AT91_EMAC_LCOL);
		ecol = at91_emac_read(AT91_EMAC_ECOL);
		dev->stats.tx_window_errors += lcol;			/* Late collisions */
		dev->stats.tx_aborted_errors += ecol;			/* 16 collisions */

		dev->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol);
	}
	return &dev->stats;
}

/*
 * Extract received frame from buffer descriptors and sent to upper layers.
 * (Called from interrupt context)
 */
static void at91ether_rx(struct net_device *dev)
{
	struct at91_private *lp = netdev_priv(dev);
	struct recv_desc_bufs *dlist;
	unsigned char *p_recv;
	struct sk_buff *skb;
	unsigned int pktlen;

	dlist = lp->dlist;
	while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) {
		p_recv = dlist->recv_buf[lp->rxBuffIndex];
		pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff;	/* Length of frame including FCS */
		skb = dev_alloc_skb(pktlen + 2);
		if (skb != NULL) {
			skb_reserve(skb, 2);
			memcpy(skb_put(skb, pktlen), p_recv, pktlen);

			skb->protocol = eth_type_trans(skb, dev);
			dev->stats.rx_bytes += pktlen;
			netif_rx(skb);
		}
		else {
			dev->stats.rx_dropped += 1;
			printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
		}

		if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST)
			dev->stats.multicast++;

		dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE;	/* reset ownership bit */
		if (lp->rxBuffIndex == MAX_RX_DESCR-1)				/* wrap after last buffer */
			lp->rxBuffIndex = 0;
		else
			lp->rxBuffIndex++;
	}
}

/*
 * MAC interrupt handler
 */
static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = (struct net_device *) dev_id;
	struct at91_private *lp = netdev_priv(dev);
	unsigned long intstatus, ctl;

	/* MAC Interrupt Status register indicates what interrupts are pending.
	   It is automatically cleared once read. */
	intstatus = at91_emac_read(AT91_EMAC_ISR);

	if (intstatus & AT91_EMAC_RCOM)		/* Receive complete */
		at91ether_rx(dev);

	if (intstatus & AT91_EMAC_TCOM) {	/* Transmit complete */
		/* The TCOM bit is set even if the transmission failed. */
		if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY))
			dev->stats.tx_errors += 1;

		if (lp->skb) {
			dev_kfree_skb_irq(lp->skb);
			lp->skb = NULL;
			dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE);
		}
		netif_wake_queue(dev);
	}

	/* Work-around for Errata #11 */
	if (intstatus & AT91_EMAC_RBNA) {
		ctl = at91_emac_read(AT91_EMAC_CTL);
		at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_RE);
		at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE);
	}

	if (intstatus & AT91_EMAC_ROVR)
		printk("%s: ROVR error\n", dev->name);

	return IRQ_HANDLED;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void at91ether_poll_controller(struct net_device *dev)
{
	unsigned long flags;

	local_irq_save(flags);
	at91ether_interrupt(dev->irq, dev);
	local_irq_restore(flags);
}
#endif

/*
 * Initialize the ethernet interface
 */
static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address,
			struct platform_device *pdev, struct clk *ether_clk)
{
	struct at91_eth_data *board_data = pdev->dev.platform_data;
	struct net_device *dev;
	struct at91_private *lp;
	unsigned int val;
	int res;

	dev = alloc_etherdev(sizeof(struct at91_private));
	if (!dev)
		return -ENOMEM;

	dev->base_addr = AT91_VA_BASE_EMAC;
	dev->irq = AT91RM9200_ID_EMAC;

	/* Install the interrupt handler */
	if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev)) {
		free_netdev(dev);
		return -EBUSY;
	}

	/* Allocate memory for DMA Receive descriptors */
	lp = netdev_priv(dev);
	lp->dlist = (struct recv_desc_bufs *) dma_alloc_coherent(NULL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys, GFP_KERNEL);
	if (lp->dlist == NULL) {
		free_irq(dev->irq, dev);
		free_netdev(dev);
		return -ENOMEM;
	}
	lp->board_data = *board_data;
	lp->ether_clk = ether_clk;
	platform_set_drvdata(pdev, dev);

	spin_lock_init(&lp->lock);

	ether_setup(dev);
	dev->open = at91ether_open;
	dev->stop = at91ether_close;
	dev->hard_start_xmit = at91ether_tx;
	dev->get_stats = at91ether_stats;
	dev->set_multicast_list = at91ether_set_rx_mode;
	dev->set_mac_address = set_mac_address;
	dev->ethtool_ops = &at91ether_ethtool_ops;
	dev->do_ioctl = at91ether_ioctl;
#ifdef CONFIG_NET_POLL_CONTROLLER
	dev->poll_controller = at91ether_poll_controller;
#endif

	SET_NETDEV_DEV(dev, &pdev->dev);

	get_mac_address(dev);		/* Get ethernet address and store it in dev->dev_addr */
	update_mac_address(dev);	/* Program ethernet address into MAC */

	at91_emac_write(AT91_EMAC_CTL, 0);

	if (lp->board_data.is_rmii)
		at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG | AT91_EMAC_RMII);
	else
		at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG);

	/* Perform PHY-specific initialization */
	spin_lock_irq(&lp->lock);
	enable_mdi();
	if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {
		read_phy(phy_address, MII_DSCR_REG, &val);
		if ((val & (1 << 10)) == 0)			/* DSCR bit 10 is 0 -- fiber mode */
			lp->phy_media = PORT_FIBRE;
	} else if (machine_is_csb337()) {
		/* mix link activity status into LED2 link state */
		write_phy(phy_address, MII_LEDCTRL_REG, 0x0d22);
	} else if (machine_is_ecbat91())
		write_phy(phy_address, MII_LEDCTRL_REG, 0x156A);

	disable_mdi();
	spin_unlock_irq(&lp->lock);

	lp->mii.dev = dev;		/* Support for ethtool */
	lp->mii.mdio_read = mdio_read;
	lp->mii.mdio_write = mdio_write;
	lp->mii.phy_id = phy_address;
	lp->mii.phy_id_mask = 0x1f;
	lp->mii.reg_num_mask = 0x1f;

	lp->phy_type = phy_type;	/* Type of PHY connected */
	lp->phy_address = phy_address;	/* MDI address of PHY */

	/* Register the network interface */
	res = register_netdev(dev);
	if (res) {
		free_irq(dev->irq, dev);
		free_netdev(dev);
		dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
		return res;
	}

	/* Determine current link speed */
	spin_lock_irq(&lp->lock);
	enable_mdi();
	update_linkspeed(dev, 0);
	disable_mdi();
	spin_unlock_irq(&lp->lock);
	netif_carrier_off(dev);		/* will be enabled in open() */

	/* If board has no PHY IRQ, use a timer to poll the PHY */
	if (!lp->board_data.phy_irq_pin) {
		init_timer(&lp->check_timer);
		lp->check_timer.data = (unsigned long)dev;
		lp->check_timer.function = at91ether_check_link;
	} else if (lp->board_data.phy_irq_pin >= 32)
		gpio_request(lp->board_data.phy_irq_pin, "ethernet_phy");

	/* Display ethernet banner */
	printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%pM)\n",
	       dev->name, (uint) dev->base_addr, dev->irq,
	       at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-",
	       at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex",
	       dev->dev_addr);
	if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID))
		printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)");
	else if (phy_type == MII_LXT971A_ID)
		printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name);
	else if (phy_type == MII_RTL8201_ID)
		printk(KERN_INFO "%s: Realtek RTL8201(B)L PHY\n", dev->name);
	else if (phy_type == MII_BCM5221_ID)
		printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name);
	else if (phy_type == MII_DP83847_ID)
		printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name);
	else if (phy_type == MII_DP83848_ID)
		printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name);
	else if (phy_type == MII_AC101L_ID)
		printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name);
	else if (phy_type == MII_KS8721_ID)
		printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name);
	else if (phy_type == MII_T78Q21x3_ID)
		printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name);
	else if (phy_type == MII_LAN83C185_ID)
		printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name);

	return 0;
}

/*
 * Detect MAC and PHY and perform initialization
 */
static int __init at91ether_probe(struct platform_device *pdev)
{
	unsigned int phyid1, phyid2;
	int detected = -1;
	unsigned long phy_id;
	unsigned short phy_address = 0;
	struct clk *ether_clk;

	ether_clk = clk_get(&pdev->dev, "ether_clk");
	if (IS_ERR(ether_clk)) {
		printk(KERN_ERR "at91_ether: no clock defined\n");
		return -ENODEV;
	}
	clk_enable(ether_clk);					/* Enable Peripheral clock */

	while ((detected != 0) && (phy_address < 32)) {
		/* Read the PHY ID registers */
		enable_mdi();
		read_phy(phy_address, MII_PHYSID1, &phyid1);
		read_phy(phy_address, MII_PHYSID2, &phyid2);
		disable_mdi();

		phy_id = (phyid1 << 16) | (phyid2 & 0xfff0);
		switch (phy_id) {
			case MII_DM9161_ID:		/* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */
			case MII_DM9161A_ID:		/* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */
			case MII_LXT971A_ID:		/* Intel LXT971A: PHY_ID1 = 0x13, PHY_ID2 = 78E0 */
			case MII_RTL8201_ID:		/* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
			case MII_BCM5221_ID:		/* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
			case MII_DP83847_ID:		/* National Semiconductor DP83847:  */
			case MII_DP83848_ID:		/* National Semiconductor DP83848:  */
			case MII_AC101L_ID:		/* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
			case MII_KS8721_ID:		/* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
			case MII_T78Q21x3_ID:		/* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */
			case MII_LAN83C185_ID:		/* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */
				detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk);
				break;
		}

		phy_address++;
	}

	clk_disable(ether_clk);					/* Disable Peripheral clock */

	return detected;
}

static int __devexit at91ether_remove(struct platform_device *pdev)
{
	struct net_device *dev = platform_get_drvdata(pdev);
	struct at91_private *lp = netdev_priv(dev);

	if (lp->board_data.phy_irq_pin >= 32)
		gpio_free(lp->board_data.phy_irq_pin);

	unregister_netdev(dev);
	free_irq(dev->irq, dev);
	dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
	clk_put(lp->ether_clk);

	platform_set_drvdata(pdev, NULL);
	free_netdev(dev);
	return 0;
}

#ifdef CONFIG_PM

static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg)
{
	struct net_device *net_dev = platform_get_drvdata(pdev);
	struct at91_private *lp = netdev_priv(net_dev);
	int phy_irq = lp->board_data.phy_irq_pin;

	if (netif_running(net_dev)) {
		if (phy_irq)
			disable_irq(phy_irq);

		netif_stop_queue(net_dev);
		netif_device_detach(net_dev);

		clk_disable(lp->ether_clk);
	}
	return 0;
}

static int at91ether_resume(struct platform_device *pdev)
{
	struct net_device *net_dev = platform_get_drvdata(pdev);
	struct at91_private *lp = netdev_priv(net_dev);
	int phy_irq = lp->board_data.phy_irq_pin;

	if (netif_running(net_dev)) {
		clk_enable(lp->ether_clk);

		netif_device_attach(net_dev);
		netif_start_queue(net_dev);

		if (phy_irq)
			enable_irq(phy_irq);
	}
	return 0;
}

#else
#define at91ether_suspend	NULL
#define at91ether_resume	NULL
#endif

static struct platform_driver at91ether_driver = {
	.probe		= at91ether_probe,
	.remove		= __devexit_p(at91ether_remove),
	.suspend	= at91ether_suspend,
	.resume		= at91ether_resume,
	.driver		= {
		.name	= DRV_NAME,
		.owner	= THIS_MODULE,
	},
};

static int __init at91ether_init(void)
{
	return platform_driver_register(&at91ether_driver);
}

static void __exit at91ether_exit(void)
{
	platform_driver_unregister(&at91ether_driver);
}

module_init(at91ether_init)
module_exit(at91ether_exit)

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver");
MODULE_AUTHOR("Andrew Victor");
MODULE_ALIAS("platform:" DRV_NAME);
