ath9k: Fix key cache slot selection for splitmic
[safe/jmp/linux-2.6] / drivers / net / bnx2.c
index 0853b3c..1a27803 100644 (file)
@@ -57,8 +57,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.8.2"
-#define DRV_MODULE_RELDATE     "Nov 10, 2008"
+#define DRV_MODULE_VERSION     "1.9.0"
+#define DRV_MODULE_RELDATE     "Dec 16, 2008"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -131,7 +131,7 @@ static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
        { PCI_VENDOR_ID_BROADCOM, 0x163b,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
        { PCI_VENDOR_ID_BROADCOM, 0x163c,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716S },
        { 0, }
 };
 
@@ -3147,6 +3147,28 @@ bnx2_has_work(struct bnx2_napi *bnapi)
        return 0;
 }
 
+static void
+bnx2_chk_missed_msi(struct bnx2 *bp)
+{
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+       u32 msi_ctrl;
+
+       if (bnx2_has_work(bnapi)) {
+               msi_ctrl = REG_RD(bp, BNX2_PCICFG_MSI_CONTROL);
+               if (!(msi_ctrl & BNX2_PCICFG_MSI_CONTROL_ENABLE))
+                       return;
+
+               if (bnapi->last_status_idx == bp->idle_chk_status_idx) {
+                       REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl &
+                              ~BNX2_PCICFG_MSI_CONTROL_ENABLE);
+                       REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl);
+                       bnx2_msi(bp->irq_tbl[0].vector, bnapi);
+               }
+       }
+
+       bp->idle_chk_status_idx = bnapi->last_status_idx;
+}
+
 static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi)
 {
        struct status_block *sblk = bnapi->status_blk.msi;
@@ -3221,14 +3243,15 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
 
                work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
 
-               if (unlikely(work_done >= budget))
-                       break;
-
                /* bnapi->last_status_idx is used below to tell the hw how
                 * much work has been processed, so we must read it before
                 * checking for more work.
                 */
                bnapi->last_status_idx = sblk->status_idx;
+
+               if (unlikely(work_done >= budget))
+                       break;
+
                rmb();
                if (likely(!bnx2_has_work(bnapi))) {
                        netif_rx_complete(bp->dev, napi);
@@ -4581,6 +4604,8 @@ bnx2_init_chip(struct bnx2 *bp)
        for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
                bp->bnx2_napi[i].last_status_idx = 0;
 
+       bp->idle_chk_status_idx = 0xffff;
+
        bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
 
        /* Set up how to generate a link change interrupt. */
@@ -5729,6 +5754,10 @@ bnx2_timer(unsigned long data)
        if (atomic_read(&bp->intr_sem) != 0)
                goto bnx2_restart_timer;
 
+       if ((bp->flags & (BNX2_FLAG_USING_MSI | BNX2_FLAG_ONE_SHOT_MSI)) ==
+            BNX2_FLAG_USING_MSI)
+               bnx2_chk_missed_msi(bp);
+
        bnx2_send_heart_beat(bp);
 
        bp->stats_blk->stat_FwRxDrop =
@@ -5798,6 +5827,8 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
 {
        int i, rc;
        struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
+       struct net_device *dev = bp->dev;
+       const int len = sizeof(bp->irq_tbl[0].name);
 
        bnx2_setup_msix_tbl(bp);
        REG_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1);
@@ -5808,7 +5839,7 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
                msix_ent[i].entry = i;
                msix_ent[i].vector = 0;
 
-               strcpy(bp->irq_tbl[i].name, bp->dev->name);
+               snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
                bp->irq_tbl[i].handler = bnx2_msi_1shot;
        }
 
@@ -6155,7 +6186,7 @@ bnx2_get_stats(struct net_device *dev)
 {
        struct bnx2 *bp = netdev_priv(dev);
        struct statistics_block *stats_blk = bp->stats_blk;
-       struct net_device_stats *net_stats = &bp->net_stats;
+       struct net_device_stats *net_stats = &dev->stats;
 
        if (bp->stats_blk == NULL) {
                return net_stats;
@@ -7215,10 +7246,13 @@ static void
 poll_bnx2(struct net_device *dev)
 {
        struct bnx2 *bp = netdev_priv(dev);
+       int i;
 
-       disable_irq(bp->pdev->irq);
-       bnx2_interrupt(bp->pdev->irq, dev);
-       enable_irq(bp->pdev->irq);
+       for (i = 0; i < bp->irq_nvecs; i++) {
+               disable_irq(bp->irq_tbl[i].vector);
+               bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]);
+               enable_irq(bp->irq_tbl[i].vector);
+       }
 }
 #endif
 
@@ -7704,6 +7738,25 @@ bnx2_init_napi(struct bnx2 *bp)
        }
 }
 
+static const struct net_device_ops bnx2_netdev_ops = {
+       .ndo_open               = bnx2_open,
+       .ndo_start_xmit         = bnx2_start_xmit,
+       .ndo_stop               = bnx2_close,
+       .ndo_get_stats          = bnx2_get_stats,
+       .ndo_set_rx_mode        = bnx2_set_rx_mode,
+       .ndo_do_ioctl           = bnx2_ioctl,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = bnx2_change_mac_addr,
+       .ndo_change_mtu         = bnx2_change_mtu,
+       .ndo_tx_timeout         = bnx2_tx_timeout,
+#ifdef BCM_VLAN
+       .ndo_vlan_rx_register   = bnx2_vlan_rx_register,
+#endif
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+       .ndo_poll_controller    = poll_bnx2,
+#endif
+};
+
 static int __devinit
 bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -7728,28 +7781,13 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                return rc;
        }
 
-       dev->open = bnx2_open;
-       dev->hard_start_xmit = bnx2_start_xmit;
-       dev->stop = bnx2_close;
-       dev->get_stats = bnx2_get_stats;
-       dev->set_rx_mode = bnx2_set_rx_mode;
-       dev->do_ioctl = bnx2_ioctl;
-       dev->set_mac_address = bnx2_change_mac_addr;
-       dev->change_mtu = bnx2_change_mtu;
-       dev->tx_timeout = bnx2_tx_timeout;
+       dev->netdev_ops = &bnx2_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef BCM_VLAN
-       dev->vlan_rx_register = bnx2_vlan_rx_register;
-#endif
        dev->ethtool_ops = &bnx2_ethtool_ops;
 
        bp = netdev_priv(dev);
        bnx2_init_napi(bp);
 
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
-       dev->poll_controller = poll_bnx2;
-#endif
-
        pci_set_drvdata(pdev, dev);
 
        memcpy(dev->dev_addr, bp->mac_addr, 6);