]> git.openfabrics.org - ~emulex/compat-rdma_3.12.git/commitdiff
RDAM/ocrdma: Pull ocrdma bug fixes This also has syncup patches from upstream kernel.
authorMitesh Ahuja <mitesh.ahuja@emulex.com>
Tue, 19 Aug 2014 13:02:26 +0000 (18:32 +0530)
committerMitesh Ahuja <mitesh.ahuja@emulex.com>
Tue, 19 Aug 2014 13:26:16 +0000 (06:26 -0700)
Moved following existing patches form /linux-next-pending to
/linux-next-cherry-picks folder

0134-RDMA-ocrdma-Eq-full-catastrophe-avoidance.patch
0135-RDMA-ocrdma-SQ-and-RQ-doorbell-offset-clean-up.patch
0136-RDMA-ocrdma-read-ASIC_ID-register-to-select-asic_gen.patch
0137-RDMA-ocrdma-Allow-DPP-QP-creation.patch
0138-RDMA-ocrdma-ABI-versioning-between-ocrdma-and-be2net.patch
0139-RDMA-ocrdma-update-version-string.patch
0140-RDMA-ocrdma-increment-abi-version-count.patch
0141-RDMA-ocrdma-Memory-leak-fix-in-ocrdma_dereg_mr.patch
0142-RDMA-ocrdma-Use-non-zero-tag-in-SRQ-posting.patch
0143-RDMA-ocrdma-Display-proper-value-for-max_mw.patch
0144-RDMA-ocrdma-Handle-CQ-overrun-error.patch
0145-RDMA-ocrdma-Support-non-embedded-mailbox-commands.patch
0146-RDMA-ocrdma-Query-controller-information.patch
0147-RDMA-ocrdma-Support-for-Skyhawk-statistics.patch
0148-RDMA-ocrdma-Display-fw-version.patch
0149-RDMA-ocrdma-code-clean-up.patch
0150-be2net-adding-abi-version-between-be2net-and-ocrdma.patch
0151-RDMA-ocrdma-ROLLBACK-dpp-posting-for-RDMA-READ.patch

commit a7bade7e3deff33f5a0f830e43596b3d8ebd3d85
Author: Selvin Xavier <selvin.xavier@emulex.com>
Date: Tue, 3 Jun 2014 11:13:00 +0530
RDMA/ocrdma: Query and initalize the PFC SL

This patch implements routine to query the PFC priority from the adapter port.

Following are the changes implemented:

 * A new FW command is implemented to query the operational/admin
   DCBX configuration from the FW and obtain active priority(service level).
 * Adds support for the async event reported by FW when the PFC priority
   changes. Service level is re-initialized during modify_qp or
   create_ah, based on this event.
 * Maintain SL value in ocrdma_dev structure and refer that as and
   when needed.

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit 3eb2ede72c26333856fbe3a8c3825d2abaf744b9
Author: Selvin Xavier <selvin.xavier@emulex.com>
Date: Fri, 18 Jul 2014 11:36:55 +0530
RDMA/ocrdma: Adding hca_type string in device atrributes

Added a new entry under sysfs for getting the HW type.

Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit 491006261a6661df25c0923e19dd995ab56c2e9d
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Tue, 27 May 2014 14:05:16 +0530
RDMA/ocrdma: Handle shutdown event from be2net driver

be2net driver sends shutdown event to ocrdma during shutdown/reboot.
As part of event processing, ocrdma calls close() and remove() to
free all the resources associated with ocrdma. This also frees
irqs used by ocrdma

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit c9a08ed7fbd10343a404a3dc899be9eac06c0d6e
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Tue, 27 May 2014 14:16:15 +0530
RDMA/ocrdma: Remove hardcoding of the max DPP QPs supported

Removing hardcoded value of max dpp qps and calculate the same from
doorbell page size and WQE size

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit 5f866391ef3c7dc6e9dd4955a231ad65b3c99742
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Tue, 27 May 2014 14:25:11 +0530
RDMA/ocrdma: Delete AH table if ocrdma_init_hw fails after AH table creation

Cleanup the AH table in error path, if HW initialization fails
after AH table creation.

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit bb2d1842ca249900a73e3850b3583c77b7d0f450
Author: Selvin Xavier <selvin.xavier@emulex.com>
Date: Wed, 28 May 2014 09:25:16 +0530
RDMA/ocrdma: Avoid reporting wrong completions in case of error CQEs

During cable pull test with a mount over nfs rdma, driver was reporting
error completions when there was no pending requests in the SQ and RQ.
This was triggering a host crash because of reporting wrong work req id.
Avoid this crash by adding a check for SQ and RQ empty condition and
prevent reporting completions if queues are empty.

Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
commit 66e9bb03219959cee18ec8cbd50c29b0c7b1c8d9
Author: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
Date: Mon, 2 Jun 2014 10:54:40 +0530
RDMA/ocrdma: Allow only SEND opcode in case of UD QPs

Prevent posting opcodes other than send and send immediate on the UD QPs

Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit 6237b9592d8494f1e9df9f6655336d196a2c244c
Author: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
Date: Fri, 18 Jul 2014 11:47:18 +0530
RDMA/ocrdma: Do proper cleanup evenif FW is in error state

If any mailbox command reports timeout, save the state in the driver, to prevent
issuing any more commands to the HW. Do proper cleanup even if FW is in error state.

Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit cb245d90fb25b9974cd316d14f02a159e2cd2fac
Author: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
Date: Wed, 28 May 2014 10:25:38 +0530
RDMA/ocrdma: Return proper value for max_mr_size

Update the max_mr_size with proper value. Corrected the response structure
of query config mailbox command.

Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit 241e833572471ef43d56d045437f0e8a80a5a186
Author: Selvin Xavier <selvin.xavier@emulex.com>
Date: Wed, 28 May 2014 16:35:23 +0530
RDMA/ocrdma : Add missing adapter mailbox opcodes

Fixing the Statistics command opcode. Also specifying the
opcode of each command for better readablilty.

Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
commit 6fbddaf8eb06d8e865771d858ba75f59c388f446
Author: Selvin Xavier <selvin.xavier@emulex.com>
Date: Thu, 29 May 2014 09:25:55 +0530
RDMA/ocrdma: Increase the size of STAG array in dev structure to 16K

HW can support 16K STAG entries. Changing this max limit.
Also, moving this array out of ocrdma_dev to reduce
the size of this structure

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit 4199b418e36dbe23f16cd741ac9514e792d5d67d
Author: Selvin Xavier <selvin.xavier@emulex.com>
Date: Tue, 3 Jun 2014 14:10:41 +0530
RDMA/ocrdma: Fixing a sparse warning

Fixing the warning about the usage of plain integer as NULL pointer

Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit c5b3d4cc260813bfe80ceb759cc53e78f7ae0f93
Author: Selvin Xavier <selvin.xavier@emulex.com>
Date: Fri, 18 Jul 2014 11:52:15 +0530
RDMA/ocrdma: Update the ocrdma module version string

Updating the ocrdma driver version string

Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit ab18a8049348c08b36d503992dd9c440d6579ad6
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Tue, 1 Jul 2014 16:13:15 +0530
RDMA/ocrdma: obtain sl from deivce structure

Currently, driver obtains service level value from ah_attr->sl
field. However, this filed is set to zero all the times from
rdma-cm. This patch allows create_ah to obtain service level from
dev->sl

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit b9b4b1998604fc5a77388dd9defaee62209a931e
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Tue, 1 Jul 2014 16:05:11 +0530
RDMA/ocrdma: update sli data structure for endian ness

updated the sli specific mailbox command request/response
data sturcures to fix endian-ness issues.

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit bc42b246b1cb9a2230739f251ff0b2d42e85c644
Author: Mitesh Ahuja <mitesh.ahuja@emulex.com>
Date: Tue, 1 Jul 2014 14:41:19 +0530
RDMA/ocrdma: report asic-id in query device

Ocrdma does not report hw_ver when query_device is issued.
This patch is adding meaningful value to this field.

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
commit b28db068f62c5af0ce3e3af91bd9326b4b570c58
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Fri, 6 Jun 2014 10:45:49 +0530
RDMA/ocrdma: do not skip setting deffered_arm

ib_request_notify_cq() when called for the first time
ocrdma tries to skip setting deffered_arm flag. This
may lead CQ to an un-armed state thus, never generating
CQ event and leaving consumer in hung state.

This patch removes the part of code that skkips setting
deffered_arm flag.

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
commit 295ec1fb5a5ecb9e35f452a1b744992c0c515066
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Thu, 5 Jun 2014 19:11:05 +0530
RDMA/ocrdma: Report actual value of max_fast_reg_page_list_len

ocrdma_query_device does not report correct value of max_fast_reg_page_list_len.
This patch applies changes to fix this bug.

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
commit 1d930f4ea2f2a4784ccfbb18b4263817db283282
Author: Devesh Sharma <devesh.sharma@emulex.com>
Date: Tue, 12 Aug 2014 17:28:59 +0530
be2net: Issue shutdown event to ocrdma driver

In the shutdown path, when be2net calls pci_disable_msix(), it
complains (BUG_ON) that irqs requested by ocrdma driver are still in
use.  This patch fixes this problem by issuing shutdown event to
ocrdma from be2net shutdown path.  As part of shutdown event
processing, ocrdma driver will free up all the resources and free
irqs.  Once this completes be2net completes pci_disable_msix
successfully.

Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
55 files changed:
linux-next-cherry-picks/0134-RDMA-ocrdma-Eq-full-catastrophe-avoidance.patch [new file with mode: 0644]
linux-next-cherry-picks/0135-RDMA-ocrdma-SQ-and-RQ-doorbell-offset-clean-up.patch [new file with mode: 0644]
linux-next-cherry-picks/0136-RDMA-ocrdma-read-ASIC_ID-register-to-select-asic_gen.patch [new file with mode: 0644]
linux-next-cherry-picks/0137-RDMA-ocrdma-Allow-DPP-QP-creation.patch [new file with mode: 0644]
linux-next-cherry-picks/0138-RDMA-ocrdma-ABI-versioning-between-ocrdma-and-be2net.patch [new file with mode: 0644]
linux-next-cherry-picks/0139-RDMA-ocrdma-update-version-string.patch [new file with mode: 0644]
linux-next-cherry-picks/0140-RDMA-ocrdma-increment-abi-version-count.patch [new file with mode: 0644]
linux-next-cherry-picks/0141-RDMA-ocrdma-Memory-leak-fix-in-ocrdma_dereg_mr.patch [new file with mode: 0644]
linux-next-cherry-picks/0142-RDMA-ocrdma-Use-non-zero-tag-in-SRQ-posting.patch [new file with mode: 0644]
linux-next-cherry-picks/0143-RDMA-ocrdma-Display-proper-value-for-max_mw.patch [new file with mode: 0644]
linux-next-cherry-picks/0144-RDMA-ocrdma-Handle-CQ-overrun-error.patch [new file with mode: 0644]
linux-next-cherry-picks/0145-RDMA-ocrdma-Support-non-embedded-mailbox-commands.patch [new file with mode: 0644]
linux-next-cherry-picks/0146-RDMA-ocrdma-Query-controller-information.patch [new file with mode: 0644]
linux-next-cherry-picks/0147-RDMA-ocrdma-Support-for-Skyhawk-statistics.patch [new file with mode: 0644]
linux-next-cherry-picks/0148-RDMA-ocrdma-Display-fw-version.patch [new file with mode: 0644]
linux-next-cherry-picks/0149-RDMA-ocrdma-code-clean-up.patch [new file with mode: 0644]
linux-next-cherry-picks/0150-be2net-adding-abi-version-between-be2net-and-ocrdma.patch [new file with mode: 0644]
linux-next-cherry-picks/0151-RDMA-ocrdma-ROLLBACK-dpp-posting-for-RDMA-READ.patch [new file with mode: 0644]
linux-next-cherry-picks/0152-RDMA-ocrdma-Query-and-initalize-the-PFC-SL.patch [new file with mode: 0644]
linux-next-cherry-picks/0153-RDMA-ocrdma-Adding-hca_type-string-in-device-atrribu.patch [new file with mode: 0644]
linux-next-cherry-picks/0154-RDMA-ocrdma-Handle-shutdown-event-from-be2net-driver.patch [new file with mode: 0644]
linux-next-cherry-picks/0155-RDMA-ocrdma-Remove-hardcoding-of-the-max-DPP-QPs-sup.patch [new file with mode: 0644]
linux-next-cherry-picks/0156-RDMA-ocrdma-Delete-AH-table-if-ocrdma_init_hw-fails-.patch [new file with mode: 0644]
linux-next-cherry-picks/0157-RDMA-ocrdma-Avoid-reporting-wrong-completions-in-cas.patch [new file with mode: 0644]
linux-next-cherry-picks/0158-RDMA-ocrdma-Allow-only-SEND-opcode-in-case-of-UD-QPs.patch [new file with mode: 0644]
linux-next-cherry-picks/0159-RDMA-ocrdma-Do-proper-cleanup-evenif-FW-is-in-error-.patch [new file with mode: 0644]
linux-next-cherry-picks/0160-RDMA-ocrdma-Return-proper-value-for-max_mr_size.patch [new file with mode: 0644]
linux-next-cherry-picks/0161-RDMA-ocrdma-Add-missing-adapter-mailbox-opcodes.patch [new file with mode: 0644]
linux-next-cherry-picks/0162-RDMA-ocrdma-Increase-the-size-of-STAG-array-in-dev-s.patch [new file with mode: 0644]
linux-next-cherry-picks/0163-RDMA-ocrdma-Fixing-a-sparse-warning.patch [new file with mode: 0644]
linux-next-cherry-picks/0164-RDMA-ocrdma-Update-the-ocrdma-module-version-string.patch [new file with mode: 0644]
linux-next-cherry-picks/0165-RDMA-ocrdma-obtain-sl-from-deivce-structure.patch [new file with mode: 0644]
linux-next-cherry-picks/0166-RDMA-ocrdma-update-sli-data-structure-for-endian-nes.patch [new file with mode: 0644]
linux-next-cherry-picks/0167-RDMA-ocrdma-report-asic-id-in-query-device.patch [new file with mode: 0644]
linux-next-pending/0005-RDMA-ocrdma-Eq-full-catastrophe-avoidance.patch [deleted file]
linux-next-pending/0005-RDMA-ocrdma-do-not-skip-setting-deffered_arm.patch [new file with mode: 0644]
linux-next-pending/0006-RDMA-ocrdma-Report-actual-value-of-max_fast_reg_page.patch [new file with mode: 0644]
linux-next-pending/0006-RDMA-ocrdma-SQ-and-RQ-doorbell-offset-clean-up.patch [deleted file]
linux-next-pending/0007-RDMA-ocrdma-read-ASIC_ID-register-to-select-asic_gen.patch [deleted file]
linux-next-pending/0008-RDMA-ocrdma-Allow-DPP-QP-creation.patch [deleted file]
linux-next-pending/0009-RDMA-ocrdma-ABI-versioning-between-ocrdma-and-be2net.patch [deleted file]
linux-next-pending/0010-RDMA-ocrdma-update-version-string.patch [deleted file]
linux-next-pending/0011-RDMA-ocrdma-increment-abi-version-count.patch [deleted file]
linux-next-pending/0012-RDMA-ocrdma-Memory-leak-fix-in-ocrdma_dereg_mr.patch [deleted file]
linux-next-pending/0013-RDMA-ocrdma-Use-non-zero-tag-in-SRQ-posting.patch [deleted file]
linux-next-pending/0014-RDMA-ocrdma-Display-proper-value-for-max_mw.patch [deleted file]
linux-next-pending/0015-RDMA-ocrdma-Handle-CQ-overrun-error.patch [deleted file]
linux-next-pending/0016-RDMA-ocrdma-Support-non-embedded-mailbox-commands.patch [deleted file]
linux-next-pending/0017-RDMA-ocrdma-Query-controller-information.patch [deleted file]
linux-next-pending/0018-RDMA-ocrdma-Support-for-Skyhawk-statistics.patch [deleted file]
linux-next-pending/0019-RDMA-ocrdma-Display-fw-version.patch [deleted file]
linux-next-pending/0020-RDMA-ocrdma-code-clean-up.patch [deleted file]
linux-next-pending/0021-be2net-adding-abi-version-between-be2net-and-ocrdma.patch [deleted file]
linux-next-pending/0023-RDMA-ocrdma-ROLLBACK-dpp-posting-for-RDMA-READ.patch [deleted file]
patches/0032-be2net-Issue-shutdown-event-to-ocrdma-driver.patch [new file with mode: 0644]

diff --git a/linux-next-cherry-picks/0134-RDMA-ocrdma-Eq-full-catastrophe-avoidance.patch b/linux-next-cherry-picks/0134-RDMA-ocrdma-Eq-full-catastrophe-avoidance.patch
new file mode 100644 (file)
index 0000000..5b93447
--- /dev/null
@@ -0,0 +1,350 @@
+From bf24e5d575c684833685a514930770c719c5dbf7 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Thu, 30 Jan 2014 15:35:40 +0530
+Subject: [PATCH 01/16] RDMA/ocrdma: Eq full catastrophe avoidance
+
+Stale entries in the CQ being destroyed causes hardware to generate EQEs indefinetly for a given CQ.
+Thus causing uncontrolled execution of irq_handler. This patch fixes this using following sementics:
+
+    * irq_handler will ring EQ doorbell atleast once and implement budgeting scheme.
+    * cq_destroy will count number of valid entires during destroy and ring
+      cq-db so that hadrware does not generate uncontrolled EQE.
+    * cq_destroy will synchronize with last running irq_handler instance.
+    * arm_cq will always defer arming CQ till poll_cq, except for the first arm_cq call.
+    * poll_cq will always ring cq-db with arm=SET if arm_cq was called prior to enter poll_cq.
+    * poll_cq will always ring cq-db with arm=UNSET if arm_cq was not called prior to enter poll_cq.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h       |   18 +++++-
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |   53 ++++++++---------
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.h    |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   81 ++++++++++++++++++++-------
+ 4 files changed, 103 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index adc11d1..a329de6 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -183,8 +183,8 @@ struct ocrdma_cq {
+                        */
+       u32 max_hw_cqe;
+       bool phase_change;
+-      bool armed, solicited;
+-      bool arm_needed;
++      bool deferred_arm, deferred_sol;
++      bool first_arm;
+       spinlock_t cq_lock ____cacheline_aligned; /* provide synchronization
+                                                  * to cq polling
+@@ -197,6 +197,7 @@ struct ocrdma_cq {
+       struct ocrdma_ucontext *ucontext;
+       dma_addr_t pa;
+       u32 len;
++      u32 cqe_cnt;
+       /* head of all qp's sq and rq for which cqes need to be flushed
+        * by the software.
+@@ -423,4 +424,17 @@ static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
+ }
++static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev,
++              int eqid)
++{
++      int indx;
++
++      for (indx = 0; indx < dev->eq_cnt; indx++) {
++              if (dev->eq_tbl[indx].q.id == eqid)
++                      return indx;
++      }
++
++      return -EINVAL;
++}
++
+ #endif
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 50219ab..135331d 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -444,7 +444,7 @@ mbx_err:
+       return status;
+ }
+-static int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq)
++int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq)
+ {
+       int irq;
+@@ -574,6 +574,7 @@ static int ocrdma_create_mq(struct ocrdma_dev *dev)
+       if (status)
+               goto alloc_err;
++      dev->eq_tbl[0].cq_cnt++;
+       status = ocrdma_mbx_mq_cq_create(dev, &dev->mq.cq, &dev->eq_tbl[0].q);
+       if (status)
+               goto mbx_cq_free;
+@@ -858,16 +859,8 @@ static void ocrdma_qp_cq_handler(struct ocrdma_dev *dev, u16 cq_idx)
+               BUG();
+       cq = dev->cq_tbl[cq_idx];
+-      if (cq == NULL) {
+-              pr_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx);
++      if (cq == NULL)
+               return;
+-      }
+-      spin_lock_irqsave(&cq->cq_lock, flags);
+-      cq->armed = false;
+-      cq->solicited = false;
+-      spin_unlock_irqrestore(&cq->cq_lock, flags);
+-
+-      ocrdma_ring_cq_db(dev, cq->id, false, false, 0);
+       if (cq->ibcq.comp_handler) {
+               spin_lock_irqsave(&cq->comp_handler_lock, flags);
+@@ -892,27 +885,35 @@ static irqreturn_t ocrdma_irq_handler(int irq, void *handle)
+       struct ocrdma_dev *dev = eq->dev;
+       struct ocrdma_eqe eqe;
+       struct ocrdma_eqe *ptr;
+-      u16 eqe_popped = 0;
+       u16 cq_id;
+-      while (1) {
++      int budget = eq->cq_cnt;
++
++      do {
+               ptr = ocrdma_get_eqe(eq);
+               eqe = *ptr;
+               ocrdma_le32_to_cpu(&eqe, sizeof(eqe));
+               if ((eqe.id_valid & OCRDMA_EQE_VALID_MASK) == 0)
+                       break;
+-              eqe_popped += 1;
++
+               ptr->id_valid = 0;
++              /* ring eq doorbell as soon as its consumed. */
++              ocrdma_ring_eq_db(dev, eq->q.id, false, true, 1);
+               /* check whether its CQE or not. */
+               if ((eqe.id_valid & OCRDMA_EQE_FOR_CQE_MASK) == 0) {
+                       cq_id = eqe.id_valid >> OCRDMA_EQE_RESOURCE_ID_SHIFT;
+                       ocrdma_cq_handler(dev, cq_id);
+               }
+               ocrdma_eq_inc_tail(eq);
+-      }
+-      ocrdma_ring_eq_db(dev, eq->q.id, true, true, eqe_popped);
+-      /* Ring EQ doorbell with num_popped to 0 to enable interrupts again. */
+-      if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX)
+-              ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0);
++
++              /* There can be a stale EQE after the last bound CQ is
++               * destroyed. EQE valid and budget == 0 implies this.
++               */
++              if (budget)
++                      budget--;
++
++      } while (budget);
++
++      ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0);
+       return IRQ_HANDLED;
+ }
+@@ -1357,12 +1358,10 @@ static void ocrdma_unbind_eq(struct ocrdma_dev *dev, u16 eq_id)
+       int i;
+       mutex_lock(&dev->dev_lock);
+-      for (i = 0; i < dev->eq_cnt; i++) {
+-              if (dev->eq_tbl[i].q.id != eq_id)
+-                      continue;
+-              dev->eq_tbl[i].cq_cnt -= 1;
+-              break;
+-      }
++      i = ocrdma_get_eq_table_index(dev, eq_id);
++      if (i == -EINVAL)
++              BUG();
++      dev->eq_tbl[i].cq_cnt -= 1;
+       mutex_unlock(&dev->dev_lock);
+ }
+@@ -1417,6 +1416,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
+       cq->eqn = ocrdma_bind_eq(dev);
+       cmd->cmd.req.rsvd_version = OCRDMA_CREATE_CQ_VER3;
+       cqe_count = cq->len / cqe_size;
++      cq->cqe_cnt = cqe_count;
+       if (cqe_count > 1024) {
+               /* Set cnt to 3 to indicate more than 1024 cq entries */
+               cmd->cmd.ev_cnt_flags |= (0x3 << OCRDMA_CREATE_CQ_CNT_SHIFT);
+@@ -1484,12 +1484,9 @@ int ocrdma_mbx_destroy_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq)
+           (cq->id << OCRDMA_DESTROY_CQ_QID_SHIFT) &
+           OCRDMA_DESTROY_CQ_QID_MASK;
+-      ocrdma_unbind_eq(dev, cq->eqn);
+       status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
+-      if (status)
+-              goto mbx_err;
++      ocrdma_unbind_eq(dev, cq->eqn);
+       dma_free_coherent(&dev->nic_info.pdev->dev, cq->len, cq->va, cq->pa);
+-mbx_err:
+       kfree(cmd);
+       return status;
+ }
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+index f2a89d4..38102b3 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+@@ -133,5 +133,6 @@ int ocrdma_qp_state_change(struct ocrdma_qp *, enum ib_qp_state new_state,
+ bool ocrdma_is_qp_in_sq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
+ bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
+ void ocrdma_flush_qp(struct ocrdma_qp *);
++int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
+ #endif                                /* __OCRDMA_HW_H__ */
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 86242ce..ae2b778 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -910,6 +910,7 @@ struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev, int entries, int vector,
+       spin_lock_init(&cq->comp_handler_lock);
+       INIT_LIST_HEAD(&cq->sq_head);
+       INIT_LIST_HEAD(&cq->rq_head);
++      cq->first_arm = true;
+       if (ib_ctx) {
+               uctx = get_ocrdma_ucontext(ib_ctx);
+@@ -927,9 +928,7 @@ struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev, int entries, int vector,
+                       goto ctx_err;
+       }
+       cq->phase = OCRDMA_CQE_VALID;
+-      cq->arm_needed = true;
+       dev->cq_tbl[cq->id] = cq;
+-
+       return &cq->ibcq;
+ ctx_err:
+@@ -952,15 +951,52 @@ int ocrdma_resize_cq(struct ib_cq *ibcq, int new_cnt,
+       return status;
+ }
++void ocrdma_flush_cq(struct ocrdma_cq *cq)
++{
++      int cqe_cnt;
++      int valid_count = 0;
++      unsigned long flags;
++
++      struct ocrdma_dev *dev = get_ocrdma_dev(cq->ibcq.device);
++      struct ocrdma_cqe *cqe = NULL;
++
++      cqe = cq->va;
++      cqe_cnt = cq->cqe_cnt;
++
++      /* Last irq might have scheduled a polling thread
++       * sync-up with it before hard flushing.
++       */
++      spin_lock_irqsave(&cq->cq_lock, flags);
++      while (cqe_cnt) {
++              if (is_cqe_valid(cq, cqe))
++                      valid_count++;
++              cqe++;
++              cqe_cnt--;
++      }
++      ocrdma_ring_cq_db(dev, cq->id, false, false, valid_count);
++      spin_unlock_irqrestore(&cq->cq_lock, flags);
++}
++
+ int ocrdma_destroy_cq(struct ib_cq *ibcq)
+ {
+       int status;
+       struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
++      struct ocrdma_eq *eq = NULL;
+       struct ocrdma_dev *dev = get_ocrdma_dev(ibcq->device);
+       int pdid = 0;
++      u32 irq, indx;
+-      status = ocrdma_mbx_destroy_cq(dev, cq);
++      dev->cq_tbl[cq->id] = NULL;
++      indx = ocrdma_get_eq_table_index(dev, cq->eqn);
++      if (indx == -EINVAL)
++              BUG();
++      eq = &dev->eq_tbl[indx];
++      irq = ocrdma_get_irq(dev, eq);
++      synchronize_irq(irq);
++      ocrdma_flush_cq(cq);
++
++      status = ocrdma_mbx_destroy_cq(dev, cq);
+       if (cq->ucontext) {
+               pdid = cq->ucontext->cntxt_pd->id;
+               ocrdma_del_mmap(cq->ucontext, (u64) cq->pa,
+@@ -969,7 +1005,6 @@ int ocrdma_destroy_cq(struct ib_cq *ibcq)
+                               ocrdma_get_db_addr(dev, pdid),
+                               dev->nic_info.db_page_size);
+       }
+-      dev->cq_tbl[cq->id] = NULL;
+       kfree(cq);
+       return status;
+@@ -2706,10 +2741,18 @@ expand_cqe:
+       }
+ stop_cqe:
+       cq->getp = cur_getp;
+-      if (polled_hw_cqes || expand || stop) {
+-              ocrdma_ring_cq_db(dev, cq->id, cq->armed, cq->solicited,
++      if (cq->deferred_arm) {
++              ocrdma_ring_cq_db(dev, cq->id, true, cq->deferred_sol,
++                                polled_hw_cqes);
++              cq->deferred_arm = false;
++              cq->deferred_sol = false;
++      } else {
++              /* We need to pop the CQE. No need to arm */
++              ocrdma_ring_cq_db(dev, cq->id, false, cq->deferred_sol,
+                                 polled_hw_cqes);
++              cq->deferred_sol = false;
+       }
++
+       return i;
+ }
+@@ -2781,30 +2824,28 @@ int ocrdma_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags cq_flags)
+       struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
+       struct ocrdma_dev *dev = get_ocrdma_dev(ibcq->device);
+       u16 cq_id;
+-      u16 cur_getp;
+-      struct ocrdma_cqe *cqe;
+       unsigned long flags;
++      bool arm_needed = false, sol_needed = false;
+       cq_id = cq->id;
+       spin_lock_irqsave(&cq->cq_lock, flags);
+       if (cq_flags & IB_CQ_NEXT_COMP || cq_flags & IB_CQ_SOLICITED)
+-              cq->armed = true;
++              arm_needed = true;
+       if (cq_flags & IB_CQ_SOLICITED)
+-              cq->solicited = true;
+-
+-      cur_getp = cq->getp;
+-      cqe = cq->va + cur_getp;
++              sol_needed = true;
+-      /* check whether any valid cqe exist or not, if not then safe to
+-       * arm. If cqe is not yet consumed, then let it get consumed and then
+-       * we arm it to avoid false interrupts.
+-       */
+-      if (!is_cqe_valid(cq, cqe) || cq->arm_needed) {
+-              cq->arm_needed = false;
+-              ocrdma_ring_cq_db(dev, cq_id, cq->armed, cq->solicited, 0);
++      if (cq->first_arm) {
++              ocrdma_ring_cq_db(dev, cq_id, arm_needed, sol_needed, 0);
++              cq->first_arm = false;
++              goto skip_defer;
+       }
++      cq->deferred_arm = true;
++
++skip_defer:
++      cq->deferred_sol = sol_needed;
+       spin_unlock_irqrestore(&cq->cq_lock, flags);
++
+       return 0;
+ }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0135-RDMA-ocrdma-SQ-and-RQ-doorbell-offset-clean-up.patch b/linux-next-cherry-picks/0135-RDMA-ocrdma-SQ-and-RQ-doorbell-offset-clean-up.patch
new file mode 100644 (file)
index 0000000..429efd9
--- /dev/null
@@ -0,0 +1,108 @@
+From 622cd67f49d6d5da5e57283ea22c89bc94783865 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <Devesh.Sharma@Emulex.Com>
+Date: Mon, 3 Feb 2014 18:17:03 +0530
+Subject: [PATCH 02/16] RDMA/ocrdma: SQ and RQ doorbell offset clean up
+
+Introducing new macros to define SQ and RQ doorbell offset.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h       |    7 -------
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |    5 ++++-
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   23 +++++++----------------
+ 3 files changed, 11 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index a329de6..283653c 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -385,13 +385,6 @@ static inline struct ocrdma_srq *get_ocrdma_srq(struct ib_srq *ibsrq)
+       return container_of(ibsrq, struct ocrdma_srq, ibsrq);
+ }
+-
+-static inline int ocrdma_get_num_posted_shift(struct ocrdma_qp *qp)
+-{
+-      return ((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY &&
+-               qp->id < 128) ? 24 : 16);
+-}
+-
+ static inline int is_cqe_valid(struct ocrdma_cq *cq, struct ocrdma_cqe *cqe)
+ {
+       int cqe_valid;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 60d5ac2..e71685a 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -103,7 +103,10 @@ enum {
+       OCRDMA_DB_GEN2_SRQ_OFFSET       = OCRDMA_DB_GEN2_RQ_OFFSET,
+       OCRDMA_DB_CQ_OFFSET             = 0x120,
+       OCRDMA_DB_EQ_OFFSET             = OCRDMA_DB_CQ_OFFSET,
+-      OCRDMA_DB_MQ_OFFSET             = 0x140
++      OCRDMA_DB_MQ_OFFSET             = 0x140,
++
++      OCRDMA_DB_SQ_SHIFT              = 16,
++      OCRDMA_DB_RQ_SHIFT              = 24
+ };
+ #define OCRDMA_DB_CQ_RING_ID_MASK       0x3FF /* bits 0 - 9 */
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index ae2b778..ef52ef2 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -1127,15 +1127,9 @@ static int ocrdma_copy_qp_uresp(struct ocrdma_qp *qp,
+       }
+       uresp.db_page_addr = usr_db;
+       uresp.db_page_size = dev->nic_info.db_page_size;
+-      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
+-              uresp.db_sq_offset = OCRDMA_DB_GEN2_SQ_OFFSET;
+-              uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ_OFFSET;
+-              uresp.db_shift = 24;
+-      } else {
+-              uresp.db_sq_offset = OCRDMA_DB_SQ_OFFSET;
+-              uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET;
+-              uresp.db_shift = 16;
+-      }
++      uresp.db_sq_offset = OCRDMA_DB_GEN2_SQ_OFFSET;
++      uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ_OFFSET;
++      uresp.db_shift = OCRDMA_DB_RQ_SHIFT;
+       if (qp->dpp_enabled) {
+               uresp.dpp_credit = dpp_credit_lmt;
+@@ -1308,7 +1302,7 @@ static void ocrdma_flush_rq_db(struct ocrdma_qp *qp)
+ {
+       if (qp->db_cache) {
+               u32 val = qp->rq.dbid | (qp->db_cache <<
+-                              ocrdma_get_num_posted_shift(qp));
++                              OCRDMA_DB_RQ_SHIFT);
+               iowrite32(val, qp->rq_db);
+               qp->db_cache = 0;
+       }
+@@ -2053,7 +2047,7 @@ static int ocrdma_build_fr(struct ocrdma_qp *qp, struct ocrdma_hdr_wqe *hdr,
+ static void ocrdma_ring_sq_db(struct ocrdma_qp *qp)
+ {
+-      u32 val = qp->sq.dbid | (1 << 16);
++      u32 val = qp->sq.dbid | (1 << OCRDMA_DB_SQ_SHIFT);
+       iowrite32(val, qp->sq_db);
+ }
+@@ -2158,12 +2152,9 @@ int ocrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ static void ocrdma_ring_rq_db(struct ocrdma_qp *qp)
+ {
+-      u32 val = qp->rq.dbid | (1 << ocrdma_get_num_posted_shift(qp));
++      u32 val = qp->rq.dbid | (1 << OCRDMA_DB_RQ_SHIFT);
+-      if (qp->state != OCRDMA_QPS_INIT)
+-              iowrite32(val, qp->rq_db);
+-      else
+-              qp->db_cache++;
++      iowrite32(val, qp->rq_db);
+ }
+ static void ocrdma_build_rqe(struct ocrdma_hdr_wqe *rqe, struct ib_recv_wr *wr,
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0136-RDMA-ocrdma-read-ASIC_ID-register-to-select-asic_gen.patch b/linux-next-cherry-picks/0136-RDMA-ocrdma-read-ASIC_ID-register-to-select-asic_gen.patch
new file mode 100644 (file)
index 0000000..d9c7ec4
--- /dev/null
@@ -0,0 +1,160 @@
+From cb733f184ebc399935d3c3e948d9288915ab9748 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 18 Feb 2014 16:02:52 +0530
+Subject: [PATCH 03/16] RDMA/ocrdma: read ASIC_ID register to select asic_gen
+
+ocrdma driver selects execution path based on sli_family and asic generation number.
+this introduces reading asic gen number from pci register instead of obtining from emulex NIC driver.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h       |   13 +++++++++++++
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |    6 +++---
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c  |    2 +-
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |   17 +++++++++++++++--
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    6 +++---
+ 5 files changed, 35 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 283653c..44064c7 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -171,6 +171,7 @@ struct ocrdma_dev {
+       int id;
+       u64 stag_arr[OCRDMA_MAX_STAG];
+       u16 pvid;
++      u32 asic_id;
+ };
+ struct ocrdma_cq {
+@@ -430,4 +431,16 @@ static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev,
+       return -EINVAL;
+ }
++static inline u8 ocrdma_get_asic_type(struct ocrdma_dev *dev)
++{
++      if (dev->nic_info.dev_family == 0xF && !dev->asic_id) {
++              pci_read_config_dword(
++                      dev->nic_info.pdev,
++                      OCRDMA_SLI_ASIC_ID_OFFSET, &dev->asic_id);
++      }
++
++      return (dev->asic_id & OCRDMA_SLI_ASIC_GEN_NUM_MASK) >>
++                              OCRDMA_SLI_ASIC_GEN_NUM_SHIFT;
++}
++
+ #endif
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 135331d..ce6f539 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -1037,7 +1037,7 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
+       attr->max_inline_data =
+           attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) +
+                             sizeof(struct ocrdma_sge));
+-      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
++      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
+               attr->ird = 1;
+               attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE;
+               attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES;
+@@ -1379,7 +1379,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
+                      __func__, dev->id, dev->attr.max_cqe, entries);
+               return -EINVAL;
+       }
+-      if (dpp_cq && (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY))
++      if (dpp_cq && (ocrdma_get_asic_type(dev) != OCRDMA_ASIC_GEN_SKH_R))
+               return -EINVAL;
+       if (dpp_cq) {
+@@ -1439,7 +1439,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
+       }
+       /* shared eq between all the consumer cqs. */
+       cmd->cmd.eqn = cq->eqn;
+-      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
++      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
+               if (dpp_cq)
+                       cmd->cmd.pgsz_pgcnt |= OCRDMA_CREATE_CQ_DPP <<
+                               OCRDMA_CREATE_CQ_TYPE_SHIFT;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 53d3ea4..b21761b 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -346,7 +346,7 @@ static int ocrdma_register_device(struct ocrdma_dev *dev)
+       dev->ibdev.process_mad = ocrdma_process_mad;
+-      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
++      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
+               dev->ibdev.uverbs_cmd_mask |=
+                    OCRDMA_UVERBS(CREATE_SRQ) |
+                    OCRDMA_UVERBS(MODIFY_SRQ) |
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index e71685a..de4ebfc 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -30,8 +30,16 @@
+ #define Bit(_b) (1 << (_b))
+-#define OCRDMA_GEN1_FAMILY    0xB
+-#define OCRDMA_GEN2_FAMILY    0x0F
++enum {
++      OCRDMA_ASIC_GEN_SKH_R = 0x04,
++      OCRDMA_ASIC_GEN_LANCER = 0x0B
++};
++
++enum {
++      OCRDMA_ASIC_REV_A0 = 0x00,
++      OCRDMA_ASIC_REV_B0 = 0x10,
++      OCRDMA_ASIC_REV_C0 = 0x20
++};
+ #define OCRDMA_SUBSYS_ROCE 10
+ enum {
+@@ -141,6 +149,11 @@ enum {
+ #define OCRDMA_MIN_Q_PAGE_SIZE (4096)
+ #define OCRDMA_MAX_Q_PAGES     (8)
++#define OCRDMA_SLI_ASIC_ID_OFFSET      0x9C
++#define OCRDMA_SLI_ASIC_REV_MASK       0x000000FF
++#define OCRDMA_SLI_ASIC_GEN_NUM_MASK   0x0000FF00
++#define OCRDMA_SLI_ASIC_GEN_NUM_SHIFT  0x08
++
+ /*
+ # 0: 4K Bytes
+ # 1: 8K Bytes
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index ef52ef2..20ef4ba 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -267,7 +267,7 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
+       if (udata && uctx) {
+               pd->dpp_enabled =
+-                      dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY;
++                      ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R;
+               pd->num_dpp_qp =
+                       pd->dpp_enabled ? OCRDMA_PD_MAX_DPP_ENABLED_QP : 0;
+       }
+@@ -1161,7 +1161,7 @@ err:
+ static void ocrdma_set_qp_db(struct ocrdma_dev *dev, struct ocrdma_qp *qp,
+                            struct ocrdma_pd *pd)
+ {
+-      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
++      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
+               qp->sq_db = dev->nic_info.db +
+                       (pd->id * dev->nic_info.db_page_size) +
+                       OCRDMA_DB_GEN2_SQ_OFFSET;
+@@ -1687,7 +1687,7 @@ static int ocrdma_copy_srq_uresp(struct ocrdma_dev *dev, struct ocrdma_srq *srq,
+           (srq->pd->id * dev->nic_info.db_page_size);
+       uresp.db_page_size = dev->nic_info.db_page_size;
+       uresp.num_rqe_allocated = srq->rq.max_cnt;
+-      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
++      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
+               uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ_OFFSET;
+               uresp.db_shift = 24;
+       } else {
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0137-RDMA-ocrdma-Allow-DPP-QP-creation.patch b/linux-next-cherry-picks/0137-RDMA-ocrdma-Allow-DPP-QP-creation.patch
new file mode 100644 (file)
index 0000000..7722c7a
--- /dev/null
@@ -0,0 +1,31 @@
+From fec1a4edb29dfab809fcdff9c600ee150874a63f Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Wed, 29 Jan 2014 14:04:45 +0530
+Subject: [PATCH 04/16] RDMA/ocrdma: Allow DPP QP creation
+
+Allow creating DPP QP even if inline-data is not requested. This is an optimization to
+lower the latency figures.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    3 +--
+ 1 files changed, 1 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index ce6f539..dc72df9 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -2026,8 +2026,7 @@ int ocrdma_mbx_create_qp(struct ocrdma_qp *qp, struct ib_qp_init_attr *attrs,
+                               OCRDMA_CREATE_QP_REQ_RQ_CQID_MASK;
+       qp->rq_cq = cq;
+-      if (pd->dpp_enabled && attrs->cap.max_inline_data && pd->num_dpp_qp &&
+-          (attrs->cap.max_inline_data <= dev->attr.max_inline_data)) {
++      if (pd->dpp_enabled && pd->num_dpp_qp) {
+               ocrdma_set_create_qp_dpp_cmd(cmd, pd, qp, enable_dpp_cq,
+                                            dpp_cq_id);
+       }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0138-RDMA-ocrdma-ABI-versioning-between-ocrdma-and-be2net.patch b/linux-next-cherry-picks/0138-RDMA-ocrdma-ABI-versioning-between-ocrdma-and-be2net.patch
new file mode 100644 (file)
index 0000000..4063cb6
--- /dev/null
@@ -0,0 +1,42 @@
+From 459a5fdb860295fdfd3f163b5deb462848f3092a Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Thu, 30 Jan 2014 09:57:37 +0530
+Subject: [PATCH 05/16] RDMA/ocrdma: ABI versioning between ocrdma and be2net
+
+While loading RoCE driver be2net driver should check for ABI version to catch
+functional incompatibilities.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_abi.h  |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |    1 +
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
+index fbac8eb..2a14d4a 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
+@@ -29,6 +29,7 @@
+ #define __OCRDMA_ABI_H__
+ #define OCRDMA_ABI_VERSION 1
++#define OCRDMA_BE_ROCE_ABI_VERSION 1
+ /* user kernel communication data structures. */
+ struct ocrdma_alloc_ucontext_resp {
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index b21761b..8f4e97c 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -541,6 +541,7 @@ static struct ocrdma_driver ocrdma_drv = {
+       .add                    = ocrdma_add,
+       .remove                 = ocrdma_remove,
+       .state_change_handler   = ocrdma_event_handler,
++      .be_abi_version         = OCRDMA_BE_ROCE_ABI_VERSION,
+ };
+ static void ocrdma_unregister_inet6addr_notifier(void)
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0139-RDMA-ocrdma-update-version-string.patch b/linux-next-cherry-picks/0139-RDMA-ocrdma-update-version-string.patch
new file mode 100644 (file)
index 0000000..18953ac
--- /dev/null
@@ -0,0 +1,47 @@
+From ee947e52b96caa36435896fdc19cd351a805bd27 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Thu, 30 Jan 2014 11:58:44 +0530
+Subject: [PATCH 06/16] RDMA/ocrdma: update version string
+
+Update the driver vrsion string and node description string.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h      |    4 +++-
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |    4 ++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 44064c7..2eb4d22 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -39,7 +39,9 @@
+ #include <be_roce.h>
+ #include "ocrdma_sli.h"
+-#define OCRDMA_ROCE_DEV_VERSION "1.0.0"
++#define OCRDMA_ROCE_DRV_VERSION "10.2.145.0-ofed"
++
++#define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
+ #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
+ #define OCRDMA_MAX_AH 512
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 8f4e97c..5d30161 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -41,8 +41,8 @@
+ #include "ocrdma_hw.h"
+ #include "ocrdma_abi.h"
+-MODULE_VERSION(OCRDMA_ROCE_DEV_VERSION);
+-MODULE_DESCRIPTION("Emulex RoCE HCA Driver");
++MODULE_VERSION(OCRDMA_ROCE_DRV_VERSION);
++MODULE_DESCRIPTION(OCRDMA_ROCE_DRV_DESC " " OCRDMA_ROCE_DRV_VERSION);
+ MODULE_AUTHOR("Emulex Corporation");
+ MODULE_LICENSE("GPL");
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0140-RDMA-ocrdma-increment-abi-version-count.patch b/linux-next-cherry-picks/0140-RDMA-ocrdma-increment-abi-version-count.patch
new file mode 100644 (file)
index 0000000..702daf3
--- /dev/null
@@ -0,0 +1,29 @@
+From 2e753c2d314295448b1822786feff345efc2e6b7 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Thu, 30 Jan 2014 11:13:22 +0530
+Subject: [PATCH 07/16] RDMA/ocrdma: increment abi version count
+
+Increment the ABI version count for driver/library interface.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_abi.h |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
+index 2a14d4a..5a82ce5 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
+@@ -28,7 +28,7 @@
+ #ifndef __OCRDMA_ABI_H__
+ #define __OCRDMA_ABI_H__
+-#define OCRDMA_ABI_VERSION 1
++#define OCRDMA_ABI_VERSION 2
+ #define OCRDMA_BE_ROCE_ABI_VERSION 1
+ /* user kernel communication data structures. */
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0141-RDMA-ocrdma-Memory-leak-fix-in-ocrdma_dereg_mr.patch b/linux-next-cherry-picks/0141-RDMA-ocrdma-Memory-leak-fix-in-ocrdma_dereg_mr.patch
new file mode 100644 (file)
index 0000000..76eb7ba
--- /dev/null
@@ -0,0 +1,30 @@
+From 8452902d31f2da4cff07b8cc169437b891ca97cd Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Thu, 30 Jan 2014 12:17:52 +0530
+Subject: [PATCH 08/16] RDMA/ocrdma: Memory leak fix in ocrdma_dereg_mr
+
+Fix for memory leak in ocrdma_dereg_mr.
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    3 +--
+ 1 files changed, 1 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 20ef4ba..9eabe27 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -840,8 +840,7 @@ int ocrdma_dereg_mr(struct ib_mr *ib_mr)
+       status = ocrdma_mbx_dealloc_lkey(dev, mr->hwmr.fr_mr, mr->hwmr.lkey);
+-      if (mr->hwmr.fr_mr == 0)
+-              ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
++      ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
+       /* it could be user registered memory. */
+       if (mr->umem)
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0142-RDMA-ocrdma-Use-non-zero-tag-in-SRQ-posting.patch b/linux-next-cherry-picks/0142-RDMA-ocrdma-Use-non-zero-tag-in-SRQ-posting.patch
new file mode 100644 (file)
index 0000000..01f8cac
--- /dev/null
@@ -0,0 +1,91 @@
+From 24a45fdbe496d1b40a017f0a8d2d0f9e6b4e8060 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Thu, 30 Jan 2014 12:37:09 +0530
+Subject: [PATCH 09/16] RDMA/ocrdma: Use non zero tag in SRQ posting
+
+As part of SRQ receive buffers posting we populate a non-zero tag
+which will be returned in SRQ receive completions.
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   28 +++++++++++++++++---------
+ 1 files changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 9eabe27..786ddfc 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -1537,7 +1537,7 @@ static void ocrdma_discard_cqes(struct ocrdma_qp *qp, struct ocrdma_cq *cq)
+       int discard_cnt = 0;
+       u32 cur_getp, stop_getp;
+       struct ocrdma_cqe *cqe;
+-      u32 qpn = 0;
++      u32 qpn = 0, wqe_idx = 0;
+       spin_lock_irqsave(&cq->cq_lock, cq_flags);
+@@ -1566,24 +1566,29 @@ static void ocrdma_discard_cqes(struct ocrdma_qp *qp, struct ocrdma_cq *cq)
+               if (qpn == 0 || qpn != qp->id)
+                       goto skip_cqe;
+-              /* mark cqe discarded so that it is not picked up later
+-               * in the poll_cq().
+-               */
+-              discard_cnt += 1;
+-              cqe->cmn.qpn = 0;
+               if (is_cqe_for_sq(cqe)) {
+                       ocrdma_hwq_inc_tail(&qp->sq);
+               } else {
+                       if (qp->srq) {
++                              wqe_idx = (le32_to_cpu(cqe->rq.buftag_qpn) >>
++                                      OCRDMA_CQE_BUFTAG_SHIFT) &
++                                      qp->srq->rq.max_wqe_idx;
++                              if (wqe_idx < 1)
++                                      BUG();
+                               spin_lock_irqsave(&qp->srq->q_lock, flags);
+                               ocrdma_hwq_inc_tail(&qp->srq->rq);
+-                              ocrdma_srq_toggle_bit(qp->srq, cur_getp);
++                              ocrdma_srq_toggle_bit(qp->srq, wqe_idx - 1);
+                               spin_unlock_irqrestore(&qp->srq->q_lock, flags);
+                       } else {
+                               ocrdma_hwq_inc_tail(&qp->rq);
+                       }
+               }
++              /* mark cqe discarded so that it is not picked up later
++               * in the poll_cq().
++               */
++              discard_cnt += 1;
++              cqe->cmn.qpn = 0;
+ skip_cqe:
+               cur_getp = (cur_getp + 1) % cq->max_hw_cqe;
+       } while (cur_getp != stop_getp);
+@@ -2239,7 +2244,7 @@ static int ocrdma_srq_get_idx(struct ocrdma_srq *srq)
+       if (row == srq->bit_fields_len)
+               BUG();
+-      return indx;
++      return indx + 1; /* Use from index 1 */
+ }
+ static void ocrdma_ring_srq_db(struct ocrdma_srq *srq)
+@@ -2576,10 +2581,13 @@ static void ocrdma_update_free_srq_cqe(struct ib_wc *ibwc,
+       srq = get_ocrdma_srq(qp->ibqp.srq);
+       wqe_idx = (le32_to_cpu(cqe->rq.buftag_qpn) >>
+-                      OCRDMA_CQE_BUFTAG_SHIFT) & srq->rq.max_wqe_idx;
++              OCRDMA_CQE_BUFTAG_SHIFT) & srq->rq.max_wqe_idx;
++      if (wqe_idx < 1)
++              BUG();
++
+       ibwc->wr_id = srq->rqe_wr_id_tbl[wqe_idx];
+       spin_lock_irqsave(&srq->q_lock, flags);
+-      ocrdma_srq_toggle_bit(srq, wqe_idx);
++      ocrdma_srq_toggle_bit(srq, wqe_idx - 1);
+       spin_unlock_irqrestore(&srq->q_lock, flags);
+       ocrdma_hwq_inc_tail(&srq->rq);
+ }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0143-RDMA-ocrdma-Display-proper-value-for-max_mw.patch b/linux-next-cherry-picks/0143-RDMA-ocrdma-Display-proper-value-for-max_mw.patch
new file mode 100644 (file)
index 0000000..74a9fc2
--- /dev/null
@@ -0,0 +1,55 @@
+From f4969efbef7ed1205bbdc35c41b04666121e04ba Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Thu, 30 Jan 2014 13:35:13 +0530
+Subject: [PATCH 10/16] RDMA/ocrdma: Display proper value for max_mw
+
+Fixing the max_mw value
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h       |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    2 +-
+ 3 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 2eb4d22..f486f3a 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -67,6 +67,7 @@ struct ocrdma_dev_attr {
+       int max_mr;
+       u64 max_mr_size;
+       u32 max_num_mr_pbl;
++      int max_mw;
+       int max_fmr;
+       int max_map_per_fmr;
+       int max_pages_per_frmr;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index dc72df9..69b4266 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -1016,6 +1016,7 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
+       attr->local_ca_ack_delay = (rsp->max_pd_ca_ack_delay &
+                                   OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_MASK) >>
+           OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_SHIFT;
++      attr->max_mw = rsp->max_mw;
+       attr->max_mr = rsp->max_mr;
+       attr->max_mr_size = ~0ull;
+       attr->max_fmr = 0;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 786ddfc..635a757 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -89,7 +89,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
+       attr->max_cq = dev->attr.max_cq;
+       attr->max_cqe = dev->attr.max_cqe;
+       attr->max_mr = dev->attr.max_mr;
+-      attr->max_mw = 0;
++      attr->max_mw = dev->attr.max_mw;
+       attr->max_pd = dev->attr.max_pd;
+       attr->atomic_cap = 0;
+       attr->max_fmr = 0;
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0144-RDMA-ocrdma-Handle-CQ-overrun-error.patch b/linux-next-cherry-picks/0144-RDMA-ocrdma-Handle-CQ-overrun-error.patch
new file mode 100644 (file)
index 0000000..90856b7
--- /dev/null
@@ -0,0 +1,46 @@
+From 5601237f4362363cb35f97caa15db3f3ba40271e Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Thu, 30 Jan 2014 13:45:11 +0530
+Subject: [PATCH 11/16] RDMA/ocrdma: Handle CQ overrun error
+
+Update the variables to handle CQ overrun errors
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    5 ++++-
+ 1 files changed, 4 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 69b4266..bd9c8b1 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -640,7 +640,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
+ {
+       struct ocrdma_qp *qp = NULL;
+       struct ocrdma_cq *cq = NULL;
+-      struct ib_event ib_evt;
++      struct ib_event ib_evt = { 0 };
+       int cq_event = 0;
+       int qp_event = 1;
+       int srq_event = 0;
+@@ -665,6 +665,8 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
+       case OCRDMA_CQ_OVERRUN_ERROR:
+               ib_evt.element.cq = &cq->ibcq;
+               ib_evt.event = IB_EVENT_CQ_ERR;
++              cq_event = 1;
++              qp_event = 0;
+               break;
+       case OCRDMA_CQ_QPCAT_ERROR:
+               ib_evt.element.qp = &qp->ibqp;
+@@ -726,6 +728,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
+                                                    qp->srq->ibsrq.
+                                                    srq_context);
+       } else if (dev_event) {
++              pr_err("%s: Fatal event received\n", dev->ibdev.name);
+               ib_dispatch_event(&ib_evt);
+       }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0145-RDMA-ocrdma-Support-non-embedded-mailbox-commands.patch b/linux-next-cherry-picks/0145-RDMA-ocrdma-Support-non-embedded-mailbox-commands.patch
new file mode 100644 (file)
index 0000000..f10b958
--- /dev/null
@@ -0,0 +1,100 @@
+From f6c4b31875b669bf6562be219578da94d2f06ee3 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Thu, 30 Jan 2014 13:52:18 +0530
+Subject: [PATCH 12/16] RDMA/ocrdma: Support non-embedded mailbox commands
+
+Added a routine to issue non-embedded mailbox commands,
+for handling large mailbox request/response data
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c |   55 +++++++++++++++++++++++++----
+ 1 files changed, 47 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index bd9c8b1..63e3747 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -953,7 +953,8 @@ static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe)
+ {
+       int status = 0;
+       u16 cqe_status, ext_status;
+-      struct ocrdma_mqe *rsp;
++      struct ocrdma_mqe *rsp_mqe;
++      struct ocrdma_mbx_rsp *rsp = NULL;
+       mutex_lock(&dev->mqe_ctx.lock);
+       ocrdma_post_mqe(dev, mqe);
+@@ -962,23 +963,61 @@ static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe)
+               goto mbx_err;
+       cqe_status = dev->mqe_ctx.cqe_status;
+       ext_status = dev->mqe_ctx.ext_status;
+-      rsp = ocrdma_get_mqe_rsp(dev);
+-      ocrdma_copy_le32_to_cpu(mqe, rsp, (sizeof(*mqe)));
++      rsp_mqe = ocrdma_get_mqe_rsp(dev);
++      ocrdma_copy_le32_to_cpu(mqe, rsp_mqe, (sizeof(*mqe)));
++      if ((mqe->hdr.spcl_sge_cnt_emb & OCRDMA_MQE_HDR_EMB_MASK) >>
++                              OCRDMA_MQE_HDR_EMB_SHIFT)
++              rsp = &mqe->u.rsp;
++
+       if (cqe_status || ext_status) {
+-              pr_err("%s() opcode=0x%x, cqe_status=0x%x, ext_status=0x%x\n",
+-                     __func__,
+-                   (rsp->u.rsp.subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >>
+-                   OCRDMA_MBX_RSP_OPCODE_SHIFT, cqe_status, ext_status);
++              pr_err("%s() cqe_status=0x%x, ext_status=0x%x,",
++                     __func__, cqe_status, ext_status);
++              if (rsp) {
++                      /* This is for embedded cmds. */
++                      pr_err("opcode=0x%x, subsystem=0x%x\n",
++                             (rsp->subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >>
++                              OCRDMA_MBX_RSP_OPCODE_SHIFT,
++                              (rsp->subsys_op & OCRDMA_MBX_RSP_SUBSYS_MASK) >>
++                              OCRDMA_MBX_RSP_SUBSYS_SHIFT);
++              }
+               status = ocrdma_get_mbx_cqe_errno(cqe_status);
+               goto mbx_err;
+       }
+-      if (mqe->u.rsp.status & OCRDMA_MBX_RSP_STATUS_MASK)
++      /* For non embedded, rsp errors are handled in ocrdma_nonemb_mbx_cmd */
++      if (rsp && (mqe->u.rsp.status & OCRDMA_MBX_RSP_STATUS_MASK))
+               status = ocrdma_get_mbx_errno(mqe->u.rsp.status);
+ mbx_err:
+       mutex_unlock(&dev->mqe_ctx.lock);
+       return status;
+ }
++static int ocrdma_nonemb_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe,
++                               void *payload_va)
++{
++      int status = 0;
++      struct ocrdma_mbx_rsp *rsp = payload_va;
++
++      if ((mqe->hdr.spcl_sge_cnt_emb & OCRDMA_MQE_HDR_EMB_MASK) >>
++                              OCRDMA_MQE_HDR_EMB_SHIFT)
++              BUG();
++
++      status = ocrdma_mbx_cmd(dev, mqe);
++      if (!status)
++              /* For non embedded, only CQE failures are handled in
++               * ocrdma_mbx_cmd. We need to check for RSP errors.
++               */
++              if (rsp->status & OCRDMA_MBX_RSP_STATUS_MASK)
++                      status = ocrdma_get_mbx_errno(rsp->status);
++
++      if (status)
++              pr_err("opcode=0x%x, subsystem=0x%x\n",
++                     (rsp->subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >>
++                      OCRDMA_MBX_RSP_OPCODE_SHIFT,
++                      (rsp->subsys_op & OCRDMA_MBX_RSP_SUBSYS_MASK) >>
++                      OCRDMA_MBX_RSP_SUBSYS_SHIFT);
++      return status;
++}
++
+ static void ocrdma_get_attr(struct ocrdma_dev *dev,
+                             struct ocrdma_dev_attr *attr,
+                             struct ocrdma_mbx_query_config *rsp)
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0146-RDMA-ocrdma-Query-controller-information.patch b/linux-next-cherry-picks/0146-RDMA-ocrdma-Query-controller-information.patch
new file mode 100644 (file)
index 0000000..6c6bcb6
--- /dev/null
@@ -0,0 +1,375 @@
+From 6ca02cc2ef0271b1e951307769c7756fdfc5120a Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Mon, 3 Feb 2014 18:23:28 +0530
+Subject: [PATCH 13/16] RDMA/ocrdma: Query controller information
+
+Issue mailbox commands to query ocrdma controller
+information and phy information and print them
+while adding ocrdma device.
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h      |   33 +++++++++
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c   |  106 ++++++++++++++++++++++++++++
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.h   |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |    6 ++
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h  |   81 +++++++++++++++++++++-
+ 5 files changed, 226 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index f486f3a..55eb0e6 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -44,6 +44,11 @@
+ #define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
+ #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
++#define OC_NAME_SH    OCRDMA_NODE_DESC "(Skyhawk)"
++#define OC_NAME_UNKNOWN OCRDMA_NODE_DESC "(Unknown)"
++
++#define OC_SKH_DEVICE_PF 0x720
++#define OC_SKH_DEVICE_VF 0x728
+ #define OCRDMA_MAX_AH 512
+ #define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)
+@@ -86,6 +91,12 @@ struct ocrdma_dev_attr {
+       u8 num_ird_pages;
+ };
++struct ocrdma_dma_mem {
++      void *va;
++      dma_addr_t pa;
++      u32 size;
++};
++
+ struct ocrdma_pbl {
+       void *va;
+       dma_addr_t pa;
+@@ -125,6 +136,14 @@ struct mqe_ctx {
+       bool cmd_done;
+ };
++
++struct phy_info {
++      u16 auto_speeds_supported;
++      u16 fixed_speeds_supported;
++      u16 phy_type;
++      u16 interface_type;
++};
++
+ struct ocrdma_dev {
+       struct ib_device ibdev;
+       struct ocrdma_dev_attr attr;
+@@ -168,6 +187,9 @@ struct ocrdma_dev {
+       struct mqe_ctx mqe_ctx;
+       struct be_dev_info nic_info;
++      struct phy_info phy;
++      char model_number[32];
++      u32 hba_port_num;
+       struct list_head entry;
+       struct rcu_head rcu;
+@@ -421,6 +443,17 @@ static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
+ }
++static inline char *hca_name(struct ocrdma_dev *dev)
++{
++      switch (dev->nic_info.pdev->device) {
++      case OC_SKH_DEVICE_PF:
++      case OC_SKH_DEVICE_VF:
++              return OC_NAME_SH;
++      default:
++              return OC_NAME_UNKNOWN;
++      }
++}
++
+ static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev,
+               int eqid)
+ {
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 63e3747..f36aa5d 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -243,6 +243,23 @@ static int ocrdma_get_mbx_errno(u32 status)
+       return err_num;
+ }
++char *port_speed_string(struct ocrdma_dev *dev)
++{
++      char *str = "";
++      u16 speeds_supported;
++
++      speeds_supported = dev->phy.fixed_speeds_supported |
++                              dev->phy.auto_speeds_supported;
++      if (speeds_supported & OCRDMA_PHY_SPEED_40GBPS)
++              str = "40Gbps ";
++      else if (speeds_supported & OCRDMA_PHY_SPEED_10GBPS)
++              str = "10Gbps ";
++      else if (speeds_supported & OCRDMA_PHY_SPEED_1GBPS)
++              str = "1Gbps ";
++
++      return str;
++}
++
+ static int ocrdma_get_mbx_cqe_errno(u16 cqe_status)
+ {
+       int err_num = -EINVAL;
+@@ -332,6 +349,11 @@ static void *ocrdma_init_emb_mqe(u8 opcode, u32 cmd_len)
+       return mqe;
+ }
++static void *ocrdma_alloc_mqe(void)
++{
++      return kzalloc(sizeof(struct ocrdma_mqe), GFP_KERNEL);
++}
++
+ static void ocrdma_free_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q)
+ {
+       dma_free_coherent(&dev->nic_info.pdev->dev, q->size, q->va, q->dma);
+@@ -1154,6 +1176,54 @@ mbx_err:
+       return status;
+ }
++int ocrdma_mbx_get_ctrl_attribs(struct ocrdma_dev *dev)
++{
++      int status = -ENOMEM;
++      struct ocrdma_dma_mem dma;
++      struct ocrdma_mqe *mqe;
++      struct ocrdma_get_ctrl_attribs_rsp *ctrl_attr_rsp;
++      struct mgmt_hba_attribs *hba_attribs;
++
++      mqe = ocrdma_alloc_mqe();
++      if (!mqe)
++              return status;
++      memset(mqe, 0, sizeof(*mqe));
++
++      dma.size = sizeof(struct ocrdma_get_ctrl_attribs_rsp);
++      dma.va   = dma_alloc_coherent(&dev->nic_info.pdev->dev,
++                                      dma.size, &dma.pa, GFP_KERNEL);
++      if (!dma.va)
++              goto free_mqe;
++
++      mqe->hdr.pyld_len = dma.size;
++      mqe->hdr.spcl_sge_cnt_emb |=
++                      (1 << OCRDMA_MQE_HDR_SGE_CNT_SHIFT) &
++                      OCRDMA_MQE_HDR_SGE_CNT_MASK;
++      mqe->u.nonemb_req.sge[0].pa_lo = (u32) (dma.pa & 0xffffffff);
++      mqe->u.nonemb_req.sge[0].pa_hi = (u32) upper_32_bits(dma.pa);
++      mqe->u.nonemb_req.sge[0].len = dma.size;
++
++      memset(dma.va, 0, dma.size);
++      ocrdma_init_mch((struct ocrdma_mbx_hdr *)dma.va,
++                      OCRDMA_CMD_GET_CTRL_ATTRIBUTES,
++                      OCRDMA_SUBSYS_COMMON,
++                      dma.size);
++
++      status = ocrdma_nonemb_mbx_cmd(dev, mqe, dma.va);
++      if (!status) {
++              ctrl_attr_rsp = (struct ocrdma_get_ctrl_attribs_rsp *)dma.va;
++              hba_attribs = &ctrl_attr_rsp->ctrl_attribs.hba_attribs;
++
++              dev->hba_port_num = hba_attribs->phy_port;
++              strncpy(dev->model_number,
++                      hba_attribs->controller_model_number, 31);
++      }
++      dma_free_coherent(&dev->nic_info.pdev->dev, dma.size, dma.va, dma.pa);
++free_mqe:
++      kfree(mqe);
++      return status;
++}
++
+ static int ocrdma_mbx_query_dev(struct ocrdma_dev *dev)
+ {
+       int status = -ENOMEM;
+@@ -1201,6 +1271,35 @@ mbx_err:
+       return status;
+ }
++int ocrdma_mbx_get_phy_info(struct ocrdma_dev *dev)
++{
++      int status = -ENOMEM;
++      struct ocrdma_mqe *cmd;
++      struct ocrdma_get_phy_info_rsp *rsp;
++
++      cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_PHY_DETAILS, sizeof(*cmd));
++      if (!cmd)
++              return status;
++
++      ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0],
++                      OCRDMA_CMD_PHY_DETAILS, OCRDMA_SUBSYS_COMMON,
++                      sizeof(*cmd));
++
++      status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
++      if (status)
++              goto mbx_err;
++
++      rsp = (struct ocrdma_get_phy_info_rsp *)cmd;
++      dev->phy.phy_type = le16_to_cpu(rsp->phy_type);
++      dev->phy.auto_speeds_supported  =
++                      le16_to_cpu(rsp->auto_speeds_supported);
++      dev->phy.fixed_speeds_supported =
++                      le16_to_cpu(rsp->fixed_speeds_supported);
++mbx_err:
++      kfree(cmd);
++      return status;
++}
++
+ int ocrdma_mbx_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
+ {
+       int status = -ENOMEM;
+@@ -2589,6 +2688,13 @@ int ocrdma_init_hw(struct ocrdma_dev *dev)
+       status = ocrdma_mbx_create_ah_tbl(dev);
+       if (status)
+               goto conf_err;
++      status = ocrdma_mbx_get_phy_info(dev);
++      if (status)
++              goto conf_err;
++      status = ocrdma_mbx_get_ctrl_attribs(dev);
++      if (status)
++              goto conf_err;
++
+       return 0;
+ conf_err:
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+index 38102b3..3f8aa86 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+@@ -135,4 +135,5 @@ bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
+ void ocrdma_flush_qp(struct ocrdma_qp *);
+ int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
++char *port_speed_string(struct ocrdma_dev *dev);
+ #endif                                /* __OCRDMA_HW_H__ */
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 5d30161..488a512 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -436,6 +436,12 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
+       spin_lock(&ocrdma_devlist_lock);
+       list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
+       spin_unlock(&ocrdma_devlist_lock);
++      pr_info("%s %s: %s \"%s\" port %d\n",
++              dev_name(&dev->nic_info.pdev->dev), hca_name(dev),
++              port_speed_string(dev), dev->model_number,
++              dev->hba_port_num);
++      pr_info("%s ocrdma%d driver loaded successfully\n",
++              dev_name(&dev->nic_info.pdev->dev), dev->id);
+       return dev;
+ alloc_err:
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index de4ebfc..9e72aec 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -82,12 +82,14 @@ enum {
+       OCRDMA_CMD_CREATE_CQ            = 12,
+       OCRDMA_CMD_CREATE_EQ            = 13,
+       OCRDMA_CMD_CREATE_MQ            = 21,
++      OCRDMA_CMD_GET_CTRL_ATTRIBUTES  = 32,
+       OCRDMA_CMD_GET_FW_VER           = 35,
+       OCRDMA_CMD_DELETE_MQ            = 53,
+       OCRDMA_CMD_DELETE_CQ            = 54,
+       OCRDMA_CMD_DELETE_EQ            = 55,
+       OCRDMA_CMD_GET_FW_CONFIG        = 58,
+-      OCRDMA_CMD_CREATE_MQ_EXT        = 90
++      OCRDMA_CMD_CREATE_MQ_EXT        = 90,
++      OCRDMA_CMD_PHY_DETAILS          = 102
+ };
+ enum {
+@@ -578,6 +580,30 @@ enum {
+       OCRDMA_FN_MODE_RDMA     = 0x4
+ };
++struct ocrdma_get_phy_info_rsp {
++      struct ocrdma_mqe_hdr hdr;
++      struct ocrdma_mbx_rsp rsp;
++
++      u16 phy_type;
++      u16 interface_type;
++      u32 misc_params;
++      u16 ext_phy_details;
++      u16 rsvd;
++      u16 auto_speeds_supported;
++      u16 fixed_speeds_supported;
++      u32 future_use[2];
++};
++
++enum {
++      OCRDMA_PHY_SPEED_ZERO = 0x0,
++      OCRDMA_PHY_SPEED_10MBPS = 0x1,
++      OCRDMA_PHY_SPEED_100MBPS = 0x2,
++      OCRDMA_PHY_SPEED_1GBPS = 0x4,
++      OCRDMA_PHY_SPEED_10GBPS = 0x8,
++      OCRDMA_PHY_SPEED_40GBPS = 0x20
++};
++
++
+ struct ocrdma_get_link_speed_rsp {
+       struct ocrdma_mqe_hdr hdr;
+       struct ocrdma_mbx_rsp rsp;
+@@ -1719,4 +1745,57 @@ struct ocrdma_av {
+       u32 valid;
+ } __packed;
++struct mgmt_hba_attribs {
++      u8 flashrom_version_string[32];
++      u8 manufacturer_name[32];
++      u32 supported_modes;
++      u32 rsvd0[3];
++      u8 ncsi_ver_string[12];
++      u32 default_extended_timeout;
++      u8 controller_model_number[32];
++      u8 controller_description[64];
++      u8 controller_serial_number[32];
++      u8 ip_version_string[32];
++      u8 firmware_version_string[32];
++      u8 bios_version_string[32];
++      u8 redboot_version_string[32];
++      u8 driver_version_string[32];
++      u8 fw_on_flash_version_string[32];
++      u32 functionalities_supported;
++      u16 max_cdblength;
++      u8 asic_revision;
++      u8 generational_guid[16];
++      u8 hba_port_count;
++      u16 default_link_down_timeout;
++      u8 iscsi_ver_min_max;
++      u8 multifunction_device;
++      u8 cache_valid;
++      u8 hba_status;
++      u8 max_domains_supported;
++      u8 phy_port;
++      u32 firmware_post_status;
++      u32 hba_mtu[8];
++      u32 rsvd1[4];
++};
++
++struct mgmt_controller_attrib {
++      struct mgmt_hba_attribs hba_attribs;
++      u16 pci_vendor_id;
++      u16 pci_device_id;
++      u16 pci_sub_vendor_id;
++      u16 pci_sub_system_id;
++      u8 pci_bus_number;
++      u8 pci_device_number;
++      u8 pci_function_number;
++      u8 interface_type;
++      u64 unique_identifier;
++      u32 rsvd0[5];
++};
++
++struct ocrdma_get_ctrl_attribs_rsp {
++      struct ocrdma_mbx_hdr hdr;
++      struct mgmt_controller_attrib ctrl_attribs;
++};
++
++
+ #endif                                /* __OCRDMA_SLI_H__ */
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0147-RDMA-ocrdma-Support-for-Skyhawk-statistics.patch b/linux-next-cherry-picks/0147-RDMA-ocrdma-Support-for-Skyhawk-statistics.patch
new file mode 100644 (file)
index 0000000..87b8562
--- /dev/null
@@ -0,0 +1,1059 @@
+From dec68de33a6a9cb72512bdbeba81850335dc1749 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 18 Feb 2014 16:44:08 +0530
+Subject: [PATCH 14/16] RDMA/ocrdma: Support for Skyhawk statistics
+
+Issue mailbox command to get the statistics counters
+from the skyhawk hardware
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/Makefile       |    2 +-
+ drivers/infiniband/hw/ocrdma/ocrdma.h       |   28 ++
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |   42 ++
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.h    |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c  |    8 +
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |  152 +++++++
+ drivers/infiniband/hw/ocrdma/ocrdma_stats.c |  623 +++++++++++++++++++++++++++
+ drivers/infiniband/hw/ocrdma/ocrdma_stats.h |   54 +++
+ 8 files changed, 909 insertions(+), 1 deletions(-)
+ create mode 100644 drivers/infiniband/hw/ocrdma/ocrdma_stats.c
+ create mode 100644 drivers/infiniband/hw/ocrdma/ocrdma_stats.h
+
+diff --git a/drivers/infiniband/hw/ocrdma/Makefile b/drivers/infiniband/hw/ocrdma/Makefile
+index 06a5bed..d1bfd4f 100644
+--- a/drivers/infiniband/hw/ocrdma/Makefile
++++ b/drivers/infiniband/hw/ocrdma/Makefile
+@@ -2,4 +2,4 @@ ccflags-y := -Idrivers/net/ethernet/emulex/benet
+ obj-$(CONFIG_INFINIBAND_OCRDMA)       += ocrdma.o
+-ocrdma-y :=   ocrdma_main.o ocrdma_verbs.o ocrdma_hw.o ocrdma_ah.o
++ocrdma-y :=   ocrdma_main.o ocrdma_verbs.o ocrdma_hw.o ocrdma_ah.o ocrdma_stats.o
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 55eb0e6..15c8ee4 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -53,6 +53,8 @@
+ #define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)
++#define convert_to_64bit(lo, hi) ((u64)hi << 32 | (u64)lo)
++
+ struct ocrdma_dev_attr {
+       u8 fw_ver[32];
+       u32 vendor_id;
+@@ -136,6 +138,18 @@ struct mqe_ctx {
+       bool cmd_done;
+ };
++struct ocrdma_stats {
++      u8 type;
++      struct ocrdma_dev *dev;
++};
++
++struct stats_mem {
++      struct ocrdma_mqe mqe;
++      void *va;
++      dma_addr_t pa;
++      u32 size;
++      char *debugfs_mem;
++};
+ struct phy_info {
+       u16 auto_speeds_supported;
+@@ -197,6 +211,20 @@ struct ocrdma_dev {
+       u64 stag_arr[OCRDMA_MAX_STAG];
+       u16 pvid;
+       u32 asic_id;
++
++      ulong last_stats_time;
++      struct mutex stats_lock; /* provide synch for debugfs operations */
++      struct stats_mem stats_mem;
++      struct ocrdma_stats rsrc_stats;
++      struct ocrdma_stats rx_stats;
++      struct ocrdma_stats wqe_stats;
++      struct ocrdma_stats tx_stats;
++      struct ocrdma_stats db_err_stats;
++      struct ocrdma_stats tx_qp_err_stats;
++      struct ocrdma_stats rx_qp_err_stats;
++      struct ocrdma_stats tx_dbg_stats;
++      struct ocrdma_stats rx_dbg_stats;
++      struct dentry *dir;
+ };
+ struct ocrdma_cq {
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index f36aa5d..3642383 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -1176,6 +1176,48 @@ mbx_err:
+       return status;
+ }
++int ocrdma_mbx_rdma_stats(struct ocrdma_dev *dev, bool reset)
++{
++      struct ocrdma_rdma_stats_req *req = dev->stats_mem.va;
++      struct ocrdma_mqe *mqe = &dev->stats_mem.mqe;
++      struct ocrdma_rdma_stats_resp *old_stats = NULL;
++      int status;
++
++      old_stats = kzalloc(sizeof(*old_stats), GFP_KERNEL);
++      if (old_stats == NULL)
++              return -ENOMEM;
++
++      memset(mqe, 0, sizeof(*mqe));
++      mqe->hdr.pyld_len = dev->stats_mem.size;
++      mqe->hdr.spcl_sge_cnt_emb |=
++                      (1 << OCRDMA_MQE_HDR_SGE_CNT_SHIFT) &
++                              OCRDMA_MQE_HDR_SGE_CNT_MASK;
++      mqe->u.nonemb_req.sge[0].pa_lo = (u32) (dev->stats_mem.pa & 0xffffffff);
++      mqe->u.nonemb_req.sge[0].pa_hi = (u32) upper_32_bits(dev->stats_mem.pa);
++      mqe->u.nonemb_req.sge[0].len = dev->stats_mem.size;
++
++      /* Cache the old stats */
++      memcpy(old_stats, req, sizeof(struct ocrdma_rdma_stats_resp));
++      memset(req, 0, dev->stats_mem.size);
++
++      ocrdma_init_mch((struct ocrdma_mbx_hdr *)req,
++                      OCRDMA_CMD_GET_RDMA_STATS,
++                      OCRDMA_SUBSYS_ROCE,
++                      dev->stats_mem.size);
++      if (reset)
++              req->reset_stats = reset;
++
++      status = ocrdma_nonemb_mbx_cmd(dev, mqe, dev->stats_mem.va);
++      if (status)
++              /* Copy from cache, if mbox fails */
++              memcpy(req, old_stats, sizeof(struct ocrdma_rdma_stats_resp));
++      else
++              ocrdma_le32_to_cpu(req, dev->stats_mem.size);
++
++      kfree(old_stats);
++      return status;
++}
++
+ int ocrdma_mbx_get_ctrl_attribs(struct ocrdma_dev *dev)
+ {
+       int status = -ENOMEM;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+index 3f8aa86..76ff06d 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+@@ -135,5 +135,6 @@ bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
+ void ocrdma_flush_qp(struct ocrdma_qp *);
+ int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
++int ocrdma_mbx_rdma_stats(struct ocrdma_dev *, bool reset);
+ char *port_speed_string(struct ocrdma_dev *dev);
+ #endif                                /* __OCRDMA_HW_H__ */
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 488a512..95b364d 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -39,6 +39,7 @@
+ #include "ocrdma_ah.h"
+ #include "be_roce.h"
+ #include "ocrdma_hw.h"
++#include "ocrdma_stats.h"
+ #include "ocrdma_abi.h"
+ MODULE_VERSION(OCRDMA_ROCE_DRV_VERSION);
+@@ -436,6 +437,9 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
+       spin_lock(&ocrdma_devlist_lock);
+       list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
+       spin_unlock(&ocrdma_devlist_lock);
++      /* Init stats */
++      ocrdma_add_port_stats(dev);
++
+       pr_info("%s %s: %s \"%s\" port %d\n",
+               dev_name(&dev->nic_info.pdev->dev), hca_name(dev),
+               port_speed_string(dev), dev->model_number,
+@@ -473,6 +477,7 @@ static void ocrdma_remove(struct ocrdma_dev *dev)
+       /* first unregister with stack to stop all the active traffic
+        * of the registered clients.
+        */
++      ocrdma_rem_port_stats(dev);
+       ib_unregister_device(&dev->ibdev);
+       spin_lock(&ocrdma_devlist_lock);
+@@ -561,6 +566,8 @@ static int __init ocrdma_init_module(void)
+ {
+       int status;
++      ocrdma_init_debugfs();
++
+ #if IS_ENABLED(CONFIG_IPV6)
+       status = register_inet6addr_notifier(&ocrdma_inet6addr_notifier);
+       if (status)
+@@ -578,6 +585,7 @@ static void __exit ocrdma_exit_module(void)
+ {
+       be_roce_unregister_driver(&ocrdma_drv);
+       ocrdma_unregister_inet6addr_notifier();
++      ocrdma_rem_debugfs();
+ }
+ module_init(ocrdma_init_module);
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 9e72aec..6e048b7 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -72,6 +72,7 @@ enum {
+       OCRDMA_CMD_ATTACH_MCAST,
+       OCRDMA_CMD_DETACH_MCAST,
++      OCRDMA_CMD_GET_RDMA_STATS,
+       OCRDMA_CMD_MAX
+ };
+@@ -1745,6 +1746,157 @@ struct ocrdma_av {
+       u32 valid;
+ } __packed;
++struct ocrdma_rsrc_stats {
++      u32 dpp_pds;
++      u32 non_dpp_pds;
++      u32 rc_dpp_qps;
++      u32 uc_dpp_qps;
++      u32 ud_dpp_qps;
++      u32 rc_non_dpp_qps;
++      u32 rsvd;
++      u32 uc_non_dpp_qps;
++      u32 ud_non_dpp_qps;
++      u32 rsvd1;
++      u32 srqs;
++      u32 rbqs;
++      u32 r64K_nsmr;
++      u32 r64K_to_2M_nsmr;
++      u32 r2M_to_44M_nsmr;
++      u32 r44M_to_1G_nsmr;
++      u32 r1G_to_4G_nsmr;
++      u32 nsmr_count_4G_to_32G;
++      u32 r32G_to_64G_nsmr;
++      u32 r64G_to_128G_nsmr;
++      u32 r128G_to_higher_nsmr;
++      u32 embedded_nsmr;
++      u32 frmr;
++      u32 prefetch_qps;
++      u32 ondemand_qps;
++      u32 phy_mr;
++      u32 mw;
++      u32 rsvd2[7];
++};
++
++struct ocrdma_db_err_stats {
++      u32 sq_doorbell_errors;
++      u32 cq_doorbell_errors;
++      u32 rq_srq_doorbell_errors;
++      u32 cq_overflow_errors;
++      u32 rsvd[4];
++};
++
++struct ocrdma_wqe_stats {
++      u32 large_send_rc_wqes_lo;
++      u32 large_send_rc_wqes_hi;
++      u32 large_write_rc_wqes_lo;
++      u32 large_write_rc_wqes_hi;
++      u32 rsvd[4];
++      u32 read_wqes_lo;
++      u32 read_wqes_hi;
++      u32 frmr_wqes_lo;
++      u32 frmr_wqes_hi;
++      u32 mw_bind_wqes_lo;
++      u32 mw_bind_wqes_hi;
++      u32 invalidate_wqes_lo;
++      u32 invalidate_wqes_hi;
++      u32 rsvd1[2];
++      u32 dpp_wqe_drops;
++      u32 rsvd2[5];
++};
++
++struct ocrdma_tx_stats {
++      u32 send_pkts_lo;
++      u32 send_pkts_hi;
++      u32 write_pkts_lo;
++      u32 write_pkts_hi;
++      u32 read_pkts_lo;
++      u32 read_pkts_hi;
++      u32 read_rsp_pkts_lo;
++      u32 read_rsp_pkts_hi;
++      u32 ack_pkts_lo;
++      u32 ack_pkts_hi;
++      u32 send_bytes_lo;
++      u32 send_bytes_hi;
++      u32 write_bytes_lo;
++      u32 write_bytes_hi;
++      u32 read_req_bytes_lo;
++      u32 read_req_bytes_hi;
++      u32 read_rsp_bytes_lo;
++      u32 read_rsp_bytes_hi;
++      u32 ack_timeouts;
++      u32 rsvd[5];
++};
++
++
++struct ocrdma_tx_qp_err_stats {
++      u32 local_length_errors;
++      u32 local_protection_errors;
++      u32 local_qp_operation_errors;
++      u32 retry_count_exceeded_errors;
++      u32 rnr_retry_count_exceeded_errors;
++      u32 rsvd[3];
++};
++
++struct ocrdma_rx_stats {
++      u32 roce_frame_bytes_lo;
++      u32 roce_frame_bytes_hi;
++      u32 roce_frame_icrc_drops;
++      u32 roce_frame_payload_len_drops;
++      u32 ud_drops;
++      u32 qp1_drops;
++      u32 psn_error_request_packets;
++      u32 psn_error_resp_packets;
++      u32 rnr_nak_timeouts;
++      u32 rnr_nak_receives;
++      u32 roce_frame_rxmt_drops;
++      u32 nak_count_psn_sequence_errors;
++      u32 rc_drop_count_lookup_errors;
++      u32 rq_rnr_naks;
++      u32 srq_rnr_naks;
++      u32 roce_frames_lo;
++      u32 roce_frames_hi;
++      u32 rsvd;
++};
++
++struct ocrdma_rx_qp_err_stats {
++      u32 nak_invalid_requst_errors;
++      u32 nak_remote_operation_errors;
++      u32 nak_count_remote_access_errors;
++      u32 local_length_errors;
++      u32 local_protection_errors;
++      u32 local_qp_operation_errors;
++      u32 rsvd[2];
++};
++
++struct ocrdma_tx_dbg_stats {
++      u32 data[100];
++};
++
++struct ocrdma_rx_dbg_stats {
++      u32 data[200];
++};
++
++struct ocrdma_rdma_stats_req {
++      struct ocrdma_mbx_hdr hdr;
++      u8 reset_stats;
++      u8 rsvd[3];
++} __packed;
++
++struct ocrdma_rdma_stats_resp {
++      struct ocrdma_mbx_hdr hdr;
++      struct ocrdma_rsrc_stats act_rsrc_stats;
++      struct ocrdma_rsrc_stats th_rsrc_stats;
++      struct ocrdma_db_err_stats      db_err_stats;
++      struct ocrdma_wqe_stats         wqe_stats;
++      struct ocrdma_tx_stats          tx_stats;
++      struct ocrdma_tx_qp_err_stats   tx_qp_err_stats;
++      struct ocrdma_rx_stats          rx_stats;
++      struct ocrdma_rx_qp_err_stats   rx_qp_err_stats;
++      struct ocrdma_tx_dbg_stats      tx_dbg_stats;
++      struct ocrdma_rx_dbg_stats      rx_dbg_stats;
++} __packed;
++
++
+ struct mgmt_hba_attribs {
+       u8 flashrom_version_string[32];
+       u8 manufacturer_name[32];
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
+new file mode 100644
+index 0000000..6b3852a
+--- /dev/null
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
+@@ -0,0 +1,623 @@
++/*******************************************************************
++ * This file is part of the Emulex RoCE Device Driver for          *
++ * RoCE (RDMA over Converged Ethernet) adapters.                   *
++ * Copyright (C) 2008-2014 Emulex. All rights reserved.            *
++ * EMULEX and SLI are trademarks of Emulex.                        *
++ * www.emulex.com                                                  *
++ *                                                                 *
++ * This program is free software; you can redistribute it and/or   *
++ * modify it under the terms of version 2 of the GNU General       *
++ * Public License as published by the Free Software Foundation.    *
++ * This program is distributed in the hope that it will be useful. *
++ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
++ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
++ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
++ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
++ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
++ * more details, a copy of which can be found in the file COPYING  *
++ * included with this package.                                     *
++ *
++ * Contact Information:
++ * linux-drivers@emulex.com
++ *
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
++ *******************************************************************/
++
++#include <rdma/ib_addr.h>
++#include "ocrdma_stats.h"
++
++static struct dentry *ocrdma_dbgfs_dir;
++
++static int ocrdma_add_stat(char *start, char *pcur,
++                              char *name, u64 count)
++{
++      char buff[128] = {0};
++      int cpy_len = 0;
++
++      snprintf(buff, 128, "%s: %llu\n", name, count);
++      cpy_len = strlen(buff);
++
++      if (pcur + cpy_len > start + OCRDMA_MAX_DBGFS_MEM) {
++              pr_err("%s: No space in stats buff\n", __func__);
++              return 0;
++      }
++
++      memcpy(pcur, buff, cpy_len);
++      return cpy_len;
++}
++
++static bool ocrdma_alloc_stats_mem(struct ocrdma_dev *dev)
++{
++      struct stats_mem *mem = &dev->stats_mem;
++
++      /* Alloc mbox command mem*/
++      mem->size = max_t(u32, sizeof(struct ocrdma_rdma_stats_req),
++                      sizeof(struct ocrdma_rdma_stats_resp));
++
++      mem->va   = dma_alloc_coherent(&dev->nic_info.pdev->dev, mem->size,
++                                       &mem->pa, GFP_KERNEL);
++      if (!mem->va) {
++              pr_err("%s: stats mbox allocation failed\n", __func__);
++              return false;
++      }
++
++      memset(mem->va, 0, mem->size);
++
++      /* Alloc debugfs mem */
++      mem->debugfs_mem = kzalloc(OCRDMA_MAX_DBGFS_MEM, GFP_KERNEL);
++      if (!mem->debugfs_mem) {
++              pr_err("%s: stats debugfs mem allocation failed\n", __func__);
++              return false;
++      }
++
++      return true;
++}
++
++static void ocrdma_release_stats_mem(struct ocrdma_dev *dev)
++{
++      struct stats_mem *mem = &dev->stats_mem;
++
++      if (mem->va)
++              dma_free_coherent(&dev->nic_info.pdev->dev, mem->size,
++                                mem->va, mem->pa);
++      kfree(mem->debugfs_mem);
++}
++
++static char *ocrdma_resource_stats(struct ocrdma_dev *dev)
++{
++      char *stats = dev->stats_mem.debugfs_mem, *pcur;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++                      (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_rsrc_stats *rsrc_stats = &rdma_stats->act_rsrc_stats;
++
++      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      pcur = stats;
++      pcur += ocrdma_add_stat(stats, pcur, "active_dpp_pds",
++                              (u64)rsrc_stats->dpp_pds);
++      pcur += ocrdma_add_stat(stats, pcur, "active_non_dpp_pds",
++                              (u64)rsrc_stats->non_dpp_pds);
++      pcur += ocrdma_add_stat(stats, pcur, "active_rc_dpp_qps",
++                              (u64)rsrc_stats->rc_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_uc_dpp_qps",
++                              (u64)rsrc_stats->uc_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_ud_dpp_qps",
++                              (u64)rsrc_stats->ud_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_rc_non_dpp_qps",
++                              (u64)rsrc_stats->rc_non_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_uc_non_dpp_qps",
++                              (u64)rsrc_stats->uc_non_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_ud_non_dpp_qps",
++                              (u64)rsrc_stats->ud_non_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_srqs",
++                              (u64)rsrc_stats->srqs);
++      pcur += ocrdma_add_stat(stats, pcur, "active_rbqs",
++                              (u64)rsrc_stats->rbqs);
++      pcur += ocrdma_add_stat(stats, pcur, "active_64K_nsmr",
++                              (u64)rsrc_stats->r64K_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_64K_to_2M_nsmr",
++                              (u64)rsrc_stats->r64K_to_2M_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_2M_to_44M_nsmr",
++                              (u64)rsrc_stats->r2M_to_44M_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_44M_to_1G_nsmr",
++                              (u64)rsrc_stats->r44M_to_1G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_1G_to_4G_nsmr",
++                              (u64)rsrc_stats->r1G_to_4G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_nsmr_count_4G_to_32G",
++                              (u64)rsrc_stats->nsmr_count_4G_to_32G);
++      pcur += ocrdma_add_stat(stats, pcur, "active_32G_to_64G_nsmr",
++                              (u64)rsrc_stats->r32G_to_64G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_64G_to_128G_nsmr",
++                              (u64)rsrc_stats->r64G_to_128G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_128G_to_higher_nsmr",
++                              (u64)rsrc_stats->r128G_to_higher_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_embedded_nsmr",
++                              (u64)rsrc_stats->embedded_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_frmr",
++                              (u64)rsrc_stats->frmr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_prefetch_qps",
++                              (u64)rsrc_stats->prefetch_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_ondemand_qps",
++                              (u64)rsrc_stats->ondemand_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "active_phy_mr",
++                              (u64)rsrc_stats->phy_mr);
++      pcur += ocrdma_add_stat(stats, pcur, "active_mw",
++                              (u64)rsrc_stats->mw);
++
++      /* Print the threshold stats */
++      rsrc_stats = &rdma_stats->th_rsrc_stats;
++
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_dpp_pds",
++                              (u64)rsrc_stats->dpp_pds);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_non_dpp_pds",
++                              (u64)rsrc_stats->non_dpp_pds);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_rc_dpp_qps",
++                              (u64)rsrc_stats->rc_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_uc_dpp_qps",
++                              (u64)rsrc_stats->uc_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_ud_dpp_qps",
++                              (u64)rsrc_stats->ud_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_rc_non_dpp_qps",
++                              (u64)rsrc_stats->rc_non_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_uc_non_dpp_qps",
++                              (u64)rsrc_stats->uc_non_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_ud_non_dpp_qps",
++                              (u64)rsrc_stats->ud_non_dpp_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_srqs",
++                              (u64)rsrc_stats->srqs);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_rbqs",
++                              (u64)rsrc_stats->rbqs);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_64K_nsmr",
++                              (u64)rsrc_stats->r64K_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_64K_to_2M_nsmr",
++                              (u64)rsrc_stats->r64K_to_2M_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_2M_to_44M_nsmr",
++                              (u64)rsrc_stats->r2M_to_44M_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_44M_to_1G_nsmr",
++                              (u64)rsrc_stats->r44M_to_1G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_1G_to_4G_nsmr",
++                              (u64)rsrc_stats->r1G_to_4G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_nsmr_count_4G_to_32G",
++                              (u64)rsrc_stats->nsmr_count_4G_to_32G);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_32G_to_64G_nsmr",
++                              (u64)rsrc_stats->r32G_to_64G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_64G_to_128G_nsmr",
++                              (u64)rsrc_stats->r64G_to_128G_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_128G_to_higher_nsmr",
++                              (u64)rsrc_stats->r128G_to_higher_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_embedded_nsmr",
++                              (u64)rsrc_stats->embedded_nsmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_frmr",
++                              (u64)rsrc_stats->frmr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_prefetch_qps",
++                              (u64)rsrc_stats->prefetch_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_ondemand_qps",
++                              (u64)rsrc_stats->ondemand_qps);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_phy_mr",
++                              (u64)rsrc_stats->phy_mr);
++      pcur += ocrdma_add_stat(stats, pcur, "threshold_mw",
++                              (u64)rsrc_stats->mw);
++      return stats;
++}
++
++static char *ocrdma_rx_stats(struct ocrdma_dev *dev)
++{
++      char *stats = dev->stats_mem.debugfs_mem, *pcur;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_rx_stats *rx_stats = &rdma_stats->rx_stats;
++
++      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      pcur = stats;
++      pcur += ocrdma_add_stat
++              (stats, pcur, "roce_frame_bytes",
++               convert_to_64bit(rx_stats->roce_frame_bytes_lo,
++               rx_stats->roce_frame_bytes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "roce_frame_icrc_drops",
++                              (u64)rx_stats->roce_frame_icrc_drops);
++      pcur += ocrdma_add_stat(stats, pcur, "roce_frame_payload_len_drops",
++                              (u64)rx_stats->roce_frame_payload_len_drops);
++      pcur += ocrdma_add_stat(stats, pcur, "ud_drops",
++                              (u64)rx_stats->ud_drops);
++      pcur += ocrdma_add_stat(stats, pcur, "qp1_drops",
++                              (u64)rx_stats->qp1_drops);
++      pcur += ocrdma_add_stat(stats, pcur, "psn_error_request_packets",
++                              (u64)rx_stats->psn_error_request_packets);
++      pcur += ocrdma_add_stat(stats, pcur, "psn_error_resp_packets",
++                              (u64)rx_stats->psn_error_resp_packets);
++      pcur += ocrdma_add_stat(stats, pcur, "rnr_nak_timeouts",
++                              (u64)rx_stats->rnr_nak_timeouts);
++      pcur += ocrdma_add_stat(stats, pcur, "rnr_nak_receives",
++                              (u64)rx_stats->rnr_nak_receives);
++      pcur += ocrdma_add_stat(stats, pcur, "roce_frame_rxmt_drops",
++                              (u64)rx_stats->roce_frame_rxmt_drops);
++      pcur += ocrdma_add_stat(stats, pcur, "nak_count_psn_sequence_errors",
++                              (u64)rx_stats->nak_count_psn_sequence_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "rc_drop_count_lookup_errors",
++                              (u64)rx_stats->rc_drop_count_lookup_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "rq_rnr_naks",
++                              (u64)rx_stats->rq_rnr_naks);
++      pcur += ocrdma_add_stat(stats, pcur, "srq_rnr_naks",
++                              (u64)rx_stats->srq_rnr_naks);
++      pcur += ocrdma_add_stat(stats, pcur, "roce_frames",
++                              convert_to_64bit(rx_stats->roce_frames_lo,
++                                               rx_stats->roce_frames_hi));
++
++      return stats;
++}
++
++static char *ocrdma_tx_stats(struct ocrdma_dev *dev)
++{
++      char *stats = dev->stats_mem.debugfs_mem, *pcur;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_tx_stats *tx_stats = &rdma_stats->tx_stats;
++
++      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      pcur = stats;
++      pcur += ocrdma_add_stat(stats, pcur, "send_pkts",
++                              convert_to_64bit(tx_stats->send_pkts_lo,
++                                               tx_stats->send_pkts_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "write_pkts",
++                              convert_to_64bit(tx_stats->write_pkts_lo,
++                                               tx_stats->write_pkts_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "read_pkts",
++                              convert_to_64bit(tx_stats->read_pkts_lo,
++                                               tx_stats->read_pkts_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "read_rsp_pkts",
++                              convert_to_64bit(tx_stats->read_rsp_pkts_lo,
++                                               tx_stats->read_rsp_pkts_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "ack_pkts",
++                              convert_to_64bit(tx_stats->ack_pkts_lo,
++                                               tx_stats->ack_pkts_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "send_bytes",
++                              convert_to_64bit(tx_stats->send_bytes_lo,
++                                               tx_stats->send_bytes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "write_bytes",
++                              convert_to_64bit(tx_stats->write_bytes_lo,
++                                               tx_stats->write_bytes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "read_req_bytes",
++                              convert_to_64bit(tx_stats->read_req_bytes_lo,
++                                               tx_stats->read_req_bytes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "read_rsp_bytes",
++                              convert_to_64bit(tx_stats->read_rsp_bytes_lo,
++                                               tx_stats->read_rsp_bytes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "ack_timeouts",
++                              (u64)tx_stats->ack_timeouts);
++
++      return stats;
++}
++
++static char *ocrdma_wqe_stats(struct ocrdma_dev *dev)
++{
++      char *stats = dev->stats_mem.debugfs_mem, *pcur;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_wqe_stats *wqe_stats = &rdma_stats->wqe_stats;
++
++      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      pcur = stats;
++      pcur += ocrdma_add_stat(stats, pcur, "large_send_rc_wqes",
++              convert_to_64bit(wqe_stats->large_send_rc_wqes_lo,
++                               wqe_stats->large_send_rc_wqes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "large_write_rc_wqes",
++              convert_to_64bit(wqe_stats->large_write_rc_wqes_lo,
++                               wqe_stats->large_write_rc_wqes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "read_wqes",
++                              convert_to_64bit(wqe_stats->read_wqes_lo,
++                                               wqe_stats->read_wqes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "frmr_wqes",
++                              convert_to_64bit(wqe_stats->frmr_wqes_lo,
++                                               wqe_stats->frmr_wqes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "mw_bind_wqes",
++                              convert_to_64bit(wqe_stats->mw_bind_wqes_lo,
++                                               wqe_stats->mw_bind_wqes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "invalidate_wqes",
++              convert_to_64bit(wqe_stats->invalidate_wqes_lo,
++                               wqe_stats->invalidate_wqes_hi));
++      pcur += ocrdma_add_stat(stats, pcur, "dpp_wqe_drops",
++                              (u64)wqe_stats->dpp_wqe_drops);
++      return stats;
++}
++
++static char *ocrdma_db_errstats(struct ocrdma_dev *dev)
++{
++      char *stats = dev->stats_mem.debugfs_mem, *pcur;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_db_err_stats *db_err_stats = &rdma_stats->db_err_stats;
++
++      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      pcur = stats;
++      pcur += ocrdma_add_stat(stats, pcur, "sq_doorbell_errors",
++                              (u64)db_err_stats->sq_doorbell_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "cq_doorbell_errors",
++                              (u64)db_err_stats->cq_doorbell_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "rq_srq_doorbell_errors",
++                              (u64)db_err_stats->rq_srq_doorbell_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "cq_overflow_errors",
++                              (u64)db_err_stats->cq_overflow_errors);
++      return stats;
++}
++
++static char *ocrdma_rxqp_errstats(struct ocrdma_dev *dev)
++{
++      char *stats = dev->stats_mem.debugfs_mem, *pcur;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_rx_qp_err_stats *rx_qp_err_stats =
++               &rdma_stats->rx_qp_err_stats;
++
++      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      pcur = stats;
++      pcur += ocrdma_add_stat(stats, pcur, "nak_invalid_requst_errors",
++                      (u64)rx_qp_err_stats->nak_invalid_requst_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "nak_remote_operation_errors",
++                      (u64)rx_qp_err_stats->nak_remote_operation_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "nak_count_remote_access_errors",
++                      (u64)rx_qp_err_stats->nak_count_remote_access_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "local_length_errors",
++                      (u64)rx_qp_err_stats->local_length_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "local_protection_errors",
++                      (u64)rx_qp_err_stats->local_protection_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "local_qp_operation_errors",
++                      (u64)rx_qp_err_stats->local_qp_operation_errors);
++      return stats;
++}
++
++static char *ocrdma_txqp_errstats(struct ocrdma_dev *dev)
++{
++      char *stats = dev->stats_mem.debugfs_mem, *pcur;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_tx_qp_err_stats *tx_qp_err_stats =
++              &rdma_stats->tx_qp_err_stats;
++
++      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      pcur = stats;
++      pcur += ocrdma_add_stat(stats, pcur, "local_length_errors",
++                      (u64)tx_qp_err_stats->local_length_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "local_protection_errors",
++                      (u64)tx_qp_err_stats->local_protection_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "local_qp_operation_errors",
++                      (u64)tx_qp_err_stats->local_qp_operation_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "retry_count_exceeded_errors",
++                      (u64)tx_qp_err_stats->retry_count_exceeded_errors);
++      pcur += ocrdma_add_stat(stats, pcur, "rnr_retry_count_exceeded_errors",
++                      (u64)tx_qp_err_stats->rnr_retry_count_exceeded_errors);
++      return stats;
++}
++
++static char *ocrdma_tx_dbg_stats(struct ocrdma_dev *dev)
++{
++      int i;
++      char *pstats = dev->stats_mem.debugfs_mem;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_tx_dbg_stats *tx_dbg_stats =
++              &rdma_stats->tx_dbg_stats;
++
++      memset(pstats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      for (i = 0; i < 100; i++)
++              pstats += snprintf(pstats, 80, "DW[%d] = 0x%x\n", i,
++                               tx_dbg_stats->data[i]);
++
++      return dev->stats_mem.debugfs_mem;
++}
++
++static char *ocrdma_rx_dbg_stats(struct ocrdma_dev *dev)
++{
++      int i;
++      char *pstats = dev->stats_mem.debugfs_mem;
++      struct ocrdma_rdma_stats_resp *rdma_stats =
++              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
++      struct ocrdma_rx_dbg_stats *rx_dbg_stats =
++              &rdma_stats->rx_dbg_stats;
++
++      memset(pstats, 0, (OCRDMA_MAX_DBGFS_MEM));
++
++      for (i = 0; i < 200; i++)
++              pstats += snprintf(pstats, 80, "DW[%d] = 0x%x\n", i,
++                               rx_dbg_stats->data[i]);
++
++      return dev->stats_mem.debugfs_mem;
++}
++
++static void ocrdma_update_stats(struct ocrdma_dev *dev)
++{
++      ulong now = jiffies, secs;
++      int status = 0;
++
++      secs = jiffies_to_msecs(now - dev->last_stats_time) / 1000U;
++      if (secs) {
++              /* update */
++              status = ocrdma_mbx_rdma_stats(dev, false);
++              if (status)
++                      pr_err("%s: stats mbox failed with status = %d\n",
++                             __func__, status);
++              dev->last_stats_time = jiffies;
++      }
++}
++
++static ssize_t ocrdma_dbgfs_ops_read(struct file *filp, char __user *buffer,
++                                      size_t usr_buf_len, loff_t *ppos)
++{
++      struct ocrdma_stats *pstats = filp->private_data;
++      struct ocrdma_dev *dev = pstats->dev;
++      ssize_t status = 0;
++      char *data = NULL;
++
++      /* No partial reads */
++      if (*ppos != 0)
++              return 0;
++
++      mutex_lock(&dev->stats_lock);
++
++      ocrdma_update_stats(dev);
++
++      switch (pstats->type) {
++      case OCRDMA_RSRC_STATS:
++              data = ocrdma_resource_stats(dev);
++              break;
++      case OCRDMA_RXSTATS:
++              data = ocrdma_rx_stats(dev);
++              break;
++      case OCRDMA_WQESTATS:
++              data = ocrdma_wqe_stats(dev);
++              break;
++      case OCRDMA_TXSTATS:
++              data = ocrdma_tx_stats(dev);
++              break;
++      case OCRDMA_DB_ERRSTATS:
++              data = ocrdma_db_errstats(dev);
++              break;
++      case OCRDMA_RXQP_ERRSTATS:
++              data = ocrdma_rxqp_errstats(dev);
++              break;
++      case OCRDMA_TXQP_ERRSTATS:
++              data = ocrdma_txqp_errstats(dev);
++              break;
++      case OCRDMA_TX_DBG_STATS:
++              data = ocrdma_tx_dbg_stats(dev);
++              break;
++      case OCRDMA_RX_DBG_STATS:
++              data = ocrdma_rx_dbg_stats(dev);
++              break;
++
++      default:
++              status = -EFAULT;
++              goto exit;
++      }
++
++      if (usr_buf_len < strlen(data)) {
++              status = -ENOSPC;
++              goto exit;
++      }
++
++      status = simple_read_from_buffer(buffer, usr_buf_len, ppos, data,
++                                       strlen(data));
++exit:
++      mutex_unlock(&dev->stats_lock);
++      return status;
++}
++
++int ocrdma_debugfs_open(struct inode *inode, struct file *file)
++{
++      if (inode->i_private)
++              file->private_data = inode->i_private;
++      return 0;
++}
++
++static const struct file_operations ocrdma_dbg_ops = {
++      .owner = THIS_MODULE,
++      .open = ocrdma_debugfs_open,
++      .read = ocrdma_dbgfs_ops_read,
++};
++
++void ocrdma_add_port_stats(struct ocrdma_dev *dev)
++{
++      if (!ocrdma_dbgfs_dir)
++              return;
++
++      /* Create post stats base dir */
++      dev->dir = debugfs_create_dir(dev->ibdev.name, ocrdma_dbgfs_dir);
++      if (!dev->dir)
++              goto err;
++
++      dev->rsrc_stats.type = OCRDMA_RSRC_STATS;
++      dev->rsrc_stats.dev = dev;
++      if (!debugfs_create_file("resource_stats", S_IRUSR, dev->dir,
++                               &dev->rsrc_stats, &ocrdma_dbg_ops))
++              goto err;
++
++      dev->rx_stats.type = OCRDMA_RXSTATS;
++      dev->rx_stats.dev = dev;
++      if (!debugfs_create_file("rx_stats", S_IRUSR, dev->dir,
++                               &dev->rx_stats, &ocrdma_dbg_ops))
++              goto err;
++
++      dev->wqe_stats.type = OCRDMA_WQESTATS;
++      dev->wqe_stats.dev = dev;
++      if (!debugfs_create_file("wqe_stats", S_IRUSR, dev->dir,
++                               &dev->wqe_stats, &ocrdma_dbg_ops))
++              goto err;
++
++      dev->tx_stats.type = OCRDMA_TXSTATS;
++      dev->tx_stats.dev = dev;
++      if (!debugfs_create_file("tx_stats", S_IRUSR, dev->dir,
++                               &dev->tx_stats, &ocrdma_dbg_ops))
++              goto err;
++
++      dev->db_err_stats.type = OCRDMA_DB_ERRSTATS;
++      dev->db_err_stats.dev = dev;
++      if (!debugfs_create_file("db_err_stats", S_IRUSR, dev->dir,
++                               &dev->db_err_stats, &ocrdma_dbg_ops))
++              goto err;
++
++
++      dev->tx_qp_err_stats.type = OCRDMA_TXQP_ERRSTATS;
++      dev->tx_qp_err_stats.dev = dev;
++      if (!debugfs_create_file("tx_qp_err_stats", S_IRUSR, dev->dir,
++                               &dev->tx_qp_err_stats, &ocrdma_dbg_ops))
++              goto err;
++
++      dev->rx_qp_err_stats.type = OCRDMA_RXQP_ERRSTATS;
++      dev->rx_qp_err_stats.dev = dev;
++      if (!debugfs_create_file("rx_qp_err_stats", S_IRUSR, dev->dir,
++                               &dev->rx_qp_err_stats, &ocrdma_dbg_ops))
++              goto err;
++
++
++      dev->tx_dbg_stats.type = OCRDMA_TX_DBG_STATS;
++      dev->tx_dbg_stats.dev = dev;
++      if (!debugfs_create_file("tx_dbg_stats", S_IRUSR, dev->dir,
++                               &dev->tx_dbg_stats, &ocrdma_dbg_ops))
++              goto err;
++
++      dev->rx_dbg_stats.type = OCRDMA_RX_DBG_STATS;
++      dev->rx_dbg_stats.dev = dev;
++      if (!debugfs_create_file("rx_dbg_stats", S_IRUSR, dev->dir,
++                               &dev->rx_dbg_stats, &ocrdma_dbg_ops))
++              goto err;
++
++      /* Now create dma_mem for stats mbx command */
++      if (!ocrdma_alloc_stats_mem(dev))
++              goto err;
++
++      mutex_init(&dev->stats_lock);
++
++      return;
++err:
++      ocrdma_release_stats_mem(dev);
++      debugfs_remove_recursive(dev->dir);
++      dev->dir = NULL;
++}
++
++void ocrdma_rem_port_stats(struct ocrdma_dev *dev)
++{
++      if (!dev->dir)
++              return;
++      mutex_destroy(&dev->stats_lock);
++      ocrdma_release_stats_mem(dev);
++      debugfs_remove(dev->dir);
++}
++
++void ocrdma_init_debugfs(void)
++{
++      /* Create base dir in debugfs root dir */
++      ocrdma_dbgfs_dir = debugfs_create_dir("ocrdma", NULL);
++}
++
++void ocrdma_rem_debugfs(void)
++{
++      debugfs_remove_recursive(ocrdma_dbgfs_dir);
++}
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_stats.h b/drivers/infiniband/hw/ocrdma/ocrdma_stats.h
+new file mode 100644
+index 0000000..5f5e20c
+--- /dev/null
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_stats.h
+@@ -0,0 +1,54 @@
++/*******************************************************************
++ * This file is part of the Emulex RoCE Device Driver for          *
++ * RoCE (RDMA over Converged Ethernet) adapters.                   *
++ * Copyright (C) 2008-2014 Emulex. All rights reserved.            *
++ * EMULEX and SLI are trademarks of Emulex.                        *
++ * www.emulex.com                                                  *
++ *                                                                 *
++ * This program is free software; you can redistribute it and/or   *
++ * modify it under the terms of version 2 of the GNU General       *
++ * Public License as published by the Free Software Foundation.    *
++ * This program is distributed in the hope that it will be useful. *
++ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
++ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
++ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
++ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
++ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
++ * more details, a copy of which can be found in the file COPYING  *
++ * included with this package.                                     *
++ *
++ * Contact Information:
++ * linux-drivers@emulex.com
++ *
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
++ *******************************************************************/
++
++#ifndef __OCRDMA_STATS_H__
++#define __OCRDMA_STATS_H__
++
++#include <linux/debugfs.h>
++#include "ocrdma.h"
++#include "ocrdma_hw.h"
++
++#define OCRDMA_MAX_DBGFS_MEM 4096
++
++enum OCRDMA_STATS_TYPE {
++      OCRDMA_RSRC_STATS,
++      OCRDMA_RXSTATS,
++      OCRDMA_WQESTATS,
++      OCRDMA_TXSTATS,
++      OCRDMA_DB_ERRSTATS,
++      OCRDMA_RXQP_ERRSTATS,
++      OCRDMA_TXQP_ERRSTATS,
++      OCRDMA_TX_DBG_STATS,
++      OCRDMA_RX_DBG_STATS
++};
++
++void ocrdma_rem_debugfs(void);
++void ocrdma_init_debugfs(void);
++void ocrdma_rem_port_stats(struct ocrdma_dev *dev);
++void ocrdma_add_port_stats(struct ocrdma_dev *dev);
++
++#endif        /* __OCRDMA_STATS_H__ */
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0148-RDMA-ocrdma-Display-fw-version.patch b/linux-next-cherry-picks/0148-RDMA-ocrdma-Display-fw-version.patch
new file mode 100644 (file)
index 0000000..b367cde
--- /dev/null
@@ -0,0 +1,91 @@
+From 7e7996497f57550a5d0b100eff66cf668e22f3e6 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 18 Feb 2014 16:49:54 +0530
+Subject: [PATCH 15/16] RDMA/ocrdma: Display fw version
+
+Adding a sysfs file for getting the FW version.
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |   41 +++++++++++++++++++++++++++-
+ 1 files changed, 40 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 95b364d..72389f6 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -399,9 +399,42 @@ static void ocrdma_free_resources(struct ocrdma_dev *dev)
+       kfree(dev->sgid_tbl);
+ }
++/* OCRDMA sysfs interface */
++static ssize_t show_rev(struct device *device, struct device_attribute *attr,
++                      char *buf)
++{
++      struct ocrdma_dev *dev = dev_get_drvdata(device);
++
++      return scnprintf(buf, PAGE_SIZE, "0x%x\n", dev->nic_info.pdev->vendor);
++}
++
++static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
++                      char *buf)
++{
++      struct ocrdma_dev *dev = dev_get_drvdata(device);
++
++      return scnprintf(buf, PAGE_SIZE, "%s\n", &dev->attr.fw_ver[0]);
++}
++
++static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
++static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
++
++static struct device_attribute *ocrdma_attributes[] = {
++      &dev_attr_hw_rev,
++      &dev_attr_fw_ver
++};
++
++static void ocrdma_remove_sysfiles(struct ocrdma_dev *dev)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(ocrdma_attributes); i++)
++              device_remove_file(&dev->ibdev.dev, ocrdma_attributes[i]);
++}
++
+ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
+ {
+-      int status = 0;
++      int status = 0, i;
+       struct ocrdma_dev *dev;
+       dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
+@@ -434,6 +467,9 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
+       if (status)
+               goto alloc_err;
++      for (i = 0; i < ARRAY_SIZE(ocrdma_attributes); i++)
++              if (device_create_file(&dev->ibdev.dev, ocrdma_attributes[i]))
++                      goto sysfs_err;
+       spin_lock(&ocrdma_devlist_lock);
+       list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
+       spin_unlock(&ocrdma_devlist_lock);
+@@ -448,6 +484,8 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
+               dev_name(&dev->nic_info.pdev->dev), dev->id);
+       return dev;
++sysfs_err:
++      ocrdma_remove_sysfiles(dev);
+ alloc_err:
+       ocrdma_free_resources(dev);
+       ocrdma_cleanup_hw(dev);
+@@ -477,6 +515,7 @@ static void ocrdma_remove(struct ocrdma_dev *dev)
+       /* first unregister with stack to stop all the active traffic
+        * of the registered clients.
+        */
++      ocrdma_remove_sysfiles(dev);
+       ocrdma_rem_port_stats(dev);
+       ib_unregister_device(&dev->ibdev);
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0149-RDMA-ocrdma-code-clean-up.patch b/linux-next-cherry-picks/0149-RDMA-ocrdma-code-clean-up.patch
new file mode 100644 (file)
index 0000000..dabe91b
--- /dev/null
@@ -0,0 +1,302 @@
+From 50e79c44289926c546c5d3467e8ad268b6e66d78 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <Devesh.Sharma@Emulex.Com>
+Date: Mon, 3 Feb 2014 19:03:44 +0530
+Subject: [PATCH 16/16] RDMA/ocrdma: code clean-up
+
+Driver code is cleaned up and couple of cosmetic changes are introduced.
+also modifying GSI QP to error during ocrdma_close is fixed.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h       |    3 +--
+ drivers/infiniband/hw/ocrdma/ocrdma_abi.h   |    4 +---
+ drivers/infiniband/hw/ocrdma/ocrdma_ah.c    |    2 +-
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |   20 ++++++++------------
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c  |    2 +-
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |   16 ++++++++--------
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   22 +++-------------------
+ 7 files changed, 23 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 15c8ee4..ad9a227 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -35,6 +35,7 @@
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_user_verbs.h>
++#include <rdma/ib_addr.h>
+ #include <be_roce.h>
+ #include "ocrdma_sli.h"
+@@ -261,7 +262,6 @@ struct ocrdma_cq {
+ struct ocrdma_pd {
+       struct ib_pd ibpd;
+-      struct ocrdma_dev *dev;
+       struct ocrdma_ucontext *uctx;
+       u32 id;
+       int num_dpp_qp;
+@@ -346,7 +346,6 @@ struct ocrdma_qp {
+       bool dpp_enabled;
+       u8 *ird_q_va;
+       bool signaled;
+-      u16 db_cache;
+ };
+ struct ocrdma_hw_mr {
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
+index 5a82ce5..1554cca 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
+@@ -108,9 +108,7 @@ struct ocrdma_create_qp_uresp {
+       u32 db_sq_offset;
+       u32 db_rq_offset;
+       u32 db_shift;
+-      u64 rsvd1;
+-      u64 rsvd2;
+-      u64 rsvd3;
++      u64 rsvd[11];
+ } __packed;
+ struct ocrdma_create_srq_uresp {
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+index 69da5dd..a507972 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+@@ -99,7 +99,7 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
+       if (!(attr->ah_flags & IB_AH_GRH))
+               return ERR_PTR(-EINVAL);
+-      ah = kzalloc(sizeof *ah, GFP_ATOMIC);
++      ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
+       if (!ah)
+               return ERR_PTR(-ENOMEM);
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 3642383..ef630b0 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -32,7 +32,6 @@
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_user_verbs.h>
+-#include <rdma/ib_addr.h>
+ #include "ocrdma.h"
+ #include "ocrdma_hw.h"
+@@ -386,8 +385,8 @@ static void ocrdma_build_q_pages(struct ocrdma_pa *q_pa, int cnt,
+       }
+ }
+-static int ocrdma_mbx_delete_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q,
+-                             int queue_type)
++static int ocrdma_mbx_delete_q(struct ocrdma_dev *dev,
++                             struct ocrdma_queue_info *q, int queue_type)
+ {
+       u8 opcode = 0;
+       int status;
+@@ -778,7 +777,6 @@ static void ocrdma_process_grp5_aync(struct ocrdma_dev *dev,
+       }
+ }
+-
+ static void ocrdma_process_acqe(struct ocrdma_dev *dev, void *ae_cqe)
+ {
+       /* async CQE processing */
+@@ -825,8 +823,6 @@ static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id)
+                       ocrdma_process_acqe(dev, cqe);
+               else if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_CMPL_MASK)
+                       ocrdma_process_mcqe(dev, cqe);
+-              else
+-                      pr_err("%s() cqe->compl is not set.\n", __func__);
+               memset(cqe, 0, sizeof(struct ocrdma_mcqe));
+               ocrdma_mcq_inc_tail(dev);
+       }
+@@ -1050,6 +1046,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
+       attr->max_qp =
+           (rsp->qp_srq_cq_ird_ord & OCRDMA_MBX_QUERY_CFG_MAX_QP_MASK) >>
+           OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT;
++      attr->max_srq =
++              (rsp->max_srq_rpir_qps & OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK) >>
++              OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET;
+       attr->max_send_sge = ((rsp->max_write_send_sge &
+                              OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >>
+                             OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT);
+@@ -1065,9 +1064,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
+       attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp &
+                               OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >>
+           OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT;
+-      attr->max_srq =
+-              (rsp->max_srq_rpir_qps & OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK) >>
+-              OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET;
+       attr->max_ird_per_qp = (rsp->max_ird_ord_per_qp &
+                               OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_MASK) >>
+           OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_SHIFT;
+@@ -1411,7 +1407,7 @@ static int ocrdma_build_q_conf(u32 *num_entries, int entry_size,
+ static int ocrdma_mbx_create_ah_tbl(struct ocrdma_dev *dev)
+ {
+-      int i ;
++      int i;
+       int status = 0;
+       int max_ah;
+       struct ocrdma_create_ah_tbl *cmd;
+@@ -2296,7 +2292,7 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
+       memcpy(&cmd->params.dgid[0], &ah_attr->grh.dgid.raw[0],
+              sizeof(cmd->params.dgid));
+       status = ocrdma_query_gid(&qp->dev->ibdev, 1,
+-                       ah_attr->grh.sgid_index, &sgid);
++                      ah_attr->grh.sgid_index, &sgid);
+       if (status)
+               return status;
+@@ -2685,7 +2681,7 @@ static int ocrdma_create_eqs(struct ocrdma_dev *dev)
+       for (i = 0; i < num_eq; i++) {
+               status = ocrdma_create_eq(dev, &dev->eq_tbl[i],
+-                                        OCRDMA_EQ_LEN);
++                                      OCRDMA_EQ_LEN);
+               if (status) {
+                       status = -EINVAL;
+                       break;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 72389f6..61836b2 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -550,7 +550,7 @@ static int ocrdma_close(struct ocrdma_dev *dev)
+               cur_qp = dev->qp_tbl;
+               for (i = 0; i < OCRDMA_MAX_QP; i++) {
+                       qp = cur_qp[i];
+-                      if (qp) {
++                      if (qp && qp->ibqp.qp_type != IB_QPT_GSI) {
+                               /* change the QP state to ERROR */
+                               _ocrdma_modify_qp(&qp->ibqp, &attrs, attr_mask);
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 6e048b7..96c9ee6 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -152,11 +152,10 @@ enum {
+ #define OCRDMA_MIN_Q_PAGE_SIZE (4096)
+ #define OCRDMA_MAX_Q_PAGES     (8)
+-#define OCRDMA_SLI_ASIC_ID_OFFSET      0x9C
+-#define OCRDMA_SLI_ASIC_REV_MASK       0x000000FF
+-#define OCRDMA_SLI_ASIC_GEN_NUM_MASK   0x0000FF00
+-#define OCRDMA_SLI_ASIC_GEN_NUM_SHIFT  0x08
+-
++#define OCRDMA_SLI_ASIC_ID_OFFSET     0x9C
++#define OCRDMA_SLI_ASIC_REV_MASK      0x000000FF
++#define OCRDMA_SLI_ASIC_GEN_NUM_MASK  0x0000FF00
++#define OCRDMA_SLI_ASIC_GEN_NUM_SHIFT 0x08
+ /*
+ # 0: 4K Bytes
+ # 1: 8K Bytes
+@@ -633,7 +632,7 @@ enum {
+ enum {
+       OCRDMA_CREATE_CQ_VER2                   = 2,
+-      OCRDMA_CREATE_CQ_VER3                   = 3,
++      OCRDMA_CREATE_CQ_VER3                   = 3,
+       OCRDMA_CREATE_CQ_PAGE_CNT_MASK          = 0xFFFF,
+       OCRDMA_CREATE_CQ_PAGE_SIZE_SHIFT        = 16,
+@@ -1093,6 +1092,7 @@ enum {
+       OCRDMA_MODIFY_QP_RSP_MAX_ORD_MASK       = 0xFFFF <<
+                                       OCRDMA_MODIFY_QP_RSP_MAX_ORD_SHIFT
+ };
++
+ struct ocrdma_modify_qp_rsp {
+       struct ocrdma_mqe_hdr hdr;
+       struct ocrdma_mbx_rsp rsp;
+@@ -1105,8 +1105,8 @@ struct ocrdma_query_qp {
+       struct ocrdma_mqe_hdr hdr;
+       struct ocrdma_mbx_hdr req;
+-#define OCRDMA_QUERY_UP_QP_ID_SHIFT 0
+-#define OCRDMA_QUERY_UP_QP_ID_MASK   0xFFFFFF
++#define OCRDMA_QUERY_UP_QP_ID_SHIFT   0
++#define OCRDMA_QUERY_UP_QP_ID_MASK    0xFFFFFF
+       u32 qp_id;
+ };
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 635a757..ce88c0b 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port,
+       dev = get_ocrdma_dev(ibdev);
+       memset(sgid, 0, sizeof(*sgid));
+-      if (index >= OCRDMA_MAX_SGID)
++      if (index > OCRDMA_MAX_SGID)
+               return -EINVAL;
+       memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid));
+@@ -144,7 +144,6 @@ static inline void get_link_speed_and_width(struct ocrdma_dev *dev,
+       }
+ }
+-
+ int ocrdma_query_port(struct ib_device *ibdev,
+                     u8 port, struct ib_port_attr *props)
+ {
+@@ -1210,7 +1209,6 @@ static void ocrdma_set_qp_init_params(struct ocrdma_qp *qp,
+       qp->signaled = (attrs->sq_sig_type == IB_SIGNAL_ALL_WR) ? true : false;
+ }
+-
+ static void ocrdma_store_gsi_qp_cq(struct ocrdma_dev *dev,
+                                  struct ib_qp_init_attr *attrs)
+ {
+@@ -1296,17 +1294,6 @@ gen_err:
+       return ERR_PTR(status);
+ }
+-
+-static void ocrdma_flush_rq_db(struct ocrdma_qp *qp)
+-{
+-      if (qp->db_cache) {
+-              u32 val = qp->rq.dbid | (qp->db_cache <<
+-                              OCRDMA_DB_RQ_SHIFT);
+-              iowrite32(val, qp->rq_db);
+-              qp->db_cache = 0;
+-      }
+-}
+-
+ int _ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+                     int attr_mask)
+ {
+@@ -1325,9 +1312,6 @@ int _ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+       if (status < 0)
+               return status;
+       status = ocrdma_mbx_modify_qp(dev, qp, attr, attr_mask, old_qps);
+-      if (!status && attr_mask & IB_QP_STATE && attr->qp_state == IB_QPS_RTR)
+-              ocrdma_flush_rq_db(qp);
+-
+       return status;
+ }
+@@ -2043,7 +2027,7 @@ static int ocrdma_build_fr(struct ocrdma_qp *qp, struct ocrdma_hdr_wqe *hdr,
+       fast_reg->num_sges = wr->wr.fast_reg.page_list_len;
+       fast_reg->size_sge =
+               get_encoded_page_size(1 << wr->wr.fast_reg.page_shift);
+-      mr = (struct ocrdma_mr *) (unsigned long) qp->dev->stag_arr[(hdr->lkey >> 8) &
++      mr = (struct ocrdma_mr *)qp->dev->stag_arr[(hdr->lkey >> 8) &
+               (OCRDMA_MAX_STAG - 1)];
+       build_frmr_pbes(wr, mr->hwmr.pbl_table, &mr->hwmr);
+       return 0;
+@@ -2878,7 +2862,7 @@ struct ib_mr *ocrdma_alloc_frmr(struct ib_pd *ibpd, int max_page_list_len)
+               goto mbx_err;
+       mr->ibmr.rkey = mr->hwmr.lkey;
+       mr->ibmr.lkey = mr->hwmr.lkey;
+-      dev->stag_arr[(mr->hwmr.lkey >> 8) & (OCRDMA_MAX_STAG - 1)] = (unsigned long) mr;
++      dev->stag_arr[(mr->hwmr.lkey >> 8) & (OCRDMA_MAX_STAG - 1)] = (u64)mr;
+       return &mr->ibmr;
+ mbx_err:
+       ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0150-be2net-adding-abi-version-between-be2net-and-ocrdma.patch b/linux-next-cherry-picks/0150-be2net-adding-abi-version-between-be2net-and-ocrdma.patch
new file mode 100644 (file)
index 0000000..4704f90
--- /dev/null
@@ -0,0 +1,57 @@
+From 9b13a993e13fc662fd44130093cf116114bae539 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Thu, 30 Jan 2014 10:00:37 +0530
+Subject: [PATCH] be2net: adding abi version between be2net and ocrdma
+
+This patch adds abi versioning between be2net and ocrdma
+driver modules. This is to catch the functional incompatibilities
+in the two drivers.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/net/ethernet/emulex/benet/be_roce.c |    6 ++++++
+ drivers/net/ethernet/emulex/benet/be_roce.h |    3 +++
+ 2 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_roce.c b/drivers/net/ethernet/emulex/benet/be_roce.c
+index 9cd5415..aa7f943 100644
+--- a/drivers/net/ethernet/emulex/benet/be_roce.c
++++ b/drivers/net/ethernet/emulex/benet/be_roce.c
+@@ -35,6 +35,12 @@ static void _be_roce_dev_add(struct be_adapter *adapter)
+       if (!ocrdma_drv)
+               return;
++
++      if (ocrdma_drv->be_abi_version != BE_ROCE_ABI_VERSION) {
++              dev_warn(&pdev->dev, "Cannot initialize RoCE due to ocrdma ABI mismatch\n");
++              return;
++      }
++
+       if (pdev->device == OC_DEVICE_ID5) {
+               /* only msix is supported on these devices */
+               if (!msix_enabled(adapter))
+diff --git a/drivers/net/ethernet/emulex/benet/be_roce.h b/drivers/net/ethernet/emulex/benet/be_roce.h
+index 2cd1129..1bfb161 100644
+--- a/drivers/net/ethernet/emulex/benet/be_roce.h
++++ b/drivers/net/ethernet/emulex/benet/be_roce.h
+@@ -21,6 +21,8 @@
+ #include <linux/pci.h>
+ #include <linux/netdevice.h>
++#define BE_ROCE_ABI_VERSION   1
++
+ struct ocrdma_dev;
+ enum be_interrupt_mode {
+@@ -52,6 +54,7 @@ struct be_dev_info {
+ /* ocrdma driver register's the callback functions with nic driver. */
+ struct ocrdma_driver {
+       unsigned char name[32];
++      u32 be_abi_version;
+       struct ocrdma_dev *(*add) (struct be_dev_info *dev_info);
+       void (*remove) (struct ocrdma_dev *);
+       void (*state_change_handler) (struct ocrdma_dev *, u32 new_state);
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0151-RDMA-ocrdma-ROLLBACK-dpp-posting-for-RDMA-READ.patch b/linux-next-cherry-picks/0151-RDMA-ocrdma-ROLLBACK-dpp-posting-for-RDMA-READ.patch
new file mode 100644 (file)
index 0000000..29b6d1e
--- /dev/null
@@ -0,0 +1,30 @@
+From 8ff7eff20329c749c1907ce71cef9fd593584554 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 25 Feb 2014 21:16:58 +0530
+Subject: [PATCH 23/23] RDMA/ocrdma: ROLLBACK dpp posting for RDMA-READ
+
+this patch is to rollback the feature to post RDMA-READ wqe through
+DPP QP.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index ef630b0..b305da6 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -2206,7 +2206,8 @@ int ocrdma_mbx_create_qp(struct ocrdma_qp *qp, struct ib_qp_init_attr *attrs,
+                               OCRDMA_CREATE_QP_REQ_RQ_CQID_MASK;
+       qp->rq_cq = cq;
+-      if (pd->dpp_enabled && pd->num_dpp_qp) {
++      if (pd->dpp_enabled && attrs->cap.max_inline_data && pd->num_dpp_qp &&
++          (attrs->cap.max_inline_data <= dev->attr.max_inline_data)) {
+               ocrdma_set_create_qp_dpp_cmd(cmd, pd, qp, enable_dpp_cq,
+                                            dpp_cq_id);
+       }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0152-RDMA-ocrdma-Query-and-initalize-the-PFC-SL.patch b/linux-next-cherry-picks/0152-RDMA-ocrdma-Query-and-initalize-the-PFC-SL.patch
new file mode 100644 (file)
index 0000000..7382663
--- /dev/null
@@ -0,0 +1,406 @@
+From a7bade7e3deff33f5a0f830e43596b3d8ebd3d85 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Tue, 3 Jun 2014 11:13:00 +0530
+Subject: [PATCH 29/45] RDMA/ocrdma: Query and initalize the PFC SL
+
+This patch implements routine to query the PFC priority from the adapter port.
+
+Following are the changes implemented:
+
+ * A new FW command is implemented to query the operational/admin
+   DCBX configuration from the FW and obtain active priority(service level).
+ * Adds support for the async event reported by FW when the PFC priority
+   changes. Service level is re-initialized during modify_qp or
+   create_ah, based on this event.
+ * Maintain SL value in ocrdma_dev structure and refer that as and
+   when needed.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h      |   21 ++++
+ drivers/infiniband/hw/ocrdma/ocrdma_ah.c   |    2 +
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c   |  172 ++++++++++++++++++++++++++++
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.h   |    2 +
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h  |   81 +++++++++++++-
+ 6 files changed, 278 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index ea9df5f..064508a 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -210,6 +210,9 @@ struct ocrdma_dev {
+       struct rcu_head rcu;
+       int id;
+       u64 stag_arr[OCRDMA_MAX_STAG];
++      u8 sl; /* service level */
++      bool pfc_state;
++      atomic_t update_sl;
+       u16 pvid;
+       u32 asic_id;
+@@ -506,4 +509,22 @@ static inline u8 ocrdma_get_asic_type(struct ocrdma_dev *dev)
+                               OCRDMA_SLI_ASIC_GEN_NUM_SHIFT;
+ }
++static inline u8 ocrdma_get_pfc_prio(u8 *pfc, u8 prio)
++{
++      return *(pfc + prio);
++}
++
++static inline u8 ocrdma_get_app_prio(u8 *app_prio, u8 prio)
++{
++      return *(app_prio + prio);
++}
++
++static inline u8 ocrdma_is_enabled_and_synced(u32 state)
++{     /* May also be used to interpret TC-state, QCN-state
++       * Appl-state and Logical-link-state in future.
++       */
++      return (state & OCRDMA_STATE_FLAG_ENABLED) &&
++              (state & OCRDMA_STATE_FLAG_SYNC);
++}
++
+ #endif
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+index a507972..0e201f4 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+@@ -99,6 +99,8 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
+       if (!(attr->ah_flags & IB_AH_GRH))
+               return ERR_PTR(-EINVAL);
++      if (atomic_cmpxchg(&dev->update_sl, 1, 0))
++              ocrdma_init_service_level(dev);
+       ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
+       if (!ah)
+               return ERR_PTR(-ENOMEM);
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index b305da6..8c472a4 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -771,6 +771,10 @@ static void ocrdma_process_grp5_aync(struct ocrdma_dev *dev,
+                                       OCRDMA_AE_PVID_MCQE_TAG_MASK) >>
+                                       OCRDMA_AE_PVID_MCQE_TAG_SHIFT);
+               break;
++
++      case OCRDMA_ASYNC_EVENT_COS_VALUE:
++              atomic_set(&dev->update_sl, 1);
++              break;
+       default:
+               /* Not interested evts. */
+               break;
+@@ -2282,6 +2286,8 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
+       if ((ah_attr->ah_flags & IB_AH_GRH) == 0)
+               return -EINVAL;
++      if (atomic_cmpxchg(&qp->dev->update_sl, 1, 0))
++              ocrdma_init_service_level(qp->dev);
+       cmd->params.tclass_sq_psn |=
+           (ah_attr->grh.traffic_class << OCRDMA_QP_PARAMS_TCLASS_SHIFT);
+       cmd->params.rnt_rc_sl_fl |=
+@@ -2315,6 +2321,10 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
+               cmd->params.vlan_dmac_b4_to_b5 |=
+                   vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT;
+               cmd->flags |= OCRDMA_QP_PARA_VLAN_EN_VALID;
++              /* override the sl with default priority if 0 */
++              cmd->params.rnt_rc_sl_fl |=
++                      (ah_attr->sl ? ah_attr->sl :
++                              qp->dev->sl) << OCRDMA_QP_PARAMS_SL_SHIFT;
+       }
+       return 0;
+ }
+@@ -2624,6 +2634,168 @@ int ocrdma_mbx_destroy_srq(struct ocrdma_dev *dev, struct ocrdma_srq *srq)
+       return status;
+ }
++static int ocrdma_mbx_get_dcbx_config(struct ocrdma_dev *dev, u32 ptype,
++                                    struct ocrdma_dcbx_cfg *dcbxcfg)
++{
++      int status = 0;
++      dma_addr_t pa;
++      struct ocrdma_mqe cmd;
++
++      struct ocrdma_get_dcbx_cfg_req *req = NULL;
++      struct ocrdma_get_dcbx_cfg_rsp *rsp = NULL;
++      struct pci_dev *pdev = dev->nic_info.pdev;
++      struct ocrdma_mqe_sge *mqe_sge = cmd.u.nonemb_req.sge;
++
++      memset(&cmd, 0, sizeof(struct ocrdma_mqe));
++      cmd.hdr.pyld_len = max_t (u32, sizeof(struct ocrdma_get_dcbx_cfg_rsp),
++                                      sizeof(struct ocrdma_get_dcbx_cfg_req));
++      req = dma_alloc_coherent(&pdev->dev, cmd.hdr.pyld_len, &pa, GFP_KERNEL);
++      if (!req) {
++              status = -ENOMEM;
++              goto mem_err;
++      }
++
++      cmd.hdr.spcl_sge_cnt_emb |= (1 << OCRDMA_MQE_HDR_SGE_CNT_SHIFT) &
++                                      OCRDMA_MQE_HDR_SGE_CNT_MASK;
++      mqe_sge->pa_lo = (u32) (pa & 0xFFFFFFFFUL);
++      mqe_sge->pa_hi = (u32) upper_32_bits(pa);
++      mqe_sge->len = cmd.hdr.pyld_len;
++
++      memset(req, 0, sizeof(struct ocrdma_get_dcbx_cfg_req));
++      ocrdma_init_mch(&req->hdr, OCRDMA_CMD_GET_DCBX_CONFIG,
++                      OCRDMA_SUBSYS_DCBX, cmd.hdr.pyld_len);
++      req->param_type = ptype;
++
++      status = ocrdma_mbx_cmd(dev, &cmd);
++      if (status)
++              goto mbx_err;
++
++      rsp = (struct ocrdma_get_dcbx_cfg_rsp *)req;
++      ocrdma_le32_to_cpu(rsp, sizeof(struct ocrdma_get_dcbx_cfg_rsp));
++      memcpy(dcbxcfg, &rsp->cfg, sizeof(struct ocrdma_dcbx_cfg));
++
++mbx_err:
++      dma_free_coherent(&pdev->dev, cmd.hdr.pyld_len, req, pa);
++mem_err:
++      return status;
++}
++
++#define OCRDMA_MAX_SERVICE_LEVEL_INDEX        0x08
++#define OCRDMA_DEFAULT_SERVICE_LEVEL  0x05
++
++static int ocrdma_parse_dcbxcfg_rsp(struct ocrdma_dev *dev, int ptype,
++                                  struct ocrdma_dcbx_cfg *dcbxcfg,
++                                  u8 *srvc_lvl)
++{
++      int status = -EINVAL, indx, slindx;
++      int ventry_cnt;
++      struct ocrdma_app_parameter *app_param;
++      u8 valid, proto_sel;
++      u8 app_prio, pfc_prio;
++      u16 proto;
++
++      if (!(dcbxcfg->tcv_aev_opv_st & OCRDMA_DCBX_STATE_MASK)) {
++              pr_info("%s ocrdma%d DCBX is disabled\n",
++                      dev_name(&dev->nic_info.pdev->dev), dev->id);
++              goto out;
++      }
++
++      if (!ocrdma_is_enabled_and_synced(dcbxcfg->pfc_state)) {
++              pr_info("%s ocrdma%d priority flow control(%s) is %s%s\n",
++                      dev_name(&dev->nic_info.pdev->dev), dev->id,
++                      (ptype > 0 ? "operational" : "admin"),
++                      (dcbxcfg->pfc_state & OCRDMA_STATE_FLAG_ENABLED) ?
++                      "enabled" : "disabled",
++                      (dcbxcfg->pfc_state & OCRDMA_STATE_FLAG_SYNC) ?
++                      "" : ", not sync'ed");
++              goto out;
++      } else {
++              pr_info("%s ocrdma%d priority flow control is enabled and sync'ed\n",
++                      dev_name(&dev->nic_info.pdev->dev), dev->id);
++      }
++
++      ventry_cnt = (dcbxcfg->tcv_aev_opv_st >>
++                              OCRDMA_DCBX_APP_ENTRY_SHIFT)
++                              & OCRDMA_DCBX_STATE_MASK;
++
++      for (indx = 0; indx < ventry_cnt; indx++) {
++              app_param = &dcbxcfg->app_param[indx];
++              valid = (app_param->valid_proto_app >>
++                              OCRDMA_APP_PARAM_VALID_SHIFT)
++                              & OCRDMA_APP_PARAM_VALID_MASK;
++              proto_sel = (app_param->valid_proto_app
++                              >>  OCRDMA_APP_PARAM_PROTO_SEL_SHIFT)
++                              & OCRDMA_APP_PARAM_PROTO_SEL_MASK;
++              proto = app_param->valid_proto_app &
++                              OCRDMA_APP_PARAM_APP_PROTO_MASK;
++
++              if (
++                      valid && proto == OCRDMA_APP_PROTO_ROCE &&
++                      proto_sel == OCRDMA_PROTO_SELECT_L2) {
++                      for (slindx = 0; slindx <
++                              OCRDMA_MAX_SERVICE_LEVEL_INDEX; slindx++) {
++                              app_prio = ocrdma_get_app_prio(
++                                              (u8 *)app_param->app_prio,
++                                              slindx);
++                              pfc_prio = ocrdma_get_pfc_prio(
++                                              (u8 *)dcbxcfg->pfc_prio,
++                                              slindx);
++
++                              if (app_prio && pfc_prio) {
++                                      *srvc_lvl = slindx;
++                                      status = 0;
++                                      goto out;
++                              }
++                      }
++                      if (slindx == OCRDMA_MAX_SERVICE_LEVEL_INDEX) {
++                              pr_info("%s ocrdma%d application priority not set for 0x%x protocol\n",
++                                      dev_name(&dev->nic_info.pdev->dev),
++                                      dev->id, proto);
++                      }
++              }
++      }
++
++out:
++      return status;
++}
++
++void ocrdma_init_service_level(struct ocrdma_dev *dev)
++{
++      int status = 0, indx;
++      struct ocrdma_dcbx_cfg dcbxcfg;
++      u8 srvc_lvl = OCRDMA_DEFAULT_SERVICE_LEVEL;
++      int ptype = OCRDMA_PARAMETER_TYPE_OPER;
++
++      for (indx = 0; indx < 2; indx++) {
++              status = ocrdma_mbx_get_dcbx_config(dev, ptype, &dcbxcfg);
++              if (status) {
++                      pr_err("%s(): status=%d\n", __func__, status);
++                      ptype = OCRDMA_PARAMETER_TYPE_ADMIN;
++                      continue;
++              }
++
++              status = ocrdma_parse_dcbxcfg_rsp(dev, ptype,
++                                                &dcbxcfg, &srvc_lvl);
++              if (status) {
++                      ptype = OCRDMA_PARAMETER_TYPE_ADMIN;
++                      continue;
++              }
++
++              break;
++      }
++
++      if (status)
++              pr_info("%s ocrdma%d service level default\n",
++                      dev_name(&dev->nic_info.pdev->dev), dev->id);
++      else
++              pr_info("%s ocrdma%d service level %d\n",
++                      dev_name(&dev->nic_info.pdev->dev), dev->id,
++                      srvc_lvl);
++
++      dev->pfc_state = ocrdma_is_enabled_and_synced(dcbxcfg.pfc_state);
++      dev->sl = srvc_lvl;
++}
++
+ int ocrdma_alloc_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah)
+ {
+       int i;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+index 76ff06d..91d7d33 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+@@ -137,4 +137,6 @@ int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
+ int ocrdma_mbx_rdma_stats(struct ocrdma_dev *, bool reset);
+ char *port_speed_string(struct ocrdma_dev *dev);
++void ocrdma_init_service_level(struct ocrdma_dev *);
++
+ #endif                                /* __OCRDMA_HW_H__ */
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index fa918a5..4d83a26 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -481,6 +481,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
+       if (status)
+               goto alloc_err;
++      ocrdma_init_service_level(dev);
+       status = ocrdma_register_device(dev);
+       if (status)
+               goto alloc_err;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 96c9ee6..4defae8 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -422,7 +422,12 @@ struct ocrdma_ae_qp_mcqe {
+ #define OCRDMA_ASYNC_RDMA_EVE_CODE 0x14
+ #define OCRDMA_ASYNC_GRP5_EVE_CODE 0x5
+-#define OCRDMA_ASYNC_EVENT_PVID_STATE 0x3
++
++enum ocrdma_async_grp5_events {
++      OCRDMA_ASYNC_EVENT_QOS_VALUE    = 0x01,
++      OCRDMA_ASYNC_EVENT_COS_VALUE    = 0x02,
++      OCRDMA_ASYNC_EVENT_PVID_STATE   = 0x03
++};
+ enum OCRDMA_ASYNC_EVENT_TYPE {
+       OCRDMA_CQ_ERROR                 = 0x00,
+@@ -1949,5 +1954,79 @@ struct ocrdma_get_ctrl_attribs_rsp {
+       struct mgmt_controller_attrib ctrl_attribs;
+ };
++#define OCRDMA_SUBSYS_DCBX 0x10
++
++enum OCRDMA_DCBX_OPCODE {
++      OCRDMA_CMD_GET_DCBX_CONFIG = 0x01
++};
++
++enum OCRDMA_DCBX_PARAM_TYPE {
++      OCRDMA_PARAMETER_TYPE_ADMIN     = 0x00,
++      OCRDMA_PARAMETER_TYPE_OPER      = 0x01,
++      OCRDMA_PARAMETER_TYPE_PEER      = 0x02
++};
++
++enum OCRDMA_DCBX_APP_PROTO {
++      OCRDMA_APP_PROTO_ROCE   = 0x8915
++};
++
++enum OCRDMA_DCBX_PROTO {
++      OCRDMA_PROTO_SELECT_L2  = 0x00,
++      OCRDMA_PROTO_SELECT_L4  = 0x01
++};
++
++enum OCRDMA_DCBX_APP_PARAM {
++      OCRDMA_APP_PARAM_APP_PROTO_MASK = 0xFFFF,
++      OCRDMA_APP_PARAM_PROTO_SEL_MASK = 0xFF,
++      OCRDMA_APP_PARAM_PROTO_SEL_SHIFT = 0x10,
++      OCRDMA_APP_PARAM_VALID_MASK     = 0xFF,
++      OCRDMA_APP_PARAM_VALID_SHIFT    = 0x18
++};
++
++enum OCRDMA_DCBX_STATE_FLAGS {
++      OCRDMA_STATE_FLAG_ENABLED       = 0x01,
++      OCRDMA_STATE_FLAG_ADDVERTISED   = 0x02,
++      OCRDMA_STATE_FLAG_WILLING       = 0x04,
++      OCRDMA_STATE_FLAG_SYNC          = 0x08,
++      OCRDMA_STATE_FLAG_UNSUPPORTED   = 0x40000000,
++      OCRDMA_STATE_FLAG_NEG_FAILD     = 0x80000000
++};
++
++enum OCRDMA_TCV_AEV_OPV_ST {
++      OCRDMA_DCBX_TC_SUPPORT_MASK     = 0xFF,
++      OCRDMA_DCBX_TC_SUPPORT_SHIFT    = 0x18,
++      OCRDMA_DCBX_APP_ENTRY_SHIFT     = 0x10,
++      OCRDMA_DCBX_OP_PARAM_SHIFT      = 0x08,
++      OCRDMA_DCBX_STATE_MASK          = 0xFF
++};
++
++struct ocrdma_app_parameter {
++      u32 valid_proto_app;
++      u32 oui;
++      u32 app_prio[2];
++};
++
++struct ocrdma_dcbx_cfg {
++      u32 tcv_aev_opv_st;
++      u32 tc_state;
++      u32 pfc_state;
++      u32 qcn_state;
++      u32 appl_state;
++      u32 ll_state;
++      u32 tc_bw[2];
++      u32 tc_prio[8];
++      u32 pfc_prio[2];
++      struct ocrdma_app_parameter app_param[15];
++};
++
++struct ocrdma_get_dcbx_cfg_req {
++      struct ocrdma_mbx_hdr hdr;
++      u32 param_type;
++} __packed;
++
++struct ocrdma_get_dcbx_cfg_rsp {
++      struct ocrdma_mbx_rsp hdr;
++      struct ocrdma_dcbx_cfg cfg;
++} __packed;
+ #endif                                /* __OCRDMA_SLI_H__ */
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0153-RDMA-ocrdma-Adding-hca_type-string-in-device-atrribu.patch b/linux-next-cherry-picks/0153-RDMA-ocrdma-Adding-hca_type-string-in-device-atrribu.patch
new file mode 100644 (file)
index 0000000..77b7a31
--- /dev/null
@@ -0,0 +1,44 @@
+From 3eb2ede72c26333856fbe3a8c3825d2abaf744b9 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Fri, 18 Jul 2014 11:36:55 +0530
+Subject: [PATCH 30/45] RDMA/ocrdma: Adding hca_type string in device atrributes
+
+Added a new entry under sysfs for getting the HW type.
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |   13 ++++++++++++-
+ 1 files changed, 12 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 4d83a26..55f2dc2 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -430,12 +430,23 @@ static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
+       return scnprintf(buf, PAGE_SIZE, "%s\n", &dev->attr.fw_ver[0]);
+ }
++static ssize_t show_hca_type(struct device *device,
++                           struct device_attribute *attr, char *buf)
++{
++      struct ocrdma_dev *dev = dev_get_drvdata(device);
++
++      return scnprintf(buf, PAGE_SIZE, "%s\n", &dev->model_number[0]);
++}
++
++
+ static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
+ static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
++static DEVICE_ATTR(hca_type, S_IRUGO, show_hca_type, NULL);
+ static struct device_attribute *ocrdma_attributes[] = {
+       &dev_attr_hw_rev,
+-      &dev_attr_fw_ver
++      &dev_attr_fw_ver,
++      &dev_attr_hca_type
+ };
+ static void ocrdma_remove_sysfiles(struct ocrdma_dev *dev)
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0154-RDMA-ocrdma-Handle-shutdown-event-from-be2net-driver.patch b/linux-next-cherry-picks/0154-RDMA-ocrdma-Handle-shutdown-event-from-be2net-driver.patch
new file mode 100644 (file)
index 0000000..8390c38
--- /dev/null
@@ -0,0 +1,46 @@
+From 491006261a6661df25c0923e19dd995ab56c2e9d Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 27 May 2014 14:05:16 +0530
+Subject: [PATCH 31/45] RDMA/ocrdma: Handle shutdown event from be2net driver
+
+be2net driver sends shutdown event to ocrdma during shutdown/reboot.
+As part of event processing, ocrdma calls close() and remove() to
+free all the resources associated with ocrdma. This also frees
+irqs used by ocrdma
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |    9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index 55f2dc2..f0bbe72 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -599,6 +599,12 @@ static int ocrdma_close(struct ocrdma_dev *dev)
+       return 0;
+ }
++static void ocrdma_shutdown(struct ocrdma_dev *dev)
++{
++      ocrdma_close(dev);
++      ocrdma_remove(dev);
++}
++
+ /* event handling via NIC driver ensures that all the NIC specific
+  * initialization done before RoCE driver notifies
+  * event to stack.
+@@ -612,6 +618,9 @@ static void ocrdma_event_handler(struct ocrdma_dev *dev, u32 event)
+       case BE_DEV_DOWN:
+               ocrdma_close(dev);
+               break;
++      case BE_DEV_SHUTDOWN:
++              ocrdma_shutdown(dev);
++              break;
+       }
+ }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0155-RDMA-ocrdma-Remove-hardcoding-of-the-max-DPP-QPs-sup.patch b/linux-next-cherry-picks/0155-RDMA-ocrdma-Remove-hardcoding-of-the-max-DPP-QPs-sup.patch
new file mode 100644 (file)
index 0000000..d250701
--- /dev/null
@@ -0,0 +1,44 @@
+From c9a08ed7fbd10343a404a3dc899be9eac06c0d6e Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 27 May 2014 14:16:15 +0530
+Subject: [PATCH 32/45] RDMA/ocrdma: Remove hardcoding of the max DPP QPs supported
+
+Removing hardcoded value of max dpp qps and calculate the same from
+doorbell page size and WQE size
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |    1 -
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    3 ++-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 4defae8..14a84b2 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -1236,7 +1236,6 @@ struct ocrdma_destroy_srq {
+ enum {
+       OCRDMA_ALLOC_PD_ENABLE_DPP      = BIT(16),
+-      OCRDMA_PD_MAX_DPP_ENABLED_QP    = 8,
+       OCRDMA_DPP_PAGE_SIZE            = 4096
+ };
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index ce88c0b..af9b6c9 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -268,7 +268,8 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
+               pd->dpp_enabled =
+                       ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R;
+               pd->num_dpp_qp =
+-                      pd->dpp_enabled ? OCRDMA_PD_MAX_DPP_ENABLED_QP : 0;
++                      pd->dpp_enabled ? (dev->nic_info.db_page_size /
++                                         dev->attr.wqe_size) : 0;
+       }
+ retry:
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0156-RDMA-ocrdma-Delete-AH-table-if-ocrdma_init_hw-fails-.patch b/linux-next-cherry-picks/0156-RDMA-ocrdma-Delete-AH-table-if-ocrdma_init_hw-fails-.patch
new file mode 100644 (file)
index 0000000..a40820a
--- /dev/null
@@ -0,0 +1,47 @@
+From 5f866391ef3c7dc6e9dd4955a231ad65b3c99742 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 27 May 2014 14:25:11 +0530
+Subject: [PATCH 33/45] RDMA/ocrdma: Delete AH table if ocrdma_init_hw fails after AH table creation
+
+Cleanup the AH table in error path, if HW initialization fails
+after AH table creation.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    7 +++++--
+ 1 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 8c472a4..f01426a 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -1505,6 +1505,7 @@ static void ocrdma_mbx_delete_ah_tbl(struct ocrdma_dev *dev)
+       ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
+       dma_free_coherent(&pdev->dev, dev->av_tbl.size, dev->av_tbl.va,
+                         dev->av_tbl.pa);
++      dev->av_tbl.va = NULL;
+       dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->av_tbl.pbl.va,
+                         dev->av_tbl.pbl.pa);
+       kfree(cmd);
+@@ -2901,13 +2902,15 @@ int ocrdma_init_hw(struct ocrdma_dev *dev)
+               goto conf_err;
+       status = ocrdma_mbx_get_phy_info(dev);
+       if (status)
+-              goto conf_err;
++              goto info_attrb_err;
+       status = ocrdma_mbx_get_ctrl_attribs(dev);
+       if (status)
+-              goto conf_err;
++              goto info_attrb_err;
+       return 0;
++info_attrb_err:
++      ocrdma_mbx_delete_ah_tbl(dev);
+ conf_err:
+       ocrdma_destroy_mq(dev);
+ mq_err:
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0157-RDMA-ocrdma-Avoid-reporting-wrong-completions-in-cas.patch b/linux-next-cherry-picks/0157-RDMA-ocrdma-Avoid-reporting-wrong-completions-in-cas.patch
new file mode 100644 (file)
index 0000000..4226983
--- /dev/null
@@ -0,0 +1,48 @@
+From bb2d1842ca249900a73e3850b3583c77b7d0f450 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Wed, 28 May 2014 09:25:16 +0530
+Subject: [PATCH 34/45] RDMA/ocrdma: Avoid reporting wrong completions in case of error CQEs
+
+During cable pull test with a mount over nfs rdma, driver was reporting
+error completions when there was no pending requests in the SQ and RQ.
+This was triggering a host crash because of reporting wrong work req id.
+Avoid this crash by adding a check for SQ and RQ empty condition and
+prevent reporting completions if queues are empty.
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   10 ++++++++++
+ 1 files changed, 10 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index af9b6c9..dda2ae9 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -2491,6 +2491,11 @@ static bool ocrdma_poll_err_scqe(struct ocrdma_qp *qp,
+                       *stop = true;
+                       expand = false;
+               }
++      } else if (is_hw_sq_empty(qp)) {
++              /* Do nothing */
++              expand = false;
++              *polled = false;
++              *stop = false;
+       } else {
+               *polled = true;
+               expand = ocrdma_update_err_scqe(ibwc, cqe, qp, status);
+@@ -2596,6 +2601,11 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe,
+                       *stop = true;
+                       expand = false;
+               }
++      } else if (is_hw_rq_empty(qp)) {
++              /* Do nothing */
++              expand = false;
++              *polled = false;
++              *stop = false;
+       } else {
+               *polled = true;
+               expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status);
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0158-RDMA-ocrdma-Allow-only-SEND-opcode-in-case-of-UD-QPs.patch b/linux-next-cherry-picks/0158-RDMA-ocrdma-Allow-only-SEND-opcode-in-case-of-UD-QPs.patch
new file mode 100644 (file)
index 0000000..10d9992
--- /dev/null
@@ -0,0 +1,35 @@
+From 66e9bb03219959cee18ec8cbd50c29b0c7b1c8d9 Mon Sep 17 00:00:00 2001
+From: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
+Date: Mon, 2 Jun 2014 10:54:40 +0530
+Subject: [PATCH 35/45] RDMA/ocrdma: Allow only SEND opcode in case of UD QPs
+
+Prevent posting opcodes other than send and send immediate on the UD QPs
+
+Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    7 +++++++
+ 1 files changed, 7 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index dda2ae9..fd1a6d9 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -2057,6 +2057,13 @@ int ocrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+       }
+       while (wr) {
++              if (qp->qp_type == IB_QPT_UD &&
++                  (wr->opcode != IB_WR_SEND &&
++                   wr->opcode != IB_WR_SEND_WITH_IMM)) {
++                      *bad_wr = wr;
++                      status = -EINVAL;
++                      break;
++              }
+               if (ocrdma_hwq_free_cnt(&qp->sq) == 0 ||
+                   wr->num_sge > qp->sq.max_sges) {
+                       *bad_wr = wr;
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0159-RDMA-ocrdma-Do-proper-cleanup-evenif-FW-is-in-error-.patch b/linux-next-cherry-picks/0159-RDMA-ocrdma-Do-proper-cleanup-evenif-FW-is-in-error-.patch
new file mode 100644 (file)
index 0000000..d454c41
--- /dev/null
@@ -0,0 +1,88 @@
+From 6237b9592d8494f1e9df9f6655336d196a2c244c Mon Sep 17 00:00:00 2001
+From: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
+Date: Fri, 18 Jul 2014 11:47:18 +0530
+Subject: [PATCH 36/45] RDMA/ocrdma: Do proper cleanup evenif FW is in error state
+
+If any mailbox command reports timeout, save the state in the driver, to prevent
+issuing any more commands to the HW. Do proper cleanup even if FW is in error state.
+
+Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h       |    1 +
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |    8 +++++++-
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   12 +++++++++++-
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 064508a..1a261aa 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -137,6 +137,7 @@ struct mqe_ctx {
+       u16 cqe_status;
+       u16 ext_status;
+       bool cmd_done;
++      bool fw_error_state;
+ };
+ struct ocrdma_stats {
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index f01426a..eeb788b 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -966,8 +966,12 @@ static int ocrdma_wait_mqe_cmpl(struct ocrdma_dev *dev)
+                                   msecs_to_jiffies(30000));
+       if (status)
+               return 0;
+-      else
++      else {
++              dev->mqe_ctx.fw_error_state = true;
++              pr_err("%s(%d) mailbox timeout: fw not responding\n",
++                     __func__, dev->id);
+               return -1;
++      }
+ }
+ /* issue a mailbox command on the MQ */
+@@ -979,6 +983,8 @@ static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe)
+       struct ocrdma_mbx_rsp *rsp = NULL;
+       mutex_lock(&dev->mqe_ctx.lock);
++      if (dev->mqe_ctx.fw_error_state)
++              goto mbx_err;
+       ocrdma_post_mqe(dev, mqe);
+       status = ocrdma_wait_mqe_cmpl(dev);
+       if (status)
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index fd1a6d9..ff0e8e0 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -329,7 +329,10 @@ static int ocrdma_dealloc_ucontext_pd(struct ocrdma_ucontext *uctx)
+       struct ocrdma_pd *pd = uctx->cntxt_pd;
+       struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device);
+-      BUG_ON(uctx->pd_in_use);
++      if (uctx->pd_in_use) {
++              pr_err("%s(%d) Freeing in use pdid=0x%x.\n",
++                     __func__, dev->id, pd->id);
++      }
+       uctx->cntxt_pd = NULL;
+       status = _ocrdma_dealloc_pd(dev, pd);
+       return status;
+@@ -846,6 +849,13 @@ int ocrdma_dereg_mr(struct ib_mr *ib_mr)
+       if (mr->umem)
+               ib_umem_release(mr->umem);
+       kfree(mr);
++
++      /* Don't stop cleanup, in case FW is unresponsive */
++      if (dev->mqe_ctx.fw_error_state) {
++              status = 0;
++              pr_err("%s(%d) fw not responding.\n",
++                     __func__, dev->id);
++      }
+       return status;
+ }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0160-RDMA-ocrdma-Return-proper-value-for-max_mr_size.patch b/linux-next-cherry-picks/0160-RDMA-ocrdma-Return-proper-value-for-max_mr_size.patch
new file mode 100644 (file)
index 0000000..c14f836
--- /dev/null
@@ -0,0 +1,60 @@
+From cb245d90fb25b9974cd316d14f02a159e2cd2fac Mon Sep 17 00:00:00 2001
+From: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
+Date: Wed, 28 May 2014 10:25:38 +0530
+Subject: [PATCH 37/45] RDMA/ocrdma: Return proper value for max_mr_size
+
+Update the max_mr_size with proper value. Corrected the response structure
+of query config mailbox command.
+
+Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.Com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |    3 ++-
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |    2 +-
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    2 +-
+ 3 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index eeb788b..802a11c 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -1088,7 +1088,8 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
+           OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_SHIFT;
+       attr->max_mw = rsp->max_mw;
+       attr->max_mr = rsp->max_mr;
+-      attr->max_mr_size = ~0ull;
++      attr->max_mr_size = ((u64)rsp->max_mr_size_hi << 32) |
++                            rsp->max_mr_size_lo;
+       attr->max_fmr = 0;
+       attr->max_pages_per_frmr = rsp->max_pages_per_frmr;
+       attr->max_num_mr_pbl = rsp->max_num_mr_pbl;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 14a84b2..3cb88f0 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -530,8 +530,8 @@ struct ocrdma_mbx_query_config {
+       u32 max_ird_ord_per_qp;
+       u32 max_shared_ird_ord;
+       u32 max_mr;
+-      u32 max_mr_size_lo;
+       u32 max_mr_size_hi;
++      u32 max_mr_size_lo;
+       u32 max_num_mr_pbl;
+       u32 max_mw;
+       u32 max_fmr;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index ff0e8e0..1e20ebd 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -69,7 +69,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
+       memcpy(&attr->fw_ver, &dev->attr.fw_ver[0],
+              min(sizeof(dev->attr.fw_ver), sizeof(attr->fw_ver)));
+       ocrdma_get_guid(dev, (u8 *)&attr->sys_image_guid);
+-      attr->max_mr_size = ~0ull;
++      attr->max_mr_size = dev->attr.max_mr_size;
+       attr->page_size_cap = 0xffff000;
+       attr->vendor_id = dev->nic_info.pdev->vendor;
+       attr->vendor_part_id = dev->nic_info.pdev->device;
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0161-RDMA-ocrdma-Add-missing-adapter-mailbox-opcodes.patch b/linux-next-cherry-picks/0161-RDMA-ocrdma-Add-missing-adapter-mailbox-opcodes.patch
new file mode 100644 (file)
index 0000000..bfe545f
--- /dev/null
@@ -0,0 +1,90 @@
+From 241e833572471ef43d56d045437f0e8a80a5a186 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Wed, 28 May 2014 16:35:23 +0530
+Subject: [PATCH 38/45] RDMA/ocrdma : Add missing adapter mailbox opcodes
+
+Fixing the Statistics command opcode. Also specifying the
+opcode of each command for better readablilty.
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h |   62 +++++++++++++++-------------
+ 1 files changed, 33 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 3cb88f0..a20d348 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -44,35 +44,39 @@ enum {
+ #define OCRDMA_SUBSYS_ROCE 10
+ enum {
+       OCRDMA_CMD_QUERY_CONFIG = 1,
+-      OCRDMA_CMD_ALLOC_PD,
+-      OCRDMA_CMD_DEALLOC_PD,
+-
+-      OCRDMA_CMD_CREATE_AH_TBL,
+-      OCRDMA_CMD_DELETE_AH_TBL,
+-
+-      OCRDMA_CMD_CREATE_QP,
+-      OCRDMA_CMD_QUERY_QP,
+-      OCRDMA_CMD_MODIFY_QP,
+-      OCRDMA_CMD_DELETE_QP,
+-
+-      OCRDMA_CMD_RSVD1,
+-      OCRDMA_CMD_ALLOC_LKEY,
+-      OCRDMA_CMD_DEALLOC_LKEY,
+-      OCRDMA_CMD_REGISTER_NSMR,
+-      OCRDMA_CMD_REREGISTER_NSMR,
+-      OCRDMA_CMD_REGISTER_NSMR_CONT,
+-      OCRDMA_CMD_QUERY_NSMR,
+-      OCRDMA_CMD_ALLOC_MW,
+-      OCRDMA_CMD_QUERY_MW,
+-
+-      OCRDMA_CMD_CREATE_SRQ,
+-      OCRDMA_CMD_QUERY_SRQ,
+-      OCRDMA_CMD_MODIFY_SRQ,
+-      OCRDMA_CMD_DELETE_SRQ,
+-
+-      OCRDMA_CMD_ATTACH_MCAST,
+-      OCRDMA_CMD_DETACH_MCAST,
+-      OCRDMA_CMD_GET_RDMA_STATS,
++      OCRDMA_CMD_ALLOC_PD = 2,
++      OCRDMA_CMD_DEALLOC_PD = 3,
++
++      OCRDMA_CMD_CREATE_AH_TBL = 4,
++      OCRDMA_CMD_DELETE_AH_TBL = 5,
++
++      OCRDMA_CMD_CREATE_QP = 6,
++      OCRDMA_CMD_QUERY_QP = 7,
++      OCRDMA_CMD_MODIFY_QP = 8 ,
++      OCRDMA_CMD_DELETE_QP = 9,
++
++      OCRDMA_CMD_RSVD1 = 10,
++      OCRDMA_CMD_ALLOC_LKEY = 11,
++      OCRDMA_CMD_DEALLOC_LKEY = 12,
++      OCRDMA_CMD_REGISTER_NSMR = 13,
++      OCRDMA_CMD_REREGISTER_NSMR = 14,
++      OCRDMA_CMD_REGISTER_NSMR_CONT = 15,
++      OCRDMA_CMD_QUERY_NSMR = 16,
++      OCRDMA_CMD_ALLOC_MW = 17,
++      OCRDMA_CMD_QUERY_MW = 18,
++
++      OCRDMA_CMD_CREATE_SRQ = 19,
++      OCRDMA_CMD_QUERY_SRQ = 20,
++      OCRDMA_CMD_MODIFY_SRQ = 21,
++      OCRDMA_CMD_DELETE_SRQ = 22,
++
++      OCRDMA_CMD_ATTACH_MCAST = 23,
++      OCRDMA_CMD_DETACH_MCAST = 24,
++
++      OCRDMA_CMD_CREATE_RBQ = 25,
++      OCRDMA_CMD_DESTROY_RBQ = 26,
++
++      OCRDMA_CMD_GET_RDMA_STATS = 27,
+       OCRDMA_CMD_MAX
+ };
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0162-RDMA-ocrdma-Increase-the-size-of-STAG-array-in-dev-s.patch b/linux-next-cherry-picks/0162-RDMA-ocrdma-Increase-the-size-of-STAG-array-in-dev-s.patch
new file mode 100644 (file)
index 0000000..68d7ac5
--- /dev/null
@@ -0,0 +1,70 @@
+From 6fbddaf8eb06d8e865771d858ba75f59c388f446 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Thu, 29 May 2014 09:25:55 +0530
+Subject: [PATCH 39/45] RDMA/ocrdma: Increase the size of STAG array in dev structure to 16K
+
+HW can support 16K STAG entries. Changing this max limit.
+Also, moving this array out of ocrdma_dev to reduce
+the size of this structure
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h      |    2 +-
+ drivers/infiniband/hw/ocrdma/ocrdma_main.c |    6 ++++++
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h  |    2 +-
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 1a261aa..2cbc26e 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -210,7 +210,7 @@ struct ocrdma_dev {
+       struct list_head entry;
+       struct rcu_head rcu;
+       int id;
+-      u64 stag_arr[OCRDMA_MAX_STAG];
++      u64 *stag_arr;
+       u8 sl; /* service level */
+       bool pfc_state;
+       atomic_t update_sl;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+index f0bbe72..7b8137d 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+@@ -398,6 +398,11 @@ static int ocrdma_alloc_resources(struct ocrdma_dev *dev)
+               if (!dev->qp_tbl)
+                       goto alloc_err;
+       }
++
++      dev->stag_arr = kzalloc(sizeof(u64) * OCRDMA_MAX_STAG, GFP_KERNEL);
++      if (dev->stag_arr == NULL)
++              goto alloc_err;
++
+       spin_lock_init(&dev->av_tbl.lock);
+       spin_lock_init(&dev->flush_q_lock);
+       return 0;
+@@ -408,6 +413,7 @@ alloc_err:
+ static void ocrdma_free_resources(struct ocrdma_dev *dev)
+ {
++      kfree(dev->stag_arr);
+       kfree(dev->qp_tbl);
+       kfree(dev->cq_tbl);
+       kfree(dev->sgid_tbl);
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index a20d348..3d08e66 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -107,7 +107,7 @@ enum {
+ #define OCRDMA_MAX_QP    2048
+ #define OCRDMA_MAX_CQ    2048
+-#define OCRDMA_MAX_STAG  8192
++#define OCRDMA_MAX_STAG 16384
+ enum {
+       OCRDMA_DB_RQ_OFFSET             = 0xE0,
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0163-RDMA-ocrdma-Fixing-a-sparse-warning.patch b/linux-next-cherry-picks/0163-RDMA-ocrdma-Fixing-a-sparse-warning.patch
new file mode 100644 (file)
index 0000000..053c8e8
--- /dev/null
@@ -0,0 +1,37 @@
+From 4199b418e36dbe23f16cd741ac9514e792d5d67d Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Tue, 3 Jun 2014 14:10:41 +0530
+Subject: [PATCH 40/45] RDMA/ocrdma: Fixing a sparse warning
+
+Fixing the warning about the usage of plain integer as NULL pointer
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 802a11c..eff3600 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -661,7 +661,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
+ {
+       struct ocrdma_qp *qp = NULL;
+       struct ocrdma_cq *cq = NULL;
+-      struct ib_event ib_evt = { 0 };
++      struct ib_event ib_evt;
+       int cq_event = 0;
+       int qp_event = 1;
+       int srq_event = 0;
+@@ -674,6 +674,8 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
+       if (cqe->cqvalid_cqid & OCRDMA_AE_MCQE_CQVALID)
+               cq = dev->cq_tbl[cqe->cqvalid_cqid & OCRDMA_AE_MCQE_CQID_MASK];
++      memset(&ib_evt, 0, sizeof(ib_evt));
++
+       ib_evt.device = &dev->ibdev;
+       switch (type) {
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0164-RDMA-ocrdma-Update-the-ocrdma-module-version-string.patch b/linux-next-cherry-picks/0164-RDMA-ocrdma-Update-the-ocrdma-module-version-string.patch
new file mode 100644 (file)
index 0000000..0d449a0
--- /dev/null
@@ -0,0 +1,28 @@
+From c5b3d4cc260813bfe80ceb759cc53e78f7ae0f93 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Fri, 18 Jul 2014 11:52:15 +0530
+Subject: [PATCH 41/45] RDMA/ocrdma: Update the ocrdma module version string
+
+Updating the ocrdma driver version string
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma.h |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
+index 2cbc26e..381dcf0 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
+@@ -40,7 +40,7 @@
+ #include <be_roce.h>
+ #include "ocrdma_sli.h"
+-#define OCRDMA_ROCE_DRV_VERSION "10.2.145.0-ofed"
++#define OCRDMA_ROCE_DRV_VERSION "10.2.287.0-ofed"
+ #define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
+ #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0165-RDMA-ocrdma-obtain-sl-from-deivce-structure.patch b/linux-next-cherry-picks/0165-RDMA-ocrdma-obtain-sl-from-deivce-structure.patch
new file mode 100644 (file)
index 0000000..6bc0b6d
--- /dev/null
@@ -0,0 +1,58 @@
+From ab18a8049348c08b36d503992dd9c440d6579ad6 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 1 Jul 2014 16:13:15 +0530
+Subject: [PATCH 42/45] RDMA/ocrdma: obtain sl from deivce structure
+
+Currently, driver obtains service level value from ah_attr->sl
+field. However, this filed is set to zero all the times from
+rdma-cm. This patch allows create_ah to obtain service level from
+dev->sl
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_ah.c |    4 +++-
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    4 +---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+index 0e201f4..11e6d1f 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+@@ -35,6 +35,8 @@
+ #include "ocrdma_ah.h"
+ #include "ocrdma_hw.h"
++#define OCRDMA_VID_PCP_SHIFT  0xD
++
+ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
+                               struct ib_ah_attr *attr, int pdid)
+ {
+@@ -55,7 +57,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
+       if (vlan_tag && (vlan_tag < 0x1000)) {
+               eth.eth_type = cpu_to_be16(0x8100);
+               eth.roce_eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE);
+-              vlan_tag |= (attr->sl & 7) << 13;
++              vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT;
+               eth.vlan_tag = cpu_to_be16(vlan_tag);
+               eth_sz = sizeof(struct ocrdma_eth_vlan);
+               vlan_enabled = true;
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index eff3600..576fe7e 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -2331,10 +2331,8 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
+               cmd->params.vlan_dmac_b4_to_b5 |=
+                   vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT;
+               cmd->flags |= OCRDMA_QP_PARA_VLAN_EN_VALID;
+-              /* override the sl with default priority if 0 */
+               cmd->params.rnt_rc_sl_fl |=
+-                      (ah_attr->sl ? ah_attr->sl :
+-                              qp->dev->sl) << OCRDMA_QP_PARAMS_SL_SHIFT;
++                      (qp->dev->sl & 0x07) << OCRDMA_QP_PARAMS_SL_SHIFT;
+       }
+       return 0;
+ }
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0166-RDMA-ocrdma-update-sli-data-structure-for-endian-nes.patch b/linux-next-cherry-picks/0166-RDMA-ocrdma-update-sli-data-structure-for-endian-nes.patch
new file mode 100644 (file)
index 0000000..eceba65
--- /dev/null
@@ -0,0 +1,317 @@
+From b9b4b1998604fc5a77388dd9defaee62209a931e Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 1 Jul 2014 16:05:11 +0530
+Subject: [PATCH 43/45] RDMA/ocrdma: update sli data structure for endian ness
+
+updated the sli specific mailbox command request/response
+data sturcures to fix endian-ness issues.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_hw.c  |   32 ++++--
+ drivers/infiniband/hw/ocrdma/ocrdma_sli.h |  147 +++++++++++++++++++++--------
+ 2 files changed, 129 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 576fe7e..1d77b9b 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -525,7 +525,7 @@ static int ocrdma_mbx_mq_cq_create(struct ocrdma_dev *dev,
+       cmd->ev_cnt_flags = OCRDMA_CREATE_CQ_DEF_FLAGS;
+       cmd->eqn = eq->id;
+-      cmd->cqe_count = cq->size / sizeof(struct ocrdma_mcqe);
++      cmd->pdid_cqecnt = cq->size / sizeof(struct ocrdma_mcqe);
+       ocrdma_build_q_pages(&cmd->pa[0], cq->size / OCRDMA_MIN_Q_PAGE_SIZE,
+                            cq->dma, PAGE_SIZE_4K);
+@@ -1265,7 +1265,9 @@ int ocrdma_mbx_get_ctrl_attribs(struct ocrdma_dev *dev)
+               ctrl_attr_rsp = (struct ocrdma_get_ctrl_attribs_rsp *)dma.va;
+               hba_attribs = &ctrl_attr_rsp->ctrl_attribs.hba_attribs;
+-              dev->hba_port_num = hba_attribs->phy_port;
++              dev->hba_port_num = (hba_attribs->ptpnum_maxdoms_hbast_cv &
++                                      OCRDMA_HBA_ATTRB_PTNUM_MASK)
++                                      >> OCRDMA_HBA_ATTRB_PTNUM_SHIFT;
+               strncpy(dev->model_number,
+                       hba_attribs->controller_model_number, 31);
+       }
+@@ -1315,7 +1317,8 @@ int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed)
+               goto mbx_err;
+       rsp = (struct ocrdma_get_link_speed_rsp *)cmd;
+-      *lnk_speed = rsp->phys_port_speed;
++      *lnk_speed = (rsp->pflt_pps_ld_pnum & OCRDMA_PHY_PS_MASK)
++                      >> OCRDMA_PHY_PS_SHIFT;
+ mbx_err:
+       kfree(cmd);
+@@ -1341,11 +1344,16 @@ int ocrdma_mbx_get_phy_info(struct ocrdma_dev *dev)
+               goto mbx_err;
+       rsp = (struct ocrdma_get_phy_info_rsp *)cmd;
+-      dev->phy.phy_type = le16_to_cpu(rsp->phy_type);
++      dev->phy.phy_type =
++                      (rsp->ityp_ptyp & OCRDMA_PHY_TYPE_MASK);
++      dev->phy.interface_type =
++                      (rsp->ityp_ptyp & OCRDMA_IF_TYPE_MASK)
++                              >> OCRDMA_IF_TYPE_SHIFT;
+       dev->phy.auto_speeds_supported  =
+-                      le16_to_cpu(rsp->auto_speeds_supported);
++                      (rsp->fspeed_aspeed & OCRDMA_ASPEED_SUPP_MASK);
+       dev->phy.fixed_speeds_supported =
+-                      le16_to_cpu(rsp->fixed_speeds_supported);
++                      (rsp->fspeed_aspeed & OCRDMA_FSPEED_SUPP_MASK)
++                              >> OCRDMA_FSPEED_SUPP_SHIFT;
+ mbx_err:
+       kfree(cmd);
+       return status;
+@@ -1470,8 +1478,8 @@ static int ocrdma_mbx_create_ah_tbl(struct ocrdma_dev *dev)
+       pbes = (struct ocrdma_pbe *)dev->av_tbl.pbl.va;
+       for (i = 0; i < dev->av_tbl.size / OCRDMA_MIN_Q_PAGE_SIZE; i++) {
+-              pbes[i].pa_lo = (u32) (pa & 0xffffffff);
+-              pbes[i].pa_hi = (u32) upper_32_bits(pa);
++              pbes[i].pa_lo = (u32)cpu_to_le32(pa & 0xffffffff);
++              pbes[i].pa_hi = (u32)cpu_to_le32(upper_32_bits(pa));
+               pa += PAGE_SIZE;
+       }
+       cmd->tbl_addr[0].lo = (u32)(dev->av_tbl.pbl.pa & 0xFFFFFFFF);
+@@ -1638,14 +1646,16 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
+                       cmd->cmd.pgsz_pgcnt |= OCRDMA_CREATE_CQ_DPP <<
+                               OCRDMA_CREATE_CQ_TYPE_SHIFT;
+               cq->phase_change = false;
+-              cmd->cmd.cqe_count = (cq->len / cqe_size);
++              cmd->cmd.pdid_cqecnt = (cq->len / cqe_size);
+       } else {
+-              cmd->cmd.cqe_count = (cq->len / cqe_size) - 1;
++              cmd->cmd.pdid_cqecnt = (cq->len / cqe_size) - 1;
+               cmd->cmd.ev_cnt_flags |= OCRDMA_CREATE_CQ_FLAGS_AUTO_VALID;
+               cq->phase_change = true;
+       }
+-      cmd->cmd.pd_id = pd_id; /* valid only for v3 */
++      /* pd_id valid only for v3 */
++      cmd->cmd.pdid_cqecnt |= (pd_id <<
++              OCRDMA_CREATE_CQ_CMD_PDID_SHIFT);
+       ocrdma_build_q_pages(&cmd->cmd.pa[0], hw_pages, cq->pa, page_size);
+       status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
+       if (status)
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+index 3d08e66..904989e 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+@@ -589,17 +589,26 @@ enum {
+       OCRDMA_FN_MODE_RDMA     = 0x4
+ };
++enum {
++      OCRDMA_IF_TYPE_MASK             = 0xFFFF0000,
++      OCRDMA_IF_TYPE_SHIFT            = 0x10,
++      OCRDMA_PHY_TYPE_MASK            = 0x0000FFFF,
++      OCRDMA_FUTURE_DETAILS_MASK      = 0xFFFF0000,
++      OCRDMA_FUTURE_DETAILS_SHIFT     = 0x10,
++      OCRDMA_EX_PHY_DETAILS_MASK      = 0x0000FFFF,
++      OCRDMA_FSPEED_SUPP_MASK         = 0xFFFF0000,
++      OCRDMA_FSPEED_SUPP_SHIFT        = 0x10,
++      OCRDMA_ASPEED_SUPP_MASK         = 0x0000FFFF
++};
++
+ struct ocrdma_get_phy_info_rsp {
+       struct ocrdma_mqe_hdr hdr;
+       struct ocrdma_mbx_rsp rsp;
+-      u16 phy_type;
+-      u16 interface_type;
++      u32 ityp_ptyp;
+       u32 misc_params;
+-      u16 ext_phy_details;
+-      u16 rsvd;
+-      u16 auto_speeds_supported;
+-      u16 fixed_speeds_supported;
++      u32 ftrdtl_exphydtl;
++      u32 fspeed_aspeed;
+       u32 future_use[2];
+ };
+@@ -612,19 +621,34 @@ enum {
+       OCRDMA_PHY_SPEED_40GBPS = 0x20
+ };
++enum {
++      OCRDMA_PORT_NUM_MASK    = 0x3F,
++      OCRDMA_PT_MASK          = 0xC0,
++      OCRDMA_PT_SHIFT         = 0x6,
++      OCRDMA_LINK_DUP_MASK    = 0x0000FF00,
++      OCRDMA_LINK_DUP_SHIFT   = 0x8,
++      OCRDMA_PHY_PS_MASK      = 0x00FF0000,
++      OCRDMA_PHY_PS_SHIFT     = 0x10,
++      OCRDMA_PHY_PFLT_MASK    = 0xFF000000,
++      OCRDMA_PHY_PFLT_SHIFT   = 0x18,
++      OCRDMA_QOS_LNKSP_MASK   = 0xFFFF0000,
++      OCRDMA_QOS_LNKSP_SHIFT  = 0x10,
++      OCRDMA_LLST_MASK        = 0xFF,
++      OCRDMA_PLFC_MASK        = 0x00000400,
++      OCRDMA_PLFC_SHIFT       = 0x8,
++      OCRDMA_PLRFC_MASK       = 0x00000200,
++      OCRDMA_PLRFC_SHIFT      = 0x8,
++      OCRDMA_PLTFC_MASK       = 0x00000100,
++      OCRDMA_PLTFC_SHIFT      = 0x8
++};
+ struct ocrdma_get_link_speed_rsp {
+       struct ocrdma_mqe_hdr hdr;
+       struct ocrdma_mbx_rsp rsp;
+-      u8 pt_port_num;
+-      u8 link_duplex;
+-      u8 phys_port_speed;
+-      u8 phys_port_fault;
+-      u16 rsvd1;
+-      u16 qos_lnk_speed;
+-      u8 logical_lnk_status;
+-      u8 rsvd2[3];
++      u32 pflt_pps_ld_pnum;
++      u32 qos_lsp;
++      u32 res_lls;
+ };
+ enum {
+@@ -675,8 +699,7 @@ struct ocrdma_create_cq_cmd {
+       u32 pgsz_pgcnt;
+       u32 ev_cnt_flags;
+       u32 eqn;
+-      u16 cqe_count;
+-      u16 pd_id;
++      u32 pdid_cqecnt;
+       u32 rsvd6;
+       struct ocrdma_pa pa[OCRDMA_CREATE_CQ_MAX_PAGES];
+ };
+@@ -687,6 +710,10 @@ struct ocrdma_create_cq {
+ };
+ enum {
++      OCRDMA_CREATE_CQ_CMD_PDID_SHIFT = 0x10
++};
++
++enum {
+       OCRDMA_CREATE_CQ_RSP_CQ_ID_MASK = 0xFFFF
+ };
+@@ -1904,12 +1931,62 @@ struct ocrdma_rdma_stats_resp {
+       struct ocrdma_rx_dbg_stats      rx_dbg_stats;
+ } __packed;
++enum {
++      OCRDMA_HBA_ATTRB_EPROM_VER_LO_MASK      = 0xFF,
++      OCRDMA_HBA_ATTRB_EPROM_VER_HI_MASK      = 0xFF00,
++      OCRDMA_HBA_ATTRB_EPROM_VER_HI_SHIFT     = 0x08,
++      OCRDMA_HBA_ATTRB_CDBLEN_MASK            = 0xFFFF,
++      OCRDMA_HBA_ATTRB_ASIC_REV_MASK          = 0xFF0000,
++      OCRDMA_HBA_ATTRB_ASIC_REV_SHIFT         = 0x10,
++      OCRDMA_HBA_ATTRB_GUID0_MASK             = 0xFF000000,
++      OCRDMA_HBA_ATTRB_GUID0_SHIFT            = 0x18,
++      OCRDMA_HBA_ATTRB_GUID13_MASK            = 0xFF,
++      OCRDMA_HBA_ATTRB_GUID14_MASK            = 0xFF00,
++      OCRDMA_HBA_ATTRB_GUID14_SHIFT           = 0x08,
++      OCRDMA_HBA_ATTRB_GUID15_MASK            = 0xFF0000,
++      OCRDMA_HBA_ATTRB_GUID15_SHIFT           = 0x10,
++      OCRDMA_HBA_ATTRB_PCNT_MASK              = 0xFF000000,
++      OCRDMA_HBA_ATTRB_PCNT_SHIFT             = 0x18,
++      OCRDMA_HBA_ATTRB_LDTOUT_MASK            = 0xFFFF,
++      OCRDMA_HBA_ATTRB_ISCSI_VER_MASK         = 0xFF0000,
++      OCRDMA_HBA_ATTRB_ISCSI_VER_SHIFT        = 0x10,
++      OCRDMA_HBA_ATTRB_MFUNC_DEV_MASK         = 0xFF000000,
++      OCRDMA_HBA_ATTRB_MFUNC_DEV_SHIFT        = 0x18,
++      OCRDMA_HBA_ATTRB_CV_MASK                = 0xFF,
++      OCRDMA_HBA_ATTRB_HBA_ST_MASK            = 0xFF00,
++      OCRDMA_HBA_ATTRB_HBA_ST_SHIFT           = 0x08,
++      OCRDMA_HBA_ATTRB_MAX_DOMS_MASK          = 0xFF0000,
++      OCRDMA_HBA_ATTRB_MAX_DOMS_SHIFT         = 0x10,
++      OCRDMA_HBA_ATTRB_PTNUM_MASK             = 0x3F000000,
++      OCRDMA_HBA_ATTRB_PTNUM_SHIFT            = 0x18,
++      OCRDMA_HBA_ATTRB_PT_MASK                = 0xC0000000,
++      OCRDMA_HBA_ATTRB_PT_SHIFT               = 0x1E,
++      OCRDMA_HBA_ATTRB_ISCSI_FET_MASK         = 0xFF,
++      OCRDMA_HBA_ATTRB_ASIC_GEN_MASK          = 0xFF00,
++      OCRDMA_HBA_ATTRB_ASIC_GEN_SHIFT         = 0x08,
++      OCRDMA_HBA_ATTRB_PCI_VID_MASK           = 0xFFFF,
++      OCRDMA_HBA_ATTRB_PCI_DID_MASK           = 0xFFFF0000,
++      OCRDMA_HBA_ATTRB_PCI_DID_SHIFT          = 0x10,
++      OCRDMA_HBA_ATTRB_PCI_SVID_MASK          = 0xFFFF,
++      OCRDMA_HBA_ATTRB_PCI_SSID_MASK          = 0xFFFF0000,
++      OCRDMA_HBA_ATTRB_PCI_SSID_SHIFT         = 0x10,
++      OCRDMA_HBA_ATTRB_PCI_BUSNUM_MASK        = 0xFF,
++      OCRDMA_HBA_ATTRB_PCI_DEVNUM_MASK        = 0xFF00,
++      OCRDMA_HBA_ATTRB_PCI_DEVNUM_SHIFT       = 0x08,
++      OCRDMA_HBA_ATTRB_PCI_FUNCNUM_MASK       = 0xFF0000,
++      OCRDMA_HBA_ATTRB_PCI_FUNCNUM_SHIFT      = 0x10,
++      OCRDMA_HBA_ATTRB_IF_TYPE_MASK           = 0xFF000000,
++      OCRDMA_HBA_ATTRB_IF_TYPE_SHIFT          = 0x18,
++      OCRDMA_HBA_ATTRB_NETFIL_MASK            =0xFF
++};
+ struct mgmt_hba_attribs {
+       u8 flashrom_version_string[32];
+       u8 manufacturer_name[32];
+       u32 supported_modes;
+-      u32 rsvd0[3];
++      u32 rsvd_eprom_verhi_verlo;
++      u32 mbx_ds_ver;
++      u32 epfw_ds_ver;
+       u8 ncsi_ver_string[12];
+       u32 default_extended_timeout;
+       u8 controller_model_number[32];
+@@ -1922,34 +1999,26 @@ struct mgmt_hba_attribs {
+       u8 driver_version_string[32];
+       u8 fw_on_flash_version_string[32];
+       u32 functionalities_supported;
+-      u16 max_cdblength;
+-      u8 asic_revision;
+-      u8 generational_guid[16];
+-      u8 hba_port_count;
+-      u16 default_link_down_timeout;
+-      u8 iscsi_ver_min_max;
+-      u8 multifunction_device;
+-      u8 cache_valid;
+-      u8 hba_status;
+-      u8 max_domains_supported;
+-      u8 phy_port;
++      u32 guid0_asicrev_cdblen;
++      u8 generational_guid[12];
++      u32 portcnt_guid15;
++      u32 mfuncdev_iscsi_ldtout;
++      u32 ptpnum_maxdoms_hbast_cv;
+       u32 firmware_post_status;
+       u32 hba_mtu[8];
+-      u32 rsvd1[4];
++      u32 res_asicgen_iscsi_feaures;
++      u32 rsvd1[3];
+ };
+ struct mgmt_controller_attrib {
+       struct mgmt_hba_attribs hba_attribs;
+-      u16 pci_vendor_id;
+-      u16 pci_device_id;
+-      u16 pci_sub_vendor_id;
+-      u16 pci_sub_system_id;
+-      u8 pci_bus_number;
+-      u8 pci_device_number;
+-      u8 pci_function_number;
+-      u8 interface_type;
+-      u64 unique_identifier;
+-      u32 rsvd0[5];
++      u32 pci_did_vid;
++      u32 pci_ssid_svid;
++      u32 ityp_fnum_devnum_bnum;
++      u32 uid_hi;
++      u32 uid_lo;
++      u32 res_nnetfil;
++      u32 rsvd0[4];
+ };
+ struct ocrdma_get_ctrl_attribs_rsp {
+-- 
+1.7.1
+
diff --git a/linux-next-cherry-picks/0167-RDMA-ocrdma-report-asic-id-in-query-device.patch b/linux-next-cherry-picks/0167-RDMA-ocrdma-report-asic-id-in-query-device.patch
new file mode 100644 (file)
index 0000000..1de1419
--- /dev/null
@@ -0,0 +1,31 @@
+From bc42b246b1cb9a2230739f251ff0b2d42e85c644 Mon Sep 17 00:00:00 2001
+From: Mitesh Ahuja <mitesh.ahuja@emulex.com>
+Date: Tue, 1 Jul 2014 14:41:19 +0530
+Subject: [PATCH 44/45] RDMA/ocrdma: report asic-id in query device
+
+Ocrdma does not report hw_ver when query_device is issued.
+This patch is adding meaningful value to this field.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 1e20ebd..e9e7220 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -73,7 +73,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
+       attr->page_size_cap = 0xffff000;
+       attr->vendor_id = dev->nic_info.pdev->vendor;
+       attr->vendor_part_id = dev->nic_info.pdev->device;
+-      attr->hw_ver = 0;
++      attr->hw_ver = dev->asic_id;
+       attr->max_qp = dev->attr.max_qp;
+       attr->max_ah = OCRDMA_MAX_AH;
+       attr->max_qp_wr = dev->attr.max_wqe;
+-- 
+1.7.1
+
diff --git a/linux-next-pending/0005-RDMA-ocrdma-Eq-full-catastrophe-avoidance.patch b/linux-next-pending/0005-RDMA-ocrdma-Eq-full-catastrophe-avoidance.patch
deleted file mode 100644 (file)
index 5b93447..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-From bf24e5d575c684833685a514930770c719c5dbf7 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Thu, 30 Jan 2014 15:35:40 +0530
-Subject: [PATCH 01/16] RDMA/ocrdma: Eq full catastrophe avoidance
-
-Stale entries in the CQ being destroyed causes hardware to generate EQEs indefinetly for a given CQ.
-Thus causing uncontrolled execution of irq_handler. This patch fixes this using following sementics:
-
-    * irq_handler will ring EQ doorbell atleast once and implement budgeting scheme.
-    * cq_destroy will count number of valid entires during destroy and ring
-      cq-db so that hadrware does not generate uncontrolled EQE.
-    * cq_destroy will synchronize with last running irq_handler instance.
-    * arm_cq will always defer arming CQ till poll_cq, except for the first arm_cq call.
-    * poll_cq will always ring cq-db with arm=SET if arm_cq was called prior to enter poll_cq.
-    * poll_cq will always ring cq-db with arm=UNSET if arm_cq was not called prior to enter poll_cq.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma.h       |   18 +++++-
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |   53 ++++++++---------
- drivers/infiniband/hw/ocrdma/ocrdma_hw.h    |    1 +
- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   81 ++++++++++++++++++++-------
- 4 files changed, 103 insertions(+), 50 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index adc11d1..a329de6 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -183,8 +183,8 @@ struct ocrdma_cq {
-                        */
-       u32 max_hw_cqe;
-       bool phase_change;
--      bool armed, solicited;
--      bool arm_needed;
-+      bool deferred_arm, deferred_sol;
-+      bool first_arm;
-       spinlock_t cq_lock ____cacheline_aligned; /* provide synchronization
-                                                  * to cq polling
-@@ -197,6 +197,7 @@ struct ocrdma_cq {
-       struct ocrdma_ucontext *ucontext;
-       dma_addr_t pa;
-       u32 len;
-+      u32 cqe_cnt;
-       /* head of all qp's sq and rq for which cqes need to be flushed
-        * by the software.
-@@ -423,4 +424,17 @@ static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
- }
-+static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev,
-+              int eqid)
-+{
-+      int indx;
-+
-+      for (indx = 0; indx < dev->eq_cnt; indx++) {
-+              if (dev->eq_tbl[indx].q.id == eqid)
-+                      return indx;
-+      }
-+
-+      return -EINVAL;
-+}
-+
- #endif
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index 50219ab..135331d 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -444,7 +444,7 @@ mbx_err:
-       return status;
- }
--static int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq)
-+int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq)
- {
-       int irq;
-@@ -574,6 +574,7 @@ static int ocrdma_create_mq(struct ocrdma_dev *dev)
-       if (status)
-               goto alloc_err;
-+      dev->eq_tbl[0].cq_cnt++;
-       status = ocrdma_mbx_mq_cq_create(dev, &dev->mq.cq, &dev->eq_tbl[0].q);
-       if (status)
-               goto mbx_cq_free;
-@@ -858,16 +859,8 @@ static void ocrdma_qp_cq_handler(struct ocrdma_dev *dev, u16 cq_idx)
-               BUG();
-       cq = dev->cq_tbl[cq_idx];
--      if (cq == NULL) {
--              pr_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx);
-+      if (cq == NULL)
-               return;
--      }
--      spin_lock_irqsave(&cq->cq_lock, flags);
--      cq->armed = false;
--      cq->solicited = false;
--      spin_unlock_irqrestore(&cq->cq_lock, flags);
--
--      ocrdma_ring_cq_db(dev, cq->id, false, false, 0);
-       if (cq->ibcq.comp_handler) {
-               spin_lock_irqsave(&cq->comp_handler_lock, flags);
-@@ -892,27 +885,35 @@ static irqreturn_t ocrdma_irq_handler(int irq, void *handle)
-       struct ocrdma_dev *dev = eq->dev;
-       struct ocrdma_eqe eqe;
-       struct ocrdma_eqe *ptr;
--      u16 eqe_popped = 0;
-       u16 cq_id;
--      while (1) {
-+      int budget = eq->cq_cnt;
-+
-+      do {
-               ptr = ocrdma_get_eqe(eq);
-               eqe = *ptr;
-               ocrdma_le32_to_cpu(&eqe, sizeof(eqe));
-               if ((eqe.id_valid & OCRDMA_EQE_VALID_MASK) == 0)
-                       break;
--              eqe_popped += 1;
-+
-               ptr->id_valid = 0;
-+              /* ring eq doorbell as soon as its consumed. */
-+              ocrdma_ring_eq_db(dev, eq->q.id, false, true, 1);
-               /* check whether its CQE or not. */
-               if ((eqe.id_valid & OCRDMA_EQE_FOR_CQE_MASK) == 0) {
-                       cq_id = eqe.id_valid >> OCRDMA_EQE_RESOURCE_ID_SHIFT;
-                       ocrdma_cq_handler(dev, cq_id);
-               }
-               ocrdma_eq_inc_tail(eq);
--      }
--      ocrdma_ring_eq_db(dev, eq->q.id, true, true, eqe_popped);
--      /* Ring EQ doorbell with num_popped to 0 to enable interrupts again. */
--      if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX)
--              ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0);
-+
-+              /* There can be a stale EQE after the last bound CQ is
-+               * destroyed. EQE valid and budget == 0 implies this.
-+               */
-+              if (budget)
-+                      budget--;
-+
-+      } while (budget);
-+
-+      ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0);
-       return IRQ_HANDLED;
- }
-@@ -1357,12 +1358,10 @@ static void ocrdma_unbind_eq(struct ocrdma_dev *dev, u16 eq_id)
-       int i;
-       mutex_lock(&dev->dev_lock);
--      for (i = 0; i < dev->eq_cnt; i++) {
--              if (dev->eq_tbl[i].q.id != eq_id)
--                      continue;
--              dev->eq_tbl[i].cq_cnt -= 1;
--              break;
--      }
-+      i = ocrdma_get_eq_table_index(dev, eq_id);
-+      if (i == -EINVAL)
-+              BUG();
-+      dev->eq_tbl[i].cq_cnt -= 1;
-       mutex_unlock(&dev->dev_lock);
- }
-@@ -1417,6 +1416,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
-       cq->eqn = ocrdma_bind_eq(dev);
-       cmd->cmd.req.rsvd_version = OCRDMA_CREATE_CQ_VER3;
-       cqe_count = cq->len / cqe_size;
-+      cq->cqe_cnt = cqe_count;
-       if (cqe_count > 1024) {
-               /* Set cnt to 3 to indicate more than 1024 cq entries */
-               cmd->cmd.ev_cnt_flags |= (0x3 << OCRDMA_CREATE_CQ_CNT_SHIFT);
-@@ -1484,12 +1484,9 @@ int ocrdma_mbx_destroy_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq)
-           (cq->id << OCRDMA_DESTROY_CQ_QID_SHIFT) &
-           OCRDMA_DESTROY_CQ_QID_MASK;
--      ocrdma_unbind_eq(dev, cq->eqn);
-       status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
--      if (status)
--              goto mbx_err;
-+      ocrdma_unbind_eq(dev, cq->eqn);
-       dma_free_coherent(&dev->nic_info.pdev->dev, cq->len, cq->va, cq->pa);
--mbx_err:
-       kfree(cmd);
-       return status;
- }
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-index f2a89d4..38102b3 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-@@ -133,5 +133,6 @@ int ocrdma_qp_state_change(struct ocrdma_qp *, enum ib_qp_state new_state,
- bool ocrdma_is_qp_in_sq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
- bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
- void ocrdma_flush_qp(struct ocrdma_qp *);
-+int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
- #endif                                /* __OCRDMA_HW_H__ */
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-index 86242ce..ae2b778 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-@@ -910,6 +910,7 @@ struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev, int entries, int vector,
-       spin_lock_init(&cq->comp_handler_lock);
-       INIT_LIST_HEAD(&cq->sq_head);
-       INIT_LIST_HEAD(&cq->rq_head);
-+      cq->first_arm = true;
-       if (ib_ctx) {
-               uctx = get_ocrdma_ucontext(ib_ctx);
-@@ -927,9 +928,7 @@ struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev, int entries, int vector,
-                       goto ctx_err;
-       }
-       cq->phase = OCRDMA_CQE_VALID;
--      cq->arm_needed = true;
-       dev->cq_tbl[cq->id] = cq;
--
-       return &cq->ibcq;
- ctx_err:
-@@ -952,15 +951,52 @@ int ocrdma_resize_cq(struct ib_cq *ibcq, int new_cnt,
-       return status;
- }
-+void ocrdma_flush_cq(struct ocrdma_cq *cq)
-+{
-+      int cqe_cnt;
-+      int valid_count = 0;
-+      unsigned long flags;
-+
-+      struct ocrdma_dev *dev = get_ocrdma_dev(cq->ibcq.device);
-+      struct ocrdma_cqe *cqe = NULL;
-+
-+      cqe = cq->va;
-+      cqe_cnt = cq->cqe_cnt;
-+
-+      /* Last irq might have scheduled a polling thread
-+       * sync-up with it before hard flushing.
-+       */
-+      spin_lock_irqsave(&cq->cq_lock, flags);
-+      while (cqe_cnt) {
-+              if (is_cqe_valid(cq, cqe))
-+                      valid_count++;
-+              cqe++;
-+              cqe_cnt--;
-+      }
-+      ocrdma_ring_cq_db(dev, cq->id, false, false, valid_count);
-+      spin_unlock_irqrestore(&cq->cq_lock, flags);
-+}
-+
- int ocrdma_destroy_cq(struct ib_cq *ibcq)
- {
-       int status;
-       struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
-+      struct ocrdma_eq *eq = NULL;
-       struct ocrdma_dev *dev = get_ocrdma_dev(ibcq->device);
-       int pdid = 0;
-+      u32 irq, indx;
--      status = ocrdma_mbx_destroy_cq(dev, cq);
-+      dev->cq_tbl[cq->id] = NULL;
-+      indx = ocrdma_get_eq_table_index(dev, cq->eqn);
-+      if (indx == -EINVAL)
-+              BUG();
-+      eq = &dev->eq_tbl[indx];
-+      irq = ocrdma_get_irq(dev, eq);
-+      synchronize_irq(irq);
-+      ocrdma_flush_cq(cq);
-+
-+      status = ocrdma_mbx_destroy_cq(dev, cq);
-       if (cq->ucontext) {
-               pdid = cq->ucontext->cntxt_pd->id;
-               ocrdma_del_mmap(cq->ucontext, (u64) cq->pa,
-@@ -969,7 +1005,6 @@ int ocrdma_destroy_cq(struct ib_cq *ibcq)
-                               ocrdma_get_db_addr(dev, pdid),
-                               dev->nic_info.db_page_size);
-       }
--      dev->cq_tbl[cq->id] = NULL;
-       kfree(cq);
-       return status;
-@@ -2706,10 +2741,18 @@ expand_cqe:
-       }
- stop_cqe:
-       cq->getp = cur_getp;
--      if (polled_hw_cqes || expand || stop) {
--              ocrdma_ring_cq_db(dev, cq->id, cq->armed, cq->solicited,
-+      if (cq->deferred_arm) {
-+              ocrdma_ring_cq_db(dev, cq->id, true, cq->deferred_sol,
-+                                polled_hw_cqes);
-+              cq->deferred_arm = false;
-+              cq->deferred_sol = false;
-+      } else {
-+              /* We need to pop the CQE. No need to arm */
-+              ocrdma_ring_cq_db(dev, cq->id, false, cq->deferred_sol,
-                                 polled_hw_cqes);
-+              cq->deferred_sol = false;
-       }
-+
-       return i;
- }
-@@ -2781,30 +2824,28 @@ int ocrdma_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags cq_flags)
-       struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
-       struct ocrdma_dev *dev = get_ocrdma_dev(ibcq->device);
-       u16 cq_id;
--      u16 cur_getp;
--      struct ocrdma_cqe *cqe;
-       unsigned long flags;
-+      bool arm_needed = false, sol_needed = false;
-       cq_id = cq->id;
-       spin_lock_irqsave(&cq->cq_lock, flags);
-       if (cq_flags & IB_CQ_NEXT_COMP || cq_flags & IB_CQ_SOLICITED)
--              cq->armed = true;
-+              arm_needed = true;
-       if (cq_flags & IB_CQ_SOLICITED)
--              cq->solicited = true;
--
--      cur_getp = cq->getp;
--      cqe = cq->va + cur_getp;
-+              sol_needed = true;
--      /* check whether any valid cqe exist or not, if not then safe to
--       * arm. If cqe is not yet consumed, then let it get consumed and then
--       * we arm it to avoid false interrupts.
--       */
--      if (!is_cqe_valid(cq, cqe) || cq->arm_needed) {
--              cq->arm_needed = false;
--              ocrdma_ring_cq_db(dev, cq_id, cq->armed, cq->solicited, 0);
-+      if (cq->first_arm) {
-+              ocrdma_ring_cq_db(dev, cq_id, arm_needed, sol_needed, 0);
-+              cq->first_arm = false;
-+              goto skip_defer;
-       }
-+      cq->deferred_arm = true;
-+
-+skip_defer:
-+      cq->deferred_sol = sol_needed;
-       spin_unlock_irqrestore(&cq->cq_lock, flags);
-+
-       return 0;
- }
--- 
-1.7.1
-
diff --git a/linux-next-pending/0005-RDMA-ocrdma-do-not-skip-setting-deffered_arm.patch b/linux-next-pending/0005-RDMA-ocrdma-do-not-skip-setting-deffered_arm.patch
new file mode 100644 (file)
index 0000000..b6236a3
--- /dev/null
@@ -0,0 +1,40 @@
+From b28db068f62c5af0ce3e3af91bd9326b4b570c58 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Fri, 6 Jun 2014 10:45:49 +0530
+Subject: [PATCH 18/21] RDMA/ocrdma: do not skip setting deffered_arm
+
+ib_request_notify_cq() when called for the first time
+ocrdma tries to skip setting deffered_arm flag. This
+may lead CQ to an un-armed state thus, never generating
+CQ event and leaving consumer in hung state.
+
+This patch removes the part of code that skkips setting
+deffered_arm flag.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    4 +---
+ 1 files changed, 1 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 55aad54..0ac7193 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -2846,11 +2846,9 @@ int ocrdma_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags cq_flags)
+       if (cq->first_arm) {
+               ocrdma_ring_cq_db(dev, cq_id, arm_needed, sol_needed, 0);
+               cq->first_arm = false;
+-              goto skip_defer;
+       }
+-      cq->deferred_arm = true;
+-skip_defer:
++      cq->deferred_arm = true;
+       cq->deferred_sol = sol_needed;
+       spin_unlock_irqrestore(&cq->cq_lock, flags);
+-- 
+1.7.1
+
diff --git a/linux-next-pending/0006-RDMA-ocrdma-Report-actual-value-of-max_fast_reg_page.patch b/linux-next-pending/0006-RDMA-ocrdma-Report-actual-value-of-max_fast_reg_page.patch
new file mode 100644 (file)
index 0000000..f27407a
--- /dev/null
@@ -0,0 +1,31 @@
+From 295ec1fb5a5ecb9e35f452a1b744992c0c515066 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Thu, 5 Jun 2014 19:11:05 +0530
+Subject: [PATCH 17/21] RDMA/ocrdma: Report actual value of max_fast_reg_page_list_len
+
+ocrdma_query_device does not report correct value of max_fast_reg_page_list_len.
+This patch applies changes to fix this bug.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
+---
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+index 90152de..55aad54 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -101,7 +101,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
+       attr->max_srq_sge = dev->attr.max_srq_sge;
+       attr->max_srq_wr = dev->attr.max_rqe;
+       attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay;
+-      attr->max_fast_reg_page_list_len = 0;
++      attr->max_fast_reg_page_list_len = dev->attr.max_pages_per_frmr;
+       attr->max_pkeys = 1;
+       return 0;
+ }
+-- 
+1.7.1
+
diff --git a/linux-next-pending/0006-RDMA-ocrdma-SQ-and-RQ-doorbell-offset-clean-up.patch b/linux-next-pending/0006-RDMA-ocrdma-SQ-and-RQ-doorbell-offset-clean-up.patch
deleted file mode 100644 (file)
index 429efd9..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-From 622cd67f49d6d5da5e57283ea22c89bc94783865 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <Devesh.Sharma@Emulex.Com>
-Date: Mon, 3 Feb 2014 18:17:03 +0530
-Subject: [PATCH 02/16] RDMA/ocrdma: SQ and RQ doorbell offset clean up
-
-Introducing new macros to define SQ and RQ doorbell offset.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma.h       |    7 -------
- drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |    5 ++++-
- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   23 +++++++----------------
- 3 files changed, 11 insertions(+), 24 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index a329de6..283653c 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -385,13 +385,6 @@ static inline struct ocrdma_srq *get_ocrdma_srq(struct ib_srq *ibsrq)
-       return container_of(ibsrq, struct ocrdma_srq, ibsrq);
- }
--
--static inline int ocrdma_get_num_posted_shift(struct ocrdma_qp *qp)
--{
--      return ((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY &&
--               qp->id < 128) ? 24 : 16);
--}
--
- static inline int is_cqe_valid(struct ocrdma_cq *cq, struct ocrdma_cqe *cqe)
- {
-       int cqe_valid;
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-index 60d5ac2..e71685a 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-@@ -103,7 +103,10 @@ enum {
-       OCRDMA_DB_GEN2_SRQ_OFFSET       = OCRDMA_DB_GEN2_RQ_OFFSET,
-       OCRDMA_DB_CQ_OFFSET             = 0x120,
-       OCRDMA_DB_EQ_OFFSET             = OCRDMA_DB_CQ_OFFSET,
--      OCRDMA_DB_MQ_OFFSET             = 0x140
-+      OCRDMA_DB_MQ_OFFSET             = 0x140,
-+
-+      OCRDMA_DB_SQ_SHIFT              = 16,
-+      OCRDMA_DB_RQ_SHIFT              = 24
- };
- #define OCRDMA_DB_CQ_RING_ID_MASK       0x3FF /* bits 0 - 9 */
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-index ae2b778..ef52ef2 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-@@ -1127,15 +1127,9 @@ static int ocrdma_copy_qp_uresp(struct ocrdma_qp *qp,
-       }
-       uresp.db_page_addr = usr_db;
-       uresp.db_page_size = dev->nic_info.db_page_size;
--      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
--              uresp.db_sq_offset = OCRDMA_DB_GEN2_SQ_OFFSET;
--              uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ_OFFSET;
--              uresp.db_shift = 24;
--      } else {
--              uresp.db_sq_offset = OCRDMA_DB_SQ_OFFSET;
--              uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET;
--              uresp.db_shift = 16;
--      }
-+      uresp.db_sq_offset = OCRDMA_DB_GEN2_SQ_OFFSET;
-+      uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ_OFFSET;
-+      uresp.db_shift = OCRDMA_DB_RQ_SHIFT;
-       if (qp->dpp_enabled) {
-               uresp.dpp_credit = dpp_credit_lmt;
-@@ -1308,7 +1302,7 @@ static void ocrdma_flush_rq_db(struct ocrdma_qp *qp)
- {
-       if (qp->db_cache) {
-               u32 val = qp->rq.dbid | (qp->db_cache <<
--                              ocrdma_get_num_posted_shift(qp));
-+                              OCRDMA_DB_RQ_SHIFT);
-               iowrite32(val, qp->rq_db);
-               qp->db_cache = 0;
-       }
-@@ -2053,7 +2047,7 @@ static int ocrdma_build_fr(struct ocrdma_qp *qp, struct ocrdma_hdr_wqe *hdr,
- static void ocrdma_ring_sq_db(struct ocrdma_qp *qp)
- {
--      u32 val = qp->sq.dbid | (1 << 16);
-+      u32 val = qp->sq.dbid | (1 << OCRDMA_DB_SQ_SHIFT);
-       iowrite32(val, qp->sq_db);
- }
-@@ -2158,12 +2152,9 @@ int ocrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
- static void ocrdma_ring_rq_db(struct ocrdma_qp *qp)
- {
--      u32 val = qp->rq.dbid | (1 << ocrdma_get_num_posted_shift(qp));
-+      u32 val = qp->rq.dbid | (1 << OCRDMA_DB_RQ_SHIFT);
--      if (qp->state != OCRDMA_QPS_INIT)
--              iowrite32(val, qp->rq_db);
--      else
--              qp->db_cache++;
-+      iowrite32(val, qp->rq_db);
- }
- static void ocrdma_build_rqe(struct ocrdma_hdr_wqe *rqe, struct ib_recv_wr *wr,
--- 
-1.7.1
-
diff --git a/linux-next-pending/0007-RDMA-ocrdma-read-ASIC_ID-register-to-select-asic_gen.patch b/linux-next-pending/0007-RDMA-ocrdma-read-ASIC_ID-register-to-select-asic_gen.patch
deleted file mode 100644 (file)
index d9c7ec4..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-From cb733f184ebc399935d3c3e948d9288915ab9748 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Tue, 18 Feb 2014 16:02:52 +0530
-Subject: [PATCH 03/16] RDMA/ocrdma: read ASIC_ID register to select asic_gen
-
-ocrdma driver selects execution path based on sli_family and asic generation number.
-this introduces reading asic gen number from pci register instead of obtining from emulex NIC driver.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma.h       |   13 +++++++++++++
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |    6 +++---
- drivers/infiniband/hw/ocrdma/ocrdma_main.c  |    2 +-
- drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |   17 +++++++++++++++--
- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    6 +++---
- 5 files changed, 35 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index 283653c..44064c7 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -171,6 +171,7 @@ struct ocrdma_dev {
-       int id;
-       u64 stag_arr[OCRDMA_MAX_STAG];
-       u16 pvid;
-+      u32 asic_id;
- };
- struct ocrdma_cq {
-@@ -430,4 +431,16 @@ static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev,
-       return -EINVAL;
- }
-+static inline u8 ocrdma_get_asic_type(struct ocrdma_dev *dev)
-+{
-+      if (dev->nic_info.dev_family == 0xF && !dev->asic_id) {
-+              pci_read_config_dword(
-+                      dev->nic_info.pdev,
-+                      OCRDMA_SLI_ASIC_ID_OFFSET, &dev->asic_id);
-+      }
-+
-+      return (dev->asic_id & OCRDMA_SLI_ASIC_GEN_NUM_MASK) >>
-+                              OCRDMA_SLI_ASIC_GEN_NUM_SHIFT;
-+}
-+
- #endif
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index 135331d..ce6f539 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -1037,7 +1037,7 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
-       attr->max_inline_data =
-           attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) +
-                             sizeof(struct ocrdma_sge));
--      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
-+      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
-               attr->ird = 1;
-               attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE;
-               attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES;
-@@ -1379,7 +1379,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
-                      __func__, dev->id, dev->attr.max_cqe, entries);
-               return -EINVAL;
-       }
--      if (dpp_cq && (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY))
-+      if (dpp_cq && (ocrdma_get_asic_type(dev) != OCRDMA_ASIC_GEN_SKH_R))
-               return -EINVAL;
-       if (dpp_cq) {
-@@ -1439,7 +1439,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
-       }
-       /* shared eq between all the consumer cqs. */
-       cmd->cmd.eqn = cq->eqn;
--      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
-+      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
-               if (dpp_cq)
-                       cmd->cmd.pgsz_pgcnt |= OCRDMA_CREATE_CQ_DPP <<
-                               OCRDMA_CREATE_CQ_TYPE_SHIFT;
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-index 53d3ea4..b21761b 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-@@ -346,7 +346,7 @@ static int ocrdma_register_device(struct ocrdma_dev *dev)
-       dev->ibdev.process_mad = ocrdma_process_mad;
--      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
-+      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
-               dev->ibdev.uverbs_cmd_mask |=
-                    OCRDMA_UVERBS(CREATE_SRQ) |
-                    OCRDMA_UVERBS(MODIFY_SRQ) |
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-index e71685a..de4ebfc 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-@@ -30,8 +30,16 @@
- #define Bit(_b) (1 << (_b))
--#define OCRDMA_GEN1_FAMILY    0xB
--#define OCRDMA_GEN2_FAMILY    0x0F
-+enum {
-+      OCRDMA_ASIC_GEN_SKH_R = 0x04,
-+      OCRDMA_ASIC_GEN_LANCER = 0x0B
-+};
-+
-+enum {
-+      OCRDMA_ASIC_REV_A0 = 0x00,
-+      OCRDMA_ASIC_REV_B0 = 0x10,
-+      OCRDMA_ASIC_REV_C0 = 0x20
-+};
- #define OCRDMA_SUBSYS_ROCE 10
- enum {
-@@ -141,6 +149,11 @@ enum {
- #define OCRDMA_MIN_Q_PAGE_SIZE (4096)
- #define OCRDMA_MAX_Q_PAGES     (8)
-+#define OCRDMA_SLI_ASIC_ID_OFFSET      0x9C
-+#define OCRDMA_SLI_ASIC_REV_MASK       0x000000FF
-+#define OCRDMA_SLI_ASIC_GEN_NUM_MASK   0x0000FF00
-+#define OCRDMA_SLI_ASIC_GEN_NUM_SHIFT  0x08
-+
- /*
- # 0: 4K Bytes
- # 1: 8K Bytes
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-index ef52ef2..20ef4ba 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-@@ -267,7 +267,7 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
-       if (udata && uctx) {
-               pd->dpp_enabled =
--                      dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY;
-+                      ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R;
-               pd->num_dpp_qp =
-                       pd->dpp_enabled ? OCRDMA_PD_MAX_DPP_ENABLED_QP : 0;
-       }
-@@ -1161,7 +1161,7 @@ err:
- static void ocrdma_set_qp_db(struct ocrdma_dev *dev, struct ocrdma_qp *qp,
-                            struct ocrdma_pd *pd)
- {
--      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
-+      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
-               qp->sq_db = dev->nic_info.db +
-                       (pd->id * dev->nic_info.db_page_size) +
-                       OCRDMA_DB_GEN2_SQ_OFFSET;
-@@ -1687,7 +1687,7 @@ static int ocrdma_copy_srq_uresp(struct ocrdma_dev *dev, struct ocrdma_srq *srq,
-           (srq->pd->id * dev->nic_info.db_page_size);
-       uresp.db_page_size = dev->nic_info.db_page_size;
-       uresp.num_rqe_allocated = srq->rq.max_cnt;
--      if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
-+      if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
-               uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ_OFFSET;
-               uresp.db_shift = 24;
-       } else {
--- 
-1.7.1
-
diff --git a/linux-next-pending/0008-RDMA-ocrdma-Allow-DPP-QP-creation.patch b/linux-next-pending/0008-RDMA-ocrdma-Allow-DPP-QP-creation.patch
deleted file mode 100644 (file)
index 7722c7a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From fec1a4edb29dfab809fcdff9c600ee150874a63f Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Wed, 29 Jan 2014 14:04:45 +0530
-Subject: [PATCH 04/16] RDMA/ocrdma: Allow DPP QP creation
-
-Allow creating DPP QP even if inline-data is not requested. This is an optimization to
-lower the latency figures.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    3 +--
- 1 files changed, 1 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index ce6f539..dc72df9 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -2026,8 +2026,7 @@ int ocrdma_mbx_create_qp(struct ocrdma_qp *qp, struct ib_qp_init_attr *attrs,
-                               OCRDMA_CREATE_QP_REQ_RQ_CQID_MASK;
-       qp->rq_cq = cq;
--      if (pd->dpp_enabled && attrs->cap.max_inline_data && pd->num_dpp_qp &&
--          (attrs->cap.max_inline_data <= dev->attr.max_inline_data)) {
-+      if (pd->dpp_enabled && pd->num_dpp_qp) {
-               ocrdma_set_create_qp_dpp_cmd(cmd, pd, qp, enable_dpp_cq,
-                                            dpp_cq_id);
-       }
--- 
-1.7.1
-
diff --git a/linux-next-pending/0009-RDMA-ocrdma-ABI-versioning-between-ocrdma-and-be2net.patch b/linux-next-pending/0009-RDMA-ocrdma-ABI-versioning-between-ocrdma-and-be2net.patch
deleted file mode 100644 (file)
index 4063cb6..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From 459a5fdb860295fdfd3f163b5deb462848f3092a Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Thu, 30 Jan 2014 09:57:37 +0530
-Subject: [PATCH 05/16] RDMA/ocrdma: ABI versioning between ocrdma and be2net
-
-While loading RoCE driver be2net driver should check for ABI version to catch
-functional incompatibilities.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_abi.h  |    1 +
- drivers/infiniband/hw/ocrdma/ocrdma_main.c |    1 +
- 2 files changed, 2 insertions(+), 0 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-index fbac8eb..2a14d4a 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-@@ -29,6 +29,7 @@
- #define __OCRDMA_ABI_H__
- #define OCRDMA_ABI_VERSION 1
-+#define OCRDMA_BE_ROCE_ABI_VERSION 1
- /* user kernel communication data structures. */
- struct ocrdma_alloc_ucontext_resp {
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-index b21761b..8f4e97c 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-@@ -541,6 +541,7 @@ static struct ocrdma_driver ocrdma_drv = {
-       .add                    = ocrdma_add,
-       .remove                 = ocrdma_remove,
-       .state_change_handler   = ocrdma_event_handler,
-+      .be_abi_version         = OCRDMA_BE_ROCE_ABI_VERSION,
- };
- static void ocrdma_unregister_inet6addr_notifier(void)
--- 
-1.7.1
-
diff --git a/linux-next-pending/0010-RDMA-ocrdma-update-version-string.patch b/linux-next-pending/0010-RDMA-ocrdma-update-version-string.patch
deleted file mode 100644 (file)
index 18953ac..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From ee947e52b96caa36435896fdc19cd351a805bd27 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Thu, 30 Jan 2014 11:58:44 +0530
-Subject: [PATCH 06/16] RDMA/ocrdma: update version string
-
-Update the driver vrsion string and node description string.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma.h      |    4 +++-
- drivers/infiniband/hw/ocrdma/ocrdma_main.c |    4 ++--
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index 44064c7..2eb4d22 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -39,7 +39,9 @@
- #include <be_roce.h>
- #include "ocrdma_sli.h"
--#define OCRDMA_ROCE_DEV_VERSION "1.0.0"
-+#define OCRDMA_ROCE_DRV_VERSION "10.2.145.0-ofed"
-+
-+#define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
- #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
- #define OCRDMA_MAX_AH 512
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-index 8f4e97c..5d30161 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-@@ -41,8 +41,8 @@
- #include "ocrdma_hw.h"
- #include "ocrdma_abi.h"
--MODULE_VERSION(OCRDMA_ROCE_DEV_VERSION);
--MODULE_DESCRIPTION("Emulex RoCE HCA Driver");
-+MODULE_VERSION(OCRDMA_ROCE_DRV_VERSION);
-+MODULE_DESCRIPTION(OCRDMA_ROCE_DRV_DESC " " OCRDMA_ROCE_DRV_VERSION);
- MODULE_AUTHOR("Emulex Corporation");
- MODULE_LICENSE("GPL");
--- 
-1.7.1
-
diff --git a/linux-next-pending/0011-RDMA-ocrdma-increment-abi-version-count.patch b/linux-next-pending/0011-RDMA-ocrdma-increment-abi-version-count.patch
deleted file mode 100644 (file)
index 702daf3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From 2e753c2d314295448b1822786feff345efc2e6b7 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Thu, 30 Jan 2014 11:13:22 +0530
-Subject: [PATCH 07/16] RDMA/ocrdma: increment abi version count
-
-Increment the ABI version count for driver/library interface.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_abi.h |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-index 2a14d4a..5a82ce5 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-@@ -28,7 +28,7 @@
- #ifndef __OCRDMA_ABI_H__
- #define __OCRDMA_ABI_H__
--#define OCRDMA_ABI_VERSION 1
-+#define OCRDMA_ABI_VERSION 2
- #define OCRDMA_BE_ROCE_ABI_VERSION 1
- /* user kernel communication data structures. */
--- 
-1.7.1
-
diff --git a/linux-next-pending/0012-RDMA-ocrdma-Memory-leak-fix-in-ocrdma_dereg_mr.patch b/linux-next-pending/0012-RDMA-ocrdma-Memory-leak-fix-in-ocrdma_dereg_mr.patch
deleted file mode 100644 (file)
index 76eb7ba..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8452902d31f2da4cff07b8cc169437b891ca97cd Mon Sep 17 00:00:00 2001
-From: Selvin Xavier <selvin.xavier@emulex.com>
-Date: Thu, 30 Jan 2014 12:17:52 +0530
-Subject: [PATCH 08/16] RDMA/ocrdma: Memory leak fix in ocrdma_dereg_mr
-
-Fix for memory leak in ocrdma_dereg_mr.
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    3 +--
- 1 files changed, 1 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-index 20ef4ba..9eabe27 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-@@ -840,8 +840,7 @@ int ocrdma_dereg_mr(struct ib_mr *ib_mr)
-       status = ocrdma_mbx_dealloc_lkey(dev, mr->hwmr.fr_mr, mr->hwmr.lkey);
--      if (mr->hwmr.fr_mr == 0)
--              ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
-+      ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
-       /* it could be user registered memory. */
-       if (mr->umem)
--- 
-1.7.1
-
diff --git a/linux-next-pending/0013-RDMA-ocrdma-Use-non-zero-tag-in-SRQ-posting.patch b/linux-next-pending/0013-RDMA-ocrdma-Use-non-zero-tag-in-SRQ-posting.patch
deleted file mode 100644 (file)
index 01f8cac..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-From 24a45fdbe496d1b40a017f0a8d2d0f9e6b4e8060 Mon Sep 17 00:00:00 2001
-From: Selvin Xavier <selvin.xavier@emulex.com>
-Date: Thu, 30 Jan 2014 12:37:09 +0530
-Subject: [PATCH 09/16] RDMA/ocrdma: Use non zero tag in SRQ posting
-
-As part of SRQ receive buffers posting we populate a non-zero tag
-which will be returned in SRQ receive completions.
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   28 +++++++++++++++++---------
- 1 files changed, 18 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-index 9eabe27..786ddfc 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-@@ -1537,7 +1537,7 @@ static void ocrdma_discard_cqes(struct ocrdma_qp *qp, struct ocrdma_cq *cq)
-       int discard_cnt = 0;
-       u32 cur_getp, stop_getp;
-       struct ocrdma_cqe *cqe;
--      u32 qpn = 0;
-+      u32 qpn = 0, wqe_idx = 0;
-       spin_lock_irqsave(&cq->cq_lock, cq_flags);
-@@ -1566,24 +1566,29 @@ static void ocrdma_discard_cqes(struct ocrdma_qp *qp, struct ocrdma_cq *cq)
-               if (qpn == 0 || qpn != qp->id)
-                       goto skip_cqe;
--              /* mark cqe discarded so that it is not picked up later
--               * in the poll_cq().
--               */
--              discard_cnt += 1;
--              cqe->cmn.qpn = 0;
-               if (is_cqe_for_sq(cqe)) {
-                       ocrdma_hwq_inc_tail(&qp->sq);
-               } else {
-                       if (qp->srq) {
-+                              wqe_idx = (le32_to_cpu(cqe->rq.buftag_qpn) >>
-+                                      OCRDMA_CQE_BUFTAG_SHIFT) &
-+                                      qp->srq->rq.max_wqe_idx;
-+                              if (wqe_idx < 1)
-+                                      BUG();
-                               spin_lock_irqsave(&qp->srq->q_lock, flags);
-                               ocrdma_hwq_inc_tail(&qp->srq->rq);
--                              ocrdma_srq_toggle_bit(qp->srq, cur_getp);
-+                              ocrdma_srq_toggle_bit(qp->srq, wqe_idx - 1);
-                               spin_unlock_irqrestore(&qp->srq->q_lock, flags);
-                       } else {
-                               ocrdma_hwq_inc_tail(&qp->rq);
-                       }
-               }
-+              /* mark cqe discarded so that it is not picked up later
-+               * in the poll_cq().
-+               */
-+              discard_cnt += 1;
-+              cqe->cmn.qpn = 0;
- skip_cqe:
-               cur_getp = (cur_getp + 1) % cq->max_hw_cqe;
-       } while (cur_getp != stop_getp);
-@@ -2239,7 +2244,7 @@ static int ocrdma_srq_get_idx(struct ocrdma_srq *srq)
-       if (row == srq->bit_fields_len)
-               BUG();
--      return indx;
-+      return indx + 1; /* Use from index 1 */
- }
- static void ocrdma_ring_srq_db(struct ocrdma_srq *srq)
-@@ -2576,10 +2581,13 @@ static void ocrdma_update_free_srq_cqe(struct ib_wc *ibwc,
-       srq = get_ocrdma_srq(qp->ibqp.srq);
-       wqe_idx = (le32_to_cpu(cqe->rq.buftag_qpn) >>
--                      OCRDMA_CQE_BUFTAG_SHIFT) & srq->rq.max_wqe_idx;
-+              OCRDMA_CQE_BUFTAG_SHIFT) & srq->rq.max_wqe_idx;
-+      if (wqe_idx < 1)
-+              BUG();
-+
-       ibwc->wr_id = srq->rqe_wr_id_tbl[wqe_idx];
-       spin_lock_irqsave(&srq->q_lock, flags);
--      ocrdma_srq_toggle_bit(srq, wqe_idx);
-+      ocrdma_srq_toggle_bit(srq, wqe_idx - 1);
-       spin_unlock_irqrestore(&srq->q_lock, flags);
-       ocrdma_hwq_inc_tail(&srq->rq);
- }
--- 
-1.7.1
-
diff --git a/linux-next-pending/0014-RDMA-ocrdma-Display-proper-value-for-max_mw.patch b/linux-next-pending/0014-RDMA-ocrdma-Display-proper-value-for-max_mw.patch
deleted file mode 100644 (file)
index 74a9fc2..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-From f4969efbef7ed1205bbdc35c41b04666121e04ba Mon Sep 17 00:00:00 2001
-From: Selvin Xavier <selvin.xavier@emulex.com>
-Date: Thu, 30 Jan 2014 13:35:13 +0530
-Subject: [PATCH 10/16] RDMA/ocrdma: Display proper value for max_mw
-
-Fixing the max_mw value
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma.h       |    1 +
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |    1 +
- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |    2 +-
- 3 files changed, 3 insertions(+), 1 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index 2eb4d22..f486f3a 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -67,6 +67,7 @@ struct ocrdma_dev_attr {
-       int max_mr;
-       u64 max_mr_size;
-       u32 max_num_mr_pbl;
-+      int max_mw;
-       int max_fmr;
-       int max_map_per_fmr;
-       int max_pages_per_frmr;
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index dc72df9..69b4266 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -1016,6 +1016,7 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
-       attr->local_ca_ack_delay = (rsp->max_pd_ca_ack_delay &
-                                   OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_MASK) >>
-           OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_SHIFT;
-+      attr->max_mw = rsp->max_mw;
-       attr->max_mr = rsp->max_mr;
-       attr->max_mr_size = ~0ull;
-       attr->max_fmr = 0;
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-index 786ddfc..635a757 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-@@ -89,7 +89,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
-       attr->max_cq = dev->attr.max_cq;
-       attr->max_cqe = dev->attr.max_cqe;
-       attr->max_mr = dev->attr.max_mr;
--      attr->max_mw = 0;
-+      attr->max_mw = dev->attr.max_mw;
-       attr->max_pd = dev->attr.max_pd;
-       attr->atomic_cap = 0;
-       attr->max_fmr = 0;
--- 
-1.7.1
-
diff --git a/linux-next-pending/0015-RDMA-ocrdma-Handle-CQ-overrun-error.patch b/linux-next-pending/0015-RDMA-ocrdma-Handle-CQ-overrun-error.patch
deleted file mode 100644 (file)
index 90856b7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From 5601237f4362363cb35f97caa15db3f3ba40271e Mon Sep 17 00:00:00 2001
-From: Selvin Xavier <selvin.xavier@emulex.com>
-Date: Thu, 30 Jan 2014 13:45:11 +0530
-Subject: [PATCH 11/16] RDMA/ocrdma: Handle CQ overrun error
-
-Update the variables to handle CQ overrun errors
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    5 ++++-
- 1 files changed, 4 insertions(+), 1 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index 69b4266..bd9c8b1 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -640,7 +640,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
- {
-       struct ocrdma_qp *qp = NULL;
-       struct ocrdma_cq *cq = NULL;
--      struct ib_event ib_evt;
-+      struct ib_event ib_evt = { 0 };
-       int cq_event = 0;
-       int qp_event = 1;
-       int srq_event = 0;
-@@ -665,6 +665,8 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
-       case OCRDMA_CQ_OVERRUN_ERROR:
-               ib_evt.element.cq = &cq->ibcq;
-               ib_evt.event = IB_EVENT_CQ_ERR;
-+              cq_event = 1;
-+              qp_event = 0;
-               break;
-       case OCRDMA_CQ_QPCAT_ERROR:
-               ib_evt.element.qp = &qp->ibqp;
-@@ -726,6 +728,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
-                                                    qp->srq->ibsrq.
-                                                    srq_context);
-       } else if (dev_event) {
-+              pr_err("%s: Fatal event received\n", dev->ibdev.name);
-               ib_dispatch_event(&ib_evt);
-       }
--- 
-1.7.1
-
diff --git a/linux-next-pending/0016-RDMA-ocrdma-Support-non-embedded-mailbox-commands.patch b/linux-next-pending/0016-RDMA-ocrdma-Support-non-embedded-mailbox-commands.patch
deleted file mode 100644 (file)
index f10b958..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-From f6c4b31875b669bf6562be219578da94d2f06ee3 Mon Sep 17 00:00:00 2001
-From: Selvin Xavier <selvin.xavier@emulex.com>
-Date: Thu, 30 Jan 2014 13:52:18 +0530
-Subject: [PATCH 12/16] RDMA/ocrdma: Support non-embedded mailbox commands
-
-Added a routine to issue non-embedded mailbox commands,
-for handling large mailbox request/response data
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c |   55 +++++++++++++++++++++++++----
- 1 files changed, 47 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index bd9c8b1..63e3747 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -953,7 +953,8 @@ static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe)
- {
-       int status = 0;
-       u16 cqe_status, ext_status;
--      struct ocrdma_mqe *rsp;
-+      struct ocrdma_mqe *rsp_mqe;
-+      struct ocrdma_mbx_rsp *rsp = NULL;
-       mutex_lock(&dev->mqe_ctx.lock);
-       ocrdma_post_mqe(dev, mqe);
-@@ -962,23 +963,61 @@ static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe)
-               goto mbx_err;
-       cqe_status = dev->mqe_ctx.cqe_status;
-       ext_status = dev->mqe_ctx.ext_status;
--      rsp = ocrdma_get_mqe_rsp(dev);
--      ocrdma_copy_le32_to_cpu(mqe, rsp, (sizeof(*mqe)));
-+      rsp_mqe = ocrdma_get_mqe_rsp(dev);
-+      ocrdma_copy_le32_to_cpu(mqe, rsp_mqe, (sizeof(*mqe)));
-+      if ((mqe->hdr.spcl_sge_cnt_emb & OCRDMA_MQE_HDR_EMB_MASK) >>
-+                              OCRDMA_MQE_HDR_EMB_SHIFT)
-+              rsp = &mqe->u.rsp;
-+
-       if (cqe_status || ext_status) {
--              pr_err("%s() opcode=0x%x, cqe_status=0x%x, ext_status=0x%x\n",
--                     __func__,
--                   (rsp->u.rsp.subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >>
--                   OCRDMA_MBX_RSP_OPCODE_SHIFT, cqe_status, ext_status);
-+              pr_err("%s() cqe_status=0x%x, ext_status=0x%x,",
-+                     __func__, cqe_status, ext_status);
-+              if (rsp) {
-+                      /* This is for embedded cmds. */
-+                      pr_err("opcode=0x%x, subsystem=0x%x\n",
-+                             (rsp->subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >>
-+                              OCRDMA_MBX_RSP_OPCODE_SHIFT,
-+                              (rsp->subsys_op & OCRDMA_MBX_RSP_SUBSYS_MASK) >>
-+                              OCRDMA_MBX_RSP_SUBSYS_SHIFT);
-+              }
-               status = ocrdma_get_mbx_cqe_errno(cqe_status);
-               goto mbx_err;
-       }
--      if (mqe->u.rsp.status & OCRDMA_MBX_RSP_STATUS_MASK)
-+      /* For non embedded, rsp errors are handled in ocrdma_nonemb_mbx_cmd */
-+      if (rsp && (mqe->u.rsp.status & OCRDMA_MBX_RSP_STATUS_MASK))
-               status = ocrdma_get_mbx_errno(mqe->u.rsp.status);
- mbx_err:
-       mutex_unlock(&dev->mqe_ctx.lock);
-       return status;
- }
-+static int ocrdma_nonemb_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe,
-+                               void *payload_va)
-+{
-+      int status = 0;
-+      struct ocrdma_mbx_rsp *rsp = payload_va;
-+
-+      if ((mqe->hdr.spcl_sge_cnt_emb & OCRDMA_MQE_HDR_EMB_MASK) >>
-+                              OCRDMA_MQE_HDR_EMB_SHIFT)
-+              BUG();
-+
-+      status = ocrdma_mbx_cmd(dev, mqe);
-+      if (!status)
-+              /* For non embedded, only CQE failures are handled in
-+               * ocrdma_mbx_cmd. We need to check for RSP errors.
-+               */
-+              if (rsp->status & OCRDMA_MBX_RSP_STATUS_MASK)
-+                      status = ocrdma_get_mbx_errno(rsp->status);
-+
-+      if (status)
-+              pr_err("opcode=0x%x, subsystem=0x%x\n",
-+                     (rsp->subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >>
-+                      OCRDMA_MBX_RSP_OPCODE_SHIFT,
-+                      (rsp->subsys_op & OCRDMA_MBX_RSP_SUBSYS_MASK) >>
-+                      OCRDMA_MBX_RSP_SUBSYS_SHIFT);
-+      return status;
-+}
-+
- static void ocrdma_get_attr(struct ocrdma_dev *dev,
-                             struct ocrdma_dev_attr *attr,
-                             struct ocrdma_mbx_query_config *rsp)
--- 
-1.7.1
-
diff --git a/linux-next-pending/0017-RDMA-ocrdma-Query-controller-information.patch b/linux-next-pending/0017-RDMA-ocrdma-Query-controller-information.patch
deleted file mode 100644 (file)
index 6c6bcb6..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-From 6ca02cc2ef0271b1e951307769c7756fdfc5120a Mon Sep 17 00:00:00 2001
-From: Selvin Xavier <selvin.xavier@emulex.com>
-Date: Mon, 3 Feb 2014 18:23:28 +0530
-Subject: [PATCH 13/16] RDMA/ocrdma: Query controller information
-
-Issue mailbox commands to query ocrdma controller
-information and phy information and print them
-while adding ocrdma device.
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma.h      |   33 +++++++++
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c   |  106 ++++++++++++++++++++++++++++
- drivers/infiniband/hw/ocrdma/ocrdma_hw.h   |    1 +
- drivers/infiniband/hw/ocrdma/ocrdma_main.c |    6 ++
- drivers/infiniband/hw/ocrdma/ocrdma_sli.h  |   81 +++++++++++++++++++++-
- 5 files changed, 226 insertions(+), 1 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index f486f3a..55eb0e6 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -44,6 +44,11 @@
- #define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
- #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
-+#define OC_NAME_SH    OCRDMA_NODE_DESC "(Skyhawk)"
-+#define OC_NAME_UNKNOWN OCRDMA_NODE_DESC "(Unknown)"
-+
-+#define OC_SKH_DEVICE_PF 0x720
-+#define OC_SKH_DEVICE_VF 0x728
- #define OCRDMA_MAX_AH 512
- #define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)
-@@ -86,6 +91,12 @@ struct ocrdma_dev_attr {
-       u8 num_ird_pages;
- };
-+struct ocrdma_dma_mem {
-+      void *va;
-+      dma_addr_t pa;
-+      u32 size;
-+};
-+
- struct ocrdma_pbl {
-       void *va;
-       dma_addr_t pa;
-@@ -125,6 +136,14 @@ struct mqe_ctx {
-       bool cmd_done;
- };
-+
-+struct phy_info {
-+      u16 auto_speeds_supported;
-+      u16 fixed_speeds_supported;
-+      u16 phy_type;
-+      u16 interface_type;
-+};
-+
- struct ocrdma_dev {
-       struct ib_device ibdev;
-       struct ocrdma_dev_attr attr;
-@@ -168,6 +187,9 @@ struct ocrdma_dev {
-       struct mqe_ctx mqe_ctx;
-       struct be_dev_info nic_info;
-+      struct phy_info phy;
-+      char model_number[32];
-+      u32 hba_port_num;
-       struct list_head entry;
-       struct rcu_head rcu;
-@@ -421,6 +443,17 @@ static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
- }
-+static inline char *hca_name(struct ocrdma_dev *dev)
-+{
-+      switch (dev->nic_info.pdev->device) {
-+      case OC_SKH_DEVICE_PF:
-+      case OC_SKH_DEVICE_VF:
-+              return OC_NAME_SH;
-+      default:
-+              return OC_NAME_UNKNOWN;
-+      }
-+}
-+
- static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev,
-               int eqid)
- {
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index 63e3747..f36aa5d 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -243,6 +243,23 @@ static int ocrdma_get_mbx_errno(u32 status)
-       return err_num;
- }
-+char *port_speed_string(struct ocrdma_dev *dev)
-+{
-+      char *str = "";
-+      u16 speeds_supported;
-+
-+      speeds_supported = dev->phy.fixed_speeds_supported |
-+                              dev->phy.auto_speeds_supported;
-+      if (speeds_supported & OCRDMA_PHY_SPEED_40GBPS)
-+              str = "40Gbps ";
-+      else if (speeds_supported & OCRDMA_PHY_SPEED_10GBPS)
-+              str = "10Gbps ";
-+      else if (speeds_supported & OCRDMA_PHY_SPEED_1GBPS)
-+              str = "1Gbps ";
-+
-+      return str;
-+}
-+
- static int ocrdma_get_mbx_cqe_errno(u16 cqe_status)
- {
-       int err_num = -EINVAL;
-@@ -332,6 +349,11 @@ static void *ocrdma_init_emb_mqe(u8 opcode, u32 cmd_len)
-       return mqe;
- }
-+static void *ocrdma_alloc_mqe(void)
-+{
-+      return kzalloc(sizeof(struct ocrdma_mqe), GFP_KERNEL);
-+}
-+
- static void ocrdma_free_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q)
- {
-       dma_free_coherent(&dev->nic_info.pdev->dev, q->size, q->va, q->dma);
-@@ -1154,6 +1176,54 @@ mbx_err:
-       return status;
- }
-+int ocrdma_mbx_get_ctrl_attribs(struct ocrdma_dev *dev)
-+{
-+      int status = -ENOMEM;
-+      struct ocrdma_dma_mem dma;
-+      struct ocrdma_mqe *mqe;
-+      struct ocrdma_get_ctrl_attribs_rsp *ctrl_attr_rsp;
-+      struct mgmt_hba_attribs *hba_attribs;
-+
-+      mqe = ocrdma_alloc_mqe();
-+      if (!mqe)
-+              return status;
-+      memset(mqe, 0, sizeof(*mqe));
-+
-+      dma.size = sizeof(struct ocrdma_get_ctrl_attribs_rsp);
-+      dma.va   = dma_alloc_coherent(&dev->nic_info.pdev->dev,
-+                                      dma.size, &dma.pa, GFP_KERNEL);
-+      if (!dma.va)
-+              goto free_mqe;
-+
-+      mqe->hdr.pyld_len = dma.size;
-+      mqe->hdr.spcl_sge_cnt_emb |=
-+                      (1 << OCRDMA_MQE_HDR_SGE_CNT_SHIFT) &
-+                      OCRDMA_MQE_HDR_SGE_CNT_MASK;
-+      mqe->u.nonemb_req.sge[0].pa_lo = (u32) (dma.pa & 0xffffffff);
-+      mqe->u.nonemb_req.sge[0].pa_hi = (u32) upper_32_bits(dma.pa);
-+      mqe->u.nonemb_req.sge[0].len = dma.size;
-+
-+      memset(dma.va, 0, dma.size);
-+      ocrdma_init_mch((struct ocrdma_mbx_hdr *)dma.va,
-+                      OCRDMA_CMD_GET_CTRL_ATTRIBUTES,
-+                      OCRDMA_SUBSYS_COMMON,
-+                      dma.size);
-+
-+      status = ocrdma_nonemb_mbx_cmd(dev, mqe, dma.va);
-+      if (!status) {
-+              ctrl_attr_rsp = (struct ocrdma_get_ctrl_attribs_rsp *)dma.va;
-+              hba_attribs = &ctrl_attr_rsp->ctrl_attribs.hba_attribs;
-+
-+              dev->hba_port_num = hba_attribs->phy_port;
-+              strncpy(dev->model_number,
-+                      hba_attribs->controller_model_number, 31);
-+      }
-+      dma_free_coherent(&dev->nic_info.pdev->dev, dma.size, dma.va, dma.pa);
-+free_mqe:
-+      kfree(mqe);
-+      return status;
-+}
-+
- static int ocrdma_mbx_query_dev(struct ocrdma_dev *dev)
- {
-       int status = -ENOMEM;
-@@ -1201,6 +1271,35 @@ mbx_err:
-       return status;
- }
-+int ocrdma_mbx_get_phy_info(struct ocrdma_dev *dev)
-+{
-+      int status = -ENOMEM;
-+      struct ocrdma_mqe *cmd;
-+      struct ocrdma_get_phy_info_rsp *rsp;
-+
-+      cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_PHY_DETAILS, sizeof(*cmd));
-+      if (!cmd)
-+              return status;
-+
-+      ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0],
-+                      OCRDMA_CMD_PHY_DETAILS, OCRDMA_SUBSYS_COMMON,
-+                      sizeof(*cmd));
-+
-+      status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
-+      if (status)
-+              goto mbx_err;
-+
-+      rsp = (struct ocrdma_get_phy_info_rsp *)cmd;
-+      dev->phy.phy_type = le16_to_cpu(rsp->phy_type);
-+      dev->phy.auto_speeds_supported  =
-+                      le16_to_cpu(rsp->auto_speeds_supported);
-+      dev->phy.fixed_speeds_supported =
-+                      le16_to_cpu(rsp->fixed_speeds_supported);
-+mbx_err:
-+      kfree(cmd);
-+      return status;
-+}
-+
- int ocrdma_mbx_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
- {
-       int status = -ENOMEM;
-@@ -2589,6 +2688,13 @@ int ocrdma_init_hw(struct ocrdma_dev *dev)
-       status = ocrdma_mbx_create_ah_tbl(dev);
-       if (status)
-               goto conf_err;
-+      status = ocrdma_mbx_get_phy_info(dev);
-+      if (status)
-+              goto conf_err;
-+      status = ocrdma_mbx_get_ctrl_attribs(dev);
-+      if (status)
-+              goto conf_err;
-+
-       return 0;
- conf_err:
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-index 38102b3..3f8aa86 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-@@ -135,4 +135,5 @@ bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
- void ocrdma_flush_qp(struct ocrdma_qp *);
- int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
-+char *port_speed_string(struct ocrdma_dev *dev);
- #endif                                /* __OCRDMA_HW_H__ */
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-index 5d30161..488a512 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-@@ -436,6 +436,12 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
-       spin_lock(&ocrdma_devlist_lock);
-       list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
-       spin_unlock(&ocrdma_devlist_lock);
-+      pr_info("%s %s: %s \"%s\" port %d\n",
-+              dev_name(&dev->nic_info.pdev->dev), hca_name(dev),
-+              port_speed_string(dev), dev->model_number,
-+              dev->hba_port_num);
-+      pr_info("%s ocrdma%d driver loaded successfully\n",
-+              dev_name(&dev->nic_info.pdev->dev), dev->id);
-       return dev;
- alloc_err:
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-index de4ebfc..9e72aec 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-@@ -82,12 +82,14 @@ enum {
-       OCRDMA_CMD_CREATE_CQ            = 12,
-       OCRDMA_CMD_CREATE_EQ            = 13,
-       OCRDMA_CMD_CREATE_MQ            = 21,
-+      OCRDMA_CMD_GET_CTRL_ATTRIBUTES  = 32,
-       OCRDMA_CMD_GET_FW_VER           = 35,
-       OCRDMA_CMD_DELETE_MQ            = 53,
-       OCRDMA_CMD_DELETE_CQ            = 54,
-       OCRDMA_CMD_DELETE_EQ            = 55,
-       OCRDMA_CMD_GET_FW_CONFIG        = 58,
--      OCRDMA_CMD_CREATE_MQ_EXT        = 90
-+      OCRDMA_CMD_CREATE_MQ_EXT        = 90,
-+      OCRDMA_CMD_PHY_DETAILS          = 102
- };
- enum {
-@@ -578,6 +580,30 @@ enum {
-       OCRDMA_FN_MODE_RDMA     = 0x4
- };
-+struct ocrdma_get_phy_info_rsp {
-+      struct ocrdma_mqe_hdr hdr;
-+      struct ocrdma_mbx_rsp rsp;
-+
-+      u16 phy_type;
-+      u16 interface_type;
-+      u32 misc_params;
-+      u16 ext_phy_details;
-+      u16 rsvd;
-+      u16 auto_speeds_supported;
-+      u16 fixed_speeds_supported;
-+      u32 future_use[2];
-+};
-+
-+enum {
-+      OCRDMA_PHY_SPEED_ZERO = 0x0,
-+      OCRDMA_PHY_SPEED_10MBPS = 0x1,
-+      OCRDMA_PHY_SPEED_100MBPS = 0x2,
-+      OCRDMA_PHY_SPEED_1GBPS = 0x4,
-+      OCRDMA_PHY_SPEED_10GBPS = 0x8,
-+      OCRDMA_PHY_SPEED_40GBPS = 0x20
-+};
-+
-+
- struct ocrdma_get_link_speed_rsp {
-       struct ocrdma_mqe_hdr hdr;
-       struct ocrdma_mbx_rsp rsp;
-@@ -1719,4 +1745,57 @@ struct ocrdma_av {
-       u32 valid;
- } __packed;
-+struct mgmt_hba_attribs {
-+      u8 flashrom_version_string[32];
-+      u8 manufacturer_name[32];
-+      u32 supported_modes;
-+      u32 rsvd0[3];
-+      u8 ncsi_ver_string[12];
-+      u32 default_extended_timeout;
-+      u8 controller_model_number[32];
-+      u8 controller_description[64];
-+      u8 controller_serial_number[32];
-+      u8 ip_version_string[32];
-+      u8 firmware_version_string[32];
-+      u8 bios_version_string[32];
-+      u8 redboot_version_string[32];
-+      u8 driver_version_string[32];
-+      u8 fw_on_flash_version_string[32];
-+      u32 functionalities_supported;
-+      u16 max_cdblength;
-+      u8 asic_revision;
-+      u8 generational_guid[16];
-+      u8 hba_port_count;
-+      u16 default_link_down_timeout;
-+      u8 iscsi_ver_min_max;
-+      u8 multifunction_device;
-+      u8 cache_valid;
-+      u8 hba_status;
-+      u8 max_domains_supported;
-+      u8 phy_port;
-+      u32 firmware_post_status;
-+      u32 hba_mtu[8];
-+      u32 rsvd1[4];
-+};
-+
-+struct mgmt_controller_attrib {
-+      struct mgmt_hba_attribs hba_attribs;
-+      u16 pci_vendor_id;
-+      u16 pci_device_id;
-+      u16 pci_sub_vendor_id;
-+      u16 pci_sub_system_id;
-+      u8 pci_bus_number;
-+      u8 pci_device_number;
-+      u8 pci_function_number;
-+      u8 interface_type;
-+      u64 unique_identifier;
-+      u32 rsvd0[5];
-+};
-+
-+struct ocrdma_get_ctrl_attribs_rsp {
-+      struct ocrdma_mbx_hdr hdr;
-+      struct mgmt_controller_attrib ctrl_attribs;
-+};
-+
-+
- #endif                                /* __OCRDMA_SLI_H__ */
--- 
-1.7.1
-
diff --git a/linux-next-pending/0018-RDMA-ocrdma-Support-for-Skyhawk-statistics.patch b/linux-next-pending/0018-RDMA-ocrdma-Support-for-Skyhawk-statistics.patch
deleted file mode 100644 (file)
index 87b8562..0000000
+++ /dev/null
@@ -1,1059 +0,0 @@
-From dec68de33a6a9cb72512bdbeba81850335dc1749 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Tue, 18 Feb 2014 16:44:08 +0530
-Subject: [PATCH 14/16] RDMA/ocrdma: Support for Skyhawk statistics
-
-Issue mailbox command to get the statistics counters
-from the skyhawk hardware
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/Makefile       |    2 +-
- drivers/infiniband/hw/ocrdma/ocrdma.h       |   28 ++
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |   42 ++
- drivers/infiniband/hw/ocrdma/ocrdma_hw.h    |    1 +
- drivers/infiniband/hw/ocrdma/ocrdma_main.c  |    8 +
- drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |  152 +++++++
- drivers/infiniband/hw/ocrdma/ocrdma_stats.c |  623 +++++++++++++++++++++++++++
- drivers/infiniband/hw/ocrdma/ocrdma_stats.h |   54 +++
- 8 files changed, 909 insertions(+), 1 deletions(-)
- create mode 100644 drivers/infiniband/hw/ocrdma/ocrdma_stats.c
- create mode 100644 drivers/infiniband/hw/ocrdma/ocrdma_stats.h
-
-diff --git a/drivers/infiniband/hw/ocrdma/Makefile b/drivers/infiniband/hw/ocrdma/Makefile
-index 06a5bed..d1bfd4f 100644
---- a/drivers/infiniband/hw/ocrdma/Makefile
-+++ b/drivers/infiniband/hw/ocrdma/Makefile
-@@ -2,4 +2,4 @@ ccflags-y := -Idrivers/net/ethernet/emulex/benet
- obj-$(CONFIG_INFINIBAND_OCRDMA)       += ocrdma.o
--ocrdma-y :=   ocrdma_main.o ocrdma_verbs.o ocrdma_hw.o ocrdma_ah.o
-+ocrdma-y :=   ocrdma_main.o ocrdma_verbs.o ocrdma_hw.o ocrdma_ah.o ocrdma_stats.o
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index 55eb0e6..15c8ee4 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -53,6 +53,8 @@
- #define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)
-+#define convert_to_64bit(lo, hi) ((u64)hi << 32 | (u64)lo)
-+
- struct ocrdma_dev_attr {
-       u8 fw_ver[32];
-       u32 vendor_id;
-@@ -136,6 +138,18 @@ struct mqe_ctx {
-       bool cmd_done;
- };
-+struct ocrdma_stats {
-+      u8 type;
-+      struct ocrdma_dev *dev;
-+};
-+
-+struct stats_mem {
-+      struct ocrdma_mqe mqe;
-+      void *va;
-+      dma_addr_t pa;
-+      u32 size;
-+      char *debugfs_mem;
-+};
- struct phy_info {
-       u16 auto_speeds_supported;
-@@ -197,6 +211,20 @@ struct ocrdma_dev {
-       u64 stag_arr[OCRDMA_MAX_STAG];
-       u16 pvid;
-       u32 asic_id;
-+
-+      ulong last_stats_time;
-+      struct mutex stats_lock; /* provide synch for debugfs operations */
-+      struct stats_mem stats_mem;
-+      struct ocrdma_stats rsrc_stats;
-+      struct ocrdma_stats rx_stats;
-+      struct ocrdma_stats wqe_stats;
-+      struct ocrdma_stats tx_stats;
-+      struct ocrdma_stats db_err_stats;
-+      struct ocrdma_stats tx_qp_err_stats;
-+      struct ocrdma_stats rx_qp_err_stats;
-+      struct ocrdma_stats tx_dbg_stats;
-+      struct ocrdma_stats rx_dbg_stats;
-+      struct dentry *dir;
- };
- struct ocrdma_cq {
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index f36aa5d..3642383 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -1176,6 +1176,48 @@ mbx_err:
-       return status;
- }
-+int ocrdma_mbx_rdma_stats(struct ocrdma_dev *dev, bool reset)
-+{
-+      struct ocrdma_rdma_stats_req *req = dev->stats_mem.va;
-+      struct ocrdma_mqe *mqe = &dev->stats_mem.mqe;
-+      struct ocrdma_rdma_stats_resp *old_stats = NULL;
-+      int status;
-+
-+      old_stats = kzalloc(sizeof(*old_stats), GFP_KERNEL);
-+      if (old_stats == NULL)
-+              return -ENOMEM;
-+
-+      memset(mqe, 0, sizeof(*mqe));
-+      mqe->hdr.pyld_len = dev->stats_mem.size;
-+      mqe->hdr.spcl_sge_cnt_emb |=
-+                      (1 << OCRDMA_MQE_HDR_SGE_CNT_SHIFT) &
-+                              OCRDMA_MQE_HDR_SGE_CNT_MASK;
-+      mqe->u.nonemb_req.sge[0].pa_lo = (u32) (dev->stats_mem.pa & 0xffffffff);
-+      mqe->u.nonemb_req.sge[0].pa_hi = (u32) upper_32_bits(dev->stats_mem.pa);
-+      mqe->u.nonemb_req.sge[0].len = dev->stats_mem.size;
-+
-+      /* Cache the old stats */
-+      memcpy(old_stats, req, sizeof(struct ocrdma_rdma_stats_resp));
-+      memset(req, 0, dev->stats_mem.size);
-+
-+      ocrdma_init_mch((struct ocrdma_mbx_hdr *)req,
-+                      OCRDMA_CMD_GET_RDMA_STATS,
-+                      OCRDMA_SUBSYS_ROCE,
-+                      dev->stats_mem.size);
-+      if (reset)
-+              req->reset_stats = reset;
-+
-+      status = ocrdma_nonemb_mbx_cmd(dev, mqe, dev->stats_mem.va);
-+      if (status)
-+              /* Copy from cache, if mbox fails */
-+              memcpy(req, old_stats, sizeof(struct ocrdma_rdma_stats_resp));
-+      else
-+              ocrdma_le32_to_cpu(req, dev->stats_mem.size);
-+
-+      kfree(old_stats);
-+      return status;
-+}
-+
- int ocrdma_mbx_get_ctrl_attribs(struct ocrdma_dev *dev)
- {
-       int status = -ENOMEM;
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-index 3f8aa86..76ff06d 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
-@@ -135,5 +135,6 @@ bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
- void ocrdma_flush_qp(struct ocrdma_qp *);
- int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
-+int ocrdma_mbx_rdma_stats(struct ocrdma_dev *, bool reset);
- char *port_speed_string(struct ocrdma_dev *dev);
- #endif                                /* __OCRDMA_HW_H__ */
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-index 488a512..95b364d 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-@@ -39,6 +39,7 @@
- #include "ocrdma_ah.h"
- #include "be_roce.h"
- #include "ocrdma_hw.h"
-+#include "ocrdma_stats.h"
- #include "ocrdma_abi.h"
- MODULE_VERSION(OCRDMA_ROCE_DRV_VERSION);
-@@ -436,6 +437,9 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
-       spin_lock(&ocrdma_devlist_lock);
-       list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
-       spin_unlock(&ocrdma_devlist_lock);
-+      /* Init stats */
-+      ocrdma_add_port_stats(dev);
-+
-       pr_info("%s %s: %s \"%s\" port %d\n",
-               dev_name(&dev->nic_info.pdev->dev), hca_name(dev),
-               port_speed_string(dev), dev->model_number,
-@@ -473,6 +477,7 @@ static void ocrdma_remove(struct ocrdma_dev *dev)
-       /* first unregister with stack to stop all the active traffic
-        * of the registered clients.
-        */
-+      ocrdma_rem_port_stats(dev);
-       ib_unregister_device(&dev->ibdev);
-       spin_lock(&ocrdma_devlist_lock);
-@@ -561,6 +566,8 @@ static int __init ocrdma_init_module(void)
- {
-       int status;
-+      ocrdma_init_debugfs();
-+
- #if IS_ENABLED(CONFIG_IPV6)
-       status = register_inet6addr_notifier(&ocrdma_inet6addr_notifier);
-       if (status)
-@@ -578,6 +585,7 @@ static void __exit ocrdma_exit_module(void)
- {
-       be_roce_unregister_driver(&ocrdma_drv);
-       ocrdma_unregister_inet6addr_notifier();
-+      ocrdma_rem_debugfs();
- }
- module_init(ocrdma_init_module);
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-index 9e72aec..6e048b7 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-@@ -72,6 +72,7 @@ enum {
-       OCRDMA_CMD_ATTACH_MCAST,
-       OCRDMA_CMD_DETACH_MCAST,
-+      OCRDMA_CMD_GET_RDMA_STATS,
-       OCRDMA_CMD_MAX
- };
-@@ -1745,6 +1746,157 @@ struct ocrdma_av {
-       u32 valid;
- } __packed;
-+struct ocrdma_rsrc_stats {
-+      u32 dpp_pds;
-+      u32 non_dpp_pds;
-+      u32 rc_dpp_qps;
-+      u32 uc_dpp_qps;
-+      u32 ud_dpp_qps;
-+      u32 rc_non_dpp_qps;
-+      u32 rsvd;
-+      u32 uc_non_dpp_qps;
-+      u32 ud_non_dpp_qps;
-+      u32 rsvd1;
-+      u32 srqs;
-+      u32 rbqs;
-+      u32 r64K_nsmr;
-+      u32 r64K_to_2M_nsmr;
-+      u32 r2M_to_44M_nsmr;
-+      u32 r44M_to_1G_nsmr;
-+      u32 r1G_to_4G_nsmr;
-+      u32 nsmr_count_4G_to_32G;
-+      u32 r32G_to_64G_nsmr;
-+      u32 r64G_to_128G_nsmr;
-+      u32 r128G_to_higher_nsmr;
-+      u32 embedded_nsmr;
-+      u32 frmr;
-+      u32 prefetch_qps;
-+      u32 ondemand_qps;
-+      u32 phy_mr;
-+      u32 mw;
-+      u32 rsvd2[7];
-+};
-+
-+struct ocrdma_db_err_stats {
-+      u32 sq_doorbell_errors;
-+      u32 cq_doorbell_errors;
-+      u32 rq_srq_doorbell_errors;
-+      u32 cq_overflow_errors;
-+      u32 rsvd[4];
-+};
-+
-+struct ocrdma_wqe_stats {
-+      u32 large_send_rc_wqes_lo;
-+      u32 large_send_rc_wqes_hi;
-+      u32 large_write_rc_wqes_lo;
-+      u32 large_write_rc_wqes_hi;
-+      u32 rsvd[4];
-+      u32 read_wqes_lo;
-+      u32 read_wqes_hi;
-+      u32 frmr_wqes_lo;
-+      u32 frmr_wqes_hi;
-+      u32 mw_bind_wqes_lo;
-+      u32 mw_bind_wqes_hi;
-+      u32 invalidate_wqes_lo;
-+      u32 invalidate_wqes_hi;
-+      u32 rsvd1[2];
-+      u32 dpp_wqe_drops;
-+      u32 rsvd2[5];
-+};
-+
-+struct ocrdma_tx_stats {
-+      u32 send_pkts_lo;
-+      u32 send_pkts_hi;
-+      u32 write_pkts_lo;
-+      u32 write_pkts_hi;
-+      u32 read_pkts_lo;
-+      u32 read_pkts_hi;
-+      u32 read_rsp_pkts_lo;
-+      u32 read_rsp_pkts_hi;
-+      u32 ack_pkts_lo;
-+      u32 ack_pkts_hi;
-+      u32 send_bytes_lo;
-+      u32 send_bytes_hi;
-+      u32 write_bytes_lo;
-+      u32 write_bytes_hi;
-+      u32 read_req_bytes_lo;
-+      u32 read_req_bytes_hi;
-+      u32 read_rsp_bytes_lo;
-+      u32 read_rsp_bytes_hi;
-+      u32 ack_timeouts;
-+      u32 rsvd[5];
-+};
-+
-+
-+struct ocrdma_tx_qp_err_stats {
-+      u32 local_length_errors;
-+      u32 local_protection_errors;
-+      u32 local_qp_operation_errors;
-+      u32 retry_count_exceeded_errors;
-+      u32 rnr_retry_count_exceeded_errors;
-+      u32 rsvd[3];
-+};
-+
-+struct ocrdma_rx_stats {
-+      u32 roce_frame_bytes_lo;
-+      u32 roce_frame_bytes_hi;
-+      u32 roce_frame_icrc_drops;
-+      u32 roce_frame_payload_len_drops;
-+      u32 ud_drops;
-+      u32 qp1_drops;
-+      u32 psn_error_request_packets;
-+      u32 psn_error_resp_packets;
-+      u32 rnr_nak_timeouts;
-+      u32 rnr_nak_receives;
-+      u32 roce_frame_rxmt_drops;
-+      u32 nak_count_psn_sequence_errors;
-+      u32 rc_drop_count_lookup_errors;
-+      u32 rq_rnr_naks;
-+      u32 srq_rnr_naks;
-+      u32 roce_frames_lo;
-+      u32 roce_frames_hi;
-+      u32 rsvd;
-+};
-+
-+struct ocrdma_rx_qp_err_stats {
-+      u32 nak_invalid_requst_errors;
-+      u32 nak_remote_operation_errors;
-+      u32 nak_count_remote_access_errors;
-+      u32 local_length_errors;
-+      u32 local_protection_errors;
-+      u32 local_qp_operation_errors;
-+      u32 rsvd[2];
-+};
-+
-+struct ocrdma_tx_dbg_stats {
-+      u32 data[100];
-+};
-+
-+struct ocrdma_rx_dbg_stats {
-+      u32 data[200];
-+};
-+
-+struct ocrdma_rdma_stats_req {
-+      struct ocrdma_mbx_hdr hdr;
-+      u8 reset_stats;
-+      u8 rsvd[3];
-+} __packed;
-+
-+struct ocrdma_rdma_stats_resp {
-+      struct ocrdma_mbx_hdr hdr;
-+      struct ocrdma_rsrc_stats act_rsrc_stats;
-+      struct ocrdma_rsrc_stats th_rsrc_stats;
-+      struct ocrdma_db_err_stats      db_err_stats;
-+      struct ocrdma_wqe_stats         wqe_stats;
-+      struct ocrdma_tx_stats          tx_stats;
-+      struct ocrdma_tx_qp_err_stats   tx_qp_err_stats;
-+      struct ocrdma_rx_stats          rx_stats;
-+      struct ocrdma_rx_qp_err_stats   rx_qp_err_stats;
-+      struct ocrdma_tx_dbg_stats      tx_dbg_stats;
-+      struct ocrdma_rx_dbg_stats      rx_dbg_stats;
-+} __packed;
-+
-+
- struct mgmt_hba_attribs {
-       u8 flashrom_version_string[32];
-       u8 manufacturer_name[32];
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
-new file mode 100644
-index 0000000..6b3852a
---- /dev/null
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
-@@ -0,0 +1,623 @@
-+/*******************************************************************
-+ * This file is part of the Emulex RoCE Device Driver for          *
-+ * RoCE (RDMA over Converged Ethernet) adapters.                   *
-+ * Copyright (C) 2008-2014 Emulex. All rights reserved.            *
-+ * EMULEX and SLI are trademarks of Emulex.                        *
-+ * www.emulex.com                                                  *
-+ *                                                                 *
-+ * This program is free software; you can redistribute it and/or   *
-+ * modify it under the terms of version 2 of the GNU General       *
-+ * Public License as published by the Free Software Foundation.    *
-+ * This program is distributed in the hope that it will be useful. *
-+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
-+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
-+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
-+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
-+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
-+ * more details, a copy of which can be found in the file COPYING  *
-+ * included with this package.                                     *
-+ *
-+ * Contact Information:
-+ * linux-drivers@emulex.com
-+ *
-+ * Emulex
-+ * 3333 Susan Street
-+ * Costa Mesa, CA 92626
-+ *******************************************************************/
-+
-+#include <rdma/ib_addr.h>
-+#include "ocrdma_stats.h"
-+
-+static struct dentry *ocrdma_dbgfs_dir;
-+
-+static int ocrdma_add_stat(char *start, char *pcur,
-+                              char *name, u64 count)
-+{
-+      char buff[128] = {0};
-+      int cpy_len = 0;
-+
-+      snprintf(buff, 128, "%s: %llu\n", name, count);
-+      cpy_len = strlen(buff);
-+
-+      if (pcur + cpy_len > start + OCRDMA_MAX_DBGFS_MEM) {
-+              pr_err("%s: No space in stats buff\n", __func__);
-+              return 0;
-+      }
-+
-+      memcpy(pcur, buff, cpy_len);
-+      return cpy_len;
-+}
-+
-+static bool ocrdma_alloc_stats_mem(struct ocrdma_dev *dev)
-+{
-+      struct stats_mem *mem = &dev->stats_mem;
-+
-+      /* Alloc mbox command mem*/
-+      mem->size = max_t(u32, sizeof(struct ocrdma_rdma_stats_req),
-+                      sizeof(struct ocrdma_rdma_stats_resp));
-+
-+      mem->va   = dma_alloc_coherent(&dev->nic_info.pdev->dev, mem->size,
-+                                       &mem->pa, GFP_KERNEL);
-+      if (!mem->va) {
-+              pr_err("%s: stats mbox allocation failed\n", __func__);
-+              return false;
-+      }
-+
-+      memset(mem->va, 0, mem->size);
-+
-+      /* Alloc debugfs mem */
-+      mem->debugfs_mem = kzalloc(OCRDMA_MAX_DBGFS_MEM, GFP_KERNEL);
-+      if (!mem->debugfs_mem) {
-+              pr_err("%s: stats debugfs mem allocation failed\n", __func__);
-+              return false;
-+      }
-+
-+      return true;
-+}
-+
-+static void ocrdma_release_stats_mem(struct ocrdma_dev *dev)
-+{
-+      struct stats_mem *mem = &dev->stats_mem;
-+
-+      if (mem->va)
-+              dma_free_coherent(&dev->nic_info.pdev->dev, mem->size,
-+                                mem->va, mem->pa);
-+      kfree(mem->debugfs_mem);
-+}
-+
-+static char *ocrdma_resource_stats(struct ocrdma_dev *dev)
-+{
-+      char *stats = dev->stats_mem.debugfs_mem, *pcur;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+                      (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_rsrc_stats *rsrc_stats = &rdma_stats->act_rsrc_stats;
-+
-+      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      pcur = stats;
-+      pcur += ocrdma_add_stat(stats, pcur, "active_dpp_pds",
-+                              (u64)rsrc_stats->dpp_pds);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_non_dpp_pds",
-+                              (u64)rsrc_stats->non_dpp_pds);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_rc_dpp_qps",
-+                              (u64)rsrc_stats->rc_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_uc_dpp_qps",
-+                              (u64)rsrc_stats->uc_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_ud_dpp_qps",
-+                              (u64)rsrc_stats->ud_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_rc_non_dpp_qps",
-+                              (u64)rsrc_stats->rc_non_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_uc_non_dpp_qps",
-+                              (u64)rsrc_stats->uc_non_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_ud_non_dpp_qps",
-+                              (u64)rsrc_stats->ud_non_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_srqs",
-+                              (u64)rsrc_stats->srqs);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_rbqs",
-+                              (u64)rsrc_stats->rbqs);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_64K_nsmr",
-+                              (u64)rsrc_stats->r64K_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_64K_to_2M_nsmr",
-+                              (u64)rsrc_stats->r64K_to_2M_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_2M_to_44M_nsmr",
-+                              (u64)rsrc_stats->r2M_to_44M_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_44M_to_1G_nsmr",
-+                              (u64)rsrc_stats->r44M_to_1G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_1G_to_4G_nsmr",
-+                              (u64)rsrc_stats->r1G_to_4G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_nsmr_count_4G_to_32G",
-+                              (u64)rsrc_stats->nsmr_count_4G_to_32G);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_32G_to_64G_nsmr",
-+                              (u64)rsrc_stats->r32G_to_64G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_64G_to_128G_nsmr",
-+                              (u64)rsrc_stats->r64G_to_128G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_128G_to_higher_nsmr",
-+                              (u64)rsrc_stats->r128G_to_higher_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_embedded_nsmr",
-+                              (u64)rsrc_stats->embedded_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_frmr",
-+                              (u64)rsrc_stats->frmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_prefetch_qps",
-+                              (u64)rsrc_stats->prefetch_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_ondemand_qps",
-+                              (u64)rsrc_stats->ondemand_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_phy_mr",
-+                              (u64)rsrc_stats->phy_mr);
-+      pcur += ocrdma_add_stat(stats, pcur, "active_mw",
-+                              (u64)rsrc_stats->mw);
-+
-+      /* Print the threshold stats */
-+      rsrc_stats = &rdma_stats->th_rsrc_stats;
-+
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_dpp_pds",
-+                              (u64)rsrc_stats->dpp_pds);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_non_dpp_pds",
-+                              (u64)rsrc_stats->non_dpp_pds);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_rc_dpp_qps",
-+                              (u64)rsrc_stats->rc_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_uc_dpp_qps",
-+                              (u64)rsrc_stats->uc_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_ud_dpp_qps",
-+                              (u64)rsrc_stats->ud_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_rc_non_dpp_qps",
-+                              (u64)rsrc_stats->rc_non_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_uc_non_dpp_qps",
-+                              (u64)rsrc_stats->uc_non_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_ud_non_dpp_qps",
-+                              (u64)rsrc_stats->ud_non_dpp_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_srqs",
-+                              (u64)rsrc_stats->srqs);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_rbqs",
-+                              (u64)rsrc_stats->rbqs);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_64K_nsmr",
-+                              (u64)rsrc_stats->r64K_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_64K_to_2M_nsmr",
-+                              (u64)rsrc_stats->r64K_to_2M_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_2M_to_44M_nsmr",
-+                              (u64)rsrc_stats->r2M_to_44M_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_44M_to_1G_nsmr",
-+                              (u64)rsrc_stats->r44M_to_1G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_1G_to_4G_nsmr",
-+                              (u64)rsrc_stats->r1G_to_4G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_nsmr_count_4G_to_32G",
-+                              (u64)rsrc_stats->nsmr_count_4G_to_32G);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_32G_to_64G_nsmr",
-+                              (u64)rsrc_stats->r32G_to_64G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_64G_to_128G_nsmr",
-+                              (u64)rsrc_stats->r64G_to_128G_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_128G_to_higher_nsmr",
-+                              (u64)rsrc_stats->r128G_to_higher_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_embedded_nsmr",
-+                              (u64)rsrc_stats->embedded_nsmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_frmr",
-+                              (u64)rsrc_stats->frmr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_prefetch_qps",
-+                              (u64)rsrc_stats->prefetch_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_ondemand_qps",
-+                              (u64)rsrc_stats->ondemand_qps);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_phy_mr",
-+                              (u64)rsrc_stats->phy_mr);
-+      pcur += ocrdma_add_stat(stats, pcur, "threshold_mw",
-+                              (u64)rsrc_stats->mw);
-+      return stats;
-+}
-+
-+static char *ocrdma_rx_stats(struct ocrdma_dev *dev)
-+{
-+      char *stats = dev->stats_mem.debugfs_mem, *pcur;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_rx_stats *rx_stats = &rdma_stats->rx_stats;
-+
-+      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      pcur = stats;
-+      pcur += ocrdma_add_stat
-+              (stats, pcur, "roce_frame_bytes",
-+               convert_to_64bit(rx_stats->roce_frame_bytes_lo,
-+               rx_stats->roce_frame_bytes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "roce_frame_icrc_drops",
-+                              (u64)rx_stats->roce_frame_icrc_drops);
-+      pcur += ocrdma_add_stat(stats, pcur, "roce_frame_payload_len_drops",
-+                              (u64)rx_stats->roce_frame_payload_len_drops);
-+      pcur += ocrdma_add_stat(stats, pcur, "ud_drops",
-+                              (u64)rx_stats->ud_drops);
-+      pcur += ocrdma_add_stat(stats, pcur, "qp1_drops",
-+                              (u64)rx_stats->qp1_drops);
-+      pcur += ocrdma_add_stat(stats, pcur, "psn_error_request_packets",
-+                              (u64)rx_stats->psn_error_request_packets);
-+      pcur += ocrdma_add_stat(stats, pcur, "psn_error_resp_packets",
-+                              (u64)rx_stats->psn_error_resp_packets);
-+      pcur += ocrdma_add_stat(stats, pcur, "rnr_nak_timeouts",
-+                              (u64)rx_stats->rnr_nak_timeouts);
-+      pcur += ocrdma_add_stat(stats, pcur, "rnr_nak_receives",
-+                              (u64)rx_stats->rnr_nak_receives);
-+      pcur += ocrdma_add_stat(stats, pcur, "roce_frame_rxmt_drops",
-+                              (u64)rx_stats->roce_frame_rxmt_drops);
-+      pcur += ocrdma_add_stat(stats, pcur, "nak_count_psn_sequence_errors",
-+                              (u64)rx_stats->nak_count_psn_sequence_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "rc_drop_count_lookup_errors",
-+                              (u64)rx_stats->rc_drop_count_lookup_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "rq_rnr_naks",
-+                              (u64)rx_stats->rq_rnr_naks);
-+      pcur += ocrdma_add_stat(stats, pcur, "srq_rnr_naks",
-+                              (u64)rx_stats->srq_rnr_naks);
-+      pcur += ocrdma_add_stat(stats, pcur, "roce_frames",
-+                              convert_to_64bit(rx_stats->roce_frames_lo,
-+                                               rx_stats->roce_frames_hi));
-+
-+      return stats;
-+}
-+
-+static char *ocrdma_tx_stats(struct ocrdma_dev *dev)
-+{
-+      char *stats = dev->stats_mem.debugfs_mem, *pcur;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_tx_stats *tx_stats = &rdma_stats->tx_stats;
-+
-+      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      pcur = stats;
-+      pcur += ocrdma_add_stat(stats, pcur, "send_pkts",
-+                              convert_to_64bit(tx_stats->send_pkts_lo,
-+                                               tx_stats->send_pkts_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "write_pkts",
-+                              convert_to_64bit(tx_stats->write_pkts_lo,
-+                                               tx_stats->write_pkts_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "read_pkts",
-+                              convert_to_64bit(tx_stats->read_pkts_lo,
-+                                               tx_stats->read_pkts_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "read_rsp_pkts",
-+                              convert_to_64bit(tx_stats->read_rsp_pkts_lo,
-+                                               tx_stats->read_rsp_pkts_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "ack_pkts",
-+                              convert_to_64bit(tx_stats->ack_pkts_lo,
-+                                               tx_stats->ack_pkts_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "send_bytes",
-+                              convert_to_64bit(tx_stats->send_bytes_lo,
-+                                               tx_stats->send_bytes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "write_bytes",
-+                              convert_to_64bit(tx_stats->write_bytes_lo,
-+                                               tx_stats->write_bytes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "read_req_bytes",
-+                              convert_to_64bit(tx_stats->read_req_bytes_lo,
-+                                               tx_stats->read_req_bytes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "read_rsp_bytes",
-+                              convert_to_64bit(tx_stats->read_rsp_bytes_lo,
-+                                               tx_stats->read_rsp_bytes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "ack_timeouts",
-+                              (u64)tx_stats->ack_timeouts);
-+
-+      return stats;
-+}
-+
-+static char *ocrdma_wqe_stats(struct ocrdma_dev *dev)
-+{
-+      char *stats = dev->stats_mem.debugfs_mem, *pcur;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_wqe_stats *wqe_stats = &rdma_stats->wqe_stats;
-+
-+      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      pcur = stats;
-+      pcur += ocrdma_add_stat(stats, pcur, "large_send_rc_wqes",
-+              convert_to_64bit(wqe_stats->large_send_rc_wqes_lo,
-+                               wqe_stats->large_send_rc_wqes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "large_write_rc_wqes",
-+              convert_to_64bit(wqe_stats->large_write_rc_wqes_lo,
-+                               wqe_stats->large_write_rc_wqes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "read_wqes",
-+                              convert_to_64bit(wqe_stats->read_wqes_lo,
-+                                               wqe_stats->read_wqes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "frmr_wqes",
-+                              convert_to_64bit(wqe_stats->frmr_wqes_lo,
-+                                               wqe_stats->frmr_wqes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "mw_bind_wqes",
-+                              convert_to_64bit(wqe_stats->mw_bind_wqes_lo,
-+                                               wqe_stats->mw_bind_wqes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "invalidate_wqes",
-+              convert_to_64bit(wqe_stats->invalidate_wqes_lo,
-+                               wqe_stats->invalidate_wqes_hi));
-+      pcur += ocrdma_add_stat(stats, pcur, "dpp_wqe_drops",
-+                              (u64)wqe_stats->dpp_wqe_drops);
-+      return stats;
-+}
-+
-+static char *ocrdma_db_errstats(struct ocrdma_dev *dev)
-+{
-+      char *stats = dev->stats_mem.debugfs_mem, *pcur;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_db_err_stats *db_err_stats = &rdma_stats->db_err_stats;
-+
-+      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      pcur = stats;
-+      pcur += ocrdma_add_stat(stats, pcur, "sq_doorbell_errors",
-+                              (u64)db_err_stats->sq_doorbell_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "cq_doorbell_errors",
-+                              (u64)db_err_stats->cq_doorbell_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "rq_srq_doorbell_errors",
-+                              (u64)db_err_stats->rq_srq_doorbell_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "cq_overflow_errors",
-+                              (u64)db_err_stats->cq_overflow_errors);
-+      return stats;
-+}
-+
-+static char *ocrdma_rxqp_errstats(struct ocrdma_dev *dev)
-+{
-+      char *stats = dev->stats_mem.debugfs_mem, *pcur;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_rx_qp_err_stats *rx_qp_err_stats =
-+               &rdma_stats->rx_qp_err_stats;
-+
-+      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      pcur = stats;
-+      pcur += ocrdma_add_stat(stats, pcur, "nak_invalid_requst_errors",
-+                      (u64)rx_qp_err_stats->nak_invalid_requst_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "nak_remote_operation_errors",
-+                      (u64)rx_qp_err_stats->nak_remote_operation_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "nak_count_remote_access_errors",
-+                      (u64)rx_qp_err_stats->nak_count_remote_access_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "local_length_errors",
-+                      (u64)rx_qp_err_stats->local_length_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "local_protection_errors",
-+                      (u64)rx_qp_err_stats->local_protection_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "local_qp_operation_errors",
-+                      (u64)rx_qp_err_stats->local_qp_operation_errors);
-+      return stats;
-+}
-+
-+static char *ocrdma_txqp_errstats(struct ocrdma_dev *dev)
-+{
-+      char *stats = dev->stats_mem.debugfs_mem, *pcur;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_tx_qp_err_stats *tx_qp_err_stats =
-+              &rdma_stats->tx_qp_err_stats;
-+
-+      memset(stats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      pcur = stats;
-+      pcur += ocrdma_add_stat(stats, pcur, "local_length_errors",
-+                      (u64)tx_qp_err_stats->local_length_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "local_protection_errors",
-+                      (u64)tx_qp_err_stats->local_protection_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "local_qp_operation_errors",
-+                      (u64)tx_qp_err_stats->local_qp_operation_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "retry_count_exceeded_errors",
-+                      (u64)tx_qp_err_stats->retry_count_exceeded_errors);
-+      pcur += ocrdma_add_stat(stats, pcur, "rnr_retry_count_exceeded_errors",
-+                      (u64)tx_qp_err_stats->rnr_retry_count_exceeded_errors);
-+      return stats;
-+}
-+
-+static char *ocrdma_tx_dbg_stats(struct ocrdma_dev *dev)
-+{
-+      int i;
-+      char *pstats = dev->stats_mem.debugfs_mem;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_tx_dbg_stats *tx_dbg_stats =
-+              &rdma_stats->tx_dbg_stats;
-+
-+      memset(pstats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      for (i = 0; i < 100; i++)
-+              pstats += snprintf(pstats, 80, "DW[%d] = 0x%x\n", i,
-+                               tx_dbg_stats->data[i]);
-+
-+      return dev->stats_mem.debugfs_mem;
-+}
-+
-+static char *ocrdma_rx_dbg_stats(struct ocrdma_dev *dev)
-+{
-+      int i;
-+      char *pstats = dev->stats_mem.debugfs_mem;
-+      struct ocrdma_rdma_stats_resp *rdma_stats =
-+              (struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
-+      struct ocrdma_rx_dbg_stats *rx_dbg_stats =
-+              &rdma_stats->rx_dbg_stats;
-+
-+      memset(pstats, 0, (OCRDMA_MAX_DBGFS_MEM));
-+
-+      for (i = 0; i < 200; i++)
-+              pstats += snprintf(pstats, 80, "DW[%d] = 0x%x\n", i,
-+                               rx_dbg_stats->data[i]);
-+
-+      return dev->stats_mem.debugfs_mem;
-+}
-+
-+static void ocrdma_update_stats(struct ocrdma_dev *dev)
-+{
-+      ulong now = jiffies, secs;
-+      int status = 0;
-+
-+      secs = jiffies_to_msecs(now - dev->last_stats_time) / 1000U;
-+      if (secs) {
-+              /* update */
-+              status = ocrdma_mbx_rdma_stats(dev, false);
-+              if (status)
-+                      pr_err("%s: stats mbox failed with status = %d\n",
-+                             __func__, status);
-+              dev->last_stats_time = jiffies;
-+      }
-+}
-+
-+static ssize_t ocrdma_dbgfs_ops_read(struct file *filp, char __user *buffer,
-+                                      size_t usr_buf_len, loff_t *ppos)
-+{
-+      struct ocrdma_stats *pstats = filp->private_data;
-+      struct ocrdma_dev *dev = pstats->dev;
-+      ssize_t status = 0;
-+      char *data = NULL;
-+
-+      /* No partial reads */
-+      if (*ppos != 0)
-+              return 0;
-+
-+      mutex_lock(&dev->stats_lock);
-+
-+      ocrdma_update_stats(dev);
-+
-+      switch (pstats->type) {
-+      case OCRDMA_RSRC_STATS:
-+              data = ocrdma_resource_stats(dev);
-+              break;
-+      case OCRDMA_RXSTATS:
-+              data = ocrdma_rx_stats(dev);
-+              break;
-+      case OCRDMA_WQESTATS:
-+              data = ocrdma_wqe_stats(dev);
-+              break;
-+      case OCRDMA_TXSTATS:
-+              data = ocrdma_tx_stats(dev);
-+              break;
-+      case OCRDMA_DB_ERRSTATS:
-+              data = ocrdma_db_errstats(dev);
-+              break;
-+      case OCRDMA_RXQP_ERRSTATS:
-+              data = ocrdma_rxqp_errstats(dev);
-+              break;
-+      case OCRDMA_TXQP_ERRSTATS:
-+              data = ocrdma_txqp_errstats(dev);
-+              break;
-+      case OCRDMA_TX_DBG_STATS:
-+              data = ocrdma_tx_dbg_stats(dev);
-+              break;
-+      case OCRDMA_RX_DBG_STATS:
-+              data = ocrdma_rx_dbg_stats(dev);
-+              break;
-+
-+      default:
-+              status = -EFAULT;
-+              goto exit;
-+      }
-+
-+      if (usr_buf_len < strlen(data)) {
-+              status = -ENOSPC;
-+              goto exit;
-+      }
-+
-+      status = simple_read_from_buffer(buffer, usr_buf_len, ppos, data,
-+                                       strlen(data));
-+exit:
-+      mutex_unlock(&dev->stats_lock);
-+      return status;
-+}
-+
-+int ocrdma_debugfs_open(struct inode *inode, struct file *file)
-+{
-+      if (inode->i_private)
-+              file->private_data = inode->i_private;
-+      return 0;
-+}
-+
-+static const struct file_operations ocrdma_dbg_ops = {
-+      .owner = THIS_MODULE,
-+      .open = ocrdma_debugfs_open,
-+      .read = ocrdma_dbgfs_ops_read,
-+};
-+
-+void ocrdma_add_port_stats(struct ocrdma_dev *dev)
-+{
-+      if (!ocrdma_dbgfs_dir)
-+              return;
-+
-+      /* Create post stats base dir */
-+      dev->dir = debugfs_create_dir(dev->ibdev.name, ocrdma_dbgfs_dir);
-+      if (!dev->dir)
-+              goto err;
-+
-+      dev->rsrc_stats.type = OCRDMA_RSRC_STATS;
-+      dev->rsrc_stats.dev = dev;
-+      if (!debugfs_create_file("resource_stats", S_IRUSR, dev->dir,
-+                               &dev->rsrc_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+      dev->rx_stats.type = OCRDMA_RXSTATS;
-+      dev->rx_stats.dev = dev;
-+      if (!debugfs_create_file("rx_stats", S_IRUSR, dev->dir,
-+                               &dev->rx_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+      dev->wqe_stats.type = OCRDMA_WQESTATS;
-+      dev->wqe_stats.dev = dev;
-+      if (!debugfs_create_file("wqe_stats", S_IRUSR, dev->dir,
-+                               &dev->wqe_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+      dev->tx_stats.type = OCRDMA_TXSTATS;
-+      dev->tx_stats.dev = dev;
-+      if (!debugfs_create_file("tx_stats", S_IRUSR, dev->dir,
-+                               &dev->tx_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+      dev->db_err_stats.type = OCRDMA_DB_ERRSTATS;
-+      dev->db_err_stats.dev = dev;
-+      if (!debugfs_create_file("db_err_stats", S_IRUSR, dev->dir,
-+                               &dev->db_err_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+
-+      dev->tx_qp_err_stats.type = OCRDMA_TXQP_ERRSTATS;
-+      dev->tx_qp_err_stats.dev = dev;
-+      if (!debugfs_create_file("tx_qp_err_stats", S_IRUSR, dev->dir,
-+                               &dev->tx_qp_err_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+      dev->rx_qp_err_stats.type = OCRDMA_RXQP_ERRSTATS;
-+      dev->rx_qp_err_stats.dev = dev;
-+      if (!debugfs_create_file("rx_qp_err_stats", S_IRUSR, dev->dir,
-+                               &dev->rx_qp_err_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+
-+      dev->tx_dbg_stats.type = OCRDMA_TX_DBG_STATS;
-+      dev->tx_dbg_stats.dev = dev;
-+      if (!debugfs_create_file("tx_dbg_stats", S_IRUSR, dev->dir,
-+                               &dev->tx_dbg_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+      dev->rx_dbg_stats.type = OCRDMA_RX_DBG_STATS;
-+      dev->rx_dbg_stats.dev = dev;
-+      if (!debugfs_create_file("rx_dbg_stats", S_IRUSR, dev->dir,
-+                               &dev->rx_dbg_stats, &ocrdma_dbg_ops))
-+              goto err;
-+
-+      /* Now create dma_mem for stats mbx command */
-+      if (!ocrdma_alloc_stats_mem(dev))
-+              goto err;
-+
-+      mutex_init(&dev->stats_lock);
-+
-+      return;
-+err:
-+      ocrdma_release_stats_mem(dev);
-+      debugfs_remove_recursive(dev->dir);
-+      dev->dir = NULL;
-+}
-+
-+void ocrdma_rem_port_stats(struct ocrdma_dev *dev)
-+{
-+      if (!dev->dir)
-+              return;
-+      mutex_destroy(&dev->stats_lock);
-+      ocrdma_release_stats_mem(dev);
-+      debugfs_remove(dev->dir);
-+}
-+
-+void ocrdma_init_debugfs(void)
-+{
-+      /* Create base dir in debugfs root dir */
-+      ocrdma_dbgfs_dir = debugfs_create_dir("ocrdma", NULL);
-+}
-+
-+void ocrdma_rem_debugfs(void)
-+{
-+      debugfs_remove_recursive(ocrdma_dbgfs_dir);
-+}
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_stats.h b/drivers/infiniband/hw/ocrdma/ocrdma_stats.h
-new file mode 100644
-index 0000000..5f5e20c
---- /dev/null
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_stats.h
-@@ -0,0 +1,54 @@
-+/*******************************************************************
-+ * This file is part of the Emulex RoCE Device Driver for          *
-+ * RoCE (RDMA over Converged Ethernet) adapters.                   *
-+ * Copyright (C) 2008-2014 Emulex. All rights reserved.            *
-+ * EMULEX and SLI are trademarks of Emulex.                        *
-+ * www.emulex.com                                                  *
-+ *                                                                 *
-+ * This program is free software; you can redistribute it and/or   *
-+ * modify it under the terms of version 2 of the GNU General       *
-+ * Public License as published by the Free Software Foundation.    *
-+ * This program is distributed in the hope that it will be useful. *
-+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
-+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
-+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
-+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
-+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
-+ * more details, a copy of which can be found in the file COPYING  *
-+ * included with this package.                                     *
-+ *
-+ * Contact Information:
-+ * linux-drivers@emulex.com
-+ *
-+ * Emulex
-+ * 3333 Susan Street
-+ * Costa Mesa, CA 92626
-+ *******************************************************************/
-+
-+#ifndef __OCRDMA_STATS_H__
-+#define __OCRDMA_STATS_H__
-+
-+#include <linux/debugfs.h>
-+#include "ocrdma.h"
-+#include "ocrdma_hw.h"
-+
-+#define OCRDMA_MAX_DBGFS_MEM 4096
-+
-+enum OCRDMA_STATS_TYPE {
-+      OCRDMA_RSRC_STATS,
-+      OCRDMA_RXSTATS,
-+      OCRDMA_WQESTATS,
-+      OCRDMA_TXSTATS,
-+      OCRDMA_DB_ERRSTATS,
-+      OCRDMA_RXQP_ERRSTATS,
-+      OCRDMA_TXQP_ERRSTATS,
-+      OCRDMA_TX_DBG_STATS,
-+      OCRDMA_RX_DBG_STATS
-+};
-+
-+void ocrdma_rem_debugfs(void);
-+void ocrdma_init_debugfs(void);
-+void ocrdma_rem_port_stats(struct ocrdma_dev *dev);
-+void ocrdma_add_port_stats(struct ocrdma_dev *dev);
-+
-+#endif        /* __OCRDMA_STATS_H__ */
--- 
-1.7.1
-
diff --git a/linux-next-pending/0019-RDMA-ocrdma-Display-fw-version.patch b/linux-next-pending/0019-RDMA-ocrdma-Display-fw-version.patch
deleted file mode 100644 (file)
index b367cde..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-From 7e7996497f57550a5d0b100eff66cf668e22f3e6 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Tue, 18 Feb 2014 16:49:54 +0530
-Subject: [PATCH 15/16] RDMA/ocrdma: Display fw version
-
-Adding a sysfs file for getting the FW version.
-
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_main.c |   41 +++++++++++++++++++++++++++-
- 1 files changed, 40 insertions(+), 1 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-index 95b364d..72389f6 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-@@ -399,9 +399,42 @@ static void ocrdma_free_resources(struct ocrdma_dev *dev)
-       kfree(dev->sgid_tbl);
- }
-+/* OCRDMA sysfs interface */
-+static ssize_t show_rev(struct device *device, struct device_attribute *attr,
-+                      char *buf)
-+{
-+      struct ocrdma_dev *dev = dev_get_drvdata(device);
-+
-+      return scnprintf(buf, PAGE_SIZE, "0x%x\n", dev->nic_info.pdev->vendor);
-+}
-+
-+static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
-+                      char *buf)
-+{
-+      struct ocrdma_dev *dev = dev_get_drvdata(device);
-+
-+      return scnprintf(buf, PAGE_SIZE, "%s\n", &dev->attr.fw_ver[0]);
-+}
-+
-+static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
-+static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
-+
-+static struct device_attribute *ocrdma_attributes[] = {
-+      &dev_attr_hw_rev,
-+      &dev_attr_fw_ver
-+};
-+
-+static void ocrdma_remove_sysfiles(struct ocrdma_dev *dev)
-+{
-+      int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(ocrdma_attributes); i++)
-+              device_remove_file(&dev->ibdev.dev, ocrdma_attributes[i]);
-+}
-+
- static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
- {
--      int status = 0;
-+      int status = 0, i;
-       struct ocrdma_dev *dev;
-       dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
-@@ -434,6 +467,9 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
-       if (status)
-               goto alloc_err;
-+      for (i = 0; i < ARRAY_SIZE(ocrdma_attributes); i++)
-+              if (device_create_file(&dev->ibdev.dev, ocrdma_attributes[i]))
-+                      goto sysfs_err;
-       spin_lock(&ocrdma_devlist_lock);
-       list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
-       spin_unlock(&ocrdma_devlist_lock);
-@@ -448,6 +484,8 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
-               dev_name(&dev->nic_info.pdev->dev), dev->id);
-       return dev;
-+sysfs_err:
-+      ocrdma_remove_sysfiles(dev);
- alloc_err:
-       ocrdma_free_resources(dev);
-       ocrdma_cleanup_hw(dev);
-@@ -477,6 +515,7 @@ static void ocrdma_remove(struct ocrdma_dev *dev)
-       /* first unregister with stack to stop all the active traffic
-        * of the registered clients.
-        */
-+      ocrdma_remove_sysfiles(dev);
-       ocrdma_rem_port_stats(dev);
-       ib_unregister_device(&dev->ibdev);
--- 
-1.7.1
-
diff --git a/linux-next-pending/0020-RDMA-ocrdma-code-clean-up.patch b/linux-next-pending/0020-RDMA-ocrdma-code-clean-up.patch
deleted file mode 100644 (file)
index dabe91b..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-From 50e79c44289926c546c5d3467e8ad268b6e66d78 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <Devesh.Sharma@Emulex.Com>
-Date: Mon, 3 Feb 2014 19:03:44 +0530
-Subject: [PATCH 16/16] RDMA/ocrdma: code clean-up
-
-Driver code is cleaned up and couple of cosmetic changes are introduced.
-also modifying GSI QP to error during ocrdma_close is fixed.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma.h       |    3 +--
- drivers/infiniband/hw/ocrdma/ocrdma_abi.h   |    4 +---
- drivers/infiniband/hw/ocrdma/ocrdma_ah.c    |    2 +-
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c    |   20 ++++++++------------
- drivers/infiniband/hw/ocrdma/ocrdma_main.c  |    2 +-
- drivers/infiniband/hw/ocrdma/ocrdma_sli.h   |   16 ++++++++--------
- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c |   22 +++-------------------
- 7 files changed, 23 insertions(+), 46 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
-index 15c8ee4..ad9a227 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
-@@ -35,6 +35,7 @@
- #include <rdma/ib_verbs.h>
- #include <rdma/ib_user_verbs.h>
-+#include <rdma/ib_addr.h>
- #include <be_roce.h>
- #include "ocrdma_sli.h"
-@@ -261,7 +262,6 @@ struct ocrdma_cq {
- struct ocrdma_pd {
-       struct ib_pd ibpd;
--      struct ocrdma_dev *dev;
-       struct ocrdma_ucontext *uctx;
-       u32 id;
-       int num_dpp_qp;
-@@ -346,7 +346,6 @@ struct ocrdma_qp {
-       bool dpp_enabled;
-       u8 *ird_q_va;
-       bool signaled;
--      u16 db_cache;
- };
- struct ocrdma_hw_mr {
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-index 5a82ce5..1554cca 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h
-@@ -108,9 +108,7 @@ struct ocrdma_create_qp_uresp {
-       u32 db_sq_offset;
-       u32 db_rq_offset;
-       u32 db_shift;
--      u64 rsvd1;
--      u64 rsvd2;
--      u64 rsvd3;
-+      u64 rsvd[11];
- } __packed;
- struct ocrdma_create_srq_uresp {
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
-index 69da5dd..a507972 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
-@@ -99,7 +99,7 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
-       if (!(attr->ah_flags & IB_AH_GRH))
-               return ERR_PTR(-EINVAL);
--      ah = kzalloc(sizeof *ah, GFP_ATOMIC);
-+      ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
-       if (!ah)
-               return ERR_PTR(-ENOMEM);
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index 3642383..ef630b0 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -32,7 +32,6 @@
- #include <rdma/ib_verbs.h>
- #include <rdma/ib_user_verbs.h>
--#include <rdma/ib_addr.h>
- #include "ocrdma.h"
- #include "ocrdma_hw.h"
-@@ -386,8 +385,8 @@ static void ocrdma_build_q_pages(struct ocrdma_pa *q_pa, int cnt,
-       }
- }
--static int ocrdma_mbx_delete_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q,
--                             int queue_type)
-+static int ocrdma_mbx_delete_q(struct ocrdma_dev *dev,
-+                             struct ocrdma_queue_info *q, int queue_type)
- {
-       u8 opcode = 0;
-       int status;
-@@ -778,7 +777,6 @@ static void ocrdma_process_grp5_aync(struct ocrdma_dev *dev,
-       }
- }
--
- static void ocrdma_process_acqe(struct ocrdma_dev *dev, void *ae_cqe)
- {
-       /* async CQE processing */
-@@ -825,8 +823,6 @@ static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id)
-                       ocrdma_process_acqe(dev, cqe);
-               else if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_CMPL_MASK)
-                       ocrdma_process_mcqe(dev, cqe);
--              else
--                      pr_err("%s() cqe->compl is not set.\n", __func__);
-               memset(cqe, 0, sizeof(struct ocrdma_mcqe));
-               ocrdma_mcq_inc_tail(dev);
-       }
-@@ -1050,6 +1046,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
-       attr->max_qp =
-           (rsp->qp_srq_cq_ird_ord & OCRDMA_MBX_QUERY_CFG_MAX_QP_MASK) >>
-           OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT;
-+      attr->max_srq =
-+              (rsp->max_srq_rpir_qps & OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK) >>
-+              OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET;
-       attr->max_send_sge = ((rsp->max_write_send_sge &
-                              OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >>
-                             OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT);
-@@ -1065,9 +1064,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
-       attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp &
-                               OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >>
-           OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT;
--      attr->max_srq =
--              (rsp->max_srq_rpir_qps & OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK) >>
--              OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET;
-       attr->max_ird_per_qp = (rsp->max_ird_ord_per_qp &
-                               OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_MASK) >>
-           OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_SHIFT;
-@@ -1411,7 +1407,7 @@ static int ocrdma_build_q_conf(u32 *num_entries, int entry_size,
- static int ocrdma_mbx_create_ah_tbl(struct ocrdma_dev *dev)
- {
--      int i ;
-+      int i;
-       int status = 0;
-       int max_ah;
-       struct ocrdma_create_ah_tbl *cmd;
-@@ -2296,7 +2292,7 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
-       memcpy(&cmd->params.dgid[0], &ah_attr->grh.dgid.raw[0],
-              sizeof(cmd->params.dgid));
-       status = ocrdma_query_gid(&qp->dev->ibdev, 1,
--                       ah_attr->grh.sgid_index, &sgid);
-+                      ah_attr->grh.sgid_index, &sgid);
-       if (status)
-               return status;
-@@ -2685,7 +2681,7 @@ static int ocrdma_create_eqs(struct ocrdma_dev *dev)
-       for (i = 0; i < num_eq; i++) {
-               status = ocrdma_create_eq(dev, &dev->eq_tbl[i],
--                                        OCRDMA_EQ_LEN);
-+                                      OCRDMA_EQ_LEN);
-               if (status) {
-                       status = -EINVAL;
-                       break;
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-index 72389f6..61836b2 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
-@@ -550,7 +550,7 @@ static int ocrdma_close(struct ocrdma_dev *dev)
-               cur_qp = dev->qp_tbl;
-               for (i = 0; i < OCRDMA_MAX_QP; i++) {
-                       qp = cur_qp[i];
--                      if (qp) {
-+                      if (qp && qp->ibqp.qp_type != IB_QPT_GSI) {
-                               /* change the QP state to ERROR */
-                               _ocrdma_modify_qp(&qp->ibqp, &attrs, attr_mask);
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-index 6e048b7..96c9ee6 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
-@@ -152,11 +152,10 @@ enum {
- #define OCRDMA_MIN_Q_PAGE_SIZE (4096)
- #define OCRDMA_MAX_Q_PAGES     (8)
--#define OCRDMA_SLI_ASIC_ID_OFFSET      0x9C
--#define OCRDMA_SLI_ASIC_REV_MASK       0x000000FF
--#define OCRDMA_SLI_ASIC_GEN_NUM_MASK   0x0000FF00
--#define OCRDMA_SLI_ASIC_GEN_NUM_SHIFT  0x08
--
-+#define OCRDMA_SLI_ASIC_ID_OFFSET     0x9C
-+#define OCRDMA_SLI_ASIC_REV_MASK      0x000000FF
-+#define OCRDMA_SLI_ASIC_GEN_NUM_MASK  0x0000FF00
-+#define OCRDMA_SLI_ASIC_GEN_NUM_SHIFT 0x08
- /*
- # 0: 4K Bytes
- # 1: 8K Bytes
-@@ -633,7 +632,7 @@ enum {
- enum {
-       OCRDMA_CREATE_CQ_VER2                   = 2,
--      OCRDMA_CREATE_CQ_VER3                   = 3,
-+      OCRDMA_CREATE_CQ_VER3                   = 3,
-       OCRDMA_CREATE_CQ_PAGE_CNT_MASK          = 0xFFFF,
-       OCRDMA_CREATE_CQ_PAGE_SIZE_SHIFT        = 16,
-@@ -1093,6 +1092,7 @@ enum {
-       OCRDMA_MODIFY_QP_RSP_MAX_ORD_MASK       = 0xFFFF <<
-                                       OCRDMA_MODIFY_QP_RSP_MAX_ORD_SHIFT
- };
-+
- struct ocrdma_modify_qp_rsp {
-       struct ocrdma_mqe_hdr hdr;
-       struct ocrdma_mbx_rsp rsp;
-@@ -1105,8 +1105,8 @@ struct ocrdma_query_qp {
-       struct ocrdma_mqe_hdr hdr;
-       struct ocrdma_mbx_hdr req;
--#define OCRDMA_QUERY_UP_QP_ID_SHIFT 0
--#define OCRDMA_QUERY_UP_QP_ID_MASK   0xFFFFFF
-+#define OCRDMA_QUERY_UP_QP_ID_SHIFT   0
-+#define OCRDMA_QUERY_UP_QP_ID_MASK    0xFFFFFF
-       u32 qp_id;
- };
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-index 635a757..ce88c0b 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
-@@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port,
-       dev = get_ocrdma_dev(ibdev);
-       memset(sgid, 0, sizeof(*sgid));
--      if (index >= OCRDMA_MAX_SGID)
-+      if (index > OCRDMA_MAX_SGID)
-               return -EINVAL;
-       memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid));
-@@ -144,7 +144,6 @@ static inline void get_link_speed_and_width(struct ocrdma_dev *dev,
-       }
- }
--
- int ocrdma_query_port(struct ib_device *ibdev,
-                     u8 port, struct ib_port_attr *props)
- {
-@@ -1210,7 +1209,6 @@ static void ocrdma_set_qp_init_params(struct ocrdma_qp *qp,
-       qp->signaled = (attrs->sq_sig_type == IB_SIGNAL_ALL_WR) ? true : false;
- }
--
- static void ocrdma_store_gsi_qp_cq(struct ocrdma_dev *dev,
-                                  struct ib_qp_init_attr *attrs)
- {
-@@ -1296,17 +1294,6 @@ gen_err:
-       return ERR_PTR(status);
- }
--
--static void ocrdma_flush_rq_db(struct ocrdma_qp *qp)
--{
--      if (qp->db_cache) {
--              u32 val = qp->rq.dbid | (qp->db_cache <<
--                              OCRDMA_DB_RQ_SHIFT);
--              iowrite32(val, qp->rq_db);
--              qp->db_cache = 0;
--      }
--}
--
- int _ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-                     int attr_mask)
- {
-@@ -1325,9 +1312,6 @@ int _ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-       if (status < 0)
-               return status;
-       status = ocrdma_mbx_modify_qp(dev, qp, attr, attr_mask, old_qps);
--      if (!status && attr_mask & IB_QP_STATE && attr->qp_state == IB_QPS_RTR)
--              ocrdma_flush_rq_db(qp);
--
-       return status;
- }
-@@ -2043,7 +2027,7 @@ static int ocrdma_build_fr(struct ocrdma_qp *qp, struct ocrdma_hdr_wqe *hdr,
-       fast_reg->num_sges = wr->wr.fast_reg.page_list_len;
-       fast_reg->size_sge =
-               get_encoded_page_size(1 << wr->wr.fast_reg.page_shift);
--      mr = (struct ocrdma_mr *) (unsigned long) qp->dev->stag_arr[(hdr->lkey >> 8) &
-+      mr = (struct ocrdma_mr *)qp->dev->stag_arr[(hdr->lkey >> 8) &
-               (OCRDMA_MAX_STAG - 1)];
-       build_frmr_pbes(wr, mr->hwmr.pbl_table, &mr->hwmr);
-       return 0;
-@@ -2878,7 +2862,7 @@ struct ib_mr *ocrdma_alloc_frmr(struct ib_pd *ibpd, int max_page_list_len)
-               goto mbx_err;
-       mr->ibmr.rkey = mr->hwmr.lkey;
-       mr->ibmr.lkey = mr->hwmr.lkey;
--      dev->stag_arr[(mr->hwmr.lkey >> 8) & (OCRDMA_MAX_STAG - 1)] = (unsigned long) mr;
-+      dev->stag_arr[(mr->hwmr.lkey >> 8) & (OCRDMA_MAX_STAG - 1)] = (u64)mr;
-       return &mr->ibmr;
- mbx_err:
-       ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
--- 
-1.7.1
-
diff --git a/linux-next-pending/0021-be2net-adding-abi-version-between-be2net-and-ocrdma.patch b/linux-next-pending/0021-be2net-adding-abi-version-between-be2net-and-ocrdma.patch
deleted file mode 100644 (file)
index 4704f90..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-From 9b13a993e13fc662fd44130093cf116114bae539 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Thu, 30 Jan 2014 10:00:37 +0530
-Subject: [PATCH] be2net: adding abi version between be2net and ocrdma
-
-This patch adds abi versioning between be2net and ocrdma
-driver modules. This is to catch the functional incompatibilities
-in the two drivers.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
-Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
----
- drivers/net/ethernet/emulex/benet/be_roce.c |    6 ++++++
- drivers/net/ethernet/emulex/benet/be_roce.h |    3 +++
- 2 files changed, 9 insertions(+), 0 deletions(-)
-
-diff --git a/drivers/net/ethernet/emulex/benet/be_roce.c b/drivers/net/ethernet/emulex/benet/be_roce.c
-index 9cd5415..aa7f943 100644
---- a/drivers/net/ethernet/emulex/benet/be_roce.c
-+++ b/drivers/net/ethernet/emulex/benet/be_roce.c
-@@ -35,6 +35,12 @@ static void _be_roce_dev_add(struct be_adapter *adapter)
-       if (!ocrdma_drv)
-               return;
-+
-+      if (ocrdma_drv->be_abi_version != BE_ROCE_ABI_VERSION) {
-+              dev_warn(&pdev->dev, "Cannot initialize RoCE due to ocrdma ABI mismatch\n");
-+              return;
-+      }
-+
-       if (pdev->device == OC_DEVICE_ID5) {
-               /* only msix is supported on these devices */
-               if (!msix_enabled(adapter))
-diff --git a/drivers/net/ethernet/emulex/benet/be_roce.h b/drivers/net/ethernet/emulex/benet/be_roce.h
-index 2cd1129..1bfb161 100644
---- a/drivers/net/ethernet/emulex/benet/be_roce.h
-+++ b/drivers/net/ethernet/emulex/benet/be_roce.h
-@@ -21,6 +21,8 @@
- #include <linux/pci.h>
- #include <linux/netdevice.h>
-+#define BE_ROCE_ABI_VERSION   1
-+
- struct ocrdma_dev;
- enum be_interrupt_mode {
-@@ -52,6 +54,7 @@ struct be_dev_info {
- /* ocrdma driver register's the callback functions with nic driver. */
- struct ocrdma_driver {
-       unsigned char name[32];
-+      u32 be_abi_version;
-       struct ocrdma_dev *(*add) (struct be_dev_info *dev_info);
-       void (*remove) (struct ocrdma_dev *);
-       void (*state_change_handler) (struct ocrdma_dev *, u32 new_state);
--- 
-1.7.1
-
diff --git a/linux-next-pending/0023-RDMA-ocrdma-ROLLBACK-dpp-posting-for-RDMA-READ.patch b/linux-next-pending/0023-RDMA-ocrdma-ROLLBACK-dpp-posting-for-RDMA-READ.patch
deleted file mode 100644 (file)
index 29b6d1e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8ff7eff20329c749c1907ce71cef9fd593584554 Mon Sep 17 00:00:00 2001
-From: Devesh Sharma <devesh.sharma@emulex.com>
-Date: Tue, 25 Feb 2014 21:16:58 +0530
-Subject: [PATCH 23/23] RDMA/ocrdma: ROLLBACK dpp posting for RDMA-READ
-
-this patch is to rollback the feature to post RDMA-READ wqe through
-DPP QP.
-
-Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
----
- drivers/infiniband/hw/ocrdma/ocrdma_hw.c |    3 ++-
- 1 files changed, 2 insertions(+), 1 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-index ef630b0..b305da6 100644
---- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
-@@ -2206,7 +2206,8 @@ int ocrdma_mbx_create_qp(struct ocrdma_qp *qp, struct ib_qp_init_attr *attrs,
-                               OCRDMA_CREATE_QP_REQ_RQ_CQID_MASK;
-       qp->rq_cq = cq;
--      if (pd->dpp_enabled && pd->num_dpp_qp) {
-+      if (pd->dpp_enabled && attrs->cap.max_inline_data && pd->num_dpp_qp &&
-+          (attrs->cap.max_inline_data <= dev->attr.max_inline_data)) {
-               ocrdma_set_create_qp_dpp_cmd(cmd, pd, qp, enable_dpp_cq,
-                                            dpp_cq_id);
-       }
--- 
-1.7.1
-
diff --git a/patches/0032-be2net-Issue-shutdown-event-to-ocrdma-driver.patch b/patches/0032-be2net-Issue-shutdown-event-to-ocrdma-driver.patch
new file mode 100644 (file)
index 0000000..f335774
--- /dev/null
@@ -0,0 +1,106 @@
+From 1d930f4ea2f2a4784ccfbb18b4263817db283282 Mon Sep 17 00:00:00 2001
+From: Devesh Sharma <devesh.sharma@emulex.com>
+Date: Tue, 12 Aug 2014 17:28:59 +0530
+Subject: [PATCH] be2net: Issue shutdown event to ocrdma driver
+
+In the shutdown path, when be2net calls pci_disable_msix(), it
+complains (BUG_ON) that irqs requested by ocrdma driver are still in
+use.  This patch fixes this problem by issuing shutdown event to
+ocrdma from be2net shutdown path.  As part of shutdown event
+processing, ocrdma driver will free up all the resources and free
+irqs.  Once this completes be2net completes pci_disable_msix
+successfully.
+
+Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+---
+ drivers/net/ethernet/emulex/benet/be.h      |    1 +
+ drivers/net/ethernet/emulex/benet/be_main.c |    1 +
+ drivers/net/ethernet/emulex/benet/be_roce.c |   18 ++++++++++++++++--
+ drivers/net/ethernet/emulex/benet/be_roce.h |    3 ++-
+ 4 files changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index c596cdd..76c196e 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -724,5 +724,6 @@ extern void be_roce_dev_remove(struct be_adapter *);
+  */
+ extern void be_roce_dev_open(struct be_adapter *);
+ extern void be_roce_dev_close(struct be_adapter *);
++extern void be_roce_dev_shutdown(struct be_adapter *);
+ #endif                                /* BE_H */
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 6f12546..78b934e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -4658,6 +4658,7 @@ static void be_shutdown(struct pci_dev *pdev)
+       if (!adapter)
+               return;
++      be_roce_dev_shutdown(adapter);
+       cancel_delayed_work_sync(&adapter->work);
+       cancel_delayed_work_sync(&adapter->func_recovery_work);
+diff --git a/drivers/net/ethernet/emulex/benet/be_roce.c b/drivers/net/ethernet/emulex/benet/be_roce.c
+index aa7f943..9f6da12 100644
+--- a/drivers/net/ethernet/emulex/benet/be_roce.c
++++ b/drivers/net/ethernet/emulex/benet/be_roce.c
+@@ -120,7 +120,8 @@ static void _be_roce_dev_open(struct be_adapter *adapter)
+ {
+       if (ocrdma_drv && adapter->ocrdma_dev &&
+           ocrdma_drv->state_change_handler)
+-              ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 0);
++              ocrdma_drv->state_change_handler(adapter->ocrdma_dev,
++                                               BE_DEV_UP);
+ }
+ void be_roce_dev_open(struct be_adapter *adapter)
+@@ -136,7 +137,8 @@ static void _be_roce_dev_close(struct be_adapter *adapter)
+ {
+       if (ocrdma_drv && adapter->ocrdma_dev &&
+           ocrdma_drv->state_change_handler)
+-              ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 1);
++              ocrdma_drv->state_change_handler(adapter->ocrdma_dev,
++                                               BE_DEV_DOWN);
+ }
+ void be_roce_dev_close(struct be_adapter *adapter)
+@@ -148,6 +150,18 @@ void be_roce_dev_close(struct be_adapter *adapter)
+       }
+ }
++void be_roce_dev_shutdown(struct be_adapter *adapter)
++{
++      if (be_roce_supported(adapter)) {
++              mutex_lock(&be_adapter_list_lock);
++              if (ocrdma_drv && adapter->ocrdma_dev &&
++                  ocrdma_drv->state_change_handler)
++                      ocrdma_drv->state_change_handler(adapter->ocrdma_dev,
++                                                       BE_DEV_SHUTDOWN);
++              mutex_unlock(&be_adapter_list_lock);
++      }
++}
++
+ int be_roce_register_driver(struct ocrdma_driver *drv)
+ {
+       struct be_adapter *dev;
+diff --git a/drivers/net/ethernet/emulex/benet/be_roce.h b/drivers/net/ethernet/emulex/benet/be_roce.h
+index 1bfb161..c36dc15 100644
+--- a/drivers/net/ethernet/emulex/benet/be_roce.h
++++ b/drivers/net/ethernet/emulex/benet/be_roce.h
+@@ -62,7 +62,8 @@ struct ocrdma_driver {
+ enum {
+       BE_DEV_UP       = 0,
+-      BE_DEV_DOWN     = 1
++      BE_DEV_DOWN     = 1,
++      BE_DEV_SHUTDOWN = 2
+ };
+ /* APIs for RoCE driver to register callback handlers,
+-- 
+1.7.1
+