]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/bnx2.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / net / bnx2.c
index 062600be073b91b47a70b0d65edb8824b941c1f8..0ba59d5aeb7f54253171f56dc711b2a3e47f0f89 100644 (file)
 #include "bnx2_fw.h"
 
 #define DRV_MODULE_NAME                "bnx2"
-#define DRV_MODULE_VERSION     "2.0.18"
-#define DRV_MODULE_RELDATE     "Oct 7, 2010"
-#define FW_MIPS_FILE_06                "bnx2/bnx2-mips-06-6.0.15.fw"
+#define DRV_MODULE_VERSION     "2.0.21"
+#define DRV_MODULE_RELDATE     "Dec 23, 2010"
+#define FW_MIPS_FILE_06                "bnx2/bnx2-mips-06-6.2.1.fw"
 #define FW_RV2P_FILE_06                "bnx2/bnx2-rv2p-06-6.0.15.fw"
-#define FW_MIPS_FILE_09                "bnx2/bnx2-mips-09-6.0.17.fw"
+#define FW_MIPS_FILE_09                "bnx2/bnx2-mips-09-6.2.1.fw"
 #define FW_RV2P_FILE_09_Ax     "bnx2/bnx2-rv2p-09ax-6.0.17.fw"
 #define FW_RV2P_FILE_09                "bnx2/bnx2-rv2p-09-6.0.17.fw"
 
@@ -766,13 +766,10 @@ bnx2_alloc_rx_mem(struct bnx2 *bp)
                int j;
 
                rxr->rx_buf_ring =
-                       vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
+                       vzalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
                if (rxr->rx_buf_ring == NULL)
                        return -ENOMEM;
 
-               memset(rxr->rx_buf_ring, 0,
-                      SW_RXBD_RING_SIZE * bp->rx_max_ring);
-
                for (j = 0; j < bp->rx_max_ring; j++) {
                        rxr->rx_desc_ring[j] =
                                dma_alloc_coherent(&bp->pdev->dev,
@@ -785,13 +782,11 @@ bnx2_alloc_rx_mem(struct bnx2 *bp)
                }
 
                if (bp->rx_pg_ring_size) {
-                       rxr->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
+                       rxr->rx_pg_ring = vzalloc(SW_RXPG_RING_SIZE *
                                                  bp->rx_max_pg_ring);
                        if (rxr->rx_pg_ring == NULL)
                                return -ENOMEM;
 
-                       memset(rxr->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
-                              bp->rx_max_pg_ring);
                }
 
                for (j = 0; j < bp->rx_max_pg_ring; j++) {
@@ -4645,13 +4640,28 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 
        /* Wait for the current PCI transaction to complete before
         * issuing a reset. */
-       REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
-              BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
-              BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
-              BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
-              BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
-       val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
-       udelay(5);
+       if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
+           (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+               REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
+                      BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
+                      BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
+                      BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
+                      BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
+               val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
+               udelay(5);
+       } else {  /* 5709 */
+               val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+               val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
+               REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
+               val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+
+               for (i = 0; i < 100; i++) {
+                       msleep(1);
+                       val = REG_RD(bp, BNX2_PCICFG_DEVICE_CONTROL);
+                       if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND))
+                               break;
+               }
+       }
 
        /* Wait for the firmware to tell us it is ok to issue a reset. */
        bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
@@ -4673,7 +4683,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
                val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
                      BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
 
-               pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val);
+               REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
 
        } else {
                val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
@@ -6086,7 +6096,7 @@ bnx2_request_irq(struct bnx2 *bp)
 }
 
 static void
-bnx2_free_irq(struct bnx2 *bp)
+__bnx2_free_irq(struct bnx2 *bp)
 {
        struct bnx2_irq *irq;
        int i;
@@ -6097,6 +6107,13 @@ bnx2_free_irq(struct bnx2 *bp)
                        free_irq(irq->vector, &bp->bnx2_napi[i]);
                irq->requested = 0;
        }
+}
+
+static void
+bnx2_free_irq(struct bnx2 *bp)
+{
+
+       __bnx2_free_irq(bp);
        if (bp->flags & BNX2_FLAG_USING_MSI)
                pci_disable_msi(bp->pdev);
        else if (bp->flags & BNX2_FLAG_USING_MSIX)
@@ -6801,28 +6818,30 @@ bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
        u32 *p = _p, i, offset;
        u8 *orig_p = _p;
        struct bnx2 *bp = netdev_priv(dev);
-       u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c,
-                                0x0800, 0x0880, 0x0c00, 0x0c10,
-                                0x0c30, 0x0d08, 0x1000, 0x101c,
-                                0x1040, 0x1048, 0x1080, 0x10a4,
-                                0x1400, 0x1490, 0x1498, 0x14f0,
-                                0x1500, 0x155c, 0x1580, 0x15dc,
-                                0x1600, 0x1658, 0x1680, 0x16d8,
-                                0x1800, 0x1820, 0x1840, 0x1854,
-                                0x1880, 0x1894, 0x1900, 0x1984,
-                                0x1c00, 0x1c0c, 0x1c40, 0x1c54,
-                                0x1c80, 0x1c94, 0x1d00, 0x1d84,
-                                0x2000, 0x2030, 0x23c0, 0x2400,
-                                0x2800, 0x2820, 0x2830, 0x2850,
-                                0x2b40, 0x2c10, 0x2fc0, 0x3058,
-                                0x3c00, 0x3c94, 0x4000, 0x4010,
-                                0x4080, 0x4090, 0x43c0, 0x4458,
-                                0x4c00, 0x4c18, 0x4c40, 0x4c54,
-                                0x4fc0, 0x5010, 0x53c0, 0x5444,
-                                0x5c00, 0x5c18, 0x5c80, 0x5c90,
-                                0x5fc0, 0x6000, 0x6400, 0x6428,
-                                0x6800, 0x6848, 0x684c, 0x6860,
-                                0x6888, 0x6910, 0x8000 };
+       static const u32 reg_boundaries[] = {
+               0x0000, 0x0098, 0x0400, 0x045c,
+               0x0800, 0x0880, 0x0c00, 0x0c10,
+               0x0c30, 0x0d08, 0x1000, 0x101c,
+               0x1040, 0x1048, 0x1080, 0x10a4,
+               0x1400, 0x1490, 0x1498, 0x14f0,
+               0x1500, 0x155c, 0x1580, 0x15dc,
+               0x1600, 0x1658, 0x1680, 0x16d8,
+               0x1800, 0x1820, 0x1840, 0x1854,
+               0x1880, 0x1894, 0x1900, 0x1984,
+               0x1c00, 0x1c0c, 0x1c40, 0x1c54,
+               0x1c80, 0x1c94, 0x1d00, 0x1d84,
+               0x2000, 0x2030, 0x23c0, 0x2400,
+               0x2800, 0x2820, 0x2830, 0x2850,
+               0x2b40, 0x2c10, 0x2fc0, 0x3058,
+               0x3c00, 0x3c94, 0x4000, 0x4010,
+               0x4080, 0x4090, 0x43c0, 0x4458,
+               0x4c00, 0x4c18, 0x4c40, 0x4c54,
+               0x4fc0, 0x5010, 0x53c0, 0x5444,
+               0x5c00, 0x5c18, 0x5c80, 0x5c90,
+               0x5fc0, 0x6000, 0x6400, 0x6428,
+               0x6800, 0x6848, 0x684c, 0x6860,
+               0x6888, 0x6910, 0x8000
+       };
 
        regs->version = 0;
 
@@ -7080,6 +7099,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
 
                bnx2_netif_stop(bp, true);
                bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
+               __bnx2_free_irq(bp);
                bnx2_free_skbs(bp);
                bnx2_free_mem(bp);
        }
@@ -7091,6 +7111,9 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
                int rc;
 
                rc = bnx2_alloc_mem(bp);
+               if (!rc)
+                       rc = bnx2_request_irq(bp);
+
                if (!rc)
                        rc = bnx2_init_nic(bp, 0);
 
@@ -7530,6 +7553,10 @@ bnx2_set_flags(struct net_device *dev, u32 data)
            !(data & ETH_FLAG_RXVLAN))
                return -EINVAL;
 
+       /* TSO with VLAN tag won't work with current firmware */
+       if (!(data & ETH_FLAG_TXVLAN))
+               return -EINVAL;
+
        rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN |
                                  ETH_FLAG_TXVLAN);
        if (rc)
@@ -7914,15 +7941,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                goto err_out_release;
        }
 
+       bnx2_set_power_state(bp, PCI_D0);
+
        /* Configure byte swap and enable write to the reg_window registers.
         * Rely on CPU to do target byte swapping on big endian systems
         * The chip's target access swapping will not swap all accesses
         */
-       pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
-                              BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
-                              BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
-
-       bnx2_set_power_state(bp, PCI_D0);
+       REG_WR(bp, BNX2_PCICFG_MISC_CONFIG,
+                  BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+                  BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
 
        bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
 
@@ -7939,11 +7966,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 
                /* AER (Advanced Error Reporting) hooks */
                err = pci_enable_pcie_error_reporting(pdev);
-               if (err) {
-                       dev_err(&pdev->dev, "pci_enable_pcie_error_reporting "
-                                           "failed 0x%x\n", err);
-                       /* non-fatal, continue */
-               }
+               if (!err)
+                       bp->flags |= BNX2_FLAG_AER_ENABLED;
 
        } else {
                bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
@@ -8206,8 +8230,10 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        return 0;
 
 err_out_unmap:
-       if (bp->flags & BNX2_FLAG_PCIE)
+       if (bp->flags & BNX2_FLAG_AER_ENABLED) {
                pci_disable_pcie_error_reporting(pdev);
+               bp->flags &= ~BNX2_FLAG_AER_ENABLED;
+       }
 
        if (bp->regview) {
                iounmap(bp->regview);
@@ -8383,8 +8409,6 @@ bnx2_remove_one(struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct bnx2 *bp = netdev_priv(dev);
 
-       flush_scheduled_work();
-
        unregister_netdev(dev);
 
        if (bp->mips_firmware)
@@ -8397,8 +8421,10 @@ bnx2_remove_one(struct pci_dev *pdev)
 
        kfree(bp->temp_stats_blk);
 
-       if (bp->flags & BNX2_FLAG_PCIE)
+       if (bp->flags & BNX2_FLAG_AER_ENABLED) {
                pci_disable_pcie_error_reporting(pdev);
+               bp->flags &= ~BNX2_FLAG_AER_ENABLED;
+       }
 
        free_netdev(dev);
 
@@ -8421,7 +8447,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
        if (!netif_running(dev))
                return 0;
 
-       flush_scheduled_work();
+       cancel_work_sync(&bp->reset_task);
        bnx2_netif_stop(bp, true);
        netif_device_detach(dev);
        del_timer_sync(&bp->timer);
@@ -8514,7 +8540,7 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
        }
        rtnl_unlock();
 
-       if (!(bp->flags & BNX2_FLAG_PCIE))
+       if (!(bp->flags & BNX2_FLAG_AER_ENABLED))
                return result;
 
        err = pci_cleanup_aer_uncorrect_error_status(pdev);