]> err.no Git - linux-2.6/blobdiff - drivers/net/tg3.c
[TG3]: Update version and reldate
[linux-2.6] / drivers / net / tg3.c
index b8f1524da5578b7d4b34f53713d370fae3e361da..994658d26b8e83d87ecf6584ab131a2a105ca6bf 100644 (file)
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.49"
-#define DRV_MODULE_RELDATE     "Feb 2, 2006"
+#define DRV_MODULE_VERSION     "3.50"
+#define DRV_MODULE_RELDATE     "Feb 4, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -223,8 +223,12 @@ static struct pci_device_id tg3_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715S,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S,
@@ -1038,9 +1042,11 @@ static void tg3_frob_aux_power(struct tg3 *tp)
                struct net_device *dev_peer;
 
                dev_peer = pci_get_drvdata(tp->pdev_peer);
+               /* remove_one() may have been run on the peer. */
                if (!dev_peer)
-                       BUG();
-               tp_peer = netdev_priv(dev_peer);
+                       tp_peer = tp;
+               else
+                       tp_peer = netdev_priv(dev_peer);
        }
 
        if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
@@ -1131,7 +1137,7 @@ static int tg3_halt_cpu(struct tg3 *, u32);
 static int tg3_nvram_lock(struct tg3 *);
 static void tg3_nvram_unlock(struct tg3 *);
 
-static int tg3_set_power_state(struct tg3 *tp, int state)
+static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 {
        u32 misc_host_ctrl;
        u16 power_control, power_caps;
@@ -1150,7 +1156,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
        power_control |= PCI_PM_CTRL_PME_STATUS;
        power_control &= ~(PCI_PM_CTRL_STATE_MASK);
        switch (state) {
-       case 0:
+       case PCI_D0:
                power_control |= 0;
                pci_write_config_word(tp->pdev,
                                      pm + PCI_PM_CTRL,
@@ -1163,15 +1169,15 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
 
                return 0;
 
-       case 1:
+       case PCI_D1:
                power_control |= 1;
                break;
 
-       case 2:
+       case PCI_D2:
                power_control |= 2;
                break;
 
-       case 3:
+       case PCI_D3hot:
                power_control |= 3;
                break;
 
@@ -2680,6 +2686,12 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
 
        err |= tg3_readphy(tp, MII_BMSR, &bmsr);
        err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+               if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
+                       bmsr |= BMSR_LSTATUS;
+               else
+                       bmsr &= ~BMSR_LSTATUS;
+       }
 
        err |= tg3_readphy(tp, MII_BMCR, &bmcr);
 
@@ -2748,6 +2760,13 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                        bmcr = new_bmcr;
                        err |= tg3_readphy(tp, MII_BMSR, &bmsr);
                        err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+                           ASIC_REV_5714) {
+                               if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
+                                       bmsr |= BMSR_LSTATUS;
+                               else
+                                       bmsr &= ~BMSR_LSTATUS;
+                       }
                        tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
                }
        }
@@ -5585,6 +5604,9 @@ static int tg3_reset_hw(struct tg3 *tp)
                tg3_abort_hw(tp, 1);
        }
 
+       if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+               tg3_phy_reset(tp);
+
        err = tg3_chip_reset(tp);
        if (err)
                return err;
@@ -6097,6 +6119,17 @@ static int tg3_reset_hw(struct tg3 *tp)
                tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG;
        }
 
+       if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) &&
+           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+               u32 tmp;
+
+               tmp = tr32(SERDES_RX_CTRL);
+               tw32(SERDES_RX_CTRL, tmp | SERDES_RX_SIG_DETECT);
+               tp->grc_local_ctrl &= ~GRC_LCLCTRL_USE_EXT_SIG_DETECT;
+               tp->grc_local_ctrl |= GRC_LCLCTRL_USE_SIG_DETECT;
+               tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+       }
+
        err = tg3_setup_phy(tp, 1);
        if (err)
                return err;
@@ -6175,7 +6208,7 @@ static int tg3_init_hw(struct tg3 *tp)
        int err;
 
        /* Force the chip into D0. */
-       err = tg3_set_power_state(tp, 0);
+       err = tg3_set_power_state(tp, PCI_D0);
        if (err)
                goto out;
 
@@ -6462,6 +6495,10 @@ static int tg3_open(struct net_device *dev)
 
        tg3_full_lock(tp, 0);
 
+       err = tg3_set_power_state(tp, PCI_D0);
+       if (err)
+               return err;
+
        tg3_disable_ints(tp);
        tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
 
@@ -6476,7 +6513,9 @@ static int tg3_open(struct net_device *dev)
 
        if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
            (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) &&
-           (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) {
+           (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX) &&
+           !((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) &&
+             (tp->pdev_peer == tp->pdev))) {
                /* All MSI supporting chips should support tagged
                 * status.  Assert that this is the case.
                 */
@@ -6839,7 +6878,6 @@ static int tg3_close(struct net_device *dev)
        tp->tg3_flags &=
                ~(TG3_FLAG_INIT_COMPLETE |
                  TG3_FLAG_GOT_SERDES_FLOWCTL);
-       netif_carrier_off(tp->dev);
 
        tg3_full_unlock(tp);
 
@@ -6856,6 +6894,10 @@ static int tg3_close(struct net_device *dev)
 
        tg3_free_consistent(tp);
 
+       tg3_set_power_state(tp, PCI_D3hot);
+
+       netif_carrier_off(tp->dev);
+
        return 0;
 }
 
@@ -7174,6 +7216,9 @@ static void tg3_get_regs(struct net_device *dev,
 
        memset(p, 0, TG3_REGDUMP_LEN);
 
+       if (tp->link_config.phy_is_low_power)
+               return;
+
        tg3_full_lock(tp, 0);
 
 #define __GET_REG32(reg)       (*(p)++ = tr32(reg))
@@ -7248,6 +7293,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        u8  *pd;
        u32 i, offset, len, val, b_offset, b_count;
 
+       if (tp->link_config.phy_is_low_power)
+               return -EAGAIN;
+
        offset = eeprom->offset;
        len = eeprom->len;
        eeprom->len = 0;
@@ -7309,6 +7357,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        u32 offset, len, b_offset, odd_len, start, end;
        u8 *buf;
 
+       if (tp->link_config.phy_is_low_power)
+               return -EAGAIN;
+
        if (eeprom->magic != TG3_EEPROM_MAGIC)
                return -EINVAL;
 
@@ -7802,7 +7853,7 @@ static int tg3_test_link(struct tg3 *tp)
 }
 
 /* Only test the commonly used registers */
-static int tg3_test_registers(struct tg3 *tp)
+static const int tg3_test_registers(struct tg3 *tp)
 {
        int i, is_5705;
        u32 offset, read_mask, write_mask, val, save_val, read_val;
@@ -8016,7 +8067,7 @@ out:
 
 static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len)
 {
-       static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a };
+       static const u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a };
        int i;
        u32 j;
 
@@ -8229,6 +8280,9 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 {
        struct tg3 *tp = netdev_priv(dev);
 
+       if (tp->link_config.phy_is_low_power)
+               tg3_set_power_state(tp, PCI_D0);
+
        memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
 
        if (tg3_test_nvram(tp) != 0) {
@@ -8286,6 +8340,9 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 
                tg3_full_unlock(tp);
        }
+       if (tp->link_config.phy_is_low_power)
+               tg3_set_power_state(tp, PCI_D3hot);
+
 }
 
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -8305,6 +8362,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
                        break;                  /* We have no PHY */
 
+               if (tp->link_config.phy_is_low_power)
+                       return -EAGAIN;
+
                spin_lock_bh(&tp->lock);
                err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
                spin_unlock_bh(&tp->lock);
@@ -8321,6 +8381,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
+               if (tp->link_config.phy_is_low_power)
+                       return -EAGAIN;
+
                spin_lock_bh(&tp->lock);
                err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
                spin_unlock_bh(&tp->lock);
@@ -9097,6 +9160,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
        tp->phy_id = PHY_ID_INVALID;
        tp->led_ctrl = LED_CTRL_MODE_PHY_1;
 
+       /* Do not even try poking around in here on Sun parts.  */
+       if (tp->tg3_flags2 & TG3_FLG2_SUN_570X)
+               return;
+
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
        if (val == NIC_SRAM_DATA_SIG_MAGIC) {
                u32 nic_cfg, led_cfg;
@@ -9552,12 +9619,36 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                }
        }
 
-       /* Find msi capability. */
+       /* The EPB bridge inside 5714, 5715, and 5780 cannot support
+        * DMA addresses > 40-bit. This bridge may have other additional
+        * 57xx devices behind it in some 4-port NIC designs for example.
+        * Any tg3 device found behind the bridge will also need the 40-bit
+        * DMA workaround.
+        */
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
                tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
+               tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
                tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
        }
+       else {
+               struct pci_dev *bridge = NULL;
+
+               do {
+                       bridge = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
+                                               PCI_DEVICE_ID_SERVERWORKS_EPB,
+                                               bridge);
+                       if (bridge && bridge->subordinate &&
+                           (bridge->subordinate->number <=
+                            tp->pdev->bus->number) &&
+                           (bridge->subordinate->subordinate >=
+                            tp->pdev->bus->number)) {
+                               tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
+                               pci_dev_put(bridge);
+                               break;
+                       }
+               } while (bridge);
+       }
 
        /* Initialize misc host control in PCI block. */
        tp->misc_host_ctrl |= (misc_ctrl_reg &
@@ -9744,7 +9835,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
 
        /* Force the chip into D0. */
-       err = tg3_set_power_state(tp, 0);
+       err = tg3_set_power_state(tp, PCI_D0);
        if (err) {
                printk(KERN_ERR PFX "(%s) transition to D0 failed\n",
                       pci_name(tp->pdev));
@@ -10303,7 +10394,14 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
                        u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f);
 
-                       if (ccval == 0x6 || ccval == 0x7)
+                       /* If the 5704 is behind the EPB bridge, we can
+                        * do the less restrictive ONE_DMA workaround for
+                        * better performance.
+                        */
+                       if ((tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) &&
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+                               tp->dma_rwctrl |= 0x8000;
+                       else if (ccval == 0x6 || ccval == 0x7)
                                tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
 
                        /* Set bit 23 to enable PCIX hw bug fix */
@@ -10759,19 +10857,20 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
-       /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit.
+       /* The EPB bridge inside 5714, 5715, and 5780 and any
+        * device behind the EPB cannot support DMA addresses > 40-bit.
         * On 64-bit systems with IOMMU, use 40-bit dma_mask.
         * On 64-bit systems without IOMMU, use 64-bit dma_mask and
         * do DMA address check in tg3_start_xmit().
         */
-       if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
+       if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
+               persist_dma_mask = dma_mask = DMA_32BIT_MASK;
+       else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
                persist_dma_mask = dma_mask = DMA_40BIT_MASK;
 #ifdef CONFIG_HIGHMEM
                dma_mask = DMA_64BIT_MASK;
 #endif
-       } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
-               persist_dma_mask = dma_mask = DMA_32BIT_MASK;
-       else
+       } else
                persist_dma_mask = dma_mask = DMA_64BIT_MASK;
 
        /* Configure DMA attributes. */
@@ -10812,11 +10911,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
        }
 
-       /* TSO is off by default, user can enable using ethtool.  */
-#if 0
-       if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)
+       /* TSO is on by default on chips that support hardware TSO.
+        * Firmware TSO on older chips gives lower performance, so it
+        * is off by default, but can be enabled using ethtool.
+        */
+       if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
                dev->features |= NETIF_F_TSO;
-#endif
 
 #endif
 
@@ -10908,8 +11008,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
               (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
               (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
               (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
-       printk(KERN_INFO "%s: dma_rwctrl[%08x]\n",
-              dev->name, tp->dma_rwctrl);
+       printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
+              dev->name, tp->dma_rwctrl,
+              (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
+               (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
 
        return 0;
 
@@ -11006,7 +11108,7 @@ static int tg3_resume(struct pci_dev *pdev)
 
        pci_restore_state(tp->pdev);
 
-       err = tg3_set_power_state(tp, 0);
+       err = tg3_set_power_state(tp, PCI_D0);
        if (err)
                return err;