bnx2x: napi_poll budget check
[safe/jmp/linux-2.6] / drivers / net / bnx2x_main.c
index 2e4d64d..e0851a7 100644 (file)
 #include <linux/zlib.h>
 #include <linux/io.h>
 
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
+
 #include "bnx2x.h"
 #include "bnx2x_init.h"
 
-#define DRV_MODULE_VERSION     "1.45.26"
-#define DRV_MODULE_RELDATE     "2009/01/26"
+#define DRV_MODULE_VERSION     "1.48.102"
+#define DRV_MODULE_RELDATE     "2009/02/12"
 #define BNX2X_BC_VER           0x040200
 
 /* Time in jiffies before concluding the transmitter is hung */
@@ -77,26 +74,26 @@ static int multi_mode = 1;
 module_param(multi_mode, int, 0);
 
 static int disable_tpa;
-static int poll;
-static int debug;
-static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
-
 module_param(disable_tpa, int, 0);
+MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature");
 
 static int int_mode;
 module_param(int_mode, int, 0);
 MODULE_PARM_DESC(int_mode, " Force interrupt mode (1 INT#x; 2 MSI)");
 
+static int poll;
 module_param(poll, int, 0);
+MODULE_PARM_DESC(poll, " Use polling (for debug)");
 
 static int mrrs = -1;
 module_param(mrrs, int, 0);
 MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)");
 
+static int debug;
 module_param(debug, int, 0);
-MODULE_PARM_DESC(disable_tpa, "disable the TPA (LRO) feature");
-MODULE_PARM_DESC(poll, "use polling (for debug)");
-MODULE_PARM_DESC(debug, "default debug msglevel");
+MODULE_PARM_DESC(debug, " Default debug msglevel");
+
+static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
 
 static struct workqueue_struct *bnx2x_wq;
 
@@ -473,7 +470,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
 static void bnx2x_fw_dump(struct bnx2x *bp)
 {
        u32 mark, offset;
-       u32 data[9];
+       __be32 data[9];
        int word;
 
        mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
@@ -507,50 +504,54 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
 
        BNX2X_ERR("begin crash dump -----------------\n");
 
-       for_each_queue(bp, i) {
+       /* Indices */
+       /* Common */
+       BNX2X_ERR("def_c_idx(%u)  def_u_idx(%u)  def_x_idx(%u)"
+                 "  def_t_idx(%u)  def_att_idx(%u)  attn_state(%u)"
+                 "  spq_prod_idx(%u)\n",
+                 bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
+                 bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+
+       /* Rx */
+       for_each_rx_queue(bp, i) {
                struct bnx2x_fastpath *fp = &bp->fp[i];
-               struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
 
-               BNX2X_ERR("queue[%d]: tx_pkt_prod(%x)  tx_pkt_cons(%x)"
-                         "  tx_bd_prod(%x)  tx_bd_cons(%x)  *tx_cons_sb(%x)\n",
-                         i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
-                         fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
-               BNX2X_ERR("          rx_bd_prod(%x)  rx_bd_cons(%x)"
+               BNX2X_ERR("queue[%d]: rx_bd_prod(%x)  rx_bd_cons(%x)"
                          "  *rx_bd_cons_sb(%x)  rx_comp_prod(%x)"
                          "  rx_comp_cons(%x)  *rx_cons_sb(%x)\n",
-                         fp->rx_bd_prod, fp->rx_bd_cons,
+                         i, fp->rx_bd_prod, fp->rx_bd_cons,
                          le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod,
                          fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb));
                BNX2X_ERR("          rx_sge_prod(%x)  last_max_sge(%x)"
-                         "  fp_c_idx(%x)  *sb_c_idx(%x)  fp_u_idx(%x)"
-                         "  *sb_u_idx(%x)  bd data(%x,%x)\n",
-                         fp->rx_sge_prod, fp->last_max_sge, fp->fp_c_idx,
-                         fp->status_blk->c_status_block.status_block_index,
-                         fp->fp_u_idx,
-                         fp->status_blk->u_status_block.status_block_index,
-                         hw_prods->packets_prod, hw_prods->bds_prod);
-
-               start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
-               end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
-               for (j = start; j < end; j++) {
-                       struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+                         "  fp_u_idx(%x) *sb_u_idx(%x)\n",
+                         fp->rx_sge_prod, fp->last_max_sge,
+                         le16_to_cpu(fp->fp_u_idx),
+                         fp->status_blk->u_status_block.status_block_index);
+       }
 
-                       BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
-                                 sw_bd->skb, sw_bd->first_bd);
-               }
+       /* Tx */
+       for_each_tx_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+               struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
 
-               start = TX_BD(fp->tx_bd_cons - 10);
-               end = TX_BD(fp->tx_bd_cons + 254);
-               for (j = start; j < end; j++) {
-                       u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+               BNX2X_ERR("queue[%d]: tx_pkt_prod(%x)  tx_pkt_cons(%x)"
+                         "  tx_bd_prod(%x)  tx_bd_cons(%x)  *tx_cons_sb(%x)\n",
+                         i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
+                         fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
+               BNX2X_ERR("          fp_c_idx(%x)  *sb_c_idx(%x)"
+                         "  bd data(%x,%x)\n", le16_to_cpu(fp->fp_c_idx),
+                         fp->status_blk->c_status_block.status_block_index,
+                         hw_prods->packets_prod, hw_prods->bds_prod);
+       }
 
-                       BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
-                                 j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
-               }
+       /* Rings */
+       /* Rx */
+       for_each_rx_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
 
                start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
                end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
-               for (j = start; j < end; j++) {
+               for (j = start; j != end; j = RX_BD(j + 1)) {
                        u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
                        struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
 
@@ -560,7 +561,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
 
                start = RX_SGE(fp->rx_sge_prod);
                end = RX_SGE(fp->last_max_sge);
-               for (j = start; j < end; j++) {
+               for (j = start; j != end; j = RX_SGE(j + 1)) {
                        u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j];
                        struct sw_rx_page *sw_page = &fp->rx_page_ring[j];
 
@@ -570,7 +571,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
 
                start = RCQ_BD(fp->rx_comp_cons - 10);
                end = RCQ_BD(fp->rx_comp_cons + 503);
-               for (j = start; j < end; j++) {
+               for (j = start; j != end; j = RCQ_BD(j + 1)) {
                        u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
 
                        BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
@@ -578,11 +579,28 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
                }
        }
 
-       BNX2X_ERR("def_c_idx(%u)  def_u_idx(%u)  def_x_idx(%u)"
-                 "  def_t_idx(%u)  def_att_idx(%u)  attn_state(%u)"
-                 "  spq_prod_idx(%u)\n",
-                 bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
-                 bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+       /* Tx */
+       for_each_tx_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+
+               start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
+               end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
+               for (j = start; j != end; j = TX_BD(j + 1)) {
+                       struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+
+                       BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
+                                 sw_bd->skb, sw_bd->first_bd);
+               }
+
+               start = TX_BD(fp->tx_bd_cons - 10);
+               end = TX_BD(fp->tx_bd_cons + 254);
+               for (j = start; j != end; j = TX_BD(j + 1)) {
+                       u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+
+                       BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
+                                 j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
+               }
+       }
 
        bnx2x_fw_dump(bp);
        bnx2x_mc_assert(bp);
@@ -661,6 +679,7 @@ static void bnx2x_int_disable(struct bnx2x *bp)
        REG_WR(bp, addr, val);
        if (REG_RD(bp, addr) != val)
                BNX2X_ERR("BUG! proper val not read from IGU!\n");
+
 }
 
 static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
@@ -762,7 +781,6 @@ static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
        /* Tell compiler that consumer and producer can change */
        barrier();
        return (fp->tx_pkt_prod != fp->tx_pkt_cons);
-
 }
 
 /* free skb in the packet ring at pos idx
@@ -856,7 +874,7 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
        return (s16)(fp->bp->tx_ring_size) - used;
 }
 
-static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
+static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
 {
        struct bnx2x *bp = fp->bp;
        struct netdev_queue *txq;
@@ -890,26 +908,24 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
                bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
                sw_cons++;
                done++;
-
-               if (done == work)
-                       break;
        }
 
        fp->tx_pkt_cons = sw_cons;
        fp->tx_bd_cons = bd_cons;
 
-       /* Need to make the tx_bd_cons update visible to start_xmit()
-        * before checking for netif_tx_queue_stopped().  Without the
-        * memory barrier, there is a small possibility that start_xmit()
-        * will miss it and cause the queue to be stopped forever.
-        */
-       smp_mb();
-
        /* TBD need a thresh? */
        if (unlikely(netif_tx_queue_stopped(txq))) {
 
                __netif_tx_lock(txq, smp_processor_id());
 
+               /* Need to make the tx_bd_cons update visible to start_xmit()
+                * before checking for netif_tx_queue_stopped().  Without the
+                * memory barrier, there is a small possibility that
+                * start_xmit() will miss it and cause the queue to be stopped
+                * forever.
+                */
+               smp_mb();
+
                if ((netif_tx_queue_stopped(txq)) &&
                    (bp->state == BNX2X_STATE_OPEN) &&
                    (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
@@ -929,12 +945,12 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
 
        DP(BNX2X_MSG_SP,
           "fp %d  cid %d  got ramrod #%d  state is %x  type is %d\n",
-          FP_IDX(fp), cid, command, bp->state,
+          fp->index, cid, command, bp->state,
           rr_cqe->ramrod_cqe.ramrod_type);
 
        bp->spq_left++;
 
-       if (FP_IDX(fp)) {
+       if (fp->index) {
                switch (command | fp->state) {
                case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
                                                BNX2X_FP_STATE_OPENING):
@@ -1411,7 +1427,7 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
 
        for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++)
                REG_WR(bp, BAR_USTRORM_INTMEM +
-                      USTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4,
+                      USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4,
                       ((u32 *)&rx_prods)[i]);
 
        mmiowb(); /* keep prod updates ordered */
@@ -1452,7 +1468,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
 
        DP(NETIF_MSG_RX_STATUS,
           "queue[%d]:  hw_comp_cons %u  sw_comp_cons %u\n",
-          FP_IDX(fp), hw_comp_cons, sw_comp_cons);
+          fp->index, hw_comp_cons, sw_comp_cons);
 
        while (sw_comp_cons != hw_comp_cons) {
                struct sw_rx_bd *rx_buf = NULL;
@@ -1648,7 +1664,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
 {
        struct bnx2x_fastpath *fp = fp_cookie;
        struct bnx2x *bp = fp->bp;
-       int index = FP_IDX(fp);
+       int index = fp->index;
 
        /* Return here if interrupt is disabled */
        if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1657,8 +1673,8 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
        }
 
        DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
-          index, FP_SB_ID(fp));
-       bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0);
+          index, fp->sb_id);
+       bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
 
 #ifdef BNX2X_STOP_ON_ERROR
        if (unlikely(bp->panic))
@@ -1686,7 +1702,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
                DP(NETIF_MSG_INTR, "not our interrupt!\n");
                return IRQ_NONE;
        }
-       DP(NETIF_MSG_INTR, "got an interrupt  status %u\n", status);
+       DP(NETIF_MSG_INTR, "got an interrupt  status 0x%x\n", status);
 
        /* Return here if interrupt is disabled */
        if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -2018,13 +2034,16 @@ static void bnx2x_calc_fc_adv(struct bnx2x *bp)
                bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
                                          ADVERTISED_Pause);
                break;
+
        case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
                bp->port.advertising |= (ADVERTISED_Asym_Pause |
                                         ADVERTISED_Pause);
                break;
+
        case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
                bp->port.advertising |= ADVERTISED_Asym_Pause;
                break;
+
        default:
                bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
                                          ADVERTISED_Pause);
@@ -2049,7 +2068,8 @@ static void bnx2x_link_report(struct bnx2x *bp)
                if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
                        if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
                                printk(", receive ");
-                               if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+                               if (bp->link_vars.flow_ctrl &
+                                   BNX2X_FLOW_CTRL_TX)
                                        printk("& transmit ");
                        } else {
                                printk(", transmit ");
@@ -2064,7 +2084,7 @@ static void bnx2x_link_report(struct bnx2x *bp)
        }
 }
 
-static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
+static u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
 {
        if (!BP_NOMCP(bp)) {
                u8 rc;
@@ -2080,18 +2100,24 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
                        bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
 
                bnx2x_acquire_phy_lock(bp);
+
+               if (load_mode == LOAD_DIAG)
+                       bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
+
                rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+
                bnx2x_release_phy_lock(bp);
 
                bnx2x_calc_fc_adv(bp);
 
-               if (bp->link_vars.link_up)
+               if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) {
+                       bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
                        bnx2x_link_report(bp);
-
+               }
 
                return rc;
        }
-       BNX2X_ERR("Bootcode is missing -not initializing link\n");
+       BNX2X_ERR("Bootcode is missing - can not initialize link\n");
        return -EINVAL;
 }
 
@@ -2104,7 +2130,7 @@ static void bnx2x_link_set(struct bnx2x *bp)
 
                bnx2x_calc_fc_adv(bp);
        } else
-               BNX2X_ERR("Bootcode is missing -not setting link\n");
+               BNX2X_ERR("Bootcode is missing - can not set link\n");
 }
 
 static void bnx2x__link_reset(struct bnx2x *bp)
@@ -2114,7 +2140,7 @@ static void bnx2x__link_reset(struct bnx2x *bp)
                bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
                bnx2x_release_phy_lock(bp);
        } else
-               BNX2X_ERR("Bootcode is missing -not resetting link\n");
+               BNX2X_ERR("Bootcode is missing - can not reset link\n");
 }
 
 static u8 bnx2x_link_test(struct bnx2x *bp)
@@ -2635,7 +2661,7 @@ static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
 {
        u32 val;
 
-       if (attn & BNX2X_DOORQ_ASSERT) {
+       if (attn & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) {
 
                val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
                BNX2X_ERR("DB hw attention 0x%x\n", val);
@@ -2994,8 +3020,8 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
 
 #define UPDATE_EXTEND_TSTAT(s, t) \
        do { \
-               diff = le32_to_cpu(tclient->s) - old_tclient->s; \
-               old_tclient->s = le32_to_cpu(tclient->s); \
+               diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \
+               old_tclient->s = tclient->s; \
                ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
        } while (0)
 
@@ -3008,8 +3034,8 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
 
 #define UPDATE_EXTEND_XSTAT(s, t) \
        do { \
-               diff = le32_to_cpu(xclient->s) - old_xclient->s; \
-               old_xclient->s = le32_to_cpu(xclient->s); \
+               diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \
+               old_xclient->s = xclient->s; \
                ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
        } while (0)
 
@@ -3518,7 +3544,10 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
        struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
        struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
        struct bnx2x_eth_stats *estats = &bp->eth_stats;
-       struct regpair diff;
+       struct {
+               u32 lo;
+               u32 hi;
+       } diff;
 
        UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
        UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
@@ -3624,7 +3653,10 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
        struct nig_stats *old = &(bp->port.old_nig_stats);
        struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
        struct bnx2x_eth_stats *estats = &bp->eth_stats;
-       struct regpair diff;
+       struct {
+               u32 lo;
+               u32 hi;
+       } diff;
        u32 nig_timer_max;
 
        if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
@@ -3988,12 +4020,12 @@ static void bnx2x_stats_update(struct bnx2x *bp)
                        "mac_discard %u  mac_filter_discard %u  "
                        "xxovrflow_discard %u  brb_truncate_discard %u  "
                        "ttl0_discard %u\n",
-                      old_tclient->checksum_discard,
+                      le32_to_cpu(old_tclient->checksum_discard),
                       bnx2x_hilo(&qstats->etherstatsoverrsizepkts_hi),
                       bnx2x_hilo(&qstats->no_buff_discard_hi),
                       estats->mac_discard, estats->mac_filter_discard,
                       estats->xxoverflow_discard, estats->brb_truncate_discard,
-                      old_tclient->ttl0_discard);
+                      le32_to_cpu(old_tclient->ttl0_discard));
 
                for_each_queue(bp, i) {
                        printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
@@ -4142,7 +4174,7 @@ static void bnx2x_timer(unsigned long data)
                struct bnx2x_fastpath *fp = &bp->fp[0];
                int rc;
 
-               bnx2x_tx_int(fp, 1000);
+               bnx2x_tx_int(fp);
                rc = bnx2x_rx_int(fp, 1000);
        }
 
@@ -4424,8 +4456,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
                if (fp->tpa_state[i] == BNX2X_TPA_START)
                        pci_unmap_single(bp->pdev,
                                         pci_unmap_addr(rx_buf, mapping),
-                                        bp->rx_buf_size,
-                                        PCI_DMA_FROMDEVICE);
+                                        bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 
                dev_kfree_skb(skb);
                rx_buf->skb = NULL;
@@ -4635,11 +4666,11 @@ static void bnx2x_init_context(struct bnx2x *bp)
                struct eth_context *context = bnx2x_sp(bp, context[i].eth);
                struct bnx2x_fastpath *fp = &bp->fp[i];
                u8 cl_id = fp->cl_id;
-               u8 sb_id = FP_SB_ID(fp);
+               u8 sb_id = fp->sb_id;
 
                context->ustorm_st_context.common.sb_index_numbers =
                                                BNX2X_RX_SB_INDEX_NUM;
-               context->ustorm_st_context.common.clientId = FP_CL_ID(fp);
+               context->ustorm_st_context.common.clientId = cl_id;
                context->ustorm_st_context.common.status_block_id = sb_id;
                context->ustorm_st_context.common.flags =
                        (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT |
@@ -4680,7 +4711,7 @@ static void bnx2x_init_context(struct bnx2x *bp)
                                                U64_HI(fp->tx_prods_mapping);
                context->xstorm_st_context.db_data_addr_lo =
                                                U64_LO(fp->tx_prods_mapping);
-               context->xstorm_st_context.statistics_data = (fp->cl_id |
+               context->xstorm_st_context.statistics_data = (cl_id |
                                XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
                context->cstorm_st_context.sb_index_number =
                                                C_SB_ETH_TX_CQ_INDEX;
@@ -4706,7 +4737,7 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
        for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
                REG_WR8(bp, BAR_TSTRORM_INTMEM +
                        TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
-                       BP_CL_ID(bp) + (i % bp->num_rx_queues));
+                       bp->fp->cl_id + (i % bp->num_rx_queues));
 }
 
 static void bnx2x_set_client_config(struct bnx2x *bp)
@@ -4770,18 +4801,22 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
                tstorm_mac_filter.mcast_drop_all = mask;
                tstorm_mac_filter.bcast_drop_all = mask;
                break;
+
        case BNX2X_RX_MODE_NORMAL:
                tstorm_mac_filter.bcast_accept_all = mask;
                break;
+
        case BNX2X_RX_MODE_ALLMULTI:
                tstorm_mac_filter.mcast_accept_all = mask;
                tstorm_mac_filter.bcast_accept_all = mask;
                break;
+
        case BNX2X_RX_MODE_PROMISC:
                tstorm_mac_filter.ucast_accept_all = mask;
                tstorm_mac_filter.mcast_accept_all = mask;
                tstorm_mac_filter.bcast_accept_all = mask;
                break;
+
        default:
                BNX2X_ERR("BAD rx mode (%d)\n", mode);
                break;
@@ -4992,14 +5027,14 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
                struct bnx2x_fastpath *fp = &bp->fp[i];
 
                REG_WR(bp, BAR_USTRORM_INTMEM +
-                      USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)),
+                      USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id),
                       U64_LO(fp->rx_comp_mapping));
                REG_WR(bp, BAR_USTRORM_INTMEM +
-                      USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4,
+                      USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4,
                       U64_HI(fp->rx_comp_mapping));
 
                REG_WR16(bp, BAR_USTRORM_INTMEM +
-                        USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
+                        USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id),
                         max_agg_size);
        }
 
@@ -5109,13 +5144,17 @@ static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
                fp->cl_id = BP_L_ID(bp) + i;
                fp->sb_id = fp->cl_id;
                DP(NETIF_MSG_IFUP,
-                  "bnx2x_init_sb(%p,%p) index %d  cl_id %d  sb %d\n",
-                  bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp));
+                  "queue[%d]:  bnx2x_init_sb(%p,%p)  cl_id %d  sb %d\n",
+                  i, bp, fp->status_blk, fp->cl_id, fp->sb_id);
                bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping,
-                             FP_SB_ID(fp));
+                             fp->sb_id);
                bnx2x_update_fpsb_idx(fp);
        }
 
+       /* ensure status block indices were read */
+       rmb();
+
+
        bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping,
                          DEF_SB_ID);
        bnx2x_update_dsb_idx(bp);
@@ -5827,6 +5866,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
        /* Port CSDM comes here */
        /* Port USDM comes here */
        /* Port XSDM comes here */
+
        bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
                             port ? TSEM_PORT1_END : TSEM_PORT0_END);
        bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
@@ -5835,6 +5875,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
                             port ? CSEM_PORT1_END : CSEM_PORT0_END);
        bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
                             port ? XSEM_PORT1_END : XSEM_PORT0_END);
+
        /* Port UPB comes here */
        /* Port XPB comes here */
 
@@ -5893,6 +5934,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
        /* Port EMAC1 comes here */
        /* Port DBU comes here */
        /* Port DBG comes here */
+
        bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
                             port ? NIG_PORT1_END : NIG_PORT0_END);
 
@@ -6374,8 +6416,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
 
                        pci_unmap_single(bp->pdev,
                                         pci_unmap_addr(rx_buf, mapping),
-                                        bp->rx_buf_size,
-                                        PCI_DMA_FROMDEVICE);
+                                        bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 
                        rx_buf->skb = NULL;
                        dev_kfree_skb(skb);
@@ -6579,7 +6620,7 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
         */
        config->hdr.length = 2;
        config->hdr.offset = port ? 32 : 0;
-       config->hdr.client_id = BP_CL_ID(bp);
+       config->hdr.client_id = bp->fp->cl_id;
        config->hdr.reserved1 = 0;
 
        /* primary MAC */
@@ -6604,9 +6645,9 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
           config->config_table[0].cam_entry.lsb_mac_addr);
 
        /* broadcast */
-       config->config_table[1].cam_entry.msb_mac_addr = 0xffff;
-       config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
-       config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
+       config->config_table[1].cam_entry.msb_mac_addr = cpu_to_le16(0xffff);
+       config->config_table[1].cam_entry.middle_mac_addr = cpu_to_le16(0xffff);
+       config->config_table[1].cam_entry.lsb_mac_addr = cpu_to_le16(0xffff);
        config->config_table[1].cam_entry.flags = cpu_to_le16(port);
        if (set)
                config->config_table[1].target_table_entry.flags =
@@ -6637,7 +6678,7 @@ static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
         */
        config->hdr.length = 1;
        config->hdr.offset = BP_FUNC(bp);
-       config->hdr.client_id = BP_CL_ID(bp);
+       config->hdr.client_id = bp->fp->cl_id;
        config->hdr.reserved1 = 0;
 
        /* primary MAC */
@@ -6671,7 +6712,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
                             int *state_p, int poll)
 {
        /* can take a while if any port is running */
-       int cnt = 500;
+       int cnt = 5000;
 
        DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
           poll ? "polling" : "waiting", state, idx);
@@ -6689,8 +6730,12 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
                }
 
                mb(); /* state is changed by bnx2x_sp_event() */
-               if (*state_p == state)
+               if (*state_p == state) {
+#ifdef BNX2X_STOP_ON_ERROR
+                       DP(NETIF_MSG_IFUP, "exit  (cnt %d)\n", 5000 - cnt);
+#endif
                        return 0;
+               }
 
                msleep(1);
        }
@@ -6870,11 +6915,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
        } else {
                int port = BP_PORT(bp);
 
-               DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+               DP(NETIF_MSG_IFUP, "NO MCP - load counts      %d, %d, %d\n",
                   load_count[0], load_count[1], load_count[2]);
                load_count[0]++;
                load_count[1 + port]++;
-               DP(NETIF_MSG_IFUP, "NO MCP new load counts       %d, %d, %d\n",
+               DP(NETIF_MSG_IFUP, "NO MCP - new load counts  %d, %d, %d\n",
                   load_count[0], load_count[1], load_count[2]);
                if (load_count[0] == 1)
                        load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
@@ -6921,7 +6966,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 
        if (CHIP_IS_E1H(bp))
                if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
-                       BNX2X_ERR("!!!  mf_cfg function disabled\n");
+                       DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
                        bp->state = BNX2X_STATE_DISABLED;
                }
 
@@ -6938,7 +6983,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
                bnx2x_set_mac_addr_e1h(bp, 1);
 
        if (bp->port.pmf)
-               bnx2x_initial_phy_init(bp);
+               bnx2x_initial_phy_init(bp, load_mode);
 
        /* Start fast path */
        switch (load_mode) {
@@ -6994,8 +7039,6 @@ load_error1:
                netif_napi_del(&bnx2x_fp(bp, i, napi));
        bnx2x_free_mem(bp);
 
-       /* TBD we really need to reset the chip
-          if we want to recover from this */
        return rc;
 }
 
@@ -7025,7 +7068,7 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
 
 static int bnx2x_stop_leading(struct bnx2x *bp)
 {
-       u16 dsb_sp_prod_idx;
+       __le16 dsb_sp_prod_idx;
        /* if the other port is handling traffic,
           this can take a lot of time */
        int cnt = 500;
@@ -7035,7 +7078,7 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
 
        /* Send HALT ramrod */
        bp->fp[0].state = BNX2X_FP_STATE_HALTING;
-       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, BP_CL_ID(bp), 0);
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0);
 
        /* Wait for completion */
        rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
@@ -7059,9 +7102,8 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
                           *bp->dsb_sp_prod, dsb_sp_prod_idx);
 #ifdef BNX2X_STOP_ON_ERROR
                        bnx2x_panic();
-#else
-                       rc = -EBUSY;
 #endif
+                       rc = -EBUSY;
                        break;
                }
                cnt--;
@@ -7170,10 +7212,9 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
                struct bnx2x_fastpath *fp = &bp->fp[i];
 
                cnt = 1000;
-               smp_rmb();
                while (bnx2x_has_tx_work_unload(fp)) {
 
-                       bnx2x_tx_int(fp, 1000);
+                       bnx2x_tx_int(fp);
                        if (!cnt) {
                                BNX2X_ERR("timeout waiting for queue[%d]\n",
                                          i);
@@ -7186,7 +7227,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
                        }
                        cnt--;
                        msleep(1);
-                       smp_rmb();
                }
        }
        /* Give HW time to discard old tx messages */
@@ -7206,7 +7246,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
                        config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
                else
                        config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port);
-               config->hdr.client_id = BP_CL_ID(bp);
+               config->hdr.client_id = bp->fp->cl_id;
                config->hdr.reserved1 = 0;
 
                bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -7270,11 +7310,11 @@ unload_error:
        if (!BP_NOMCP(bp))
                reset_code = bnx2x_fw_command(bp, reset_code);
        else {
-               DP(NETIF_MSG_IFDOWN, "NO MCP load counts      %d, %d, %d\n",
+               DP(NETIF_MSG_IFDOWN, "NO MCP load counts      %d, %d, %d\n",
                   load_count[0], load_count[1], load_count[2]);
                load_count[0]--;
                load_count[1 + port]--;
-               DP(NETIF_MSG_IFDOWN, "NO MCP new load counts  %d, %d, %d\n",
+               DP(NETIF_MSG_IFDOWN, "NO MCP new load counts  %d, %d, %d\n",
                   load_count[0], load_count[1], load_count[2]);
                if (load_count[0] == 0)
                        reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
@@ -7294,6 +7334,7 @@ unload_error:
        /* Report UNLOAD_DONE to MCP */
        if (!BP_NOMCP(bp))
                bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+
        bp->port.pmf = 0;
 
        /* Free SKBs, SGEs, TPA pool and driver internals */
@@ -7582,7 +7623,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
                bp->flags |= NO_WOL_FLAG;
        }
        BNX2X_DEV_INFO("%sWoL capable\n",
-                      (bp->flags & NO_WOL_FLAG) ? "Not " : "");
+                      (bp->flags & NO_WOL_FLAG) ? "not " : "");
 
        val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
        val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
@@ -8024,6 +8065,12 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
                bp->link_params.feature_config_flags &=
                                ~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
 
+       /* If the device is capable of WoL, set the default state according
+        * to the HW
+        */
+       bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
+                  (config & PORT_FEATURE_WOL_ENABLED));
+
        BNX2X_DEV_INFO("lane_config 0x%08x  ext_phy_config 0x%08x"
                       "  speed_cap_mask 0x%08x  link_config 0x%08x\n",
                       bp->link_params.lane_config,
@@ -8072,7 +8119,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
                                       "(0x%04x)\n",
                                       func, bp->e1hov, bp->e1hov);
                } else {
-                       BNX2X_DEV_INFO("Single function mode\n");
+                       BNX2X_DEV_INFO("single function mode\n");
                        if (BP_E1HVN(bp)) {
                                BNX2X_ERR("!!!  No valid E1HOV for func %d,"
                                          "  aborting\n", func);
@@ -8610,7 +8657,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp)
                        MCPR_NVM_ACCESS_ENABLE_WR_EN)));
 }
 
-static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
+static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
                                  u32 cmd_flags)
 {
        int count, i, rc;
@@ -8646,8 +8693,7 @@ static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
                        /* we read nvram data in cpu order
                         * but ethtool sees it as an array of bytes
                         * converting to big-endian will do the work */
-                       val = cpu_to_be32(val);
-                       *ret_val = val;
+                       *ret_val = cpu_to_be32(val);
                        rc = 0;
                        break;
                }
@@ -8661,7 +8707,7 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
 {
        int rc;
        u32 cmd_flags;
-       u32 val;
+       __be32 val;
 
        if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
                DP(BNX2X_MSG_NVM,
@@ -8780,7 +8826,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
        int rc;
        u32 cmd_flags;
        u32 align_offset;
-       u32 val;
+       __be32 val;
 
        if (offset + buf_size > bp->common.flash_size) {
                DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
@@ -8999,7 +9045,8 @@ static void bnx2x_get_pauseparam(struct net_device *dev,
 {
        struct bnx2x *bp = netdev_priv(dev);
 
-       epause->autoneg = (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
+       epause->autoneg = (bp->link_params.req_flow_ctrl ==
+                          BNX2X_FLOW_CTRL_AUTO) &&
                          (bp->link_params.req_line_speed == SPEED_AUTO_NEG);
 
        epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
@@ -9319,23 +9366,23 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
        u16 len;
        int rc = -ENODEV;
 
-       if (loopback_mode == BNX2X_MAC_LOOPBACK) {
+       /* check the loopback mode */
+       switch (loopback_mode) {
+       case BNX2X_PHY_LOOPBACK:
+               if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10)
+                       return -EINVAL;
+               break;
+       case BNX2X_MAC_LOOPBACK:
                bp->link_params.loopback_mode = LOOPBACK_BMAC;
                bnx2x_phy_init(&bp->link_params, &bp->link_vars);
-
-       } else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
-               u16 cnt = 1000;
-               bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
-               bnx2x_phy_init(&bp->link_params, &bp->link_vars);
-               /* wait until link state is restored */
-               if (link_up)
-                       while (cnt-- && bnx2x_test_link(&bp->link_params,
-                                                       &bp->link_vars))
-                               msleep(10);
-       } else
+               break;
+       default:
                return -EINVAL;
+       }
 
-       pkt_size = 1514;
+       /* prepare the loopback packet */
+       pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
+                    bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
        skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
        if (!skb) {
                rc = -ENOMEM;
@@ -9347,6 +9394,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
        for (i = ETH_HLEN; i < pkt_size; i++)
                packet[i] = (unsigned char) (i & 0xff);
 
+       /* send the loopback packet */
        num_pkts = 0;
        tx_start_idx = le16_to_cpu(*fp->tx_cons_sb);
        rx_start_idx = le16_to_cpu(*fp->rx_cons_sb);
@@ -9371,12 +9419,10 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
 
        wmb();
 
-       fp->hw_tx_prods->bds_prod =
-               cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1);
+       le16_add_cpu(&fp->hw_tx_prods->bds_prod, 1);
        mb(); /* FW restriction: must not reorder writing nbd and packets */
-       fp->hw_tx_prods->packets_prod =
-               cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
-       DOORBELL(bp, FP_IDX(fp), 0);
+       le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+       DOORBELL(bp, fp->index, 0);
 
        mmiowb();
 
@@ -9431,7 +9477,7 @@ test_loopback_exit:
 
 static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
 {
-       int rc = 0;
+       int rc = 0, res;
 
        if (!netif_running(bp->dev))
                return BNX2X_LOOPBACK_FAILED;
@@ -9439,14 +9485,16 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
        bnx2x_netif_stop(bp, 1);
        bnx2x_acquire_phy_lock(bp);
 
-       if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
-               DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
-               rc |= BNX2X_MAC_LOOPBACK_FAILED;
+       res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up);
+       if (res) {
+               DP(NETIF_MSG_PROBE, "  PHY loopback failed  (res %d)\n", res);
+               rc |= BNX2X_PHY_LOOPBACK_FAILED;
        }
 
-       if (bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up)) {
-               DP(NETIF_MSG_PROBE, "PHY loopback failed\n");
-               rc |= BNX2X_PHY_LOOPBACK_FAILED;
+       res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up);
+       if (res) {
+               DP(NETIF_MSG_PROBE, "  MAC loopback failed  (res %d)\n", res);
+               rc |= BNX2X_MAC_LOOPBACK_FAILED;
        }
 
        bnx2x_release_phy_lock(bp);
@@ -9473,14 +9521,14 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
                { 0x778,  0x70 },
                {     0,     0 }
        };
-       u32 buf[0x350 / 4];
+       __be32 buf[0x350 / 4];
        u8 *data = (u8 *)buf;
        int i, rc;
        u32 magic, csum;
 
        rc = bnx2x_nvram_read(bp, 0, data, 4);
        if (rc) {
-               DP(NETIF_MSG_PROBE, "magic value read (rc -%d)\n", -rc);
+               DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc);
                goto test_nvram_exit;
        }
 
@@ -9497,7 +9545,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
                                      nvram_tbl[i].size);
                if (rc) {
                        DP(NETIF_MSG_PROBE,
-                          "nvram_tbl[%d] read data (rc -%d)\n", i, -rc);
+                          "nvram_tbl[%d] read data (rc %d)\n", i, rc);
                        goto test_nvram_exit;
                }
 
@@ -9527,7 +9575,7 @@ static int bnx2x_test_intr(struct bnx2x *bp)
                config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
        else
                config->hdr.offset = BP_FUNC(bp);
-       config->hdr.client_id = BP_CL_ID(bp);
+       config->hdr.client_id = bp->fp->cl_id;
        config->hdr.reserved1 = 0;
 
        rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -10018,25 +10066,41 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
        bnx2x_update_fpsb_idx(fp);
 
        if (bnx2x_has_tx_work(fp))
-               bnx2x_tx_int(fp, budget);
+               bnx2x_tx_int(fp);
 
-       if (bnx2x_has_rx_work(fp))
+       if (bnx2x_has_rx_work(fp)) {
                work_done = bnx2x_rx_int(fp, budget);
-       rmb(); /* BNX2X_HAS_WORK() reads the status block */
 
-       /* must not complete if we consumed full budget */
-       if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
+               /* must not complete if we consumed full budget */
+               if (work_done >= budget)
+                       goto poll_again;
+       }
+
+       /* BNX2X_HAS_WORK() reads the status block, thus we need to
+        * ensure that status block indices have been actually read
+        * (bnx2x_update_fpsb_idx) prior to this check (BNX2X_HAS_WORK)
+        * so that we won't write the "newer" value of the status block to IGU
+        * (if there was a DMA right after BNX2X_HAS_WORK and
+        * if there is no rmb, the memory reading (bnx2x_update_fpsb_idx)
+        * may be postponed to right before bnx2x_ack_sb). In this case
+        * there will never be another interrupt until there is another update
+        * of the status block, while there is still unhandled work.
+        */
+       rmb();
 
+       if (!BNX2X_HAS_WORK(fp)) {
 #ifdef BNX2X_STOP_ON_ERROR
 poll_panic:
 #endif
                napi_complete(napi);
 
-               bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID,
+               bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
                             le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
-               bnx2x_ack_sb(bp, FP_SB_ID(fp), CSTORM_ID,
+               bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
                             le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
        }
+
+poll_again:
        return work_done;
 }
 
@@ -10112,7 +10176,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
                rc = XMIT_PLAIN;
 
        else {
-               if (skb->protocol == ntohs(ETH_P_IPV6)) {
+               if (skb->protocol == htons(ETH_P_IPV6)) {
                        rc = XMIT_CSUM_V6;
                        if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
                                rc |= XMIT_CSUM_TCP;
@@ -10134,7 +10198,9 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
 }
 
 #if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
-/* check if packet requires linearization (packet is too fragmented) */
+/* check if packet requires linearization (packet is too fragmented)
+   no need to check fragmentation if page size > 8K (there will be no
+   violation to FW restrictions) */
 static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
                             u32 xmit_type)
 {
@@ -10193,7 +10259,6 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
                                wnd_sum -=
                                        skb_shinfo(skb)->frags[wnd_idx].size;
                        }
-
                } else {
                        /* in non-LSO too fragmented packet should always
                           be linearized */
@@ -10256,8 +10321,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
           ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
 
 #if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
-       /* First, check if we need to linearize the skb
-          (due to FW restrictions) */
+       /* First, check if we need to linearize the skb (due to FW
+          restrictions). No need to check fragmentation if page size > 8K
+          (there will be no violation to FW restrictions) */
        if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
                /* Statistics of linearization */
                bp->lin_cnt++;
@@ -10322,9 +10388,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                hlen = (skb_network_header(skb) - skb->data + vlan_off) / 2;
 
                /* for now NS flag is not used in Linux */
-               pbd->global_data = (hlen |
-                                   ((skb->protocol == ntohs(ETH_P_8021Q)) <<
-                                    ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
+               pbd->global_data =
+                       (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
+                                ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
 
                pbd->ip_hlen = (skb_transport_header(skb) -
                                skb_network_header(skb)) / 2;
@@ -10468,12 +10534,10 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        wmb();
 
-       fp->hw_tx_prods->bds_prod =
-               cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
+       le16_add_cpu(&fp->hw_tx_prods->bds_prod, nbd);
        mb(); /* FW restriction: must not reorder writing nbd and packets */
-       fp->hw_tx_prods->packets_prod =
-               cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
-       DOORBELL(bp, FP_IDX(fp), 0);
+       le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+       DOORBELL(bp, fp->index, 0);
 
        mmiowb();
 
@@ -10520,7 +10584,7 @@ static int bnx2x_close(struct net_device *dev)
        return 0;
 }
 
-/* called with netif_tx_lock from set_multicast */
+/* called with netif_tx_lock from dev_mcast.c */
 static void bnx2x_set_rx_mode(struct net_device *dev)
 {
        struct bnx2x *bp = netdev_priv(dev);
@@ -10786,7 +10850,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
        .ndo_open               = bnx2x_open,
        .ndo_stop               = bnx2x_close,
        .ndo_start_xmit         = bnx2x_start_xmit,
-       .ndo_set_multicast_list = bnx2x_set_rx_mode,
+       .ndo_set_multicast_list = bnx2x_set_rx_mode,
        .ndo_set_mac_address    = bnx2x_change_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = bnx2x_ioctl,
@@ -10800,7 +10864,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
 #endif
 };
 
-
 static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
                                    struct net_device *dev)
 {
@@ -11279,8 +11342,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
 
 static struct pci_error_handlers bnx2x_err_handler = {
        .error_detected = bnx2x_io_error_detected,
-       .slot_reset = bnx2x_io_slot_reset,
-       .resume = bnx2x_io_resume,
+       .slot_reset     = bnx2x_io_slot_reset,
+       .resume         = bnx2x_io_resume,
 };
 
 static struct pci_driver bnx2x_pci_driver = {