diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/3c59x.c | 126 |
1 files changed, 49 insertions, 77 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index d339308539fa..4ae78bf377cd 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -1335,7 +1335,7 @@ static int __devinit vortex_probe1(struct device *gendev, | |||
1335 | vp->enable_wol = 1; | 1335 | vp->enable_wol = 1; |
1336 | } | 1336 | } |
1337 | 1337 | ||
1338 | vp->force_fd = vp->full_duplex; | 1338 | vp->mii.force_media = vp->full_duplex; |
1339 | vp->options = option; | 1339 | vp->options = option; |
1340 | /* Read the station address from the EEPROM. */ | 1340 | /* Read the station address from the EEPROM. */ |
1341 | EL3WINDOW(0); | 1341 | EL3WINDOW(0); |
@@ -1625,6 +1625,46 @@ issue_and_wait(struct net_device *dev, int cmd) | |||
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | static void | 1627 | static void |
1628 | vortex_set_duplex(struct net_device *dev) | ||
1629 | { | ||
1630 | struct vortex_private *vp = netdev_priv(dev); | ||
1631 | void __iomem *ioaddr = vp->ioaddr; | ||
1632 | |||
1633 | printk(KERN_INFO "%s: setting %s-duplex.\n", | ||
1634 | dev->name, (vp->full_duplex) ? "full" : "half"); | ||
1635 | |||
1636 | EL3WINDOW(3); | ||
1637 | /* Set the full-duplex bit. */ | ||
1638 | iowrite16(((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | | ||
1639 | (vp->large_frames ? 0x40 : 0) | | ||
1640 | ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? | ||
1641 | 0x100 : 0), | ||
1642 | ioaddr + Wn3_MAC_Ctrl); | ||
1643 | |||
1644 | issue_and_wait(dev, TxReset); | ||
1645 | /* | ||
1646 | * Don't reset the PHY - that upsets autonegotiation during DHCP operations. | ||
1647 | */ | ||
1648 | issue_and_wait(dev, RxReset|0x04); | ||
1649 | } | ||
1650 | |||
1651 | static void vortex_check_media(struct net_device *dev, unsigned int init) | ||
1652 | { | ||
1653 | struct vortex_private *vp = netdev_priv(dev); | ||
1654 | unsigned int ok_to_print = 0; | ||
1655 | |||
1656 | if (vortex_debug > 3) | ||
1657 | ok_to_print = 1; | ||
1658 | |||
1659 | if (mii_check_media(&vp->mii, ok_to_print, init)) { | ||
1660 | vp->full_duplex = vp->mii.full_duplex; | ||
1661 | vortex_set_duplex(dev); | ||
1662 | } else if (init) { | ||
1663 | vortex_set_duplex(dev); | ||
1664 | } | ||
1665 | } | ||
1666 | |||
1667 | static void | ||
1628 | vortex_up(struct net_device *dev) | 1668 | vortex_up(struct net_device *dev) |
1629 | { | 1669 | { |
1630 | struct vortex_private *vp = netdev_priv(dev); | 1670 | struct vortex_private *vp = netdev_priv(dev); |
@@ -1684,53 +1724,20 @@ vortex_up(struct net_device *dev) | |||
1684 | printk(KERN_DEBUG "%s: Initial media type %s.\n", | 1724 | printk(KERN_DEBUG "%s: Initial media type %s.\n", |
1685 | dev->name, media_tbl[dev->if_port].name); | 1725 | dev->name, media_tbl[dev->if_port].name); |
1686 | 1726 | ||
1687 | vp->full_duplex = vp->force_fd; | 1727 | vp->full_duplex = vp->mii.force_media; |
1688 | config = BFINS(config, dev->if_port, 20, 4); | 1728 | config = BFINS(config, dev->if_port, 20, 4); |
1689 | if (vortex_debug > 6) | 1729 | if (vortex_debug > 6) |
1690 | printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); | 1730 | printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); |
1691 | iowrite32(config, ioaddr + Wn3_Config); | 1731 | iowrite32(config, ioaddr + Wn3_Config); |
1692 | 1732 | ||
1733 | netif_carrier_off(dev); | ||
1693 | if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { | 1734 | if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { |
1694 | int mii_reg1, mii_reg5; | ||
1695 | EL3WINDOW(4); | 1735 | EL3WINDOW(4); |
1696 | /* Read BMSR (reg1) only to clear old status. */ | 1736 | vortex_check_media(dev, 1); |
1697 | mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR); | ||
1698 | mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); | ||
1699 | if (mii_reg5 == 0xffff || mii_reg5 == 0x0000) { | ||
1700 | netif_carrier_off(dev); /* No MII device or no link partner report */ | ||
1701 | } else { | ||
1702 | mii_reg5 &= vp->advertising; | ||
1703 | if ((mii_reg5 & 0x0100) != 0 /* 100baseTx-FD */ | ||
1704 | || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */ | ||
1705 | vp->full_duplex = 1; | ||
1706 | netif_carrier_on(dev); | ||
1707 | } | ||
1708 | vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0); | ||
1709 | if (vortex_debug > 1) | ||
1710 | printk(KERN_INFO "%s: MII #%d status %4.4x, link partner capability %4.4x," | ||
1711 | " info1 %04x, setting %s-duplex.\n", | ||
1712 | dev->name, vp->phys[0], | ||
1713 | mii_reg1, mii_reg5, | ||
1714 | vp->info1, ((vp->info1 & 0x8000) || vp->full_duplex) ? "full" : "half"); | ||
1715 | EL3WINDOW(3); | ||
1716 | } | 1737 | } |
1738 | else | ||
1739 | vortex_set_duplex(dev); | ||
1717 | 1740 | ||
1718 | /* Set the full-duplex bit. */ | ||
1719 | iowrite16( ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | | ||
1720 | (vp->large_frames ? 0x40 : 0) | | ||
1721 | ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), | ||
1722 | ioaddr + Wn3_MAC_Ctrl); | ||
1723 | |||
1724 | if (vortex_debug > 1) { | ||
1725 | printk(KERN_DEBUG "%s: vortex_up() InternalConfig %8.8x.\n", | ||
1726 | dev->name, config); | ||
1727 | } | ||
1728 | |||
1729 | issue_and_wait(dev, TxReset); | ||
1730 | /* | ||
1731 | * Don't reset the PHY - that upsets autonegotiation during DHCP operations. | ||
1732 | */ | ||
1733 | issue_and_wait(dev, RxReset|0x04); | ||
1734 | 1741 | ||
1735 | iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); | 1742 | iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); |
1736 | 1743 | ||
@@ -1892,7 +1899,7 @@ vortex_timer(unsigned long data) | |||
1892 | void __iomem *ioaddr = vp->ioaddr; | 1899 | void __iomem *ioaddr = vp->ioaddr; |
1893 | int next_tick = 60*HZ; | 1900 | int next_tick = 60*HZ; |
1894 | int ok = 0; | 1901 | int ok = 0; |
1895 | int media_status, mii_status, old_window; | 1902 | int media_status, old_window; |
1896 | 1903 | ||
1897 | if (vortex_debug > 2) { | 1904 | if (vortex_debug > 2) { |
1898 | printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n", | 1905 | printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n", |
@@ -1924,44 +1931,9 @@ vortex_timer(unsigned long data) | |||
1924 | break; | 1931 | break; |
1925 | case XCVR_MII: case XCVR_NWAY: | 1932 | case XCVR_MII: case XCVR_NWAY: |
1926 | { | 1933 | { |
1927 | spin_lock_bh(&vp->lock); | ||
1928 | mii_status = mdio_read(dev, vp->phys[0], MII_BMSR); | ||
1929 | if (!(mii_status & BMSR_LSTATUS)) { | ||
1930 | /* Re-read to get actual link status */ | ||
1931 | mii_status = mdio_read(dev, vp->phys[0], MII_BMSR); | ||
1932 | } | ||
1933 | ok = 1; | 1934 | ok = 1; |
1934 | if (vortex_debug > 2) | 1935 | spin_lock_bh(&vp->lock); |
1935 | printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n", | 1936 | vortex_check_media(dev, 0); |
1936 | dev->name, mii_status); | ||
1937 | if (mii_status & BMSR_LSTATUS) { | ||
1938 | int mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); | ||
1939 | if (! vp->force_fd && mii_reg5 != 0xffff) { | ||
1940 | int duplex; | ||
1941 | |||
1942 | mii_reg5 &= vp->advertising; | ||
1943 | duplex = (mii_reg5&0x0100) || (mii_reg5 & 0x01C0) == 0x0040; | ||
1944 | if (vp->full_duplex != duplex) { | ||
1945 | vp->full_duplex = duplex; | ||
1946 | printk(KERN_INFO "%s: Setting %s-duplex based on MII " | ||
1947 | "#%d link partner capability of %4.4x.\n", | ||
1948 | dev->name, vp->full_duplex ? "full" : "half", | ||
1949 | vp->phys[0], mii_reg5); | ||
1950 | /* Set the full-duplex bit. */ | ||
1951 | EL3WINDOW(3); | ||
1952 | iowrite16( (vp->full_duplex ? 0x20 : 0) | | ||
1953 | (vp->large_frames ? 0x40 : 0) | | ||
1954 | ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), | ||
1955 | ioaddr + Wn3_MAC_Ctrl); | ||
1956 | if (vortex_debug > 1) | ||
1957 | printk(KERN_DEBUG "Setting duplex in Wn3_MAC_Ctrl\n"); | ||
1958 | /* AKPM: bug: should reset Tx and Rx after setting Duplex. Page 180 */ | ||
1959 | } | ||
1960 | } | ||
1961 | netif_carrier_on(dev); | ||
1962 | } else { | ||
1963 | netif_carrier_off(dev); | ||
1964 | } | ||
1965 | spin_unlock_bh(&vp->lock); | 1937 | spin_unlock_bh(&vp->lock); |
1966 | } | 1938 | } |
1967 | break; | 1939 | break; |