Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-next-2.6
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 5fedc27..0dbb4cb 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -293,7 +293,8 @@
 
 		if (msecs > 4000) {
 			dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
-			be_detect_dump_ue(adapter);
+			if (!lancer_chip(adapter))
+				be_detect_dump_ue(adapter);
 			return -1;
 		}
 
@@ -729,8 +730,6 @@
 	if (lancer_chip(adapter)) {
 		req->hdr.version = 2;
 		req->page_size = 1; /* 1 for 4K */
-		AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt,
-								coalesce_wm);
 		AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt,
 								no_delay);
 		AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt,
@@ -1405,12 +1404,24 @@
 /* Uses MCC for this command as it may be called in BH context
  * Uses synchronous mcc
  */
-int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
+int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
 {
 	struct be_mcc_wrb *wrb;
-	struct be_cmd_req_promiscuous_config *req;
+	struct be_cmd_req_rx_filter *req;
+	struct be_dma_mem promiscous_cmd;
+	struct be_sge *sge;
 	int status;
 
+	memset(&promiscous_cmd, 0, sizeof(struct be_dma_mem));
+	promiscous_cmd.size = sizeof(struct be_cmd_req_rx_filter);
+	promiscous_cmd.va = pci_alloc_consistent(adapter->pdev,
+				promiscous_cmd.size, &promiscous_cmd.dma);
+	if (!promiscous_cmd.va) {
+		dev_err(&adapter->pdev->dev,
+				"Memory allocation failure\n");
+		return -ENOMEM;
+	}
+
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
@@ -1418,26 +1429,30 @@
 		status = -EBUSY;
 		goto err;
 	}
-	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_PROMISCUOUS);
+	req = promiscous_cmd.va;
+	sge = nonembedded_sgl(wrb);
 
-	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
-		OPCODE_ETH_PROMISCUOUS, sizeof(*req));
+	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+					OPCODE_COMMON_NTWK_RX_FILTER);
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+			OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
 
-	/* In FW versions X.102.149/X.101.487 and later,
-	 * the port setting associated only with the
-	 * issuing pci function will take effect
-	 */
-	if (port_num)
-		req->port1_promiscuous = en;
-	else
-		req->port0_promiscuous = en;
+	req->if_id = cpu_to_le32(adapter->if_handle);
+	req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
+	if (en)
+		req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
+
+	sge->pa_hi = cpu_to_le32(upper_32_bits(promiscous_cmd.dma));
+	sge->pa_lo = cpu_to_le32(promiscous_cmd.dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(promiscous_cmd.size);
 
 	status = be_mcc_notify_wait(adapter);
 
 err:
 	spin_unlock_bh(&adapter->mcc_lock);
+	pci_free_consistent(adapter->pdev, promiscous_cmd.size,
+			promiscous_cmd.va, promiscous_cmd.dma);
 	return status;
 }
 
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index af4bbff..78256b6 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -714,13 +714,6 @@
 	u16 normal_vlan[64];
 } __packed;
 
-struct be_cmd_req_promiscuous_config {
-	struct be_cmd_req_hdr hdr;
-	u8 port0_promiscuous;
-	u8 port1_promiscuous;
-	u16 rsvd0;
-} __packed;
-
 /******************** Multicast MAC Config *******************/
 #define BE_MAX_MC		64 /* set mcast promisc if > 64 */
 struct macaddr {
@@ -741,6 +734,20 @@
 	return &cmd->hw_stats;
 }
 
+
+/******************* RX FILTER ******************************/
+struct be_cmd_req_rx_filter {
+	struct be_cmd_req_hdr hdr;
+	u32 global_flags_mask;
+	u32 global_flags;
+	u32 if_flags_mask;
+	u32 if_flags;
+	u32 if_id;
+	u32 multicast_num;
+	struct macaddr mac[BE_MAX_MC];
+};
+
+
 /******************** Link Status Query *******************/
 struct be_cmd_req_link_status {
 	struct be_cmd_req_hdr hdr;
@@ -1122,8 +1129,7 @@
 extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
 			u16 *vtag_array, u32 num, bool untagged,
 			bool promiscuous);
-extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
-			u8 port_num, bool en);
+extern int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en);
 extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 			struct net_device *netdev, struct be_dma_mem *mem);
 extern int be_cmd_set_flow_control(struct be_adapter *adapter,
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 3fb4a1f..243172b 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -698,7 +698,7 @@
 	struct be_adapter *adapter = netdev_priv(netdev);
 
 	if (netdev->flags & IFF_PROMISC) {
-		be_cmd_promiscuous_config(adapter, adapter->port_num, 1);
+		be_cmd_promiscuous_config(adapter, true);
 		adapter->promiscuous = true;
 		goto done;
 	}
@@ -706,7 +706,7 @@
 	/* BE was previously in promiscuous mode; disable it */
 	if (adapter->promiscuous) {
 		adapter->promiscuous = false;
-		be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
+		be_cmd_promiscuous_config(adapter, false);
 	}
 
 	/* Enable multicast promisc if num configured exceeds what we support */
@@ -1275,7 +1275,7 @@
 	return txcp;
 }
 
-static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
+static u16 be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
 {
 	struct be_queue_info *txq = &adapter->tx_obj.q;
 	struct be_eth_wrb *wrb;
@@ -1302,9 +1302,8 @@
 		queue_tail_inc(txq);
 	} while (cur_index != last_index);
 
-	atomic_sub(num_wrbs, &txq->used);
-
 	kfree_skb(sent_skb);
+	return num_wrbs;
 }
 
 static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
@@ -1387,7 +1386,7 @@
 	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
 	struct be_queue_info *txq = &adapter->tx_obj.q;
 	struct be_eth_tx_compl *txcp;
-	u16 end_idx, cmpl = 0, timeo = 0;
+	u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0;
 	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
 	struct sk_buff *sent_skb;
 	bool dummy_wrb;
@@ -1397,12 +1396,14 @@
 		while ((txcp = be_tx_compl_get(tx_cq))) {
 			end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
 					wrb_index, txcp);
-			be_tx_compl_process(adapter, end_idx);
+			num_wrbs += be_tx_compl_process(adapter, end_idx);
 			cmpl++;
 		}
 		if (cmpl) {
 			be_cq_notify(adapter, tx_cq->id, false, cmpl);
+			atomic_sub(num_wrbs, &txq->used);
 			cmpl = 0;
+			num_wrbs = 0;
 		}
 
 		if (atomic_read(&txq->used) == 0 || ++timeo > 200)
@@ -1422,7 +1423,8 @@
 		index_adv(&end_idx,
 			wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1,
 			txq->len);
-		be_tx_compl_process(adapter, end_idx);
+		num_wrbs = be_tx_compl_process(adapter, end_idx);
+		atomic_sub(num_wrbs, &txq->used);
 	}
 }
 
@@ -1757,12 +1759,15 @@
 			break;
 
 		/* Ignore flush completions */
-		if (rxcp->num_rcvd) {
+		if (rxcp->num_rcvd && rxcp->pkt_size) {
 			if (do_gro(rxcp))
 				be_rx_compl_process_gro(adapter, rxo, rxcp);
 			else
 				be_rx_compl_process(adapter, rxo, rxcp);
+		} else if (rxcp->pkt_size == 0) {
+			be_rx_compl_discard(adapter, rxo, rxcp);
 		}
+
 		be_rx_stats_update(rxo, rxcp);
 	}
 
@@ -1793,12 +1798,12 @@
 	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
 	struct be_eth_tx_compl *txcp;
 	int tx_compl = 0, mcc_compl, status = 0;
-	u16 end_idx;
+	u16 end_idx, num_wrbs = 0;
 
 	while ((txcp = be_tx_compl_get(tx_cq))) {
 		end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
 				wrb_index, txcp);
-		be_tx_compl_process(adapter, end_idx);
+		num_wrbs += be_tx_compl_process(adapter, end_idx);
 		tx_compl++;
 	}
 
@@ -1814,6 +1819,8 @@
 	if (tx_compl) {
 		be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl);
 
+		atomic_sub(num_wrbs, &txq->used);
+
 		/* As Tx wrbs have been freed up, wake up netdev queue if
 		 * it was stopped due to lack of tx wrbs.
 		 */