/*
 * This file is part of the Chelsio T3 Ethernet driver.
 *
 * Copyright (C) 2005-2009 Chelsio Communications.  All rights reserved.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the LICENSE file included in this
 * release for licensing terms and conditions.
 */

#include "common.h"
#include "regs.h"

enum {
	PMD_RSD     = 10,   /* PMA/PMD receive signal detect register */
	PCS_STAT1_X = 24,   /* 10GBASE-X PCS status 1 register */
	PCS_STAT1_R = 32,   /* 10GBASE-R PCS status 1 register */
	XS_LN_STAT  = 24    /* XS lane status register */
};

enum {
	AEL100X_TX_DISABLE  = 9,
	AEL100X_TX_CONFIG1  = 0xc002,

	AEL1002_PWR_DOWN_HI = 0xc011,
	AEL1002_PWR_DOWN_LO = 0xc012,
	AEL1002_XFI_EQL     = 0xc015,
	AEL1002_LB_EN       = 0xc017,

	AEL_OPT_SETTINGS    = 0xc017,
	AEL_I2C_CTRL        = 0xc30a,
	AEL_I2C_DATA        = 0xc30b,
	AEL_I2C_STAT        = 0xc30c,

	AEL2005_GPIO_CTRL   = 0xc214,
	AEL2005_GPIO_STAT   = 0xc215,

	AEL2020_GPIO_INTR   = 0xc103,	/* Latch High (LH) */
	AEL2020_GPIO_CTRL   = 0xc108,	/* Store Clear (SC) */
	AEL2020_GPIO_STAT   = 0xc10c,	/* Read Only (RO) */
	AEL2020_GPIO_CFG    = 0xc110,	/* Read Write (RW) */

	/* there are four GPIO pins per PHY channel */
	/*
	 * Erratum: GPIO "ports" 2 & 3 are swapped relative to the
	 * documentation.  "port 2" was supposed to manage GPIO X_0
	 * and "port 3" was supposed to manage GPIO X_1.  Instead
	 * port 2 manages GPIO X_1 and port 3 manages GPIO X_0 ...
	 */
	/* name/function      port         default at reset */
	AEL2020_GPIO_SDA    = 0,	/* IN: i2c serial data */
	AEL2020_GPIO_MODDET = 1,	/* IN: Module Detect */
	AEL2020_GPIO_0      = 3,	/* IN: unassigned */
	AEL2020_GPIO_1      = 2,	/* OUT: unassigned */
	AEL2020_GPIO_LSTAT  = AEL2020_GPIO_1, /* wired to link status LED */
};

enum { edc_none, edc_sr, edc_twinax };

/* PHY module I2C device address */
enum {
	MODULE_DEV_ADDR	= 0xa0,
	SFF_DEV_ADDR	= 0xa2,
};

/* PHY transceiver type */
enum {
	phy_transtype_unknown = 0,
	phy_transtype_sfp     = 3,
	phy_transtype_xfp     = 6,
};		

#define AEL2005_MODDET_IRQ 4

struct reg_val {
	unsigned short mmd_addr;
	unsigned short reg_addr;
	unsigned short clear_bits;
	unsigned short set_bits;
};

static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms);

static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
{
	int err;

	for (err = 0; rv->mmd_addr && !err; rv++) {
		if (rv->clear_bits == 0xffff)
			err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
					 rv->set_bits);
		else
			err = t3_mdio_change_bits(phy, rv->mmd_addr,
						  rv->reg_addr, rv->clear_bits,
						  rv->set_bits);
	}
	return err;
}

static void ael100x_txon(struct cphy *phy)
{
	int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;

	msleep(100);
	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
	msleep(30);
}

/*
 * Read an 8-bit word from a device attached to the PHY's i2c bus.
 */
static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
{
	int i, err;
	unsigned int stat, data;

	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
			 (dev_addr << 8) | (1 << 8) | word_addr);
	if (err)
		return err;

	for (i = 0; i < 200; i++) {
		msleep(1);
		err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
		if (err)
			return err;
		if ((stat & 3) == 1) {
			err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
					&data);
			if (err)
				return err;
			return data >> 8;
		}
	}
	CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %#x.%#x timed out\n",
		phy->addr, dev_addr, word_addr);
	return -ETIMEDOUT;
}

/*
 * Write an 8-bit word to a device attached to the PHY's i2c bus.
 */
static int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data)
{
	int i, err;
	unsigned int stat;

	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, data);
	if (err)
		return err;

	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
			 (dev_addr << 8) | word_addr);
	if (err)
		return err;

	for (i = 0; i < 200; i++) {
		msleep(1);
		err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
		if (err)
			return err;
		if ((stat & 3) == 1)
			return 0;
	}
	CH_WARN(phy->adapter, "PHY %u i2c Write of dev.addr %#x.%#x = %#x timed out\n",
		phy->addr, dev_addr, word_addr, data);
	return -ETIMEDOUT;
}

static int get_phytrans_type(struct cphy *phy)
{
	int v;

	v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0);
	if (v < 0)
		return phy_transtype_unknown;

	return v;
}

static int ael_laser_down(struct cphy *phy, int enable)
{
	int v, dev_addr;

	v = get_phytrans_type(phy);
	if (v < 0)
		return v;

	if (v == phy_transtype_sfp) {
		/* Check SFF Soft TX disable is supported */
		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 93);
		if (v < 0)
			return v;

		v &= 0x40;
		if (!v)
			return v;

		dev_addr = SFF_DEV_ADDR;	
	} else if (v == phy_transtype_xfp)
		dev_addr = MODULE_DEV_ADDR;
	else
		return v;

	v = ael_i2c_rd(phy, dev_addr, 110);
	if (v < 0)
		return v;

	if (enable)
		v |= 0x40;
	else
		v &= ~0x40;

	v = ael_i2c_wr(phy, dev_addr, 110, v);

	return v;
}

static int ael1002_power_down(struct cphy *phy, int enable)
{
	int err;

	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
	if (!err)
		err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
					  BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
	return err;
}

static int ael1002_get_module_type(struct cphy *phy, int delay_ms)
{
	int v;

	if (delay_ms)
		msleep(delay_ms);

	v = ael2xxx_get_module_type(phy, delay_ms);

	return (v == -ETIMEDOUT ? phy_modtype_none : v);
}

static int ael1002_reset(struct cphy *phy, int wait)
{
	int err;

	if ((err = ael1002_power_down(phy, 0)) ||
	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
	    (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
				       0, 1 << 5)))
		return err;

	err = ael1002_get_module_type(phy, 300);
	if (err >= 0)
		phy->modtype = err;

	return 0;
}

static int ael1002_intr_noop(struct cphy *phy)
{
	return 0;
}

/*
 * Get link status for a 10GBASE-R device.
 */
static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
			     int *duplex, int *fc)
{
	if (link_ok) {
		unsigned int stat0, stat1, stat2;
		int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);

		if (!err)
			err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
		if (!err)
			err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
		if (err)
			return err;
		*link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
	}
	if (speed)
		*speed = SPEED_10000;
	if (duplex)
		*duplex = DUPLEX_FULL;
	return 0;
}

#ifdef C99_NOT_SUPPORTED
static struct cphy_ops ael1002_ops = {
	ael1002_reset,
	ael1002_intr_noop,
	ael1002_intr_noop,
	ael1002_intr_noop,
	ael1002_intr_noop,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	get_link_status_r,
	ael1002_power_down,
};
#else
static struct cphy_ops ael1002_ops = {
	.reset           = ael1002_reset,
	.intr_enable     = ael1002_intr_noop,
	.intr_disable    = ael1002_intr_noop,
	.intr_clear      = ael1002_intr_noop,
	.intr_handler    = ael1002_intr_noop,
	.get_link_status = get_link_status_r,
	.power_down      = ael1002_power_down,
};
#endif

int t3_ael1002_phy_prep(pinfo_t *pinfo, int phy_addr,
			const struct mdio_ops *mdio_ops)
{
	int err;
	struct cphy *phy = &pinfo->phy;

	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1002_ops, mdio_ops,
		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
		  "10GBASE-R");
	ael100x_txon(phy);
	ael_laser_down(phy, 0);

	err = ael1002_get_module_type(phy, 0);
	if (err >= 0)
		phy->modtype = err;

	return 0;
}

static int ael1006_reset(struct cphy *phy, int wait)
{
	int err;

	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
	if (err)
		return err;

	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 
			 F_GPIO6_OUT_VAL, 0);

	msleep(125);

	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 
			 F_GPIO6_OUT_VAL, F_GPIO6_OUT_VAL);

	msleep(125);

	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
	if (err)
		return err;

	msleep(125);

	err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 1);
	if (err)
		return err;
	
	msleep(125);

	err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0);

	return err;
	   
}

#ifdef C99_NOT_SUPPORTED
static struct cphy_ops ael1006_ops = {
	ael1006_reset,
	t3_phy_lasi_intr_enable,
	t3_phy_lasi_intr_disable,
	t3_phy_lasi_intr_clear,
	t3_phy_lasi_intr_handler,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	get_link_status_r,
	ael1002_power_down,
};
#else
static struct cphy_ops ael1006_ops = {
	.reset           = ael1006_reset,
	.intr_enable     = t3_phy_lasi_intr_enable,
	.intr_disable    = t3_phy_lasi_intr_disable,
	.intr_clear      = t3_phy_lasi_intr_clear,
	.intr_handler    = t3_phy_lasi_intr_handler,
	.get_link_status = get_link_status_r,
	.power_down      = ael1002_power_down,
};
#endif

int t3_ael1006_phy_prep(pinfo_t *pinfo, int phy_addr,
			const struct mdio_ops *mdio_ops)
{
	struct cphy *phy = &pinfo->phy;

	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1006_ops, mdio_ops,
		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
		  "10GBASE-SR");
	phy->modtype = phy_modtype_sr;
	ael100x_txon(phy);
	return 0;
}

/*
 * Decode our module type.
 */
static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
{
	int v;

	if (delay_ms)
		msleep(delay_ms);

	v = get_phytrans_type(phy);
	if (v == phy_transtype_sfp) {
		/* SFP: see SFF-8472 for below */

		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3);
		if (v < 0)
			return v;

		if (v == 0x1)
			goto twinax;
		if (v == 0x10)
			return phy_modtype_sr;
		if (v == 0x20)
			return phy_modtype_lr;
		if (v == 0x40)
			return phy_modtype_lrm;

		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 8);
		if (v < 0)
			return v;
		if (v == 4) {
			v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 60);
			if (v < 0)
				return v;
			if (v & 0x1)
				goto twinax;
		}

		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6);
		if (v < 0)
			return v;
		if (v != 4)
			return phy_modtype_unknown;

		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10);
		if (v < 0)
			return v;

		if (v & 0x80) {
twinax:
			v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
			if (v < 0)
				return v;
			return v > 10 ? phy_modtype_twinax_long :
			    phy_modtype_twinax;
		}
	} else if (v == phy_transtype_xfp) {
		/* XFP: See INF-8077i for details. */

		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127);
		if (v < 0)
			return v;

		if (v != 1) {
			/* XXX: set page select to table 1 yourself */
			return phy_modtype_unknown;
		}

		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131);
		if (v < 0)
			return v;
		v &= 0xf0;
		if (v == 0x10)
			return phy_modtype_lrm;
		if (v == 0x40)
			return phy_modtype_lr;
		if (v == 0x80)
			return phy_modtype_sr;
	}

	return phy_modtype_unknown;
}

/*
 * Code to support the Aeluros/NetLogic 2005 10Gb PHY.
 */
static int ael2005_setup_sr_edc(struct cphy *phy)
{
	static struct reg_val regs[] = {
		{ MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
		{ MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
		{ MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
		{ 0, 0, 0, 0 }
	};
	int i, err, size;

	err = set_phy_regs(phy, regs);
	if (err)
		return err;

	msleep(50);

	if (phy->priv != edc_sr)
		size = t3_get_edc_fw(phy, EDC_OPT_AEL2005);
	if (size < 0)
		return size;

	for (i = 0; i <  size / sizeof(u16) && !err; i += 2)
		err = mdio_write(phy, MDIO_DEV_PMA_PMD,
				 phy->phy_cache[i],
				 phy->phy_cache[i + 1]);
	if (!err)
		phy->priv = edc_sr;
	return err;
}

static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
{
	static struct reg_val regs[] = {
		{ MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
		{ 0, 0, 0, 0 }
	};
	static struct reg_val preemphasis[] = {
		{ MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
		{ MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
		{ 0, 0, 0, 0 }
	};
	int i, err, size;

	err = set_phy_regs(phy, regs);
	if (!err && modtype == phy_modtype_twinax_long)
		err = set_phy_regs(phy, preemphasis);
	if (err)
		return err;

	msleep(50);

	if (phy->priv != edc_twinax)
		size = t3_get_edc_fw(phy, EDC_TWX_AEL2005);
	if (size < 0)
		return size;

	for (i = 0; i <  size / sizeof(u16) && !err; i += 2)
		err = mdio_write(phy, MDIO_DEV_PMA_PMD,
				 phy->phy_cache[i],
				 phy->phy_cache[i + 1]);
	if (!err)
		phy->priv = edc_twinax;
	return err;
}

static int ael2005_get_module_type(struct cphy *phy, int delay_ms)
{
	int v;
	unsigned int stat;

	v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
	if (v)
		return v;

	if (stat & (1 << 8))			/* module absent */
		return phy_modtype_none;

	return ael2xxx_get_module_type(phy, delay_ms);
}

static int ael2005_intr_enable(struct cphy *phy)
{
	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
	return err ? err : t3_phy_lasi_intr_enable(phy);
}

static int ael2005_intr_disable(struct cphy *phy)
{
	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
	return err ? err : t3_phy_lasi_intr_disable(phy);
}

static int ael2005_intr_clear(struct cphy *phy)
{
	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
	return err ? err : t3_phy_lasi_intr_clear(phy);
}

static int ael2005_reset(struct cphy *phy, int wait)
{
	static struct reg_val regs0[] = {
		{ MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
		{ MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
		{ MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
		{ 0, 0, 0, 0 }
	};
	static struct reg_val regs1[] = {
		{ MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
		{ MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
		{ 0, 0, 0, 0 }
	};

	int err;
	unsigned int lasi_ctrl;

	err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
	if (err)
		return err;

	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
	if (err)
		return err;

	msleep(125);
	phy->priv = edc_none;
	err = set_phy_regs(phy, regs0);
	if (err)
		return err;

	msleep(50);

	err = ael2005_get_module_type(phy, 0);
	if (err < 0)
		return err;
	phy->modtype = (u8)err;

	if (err == phy_modtype_none)
		err = 0;
	else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
		err = ael2005_setup_twinax_edc(phy, err);
	else
		err = ael2005_setup_sr_edc(phy);
	if (err)
		return err;

	err = set_phy_regs(phy, regs1);
	if (err)
		return err;

	/* reset wipes out interrupts, reenable them if they were on */
	if (lasi_ctrl & 1)
		err = ael2005_intr_enable(phy);
	return err;
}

static int ael2005_intr_handler(struct cphy *phy)
{
	unsigned int stat;
	int ret, edc_needed, cause = 0;

	ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
	if (ret)
		return ret;

	if (stat & AEL2005_MODDET_IRQ) {
		ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
				 0xd00);
		if (ret)
			return ret;

		/* modules have max 300 ms init time after hot plug */
		ret = ael2005_get_module_type(phy, 300);
		if (ret < 0)
			return ret;

		phy->modtype = (u8)ret;
		if (ret == phy_modtype_none)
			edc_needed = phy->priv;       /* on unplug retain EDC */
		else if (ret == phy_modtype_twinax ||
			 ret == phy_modtype_twinax_long)
			edc_needed = edc_twinax;
		else
			edc_needed = edc_sr;

		if (edc_needed != phy->priv) {
			ret = ael2005_reset(phy, 0);
			return ret ? ret : cphy_cause_module_change;
		}
		cause = cphy_cause_module_change;
	}

	ret = t3_phy_lasi_intr_handler(phy);
	if (ret < 0)
		return ret;

	ret |= cause;
	if (!ret)
		ret |= cphy_cause_link_change;
	return ret;
}

static struct cphy_ops ael2005_ops = {
#ifdef C99_NOT_SUPPORTED
	ael2005_reset,
	ael2005_intr_enable,
	ael2005_intr_disable,
	ael2005_intr_clear,
	ael2005_intr_handler,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	get_link_status_r,
	ael1002_power_down,
#else
	.reset           = ael2005_reset,
	.intr_enable     = ael2005_intr_enable,
	.intr_disable    = ael2005_intr_disable,
	.intr_clear      = ael2005_intr_clear,
	.intr_handler    = ael2005_intr_handler,
	.get_link_status = get_link_status_r,
	.power_down      = ael1002_power_down,
#endif
};

int t3_ael2005_phy_prep(pinfo_t *pinfo, int phy_addr,
			const struct mdio_ops *mdio_ops)
{
	int err;
	struct cphy *phy = &pinfo->phy;

	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2005_ops, mdio_ops,
		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
		  SUPPORTED_IRQ, "10GBASE-R");
	msleep(125);
	ael_laser_down(phy, 0);

	err = ael2005_get_module_type(phy, 0);
	if (err >= 0)
		phy->modtype = err;

	return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
				   1 << 5);
}

/*
 * The Aeluros/NetLogic AEL2020 is nearly identical to the AEL2005.  It's
 * basically two AEL2005's packaged up into a single die.  There are some
 * small differences which we account for here:
 *
 * 1. AEL2020 Errata.  See in particular erratum #2 concerning a "CDRLOL
 *    signal being asserted under all conditions" resulting in "PMD link
 *    status to be down all the time."
 *
 * 2. The Link Status LED is controlled by the AEL2020 GPIO configuration
 *    for AEL2020 GPIO pins 0_1 and 1_1.  See comments regarding Traffic
 *    Indicator Mode on pages 18-20 of the AEL2020 datasheet.
 *
 * 3. Different GPIO logic used to enable, mask and detect interrupts,
 *    and detect module types.
 *
 * 4. The EDC logic can be turned off for optical modules resulting in
 *    significant power savings.
 *
 * 5. Slightly different reset logic and uP firmware.
 *
 * Unfortunately, despite the high degree of similarity between the AEL2005
 * and the AEL2020 PHYs, we need to duplicate the vast majority of the code
 * because of the differences and the small size of the code base.
 */

/*
 * Setup EDC and other parameters for operation with an optical module.
 */
static int ael2020_setup_sr_edc(struct cphy *phy)
{
	static struct reg_val regs[] = {
		/* set CDR offset to 10 */
		{ MDIO_DEV_PMA_PMD, 0xcc01, 0xffff, 0x488a },

		/* adjust 10G RX bias current */
		{ MDIO_DEV_PMA_PMD, 0xcb1b, 0xffff, 0x0200 },
		{ MDIO_DEV_PMA_PMD, 0xcb1c, 0xffff, 0x00f0 },
		{ MDIO_DEV_PMA_PMD, 0xcc06, 0xffff, 0x00e0 },

		/* end */
		{ 0, 0, 0, 0 }
	};
	int err;

	err = set_phy_regs(phy, regs);
	msleep(50);
	if (err)
		return err;

	phy->priv = edc_sr;
	return 0;
}

/*
 * Setup EDC and other parameters for operation with an TWINAX module.
 */
static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
{
	/* set uC to 40MHz */
	static struct reg_val uCclock40MHz[] = {
		{ MDIO_DEV_PMA_PMD, 0xff28, 0xffff, 0x4001 },
		{ MDIO_DEV_PMA_PMD, 0xff2a, 0xffff, 0x0002 },
		{ 0, 0, 0, 0 }
	};

	/* activate uC clock */
	static struct reg_val uCclockActivate[] = {
		{ MDIO_DEV_PMA_PMD, 0xd000, 0xffff, 0x5200 },
		{ 0, 0, 0, 0 }
	};

	/* set PC to start of SRAM and activate uC */
	static struct reg_val uCactivate[] = {
		{ MDIO_DEV_PMA_PMD, 0xd080, 0xffff, 0x0100 },
		{ MDIO_DEV_PMA_PMD, 0xd092, 0xffff, 0x0000 },
		{ 0, 0, 0, 0 }
	};

	int i, err, size;

	/* set uC clock and activate it */
	err = set_phy_regs(phy, uCclock40MHz);
	msleep(500);
	if (err)
		return err;
	err = set_phy_regs(phy, uCclockActivate);
	msleep(500);
	if (err)
		return err;

	if (phy->priv != edc_twinax)
		size = t3_get_edc_fw(phy, EDC_TWX_AEL2020);
	if (err)
		return err;

	for (i = 0; i <  size / sizeof(u16) && !err; i += 2)
		err = mdio_write(phy, MDIO_DEV_PMA_PMD,
				 phy->phy_cache[i],
				 phy->phy_cache[i + 1]);


	/* activate uC */
	err = set_phy_regs(phy, uCactivate);
	if (!err)
		phy->priv = edc_twinax;
	return err;
}

/*
 * Return Module Type.
 */
static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
{
	int v;
	unsigned int stat;

	v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_STAT, &stat);
	if (v)
		return v;

	if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) {
		/* module absent */
		return phy_modtype_none;
	}

	return ael2xxx_get_module_type(phy, delay_ms);
}

/*
 * Note that on the AEL2005 putting the PHY into low power mode also asserts
 * the LOS_OUT pin on that PHY.  On the AEL2020 the internal "LOS" signal
 * which we route to the "link status" LED is _not_ affected by putting the
 * PHY into low power mode.  So we change the GPIO configuration for the link
 * status LED in the interrupt enable/disable functions in order to cause it
 * to go off when the interface is brought down.
 */

/*
 * Enable PHY interrupts.  We enable "Module Detection" interrupts (on any
 * state transition) and then generic Link Alarm Status Interrupt (LASI).
 */
static int ael2020_intr_enable(struct cphy *phy)
{
	struct reg_val regs[] = {
		/* output Module's Loss Of Signal (LOS) to LED */
		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
			0xffff, 0x4 },
		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
			0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },

		 /* enable module detect status change interrupts */
		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
			0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) },

		/* end */
		{ 0, 0, 0, 0 }
	};
	int err;

	/* set up "link status" LED and enable module change interrupts */
	err = set_phy_regs(phy, regs);
	if (err)
		return err;

        /*
	 * The AEL2020 doesn't seem to send an interrupt when a link is
	 * already establish and you enable interrupts.  So we we schedule a
	 * link status check.
	 */
	t3_os_link_fault_handler(phy->adapter, phy->pinfo->port_id);

	/* enable standard Link Alarm Status Interrupts */
	err = t3_phy_lasi_intr_enable(phy);
	if (err)
		return err;

	return 0;
}

/*
 * Disable PHY interrupts.  The mirror of the above ...
 */
static int ael2020_intr_disable(struct cphy *phy)
{
	struct reg_val regs[] = {
		/* reset "link status" LED to "off" */
		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
			0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) },

		/* disable module detect status change interrupts */
		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
			0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) },

		/* end */
		{ 0, 0, 0, 0 }
	};
	int err;

	/* turn off "link status" LED and disable module change interrupts */
	err = set_phy_regs(phy, regs);
	if (err)
		return err;

	/* disable standard Link Alarm Status Interrupts */
	return t3_phy_lasi_intr_disable(phy);
}

/*
 * Clear PHY interrupt state.
 */
static int ael2020_intr_clear(struct cphy *phy)
{
	/*
	 * The GPIO Interrupt register on the AEL2020 is a "Latching High"
	 * (LH) register which is cleared to the current state when it's read.
	 * Thus, we simply read the register and discard the result.
	 */
	unsigned int stat;
	int err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat);
	return err ? err : t3_phy_lasi_intr_clear(phy);
}

/*
 * Common register settings for the AEL2020 when it comes out of reset.
 */
static struct reg_val ael2020_reset_regs[] = {
	/* Erratum #2: CDRLOL asserted, causing PMA link down status */
	{ MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x3101 },

	/* force XAUI to send LF when RX_LOS is asserted */
	{ MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 },

	{ MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0x0100 },
	{ MDIO_DEV_PMA_PMD, 0xca22, 0xffff, 0x0100 },
	{ MDIO_DEV_PMA_PMD, 0xca42, 0xffff, 0x0100 },

	/* allow writes to transceiver module EEPROM on i2c bus */
	{ MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 },
	{ MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 },
	{ MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 },

	/* initiate reset sequencer */
	{ MDIO_DEV_PMA_PMD, 0xc20d, 0xffff, 0x0002 },

	/* end */
	{ 0, 0, 0, 0 }
};

/*
 * Reset the PHY and put it into a canonical operating state.
 */
static int ael2020_reset(struct cphy *phy, int wait)
{
	int err;
	unsigned int lasi_ctrl;

	/* grab current interrupt state */
	err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
	if (err)
		return err;

	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 125);
	if (err)
		return err;
	msleep(100);

	/* basic initialization for all module types */
	phy->priv = edc_none;
	err = set_phy_regs(phy, ael2020_reset_regs);
	if (err)
		return err;
	msleep(100);

	/* determine module type and perform appropriate initialization */
	err = ael2020_get_module_type(phy, 0);
	if (err < 0)
		return err;
	phy->modtype = (u8)err;
	if (err == phy_modtype_none)
		err = 0;
	else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
		err = ael2020_setup_twinax_edc(phy, err);
	else
		err = ael2020_setup_sr_edc(phy);
	if (err)
		return err;

	/* reset wipes out interrupts, reenable them if they were on */
	if (lasi_ctrl & 1)
		err = ael2020_intr_enable(phy);
	return err;
}

/*
 * Handle a PHY interrupt.
 */
static int ael2020_intr_handler(struct cphy *phy)
{
	unsigned int stat;
	int ret, edc_needed, cause = 0;

	ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat);
	if (ret)
		return ret;

	if (stat & (0x1 << AEL2020_GPIO_MODDET)) {
		/* modules have max 300 ms init time after hot plug */
		ret = ael2020_get_module_type(phy, 300);
		if (ret < 0)
			return ret;

		phy->modtype = (u8)ret;
		if (ret == phy_modtype_none)
			edc_needed = phy->priv;       /* on unplug retain EDC */
		else if (ret == phy_modtype_twinax ||
			 ret == phy_modtype_twinax_long)
			edc_needed = edc_twinax;
		else
			edc_needed = edc_sr;

		if (edc_needed != phy->priv) {
			ret = ael2020_reset(phy, 0);
			return ret ? ret : cphy_cause_module_change;
		}
		cause = cphy_cause_module_change;
	}

	ret = t3_phy_lasi_intr_handler(phy);
	if (ret < 0)
		return ret;

	ret |= cause;
	if (!ret)
		ret |= cphy_cause_link_change;
	return ret;
}

static struct cphy_ops ael2020_ops = {
#ifdef C99_NOT_SUPPORTED
	ael2020_reset,
	ael2020_intr_enable,
	ael2020_intr_disable,
	ael2020_intr_clear,
	ael2020_intr_handler,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	get_link_status_r,
	ael1002_power_down,
#else
	.reset           = ael2020_reset,
	.intr_enable     = ael2020_intr_enable,
	.intr_disable    = ael2020_intr_disable,
	.intr_clear      = ael2020_intr_clear,
	.intr_handler    = ael2020_intr_handler,
	.get_link_status = get_link_status_r,
	.power_down      = ael1002_power_down,
#endif
};

int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr,
			const struct mdio_ops *mdio_ops)
{
	int err;
	struct cphy *phy = &pinfo->phy;

	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2020_ops, mdio_ops,
		SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
		  SUPPORTED_IRQ, "10GBASE-R");
	msleep(125);

	err = set_phy_regs(phy, ael2020_reset_regs);
	if (err)
		return err;
	msleep(100);

	err = ael2020_get_module_type(phy, 0);
	if (err >= 0)
		phy->modtype = err;

	ael_laser_down(phy, 0);
	return 0;
}

/*
 * Get link status for a 10GBASE-X device.
 */
static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
			     int *duplex, int *fc)
{
	if (link_ok) {
		unsigned int stat0, stat1, stat2;
		int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);

		if (!err)
			err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
		if (!err)
			err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
		if (err)
			return err;
		*link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
	}
	if (speed)
		*speed = SPEED_10000;
	if (duplex)
		*duplex = DUPLEX_FULL;
	return 0;
}

#ifdef C99_NOT_SUPPORTED
static struct cphy_ops qt2045_ops = {
	ael1006_reset,
	t3_phy_lasi_intr_enable,
	t3_phy_lasi_intr_disable,
	t3_phy_lasi_intr_clear,
	t3_phy_lasi_intr_handler,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	get_link_status_x,
	ael1002_power_down,
};
#else
static struct cphy_ops qt2045_ops = {
	.reset           = ael1006_reset,
	.intr_enable     = t3_phy_lasi_intr_enable,
	.intr_disable    = t3_phy_lasi_intr_disable,
	.intr_clear      = t3_phy_lasi_intr_clear,
	.intr_handler    = t3_phy_lasi_intr_handler,
	.get_link_status = get_link_status_x,
	.power_down      = ael1002_power_down,
};
#endif

int t3_qt2045_phy_prep(pinfo_t *pinfo, int phy_addr,
		       const struct mdio_ops *mdio_ops)
{
	unsigned int stat;
	struct cphy *phy = &pinfo->phy;

	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &qt2045_ops, mdio_ops,
		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
		  "10GBASE-CX4");

	/*
	 * Some cards where the PHY is supposed to be at address 0 actually
	 * have it at 1.
	 */
	if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
	    stat == 0xffff)
		phy->addr = 1;
	return 0;
}

static int xaui_direct_reset(struct cphy *phy, int wait)
{
	return 0;
}

static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
				       int *speed, int *duplex, int *fc)
{
	if (link_ok) {
		unsigned int status;
		adapter_t *adapter = phy->adapter;

		status = t3_read_reg(adapter,
				     XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
			 t3_read_reg(adapter,
				     XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
			 t3_read_reg(adapter,
				     XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
			 t3_read_reg(adapter,
				     XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
		*link_ok = !(status & F_LOWSIG0);
	}
	if (speed)
		*speed = SPEED_10000;
	if (duplex)
		*duplex = DUPLEX_FULL;
	return 0;
}

static int xaui_direct_power_down(struct cphy *phy, int enable)
{
	return 0;
}

#ifdef C99_NOT_SUPPORTED
static struct cphy_ops xaui_direct_ops = {
	xaui_direct_reset,
	ael1002_intr_noop,
	ael1002_intr_noop,
	ael1002_intr_noop,
	ael1002_intr_noop,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	xaui_direct_get_link_status,
	xaui_direct_power_down,
};
#else
static struct cphy_ops xaui_direct_ops = {
	.reset           = xaui_direct_reset,
	.intr_enable     = ael1002_intr_noop,
	.intr_disable    = ael1002_intr_noop,
	.intr_clear      = ael1002_intr_noop,
	.intr_handler    = ael1002_intr_noop,
	.get_link_status = xaui_direct_get_link_status,
	.power_down      = xaui_direct_power_down,
};
#endif

int t3_xaui_direct_phy_prep(pinfo_t *pinfo, int phy_addr,
			    const struct mdio_ops *mdio_ops)
{
	cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &xaui_direct_ops, mdio_ops,
		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
		  "10GBASE-CX4");
	return 0;
}
