Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / sky2.c
index 53cce74..37f486b 100644 (file)
@@ -50,7 +50,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.25"
+#define DRV_VERSION            "1.26"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -374,8 +374,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                        ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
 
                        /* downshift on PHY 88E1112 and 88E1149 is changed */
-                       if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED)
-                           && (hw->flags & SKY2_HW_NEWER_PHY)) {
+                       if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
+                            (hw->flags & SKY2_HW_NEWER_PHY)) {
                                /* set downshift counter to 3x and enable downshift */
                                ctrl &= ~PHY_M_PC_DSC_MSK;
                                ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
@@ -619,8 +619,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                /* no effect on Yukon-XL */
                gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
 
-               if ( !(sky2->flags & SKY2_FLAG_AUTO_SPEED)
-                    || sky2->speed == SPEED_100) {
+               if (!(sky2->flags & SKY2_FLAG_AUTO_SPEED) ||
+                   sky2->speed == SPEED_100) {
                        /* turn on 100 Mbps LED (LED_LINK100) */
                        ledover |= PHY_M_LED_MO_100(MO_LED_ON);
                }
@@ -644,7 +644,6 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
 {
        u32 reg1;
 
-       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
        reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
        reg1 &= ~phy_power[port];
 
@@ -652,7 +651,6 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
                reg1 |= coma_mode[port];
 
        sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        sky2_pci_read32(hw, PCI_DEV_REG1);
 
        if (hw->chip_id == CHIP_ID_YUKON_FE)
@@ -709,11 +707,9 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
                gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN);
        }
 
-       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
        reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
        reg1 |= phy_power[port];                /* set PHY to PowerDown/COMA Mode */
        sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 }
 
 /* Force a renegotiation */
@@ -937,8 +933,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
        /* On chips without ram buffer, pause is controled by MAC level */
        if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
                /* Pause threshold is scaled by 8 in bytes */
-               if (hw->chip_id == CHIP_ID_YUKON_FE_P
-                       && hw->chip_rev == CHIP_REV_YU_FE2_A0)
+               if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+                   hw->chip_rev == CHIP_REV_YU_FE2_A0)
                        reg = 1568 / 8;
                else
                        reg = 1024 / 8;
@@ -1353,8 +1349,8 @@ static int sky2_rx_start(struct sky2_port *sky2)
        /* These chips have no ram buffer?
         * MAC Rx RAM Read is controlled by hardware */
        if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
-           (hw->chip_rev == CHIP_REV_YU_EC_U_A1
-            || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
+           (hw->chip_rev == CHIP_REV_YU_EC_U_A1 ||
+            hw->chip_rev == CHIP_REV_YU_EC_U_B0))
                sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);
 
        sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
@@ -1560,8 +1556,8 @@ static int sky2_up(struct net_device *dev)
                sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
 
        /* Set almost empty threshold */
-       if (hw->chip_id == CHIP_ID_YUKON_EC_U
-           && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+           hw->chip_rev == CHIP_REV_YU_EC_U_A0)
                sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
 
        sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
@@ -1848,7 +1844,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
        sky2->tx_cons = idx;
        smp_mb();
 
-       if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
+       /* Wake unless it's detached, and called e.g. from sky2_down() */
+       if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev))
                netif_wake_queue(dev);
 }
 
@@ -1907,8 +1904,8 @@ static int sky2_down(struct net_device *dev)
        sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
 
        /* Workaround shared GMAC reset */
-       if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
-             && port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
+       if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 &&
+             port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
                sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
 
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
@@ -2017,7 +2014,7 @@ static void sky2_link_down(struct sky2_port *sky2)
 
        netif_carrier_off(sky2->netdev);
 
-       /* Turn on link LED */
+       /* Turn off link LED */
        sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
 
        if (netif_msg_link(sky2))
@@ -2085,8 +2082,8 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
                        sky2->flow_status = FC_TX;
        }
 
-       if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000
-           && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
+       if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 &&
+           !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
                sky2->flow_status = FC_NONE;
 
        if (sky2->flow_status & FC_TX)
@@ -2643,7 +2640,6 @@ static void sky2_hw_intr(struct sky2_hw *hw)
        if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
                u16 pci_err;
 
-               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                pci_err = sky2_pci_read16(hw, PCI_STATUS);
                if (net_ratelimit())
                        dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
@@ -2651,14 +2647,12 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 
                sky2_pci_write16(hw, PCI_STATUS,
                                      pci_err | PCI_STATUS_ERROR_BITS);
-               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        }
 
        if (status & Y2_IS_PCI_EXP) {
                /* PCI-Express uncorrectable Error occurred */
                u32 err;
 
-               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
                sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
                             0xfffffffful);
@@ -2666,7 +2660,6 @@ static void sky2_hw_intr(struct sky2_hw *hw)
                        dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
 
                sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
-               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        }
 
        if (status & Y2_HWE_L1_MASK)
@@ -2968,8 +2961,13 @@ static int __devinit sky2_init(struct sky2_hw *hw)
                break;
 
        case CHIP_ID_YUKON_UL_2:
+               hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_ADV_POWER_CTL;
+               break;
+
        case CHIP_ID_YUKON_OPT:
                hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_NEW_LE
                        | SKY2_HW_ADV_POWER_CTL;
                break;
 
@@ -3040,7 +3038,6 @@ static void sky2_reset(struct sky2_hw *hw)
        }
 
        sky2_power_on(hw);
-       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
        for (i = 0; i < hw->ports; i++) {
                sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
@@ -3244,8 +3241,8 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
 
-       if ((wol->wolopts & ~sky2_wol_supported(sky2->hw))
-           || !device_can_wakeup(&hw->pdev->dev))
+       if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
+           !device_can_wakeup(&hw->pdev->dev))
                return -EOPNOTSUPP;
 
        sky2->wol = wol->wolopts;
@@ -4521,7 +4518,7 @@ static const char *sky2_name(u8 chipid, char *buf, int sz)
                "Optima",       /* 0xbc */
        };
 
-       if (chipid >= CHIP_ID_YUKON_XL && chipid < CHIP_ID_YUKON_OPT)
+       if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OPT)
                strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
        else
                snprintf(buf, sz, "(chip %#x)", chipid);
@@ -4651,6 +4648,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                goto err_out_free_netdev;
        }
 
+       netif_carrier_off(dev);
+
        netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
 
        err = request_irq(pdev->irq, sky2_intr,
@@ -4686,6 +4685,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
        INIT_WORK(&hw->restart_work, sky2_restart);
 
        pci_set_drvdata(pdev, hw);
+       pdev->d3_delay = 150;
 
        return 0;