Commit 5e659515569220701bfe3c8936dcab67554cc286
Committed by
David S. Miller
1 parent
cfe2462c6a
Exists in
master
and in
4 other branches
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 |