// SPDX-License-Identifier: GPL-2.0-only
/*
 * New driver for Marvell Yukon chipset and SysKonnect Gigabit
 * Ethernet adapters. Based on earlier sk98lin, e100 and
 * FreeBSD if_sk drivers.
 *
 * This driver intentionally does not support all the features
 * of the original driver such as link fail-over and link management because
 * those should be done at higher levels.
 *
 * Copyright (C) 2004, 2005 Stephen Hemminger <shemminger@osdl.org>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/pci.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/mii.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#include <linux/prefetch.h>
#include <asm/irq.h>

#include "skge.h"

#define DRV_NAME		"skge"
#define DRV_VERSION		"1.14"

#define DEFAULT_TX_RING_SIZE	128
#define DEFAULT_RX_RING_SIZE	512
#define MAX_TX_RING_SIZE	1024
#define TX_LOW_WATER		(MAX_SKB_FRAGS + 1)
#define MAX_RX_RING_SIZE	4096
#define RX_COPY_THRESHOLD	128
#define RX_BUF_SIZE		1536
#define PHY_RETRIES	        1000
#define ETH_JUMBO_MTU		9000
#define TX_WATCHDOG		(5 * HZ)
#define BLINK_MS		250
#define LINK_HZ			HZ

#define SKGE_EEPROM_MAGIC	0x9933aabb


MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

static const u32 default_msg = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
				NETIF_MSG_LINK | NETIF_MSG_IFUP |
				NETIF_MSG_IFDOWN);

static int debug = -1;	/* defaults above */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");

static const struct pci_device_id skge_id_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, 0x1700) },	  /* 3Com 3C940 */
	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, 0x80EB) },	  /* 3Com 3C940B */
#ifdef CONFIG_SKGE_GENESIS
	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x4300) }, /* SK-9xx */
#endif
	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x4320) }, /* SK-98xx V2.0 */
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },	  /* D-Link DGE-530T (rev.B) */
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4c00) },	  /* D-Link DGE-530T */
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302) },	  /* D-Link DGE-530T Rev C1 */
	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },	  /* Marvell Yukon 88E8001/8003/8010 */
	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) },	  /* Belkin */
	{ PCI_DEVICE(PCI_VENDOR_ID_CNET, 0x434E) }, 	  /* CNet PowerG-2000 */
	{ PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, 0x1064) },	  /* Linksys EG1064 v2 */
	{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015 }, /* Linksys EG1032 v2 */
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, skge_id_table);

static int skge_up(struct net_device *dev);
static int skge_down(struct net_device *dev);
static void skge_phy_reset(struct skge_port *skge);
static void skge_tx_clean(struct net_device *dev);
static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
static void genesis_get_stats(struct skge_port *skge, u64 *data);
static void yukon_get_stats(struct skge_port *skge, u64 *data);
static void yukon_init(struct skge_hw *hw, int port);
static void genesis_mac_init(struct skge_hw *hw, int port);
static void genesis_link_up(struct skge_port *skge);
static void skge_set_multicast(struct net_device *dev);
static irqreturn_t skge_intr(int irq, void *dev_id);

/* Avoid conditionals by using array */
static const int txqaddr[] = { Q_XA1, Q_XA2 };
static const int rxqaddr[] = { Q_R1, Q_R2 };
static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
static const u32 napimask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F };
static const u32 portmask[] = { IS_PORT_1, IS_PORT_2 };

static inline bool is_genesis(const struct skge_hw *hw)
{
#ifdef CONFIG_SKGE_GENESIS
	return hw->chip_id == CHIP_ID_GENESIS;
#else
	return false;
#endif
}

static int skge_get_regs_len(struct net_device *dev)
{
	return 0x4000;
}

/*
 * Returns copy of whole control register region
 * Note: skip RAM address register because accessing it will
 * 	 cause bus hangs!
 */
static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
			  void *p)
{
	const struct skge_port *skge = netdev_priv(dev);
	const void __iomem *io = skge->hw->regs;

	regs->version = 1;
	memset(p, 0, regs->len);
	memcpy_fromio(p, io, B3_RAM_ADDR);

	if (regs->len > B3_RI_WTO_R1) {
		memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1,
			      regs->len - B3_RI_WTO_R1);
	}
}

/* Wake on Lan only supported on Yukon chips with rev 1 or above */
static u32 wol_supported(const struct skge_hw *hw)
{
	if (is_genesis(hw))
		return 0;

	if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
		return 0;

	return WAKE_MAGIC | WAKE_PHY;
}

static void skge_wol_init(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u16 ctrl;

	skge_write16(hw, B0_CTST, CS_RST_CLR);
	skge_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR);

	/* Turn on Vaux */
	skge_write8(hw, B0_POWER_CTRL,
		    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF);

	/* WA code for COMA mode -- clear PHY reset */
	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
		u32 reg = skge_read32(hw, B2_GP_IO);
		reg |= GP_DIR_9;
		reg &= ~GP_IO_9;
		skge_write32(hw, B2_GP_IO, reg);
	}

	skge_write32(hw, SK_REG(port, GPHY_CTRL),
		     GPC_DIS_SLEEP |
		     GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
		     GPC_ANEG_1 | GPC_RST_SET);

	skge_write32(hw, SK_REG(port, GPHY_CTRL),
		     GPC_DIS_SLEEP |
		     GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
		     GPC_ANEG_1 | GPC_RST_CLR);

	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);

	/* Force to 10/100 skge_reset will re-enable on resume	 */
	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
		     (PHY_AN_100FULL | PHY_AN_100HALF |
		      PHY_AN_10FULL | PHY_AN_10HALF | PHY_AN_CSMA));
	/* no 1000 HD/FD */
	gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, 0);
	gm_phy_write(hw, port, PHY_MARV_CTRL,
		     PHY_CT_RESET | PHY_CT_SPS_LSB | PHY_CT_ANE |
		     PHY_CT_RE_CFG | PHY_CT_DUP_MD);


	/* Set GMAC to no flow control and auto update for speed/duplex */
	gma_write16(hw, port, GM_GP_CTRL,
		    GM_GPCR_FC_TX_DIS|GM_GPCR_TX_ENA|GM_GPCR_RX_ENA|
		    GM_GPCR_DUP_FULL|GM_GPCR_FC_RX_DIS|GM_GPCR_AU_FCT_DIS);

	/* Set WOL address */
	memcpy_toio(hw->regs + WOL_REGS(port, WOL_MAC_ADDR),
		    skge->netdev->dev_addr, ETH_ALEN);

	/* Turn on appropriate WOL control bits */
	skge_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), WOL_CTL_CLEAR_RESULT);
	ctrl = 0;
	if (skge->wol & WAKE_PHY)
		ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG|WOL_CTL_ENA_LINK_CHG_UNIT;
	else
		ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG|WOL_CTL_DIS_LINK_CHG_UNIT;

	if (skge->wol & WAKE_MAGIC)
		ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT;
	else
		ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;

	ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
	skge_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);

	/* block receiver */
	skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
}

static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
	struct skge_port *skge = netdev_priv(dev);

	wol->supported = wol_supported(skge->hw);
	wol->wolopts = skge->wol;
}

static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;

	if ((wol->wolopts & ~wol_supported(hw)) ||
	    !device_can_wakeup(&hw->pdev->dev))
		return -EOPNOTSUPP;

	skge->wol = wol->wolopts;

	device_set_wakeup_enable(&hw->pdev->dev, skge->wol);

	return 0;
}

/* Determine supported/advertised modes based on hardware.
 * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
 */
static u32 skge_supported_modes(const struct skge_hw *hw)
{
	u32 supported;

	if (hw->copper) {
		supported = (SUPPORTED_10baseT_Half |
			     SUPPORTED_10baseT_Full |
			     SUPPORTED_100baseT_Half |
			     SUPPORTED_100baseT_Full |
			     SUPPORTED_1000baseT_Half |
			     SUPPORTED_1000baseT_Full |
			     SUPPORTED_Autoneg |
			     SUPPORTED_TP);

		if (is_genesis(hw))
			supported &= ~(SUPPORTED_10baseT_Half |
				       SUPPORTED_10baseT_Full |
				       SUPPORTED_100baseT_Half |
				       SUPPORTED_100baseT_Full);

		else if (hw->chip_id == CHIP_ID_YUKON)
			supported &= ~SUPPORTED_1000baseT_Half;
	} else
		supported = (SUPPORTED_1000baseT_Full |
			     SUPPORTED_1000baseT_Half |
			     SUPPORTED_FIBRE |
			     SUPPORTED_Autoneg);

	return supported;
}

static int skge_get_link_ksettings(struct net_device *dev,
				   struct ethtool_link_ksettings *cmd)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	u32 supported, advertising;

	supported = skge_supported_modes(hw);

	if (hw->copper) {
		cmd->base.port = PORT_TP;
		cmd->base.phy_address = hw->phy_addr;
	} else
		cmd->base.port = PORT_FIBRE;

	advertising = skge->advertising;
	cmd->base.autoneg = skge->autoneg;
	cmd->base.speed = skge->speed;
	cmd->base.duplex = skge->duplex;

	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
						supported);
	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
						advertising);

	return 0;
}

static int skge_set_link_ksettings(struct net_device *dev,
				   const struct ethtool_link_ksettings *cmd)
{
	struct skge_port *skge = netdev_priv(dev);
	const struct skge_hw *hw = skge->hw;
	u32 supported = skge_supported_modes(hw);
	int err = 0;
	u32 advertising;

	ethtool_convert_link_mode_to_legacy_u32(&advertising,
						cmd->link_modes.advertising);

	if (cmd->base.autoneg == AUTONEG_ENABLE) {
		advertising = supported;
		skge->duplex = -1;
		skge->speed = -1;
	} else {
		u32 setting;
		u32 speed = cmd->base.speed;

		switch (speed) {
		case SPEED_1000:
			if (cmd->base.duplex == DUPLEX_FULL)
				setting = SUPPORTED_1000baseT_Full;
			else if (cmd->base.duplex == DUPLEX_HALF)
				setting = SUPPORTED_1000baseT_Half;
			else
				return -EINVAL;
			break;
		case SPEED_100:
			if (cmd->base.duplex == DUPLEX_FULL)
				setting = SUPPORTED_100baseT_Full;
			else if (cmd->base.duplex == DUPLEX_HALF)
				setting = SUPPORTED_100baseT_Half;
			else
				return -EINVAL;
			break;

		case SPEED_10:
			if (cmd->base.duplex == DUPLEX_FULL)
				setting = SUPPORTED_10baseT_Full;
			else if (cmd->base.duplex == DUPLEX_HALF)
				setting = SUPPORTED_10baseT_Half;
			else
				return -EINVAL;
			break;
		default:
			return -EINVAL;
		}

		if ((setting & supported) == 0)
			return -EINVAL;

		skge->speed = speed;
		skge->duplex = cmd->base.duplex;
	}

	skge->autoneg = cmd->base.autoneg;
	skge->advertising = advertising;

	if (netif_running(dev)) {
		skge_down(dev);
		err = skge_up(dev);
		if (err) {
			dev_close(dev);
			return err;
		}
	}

	return 0;
}

static void skge_get_drvinfo(struct net_device *dev,
			     struct ethtool_drvinfo *info)
{
	struct skge_port *skge = netdev_priv(dev);

	strscpy(info->driver, DRV_NAME, sizeof(info->driver));
	strscpy(info->version, DRV_VERSION, sizeof(info->version));
	strscpy(info->bus_info, pci_name(skge->hw->pdev),
		sizeof(info->bus_info));
}

static const struct skge_stat {
	char 	   name[ETH_GSTRING_LEN];
	u16	   xmac_offset;
	u16	   gma_offset;
} skge_stats[] = {
	{ "tx_bytes",		XM_TXO_OK_HI,  GM_TXO_OK_HI },
	{ "rx_bytes",		XM_RXO_OK_HI,  GM_RXO_OK_HI },

	{ "tx_broadcast",	XM_TXF_BC_OK,  GM_TXF_BC_OK },
	{ "rx_broadcast",	XM_RXF_BC_OK,  GM_RXF_BC_OK },
	{ "tx_multicast",	XM_TXF_MC_OK,  GM_TXF_MC_OK },
	{ "rx_multicast",	XM_RXF_MC_OK,  GM_RXF_MC_OK },
	{ "tx_unicast",		XM_TXF_UC_OK,  GM_TXF_UC_OK },
	{ "rx_unicast",		XM_RXF_UC_OK,  GM_RXF_UC_OK },
	{ "tx_mac_pause",	XM_TXF_MPAUSE, GM_TXF_MPAUSE },
	{ "rx_mac_pause",	XM_RXF_MPAUSE, GM_RXF_MPAUSE },

	{ "collisions",		XM_TXF_SNG_COL, GM_TXF_SNG_COL },
	{ "multi_collisions",	XM_TXF_MUL_COL, GM_TXF_MUL_COL },
	{ "aborted",		XM_TXF_ABO_COL, GM_TXF_ABO_COL },
	{ "late_collision",	XM_TXF_LAT_COL, GM_TXF_LAT_COL },
	{ "fifo_underrun",	XM_TXE_FIFO_UR, GM_TXE_FIFO_UR },
	{ "fifo_overflow",	XM_RXE_FIFO_OV, GM_RXE_FIFO_OV },

	{ "rx_toolong",		XM_RXF_LNG_ERR, GM_RXF_LNG_ERR },
	{ "rx_jabber",		XM_RXF_JAB_PKT, GM_RXF_JAB_PKT },
	{ "rx_runt",		XM_RXE_RUNT, 	GM_RXE_FRAG },
	{ "rx_too_long",	XM_RXF_LNG_ERR, GM_RXF_LNG_ERR },
	{ "rx_fcs_error",	XM_RXF_FCS_ERR, GM_RXF_FCS_ERR },
};

static int skge_get_sset_count(struct net_device *dev, int sset)
{
	switch (sset) {
	case ETH_SS_STATS:
		return ARRAY_SIZE(skge_stats);
	default:
		return -EOPNOTSUPP;
	}
}

static void skge_get_ethtool_stats(struct net_device *dev,
				   struct ethtool_stats *stats, u64 *data)
{
	struct skge_port *skge = netdev_priv(dev);

	if (is_genesis(skge->hw))
		genesis_get_stats(skge, data);
	else
		yukon_get_stats(skge, data);
}

/* Use hardware MIB variables for critical path statistics and
 * transmit feedback not reported at interrupt.
 * Other errors are accounted for in interrupt handler.
 */
static struct net_device_stats *skge_get_stats(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	u64 data[ARRAY_SIZE(skge_stats)];

	if (is_genesis(skge->hw))
		genesis_get_stats(skge, data);
	else
		yukon_get_stats(skge, data);

	dev->stats.tx_bytes = data[0];
	dev->stats.rx_bytes = data[1];
	dev->stats.tx_packets = data[2] + data[4] + data[6];
	dev->stats.rx_packets = data[3] + data[5] + data[7];
	dev->stats.multicast = data[3] + data[5];
	dev->stats.collisions = data[10];
	dev->stats.tx_aborted_errors = data[12];

	return &dev->stats;
}

static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
	int i;

	switch (stringset) {
	case ETH_SS_STATS:
		for (i = 0; i < ARRAY_SIZE(skge_stats); i++)
			memcpy(data + i * ETH_GSTRING_LEN,
			       skge_stats[i].name, ETH_GSTRING_LEN);
		break;
	}
}

static void skge_get_ring_param(struct net_device *dev,
				struct ethtool_ringparam *p,
				struct kernel_ethtool_ringparam *kernel_p,
				struct netlink_ext_ack *extack)
{
	struct skge_port *skge = netdev_priv(dev);

	p->rx_max_pending = MAX_RX_RING_SIZE;
	p->tx_max_pending = MAX_TX_RING_SIZE;

	p->rx_pending = skge->rx_ring.count;
	p->tx_pending = skge->tx_ring.count;
}

static int skge_set_ring_param(struct net_device *dev,
			       struct ethtool_ringparam *p,
			       struct kernel_ethtool_ringparam *kernel_p,
			       struct netlink_ext_ack *extack)
{
	struct skge_port *skge = netdev_priv(dev);
	int err = 0;

	if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
	    p->tx_pending < TX_LOW_WATER || p->tx_pending > MAX_TX_RING_SIZE)
		return -EINVAL;

	skge->rx_ring.count = p->rx_pending;
	skge->tx_ring.count = p->tx_pending;

	if (netif_running(dev)) {
		skge_down(dev);
		err = skge_up(dev);
		if (err)
			dev_close(dev);
	}

	return err;
}

static u32 skge_get_msglevel(struct net_device *netdev)
{
	struct skge_port *skge = netdev_priv(netdev);
	return skge->msg_enable;
}

static void skge_set_msglevel(struct net_device *netdev, u32 value)
{
	struct skge_port *skge = netdev_priv(netdev);
	skge->msg_enable = value;
}

static int skge_nway_reset(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);

	if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev))
		return -EINVAL;

	skge_phy_reset(skge);
	return 0;
}

static void skge_get_pauseparam(struct net_device *dev,
				struct ethtool_pauseparam *ecmd)
{
	struct skge_port *skge = netdev_priv(dev);

	ecmd->rx_pause = ((skge->flow_control == FLOW_MODE_SYMMETRIC) ||
			  (skge->flow_control == FLOW_MODE_SYM_OR_REM));
	ecmd->tx_pause = (ecmd->rx_pause ||
			  (skge->flow_control == FLOW_MODE_LOC_SEND));

	ecmd->autoneg = ecmd->rx_pause || ecmd->tx_pause;
}

static int skge_set_pauseparam(struct net_device *dev,
			       struct ethtool_pauseparam *ecmd)
{
	struct skge_port *skge = netdev_priv(dev);
	struct ethtool_pauseparam old;
	int err = 0;

	skge_get_pauseparam(dev, &old);

	if (ecmd->autoneg != old.autoneg)
		skge->flow_control = ecmd->autoneg ? FLOW_MODE_NONE : FLOW_MODE_SYMMETRIC;
	else {
		if (ecmd->rx_pause && ecmd->tx_pause)
			skge->flow_control = FLOW_MODE_SYMMETRIC;
		else if (ecmd->rx_pause && !ecmd->tx_pause)
			skge->flow_control = FLOW_MODE_SYM_OR_REM;
		else if (!ecmd->rx_pause && ecmd->tx_pause)
			skge->flow_control = FLOW_MODE_LOC_SEND;
		else
			skge->flow_control = FLOW_MODE_NONE;
	}

	if (netif_running(dev)) {
		skge_down(dev);
		err = skge_up(dev);
		if (err) {
			dev_close(dev);
			return err;
		}
	}

	return 0;
}

/* Chip internal frequency for clock calculations */
static inline u32 hwkhz(const struct skge_hw *hw)
{
	return is_genesis(hw) ? 53125 : 78125;
}

/* Chip HZ to microseconds */
static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
{
	return (ticks * 1000) / hwkhz(hw);
}

/* Microseconds to chip HZ */
static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
{
	return hwkhz(hw) * usec / 1000;
}

static int skge_get_coalesce(struct net_device *dev,
			     struct ethtool_coalesce *ecmd,
			     struct kernel_ethtool_coalesce *kernel_coal,
			     struct netlink_ext_ack *extack)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int port = skge->port;

	ecmd->rx_coalesce_usecs = 0;
	ecmd->tx_coalesce_usecs = 0;

	if (skge_read32(hw, B2_IRQM_CTRL) & TIM_START) {
		u32 delay = skge_clk2usec(hw, skge_read32(hw, B2_IRQM_INI));
		u32 msk = skge_read32(hw, B2_IRQM_MSK);

		if (msk & rxirqmask[port])
			ecmd->rx_coalesce_usecs = delay;
		if (msk & txirqmask[port])
			ecmd->tx_coalesce_usecs = delay;
	}

	return 0;
}

/* Note: interrupt timer is per board, but can turn on/off per port */
static int skge_set_coalesce(struct net_device *dev,
			     struct ethtool_coalesce *ecmd,
			     struct kernel_ethtool_coalesce *kernel_coal,
			     struct netlink_ext_ack *extack)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u32 msk = skge_read32(hw, B2_IRQM_MSK);
	u32 delay = 25;

	if (ecmd->rx_coalesce_usecs == 0)
		msk &= ~rxirqmask[port];
	else if (ecmd->rx_coalesce_usecs < 25 ||
		 ecmd->rx_coalesce_usecs > 33333)
		return -EINVAL;
	else {
		msk |= rxirqmask[port];
		delay = ecmd->rx_coalesce_usecs;
	}

	if (ecmd->tx_coalesce_usecs == 0)
		msk &= ~txirqmask[port];
	else if (ecmd->tx_coalesce_usecs < 25 ||
		 ecmd->tx_coalesce_usecs > 33333)
		return -EINVAL;
	else {
		msk |= txirqmask[port];
		delay = min(delay, ecmd->rx_coalesce_usecs);
	}

	skge_write32(hw, B2_IRQM_MSK, msk);
	if (msk == 0)
		skge_write32(hw, B2_IRQM_CTRL, TIM_STOP);
	else {
		skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, delay));
		skge_write32(hw, B2_IRQM_CTRL, TIM_START);
	}
	return 0;
}

enum led_mode { LED_MODE_OFF, LED_MODE_ON, LED_MODE_TST };
static void skge_led(struct skge_port *skge, enum led_mode mode)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;

	spin_lock_bh(&hw->phy_lock);
	if (is_genesis(hw)) {
		switch (mode) {
		case LED_MODE_OFF:
			if (hw->phy_type == SK_PHY_BCOM)
				xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
			else {
				skge_write32(hw, SK_REG(port, TX_LED_VAL), 0);
				skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF);
			}
			skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
			skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
			skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
			break;

		case LED_MODE_ON:
			skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
			skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);

			skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
			skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);

			break;

		case LED_MODE_TST:
			skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON);
			skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
			skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);

			if (hw->phy_type == SK_PHY_BCOM)
				xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
			else {
				skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON);
				skge_write32(hw, SK_REG(port, TX_LED_VAL), 100);
				skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
			}

		}
	} else {
		switch (mode) {
		case LED_MODE_OFF:
			gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
				     PHY_M_LED_MO_DUP(MO_LED_OFF)  |
				     PHY_M_LED_MO_10(MO_LED_OFF)   |
				     PHY_M_LED_MO_100(MO_LED_OFF)  |
				     PHY_M_LED_MO_1000(MO_LED_OFF) |
				     PHY_M_LED_MO_RX(MO_LED_OFF));
			break;
		case LED_MODE_ON:
			gm_phy_write(hw, port, PHY_MARV_LED_CTRL,
				     PHY_M_LED_PULS_DUR(PULS_170MS) |
				     PHY_M_LED_BLINK_RT(BLINK_84MS) |
				     PHY_M_LEDC_TX_CTRL |
				     PHY_M_LEDC_DP_CTRL);

			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
				     PHY_M_LED_MO_RX(MO_LED_OFF) |
				     (skge->speed == SPEED_100 ?
				      PHY_M_LED_MO_100(MO_LED_ON) : 0));
			break;
		case LED_MODE_TST:
			gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
				     PHY_M_LED_MO_DUP(MO_LED_ON)  |
				     PHY_M_LED_MO_10(MO_LED_ON)   |
				     PHY_M_LED_MO_100(MO_LED_ON)  |
				     PHY_M_LED_MO_1000(MO_LED_ON) |
				     PHY_M_LED_MO_RX(MO_LED_ON));
		}
	}
	spin_unlock_bh(&hw->phy_lock);
}

/* blink LED's for finding board */
static int skge_set_phys_id(struct net_device *dev,
			    enum ethtool_phys_id_state state)
{
	struct skge_port *skge = netdev_priv(dev);

	switch (state) {
	case ETHTOOL_ID_ACTIVE:
		return 2;	/* cycle on/off twice per second */

	case ETHTOOL_ID_ON:
		skge_led(skge, LED_MODE_TST);
		break;

	case ETHTOOL_ID_OFF:
		skge_led(skge, LED_MODE_OFF);
		break;

	case ETHTOOL_ID_INACTIVE:
		/* back to regular LED state */
		skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
	}

	return 0;
}

static int skge_get_eeprom_len(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	u32 reg2;

	pci_read_config_dword(skge->hw->pdev, PCI_DEV_REG2, &reg2);
	return 1 << (((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
}

static u32 skge_vpd_read(struct pci_dev *pdev, int cap, u16 offset)
{
	u32 val;

	pci_write_config_word(pdev, cap + PCI_VPD_ADDR, offset);

	do {
		pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
	} while (!(offset & PCI_VPD_ADDR_F));

	pci_read_config_dword(pdev, cap + PCI_VPD_DATA, &val);
	return val;
}

static void skge_vpd_write(struct pci_dev *pdev, int cap, u16 offset, u32 val)
{
	pci_write_config_dword(pdev, cap + PCI_VPD_DATA, val);
	pci_write_config_word(pdev, cap + PCI_VPD_ADDR,
			      offset | PCI_VPD_ADDR_F);

	do {
		pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
	} while (offset & PCI_VPD_ADDR_F);
}

static int skge_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
			   u8 *data)
{
	struct skge_port *skge = netdev_priv(dev);
	struct pci_dev *pdev = skge->hw->pdev;
	int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD);
	int length = eeprom->len;
	u16 offset = eeprom->offset;

	if (!cap)
		return -EINVAL;

	eeprom->magic = SKGE_EEPROM_MAGIC;

	while (length > 0) {
		u32 val = skge_vpd_read(pdev, cap, offset);
		int n = min_t(int, length, sizeof(val));

		memcpy(data, &val, n);
		length -= n;
		data += n;
		offset += n;
	}
	return 0;
}

static int skge_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
			   u8 *data)
{
	struct skge_port *skge = netdev_priv(dev);
	struct pci_dev *pdev = skge->hw->pdev;
	int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD);
	int length = eeprom->len;
	u16 offset = eeprom->offset;

	if (!cap)
		return -EINVAL;

	if (eeprom->magic != SKGE_EEPROM_MAGIC)
		return -EINVAL;

	while (length > 0) {
		u32 val;
		int n = min_t(int, length, sizeof(val));

		if (n < sizeof(val))
			val = skge_vpd_read(pdev, cap, offset);
		memcpy(&val, data, n);

		skge_vpd_write(pdev, cap, offset, val);

		length -= n;
		data += n;
		offset += n;
	}
	return 0;
}

static const struct ethtool_ops skge_ethtool_ops = {
	.supported_coalesce_params = ETHTOOL_COALESCE_USECS,
	.get_drvinfo	= skge_get_drvinfo,
	.get_regs_len	= skge_get_regs_len,
	.get_regs	= skge_get_regs,
	.get_wol	= skge_get_wol,
	.set_wol	= skge_set_wol,
	.get_msglevel	= skge_get_msglevel,
	.set_msglevel	= skge_set_msglevel,
	.nway_reset	= skge_nway_reset,
	.get_link	= ethtool_op_get_link,
	.get_eeprom_len	= skge_get_eeprom_len,
	.get_eeprom	= skge_get_eeprom,
	.set_eeprom	= skge_set_eeprom,
	.get_ringparam	= skge_get_ring_param,
	.set_ringparam	= skge_set_ring_param,
	.get_pauseparam = skge_get_pauseparam,
	.set_pauseparam = skge_set_pauseparam,
	.get_coalesce	= skge_get_coalesce,
	.set_coalesce	= skge_set_coalesce,
	.get_strings	= skge_get_strings,
	.set_phys_id	= skge_set_phys_id,
	.get_sset_count = skge_get_sset_count,
	.get_ethtool_stats = skge_get_ethtool_stats,
	.get_link_ksettings = skge_get_link_ksettings,
	.set_link_ksettings = skge_set_link_ksettings,
};

/*
 * Allocate ring elements and chain them together
 * One-to-one association of board descriptors with ring elements
 */
static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base)
{
	struct skge_tx_desc *d;
	struct skge_element *e;
	int i;

	ring->start = kcalloc(ring->count, sizeof(*e), GFP_KERNEL);
	if (!ring->start)
		return -ENOMEM;

	for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) {
		e->desc = d;
		if (i == ring->count - 1) {
			e->next = ring->start;
			d->next_offset = base;
		} else {
			e->next = e + 1;
			d->next_offset = base + (i+1) * sizeof(*d);
		}
	}
	ring->to_use = ring->to_clean = ring->start;

	return 0;
}

/* Allocate and setup a new buffer for receiving */
static int skge_rx_setup(struct skge_port *skge, struct skge_element *e,
			 struct sk_buff *skb, unsigned int bufsize)
{
	struct skge_rx_desc *rd = e->desc;
	dma_addr_t map;

	map = dma_map_single(&skge->hw->pdev->dev, skb->data, bufsize,
			     DMA_FROM_DEVICE);

	if (dma_mapping_error(&skge->hw->pdev->dev, map))
		return -1;

	rd->dma_lo = lower_32_bits(map);
	rd->dma_hi = upper_32_bits(map);
	e->skb = skb;
	rd->csum1_start = ETH_HLEN;
	rd->csum2_start = ETH_HLEN;
	rd->csum1 = 0;
	rd->csum2 = 0;

	wmb();

	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
	dma_unmap_addr_set(e, mapaddr, map);
	dma_unmap_len_set(e, maplen, bufsize);
	return 0;
}

/* Resume receiving using existing skb,
 * Note: DMA address is not changed by chip.
 * 	 MTU not changed while receiver active.
 */
static inline void skge_rx_reuse(struct skge_element *e, unsigned int size)
{
	struct skge_rx_desc *rd = e->desc;

	rd->csum2 = 0;
	rd->csum2_start = ETH_HLEN;

	wmb();

	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size;
}


/* Free all  buffers in receive ring, assumes receiver stopped */
static void skge_rx_clean(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	struct skge_ring *ring = &skge->rx_ring;
	struct skge_element *e;

	e = ring->start;
	do {
		struct skge_rx_desc *rd = e->desc;
		rd->control = 0;
		if (e->skb) {
			dma_unmap_single(&hw->pdev->dev,
					 dma_unmap_addr(e, mapaddr),
					 dma_unmap_len(e, maplen),
					 DMA_FROM_DEVICE);
			dev_kfree_skb(e->skb);
			e->skb = NULL;
		}
	} while ((e = e->next) != ring->start);
}


/* Allocate buffers for receive ring
 * For receive:  to_clean is next received frame.
 */
static int skge_rx_fill(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_ring *ring = &skge->rx_ring;
	struct skge_element *e;

	e = ring->start;
	do {
		struct sk_buff *skb;

		skb = __netdev_alloc_skb(dev, skge->rx_buf_size + NET_IP_ALIGN,
					 GFP_KERNEL);
		if (!skb)
			return -ENOMEM;

		skb_reserve(skb, NET_IP_ALIGN);
		if (skge_rx_setup(skge, e, skb, skge->rx_buf_size) < 0) {
			dev_kfree_skb(skb);
			return -EIO;
		}
	} while ((e = e->next) != ring->start);

	ring->to_clean = ring->start;
	return 0;
}

static const char *skge_pause(enum pause_status status)
{
	switch (status) {
	case FLOW_STAT_NONE:
		return "none";
	case FLOW_STAT_REM_SEND:
		return "rx only";
	case FLOW_STAT_LOC_SEND:
		return "tx_only";
	case FLOW_STAT_SYMMETRIC:		/* Both station may send PAUSE */
		return "both";
	default:
		return "indeterminated";
	}
}


static void skge_link_up(struct skge_port *skge)
{
	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
		    LED_BLK_OFF|LED_SYNC_OFF|LED_REG_ON);

	netif_carrier_on(skge->netdev);
	netif_wake_queue(skge->netdev);

	netif_info(skge, link, skge->netdev,
		   "Link is up at %d Mbps, %s duplex, flow control %s\n",
		   skge->speed,
		   skge->duplex == DUPLEX_FULL ? "full" : "half",
		   skge_pause(skge->flow_status));
}

static void skge_link_down(struct skge_port *skge)
{
	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_REG_OFF);
	netif_carrier_off(skge->netdev);
	netif_stop_queue(skge->netdev);

	netif_info(skge, link, skge->netdev, "Link is down\n");
}

static void xm_link_down(struct skge_hw *hw, int port)
{
	struct net_device *dev = hw->dev[port];
	struct skge_port *skge = netdev_priv(dev);

	xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE);

	if (netif_carrier_ok(dev))
		skge_link_down(skge);
}

static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
{
	int i;

	xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
	*val = xm_read16(hw, port, XM_PHY_DATA);

	if (hw->phy_type == SK_PHY_XMAC)
		goto ready;

	for (i = 0; i < PHY_RETRIES; i++) {
		if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
			goto ready;
		udelay(1);
	}

	return -ETIMEDOUT;
 ready:
	*val = xm_read16(hw, port, XM_PHY_DATA);

	return 0;
}

static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
{
	u16 v = 0;
	if (__xm_phy_read(hw, port, reg, &v))
		pr_warn("%s: phy read timed out\n", hw->dev[port]->name);
	return v;
}

static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{
	int i;

	xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
	for (i = 0; i < PHY_RETRIES; i++) {
		if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
			goto ready;
		udelay(1);
	}
	return -EIO;

 ready:
	xm_write16(hw, port, XM_PHY_DATA, val);
	for (i = 0; i < PHY_RETRIES; i++) {
		if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
			return 0;
		udelay(1);
	}
	return -ETIMEDOUT;
}

static void genesis_init(struct skge_hw *hw)
{
	/* set blink source counter */
	skge_write32(hw, B2_BSC_INI, (SK_BLK_DUR * SK_FACT_53) / 100);
	skge_write8(hw, B2_BSC_CTRL, BSC_START);

	/* configure mac arbiter */
	skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);

	/* configure mac arbiter timeout values */
	skge_write8(hw, B3_MA_TOINI_RX1, SK_MAC_TO_53);
	skge_write8(hw, B3_MA_TOINI_RX2, SK_MAC_TO_53);
	skge_write8(hw, B3_MA_TOINI_TX1, SK_MAC_TO_53);
	skge_write8(hw, B3_MA_TOINI_TX2, SK_MAC_TO_53);

	skge_write8(hw, B3_MA_RCINI_RX1, 0);
	skge_write8(hw, B3_MA_RCINI_RX2, 0);
	skge_write8(hw, B3_MA_RCINI_TX1, 0);
	skge_write8(hw, B3_MA_RCINI_TX2, 0);

	/* configure packet arbiter timeout */
	skge_write16(hw, B3_PA_CTRL, PA_RST_CLR);
	skge_write16(hw, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
	skge_write16(hw, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
	skge_write16(hw, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
	skge_write16(hw, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
}

static void genesis_reset(struct skge_hw *hw, int port)
{
	static const u8 zero[8]  = { 0 };
	u32 reg;

	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);

	/* reset the statistics module */
	xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
	xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE);
	xm_write32(hw, port, XM_MODE, 0);		/* clear Mode Reg */
	xm_write16(hw, port, XM_TX_CMD, 0);	/* reset TX CMD Reg */
	xm_write16(hw, port, XM_RX_CMD, 0);	/* reset RX CMD Reg */

	/* disable Broadcom PHY IRQ */
	if (hw->phy_type == SK_PHY_BCOM)
		xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);

	xm_outhash(hw, port, XM_HSM, zero);

	/* Flush TX and RX fifo */
	reg = xm_read32(hw, port, XM_MODE);
	xm_write32(hw, port, XM_MODE, reg | XM_MD_FTF);
	xm_write32(hw, port, XM_MODE, reg | XM_MD_FRF);
}

/* Convert mode to MII values  */
static const u16 phy_pause_map[] = {
	[FLOW_MODE_NONE] =	0,
	[FLOW_MODE_LOC_SEND] =	PHY_AN_PAUSE_ASYM,
	[FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP,
	[FLOW_MODE_SYM_OR_REM]  = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
};

/* special defines for FIBER (88E1011S only) */
static const u16 fiber_pause_map[] = {
	[FLOW_MODE_NONE]	= PHY_X_P_NO_PAUSE,
	[FLOW_MODE_LOC_SEND]	= PHY_X_P_ASYM_MD,
	[FLOW_MODE_SYMMETRIC]	= PHY_X_P_SYM_MD,
	[FLOW_MODE_SYM_OR_REM]	= PHY_X_P_BOTH_MD,
};


/* Check status of Broadcom phy link */
static void bcom_check_link(struct skge_hw *hw, int port)
{
	struct net_device *dev = hw->dev[port];
	struct skge_port *skge = netdev_priv(dev);
	u16 status;

	/* read twice because of latch */
	xm_phy_read(hw, port, PHY_BCOM_STAT);
	status = xm_phy_read(hw, port, PHY_BCOM_STAT);

	if ((status & PHY_ST_LSYNC) == 0) {
		xm_link_down(hw, port);
		return;
	}

	if (skge->autoneg == AUTONEG_ENABLE) {
		u16 lpa, aux;

		if (!(status & PHY_ST_AN_OVER))
			return;

		lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
		if (lpa & PHY_B_AN_RF) {
			netdev_notice(dev, "remote fault\n");
			return;
		}

		aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);

		/* Check Duplex mismatch */
		switch (aux & PHY_B_AS_AN_RES_MSK) {
		case PHY_B_RES_1000FD:
			skge->duplex = DUPLEX_FULL;
			break;
		case PHY_B_RES_1000HD:
			skge->duplex = DUPLEX_HALF;
			break;
		default:
			netdev_notice(dev, "duplex mismatch\n");
			return;
		}

		/* We are using IEEE 802.3z/D5.0 Table 37-4 */
		switch (aux & PHY_B_AS_PAUSE_MSK) {
		case PHY_B_AS_PAUSE_MSK:
			skge->flow_status = FLOW_STAT_SYMMETRIC;
			break;
		case PHY_B_AS_PRR:
			skge->flow_status = FLOW_STAT_REM_SEND;
			break;
		case PHY_B_AS_PRT:
			skge->flow_status = FLOW_STAT_LOC_SEND;
			break;
		default:
			skge->flow_status = FLOW_STAT_NONE;
		}
		skge->speed = SPEED_1000;
	}

	if (!netif_carrier_ok(dev))
		genesis_link_up(skge);
}

/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
 * Phy on for 100 or 10Mbit operation
 */
static void bcom_phy_init(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	int i;
	u16 id1, r, ext, ctl;

	/* magic workaround patterns for Broadcom */
	static const struct {
		u16 reg;
		u16 val;
	} A1hack[] = {
		{ 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 },
		{ 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 },
		{ 0x15, 0x0132 }, { 0x17, 0x8006 }, { 0x15, 0x0232 },
		{ 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
	}, C0hack[] = {
		{ 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 },
		{ 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
	};

	/* read Id from external PHY (all have the same address) */
	id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);

	/* Optimize MDIO transfer by suppressing preamble. */
	r = xm_read16(hw, port, XM_MMU_CMD);
	r |=  XM_MMU_NO_PRE;
	xm_write16(hw, port, XM_MMU_CMD, r);

	switch (id1) {
	case PHY_BCOM_ID1_C0:
		/*
		 * Workaround BCOM Errata for the C0 type.
		 * Write magic patterns to reserved registers.
		 */
		for (i = 0; i < ARRAY_SIZE(C0hack); i++)
			xm_phy_write(hw, port,
				     C0hack[i].reg, C0hack[i].val);

		break;
	case PHY_BCOM_ID1_A1:
		/*
		 * Workaround BCOM Errata for the A1 type.
		 * Write magic patterns to reserved registers.
		 */
		for (i = 0; i < ARRAY_SIZE(A1hack); i++)
			xm_phy_write(hw, port,
				     A1hack[i].reg, A1hack[i].val);
		break;
	}

	/*
	 * Workaround BCOM Errata (#10523) for all BCom PHYs.
	 * Disable Power Management after reset.
	 */
	r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
	r |= PHY_B_AC_DIS_PM;
	xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r);

	/* Dummy read */
	xm_read16(hw, port, XM_ISRC);

	ext = PHY_B_PEC_EN_LTR; /* enable tx led */
	ctl = PHY_CT_SP1000;	/* always 1000mbit */

	if (skge->autoneg == AUTONEG_ENABLE) {
		/*
		 * Workaround BCOM Errata #1 for the C5 type.
		 * 1000Base-T Link Acquisition Failure in Slave Mode
		 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
		 */
		u16 adv = PHY_B_1000C_RD;
		if (skge->advertising & ADVERTISED_1000baseT_Half)
			adv |= PHY_B_1000C_AHD;
		if (skge->advertising & ADVERTISED_1000baseT_Full)
			adv |= PHY_B_1000C_AFD;
		xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv);

		ctl |= PHY_CT_ANE | PHY_CT_RE_CFG;
	} else {
		if (skge->duplex == DUPLEX_FULL)
			ctl |= PHY_CT_DUP_MD;
		/* Force to slave */
		xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE);
	}

	/* Set autonegotiation pause parameters */
	xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV,
		     phy_pause_map[skge->flow_control] | PHY_AN_CSMA);

	/* Handle Jumbo frames */
	if (hw->dev[port]->mtu > ETH_DATA_LEN) {
		xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
			     PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);

		ext |= PHY_B_PEC_HIGH_LA;

	}

	xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
	xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);

	/* Use link status change interrupt */
	xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
}

static void xm_phy_init(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u16 ctrl = 0;

	if (skge->autoneg == AUTONEG_ENABLE) {
		if (skge->advertising & ADVERTISED_1000baseT_Half)
			ctrl |= PHY_X_AN_HD;
		if (skge->advertising & ADVERTISED_1000baseT_Full)
			ctrl |= PHY_X_AN_FD;

		ctrl |= fiber_pause_map[skge->flow_control];

		xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl);

		/* Restart Auto-negotiation */
		ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
	} else {
		/* Set DuplexMode in Config register */
		if (skge->duplex == DUPLEX_FULL)
			ctrl |= PHY_CT_DUP_MD;
		/*
		 * Do NOT enable Auto-negotiation here. This would hold
		 * the link down because no IDLEs are transmitted
		 */
	}

	xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl);

	/* Poll PHY for status changes */
	mod_timer(&skge->link_timer, jiffies + LINK_HZ);
}

static int xm_check_link(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u16 status;

	/* read twice because of latch */
	xm_phy_read(hw, port, PHY_XMAC_STAT);
	status = xm_phy_read(hw, port, PHY_XMAC_STAT);

	if ((status & PHY_ST_LSYNC) == 0) {
		xm_link_down(hw, port);
		return 0;
	}

	if (skge->autoneg == AUTONEG_ENABLE) {
		u16 lpa, res;

		if (!(status & PHY_ST_AN_OVER))
			return 0;

		lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
		if (lpa & PHY_B_AN_RF) {
			netdev_notice(dev, "remote fault\n");
			return 0;
		}

		res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI);

		/* Check Duplex mismatch */
		switch (res & (PHY_X_RS_HD | PHY_X_RS_FD)) {
		case PHY_X_RS_FD:
			skge->duplex = DUPLEX_FULL;
			break;
		case PHY_X_RS_HD:
			skge->duplex = DUPLEX_HALF;
			break;
		default:
			netdev_notice(dev, "duplex mismatch\n");
			return 0;
		}

		/* We are using IEEE 802.3z/D5.0 Table 37-4 */
		if ((skge->flow_control == FLOW_MODE_SYMMETRIC ||
		     skge->flow_control == FLOW_MODE_SYM_OR_REM) &&
		    (lpa & PHY_X_P_SYM_MD))
			skge->flow_status = FLOW_STAT_SYMMETRIC;
		else if (skge->flow_control == FLOW_MODE_SYM_OR_REM &&
			 (lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD)
			/* Enable PAUSE receive, disable PAUSE transmit */
			skge->flow_status  = FLOW_STAT_REM_SEND;
		else if (skge->flow_control == FLOW_MODE_LOC_SEND &&
			 (lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD)
			/* Disable PAUSE receive, enable PAUSE transmit */
			skge->flow_status = FLOW_STAT_LOC_SEND;
		else
			skge->flow_status = FLOW_STAT_NONE;

		skge->speed = SPEED_1000;
	}

	if (!netif_carrier_ok(dev))
		genesis_link_up(skge);
	return 1;
}

/* Poll to check for link coming up.
 *
 * Since internal PHY is wired to a level triggered pin, can't
 * get an interrupt when carrier is detected, need to poll for
 * link coming up.
 */
static void xm_link_timer(struct timer_list *t)
{
	struct skge_port *skge = from_timer(skge, t, link_timer);
	struct net_device *dev = skge->netdev;
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	int i;
	unsigned long flags;

	if (!netif_running(dev))
		return;

	spin_lock_irqsave(&hw->phy_lock, flags);

	/*
	 * Verify that the link by checking GPIO register three times.
	 * This pin has the signal from the link_sync pin connected to it.
	 */
	for (i = 0; i < 3; i++) {
		if (xm_read16(hw, port, XM_GP_PORT) & XM_GP_INP_ASS)
			goto link_down;
	}

	/* Re-enable interrupt to detect link down */
	if (xm_check_link(dev)) {
		u16 msk = xm_read16(hw, port, XM_IMSK);
		msk &= ~XM_IS_INP_ASS;
		xm_write16(hw, port, XM_IMSK, msk);
		xm_read16(hw, port, XM_ISRC);
	} else {
link_down:
		mod_timer(&skge->link_timer,
			  round_jiffies(jiffies + LINK_HZ));
	}
	spin_unlock_irqrestore(&hw->phy_lock, flags);
}

static void genesis_mac_init(struct skge_hw *hw, int port)
{
	struct net_device *dev = hw->dev[port];
	struct skge_port *skge = netdev_priv(dev);
	int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
	int i;
	u32 r;
	static const u8 zero[6]  = { 0 };

	for (i = 0; i < 10; i++) {
		skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
			     MFF_SET_MAC_RST);
		if (skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST)
			goto reset_ok;
		udelay(1);
	}

	netdev_warn(dev, "genesis reset failed\n");

 reset_ok:
	/* Unreset the XMAC. */
	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);

	/*
	 * Perform additional initialization for external PHYs,
	 * namely for the 1000baseTX cards that use the XMAC's
	 * GMII mode.
	 */
	if (hw->phy_type != SK_PHY_XMAC) {
		/* Take external Phy out of reset */
		r = skge_read32(hw, B2_GP_IO);
		if (port == 0)
			r |= GP_DIR_0|GP_IO_0;
		else
			r |= GP_DIR_2|GP_IO_2;

		skge_write32(hw, B2_GP_IO, r);

		/* Enable GMII interface */
		xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
	}


	switch (hw->phy_type) {
	case SK_PHY_XMAC:
		xm_phy_init(skge);
		break;
	case SK_PHY_BCOM:
		bcom_phy_init(skge);
		bcom_check_link(hw, port);
	}

	/* Set Station Address */
	xm_outaddr(hw, port, XM_SA, dev->dev_addr);

	/* We don't use match addresses so clear */
	for (i = 1; i < 16; i++)
		xm_outaddr(hw, port, XM_EXM(i), zero);

	/* Clear MIB counters */
	xm_write16(hw, port, XM_STAT_CMD,
			XM_SC_CLR_RXC | XM_SC_CLR_TXC);
	/* Clear two times according to Errata #3 */
	xm_write16(hw, port, XM_STAT_CMD,
			XM_SC_CLR_RXC | XM_SC_CLR_TXC);

	/* configure Rx High Water Mark (XM_RX_HI_WM) */
	xm_write16(hw, port, XM_RX_HI_WM, 1450);

	/* We don't need the FCS appended to the packet. */
	r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS;
	if (jumbo)
		r |= XM_RX_BIG_PK_OK;

	if (skge->duplex == DUPLEX_HALF) {
		/*
		 * If in manual half duplex mode the other side might be in
		 * full duplex mode, so ignore if a carrier extension is not seen
		 * on frames received
		 */
		r |= XM_RX_DIS_CEXT;
	}
	xm_write16(hw, port, XM_RX_CMD, r);

	/* We want short frames padded to 60 bytes. */
	xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD);

	/* Increase threshold for jumbo frames on dual port */
	if (hw->ports > 1 && jumbo)
		xm_write16(hw, port, XM_TX_THR, 1020);
	else
		xm_write16(hw, port, XM_TX_THR, 512);

	/*
	 * Enable the reception of all error frames. This is
	 * a necessary evil due to the design of the XMAC. The
	 * XMAC's receive FIFO is only 8K in size, however jumbo
	 * frames can be up to 9000 bytes in length. When bad
	 * frame filtering is enabled, the XMAC's RX FIFO operates
	 * in 'store and forward' mode. For this to work, the
	 * entire frame has to fit into the FIFO, but that means
	 * that jumbo frames larger than 8192 bytes will be
	 * truncated. Disabling all bad frame filtering causes
	 * the RX FIFO to operate in streaming mode, in which
	 * case the XMAC will start transferring frames out of the
	 * RX FIFO as soon as the FIFO threshold is reached.
	 */
	xm_write32(hw, port, XM_MODE, XM_DEF_MODE);


	/*
	 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
	 *	- Enable all bits excepting 'Octets Rx OK Low CntOv'
	 *	  and 'Octets Rx OK Hi Cnt Ov'.
	 */
	xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK);

	/*
	 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
	 *	- Enable all bits excepting 'Octets Tx OK Low CntOv'
	 *	  and 'Octets Tx OK Hi Cnt Ov'.
	 */
	xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK);

	/* Configure MAC arbiter */
	skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);

	/* configure timeout values */
	skge_write8(hw, B3_MA_TOINI_RX1, 72);
	skge_write8(hw, B3_MA_TOINI_RX2, 72);
	skge_write8(hw, B3_MA_TOINI_TX1, 72);
	skge_write8(hw, B3_MA_TOINI_TX2, 72);

	skge_write8(hw, B3_MA_RCINI_RX1, 0);
	skge_write8(hw, B3_MA_RCINI_RX2, 0);
	skge_write8(hw, B3_MA_RCINI_TX1, 0);
	skge_write8(hw, B3_MA_RCINI_TX2, 0);

	/* Configure Rx MAC FIFO */
	skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR);
	skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT);
	skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD);

	/* Configure Tx MAC FIFO */
	skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR);
	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
	skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);

	if (jumbo) {
		/* Enable frame flushing if jumbo frames used */
		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
	} else {
		/* enable timeout timers if normal frames */
		skge_write16(hw, B3_PA_CTRL,
			     (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
	}
}

static void genesis_stop(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	unsigned retries = 1000;
	u16 cmd;

	/* Disable Tx and Rx */
	cmd = xm_read16(hw, port, XM_MMU_CMD);
	cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
	xm_write16(hw, port, XM_MMU_CMD, cmd);

	genesis_reset(hw, port);

	/* Clear Tx packet arbiter timeout IRQ */
	skge_write16(hw, B3_PA_CTRL,
		     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);

	/* Reset the MAC */
	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
	do {
		skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
		if (!(skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST))
			break;
	} while (--retries > 0);

	/* For external PHYs there must be special handling */
	if (hw->phy_type != SK_PHY_XMAC) {
		u32 reg = skge_read32(hw, B2_GP_IO);
		if (port == 0) {
			reg |= GP_DIR_0;
			reg &= ~GP_IO_0;
		} else {
			reg |= GP_DIR_2;
			reg &= ~GP_IO_2;
		}
		skge_write32(hw, B2_GP_IO, reg);
		skge_read32(hw, B2_GP_IO);
	}

	xm_write16(hw, port, XM_MMU_CMD,
			xm_read16(hw, port, XM_MMU_CMD)
			& ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));

	xm_read16(hw, port, XM_MMU_CMD);
}


static void genesis_get_stats(struct skge_port *skge, u64 *data)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	int i;
	unsigned long timeout = jiffies + HZ;

	xm_write16(hw, port,
			XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);

	/* wait for update to complete */
	while (xm_read16(hw, port, XM_STAT_CMD)
	       & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) {
		if (time_after(jiffies, timeout))
			break;
		udelay(10);
	}

	/* special case for 64 bit octet counter */
	data[0] = (u64) xm_read32(hw, port, XM_TXO_OK_HI) << 32
		| xm_read32(hw, port, XM_TXO_OK_LO);
	data[1] = (u64) xm_read32(hw, port, XM_RXO_OK_HI) << 32
		| xm_read32(hw, port, XM_RXO_OK_LO);

	for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
		data[i] = xm_read32(hw, port, skge_stats[i].xmac_offset);
}

static void genesis_mac_intr(struct skge_hw *hw, int port)
{
	struct net_device *dev = hw->dev[port];
	struct skge_port *skge = netdev_priv(dev);
	u16 status = xm_read16(hw, port, XM_ISRC);

	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
		     "mac interrupt status 0x%x\n", status);

	if (hw->phy_type == SK_PHY_XMAC && (status & XM_IS_INP_ASS)) {
		xm_link_down(hw, port);
		mod_timer(&skge->link_timer, jiffies + 1);
	}

	if (status & XM_IS_TXF_UR) {
		xm_write32(hw, port, XM_MODE, XM_MD_FTF);
		++dev->stats.tx_fifo_errors;
	}
}

static void genesis_link_up(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u16 cmd, msk;
	u32 mode;

	cmd = xm_read16(hw, port, XM_MMU_CMD);

	/*
	 * enabling pause frame reception is required for 1000BT
	 * because the XMAC is not reset if the link is going down
	 */
	if (skge->flow_status == FLOW_STAT_NONE ||
	    skge->flow_status == FLOW_STAT_LOC_SEND)
		/* Disable Pause Frame Reception */
		cmd |= XM_MMU_IGN_PF;
	else
		/* Enable Pause Frame Reception */
		cmd &= ~XM_MMU_IGN_PF;

	xm_write16(hw, port, XM_MMU_CMD, cmd);

	mode = xm_read32(hw, port, XM_MODE);
	if (skge->flow_status == FLOW_STAT_SYMMETRIC ||
	    skge->flow_status == FLOW_STAT_LOC_SEND) {
		/*
		 * Configure Pause Frame Generation
		 * Use internal and external Pause Frame Generation.
		 * Sending pause frames is edge triggered.
		 * Send a Pause frame with the maximum pause time if
		 * internal oder external FIFO full condition occurs.
		 * Send a zero pause time frame to re-start transmission.
		 */
		/* XM_PAUSE_DA = '010000C28001' (default) */
		/* XM_MAC_PTIME = 0xffff (maximum) */
		/* remember this value is defined in big endian (!) */
		xm_write16(hw, port, XM_MAC_PTIME, 0xffff);

		mode |= XM_PAUSE_MODE;
		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
	} else {
		/*
		 * disable pause frame generation is required for 1000BT
		 * because the XMAC is not reset if the link is going down
		 */
		/* Disable Pause Mode in Mode Register */
		mode &= ~XM_PAUSE_MODE;

		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
	}

	xm_write32(hw, port, XM_MODE, mode);

	/* Turn on detection of Tx underrun */
	msk = xm_read16(hw, port, XM_IMSK);
	msk &= ~XM_IS_TXF_UR;
	xm_write16(hw, port, XM_IMSK, msk);

	xm_read16(hw, port, XM_ISRC);

	/* get MMU Command Reg. */
	cmd = xm_read16(hw, port, XM_MMU_CMD);
	if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL)
		cmd |= XM_MMU_GMII_FD;

	/*
	 * Workaround BCOM Errata (#10523) for all BCom Phys
	 * Enable Power Management after link up
	 */
	if (hw->phy_type == SK_PHY_BCOM) {
		xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
			     xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
			     & ~PHY_B_AC_DIS_PM);
		xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
	}

	/* enable Rx/Tx */
	xm_write16(hw, port, XM_MMU_CMD,
			cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
	skge_link_up(skge);
}


static inline void bcom_phy_intr(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u16 isrc;

	isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
		     "phy interrupt status 0x%x\n", isrc);

	if (isrc & PHY_B_IS_PSE)
		pr_err("%s: uncorrectable pair swap error\n",
		       hw->dev[port]->name);

	/* Workaround BCom Errata:
	 *	enable and disable loopback mode if "NO HCD" occurs.
	 */
	if (isrc & PHY_B_IS_NO_HDCL) {
		u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL);
		xm_phy_write(hw, port, PHY_BCOM_CTRL,
				  ctrl | PHY_CT_LOOP);
		xm_phy_write(hw, port, PHY_BCOM_CTRL,
				  ctrl & ~PHY_CT_LOOP);
	}

	if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
		bcom_check_link(hw, port);

}

static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{
	int i;

	gma_write16(hw, port, GM_SMI_DATA, val);
	gma_write16(hw, port, GM_SMI_CTRL,
			 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
	for (i = 0; i < PHY_RETRIES; i++) {
		udelay(1);

		if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
			return 0;
	}

	pr_warn("%s: phy write timeout\n", hw->dev[port]->name);
	return -EIO;
}

static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
{
	int i;

	gma_write16(hw, port, GM_SMI_CTRL,
			 GM_SMI_CT_PHY_AD(hw->phy_addr)
			 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);

	for (i = 0; i < PHY_RETRIES; i++) {
		udelay(1);
		if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
			goto ready;
	}

	return -ETIMEDOUT;
 ready:
	*val = gma_read16(hw, port, GM_SMI_DATA);
	return 0;
}

static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
{
	u16 v = 0;
	if (__gm_phy_read(hw, port, reg, &v))
		pr_warn("%s: phy read timeout\n", hw->dev[port]->name);
	return v;
}

/* Marvell Phy Initialization */
static void yukon_init(struct skge_hw *hw, int port)
{
	struct skge_port *skge = netdev_priv(hw->dev[port]);
	u16 ctrl, ct1000, adv;

	if (skge->autoneg == AUTONEG_ENABLE) {
		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);

		ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
			  PHY_M_EC_MAC_S_MSK);
		ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);

		ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);

		gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
	}

	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
	if (skge->autoneg == AUTONEG_DISABLE)
		ctrl &= ~PHY_CT_ANE;

	ctrl |= PHY_CT_RESET;
	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);

	ctrl = 0;
	ct1000 = 0;
	adv = PHY_AN_CSMA;

	if (skge->autoneg == AUTONEG_ENABLE) {
		if (hw->copper) {
			if (skge->advertising & ADVERTISED_1000baseT_Full)
				ct1000 |= PHY_M_1000C_AFD;
			if (skge->advertising & ADVERTISED_1000baseT_Half)
				ct1000 |= PHY_M_1000C_AHD;
			if (skge->advertising & ADVERTISED_100baseT_Full)
				adv |= PHY_M_AN_100_FD;
			if (skge->advertising & ADVERTISED_100baseT_Half)
				adv |= PHY_M_AN_100_HD;
			if (skge->advertising & ADVERTISED_10baseT_Full)
				adv |= PHY_M_AN_10_FD;
			if (skge->advertising & ADVERTISED_10baseT_Half)
				adv |= PHY_M_AN_10_HD;

			/* Set Flow-control capabilities */
			adv |= phy_pause_map[skge->flow_control];
		} else {
			if (skge->advertising & ADVERTISED_1000baseT_Full)
				adv |= PHY_M_AN_1000X_AFD;
			if (skge->advertising & ADVERTISED_1000baseT_Half)
				adv |= PHY_M_AN_1000X_AHD;

			adv |= fiber_pause_map[skge->flow_control];
		}

		/* Restart Auto-negotiation */
		ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
	} else {
		/* forced speed/duplex settings */
		ct1000 = PHY_M_1000C_MSE;

		if (skge->duplex == DUPLEX_FULL)
			ctrl |= PHY_CT_DUP_MD;

		switch (skge->speed) {
		case SPEED_1000:
			ctrl |= PHY_CT_SP1000;
			break;
		case SPEED_100:
			ctrl |= PHY_CT_SP100;
			break;
		}

		ctrl |= PHY_CT_RESET;
	}

	gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);

	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);

	/* Enable phy interrupt on autonegotiation complete (or link up) */
	if (skge->autoneg == AUTONEG_ENABLE)
		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_MSK);
	else
		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK);
}

static void yukon_reset(struct skge_hw *hw, int port)
{
	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */
	gma_write16(hw, port, GM_MC_ADDR_H1, 0);	/* clear MC hash */
	gma_write16(hw, port, GM_MC_ADDR_H2, 0);
	gma_write16(hw, port, GM_MC_ADDR_H3, 0);
	gma_write16(hw, port, GM_MC_ADDR_H4, 0);

	gma_write16(hw, port, GM_RX_CTRL,
			 gma_read16(hw, port, GM_RX_CTRL)
			 | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
}

/* Apparently, early versions of Yukon-Lite had wrong chip_id? */
static int is_yukon_lite_a0(struct skge_hw *hw)
{
	u32 reg;
	int ret;

	if (hw->chip_id != CHIP_ID_YUKON)
		return 0;

	reg = skge_read32(hw, B2_FAR);
	skge_write8(hw, B2_FAR + 3, 0xff);
	ret = (skge_read8(hw, B2_FAR + 3) != 0);
	skge_write32(hw, B2_FAR, reg);
	return ret;
}

static void yukon_mac_init(struct skge_hw *hw, int port)
{
	struct skge_port *skge = netdev_priv(hw->dev[port]);
	int i;
	u32 reg;
	const u8 *addr = hw->dev[port]->dev_addr;

	/* WA code for COMA mode -- set PHY reset */
	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
		reg = skge_read32(hw, B2_GP_IO);
		reg |= GP_DIR_9 | GP_IO_9;
		skge_write32(hw, B2_GP_IO, reg);
	}

	/* hard reset */
	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);

	/* WA code for COMA mode -- clear PHY reset */
	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
		reg = skge_read32(hw, B2_GP_IO);
		reg |= GP_DIR_9;
		reg &= ~GP_IO_9;
		skge_write32(hw, B2_GP_IO, reg);
	}

	/* Set hardware config mode */
	reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
		GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE;
	reg |= hw->copper ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB;

	/* Clear GMC reset */
	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);

	if (skge->autoneg == AUTONEG_DISABLE) {
		reg = GM_GPCR_AU_ALL_DIS;
		gma_write16(hw, port, GM_GP_CTRL,
				 gma_read16(hw, port, GM_GP_CTRL) | reg);

		switch (skge->speed) {
		case SPEED_1000:
			reg &= ~GM_GPCR_SPEED_100;
			reg |= GM_GPCR_SPEED_1000;
			break;
		case SPEED_100:
			reg &= ~GM_GPCR_SPEED_1000;
			reg |= GM_GPCR_SPEED_100;
			break;
		case SPEED_10:
			reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
			break;
		}

		if (skge->duplex == DUPLEX_FULL)
			reg |= GM_GPCR_DUP_FULL;
	} else
		reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;

	switch (skge->flow_control) {
	case FLOW_MODE_NONE:
		skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
		reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
		break;
	case FLOW_MODE_LOC_SEND:
		/* disable Rx flow-control */
		reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
		break;
	case FLOW_MODE_SYMMETRIC:
	case FLOW_MODE_SYM_OR_REM:
		/* enable Tx & Rx flow-control */
		break;
	}

	gma_write16(hw, port, GM_GP_CTRL, reg);
	skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC));

	yukon_init(hw, port);

	/* MIB clear */
	reg = gma_read16(hw, port, GM_PHY_ADDR);
	gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);

	for (i = 0; i < GM_MIB_CNT_SIZE; i++)
		gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i);
	gma_write16(hw, port, GM_PHY_ADDR, reg);

	/* transmit control */
	gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));

	/* receive control reg: unicast + multicast + no FCS  */
	gma_write16(hw, port, GM_RX_CTRL,
			 GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);

	/* transmit flow control */
	gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);

	/* transmit parameter */
	gma_write16(hw, port, GM_TX_PARAM,
			 TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
			 TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
			 TX_IPG_JAM_DATA(TX_IPG_JAM_DEF));

	/* configure the Serial Mode Register */
	reg = DATA_BLIND_VAL(DATA_BLIND_DEF)
		| GM_SMOD_VLAN_ENA
		| IPG_DATA_VAL(IPG_DATA_DEF);

	if (hw->dev[port]->mtu > ETH_DATA_LEN)
		reg |= GM_SMOD_JUMBO_ENA;

	gma_write16(hw, port, GM_SERIAL_MODE, reg);

	/* physical address: used for pause frames */
	gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
	/* virtual address for data */
	gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);

	/* enable interrupt mask for counter overflows */
	gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
	gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
	gma_write16(hw, port, GM_TR_IRQ_MSK, 0);

	/* Initialize Mac Fifo */

	/* Configure Rx MAC FIFO */
	skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
	reg = GMF_OPER_ON | GMF_RX_F_FL_ON;

	/* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
	if (is_yukon_lite_a0(hw))
		reg &= ~GMF_RX_F_FL_ON;

	skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
	skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
	/*
	 * because Pause Packet Truncation in GMAC is not working
	 * we have to increase the Flush Threshold to 64 bytes
	 * in order to flush pause packets in Rx FIFO on Yukon-1
	 */
	skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1);

	/* Configure Tx MAC FIFO */
	skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
	skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
}

/* Go into power down mode */
static void yukon_suspend(struct skge_hw *hw, int port)
{
	u16 ctrl;

	ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
	ctrl |= PHY_M_PC_POL_R_DIS;
	gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);

	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
	ctrl |= PHY_CT_RESET;
	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);

	/* switch IEEE compatible power down mode on */
	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
	ctrl |= PHY_CT_PDOWN;
	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
}

static void yukon_stop(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;

	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
	yukon_reset(hw, port);

	gma_write16(hw, port, GM_GP_CTRL,
			 gma_read16(hw, port, GM_GP_CTRL)
			 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
	gma_read16(hw, port, GM_GP_CTRL);

	yukon_suspend(hw, port);

	/* set GPHY Control reset */
	skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
	skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
}

static void yukon_get_stats(struct skge_port *skge, u64 *data)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	int i;

	data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
		| gma_read32(hw, port, GM_TXO_OK_LO);
	data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
		| gma_read32(hw, port, GM_RXO_OK_LO);

	for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
		data[i] = gma_read32(hw, port,
					  skge_stats[i].gma_offset);
}

static void yukon_mac_intr(struct skge_hw *hw, int port)
{
	struct net_device *dev = hw->dev[port];
	struct skge_port *skge = netdev_priv(dev);
	u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC));

	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
		     "mac interrupt status 0x%x\n", status);

	if (status & GM_IS_RX_FF_OR) {
		++dev->stats.rx_fifo_errors;
		skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
	}

	if (status & GM_IS_TX_FF_UR) {
		++dev->stats.tx_fifo_errors;
		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
	}

}

static u16 yukon_speed(const struct skge_hw *hw, u16 aux)
{
	switch (aux & PHY_M_PS_SPEED_MSK) {
	case PHY_M_PS_SPEED_1000:
		return SPEED_1000;
	case PHY_M_PS_SPEED_100:
		return SPEED_100;
	default:
		return SPEED_10;
	}
}

static void yukon_link_up(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u16 reg;

	/* Enable Transmit FIFO Underrun */
	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);

	reg = gma_read16(hw, port, GM_GP_CTRL);
	if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
		reg |= GM_GPCR_DUP_FULL;

	/* enable Rx/Tx */
	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
	gma_write16(hw, port, GM_GP_CTRL, reg);

	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK);
	skge_link_up(skge);
}

static void yukon_link_down(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u16 ctrl;

	ctrl = gma_read16(hw, port, GM_GP_CTRL);
	ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
	gma_write16(hw, port, GM_GP_CTRL, ctrl);

	if (skge->flow_status == FLOW_STAT_REM_SEND) {
		ctrl = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
		ctrl |= PHY_M_AN_ASP;
		/* restore Asymmetric Pause bit */
		gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, ctrl);
	}

	skge_link_down(skge);

	yukon_init(hw, port);
}

static void yukon_phy_intr(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	const char *reason = NULL;
	u16 istatus, phystat;

	istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
	phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);

	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
		     "phy interrupt status 0x%x 0x%x\n", istatus, phystat);

	if (istatus & PHY_M_IS_AN_COMPL) {
		if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
		    & PHY_M_AN_RF) {
			reason = "remote fault";
			goto failed;
		}

		if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
			reason = "master/slave fault";
			goto failed;
		}

		if (!(phystat & PHY_M_PS_SPDUP_RES)) {
			reason = "speed/duplex";
			goto failed;
		}

		skge->duplex = (phystat & PHY_M_PS_FULL_DUP)
			? DUPLEX_FULL : DUPLEX_HALF;
		skge->speed = yukon_speed(hw, phystat);

		/* We are using IEEE 802.3z/D5.0 Table 37-4 */
		switch (phystat & PHY_M_PS_PAUSE_MSK) {
		case PHY_M_PS_PAUSE_MSK:
			skge->flow_status = FLOW_STAT_SYMMETRIC;
			break;
		case PHY_M_PS_RX_P_EN:
			skge->flow_status = FLOW_STAT_REM_SEND;
			break;
		case PHY_M_PS_TX_P_EN:
			skge->flow_status = FLOW_STAT_LOC_SEND;
			break;
		default:
			skge->flow_status = FLOW_STAT_NONE;
		}

		if (skge->flow_status == FLOW_STAT_NONE ||
		    (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF))
			skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
		else
			skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
		yukon_link_up(skge);
		return;
	}

	if (istatus & PHY_M_IS_LSP_CHANGE)
		skge->speed = yukon_speed(hw, phystat);

	if (istatus & PHY_M_IS_DUP_CHANGE)
		skge->duplex = (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
	if (istatus & PHY_M_IS_LST_CHANGE) {
		if (phystat & PHY_M_PS_LINK_UP)
			yukon_link_up(skge);
		else
			yukon_link_down(skge);
	}
	return;
 failed:
	pr_err("%s: autonegotiation failed (%s)\n", skge->netdev->name, reason);

	/* XXX restart autonegotiation? */
}

static void skge_phy_reset(struct skge_port *skge)
{
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	struct net_device *dev = hw->dev[port];

	netif_stop_queue(skge->netdev);
	netif_carrier_off(skge->netdev);

	spin_lock_bh(&hw->phy_lock);
	if (is_genesis(hw)) {
		genesis_reset(hw, port);
		genesis_mac_init(hw, port);
	} else {
		yukon_reset(hw, port);
		yukon_init(hw, port);
	}
	spin_unlock_bh(&hw->phy_lock);

	skge_set_multicast(dev);
}

/* Basic MII support */
static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct mii_ioctl_data *data = if_mii(ifr);
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int err = -EOPNOTSUPP;

	if (!netif_running(dev))
		return -ENODEV;	/* Phy still in reset */

	switch (cmd) {
	case SIOCGMIIPHY:
		data->phy_id = hw->phy_addr;

		fallthrough;
	case SIOCGMIIREG: {
		u16 val = 0;
		spin_lock_bh(&hw->phy_lock);

		if (is_genesis(hw))
			err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
		else
			err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
		spin_unlock_bh(&hw->phy_lock);
		data->val_out = val;
		break;
	}

	case SIOCSMIIREG:
		spin_lock_bh(&hw->phy_lock);
		if (is_genesis(hw))
			err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
				   data->val_in);
		else
			err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
				   data->val_in);
		spin_unlock_bh(&hw->phy_lock);
		break;
	}
	return err;
}

static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
{
	u32 end;

	start /= 8;
	len /= 8;
	end = start + len - 1;

	skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
	skge_write32(hw, RB_ADDR(q, RB_START), start);
	skge_write32(hw, RB_ADDR(q, RB_WP), start);
	skge_write32(hw, RB_ADDR(q, RB_RP), start);
	skge_write32(hw, RB_ADDR(q, RB_END), end);

	if (q == Q_R1 || q == Q_R2) {
		/* Set thresholds on receive queue's */
		skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
			     start + (2*len)/3);
		skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
			     start + (len/3));
	} else {
		/* Enable store & forward on Tx queue's because
		 * Tx FIFO is only 4K on Genesis and 1K on Yukon
		 */
		skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
	}

	skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
}

/* Setup Bus Memory Interface */
static void skge_qset(struct skge_port *skge, u16 q,
		      const struct skge_element *e)
{
	struct skge_hw *hw = skge->hw;
	u32 watermark = 0x600;
	u64 base = skge->dma + (e->desc - skge->mem);

	/* optimization to reduce window on 32bit/33mhz */
	if ((skge_read16(hw, B0_CTST) & (CS_BUS_CLOCK | CS_BUS_SLOT_SZ)) == 0)
		watermark /= 2;

	skge_write32(hw, Q_ADDR(q, Q_CSR), CSR_CLR_RESET);
	skge_write32(hw, Q_ADDR(q, Q_F), watermark);
	skge_write32(hw, Q_ADDR(q, Q_DA_H), (u32)(base >> 32));
	skge_write32(hw, Q_ADDR(q, Q_DA_L), (u32)base);
}

static int skge_up(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	u32 chunk, ram_addr;
	size_t rx_size, tx_size;
	int err;

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

	netif_info(skge, ifup, skge->netdev, "enabling interface\n");

	if (dev->mtu > RX_BUF_SIZE)
		skge->rx_buf_size = dev->mtu + ETH_HLEN;
	else
		skge->rx_buf_size = RX_BUF_SIZE;


	rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc);
	tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc);
	skge->mem_size = tx_size + rx_size;
	skge->mem = dma_alloc_coherent(&hw->pdev->dev, skge->mem_size,
				       &skge->dma, GFP_KERNEL);
	if (!skge->mem)
		return -ENOMEM;

	BUG_ON(skge->dma & 7);

	if (upper_32_bits(skge->dma) != upper_32_bits(skge->dma + skge->mem_size)) {
		dev_err(&hw->pdev->dev, "dma_alloc_coherent region crosses 4G boundary\n");
		err = -EINVAL;
		goto free_pci_mem;
	}

	err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma);
	if (err)
		goto free_pci_mem;

	err = skge_rx_fill(dev);
	if (err)
		goto free_rx_ring;

	err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size,
			      skge->dma + rx_size);
	if (err)
		goto free_rx_ring;

	if (hw->ports == 1) {
		err = request_irq(hw->pdev->irq, skge_intr, IRQF_SHARED,
				  dev->name, hw);
		if (err) {
			netdev_err(dev, "Unable to allocate interrupt %d error: %d\n",
				   hw->pdev->irq, err);
			goto free_tx_ring;
		}
	}

	/* Initialize MAC */
	netif_carrier_off(dev);
	spin_lock_bh(&hw->phy_lock);
	if (is_genesis(hw))
		genesis_mac_init(hw, port);
	else
		yukon_mac_init(hw, port);
	spin_unlock_bh(&hw->phy_lock);

	/* Configure RAMbuffers - equally between ports and tx/rx */
	chunk = (hw->ram_size  - hw->ram_offset) / (hw->ports * 2);
	ram_addr = hw->ram_offset + 2 * chunk * port;

	skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
	skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);

	BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean);
	skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk);
	skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);

	/* Start receiver BMU */
	wmb();
	skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
	skge_led(skge, LED_MODE_ON);

	spin_lock_irq(&hw->hw_lock);
	hw->intr_mask |= portmask[port];
	skge_write32(hw, B0_IMSK, hw->intr_mask);
	skge_read32(hw, B0_IMSK);
	spin_unlock_irq(&hw->hw_lock);

	napi_enable(&skge->napi);

	skge_set_multicast(dev);

	return 0;

 free_tx_ring:
	kfree(skge->tx_ring.start);
 free_rx_ring:
	skge_rx_clean(skge);
	kfree(skge->rx_ring.start);
 free_pci_mem:
	dma_free_coherent(&hw->pdev->dev, skge->mem_size, skge->mem,
			  skge->dma);
	skge->mem = NULL;

	return err;
}

/* stop receiver */
static void skge_rx_stop(struct skge_hw *hw, int port)
{
	skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP);
	skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL),
		     RB_RST_SET|RB_DIS_OP_MD);
	skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
}

static int skge_down(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int port = skge->port;

	if (!skge->mem)
		return 0;

	netif_info(skge, ifdown, skge->netdev, "disabling interface\n");

	netif_tx_disable(dev);

	if (is_genesis(hw) && hw->phy_type == SK_PHY_XMAC)
		del_timer_sync(&skge->link_timer);

	napi_disable(&skge->napi);
	netif_carrier_off(dev);

	spin_lock_irq(&hw->hw_lock);
	hw->intr_mask &= ~portmask[port];
	skge_write32(hw, B0_IMSK, (hw->ports == 1) ? 0 : hw->intr_mask);
	skge_read32(hw, B0_IMSK);
	spin_unlock_irq(&hw->hw_lock);

	if (hw->ports == 1)
		free_irq(hw->pdev->irq, hw);

	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_REG_OFF);
	if (is_genesis(hw))
		genesis_stop(skge);
	else
		yukon_stop(skge);

	/* Stop transmitter */
	skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
	skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
		     RB_RST_SET|RB_DIS_OP_MD);


	/* Disable Force Sync bit and Enable Alloc bit */
	skge_write8(hw, SK_REG(port, TXA_CTRL),
		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);

	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
	skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
	skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);

	/* Reset PCI FIFO */
	skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET);
	skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);

	/* Reset the RAM Buffer async Tx queue */
	skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET);

	skge_rx_stop(hw, port);

	if (is_genesis(hw)) {
		skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
		skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
	} else {
		skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
	}

	skge_led(skge, LED_MODE_OFF);

	netif_tx_lock_bh(dev);
	skge_tx_clean(dev);
	netif_tx_unlock_bh(dev);

	skge_rx_clean(skge);

	kfree(skge->rx_ring.start);
	kfree(skge->tx_ring.start);
	dma_free_coherent(&hw->pdev->dev, skge->mem_size, skge->mem,
			  skge->dma);
	skge->mem = NULL;
	return 0;
}

static inline int skge_avail(const struct skge_ring *ring)
{
	smp_mb();
	return ((ring->to_clean > ring->to_use) ? 0 : ring->count)
		+ (ring->to_clean - ring->to_use) - 1;
}

static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
				   struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	struct skge_element *e;
	struct skge_tx_desc *td;
	int i;
	u32 control, len;
	dma_addr_t map;

	if (skb_padto(skb, ETH_ZLEN))
		return NETDEV_TX_OK;

	if (unlikely(skge_avail(&skge->tx_ring) < skb_shinfo(skb)->nr_frags + 1))
		return NETDEV_TX_BUSY;

	e = skge->tx_ring.to_use;
	td = e->desc;
	BUG_ON(td->control & BMU_OWN);
	e->skb = skb;
	len = skb_headlen(skb);
	map = dma_map_single(&hw->pdev->dev, skb->data, len, DMA_TO_DEVICE);
	if (dma_mapping_error(&hw->pdev->dev, map))
		goto mapping_error;

	dma_unmap_addr_set(e, mapaddr, map);
	dma_unmap_len_set(e, maplen, len);

	td->dma_lo = lower_32_bits(map);
	td->dma_hi = upper_32_bits(map);

	if (skb->ip_summed == CHECKSUM_PARTIAL) {
		const int offset = skb_checksum_start_offset(skb);

		/* This seems backwards, but it is what the sk98lin
		 * does.  Looks like hardware is wrong?
		 */
		if (ipip_hdr(skb)->protocol == IPPROTO_UDP &&
		    hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
			control = BMU_TCP_CHECK;
		else
			control = BMU_UDP_CHECK;

		td->csum_offs = 0;
		td->csum_start = offset;
		td->csum_write = offset + skb->csum_offset;
	} else
		control = BMU_CHECK;

	if (!skb_shinfo(skb)->nr_frags) /* single buffer i.e. no fragments */
		control |= BMU_EOF | BMU_IRQ_EOF;
	else {
		struct skge_tx_desc *tf = td;

		control |= BMU_STFWD;
		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
			const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];

			map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
					       skb_frag_size(frag), DMA_TO_DEVICE);
			if (dma_mapping_error(&hw->pdev->dev, map))
				goto mapping_unwind;

			e = e->next;
			e->skb = skb;
			tf = e->desc;
			BUG_ON(tf->control & BMU_OWN);

			tf->dma_lo = lower_32_bits(map);
			tf->dma_hi = upper_32_bits(map);
			dma_unmap_addr_set(e, mapaddr, map);
			dma_unmap_len_set(e, maplen, skb_frag_size(frag));

			tf->control = BMU_OWN | BMU_SW | control | skb_frag_size(frag);
		}
		tf->control |= BMU_EOF | BMU_IRQ_EOF;
	}
	/* Make sure all the descriptors written */
	wmb();
	td->control = BMU_OWN | BMU_SW | BMU_STF | control | len;
	wmb();

	netdev_sent_queue(dev, skb->len);

	skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START);

	netif_printk(skge, tx_queued, KERN_DEBUG, skge->netdev,
		     "tx queued, slot %td, len %d\n",
		     e - skge->tx_ring.start, skb->len);

	skge->tx_ring.to_use = e->next;
	smp_wmb();

	if (skge_avail(&skge->tx_ring) <= TX_LOW_WATER) {
		netdev_dbg(dev, "transmit queue full\n");
		netif_stop_queue(dev);
	}

	return NETDEV_TX_OK;

mapping_unwind:
	e = skge->tx_ring.to_use;
	dma_unmap_single(&hw->pdev->dev, dma_unmap_addr(e, mapaddr),
			 dma_unmap_len(e, maplen), DMA_TO_DEVICE);
	while (i-- > 0) {
		e = e->next;
		dma_unmap_page(&hw->pdev->dev, dma_unmap_addr(e, mapaddr),
			       dma_unmap_len(e, maplen), DMA_TO_DEVICE);
	}

mapping_error:
	if (net_ratelimit())
		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
	dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
}


/* Free resources associated with this reing element */
static inline void skge_tx_unmap(struct pci_dev *pdev, struct skge_element *e,
				 u32 control)
{
	/* skb header vs. fragment */
	if (control & BMU_STF)
		dma_unmap_single(&pdev->dev, dma_unmap_addr(e, mapaddr),
				 dma_unmap_len(e, maplen), DMA_TO_DEVICE);
	else
		dma_unmap_page(&pdev->dev, dma_unmap_addr(e, mapaddr),
			       dma_unmap_len(e, maplen), DMA_TO_DEVICE);
}

/* Free all buffers in transmit ring */
static void skge_tx_clean(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_element *e;

	for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
		struct skge_tx_desc *td = e->desc;

		skge_tx_unmap(skge->hw->pdev, e, td->control);

		if (td->control & BMU_EOF)
			dev_kfree_skb(e->skb);
		td->control = 0;
	}

	netdev_reset_queue(dev);
	skge->tx_ring.to_clean = e;
}

static void skge_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
	struct skge_port *skge = netdev_priv(dev);

	netif_printk(skge, timer, KERN_DEBUG, skge->netdev, "tx timeout\n");

	skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP);
	skge_tx_clean(dev);
	netif_wake_queue(dev);
}

static int skge_change_mtu(struct net_device *dev, int new_mtu)
{
	int err;

	if (!netif_running(dev)) {
		dev->mtu = new_mtu;
		return 0;
	}

	skge_down(dev);

	dev->mtu = new_mtu;

	err = skge_up(dev);
	if (err)
		dev_close(dev);

	return err;
}

static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };

static void genesis_add_filter(u8 filter[8], const u8 *addr)
{
	u32 crc, bit;

	crc = ether_crc_le(ETH_ALEN, addr);
	bit = ~crc & 0x3f;
	filter[bit/8] |= 1 << (bit%8);
}

static void genesis_set_multicast(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	struct netdev_hw_addr *ha;
	u32 mode;
	u8 filter[8];

	mode = xm_read32(hw, port, XM_MODE);
	mode |= XM_MD_ENA_HASH;
	if (dev->flags & IFF_PROMISC)
		mode |= XM_MD_ENA_PROM;
	else
		mode &= ~XM_MD_ENA_PROM;

	if (dev->flags & IFF_ALLMULTI)
		memset(filter, 0xff, sizeof(filter));
	else {
		memset(filter, 0, sizeof(filter));

		if (skge->flow_status == FLOW_STAT_REM_SEND ||
		    skge->flow_status == FLOW_STAT_SYMMETRIC)
			genesis_add_filter(filter, pause_mc_addr);

		netdev_for_each_mc_addr(ha, dev)
			genesis_add_filter(filter, ha->addr);
	}

	xm_write32(hw, port, XM_MODE, mode);
	xm_outhash(hw, port, XM_HSM, filter);
}

static void yukon_add_filter(u8 filter[8], const u8 *addr)
{
	u32 bit = ether_crc(ETH_ALEN, addr) & 0x3f;

	filter[bit / 8] |= 1 << (bit % 8);
}

static void yukon_set_multicast(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	int port = skge->port;
	struct netdev_hw_addr *ha;
	int rx_pause = (skge->flow_status == FLOW_STAT_REM_SEND ||
			skge->flow_status == FLOW_STAT_SYMMETRIC);
	u16 reg;
	u8 filter[8];

	memset(filter, 0, sizeof(filter));

	reg = gma_read16(hw, port, GM_RX_CTRL);
	reg |= GM_RXCR_UCF_ENA;

	if (dev->flags & IFF_PROMISC) 		/* promiscuous */
		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
	else if (dev->flags & IFF_ALLMULTI)	/* all multicast */
		memset(filter, 0xff, sizeof(filter));
	else if (netdev_mc_empty(dev) && !rx_pause)/* no multicast */
		reg &= ~GM_RXCR_MCF_ENA;
	else {
		reg |= GM_RXCR_MCF_ENA;

		if (rx_pause)
			yukon_add_filter(filter, pause_mc_addr);

		netdev_for_each_mc_addr(ha, dev)
			yukon_add_filter(filter, ha->addr);
	}


	gma_write16(hw, port, GM_MC_ADDR_H1,
			 (u16)filter[0] | ((u16)filter[1] << 8));
	gma_write16(hw, port, GM_MC_ADDR_H2,
			 (u16)filter[2] | ((u16)filter[3] << 8));
	gma_write16(hw, port, GM_MC_ADDR_H3,
			 (u16)filter[4] | ((u16)filter[5] << 8));
	gma_write16(hw, port, GM_MC_ADDR_H4,
			 (u16)filter[6] | ((u16)filter[7] << 8));

	gma_write16(hw, port, GM_RX_CTRL, reg);
}

static inline u16 phy_length(const struct skge_hw *hw, u32 status)
{
	if (is_genesis(hw))
		return status >> XMR_FS_LEN_SHIFT;
	else
		return status >> GMR_FS_LEN_SHIFT;
}

static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
{
	if (is_genesis(hw))
		return (status & (XMR_FS_ERR | XMR_FS_2L_VLAN)) != 0;
	else
		return (status & GMR_FS_ANY_ERR) ||
			(status & GMR_FS_RX_OK) == 0;
}

static void skge_set_multicast(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);

	if (is_genesis(skge->hw))
		genesis_set_multicast(dev);
	else
		yukon_set_multicast(dev);

}


/* Get receive buffer from descriptor.
 * Handles copy of small buffers and reallocation failures
 */
static struct sk_buff *skge_rx_get(struct net_device *dev,
				   struct skge_element *e,
				   u32 control, u32 status, u16 csum)
{
	struct skge_port *skge = netdev_priv(dev);
	struct sk_buff *skb;
	u16 len = control & BMU_BBC;

	netif_printk(skge, rx_status, KERN_DEBUG, skge->netdev,
		     "rx slot %td status 0x%x len %d\n",
		     e - skge->rx_ring.start, status, len);

	if (len > skge->rx_buf_size)
		goto error;

	if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF))
		goto error;

	if (bad_phy_status(skge->hw, status))
		goto error;

	if (phy_length(skge->hw, status) != len)
		goto error;

	if (len < RX_COPY_THRESHOLD) {
		skb = netdev_alloc_skb_ip_align(dev, len);
		if (!skb)
			goto resubmit;

		dma_sync_single_for_cpu(&skge->hw->pdev->dev,
					dma_unmap_addr(e, mapaddr),
					dma_unmap_len(e, maplen),
					DMA_FROM_DEVICE);
		skb_copy_from_linear_data(e->skb, skb->data, len);
		dma_sync_single_for_device(&skge->hw->pdev->dev,
					   dma_unmap_addr(e, mapaddr),
					   dma_unmap_len(e, maplen),
					   DMA_FROM_DEVICE);
		skge_rx_reuse(e, skge->rx_buf_size);
	} else {
		struct skge_element ee;
		struct sk_buff *nskb;

		nskb = netdev_alloc_skb_ip_align(dev, skge->rx_buf_size);
		if (!nskb)
			goto resubmit;

		ee = *e;

		skb = ee.skb;
		prefetch(skb->data);

		if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) {
			dev_kfree_skb(nskb);
			goto resubmit;
		}

		dma_unmap_single(&skge->hw->pdev->dev,
				 dma_unmap_addr(&ee, mapaddr),
				 dma_unmap_len(&ee, maplen), DMA_FROM_DEVICE);
	}

	skb_put(skb, len);

	if (dev->features & NETIF_F_RXCSUM) {
		skb->csum = le16_to_cpu(csum);
		skb->ip_summed = CHECKSUM_COMPLETE;
	}

	skb->protocol = eth_type_trans(skb, dev);

	return skb;
error:

	netif_printk(skge, rx_err, KERN_DEBUG, skge->netdev,
		     "rx err, slot %td control 0x%x status 0x%x\n",
		     e - skge->rx_ring.start, control, status);

	if (is_genesis(skge->hw)) {
		if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
			dev->stats.rx_length_errors++;
		if (status & XMR_FS_FRA_ERR)
			dev->stats.rx_frame_errors++;
		if (status & XMR_FS_FCS_ERR)
			dev->stats.rx_crc_errors++;
	} else {
		if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
			dev->stats.rx_length_errors++;
		if (status & GMR_FS_FRAGMENT)
			dev->stats.rx_frame_errors++;
		if (status & GMR_FS_CRC_ERR)
			dev->stats.rx_crc_errors++;
	}

resubmit:
	skge_rx_reuse(e, skge->rx_buf_size);
	return NULL;
}

/* Free all buffers in Tx ring which are no longer owned by device */
static void skge_tx_done(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_ring *ring = &skge->tx_ring;
	struct skge_element *e;
	unsigned int bytes_compl = 0, pkts_compl = 0;

	skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);

	for (e = ring->to_clean; e != ring->to_use; e = e->next) {
		u32 control = ((const struct skge_tx_desc *) e->desc)->control;

		if (control & BMU_OWN)
			break;

		skge_tx_unmap(skge->hw->pdev, e, control);

		if (control & BMU_EOF) {
			netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev,
				     "tx done slot %td\n",
				     e - skge->tx_ring.start);

			pkts_compl++;
			bytes_compl += e->skb->len;

			dev_consume_skb_any(e->skb);
		}
	}
	netdev_completed_queue(dev, pkts_compl, bytes_compl);
	skge->tx_ring.to_clean = e;

	/* Can run lockless until we need to synchronize to restart queue. */
	smp_mb();

	if (unlikely(netif_queue_stopped(dev) &&
		     skge_avail(&skge->tx_ring) > TX_LOW_WATER)) {
		netif_tx_lock(dev);
		if (unlikely(netif_queue_stopped(dev) &&
			     skge_avail(&skge->tx_ring) > TX_LOW_WATER)) {
			netif_wake_queue(dev);

		}
		netif_tx_unlock(dev);
	}
}

static int skge_poll(struct napi_struct *napi, int budget)
{
	struct skge_port *skge = container_of(napi, struct skge_port, napi);
	struct net_device *dev = skge->netdev;
	struct skge_hw *hw = skge->hw;
	struct skge_ring *ring = &skge->rx_ring;
	struct skge_element *e;
	int work_done = 0;

	skge_tx_done(dev);

	skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);

	for (e = ring->to_clean; prefetch(e->next), work_done < budget; e = e->next) {
		struct skge_rx_desc *rd = e->desc;
		struct sk_buff *skb;
		u32 control;

		rmb();
		control = rd->control;
		if (control & BMU_OWN)
			break;

		skb = skge_rx_get(dev, e, control, rd->status, rd->csum2);
		if (likely(skb)) {
			napi_gro_receive(napi, skb);
			++work_done;
		}
	}
	ring->to_clean = e;

	/* restart receiver */
	wmb();
	skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START);

	if (work_done < budget && napi_complete_done(napi, work_done)) {
		unsigned long flags;

		spin_lock_irqsave(&hw->hw_lock, flags);
		hw->intr_mask |= napimask[skge->port];
		skge_write32(hw, B0_IMSK, hw->intr_mask);
		skge_read32(hw, B0_IMSK);
		spin_unlock_irqrestore(&hw->hw_lock, flags);
	}

	return work_done;
}

/* Parity errors seem to happen when Genesis is connected to a switch
 * with no other ports present. Heartbeat error??
 */
static void skge_mac_parity(struct skge_hw *hw, int port)
{
	struct net_device *dev = hw->dev[port];

	++dev->stats.tx_heartbeat_errors;

	if (is_genesis(hw))
		skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
			     MFF_CLR_PERR);
	else
		/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T),
			    (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
			    ? GMF_CLI_TX_FC : GMF_CLI_TX_PE);
}

static void skge_mac_intr(struct skge_hw *hw, int port)
{
	if (is_genesis(hw))
		genesis_mac_intr(hw, port);
	else
		yukon_mac_intr(hw, port);
}

/* Handle device specific framing and timeout interrupts */
static void skge_error_irq(struct skge_hw *hw)
{
	struct pci_dev *pdev = hw->pdev;
	u32 hwstatus = skge_read32(hw, B0_HWE_ISRC);

	if (is_genesis(hw)) {
		/* clear xmac errors */
		if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
			skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT);
		if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
			skge_write16(hw, RX_MFF_CTRL2, MFF_CLR_INSTAT);
	} else {
		/* Timestamp (unused) overflow */
		if (hwstatus & IS_IRQ_TIST_OV)
			skge_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
	}

	if (hwstatus & IS_RAM_RD_PAR) {
		dev_err(&pdev->dev, "Ram read data parity error\n");
		skge_write16(hw, B3_RI_CTRL, RI_CLR_RD_PERR);
	}

	if (hwstatus & IS_RAM_WR_PAR) {
		dev_err(&pdev->dev, "Ram write data parity error\n");
		skge_write16(hw, B3_RI_CTRL, RI_CLR_WR_PERR);
	}

	if (hwstatus & IS_M1_PAR_ERR)
		skge_mac_parity(hw, 0);

	if (hwstatus & IS_M2_PAR_ERR)
		skge_mac_parity(hw, 1);

	if (hwstatus & IS_R1_PAR_ERR) {
		dev_err(&pdev->dev, "%s: receive queue parity error\n",
			hw->dev[0]->name);
		skge_write32(hw, B0_R1_CSR, CSR_IRQ_CL_P);
	}

	if (hwstatus & IS_R2_PAR_ERR) {
		dev_err(&pdev->dev, "%s: receive queue parity error\n",
			hw->dev[1]->name);
		skge_write32(hw, B0_R2_CSR, CSR_IRQ_CL_P);
	}

	if (hwstatus & (IS_IRQ_MST_ERR|IS_IRQ_STAT)) {
		u16 pci_status, pci_cmd;

		pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
		pci_read_config_word(pdev, PCI_STATUS, &pci_status);

		dev_err(&pdev->dev, "PCI error cmd=%#x status=%#x\n",
			pci_cmd, pci_status);

		/* Write the error bits back to clear them. */
		pci_status &= PCI_STATUS_ERROR_BITS;
		skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
		pci_write_config_word(pdev, PCI_COMMAND,
				      pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
		pci_write_config_word(pdev, PCI_STATUS, pci_status);
		skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);

		/* if error still set then just ignore it */
		hwstatus = skge_read32(hw, B0_HWE_ISRC);
		if (hwstatus & IS_IRQ_STAT) {
			dev_warn(&hw->pdev->dev, "unable to clear error (so ignoring them)\n");
			hw->intr_mask &= ~IS_HW_ERR;
		}
	}
}

/*
 * Interrupt from PHY are handled in tasklet (softirq)
 * because accessing phy registers requires spin wait which might
 * cause excess interrupt latency.
 */
static void skge_extirq(struct tasklet_struct *t)
{
	struct skge_hw *hw = from_tasklet(hw, t, phy_task);
	int port;

	for (port = 0; port < hw->ports; port++) {
		struct net_device *dev = hw->dev[port];

		if (netif_running(dev)) {
			struct skge_port *skge = netdev_priv(dev);

			spin_lock(&hw->phy_lock);
			if (!is_genesis(hw))
				yukon_phy_intr(skge);
			else if (hw->phy_type == SK_PHY_BCOM)
				bcom_phy_intr(skge);
			spin_unlock(&hw->phy_lock);
		}
	}

	spin_lock_irq(&hw->hw_lock);
	hw->intr_mask |= IS_EXT_REG;
	skge_write32(hw, B0_IMSK, hw->intr_mask);
	skge_read32(hw, B0_IMSK);
	spin_unlock_irq(&hw->hw_lock);
}

static irqreturn_t skge_intr(int irq, void *dev_id)
{
	struct skge_hw *hw = dev_id;
	u32 status;
	int handled = 0;

	spin_lock(&hw->hw_lock);
	/* Reading this register masks IRQ */
	status = skge_read32(hw, B0_SP_ISRC);
	if (status == 0 || status == ~0)
		goto out;

	handled = 1;
	status &= hw->intr_mask;
	if (status & IS_EXT_REG) {
		hw->intr_mask &= ~IS_EXT_REG;
		tasklet_schedule(&hw->phy_task);
	}

	if (status & (IS_XA1_F|IS_R1_F)) {
		struct skge_port *skge = netdev_priv(hw->dev[0]);
		hw->intr_mask &= ~(IS_XA1_F|IS_R1_F);
		napi_schedule(&skge->napi);
	}

	if (status & IS_PA_TO_TX1)
		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1);

	if (status & IS_PA_TO_RX1) {
		++hw->dev[0]->stats.rx_over_errors;
		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1);
	}


	if (status & IS_MAC1)
		skge_mac_intr(hw, 0);

	if (hw->dev[1]) {
		struct skge_port *skge = netdev_priv(hw->dev[1]);

		if (status & (IS_XA2_F|IS_R2_F)) {
			hw->intr_mask &= ~(IS_XA2_F|IS_R2_F);
			napi_schedule(&skge->napi);
		}

		if (status & IS_PA_TO_RX2) {
			++hw->dev[1]->stats.rx_over_errors;
			skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2);
		}

		if (status & IS_PA_TO_TX2)
			skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX2);

		if (status & IS_MAC2)
			skge_mac_intr(hw, 1);
	}

	if (status & IS_HW_ERR)
		skge_error_irq(hw);
out:
	skge_write32(hw, B0_IMSK, hw->intr_mask);
	skge_read32(hw, B0_IMSK);
	spin_unlock(&hw->hw_lock);

	return IRQ_RETVAL(handled);
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void skge_netpoll(struct net_device *dev)
{
	struct skge_port *skge = netdev_priv(dev);

	disable_irq(dev->irq);
	skge_intr(dev->irq, skge->hw);
	enable_irq(dev->irq);
}
#endif

static int skge_set_mac_address(struct net_device *dev, void *p)
{
	struct skge_port *skge = netdev_priv(dev);
	struct skge_hw *hw = skge->hw;
	unsigned port = skge->port;
	const struct sockaddr *addr = p;
	u16 ctrl;

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

	eth_hw_addr_set(dev, addr->sa_data);

	if (!netif_running(dev)) {
		memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
		memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);
	} else {
		/* disable Rx */
		spin_lock_bh(&hw->phy_lock);
		ctrl = gma_read16(hw, port, GM_GP_CTRL);
		gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA);

		memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
		memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);

		if (is_genesis(hw))
			xm_outaddr(hw, port, XM_SA, dev->dev_addr);
		else {
			gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
			gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
		}

		gma_write16(hw, port, GM_GP_CTRL, ctrl);
		spin_unlock_bh(&hw->phy_lock);
	}

	return 0;
}

static const struct {
	u8 id;
	const char *name;
} skge_chips[] = {
	{ CHIP_ID_GENESIS,	"Genesis" },
	{ CHIP_ID_YUKON,	 "Yukon" },
	{ CHIP_ID_YUKON_LITE,	 "Yukon-Lite"},
	{ CHIP_ID_YUKON_LP,	 "Yukon-LP"},
};

static const char *skge_board_name(const struct skge_hw *hw)
{
	int i;
	static char buf[16];

	for (i = 0; i < ARRAY_SIZE(skge_chips); i++)
		if (skge_chips[i].id == hw->chip_id)
			return skge_chips[i].name;

	snprintf(buf, sizeof(buf), "chipid 0x%x", hw->chip_id);
	return buf;
}


/*
 * Setup the board data structure, but don't bring up
 * the port(s)
 */
static int skge_reset(struct skge_hw *hw)
{
	u32 reg;
	u16 ctst, pci_status;
	u8 t8, mac_cfg, pmd_type;
	int i;

	ctst = skge_read16(hw, B0_CTST);

	/* do a SW reset */
	skge_write8(hw, B0_CTST, CS_RST_SET);
	skge_write8(hw, B0_CTST, CS_RST_CLR);

	/* clear PCI errors, if any */
	skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
	skge_write8(hw, B2_TST_CTRL2, 0);

	pci_read_config_word(hw->pdev, PCI_STATUS, &pci_status);
	pci_write_config_word(hw->pdev, PCI_STATUS,
			      pci_status | PCI_STATUS_ERROR_BITS);
	skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
	skge_write8(hw, B0_CTST, CS_MRST_CLR);

	/* restore CLK_RUN bits (for Yukon-Lite) */
	skge_write16(hw, B0_CTST,
		     ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA));

	hw->chip_id = skge_read8(hw, B2_CHIP_ID);
	hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
	pmd_type = skge_read8(hw, B2_PMD_TYP);
	hw->copper = (pmd_type == 'T' || pmd_type == '1');

	switch (hw->chip_id) {
	case CHIP_ID_GENESIS:
#ifdef CONFIG_SKGE_GENESIS
		switch (hw->phy_type) {
		case SK_PHY_XMAC:
			hw->phy_addr = PHY_ADDR_XMAC;
			break;
		case SK_PHY_BCOM:
			hw->phy_addr = PHY_ADDR_BCOM;
			break;
		default:
			dev_err(&hw->pdev->dev, "unsupported phy type 0x%x\n",
			       hw->phy_type);
			return -EOPNOTSUPP;
		}
		break;
#else
		dev_err(&hw->pdev->dev, "Genesis chip detected but not configured\n");
		return -EOPNOTSUPP;
#endif

	case CHIP_ID_YUKON:
	case CHIP_ID_YUKON_LITE:
	case CHIP_ID_YUKON_LP:
		if (hw->phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S')
			hw->copper = 1;

		hw->phy_addr = PHY_ADDR_MARV;
		break;

	default:
		dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
		       hw->chip_id);
		return -EOPNOTSUPP;
	}

	mac_cfg = skge_read8(hw, B2_MAC_CFG);
	hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2;
	hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4;

	/* read the adapters RAM size */
	t8 = skge_read8(hw, B2_E_0);
	if (is_genesis(hw)) {
		if (t8 == 3) {
			/* special case: 4 x 64k x 36, offset = 0x80000 */
			hw->ram_size = 0x100000;
			hw->ram_offset = 0x80000;
		} else
			hw->ram_size = t8 * 512;
	} else if (t8 == 0)
		hw->ram_size = 0x20000;
	else
		hw->ram_size = t8 * 4096;

	hw->intr_mask = IS_HW_ERR;

	/* Use PHY IRQ for all but fiber based Genesis board */
	if (!(is_genesis(hw) && hw->phy_type == SK_PHY_XMAC))
		hw->intr_mask |= IS_EXT_REG;

	if (is_genesis(hw))
		genesis_init(hw);
	else {
		/* switch power to VCC (WA for VAUX problem) */
		skge_write8(hw, B0_POWER_CTRL,
			    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);

		/* avoid boards with stuck Hardware error bits */
		if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
		    (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
			dev_warn(&hw->pdev->dev, "stuck hardware sensor bit\n");
			hw->intr_mask &= ~IS_HW_ERR;
		}

		/* Clear PHY COMA */
		skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
		pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
		reg &= ~PCI_PHY_COMA;
		pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
		skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);


		for (i = 0; i < hw->ports; i++) {
			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
		}
	}

	/* turn off hardware timer (unused) */
	skge_write8(hw, B2_TI_CTRL, TIM_STOP);
	skge_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
	skge_write8(hw, B0_LED, LED_STAT_ON);

	/* enable the Tx Arbiters */
	for (i = 0; i < hw->ports; i++)
		skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);

	/* Initialize ram interface */
	skge_write16(hw, B3_RI_CTRL, RI_RST_CLR);

	skge_write8(hw, B3_RI_WTO_R1, SK_RI_TO_53);
	skge_write8(hw, B3_RI_WTO_XA1, SK_RI_TO_53);
	skge_write8(hw, B3_RI_WTO_XS1, SK_RI_TO_53);
	skge_write8(hw, B3_RI_RTO_R1, SK_RI_TO_53);
	skge_write8(hw, B3_RI_RTO_XA1, SK_RI_TO_53);
	skge_write8(hw, B3_RI_RTO_XS1, SK_RI_TO_53);
	skge_write8(hw, B3_RI_WTO_R2, SK_RI_TO_53);
	skge_write8(hw, B3_RI_WTO_XA2, SK_RI_TO_53);
	skge_write8(hw, B3_RI_WTO_XS2, SK_RI_TO_53);
	skge_write8(hw, B3_RI_RTO_R2, SK_RI_TO_53);
	skge_write8(hw, B3_RI_RTO_XA2, SK_RI_TO_53);
	skge_write8(hw, B3_RI_RTO_XS2, SK_RI_TO_53);

	skge_write32(hw, B0_HWE_IMSK, IS_ERR_MSK);

	/* Set interrupt moderation for Transmit only
	 * Receive interrupts avoided by NAPI
	 */
	skge_write32(hw, B2_IRQM_MSK, IS_XA1_F|IS_XA2_F);
	skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100));
	skge_write32(hw, B2_IRQM_CTRL, TIM_START);

	/* Leave irq disabled until first port is brought up. */
	skge_write32(hw, B0_IMSK, 0);

	for (i = 0; i < hw->ports; i++) {
		if (is_genesis(hw))
			genesis_reset(hw, i);
		else
			yukon_reset(hw, i);
	}

	return 0;
}


#ifdef CONFIG_SKGE_DEBUG

static struct dentry *skge_debug;

static int skge_debug_show(struct seq_file *seq, void *v)
{
	struct net_device *dev = seq->private;
	const struct skge_port *skge = netdev_priv(dev);
	const struct skge_hw *hw = skge->hw;
	const struct skge_element *e;

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

	seq_printf(seq, "IRQ src=%x mask=%x\n", skge_read32(hw, B0_ISRC),
		   skge_read32(hw, B0_IMSK));

	seq_printf(seq, "Tx Ring: (%d)\n", skge_avail(&skge->tx_ring));
	for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
		const struct skge_tx_desc *t = e->desc;
		seq_printf(seq, "%#x dma=%#x%08x %#x csum=%#x/%x/%x\n",
			   t->control, t->dma_hi, t->dma_lo, t->status,
			   t->csum_offs, t->csum_write, t->csum_start);
	}

	seq_puts(seq, "\nRx Ring:\n");
	for (e = skge->rx_ring.to_clean; ; e = e->next) {
		const struct skge_rx_desc *r = e->desc;

		if (r->control & BMU_OWN)
			break;

		seq_printf(seq, "%#x dma=%#x%08x %#x %#x csum=%#x/%x\n",
			   r->control, r->dma_hi, r->dma_lo, r->status,
			   r->timestamp, r->csum1, r->csum1_start);
	}

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(skge_debug);

/*
 * Use network device events to create/remove/rename
 * debugfs file entries
 */
static int skge_device_event(struct notifier_block *unused,
			     unsigned long event, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct skge_port *skge;

	if (dev->netdev_ops->ndo_open != &skge_up || !skge_debug)
		goto done;

	skge = netdev_priv(dev);
	switch (event) {
	case NETDEV_CHANGENAME:
		if (skge->debugfs)
			skge->debugfs = debugfs_rename(skge_debug,
						       skge->debugfs,
						       skge_debug, dev->name);
		break;

	case NETDEV_GOING_DOWN:
		debugfs_remove(skge->debugfs);
		skge->debugfs = NULL;
		break;

	case NETDEV_UP:
		skge->debugfs = debugfs_create_file(dev->name, 0444, skge_debug,
						    dev, &skge_debug_fops);
		break;
	}

done:
	return NOTIFY_DONE;
}

static struct notifier_block skge_notifier = {
	.notifier_call = skge_device_event,
};


static __init void skge_debug_init(void)
{
	skge_debug = debugfs_create_dir("skge", NULL);

	register_netdevice_notifier(&skge_notifier);
}

static __exit void skge_debug_cleanup(void)
{
	if (skge_debug) {
		unregister_netdevice_notifier(&skge_notifier);
		debugfs_remove(skge_debug);
		skge_debug = NULL;
	}
}

#else
#define skge_debug_init()
#define skge_debug_cleanup()
#endif

static const struct net_device_ops skge_netdev_ops = {
	.ndo_open		= skge_up,
	.ndo_stop		= skge_down,
	.ndo_start_xmit		= skge_xmit_frame,
	.ndo_eth_ioctl		= skge_ioctl,
	.ndo_get_stats		= skge_get_stats,
	.ndo_tx_timeout		= skge_tx_timeout,
	.ndo_change_mtu		= skge_change_mtu,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_rx_mode	= skge_set_multicast,
	.ndo_set_mac_address	= skge_set_mac_address,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= skge_netpoll,
#endif
};


/* Initialize network device */
static struct net_device *skge_devinit(struct skge_hw *hw, int port,
				       int highmem)
{
	struct skge_port *skge;
	struct net_device *dev = alloc_etherdev(sizeof(*skge));
	u8 addr[ETH_ALEN];

	if (!dev)
		return NULL;

	SET_NETDEV_DEV(dev, &hw->pdev->dev);
	dev->netdev_ops = &skge_netdev_ops;
	dev->ethtool_ops = &skge_ethtool_ops;
	dev->watchdog_timeo = TX_WATCHDOG;
	dev->irq = hw->pdev->irq;

	/* MTU range: 60 - 9000 */
	dev->min_mtu = ETH_ZLEN;
	dev->max_mtu = ETH_JUMBO_MTU;

	if (highmem)
		dev->features |= NETIF_F_HIGHDMA;

	skge = netdev_priv(dev);
	netif_napi_add(dev, &skge->napi, skge_poll);
	skge->netdev = dev;
	skge->hw = hw;
	skge->msg_enable = netif_msg_init(debug, default_msg);

	skge->tx_ring.count = DEFAULT_TX_RING_SIZE;
	skge->rx_ring.count = DEFAULT_RX_RING_SIZE;

	/* Auto speed and flow control */
	skge->autoneg = AUTONEG_ENABLE;
	skge->flow_control = FLOW_MODE_SYM_OR_REM;
	skge->duplex = -1;
	skge->speed = -1;
	skge->advertising = skge_supported_modes(hw);

	if (device_can_wakeup(&hw->pdev->dev)) {
		skge->wol = wol_supported(hw) & WAKE_MAGIC;
		device_set_wakeup_enable(&hw->pdev->dev, skge->wol);
	}

	hw->dev[port] = dev;

	skge->port = port;

	/* Only used for Genesis XMAC */
	if (is_genesis(hw))
		timer_setup(&skge->link_timer, xm_link_timer, 0);
	else {
		dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
		                   NETIF_F_RXCSUM;
		dev->features |= dev->hw_features;
	}

	/* read the mac address */
	memcpy_fromio(addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
	eth_hw_addr_set(dev, addr);

	return dev;
}

static void skge_show_addr(struct net_device *dev)
{
	const struct skge_port *skge = netdev_priv(dev);

	netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr);
}

static int only_32bit_dma;

static int skge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev, *dev1;
	struct skge_hw *hw;
	int err, using_dac = 0;

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "cannot enable PCI device\n");
		goto err_out;
	}

	err = pci_request_regions(pdev, DRV_NAME);
	if (err) {
		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
		goto err_out_disable_pdev;
	}

	pci_set_master(pdev);

	if (!only_32bit_dma && !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
		using_dac = 1;
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
	} else if (!(err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)))) {
		using_dac = 0;
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
	}

	if (err) {
		dev_err(&pdev->dev, "no usable DMA configuration\n");
		goto err_out_free_regions;
	}

#ifdef __BIG_ENDIAN
	/* byte swap descriptors in hardware */
	{
		u32 reg;

		pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
		reg |= PCI_REV_DESC;
		pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
	}
#endif

	err = -ENOMEM;
	/* space for skge@pci:0000:04:00.0 */
	hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
		     + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
	if (!hw)
		goto err_out_free_regions;

	sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));

	hw->pdev = pdev;
	spin_lock_init(&hw->hw_lock);
	spin_lock_init(&hw->phy_lock);
	tasklet_setup(&hw->phy_task, skge_extirq);

	hw->regs = ioremap(pci_resource_start(pdev, 0), 0x4000);
	if (!hw->regs) {
		dev_err(&pdev->dev, "cannot map device registers\n");
		goto err_out_free_hw;
	}

	err = skge_reset(hw);
	if (err)
		goto err_out_iounmap;

	pr_info("%s addr 0x%llx irq %d chip %s rev %d\n",
		DRV_VERSION,
		(unsigned long long)pci_resource_start(pdev, 0), pdev->irq,
		skge_board_name(hw), hw->chip_rev);

	dev = skge_devinit(hw, 0, using_dac);
	if (!dev) {
		err = -ENOMEM;
		goto err_out_led_off;
	}

	/* Some motherboards are broken and has zero in ROM. */
	if (!is_valid_ether_addr(dev->dev_addr))
		dev_warn(&pdev->dev, "bad (zero?) ethernet address in rom\n");

	err = register_netdev(dev);
	if (err) {
		dev_err(&pdev->dev, "cannot register net device\n");
		goto err_out_free_netdev;
	}

	skge_show_addr(dev);

	if (hw->ports > 1) {
		dev1 = skge_devinit(hw, 1, using_dac);
		if (!dev1) {
			err = -ENOMEM;
			goto err_out_unregister;
		}

		err = register_netdev(dev1);
		if (err) {
			dev_err(&pdev->dev, "cannot register second net device\n");
			goto err_out_free_dev1;
		}

		err = request_irq(pdev->irq, skge_intr, IRQF_SHARED,
				  hw->irq_name, hw);
		if (err) {
			dev_err(&pdev->dev, "cannot assign irq %d\n",
				pdev->irq);
			goto err_out_unregister_dev1;
		}

		skge_show_addr(dev1);
	}
	pci_set_drvdata(pdev, hw);

	return 0;

err_out_unregister_dev1:
	unregister_netdev(dev1);
err_out_free_dev1:
	free_netdev(dev1);
err_out_unregister:
	unregister_netdev(dev);
err_out_free_netdev:
	free_netdev(dev);
err_out_led_off:
	skge_write16(hw, B0_LED, LED_STAT_OFF);
err_out_iounmap:
	iounmap(hw->regs);
err_out_free_hw:
	kfree(hw);
err_out_free_regions:
	pci_release_regions(pdev);
err_out_disable_pdev:
	pci_disable_device(pdev);
err_out:
	return err;
}

static void skge_remove(struct pci_dev *pdev)
{
	struct skge_hw *hw  = pci_get_drvdata(pdev);
	struct net_device *dev0, *dev1;

	if (!hw)
		return;

	dev1 = hw->dev[1];
	if (dev1)
		unregister_netdev(dev1);
	dev0 = hw->dev[0];
	unregister_netdev(dev0);

	tasklet_kill(&hw->phy_task);

	spin_lock_irq(&hw->hw_lock);
	hw->intr_mask = 0;

	if (hw->ports > 1) {
		skge_write32(hw, B0_IMSK, 0);
		skge_read32(hw, B0_IMSK);
	}
	spin_unlock_irq(&hw->hw_lock);

	skge_write16(hw, B0_LED, LED_STAT_OFF);
	skge_write8(hw, B0_CTST, CS_RST_SET);

	if (hw->ports > 1)
		free_irq(pdev->irq, hw);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	if (dev1)
		free_netdev(dev1);
	free_netdev(dev0);

	iounmap(hw->regs);
	kfree(hw);
}

#ifdef CONFIG_PM_SLEEP
static int skge_suspend(struct device *dev)
{
	struct skge_hw *hw  = dev_get_drvdata(dev);
	int i;

	if (!hw)
		return 0;

	for (i = 0; i < hw->ports; i++) {
		struct net_device *dev = hw->dev[i];
		struct skge_port *skge = netdev_priv(dev);

		if (netif_running(dev))
			skge_down(dev);

		if (skge->wol)
			skge_wol_init(skge);
	}

	skge_write32(hw, B0_IMSK, 0);

	return 0;
}

static int skge_resume(struct device *dev)
{
	struct skge_hw *hw  = dev_get_drvdata(dev);
	int i, err;

	if (!hw)
		return 0;

	err = skge_reset(hw);
	if (err)
		goto out;

	for (i = 0; i < hw->ports; i++) {
		struct net_device *dev = hw->dev[i];

		if (netif_running(dev)) {
			err = skge_up(dev);

			if (err) {
				netdev_err(dev, "could not up: %d\n", err);
				dev_close(dev);
				goto out;
			}
		}
	}
out:
	return err;
}

static SIMPLE_DEV_PM_OPS(skge_pm_ops, skge_suspend, skge_resume);
#define SKGE_PM_OPS (&skge_pm_ops)

#else

#define SKGE_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */

static void skge_shutdown(struct pci_dev *pdev)
{
	struct skge_hw *hw  = pci_get_drvdata(pdev);
	int i;

	if (!hw)
		return;

	for (i = 0; i < hw->ports; i++) {
		struct net_device *dev = hw->dev[i];
		struct skge_port *skge = netdev_priv(dev);

		if (skge->wol)
			skge_wol_init(skge);
	}

	pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
	pci_set_power_state(pdev, PCI_D3hot);
}

static struct pci_driver skge_driver = {
	.name =         DRV_NAME,
	.id_table =     skge_id_table,
	.probe =        skge_probe,
	.remove =       skge_remove,
	.shutdown =	skge_shutdown,
	.driver.pm =	SKGE_PM_OPS,
};

static const struct dmi_system_id skge_32bit_dma_boards[] = {
	{
		.ident = "Gigabyte nForce boards",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"),
			DMI_MATCH(DMI_BOARD_NAME, "nForce"),
		},
	},
	{
		.ident = "ASUS P5NSLI",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
			DMI_MATCH(DMI_BOARD_NAME, "P5NSLI")
		},
	},
	{
		.ident = "FUJITSU SIEMENS A8NE-FM",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
			DMI_MATCH(DMI_BOARD_NAME, "A8NE-FM")
		},
	},
	{}
};

static int __init skge_init_module(void)
{
	if (dmi_check_system(skge_32bit_dma_boards))
		only_32bit_dma = 1;
	skge_debug_init();
	return pci_register_driver(&skge_driver);
}

static void __exit skge_cleanup_module(void)
{
	pci_unregister_driver(&skge_driver);
	skge_debug_cleanup();
}

module_init(skge_init_module);
module_exit(skge_cleanup_module);
