summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i/bnx2i_hwi.c
diff options
context:
space:
mode:
authorAnil Veerabhadrappa <anilgv@broadcom.com>2009-12-07 11:40:18 -0800
committerJames Bottomley <James.Bottomley@suse.de>2009-12-10 09:45:57 -0600
commit8776193bc308553ac0011b3bb2dd1837e0c6ab28 (patch)
tree4334f5402592860b0c426d765a5647a20648d24d /drivers/scsi/bnx2i/bnx2i_hwi.c
parentf8c9abe797c54e798b4025b54d71e5d2054c929a (diff)
[SCSI] bnx2i: update CQ arming algorith for 5771x chipsets
Only affects 5771x (10G chipsets) devices This is an optimized CQ arming algoritm which takes into account the number of outstanding tasks Signed-off-by: Anil Veerabhadrappa <anilgv@broadcom.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_hwi.c')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 5c8d7630c13..bb69a14a4af 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -133,20 +133,38 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action)
{
struct bnx2i_5771x_cq_db *cq_db;
u16 cq_index;
+ u16 next_index;
+ u32 num_active_cmds;
+
+ /* Coalesce CQ entries only on 10G devices */
if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
return;
+ /* Do not update CQ DB multiple times before firmware writes
+ * '0xFFFF' to CQDB->SQN field. Deviation may cause spurious
+ * interrupts and other unwanted results
+ */
+ cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt;
+ if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
+ return;
+
if (action == CNIC_ARM_CQE) {
- cq_index = ep->qp.cqe_exp_seq_sn +
- ep->num_active_cmds / event_coal_div;
- cq_index %= (ep->qp.cqe_size * 2 + 1);
- if (!cq_index) {
+ num_active_cmds = ep->num_active_cmds;
+ if (num_active_cmds <= event_coal_min)
+ next_index = 1;
+ else
+ next_index = event_coal_min +
+ (num_active_cmds - event_coal_min) / event_coal_div;
+ if (!next_index)
+ next_index = 1;
+ cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1;
+ if (cq_index > ep->qp.cqe_size * 2)
+ cq_index -= ep->qp.cqe_size * 2;
+ if (!cq_index)
cq_index = 1;
- cq_db = (struct bnx2i_5771x_cq_db *)
- ep->qp.cq_pgtbl_virt;
- cq_db->sqn[0] = cq_index;
- }
+
+ cq_db->sqn[0] = cq_index;
}
}