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.
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 7bdf954..f7858a6 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 @@
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 @@
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 @@
}
}
- gem_init_pause_thresholds(gp);
-
return 0;
}
@@ -1919,6 +1922,7 @@
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 @@
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 @@
{
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 @@
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)