aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2008-06-23 20:33:01 -0700
committerDavid S. Miller <davem@davemloft.net>2008-06-23 20:33:01 -0700
commit34f80b04f325078ff21123579343d99756ad8d0e (patch)
treeb24ef6256970da8cfad6124dc698a9e351d46eb1 /drivers/net/bnx2x_main.c
parente523287e8edad79b4e5753f98dcf8f75cabd3963 (diff)
bnx2x: Add support for BCM57711 HW
Supporting the 57711 and 57711E - refers to in the code as E1H. The 57710 is referred to as E1. To support the new members in the family, the bnx2x structure was divided to 3 parts: common, port and function. These changes caused some rearrangement in the bnx2x.h file. A set of accessories macros were added to make access to the bnx2x structure more readable Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x_main.c3875
1 files changed, 2423 insertions, 1452 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index efa942688f8..90b54e4c5c3 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1,4 +1,4 @@
-/* bnx2x.c: Broadcom Everest network driver.
+/* bnx2x_main.c: Broadcom Everest network driver.
*
* Copyright (c) 2007-2008 Broadcom Corporation
*
@@ -15,12 +15,6 @@
*
*/
-/* define this to make the driver freeze on error
- * to allow getting debug info
- * (you will need to reboot afterwards)
- */
-/*#define BNX2X_STOP_ON_ERROR*/
-
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -46,16 +40,17 @@
#include <linux/mii.h>
#ifdef NETIF_F_HW_VLAN_TX
#include <linux/if_vlan.h>
- #define BCM_VLAN 1
#endif
#include <net/ip.h>
#include <net/tcp.h>
#include <net/checksum.h>
+#include <linux/version.h>
+#include <net/ip6_checksum.h>
#include <linux/workqueue.h>
#include <linux/crc32.h>
+#include <linux/crc32c.h>
#include <linux/prefetch.h>
#include <linux/zlib.h>
-#include <linux/version.h>
#include <linux/io.h>
#include "bnx2x_reg.h"
@@ -67,13 +62,13 @@
#define DRV_MODULE_VERSION "1.42.4"
#define DRV_MODULE_RELDATE "2008/4/9"
-#define BNX2X_BC_VER 0x040200
+#define BNX2X_BC_VER 0x040200
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT (5*HZ)
+/* Time in jiffies before concluding the transmitter is hung */
+#define TX_TIMEOUT (5*HZ)
static char version[] __devinitdata =
- "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver "
+ "Broadcom NetXtreme II 5771x 10Gigabit Ethernet Driver "
DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Eliezer Tamir");
@@ -83,20 +78,19 @@ MODULE_VERSION(DRV_MODULE_VERSION);
static int use_inta;
static int poll;
-static int onefunc;
-static int nomcp;
static int debug;
+static int nomcp;
+static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
static int use_multi;
module_param(use_inta, int, 0);
module_param(poll, int, 0);
-module_param(onefunc, int, 0);
module_param(debug, int, 0);
+module_param(nomcp, int, 0);
MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
MODULE_PARM_DESC(poll, "use polling (for debug)");
-MODULE_PARM_DESC(onefunc, "enable only first function");
-MODULE_PARM_DESC(nomcp, "ignore management CPU (Implies onefunc)");
MODULE_PARM_DESC(debug, "default debug msglevel");
+MODULE_PARM_DESC(nomcp, "ignore management CPU");
#ifdef BNX2X_MULTI
module_param(use_multi, int, 0);
@@ -105,18 +99,27 @@ MODULE_PARM_DESC(use_multi, "use per-CPU queues");
enum bnx2x_board_type {
BCM57710 = 0,
+ BCM57711 = 1,
+ BCM57711E = 2,
};
-/* indexed by board_t, above */
+/* indexed by board_type, above */
static struct {
char *name;
} board_info[] __devinitdata = {
- { "Broadcom NetXtreme II BCM57710 XGb" }
+ { "Broadcom NetXtreme II BCM57710 XGb" },
+ { "Broadcom NetXtreme II BCM57711 XGb" },
+ { "Broadcom NetXtreme II BCM57711E XGb" }
};
+
static const struct pci_device_id bnx2x_pci_tbl[] = {
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711 },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711E },
{ 0 }
};
@@ -201,7 +204,8 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
#else
DMAE_CMD_ENDIANITY_DW_SWAP |
#endif
- (bp->port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
dmae->src_addr_lo = U64_LO(dma_addr);
dmae->src_addr_hi = U64_HI(dma_addr);
dmae->dst_addr_lo = dst_addr >> 2;
@@ -224,7 +228,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
*wb_comp = 0;
- bnx2x_post_dmae(bp, dmae, (bp->port)*MAX_DMAE_C_PER_PORT);
+ bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
udelay(5);
@@ -277,7 +281,8 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
#else
DMAE_CMD_ENDIANITY_DW_SWAP |
#endif
- (bp->port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
dmae->src_addr_lo = src_addr >> 2;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
@@ -297,7 +302,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
*wb_comp = 0;
- bnx2x_post_dmae(bp, dmae, (bp->port)*MAX_DMAE_C_PER_PORT);
+ bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
udelay(5);
@@ -345,47 +350,122 @@ static u64 bnx2x_wb_rd(struct bnx2x *bp, int reg)
static int bnx2x_mc_assert(struct bnx2x *bp)
{
- int i, j, rc = 0;
char last_idx;
- const char storm[] = {"XTCU"};
- const u32 intmem_base[] = {
- BAR_XSTRORM_INTMEM,
- BAR_TSTRORM_INTMEM,
- BAR_CSTRORM_INTMEM,
- BAR_USTRORM_INTMEM
- };
-
- /* Go through all instances of all SEMIs */
- for (i = 0; i < 4; i++) {
- last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET +
- intmem_base[i]);
- if (last_idx)
- BNX2X_LOG("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
- storm[i], last_idx);
-
- /* print the asserts */
- for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) {
- u32 row0, row1, row2, row3;
-
- row0 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) +
- intmem_base[i]);
- row1 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 4 +
- intmem_base[i]);
- row2 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 8 +
- intmem_base[i]);
- row3 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 12 +
- intmem_base[i]);
-
- if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_LOG("DATA %cSTORM_ASSERT_INDEX 0x%x ="
- " 0x%08x 0x%08x 0x%08x 0x%08x\n",
- storm[i], j, row3, row2, row1, row0);
- rc++;
- } else {
- break;
- }
+ int i, rc = 0;
+ u32 row0, row1, row2, row3;
+
+ /* XSTORM */
+ last_idx = REG_RD8(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("XSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("XSTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
+ }
+ }
+
+ /* TSTORM */
+ last_idx = REG_RD8(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("TSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("TSTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
+ }
+ }
+
+ /* CSTORM */
+ last_idx = REG_RD8(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("CSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("CSTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
}
}
+
+ /* USTORM */
+ last_idx = REG_RD8(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("USTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("USTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
+ }
+ }
+
return rc;
}
@@ -428,14 +508,16 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
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)"
- " *rx_cons_sb(%x) rx_comp_prod(%x)"
- " rx_comp_cons(%x) fp_c_idx(%x) fp_u_idx(%x)"
- " bd data(%x,%x)\n",
+ " 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, *fp->tx_cons_sb, *fp->rx_cons_sb,
- fp->rx_comp_prod, fp->rx_comp_cons, fp->fp_c_idx,
- fp->fp_u_idx, hw_prods->packets_prod,
+ fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
+ BNX2X_ERR(" rx_comp_prod(%x) rx_comp_cons(%x)"
+ " *rx_cons_sb(%x)\n",
+ fp->rx_comp_prod, fp->rx_comp_cons,
+ le16_to_cpu(*fp->rx_cons_sb));
+ BNX2X_ERR(" fp_c_idx(%x) fp_u_idx(%x)"
+ " bd data(%x,%x)\n",
+ fp->fp_c_idx, fp->fp_u_idx, hw_prods->packets_prod,
hw_prods->bds_prod);
start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
@@ -463,7 +545,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
BNX2X_ERR("rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
- j, rx_bd[0], rx_bd[1], sw_bd->skb);
+ j, rx_bd[1], rx_bd[0], sw_bd->skb);
}
start = RCQ_BD(fp->rx_comp_cons - 10);
@@ -482,7 +564,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
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);
-
+ bnx2x_fw_dump(bp);
bnx2x_mc_assert(bp);
BNX2X_ERR("end crash dump -----------------\n");
@@ -492,7 +574,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
static void bnx2x_int_enable(struct bnx2x *bp)
{
- int port = bp->port;
+ int port = BP_PORT(bp);
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
u32 val = REG_RD(bp, addr);
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
@@ -507,7 +589,6 @@ static void bnx2x_int_enable(struct bnx2x *bp)
HC_CONFIG_0_REG_INT_LINE_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
- /* Errata A0.158 workaround */
DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
val, port, addr, msix);
@@ -520,11 +601,25 @@ static void bnx2x_int_enable(struct bnx2x *bp)
val, port, addr, msix);
REG_WR(bp, addr, val);
+
+ if (CHIP_IS_E1H(bp)) {
+ /* init leading/trailing edge */
+ if (IS_E1HMF(bp)) {
+ val = (0xfe0f | (1 << (BP_E1HVN(bp) + 4)));
+ if (bp->port.pmf)
+ /* enable nig attention */
+ val |= 0x0100;
+ } else
+ val = 0xffff;
+
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
+ }
}
static void bnx2x_int_disable(struct bnx2x *bp)
{
- int port = bp->port;
+ int port = BP_PORT(bp);
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
u32 val = REG_RD(bp, addr);
@@ -543,10 +638,10 @@ static void bnx2x_int_disable(struct bnx2x *bp)
static void bnx2x_int_disable_sync(struct bnx2x *bp)
{
-
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
int i;
+ /* disable interrupt handling */
atomic_inc(&bp->intr_sem);
/* prevent the HW from sending interrupts */
bnx2x_int_disable(bp);
@@ -563,30 +658,29 @@ static void bnx2x_int_disable_sync(struct bnx2x *bp)
/* make sure sp_task is not running */
cancel_work_sync(&bp->sp_task);
-
}
-/* fast path code */
+/* fast path */
/*
- * general service functions
+ * General service functions
*/
-static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 id,
+static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
u8 storm, u16 index, u8 op, u8 update)
{
- u32 igu_addr = (IGU_ADDR_INT_ACK + IGU_PORT_BASE * bp->port) * 8;
+ u32 igu_addr = (IGU_ADDR_INT_ACK + IGU_FUNC_BASE * BP_FUNC(bp)) * 8;
struct igu_ack_register igu_ack;
igu_ack.status_block_index = index;
igu_ack.sb_id_and_flags =
- ((id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
+ ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
(storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) |
(update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
(op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
-/* DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n",
- (*(u32 *)&igu_ack), BAR_IGU_INTMEM + igu_addr); */
+ DP(BNX2X_MSG_OFF, "write 0x%08x to IGU addr 0x%x\n",
+ (*(u32 *)&igu_ack), BAR_IGU_INTMEM + igu_addr);
REG_WR(bp, BAR_IGU_INTMEM + igu_addr, (*(u32 *)&igu_ack));
}
@@ -614,8 +708,9 @@ static inline int bnx2x_has_work(struct bnx2x_fastpath *fp)
if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
rx_cons_sb++;
- if ((rx_cons_sb != fp->rx_comp_cons) ||
- (le16_to_cpu(*fp->tx_cons_sb) != fp->tx_pkt_cons))
+ if ((fp->rx_comp_cons != rx_cons_sb) ||
+ (fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) ||
+ (fp->tx_pkt_prod != fp->tx_pkt_cons))
return 1;
return 0;
@@ -623,11 +718,11 @@ static inline int bnx2x_has_work(struct bnx2x_fastpath *fp)
static u16 bnx2x_ack_int(struct bnx2x *bp)
{
- u32 igu_addr = (IGU_ADDR_SIMD_MASK + IGU_PORT_BASE * bp->port) * 8;
+ u32 igu_addr = (IGU_ADDR_SIMD_MASK + IGU_FUNC_BASE * BP_FUNC(bp)) * 8;
u32 result = REG_RD(bp, BAR_IGU_INTMEM + igu_addr);
-/* DP(NETIF_MSG_INTR, "read 0x%08x from IGU addr 0x%x\n",
- result, BAR_IGU_INTMEM + igu_addr); */
+ DP(BNX2X_MSG_OFF, "read 0x%08x from IGU addr 0x%x\n",
+ result, BAR_IGU_INTMEM + igu_addr);
#ifdef IGU_DEBUG
#warning IGU_DEBUG active
@@ -653,7 +748,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx];
struct eth_tx_bd *tx_bd;
struct sk_buff *skb = tx_buf->skb;
- u16 bd_idx = tx_buf->first_bd;
+ u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
int nbd;
DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n",
@@ -666,9 +761,10 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
nbd = le16_to_cpu(tx_bd->nbd) - 1;
+ new_cons = nbd + tx_buf->first_bd;
#ifdef BNX2X_STOP_ON_ERROR
if (nbd > (MAX_SKB_FRAGS + 2)) {
- BNX2X_ERR("bad nbd!\n");
+ BNX2X_ERR("BAD nbd!\n");
bnx2x_panic();
}
#endif
@@ -708,32 +804,30 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
tx_buf->first_bd = 0;
tx_buf->skb = NULL;
- return bd_idx;
+ return new_cons;
}
-static inline u32 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
+static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
{
- u16 used;
- u32 prod;
- u32 cons;
+ s16 used;
+ u16 prod;
+ u16 cons;
- /* Tell compiler that prod and cons can change */
- barrier();
+ barrier(); /* Tell compiler that prod and cons can change */
prod = fp->tx_bd_prod;
cons = fp->tx_bd_cons;
- used = (NUM_TX_BD - NUM_TX_RINGS + prod - cons +
- (cons / TX_DESC_CNT) - (prod / TX_DESC_CNT));
-
- if (prod >= cons) {
- /* used = prod - cons - prod/size + cons/size */
- used -= NUM_TX_BD - NUM_TX_RINGS;
- }
+ /* NUM_TX_RINGS = number of "next-page" entries
+ It will be used as a threshold */
+ used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS;
+#ifdef BNX2X_STOP_ON_ERROR
+ BUG_TRAP(used >= 0);
BUG_TRAP(used <= fp->bp->tx_ring_size);
BUG_TRAP((fp->bp->tx_ring_size - used) <= MAX_TX_AVAIL);
+#endif
- return (fp->bp->tx_ring_size - used);
+ return (s16)(fp->bp->tx_ring_size) - used;
}
static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
@@ -757,10 +851,10 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
/* prefetch(bp->tx_buf_ring[pkt_cons].skb); */
- DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %d\n",
+ DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n",
hw_cons, sw_cons, pkt_cons);
-/* if (NEXT_TX_IDX(sw_cons) != hw_cons) {
+/* if (NEXT_TX_IDX(sw_cons) != hw_cons) {
rmb();
prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb);
}
@@ -793,7 +887,6 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
netif_wake_queue(bp->dev);
netif_tx_unlock(bp->dev);
-
}
}
@@ -804,13 +897,14 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data);
int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data);
- DP(NETIF_MSG_RX_STATUS,
+ DP(BNX2X_MSG_SP,
"fp %d cid %d got ramrod #%d state is %x type is %d\n",
- fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.type);
+ FP_IDX(fp), cid, command, bp->state,
+ rr_cqe->ramrod_cqe.ramrod_type);
bp->spq_left++;
- if (fp->index) {
+ if (FP_IDX(fp)) {
switch (command | fp->state) {
case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
BNX2X_FP_STATE_OPENING):
@@ -826,10 +920,11 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
break;
default:
- BNX2X_ERR("unexpected MC reply(%d) state is %x\n",
- command, fp->state);
+ BNX2X_ERR("unexpected MC reply (%d) "
+ "fp->state is %x\n", command, fp->state);
+ break;
}
- mb(); /* force bnx2x_wait_ramrod to see the change */
+ mb(); /* force bnx2x_wait_ramrod() to see the change */
return;
}
@@ -846,25 +941,25 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
break;
case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n",
- cid);
+ DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
+ case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n");
+ DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
break;
default:
- BNX2X_ERR("unexpected ramrod (%d) state is %x\n",
+ BNX2X_ERR("unexpected MC reply (%d) bp->state is %x\n",
command, bp->state);
+ break;
}
-
- mb(); /* force bnx2x_wait_ramrod to see the change */
+ mb(); /* force bnx2x_wait_ramrod() to see the change */
}
static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
@@ -882,7 +977,6 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
PCI_DMA_FROMDEVICE);
if (unlikely(dma_mapping_error(mapping))) {
-
dev_kfree_skb(skb);
return -ENOMEM;
}
@@ -924,7 +1018,7 @@ static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
{
struct bnx2x *bp = fp->bp;
- u16 bd_cons, bd_prod, comp_ring_cons;
+ u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons;
u16 hw_comp_cons, sw_comp_cons, sw_comp_prod;
int rx_pkt = 0;
@@ -933,12 +1027,15 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
return 0;
#endif
+ /* CQ "next element" is of the size of the regular element,
+ that's why it's ok here */
hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb);
if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
hw_comp_cons++;
bd_cons = fp->rx_bd_cons;
bd_prod = fp->rx_bd_prod;
+ bd_prod_fw = bd_prod;
sw_comp_cons = fp->rx_comp_cons;
sw_comp_prod = fp->rx_comp_prod;
@@ -949,34 +1046,31 @@ 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->index, hw_comp_cons, sw_comp_cons);
+ FP_IDX(fp), hw_comp_cons, sw_comp_cons);
while (sw_comp_cons != hw_comp_cons) {
- unsigned int len, pad;
- struct sw_rx_bd *rx_buf;
+ struct sw_rx_bd *rx_buf = NULL;
struct sk_buff *skb;
union eth_rx_cqe *cqe;
+ u8 cqe_fp_flags;
+ u16 len, pad;
comp_ring_cons = RCQ_BD(sw_comp_cons);
bd_prod = RX_BD(bd_prod);
bd_cons = RX_BD(bd_cons);
cqe = &fp->rx_comp_ring[comp_ring_cons];
+ cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
- DP(NETIF_MSG_RX_STATUS, "hw_comp_cons %u sw_comp_cons %u"
- " comp_ring (%u) bd_ring (%u,%u)\n",
- hw_comp_cons, sw_comp_cons,
- comp_ring_cons, bd_prod, bd_cons);
DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x"
- " queue %x vlan %x len %x\n",
- cqe->fast_path_cqe.type,
- cqe->fast_path_cqe.error_type_flags,
- cqe->fast_path_cqe.status_flags,
+ " queue %x vlan %x len %u\n", CQE_TYPE(cqe_fp_flags),
+ cqe_fp_flags, cqe->fast_path_cqe.status_flags,
cqe->fast_path_cqe.rss_hash_result,
- cqe->fast_path_cqe.vlan_tag, cqe->fast_path_cqe.pkt_len);
+ le16_to_cpu(cqe->fast_path_cqe.vlan_tag),
+ le16_to_cpu(cqe->fast_path_cqe.pkt_len));
/* is this a slowpath msg? */
- if (unlikely(cqe->fast_path_cqe.type)) {
+ if (unlikely(CQE_TYPE(cqe_fp_flags))) {
bnx2x_sp_event(fp, cqe);
goto next_cqe;
@@ -984,7 +1078,6 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
} else {
rx_buf = &fp->rx_buf_ring[bd_cons];
skb = rx_buf->skb;
-
len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
pad = cqe->fast_path_cqe.placement_offset;
@@ -996,13 +1089,11 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
prefetch(((char *)(skb)) + 128);
/* is this an error packet? */
- if (unlikely(cqe->fast_path_cqe.error_type_flags &
- ETH_RX_ERROR_FALGS)) {
+ if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
/* do we sometimes forward error packets anyway? */
DP(NETIF_MSG_RX_ERR,
- "ERROR flags(%u) Rx packet(%u)\n",
- cqe->fast_path_cqe.error_type_flags,
- sw_comp_cons);
+ "ERROR flags %x rx packet %u\n",
+ cqe_fp_flags, sw_comp_cons);
/* TBD make sure MC counts this as a drop */
goto reuse_rx;
}
@@ -1018,7 +1109,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
len + pad);
if (new_skb == NULL) {
DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped "
+ "ERROR packet dropped "
"because of alloc failure\n");
/* TBD count this as a drop? */
goto reuse_rx;
@@ -1044,7 +1135,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
} else {
DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped because "
+ "ERROR packet dropped because "
"of alloc failure\n");
reuse_rx:
bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
@@ -1061,14 +1152,14 @@ reuse_rx:
}
#ifdef BCM_VLAN
- if ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags)
- & PARSING_FLAGS_NUMBER_OF_NESTED_VLANS)
- && (bp->vlgrp != NULL))
+ if ((bp->vlgrp != NULL) &&
+ (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
+ PARSING_FLAGS_VLAN))
vlan_hwaccel_receive_skb(skb, bp->vlgrp,
le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
else
#endif
- netif_receive_skb(skb);
+ netif_receive_skb(skb);
bp->dev->last_rx = jiffies;
@@ -1077,22 +1168,25 @@ next_rx:
bd_cons = NEXT_RX_IDX(bd_cons);
bd_prod = NEXT_RX_IDX(bd_prod);
+ bd_prod_fw = NEXT_RX_IDX(bd_prod_fw);
+ rx_pkt++;
next_cqe:
sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod);
sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons);
- rx_pkt++;
- if ((rx_pkt == budget))
+ if (rx_pkt == budget)
break;
} /* while */
fp->rx_bd_cons = bd_cons;
- fp->rx_bd_prod = bd_prod;
+ fp->rx_bd_prod = bd_prod_fw;
fp->rx_comp_cons = sw_comp_cons;
fp->rx_comp_prod = sw_comp_prod;
REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_RCQ_PROD_OFFSET(bp->port, fp->index), sw_comp_prod);
+ TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)),
+ sw_comp_prod);
+
mmiowb(); /* keep prod updates ordered */
@@ -1107,10 +1201,11 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
struct bnx2x_fastpath *fp = fp_cookie;
struct bnx2x *bp = fp->bp;
struct net_device *dev = bp->dev;
- int index = fp->index;
+ int index = FP_IDX(fp);
- DP(NETIF_MSG_INTR, "got an msix interrupt on [%d]\n", index);
- bnx2x_ack_sb(bp, index, USTORM_ID, 0, IGU_INT_DISABLE, 0);
+ 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);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -1123,6 +1218,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
prefetch(&fp->status_blk->u_status_block.status_block_index);
netif_rx_schedule(dev, &bnx2x_fp(bp, index, napi));
+
return IRQ_HANDLED;
}
@@ -1131,26 +1227,28 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
struct net_device *dev = dev_instance;
struct bnx2x *bp = netdev_priv(dev);
u16 status = bnx2x_ack_int(bp);
+ u16 mask;
+ /* Return here if interrupt is shared and it's not for us */
if (unlikely(status == 0)) {
DP(NETIF_MSG_INTR, "not our interrupt!\n");
return IRQ_NONE;
}
-
- DP(NETIF_MSG_INTR, "got an interrupt status is %u\n", status);
+ DP(NETIF_MSG_INTR, "got an interrupt status %u\n", status);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
return IRQ_HANDLED;
#endif
- /* Return here if interrupt is shared and is disabled */
+ /* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
return IRQ_HANDLED;
}
- if (status & 0x2) {
+ mask = 0x2 << bp->fp[0].sb_id;
+ if (status & mask) {
struct bnx2x_fastpath *fp = &bp->fp[0];
prefetch(fp->rx_cons_sb);
@@ -1160,13 +1258,11 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
netif_rx_schedule(dev, &bnx2x_fp(bp, 0, napi));
- status &= ~0x2;
- if (!status)
- return IRQ_HANDLED;
+ status &= ~mask;
}
- if (unlikely(status & 0x1)) {
+ if (unlikely(status & 0x1)) {
schedule_work(&bp->sp_task);
status &= ~0x1;
@@ -1174,8 +1270,9 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
return IRQ_HANDLED;
}
- DP(NETIF_MSG_INTR, "got an unknown interrupt! (status is %u)\n",
- status);
+ if (status)
+ DP(NETIF_MSG_INTR, "got an unknown interrupt! (status %u)\n",
+ status);
return IRQ_HANDLED;
}
@@ -1193,7 +1290,7 @@ static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
{
u32 lock_status;
u32 resource_bit = (1 << resource);
- u8 port = bp->port;
+ u8 port = BP_PORT(bp);
int cnt;
/* Validating that the resource is within range */
@@ -1231,7 +1328,7 @@ static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
{
u32 lock_status;
u32 resource_bit = (1 << resource);
- u8 port = bp->port;
+ u8 port = BP_PORT(bp);
/* Validating that the resource is within range */
if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
@@ -1258,7 +1355,7 @@ static void bnx2x_phy_hw_lock(struct bnx2x *bp)
{
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
- mutex_lock(&bp->phy_mutex);
+ mutex_lock(&bp->port.phy_mutex);
if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
(ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
@@ -1273,14 +1370,14 @@ static void bnx2x_phy_hw_unlock(struct bnx2x *bp)
(ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
- mutex_unlock(&bp->phy_mutex);
+ mutex_unlock(&bp->port.phy_mutex);
}
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
{
/* The GPIO should be swapped if swap register is set and active */
int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
- REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port;
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ BP_PORT(bp);
int gpio_shift = gpio_num +
(gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
u32 gpio_mask = (1 << gpio_shift);
@@ -1379,18 +1476,18 @@ static void bnx2x_calc_fc_adv(struct bnx2x *bp)
{
switch (bp->link_vars.ieee_fc) {
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE:
- bp->advertising &= ~(ADVERTISED_Asym_Pause |
+ bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
- bp->advertising |= (ADVERTISED_Asym_Pause |
+ bp->port.advertising |= (ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
- bp->advertising |= ADVERTISED_Asym_Pause;
+ bp->port.advertising |= ADVERTISED_Asym_Pause;
break;
default:
- bp->advertising &= ~(ADVERTISED_Asym_Pause |
+ bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
}
@@ -1443,6 +1540,7 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
bnx2x_link_report(bp);
bnx2x_calc_fc_adv(bp);
+
return rc;
}
@@ -1473,15 +1571,261 @@ static u8 bnx2x_link_test(struct bnx2x *bp)
return rc;
}
+/* Calculates the sum of vn_min_rates.
+ It's needed for further normalizing of the min_rates.
+
+ Returns:
+ sum of vn_min_rates
+ or
+ 0 - if all the min_rates are 0.
+ In the later case fainess algorithm should be deactivated.
+ If not all min_rates are zero then those that are zeroes will
+ be set to 1.
+ */
+static u32 bnx2x_calc_vn_wsum(struct bnx2x *bp)
+{
+ int i, port = BP_PORT(bp);
+ u32 wsum = 0;
+ int all_zero = 1;
+
+ for (i = 0; i < E1HVN_MAX; i++) {
+ u32 vn_cfg =
+ SHMEM_RD(bp, mf_cfg.func_mf_config[2*i + port].config);
+ u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
+ FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
+ if (!(vn_cfg & FUNC_MF_CFG_FUNC_HIDE)) {
+ /* If min rate is zero - set it to 1 */
+ if (!vn_min_rate)
+ vn_min_rate = DEF_MIN_RATE;
+ else
+ all_zero = 0;
+
+ wsum += vn_min_rate;
+ }
+ }
+
+ /* ... only if all min rates are zeros - disable FAIRNESS */
+ if (all_zero)
+ return 0;
+
+ return wsum;
+}
+
+static void bnx2x_init_port_minmax(struct bnx2x *bp,
+ int en_fness,
+ u16 port_rate,
+ struct cmng_struct_per_port *m_cmng_port)
+{
+ u32 r_param = port_rate / 8;
+ int port = BP_PORT(bp);
+ int i;
+
+ memset(m_cmng_port, 0, sizeof(struct cmng_struct_per_port));
+
+ /* Enable minmax only if we are in e1hmf mode */
+ if (IS_E1HMF(bp)) {
+ u32 fair_periodic_timeout_usec;
+ u32 t_fair;
+
+ /* Enable rate shaping and fairness */
+ m_cmng_port->flags.cmng_vn_enable = 1;
+ m_cmng_port->flags.fairness_enable = en_fness ? 1 : 0;
+ m_cmng_port->flags.rate_shaping_enable = 1;
+
+ if (!en_fness)
+ DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+ " fairness will be disabled\n");
+
+ /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
+ m_cmng_port->rs_vars.rs_periodic_timeout =
+ RS_PERIODIC_TIMEOUT_USEC / 4;
+
+ /* this is the threshold below which no timer arming will occur
+ 1.25 coefficient is for the threshold to be a little bigger
+ than the real time, to compensate for timer in-accuracy */
+ m_cmng_port->rs_vars.rs_threshold =
+ (RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
+
+ /* resolution of fairness timer */
+ fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
+ /* for 10G it is 1000usec. for 1G it is 10000usec. */
+ t_fair = T_FAIR_COEF / port_rate;
+
+ /* this is the threshold below which we won't arm
+ the timer anymore */
+ m_cmng_port->fair_vars.fair_threshold = QM_ARB_BYTES;
+
+ /* we multiply by 1e3/8 to get bytes/msec.
+ We don't want the credits to pass a credit
+ of the T_FAIR*FAIR_MEM (algorithm resolution) */
+ m_cmng_port->fair_vars.upper_bound =
+ r_param * t_fair * FAIR_MEM;
+ /* since each tick is 4 usec */
+ m_cmng_port->fair_vars.fairness_timeout =
+ fair_periodic_timeout_usec / 4;
+
+ } else {
+ /* Disable rate shaping and fairness */
+ m_cmng_port->flags.cmng_vn_enable = 0;
+ m_cmng_port->flags.fairness_enable = 0;
+ m_cmng_port->flags.rate_shaping_enable = 0;
+
+ DP(NETIF_MSG_IFUP,
+ "Single function mode minmax will be disabled\n");
+ }
+
+ /* Store it to internal memory */
+ for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
+ ((u32 *)(m_cmng_port))[i]);
+}
+
+static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
+ u32 wsum, u16 port_rate,
+ struct cmng_struct_per_port *m_cmng_port)
+{
+ struct rate_sh