diff options
author | davem <davem> | 2001-12-05 08:40:54 +0000 |
---|---|---|
committer | davem <davem> | 2001-12-05 08:40:54 +0000 |
commit | bb4151ea0cc36c72571dcd3cb796750023f62080 (patch) | |
tree | 4f3d056c0036f027a1c5886a64614b6f2c8817af | |
parent | 08bdaa4d7967fc17fb9241307407251aecbc37bc (diff) | |
download | netdev-vger-cvs-bb4151ea0cc36c72571dcd3cb796750023f62080.tar.gz |
SunGEM fixes from Banjamin.
Only depend upon BMSR_LSTATUS in gem_link_timer.
Call gem_init_pause_thresholds after gem_init_mac
not before or else we will lose the settings.
Set MIF_CFG bits correctly in gem_apple_powerup.
Make gem_ioctl take the pm_sem.
-rw-r--r-- | drivers/net/sungem.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 7bdf954a2..f7858a63c 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1,4 +1,4 @@ -/* $Id: sungem.c,v 1.42 2001-11-29 21:20:40 davem Exp $ +/* $Id: sungem.c,v 1.43 2001-12-05 08:40:54 davem Exp $ * sungem.c: Sun GEM ethernet driver. * * Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com) @@ -1139,16 +1139,22 @@ static void gem_link_timer(unsigned long data) if (gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) { u16 val = phy_read(gp, MII_BMSR); - u16 cntl = phy_read(gp, MII_BMCR); int up; /* When using autoneg, we really wait for ANEGCOMPLETE or we may * get a "transcient" incorrect link state */ - if (cntl & BMCR_ANENABLE) - up = (val & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS)) == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS); - else - up = (val & BMSR_LSTATUS) != 0; +#if 0 + { + u16 cntl = phy_read(gp, MII_BMCR); + if (cntl & BMCR_ANENABLE) + up = (val & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS)) == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS); + else + up = (val & BMSR_LSTATUS) != 0; + } +#else + up = (val & BMSR_LSTATUS) != 0; +#endif if (up) { /* Ok, here we got a link. If we had it due to a forced * fallback, and we were configured for autoneg, we do @@ -1829,7 +1835,6 @@ static int gem_check_invariants(struct gem *gp) gp->phy_type = phy_mii_mdio0; gp->tx_fifo_sz = readl(gp->regs + TXDMA_FSZ) * 64; gp->rx_fifo_sz = readl(gp->regs + RXDMA_FSZ) * 64; - gem_init_pause_thresholds(gp); return 0; } @@ -1902,8 +1907,6 @@ static int gem_check_invariants(struct gem *gp) } } - gem_init_pause_thresholds(gp); - return 0; } @@ -1919,6 +1922,7 @@ static void gem_init_hw(struct gem *gp, int restart_link) gem_init_phy(gp); gem_init_dma(gp); gem_init_mac(gp); + gem_init_pause_thresholds(gp); spin_lock_irq(&gp->lock); if (restart_link) { @@ -1961,7 +1965,8 @@ static void gem_apple_powerup(struct gem *gp) mdelay(1); mif_cfg = readl(gp->regs + MIF_CFG); - mif_cfg &= ~(MIF_CFG_PSELECT|MIF_CFG_POLL|MIF_CFG_BBMODE|MIF_CFG_MDI0); + mif_cfg &= ~(MIF_CFG_PSELECT|MIF_CFG_POLL|MIF_CFG_BBMODE|MIF_CFG_MDI1); + mif_cfg |= MIF_CFG_MDI0; writel(mif_cfg, gp->regs + MIF_CFG); writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE); writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG); @@ -2545,10 +2550,17 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct gem *gp = dev->priv; struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; - + int rc = -EOPNOTSUPP; + + /* Hold the PM semaphore while doing ioctl's or we may collide + * with open/close and power management and oops. + */ + down(&gp->pm_sem); + switch (cmd) { case SIOCETHTOOL: - return gem_ethtool_ioctl(dev, ifr->ifr_data); + rc = gem_ethtool_ioctl(dev, ifr->ifr_data); + break; case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = gp->mii_phy_addr; @@ -2556,16 +2568,22 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: /* Read MII PHY register. */ data->val_out = __phy_read(gp, data->reg_num & 0x1f, data->phy_id & 0x1f); - return 0; + rc = 0; + break; case SIOCSMIIREG: /* Write MII PHY register. */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - __phy_write(gp, data->reg_num & 0x1f, data->val_in, data->phy_id & 0x1f); - return 0; + if (!capable(CAP_NET_ADMIN)) { + rc = -EPERM; + } else { + __phy_write(gp, data->reg_num & 0x1f, data->val_in, data->phy_id & 0x1f); + rc = 0; + } + break; }; - return -EOPNOTSUPP; + up(&gp->pm_sem); + + return rc; } static int __devinit gem_get_device_address(struct gem *gp) |