[ewg] [PATCH 8/10] nes: multicast performance enhancement

Glenn Grundstrom NetEffect glenn at lists.openfabrics.org
Thu Dec 20 12:36:13 PST 2007


Move multicast processing to it's own QP and setup the
hardware to use it.

Signed-off-by: Glenn Grundstrom <ggrundstrom at neteffect.com>

---

diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 06d1963..515133d 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -698,7 +698,7 @@ void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count)
 
 	nes_write_indexed(nesdev, 0x000001E4, 0x00000007);
 	/* nes_write_indexed(nesdev, 0x000001E8, 0x000208C4); */
-	nes_write_indexed(nesdev, 0x000001E8, 0x00020844);
+	nes_write_indexed(nesdev, 0x000001E8, 0x00020874);
 	nes_write_indexed(nesdev, 0x000001D8, 0x00048002);
 	/* nes_write_indexed(nesdev, 0x000001D8, 0x0004B002); */
 	nes_write_indexed(nesdev, 0x000001FC, 0x00050005);
@@ -753,7 +753,7 @@ void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count)
 	nes_write_indexed(nesdev, 0x000060C0, 0x0000028e);
 	nes_write_indexed(nesdev, 0x000060C8, 0x00000020);
 														//
-	nes_write_indexed(nesdev, 0x000001EC, 0x5b2625a0);
+	nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0);
 	/* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */
 
 	if (hw_rev != NE020_REV) {
@@ -1377,7 +1377,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
 		nic_sqe = &nesvnic->nic.sq_vbase[counter];
 		nic_sqe->wqe_words[NES_NIC_SQ_WQE_MISC_IDX] =
 				cpu_to_le32(NES_NIC_SQ_WQE_DISABLE_CHKSUM |
-							NES_NIC_SQ_WQE_COMPLETION);
+				NES_NIC_SQ_WQE_COMPLETION);
 		nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX] =
 				cpu_to_le32((u32)NES_FIRST_FRAG_SIZE << 16);
 		nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX] =
@@ -1386,6 +1386,15 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
 				cpu_to_le32((u32)((u64)nesvnic->nic.frag_paddr[counter] >> 32));
 	}
 
+	nesvnic->mcrq_nic.sq_vbase = (void*)0;
+	nesvnic->mcrq_nic.sq_pbase = 0;
+	nesvnic->mcrq_nic.sq_head = 0;
+	nesvnic->mcrq_nic.sq_tail = 0;
+	nesvnic->mcrq_nic.sq_size = 0;
+	nesvnic->get_cqp_request = nes_get_cqp_request;
+	nesvnic->post_cqp_request = nes_post_cqp_request;
+	nesvnic->mcrq_mcast_filter = 0;
+
 	spin_lock_init(&nesvnic->nic.sq_lock);
 	spin_lock_init(&nesvnic->nic.rq_lock);
 
@@ -1404,6 +1413,17 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
 	vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
 	pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
 
+	nesvnic->mcrq_nic.rq_vbase = vmem;
+	nesvnic->mcrq_nic.rq_pbase = pmem;
+	nesvnic->mcrq_nic.rq_head = 0;
+	nesvnic->mcrq_nic.rq_tail = 0;
+	nesvnic->mcrq_nic.rq_size = NES_NIC_WQ_SIZE;
+
+	/* setup the CQ */
+	vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
+	pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
+	nesvnic->mcrq_nic.qp_id = nesvnic->nic_index + 32;
+
 	nesvnic->nic_cq.cq_vbase = vmem;
 	nesvnic->nic_cq.cq_pbase = pmem;
 	nesvnic->nic_cq.cq_head = 0;
@@ -1484,6 +1504,19 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
 	/* Ring doorbell (2 WQEs) */
 	nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x02800000 | nesdev->cqp.qp_id);
 
+	/* Send CreateQP request to CQP */
+	nic_context++;
+	nic_context->context_words[NES_NIC_CTX_MISC_IDX] =
+			cpu_to_le32((u32)NES_NIC_CTX_SIZE |
+			((u32)PCI_FUNC(nesdev->pcidev->devfn) << 12) | (1 << 18));
+
+	u64temp = (u64)nesvnic->mcrq_nic.sq_pbase;
+	nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
+	nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
+	u64temp = (u64)nesvnic->mcrq_nic.rq_pbase;
+	nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
+	nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
+
 	spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
 	nes_debug(NES_DBG_INIT, "Waiting for create NIC QP%u to complete.\n",
 			nesvnic->nic.qp_id);
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index 0279d4c..2efb55e 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -1161,9 +1161,11 @@ struct nes_vnic {
 	dma_addr_t           nic_pbase;
 	struct nes_hw_nic    nic;
 	struct nes_hw_nic_cq nic_cq;
-
+	struct nes_hw_nic    mcrq_nic;
+	struct nes_ucontext *mcrq_ucontext;
 	struct nes_cqp_request* (*get_cqp_request)(struct nes_device *nesdev);
 	void (*post_cqp_request)(struct nes_device*, struct nes_cqp_request *, int);
+	int (*mcrq_mcast_filter)( struct nes_vnic* nesvnic, __u8* dmi_addr );
 	struct net_device_stats netstats;
 	/* used to put the netdev on the adapters logical port list */
 	struct list_head list;
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 496024a..bd3f9e8 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -901,6 +901,9 @@ void nes_netdev_set_multicast_list(struct net_device *netdev)
 		perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 0x80;
 		perfect_filter_register_address += nesvnic->nic_index*0x40;
 		for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
+			while ( multicast_addr && nesvnic->mcrq_mcast_filter && (nesvnic->mcrq_mcast_filter( nesvnic, multicast_addr->dmi_addr ) == 0) ) {
+				multicast_addr = multicast_addr->next;
+			}
 			if (multicast_addr) {
 				nes_debug(NES_DBG_NIC_RX, "Assigning MC Address = %02X%02X%02X%02X%02X%02X to register 0x%04X\n",
 						  multicast_addr->dmi_addr[0], multicast_addr->dmi_addr[1],
diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h
index 6ab2357..d5a91a1 100644
--- a/drivers/infiniband/hw/nes/nes_user.h
+++ b/drivers/infiniband/hw/nes/nes_user.h
@@ -72,6 +72,8 @@ struct nes_alloc_pd_resp {
 
 struct nes_create_cq_req {
 	__u64 user_cq_buffer;
+	__u8 mcrqf;
+	__u8 reserved[7];
 };
 
 struct nes_create_qp_req {
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 97cb51e..9751d0d 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1702,6 +1702,10 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
 			kfree(nescq);
 			return ERR_PTR(-EFAULT);
 		}
+		nesvnic->mcrq_ucontext = nes_ucontext;
+		nes_ucontext->mcrqf = req.mcrqf;
+		if (nes_ucontext->mcrqf)
+			nescq->hw_cq.cq_number = nesvnic->mcrq_nic.qp_id;
 		nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n",
 				(unsigned long)req.user_cq_buffer, entries);
 		list_for_each_entry(nespbl, &nes_ucontext->cq_reg_mem_list, list) {
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h
index 96d59ce..c5ee39d 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.h
+++ b/drivers/infiniband/hw/nes/nes_verbs.h
@@ -54,6 +54,7 @@ struct nes_ucontext {
 	u16                first_free_wq;
 	struct list_head   cq_reg_mem_list;
 	struct list_head   qp_reg_mem_list;
+	u8                 mcrqf;
 };
 
 struct nes_pd {



More information about the ewg mailing list