Commit 5e659515569220701bfe3c8936dcab67554cc286

Authored by Divy Le Ray
Committed by David S. Miller
1 parent cfe2462c6a

cxgb3: AEL2020 phy support update

We don't always see the link status update interrupt
when we come out of reset and the peer is up.
Check and report the link status right before enabling interrupts.
Also fix LED settings, to get a consistent link status.

Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 83 additions and 27 deletions Side-by-side Diff

drivers/net/cxgb3/adapter.h
... ... @@ -276,6 +276,14 @@
276 276 return netdev_priv(adap->port[idx]);
277 277 }
278 278  
  279 +static inline int phy2portid(struct cphy *phy)
  280 +{
  281 + struct adapter *adap = phy->adapter;
  282 + struct port_info *port0 = adap2pinfo(adap, 0);
  283 +
  284 + return &port0->phy == phy ? 0 : 1;
  285 +}
  286 +
279 287 #define OFFLOAD_DEVMAP_BIT 15
280 288  
281 289 #define tdev2adap(d) container_of(d, struct adapter, tdev)
drivers/net/cxgb3/ael1002.c
... ... @@ -1643,9 +1643,39 @@
1643 1643 */
1644 1644 static int ael2020_intr_enable(struct cphy *phy)
1645 1645 {
1646   - int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
1647   - 0x2 << (AEL2020_GPIO_MODDET*4));
1648   - return err ? err : t3_phy_lasi_intr_enable(phy);
  1646 + struct reg_val regs[] = {
  1647 + /* output Module's Loss Of Signal (LOS) to LED */
  1648 + { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
  1649 + 0xffff, 0x4 },
  1650 + { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
  1651 + 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
  1652 +
  1653 + /* enable module detect status change interrupts */
  1654 + { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
  1655 + 0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) },
  1656 +
  1657 + /* end */
  1658 + { 0, 0, 0, 0 }
  1659 + };
  1660 + int err, link_ok = 0;
  1661 +
  1662 + /* set up "link status" LED and enable module change interrupts */
  1663 + err = set_phy_regs(phy, regs);
  1664 + if (err)
  1665 + return err;
  1666 +
  1667 + err = get_link_status_r(phy, &link_ok, NULL, NULL, NULL);
  1668 + if (err)
  1669 + return err;
  1670 + if (link_ok)
  1671 + t3_link_changed(phy->adapter,
  1672 + phy2portid(phy));
  1673 +
  1674 + err = t3_phy_lasi_intr_enable(phy);
  1675 + if (err)
  1676 + return err;
  1677 +
  1678 + return 0;
1649 1679 }
1650 1680  
1651 1681 /*
... ... @@ -1653,9 +1683,26 @@
1653 1683 */
1654 1684 static int ael2020_intr_disable(struct cphy *phy)
1655 1685 {
1656   - int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
1657   - 0x1 << (AEL2020_GPIO_MODDET*4));
1658   - return err ? err : t3_phy_lasi_intr_disable(phy);
  1686 + struct reg_val regs[] = {
  1687 + /* reset "link status" LED to "off" */
  1688 + { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
  1689 + 0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) },
  1690 +
  1691 + /* disable module detect status change interrupts */
  1692 + { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
  1693 + 0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) },
  1694 +
  1695 + /* end */
  1696 + { 0, 0, 0, 0 }
  1697 + };
  1698 + int err;
  1699 +
  1700 + /* turn off "link status" LED and disable module change interrupts */
  1701 + err = set_phy_regs(phy, regs);
  1702 + if (err)
  1703 + return err;
  1704 +
  1705 + return t3_phy_lasi_intr_disable(phy);
1659 1706 }
1660 1707  
1661 1708 /*
1662 1709  
... ... @@ -1673,31 +1720,26 @@
1673 1720 return err ? err : t3_phy_lasi_intr_clear(phy);
1674 1721 }
1675 1722  
  1723 +static struct reg_val ael2020_reset_regs[] = {
  1724 + /* Erratum #2: CDRLOL asserted, causing PMA link down status */
  1725 + { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 },
  1726 +
  1727 + /* force XAUI to send LF when RX_LOS is asserted */
  1728 + { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 },
  1729 +
  1730 + /* allow writes to transceiver module EEPROM on i2c bus */
  1731 + { MDIO_MMD_PMAPMD, 0xff02, 0xffff, 0x0023 },
  1732 + { MDIO_MMD_PMAPMD, 0xff03, 0xffff, 0x0000 },
  1733 + { MDIO_MMD_PMAPMD, 0xff04, 0xffff, 0x0000 },
  1734 +
  1735 + /* end */
  1736 + { 0, 0, 0, 0 }
  1737 +};
1676 1738 /*
1677 1739 * Reset the PHY and put it into a canonical operating state.
1678 1740 */
1679 1741 static int ael2020_reset(struct cphy *phy, int wait)
1680 1742 {
1681   - static struct reg_val regs0[] = {
1682   - /* Erratum #2: CDRLOL asserted, causing PMA link down status */
1683   - { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 },
1684   -
1685   - /* force XAUI to send LF when RX_LOS is asserted */
1686   - { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 },
1687   -
1688   - /* RX_LOS pin is active high */
1689   - { MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS,
1690   - 0x0020, 0x0020 },
1691   -
1692   - /* output Module's Loss Of Signal (LOS) to LED */
1693   - { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
1694   - 0xffff, 0x0004 },
1695   - { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
1696   - 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
1697   -
1698   - /* end */
1699   - { 0, 0, 0, 0 }
1700   - };
1701 1743 int err;
1702 1744 unsigned int lasi_ctrl;
1703 1745  
... ... @@ -1714,7 +1756,7 @@
1714 1756  
1715 1757 /* basic initialization for all module types */
1716 1758 phy->priv = edc_none;
1717   - err = set_phy_regs(phy, regs0);
  1759 + err = set_phy_regs(phy, ael2020_reset_regs);
1718 1760 if (err)
1719 1761 return err;
1720 1762  
1721 1763  
... ... @@ -1792,10 +1834,16 @@
1792 1834 int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
1793 1835 const struct mdio_ops *mdio_ops)
1794 1836 {
  1837 + int err;
  1838 +
1795 1839 cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops,
1796 1840 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1797 1841 SUPPORTED_IRQ, "10GBASE-R");
1798 1842 msleep(125);
  1843 +
  1844 + err = set_phy_regs(phy, ael2020_reset_regs);
  1845 + if (err)
  1846 + return err;
1799 1847 return 0;
1800 1848 }
1801 1849