Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
[pandora-kernel.git] / drivers / net / tg3.c
index d9123c9..4056ba1 100644 (file)
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.69"
-#define DRV_MODULE_RELDATE     "November 15, 2006"
+#define DRV_MODULE_VERSION     "3.71"
+#define DRV_MODULE_RELDATE     "December 15, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -192,6 +192,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787F)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715)},
@@ -958,6 +959,13 @@ static int tg3_phy_reset(struct tg3 *tp)
        u32 phy_status;
        int err;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               u32 val;
+
+               val = tr32(GRC_MISC_CFG);
+               tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ);
+               udelay(40);
+       }
        err  = tg3_readphy(tp, MII_BMSR, &phy_status);
        err |= tg3_readphy(tp, MII_BMSR, &phy_status);
        if (err != 0)
@@ -1061,7 +1069,7 @@ static void tg3_frob_aux_power(struct tg3 *tp)
 {
        struct tg3 *tp_peer = tp;
 
-       if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0)
+       if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0)
                return;
 
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
@@ -1169,7 +1177,15 @@ static void tg3_power_down_phy(struct tg3 *tp)
        if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
                return;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               u32 val;
+
+               tg3_bmcr_reset(tp);
+               val = tr32(GRC_MISC_CFG);
+               tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
+               udelay(40);
+               return;
+       } else {
                tg3_writephy(tp, MII_TG3_EXT_CTRL,
                             MII_TG3_EXT_CTRL_FORCE_LED_OFF);
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
@@ -1212,8 +1228,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                                      power_control);
                udelay(100);    /* Delay after power state change */
 
-               /* Switch out of Vaux if it is not a LOM */
-               if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
+               /* Switch out of Vaux if it is a NIC */
+               if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
                        tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
 
                return 0;
@@ -1401,8 +1417,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 static void tg3_link_report(struct tg3 *tp)
 {
        if (!netif_carrier_ok(tp->dev)) {
-               printk(KERN_INFO PFX "%s: Link is down.\n", tp->dev->name);
-       } else {
+               if (netif_msg_link(tp))
+                       printk(KERN_INFO PFX "%s: Link is down.\n",
+                              tp->dev->name);
+       } else if (netif_msg_link(tp)) {
                printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
                       tp->dev->name,
                       (tp->link_config.active_speed == SPEED_1000 ?
@@ -1557,12 +1575,6 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
 
                tg3_writephy(tp, MII_ADVERTISE, new_adv);
        } else if (tp->link_config.speed == SPEED_INVALID) {
-               tp->link_config.advertising =
-                       (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
-                        ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
-                        ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
-                        ADVERTISED_Autoneg | ADVERTISED_MII);
-
                if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
                        tp->link_config.advertising &=
                                ~(ADVERTISED_1000baseT_Half |
@@ -1706,25 +1718,36 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp)
        return err;
 }
 
-static int tg3_copper_is_advertising_all(struct tg3 *tp)
+static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask)
 {
-       u32 adv_reg, all_mask;
+       u32 adv_reg, all_mask = 0;
+
+       if (mask & ADVERTISED_10baseT_Half)
+               all_mask |= ADVERTISE_10HALF;
+       if (mask & ADVERTISED_10baseT_Full)
+               all_mask |= ADVERTISE_10FULL;
+       if (mask & ADVERTISED_100baseT_Half)
+               all_mask |= ADVERTISE_100HALF;
+       if (mask & ADVERTISED_100baseT_Full)
+               all_mask |= ADVERTISE_100FULL;
 
        if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg))
                return 0;
 
-       all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL |
-                   ADVERTISE_100HALF | ADVERTISE_100FULL);
        if ((adv_reg & all_mask) != all_mask)
                return 0;
        if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
                u32 tg3_ctrl;
 
+               all_mask = 0;
+               if (mask & ADVERTISED_1000baseT_Half)
+                       all_mask |= ADVERTISE_1000HALF;
+               if (mask & ADVERTISED_1000baseT_Full)
+                       all_mask |= ADVERTISE_1000FULL;
+
                if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl))
                        return 0;
 
-               all_mask = (MII_TG3_CTRL_ADV_1000_HALF |
-                           MII_TG3_CTRL_ADV_1000_FULL);
                if ((tg3_ctrl & all_mask) != all_mask)
                        return 0;
        }
@@ -1884,7 +1907,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
                                /* Force autoneg restart if we are exiting
                                 * low power mode.
                                 */
-                               if (!tg3_copper_is_advertising_all(tp))
+                               if (!tg3_copper_is_advertising_all(tp,
+                                               tp->link_config.advertising))
                                        current_link_up = 0;
                        } else {
                                current_link_up = 0;
@@ -3703,8 +3727,9 @@ static void tg3_tx_timeout(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
-              dev->name);
+       if (netif_msg_tx_err(tp))
+               printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
+                      dev->name);
 
        schedule_work(&tp->reset_task);
 }
@@ -4416,7 +4441,7 @@ static void tg3_free_consistent(struct tg3 *tp)
  */
 static int tg3_alloc_consistent(struct tg3 *tp)
 {
-       tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) *
+       tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) *
                                      (TG3_RX_RING_SIZE +
                                       TG3_RX_JUMBO_RING_SIZE)) +
                                     (sizeof(struct tx_ring_info) *
@@ -4425,13 +4450,6 @@ static int tg3_alloc_consistent(struct tg3 *tp)
        if (!tp->rx_std_buffers)
                return -ENOMEM;
 
-       memset(tp->rx_std_buffers, 0,
-              (sizeof(struct ring_info) *
-               (TG3_RX_RING_SIZE +
-                TG3_RX_JUMBO_RING_SIZE)) +
-              (sizeof(struct tx_ring_info) *
-               TG3_TX_RING_SIZE));
-
        tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
        tp->tx_buffers = (struct tx_ring_info *)
                &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
@@ -6396,16 +6414,17 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        udelay(40);
 
        /* tp->grc_local_ctrl is partially set up during tg3_get_invariants().
-        * If TG3_FLAG_EEPROM_WRITE_PROT is set, we should read the
+        * If TG3_FLG2_IS_NIC is zero, we should read the
         * register to preserve the GPIO settings for LOMs. The GPIOs,
         * whether used as inputs or outputs, are set by boot code after
         * reset.
         */
-       if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+       if (!(tp->tg3_flags2 & TG3_FLG2_IS_NIC)) {
                u32 gpio_mask;
 
-               gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE2 |
-                           GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT2;
+               gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 |
+                           GRC_LCLCTRL_GPIO_OE2 | GRC_LCLCTRL_GPIO_OUTPUT0 |
+                           GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_GPIO_OUTPUT2;
 
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
                        gpio_mask |= GRC_LCLCTRL_GPIO_OE3 |
@@ -6417,8 +6436,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
 
                /* GPIO1 must be driven high for eeprom write protect */
-               tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
-                                      GRC_LCLCTRL_GPIO_OUTPUT1);
+               if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)
+                       tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
+                                              GRC_LCLCTRL_GPIO_OUTPUT1);
        }
        tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
        udelay(100);
@@ -6976,6 +6996,8 @@ static int tg3_open(struct net_device *dev)
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
+       netif_carrier_off(tp->dev);
+
        tg3_full_lock(tp, 0);
 
        err = tg3_set_power_state(tp, PCI_D0);
@@ -7969,6 +7991,10 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                tp->link_config.duplex = cmd->duplex;
        }
 
+       tp->link_config.orig_speed = tp->link_config.speed;
+       tp->link_config.orig_duplex = tp->link_config.duplex;
+       tp->link_config.orig_autoneg = tp->link_config.autoneg;
+
        if (netif_running(dev))
                tg3_setup_phy(tp, 1);
 
@@ -8656,7 +8682,9 @@ static int tg3_test_registers(struct tg3 *tp)
        return 0;
 
 out:
-       printk(KERN_ERR PFX "Register test failed at offset %x\n", offset);
+       if (netif_msg_hw(tp))
+               printk(KERN_ERR PFX "Register test failed at offset %x\n",
+                      offset);
        tw32(offset, save_val);
        return -EIO;
 }
@@ -8781,17 +8809,20 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                                        tg3_writephy(tp, 0x10, phy & ~0x4000);
                                tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
                        }
-               }
-               val = BMCR_LOOPBACK | BMCR_FULLDPLX;
-               if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
-                       val |= BMCR_SPEED100;
-               else
-                       val |= BMCR_SPEED1000;
+                       val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
+               } else
+                       val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
 
                tg3_writephy(tp, MII_BMCR, val);
                udelay(40);
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+
+               mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
+                          MAC_MODE_LINK_POLARITY;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                        tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
+                       mac_mode |= MAC_MODE_PORT_MODE_MII;
+               } else
+                       mac_mode |= MAC_MODE_PORT_MODE_GMII;
 
                /* reset to prevent losing 1st rx packet intermittently */
                if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
@@ -8799,12 +8830,6 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                        udelay(10);
                        tw32_f(MAC_RX_MODE, tp->rx_mode);
                }
-               mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-                          MAC_MODE_LINK_POLARITY;
-               if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
-                       mac_mode |= MAC_MODE_PORT_MODE_MII;
-               else
-                       mac_mode |= MAC_MODE_PORT_MODE_GMII;
                if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
                        mac_mode &= ~MAC_MODE_LINK_POLARITY;
                        tg3_writephy(tp, MII_TG3_EXT_CTRL,
@@ -9456,16 +9481,12 @@ static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
 static void __devinit tg3_nvram_init(struct tg3 *tp)
 {
-       int j;
-
        tw32_f(GRC_EEPROM_ADDR,
             (EEPROM_ADDR_FSM_RESET |
              (EEPROM_DEFAULT_CLOCK_PERIOD <<
               EEPROM_ADDR_CLKPERD_SHIFT)));
 
-       /* XXX schedule_timeout() ... */
-       for (j = 0; j < 100; j++)
-               udelay(10);
+       msleep(1);
 
        /* Enable seeprom accesses. */
        tw32_f(GRC_LOCAL_CTRL,
@@ -9526,12 +9547,12 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
              EEPROM_ADDR_ADDR_MASK) |
             EEPROM_ADDR_READ | EEPROM_ADDR_START);
 
-       for (i = 0; i < 10000; i++) {
+       for (i = 0; i < 1000; i++) {
                tmp = tr32(GRC_EEPROM_ADDR);
 
                if (tmp & EEPROM_ADDR_COMPLETE)
                        break;
-               udelay(100);
+               msleep(1);
        }
        if (!(tmp & EEPROM_ADDR_COMPLETE))
                return -EBUSY;
@@ -9656,12 +9677,12 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
                        EEPROM_ADDR_START |
                        EEPROM_ADDR_WRITE);
 
-               for (j = 0; j < 10000; j++) {
+               for (j = 0; j < 1000; j++) {
                        val = tr32(GRC_EEPROM_ADDR);
 
                        if (val & EEPROM_ADDR_COMPLETE)
                                break;
-                       udelay(100);
+                       msleep(1);
                }
                if (!(val & EEPROM_ADDR_COMPLETE)) {
                        rc = -EBUSY;
@@ -9965,8 +9986,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
        tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-               if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM))
+               if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) {
                        tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
+                       tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
+               }
                return;
        }
 
@@ -10066,10 +10089,17 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                    tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
                        tp->led_ctrl = LED_CTRL_MODE_PHY_2;
 
-               if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)
+               if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
                        tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
-               else
+                       if ((tp->pdev->subsystem_vendor ==
+                            PCI_VENDOR_ID_ARIMA) &&
+                           (tp->pdev->subsystem_device == 0x205a ||
+                            tp->pdev->subsystem_device == 0x2063))
+                               tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
+               } else {
                        tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
+                       tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
+               }
 
                if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
                        tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
@@ -10147,7 +10177,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
 
        if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) &&
            !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
-               u32 bmsr, adv_reg, tg3_ctrl;
+               u32 bmsr, adv_reg, tg3_ctrl, mask;
 
                tg3_readphy(tp, MII_BMSR, &bmsr);
                if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
@@ -10171,7 +10201,10 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
                                             MII_TG3_CTRL_ENABLE_AS_MASTER);
                }
 
-               if (!tg3_copper_is_advertising_all(tp)) {
+               mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+                       ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+                       ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);
+               if (!tg3_copper_is_advertising_all(tp, mask)) {
                        tg3_writephy(tp, MII_ADVERTISE, adv_reg);
 
                        if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
@@ -10695,7 +10728,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;
 
        /* Get eeprom hw config before calling tg3_set_power_state().
-        * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be
+        * In particular, the TG3_FLG2_IS_NIC flag must be
         * determined before calling tg3_set_power_state() so that
         * we know whether or not to switch out of Vaux power.
         * When the flag is set, it means that GPIO1 is used for eeprom
@@ -10862,7 +10895,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
              tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) ||
            (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
             (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F ||
-             tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)) ||
+             tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F ||
+             tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
@@ -11903,6 +11937,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         */
        pci_save_state(tp->pdev);
 
+       pci_set_drvdata(pdev, dev);
+
        err = register_netdev(dev);
        if (err) {
                printk(KERN_ERR PFX "Cannot register net device, "
@@ -11910,15 +11946,15 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
-       pci_set_drvdata(pdev, dev);
-
-       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %sBaseT Ethernet ",
+       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ",
               dev->name,
               tp->board_part_number,
               tp->pci_chip_rev_id,
               tg3_phy_string(tp),
               tg3_bus_string(tp, str),
-              (tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000");
+              ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
+               ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
+                "10/100/1000Base-T")));
 
        for (i = 0; i < 6; i++)
                printk("%2.2x%c", dev->dev_addr[i],
@@ -11940,8 +11976,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
               (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
                (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
 
-       netif_carrier_off(tp->dev);
-
        return 0;
 
 err_out_iounmap: