BUG_ON() Conversion in drivers/net/
[deliverable/linux.git] / drivers / net / tg3.c
index 5182a3be7f21339939cbc55dac4c638670b6d6da..46f55fb9a053a1fdab97067100aa460d162c3900 100644 (file)
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.51"
-#define DRV_MODULE_RELDATE     "Feb 21, 2006"
+#define DRV_MODULE_VERSION     "3.55"
+#define DRV_MODULE_RELDATE     "Mar 27, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -225,6 +225,10 @@ 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_5754M,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M,
@@ -493,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
        unsigned long flags;
 
        spin_lock_irqsave(&tp->indirect_lock, flags);
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+       if (tp->write32 != tg3_write_indirect_reg32) {
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
+               tw32_f(TG3PCI_MEM_WIN_DATA, val);
 
-       /* Always leave this as zero. */
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
-       spin_unlock_irqrestore(&tp->indirect_lock, flags);
-}
+               /* Always leave this as zero. */
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       } else {
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
 
-static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val)
-{
-       /* If no workaround is needed, write to mem space directly */
-       if (tp->write32 != tg3_write_indirect_reg32)
-               tw32(NIC_SRAM_WIN_BASE + off, val);
-       else
-               tg3_write_mem(tp, off, val);
+               /* Always leave this as zero. */
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       }
+       spin_unlock_irqrestore(&tp->indirect_lock, flags);
 }
 
 static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
@@ -515,11 +518,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
        unsigned long flags;
 
        spin_lock_irqsave(&tp->indirect_lock, flags);
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
-       pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+       if (tp->write32 != tg3_write_indirect_reg32) {
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
+               *val = tr32(TG3PCI_MEM_WIN_DATA);
 
-       /* Always leave this as zero. */
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+               /* Always leave this as zero. */
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       } else {
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+               pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+
+               /* Always leave this as zero. */
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       }
        spin_unlock_irqrestore(&tp->indirect_lock, flags);
 }
 
@@ -546,6 +557,9 @@ static void tg3_enable_ints(struct tg3 *tp)
             (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
                       (tp->last_tag << 24));
+       if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+               tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+                              (tp->last_tag << 24));
        tg3_cond_int(tp);
 }
 
@@ -1145,6 +1159,19 @@ static int tg3_halt_cpu(struct tg3 *, u32);
 static int tg3_nvram_lock(struct tg3 *);
 static void tg3_nvram_unlock(struct tg3 *);
 
+static void tg3_power_down_phy(struct tg3 *tp)
+{
+       /* The PHY should not be powered down on some chips because
+        * of bugs.
+        */
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 &&
+            (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
+               return;
+       tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
+}
+
 static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 {
        u32 misc_host_ctrl;
@@ -1324,8 +1351,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        tg3_writephy(tp, MII_TG3_EXT_CTRL,
                                     MII_TG3_EXT_CTRL_FORCE_LED_OFF);
                        tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
-                       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
-                               tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
+                       tg3_power_down_phy(tp);
                }
        }
 
@@ -1348,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                }
        }
 
+       tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
+
        /* Finally, set the new power state. */
        pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
        udelay(100);    /* Delay after power state change */
 
-       tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
-
        return 0;
 }
 
@@ -2940,9 +2966,7 @@ static void tg3_tx(struct tg3 *tp)
                struct sk_buff *skb = ri->skb;
                int i;
 
-               if (unlikely(skb == NULL))
-                       BUG();
-
+               BUG_ON(skb == NULL);
                pci_unmap_single(tp->pdev,
                                 pci_unmap_addr(ri, mapping),
                                 skb_headlen(skb),
@@ -2953,12 +2977,10 @@ static void tg3_tx(struct tg3 *tp)
                sw_idx = NEXT_TX(sw_idx);
 
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-                       if (unlikely(sw_idx == hw_idx))
-                               BUG();
+                       BUG_ON(sw_idx == hw_idx);
 
                        ri = &tp->tx_buffers[sw_idx];
-                       if (unlikely(ri->skb != NULL))
-                               BUG();
+                       BUG_ON(ri->skb != NULL);
 
                        pci_unmap_page(tp->pdev,
                                       pci_unmap_addr(ri, mapping),
@@ -3365,6 +3387,23 @@ static inline void tg3_full_unlock(struct tg3 *tp)
        spin_unlock_bh(&tp->lock);
 }
 
+/* One-shot MSI handler - Chip automatically disables interrupt
+ * after sending MSI so driver doesn't have to do it.
+ */
+static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct net_device *dev = dev_id;
+       struct tg3 *tp = netdev_priv(dev);
+
+       prefetch(tp->hw_status);
+       prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+
+       if (likely(!tg3_irq_sync(tp)))
+               netif_rx_schedule(dev);         /* schedule NAPI poll */
+
+       return IRQ_HANDLED;
+}
+
 /* MSI ISR - No need to check for interrupt sharing and no need to
  * flush status block and interrupt mailbox. PCI ordering rules
  * guarantee that MSI will arrive after the status block.
@@ -3564,7 +3603,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
                                          int len)
 {
 #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
-       if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+       if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
                return (((u64) mapping + len) > DMA_40BIT_MASK);
        return 0;
 #else
@@ -4525,6 +4564,7 @@ static int tg3_chip_reset(struct tg3 *tp)
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                tw32(GRC_FASTBOOT_PC, 0);
 
@@ -4891,9 +4931,8 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
 {
        int i;
 
-       if (offset == TX_CPU_BASE &&
-           (tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
-               BUG();
+       BUG_ON(offset == TX_CPU_BASE &&
+           (tp->tg3_flags2 & TG3_FLG2_5705_PLUS));
 
        if (offset == RX_CPU_BASE) {
                for (i = 0; i < 10000; i++) {
@@ -6120,6 +6159,9 @@ static int tg3_reset_hw(struct tg3 *tp)
                        gpio_mask |= GRC_LCLCTRL_GPIO_OE3 |
                                     GRC_LCLCTRL_GPIO_OUTPUT3;
 
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+                       gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL;
+
                tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
 
                /* GPIO1 must be driven high for eeprom write protect */
@@ -6159,7 +6201,8 @@ static int tg3_reset_hw(struct tg3 *tp)
        }
 
        /* Enable host coalescing bug fix */
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) ||
+           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787))
                val |= (1 << 29);
 
        tw32_f(WDMAC_MODE, val);
@@ -6217,6 +6260,9 @@ static int tg3_reset_hw(struct tg3 *tp)
        udelay(100);
 
        tp->rx_mode = RX_MODE_ENABLE;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+               tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
+
        tw32_f(MAC_RX_MODE, tp->rx_mode);
        udelay(10);
 
@@ -6417,6 +6463,9 @@ static void tg3_timer(unsigned long __opaque)
 {
        struct tg3 *tp = (struct tg3 *) __opaque;
 
+       if (tp->irq_sync)
+               goto restart_timer;
+
        spin_lock(&tp->lock);
 
        if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
@@ -6493,11 +6542,11 @@ static void tg3_timer(unsigned long __opaque)
                if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
                        u32 val;
 
-                       tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
-                                          FWCMD_NICDRV_ALIVE2);
-                       tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+                       tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
+                                     FWCMD_NICDRV_ALIVE2);
+                       tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
                        /* 5 seconds timeout */
-                       tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
+                       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);
@@ -6507,10 +6556,31 @@ static void tg3_timer(unsigned long __opaque)
 
        spin_unlock(&tp->lock);
 
+restart_timer:
        tp->timer.expires = jiffies + tp->timer_offset;
        add_timer(&tp->timer);
 }
 
+static int tg3_request_irq(struct tg3 *tp)
+{
+       irqreturn_t (*fn)(int, void *, struct pt_regs *);
+       unsigned long flags;
+       struct net_device *dev = tp->dev;
+
+       if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+               fn = tg3_msi;
+               if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+                       fn = tg3_msi_1shot;
+               flags = SA_SAMPLE_RANDOM;
+       } else {
+               fn = tg3_interrupt;
+               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+                       fn = tg3_interrupt_tagged;
+               flags = SA_SHIRQ | SA_SAMPLE_RANDOM;
+       }
+       return (request_irq(tp->pdev->irq, fn, flags, dev->name, dev));
+}
+
 static int tg3_test_interrupt(struct tg3 *tp)
 {
        struct net_device *dev = tp->dev;
@@ -6547,16 +6617,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
 
        free_irq(tp->pdev->irq, dev);
        
-       if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
-               err = request_irq(tp->pdev->irq, tg3_msi,
-                                 SA_SAMPLE_RANDOM, dev->name, dev);
-       else {
-               irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
-               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
-                       fn = tg3_interrupt_tagged;
-               err = request_irq(tp->pdev->irq, fn,
-                                 SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
-       }
+       err = tg3_request_irq(tp);
 
        if (err)
                return err;
@@ -6608,14 +6669,7 @@ static int tg3_test_msi(struct tg3 *tp)
 
        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
 
-       {
-               irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
-               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
-                       fn = tg3_interrupt_tagged;
-
-               err = request_irq(tp->pdev->irq, fn,
-                                 SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
-       }
+       err = tg3_request_irq(tp);
        if (err)
                return err;
 
@@ -6677,17 +6731,7 @@ static int tg3_open(struct net_device *dev)
                        tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
                }
        }
-       if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
-               err = request_irq(tp->pdev->irq, tg3_msi,
-                                 SA_SAMPLE_RANDOM, dev->name, dev);
-       else {
-               irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
-               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
-                       fn = tg3_interrupt_tagged;
-
-               err = request_irq(tp->pdev->irq, fn,
-                                 SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
-       }
+       err = tg3_request_irq(tp);
 
        if (err) {
                if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -6752,6 +6796,14 @@ static int tg3_open(struct net_device *dev)
 
                        return err;
                }
+
+               if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+                       if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) {
+                               u32 val = tr32(0x7c04);
+
+                               tw32(0x7c04, val | (1 << 29));
+                       }
+               }
        }
 
        tg3_full_lock(tp, 0);
@@ -7435,6 +7487,7 @@ static int tg3_get_eeprom_len(struct net_device *dev)
 }
 
 static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val);
+static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val);
 
 static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
@@ -7643,6 +7696,7 @@ static void tg3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info
   
        strcpy(info->driver, DRV_MODULE_NAME);
        strcpy(info->version, DRV_MODULE_VERSION);
+       strcpy(info->fw_version, tp->fw_ver);
        strcpy(info->bus_info, pci_name(tp->pdev));
 }
   
@@ -7871,7 +7925,8 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data)
                return 0;
        }
   
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                ethtool_op_set_tx_hw_csum(dev, data);
        else
                ethtool_op_set_tx_csum(dev, data);
@@ -7951,10 +8006,9 @@ static int tg3_test_nvram(struct tg3 *tp)
        u32 *buf, csum, magic;
        int i, j, err = 0, size;
 
-       if (tg3_nvram_read(tp, 0, &magic) != 0)
+       if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
                return -EIO;
 
-       magic = swab32(magic);
        if (magic == TG3_EEPROM_MAGIC)
                size = NVRAM_TEST_SIZE;
        else if ((magic & 0xff000000) == 0xa5000000) {
@@ -8036,7 +8090,7 @@ static int tg3_test_link(struct tg3 *tp)
 }
 
 /* Only test the commonly used registers */
-static const int tg3_test_registers(struct tg3 *tp)
+static int tg3_test_registers(struct tg3 *tp)
 {
        int i, is_5705;
        u32 offset, read_mask, write_mask, val, save_val, read_val;
@@ -8284,14 +8338,25 @@ static int tg3_test_memory(struct tg3 *tp)
                { 0x00008000, 0x02000},
                { 0x00010000, 0x0e000},
                { 0xffffffff, 0x00000}
+       }, mem_tbl_5755[] = {
+               { 0x00000200, 0x00008},
+               { 0x00004000, 0x00800},
+               { 0x00006000, 0x00800},
+               { 0x00008000, 0x02000},
+               { 0x00010000, 0x0c000},
+               { 0xffffffff, 0x00000}
        };
        struct mem_entry *mem_tbl;
        int err = 0;
        int i;
 
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
-               mem_tbl = mem_tbl_5705;
-       else
+       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+                       mem_tbl = mem_tbl_5755;
+               else
+                       mem_tbl = mem_tbl_5705;
+       } else
                mem_tbl = mem_tbl_570x;
 
        for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
@@ -8340,8 +8405,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                }
                mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
                           MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
-               if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)
+               if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
                        mac_mode &= ~MAC_MODE_LINK_POLARITY;
+                       tg3_writephy(tp, MII_TG3_EXT_CTRL,
+                                    MII_TG3_EXT_CTRL_LNK3_LED_MODE);
+               }
                tw32(MAC_MODE, mac_mode);
        }
        else
@@ -8717,10 +8785,9 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
 
        tp->nvram_size = EEPROM_CHIP_SIZE;
 
-       if (tg3_nvram_read(tp, 0, &val) != 0)
+       if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
                return;
 
-       magic = swab32(val);
        if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000))
                return;
 
@@ -8732,10 +8799,10 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
        cursize = 0x10;
 
        while (cursize < tp->nvram_size) {
-               if (tg3_nvram_read(tp, cursize, &val) != 0)
+               if (tg3_nvram_read_swab(tp, cursize, &val) != 0)
                        return;
 
-               if (swab32(val) == magic)
+               if (val == magic)
                        break;
 
                cursize <<= 1;
@@ -8748,11 +8815,11 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
 {
        u32 val;
 
-       if (tg3_nvram_read(tp, 0, &val) != 0)
+       if (tg3_nvram_read_swab(tp, 0, &val) != 0)
                return;
 
        /* Selfboot format */
-       if (swab32(val) != TG3_EEPROM_MAGIC) {
+       if (val != TG3_EEPROM_MAGIC) {
                tg3_get_eeprom_size(tp);
                return;
        }
@@ -8880,6 +8947,47 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
        }
 }
 
+static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
+{
+       u32 nvcfg1;
+
+       nvcfg1 = tr32(NVRAM_CFG1);
+
+       /* NVRAM protection for TPM */
+       if (nvcfg1 & (1 << 27))
+               tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+
+       switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+               case FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ:
+               case FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ:
+                       tp->nvram_jedecnum = JEDEC_ATMEL;
+                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+                       tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+                       nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+                       tw32(NVRAM_CFG1, nvcfg1);
+                       break;
+               case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+               case FLASH_5755VENDOR_ATMEL_FLASH_1:
+               case FLASH_5755VENDOR_ATMEL_FLASH_2:
+               case FLASH_5755VENDOR_ATMEL_FLASH_3:
+               case FLASH_5755VENDOR_ATMEL_FLASH_4:
+                       tp->nvram_jedecnum = JEDEC_ATMEL;
+                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
+                       tp->nvram_pagesize = 264;
+                       break;
+               case FLASH_5752VENDOR_ST_M45PE10:
+               case FLASH_5752VENDOR_ST_M45PE20:
+               case FLASH_5752VENDOR_ST_M45PE40:
+                       tp->nvram_jedecnum = JEDEC_ST;
+                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
+                       tp->nvram_pagesize = 256;
+                       break;
+       }
+}
+
 static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
 {
        u32 nvcfg1;
@@ -8953,6 +9061,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
 
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
                        tg3_get_5752_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+                       tg3_get_5755_nvram_info(tp);
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                        tg3_get_5787_nvram_info(tp);
                else
@@ -9024,6 +9134,34 @@ static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
        return 0;
 }
 
+static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
+{
+       if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+           (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+           (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+           (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+               addr = ((addr / tp->nvram_pagesize) <<
+                       ATMEL_AT45DB0X1B_PAGE_POS) +
+                      (addr % tp->nvram_pagesize);
+
+       return addr;
+}
+
+static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
+{
+       if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+           (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+           (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+           (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+               addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
+                       tp->nvram_pagesize) +
+                      (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
+
+       return addr;
+}
+
 static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
 {
        int ret;
@@ -9036,14 +9174,7 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
        if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
                return tg3_nvram_read_using_eeprom(tp, offset, val);
 
-       if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
-               (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-               (tp->nvram_jedecnum == JEDEC_ATMEL)) {
-
-               offset = ((offset / tp->nvram_pagesize) <<
-                         ATMEL_AT45DB0X1B_PAGE_POS) +
-                       (offset % tp->nvram_pagesize);
-       }
+       offset = tg3_nvram_phys_addr(tp, offset);
 
        if (offset > NVRAM_ADDR_MSK)
                return -EINVAL;
@@ -9068,6 +9199,16 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
        return ret;
 }
 
+static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val)
+{
+       int err;
+       u32 tmp;
+
+       err = tg3_nvram_read(tp, offset, &tmp);
+       *val = swab32(tmp);
+       return err;
+}
+
 static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
                                    u32 offset, u32 len, u8 *buf)
 {
@@ -9220,15 +9361,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
 
                page_off = offset % tp->nvram_pagesize;
 
-               if ((tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-                       (tp->nvram_jedecnum == JEDEC_ATMEL)) {
-
-                       phy_addr = ((offset / tp->nvram_pagesize) <<
-                                   ATMEL_AT45DB0X1B_PAGE_POS) + page_off;
-               }
-               else {
-                       phy_addr = offset;
-               }
+               phy_addr = tg3_nvram_phys_addr(tp, offset);
 
                tw32(NVRAM_ADDR, phy_addr);
 
@@ -9243,6 +9376,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
                        nvram_cmd |= NVRAM_CMD_LAST;
 
                if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) &&
+                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
                    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) &&
                    (tp->nvram_jedecnum == JEDEC_ST) &&
                    (nvram_cmd & NVRAM_CMD_FIRST)) {
@@ -9381,12 +9515,18 @@ static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp)
        return NULL;
 }
 
-/* Since this function may be called in D3-hot power state during
- * tg3_init_one(), only config cycles are allowed.
- */
 static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 {
        u32 val;
+       u16 pmcsr;
+
+       /* On some early chips the SRAM cannot be accessed in D3hot state,
+        * so need make sure we're in D0.
+        */
+       pci_read_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, &pmcsr);
+       pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+       pci_write_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, pmcsr);
+       msleep(1);
 
        /* Make sure register accesses (indirect or otherwise)
         * will function correctly.
@@ -9657,10 +9797,10 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                return;
        }
 
-       if (tg3_nvram_read(tp, 0x0, &magic))
+       if (tg3_nvram_read_swab(tp, 0x0, &magic))
                return;
 
-       if (swab32(magic) == TG3_EEPROM_MAGIC) {
+       if (magic == TG3_EEPROM_MAGIC) {
                for (i = 0; i < 256; i += 4) {
                        u32 tmp;
 
@@ -9740,6 +9880,46 @@ out_not_found:
        strcpy(tp->board_part_number, "none");
 }
 
+static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+{
+       u32 val, offset, start;
+
+       if (tg3_nvram_read_swab(tp, 0, &val))
+               return;
+
+       if (val != TG3_EEPROM_MAGIC)
+               return;
+
+       if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
+           tg3_nvram_read_swab(tp, 0x4, &start))
+               return;
+
+       offset = tg3_nvram_logical_addr(tp, offset);
+       if (tg3_nvram_read_swab(tp, offset, &val))
+               return;
+
+       if ((val & 0xfc000000) == 0x0c000000) {
+               u32 ver_offset, addr;
+               int i;
+
+               if (tg3_nvram_read_swab(tp, offset + 4, &val) ||
+                   tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
+                       return;
+
+               if (val != 0)
+                       return;
+
+               addr = offset + ver_offset - start;
+               for (i = 0; i < 16; i += 4) {
+                       if (tg3_nvram_read(tp, addr + i, &val))
+                               return;
+
+                       val = cpu_to_le32(val);
+                       memcpy(tp->fw_ver + i, &val, 4);
+               }
+       }
+}
+
 #ifdef CONFIG_SPARC64
 static int __devinit tg3_is_sun_570X(struct tg3 *tp)
 {
@@ -9931,6 +10111,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
@@ -9940,15 +10121,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
 
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) {
                        tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
-               else
+                       tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
+               } else
                        tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1;
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787)
                tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
 
@@ -10105,6 +10289,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+               tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
+
        /* Force the chip into D0. */
        err = tg3_set_power_state(tp, PCI_D0);
        if (err) {
@@ -10160,6 +10347,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
 
        if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+           (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
            (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787))
                tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
 
@@ -10260,6 +10448,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        tg3_read_partno(tp);
+       tg3_read_fw_ver(tp);
 
        if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
                tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT;
@@ -10298,7 +10487,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        /* All chips before 5787 can get confused if TX buffers
         * straddle the 4GB address boundary in some cases.
         */
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                tp->dev->hard_start_xmit = tg3_start_xmit;
        else
                tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug;
@@ -10350,6 +10540,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
 {
        struct net_device *dev = tp->dev;
        u32 hi, lo, mac_offset;
+       int addr_ok = 0;
 
 #ifdef CONFIG_SPARC64
        if (!tg3_get_macaddr_sparc(tp))
@@ -10379,29 +10570,34 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
                dev->dev_addr[3] = (lo >> 16) & 0xff;
                dev->dev_addr[4] = (lo >>  8) & 0xff;
                dev->dev_addr[5] = (lo >>  0) & 0xff;
-       }
-       /* Next, try NVRAM. */
-       else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) &&
-                !tg3_nvram_read(tp, mac_offset + 0, &hi) &&
-                !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
-               dev->dev_addr[0] = ((hi >> 16) & 0xff);
-               dev->dev_addr[1] = ((hi >> 24) & 0xff);
-               dev->dev_addr[2] = ((lo >>  0) & 0xff);
-               dev->dev_addr[3] = ((lo >>  8) & 0xff);
-               dev->dev_addr[4] = ((lo >> 16) & 0xff);
-               dev->dev_addr[5] = ((lo >> 24) & 0xff);
-       }
-       /* Finally just fetch it out of the MAC control regs. */
-       else {
-               hi = tr32(MAC_ADDR_0_HIGH);
-               lo = tr32(MAC_ADDR_0_LOW);
 
-               dev->dev_addr[5] = lo & 0xff;
-               dev->dev_addr[4] = (lo >> 8) & 0xff;
-               dev->dev_addr[3] = (lo >> 16) & 0xff;
-               dev->dev_addr[2] = (lo >> 24) & 0xff;
-               dev->dev_addr[1] = hi & 0xff;
-               dev->dev_addr[0] = (hi >> 8) & 0xff;
+               /* Some old bootcode may report a 0 MAC address in SRAM */
+               addr_ok = is_valid_ether_addr(&dev->dev_addr[0]);
+       }
+       if (!addr_ok) {
+               /* Next, try NVRAM. */
+               if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) &&
+                   !tg3_nvram_read(tp, mac_offset + 0, &hi) &&
+                   !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
+                       dev->dev_addr[0] = ((hi >> 16) & 0xff);
+                       dev->dev_addr[1] = ((hi >> 24) & 0xff);
+                       dev->dev_addr[2] = ((lo >>  0) & 0xff);
+                       dev->dev_addr[3] = ((lo >>  8) & 0xff);
+                       dev->dev_addr[4] = ((lo >> 16) & 0xff);
+                       dev->dev_addr[5] = ((lo >> 24) & 0xff);
+               }
+               /* Finally just fetch it out of the MAC control regs. */
+               else {
+                       hi = tr32(MAC_ADDR_0_HIGH);
+                       lo = tr32(MAC_ADDR_0_LOW);
+
+                       dev->dev_addr[5] = lo & 0xff;
+                       dev->dev_addr[4] = (lo >> 8) & 0xff;
+                       dev->dev_addr[3] = (lo >> 16) & 0xff;
+                       dev->dev_addr[2] = (lo >> 24) & 0xff;
+                       dev->dev_addr[1] = hi & 0xff;
+                       dev->dev_addr[0] = (hi >> 8) & 0xff;
+               }
        }
 
        if (!is_valid_ether_addr(&dev->dev_addr[0])) {
@@ -10829,7 +11025,6 @@ static void __devinit tg3_init_link_config(struct tg3 *tp)
        tp->link_config.speed = SPEED_INVALID;
        tp->link_config.duplex = DUPLEX_INVALID;
        tp->link_config.autoneg = AUTONEG_ENABLE;
-       netif_carrier_off(tp->dev);
        tp->link_config.active_speed = SPEED_INVALID;
        tp->link_config.active_duplex = DUPLEX_INVALID;
        tp->link_config.phy_is_low_power = 0;
@@ -10888,6 +11083,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
        case PHY_ID_BCM5752:    return "5752";
        case PHY_ID_BCM5714:    return "5714";
        case PHY_ID_BCM5780:    return "5780";
+       case PHY_ID_BCM5755:    return "5755";
        case PHY_ID_BCM5787:    return "5787";
        case PHY_ID_BCM8002:    return "8002/serdes";
        case 0:                 return "serdes";
@@ -11236,7 +11432,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         * checksumming.
         */
        if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                        dev->features |= NETIF_F_HW_CSUM;
                else
                        dev->features |= NETIF_F_IP_CSUM;
@@ -11293,6 +11490,8 @@ 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:
This page took 0.098466 seconds and 5 git commands to generate.