|
@@ -1643,9 +1643,39 @@ static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
|
|
|
*/
|
|
|
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);
|
|
|
+ struct reg_val regs[] = {
|
|
|
+ /* output Module's Loss Of Signal (LOS) to LED */
|
|
|
+ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
|
|
|
+ 0xffff, 0x4 },
|
|
|
+ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
|
|
|
+ 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
|
|
|
+
|
|
|
+ /* enable module detect status change interrupts */
|
|
|
+ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
|
|
|
+ 0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) },
|
|
|
+
|
|
|
+ /* end */
|
|
|
+ { 0, 0, 0, 0 }
|
|
|
+ };
|
|
|
+ int err, link_ok = 0;
|
|
|
+
|
|
|
+ /* set up "link status" LED and enable module change interrupts */
|
|
|
+ err = set_phy_regs(phy, regs);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ err = get_link_status_r(phy, &link_ok, NULL, NULL, NULL);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+ if (link_ok)
|
|
|
+ t3_link_changed(phy->adapter,
|
|
|
+ phy2portid(phy));
|
|
|
+
|
|
|
+ err = t3_phy_lasi_intr_enable(phy);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1653,9 +1683,26 @@ static int ael2020_intr_enable(struct cphy *phy)
|
|
|
*/
|
|
|
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);
|
|
|
+ struct reg_val regs[] = {
|
|
|
+ /* reset "link status" LED to "off" */
|
|
|
+ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
|
|
|
+ 0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) },
|
|
|
+
|
|
|
+ /* disable module detect status change interrupts */
|
|
|
+ { MDIO_MMD_PMAPMD, 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;
|
|
|
+
|
|
|
+ return t3_phy_lasi_intr_disable(phy);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1673,31 +1720,26 @@ static int ael2020_intr_clear(struct cphy *phy)
|
|
|
return err ? err : t3_phy_lasi_intr_clear(phy);
|
|
|
}
|
|
|
|
|
|
+static struct reg_val ael2020_reset_regs[] = {
|
|
|
+ /* 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 },
|
|
|
+
|
|
|
+ /* allow writes to transceiver module EEPROM on i2c bus */
|
|
|
+ { MDIO_MMD_PMAPMD, 0xff02, 0xffff, 0x0023 },
|
|
|
+ { MDIO_MMD_PMAPMD, 0xff03, 0xffff, 0x0000 },
|
|
|
+ { MDIO_MMD_PMAPMD, 0xff04, 0xffff, 0x0000 },
|
|
|
+
|
|
|
+ /* 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)
|
|
|
{
|
|
|
- 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;
|
|
|
|
|
@@ -1714,7 +1756,7 @@ static int ael2020_reset(struct cphy *phy, int wait)
|
|
|
|
|
|
/* basic initialization for all module types */
|
|
|
phy->priv = edc_none;
|
|
|
- err = set_phy_regs(phy, regs0);
|
|
|
+ err = set_phy_regs(phy, ael2020_reset_regs);
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
@@ -1792,10 +1834,16 @@ static struct cphy_ops ael2020_ops = {
|
|
|
int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
|
|
|
const struct mdio_ops *mdio_ops)
|
|
|
{
|
|
|
+ int err;
|
|
|
+
|
|
|
cphy_init(phy, adapter, 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;
|
|
|
return 0;
|
|
|
}
|
|
|
|