aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavem <davem>2001-12-05 08:40:54 +0000
committerdavem <davem>2001-12-05 08:40:54 +0000
commitbb4151ea0cc36c72571dcd3cb796750023f62080 (patch)
tree4f3d056c0036f027a1c5886a64614b6f2c8817af
parent08bdaa4d7967fc17fb9241307407251aecbc37bc (diff)
downloadnetdev-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.c54
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)