[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