]> err.no Git - linux-2.6/blobdiff - drivers/net/tg3.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux...
[linux-2.6] / drivers / net / tg3.c
index db606b603884530aa0f433c56a4d080f0e0c6714..07b3f77e7626dd646dcd0aed83484e12ef3579d8 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.87"
-#define DRV_MODULE_RELDATE     "December 20, 2007"
+#define DRV_MODULE_VERSION     "3.92"
+#define DRV_MODULE_RELDATE     "May 2, 2008"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -804,6 +804,12 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
        return ret;
 }
 
+static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
+{
+       tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+       tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+}
+
 static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
 {
        u32 phy;
@@ -886,6 +892,49 @@ static int tg3_bmcr_reset(struct tg3 *tp)
        return 0;
 }
 
+static void tg3_phy_apply_otp(struct tg3 *tp)
+{
+       u32 otp, phy;
+
+       if (!tp->phy_otp)
+               return;
+
+       otp = tp->phy_otp;
+
+       /* Enable SM_DSP clock and tx 6dB coding. */
+       phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+             MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
+             MII_TG3_AUXCTL_ACTL_TX_6DB;
+       tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+
+       phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT);
+       phy |= MII_TG3_DSP_TAP1_AGCTGT_DFLT;
+       tg3_phydsp_write(tp, MII_TG3_DSP_TAP1, phy);
+
+       phy = ((otp & TG3_OTP_HPFFLTR_MASK) >> TG3_OTP_HPFFLTR_SHIFT) |
+             ((otp & TG3_OTP_HPFOVER_MASK) >> TG3_OTP_HPFOVER_SHIFT);
+       tg3_phydsp_write(tp, MII_TG3_DSP_AADJ1CH0, phy);
+
+       phy = ((otp & TG3_OTP_LPFDIS_MASK) >> TG3_OTP_LPFDIS_SHIFT);
+       phy |= MII_TG3_DSP_AADJ1CH3_ADCCKADJ;
+       tg3_phydsp_write(tp, MII_TG3_DSP_AADJ1CH3, phy);
+
+       phy = ((otp & TG3_OTP_VDAC_MASK) >> TG3_OTP_VDAC_SHIFT);
+       tg3_phydsp_write(tp, MII_TG3_DSP_EXP75, phy);
+
+       phy = ((otp & TG3_OTP_10BTAMP_MASK) >> TG3_OTP_10BTAMP_SHIFT);
+       tg3_phydsp_write(tp, MII_TG3_DSP_EXP96, phy);
+
+       phy = ((otp & TG3_OTP_ROFF_MASK) >> TG3_OTP_ROFF_SHIFT) |
+             ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT);
+       tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy);
+
+       /* Turn off SM_DSP clock. */
+       phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+             MII_TG3_AUXCTL_ACTL_TX_6DB;
+       tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+}
+
 static int tg3_wait_macro_done(struct tg3 *tp)
 {
        int limit = 100;
@@ -1073,6 +1122,7 @@ static void tg3_link_report(struct tg3 *);
  */
 static int tg3_phy_reset(struct tg3 *tp)
 {
+       u32 cpmuctrl;
        u32 phy_status;
        int err;
 
@@ -1102,10 +1152,28 @@ static int tg3_phy_reset(struct tg3 *tp)
                goto out;
        }
 
+       cpmuctrl = 0;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+           GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) {
+               cpmuctrl = tr32(TG3_CPMU_CTRL);
+               if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY)
+                       tw32(TG3_CPMU_CTRL,
+                            cpmuctrl & ~CPMU_CTRL_GPHY_10MB_RXONLY);
+       }
+
        err = tg3_bmcr_reset(tp);
        if (err)
                return err;
 
+       if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) {
+               u32 phy;
+
+               phy = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz;
+               tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, phy);
+
+               tw32(TG3_CPMU_CTRL, cpmuctrl);
+       }
+
        if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
                u32 val;
 
@@ -1124,6 +1192,8 @@ static int tg3_phy_reset(struct tg3 *tp)
                             MII_TG3_MISC_SHDW_APD_WKTM_84MS);
        }
 
+       tg3_phy_apply_otp(tp);
+
 out:
        if (tp->tg3_flags2 & TG3_FLG2_PHY_ADC_BUG) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
@@ -1586,12 +1656,76 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
        return 0;
 }
 
+/* tp->lock is held. */
+static void tg3_wait_for_event_ack(struct tg3 *tp)
+{
+       int i;
+
+       /* Wait for up to 2.5 milliseconds */
+       for (i = 0; i < 250000; i++) {
+               if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
+                       break;
+               udelay(10);
+       }
+}
+
+/* tp->lock is held. */
+static void tg3_ump_link_report(struct tg3 *tp)
+{
+       u32 reg;
+       u32 val;
+
+       if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+           !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
+               return;
+
+       tg3_wait_for_event_ack(tp);
+
+       tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
+
+       tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
+
+       val = 0;
+       if (!tg3_readphy(tp, MII_BMCR, &reg))
+               val = reg << 16;
+       if (!tg3_readphy(tp, MII_BMSR, &reg))
+               val |= (reg & 0xffff);
+       tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val);
+
+       val = 0;
+       if (!tg3_readphy(tp, MII_ADVERTISE, &reg))
+               val = reg << 16;
+       if (!tg3_readphy(tp, MII_LPA, &reg))
+               val |= (reg & 0xffff);
+       tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
+
+       val = 0;
+       if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) {
+               if (!tg3_readphy(tp, MII_CTRL1000, &reg))
+                       val = reg << 16;
+               if (!tg3_readphy(tp, MII_STAT1000, &reg))
+                       val |= (reg & 0xffff);
+       }
+       tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val);
+
+       if (!tg3_readphy(tp, MII_PHYADDR, &reg))
+               val = reg << 16;
+       else
+               val = 0;
+       tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
+
+       val = tr32(GRC_RX_CPU_EVENT);
+       val |= GRC_RX_CPU_DRIVER_EVENT;
+       tw32_f(GRC_RX_CPU_EVENT, val);
+}
+
 static void tg3_link_report(struct tg3 *tp)
 {
        if (!netif_carrier_ok(tp->dev)) {
                if (netif_msg_link(tp))
                        printk(KERN_INFO PFX "%s: Link is down.\n",
                               tp->dev->name);
+               tg3_ump_link_report(tp);
        } else if (netif_msg_link(tp)) {
                printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
                       tp->dev->name,
@@ -1609,6 +1743,7 @@ static void tg3_link_report(struct tg3 *tp)
                       "on" : "off",
                       (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
                       "on" : "off");
+               tg3_ump_link_report(tp);
        }
 }
 
@@ -2027,9 +2162,11 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
              MAC_STATUS_LNKSTATE_CHANGED));
        udelay(40);
 
-       tp->mi_mode = MAC_MI_MODE_BASE;
-       tw32_f(MAC_MI_MODE, tp->mi_mode);
-       udelay(80);
+       if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
+               tw32_f(MAC_MI_MODE,
+                    (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
+               udelay(80);
+       }
 
        tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
 
@@ -3947,6 +4084,8 @@ static int tg3_halt(struct tg3 *, int, int);
  * Invoked with tp->lock held.
  */
 static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
+       __releases(tp->lock)
+       __acquires(tp->lock)
 {
        int err;
 
@@ -4065,11 +4204,21 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
                                       u32 last_plus_one, u32 *start,
                                       u32 base_flags, u32 mss)
 {
-       struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC);
+       struct sk_buff *new_skb;
        dma_addr_t new_addr = 0;
        u32 entry = *start;
        int i, ret = 0;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
+               new_skb = skb_copy(skb, GFP_ATOMIC);
+       else {
+               int more_headroom = 4 - ((unsigned long)skb->data & 3);
+
+               new_skb = skb_copy_expand(skb,
+                                         skb_headroom(skb) + more_headroom,
+                                         skb_tailroom(skb), GFP_ATOMIC);
+       }
+
        if (!new_skb) {
                ret = -1;
        } else {
@@ -4279,7 +4428,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
        }
 
        segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO);
-       if (unlikely(IS_ERR(segs)))
+       if (IS_ERR(segs))
                goto tg3_tso_bug_end;
 
        do {
@@ -4392,7 +4541,9 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 
        would_hit_hwbug = 0;
 
-       if (tg3_4g_overflow_test(mapping, len))
+       if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+               would_hit_hwbug = 1;
+       else if (tg3_4g_overflow_test(mapping, len))
                would_hit_hwbug = 1;
 
        tg3_set_txd(tp, entry, mapping, len, base_flags,
@@ -5414,19 +5565,17 @@ static void tg3_stop_fw(struct tg3 *tp)
        if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
           !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
                u32 val;
-               int i;
+
+               /* Wait for RX cpu to ACK the previous event. */
+               tg3_wait_for_event_ack(tp);
 
                tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
                val = tr32(GRC_RX_CPU_EVENT);
-               val |= (1 << 14);
+               val |= GRC_RX_CPU_DRIVER_EVENT;
                tw32(GRC_RX_CPU_EVENT, val);
 
-               /* Wait for RX cpu to ACK the event.  */
-               for (i = 0; i < 100; i++) {
-                       if (!(tr32(GRC_RX_CPU_EVENT) & (1 << 14)))
-                               break;
-                       udelay(1);
-               }
+               /* Wait for RX cpu to ACK this event. */
+               tg3_wait_for_event_ack(tp);
        }
 }
 
@@ -7018,7 +7167,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tp->link_config.autoneg = tp->link_config.orig_autoneg;
        }
 
-       tp->mi_mode = MAC_MI_MODE_BASE;
+       tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
        tw32_f(MAC_MI_MODE, tp->mi_mode);
        udelay(80);
 
@@ -7316,14 +7465,16 @@ static void tg3_timer(unsigned long __opaque)
                if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
                        u32 val;
 
+                       tg3_wait_for_event_ack(tp);
+
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
                                      FWCMD_NICDRV_ALIVE3);
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
                        /* 5 seconds timeout */
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
                        val = tr32(GRC_RX_CPU_EVENT);
-                       val |= (1 << 14);
-                       tw32(GRC_RX_CPU_EVENT, val);
+                       val |= GRC_RX_CPU_DRIVER_EVENT;
+                       tw32_f(GRC_RX_CPU_EVENT, val);
                }
                tp->asf_counter = tp->asf_multiplier;
        }
@@ -8781,7 +8932,7 @@ static int tg3_phys_id(struct net_device *dev, u32 data)
                return -EAGAIN;
 
        if (data == 0)
-               data = 2;
+               data = UINT_MAX / 2;
 
        for (i = 0; i < (data * 2); i++) {
                if ((i % 2) == 0)
@@ -9464,7 +9615,8 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (err)
                return TG3_LOOPBACK_FAILED;
 
-       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
                int i;
                u32 status;
 
@@ -9481,7 +9633,7 @@ static int tg3_test_loopback(struct tg3 *tp)
                if (status != CPMU_MUTEX_GNT_DRIVER)
                        return TG3_LOOPBACK_FAILED;
 
-               /* Turn off power management based on link speed. */
+               /* Turn off link-based power management. */
                cpmuctrl = tr32(TG3_CPMU_CTRL);
                tw32(TG3_CPMU_CTRL,
                     cpmuctrl & ~(CPMU_CTRL_LINK_SPEED_MODE |
@@ -9491,7 +9643,8 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
                err |= TG3_MAC_LOOPBACK_FAILED;
 
-       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
                tw32(TG3_CPMU_CTRL, cpmuctrl);
 
                /* Release the mutex */
@@ -9801,7 +9954,7 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
                        return;
                }
        }
-       tp->nvram_size = 0x80000;
+       tp->nvram_size = TG3_NVRAM_SIZE_512KB;
 }
 
 static void __devinit tg3_get_nvram_info(struct tg3 *tp)
@@ -9942,11 +10095,14 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
                        tp->nvram_pagesize = 264;
                        if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
                            nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
-                               tp->nvram_size = (protect ? 0x3e200 : 0x80000);
+                               tp->nvram_size = (protect ? 0x3e200 :
+                                                 TG3_NVRAM_SIZE_512KB);
                        else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
-                               tp->nvram_size = (protect ? 0x1f200 : 0x40000);
+                               tp->nvram_size = (protect ? 0x1f200 :
+                                                 TG3_NVRAM_SIZE_256KB);
                        else
-                               tp->nvram_size = (protect ? 0x1f200 : 0x20000);
+                               tp->nvram_size = (protect ? 0x1f200 :
+                                                 TG3_NVRAM_SIZE_128KB);
                        break;
                case FLASH_5752VENDOR_ST_M45PE10:
                case FLASH_5752VENDOR_ST_M45PE20:
@@ -9956,11 +10112,17 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
                        tp->tg3_flags2 |= TG3_FLG2_FLASH;
                        tp->nvram_pagesize = 256;
                        if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
-                               tp->nvram_size = (protect ? 0x10000 : 0x20000);
+                               tp->nvram_size = (protect ?
+                                                 TG3_NVRAM_SIZE_64KB :
+                                                 TG3_NVRAM_SIZE_128KB);
                        else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
-                               tp->nvram_size = (protect ? 0x10000 : 0x40000);
+                               tp->nvram_size = (protect ?
+                                                 TG3_NVRAM_SIZE_64KB :
+                                                 TG3_NVRAM_SIZE_256KB);
                        else
-                               tp->nvram_size = (protect ? 0x20000 : 0x80000);
+                               tp->nvram_size = (protect ?
+                                                 TG3_NVRAM_SIZE_128KB :
+                                                 TG3_NVRAM_SIZE_512KB);
                        break;
        }
 }
@@ -10054,25 +10216,25 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
                        case FLASH_5761VENDOR_ATMEL_MDB161D:
                        case FLASH_5761VENDOR_ST_A_M45PE16:
                        case FLASH_5761VENDOR_ST_M_M45PE16:
-                               tp->nvram_size = 0x100000;
+                               tp->nvram_size = TG3_NVRAM_SIZE_2MB;
                                break;
                        case FLASH_5761VENDOR_ATMEL_ADB081D:
                        case FLASH_5761VENDOR_ATMEL_MDB081D:
                        case FLASH_5761VENDOR_ST_A_M45PE80:
                        case FLASH_5761VENDOR_ST_M_M45PE80:
-                               tp->nvram_size = 0x80000;
+                               tp->nvram_size = TG3_NVRAM_SIZE_1MB;
                                break;
                        case FLASH_5761VENDOR_ATMEL_ADB041D:
                        case FLASH_5761VENDOR_ATMEL_MDB041D:
                        case FLASH_5761VENDOR_ST_A_M45PE40:
                        case FLASH_5761VENDOR_ST_M_M45PE40:
-                               tp->nvram_size = 0x40000;
+                               tp->nvram_size = TG3_NVRAM_SIZE_512KB;
                                break;
                        case FLASH_5761VENDOR_ATMEL_ADB021D:
                        case FLASH_5761VENDOR_ATMEL_MDB021D:
                        case FLASH_5761VENDOR_ST_A_M45PE20:
                        case FLASH_5761VENDOR_ST_M_M45PE20:
-                               tp->nvram_size = 0x20000;
+                               tp->nvram_size = TG3_NVRAM_SIZE_256KB;
                                break;
                }
        }
@@ -10724,9 +10886,8 @@ 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 (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-                   tp->pci_chip_rev_id == CHIPREV_ID_5784_A1)
-                       tp->led_ctrl = LED_CTRL_MODE_MAC;
+               if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX)
+                       tp->led_ctrl = LED_CTRL_MODE_PHY_1;
 
                if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
                        tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
@@ -10773,6 +10934,55 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
        }
 }
 
+static int __devinit tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
+{
+       int i;
+       u32 val;
+
+       tw32(OTP_CTRL, cmd | OTP_CTRL_OTP_CMD_START);
+       tw32(OTP_CTRL, cmd);
+
+       /* Wait for up to 1 ms for command to execute. */
+       for (i = 0; i < 100; i++) {
+               val = tr32(OTP_STATUS);
+               if (val & OTP_STATUS_CMD_DONE)
+                       break;
+               udelay(10);
+       }
+
+       return (val & OTP_STATUS_CMD_DONE) ? 0 : -EBUSY;
+}
+
+/* Read the gphy configuration from the OTP region of the chip.  The gphy
+ * configuration is a 32-bit value that straddles the alignment boundary.
+ * We do two 32-bit reads and then shift and merge the results.
+ */
+static u32 __devinit tg3_read_otp_phycfg(struct tg3 *tp)
+{
+       u32 bhalf_otp, thalf_otp;
+
+       tw32(OTP_MODE, OTP_MODE_OTP_THRU_GRC);
+
+       if (tg3_issue_otp_command(tp, OTP_CTRL_OTP_CMD_INIT))
+               return 0;
+
+       tw32(OTP_ADDRESS, OTP_ADDRESS_MAGIC1);
+
+       if (tg3_issue_otp_command(tp, OTP_CTRL_OTP_CMD_READ))
+               return 0;
+
+       thalf_otp = tr32(OTP_READ_DATA);
+
+       tw32(OTP_ADDRESS, OTP_ADDRESS_MAGIC2);
+
+       if (tg3_issue_otp_command(tp, OTP_CTRL_OTP_CMD_READ))
+               return 0;
+
+       bhalf_otp = tr32(OTP_READ_DATA);
+
+       return ((thalf_otp & 0x0000ffff) << 16) | (bhalf_otp >> 16);
+}
+
 static int __devinit tg3_phy_probe(struct tg3 *tp)
 {
        u32 hw_phy_id_1, hw_phy_id_2;
@@ -11214,6 +11424,38 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                }
        }
 
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
+               static struct tg3_dev_id {
+                       u32     vendor;
+                       u32     device;
+               } bridge_chipsets[] = {
+                       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0 },
+                       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1 },
+                       { },
+               };
+               struct tg3_dev_id *pci_id = &bridge_chipsets[0];
+               struct pci_dev *bridge = NULL;
+
+               while (pci_id->vendor != 0) {
+                       bridge = pci_get_device(pci_id->vendor,
+                                               pci_id->device,
+                                               bridge);
+                       if (!bridge) {
+                               pci_id++;
+                               continue;
+                       }
+                       if (bridge->subordinate &&
+                           (bridge->subordinate->number <=
+                            tp->pdev->bus->number) &&
+                           (bridge->subordinate->subordinate >=
+                            tp->pdev->bus->number)) {
+                               tp->tg3_flags3 |= TG3_FLG3_5701_DMA_BUG;
+                               pci_dev_put(bridge);
+                               break;
+                       }
+               }
+       }
+
        /* 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.
@@ -11586,6 +11828,19 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                        tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+           GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) {
+               tp->phy_otp = tg3_read_otp_phycfg(tp);
+               if (tp->phy_otp == 0)
+                       tp->phy_otp = TG3_OTP_DEFAULT;
+       }
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+               tp->mi_mode = MAC_MI_MODE_500KHZ_CONST;
+       else
+               tp->mi_mode = MAC_MI_MODE_BASE;
+
        tp->coalesce_mode = 0;
        if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX &&
            GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
@@ -11841,7 +12096,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
        }
 
        if (!is_valid_ether_addr(&dev->dev_addr[0])) {
-#ifdef CONFIG_SPARC64
+#ifdef CONFIG_SPARC
                if (!tg3_get_default_macaddr_sparc(tp))
                        return 0;
 #endif
@@ -12446,7 +12701,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        static int tg3_version_printed = 0;
-       unsigned long tg3reg_base, tg3reg_len;
+       resource_size_t tg3reg_base;
+       unsigned long tg3reg_len;
        struct net_device *dev;
        struct tg3 *tp;
        int err, pm_cap;
@@ -12513,7 +12769,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        tp->mac_mode = TG3_DEF_MAC_MODE;
        tp->rx_mode = TG3_DEF_RX_MODE;
        tp->tx_mode = TG3_DEF_TX_MODE;
-       tp->mi_mode = MAC_MI_MODE_BASE;
+
        if (tg3_debug > 0)
                tp->msg_enable = tg3_debug;
        else