|  | /* | 
|  | * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. | 
|  | * | 
|  | * This software is available to you under a choice of one of two | 
|  | * licenses.  You may choose to be licensed under the terms of the GNU | 
|  | * General Public License (GPL) Version 2, available from the file | 
|  | * COPYING in the main directory of this source tree, or the | 
|  | * OpenIB.org BSD license below: | 
|  | * | 
|  | *     Redistribution and use in source and binary forms, with or | 
|  | *     without modification, are permitted provided that the following | 
|  | *     conditions are met: | 
|  | * | 
|  | *      - Redistributions of source code must retain the above | 
|  | *        copyright notice, this list of conditions and the following | 
|  | *        disclaimer. | 
|  | * | 
|  | *      - Redistributions in binary form must reproduce the above | 
|  | *        copyright notice, this list of conditions and the following | 
|  | *        disclaimer in the documentation and/or other materials | 
|  | *        provided with the distribution. | 
|  | * | 
|  | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
|  | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
|  | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
|  | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 
|  | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 
|  | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
|  | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
|  | * SOFTWARE. | 
|  | */ | 
|  | #include "common.h" | 
|  | #include "regs.h" | 
|  |  | 
|  | enum { | 
|  | 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) */ | 
|  |  | 
|  | 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 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 = t3_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->mdio.prtad == 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 = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, | 
|  | (dev_addr << 8) | (1 << 8) | word_addr); | 
|  | if (err) | 
|  | return err; | 
|  |  | 
|  | for (i = 0; i < 200; i++) { | 
|  | msleep(1); | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); | 
|  | if (err) | 
|  | return err; | 
|  | if ((stat & 3) == 1) { | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, 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->mdio.prtad, dev_addr, word_addr); | 
|  | return -ETIMEDOUT; | 
|  | } | 
|  |  | 
|  | static int ael1002_power_down(struct cphy *phy, int enable) | 
|  | { | 
|  | int err; | 
|  |  | 
|  | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable); | 
|  | if (!err) | 
|  | err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, | 
|  | MDIO_MMD_PMAPMD, MDIO_CTRL1, | 
|  | MDIO_CTRL1_LPOWER, enable); | 
|  | return err; | 
|  | } | 
|  |  | 
|  | static int ael1002_reset(struct cphy *phy, int wait) | 
|  | { | 
|  | int err; | 
|  |  | 
|  | if ((err = ael1002_power_down(phy, 0)) || | 
|  | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) || | 
|  | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) || | 
|  | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) || | 
|  | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) || | 
|  | (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN, | 
|  | 0, 1 << 5))) | 
|  | return 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 = t3_mdio_read(phy, MDIO_MMD_PMAPMD, | 
|  | MDIO_PMA_RXDET, &stat0); | 
|  |  | 
|  | if (!err) | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PCS, | 
|  | MDIO_PCS_10GBRT_STAT1, &stat1); | 
|  | if (!err) | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PHYXS, | 
|  | MDIO_PHYXS_LNSTAT, &stat2); | 
|  | if (err) | 
|  | return err; | 
|  | *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; | 
|  | } | 
|  | if (speed) | 
|  | *speed = SPEED_10000; | 
|  | if (duplex) | 
|  | *duplex = DUPLEX_FULL; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | 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, | 
|  | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | 
|  | }; | 
|  |  | 
|  | int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, | 
|  | int phy_addr, const struct mdio_ops *mdio_ops) | 
|  | { | 
|  | cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops, | 
|  | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, | 
|  | "10GBASE-R"); | 
|  | ael100x_txon(phy); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int ael1006_reset(struct cphy *phy, int wait) | 
|  | { | 
|  | return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait); | 
|  | } | 
|  |  | 
|  | static int ael1006_power_down(struct cphy *phy, int enable) | 
|  | { | 
|  | return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, | 
|  | MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); | 
|  | } | 
|  |  | 
|  | 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 = ael1006_power_down, | 
|  | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | 
|  | }; | 
|  |  | 
|  | int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | 
|  | int phy_addr, const struct mdio_ops *mdio_ops) | 
|  | { | 
|  | cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops, | 
|  | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, | 
|  | "10GBASE-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); | 
|  |  | 
|  | /* see SFF-8472 for below */ | 
|  | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); | 
|  | if (v < 0) | 
|  | return v; | 
|  |  | 
|  | 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, 6); | 
|  | if (v < 0) | 
|  | return v; | 
|  | if (v != 4) | 
|  | goto unknown; | 
|  |  | 
|  | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); | 
|  | if (v < 0) | 
|  | return v; | 
|  |  | 
|  | if (v & 0x80) { | 
|  | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); | 
|  | if (v < 0) | 
|  | return v; | 
|  | return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; | 
|  | } | 
|  | unknown: | 
|  | 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_MMD_PMAPMD, 0xc003, 0xffff, 0x181 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a }, | 
|  | { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  | static u16 sr_edc[] = { | 
|  | 0xcc00, 0x2ff4, | 
|  | 0xcc01, 0x3cd4, | 
|  | 0xcc02, 0x2015, | 
|  | 0xcc03, 0x3105, | 
|  | 0xcc04, 0x6524, | 
|  | 0xcc05, 0x27ff, | 
|  | 0xcc06, 0x300f, | 
|  | 0xcc07, 0x2c8b, | 
|  | 0xcc08, 0x300b, | 
|  | 0xcc09, 0x4009, | 
|  | 0xcc0a, 0x400e, | 
|  | 0xcc0b, 0x2f72, | 
|  | 0xcc0c, 0x3002, | 
|  | 0xcc0d, 0x1002, | 
|  | 0xcc0e, 0x2172, | 
|  | 0xcc0f, 0x3012, | 
|  | 0xcc10, 0x1002, | 
|  | 0xcc11, 0x25d2, | 
|  | 0xcc12, 0x3012, | 
|  | 0xcc13, 0x1002, | 
|  | 0xcc14, 0xd01e, | 
|  | 0xcc15, 0x27d2, | 
|  | 0xcc16, 0x3012, | 
|  | 0xcc17, 0x1002, | 
|  | 0xcc18, 0x2004, | 
|  | 0xcc19, 0x3c84, | 
|  | 0xcc1a, 0x6436, | 
|  | 0xcc1b, 0x2007, | 
|  | 0xcc1c, 0x3f87, | 
|  | 0xcc1d, 0x8676, | 
|  | 0xcc1e, 0x40b7, | 
|  | 0xcc1f, 0xa746, | 
|  | 0xcc20, 0x4047, | 
|  | 0xcc21, 0x5673, | 
|  | 0xcc22, 0x2982, | 
|  | 0xcc23, 0x3002, | 
|  | 0xcc24, 0x13d2, | 
|  | 0xcc25, 0x8bbd, | 
|  | 0xcc26, 0x2862, | 
|  | 0xcc27, 0x3012, | 
|  | 0xcc28, 0x1002, | 
|  | 0xcc29, 0x2092, | 
|  | 0xcc2a, 0x3012, | 
|  | 0xcc2b, 0x1002, | 
|  | 0xcc2c, 0x5cc3, | 
|  | 0xcc2d, 0x314, | 
|  | 0xcc2e, 0x2942, | 
|  | 0xcc2f, 0x3002, | 
|  | 0xcc30, 0x1002, | 
|  | 0xcc31, 0xd019, | 
|  | 0xcc32, 0x2032, | 
|  | 0xcc33, 0x3012, | 
|  | 0xcc34, 0x1002, | 
|  | 0xcc35, 0x2a04, | 
|  | 0xcc36, 0x3c74, | 
|  | 0xcc37, 0x6435, | 
|  | 0xcc38, 0x2fa4, | 
|  | 0xcc39, 0x3cd4, | 
|  | 0xcc3a, 0x6624, | 
|  | 0xcc3b, 0x5563, | 
|  | 0xcc3c, 0x2d42, | 
|  | 0xcc3d, 0x3002, | 
|  | 0xcc3e, 0x13d2, | 
|  | 0xcc3f, 0x464d, | 
|  | 0xcc40, 0x2862, | 
|  | 0xcc41, 0x3012, | 
|  | 0xcc42, 0x1002, | 
|  | 0xcc43, 0x2032, | 
|  | 0xcc44, 0x3012, | 
|  | 0xcc45, 0x1002, | 
|  | 0xcc46, 0x2fb4, | 
|  | 0xcc47, 0x3cd4, | 
|  | 0xcc48, 0x6624, | 
|  | 0xcc49, 0x5563, | 
|  | 0xcc4a, 0x2d42, | 
|  | 0xcc4b, 0x3002, | 
|  | 0xcc4c, 0x13d2, | 
|  | 0xcc4d, 0x2ed2, | 
|  | 0xcc4e, 0x3002, | 
|  | 0xcc4f, 0x1002, | 
|  | 0xcc50, 0x2fd2, | 
|  | 0xcc51, 0x3002, | 
|  | 0xcc52, 0x1002, | 
|  | 0xcc53, 0x004, | 
|  | 0xcc54, 0x2942, | 
|  | 0xcc55, 0x3002, | 
|  | 0xcc56, 0x1002, | 
|  | 0xcc57, 0x2092, | 
|  | 0xcc58, 0x3012, | 
|  | 0xcc59, 0x1002, | 
|  | 0xcc5a, 0x5cc3, | 
|  | 0xcc5b, 0x317, | 
|  | 0xcc5c, 0x2f72, | 
|  | 0xcc5d, 0x3002, | 
|  | 0xcc5e, 0x1002, | 
|  | 0xcc5f, 0x2942, | 
|  | 0xcc60, 0x3002, | 
|  | 0xcc61, 0x1002, | 
|  | 0xcc62, 0x22cd, | 
|  | 0xcc63, 0x301d, | 
|  | 0xcc64, 0x2862, | 
|  | 0xcc65, 0x3012, | 
|  | 0xcc66, 0x1002, | 
|  | 0xcc67, 0x2ed2, | 
|  | 0xcc68, 0x3002, | 
|  | 0xcc69, 0x1002, | 
|  | 0xcc6a, 0x2d72, | 
|  | 0xcc6b, 0x3002, | 
|  | 0xcc6c, 0x1002, | 
|  | 0xcc6d, 0x628f, | 
|  | 0xcc6e, 0x2112, | 
|  | 0xcc6f, 0x3012, | 
|  | 0xcc70, 0x1002, | 
|  | 0xcc71, 0x5aa3, | 
|  | 0xcc72, 0x2dc2, | 
|  | 0xcc73, 0x3002, | 
|  | 0xcc74, 0x1312, | 
|  | 0xcc75, 0x6f72, | 
|  | 0xcc76, 0x1002, | 
|  | 0xcc77, 0x2807, | 
|  | 0xcc78, 0x31a7, | 
|  | 0xcc79, 0x20c4, | 
|  | 0xcc7a, 0x3c24, | 
|  | 0xcc7b, 0x6724, | 
|  | 0xcc7c, 0x1002, | 
|  | 0xcc7d, 0x2807, | 
|  | 0xcc7e, 0x3187, | 
|  | 0xcc7f, 0x20c4, | 
|  | 0xcc80, 0x3c24, | 
|  | 0xcc81, 0x6724, | 
|  | 0xcc82, 0x1002, | 
|  | 0xcc83, 0x2514, | 
|  | 0xcc84, 0x3c64, | 
|  | 0xcc85, 0x6436, | 
|  | 0xcc86, 0xdff4, | 
|  | 0xcc87, 0x6436, | 
|  | 0xcc88, 0x1002, | 
|  | 0xcc89, 0x40a4, | 
|  | 0xcc8a, 0x643c, | 
|  | 0xcc8b, 0x4016, | 
|  | 0xcc8c, 0x8c6c, | 
|  | 0xcc8d, 0x2b24, | 
|  | 0xcc8e, 0x3c24, | 
|  | 0xcc8f, 0x6435, | 
|  | 0xcc90, 0x1002, | 
|  | 0xcc91, 0x2b24, | 
|  | 0xcc92, 0x3c24, | 
|  | 0xcc93, 0x643a, | 
|  | 0xcc94, 0x4025, | 
|  | 0xcc95, 0x8a5a, | 
|  | 0xcc96, 0x1002, | 
|  | 0xcc97, 0x2731, | 
|  | 0xcc98, 0x3011, | 
|  | 0xcc99, 0x1001, | 
|  | 0xcc9a, 0xc7a0, | 
|  | 0xcc9b, 0x100, | 
|  | 0xcc9c, 0xc502, | 
|  | 0xcc9d, 0x53ac, | 
|  | 0xcc9e, 0xc503, | 
|  | 0xcc9f, 0xd5d5, | 
|  | 0xcca0, 0xc600, | 
|  | 0xcca1, 0x2a6d, | 
|  | 0xcca2, 0xc601, | 
|  | 0xcca3, 0x2a4c, | 
|  | 0xcca4, 0xc602, | 
|  | 0xcca5, 0x111, | 
|  | 0xcca6, 0xc60c, | 
|  | 0xcca7, 0x5900, | 
|  | 0xcca8, 0xc710, | 
|  | 0xcca9, 0x700, | 
|  | 0xccaa, 0xc718, | 
|  | 0xccab, 0x700, | 
|  | 0xccac, 0xc720, | 
|  | 0xccad, 0x4700, | 
|  | 0xccae, 0xc801, | 
|  | 0xccaf, 0x7f50, | 
|  | 0xccb0, 0xc802, | 
|  | 0xccb1, 0x7760, | 
|  | 0xccb2, 0xc803, | 
|  | 0xccb3, 0x7fce, | 
|  | 0xccb4, 0xc804, | 
|  | 0xccb5, 0x5700, | 
|  | 0xccb6, 0xc805, | 
|  | 0xccb7, 0x5f11, | 
|  | 0xccb8, 0xc806, | 
|  | 0xccb9, 0x4751, | 
|  | 0xccba, 0xc807, | 
|  | 0xccbb, 0x57e1, | 
|  | 0xccbc, 0xc808, | 
|  | 0xccbd, 0x2700, | 
|  | 0xccbe, 0xc809, | 
|  | 0xccbf, 0x000, | 
|  | 0xccc0, 0xc821, | 
|  | 0xccc1, 0x002, | 
|  | 0xccc2, 0xc822, | 
|  | 0xccc3, 0x014, | 
|  | 0xccc4, 0xc832, | 
|  | 0xccc5, 0x1186, | 
|  | 0xccc6, 0xc847, | 
|  | 0xccc7, 0x1e02, | 
|  | 0xccc8, 0xc013, | 
|  | 0xccc9, 0xf341, | 
|  | 0xccca, 0xc01a, | 
|  | 0xcccb, 0x446, | 
|  | 0xcccc, 0xc024, | 
|  | 0xcccd, 0x1000, | 
|  | 0xccce, 0xc025, | 
|  | 0xcccf, 0xa00, | 
|  | 0xccd0, 0xc026, | 
|  | 0xccd1, 0xc0c, | 
|  | 0xccd2, 0xc027, | 
|  | 0xccd3, 0xc0c, | 
|  | 0xccd4, 0xc029, | 
|  | 0xccd5, 0x0a0, | 
|  | 0xccd6, 0xc030, | 
|  | 0xccd7, 0xa00, | 
|  | 0xccd8, 0xc03c, | 
|  | 0xccd9, 0x01c, | 
|  | 0xccda, 0xc005, | 
|  | 0xccdb, 0x7a06, | 
|  | 0xccdc, 0x000, | 
|  | 0xccdd, 0x2731, | 
|  | 0xccde, 0x3011, | 
|  | 0xccdf, 0x1001, | 
|  | 0xcce0, 0xc620, | 
|  | 0xcce1, 0x000, | 
|  | 0xcce2, 0xc621, | 
|  | 0xcce3, 0x03f, | 
|  | 0xcce4, 0xc622, | 
|  | 0xcce5, 0x000, | 
|  | 0xcce6, 0xc623, | 
|  | 0xcce7, 0x000, | 
|  | 0xcce8, 0xc624, | 
|  | 0xcce9, 0x000, | 
|  | 0xccea, 0xc625, | 
|  | 0xcceb, 0x000, | 
|  | 0xccec, 0xc627, | 
|  | 0xcced, 0x000, | 
|  | 0xccee, 0xc628, | 
|  | 0xccef, 0x000, | 
|  | 0xccf0, 0xc62c, | 
|  | 0xccf1, 0x000, | 
|  | 0xccf2, 0x000, | 
|  | 0xccf3, 0x2806, | 
|  | 0xccf4, 0x3cb6, | 
|  | 0xccf5, 0xc161, | 
|  | 0xccf6, 0x6134, | 
|  | 0xccf7, 0x6135, | 
|  | 0xccf8, 0x5443, | 
|  | 0xccf9, 0x303, | 
|  | 0xccfa, 0x6524, | 
|  | 0xccfb, 0x00b, | 
|  | 0xccfc, 0x1002, | 
|  | 0xccfd, 0x2104, | 
|  | 0xccfe, 0x3c24, | 
|  | 0xccff, 0x2105, | 
|  | 0xcd00, 0x3805, | 
|  | 0xcd01, 0x6524, | 
|  | 0xcd02, 0xdff4, | 
|  | 0xcd03, 0x4005, | 
|  | 0xcd04, 0x6524, | 
|  | 0xcd05, 0x1002, | 
|  | 0xcd06, 0x5dd3, | 
|  | 0xcd07, 0x306, | 
|  | 0xcd08, 0x2ff7, | 
|  | 0xcd09, 0x38f7, | 
|  | 0xcd0a, 0x60b7, | 
|  | 0xcd0b, 0xdffd, | 
|  | 0xcd0c, 0x00a, | 
|  | 0xcd0d, 0x1002, | 
|  | 0xcd0e, 0 | 
|  | }; | 
|  | int i, err; | 
|  |  | 
|  | err = set_phy_regs(phy, regs); | 
|  | if (err) | 
|  | return err; | 
|  |  | 
|  | msleep(50); | 
|  |  | 
|  | for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) | 
|  | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i], | 
|  | sr_edc[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_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  | static struct reg_val preemphasis[] = { | 
|  | { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  | static u16 twinax_edc[] = { | 
|  | 0xcc00, 0x4009, | 
|  | 0xcc01, 0x27ff, | 
|  | 0xcc02, 0x300f, | 
|  | 0xcc03, 0x40aa, | 
|  | 0xcc04, 0x401c, | 
|  | 0xcc05, 0x401e, | 
|  | 0xcc06, 0x2ff4, | 
|  | 0xcc07, 0x3cd4, | 
|  | 0xcc08, 0x2035, | 
|  | 0xcc09, 0x3145, | 
|  | 0xcc0a, 0x6524, | 
|  | 0xcc0b, 0x26a2, | 
|  | 0xcc0c, 0x3012, | 
|  | 0xcc0d, 0x1002, | 
|  | 0xcc0e, 0x29c2, | 
|  | 0xcc0f, 0x3002, | 
|  | 0xcc10, 0x1002, | 
|  | 0xcc11, 0x2072, | 
|  | 0xcc12, 0x3012, | 
|  | 0xcc13, 0x1002, | 
|  | 0xcc14, 0x22cd, | 
|  | 0xcc15, 0x301d, | 
|  | 0xcc16, 0x2e52, | 
|  | 0xcc17, 0x3012, | 
|  | 0xcc18, 0x1002, | 
|  | 0xcc19, 0x28e2, | 
|  | 0xcc1a, 0x3002, | 
|  | 0xcc1b, 0x1002, | 
|  | 0xcc1c, 0x628f, | 
|  | 0xcc1d, 0x2ac2, | 
|  | 0xcc1e, 0x3012, | 
|  | 0xcc1f, 0x1002, | 
|  | 0xcc20, 0x5553, | 
|  | 0xcc21, 0x2ae2, | 
|  | 0xcc22, 0x3002, | 
|  | 0xcc23, 0x1302, | 
|  | 0xcc24, 0x401e, | 
|  | 0xcc25, 0x2be2, | 
|  | 0xcc26, 0x3012, | 
|  | 0xcc27, 0x1002, | 
|  | 0xcc28, 0x2da2, | 
|  | 0xcc29, 0x3012, | 
|  | 0xcc2a, 0x1002, | 
|  | 0xcc2b, 0x2ba2, | 
|  | 0xcc2c, 0x3002, | 
|  | 0xcc2d, 0x1002, | 
|  | 0xcc2e, 0x5ee3, | 
|  | 0xcc2f, 0x305, | 
|  | 0xcc30, 0x400e, | 
|  | 0xcc31, 0x2bc2, | 
|  | 0xcc32, 0x3002, | 
|  | 0xcc33, 0x1002, | 
|  | 0xcc34, 0x2b82, | 
|  | 0xcc35, 0x3012, | 
|  | 0xcc36, 0x1002, | 
|  | 0xcc37, 0x5663, | 
|  | 0xcc38, 0x302, | 
|  | 0xcc39, 0x401e, | 
|  | 0xcc3a, 0x6f72, | 
|  | 0xcc3b, 0x1002, | 
|  | 0xcc3c, 0x628f, | 
|  | 0xcc3d, 0x2be2, | 
|  | 0xcc3e, 0x3012, | 
|  | 0xcc3f, 0x1002, | 
|  | 0xcc40, 0x22cd, | 
|  | 0xcc41, 0x301d, | 
|  | 0xcc42, 0x2e52, | 
|  | 0xcc43, 0x3012, | 
|  | 0xcc44, 0x1002, | 
|  | 0xcc45, 0x2522, | 
|  | 0xcc46, 0x3012, | 
|  | 0xcc47, 0x1002, | 
|  | 0xcc48, 0x2da2, | 
|  | 0xcc49, 0x3012, | 
|  | 0xcc4a, 0x1002, | 
|  | 0xcc4b, 0x2ca2, | 
|  | 0xcc4c, 0x3012, | 
|  | 0xcc4d, 0x1002, | 
|  | 0xcc4e, 0x2fa4, | 
|  | 0xcc4f, 0x3cd4, | 
|  | 0xcc50, 0x6624, | 
|  | 0xcc51, 0x410b, | 
|  | 0xcc52, 0x56b3, | 
|  | 0xcc53, 0x3c4, | 
|  | 0xcc54, 0x2fb2, | 
|  | 0xcc55, 0x3002, | 
|  | 0xcc56, 0x1002, | 
|  | 0xcc57, 0x220b, | 
|  | 0xcc58, 0x303b, | 
|  | 0xcc59, 0x56b3, | 
|  | 0xcc5a, 0x3c3, | 
|  | 0xcc5b, 0x866b, | 
|  | 0xcc5c, 0x400c, | 
|  | 0xcc5d, 0x23a2, | 
|  | 0xcc5e, 0x3012, | 
|  | 0xcc5f, 0x1002, | 
|  | 0xcc60, 0x2da2, | 
|  | 0xcc61, 0x3012, | 
|  | 0xcc62, 0x1002, | 
|  | 0xcc63, 0x2ca2, | 
|  | 0xcc64, 0x3012, | 
|  | 0xcc65, 0x1002, | 
|  | 0xcc66, 0x2fb4, | 
|  | 0xcc67, 0x3cd4, | 
|  | 0xcc68, 0x6624, | 
|  | 0xcc69, 0x56b3, | 
|  | 0xcc6a, 0x3c3, | 
|  | 0xcc6b, 0x866b, | 
|  | 0xcc6c, 0x401c, | 
|  | 0xcc6d, 0x2205, | 
|  | 0xcc6e, 0x3035, | 
|  | 0xcc6f, 0x5b53, | 
|  | 0xcc70, 0x2c52, | 
|  | 0xcc71, 0x3002, | 
|  | 0xcc72, 0x13c2, | 
|  | 0xcc73, 0x5cc3, | 
|  | 0xcc74, 0x317, | 
|  | 0xcc75, 0x2522, | 
|  | 0xcc76, 0x3012, | 
|  | 0xcc77, 0x1002, | 
|  | 0xcc78, 0x2da2, | 
|  | 0xcc79, 0x3012, | 
|  | 0xcc7a, 0x1002, | 
|  | 0xcc7b, 0x2b82, | 
|  | 0xcc7c, 0x3012, | 
|  | 0xcc7d, 0x1002, | 
|  | 0xcc7e, 0x5663, | 
|  | 0xcc7f, 0x303, | 
|  | 0xcc80, 0x401e, | 
|  | 0xcc81, 0x004, | 
|  | 0xcc82, 0x2c42, | 
|  | 0xcc83, 0x3012, | 
|  | 0xcc84, 0x1002, | 
|  | 0xcc85, 0x6f72, | 
|  | 0xcc86, 0x1002, | 
|  | 0xcc87, 0x628f, | 
|  | 0xcc88, 0x2304, | 
|  | 0xcc89, 0x3c84, | 
|  | 0xcc8a, 0x6436, | 
|  | 0xcc8b, 0xdff4, | 
|  | 0xcc8c, 0x6436, | 
|  | 0xcc8d, 0x2ff5, | 
|  | 0xcc8e, 0x3005, | 
|  | 0xcc8f, 0x8656, | 
|  | 0xcc90, 0xdfba, | 
|  | 0xcc91, 0x56a3, | 
|  | 0xcc92, 0xd05a, | 
|  | 0xcc93, 0x21c2, | 
|  | 0xcc94, 0x3012, | 
|  | 0xcc95, 0x1392, | 
|  | 0xcc96, 0xd05a, | 
|  | 0xcc97, 0x56a3, | 
|  | 0xcc98, 0xdfba, | 
|  | 0xcc99, 0x383, | 
|  | 0xcc9a, 0x6f72, | 
|  | 0xcc9b, 0x1002, | 
|  | 0xcc9c, 0x28c5, | 
|  | 0xcc9d, 0x3005, | 
|  | 0xcc9e, 0x4178, | 
|  | 0xcc9f, 0x5653, | 
|  | 0xcca0, 0x384, | 
|  | 0xcca1, 0x22b2, | 
|  | 0xcca2, 0x3012, | 
|  | 0xcca3, 0x1002, | 
|  | 0xcca4, 0x2be5, | 
|  | 0xcca5, 0x3005, | 
|  | 0xcca6, 0x41e8, | 
|  | 0xcca7, 0x5653, | 
|  | 0xcca8, 0x382, | 
|  | 0xcca9, 0x002, | 
|  | 0xccaa, 0x4258, | 
|  | 0xccab, 0x2474, | 
|  | 0xccac, 0x3c84, | 
|  | 0xccad, 0x6437, | 
|  | 0xccae, 0xdff4, | 
|  | 0xccaf, 0x6437, | 
|  | 0xccb0, 0x2ff5, | 
|  | 0xccb1, 0x3c05, | 
|  | 0xccb2, 0x8757, | 
|  | 0xccb3, 0xb888, | 
|  | 0xccb4, 0x9787, | 
|  | 0xccb5, 0xdff4, | 
|  | 0xccb6, 0x6724, | 
|  | 0xccb7, 0x866a, | 
|  | 0xccb8, 0x6f72, | 
|  | 0xccb9, 0x1002, | 
|  | 0xccba, 0x2d01, | 
|  | 0xccbb, 0x3011, | 
|  | 0xccbc, 0x1001, | 
|  | 0xccbd, 0xc620, | 
|  | 0xccbe, 0x14e5, | 
|  | 0xccbf, 0xc621, | 
|  | 0xccc0, 0xc53d, | 
|  | 0xccc1, 0xc622, | 
|  | 0xccc2, 0x3cbe, | 
|  | 0xccc3, 0xc623, | 
|  | 0xccc4, 0x4452, | 
|  | 0xccc5, 0xc624, | 
|  | 0xccc6, 0xc5c5, | 
|  | 0xccc7, 0xc625, | 
|  | 0xccc8, 0xe01e, | 
|  | 0xccc9, 0xc627, | 
|  | 0xccca, 0x000, | 
|  | 0xcccb, 0xc628, | 
|  | 0xcccc, 0x000, | 
|  | 0xcccd, 0xc62b, | 
|  | 0xccce, 0x000, | 
|  | 0xcccf, 0xc62c, | 
|  | 0xccd0, 0x000, | 
|  | 0xccd1, 0x000, | 
|  | 0xccd2, 0x2d01, | 
|  | 0xccd3, 0x3011, | 
|  | 0xccd4, 0x1001, | 
|  | 0xccd5, 0xc620, | 
|  | 0xccd6, 0x000, | 
|  | 0xccd7, 0xc621, | 
|  | 0xccd8, 0x000, | 
|  | 0xccd9, 0xc622, | 
|  | 0xccda, 0x0ce, | 
|  | 0xccdb, 0xc623, | 
|  | 0xccdc, 0x07f, | 
|  | 0xccdd, 0xc624, | 
|  | 0xccde, 0x032, | 
|  | 0xccdf, 0xc625, | 
|  | 0xcce0, 0x000, | 
|  | 0xcce1, 0xc627, | 
|  | 0xcce2, 0x000, | 
|  | 0xcce3, 0xc628, | 
|  | 0xcce4, 0x000, | 
|  | 0xcce5, 0xc62b, | 
|  | 0xcce6, 0x000, | 
|  | 0xcce7, 0xc62c, | 
|  | 0xcce8, 0x000, | 
|  | 0xcce9, 0x000, | 
|  | 0xccea, 0x2d01, | 
|  | 0xcceb, 0x3011, | 
|  | 0xccec, 0x1001, | 
|  | 0xcced, 0xc502, | 
|  | 0xccee, 0x609f, | 
|  | 0xccef, 0xc600, | 
|  | 0xccf0, 0x2a6e, | 
|  | 0xccf1, 0xc601, | 
|  | 0xccf2, 0x2a2c, | 
|  | 0xccf3, 0xc60c, | 
|  | 0xccf4, 0x5400, | 
|  | 0xccf5, 0xc710, | 
|  | 0xccf6, 0x700, | 
|  | 0xccf7, 0xc718, | 
|  | 0xccf8, 0x700, | 
|  | 0xccf9, 0xc720, | 
|  | 0xccfa, 0x4700, | 
|  | 0xccfb, 0xc728, | 
|  | 0xccfc, 0x700, | 
|  | 0xccfd, 0xc729, | 
|  | 0xccfe, 0x1207, | 
|  | 0xccff, 0xc801, | 
|  | 0xcd00, 0x7f50, | 
|  | 0xcd01, 0xc802, | 
|  | 0xcd02, 0x7760, | 
|  | 0xcd03, 0xc803, | 
|  | 0xcd04, 0x7fce, | 
|  | 0xcd05, 0xc804, | 
|  | 0xcd06, 0x520e, | 
|  | 0xcd07, 0xc805, | 
|  | 0xcd08, 0x5c11, | 
|  | 0xcd09, 0xc806, | 
|  | 0xcd0a, 0x3c51, | 
|  | 0xcd0b, 0xc807, | 
|  | 0xcd0c, 0x4061, | 
|  | 0xcd0d, 0xc808, | 
|  | 0xcd0e, 0x49c1, | 
|  | 0xcd0f, 0xc809, | 
|  | 0xcd10, 0x3840, | 
|  | 0xcd11, 0xc80a, | 
|  | 0xcd12, 0x000, | 
|  | 0xcd13, 0xc821, | 
|  | 0xcd14, 0x002, | 
|  | 0xcd15, 0xc822, | 
|  | 0xcd16, 0x046, | 
|  | 0xcd17, 0xc844, | 
|  | 0xcd18, 0x182f, | 
|  | 0xcd19, 0xc013, | 
|  | 0xcd1a, 0xf341, | 
|  | 0xcd1b, 0xc01a, | 
|  | 0xcd1c, 0x446, | 
|  | 0xcd1d, 0xc024, | 
|  | 0xcd1e, 0x1000, | 
|  | 0xcd1f, 0xc025, | 
|  | 0xcd20, 0xa00, | 
|  | 0xcd21, 0xc026, | 
|  | 0xcd22, 0xc0c, | 
|  | 0xcd23, 0xc027, | 
|  | 0xcd24, 0xc0c, | 
|  | 0xcd25, 0xc029, | 
|  | 0xcd26, 0x0a0, | 
|  | 0xcd27, 0xc030, | 
|  | 0xcd28, 0xa00, | 
|  | 0xcd29, 0xc03c, | 
|  | 0xcd2a, 0x01c, | 
|  | 0xcd2b, 0x000, | 
|  | 0xcd2c, 0x2b84, | 
|  | 0xcd2d, 0x3c74, | 
|  | 0xcd2e, 0x6435, | 
|  | 0xcd2f, 0xdff4, | 
|  | 0xcd30, 0x6435, | 
|  | 0xcd31, 0x2806, | 
|  | 0xcd32, 0x3006, | 
|  | 0xcd33, 0x8565, | 
|  | 0xcd34, 0x2b24, | 
|  | 0xcd35, 0x3c24, | 
|  | 0xcd36, 0x6436, | 
|  | 0xcd37, 0x1002, | 
|  | 0xcd38, 0x2b24, | 
|  | 0xcd39, 0x3c24, | 
|  | 0xcd3a, 0x6436, | 
|  | 0xcd3b, 0x4045, | 
|  | 0xcd3c, 0x8656, | 
|  | 0xcd3d, 0x1002, | 
|  | 0xcd3e, 0x2807, | 
|  | 0xcd3f, 0x31a7, | 
|  | 0xcd40, 0x20c4, | 
|  | 0xcd41, 0x3c24, | 
|  | 0xcd42, 0x6724, | 
|  | 0xcd43, 0x1002, | 
|  | 0xcd44, 0x2807, | 
|  | 0xcd45, 0x3187, | 
|  | 0xcd46, 0x20c4, | 
|  | 0xcd47, 0x3c24, | 
|  | 0xcd48, 0x6724, | 
|  | 0xcd49, 0x1002, | 
|  | 0xcd4a, 0x2514, | 
|  | 0xcd4b, 0x3c64, | 
|  | 0xcd4c, 0x6436, | 
|  | 0xcd4d, 0xdff4, | 
|  | 0xcd4e, 0x6436, | 
|  | 0xcd4f, 0x1002, | 
|  | 0xcd50, 0x2806, | 
|  | 0xcd51, 0x3cb6, | 
|  | 0xcd52, 0xc161, | 
|  | 0xcd53, 0x6134, | 
|  | 0xcd54, 0x6135, | 
|  | 0xcd55, 0x5443, | 
|  | 0xcd56, 0x303, | 
|  | 0xcd57, 0x6524, | 
|  | 0xcd58, 0x00b, | 
|  | 0xcd59, 0x1002, | 
|  | 0xcd5a, 0xd019, | 
|  | 0xcd5b, 0x2104, | 
|  | 0xcd5c, 0x3c24, | 
|  | 0xcd5d, 0x2105, | 
|  | 0xcd5e, 0x3805, | 
|  | 0xcd5f, 0x6524, | 
|  | 0xcd60, 0xdff4, | 
|  | 0xcd61, 0x4005, | 
|  | 0xcd62, 0x6524, | 
|  | 0xcd63, 0x2e8d, | 
|  | 0xcd64, 0x303d, | 
|  | 0xcd65, 0x5dd3, | 
|  | 0xcd66, 0x306, | 
|  | 0xcd67, 0x2ff7, | 
|  | 0xcd68, 0x38f7, | 
|  | 0xcd69, 0x60b7, | 
|  | 0xcd6a, 0xdffd, | 
|  | 0xcd6b, 0x00a, | 
|  | 0xcd6c, 0x1002, | 
|  | 0xcd6d, 0 | 
|  | }; | 
|  | int i, err; | 
|  |  | 
|  | 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); | 
|  |  | 
|  | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) | 
|  | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], | 
|  | twinax_edc[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 = t3_mdio_read(phy, MDIO_MMD_PMAPMD, 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 = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200); | 
|  | return err ? err : t3_phy_lasi_intr_enable(phy); | 
|  | } | 
|  |  | 
|  | static int ael2005_intr_disable(struct cphy *phy) | 
|  | { | 
|  | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100); | 
|  | return err ? err : t3_phy_lasi_intr_disable(phy); | 
|  | } | 
|  |  | 
|  | static int ael2005_intr_clear(struct cphy *phy) | 
|  | { | 
|  | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, 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_MMD_PMAPMD, 0xc001, 0, 1 << 5 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, | 
|  | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  | static struct reg_val regs1[] = { | 
|  | { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 }, | 
|  | { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  |  | 
|  | int err; | 
|  | unsigned int lasi_ctrl; | 
|  |  | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, | 
|  | &lasi_ctrl); | 
|  | if (err) | 
|  | return err; | 
|  |  | 
|  | err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 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 = err; | 
|  |  | 
|  | 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 = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat); | 
|  | if (ret) | 
|  | return ret; | 
|  |  | 
|  | if (stat & AEL2005_MODDET_IRQ) { | 
|  | ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, 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 = 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; | 
|  | return ret ? ret : cphy_cause_link_change; | 
|  | } | 
|  |  | 
|  | static struct cphy_ops ael2005_ops = { | 
|  | .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, | 
|  | .mmds            = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | 
|  | }; | 
|  |  | 
|  | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | 
|  | int phy_addr, const struct mdio_ops *mdio_ops) | 
|  | { | 
|  | cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops, | 
|  | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | | 
|  | SUPPORTED_IRQ, "10GBASE-R"); | 
|  | msleep(125); | 
|  | return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0, | 
|  | 1 << 5); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * 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_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a }, | 
|  |  | 
|  | /* adjust 10G RX bias current */ | 
|  | { MDIO_MMD_PMAPMD, 0xcb1b, 0xffff, 0x0200 }, | 
|  | { MDIO_MMD_PMAPMD, 0xcb1c, 0xffff, 0x00f0 }, | 
|  | { MDIO_MMD_PMAPMD, 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_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 }, | 
|  | { MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  |  | 
|  | /* activate uC clock */ | 
|  | static struct reg_val uCclockActivate[] = { | 
|  | { MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  |  | 
|  | /* set PC to start of SRAM and activate uC */ | 
|  | static struct reg_val uCactivate[] = { | 
|  | { MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 }, | 
|  | { MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 }, | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  |  | 
|  | /* TWINAX EDC firmware */ | 
|  | static u16 twinax_edc[] = { | 
|  | 0xd800, 0x4009, | 
|  | 0xd801, 0x2fff, | 
|  | 0xd802, 0x300f, | 
|  | 0xd803, 0x40aa, | 
|  | 0xd804, 0x401c, | 
|  | 0xd805, 0x401e, | 
|  | 0xd806, 0x2ff4, | 
|  | 0xd807, 0x3dc4, | 
|  | 0xd808, 0x2035, | 
|  | 0xd809, 0x3035, | 
|  | 0xd80a, 0x6524, | 
|  | 0xd80b, 0x2cb2, | 
|  | 0xd80c, 0x3012, | 
|  | 0xd80d, 0x1002, | 
|  | 0xd80e, 0x26e2, | 
|  | 0xd80f, 0x3022, | 
|  | 0xd810, 0x1002, | 
|  | 0xd811, 0x27d2, | 
|  | 0xd812, 0x3022, | 
|  | 0xd813, 0x1002, | 
|  | 0xd814, 0x2822, | 
|  | 0xd815, 0x3012, | 
|  | 0xd816, 0x1002, | 
|  | 0xd817, 0x2492, | 
|  | 0xd818, 0x3022, | 
|  | 0xd819, 0x1002, | 
|  | 0xd81a, 0x2772, | 
|  | 0xd81b, 0x3012, | 
|  | 0xd81c, 0x1002, | 
|  | 0xd81d, 0x23d2, | 
|  | 0xd81e, 0x3022, | 
|  | 0xd81f, 0x1002, | 
|  | 0xd820, 0x22cd, | 
|  | 0xd821, 0x301d, | 
|  | 0xd822, 0x27f2, | 
|  | 0xd823, 0x3022, | 
|  | 0xd824, 0x1002, | 
|  | 0xd825, 0x5553, | 
|  | 0xd826, 0x0307, | 
|  | 0xd827, 0x2522, | 
|  | 0xd828, 0x3022, | 
|  | 0xd829, 0x1002, | 
|  | 0xd82a, 0x2142, | 
|  | 0xd82b, 0x3012, | 
|  | 0xd82c, 0x1002, | 
|  | 0xd82d, 0x4016, | 
|  | 0xd82e, 0x5e63, | 
|  | 0xd82f, 0x0344, | 
|  | 0xd830, 0x2142, | 
|  | 0xd831, 0x3012, | 
|  | 0xd832, 0x1002, | 
|  | 0xd833, 0x400e, | 
|  | 0xd834, 0x2522, | 
|  | 0xd835, 0x3022, | 
|  | 0xd836, 0x1002, | 
|  | 0xd837, 0x2b52, | 
|  | 0xd838, 0x3012, | 
|  | 0xd839, 0x1002, | 
|  | 0xd83a, 0x2742, | 
|  | 0xd83b, 0x3022, | 
|  | 0xd83c, 0x1002, | 
|  | 0xd83d, 0x25e2, | 
|  | 0xd83e, 0x3022, | 
|  | 0xd83f, 0x1002, | 
|  | 0xd840, 0x2fa4, | 
|  | 0xd841, 0x3dc4, | 
|  | 0xd842, 0x6624, | 
|  | 0xd843, 0x414b, | 
|  | 0xd844, 0x56b3, | 
|  | 0xd845, 0x03c6, | 
|  | 0xd846, 0x866b, | 
|  | 0xd847, 0x400c, | 
|  | 0xd848, 0x2712, | 
|  | 0xd849, 0x3012, | 
|  | 0xd84a, 0x1002, | 
|  | 0xd84b, 0x2c4b, | 
|  | 0xd84c, 0x309b, | 
|  | 0xd84d, 0x56b3, | 
|  | 0xd84e, 0x03c3, | 
|  | 0xd84f, 0x866b, | 
|  | 0xd850, 0x400c, | 
|  | 0xd851, 0x2272, | 
|  | 0xd852, 0x3022, | 
|  | 0xd853, 0x1002, | 
|  | 0xd854, 0x2742, | 
|  | 0xd855, 0x3022, | 
|  | 0xd856, 0x1002, | 
|  | 0xd857, 0x25e2, | 
|  | 0xd858, 0x3022, | 
|  | 0xd859, 0x1002, | 
|  | 0xd85a, 0x2fb4, | 
|  | 0xd85b, 0x3dc4, | 
|  | 0xd85c, 0x6624, | 
|  | 0xd85d, 0x56b3, | 
|  | 0xd85e, 0x03c3, | 
|  | 0xd85f, 0x866b, | 
|  | 0xd860, 0x401c, | 
|  | 0xd861, 0x2c45, | 
|  | 0xd862, 0x3095, | 
|  | 0xd863, 0x5b53, | 
|  | 0xd864, 0x2372, | 
|  | 0xd865, 0x3012, | 
|  | 0xd866, 0x13c2, | 
|  | 0xd867, 0x5cc3, | 
|  | 0xd868, 0x2712, | 
|  | 0xd869, 0x3012, | 
|  | 0xd86a, 0x1312, | 
|  | 0xd86b, 0x2b52, | 
|  | 0xd86c, 0x3012, | 
|  | 0xd86d, 0x1002, | 
|  | 0xd86e, 0x2742, | 
|  | 0xd86f, 0x3022, | 
|  | 0xd870, 0x1002, | 
|  | 0xd871, 0x2582, | 
|  | 0xd872, 0x3022, | 
|  | 0xd873, 0x1002, | 
|  | 0xd874, 0x2142, | 
|  | 0xd875, 0x3012, | 
|  | 0xd876, 0x1002, | 
|  | 0xd877, 0x628f, | 
|  | 0xd878, 0x2985, | 
|  | 0xd879, 0x33a5, | 
|  | 0xd87a, 0x25e2, | 
|  | 0xd87b, 0x3022, | 
|  | 0xd87c, 0x1002, | 
|  | 0xd87d, 0x5653, | 
|  | 0xd87e, 0x03d2, | 
|  | 0xd87f, 0x401e, | 
|  | 0xd880, 0x6f72, | 
|  | 0xd881, 0x1002, | 
|  | 0xd882, 0x628f, | 
|  | 0xd883, 0x2304, | 
|  | 0xd884, 0x3c84, | 
|  | 0xd885, 0x6436, | 
|  | 0xd886, 0xdff4, | 
|  | 0xd887, 0x6436, | 
|  | 0xd888, 0x2ff5, | 
|  | 0xd889, 0x3005, | 
|  | 0xd88a, 0x8656, | 
|  | 0xd88b, 0xdfba, | 
|  | 0xd88c, 0x56a3, | 
|  | 0xd88d, 0xd05a, | 
|  | 0xd88e, 0x2972, | 
|  | 0xd88f, 0x3012, | 
|  | 0xd890, 0x1392, | 
|  | 0xd891, 0xd05a, | 
|  | 0xd892, 0x56a3, | 
|  | 0xd893, 0xdfba, | 
|  | 0xd894, 0x0383, | 
|  | 0xd895, 0x6f72, | 
|  | 0xd896, 0x1002, | 
|  | 0xd897, 0x2b45, | 
|  | 0xd898, 0x3005, | 
|  | 0xd899, 0x4178, | 
|  | 0xd89a, 0x5653, | 
|  | 0xd89b, 0x0384, | 
|  | 0xd89c, 0x2a62, | 
|  | 0xd89d, 0x3012, | 
|  | 0xd89e, 0x1002, | 
|  | 0xd89f, 0x2f05, | 
|  | 0xd8a0, 0x3005, | 
|  | 0xd8a1, 0x41c8, | 
|  | 0xd8a2, 0x5653, | 
|  | 0xd8a3, 0x0382, | 
|  | 0xd8a4, 0x0002, | 
|  | 0xd8a5, 0x4218, | 
|  | 0xd8a6, 0x2474, | 
|  | 0xd8a7, 0x3c84, | 
|  | 0xd8a8, 0x6437, | 
|  | 0xd8a9, 0xdff4, | 
|  | 0xd8aa, 0x6437, | 
|  | 0xd8ab, 0x2ff5, | 
|  | 0xd8ac, 0x3c05, | 
|  | 0xd8ad, 0x8757, | 
|  | 0xd8ae, 0xb888, | 
|  | 0xd8af, 0x9787, | 
|  | 0xd8b0, 0xdff4, | 
|  | 0xd8b1, 0x6724, | 
|  | 0xd8b2, 0x866a, | 
|  | 0xd8b3, 0x6f72, | 
|  | 0xd8b4, 0x1002, | 
|  | 0xd8b5, 0x2641, | 
|  | 0xd8b6, 0x3021, | 
|  | 0xd8b7, 0x1001, | 
|  | 0xd8b8, 0xc620, | 
|  | 0xd8b9, 0x0000, | 
|  | 0xd8ba, 0xc621, | 
|  | 0xd8bb, 0x0000, | 
|  | 0xd8bc, 0xc622, | 
|  | 0xd8bd, 0x00ce, | 
|  | 0xd8be, 0xc623, | 
|  | 0xd8bf, 0x007f, | 
|  | 0xd8c0, 0xc624, | 
|  | 0xd8c1, 0x0032, | 
|  | 0xd8c2, 0xc625, | 
|  | 0xd8c3, 0x0000, | 
|  | 0xd8c4, 0xc627, | 
|  | 0xd8c5, 0x0000, | 
|  | 0xd8c6, 0xc628, | 
|  | 0xd8c7, 0x0000, | 
|  | 0xd8c8, 0xc62c, | 
|  | 0xd8c9, 0x0000, | 
|  | 0xd8ca, 0x0000, | 
|  | 0xd8cb, 0x2641, | 
|  | 0xd8cc, 0x3021, | 
|  | 0xd8cd, 0x1001, | 
|  | 0xd8ce, 0xc502, | 
|  | 0xd8cf, 0x53ac, | 
|  | 0xd8d0, 0xc503, | 
|  | 0xd8d1, 0x2cd3, | 
|  | 0xd8d2, 0xc600, | 
|  | 0xd8d3, 0x2a6e, | 
|  | 0xd8d4, 0xc601, | 
|  | 0xd8d5, 0x2a2c, | 
|  | 0xd8d6, 0xc605, | 
|  | 0xd8d7, 0x5557, | 
|  | 0xd8d8, 0xc60c, | 
|  | 0xd8d9, 0x5400, | 
|  | 0xd8da, 0xc710, | 
|  | 0xd8db, 0x0700, | 
|  | 0xd8dc, 0xc711, | 
|  | 0xd8dd, 0x0f06, | 
|  | 0xd8de, 0xc718, | 
|  | 0xd8df, 0x0700, | 
|  | 0xd8e0, 0xc719, | 
|  | 0xd8e1, 0x0f06, | 
|  | 0xd8e2, 0xc720, | 
|  | 0xd8e3, 0x4700, | 
|  | 0xd8e4, 0xc721, | 
|  | 0xd8e5, 0x0f06, | 
|  | 0xd8e6, 0xc728, | 
|  | 0xd8e7, 0x0700, | 
|  | 0xd8e8, 0xc729, | 
|  | 0xd8e9, 0x1207, | 
|  | 0xd8ea, 0xc801, | 
|  | 0xd8eb, 0x7f50, | 
|  | 0xd8ec, 0xc802, | 
|  | 0xd8ed, 0x7760, | 
|  | 0xd8ee, 0xc803, | 
|  | 0xd8ef, 0x7fce, | 
|  | 0xd8f0, 0xc804, | 
|  | 0xd8f1, 0x520e, | 
|  | 0xd8f2, 0xc805, | 
|  | 0xd8f3, 0x5c11, | 
|  | 0xd8f4, 0xc806, | 
|  | 0xd8f5, 0x3c51, | 
|  | 0xd8f6, 0xc807, | 
|  | 0xd8f7, 0x4061, | 
|  | 0xd8f8, 0xc808, | 
|  | 0xd8f9, 0x49c1, | 
|  | 0xd8fa, 0xc809, | 
|  | 0xd8fb, 0x3840, | 
|  | 0xd8fc, 0xc80a, | 
|  | 0xd8fd, 0x0000, | 
|  | 0xd8fe, 0xc821, | 
|  | 0xd8ff, 0x0002, | 
|  | 0xd900, 0xc822, | 
|  | 0xd901, 0x0046, | 
|  | 0xd902, 0xc844, | 
|  | 0xd903, 0x182f, | 
|  | 0xd904, 0xc013, | 
|  | 0xd905, 0xf341, | 
|  | 0xd906, 0xc084, | 
|  | 0xd907, 0x0030, | 
|  | 0xd908, 0xc904, | 
|  | 0xd909, 0x1401, | 
|  | 0xd90a, 0xcb0c, | 
|  | 0xd90b, 0x0004, | 
|  | 0xd90c, 0xcb0e, | 
|  | 0xd90d, 0xa00a, | 
|  | 0xd90e, 0xcb0f, | 
|  | 0xd90f, 0xc0c0, | 
|  | 0xd910, 0xcb10, | 
|  | 0xd911, 0xc0c0, | 
|  | 0xd912, 0xcb11, | 
|  | 0xd913, 0x00a0, | 
|  | 0xd914, 0xcb12, | 
|  | 0xd915, 0x0007, | 
|  | 0xd916, 0xc241, | 
|  | 0xd917, 0xa000, | 
|  | 0xd918, 0xc243, | 
|  | 0xd919, 0x7fe0, | 
|  | 0xd91a, 0xc604, | 
|  | 0xd91b, 0x000e, | 
|  | 0xd91c, 0xc609, | 
|  | 0xd91d, 0x00f5, | 
|  | 0xd91e, 0xc611, | 
|  | 0xd91f, 0x000e, | 
|  | 0xd920, 0xc660, | 
|  | 0xd921, 0x9600, | 
|  | 0xd922, 0xc687, | 
|  | 0xd923, 0x0004, | 
|  | 0xd924, 0xc60a, | 
|  | 0xd925, 0x04f5, | 
|  | 0xd926, 0x0000, | 
|  | 0xd927, 0x2641, | 
|  | 0xd928, 0x3021, | 
|  | 0xd929, 0x1001, | 
|  | 0xd92a, 0xc620, | 
|  | 0xd92b, 0x14e5, | 
|  | 0xd92c, 0xc621, | 
|  | 0xd92d, 0xc53d, | 
|  | 0xd92e, 0xc622, | 
|  | 0xd92f, 0x3cbe, | 
|  | 0xd930, 0xc623, | 
|  | 0xd931, 0x4452, | 
|  | 0xd932, 0xc624, | 
|  | 0xd933, 0xc5c5, | 
|  | 0xd934, 0xc625, | 
|  | 0xd935, 0xe01e, | 
|  | 0xd936, 0xc627, | 
|  | 0xd937, 0x0000, | 
|  | 0xd938, 0xc628, | 
|  | 0xd939, 0x0000, | 
|  | 0xd93a, 0xc62c, | 
|  | 0xd93b, 0x0000, | 
|  | 0xd93c, 0x0000, | 
|  | 0xd93d, 0x2b84, | 
|  | 0xd93e, 0x3c74, | 
|  | 0xd93f, 0x6435, | 
|  | 0xd940, 0xdff4, | 
|  | 0xd941, 0x6435, | 
|  | 0xd942, 0x2806, | 
|  | 0xd943, 0x3006, | 
|  | 0xd944, 0x8565, | 
|  | 0xd945, 0x2b24, | 
|  | 0xd946, 0x3c24, | 
|  | 0xd947, 0x6436, | 
|  | 0xd948, 0x1002, | 
|  | 0xd949, 0x2b24, | 
|  | 0xd94a, 0x3c24, | 
|  | 0xd94b, 0x6436, | 
|  | 0xd94c, 0x4045, | 
|  | 0xd94d, 0x8656, | 
|  | 0xd94e, 0x5663, | 
|  | 0xd94f, 0x0302, | 
|  | 0xd950, 0x401e, | 
|  | 0xd951, 0x1002, | 
|  | 0xd952, 0x2807, | 
|  | 0xd953, 0x31a7, | 
|  | 0xd954, 0x20c4, | 
|  | 0xd955, 0x3c24, | 
|  | 0xd956, 0x6724, | 
|  | 0xd957, 0x1002, | 
|  | 0xd958, 0x2807, | 
|  | 0xd959, 0x3187, | 
|  | 0xd95a, 0x20c4, | 
|  | 0xd95b, 0x3c24, | 
|  | 0xd95c, 0x6724, | 
|  | 0xd95d, 0x1002, | 
|  | 0xd95e, 0x24f4, | 
|  | 0xd95f, 0x3c64, | 
|  | 0xd960, 0x6436, | 
|  | 0xd961, 0xdff4, | 
|  | 0xd962, 0x6436, | 
|  | 0xd963, 0x1002, | 
|  | 0xd964, 0x2006, | 
|  | 0xd965, 0x3d76, | 
|  | 0xd966, 0xc161, | 
|  | 0xd967, 0x6134, | 
|  | 0xd968, 0x6135, | 
|  | 0xd969, 0x5443, | 
|  | 0xd96a, 0x0303, | 
|  | 0xd96b, 0x6524, | 
|  | 0xd96c, 0x00fb, | 
|  | 0xd96d, 0x1002, | 
|  | 0xd96e, 0x20d4, | 
|  | 0xd96f, 0x3c24, | 
|  | 0xd970, 0x2025, | 
|  | 0xd971, 0x3005, | 
|  | 0xd972, 0x6524, | 
|  | 0xd973, 0x1002, | 
|  | 0xd974, 0xd019, | 
|  | 0xd975, 0x2104, | 
|  | 0xd976, 0x3c24, | 
|  | 0xd977, 0x2105, | 
|  | 0xd978, 0x3805, | 
|  | 0xd979, 0x6524, | 
|  | 0xd97a, 0xdff4, | 
|  | 0xd97b, 0x4005, | 
|  | 0xd97c, 0x6524, | 
|  | 0xd97d, 0x2e8d, | 
|  | 0xd97e, 0x303d, | 
|  | 0xd97f, 0x2408, | 
|  | 0xd980, 0x35d8, | 
|  | 0xd981, 0x5dd3, | 
|  | 0xd982, 0x0307, | 
|  | 0xd983, 0x8887, | 
|  | 0xd984, 0x63a7, | 
|  | 0xd985, 0x8887, | 
|  | 0xd986, 0x63a7, | 
|  | 0xd987, 0xdffd, | 
|  | 0xd988, 0x00f9, | 
|  | 0xd989, 0x1002, | 
|  | 0xd98a, 0x0000, | 
|  | }; | 
|  | int i, err; | 
|  |  | 
|  | /* 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; | 
|  |  | 
|  | /* write TWINAX EDC firmware into PHY */ | 
|  | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) | 
|  | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], | 
|  | twinax_edc[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 = t3_mdio_read(phy, MDIO_MMD_PMAPMD, 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); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * 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) | 
|  | { | 
|  | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | 
|  | 0x2 << (AEL2020_GPIO_MODDET*4)); | 
|  | return err ? err : t3_phy_lasi_intr_enable(phy); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Disable PHY interrupts.  The mirror of the above ... | 
|  | */ | 
|  | static int ael2020_intr_disable(struct cphy *phy) | 
|  | { | 
|  | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | 
|  | 0x1 << (AEL2020_GPIO_MODDET*4)); | 
|  | return err ? err : 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 = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat); | 
|  | return err ? err : t3_phy_lasi_intr_clear(phy); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Reset the PHY and put it into a canonical operating state. | 
|  | */ | 
|  | static int ael2020_reset(struct cphy *phy, int wait) | 
|  | { | 
|  | static struct reg_val regs0[] = { | 
|  | /* Erratum #2: CDRLOL asserted, causing PMA link down status */ | 
|  | { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 }, | 
|  |  | 
|  | /* force XAUI to send LF when RX_LOS is asserted */ | 
|  | { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 }, | 
|  |  | 
|  | /* RX_LOS pin is active high */ | 
|  | { MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, | 
|  | 0x0020, 0x0020 }, | 
|  |  | 
|  | /* output Module's Loss Of Signal (LOS) to LED */ | 
|  | { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, | 
|  | 0xffff, 0x0004 }, | 
|  | { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | 
|  | 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) }, | 
|  |  | 
|  | /* end */ | 
|  | { 0, 0, 0, 0 } | 
|  | }; | 
|  | int err; | 
|  | unsigned int lasi_ctrl; | 
|  |  | 
|  | /* grab current interrupt state */ | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, | 
|  | &lasi_ctrl); | 
|  | if (err) | 
|  | return err; | 
|  |  | 
|  | err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 125); | 
|  | if (err) | 
|  | return err; | 
|  | msleep(100); | 
|  |  | 
|  | /* basic initialization for all module types */ | 
|  | phy->priv = edc_none; | 
|  | err = set_phy_regs(phy, regs0); | 
|  | if (err) | 
|  | return err; | 
|  |  | 
|  | /* 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_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 = ael2005_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 = t3_mdio_read(phy, MDIO_MMD_PMAPMD, 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; | 
|  | return ret ? ret : cphy_cause_link_change; | 
|  | } | 
|  |  | 
|  | static struct cphy_ops ael2020_ops = { | 
|  | .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, | 
|  | .mmds		 = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | 
|  | }; | 
|  |  | 
|  | int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, | 
|  | const struct mdio_ops *mdio_ops) | 
|  | { | 
|  | cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops, | 
|  | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | | 
|  | SUPPORTED_IRQ, "10GBASE-R"); | 
|  | msleep(125); | 
|  | 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 = t3_mdio_read(phy, MDIO_MMD_PMAPMD, | 
|  | MDIO_PMA_RXDET, &stat0); | 
|  |  | 
|  | if (!err) | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PCS, | 
|  | MDIO_PCS_10GBX_STAT1, &stat1); | 
|  | if (!err) | 
|  | err = t3_mdio_read(phy, MDIO_MMD_PHYXS, | 
|  | MDIO_PHYXS_LNSTAT, &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; | 
|  | } | 
|  |  | 
|  | 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 = ael1006_power_down, | 
|  | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | 
|  | }; | 
|  |  | 
|  | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, | 
|  | int phy_addr, const struct mdio_ops *mdio_ops) | 
|  | { | 
|  | unsigned int stat; | 
|  |  | 
|  | cphy_init(phy, adapter, 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 && | 
|  | !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) && | 
|  | stat == 0xffff) | 
|  | phy->mdio.prtad = 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; | 
|  | int prtad = phy->mdio.prtad; | 
|  |  | 
|  | status = t3_read_reg(phy->adapter, | 
|  | XGM_REG(A_XGM_SERDES_STAT0, prtad)) | | 
|  | t3_read_reg(phy->adapter, | 
|  | XGM_REG(A_XGM_SERDES_STAT1, prtad)) | | 
|  | t3_read_reg(phy->adapter, | 
|  | XGM_REG(A_XGM_SERDES_STAT2, prtad)) | | 
|  | t3_read_reg(phy->adapter, | 
|  | XGM_REG(A_XGM_SERDES_STAT3, prtad)); | 
|  | *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; | 
|  | } | 
|  |  | 
|  | 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, | 
|  | }; | 
|  |  | 
|  | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, | 
|  | int phy_addr, const struct mdio_ops *mdio_ops) | 
|  | { | 
|  | cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, | 
|  | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, | 
|  | "10GBASE-CX4"); | 
|  | return 0; | 
|  | } |