diff options
author | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-03-05 20:29:18 +0000 |
---|---|---|
committer | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-03-05 20:29:18 +0000 |
commit | 5b74d557fa51ff9aa9e3e33883328798a96b1eed (patch) | |
tree | 58836b9307a2958ed795cd140cebd1f12b5598e8 /target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c | |
parent | 99dab77b599d97fa02014c8c068885982fc6676f (diff) |
ar71xx: ag71xx: move link update function
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@20003 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c')
-rw-r--r-- | target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c index 5362edec6b..3644b2dd91 100644 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c +++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c @@ -310,6 +310,107 @@ static void ag71xx_rings_cleanup(struct ag71xx *ag) ag71xx_ring_free(&ag->tx_ring); } +static unsigned char *ag71xx_speed_str(struct ag71xx *ag) +{ + switch (ag->speed) { + case SPEED_1000: + return "1000"; + case SPEED_100: + return "100"; + case SPEED_10: + return "10"; + } + + return "?"; +} + +void ag71xx_link_adjust(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + u32 cfg2; + u32 ifctl; + u32 fifo5; + u32 mii_speed; + + if (!ag->link) { + netif_carrier_off(ag->dev); + if (netif_msg_link(ag)) + printk(KERN_INFO "%s: link down\n", ag->dev->name); + return; + } + + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; + + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); + ifctl &= ~(MAC_IFCTL_SPEED); + + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); + fifo5 &= ~FIFO_CFG5_BM; + + switch (ag->speed) { + case SPEED_1000: + mii_speed = MII_CTRL_SPEED_1000; + cfg2 |= MAC_CFG2_IF_1000; + fifo5 |= FIFO_CFG5_BM; + break; + case SPEED_100: + mii_speed = MII_CTRL_SPEED_100; + cfg2 |= MAC_CFG2_IF_10_100; + ifctl |= MAC_IFCTL_SPEED; + break; + case SPEED_10: + mii_speed = MII_CTRL_SPEED_10; + cfg2 |= MAC_CFG2_IF_10_100; + break; + default: + BUG(); + return; + } + + if (pdata->is_ar91xx) + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); + else if (pdata->is_ar724x) + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); + else + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); + + if (pdata->set_pll) + pdata->set_pll(ag->speed); + + ag71xx_mii_ctrl_set_speed(ag, mii_speed); + + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); + + netif_carrier_on(ag->dev); + if (netif_msg_link(ag)) + printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", + ag->dev->name, + ag71xx_speed_str(ag), + (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); + + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); + + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); + + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), + ag71xx_mii_ctrl_rr(ag)); +} + static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) { u32 t; |