aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2009-07-07 15:48:43 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-08 13:54:23 -0400
commit5e659515569220701bfe3c8936dcab67554cc286 (patch)
treeb8ecba536862e83ff0792e777d949e6f750b793c /drivers/net
parentcfe2462c6af309ee70e4aeefa55cae976071b9e2 (diff)
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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/cxgb3/adapter.h8
-rw-r--r--drivers/net/cxgb3/ael1002.c102
2 files changed, 83 insertions, 27 deletions
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 1694fad38720..bfa312d43d86 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -276,6 +276,14 @@ static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
276 return netdev_priv(adap->port[idx]); 276 return netdev_priv(adap->port[idx]);
277} 277}
278 278
279static 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#define OFFLOAD_DEVMAP_BIT 15 287#define OFFLOAD_DEVMAP_BIT 15
280 288
281#define tdev2adap(d) container_of(d, struct adapter, tdev) 289#define tdev2adap(d) container_of(d, struct adapter, tdev)
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 949d248b746b..66e47f76f32b 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -1643,9 +1643,39 @@ static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
1643 */ 1643 */
1644static int ael2020_intr_enable(struct cphy *phy) 1644static int ael2020_intr_enable(struct cphy *phy)
1645{ 1645{
1646 int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, 1646 struct reg_val regs[] = {
1647 0x2 << (AEL2020_GPIO_MODDET*4)); 1647 /* output Module's Loss Of Signal (LOS) to LED */
1648 return err ? err : t3_phy_lasi_intr_enable(phy); 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 @@ static int ael2020_intr_enable(struct cphy *phy)
1653 */ 1683 */
1654static int ael2020_intr_disable(struct cphy *phy) 1684static int ael2020_intr_disable(struct cphy *phy)
1655{ 1685{
1656 int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, 1686 struct reg_val regs[] = {
1657 0x1 << (AEL2020_GPIO_MODDET*4)); 1687 /* reset "link status" LED to "off" */
1658 return err ? err : t3_phy_lasi_intr_disable(phy); 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/*
@@ -1673,31 +1720,26 @@ static int ael2020_intr_clear(struct cphy *phy)
1673 return err ? err : t3_phy_lasi_intr_clear(phy); 1720 return err ? err : t3_phy_lasi_intr_clear(phy);
1674} 1721}
1675 1722
1723static 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 * Reset the PHY and put it into a canonical operating state. 1739 * Reset the PHY and put it into a canonical operating state.
1678 */ 1740 */
1679static int ael2020_reset(struct cphy *phy, int wait) 1741static 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 int err; 1743 int err;
1702 unsigned int lasi_ctrl; 1744 unsigned int lasi_ctrl;
1703 1745
@@ -1714,7 +1756,7 @@ static int ael2020_reset(struct cphy *phy, int wait)
1714 1756
1715 /* basic initialization for all module types */ 1757 /* basic initialization for all module types */
1716 phy->priv = edc_none; 1758 phy->priv = edc_none;
1717 err = set_phy_regs(phy, regs0); 1759 err = set_phy_regs(phy, ael2020_reset_regs);
1718 if (err) 1760 if (err)
1719 return err; 1761 return err;
1720 1762
@@ -1792,10 +1834,16 @@ static struct cphy_ops ael2020_ops = {
1792int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, 1834int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
1793 const struct mdio_ops *mdio_ops) 1835 const struct mdio_ops *mdio_ops)
1794{ 1836{
1837 int err;
1838
1795 cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops, 1839 cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops,
1796 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | 1840 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1797 SUPPORTED_IRQ, "10GBASE-R"); 1841 SUPPORTED_IRQ, "10GBASE-R");
1798 msleep(125); 1842 msleep(125);
1843
1844 err = set_phy_regs(phy, ael2020_reset_regs);
1845 if (err)
1846 return err;
1799 return 0; 1847 return 0;
1800} 1848}
1801 1849