aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/bnx2x
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x')
-rw-r--r--drivers/net/bnx2x/bnx2x.h35
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c643
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h454
-rw-r--r--drivers/net/bnx2x/bnx2x_dcb.c202
-rw-r--r--drivers/net/bnx2x/bnx2x_dcb.h16
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c167
-rw-r--r--drivers/net/bnx2x/bnx2x_fw_defs.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_fw_file_hdr.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h4
-rw-r--r--drivers/net/bnx2x/bnx2x_init.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_init_ops.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c14
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c360
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.c2
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.h2
16 files changed, 1108 insertions, 801 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index e0fca701d2f..668a578c49e 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1,6 +1,6 @@
/* bnx2x.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,8 +22,8 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.62.11-0"
-#define DRV_MODULE_RELDATE "2011/01/31"
+#define DRV_MODULE_VERSION "1.62.12-0"
+#define DRV_MODULE_RELDATE "2011/03/20"
#define BNX2X_BC_VER 0x040200
#define BNX2X_MULTI_QUEUE
@@ -473,7 +473,8 @@ struct bnx2x_fastpath {
#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS)
#define MAX_RX_BD (NUM_RX_BD - 1)
#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
-#define MIN_RX_AVAIL 128
+#define MIN_RX_SIZE_TPA 72
+#define MIN_RX_SIZE_NONTPA 10
#define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL
#define INIT_RX_RING_SIZE MAX_RX_AVAIL
#define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \
@@ -893,6 +894,22 @@ typedef enum {
(&bp->def_status_blk->sp_sb.\
index_values[HC_SP_INDEX_EQ_CONS])
+/* This is a data that will be used to create a link report message.
+ * We will keep the data used for the last link report in order
+ * to prevent reporting the same link parameters twice.
+ */
+struct bnx2x_link_report_data {
+ u16 line_speed; /* Effective line speed */
+ unsigned long link_report_flags;/* BNX2X_LINK_REPORT_XXX flags */
+};
+
+enum {
+ BNX2X_LINK_REPORT_FD, /* Full DUPLEX */
+ BNX2X_LINK_REPORT_LINK_DOWN,
+ BNX2X_LINK_REPORT_RX_FC_ON,
+ BNX2X_LINK_REPORT_TX_FC_ON,
+};
+
struct bnx2x {
/* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure
@@ -918,7 +935,6 @@ struct bnx2x {
int tx_ring_size;
- u32 rx_csum;
/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
#define ETH_MIN_PACKET_SIZE 60
@@ -1026,6 +1042,9 @@ struct bnx2x {
struct link_params link_params;
struct link_vars link_vars;
+ u32 link_cnt;
+ struct bnx2x_link_report_data last_reported_link;
+
struct mdio_if_info mdio;
struct bnx2x_common common;
@@ -1223,6 +1242,10 @@ struct bnx2x {
/* DCBX Negotiation results */
struct dcbx_features dcbx_local_feat;
u32 dcbx_error;
+#ifdef BCM_DCBNL
+ struct dcbx_features dcbx_remote_feat;
+ u32 dcbx_remote_flags;
+#endif
u32 pending_max;
};
@@ -1442,6 +1465,8 @@ struct bnx2x_func_init_params {
#define WAIT_RAMROD_POLL 0x01
#define WAIT_RAMROD_COMMON 0x02
+void bnx2x_read_mf_cfg(struct bnx2x *bp);
+
/* dmae */
void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 16581df5ee4..ca2bbc0e5d4 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1,6 +1,6 @@
/* bnx2x_cmn.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,6 +27,49 @@
static int bnx2x_setup_irqs(struct bnx2x *bp);
+/**
+ * bnx2x_bz_fp - zero content of the fastpath structure.
+ *
+ * @bp: driver handle
+ * @index: fastpath index to be zeroed
+ *
+ * Makes sure the contents of the bp->fp[index].napi is kept
+ * intact.
+ */
+static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
+{
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+ struct napi_struct orig_napi = fp->napi;
+ /* bzero bnx2x_fastpath contents */
+ memset(fp, 0, sizeof(*fp));
+
+ /* Restore the NAPI object as it has been already initialized */
+ fp->napi = orig_napi;
+}
+
+/**
+ * bnx2x_move_fp - move content of the fastpath structure.
+ *
+ * @bp: driver handle
+ * @from: source FP index
+ * @to: destination FP index
+ *
+ * Makes sure the contents of the bp->fp[to].napi is kept
+ * intact.
+ */
+static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to)
+{
+ struct bnx2x_fastpath *from_fp = &bp->fp[from];
+ struct bnx2x_fastpath *to_fp = &bp->fp[to];
+ struct napi_struct orig_napi = to_fp->napi;
+ /* Move bnx2x_fastpath contents */
+ memcpy(to_fp, from_fp, sizeof(*to_fp));
+ to_fp->index = to;
+
+ /* Restore the NAPI object as it has been already initialized */
+ to_fp->napi = orig_napi;
+}
+
/* free skb in the packet ring at pos idx
* return idx of last bd freed
*/
@@ -265,13 +308,15 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
*/
#define TPA_TSTAMP_OPT_LEN 12
/**
- * Calculate the approximate value of the MSS for this
- * aggregation using the first packet of it.
+ * bnx2x_set_lro_mss - calculate the approximate value of the MSS
*
- * @param bp
- * @param parsing_flags Parsing flags from the START CQE
- * @param len_on_bd Total length of the first packet for the
- * aggregation.
+ * @bp: driver handle
+ * @parsing_flags: parsing flags from the START CQE
+ * @len_on_bd: total length of the first packet for the
+ * aggregation.
+ *
+ * Approximate value of the MSS for this aggregation calculated using
+ * the first packet of it.
*/
static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags,
u16 len_on_bd)
@@ -640,7 +685,7 @@ reuse_rx:
skb_checksum_none_assert(skb);
- if (bp->rx_csum) {
+ if (bp->dev->features & NETIF_F_RXCSUM) {
if (likely(BNX2X_RX_CSUM_OK(cqe)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
@@ -758,35 +803,119 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp)
return line_speed;
}
+/**
+ * bnx2x_fill_report_data - fill link report data to report
+ *
+ * @bp: driver handle
+ * @data: link state to update
+ *
+ * It uses a none-atomic bit operations because is called under the mutex.
+ */
+static inline void bnx2x_fill_report_data(struct bnx2x *bp,
+ struct bnx2x_link_report_data *data)
+{
+ u16 line_speed = bnx2x_get_mf_speed(bp);
+
+ memset(data, 0, sizeof(*data));
+
+ /* Fill the report data: efective line speed */
+ data->line_speed = line_speed;
+
+ /* Link is down */
+ if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &data->link_report_flags);
+
+ /* Full DUPLEX */
+ if (bp->link_vars.duplex == DUPLEX_FULL)
+ __set_bit(BNX2X_LINK_REPORT_FD, &data->link_report_flags);
+
+ /* Rx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ __set_bit(BNX2X_LINK_REPORT_RX_FC_ON, &data->link_report_flags);
+
+ /* Tx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ __set_bit(BNX2X_LINK_REPORT_TX_FC_ON, &data->link_report_flags);
+}
+
+/**
+ * bnx2x_link_report - report link status to OS.
+ *
+ * @bp: driver handle
+ *
+ * Calls the __bnx2x_link_report() under the same locking scheme
+ * as a link/PHY state managing code to ensure a consistent link
+ * reporting.
+ */
+
void bnx2x_link_report(struct bnx2x *bp)
{
- if (bp->flags & MF_FUNC_DIS) {
- netif_carrier_off(bp->dev);
- netdev_err(bp->dev, "NIC Link is Down\n");
- return;
- }
+ bnx2x_acquire_phy_lock(bp);
+ __bnx2x_link_report(bp);
+ bnx2x_release_phy_lock(bp);
+}
- if (bp->link_vars.link_up) {
- u16 line_speed;
+/**
+ * __bnx2x_link_report - report link status to OS.
+ *
+ * @bp: driver handle
+ *
+ * None atomic inmlementation.
+ * Should be called under the phy_lock.
+ */
+void __bnx2x_link_report(struct bnx2x *bp)
+{
+ struct bnx2x_link_report_data cur_data;
- if (bp->state == BNX2X_STATE_OPEN)
- netif_carrier_on(bp->dev);
- netdev_info(bp->dev, "NIC Link is Up, ");
+ /* reread mf_cfg */
+ if (!CHIP_IS_E1(bp))
+ bnx2x_read_mf_cfg(bp);
+
+ /* Read the current link report info */
+ bnx2x_fill_report_data(bp, &cur_data);
+
+ /* Don't report link down or exactly the same link status twice */
+ if (!memcmp(&cur_data, &bp->last_reported_link, sizeof(cur_data)) ||
+ (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->last_reported_link.link_report_flags) &&
+ test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &cur_data.link_report_flags)))
+ return;
- line_speed = bnx2x_get_mf_speed(bp);
+ bp->link_cnt++;
- pr_cont("%d Mbps ", line_speed);
+ /* We are going to report a new link parameters now -
+ * remember the current data for the next time.
+ */
+ memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data));
+
+ if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &cur_data.link_report_flags)) {
+ netif_carrier_off(bp->dev);
+ netdev_err(bp->dev, "NIC Link is Down\n");
+ return;
+ } else {
+ netif_carrier_on(bp->dev);
+ netdev_info(bp->dev, "NIC Link is Up, ");
+ pr_cont("%d Mbps ", cur_data.line_speed);
- if (bp->link_vars.duplex == DUPLEX_FULL)
+ if (test_and_clear_bit(BNX2X_LINK_REPORT_FD,
+ &cur_data.link_report_flags))
pr_cont("full duplex");
else
pr_cont("half duplex");
- if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
- if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
+ /* Handle the FC at the end so that only these flags would be
+ * possibly set. This way we may easily check if there is no FC
+ * enabled.
+ */
+ if (cur_data.link_report_flags) {
+ if (test_bit(BNX2X_LINK_REPORT_RX_FC_ON,
+ &cur_data.link_report_flags)) {
pr_cont(", receive ");
- if (bp->link_vars.flow_ctrl &
- BNX2X_FLOW_CTRL_TX)
+ if (test_bit(BNX2X_LINK_REPORT_TX_FC_ON,
+ &cur_data.link_report_flags))
pr_cont("& transmit ");
} else {
pr_cont(", transmit ");
@@ -794,62 +923,9 @@ void bnx2x_link_report(struct bnx2x *bp)
pr_cont("flow control ON");
}
pr_cont("\n");
-
- } else { /* link_down */
- netif_carrier_off(bp->dev);
- netdev_err(bp->dev, "NIC Link is Down\n");
}
}
-/* Returns the number of actually allocated BDs */
-static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
- int rx_ring_size)
-{
- struct bnx2x *bp = fp->bp;
- u16 ring_prod, cqe_ring_prod;
- int i;
-
- fp->rx_comp_cons = 0;
- cqe_ring_prod = ring_prod = 0;
- for (i = 0; i < rx_ring_size; i++) {
- if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
- BNX2X_ERR("was only able to allocate "
- "%d rx skbs on queue[%d]\n", i, fp->index);
- fp->eth_q_stats.rx_skb_alloc_failed++;
- break;
- }
- ring_prod = NEXT_RX_IDX(ring_prod);
- cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
- WARN_ON(ring_prod <= i);
- }
-
- fp->rx_bd_prod = ring_prod;
- /* Limit the CQE producer by the CQE ring size */
- fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
- cqe_ring_prod);
- fp->rx_pkt = fp->rx_calls = 0;
-
- return i;
-}
-
-static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp)
-{
- struct bnx2x *bp = fp->bp;
- int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
- MAX_RX_AVAIL/bp->num_queues;
-
- rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size);
-
- bnx2x_alloc_rx_bds(fp, rx_ring_size);
-
- /* Warning!
- * this will generate an interrupt (to the TSTORM)
- * must only be done after chip is initialized
- */
- bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
- fp->rx_sge_prod);
-}
-
void bnx2x_init_rx_rings(struct bnx2x *bp)
{
int func = BP_FUNC(bp);
@@ -858,6 +934,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
u16 ring_prod;
int i, j;
+ /* Allocate TPA resources */
for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
@@ -865,6 +942,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
"mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
if (!fp->disable_tpa) {
+ /* Fill the per-aggregation pool */
for (i = 0; i < max_agg_queues; i++) {
fp->tpa_pool[i].skb =
netdev_alloc_skb(bp->dev, fp->rx_buf_size);
@@ -919,13 +997,13 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
fp->rx_bd_cons = 0;
- bnx2x_set_next_page_rx_bd(fp);
-
- /* CQ ring */
- bnx2x_set_next_page_rx_cq(fp);
-
- /* Allocate BDs and initialize BD ring */
- bnx2x_alloc_rx_bd_ring(fp);
+ /* Activate BD ring */
+ /* Warning!
+ * this will generate an interrupt (to the TSTORM)
+ * must only be done after chip is initialized
+ */
+ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
+ fp->rx_sge_prod);
if (j != 0)
continue;
@@ -959,27 +1037,40 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
}
}
+static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp)
+{
+ struct bnx2x *bp = fp->bp;
+ int i;
+
+ /* ring wasn't allocated */
+ if (fp->rx_buf_ring == NULL)
+ return;
+
+ for (i = 0; i < NUM_RX_BD; i++) {
+ struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
+ struct sk_buff *skb = rx_buf->skb;
+
+ if (skb == NULL)
+ continue;
+
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ fp->rx_buf_size, DMA_FROM_DEVICE);
+
+ rx_buf->skb = NULL;
+ dev_kfree_skb(skb);
+ }
+}
+
static void bnx2x_free_rx_skbs(struct bnx2x *bp)
{
- int i, j;
+ int j;
for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
- for (i = 0; i < NUM_RX_BD; i++) {
- struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
- struct sk_buff *skb = rx_buf->skb;
-
- if (skb == NULL)
- continue;
-
- dma_unmap_single(&bp->pdev->dev,
- dma_unmap_addr(rx_buf, mapping),
- fp->rx_buf_size, DMA_FROM_DEVICE);
+ bnx2x_free_rx_bds(fp);
- rx_buf->skb = NULL;
- dev_kfree_skb(skb);
- }
if (!fp->disable_tpa)
bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ?
ETH_MAX_AGGREGATION_QUEUES_E1 :
@@ -1345,29 +1436,47 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
+ /* Set the initial link reported state to link down */
+ bnx2x_acquire_phy_lock(bp);
+ memset(&bp->last_reported_link, 0, sizeof(bp->last_reported_link));
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->last_reported_link.link_report_flags);
+ bnx2x_release_phy_lock(bp);
+
/* must be called before memory allocation and HW init */
bnx2x_ilt_set_info(bp);
+ /* zero fastpath structures preserving invariants like napi which are
+ * allocated only once
+ */
+ for_each_queue(bp, i)
+ bnx2x_bz_fp(bp, i);
+
/* Set the receive queues buffer size */
bnx2x_set_rx_buf_size(bp);
+ for_each_queue(bp, i)
+ bnx2x_fp(bp, i, disable_tpa) =
+ ((bp->flags & TPA_ENABLE_FLAG) == 0);
+
+#ifdef BCM_CNIC
+ /* We don't want TPA on FCoE L2 ring */
+ bnx2x_fcoe(bp, disable_tpa) = 1;
+#endif
+
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
+ /* As long as bnx2x_alloc_mem() may possibly update
+ * bp->num_queues, bnx2x_set_real_num_queues() should always
+ * come after it.
+ */
rc = bnx2x_set_real_num_queues(bp);
if (rc) {
BNX2X_ERR("Unable to set real_num_queues\n");
goto load_error0;
}
- for_each_queue(bp, i)
- bnx2x_fp(bp, i, disable_tpa) =
- ((bp->flags & TPA_ENABLE_FLAG) == 0);
-
-#ifdef BCM_CNIC
- /* We don't want TPA on FCoE L2 ring */
- bnx2x_fcoe(bp, disable_tpa) = 1;
-#endif
bnx2x_napi_enable(bp);
/* Send LOAD_REQUEST command to MCP
@@ -1976,12 +2085,11 @@ static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
}
/**
- * Update PBD in GSO case.
+ * bnx2x_set_pbd_gso - update PBD in GSO case.
*
- * @param skb
- * @param tx_start_bd
- * @param pbd
- * @param xmit_type
+ * @skb: packet skb
+ * @pbd: parse BD
+ * @xmit_type: xmit flags
*/
static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
struct eth_tx_parse_bd_e1x *pbd,
@@ -2008,13 +2116,14 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
}
/**
+ * bnx2x_set_pbd_csum_e2 - update PBD with checksum and return header length
*
- * @param skb
- * @param tx_start_bd
- * @param pbd_e2
- * @param xmit_type
+ * @bp: driver handle
+ * @skb: packet skb
+ * @parsing_data: data to be updated
+ * @xmit_type: xmit flags
*
- * @return header len
+ * 57712 related
*/
static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
u32 *parsing_data, u32 xmit_type)
@@ -2039,13 +2148,12 @@ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
}
/**
+ * bnx2x_set_pbd_csum - update PBD with checksum and return header length
*
- * @param skb
- * @param tx_start_bd
- * @param pbd
- * @param xmit_type
- *
- * @return Header length
+ * @bp: driver handle
+ * @skb: packet skb
+ * @pbd: parse BD to be updated
+ * @xmit_type: xmit flags
*/
static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb,
struct eth_tx_parse_bd_e1x *pbd,
@@ -2393,6 +2501,232 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p)
return 0;
}
+static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index)
+{
+ union host_hc_status_block *sb = &bnx2x_fp(bp, fp_index, status_blk);
+ struct bnx2x_fastpath *fp = &bp->fp[fp_index];
+
+ /* Common */
+#ifdef BCM_CNIC
+ if (IS_FCOE_IDX(fp_index)) {
+ memset(sb, 0, sizeof(union host_hc_status_block));
+ fp->status_blk_mapping = 0;
+
+ } else {
+#endif
+ /* status blocks */
+ if (CHIP_IS_E2(bp))
+ BNX2X_PCI_FREE(sb->e2_sb,
+ bnx2x_fp(bp, fp_index,
+ status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_FREE(sb->e1x_sb,
+ bnx2x_fp(bp, fp_index,
+ status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+ }
+#endif
+ /* Rx */
+ if (!skip_rx_queue(bp, fp_index)) {
+ bnx2x_free_rx_bds(fp);
+
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_desc_ring),
+ bnx2x_fp(bp, fp_index, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_comp_ring),
+ bnx2x_fp(bp, fp_index, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) *
+ NUM_RCQ_BD);
+
+ /* SGE ring */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_page_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_sge_ring),
+ bnx2x_fp(bp, fp_index, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ }
+
+ /* Tx */
+ if (!skip_tx_queue(bp, fp_index)) {
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, tx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, tx_desc_ring),
+ bnx2x_fp(bp, fp_index, tx_desc_mapping),
+ sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ }
+ /* end of fastpath */
+}
+
+void bnx2x_free_fp_mem(struct bnx2x *bp)
+{
+ int i;
+ for_each_queue(bp, i)
+ bnx2x_free_fp_mem_at(bp, i);
+}
+
+static inline void set_sb_shortcuts(struct bnx2x *bp, int index)
+{
+ union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk);
+ if (CHIP_IS_E2(bp)) {
+ bnx2x_fp(bp, index, sb_index_values) =
+ (__le16 *)status_blk.e2_sb->sb.index_values;
+ bnx2x_fp(bp, index, sb_running_index) =
+ (__le16 *)status_blk.e2_sb->sb.running_index;
+ } else {
+ bnx2x_fp(bp, index, sb_index_values) =
+ (__le16 *)status_blk.e1x_sb->sb.index_values;
+ bnx2x_fp(bp, index, sb_running_index) =
+ (__le16 *)status_blk.e1x_sb->sb.running_index;
+ }
+}
+
+static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
+{
+ union host_hc_status_block *sb;
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+ int ring_size = 0;
+
+ /* if rx_ring_size specified - use it */
+ int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
+ MAX_RX_AVAIL/bp->num_queues;
+
+ /* allocate at least number of buffers required by FW */
+ rx_ring_size = max_t(int, fp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+ MIN_RX_SIZE_TPA,
+ rx_ring_size);
+
+ bnx2x_fp(bp, index, bp) = bp;
+ bnx2x_fp(bp, index, index) = index;
+
+ /* Common */
+ sb = &bnx2x_fp(bp, index, status_blk);
+#ifdef BCM_CNIC
+ if (!IS_FCOE_IDX(index)) {
+#endif
+ /* status blocks */
+ if (CHIP_IS_E2(bp))
+ BNX2X_PCI_ALLOC(sb->e2_sb,
+ &bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_ALLOC(sb->e1x_sb,
+ &bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+ }
+#endif
+ set_sb_shortcuts(bp, index);
+
+ /* Tx */
+ if (!skip_tx_queue(bp, index)) {
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_ALLOC(bnx2x_fp(bp, index, tx_buf_ring),
+ sizeof(struct sw_tx_bd) * NUM_TX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, tx_desc_ring),
+ &bnx2x_fp(bp, index, tx_desc_mapping),
+ sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ }
+
+ /* Rx */
+ if (!skip_rx_queue(bp, index)) {
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
+ BNX2X_ALLOC(bnx2x_fp(bp, index, rx_buf_ring),
+ sizeof(struct sw_rx_bd) * NUM_RX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_desc_ring),
+ &bnx2x_fp(bp, index, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_comp_ring),
+ &bnx2x_fp(bp, index, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) *
+ NUM_RCQ_BD);
+
+ /* SGE ring */
+ BNX2X_ALLOC(bnx2x_fp(bp, index, rx_page_ring),
+ sizeof(struct sw_rx_page) * NUM_RX_SGE);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_sge_ring),
+ &bnx2x_fp(bp, index, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ /* RX BD ring */
+ bnx2x_set_next_page_rx_bd(fp);
+
+ /* CQ ring */
+ bnx2x_set_next_page_rx_cq(fp);
+
+ /* BDs */
+ ring_size = bnx2x_alloc_rx_bds(fp, rx_ring_size);
+ if (ring_size < rx_ring_size)
+ goto alloc_mem_err;
+ }
+
+ return 0;
+
+/* handles low memory cases */
+alloc_mem_err:
+ BNX2X_ERR("Unable to allocate full memory for queue %d (size %d)\n",
+ index, ring_size);
+ /* FW will drop all packets if queue is not big enough,
+ * In these cases we disable the queue
+ * Min size diferent for TPA and non-TPA queues
+ */
+ if (ring_size < (fp->disable_tpa ?
+ MIN_RX_SIZE_TPA : MIN_RX_SIZE_NONTPA)) {
+ /* release memory allocated for this queue */
+ bnx2x_free_fp_mem_at(bp, index);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int bnx2x_alloc_fp_mem(struct bnx2x *bp)
+{
+ int i;
+
+ /**
+ * 1. Allocate FP for leading - fatal if error
+ * 2. {CNIC} Allocate FCoE FP - fatal if error
+ * 3. Allocate RSS - fix number of queues if error
+ */
+
+ /* leading */
+ if (bnx2x_alloc_fp_mem_at(bp, 0))
+ return -ENOMEM;
+#ifdef BCM_CNIC
+ /* FCoE */
+ if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX))
+ return -ENOMEM;
+#endif
+ /* RSS */
+ for_each_nondefault_eth_queue(bp, i)
+ if (bnx2x_alloc_fp_mem_at(bp, i))
+ break;
+
+ /* handle memory failures */
+ if (i != BNX2X_NUM_ETH_QUEUES(bp)) {
+ int delta = BNX2X_NUM_ETH_QUEUES(bp) - i;
+
+ WARN_ON(delta < 0);
+#ifdef BCM_CNIC
+ /**
+ * move non eth FPs next to last eth FP
+ * must be done in that order
+ * FCOE_IDX < FWD_IDX < OOO_IDX
+ */
+
+ /* move FCoE fp */
+ bnx2x_move_fp(bp, FCOE_IDX, FCOE_IDX - delta);
+#endif
+ bp->num_queues -= delta;
+ BNX2X_ERR("Adjusted num of queues from %d to %d\n",
+ bp->num_queues + delta, bp->num_queues);
+ }
+
+ return 0;
+}
static int bnx2x_setup_irqs(struct bnx2x *bp)
{
@@ -2457,11 +2791,21 @@ alloc_err:
}
+static int bnx2x_reload_if_running(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (unlikely(!netif_running(dev)))
+ return 0;
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ return bnx2x_nic_load(bp, LOAD_NORMAL);
+}
+
/* called with rtnl_lock */
int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
{
struct bnx2x *bp = netdev_priv(dev);
- int rc = 0;
if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
printk(KERN_ERR "Handling parity error recovery. Try again later\n");
@@ -2478,12 +2822,55 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
*/
dev->mtu = new_mtu;
- if (netif_running(dev)) {
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+ return bnx2x_reload_if_running(dev);
+}
+
+u32 bnx2x_fix_features(struct net_device *dev, u32 features)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ /* TPA requires Rx CSUM offloading */
+ if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa)
+ features &= ~NETIF_F_LRO;
+
+ return features;
+}
+
+int bnx2x_set_features(struct net_device *dev, u32 features)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 flags = bp->flags;
+ bool bnx2x_reload = false;
+
+ if (features & NETIF_F_LRO)
+ flags |= TPA_ENABLE_FLAG;
+ else
+ flags &= ~TPA_ENABLE_FLAG;
+
+ if (features & NETIF_F_LOOPBACK) {
+ if (bp->link_params.loopback_mode != LOOPBACK_BMAC) {
+ bp->link_params.loopback_mode = LOOPBACK_BMAC;
+ bnx2x_reload = true;
+ }
+ } else {
+ if (bp->link_params.loopback_mode != LOOPBACK_NONE) {
+ bp->link_params.loopback_mode = LOOPBACK_NONE;
+ bnx2x_reload = true;
+ }
}
- return rc;
+ if (flags ^ bp->flags) {
+ bp->flags = flags;
+ bnx2x_reload = true;
+ }
+
+ if (bnx2x_reload) {
+ if (bp->recovery_state == BNX2X_RECOVERY_DONE)
+ return bnx2x_reload_if_running(dev);
+ /* else: bnx2x_nic_load() will be called at end of recovery */
+ }
+
+ return 0;
}
void bnx2x_tx_timeout(struct net_device *dev)
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index ef37b98d614..fab161e8030 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -1,6 +1,6 @@
/* bnx2x_cmn.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,260 +25,277 @@
extern int num_queues;
+/************************ Macros ********************************/
+#define BNX2X_PCI_FREE(x, y, size) \
+ do { \
+ if (x) { \
+ dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
+ x = NULL; \
+ y = 0; \
+ } \
+ } while (0)
+
+#define BNX2X_FREE(x) \
+ do { \
+ if (x) { \
+ kfree((void *)x); \
+ x = NULL; \
+ } \
+ } while (0)
+
+#define BNX2X_PCI_ALLOC(x, y, size) \
+ do { \
+ x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+ if (x == NULL) \
+ goto alloc_mem_err; \
+ memset((void *)x, 0, size); \
+ } while (0)
+
+#define BNX2X_ALLOC(x, size) \
+ do { \
+ x = kzalloc(size, GFP_KERNEL); \
+ if (x == NULL) \
+ goto alloc_mem_err; \
+ } while (0)
+
/*********************** Interfaces ****************************
* Functions that need to be implemented by each driver version
*/
/**
- * Initialize link parameters structure variables.
- *
- * @param bp
- * @param load_mode
+ * bnx2x_initial_phy_init - initialize link parameters structure variables.
*
- * @return u8
+ * @bp: driver handle
+ * @load_mode: current mode
*/
u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode);
/**
- * Configure hw according to link parameters structure.
+ * bnx2x_link_set - configure hw according to link parameters structure.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_link_set(struct bnx2x *bp);
/**
- * Query link status
+ * bnx2x_link_test - query link status.
*
- * @param bp
- * @param is_serdes
+ * @bp: driver handle
+ * @is_serdes: bool
*
- * @return 0 - link is UP
+ * Returns 0 if link is UP.
*/
u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes);
/**
- * Handles link status change
+ * bnx2x__link_status_update - handles link status change.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x__link_status_update(struct bnx2x *bp);
/**
- * Report link status to upper layer
- *
- * @param bp
+ * bnx2x_link_report - report link status to upper layer.
*
- * @return int
+ * @bp: driver handle
*/
void bnx2x_link_report(struct bnx2x *bp);
+/* None-atomic version of bnx2x_link_report() */
+void __bnx2x_link_report(struct bnx2x *bp);
+
/**
- * calculates MF speed according to current linespeed and MF
- * configuration
+ * bnx2x_get_mf_speed - calculate MF speed.
*
- * @param bp
+ * @bp: driver handle
*
- * @return u16
+ * Takes into account current linespeed and MF configuration.
*/
u16 bnx2x_get_mf_speed(struct bnx2x *bp);
/**
- * MSI-X slowpath interrupt handler
- *
- * @param irq
- * @param dev_instance
+ * bnx2x_msix_sp_int - MSI-X slowpath interrupt handler
*
- * @return irqreturn_t
+ * @irq: irq number
+ * @dev_instance: private instance
*/
irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance);
/**
- * non MSI-X interrupt handler
+ * bnx2x_interrupt - non MSI-X interrupt handler
*
- * @param irq
- * @param dev_instance
- *
- * @return irqreturn_t
+ * @irq: irq number
+ * @dev_instance: private instance
*/
irqreturn_t bnx2x_interrupt(int irq, void *dev_instance);
#ifdef BCM_CNIC
/**
- * Send command to cnic driver
+ * bnx2x_cnic_notify - send command to cnic driver
*
- * @param bp
- * @param cmd
+ * @bp: driver handle
+ * @cmd: command
*/
int bnx2x_cnic_notify(struct bnx2x *bp, int cmd);
/**
- * Provides cnic information for proper interrupt handling
+ * bnx2x_setup_cnic_irq_info - provides cnic with IRQ information
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
#endif
/**
- * Enable HW interrupts.
+ * bnx2x_int_enable - enable HW interrupts.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_int_enable(struct bnx2x *bp);
/**
- * Disable interrupts. This function ensures that there are no
- * ISRs or SP DPCs (sp_task) are running after it returns.
+ * bnx2x_int_disable_sync - disable interrupts.
*
- * @param bp
- * @param disable_hw if true, disable HW interrupts.
+ * @bp: driver handle
+ * @disable_hw: true, disable HW interrupts.
+ *
+ * This function ensures that there are no
+ * ISRs or SP DPCs (sp_task) are running after it returns.
*/
void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
/**
- * Loads device firmware
+ * bnx2x_init_firmware - loads device firmware
*
- * @param bp
- *
- * @return int
+ * @bp: driver handle
*/
int bnx2x_init_firmware(struct bnx2x *bp);
/**
- * Init HW blocks according to current initialization stage:
- * COMMON, PORT or FUNCTION.
- *
- * @param bp
- * @param load_code: COMMON, PORT or FUNCTION
+ * bnx2x_init_hw - init HW blocks according to current initialization stage.
*
- * @return int
+ * @bp: driver handle
+ * @load_code: COMMON, PORT or FUNCTION
*/
int bnx2x_init_hw(struct bnx2x *bp, u32 load_code);
/**
- * Init driver internals:
+ * bnx2x_nic_init - init driver internals.
+ *
+ * @bp: driver handle
+ * @load_code: COMMON, PORT or FUNCTION
+ *
+ * Initializes:
* - rings
* - status blocks
* - etc.
- *
- * @param bp
- * @param load_code COMMON, PORT or FUNCTION
*/
void bnx2x_nic_init(struct bnx2x *bp, u32 load_code);
/**
- * Allocate driver's memory.
- *
- * @param bp
+ * bnx2x_alloc_mem - allocate driver's memory.
*
- * @return int
+ * @bp: driver handle
*/
int bnx2x_alloc_mem(struct bnx2x *bp);
/**
- * Release driver's memory.
+ * bnx2x_free_mem - release driver's memory.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_free_mem(struct bnx2x *bp);
/**
- * Setup eth Client.
+ * bnx2x_setup_client - setup eth client.
*
- * @param bp
- * @param fp
- * @param is_leading
- *
- * @return int
+ * @bp: driver handle
+ * @fp: pointer to fastpath structure
+ * @is_leading: boolean
*/
int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp,
int is_leading);
/**
- * Set number of queues according to mode
- *
- * @param bp
+ * bnx2x_set_num_queues - set number of queues according to mode.
*
+ * @bp: driver handle
*/
void bnx2x_set_num_queues(struct bnx2x *bp);
/**
- * Cleanup chip internals:
+ * bnx2x_chip_cleanup - cleanup chip internals.
+ *
+ * @bp: driver handle
+ * @unload_mode: COMMON, PORT, FUNCTION
+ *
* - Cleanup MAC configuration.
- * - Close clients.
+ * - Closes clients.
* - etc.
- *
- * @param bp
- * @param unload_mode
*/
void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode);
/**
- * Acquire HW lock.
+ * bnx2x_acquire_hw_lock - acquire HW lock.
*
- * @param bp
- * @param resource Resource bit which was locked
- *
- * @return int
+ * @bp: driver handle
+ * @resource: resource bit which was locked
*/
int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource);
/**
- * Release HW lock.
- *
- * @param bp driver handle
- * @param resource Resource bit which was locked
+ * bnx2x_release_hw_lock - release HW lock.
*
- * @return int
+ * @bp: driver handle
+ * @resource: resource bit which was locked
*/
int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource);
/**
- * Configure eth MAC address in the HW according to the value in
- * netdev->dev_addr.
+ * bnx2x_set_eth_mac - configure eth MAC address in the HW
*
- * @param bp driver handle
- * @param set
+ * @bp: driver handle
+ * @set: set or clear
+ *
+ * Configures according to the value in netdev->dev_addr.
*/
void bnx2x_set_eth_mac(struct bnx2x *bp, int set);
#ifdef BCM_CNIC
/**
- * Set/Clear FIP MAC(s) at the next enties in the CAM after the ETH
- * MAC(s). This function will wait until the ramdord completion
- * returns.
+ * bnx2x_set_fip_eth_mac_addr - Set/Clear FIP MAC(s)
*
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp: driver handle
+ * @set: set or clear the CAM entry
*
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * Used next enties in the CAM after the ETH MAC(s).
+ * This function will wait until the ramdord completion returns.
+ * Return 0 if cussess, -ENODEV if ramrod doesn't return.
*/
int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set);
/**
- * Set/Clear ALL_ENODE mcast MAC.
- *
- * @param bp
- * @param set
+ * bnx2x_set_all_enode_macs - Set/Clear ALL_ENODE mcast MAC.
*
- * @return int
+ * @bp: driver handle
+ * @set: set or clear
*/
int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set);
#endif
/**
- * Set MAC filtering configurations.
+ * bnx2x_set_rx_mode - set MAC filtering configurations.
*
- * @remarks called with netif_tx_lock from dev_mcast.c
+ * @dev: netdevice
*
- * @param dev net_device
+ * called with netif_tx_lock from dev_mcast.c
*/
void bnx2x_set_rx_mode(struct net_device *dev);
/**
- * Configure MAC filtering rules in a FW.
+ * bnx2x_set_storm_rx_mode - configure MAC filtering rules in a FW.
*
- * @param bp driver handle
+ * @bp: driver handle
*/
void bnx2x_set_storm_rx_mode(struct bnx2x *bp);
@@ -290,63 +307,59 @@ bool bnx2x_reset_is_done(struct bnx2x *bp);
void bnx2x_disable_close_the_gate(struct bnx2x *bp);
/**
- * Perform statistics handling according to event
+ * bnx2x_stats_handle - perform statistics handling according to event.
*
- * @param bp driver handle
- * @param event bnx2x_stats_event
+ * @bp: driver handle
+ * @event: bnx2x_stats_event
*/
void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
/**
- * Handle ramrods completion
+ * bnx2x_sp_event - handle ramrods completion.
*
- * @param fp fastpath handle for the event
- * @param rr_cqe eth_rx_cqe
+ * @fp: fastpath handle for the event
+ * @rr_cqe: eth_rx_cqe
*/
void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe);
/**
- * Init/halt function before/after sending
- * CLIENT_SETUP/CFC_DEL for the first/last client.
+ * bnx2x_func_start - init function
*
- * @param bp
+ * @bp: driver handle
*
- * @return int
+ * Must be called before sending CLIENT_SETUP for the first client.
*/
int bnx2x_func_start(struct bnx2x *bp);
/**
- * Prepare ILT configurations according to current driver
- * parameters.
+ * bnx2x_ilt_set_info - prepare ILT configurations.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_ilt_set_info(struct bnx2x *bp);
/**
- * Inintialize dcbx protocol
+ * bnx2x_dcbx_init - initialize dcbx protocol.
*
- * @param bp
+ * @bp: driver handle
*/
void bnx2x_dcbx_init(struct bnx2x *bp);
/**
- * Set power state to the requested value. Currently only D0 and
- * D3hot are supported.
+ * bnx2x_set_power_state - set power state to the requested value.
*
- * @param bp
- * @param state D0 or D3hot
+ * @bp: driver handle
+ * @state: required state D0 or D3hot
*
- * @return int
+ * Currently only D0 and D3hot are supported.
*/
int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state);
/**
- * Updates MAX part of MF configuration in HW
- * (if required)
+ * bnx2x_update_max_mf_config - update MAX part of MF configuration in HW.
*
- * @param bp
- * @param value
+ * @bp: driver handle
+ * @value: new value
*/
void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value);
@@ -377,83 +390,72 @@ int bnx2x_resume(struct pci_dev *pdev);
/* Release IRQ vectors */
void bnx2x_free_irq(struct bnx2x *bp);
+void bnx2x_free_fp_mem(struct bnx2x *bp);
+int bnx2x_alloc_fp_mem(struct bnx2x *bp);
+
void bnx2x_init_rx_rings(struct bnx2x *bp);
void bnx2x_free_skbs(struct bnx2x *bp);
void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw);
void bnx2x_netif_start(struct bnx2x *bp);
/**
- * Fill msix_table, request vectors, update num_queues according
- * to number of available vectors
+ * bnx2x_enable_msix - set msix configuration.
*
- * @param bp
+ * @bp: driver handle
*
- * @return int
+ * fills msix_table, requests vectors, updates num_queues
+ * according to number of available vectors.
*/
int bnx2x_enable_msix(struct bnx2x *bp);
/**
- * Request msi mode from OS, updated internals accordingly
- *
- * @param bp
+ * bnx2x_enable_msi - request msi mode from OS, updated internals accordingly
*
- * @return int
+ * @bp: driver handle
*/
int bnx2x_enable_msi(struct bnx2x *bp);
/**
- * NAPI callback
+ * bnx2x_poll - NAPI callback
*
- * @param napi
- * @param budget
+ * @napi: napi structure
+ * @budget:
*
- * @return int
*/
int bnx2x_poll(struct napi_struct *napi, int budget);
/**
- * Allocate/release memories outsize main driver structure
+ * bnx2x_alloc_mem_bp - allocate memories outsize main driver structure
*
- * @param bp
- *
- * @return int
+ * @bp: driver handle
*/
int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp);
-void bnx2x_free_mem_bp(struct bnx2x *bp);
/**
- * Change mtu netdev callback
+ * bnx2x_free_mem_bp - release memories outsize main driver structure
*
- * @param dev
- * @param new_mtu
- *
- * @return int
+ * @bp: driver handle
*/
-int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+void bnx2x_free_mem_bp(struct bnx2x *bp);
/**
- * tx timeout netdev callback
+ * bnx2x_change_mtu - change mtu netdev callback
*
- * @param dev
- * @param new_mtu
+ * @dev: net device
+ * @new_mtu: requested mtu
*
- * @return int
*/
-void bnx2x_tx_timeout(struct net_device *dev);
+int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+
+u32 bnx2x_fix_features(struct net_device *dev, u32 features);
+int bnx2x_set_features(struct net_device *dev, u32 features);
-#ifdef BCM_VLAN
/**
- * vlan rx register netdev callback
+ * bnx2x_tx_timeout - tx timeout netdev callback
*
- * @param dev
- * @param new_mtu
- *
- * @return int
+ * @dev: net device
*/
-void bnx2x_vlan_rx_register(struct net_device *dev,
- struct vlan_group *vlgrp);
-
-#endif
+void bnx2x_tx_timeout(struct net_device *dev);
static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
{
@@ -705,7 +707,7 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
/**
* disables tx from stack point of view
*
- * @param bp
+ * @bp: driver handle
*/
static inline void bnx2x_tx_disable(struct bnx2x *bp)
{
@@ -880,6 +882,9 @@ static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
{
int i;
+ if (fp->disable_tpa)
+ return;
+
for (i = 0; i < last; i++)
bnx2x_free_rx_sge(bp, fp, i);
}
@@ -908,36 +913,39 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
}
}
-
-static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
+static inline void bnx2x_init_tx_ring_one(struct bnx2x_fastpath *fp)
{
- int i, j;
+ int i;
- for_each_tx_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
+ for (i = 1; i <= NUM_TX_RINGS; i++) {
+ struct eth_tx_next_bd *tx_next_bd =
+ &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd;
- for (i = 1; i <= NUM_TX_RINGS; i++) {
- struct eth_tx_next_bd *tx_next_bd =
- &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd;
+ tx_next_bd->addr_hi =
+ cpu_to_le32(U64_HI(fp->tx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+ tx_next_bd->addr_lo =
+ cpu_to_le32(U64_LO(fp->tx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+ }
- tx_next_bd->addr_hi =
- cpu_to_le32(U64_HI(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- tx_next_bd->addr_lo =
- cpu_to_le32(U64_LO(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- }
+ SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1);
+ fp->tx_db.data.zero_fill1 = 0;
+ fp->tx_db.data.prod = 0;
- SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1);
- fp->tx_db.data.zero_fill1 = 0;
- fp->tx_db.data.prod = 0;
+ fp->tx_pkt_prod = 0;
+ fp->tx_pkt_cons = 0;
+ fp->tx_bd_prod = 0;
+ fp->tx_bd_cons = 0;
+ fp->tx_pkt = 0;
+}
- fp->tx_pkt_prod = 0;
- fp->tx_pkt_cons = 0;
- fp->tx_bd_prod = 0;
- fp->tx_bd_cons = 0;
- fp->tx_pkt = 0;
- }
+static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_tx_queue(bp, i)
+ bnx2x_init_tx_ring_one(&bp->fp[i]);
}
static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp)
@@ -992,6 +1000,44 @@ static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp)
}
}
+/* Returns the number of actually allocated BDs */
+static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
+ int rx_ring_size)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 ring_prod, cqe_ring_prod;
+ int i;
+
+ fp->rx_comp_cons = 0;
+ cqe_ring_prod = ring_prod = 0;
+
+ /* This routine is called only during fo init so
+ * fp->eth_q_stats.rx_skb_alloc_failed = 0
+ */
+ for (i = 0; i < rx_ring_size; i++) {
+ if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
+ fp->eth_q_stats.rx_skb_alloc_failed++;
+ continue;
+ }
+ ring_prod = NEXT_RX_IDX(ring_prod);
+ cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
+ WARN_ON(ring_prod <= (i - fp->eth_q_stats.rx_skb_alloc_failed));
+ }
+
+ if (fp->eth_q_stats.rx_skb_alloc_failed)
+ BNX2X_ERR("was only able to allocate "
+ "%d rx skbs on queue[%d]\n",
+ (i - fp->eth_q_stats.rx_skb_alloc_failed), fp->index);
+
+ fp->rx_bd_prod = ring_prod;
+ /* Limit the CQE producer by the CQE ring size */
+ fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
+ cqe_ring_prod);
+ fp->rx_pkt = fp->rx_calls = 0;
+
+ return i - fp->eth_q_stats.rx_skb_alloc_failed;
+}
+
#ifdef BCM_CNIC
static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
{
@@ -1041,12 +1087,23 @@ static inline void storm_memset_cmng(struct bnx2x *bp,
struct cmng_struct_per_port *cmng,
u8 port)
{
- size_t size = sizeof(struct cmng_struct_per_port);
+ size_t size =
+ sizeof(struct rate_shaping_vars_per_port) +
+ sizeof(struct fairness_vars_per_port) +
+ sizeof(struct safc_struct_per_port) +
+ sizeof(struct pfc_struct_per_port);
u32 addr = BAR_XSTRORM_INTMEM +
XSTORM_CMNG_PER_PORT_VARS_OFFSET(port);
__storm_memset_struct(bp, addr, size, (u32 *)cmng);
+
+ addr += size + 4 /* SKIP DCB+LLFC */;
+ size = sizeof(struct cmng_struct_per_port) -
+ size /* written */ - 4 /*skipped*/;
+
+ __storm_memset_struct(bp, addr, size,
+ (u32 *)(cmng->traffic_type_to_priority_cos));
}
/* HW Lock for shared dual port PHYs */
@@ -1054,12 +1111,11 @@ void bnx2x_acquire_phy_lock(struct bnx2x *bp);
void bnx2x_release_phy_lock(struct bnx2x *bp);
/**
- * Extracts MAX BW part from MF configuration.
+ * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration.
*
- * @param bp
- * @param mf_cfg
+ * @bp: driver handle
+ * @mf_cfg: MF configuration
*
- * @return u16
*/
static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg)
{
diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c
index 9a24d79c71d..410a49e571a 100644
--- a/drivers/net/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/bnx2x/bnx2x_dcb.c
@@ -1,6 +1,6 @@
/* bnx2x_dcb.c: Broadcom Everest network driver.
*
- * Copyright 2009-2010 Broadcom Corporation
+ * Copyright 2009-2011 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -485,6 +485,36 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp)
}
}
+#ifdef BCM_DCBNL
+static int bnx2x_dcbx_read_shmem_remote_mib(struct bnx2x *bp)
+{
+ struct lldp_remote_mib remote_mib = {0};
+ u32 dcbx_remote_mib_offset = SHMEM2_RD(bp, dcbx_remote_mib_offset);
+ int rc;
+
+ DP(NETIF_MSG_LINK, "dcbx_remote_mib_offset 0x%x\n",
+ dcbx_remote_mib_offset);
+
+ if (SHMEM_DCBX_REMOTE_MIB_NONE == dcbx_remote_mib_offset) {
+ BNX2X_ERR("FW doesn't support dcbx_remote_mib_offset\n");
+ return -EINVAL;
+ }
+
+ rc = bnx2x_dcbx_read_mib(bp, (u32 *)&remote_mib, dcbx_remote_mib_offset,
+ DCBX_READ_REMOTE_MIB);
+
+ if (rc) {
+ BNX2X_ERR("Faild to read remote mib from FW\n");
+ return rc;
+ }
+
+ /* save features and flags */
+ bp->dcbx_remote_feat = remote_mib.features;
+ bp->dcbx_remote_flags = remote_mib.flags;
+ return 0;
+}
+#endif
+
static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
{
struct lldp_local_mib local_mib = {0};
@@ -571,6 +601,28 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
{
switch (state) {
case BNX2X_DCBX_STATE_NEG_RECEIVED:
+#ifdef BCM_CNIC
+ if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
+ struct cnic_ops *c_ops;
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+ bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
+ cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO;
+ cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI;
+
+ rcu_read_lock();
+ c_ops = rcu_dereference(bp->cnic_ops);
+ if (c_ops) {
+ bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD);
+ rcu_read_unlock();
+ return;
+ }
+ rcu_read_unlock();
+ }
+
+ /* fall through if no CNIC initialized */
+ case BNX2X_DCBX_STATE_ISCSI_STOPPED:
+#endif
+
{
DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
#ifdef BCM_DCBNL
@@ -579,6 +631,10 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
* negotiation results
*/
bnx2x_dcbnl_update_applist(bp, true);
+
+ /* Read rmeote mib if dcbx is in the FW */
+ if (bnx2x_dcbx_read_shmem_remote_mib(bp))
+ return;
#endif
/* Read neg results if dcbx is in the FW */
if (bnx2x_dcbx_read_shmem_neg_results(bp))
@@ -1057,12 +1113,6 @@ static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp,
}
}
-
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
struct cos_help_data *cos_data,
u32 pri_join_mask)
@@ -1075,11 +1125,6 @@ static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
cos_data->num_of_cos = 1;
}
-/*******************************************************************************
- * Description: updating the cos bw
- *
- * Return:
- ******************************************************************************/
static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
struct cos_entry_help_data *data,
u8 pg_bw)
@@ -1090,11 +1135,6 @@ static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
data->cos_bw += pg_bw;
}
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
struct cos_help_data *cos_data,
u32 *pg_pri_orginal_spread,
@@ -1347,11 +1387,6 @@ static void bnx2x_dcbx_two_pg_to_cos_params(
}
}
-/*******************************************************************************
- * Description: Still
- *
- * Return:
- ******************************************************************************/
static void bnx2x_dcbx_three_pg_to_cos_params(
struct bnx2x *bp,
struct pg_help_data *pg_help_data,
@@ -1539,11 +1574,6 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
}
}
-/*******************************************************************************
- * Description: Fill pfc_config struct that will be sent in DCBX start ramrod
- *
- * Return:
- ******************************************************************************/
static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
{
struct flow_control_configuration *pfc_fw_cfg = NULL;
@@ -2035,7 +2065,6 @@ static u8 bnx2x_dcbnl_set_dcbx(struct net_device *netdev, u8 state)
return 0;
}
-
static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
u8 *flags)
{
@@ -2115,31 +2144,100 @@ static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
return rval;
}
+static int bnx2x_peer_appinfo(struct net_device *netdev,
+ struct dcb_peer_app_info *info, u16* app_count)
+{
+ int i;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(NETIF_MSG_LINK, "APP-INFO\n");
+
+ info->willing = (bp->dcbx_remote_flags & DCBX_APP_REM_WILLING) ?: 0;
+ info->error = (bp->dcbx_remote_flags & DCBX_APP_RX_ERROR) ?: 0;
+ *app_count = 0;
+
+ for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
+ if (bp->dcbx_remote_feat.app.app_pri_tbl[i].appBitfield &
+ DCBX_APP_ENTRY_VALID)
+ (*app_count)++;
+ return 0;
+}
+
+static int bnx2x_peer_apptable(struct net_device *netdev,
+ struct dcb_app *table)
+{
+ int i, j;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(NETIF_MSG_LINK, "APP-TABLE\n");
+
+ for (i = 0, j = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
+ struct dcbx_app_priority_entry *ent =
+ &bp->dcbx_remote_feat.app.app_pri_tbl[i];
+
+ if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
+ table[j].selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
+ table[j].priority = bnx2x_dcbx_dcbnl_app_up(ent);
+ table[j++].protocol = ent->app_id;
+ }
+ }
+ return 0;
+}
+
+static int bnx2x_cee_peer_getpg(struct net_device *netdev, struct cee_pg *pg)
+{
+ int i;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ pg->willing = (bp->dcbx_remote_flags & DCBX_ETS_REM_WILLING) ?: 0;
+
+ for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
+ pg->pg_bw[i] =
+ DCBX_PG_BW_GET(bp->dcbx_remote_feat.ets.pg_bw_tbl, i);
+ pg->prio_pg[i] =
+ DCBX_PRI_PG_GET(bp->dcbx_remote_feat.ets.pri_pg_tbl, i);
+ }
+ return 0;
+}
+
+static int bnx2x_cee_peer_getpfc(struct net_device *netdev,
+ struct cee_pfc *pfc)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ pfc->tcs_supported = bp->dcbx_remote_feat.pfc.pfc_caps;
+ pfc->pfc_en = bp->dcbx_remote_feat.pfc.pri_en_bitmap;
+ return 0;
+}
+
const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
- .getstate = bnx2x_dcbnl_get_state,
- .setstate = bnx2x_dcbnl_set_state,
- .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr,
- .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx,
- .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx,
- .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx,
- .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx,
- .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx,
- .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx,
- .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx,
- .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx,
- .setpfccfg = bnx2x_dcbnl_set_pfc_cfg,
- .getpfccfg = bnx2x_dcbnl_get_pfc_cfg,
- .setall = bnx2x_dcbnl_set_all,
- .getcap = bnx2x_dcbnl_get_cap,
- .getnumtcs = bnx2x_dcbnl_get_numtcs,
- .setnumtcs = bnx2x_dcbnl_set_numtcs,
- .getpfcstate = bnx2x_dcbnl_get_pfc_state,
- .setpfcstate = bnx2x_dcbnl_set_pfc_state,
- .setapp = bnx2x_dcbnl_set_app_up,
- .getdcbx = bnx2x_dcbnl_get_dcbx,
- .setdcbx = bnx2x_dcbnl_set_dcbx,
- .getfeatcfg = bnx2x_dcbnl_get_featcfg,
- .setfeatcfg = bnx2x_dcbnl_set_featcfg,
+ .getstate = bnx2x_dcbnl_get_state,
+ .setstate = bnx2x_dcbnl_set_state,
+ .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr,
+ .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx,
+ .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx,
+ .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx,
+ .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx,
+ .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx,
+ .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx,
+ .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx,
+ .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx,
+ .setpfccfg = bnx2x_dcbnl_set_pfc_cfg,
+ .getpfccfg = bnx2x_dcbnl_get_pfc_cfg,
+ .setall = bnx2x_dcbnl_set_all,
+ .getcap = bnx2x_dcbnl_get_cap,
+ .getnumtcs = bnx2x_dcbnl_get_numtcs,
+ .setnumtcs = bnx2x_dcbnl_set_numtcs,
+ .getpfcstate = bnx2x_dcbnl_get_pfc_state,
+ .setpfcstate = bnx2x_dcbnl_set_pfc_state,
+ .setapp = bnx2x_dcbnl_set_app_up,
+ .getdcbx = bnx2x_dcbnl_get_dcbx,
+ .setdcbx = bnx2x_dcbnl_set_dcbx,
+ .getfeatcfg = bnx2x_dcbnl_get_featcfg,
+ .setfeatcfg = bnx2x_dcbnl_set_featcfg,
+ .peer_getappinfo = bnx2x_peer_appinfo,
+ .peer_getapptable = bnx2x_peer_apptable,
+ .cee_peer_getpg = bnx2x_cee_peer_getpg,
+ .cee_peer_getpfc = bnx2x_cee_peer_getpfc,
};
#endif /* BCM_DCBNL */
diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h
index 71b8eda43bd..bed369d67e0 100644
--- a/drivers/net/bnx2x/bnx2x_dcb.h
+++ b/drivers/net/bnx2x/bnx2x_dcb.h
@@ -1,6 +1,6 @@
/* bnx2x_dcb.h: Broadcom Everest network driver.
*
- * Copyright 2009-2010 Broadcom Corporation
+ * Copyright 2009-2011 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -61,9 +61,6 @@ struct bnx2x_dcbx_port_params {
#define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE 1
#define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID (BNX2X_DCBX_CONFIG_INV_VALUE)
-/*******************************************************************************
- * LLDP protocol configuration parameters.
- ******************************************************************************/
struct bnx2x_config_lldp_params {
u32 overwrite_settings;
u32 msg_tx_hold;
@@ -83,9 +80,6 @@ struct bnx2x_admin_priority_app_table {
u32 app_id;
};
-/*******************************************************************************
- * DCBX protocol configuration parameters.
- ******************************************************************************/
struct bnx2x_config_dcbx_params {
u32 overwrite_settings;
u32 admin_dcbx_version;
@@ -183,9 +177,13 @@ void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled);
enum {
BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1,
- BNX2X_DCBX_STATE_TX_PAUSED = 0x2,
- BNX2X_DCBX_STATE_TX_RELEASED = 0x4
+#ifdef BCM_CNIC
+ BNX2X_DCBX_STATE_ISCSI_STOPPED,
+#endif
+ BNX2X_DCBX_STATE_TX_PAUSED,
+ BNX2X_DCBX_STATE_TX_RELEASED
};
+
void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
/* DCB netlink */
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 89cb977898c..727fe89ff37 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1,6 +1,6 @@
/* bnx2x_ethtool.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -167,6 +167,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+
/* Dual Media boards present all available port types */
cmd->supported = bp->port.supported[cfg_idx] |
(bp->port.supported[cfg_idx ^ 1] &
@@ -176,16 +177,16 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if ((bp->state == BNX2X_STATE_OPEN) &&
!(bp->flags & MF_FUNC_DIS) &&
(bp->link_vars.link_up)) {
- cmd->speed = bp->link_vars.line_speed;
+ ethtool_cmd_speed_set(cmd, bp->link_vars.line_speed);
cmd->duplex = bp->link_vars.duplex;
} else {
-
- cmd->speed = bp->link_params.req_line_speed[cfg_idx];
+ ethtool_cmd_speed_set(
+ cmd, bp->link_params.req_line_speed[cfg_idx]);
cmd->duplex = bp->link_params.req_duplex[cfg_idx];
}
if (IS_MF(bp))
- cmd->speed = bnx2x_get_mf_speed(bp);
+ ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp));
if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
cmd->port = PORT_TP;
@@ -206,10 +207,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->maxrxpkt = 0;
DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
+ DP_LEVEL " supported 0x%x advertising 0x%x speed %u\n"
DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+ cmd->cmd, cmd->supported, cmd->advertising,
+ ethtool_cmd_speed(cmd),
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
@@ -226,16 +228,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return 0;
DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- " supported 0x%x advertising 0x%x speed %d speed_hi %d\n"
+ " supported 0x%x advertising 0x%x speed %u\n"
" duplex %d port %d phy_address %d transceiver %d\n"
" autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
- cmd->speed_hi,
+ cmd->cmd, cmd->supported, cmd->advertising,
+ ethtool_cmd_speed(cmd),
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
- speed = cmd->speed;
- speed |= (cmd->speed_hi << 16);
+ speed = ethtool_cmd_speed(cmd);
if (IS_MF_SI(bp)) {
u32 part;
@@ -439,7 +440,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
default:
- DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed);
+ DP(NETIF_MSG_LINK, "Unsupported speed %u\n", speed);
return -EINVAL;
}
@@ -1219,7 +1220,8 @@ static int bnx2x_set_ringparam(struct net_device *dev,
}
if ((ering->rx_pending > MAX_RX_AVAIL) ||
- (ering->rx_pending < MIN_RX_AVAIL) ||
+ (ering->rx_pending < (bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+ MIN_RX_SIZE_TPA)) ||
(ering->tx_pending > MAX_TX_AVAIL) ||
(ering->tx_pending <= MAX_SKB_FRAGS + 4))
return -EINVAL;
@@ -1299,91 +1301,6 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
return 0;
}
-static int bnx2x_set_flags(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int changed = 0;
- int rc = 0;
-
- if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
- printk(KERN_ERR "Handling parity error recovery. Try again later\n");
- return -EAGAIN;
- }
-
- if (!(data & ETH_FLAG_RXVLAN))
- return -EINVAL;
-
- if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
- return -EINVAL;
-
- rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN |
- ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
- if (rc)
- return rc;
-
- /* TPA requires Rx CSUM offloading */
- if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
- if (!(bp->flags & TPA_ENABLE_FLAG)) {
- bp->flags |= TPA_ENABLE_FLAG;
- changed = 1;
- }
- } else if (bp->flags & TPA_ENABLE_FLAG) {
- dev->features &= ~NETIF_F_LRO;
- bp->flags &= ~TPA_ENABLE_FLAG;
- changed = 1;
- }
-
- if (changed && netif_running(dev)) {
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- rc = bnx2x_nic_load(bp, LOAD_NORMAL);
- }
-
- return rc;
-}
-
-static u32 bnx2x_get_rx_csum(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- return bp->rx_csum;
-}
-
-static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc = 0;
-
- if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
- printk(KERN_ERR "Handling parity error recovery. Try again later\n");
- return -EAGAIN;
- }
-
- bp->rx_csum = data;
-
- /* Disable TPA, when Rx CSUM is disabled. Otherwise all
- TPA'ed packets will be discarded due to wrong TCP CSUM */
- if (!data) {
- u32 flags = ethtool_op_get_flags(dev);
-
- rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
- }
-
- return rc;
-}
-
-static int bnx2x_set_tso(struct net_device *dev, u32 data)
-{
- if (data) {
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features |= NETIF_F_TSO6;
- } else {
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features &= ~NETIF_F_TSO6;
- }
-
- return 0;
-}
-
static const struct {
char string[ETH_GSTRING_LEN];
} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
@@ -2097,35 +2014,37 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
}
}
-static int bnx2x_phys_id(struct net_device *dev, u32 data)
+static int bnx2x_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct bnx2x *bp = netdev_priv(dev);
- int i;
if (!netif_running(dev))
- return 0;
+ return -EAGAIN;
if (!bp->port.pmf)
- return 0;
+ return -EOPNOTSUPP;
- if (data == 0)
- data = 2;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0)
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_ON, SPEED_1000);
- else
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_FRONT_PANEL_OFF, 0);
+ case ETHTOOL_ID_ON:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_ON, SPEED_1000);
+ break;
- msleep_interruptible(500);
- if (signal_pending(current))
- break;
- }
+ case ETHTOOL_ID_OFF:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_FRONT_PANEL_OFF, 0);
+
+ break;
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_OPER, bp->link_vars.line_speed);
+ case ETHTOOL_ID_INACTIVE:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_OPER,
+ bp->link_vars.line_speed);
+ }
return 0;
}
@@ -2204,20 +2123,10 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
.set_ringparam = bnx2x_set_ringparam,
.get_pauseparam = bnx2x_get_pauseparam,
.set_pauseparam = bnx2x_set_pauseparam,
- .get_rx_csum = bnx2x_get_rx_csum,
- .set_rx_csum = bnx2x_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .set_flags = bnx2x_set_flags,
- .get_flags = ethtool_op_get_flags,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = bnx2x_set_tso,
.self_test = bnx2x_self_test,
.get_sset_count = bnx2x_get_sset_count,
.get_strings = bnx2x_get_strings,
- .phys_id = bnx2x_phys_id,
+ .set_phys_id = bnx2x_set_phys_id,
.get_ethtool_stats = bnx2x_get_ethtool_stats,
.get_rxnfc = bnx2x_get_rxnfc,
.get_rxfh_indir = bnx2x_get_rxfh_indir,
diff --git a/drivers/net/bnx2x/bnx2x_fw_defs.h b/drivers/net/bnx2x/bnx2x_fw_defs.h
index f4e5b1ce814..9fe367836a5 100644
--- a/drivers/net/bnx2x/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x/bnx2x_fw_defs.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_defs.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
index f807262911e..f4a07fbaed0 100644
--- a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
+++ b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_file_hdr.h: FW binary file header structure.
*
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h
index dac1bf9cbbf..cdf19fe7c7f 100644
--- a/drivers/net/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/bnx2x/bnx2x_hsi.h
@@ -1,6 +1,6 @@
/* bnx2x_hsi.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1929,7 +1929,7 @@ struct host_func_stats {
#define BCM_5710_FW_MAJOR_VERSION 6
#define BCM_5710_FW_MINOR_VERSION 2
-#define BCM_5710_FW_REVISION_VERSION 5
+#define BCM_5710_FW_REVISION_VERSION 9
#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h
index fa6dbe3f205..d5399206f66 100644
--- a/drivers/net/bnx2x/bnx2x_init.h
+++ b/drivers/net/bnx2x/bnx2x_init.h
@@ -1,7 +1,7 @@
/* bnx2x_init.h: Broadcom Everest network driver.
* Structures and macroes needed during the initialization.
*
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h
index 66df29fcf75..aafd0232393 100644
--- a/drivers/net/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x/bnx2x_init_ops.h
@@ -2,7 +2,7 @@
* Static functions needed during the initialization.
* This file is "included" in bnx2x_main.c.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 974ef2be36a..076e11f5769 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -385,7 +385,7 @@ u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
return 0;
}
/******************************************************************/
-/* ETS section */
+/* PFC section */
/******************************************************************/
static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
@@ -1301,14 +1301,12 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
return 0;
}
-/*
- * get_emac_base
- *
- * @param cb
- * @param mdc_mdio_access
- * @param port
+/**
+ * bnx2x_get_emac_base - retrive emac base address
*
- * @return u32
+ * @bp: driver handle
+ * @mdc_mdio_access: access type
+ * @port: port id
*
* This function selects the MDC/MDIO access (through emac0 or
* emac1) depend on the mdc_mdio_access, port, port swapped. Each
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index a97a4a1c344..f45c0caf324 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -1,6 +1,6 @@
/* bnx2x_main.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -2036,7 +2036,7 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp)
return CMNG_FNS_NONE;
}
-static void bnx2x_read_mf_cfg(struct bnx2x *bp)
+void bnx2x_read_mf_cfg(struct bnx2x *bp)
{
int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1);
@@ -2123,7 +2123,6 @@ static inline void bnx2x_link_sync_notify(struct bnx2x *bp)
/* This function is called upon link interrupt */
static void bnx2x_link_attn(struct bnx2x *bp)
{
- u32 prev_link_status = bp->link_vars.link_status;
/* Make sure that we are synced with the current statistics */
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -2168,17 +2167,15 @@ static void bnx2x_link_attn(struct bnx2x *bp)
"single function mode without fairness\n");
}
+ __bnx2x_link_report(bp);
+
if (IS_MF(bp))
bnx2x_link_sync_notify(bp);
-
- /* indicate link status only if link status actually changed */
- if (prev_link_status != bp->link_vars.link_status)
- bnx2x_link_report(bp);
}
void bnx2x__link_status_update(struct bnx2x *bp)
{
- if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS))
+ if (bp->state != BNX2X_STATE_OPEN)
return;
bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
@@ -2188,10 +2185,6 @@ void bnx2x__link_status_update(struct bnx2x *bp)
else
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- /* the link status update could be the result of a DCC event
- hence re-read the shmem mf configuration */
- bnx2x_read_mf_cfg(bp);
-
/* indicate link status */
bnx2x_link_report(bp);
}
@@ -3120,10 +3113,14 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
if (val & DRV_STATUS_SET_MF_BW)
bnx2x_set_mf_bw(bp);
- bnx2x__link_status_update(bp);
if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF))
bnx2x_pmf_update(bp);
+ /* Always call it here: bnx2x_link_report() will
+ * prevent the link indication duplication.
+ */
+ bnx2x__link_status_update(bp);
+
if (bp->port.pmf &&
(val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS) &&
bp->dcbx_enabled > 0)
@@ -3904,10 +3901,9 @@ static void bnx2x_timer(unsigned long data)
if (poll) {
struct bnx2x_fastpath *fp = &bp->fp[0];
- int rc;
bnx2x_tx_int(fp);
- rc = bnx2x_rx_int(fp, 1000);
+ bnx2x_rx_int(fp, 1000);
}
if (!BP_NOMCP(bp)) {
@@ -4062,7 +4058,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
struct hc_status_block_data_e2 sb_data_e2;
struct hc_status_block_data_e1x sb_data_e1x;
struct hc_status_block_sm *hc_sm_p;
- struct hc_index_data *hc_index_p;
int data_size;
u32 *sb_data_p;
@@ -4083,7 +4078,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
sb_data_e2.common.host_sb_addr.hi = U64_HI(mapping);
sb_data_e2.common.host_sb_addr.lo = U64_LO(mapping);
hc_sm_p = sb_data_e2.common.state_machine;
- hc_index_p = sb_data_e2.index_data;
sb_data_p = (u32 *)&sb_data_e2;
data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32);
} else {
@@ -4097,7 +4091,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping);
sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping);
hc_sm_p = sb_data_e1x.common.state_machine;
- hc_index_p = sb_data_e1x.index_data;
sb_data_p = (u32 *)&sb_data_e1x;
data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32);
}
@@ -4454,7 +4447,7 @@ static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx)
fp->state = BNX2X_FP_STATE_CLOSED;
- fp->index = fp->cid = fp_idx;
+ fp->cid = fp_idx;
fp->cl_id = BP_L_ID(bp) + fp_idx;
fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE;
fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE;
@@ -4566,9 +4559,11 @@ gunzip_nomem1:
static void bnx2x_gunzip_end(struct bnx2x *bp)
{
- kfree(bp->strm->workspace);
- kfree(bp->strm);
- bp->strm = NULL;
+ if (bp->strm) {
+ kfree(bp->strm->workspace);
+ kfree(bp->strm);
+ bp->strm = NULL;
+ }
if (bp->gunzip_buf) {
dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf,
@@ -5876,9 +5871,6 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
bp->dmae_ready = 0;
spin_lock_init(&bp->dmae_lock);
- rc = bnx2x_gunzip_init(bp);
- if (rc)
- return rc;
switch (load_code) {
case FW_MSG_CODE_DRV_LOAD_COMMON:
@@ -5922,80 +5914,10 @@ init_hw_err:
void bnx2x_free_mem(struct bnx2x *bp)
{
-
-#define BNX2X_PCI_FREE(x, y, size) \
- do { \
- if (x) { \
- dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
- x = NULL; \
- y = 0; \
- } \
- } while (0)
-
-#define BNX2X_FREE(x) \
- do { \
- if (x) { \
- kfree((void *)x); \
- x = NULL; \
- } \
- } while (0)
-
- int i;
+ bnx2x_gunzip_end(bp);
/* fastpath */
- /* Common */
- for_each_queue(bp, i) {
-#ifdef BCM_CNIC
- /* FCoE client uses default status block */
- if (IS_FCOE_IDX(i)) {
- union host_hc_status_block *sb =
- &bnx2x_fp(bp, i, status_blk);
- memset(sb, 0, sizeof(union host_hc_status_block));
- bnx2x_fp(bp, i, status_blk_mapping) = 0;
- } else {
-#endif
- /* status blocks */
- if (CHIP_IS_E2(bp))
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb),
- bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e2));
- else
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb),
- bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e1x));
-#ifdef BCM_CNIC
- }
-#endif
- }
- /* Rx */
- for_each_rx_queue(bp, i) {
-
- /* fastpath rx rings: rx_buf rx_desc rx_comp */
- BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
- bnx2x_fp(bp, i, rx_desc_mapping),
- sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring),
- bnx2x_fp(bp, i, rx_comp_mapping),
- sizeof(struct eth_fast_path_rx_cqe) *
- NUM_RCQ_BD);
-
- /* SGE ring */
- BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring),
- bnx2x_fp(bp, i, rx_sge_mapping),
- BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
- }
- /* Tx */
- for_each_tx_queue(bp, i) {
-
- /* fastpath tx rings: tx_buf tx_desc */
- BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
- bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(union eth_tx_bd_types) * NUM_TX_BD);
- }
+ bnx2x_free_fp_mem(bp);
/* end of fastpath */
BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
@@ -6028,101 +5950,13 @@ void bnx2x_free_mem(struct bnx2x *bp)
BCM_PAGE_SIZE * NUM_EQ_PAGES);
BNX2X_FREE(bp->rx_indir_table);
-
-#undef BNX2X_PCI_FREE
-#undef BNX2X_KFREE
}
-static inline void set_sb_shortcuts(struct bnx2x *bp, int index)
-{
- union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk);
- if (CHIP_IS_E2(bp)) {
- bnx2x_fp(bp, index, sb_index_values) =
- (__le16 *)status_blk.e2_sb->sb.index_values;
- bnx2x_fp(bp, index, sb_running_index) =
- (__le16 *)status_blk.e2_sb->sb.running_index;
- } else {
- bnx2x_fp(bp, index, sb_index_values) =
- (__le16 *)status_blk.e1x_sb->sb.index_values;
- bnx2x_fp(bp, index, sb_running_index) =
- (__le16 *)status_blk.e1x_sb->sb.running_index;
- }
-}
int bnx2x_alloc_mem(struct bnx2x *bp)
{
-#define BNX2X_PCI_ALLOC(x, y, size) \
- do { \
- x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
- if (x == NULL) \
- goto alloc_mem_err; \
- memset(x, 0, size); \
- } while (0)
-
-#define BNX2X_ALLOC(x, size) \
- do { \
- x = kzalloc(size, GFP_KERNEL); \
- if (x == NULL) \
- goto alloc_mem_err; \
- } while (0)
-
- int i;
-
- /* fastpath */
- /* Common */
- for_each_queue(bp, i) {
- union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk);
- bnx2x_fp(bp, i, bp) = bp;
- /* status blocks */
-#ifdef BCM_CNIC
- if (!IS_FCOE_IDX(i)) {
-#endif
- if (CHIP_IS_E2(bp))
- BNX2X_PCI_ALLOC(sb->e2_sb,
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e2));
- else
- BNX2X_PCI_ALLOC(sb->e1x_sb,
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e1x));
-#ifdef BCM_CNIC
- }
-#endif
- set_sb_shortcuts(bp, i);
- }
- /* Rx */
- for_each_queue(bp, i) {
-
- /* fastpath rx rings: rx_buf rx_desc rx_comp */
- BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
- sizeof(struct sw_rx_bd) * NUM_RX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
- &bnx2x_fp(bp, i, rx_desc_mapping),
- sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring),
- &bnx2x_fp(bp, i, rx_comp_mapping),
- sizeof(struct eth_fast_path_rx_cqe) *
- NUM_RCQ_BD);
-
- /* SGE ring */
- BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring),
- sizeof(struct sw_rx_page) * NUM_RX_SGE);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring),
- &bnx2x_fp(bp, i, rx_sge_mapping),
- BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
- }
- /* Tx */
- for_each_queue(bp, i) {
-
- /* fastpath tx rings: tx_buf tx_desc */
- BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
- sizeof(struct sw_tx_bd) * NUM_TX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
- &bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(union eth_tx_bd_types) * NUM_TX_BD);
- }
- /* end of fastpath */
+ if (bnx2x_gunzip_init(bp))
+ return -ENOMEM;
#ifdef BCM_CNIC
if (CHIP_IS_E2(bp))
@@ -6162,14 +5996,18 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) *
TSTORM_INDIRECTION_TABLE_SIZE);
+
+ /* fastpath */
+ /* need to be done at the end, since it's self adjusting to amount
+ * of memory available for RSS queues
+ */
+ if (bnx2x_alloc_fp_mem(bp))
+ goto alloc_mem_err;
return 0;
alloc_mem_err:
bnx2x_free_mem(bp);
return -ENOMEM;
-
-#undef BNX2X_PCI_ALLOC
-#undef BNX2X_ALLOC
}
/*
@@ -6197,14 +6035,14 @@ static int bnx2x_func_stop(struct bnx2x *bp)
}
/**
- * Sets a MAC in a CAM for a few L2 Clients for E1x chips
+ * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips
*
- * @param bp driver descriptor
- * @param set set or clear an entry (1 or 0)
- * @param mac pointer to a buffer containing a MAC
- * @param cl_bit_vec bit vector of clients to register a MAC for
- * @param cam_offset offset in a CAM to use
- * @param is_bcast is the set MAC a broadcast address (for E1 only)
+ * @bp: driver handle
+ * @set: set or clear an entry (1 or 0)
+ * @mac: pointer to a buffer containing a MAC
+ * @cl_bit_vec: bit vector of clients to register a MAC for
+ * @cam_offset: offset in a CAM to use
+ * @is_bcast: is the set MAC a broadcast address (for E1 only)
*/
static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
u32 cl_bit_vec, u8 cam_offset,
@@ -6564,14 +6402,13 @@ void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp)
#ifdef BCM_CNIC
/**
- * Set iSCSI MAC(s) at the next enties in the CAM after the ETH
- * MAC(s). This function will wait until the ramdord completion
- * returns.
+ * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s).
*
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp: driver handle
+ * @set: set or clear the CAM entry
*
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * This function will wait until the ramdord completion returns.
+ * Return 0 if success, -ENODEV if ramrod doesn't return.
*/
static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
{
@@ -6592,14 +6429,13 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
}
/**
- * Set FCoE L2 MAC(s) at the next enties in the CAM after the
- * ETH MAC(s). This function will wait until the ramdord
- * completion returns.
+ * bnx2x_set_fip_eth_mac_addr - set FCoE L2 MAC(s)
*
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp: driver handle
+ * @set: set or clear the CAM entry
*
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * This function will wait until the ramrod completion returns.
+ * Returns 0 if success, -ENODEV if ramrod doesn't return.
*/
int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set)
{
@@ -6803,12 +6639,11 @@ static int bnx2x_setup_fw_client(struct bnx2x *bp,
}
/**
- * Configure interrupt mode according to current configuration.
- * In case of MSI-X it will also try to enable MSI-X.
+ * bnx2x_set_int_mode - configure interrupt mode
*
- * @param bp
+ * @bp: driver handle
*
- * @return int
+ * In case of MSI-X it will also try to enable MSI-X.
*/
static int __devinit bnx2x_set_int_mode(struct bnx2x *bp)
{
@@ -7392,10 +7227,11 @@ static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val)
MF_CFG_WR(bp, shared_mf_config.clp_mb, val | SHARED_MF_CLP_MAGIC);
}
-/* Restore the value of the `magic' bit.
+/**
+ * bnx2x_clp_reset_done - restore the value of the `magic' bit.
*
- * @param pdev Device handle.
- * @param magic_val Old value of the `magic' bit.
+ * @bp: driver handle
+ * @magic_val: old value of the `magic' bit.
*/
static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val)
{
@@ -7406,10 +7242,12 @@ static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val)
}
/**
- * Prepares for MCP reset: takes care of CLP configurations.
+ * bnx2x_reset_mcp_prep - prepare for MCP reset.
*
- * @param bp
- * @param magic_val Old value of 'magic' bit.
+ * @bp: driver handle
+ * @magic_val: old value of 'magic' bit.
+ *
+ * Takes care of CLP configurations.
*/
static void bnx2x_reset_mcp_prep(struct bnx2x *bp, u32 *magic_val)
{
@@ -7434,10 +7272,10 @@ static void bnx2x_reset_mcp_prep(struct bnx2x *bp, u32 *magic_val)
#define MCP_TIMEOUT 5000 /* 5 seconds (in ms) */
#define MCP_ONE_TIMEOUT 100 /* 100 ms */
-/* Waits for MCP_ONE_TIMEOUT or MCP_ONE_TIMEOUT*10,
- * depending on the HW type.
+/**
+ * bnx2x_mcp_wait_one - wait for MCP_ONE_TIMEOUT
*
- * @param bp
+ * @bp: driver handle
*/
static inline void bnx2x_mcp_wait_one(struct bnx2x *bp)
{
@@ -8059,13 +7897,9 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
(val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ?
FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0;
- if (BP_E1HVN(bp) == 0) {
- pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
- bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
- } else {
- /* no WOL capability for E1HVN != 0 */
- bp->flags |= NO_WOL_FLAG;
- }
+ pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
+ bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
+
BNX2X_DEV_INFO("%sWoL capable\n",
(bp->flags & NO_WOL_FLAG) ? "not " : "");
@@ -8571,15 +8405,6 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
BNX2X_DEV_INFO("Read iSCSI MAC: "
"0x%x:0x%04x\n", val2, val);
bnx2x_set_mac_buf(iscsi_mac, val, val2);
-
- /* Disable iSCSI OOO if MAC configuration is
- * invalid.
- */
- if (!is_valid_ether_addr(iscsi_mac)) {
- bp->flags |= NO_ISCSI_OOO_FLAG |
- NO_ISCSI_FLAG;
- memset(iscsi_mac, 0, ETH_ALEN);
- }
} else
bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
@@ -8592,13 +8417,6 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
"0x%x:0x%04x\n", val2, val);
bnx2x_set_mac_buf(fip_mac, val, val2);
- /* Disable FCoE if MAC configuration is
- * invalid.
- */
- if (!is_valid_ether_addr(fip_mac)) {
- bp->flags |= NO_FCOE_FLAG;
- memset(bp->fip_mac, 0, ETH_ALEN);
- }
} else
bp->flags |= NO_FCOE_FLAG;
}
@@ -8629,13 +8447,29 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
else if (!IS_MF(bp))
memcpy(fip_mac, iscsi_mac, ETH_ALEN);
}
+
+ /* Disable iSCSI if MAC configuration is
+ * invalid.
+ */
+ if (!is_valid_ether_addr(iscsi_mac)) {
+ bp->flags |= NO_ISCSI_FLAG;
+ memset(iscsi_mac, 0, ETH_ALEN);
+ }
+
+ /* Disable FCoE if MAC configuration is
+ * invalid.
+ */
+ if (!is_valid_ether_addr(fip_mac)) {
+ bp->flags |= NO_FCOE_FLAG;
+ memset(bp->fip_mac, 0, ETH_ALEN);
+ }
#endif
}
static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
{
int /*abs*/func = BP_ABS_FUNC(bp);
- int vn, port;
+ int vn;
u32 val = 0;
int rc = 0;
@@ -8670,7 +8504,6 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
bp->mf_ov = 0;
bp->mf_mode = 0;
vn = BP_E1HVN(bp);
- port = BP_PORT(bp);
if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) {
DP(NETIF_MSG_PROBE,
@@ -8904,8 +8737,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->multi_mode = multi_mode;
bp->int_mode = int_mode;
- bp->dev->features |= NETIF_F_GRO;
-
/* Set TPA flags */
if (disable_tpa) {
bp->flags &= ~TPA_ENABLE_FLAG;
@@ -8925,8 +8756,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->tx_ring_size = MAX_TX_AVAIL;
- bp->rx_csum = 1;
-
/* make sure that the numbers are in the right granularity */
bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR;
bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR;
@@ -9304,6 +9133,8 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = bnx2x_ioctl,
.ndo_change_mtu = bnx2x_change_mtu,
+ .ndo_fix_features = bnx2x_fix_features,
+ .ndo_set_features = bnx2x_set_features,
.ndo_tx_timeout = bnx2x_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = poll_bnx2x,
@@ -9430,20 +9261,20 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
dev->netdev_ops = &bnx2x_netdev_ops;
bnx2x_set_ethtool_ops(dev);
- dev->features |= NETIF_F_SG;
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
+ NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_TX;
+
+ dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
+
+ dev->features |= dev->hw_features | NETIF_F_HW_VLAN_RX;
if (bp->flags & USING_DAC_FLAG)
dev->features |= NETIF_F_HIGHDMA;
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features |= NETIF_F_TSO6;
- dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
- dev->vlan_features |= NETIF_F_SG;
- dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- if (bp->flags & USING_DAC_FLAG)
- dev->vlan_features |= NETIF_F_HIGHDMA;
- dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->vlan_features |= NETIF_F_TSO6;
+ /* Add Loopback capability to the device */
+ dev->hw_features |= NETIF_F_LOOPBACK;
#ifdef BCM_DCBNL
dev->dcbnl_ops = &bnx2x_dcbnl_ops;
@@ -10342,6 +10173,11 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
break;
}
+ case DRV_CTL_ISCSI_STOPPED_CMD: {
+ bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_ISCSI_STOPPED);
+ break;
+ }
+
default:
BNX2X_ERR("unknown command %x\n", ctl->cmd);
rc = -EINVAL;
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h
index 1509a2318af..86bba25d2d3 100644
--- a/drivers/net/bnx2x/bnx2x_reg.h
+++ b/drivers/net/bnx2x/bnx2x_reg.h
@@ -1,6 +1,6 @@
/* bnx2x_reg.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c
index 3445ded6674..e535bfa0894 100644
--- a/drivers/net/bnx2x/bnx2x_stats.c
+++ b/drivers/net/bnx2x/bnx2x_stats.c
@@ -1,6 +1,6 @@
/* bnx2x_stats.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h
index 596798c4745..45d14d8bc1a 100644
--- a/drivers/net/bnx2x/bnx2x_stats.h
+++ b/drivers/net/bnx2x/bnx2x_stats.h
@@ -1,6 +1,6 @@
/* bnx2x_stats.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by