]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/bnx2.c
ibm_newemac: Cleanup/Fix RGMII MDIO support detection
[linux-2.6-omap-h63xx.git] / drivers / net / bnx2.c
index d68accea380bb3adcf40aaeece00d607d006d4bc..da767d3d5af5bb552a6d0dce0792112a3179fc6c 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/dma-mapping.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <linux/delay.h>
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.6.7"
-#define DRV_MODULE_RELDATE     "October 10, 2007"
+#define DRV_MODULE_VERSION     "1.6.8"
+#define DRV_MODULE_RELDATE     "October 17, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -2652,10 +2652,10 @@ static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget)
                REG_RD(bp, BNX2_HC_COMMAND);
        }
 
-       if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
+       if (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
                bnx2_tx_int(bp);
 
-       if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons)
+       if (sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons)
                work_done += bnx2_rx_int(bp, budget - work_done);
 
        return work_done;
@@ -2665,6 +2665,7 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
 {
        struct bnx2 *bp = container_of(napi, struct bnx2, napi);
        int work_done = 0;
+       struct status_block *sblk = bp->status_blk;
 
        while (1) {
                work_done = bnx2_poll_work(bp, work_done, budget);
@@ -2672,16 +2673,19 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
                if (unlikely(work_done >= budget))
                        break;
 
+               /* bp->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.
+                */
+               bp->last_status_idx = sblk->status_idx;
+               rmb();
                if (likely(!bnx2_has_work(bp))) {
-                       bp->last_status_idx = bp->status_blk->status_idx;
-                       rmb();
-
                        netif_rx_complete(bp->dev, napi);
                        if (likely(bp->flags & USING_MSI_FLAG)) {
                                REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                                       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
                                       bp->last_status_idx);
-                               return 0;
+                               break;
                        }
                        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                               BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -3075,14 +3079,18 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
                        autoneg = bp->autoneg;
                        advertising = bp->advertising;
 
-                       bp->autoneg = AUTONEG_SPEED;
-                       bp->advertising = ADVERTISED_10baseT_Half |
-                               ADVERTISED_10baseT_Full |
-                               ADVERTISED_100baseT_Half |
-                               ADVERTISED_100baseT_Full |
-                               ADVERTISED_Autoneg;
+                       if (bp->phy_port == PORT_TP) {
+                               bp->autoneg = AUTONEG_SPEED;
+                               bp->advertising = ADVERTISED_10baseT_Half |
+                                       ADVERTISED_10baseT_Full |
+                                       ADVERTISED_100baseT_Half |
+                                       ADVERTISED_100baseT_Full |
+                                       ADVERTISED_Autoneg;
+                       }
 
-                       bnx2_setup_copper_phy(bp);
+                       spin_lock_bh(&bp->phy_lock);
+                       bnx2_setup_phy(bp, bp->phy_port);
+                       spin_unlock_bh(&bp->phy_lock);
 
                        bp->autoneg = autoneg;
                        bp->advertising = advertising;
@@ -3093,10 +3101,16 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
 
                        /* Enable port mode. */
                        val &= ~BNX2_EMAC_MODE_PORT;
-                       val |= BNX2_EMAC_MODE_PORT_MII |
-                              BNX2_EMAC_MODE_MPKT_RCVD |
+                       val |= BNX2_EMAC_MODE_MPKT_RCVD |
                               BNX2_EMAC_MODE_ACPI_RCVD |
                               BNX2_EMAC_MODE_MPKT;
+                       if (bp->phy_port == PORT_TP)
+                               val |= BNX2_EMAC_MODE_PORT_MII;
+                       else {
+                               val |= BNX2_EMAC_MODE_PORT_GMII;
+                               if (bp->line_speed == SPEED_2500)
+                                       val |= BNX2_EMAC_MODE_25G_MODE;
+                       }
 
                        REG_WR(bp, BNX2_EMAC_MODE, val);
 
@@ -6424,7 +6438,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        /* enable device (incl. PCI PM wakeup), and bus-mastering */
        rc = pci_enable_device(pdev);
        if (rc) {
-               dev_err(&pdev->dev, "Cannot enable PCI device, aborting.");
+               dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
                goto err_out;
        }