aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/3c59x.c
diff options
context:
space:
mode:
authorSteffen Klassert <klassert@mathematik.tu-chemnitz.de>2006-03-26 04:37:39 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-26 11:56:58 -0500
commit125d5ce8a4e9e4babaed52518fecc9eb6958455d (patch)
tree2a82dbe7d919827a8998d198d3a46ba72685f17c /drivers/net/3c59x.c
parent33644c5e15917b36c26f0c30c48786c5e8e62be1 (diff)
[PATCH] 3c59x: use mii_check_media
Check for media changes and netif_carrier by using mii_check_media() if mii is used. Signed-off-by: Steffen Klassert <klassert@mathematik.tu-chemnitz.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/net/3c59x.c')
-rw-r--r--drivers/net/3c59x.c126
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
1627static void 1627static void
1628vortex_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
1651static 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
1667static void
1628vortex_up(struct net_device *dev) 1668vortex_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;