// SPDX-License-Identifier: GPL-2.0-only
/*****************************************************************************
 *                                                                           *
 * File: subr.c                                                              *
 * $Revision: 1.27 $                                                         *
 * $Date: 2005/06/22 01:08:36 $                                              *
 * Description:                                                              *
 *  Various subroutines (intr,pio,etc.) used by Chelsio 10G Ethernet driver. *
 *  part of the Chelsio 10Gb Ethernet Driver.                                *
 *                                                                           *
 *                                                                           *
 * http://www.chelsio.com                                                    *
 *                                                                           *
 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc.                    *
 * All rights reserved.                                                      *
 *                                                                           *
 * Maintainers: maintainers@chelsio.com                                      *
 *                                                                           *
 * Authors: Dimitrios Michailidis   <dm@chelsio.com>                         *
 *          Tina Yang               <tainay@chelsio.com>                     *
 *          Felix Marti             <felix@chelsio.com>                      *
 *          Scott Bardone           <sbardone@chelsio.com>                   *
 *          Kurt Ottaway            <kottaway@chelsio.com>                   *
 *          Frank DiMambro          <frank@chelsio.com>                      *
 *                                                                           *
 * History:                                                                  *
 *                                                                           *
 ****************************************************************************/

#include "common.h"
#include "elmer0.h"
#include "regs.h"
#include "gmac.h"
#include "cphy.h"
#include "sge.h"
#include "tp.h"
#include "espi.h"

/**
 *	t1_wait_op_done - wait until an operation is completed
 *	@adapter: the adapter performing the operation
 *	@reg: the register to check for completion
 *	@mask: a single-bit field within @reg that indicates completion
 *	@polarity: the value of the field when the operation is completed
 *	@attempts: number of check iterations
 *      @delay: delay in usecs between iterations
 *
 *	Wait until an operation is completed by checking a bit in a register
 *	up to @attempts times.  Returns %0 if the operation completes and %1
 *	otherwise.
 */
static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity,
			   int attempts, int delay)
{
	while (1) {
		u32 val = readl(adapter->regs + reg) & mask;

		if (!!val == polarity)
			return 0;
		if (--attempts == 0)
			return 1;
		if (delay)
			udelay(delay);
	}
}

#define TPI_ATTEMPTS 50

/*
 * Write a register over the TPI interface (unlocked and locked versions).
 */
int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
{
	int tpi_busy;

	writel(addr, adapter->regs + A_TPI_ADDR);
	writel(value, adapter->regs + A_TPI_WR_DATA);
	writel(F_TPIWR, adapter->regs + A_TPI_CSR);

	tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
				   TPI_ATTEMPTS, 3);
	if (tpi_busy)
		pr_alert("%s: TPI write to 0x%x failed\n",
			 adapter->name, addr);
	return tpi_busy;
}

int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
{
	int ret;

	spin_lock(&adapter->tpi_lock);
	ret = __t1_tpi_write(adapter, addr, value);
	spin_unlock(&adapter->tpi_lock);
	return ret;
}

/*
 * Read a register over the TPI interface (unlocked and locked versions).
 */
int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
{
	int tpi_busy;

	writel(addr, adapter->regs + A_TPI_ADDR);
	writel(0, adapter->regs + A_TPI_CSR);

	tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
				   TPI_ATTEMPTS, 3);
	if (tpi_busy)
		pr_alert("%s: TPI read from 0x%x failed\n",
			 adapter->name, addr);
	else
		*valp = readl(adapter->regs + A_TPI_RD_DATA);
	return tpi_busy;
}

int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
{
	int ret;

	spin_lock(&adapter->tpi_lock);
	ret = __t1_tpi_read(adapter, addr, valp);
	spin_unlock(&adapter->tpi_lock);
	return ret;
}

/*
 * Set a TPI parameter.
 */
static void t1_tpi_par(adapter_t *adapter, u32 value)
{
	writel(V_TPIPAR(value), adapter->regs + A_TPI_PAR);
}

/*
 * Called when a port's link settings change to propagate the new values to the
 * associated PHY and MAC.  After performing the common tasks it invokes an
 * OS-specific handler.
 */
void t1_link_changed(adapter_t *adapter, int port_id)
{
	int link_ok, speed, duplex, fc;
	struct cphy *phy = adapter->port[port_id].phy;
	struct link_config *lc = &adapter->port[port_id].link_config;

	phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);

	lc->speed = speed < 0 ? SPEED_INVALID : speed;
	lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
	if (!(lc->requested_fc & PAUSE_AUTONEG))
		fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);

	if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
		/* Set MAC speed, duplex, and flow control to match PHY. */
		struct cmac *mac = adapter->port[port_id].mac;

		mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc);
		lc->fc = (unsigned char)fc;
	}
	t1_link_negotiated(adapter, port_id, link_ok, speed, duplex, fc);
}

static bool t1_pci_intr_handler(adapter_t *adapter)
{
	u32 pcix_cause;

	pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause);

	if (pcix_cause) {
		pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE,
				       pcix_cause);
		/* PCI errors are fatal */
		t1_interrupts_disable(adapter);
		adapter->pending_thread_intr |= F_PL_INTR_SGE_ERR;
		pr_alert("%s: PCI error encountered.\n", adapter->name);
		return true;
	}
	return false;
}

#ifdef CONFIG_CHELSIO_T1_1G
#include "fpga_defs.h"

/*
 * PHY interrupt handler for FPGA boards.
 */
static int fpga_phy_intr_handler(adapter_t *adapter)
{
	int p;
	u32 cause = readl(adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);

	for_each_port(adapter, p)
		if (cause & (1 << p)) {
			struct cphy *phy = adapter->port[p].phy;
			int phy_cause = phy->ops->interrupt_handler(phy);

			if (phy_cause & cphy_cause_link_change)
				t1_link_changed(adapter, p);
		}
	writel(cause, adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
	return 0;
}

/*
 * Slow path interrupt handler for FPGAs.
 */
static irqreturn_t fpga_slow_intr(adapter_t *adapter)
{
	u32 cause = readl(adapter->regs + A_PL_CAUSE);
	irqreturn_t ret = IRQ_NONE;

	cause &= ~F_PL_INTR_SGE_DATA;
	if (cause & F_PL_INTR_SGE_ERR) {
		if (t1_sge_intr_error_handler(adapter->sge))
			ret = IRQ_WAKE_THREAD;
	}

	if (cause & FPGA_PCIX_INTERRUPT_GMAC)
		fpga_phy_intr_handler(adapter);

	if (cause & FPGA_PCIX_INTERRUPT_TP) {
		/*
		 * FPGA doesn't support MC4 interrupts and it requires
		 * this odd layer of indirection for MC5.
		 */
		u32 tp_cause = readl(adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE);

		/* Clear TP interrupt */
		writel(tp_cause, adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE);
	}
	if (cause & FPGA_PCIX_INTERRUPT_PCIX) {
		if (t1_pci_intr_handler(adapter))
			ret = IRQ_WAKE_THREAD;
	}

	/* Clear the interrupts just processed. */
	if (cause)
		writel(cause, adapter->regs + A_PL_CAUSE);

	if (ret != IRQ_NONE)
		return ret;

	return cause == 0 ? IRQ_NONE : IRQ_HANDLED;
}
#endif

/*
 * Wait until Elmer's MI1 interface is ready for new operations.
 */
static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg)
{
	int attempts = 100, busy;

	do {
		u32 val;

		__t1_tpi_read(adapter, mi1_reg, &val);
		busy = val & F_MI1_OP_BUSY;
		if (busy)
			udelay(10);
	} while (busy && --attempts);
	if (busy)
		pr_alert("%s: MDIO operation timed out\n", adapter->name);
	return busy;
}

/*
 * MI1 MDIO initialization.
 */
static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
{
	u32 clkdiv = bi->clock_elmer0 / (2 * bi->mdio_mdc) - 1;
	u32 val = F_MI1_PREAMBLE_ENABLE | V_MI1_MDI_INVERT(bi->mdio_mdiinv) |
		V_MI1_MDI_ENABLE(bi->mdio_mdien) | V_MI1_CLK_DIV(clkdiv);

	if (!(bi->caps & SUPPORTED_10000baseT_Full))
		val |= V_MI1_SOF(1);
	t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val);
}

#if defined(CONFIG_CHELSIO_T1_1G)
/*
 * Elmer MI1 MDIO read/write operations.
 */
static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr,
			 u16 reg_addr)
{
	struct adapter *adapter = dev->ml_priv;
	u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
	unsigned int val;

	spin_lock(&adapter->tpi_lock);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
	__t1_tpi_write(adapter,
			A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
	mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
	__t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
	spin_unlock(&adapter->tpi_lock);
	return val;
}

static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
			  u16 reg_addr, u16 val)
{
	struct adapter *adapter = dev->ml_priv;
	u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);

	spin_lock(&adapter->tpi_lock);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
	__t1_tpi_write(adapter,
			A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_WRITE);
	mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
	spin_unlock(&adapter->tpi_lock);
	return 0;
}

static const struct mdio_ops mi1_mdio_ops = {
	.init = mi1_mdio_init,
	.read = mi1_mdio_read,
	.write = mi1_mdio_write,
	.mode_support = MDIO_SUPPORTS_C22
};

#endif

static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
			     u16 reg_addr)
{
	struct adapter *adapter = dev->ml_priv;
	u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
	unsigned int val;

	spin_lock(&adapter->tpi_lock);

	/* Write the address we want. */
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
		       MI1_OP_INDIRECT_ADDRESS);
	mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);

	/* Write the operation we want. */
	__t1_tpi_write(adapter,
			A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ);
	mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);

	/* Read the data. */
	__t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
	spin_unlock(&adapter->tpi_lock);
	return val;
}

static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr,
			      int mmd_addr, u16 reg_addr, u16 val)
{
	struct adapter *adapter = dev->ml_priv;
	u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);

	spin_lock(&adapter->tpi_lock);

	/* Write the address we want. */
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
		       MI1_OP_INDIRECT_ADDRESS);
	mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);

	/* Write the data. */
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
	__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE);
	mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
	spin_unlock(&adapter->tpi_lock);
	return 0;
}

static const struct mdio_ops mi1_mdio_ext_ops = {
	.init = mi1_mdio_init,
	.read = mi1_mdio_ext_read,
	.write = mi1_mdio_ext_write,
	.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
};

enum {
	CH_BRD_T110_1CU,
	CH_BRD_N110_1F,
	CH_BRD_N210_1F,
	CH_BRD_T210_1F,
	CH_BRD_T210_1CU,
	CH_BRD_N204_4CU,
};

static const struct board_info t1_board[] = {
	{
		.board		= CHBT_BOARD_CHT110,
		.port_number	= 1,
		.caps		= SUPPORTED_10000baseT_Full,
		.chip_term	= CHBT_TERM_T1,
		.chip_mac	= CHBT_MAC_PM3393,
		.chip_phy	= CHBT_PHY_MY3126,
		.clock_core	= 125000000,
		.clock_mc3	= 150000000,
		.clock_mc4	= 125000000,
		.espi_nports	= 1,
		.clock_elmer0	= 44,
		.mdio_mdien	= 1,
		.mdio_mdiinv	= 1,
		.mdio_mdc	= 1,
		.mdio_phybaseaddr = 1,
		.gmac		= &t1_pm3393_ops,
		.gphy		= &t1_my3126_ops,
		.mdio_ops	= &mi1_mdio_ext_ops,
		.desc		= "Chelsio T110 1x10GBase-CX4 TOE",
	},

	{
		.board		= CHBT_BOARD_N110,
		.port_number	= 1,
		.caps		= SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
		.chip_term	= CHBT_TERM_T1,
		.chip_mac	= CHBT_MAC_PM3393,
		.chip_phy	= CHBT_PHY_88X2010,
		.clock_core	= 125000000,
		.espi_nports	= 1,
		.clock_elmer0	= 44,
		.mdio_mdien	= 0,
		.mdio_mdiinv	= 0,
		.mdio_mdc	= 1,
		.mdio_phybaseaddr = 0,
		.gmac		= &t1_pm3393_ops,
		.gphy		= &t1_mv88x201x_ops,
		.mdio_ops	= &mi1_mdio_ext_ops,
		.desc		= "Chelsio N110 1x10GBaseX NIC",
	},

	{
		.board		= CHBT_BOARD_N210,
		.port_number	= 1,
		.caps		= SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
		.chip_term	= CHBT_TERM_T2,
		.chip_mac	= CHBT_MAC_PM3393,
		.chip_phy	= CHBT_PHY_88X2010,
		.clock_core	= 125000000,
		.espi_nports	= 1,
		.clock_elmer0	= 44,
		.mdio_mdien	= 0,
		.mdio_mdiinv	= 0,
		.mdio_mdc	= 1,
		.mdio_phybaseaddr = 0,
		.gmac		= &t1_pm3393_ops,
		.gphy		= &t1_mv88x201x_ops,
		.mdio_ops	= &mi1_mdio_ext_ops,
		.desc		= "Chelsio N210 1x10GBaseX NIC",
	},

	{
		.board		= CHBT_BOARD_CHT210,
		.port_number	= 1,
		.caps		= SUPPORTED_10000baseT_Full,
		.chip_term	= CHBT_TERM_T2,
		.chip_mac	= CHBT_MAC_PM3393,
		.chip_phy	= CHBT_PHY_88X2010,
		.clock_core	= 125000000,
		.clock_mc3	= 133000000,
		.clock_mc4	= 125000000,
		.espi_nports	= 1,
		.clock_elmer0	= 44,
		.mdio_mdien	= 0,
		.mdio_mdiinv	= 0,
		.mdio_mdc	= 1,
		.mdio_phybaseaddr = 0,
		.gmac		= &t1_pm3393_ops,
		.gphy		= &t1_mv88x201x_ops,
		.mdio_ops	= &mi1_mdio_ext_ops,
		.desc		= "Chelsio T210 1x10GBaseX TOE",
	},

	{
		.board		= CHBT_BOARD_CHT210,
		.port_number	= 1,
		.caps		= SUPPORTED_10000baseT_Full,
		.chip_term	= CHBT_TERM_T2,
		.chip_mac	= CHBT_MAC_PM3393,
		.chip_phy	= CHBT_PHY_MY3126,
		.clock_core	= 125000000,
		.clock_mc3	= 133000000,
		.clock_mc4	= 125000000,
		.espi_nports	= 1,
		.clock_elmer0	= 44,
		.mdio_mdien	= 1,
		.mdio_mdiinv	= 1,
		.mdio_mdc	= 1,
		.mdio_phybaseaddr = 1,
		.gmac		= &t1_pm3393_ops,
		.gphy		= &t1_my3126_ops,
		.mdio_ops	= &mi1_mdio_ext_ops,
		.desc		= "Chelsio T210 1x10GBase-CX4 TOE",
	},

#ifdef CONFIG_CHELSIO_T1_1G
	{
		.board		= CHBT_BOARD_CHN204,
		.port_number	= 4,
		.caps		= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full
				| SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full
				| SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
				  SUPPORTED_PAUSE | SUPPORTED_TP,
		.chip_term	= CHBT_TERM_T2,
		.chip_mac	= CHBT_MAC_VSC7321,
		.chip_phy	= CHBT_PHY_88E1111,
		.clock_core	= 100000000,
		.espi_nports	= 4,
		.clock_elmer0	= 44,
		.mdio_mdien	= 0,
		.mdio_mdiinv	= 0,
		.mdio_mdc	= 0,
		.mdio_phybaseaddr = 4,
		.gmac		= &t1_vsc7326_ops,
		.gphy		= &t1_mv88e1xxx_ops,
		.mdio_ops	= &mi1_mdio_ops,
		.desc		= "Chelsio N204 4x100/1000BaseT NIC",
	},
#endif

};

const struct pci_device_id t1_pci_tbl[] = {
	CH_DEVICE(8, 0, CH_BRD_T110_1CU),
	CH_DEVICE(8, 1, CH_BRD_T110_1CU),
	CH_DEVICE(7, 0, CH_BRD_N110_1F),
	CH_DEVICE(10, 1, CH_BRD_N210_1F),
	CH_DEVICE(11, 1, CH_BRD_T210_1F),
	CH_DEVICE(14, 1, CH_BRD_T210_1CU),
	CH_DEVICE(16, 1, CH_BRD_N204_4CU),
	{ 0 }
};

MODULE_DEVICE_TABLE(pci, t1_pci_tbl);

/*
 * Return the board_info structure with a given index.  Out-of-range indices
 * return NULL.
 */
const struct board_info *t1_get_board_info(unsigned int board_id)
{
	return board_id < ARRAY_SIZE(t1_board) ? &t1_board[board_id] : NULL;
}

struct chelsio_vpd_t {
	u32 format_version;
	u8 serial_number[16];
	u8 mac_base_address[6];
	u8 pad[2];           /* make multiple-of-4 size requirement explicit */
};

#define EEPROMSIZE        (8 * 1024)
#define EEPROM_MAX_POLL   4

/*
 * Read SEEPROM. A zero is written to the flag register when the address is
 * written to the Control register. The hardware device will set the flag to a
 * one when 4B have been transferred to the Data register.
 */
int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data)
{
	int i = EEPROM_MAX_POLL;
	u16 val;
	u32 v;

	if (addr >= EEPROMSIZE || (addr & 3))
		return -EINVAL;

	pci_write_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, (u16)addr);
	do {
		udelay(50);
		pci_read_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, &val);
	} while (!(val & F_VPD_OP_FLAG) && --i);

	if (!(val & F_VPD_OP_FLAG)) {
		pr_err("%s: reading EEPROM address 0x%x failed\n",
		       adapter->name, addr);
		return -EIO;
	}
	pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, &v);
	*data = cpu_to_le32(v);
	return 0;
}

static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd)
{
	int addr, ret = 0;

	for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32))
		ret = t1_seeprom_read(adapter, addr,
				      (__le32 *)((u8 *)vpd + addr));

	return ret;
}

/*
 * Read a port's MAC address from the VPD ROM.
 */
static int vpd_macaddress_get(adapter_t *adapter, int index, u8 mac_addr[])
{
	struct chelsio_vpd_t vpd;

	if (t1_eeprom_vpd_get(adapter, &vpd))
		return 1;
	memcpy(mac_addr, vpd.mac_base_address, 5);
	mac_addr[5] = vpd.mac_base_address[5] + index;
	return 0;
}

/*
 * Set up the MAC/PHY according to the requested link settings.
 *
 * If the PHY can auto-negotiate first decide what to advertise, then
 * enable/disable auto-negotiation as desired and reset.
 *
 * If the PHY does not auto-negotiate we just reset it.
 *
 * If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
 * otherwise do it later based on the outcome of auto-negotiation.
 */
int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
{
	unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);

	if (lc->supported & SUPPORTED_Autoneg) {
		lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE);
		if (fc) {
			if (fc == ((PAUSE_RX | PAUSE_TX) &
				   (mac->adapter->params.nports < 2)))
				lc->advertising |= ADVERTISED_PAUSE;
			else {
				lc->advertising |= ADVERTISED_ASYM_PAUSE;
				if (fc == PAUSE_RX)
					lc->advertising |= ADVERTISED_PAUSE;
			}
		}
		phy->ops->advertise(phy, lc->advertising);

		if (lc->autoneg == AUTONEG_DISABLE) {
			lc->speed = lc->requested_speed;
			lc->duplex = lc->requested_duplex;
			lc->fc = (unsigned char)fc;
			mac->ops->set_speed_duplex_fc(mac, lc->speed,
						      lc->duplex, fc);
			/* Also disables autoneg */
			phy->state = PHY_AUTONEG_RDY;
			phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
			phy->ops->reset(phy, 0);
		} else {
			phy->state = PHY_AUTONEG_EN;
			phy->ops->autoneg_enable(phy); /* also resets PHY */
		}
	} else {
		phy->state = PHY_AUTONEG_RDY;
		mac->ops->set_speed_duplex_fc(mac, -1, -1, fc);
		lc->fc = (unsigned char)fc;
		phy->ops->reset(phy, 0);
	}
	return 0;
}

/*
 * External interrupt handler for boards using elmer0.
 */
int t1_elmer0_ext_intr_handler(adapter_t *adapter)
{
	struct cphy *phy;
	int phy_cause;
	u32 cause;

	t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause);

	switch (board_info(adapter)->board) {
#ifdef CONFIG_CHELSIO_T1_1G
	case CHBT_BOARD_CHT204:
	case CHBT_BOARD_CHT204E:
	case CHBT_BOARD_CHN204:
	case CHBT_BOARD_CHT204V: {
		int i, port_bit;
		for_each_port(adapter, i) {
			port_bit = i + 1;
			if (!(cause & (1 << port_bit)))
				continue;

			phy = adapter->port[i].phy;
			phy_cause = phy->ops->interrupt_handler(phy);
			if (phy_cause & cphy_cause_link_change)
				t1_link_changed(adapter, i);
		}
		break;
	}
	case CHBT_BOARD_CHT101:
		if (cause & ELMER0_GP_BIT1) { /* Marvell 88E1111 interrupt */
			phy = adapter->port[0].phy;
			phy_cause = phy->ops->interrupt_handler(phy);
			if (phy_cause & cphy_cause_link_change)
				t1_link_changed(adapter, 0);
		}
		break;
	case CHBT_BOARD_7500: {
		int p;
		/*
		 * Elmer0's interrupt cause isn't useful here because there is
		 * only one bit that can be set for all 4 ports.  This means
		 * we are forced to check every PHY's interrupt status
		 * register to see who initiated the interrupt.
		 */
		for_each_port(adapter, p) {
			phy = adapter->port[p].phy;
			phy_cause = phy->ops->interrupt_handler(phy);
			if (phy_cause & cphy_cause_link_change)
			    t1_link_changed(adapter, p);
		}
		break;
	}
#endif
	case CHBT_BOARD_CHT210:
	case CHBT_BOARD_N210:
	case CHBT_BOARD_N110:
		if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */
			phy = adapter->port[0].phy;
			phy_cause = phy->ops->interrupt_handler(phy);
			if (phy_cause & cphy_cause_link_change)
				t1_link_changed(adapter, 0);
		}
		break;
	case CHBT_BOARD_8000:
	case CHBT_BOARD_CHT110:
		if (netif_msg_intr(adapter))
			dev_dbg(&adapter->pdev->dev,
				"External interrupt cause 0x%x\n", cause);
		if (cause & ELMER0_GP_BIT1) {        /* PMC3393 INTB */
			struct cmac *mac = adapter->port[0].mac;

			mac->ops->interrupt_handler(mac);
		}
		if (cause & ELMER0_GP_BIT5) {        /* XPAK MOD_DETECT */
			u32 mod_detect;

			t1_tpi_read(adapter,
					A_ELMER0_GPI_STAT, &mod_detect);
			if (netif_msg_link(adapter))
				dev_info(&adapter->pdev->dev, "XPAK %s\n",
					 mod_detect ? "removed" : "inserted");
		}
		break;
	}
	t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause);
	return 0;
}

/* Enables all interrupts. */
void t1_interrupts_enable(adapter_t *adapter)
{
	unsigned int i;

	adapter->slow_intr_mask = F_PL_INTR_SGE_ERR | F_PL_INTR_TP;

	t1_sge_intr_enable(adapter->sge);
	t1_tp_intr_enable(adapter->tp);
	if (adapter->espi) {
		adapter->slow_intr_mask |= F_PL_INTR_ESPI;
		t1_espi_intr_enable(adapter->espi);
	}

	/* Enable MAC/PHY interrupts for each port. */
	for_each_port(adapter, i) {
		adapter->port[i].mac->ops->interrupt_enable(adapter->port[i].mac);
		adapter->port[i].phy->ops->interrupt_enable(adapter->port[i].phy);
	}

	/* Enable PCIX & external chip interrupts on ASIC boards. */
	if (t1_is_asic(adapter)) {
		u32 pl_intr = readl(adapter->regs + A_PL_ENABLE);

		/* PCI-X interrupts */
		pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE,
				       0xffffffff);

		adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
		pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
		writel(pl_intr, adapter->regs + A_PL_ENABLE);
	}
}

/* Disables all interrupts. */
void t1_interrupts_disable(adapter_t* adapter)
{
	unsigned int i;

	t1_sge_intr_disable(adapter->sge);
	t1_tp_intr_disable(adapter->tp);
	if (adapter->espi)
		t1_espi_intr_disable(adapter->espi);

	/* Disable MAC/PHY interrupts for each port. */
	for_each_port(adapter, i) {
		adapter->port[i].mac->ops->interrupt_disable(adapter->port[i].mac);
		adapter->port[i].phy->ops->interrupt_disable(adapter->port[i].phy);
	}

	/* Disable PCIX & external chip interrupts. */
	if (t1_is_asic(adapter))
		writel(0, adapter->regs + A_PL_ENABLE);

	/* PCI-X interrupts */
	pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0);

	adapter->slow_intr_mask = 0;
}

/* Clears all interrupts */
void t1_interrupts_clear(adapter_t* adapter)
{
	unsigned int i;

	t1_sge_intr_clear(adapter->sge);
	t1_tp_intr_clear(adapter->tp);
	if (adapter->espi)
		t1_espi_intr_clear(adapter->espi);

	/* Clear MAC/PHY interrupts for each port. */
	for_each_port(adapter, i) {
		adapter->port[i].mac->ops->interrupt_clear(adapter->port[i].mac);
		adapter->port[i].phy->ops->interrupt_clear(adapter->port[i].phy);
	}

	/* Enable interrupts for external devices. */
	if (t1_is_asic(adapter)) {
		u32 pl_intr = readl(adapter->regs + A_PL_CAUSE);

		writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX,
		       adapter->regs + A_PL_CAUSE);
	}

	/* PCI-X interrupts */
	pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff);
}

/*
 * Slow path interrupt handler for ASICs.
 */
static irqreturn_t asic_slow_intr(adapter_t *adapter)
{
	u32 cause = readl(adapter->regs + A_PL_CAUSE);
	irqreturn_t ret = IRQ_HANDLED;

	cause &= adapter->slow_intr_mask;
	if (!cause)
		return IRQ_NONE;
	if (cause & F_PL_INTR_SGE_ERR) {
		if (t1_sge_intr_error_handler(adapter->sge))
			ret = IRQ_WAKE_THREAD;
	}
	if (cause & F_PL_INTR_TP)
		t1_tp_intr_handler(adapter->tp);
	if (cause & F_PL_INTR_ESPI)
		t1_espi_intr_handler(adapter->espi);
	if (cause & F_PL_INTR_PCIX) {
		if (t1_pci_intr_handler(adapter))
			ret = IRQ_WAKE_THREAD;
	}
	if (cause & F_PL_INTR_EXT) {
		/* Wake the threaded interrupt to handle external interrupts as
		 * we require a process context. We disable EXT interrupts in
		 * the interim and let the thread reenable them when it's done.
		 */
		adapter->pending_thread_intr |= F_PL_INTR_EXT;
		adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
		writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
		       adapter->regs + A_PL_ENABLE);
		ret = IRQ_WAKE_THREAD;
	}

	/* Clear the interrupts just processed. */
	writel(cause, adapter->regs + A_PL_CAUSE);
	readl(adapter->regs + A_PL_CAUSE); /* flush writes */
	return ret;
}

irqreturn_t t1_slow_intr_handler(adapter_t *adapter)
{
#ifdef CONFIG_CHELSIO_T1_1G
	if (!t1_is_asic(adapter))
		return fpga_slow_intr(adapter);
#endif
	return asic_slow_intr(adapter);
}

/* Power sequencing is a work-around for Intel's XPAKs. */
static void power_sequence_xpak(adapter_t* adapter)
{
	u32 mod_detect;
	u32 gpo;

	/* Check for XPAK */
	t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect);
	if (!(ELMER0_GP_BIT5 & mod_detect)) {
		/* XPAK is present */
		t1_tpi_read(adapter, A_ELMER0_GPO, &gpo);
		gpo |= ELMER0_GP_BIT18;
		t1_tpi_write(adapter, A_ELMER0_GPO, gpo);
	}
}

int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
		     struct adapter_params *p)
{
	p->chip_version = bi->chip_term;
	p->is_asic = (p->chip_version != CHBT_TERM_FPGA);
	if (p->chip_version == CHBT_TERM_T1 ||
	    p->chip_version == CHBT_TERM_T2 ||
	    p->chip_version == CHBT_TERM_FPGA) {
		u32 val = readl(adapter->regs + A_TP_PC_CONFIG);

		val = G_TP_PC_REV(val);
		if (val == 2)
			p->chip_revision = TERM_T1B;
		else if (val == 3)
			p->chip_revision = TERM_T2;
		else
			return -1;
	} else
		return -1;
	return 0;
}

/*
 * Enable board components other than the Chelsio chip, such as external MAC
 * and PHY.
 */
static int board_init(adapter_t *adapter, const struct board_info *bi)
{
	switch (bi->board) {
	case CHBT_BOARD_8000:
	case CHBT_BOARD_N110:
	case CHBT_BOARD_N210:
	case CHBT_BOARD_CHT210:
		t1_tpi_par(adapter, 0xf);
		t1_tpi_write(adapter, A_ELMER0_GPO, 0x800);
		break;
	case CHBT_BOARD_CHT110:
		t1_tpi_par(adapter, 0xf);
		t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800);

		/* TBD XXX Might not need.  This fixes a problem
		 *         described in the Intel SR XPAK errata.
		 */
		power_sequence_xpak(adapter);
		break;
#ifdef CONFIG_CHELSIO_T1_1G
	case CHBT_BOARD_CHT204E:
		/* add config space write here */
	case CHBT_BOARD_CHT204:
	case CHBT_BOARD_CHT204V:
	case CHBT_BOARD_CHN204:
		t1_tpi_par(adapter, 0xf);
		t1_tpi_write(adapter, A_ELMER0_GPO, 0x804);
		break;
	case CHBT_BOARD_CHT101:
	case CHBT_BOARD_7500:
		t1_tpi_par(adapter, 0xf);
		t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804);
		break;
#endif
	}
	return 0;
}

/*
 * Initialize and configure the Terminator HW modules.  Note that external
 * MAC and PHYs are initialized separately.
 */
int t1_init_hw_modules(adapter_t *adapter)
{
	int err = -EIO;
	const struct board_info *bi = board_info(adapter);

	if (!bi->clock_mc4) {
		u32 val = readl(adapter->regs + A_MC4_CFG);

		writel(val | F_READY | F_MC4_SLOW, adapter->regs + A_MC4_CFG);
		writel(F_M_BUS_ENABLE | F_TCAM_RESET,
		       adapter->regs + A_MC5_CONFIG);
	}

	if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac,
					  bi->espi_nports))
		goto out_err;

	if (t1_tp_reset(adapter->tp, &adapter->params.tp, bi->clock_core))
		goto out_err;

	err = t1_sge_configure(adapter->sge, &adapter->params.sge);
	if (err)
		goto out_err;

	err = 0;
out_err:
	return err;
}

/*
 * Determine a card's PCI mode.
 */
static void get_pci_mode(adapter_t *adapter, struct chelsio_pci_params *p)
{
	static const unsigned short speed_map[] = { 33, 66, 100, 133 };
	u32 pci_mode;

	pci_read_config_dword(adapter->pdev, A_PCICFG_MODE, &pci_mode);
	p->speed = speed_map[G_PCI_MODE_CLK(pci_mode)];
	p->width = (pci_mode & F_PCI_MODE_64BIT) ? 64 : 32;
	p->is_pcix = (pci_mode & F_PCI_MODE_PCIX) != 0;
}

/*
 * Release the structures holding the SW per-Terminator-HW-module state.
 */
void t1_free_sw_modules(adapter_t *adapter)
{
	unsigned int i;

	for_each_port(adapter, i) {
		struct cmac *mac = adapter->port[i].mac;
		struct cphy *phy = adapter->port[i].phy;

		if (mac)
			mac->ops->destroy(mac);
		if (phy)
			phy->ops->destroy(phy);
	}

	if (adapter->sge)
		t1_sge_destroy(adapter->sge);
	if (adapter->tp)
		t1_tp_destroy(adapter->tp);
	if (adapter->espi)
		t1_espi_destroy(adapter->espi);
}

static void init_link_config(struct link_config *lc,
			     const struct board_info *bi)
{
	lc->supported = bi->caps;
	lc->requested_speed = lc->speed = SPEED_INVALID;
	lc->requested_duplex = lc->duplex = DUPLEX_INVALID;
	lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
	if (lc->supported & SUPPORTED_Autoneg) {
		lc->advertising = lc->supported;
		lc->autoneg = AUTONEG_ENABLE;
		lc->requested_fc |= PAUSE_AUTONEG;
	} else {
		lc->advertising = 0;
		lc->autoneg = AUTONEG_DISABLE;
	}
}

/*
 * Allocate and initialize the data structures that hold the SW state of
 * the Terminator HW modules.
 */
int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi)
{
	unsigned int i;

	adapter->params.brd_info = bi;
	adapter->params.nports = bi->port_number;
	adapter->params.stats_update_period = bi->gmac->stats_update_period;

	adapter->sge = t1_sge_create(adapter, &adapter->params.sge);
	if (!adapter->sge) {
		pr_err("%s: SGE initialization failed\n",
		       adapter->name);
		goto error;
	}

	if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) {
		pr_err("%s: ESPI initialization failed\n",
		       adapter->name);
		goto error;
	}

	adapter->tp = t1_tp_create(adapter, &adapter->params.tp);
	if (!adapter->tp) {
		pr_err("%s: TP initialization failed\n",
		       adapter->name);
		goto error;
	}

	board_init(adapter, bi);
	bi->mdio_ops->init(adapter, bi);
	if (bi->gphy->reset)
		bi->gphy->reset(adapter);
	if (bi->gmac->reset)
		bi->gmac->reset(adapter);

	for_each_port(adapter, i) {
		u8 hw_addr[6];
		struct cmac *mac;
		int phy_addr = bi->mdio_phybaseaddr + i;

		adapter->port[i].phy = bi->gphy->create(adapter->port[i].dev,
							phy_addr, bi->mdio_ops);
		if (!adapter->port[i].phy) {
			pr_err("%s: PHY %d initialization failed\n",
			       adapter->name, i);
			goto error;
		}

		adapter->port[i].mac = mac = bi->gmac->create(adapter, i);
		if (!mac) {
			pr_err("%s: MAC %d initialization failed\n",
			       adapter->name, i);
			goto error;
		}

		/*
		 * Get the port's MAC addresses either from the EEPROM if one
		 * exists or the one hardcoded in the MAC.
		 */
		if (!t1_is_asic(adapter) || bi->chip_mac == CHBT_MAC_DUMMY)
			mac->ops->macaddress_get(mac, hw_addr);
		else if (vpd_macaddress_get(adapter, i, hw_addr)) {
			pr_err("%s: could not read MAC address from VPD ROM\n",
			       adapter->port[i].dev->name);
			goto error;
		}
		eth_hw_addr_set(adapter->port[i].dev, hw_addr);
		init_link_config(&adapter->port[i].link_config, bi);
	}

	get_pci_mode(adapter, &adapter->params.pci);
	t1_interrupts_clear(adapter);
	return 0;

error:
	t1_free_sw_modules(adapter);
	return -1;
}
